• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkonq

konq_operations.cpp

Go to the documentation of this file.
00001 /*  This file is part of the KDE project
00002     Copyright 2000-2007  David Faure <faure@kde.org>
00003     Copyright 2003       Waldo Bastian <bastian@kde.org>
00004     Copyright 2002       Michael Brade <brade@kde.org>
00005     Copyright 2001-2002  Alexander Neundorf <neundorf@kde.org>
00006     Copyright 2000-2001  Simon Hausmann <hausmann@kde.org>
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) version 3.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00021 */
00022 
00023 #include "konq_operations.h"
00024 #include "konqmimedata.h"
00025 
00026 #include <ktoolinvocation.h>
00027 #include <kautomount.h>
00028 #include <kmountpoint.h>
00029 #include <kinputdialog.h>
00030 #include <klocale.h>
00031 #include <kmessagebox.h>
00032 #include <knotification.h>
00033 #include <krun.h>
00034 #include <kshell.h>
00035 #include <kprocess.h>
00036 #include <kshortcut.h>
00037 #include <kprotocolmanager.h>
00038 #include <kio/deletejob.h>
00039 #include <kio/fileundomanager.h>
00040 #include <kio/job.h>
00041 #include <kio/jobuidelegate.h>
00042 #include <kio/jobclasses.h>
00043 #include <kio/copyjob.h>
00044 #include <kio/paste.h>
00045 #include <kio/renamedialog.h>
00046 #include <kdirnotify.h>
00047 #include <kuiserverjobtracker.h>
00048 #include <kstandarddirs.h>
00049 // For doDrop
00050 #include <kauthorized.h>
00051 #include <kglobal.h>
00052 #include <kglobalsettings.h>
00053 #include <kdebug.h>
00054 #include <kfileitem.h>
00055 #include <kdesktopfile.h>
00056 
00057 //#include <konq_iconviewwidget.h>
00058 #include <QtDBus/QtDBus>
00059 #include <QMenu>
00060 #include <QApplication>
00061 #include <QClipboard>
00062 #include <QDropEvent>
00063 #include <QList>
00064 #include <QDir>
00065 
00066 #include <assert.h>
00067 #include <unistd.h>
00068 #include <kconfiggroup.h>
00069 
00070 KonqOperations::KonqOperations( QWidget *parent )
00071     : QObject( parent ),
00072       m_method( UNKNOWN ), m_info(0), m_pasteInfo(0)
00073 {
00074     setObjectName( "KonqOperations" );
00075 }
00076 
00077 KonqOperations::~KonqOperations()
00078 {
00079     delete m_info;
00080     delete m_pasteInfo;
00081 }
00082 
00083 void KonqOperations::editMimeType( const QString & mimeType, QWidget* parent )
00084 {
00085     QString keditfiletype = QLatin1String("keditfiletype");
00086     KRun::runCommand( keditfiletype
00087                       + " --parent " + QString::number( (long)parent->winId())
00088                       + ' ' + KShell::quoteArg(mimeType),
00089                       keditfiletype, keditfiletype /*unused*/, parent );
00090 }
00091 
00092 void KonqOperations::del( QWidget * parent, Operation method, const KUrl::List & selectedUrls )
00093 {
00094     kDebug(1203) << "KonqOperations::del " << parent->metaObject()->className();
00095     if ( selectedUrls.isEmpty() )
00096     {
00097         kWarning(1203) << "Empty URL list !" ;
00098         return;
00099     }
00100 
00101     KonqOperations * op = new KonqOperations( parent );
00102     ConfirmationType confirmation = DEFAULT_CONFIRMATION;
00103     op->_del( method, selectedUrls, confirmation );
00104 }
00105 
00106 void KonqOperations::emptyTrash( QWidget* parent )
00107 {
00108     KonqOperations *op = new KonqOperations( parent );
00109     op->_del( EMPTYTRASH, KUrl("trash:/"), SKIP_CONFIRMATION );
00110 }
00111 
00112 void KonqOperations::restoreTrashedItems( const KUrl::List& urls, QWidget* parent )
00113 {
00114     KonqOperations *op = new KonqOperations( parent );
00115     op->_restoreTrashedItems( urls );
00116 }
00117 
00118 KIO::SimpleJob* KonqOperations::mkdir( QWidget *parent, const KUrl & url )
00119 {
00120     KIO::SimpleJob * job = KIO::mkdir(url);
00121     job->ui()->setWindow(parent);
00122     job->ui()->setAutoErrorHandlingEnabled(true);
00123     KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Mkdir, KUrl(), url, job );
00124     return job;
00125 }
00126 
00127 void KonqOperations::doPaste( QWidget * parent, const KUrl & destUrl, const QPoint &pos )
00128 {
00129     // move or not move ?
00130     bool move = false;
00131     const QMimeData *data = QApplication::clipboard()->mimeData();
00132     if ( data->hasFormat( "application/x-kde-cutselection" ) ) {
00133       move = KonqMimeData::decodeIsCutSelection( data );
00134       kDebug(1203) << "move (from clipboard data) = " << move;
00135     }
00136 
00137     KIO::Job *job = KIO::pasteClipboard( destUrl, parent, move );
00138     if ( job )
00139     {
00140         KonqOperations * op = new KonqOperations( parent );
00141         KIO::CopyJob * copyJob = static_cast<KIO::CopyJob *>(job);
00142         KIOPasteInfo * pi = new KIOPasteInfo;
00143         pi->mousePos = pos;
00144         op->setPasteInfo( pi );
00145         op->setOperation( job, move ? MOVE : COPY, copyJob->destUrl() );
00146         KIO::FileUndoManager::self()->recordJob( move ? KIO::FileUndoManager::Move : KIO::FileUndoManager::Copy, KUrl::List(), destUrl, job );
00147     }
00148 }
00149 
00150 void KonqOperations::copy( QWidget * parent, Operation method, const KUrl::List & selectedUrls, const KUrl& destUrl )
00151 {
00152     kDebug(1203) << "KonqOperations::copy() " << parent->metaObject()->className();
00153     if ((method!=COPY) && (method!=MOVE) && (method!=LINK))
00154     {
00155         kWarning(1203) << "Illegal copy method !" ;
00156         return;
00157     }
00158     if ( selectedUrls.isEmpty() )
00159     {
00160         kWarning(1203) << "Empty URL list !" ;
00161         return;
00162     }
00163 
00164     KonqOperations * op = new KonqOperations( parent );
00165     KIO::CopyJob* job;
00166     if (method == LINK)
00167         job = KIO::link( selectedUrls, destUrl );
00168     else if (method == MOVE)
00169         job = KIO::move( selectedUrls, destUrl );
00170     else
00171         job = KIO::copy( selectedUrls, destUrl );
00172 
00173     op->setOperation( job, method, destUrl );
00174 
00175     KIO::FileUndoManager::self()->recordCopyJob(job);
00176 }
00177 
00178 void KonqOperations::_del( Operation method, const KUrl::List & _selectedUrls, ConfirmationType confirmation )
00179 {
00180     KUrl::List selectedUrls;
00181     for (KUrl::List::ConstIterator it = _selectedUrls.begin(); it != _selectedUrls.end(); ++it)
00182         if (KProtocolManager::supportsDeleting(*it))
00183             selectedUrls.append(*it);
00184     if (selectedUrls.isEmpty()) {
00185         delete this; // this one is ok, _del is always called directly
00186         return;
00187     }
00188 
00189     if ( confirmation == SKIP_CONFIRMATION || askDeleteConfirmation( selectedUrls, method, confirmation, parentWidget() ) )
00190     {
00191         //m_srcUrls = selectedUrls;
00192         KIO::Job *job;
00193         m_method = method;
00194         switch( method )
00195         {
00196         case TRASH:
00197         {
00198             job = KIO::trash( selectedUrls );
00199             KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Trash, selectedUrls, KUrl("trash:/"), job );
00200             break;
00201         }
00202         case EMPTYTRASH:
00203         {
00204             // Same as in ktrash --empty
00205             QByteArray packedArgs;
00206             QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00207             stream << (int)1;
00208             job = KIO::special( KUrl("trash:/"), packedArgs );
00209             KNotification::event("Trash: emptied", QString() , QPixmap() , 0l, KNotification::DefaultEvent );
00210             break;
00211         }
00212         case DEL:
00213             job = KIO::del( selectedUrls );
00214             break;
00215         default:
00216             kWarning() << "Unknown operation: " << method ;
00217             delete this; // this one is ok, _del is always called directly
00218             return;
00219         }
00220         job->ui()->setWindow(parentWidget());
00221         connect( job, SIGNAL( result( KJob * ) ),
00222                  SLOT( slotResult( KJob * ) ) );
00223     } else {
00224         delete this; // this one is ok, _del is always called directly
00225     }
00226 }
00227 
00228 void KonqOperations::_restoreTrashedItems( const KUrl::List& urls )
00229 {
00230     m_method = RESTORE;
00231     KonqMultiRestoreJob* job = new KonqMultiRestoreJob( urls );
00232     job->ui()->setWindow(parentWidget());
00233     KIO::getJobTracker()->registerJob(job);
00234     connect( job, SIGNAL( result( KJob * ) ),
00235              SLOT( slotResult( KJob * ) ) );
00236 }
00237 
00238 bool KonqOperations::askDeleteConfirmation( const KUrl::List & selectedUrls, int method, ConfirmationType confirmation, QWidget* widget )
00239 {
00240     KIO::JobUiDelegate::DeletionType deletionType = method == DEL ? KIO::JobUiDelegate::Delete : KIO::JobUiDelegate::Trash;
00241     KIO::JobUiDelegate::ConfirmationType confirmationType = confirmation == FORCE_CONFIRMATION ? KIO::JobUiDelegate::ForceConfirmation : KIO::JobUiDelegate::DefaultConfirmation;
00242     KIO::JobUiDelegate uiDelegate;
00243     uiDelegate.setWindow(widget);
00244     return uiDelegate.askDeleteConfirmation(selectedUrls, deletionType, confirmationType);
00245 }
00246 
00247 void KonqOperations::doDrop( const KFileItem & destItem, const KUrl & dest, QDropEvent * ev, QWidget * parent )
00248 {
00249     kDebug(1203) << "doDrop: dest:" << dest;
00250     QMap<QString, QString> metaData;
00251     const KUrl::List lst = KUrl::List::fromMimeData(ev->mimeData(), &metaData);
00252     if (!lst.isEmpty()) { // Are they urls ?
00253         //kDebug(1203) << "metaData:" << metaData.count() << "entries.";
00254         //QMap<QString,QString>::ConstIterator mit;
00255         //for( mit = metaData.begin(); mit != metaData.end(); ++mit ) {
00256         //    kDebug(1203) << "metaData: key=" << mit.key() << "value=" << mit.value();
00257         //}
00258         // Check if we dropped something on itself
00259         KUrl::List::ConstIterator it = lst.begin();
00260         for (; it != lst.end() ; it++) {
00261             kDebug(1203) << "URL:" << (*it);
00262             if (dest.equals(*it, KUrl::CompareWithoutTrailingSlash)) {
00263                 // The event source may be the view or an item (icon)
00264                 // Note: ev->source() can be 0L! (in case of kdesktop) (Simon)
00265                 if ( !ev->source() || ( ev->source() != parent && ev->source()->parent() != parent ) )
00266                     KMessageBox::sorry( parent, i18n("You cannot drop a folder on to itself") );
00267                 kDebug(1203) << "Dropped on itself";
00268                 ev->setAccepted( false );
00269                 return; // do nothing instead of displaying kfm's annoying error box
00270             }
00271         }
00272 
00273         // Check the state of the modifiers key at the time of the drop
00274         Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
00275 
00276         Qt::DropAction action = ev->dropAction();
00277         // Check for the drop of a bookmark -> we want a Link action
00278         if ( ev->provides("application/x-xbel") )
00279         {
00280             modifiers |= Qt::ControlModifier | Qt::ShiftModifier;
00281             action = Qt::LinkAction;
00282             kDebug(1203) << "KonqOperations::doDrop Bookmark -> emulating Link";
00283         }
00284 
00285         KonqOperations * op = new KonqOperations(parent);
00286         op->setDropInfo( new DropInfo( modifiers, lst, metaData, QCursor::pos(), action ) );
00287 
00288         // Ok, now we need destItem.
00289         if ( !destItem.isNull() )
00290         {
00291             op->asyncDrop( destItem ); // we have it already
00292         }
00293         else
00294         {
00295             // we need to stat to get it.
00296             op->_statUrl( dest, op, SLOT( asyncDrop( const KFileItem & ) ) );
00297         }
00298         // In both cases asyncDrop will delete op when done
00299 
00300         ev->acceptProposedAction();
00301     }
00302     else
00303     {
00304         //kDebug(1203) << "Pasting to " << dest.url();
00305         KonqOperations * op = new KonqOperations(parent);
00306         KIO::CopyJob* job = KIO::pasteMimeSource( ev->mimeData(), dest,
00307                                                   i18n( "File name for dropped contents:" ),
00308                                                   parent );
00309         if ( job ) // 0 if canceled by user
00310         {
00311             op->setOperation( job, COPY, job->destUrl() );
00312             KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Copy, KUrl::List(), dest, job );
00313         }
00314         ev->acceptProposedAction();
00315     }
00316 }
00317 
00318 void KonqOperations::asyncDrop( const KFileItem & destItem )
00319 {
00320     assert(m_info); // setDropInfo should have been called before asyncDrop
00321     bool m_destIsLocal = false;
00322     m_destUrl = destItem.mostLocalUrl(m_destIsLocal); // #168154
00323 
00324     //kDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destUrl;
00325     // Check what the destination is
00326     if ( destItem.isDir() )
00327     {
00328         doDropFileCopy();
00329         return;
00330     }
00331     if ( !m_destIsLocal )
00332     {
00333         // We dropped onto a remote URL that is not a directory!
00334         // (e.g. an HTTP link in the sidebar).
00335         // Can't do that, but we can't prevent it before stating the dest....
00336         kWarning(1203) << "Cannot drop onto " << m_destUrl ;
00337         deleteLater();
00338         return;
00339     }
00340     if ( destItem.isDesktopFile() )
00341     {
00342         // Local .desktop file. What type ?
00343         KDesktopFile desktopFile( m_destUrl.path() );
00344         KConfigGroup desktopGroup = desktopFile.desktopGroup();
00345         if ( desktopFile.hasApplicationType() )
00346         {
00347             QString error;
00348             const QStringList urlStrList = m_info->urls.toStringList();
00349             if ( KToolInvocation::startServiceByDesktopPath( m_destUrl.path(), urlStrList, &error ) > 0 )
00350                 KMessageBox::error( parentWidget(), error );
00351         }
00352         else
00353         {
00354             // Device or Link -> adjust dest
00355             if ( desktopFile.hasDeviceType() && desktopGroup.hasKey("MountPoint") ) {
00356                 QString point = desktopGroup.readEntry( "MountPoint" );
00357                 m_destUrl.setPath( point );
00358                 QString dev = desktopFile.readDevice();
00359                 KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByDevice( dev );
00360                 // Is the device already mounted ?
00361                 if ( mp ) {
00362                     doDropFileCopy();
00363                 }
00364 #ifndef Q_WS_WIN
00365                 else
00366                 {
00367                     const bool ro = desktopGroup.readEntry( "ReadOnly", false );
00368                     const QByteArray fstype = desktopGroup.readEntry( "FSType" ).toLatin1();
00369                     KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destUrl.path(), false );
00370                     connect( am, SIGNAL( finished() ), this, SLOT( doDropFileCopy() ) );
00371                 }
00372 #endif
00373                 return;
00374             }
00375             else if ( desktopFile.hasLinkType() && desktopGroup.hasKey("URL") ) {
00376                 m_destUrl = desktopGroup.readPathEntry("URL", QString());
00377                 doDropFileCopy();
00378                 return;
00379             }
00380             // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those.
00381         }
00382     }
00383     else
00384     {
00385         // Should be a local executable
00386         // (If this fails, there is a bug in KFileItem::acceptsDrops / KDirModel::flags)
00387         kDebug(1203) << "KonqOperations::doDrop " << m_destUrl.path() << "should be an executable";
00388         Q_ASSERT ( access( QFile::encodeName(m_destUrl.path()), X_OK ) == 0 );
00389         // Launch executable for each of the files
00390         QStringList args;
00391         const KUrl::List lst = m_info->urls;
00392         KUrl::List::ConstIterator it = lst.begin();
00393         for ( ; it != lst.end() ; it++ )
00394             args << (*it).path(); // assume local files
00395         kDebug(1203) << "starting " << m_destUrl.path() << " with " << lst.count() << " arguments";
00396         KProcess::startDetached( m_destUrl.path(), args );
00397     }
00398     deleteLater();
00399 }
00400 
00401 void KonqOperations::doDropFileCopy()
00402 {
00403     assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop
00404     const KUrl::List lst = m_info->urls;
00405     Qt::DropAction action = m_info->action;
00406     bool isDesktopFile = false;
00407     bool itemIsOnDesktop = false;
00408     bool allItemsAreFromTrash = true;
00409     KUrl::List mlst; // list of items that can be moved
00410     for (KUrl::List::ConstIterator it = lst.begin(); it != lst.end(); ++it)
00411     {
00412         bool local = (*it).isLocalFile();
00413         if ( KProtocolManager::supportsDeleting( *it ) && (!local || QFileInfo((*it).directory()).isWritable() ))
00414             mlst.append(*it);
00415         if ( local && KDesktopFile::isDesktopFile((*it).path()))
00416             isDesktopFile = true;
00417         if ( local && (*it).path().startsWith(KGlobalSettings::desktopPath()))
00418             itemIsOnDesktop = true;
00419         if ( local || (*it).protocol() != "trash" )
00420             allItemsAreFromTrash = false;
00421     }
00422 
00423     bool linkOnly = false;
00424     if (isDesktopFile && !KAuthorized::authorizeKAction("run_desktop_files") &&
00425         (m_destUrl.path( KUrl::AddTrailingSlash ) == KGlobalSettings::desktopPath()) )
00426     {
00427        linkOnly = true;
00428     }
00429 
00430     if ( !mlst.isEmpty() && m_destUrl.protocol() == "trash" )
00431     {
00432         if ( itemIsOnDesktop && !KAuthorized::authorizeKAction("editable_desktop_icons") )
00433         {
00434             deleteLater();
00435             return;
00436         }
00437 
00438         m_method = TRASH;
00439         if ( askDeleteConfirmation( mlst, TRASH, DEFAULT_CONFIRMATION, parentWidget() ) )
00440             action = Qt::MoveAction;
00441         else
00442         {
00443             deleteLater();
00444             return;
00445         }
00446     }
00447     else if ( allItemsAreFromTrash || m_destUrl.protocol() == "trash" ) {
00448         // No point in asking copy/move/link when using dnd from or to the trash.
00449         action = Qt::MoveAction;
00450     }
00451     else if ( (
00452         ((m_info->keyboardModifiers & Qt::ControlModifier) == 0) &&
00453         ((m_info->keyboardModifiers & Qt::ShiftModifier) == 0) &&
00454         ((m_info->keyboardModifiers & Qt::AltModifier) == 0) ) || linkOnly )
00455     {
00456         // Neither control, shift or alt are pressed => show popup menu
00457 
00458         // TODO move this code out somehow. Allow user of KonqOperations to add his own actions...
00459 #if 0
00460         KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
00461         bool bSetWallpaper = false;
00462         if ( iconView && iconView->maySetWallpaper() && lst.count() == 1 )
00463     {
00464             KUrl url = lst.first();
00465             KMimeType::Ptr mime = KMimeType::findByUrl( url );
00466             if ( mime && ( ( KImageIO::isSupported(mime->name(), KImageIO::Reading) ) ||
00467                  mime->is( "image/svg+xml" ) ) )
00468             {
00469                 bSetWallpaper = true;
00470             }
00471         }
00472 #endif
00473 
00474         // Check what the source can do
00475         const KUrl url = lst.first(); // we'll assume it's the same for all URLs (hack)
00476         bool sReading = KProtocolManager::supportsReading( url );
00477         bool sDeleting = KProtocolManager::supportsDeleting( url );
00478         bool sMoving = KProtocolManager::supportsMoving( url );
00479         // Check what the destination can do
00480         bool dWriting = KProtocolManager::supportsWriting( m_destUrl );
00481         if ( !dWriting )
00482         {
00483             deleteLater();
00484             return;
00485         }
00486 
00487         // We don't want to offer "move" for temp files. They might come from
00488         // kmail using a tempfile for attachments, or ark using a tempdir for
00489         // extracting an archive -- in all cases, we can't implement a real move,
00490         // it's just a copy of the tempfile [and the source app will delete it later].
00491         // https://www.intevation.de/roundup/kolab/issue2026
00492         if (url.isLocalFile() && url.path().startsWith(KStandardDirs::locateLocal("tmp", QString()))) {
00493             sMoving = false;
00494             sDeleting = false;
00495         }
00496 
00497         QMenu popup;
00498         QString seq = QKeySequence( Qt::ShiftModifier ).toString();
00499         seq.chop(1); // chop superfluous '+'
00500         QAction* popupMoveAction = new QAction(i18n( "&Move Here" ) + '\t' + seq, this);
00501         popupMoveAction->setIcon(KIcon("go-jump"));
00502         seq = QKeySequence( Qt::ControlModifier ).toString();
00503         seq.chop(1);
00504         QAction* popupCopyAction = new QAction(i18n( "&Copy Here" ) + '\t' + seq, this);
00505         popupCopyAction->setIcon(KIcon("edit-copy"));
00506         seq = QKeySequence( Qt::ControlModifier + Qt::ShiftModifier ).toString();
00507         seq.chop(1);
00508         QAction* popupLinkAction = new QAction(i18n( "&Link Here" ) + '\t' + seq, this);
00509         popupLinkAction->setIcon(KIcon("edit-link"));
00510         QAction* popupWallAction = new QAction( i18n( "Set as &Wallpaper" ), this );
00511         popupWallAction->setIcon(KIcon("preferences-desktop-wallpaper"));
00512         QAction* popupCancelAction = new QAction(i18n( "C&ancel" ) + '\t' + QKeySequence( Qt::Key_Escape ).toString(), this);
00513         popupCancelAction->setIcon(KIcon("process-stop"));
00514 
00515         if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly )
00516         {
00517             bool equalDestination = true;
00518             foreach ( const KUrl & src, lst )
00519             {
00520                 const bool equalProtocol = ( m_destUrl.protocol() == src.protocol() );
00521                 if ( !equalProtocol || m_destUrl.path(KUrl::RemoveTrailingSlash) != src.directory() )
00522                 {
00523                     equalDestination = false;
00524                     break;
00525                 }
00526             }
00527             
00528             if ( !equalDestination )
00529                 popup.addAction(popupMoveAction);
00530         }
00531 
00532         if ( sReading && !linkOnly)
00533             popup.addAction(popupCopyAction);
00534 
00535         popup.addAction(popupLinkAction);
00536 
00537 #if 0
00538         if (bSetWallpaper)
00539             popup.addAction(popupWallAction);
00540 #endif
00541 
00542         popup.addSeparator();
00543         popup.addAction(popupCancelAction);
00544 
00545         QAction* result = popup.exec( m_info->mousePos );
00546 
00547         if(result == popupCopyAction)
00548             action = Qt::CopyAction;
00549         else if(result == popupMoveAction)
00550             action = Qt::MoveAction;
00551         else if(result == popupLinkAction)
00552             action = Qt::LinkAction;
00553         else if(result == popupCancelAction || !result)
00554         {
00555             deleteLater();
00556             return;
00557         }
00558     }
00559 
00560     KIO::CopyJob * job = 0;
00561     switch ( action ) {
00562     case Qt::MoveAction :
00563         job = KIO::move( lst, m_destUrl );
00564         job->setMetaData( m_info->metaData );
00565         setOperation( job, m_method == TRASH ? TRASH : MOVE, m_destUrl );
00566         KIO::FileUndoManager::self()->recordJob(
00567             m_method == TRASH ? KIO::FileUndoManager::Trash : KIO::FileUndoManager::Move,
00568             lst, m_destUrl, job );
00569         return; // we still have stuff to do -> don't delete ourselves
00570     case Qt::CopyAction :
00571         job = KIO::copy( lst, m_destUrl );
00572         job->setMetaData( m_info->metaData );
00573         setOperation( job, COPY, m_destUrl );
00574         KIO::FileUndoManager::self()->recordCopyJob(job);
00575         return;
00576     case Qt::LinkAction :
00577         kDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count();
00578         job = KIO::link( lst, m_destUrl );
00579         job->setMetaData( m_info->metaData );
00580         setOperation( job, LINK, m_destUrl );
00581         KIO::FileUndoManager::self()->recordCopyJob(job);
00582         return;
00583     default : kError(1203) << "Unknown action " << (int)action << endl;
00584     }
00585     deleteLater();
00586 }
00587 
00588 void KonqOperations::rename( QWidget * parent, const KUrl & oldurl, const KUrl& newurl )
00589 {
00590     kDebug(1203) << "KonqOperations::rename oldurl=" << oldurl << " newurl=" << newurl;
00591     if ( oldurl == newurl )
00592         return;
00593 
00594     KUrl::List lst;
00595     lst.append(oldurl);
00596     KIO::Job * job = KIO::moveAs( oldurl, newurl, oldurl.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags );
00597     KonqOperations * op = new KonqOperations( parent );
00598     op->setOperation( job, MOVE, newurl );
00599     KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::Rename, lst, newurl, job );
00600     // if moving the desktop then update config file and emit
00601     if ( oldurl.isLocalFile() && oldurl.path( KUrl::AddTrailingSlash ) == KGlobalSettings::desktopPath() )
00602     {
00603         kDebug(1203) << "That rename was the Desktop path, updating config files";
00604         KSharedConfig::Ptr globalConfig = KGlobal::config();
00605         KConfigGroup cgs( globalConfig, "Paths" );
00606         cgs.writePathEntry("Desktop" , newurl.path(), KConfigBase::Persistent|KConfigBase::Global );
00607         cgs.sync();
00608         KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_PATHS);
00609     }
00610 }
00611 
00612 void KonqOperations::setOperation( KIO::Job * job, Operation method, const KUrl & dest )
00613 {
00614     m_method = method;
00615     m_destUrl = dest;
00616     if ( job )
00617     {
00618         job->ui()->setWindow(parentWidget());
00619         connect( job, SIGNAL( result( KJob * ) ),
00620                  SLOT( slotResult( KJob * ) ) );
00621 #if 0
00622         KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job);
00623         KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
00624         if (copyJob && iconView)
00625         {
00626             connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QList<KIO::CopyInfo> &)),
00627                  this, SLOT(slotAboutToCreate(KIO::Job *,const QList<KIO::CopyInfo> &)));
00628             // TODO move this connect into the iconview!
00629             connect(this, SIGNAL(aboutToCreate(const QPoint &, const QList<KIO::CopyInfo> &)),
00630                  iconView, SLOT(slotAboutToCreate(const QPoint &, const QList<KIO::CopyInfo> &)));
00631         }
00632 #endif
00633     }
00634     else // for link
00635         slotResult( 0L );
00636 }
00637 
00638 void KonqOperations::slotAboutToCreate(KIO::Job *, const QList<KIO::CopyInfo> &files)
00639 {
00640     emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files);
00641 }
00642 
00643 void KonqOperations::statUrl( const KUrl & url, const QObject *receiver, const char *member, QWidget* parent )
00644 {
00645     KonqOperations * op = new KonqOperations( parent );
00646     op->m_method = STAT;
00647     op->_statUrl( url, receiver, member );
00648 }
00649 
00650 void KonqOperations::_statUrl( const KUrl & url, const QObject *receiver, const char *member )
00651 {
00652     connect( this, SIGNAL( statFinished( const KFileItem & ) ), receiver, member );
00653     KIO::StatJob * job = KIO::stat( url /*, KIO::HideProgressInfo?*/ );
00654     job->ui()->setWindow(parentWidget());
00655     connect( job, SIGNAL( result( KJob * ) ),
00656              SLOT( slotStatResult( KJob * ) ) );
00657 }
00658 
00659 void KonqOperations::slotStatResult( KJob * job )
00660 {
00661     if ( job->error())
00662     {
00663         static_cast<KIO::Job*>( job )->ui()->showErrorMessage();
00664     }
00665     else
00666     {
00667         KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
00668         KFileItem item( statJob->statResult(), statJob->url() );
00669         emit statFinished( item );
00670     }
00671     // If we're only here for a stat, we're done. But not if we used _statUrl internally
00672     if ( m_method == STAT )
00673         deleteLater();
00674 }
00675 
00676 void KonqOperations::slotResult( KJob * job )
00677 {
00678     if (job && job->error())
00679     {
00680         static_cast<KIO::Job*>( job )->ui()->showErrorMessage();
00681     }
00682     if ( m_method == EMPTYTRASH ) {
00683         // Update konq windows opened on trash:/
00684         org::kde::KDirNotify::emitFilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones...
00685     }
00686     deleteLater();
00687 }
00688 
00689 void KonqOperations::rename( QWidget * parent, const KUrl & oldurl, const QString & name )
00690 {
00691     KUrl newurl( oldurl );
00692     newurl.setPath( oldurl.directory( KUrl::AppendTrailingSlash ) + name );
00693     kDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl;
00694     rename( parent, oldurl, newurl );
00695 }
00696 
00697 KIO::SimpleJob* KonqOperations::newDir( QWidget * parent, const KUrl & baseUrl )
00698 {
00699     bool ok;
00700     QString name = i18n( "New Folder" );
00701     if ( baseUrl.isLocalFile() && QFileInfo( baseUrl.path( KUrl::AddTrailingSlash ) + name ).exists() )
00702         name = KIO::RenameDialog::suggestName( baseUrl, i18n( "New Folder" ) );
00703 
00704     name = KInputDialog::getText ( i18n( "New Folder" ),
00705         i18n( "Enter folder name:" ), name, &ok, parent );
00706     if ( ok && !name.isEmpty() )
00707     {
00708         KUrl url;
00709         if ((name[0] == '/') || (name[0] == '~'))
00710         {
00711            url.setPath(KShell::tildeExpand(name));
00712         }
00713         else
00714         {
00715            name = KIO::encodeFileName( name );
00716            url = baseUrl;
00717            url.addPath( name );
00718         }
00719         return KonqOperations::mkdir( parent, url );
00720     }
00721     return 0;
00722 }
00723 
00725 
00726 KonqMultiRestoreJob::KonqMultiRestoreJob( const KUrl::List& urls )
00727     : KIO::Job(),
00728       m_urls( urls ), m_urlsIterator( m_urls.begin() ),
00729       m_progress( 0 )
00730 {
00731     QTimer::singleShot(0, this, SLOT(slotStart()));
00732     setUiDelegate(new KIO::JobUiDelegate);
00733 }
00734 
00735 void KonqMultiRestoreJob::slotStart()
00736 {
00737     if ( m_urlsIterator == m_urls.begin() ) // first time: emit total
00738         setTotalAmount( KJob::Files, m_urls.count() );
00739 
00740     if ( m_urlsIterator != m_urls.end() )
00741     {
00742         const KUrl& url = *m_urlsIterator;
00743 
00744         KUrl new_url = url;
00745         if ( new_url.protocol()=="system"
00746           && new_url.path().startsWith("/trash") )
00747         {
00748             QString path = new_url.path();
00749         path.remove(0, 6);
00750         new_url.setProtocol("trash");
00751         new_url.setPath(path);
00752         }
00753 
00754         Q_ASSERT( new_url.protocol() == "trash" );
00755         QByteArray packedArgs;
00756         QDataStream stream( &packedArgs, QIODevice::WriteOnly );
00757         stream << (int)3 << new_url;
00758         KIO::Job* job = KIO::special( new_url, packedArgs, KIO::HideProgressInfo );
00759         addSubjob( job );
00760         setProcessedAmount(KJob::Files, processedAmount(KJob::Files) + 1);
00761     }
00762     else // done!
00763     {
00764         org::kde::KDirNotify::emitFilesRemoved(m_urls.toStringList() );
00765         emitResult();
00766     }
00767 }
00768 
00769 void KonqMultiRestoreJob::slotResult( KJob *job )
00770 {
00771     if ( job->error() )
00772     {
00773         KIO::Job::slotResult( job ); // will set the error and emit result(this)
00774         return;
00775     }
00776     removeSubjob(job);
00777     // Move on to next one
00778     ++m_urlsIterator;
00779     ++m_progress;
00780     //emit processedSize( this, m_progress );
00781     emitPercent( m_progress, m_urls.count() );
00782     slotStart();
00783 }
00784 
00785 QWidget* KonqOperations::parentWidget() const
00786 {
00787     return static_cast<QWidget *>( parent() );
00788 }
00789 
00790 #include "konq_operations.moc"

libkonq

Skip menu "libkonq"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal