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(),
00578                                     KImageIO::Reading))))
00579         {
00580             bSetWallpaper = true;
00581         }
00582 
00583         // Check what the source can do
00584         KURL url = lst.first(); // we'll assume it's the same for all URLs (hack)
00585         bool sReading = KProtocolInfo::supportsReading( url );
00586         bool sDeleting = KProtocolInfo::supportsDeleting( url );
00587         bool sMoving = KProtocolInfo::supportsMoving( url );
00588         // Check what the destination can do
00589         bool dWriting = KProtocolInfo::supportsWriting( m_destURL );
00590         if ( !dWriting )
00591         {
00592             delete this;
00593             return;
00594         }
00595 
00596         QPopupMenu popup;
00597         if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly )
00598             popup.insertItem(SmallIconSet("goto"), i18n( "&Move Here" ) + "\t" + KKey::modFlagLabel( KKey::SHIFT ), 2 );
00599         if ( sReading && !linkOnly)
00600             popup.insertItem(SmallIconSet("editcopy"), i18n( "&Copy Here" ) + "\t" + KKey::modFlagLabel( KKey::CTRL ), 1 );
00601         popup.insertItem(SmallIconSet("www"), i18n( "&Link Here" ) + "\t" + KKey::modFlagLabel( (KKey::ModFlag)( KKey::CTRL|KKey::SHIFT ) ), 3 );
00602         if (bSetWallpaper)
00603             popup.insertItem(SmallIconSet("background"), i18n( "Set as &Wallpaper" ), 4 );
00604         popup.insertSeparator();
00605         popup.insertItem(SmallIconSet("cancel"), i18n( "C&ancel" ) + "\t" + KKey( Qt::Key_Escape ).toString(), 5);
00606 
00607         int result = popup.exec( m_info->mousePos );
00608 
00609         switch (result) {
00610         case 1 : action = QDropEvent::Copy; break;
00611         case 2 : action = QDropEvent::Move; break;
00612         case 3 : action = QDropEvent::Link; break;
00613         case 4 :
00614         {
00615             kdDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url() << endl;
00616             if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first());
00617             delete this;
00618             return;
00619         }
00620         case 5 :
00621         default : delete this; return;
00622         }
00623     }
00624 
00625     KIO::Job * job = 0;
00626     switch ( action ) {
00627     case QDropEvent::Move :
00628         job = KIO::move( lst, m_destURL );
00629         job->setMetaData( m_info->metaData );
00630         setOperation( job, m_method == TRASH ? TRASH : MOVE, lst, m_destURL );
00631         (void) new KonqCommandRecorder(
00632             m_method == TRASH ? KonqCommand::TRASH : KonqCommand::MOVE,
00633             lst, m_destURL, job );
00634         return; // we still have stuff to do -> don't delete ourselves
00635     case QDropEvent::Copy :
00636         job = KIO::copy( lst, m_destURL );
00637         job->setMetaData( m_info->metaData );
00638         setOperation( job, COPY, lst, m_destURL );
00639         (void) new KonqCommandRecorder( KonqCommand::COPY, lst, m_destURL, job );
00640         return;
00641     case QDropEvent::Link :
00642         kdDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count() << endl;
00643         job = KIO::link( lst, m_destURL );
00644         job->setMetaData( m_info->metaData );
00645         setOperation( job, LINK, lst, m_destURL );
00646         (void) new KonqCommandRecorder( KonqCommand::LINK, lst, m_destURL, job );
00647         return;
00648     default : kdError(1203) << "Unknown action " << (int)action << endl;
00649     }
00650     delete this;
00651 }
00652 
00653 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const KURL& newurl )
00654 {
00655     kdDebug(1203) << "KonqOperations::rename oldurl=" << oldurl << " newurl=" << newurl << endl;
00656     if ( oldurl == newurl )
00657         return;
00658 
00659     KURL::List lst;
00660     lst.append(oldurl);
00661     KIO::Job * job = KIO::moveAs( oldurl, newurl, !oldurl.isLocalFile() );
00662     KonqOperations * op = new KonqOperations( parent );
00663     op->setOperation( job, MOVE, lst, newurl );
00664     (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, newurl, job );
00665     // if moving the desktop then update config file and emit
00666     if ( oldurl.isLocalFile() && oldurl.path(1) == KGlobalSettings::desktopPath() )
00667     {
00668         kdDebug(1203) << "That rename was the Desktop path, updating config files" << endl;
00669         KConfig *globalConfig = KGlobal::config();
00670         KConfigGroupSaver cgs( globalConfig, "Paths" );
00671         globalConfig->writePathEntry("Desktop" , newurl.path(), true, true );
00672         globalConfig->sync();
00673         KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS);
00674     }
00675 }
00676 
00677 void KonqOperations::setOperation( KIO::Job * job, int method, const KURL::List & /*src*/, const KURL & dest )
00678 {
00679     m_method = method;
00680     //m_srcURLs = src;
00681     m_destURL = dest;
00682     if ( job )
00683     {
00684         connect( job, SIGNAL( result( KIO::Job * ) ),
00685                  SLOT( slotResult( KIO::Job * ) ) );
00686     }
00687     else // for link
00688         slotResult( 0L );
00689 
00690     KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job);
00691     KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
00692     if (copyJob && iconView)
00693     {
00694         connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)),
00695              this, SLOT(slotAboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)));
00696         connect(this, SIGNAL(aboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)),
00697              iconView, SLOT(slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)));
00698     }
00699 }
00700 
00701 void KonqOperations::slotAboutToCreate(KIO::Job *, const QValueList<KIO::CopyInfo> &files)
00702 {
00703     emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files);
00704 }
00705 
00706 void KonqOperations::statURL( const KURL & url, const QObject *receiver, const char *member )
00707 {
00708     KonqOperations * op = new KonqOperations( 0L );
00709     op->_statURL( url, receiver, member );
00710     op->m_method = STAT;
00711 }
00712 
00713 void KonqOperations::_statURL( const KURL & url, const QObject *receiver, const char *member )
00714 {
00715     connect( this, SIGNAL( statFinished( const KFileItem * ) ), receiver, member );
00716     KIO::StatJob * job = KIO::stat( url /*, false?*/ );
00717     connect( job, SIGNAL( result( KIO::Job * ) ),
00718              SLOT( slotStatResult( KIO::Job * ) ) );
00719 }
00720 
00721 void KonqOperations::slotStatResult( KIO::Job * job )
00722 {
00723     if ( job->error())
00724         job->showErrorDialog( (QWidget*)parent() );
00725     else
00726     {
00727         KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
00728         KFileItem * item = new KFileItem( statJob->statResult(), statJob->url() );
00729         emit statFinished( item );
00730         delete item;
00731     }
00732     // If we're only here for a stat, we're done. But not if we used _statURL internally
00733     if ( m_method == STAT )
00734         delete this;
00735 }
00736 
00737 void KonqOperations::slotResult( KIO::Job * job )
00738 {
00739     if (job && job->error())
00740         job->showErrorDialog( (QWidget*)parent() );
00741     if ( m_method == EMPTYTRASH ) {
00742         // Update konq windows opened on trash:/
00743         KDirNotify_stub allDirNotify("*", "KDirNotify*");
00744         allDirNotify.FilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones...
00745     }
00746     delete this;
00747 }
00748 
00749 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const QString & name )
00750 {
00751     KURL newurl( oldurl );
00752     newurl.setPath( oldurl.directory(false, true) + name );
00753     kdDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl << endl;
00754     rename( parent, oldurl, newurl );
00755 }
00756 
00757 void KonqOperations::newDir( QWidget * parent, const KURL & baseURL )
00758 {
00759     bool ok;
00760     QString name = i18n( "New Folder" );
00761     if ( baseURL.isLocalFile() && QFileInfo( baseURL.path(+1) + name ).exists() )
00762         name = KIO::RenameDlg::suggestName( baseURL, i18n( "New Folder" ) );
00763 
00764     name = KInputDialog::getText ( i18n( "New Folder" ),
00765         i18n( "Enter folder name:" ), name, &ok, parent );
00766     if ( ok && !name.isEmpty() )
00767     {
00768         KURL url;
00769         if ((name[0] == '/') || (name[0] == '~'))
00770         {
00771            url.setPath(KShell::tildeExpand(name));
00772         }
00773         else
00774         {
00775            name = KIO::encodeFileName( name );
00776            url = baseURL;
00777            url.addPath( name );
00778         }
00779         KonqOperations::mkdir( 0L, url );
00780     }
00781 }
00782 
00784 
00785 KonqMultiRestoreJob::KonqMultiRestoreJob( const KURL::List& urls, bool showProgressInfo )
00786     : KIO::Job( showProgressInfo ),
00787       m_urls( urls ), m_urlsIterator( m_urls.begin() ),
00788       m_progress( 0 )
00789 {
00790   QTimer::singleShot(0, this, SLOT(slotStart()));
00791 }
00792 
00793 void KonqMultiRestoreJob::slotStart()
00794 {
00795     // Well, it's not a total in bytes, so this would look weird
00796     //if ( m_urlsIterator == m_urls.begin() ) // first time: emit total
00797     //    emit totalSize( m_urls.count() );
00798 
00799     if ( m_urlsIterator != m_urls.end() )
00800     {
00801         const KURL& url = *m_urlsIterator;
00802         Q_ASSERT( url.protocol() == "trash" );
00803         QByteArray packedArgs;
00804         QDataStream stream( packedArgs, IO_WriteOnly );
00805         stream << (int)3 << url;
00806         KIO::Job* job = KIO::special( url, packedArgs );
00807         addSubjob( job );
00808     }
00809     else // done!
00810     {
00811         KDirNotify_stub allDirNotify("*", "KDirNotify*");
00812         allDirNotify.FilesRemoved( m_urls );
00813         emitResult();
00814     }
00815 }
00816 
00817 void KonqMultiRestoreJob::slotResult( KIO::Job *job )
00818 {
00819     if ( job->error() )
00820     {
00821         KIO::Job::slotResult( job ); // will set the error and emit result(this)
00822         return;
00823     }
00824     subjobs.remove( job );
00825     // Move on to next one
00826     ++m_urlsIterator;
00827     ++m_progress;
00828     //emit processedSize( this, m_progress );
00829     emitPercent( m_progress, m_urls.count() );
00830     slotStart();
00831 }
00832 
00833 #include "konq_operations.moc"
KDE Logo
This file is part of the documentation for libkonq Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Nov 4 00:45:17 2005 by doxygen 1.4.0 written by Dimitri van Heesch, © 1997-2003