libkonq Library API Documentation

konq_operations.cc

00001 /*  This file is part of the KDE project
00002     Copyright (C) 2000  David Faure <faure@kde.org>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 */
00018 
00019 #include <qclipboard.h>
00020 #include "konq_operations.h"
00021 
00022 #include <kautomount.h>
00023 #include <kinputdialog.h>
00024 #include <klocale.h>
00025 #include <kmessagebox.h>
00026 #include <knotifyclient.h>
00027 #include <krun.h>
00028 #include <kshell.h>
00029 #include <kshortcut.h>
00030 
00031 #include <kdirnotify_stub.h>
00032 
00033 #include <dcopclient.h>
00034 #include "konq_undo.h"
00035 #include "konq_defaults.h"
00036 #include "konqbookmarkmanager.h"
00037 
00038 // For doDrop
00039 #include <qdir.h>//first
00040 #include <assert.h>
00041 #include <kapplication.h>
00042 #include <kipc.h>
00043 #include <kdebug.h>
00044 #include <kfileitem.h>
00045 #include <kdesktopfile.h>
00046 #include <kurldrag.h>
00047 #include <kglobalsettings.h>
00048 #include <kimageio.h>
00049 #include <kio/job.h>
00050 #include <kio/jobclasses.h>
00051 #include <kio/paste.h>
00052 #include <kio/netaccess.h>
00053 #include <kio/renamedlg.h>
00054 #include <konq_drag.h>
00055 #include <konq_iconviewwidget.h>
00056 #include <kprotocolinfo.h>
00057 #include <kprocess.h>
00058 #include <kstringhandler.h>
00059 #include <qpopupmenu.h>
00060 #include <unistd.h>
00061 #include <X11/Xlib.h>
00062 
00063 KBookmarkManager * KonqBookmarkManager::s_bookmarkManager;
00064 
00065 KonqOperations::KonqOperations( QWidget *parent )
00066     : QObject( parent, "KonqOperations" ),
00067       m_method( UNKNOWN ), m_info(0L), m_pasteInfo(0L)
00068 {
00069 }
00070 
00071 KonqOperations::~KonqOperations()
00072 {
00073     delete m_info;
00074     delete m_pasteInfo;
00075 }
00076 
00077 void KonqOperations::editMimeType( const QString & mimeType )
00078 {
00079   QString keditfiletype = QString::fromLatin1("keditfiletype");
00080   KRun::runCommand( keditfiletype + " " + KProcess::quote(mimeType),
00081                     keditfiletype, keditfiletype /*unused*/);
00082 }
00083 
00084 void KonqOperations::del( QWidget * parent, int method, const KURL::List & selectedURLs )
00085 {
00086   kdDebug(1203) << "KonqOperations::del " << parent->className() << endl;
00087   if ( selectedURLs.isEmpty() )
00088   {
00089     kdWarning(1203) << "Empty URL list !" << endl;
00090     return;
00091   }
00092 
00093   KonqOperations * op = new KonqOperations( parent );
00094   int confirmation = DEFAULT_CONFIRMATION;
00095   op->_del( method, selectedURLs, confirmation );
00096 }
00097 
00098 void KonqOperations::emptyTrash()
00099 {
00100   KonqOperations *op = new KonqOperations( 0L );
00101   op->_del( EMPTYTRASH, KURL("trash:/"), SKIP_CONFIRMATION );
00102 }
00103 
00104 void KonqOperations::restoreTrashedItems( const KURL::List& urls )
00105 {
00106   KonqOperations *op = new KonqOperations( 0L );
00107   op->_restoreTrashedItems( urls );
00108 }
00109 
00110 void KonqOperations::mkdir( QWidget *parent, const KURL & url )
00111 {
00112     KIO::Job * job = KIO::mkdir( url );
00113     KonqOperations * op = new KonqOperations( parent );
00114     op->setOperation( job, MKDIR, KURL::List(), url );
00115     (void) new KonqCommandRecorder( KonqCommand::MKDIR, KURL(), url, job ); // no support yet, apparently
00116 }
00117 
00118 void KonqOperations::doPaste( QWidget * parent, const KURL & destURL )
00119 {
00120    doPaste(parent, destURL, QPoint());
00121 }
00122 
00123 void KonqOperations::doPaste( QWidget * parent, const KURL & destURL, const QPoint &pos )
00124 {
00125     // move or not move ?
00126     bool move = false;
00127     QMimeSource *data = QApplication::clipboard()->data();
00128     if ( data->provides( "application/x-kde-cutselection" ) ) {
00129       move = KonqDrag::decodeIsCutSelection( data );
00130       kdDebug(1203) << "move (from clipboard data) = " << move << endl;
00131     }
00132 
00133     KIO::Job *job = KIO::pasteClipboard( destURL, move );
00134     if ( job )
00135     {
00136         KonqOperations * op = new KonqOperations( parent );
00137         KIO::CopyJob * copyJob = static_cast<KIO::CopyJob *>(job);
00138         KIOPasteInfo * pi = new KIOPasteInfo;
00139         pi->destURL = destURL;
00140         pi->mousePos = pos;
00141         op->setPasteInfo( pi );
00142         op->setOperation( job, move ? MOVE : COPY, copyJob->srcURLs(), copyJob->destURL() );
00143         (void) new KonqCommandRecorder( move ? KonqCommand::MOVE : KonqCommand::COPY, KURL::List(), destURL, job );
00144     }
00145 }
00146 
00147 void KonqOperations::copy( QWidget * parent, int method, const KURL::List & selectedURLs, const KURL& destUrl )
00148 {
00149   kdDebug(1203) << "KonqOperations::copy() " << parent->className() << endl;
00150   if ((method!=COPY) && (method!=MOVE) && (method!=LINK))
00151   {
00152     kdWarning(1203) << "Illegal copy method !" << endl;
00153     return;
00154   }
00155   if ( selectedURLs.isEmpty() )
00156   {
00157     kdWarning(1203) << "Empty URL list !" << endl;
00158     return;
00159   }
00160 
00161   KonqOperations * op = new KonqOperations( parent );
00162   KIO::Job* job(0);
00163   if (method==LINK)
00164      job= KIO::link( selectedURLs, destUrl);
00165   else if (method==MOVE)
00166      job= KIO::move( selectedURLs, destUrl);
00167   else
00168      job= KIO::copy( selectedURLs, destUrl);
00169 
00170   op->setOperation( job, method, selectedURLs, destUrl );
00171 
00172   if (method==COPY)
00173      (void) new KonqCommandRecorder( KonqCommand::COPY, selectedURLs, destUrl, job );
00174   else
00175      (void) new KonqCommandRecorder( method==MOVE?KonqCommand::MOVE:KonqCommand::LINK, selectedURLs, destUrl, job );
00176 }
00177 
00178 void KonqOperations::_del( int method, const KURL::List & _selectedURLs, int confirmation )
00179 {
00180     KURL::List selectedURLs;
00181     for (KURL::List::ConstIterator it = _selectedURLs.begin(); it != _selectedURLs.end(); ++it)
00182         if (KProtocolInfo::supportsDeleting(*it))
00183             selectedURLs.append(*it);
00184     if (selectedURLs.isEmpty()) {
00185         delete this;
00186         return;
00187     }
00188 
00189   m_method = method;
00190   if ( confirmation == SKIP_CONFIRMATION || askDeleteConfirmation( selectedURLs, confirmation ) )
00191   {
00192     //m_srcURLs = selectedURLs;
00193     KIO::Job *job;
00194     switch( method )
00195     {
00196       case TRASH:
00197       {
00198         job = KIO::trash( selectedURLs );
00199         (void) new KonqCommandRecorder( KonqCommand::TRASH, selectedURLs, "trash:/", job );
00200          break;
00201       }
00202       case EMPTYTRASH:
00203       {
00204         // Same as in ktrash --empty
00205         QByteArray packedArgs;
00206         QDataStream stream( packedArgs, IO_WriteOnly );
00207         stream << (int)1;
00208         job = KIO::special( "trash:/", packedArgs );
00209         KNotifyClient::event(0, "Trash: emptied");
00210         break;
00211       }
00212       case DEL:
00213         job = KIO::del( selectedURLs );
00214         break;
00215       case SHRED:
00216         job = KIO::del( selectedURLs, true );
00217         break;
00218       default:
00219         kdWarning() << "Unknown operation: " << method << endl;
00220         delete this;
00221         return;
00222     }
00223     connect( job, SIGNAL( result( KIO::Job * ) ),
00224              SLOT( slotResult( KIO::Job * ) ) );
00225   } else
00226     delete this;
00227 }
00228 
00229 void KonqOperations::_restoreTrashedItems( const KURL::List& urls )
00230 {
00231     m_method = RESTORE;
00232     KonqMultiRestoreJob* job = new KonqMultiRestoreJob( urls, true );
00233     connect( job, SIGNAL( result( KIO::Job * ) ),
00234              SLOT( slotResult( KIO::Job * ) ) );
00235 }
00236 
00237 bool KonqOperations::askDeleteConfirmation( const KURL::List & selectedURLs, int confirmation )
00238 {
00239     QString keyName;
00240     bool ask = ( confirmation == FORCE_CONFIRMATION );
00241     if ( !ask )
00242     {
00243         KConfig config("konquerorrc", true, false);
00244         config.setGroup( "Trash" );
00245         keyName = ( m_method == DEL ? "ConfirmDelete" : m_method == SHRED ? "ConfirmShred" : "ConfirmTrash" );
00246         bool defaultValue = ( m_method == DEL ? DEFAULT_CONFIRMDELETE : m_method == SHRED ? DEFAULT_CONFIRMSHRED : DEFAULT_CONFIRMTRASH );
00247         ask = config.readBoolEntry( keyName, defaultValue );
00248     }
00249     if ( ask )
00250     {
00251       KURL::List::ConstIterator it = selectedURLs.begin();
00252       QStringList prettyList;
00253       for ( ; it != selectedURLs.end(); ++it ) {
00254         if ( (*it).protocol() == "trash" ) {
00255           QString path = (*it).path();
00256           // HACK (#98983): remove "0-foo". Note that it works better than 
00257       // displaying KFileItem::name(), for files under a subdir.
00258           prettyList.append( path.remove(QRegExp("^/[0-9]*-")) );
00259         } else
00260           prettyList.append( (*it).pathOrURL() );
00261       }
00262 
00263       int result;
00264       switch(m_method)
00265       {
00266       case DEL:
00267           result = KMessageBox::warningContinueCancelList( 0,
00268                 i18n( "Do you really want to delete this item?", "Do you really want to delete these %n items?", prettyList.count()),
00269                 prettyList,
00270         i18n( "Delete Files" ),
00271         KStdGuiItem::del(),
00272         keyName, KMessageBox::Dangerous);
00273      break;
00274 
00275       case SHRED:
00276           result = KMessageBox::warningContinueCancelList( 0,
00277                 i18n( "Do you really want to shred this item?", "Do you really want to shred these %n items?", prettyList.count()),
00278                 prettyList,
00279                 i18n( "Shred Files" ),
00280         KGuiItem( i18n( "Shred" ), "editshred" ),
00281         keyName, KMessageBox::Dangerous);
00282         break;
00283 
00284       case MOVE:
00285       default:
00286           result = KMessageBox::warningContinueCancelList( 0,
00287                 i18n( "Do you really want to move this item to the trash?", "Do you really want to move these %n items to the trash?", prettyList.count()),
00288                 prettyList,
00289         i18n( "Move to Trash" ),
00290         KGuiItem( i18n( "Verb", "&Trash" ), "edittrash"),
00291         keyName, KMessageBox::Dangerous);
00292       }
00293       if (!keyName.isEmpty())
00294       {
00295          // Check kmessagebox setting... erase & copy to konquerorrc.
00296          KConfig *config = kapp->config();
00297          KConfigGroupSaver saver(config, "Notification Messages");
00298          if (!config->readBoolEntry(keyName, true))
00299          {
00300             config->writeEntry(keyName, true);
00301             config->sync();
00302             KConfig konq_config("konquerorrc", false);
00303             konq_config.setGroup( "Trash" );
00304             konq_config.writeEntry( keyName, false );
00305          }
00306       }
00307       return (result == KMessageBox::Continue);
00308     }
00309     return true;
00310 }
00311 
00312 void KonqOperations::doDrop( const KFileItem * destItem, const KURL & dest, QDropEvent * ev, QWidget * parent )
00313 {
00314     kdDebug(1203) << "doDrop: dest : " << dest.url() << endl;
00315     KURL::List lst;
00316     QMap<QString, QString> metaData;
00317     if ( KURLDrag::decode( ev, lst, metaData ) ) // Are they urls ?
00318     {
00319         if( lst.count() == 0 )
00320         {
00321             kdWarning(1203) << "Oooops, no data ...." << endl;
00322             ev->accept(false);
00323             return;
00324         }
00325         kdDebug(1203) << "KonqOperations::doDrop metaData: " << metaData.count() << " entries." << endl;
00326         QMap<QString,QString>::ConstIterator mit;
00327         for( mit = metaData.begin(); mit != metaData.end(); ++mit )
00328         {
00329             kdDebug(1203) << "metaData: key=" << mit.key() << " value=" << mit.data() << endl;
00330         }
00331         // Check if we dropped something on itself
00332         KURL::List::Iterator it = lst.begin();
00333         for ( ; it != lst.end() ; it++ )
00334         {
00335             kdDebug(1203) << "URL : " << (*it).url() << endl;
00336             if ( dest.equals( *it, true /*ignore trailing slashes*/ ) )
00337             {
00338                 // The event source may be the view or an item (icon)
00339                 // Note: ev->source() can be 0L! (in case of kdesktop) (Simon)
00340                 if ( !ev->source() || ev->source() != parent && ev->source()->parent() != parent )
00341                     KMessageBox::sorry( parent, i18n("You cannot drop a folder on to itself") );
00342                 kdDebug(1203) << "Dropped on itself" << endl;
00343                 ev->accept(false);
00344                 return; // do nothing instead of displaying kfm's annoying error box
00345             }
00346         }
00347 
00348         // Check the state of the modifiers key at the time of the drop
00349         Window root;
00350         Window child;
00351         int root_x, root_y, win_x, win_y;
00352         uint keybstate;
00353         XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
00354                        &root_x, &root_y, &win_x, &win_y, &keybstate );
00355 
00356         QDropEvent::Action action = ev->action();
00357         // Check for the drop of a bookmark -> we want a Link action
00358         if ( ev->provides("application/x-xbel") )
00359         {
00360             keybstate |= ControlMask | ShiftMask;
00361             action = QDropEvent::Link;
00362             kdDebug(1203) << "KonqOperations::doDrop Bookmark -> emulating Link" << endl;
00363         }
00364 
00365         KonqOperations * op = new KonqOperations(parent);
00366         op->setDropInfo( new DropInfo( keybstate, lst, metaData, win_x, win_y, action ) );
00367 
00368         // Ok, now we need destItem.
00369         if ( destItem )
00370         {
00371             op->asyncDrop( destItem ); // we have it already
00372         }
00373         else
00374         {
00375             // we need to stat to get it.
00376             op->_statURL( dest, op, SLOT( asyncDrop( const KFileItem * ) ) );
00377         }
00378         // In both cases asyncDrop will delete op when done
00379 
00380         ev->acceptAction();
00381     }
00382     else
00383     {
00384         QStrList formats;
00385 
00386         for ( int i = 0; ev->format( i ); i++ )
00387             if ( *( ev->format( i ) ) )
00388                 formats.append( ev->format( i ) );
00389         if ( formats.count() >= 1 )
00390         {
00391             //kdDebug(1203) << "Pasting to " << dest.url() << endl;
00392 
00393             QByteArray data;
00394 
00395             QString text;
00396             if ( QTextDrag::canDecode( ev ) && QTextDrag::decode( ev, text ) )
00397             {
00398                 QTextStream txtStream( data, IO_WriteOnly );
00399                 txtStream << text;
00400             }
00401             else
00402                 data = ev->data( formats.first() );
00403 
00404             // Delay the call to KIO::pasteData so that the event filters can return. See #38688.
00405             KonqOperations * op = new KonqOperations(parent);
00406             KIOPasteInfo * pi = new KIOPasteInfo;
00407             pi->data = data;
00408             pi->destURL = dest;
00409             pi->mousePos = ev->pos();
00410             pi->dialogText = i18n( "File name for dropped contents:" );
00411             op->setPasteInfo( pi );
00412             QTimer::singleShot( 0, op, SLOT( slotKIOPaste() ) );
00413         }
00414         ev->acceptAction();
00415     }
00416 }
00417 
00418 void KonqOperations::slotKIOPaste()
00419 {
00420     assert(m_pasteInfo); // setPasteInfo should have been called before
00421     KIO::CopyJob *job = KIO::pasteDataAsync( m_pasteInfo->destURL, m_pasteInfo->data, m_pasteInfo->dialogText );
00422     if ( job )
00423     {
00424         setOperation( job, COPY, KURL::List(), job->destURL() );
00425         (void) new KonqCommandRecorder( KonqCommand::COPY, KURL::List(), m_destURL, job );
00426     }
00427     else
00428     {
00429         delete this;
00430     }
00431 }
00432 
00433 void KonqOperations::asyncDrop( const KFileItem * destItem )
00434 {
00435     assert(m_info); // setDropInfo should have been called before asyncDrop
00436     m_destURL = destItem->url();
00437 
00438     //kdDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destURL << endl;
00439     // Check what the destination is
00440     if ( destItem->isDir() )
00441     {
00442         doFileCopy();
00443         return;
00444     }
00445     if ( !m_destURL.isLocalFile() )
00446     {
00447         // We dropped onto a remote URL that is not a directory!
00448         // (e.g. an HTTP link in the sidebar).
00449         // Can't do that, but we can't prevent it before stating the dest....
00450         kdWarning(1203) << "Cannot drop onto " << m_destURL << endl;
00451         delete this;
00452         return;
00453     }
00454     if ( destItem->mimetype() == "application/x-desktop")
00455     {
00456         // Local .desktop file. What type ?
00457         KDesktopFile desktopFile( m_destURL.path() );
00458         if ( desktopFile.hasApplicationType() )
00459         {
00460             QString error;
00461             QStringList stringList;
00462             KURL::List lst = m_info->lst;
00463             KURL::List::Iterator it = lst.begin();
00464             for ( ; it != lst.end() ; it++ )
00465             {
00466                 stringList.append((*it).url());
00467             }
00468             if ( KApplication::startServiceByDesktopPath( m_destURL.path(), stringList, &error ) > 0 )
00469                 KMessageBox::error( 0L, error );
00470         }
00471         else
00472         {
00473             // Device or Link -> adjust dest
00474             if ( desktopFile.hasDeviceType() && desktopFile.hasKey("MountPoint") ) {
00475                 QString point = desktopFile.readEntry( "MountPoint" );
00476                 m_destURL.setPath( point );
00477                 QString dev = desktopFile.readDevice();
00478                 QString mp = KIO::findDeviceMountPoint( dev );
00479                 // Is the device already mounted ?
00480                 if ( !mp.isNull() )
00481                     doFileCopy();
00482                 else
00483                 {
00484                     bool ro = desktopFile.readBoolEntry( "ReadOnly", false );
00485                     QString fstype = desktopFile.readEntry( "FSType" );
00486                     KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destURL.path(), false );
00487                     connect( am, SIGNAL( finished() ), this, SLOT( doFileCopy() ) );
00488                 }
00489                 return;
00490             }
00491             else if ( desktopFile.hasLinkType() && desktopFile.hasKey("URL") ) {
00492                 m_destURL = desktopFile.readPathEntry("URL");
00493                 doFileCopy();
00494                 return;
00495             }
00496             // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those.
00497         }
00498     }
00499     else
00500     {
00501         // Should be a local executable
00502         // (If this fails, there is a bug in KFileItem::acceptsDrops)
00503         kdDebug(1203) << "KonqOperations::doDrop " << m_destURL.path() << "should be an executable" << endl;
00504         Q_ASSERT ( access( QFile::encodeName(m_destURL.path()), X_OK ) == 0 );
00505         KProcess proc;
00506         proc << m_destURL.path() ;
00507         // Launch executable for each of the files
00508         KURL::List lst = m_info->lst;
00509         KURL::List::Iterator it = lst.begin();
00510         for ( ; it != lst.end() ; it++ )
00511             proc << (*it).path(); // assume local files
00512         kdDebug(1203) << "starting " << m_destURL.path() << " with " << lst.count() << " arguments" << endl;
00513         proc.start( KProcess::DontCare );
00514     }
00515     delete this;
00516 }
00517 
00518 void KonqOperations::doFileCopy()
00519 {
00520     assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop
00521     KURL::List lst = m_info->lst;
00522     QDropEvent::Action action = m_info->action;
00523     bool isDesktopFile = false;
00524     bool itemIsOnDesktop = false;
00525     bool allItemsAreFromTrash = true;
00526     KURL::List mlst; // list of items that can be moved
00527     for (KURL::List::ConstIterator it = lst.begin(); it != lst.end(); ++it)
00528     {
00529         bool local = (*it).isLocalFile();
00530         if ( KProtocolInfo::supportsDeleting( *it ) && (!local || QFileInfo((*it).directory()).isWritable() ))
00531             mlst.append(*it);
00532         if ( local && KDesktopFile::isDesktopFile((*it).path()))
00533             isDesktopFile = true;
00534         if ( local && (*it).path().startsWith(KGlobalSettings::desktopPath()))
00535             itemIsOnDesktop = true;
00536         if ( local || (*it).protocol() != "trash" )
00537             allItemsAreFromTrash = false;
00538     }
00539 
00540     bool linkOnly = false;
00541     if (isDesktopFile && !kapp->authorize("run_desktop_files") &&
00542         (m_destURL.path(1) == KGlobalSettings::desktopPath()) )
00543     {
00544        linkOnly = true;
00545     }
00546 
00547     if ( !mlst.isEmpty() && m_destURL.protocol() == "trash" )
00548     {
00549         if ( itemIsOnDesktop && !kapp->authorize("editable_desktop_icons") )
00550         {
00551             delete this;
00552             return;
00553         }
00554 
00555         m_method = TRASH;
00556         if ( askDeleteConfirmation( mlst, DEFAULT_CONFIRMATION ) )
00557             action = QDropEvent::Move;
00558         else
00559         {
00560             delete this;
00561             return;
00562         }
00563     }
00564     else if ( allItemsAreFromTrash || m_destURL.protocol() == "trash" ) {
00565         // No point in asking copy/move/link when using dnd from or to the trash.
00566         action = QDropEvent::Move;
00567     }
00568     else if ( (((m_info->keybstate & ControlMask) == 0) && ((m_info->keybstate & ShiftMask) == 0)) ||
00569               linkOnly )
00570     {
00571         // Neither control nor shift are pressed => show popup menu
00572         KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
00573         bool bSetWallpaper = false;
00574         if (iconView && iconView->maySetWallpaper() &&
00575             (lst.count() == 1) &&
00576             ((!KImageIO::type(lst.first().path()).isEmpty()) ||
00577              (KImageIO::isSupported(KMimeType::findByURL(lst.first())->name(), KImageIO::Reading)) ||
00578               lst.first().fileName().endsWith(".svg") || 
00579               lst.first().fileName().endsWith(".svgz")))
00580         {
00581             bSetWallpaper = true;
00582         }
00583 
00584         // Check what the source can do
00585         KURL url = lst.first(); // we'll assume it's the same for all URLs (hack)
00586         bool sReading = KProtocolInfo::supportsReading( url );
00587         bool sDeleting = KProtocolInfo::supportsDeleting( url );
00588         bool sMoving = KProtocolInfo::supportsMoving( url );
00589         // Check what the destination can do
00590         bool dWriting = KProtocolInfo::supportsWriting( m_destURL );
00591         if ( !dWriting )
00592         {
00593             delete this;
00594             return;
00595         }
00596 
00597         QPopupMenu popup;
00598         if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly )
00599             popup.insertItem(SmallIconSet("goto"), i18n( "&Move Here" ) + "\t" + KKey::modFlagLabel( KKey::SHIFT ), 2 );
00600         if ( sReading && !linkOnly)
00601             popup.insertItem(SmallIconSet("editcopy"), i18n( "&Copy Here" ) + "\t" + KKey::modFlagLabel( KKey::CTRL ), 1 );
00602         popup.insertItem(SmallIconSet("www"), i18n( "&Link Here" ) + "\t" + KKey::modFlagLabel( (KKey::ModFlag)( KKey::CTRL|KKey::SHIFT ) ), 3 );
00603         if (bSetWallpaper)
00604             popup.insertItem(SmallIconSet("background"), i18n( "Set as &Wallpaper" ), 4 );
00605         popup.insertSeparator();
00606         popup.insertItem(SmallIconSet("cancel"), i18n( "C&ancel" ) + "\t" + KKey( Qt::Key_Escape ).toString(), 5);
00607 
00608         int result = popup.exec( m_info->mousePos );
00609 
00610         switch (result) {
00611         case 1 : action = QDropEvent::Copy; break;
00612         case 2 : action = QDropEvent::Move; break;
00613         case 3 : action = QDropEvent::Link; break;
00614         case 4 :
00615         {
00616             kdDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url() << endl;
00617             if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first());
00618             delete this;
00619             return;
00620         }
00621         case 5 :
00622         default : delete this; return;
00623         }
00624     }
00625 
00626     KIO::Job * job = 0;
00627     switch ( action ) {
00628     case QDropEvent::Move :
00629         job = KIO::move( lst, m_destURL );
00630         job->setMetaData( m_info->metaData );
00631         setOperation( job, m_method == TRASH ? TRASH : MOVE, lst, m_destURL );
00632         (void) new KonqCommandRecorder(
00633             m_method == TRASH ? KonqCommand::TRASH : KonqCommand::MOVE,
00634             lst, m_destURL, job );
00635         return; // we still have stuff to do -> don't delete ourselves
00636     case QDropEvent::Copy :
00637         job = KIO::copy( lst, m_destURL );
00638         job->setMetaData( m_info->metaData );
00639         setOperation( job, COPY, lst, m_destURL );
00640         (void) new KonqCommandRecorder( KonqCommand::COPY, lst, m_destURL, job );
00641         return;
00642     case QDropEvent::Link :
00643         kdDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count() << endl;
00644         job = KIO::link( lst, m_destURL );
00645         job->setMetaData( m_info->metaData );
00646         setOperation( job, LINK, lst, m_destURL );
00647         (void) new KonqCommandRecorder( KonqCommand::LINK, lst, m_destURL, job );
00648         return;
00649     default : kdError(1203) << "Unknown action " << (int)action << endl;
00650     }
00651     delete this;
00652 }
00653 
00654 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const KURL& newurl )
00655 {
00656     kdDebug(1203) << "KonqOperations::rename oldurl=" << oldurl << " newurl=" << newurl << endl;
00657     if ( oldurl == newurl )
00658         return;
00659 
00660     KURL::List lst;
00661     lst.append(oldurl);
00662     KIO::Job * job = KIO::moveAs( oldurl, newurl, !oldurl.isLocalFile() );
00663     KonqOperations * op = new KonqOperations( parent );
00664     op->setOperation( job, MOVE, lst, newurl );
00665     (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, newurl, job );
00666     // if moving the desktop then update config file and emit
00667     if ( oldurl.isLocalFile() && oldurl.path(1) == KGlobalSettings::desktopPath() )
00668     {
00669         kdDebug(1203) << "That rename was the Desktop path, updating config files" << endl;
00670         KConfig *globalConfig = KGlobal::config();
00671         KConfigGroupSaver cgs( globalConfig, "Paths" );
00672         globalConfig->writePathEntry("Desktop" , newurl.path(), true, true );
00673         globalConfig->sync();
00674         KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS);
00675     }
00676 }
00677 
00678 void KonqOperations::setOperation( KIO::Job * job, int method, const KURL::List & /*src*/, const KURL & dest )
00679 {
00680     m_method = method;
00681     //m_srcURLs = src;
00682     m_destURL = dest;
00683     if ( job )
00684     {
00685         connect( job, SIGNAL( result( KIO::Job * ) ),
00686                  SLOT( slotResult( KIO::Job * ) ) );
00687     }
00688     else // for link
00689         slotResult( 0L );
00690 
00691     KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job);
00692     KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
00693     if (copyJob && iconView)
00694     {
00695         connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)),
00696              this, SLOT(slotAboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)));
00697         connect(this, SIGNAL(aboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)),
00698              iconView, SLOT(slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)));
00699     }
00700 }
00701 
00702 void KonqOperations::slotAboutToCreate(KIO::Job *, const QValueList<KIO::CopyInfo> &files)
00703 {
00704     emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files);
00705 }
00706 
00707 void KonqOperations::statURL( const KURL & url, const QObject *receiver, const char *member )
00708 {
00709     KonqOperations * op = new KonqOperations( 0L );
00710     op->_statURL( url, receiver, member );
00711     op->m_method = STAT;
00712 }
00713 
00714 void KonqOperations::_statURL( const KURL & url, const QObject *receiver, const char *member )
00715 {
00716     connect( this, SIGNAL( statFinished( const KFileItem * ) ), receiver, member );
00717     KIO::StatJob * job = KIO::stat( url /*, false?*/ );
00718     connect( job, SIGNAL( result( KIO::Job * ) ),
00719              SLOT( slotStatResult( KIO::Job * ) ) );
00720 }
00721 
00722 void KonqOperations::slotStatResult( KIO::Job * job )
00723 {
00724     if ( job->error())
00725         job->showErrorDialog( (QWidget*)parent() );
00726     else
00727     {
00728         KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
00729         KFileItem * item = new KFileItem( statJob->statResult(), statJob->url() );
00730         emit statFinished( item );
00731         delete item;
00732     }
00733     // If we're only here for a stat, we're done. But not if we used _statURL internally
00734     if ( m_method == STAT )
00735         delete this;
00736 }
00737 
00738 void KonqOperations::slotResult( KIO::Job * job )
00739 {
00740     if (job && job->error())
00741         job->showErrorDialog( (QWidget*)parent() );
00742     if ( m_method == EMPTYTRASH ) {
00743         // Update konq windows opened on trash:/
00744         KDirNotify_stub allDirNotify("*", "KDirNotify*");
00745         allDirNotify.FilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones...
00746     }
00747     delete this;
00748 }
00749 
00750 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const QString & name )
00751 {
00752     KURL newurl( oldurl );
00753     newurl.setPath( oldurl.directory(false, true) + name );
00754     kdDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl << endl;
00755     rename( parent, oldurl, newurl );
00756 }
00757 
00758 void KonqOperations::newDir( QWidget * parent, const KURL & baseURL )
00759 {
00760     bool ok;
00761     QString name = i18n( "New Folder" );
00762     if ( baseURL.isLocalFile() && QFileInfo( baseURL.path(+1) + name ).exists() )
00763         name = KIO::RenameDlg::suggestName( baseURL, i18n( "New Folder" ) );
00764 
00765     name = KInputDialog::getText ( i18n( "New Folder" ),
00766         i18n( "Enter folder name:" ), name, &ok, parent );
00767     if ( ok && !name.isEmpty() )
00768     {
00769         KURL url;
00770         if ((name[0] == '/') || (name[0] == '~'))
00771         {
00772            url.setPath(KShell::tildeExpand(name));
00773         }
00774         else
00775         {
00776            name = KIO::encodeFileName( name );
00777            url = baseURL;
00778            url.addPath( name );
00779         }
00780         KonqOperations::mkdir( 0L, url );
00781     }
00782 }
00783 
00785 
00786 KonqMultiRestoreJob::KonqMultiRestoreJob( const KURL::List& urls, bool showProgressInfo )
00787     : KIO::Job( showProgressInfo ),
00788       m_urls( urls ), m_urlsIterator( m_urls.begin() ),
00789       m_progress( 0 )
00790 {
00791   QTimer::singleShot(0, this, SLOT(slotStart()));
00792 }
00793 
00794 void KonqMultiRestoreJob::slotStart()
00795 {
00796     // Well, it's not a total in bytes, so this would look weird
00797     //if ( m_urlsIterator == m_urls.begin() ) // first time: emit total
00798     //    emit totalSize( m_urls.count() );
00799 
00800     if ( m_urlsIterator != m_urls.end() )
00801     {
00802         const KURL& url = *m_urlsIterator;
00803         Q_ASSERT( url.protocol() == "trash" );
00804         QByteArray packedArgs;
00805         QDataStream stream( packedArgs, IO_WriteOnly );
00806         stream << (int)3 << url;
00807         KIO::Job* job = KIO::special( url, packedArgs );
00808         addSubjob( job );
00809     }
00810     else // done!
00811     {
00812         KDirNotify_stub allDirNotify("*", "KDirNotify*");
00813         allDirNotify.FilesRemoved( m_urls );
00814         emitResult();
00815     }
00816 }
00817 
00818 void KonqMultiRestoreJob::slotResult( KIO::Job *job )
00819 {
00820     if ( job->error() )
00821     {
00822         KIO::Job::slotResult( job ); // will set the error and emit result(this)
00823         return;
00824     }
00825     subjobs.remove( job );
00826     // Move on to next one
00827     ++m_urlsIterator;
00828     ++m_progress;
00829     //emit processedSize( this, m_progress );
00830     emitPercent( m_progress, m_urls.count() );
00831     slotStart();
00832 }
00833 
00834 #include "konq_operations.moc"
KDE Logo
This file is part of the documentation for libkonq Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 13 19:27:50 2006 by doxygen 1.4.3 written by Dimitri van Heesch, © 1997-2003