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., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 
00019 #include <qclipboard.h>
00020 #include <konq_operations.h>
00021 #include <klocale.h>
00022 #include <kmessagebox.h>
00023 #include <kautomount.h>
00024 #include <krun.h>
00025 
00026 #include <kdirnotify_stub.h>
00027 
00028 #include <dcopclient.h>
00029 #include "konq_undo.h"
00030 #include "konq_defaults.h"
00031 #include "konqbookmarkmanager.h"
00032 
00033 // For doDrop
00034 #include <qdir.h>//first
00035 #include <assert.h>
00036 #include <kapplication.h>
00037 #include <kipc.h>
00038 #include <kdebug.h>
00039 #include <kfileitem.h>
00040 #include <kdesktopfile.h>
00041 #include <kurldrag.h>
00042 #include <kglobalsettings.h>
00043 #include <kimageio.h>
00044 #include <kio/job.h>
00045 #include <kio/paste.h>
00046 #include <konq_drag.h>
00047 #include <konq_iconviewwidget.h>
00048 #include <kprotocolinfo.h>
00049 #include <kprocess.h>
00050 #include <kstringhandler.h>
00051 #include <qpopupmenu.h>
00052 #include <unistd.h>
00053 #include <X11/Xlib.h>
00054 
00055 KBookmarkManager * KonqBookmarkManager::s_bookmarkManager;
00056 
00057 KonqOperations::KonqOperations( QWidget *parent )
00058     : QObject( parent, "KonqOperations" ), m_info(0L), m_pasteInfo(0L)
00059 {
00060 }
00061 
00062 KonqOperations::~KonqOperations()
00063 {
00064     delete m_info;
00065     delete m_pasteInfo;
00066 }
00067 
00068 void KonqOperations::editMimeType( const QString & mimeType )
00069 {
00070   QString keditfiletype = QString::fromLatin1("keditfiletype");
00071   KRun::runCommand( keditfiletype + " " + mimeType,
00072                     keditfiletype, keditfiletype /*unused*/);
00073 }
00074 
00075 void KonqOperations::del( QWidget * parent, int method, const KURL::List & selectedURLs )
00076 {
00077   kdDebug(1203) << "KonqOperations::del " << parent->className() << endl;
00078   if ( selectedURLs.isEmpty() )
00079   {
00080     kdWarning(1203) << "Empty URL list !" << endl;
00081     return;
00082   }
00083   // We have to check the trash itself isn't part of the selected
00084   // URLs.
00085   bool bTrashIncluded = false;
00086   KURL::List::ConstIterator it = selectedURLs.begin();
00087   for ( ; it != selectedURLs.end() && !bTrashIncluded; ++it )
00088       if ( (*it).isLocalFile() && (*it).path(1) == KGlobalSettings::trashPath() )
00089           bTrashIncluded = true;
00090   int confirmation = DEFAULT_CONFIRMATION;
00091   if ( bTrashIncluded )
00092   {
00093       switch ( method ) {
00094           case TRASH:
00095               KMessageBox::sorry(0, i18n("You can't trash the trash bin."));
00096               return;
00097           case DEL:
00098           case SHRED:
00099               confirmation = FORCE_CONFIRMATION;
00100               break;
00101       }
00102   }
00103   KonqOperations * op = new KonqOperations( parent );
00104   op->_del( method, selectedURLs, confirmation );
00105 }
00106 
00107 void KonqOperations::emptyTrash()
00108 {
00109   KonqOperations *op = new KonqOperations( 0L );
00110 
00111   QDir trashDir( KGlobalSettings::trashPath() );
00112   QStringList files = trashDir.entryList( QDir::All | QDir::Hidden | QDir::System );
00113   files.remove(QString("."));
00114   files.remove(QString(".."));
00115   files.remove(QString(".directory"));
00116 
00117   QStringList::Iterator it(files.begin());
00118   for (; it != files.end(); ++it )
00119     (*it).prepend( KGlobalSettings::trashPath() );
00120 
00121   KURL::List urls;
00122   it = files.begin();
00123   for (; it != files.end(); ++it )
00124   {
00125     KURL u;
00126     u.setPath( *it );
00127     urls.append( u );
00128   }
00129 
00130   if ( urls.count() > 0 )
00131     op->_del( EMPTYTRASH, urls, SKIP_CONFIRMATION );
00132 
00133 }
00134 
00135 void KonqOperations::mkdir( QWidget *parent, const KURL & url )
00136 {
00137     KIO::Job * job = KIO::mkdir( url );
00138     KonqOperations * op = new KonqOperations( parent );
00139     op->setOperation( job, MKDIR, KURL::List(), url );
00140     (void) new KonqCommandRecorder( KonqCommand::MKDIR, KURL(), url, job ); // no support yet, apparently
00141 }
00142 
00143 void KonqOperations::doPaste( QWidget * parent, const KURL & destURL )
00144 {
00145     // move or not move ?
00146     bool move = false;
00147     QMimeSource *data = QApplication::clipboard()->data();
00148     if ( data->provides( "application/x-kde-cutselection" ) ) {
00149       move = KonqDrag::decodeIsCutSelection( data );
00150       kdDebug(1203) << "move (from clipboard data) = " << move << endl;
00151     }
00152 
00153     KIO::Job *job = KIO::pasteClipboard( destURL, move );
00154     if ( job )
00155     {
00156         KonqOperations * op = new KonqOperations( parent );
00157         KIO::CopyJob * copyJob = static_cast<KIO::CopyJob *>(job);
00158         op->setOperation( job, move ? MOVE : COPY, copyJob->srcURLs(), copyJob->destURL() );
00159         (void) new KonqCommandRecorder( move ? KonqCommand::MOVE : KonqCommand::COPY, KURL::List(), destURL, job );
00160     }
00161 }
00162 
00163 void KonqOperations::copy( QWidget * parent, int method, const KURL::List & selectedURLs, const KURL& destUrl )
00164 {
00165   kdDebug(1203) << "KonqOperations::copy() " << parent->className() << endl;
00166   if ((method!=COPY) && (method!=MOVE) && (method!=LINK))
00167   {
00168     kdWarning(1203) << "Illegal copy method !" << endl;
00169     return;
00170   }
00171   if ( selectedURLs.isEmpty() )
00172   {
00173     kdWarning(1203) << "Empty URL list !" << endl;
00174     return;
00175   }
00176 
00177   KonqOperations * op = new KonqOperations( parent );
00178   KIO::Job* job(0);
00179   if (method==LINK)
00180      job= KIO::link( selectedURLs, destUrl);
00181   else if (method==MOVE)
00182      job= KIO::move( selectedURLs, destUrl);
00183   else
00184      job= KIO::copy( selectedURLs, destUrl);
00185 
00186   op->setOperation( job, method, selectedURLs, destUrl );
00187 
00188   if (method==COPY)
00189      (void) new KonqCommandRecorder( KonqCommand::COPY, selectedURLs, destUrl, job );
00190   else
00191      (void) new KonqCommandRecorder( method==MOVE?KonqCommand::MOVE:KonqCommand::LINK, selectedURLs, destUrl, job );
00192 }
00193 
00194 void KonqOperations::_del( int method, const KURL::List & _selectedURLs, int confirmation )
00195 {
00196     KURL::List selectedURLs;
00197     for (KURL::List::ConstIterator it = _selectedURLs.begin(); it != _selectedURLs.end(); ++it)
00198         if (KProtocolInfo::supportsDeleting(*it))
00199             selectedURLs.append(*it);
00200     if (selectedURLs.isEmpty()) {
00201         delete this;
00202         return;
00203     }
00204 
00205   m_method = method;
00206   if ( confirmation == SKIP_CONFIRMATION || askDeleteConfirmation( selectedURLs, confirmation ) )
00207   {
00208     //m_srcURLs = selectedURLs;
00209     KIO::Job *job;
00210     switch( method )
00211     {
00212       case TRASH:
00213       {
00214         // Make sure the trash exists. Usually the case, but not when starting
00215         // konq standalone.
00216         QString trashPath = KGlobalSettings::trashPath();
00217         if ( !QFile::exists( trashPath ) )
00218             KStandardDirs::makeDir( QFile::encodeName( trashPath ) );
00219         KURL u;
00220         u.setPath( trashPath );
00221         job = KIO::move( selectedURLs, u );
00222         (void) new KonqCommandRecorder( KonqCommand::MOVE, selectedURLs, u, job );
00223          break;
00224       }
00225       case EMPTYTRASH:
00226       case DEL:
00227         job = KIO::del( selectedURLs );
00228         break;
00229       case SHRED:
00230         job = KIO::del( selectedURLs, true );
00231         break;
00232       default:
00233         Q_ASSERT(0);
00234         delete this;
00235         return;
00236     }
00237     connect( job, SIGNAL( result( KIO::Job * ) ),
00238              SLOT( slotResult( KIO::Job * ) ) );
00239   } else
00240     delete this;
00241 }
00242 
00243 bool KonqOperations::askDeleteConfirmation( const KURL::List & selectedURLs, int confirmation )
00244 {
00245     QString keyName;
00246     bool ask = ( confirmation == FORCE_CONFIRMATION );
00247     if ( !ask )
00248     {
00249         KConfig config("konquerorrc", true, false);
00250         config.setGroup( "Trash" );
00251         keyName = ( m_method == DEL ? "ConfirmDelete" : m_method == SHRED ? "ConfirmShred" : "ConfirmTrash" );
00252         bool defaultValue = ( m_method == DEL ? DEFAULT_CONFIRMDELETE : m_method == SHRED ? DEFAULT_CONFIRMSHRED : DEFAULT_CONFIRMTRASH );
00253         ask = config.readBoolEntry( keyName, defaultValue );
00254     }
00255     if ( ask )
00256     {
00257       KURL::List::ConstIterator it = selectedURLs.begin();
00258       QStringList prettyList;
00259       for ( ; it != selectedURLs.end(); ++it )
00260         prettyList.append( (*it).prettyURL() );
00261 
00262       int result;
00263       if ( prettyList.count() == 1 )
00264       {
00265         QString filename = KStringHandler::csqueeze(KIO::decodeFileName(selectedURLs.first().fileName()));
00266         QString directory = KStringHandler::csqueeze(selectedURLs.first().directory());
00267         switch(m_method)
00268         {
00269           case DEL:
00270 
00271              // We're going to be part of the format string after the first arg(), so we need to escape %n's
00272              // However, arg() doesn't actually support using %% as a literal % or anything useful like that
00273              // This should take care of the problem
00274              filename.replace(QRegExp("%"), "%<i></i>");
00275 
00276              result = KMessageBox::warningContinueCancel( 0,
00277                 i18n( "<p>Do you really want to delete <b>%1</b> from <b>%2</b>?</p>" ).arg( filename ).arg( directory ),
00278                 i18n( "Delete File" ),
00279                 i18n( "Delete" ),
00280                 keyName, false);
00281              break;
00282 
00283           case SHRED:
00284              result = KMessageBox::warningContinueCancel( 0,
00285                 i18n( "<p>Do you really want to shred <b>%1</b>?</p>" ).arg( filename ),
00286                 i18n( "Shred File" ),
00287                 i18n( "Shred" ),
00288                 keyName, false);
00289              break;
00290 
00291           case MOVE:
00292           default:
00293              result = KMessageBox::warningContinueCancel( 0,
00294                 i18n( "<p>Do you really want to move <b>%1</b> to the trash?</p>" ).arg( filename ),
00295                 i18n( "Move to Trash" ),
00296                 i18n( "Verb", "Trash" ),
00297                 keyName, false);
00298              break;
00299         }
00300       }
00301       else
00302       {
00303         switch(m_method)
00304         {
00305           case DEL:
00306              result = KMessageBox::warningContinueCancelList( 0,
00307                 // The "singular" form will never be shown in English, but
00308                 // Stephan wants me to use the standard form for a plural.
00309                 i18n( "Do you really want to delete this item?", "Do you really want to delete these %n items?", prettyList.count()),
00310                 prettyList,
00311                 i18n( "Delete Files" ),
00312                 i18n( "Delete" ),
00313                 keyName);
00314              break;
00315 
00316           case SHRED:
00317              result = KMessageBox::warningContinueCancelList( 0,
00318                 i18n( "Do you really want to shred this item?", "Do you really want to shred these %n items?", prettyList.count()),
00319                 prettyList,
00320                 i18n( "Shred Files" ),
00321                 i18n( "Shred" ),
00322                 keyName);
00323              break;
00324 
00325           case MOVE:
00326           default:
00327              result = KMessageBox::warningContinueCancelList( 0,
00328                 i18n( "Do you really want to move this item to the trashcan?", "Do you really want to move these %n items to the trashcan?", prettyList.count()),
00329                 prettyList,
00330                 i18n( "Move to Trash" ),
00331                 i18n( "Verb", "Trash" ),
00332                 keyName);
00333              break;
00334         }
00335       }
00336       if (!keyName.isEmpty())
00337       {
00338          // Check kmessagebox setting... erase & copy to konquerorrc.
00339          KConfig *config = kapp->config();
00340          KConfigGroupSaver saver(config, "Notification Messages");
00341          if (!config->readBoolEntry(keyName, true))
00342          {
00343             config->writeEntry(keyName, true);
00344             config->sync();
00345             KConfig konq_config("konquerorrc", false);
00346             konq_config.setGroup( "Trash" );
00347             konq_config.writeEntry( keyName, false );
00348          }
00349       }
00350       return (result == KMessageBox::Continue);
00351     }
00352     return true;
00353 }
00354 
00355 //static
00356 void KonqOperations::doDrop( const KFileItem * destItem, const KURL & dest, QDropEvent * ev, QWidget * parent )
00357 {
00358     kdDebug(1203) << "doDrop: dest : " << dest.url() << kdBacktrace( 5 ) << endl;
00359     KURL::List lst;
00360     QMap<QString, QString> metaData;
00361     if ( KURLDrag::decode( ev, lst, metaData ) ) // Are they urls ?
00362     {
00363         if( lst.count() == 0 )
00364         {
00365             kdWarning(1203) << "Oooops, no data ...." << endl;
00366             ev->accept(false);
00367             return;
00368         }
00369         kdDebug() << "KonqOperations::doDrop metaData: " << metaData.count() << " entries." << endl;
00370         QMap<QString,QString>::ConstIterator mit;
00371         for( mit = metaData.begin(); mit != metaData.end(); ++mit )
00372         {
00373             kdDebug() << "metaData: key=" << mit.key() << " value=" << mit.data() << endl;
00374         }
00375         // Check if we dropped something on itself
00376         KURL::List::Iterator it = lst.begin();
00377         for ( ; it != lst.end() ; it++ )
00378         {
00379             kdDebug(1203) << "URL : " << (*it).url() << endl;
00380             if ( dest.cmp( *it, true /*ignore trailing slashes*/ ) )
00381             {
00382                 // The event source may be the view or an item (icon)
00383                 // Note: ev->source() can be 0L! (in case of kdesktop) (Simon)
00384                 if ( !ev->source() || ev->source() != parent && ev->source()->parent() != parent )
00385                     KMessageBox::sorry( parent, i18n("You can't drop a directory onto itself") );
00386                 kdDebug(1203) << "Dropped on itself" << endl;
00387                 ev->accept(false);
00388                 return; // do nothing instead of displaying kfm's annoying error box
00389             }
00390         }
00391 
00392         // Check the state of the modifiers key at the time of the drop
00393         Window root;
00394         Window child;
00395         int root_x, root_y, win_x, win_y;
00396         uint keybstate;
00397         XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
00398                        &root_x, &root_y, &win_x, &win_y, &keybstate );
00399 
00400         QDropEvent::Action action = ev->action();
00401         // Check for the drop of a bookmark -> we want a Link action
00402         if ( ev->provides("application/x-xbel") )
00403         {
00404             keybstate |= ControlMask | ShiftMask;
00405             action = QDropEvent::Link;
00406             kdDebug(1203) << "KonqOperations::doDrop Bookmark -> emulating Link" << endl;
00407         }
00408 
00409         KonqOperations * op = new KonqOperations(parent);
00410         op->setDropInfo( new DropInfo( keybstate, lst, metaData, win_x, win_y, action ) );
00411 
00412         // Ok, now we need destItem.
00413         if ( destItem )
00414         {
00415             op->asyncDrop( destItem ); // we have it already
00416         }
00417         else
00418         {
00419             // we need to stat to get it.
00420             op->_statURL( dest, op, SLOT( asyncDrop( const KFileItem * ) ) );
00421         }
00422         // In both cases asyncDrop will delete op when done
00423 
00424         ev->acceptAction();
00425     }
00426     else
00427     {
00428         QStrList formats;
00429 
00430         for ( int i = 0; ev->format( i ); i++ )
00431             if ( *( ev->format( i ) ) )
00432                 formats.append( ev->format( i ) );
00433         if ( formats.count() >= 1 )
00434         {
00435             //kdDebug(1203) << "Pasting to " << dest.url() << endl;
00436 
00437             QByteArray data;
00438 
00439             QString text;
00440             if ( QTextDrag::canDecode( ev ) && QTextDrag::decode( ev, text ) )
00441             {
00442                 QTextStream txtStream( data, IO_WriteOnly );
00443                 txtStream << text;
00444             }
00445             else
00446                 data = ev->data( formats.first() );
00447 
00448             // Delay the call to KIO::pasteData so that the event filters can return. See #38688.
00449             KonqOperations * op = new KonqOperations(parent);
00450             KIOPasteInfo * pi = new KIOPasteInfo;
00451             pi->data = data;
00452             pi->destURL = dest;
00453             op->setPasteInfo( pi );
00454             QTimer::singleShot( 0, op, SLOT( slotKIOPaste() ) );
00455         }
00456         ev->acceptAction();
00457     }
00458 }
00459 
00460 void KonqOperations::slotKIOPaste()
00461 {
00462     assert(m_pasteInfo); // setPasteInfo should have been called before
00463     KIO::pasteData( m_pasteInfo->destURL, m_pasteInfo->data );
00464     delete this;
00465 }
00466 
00467 void KonqOperations::asyncDrop( const KFileItem * destItem )
00468 {
00469     assert(m_info); // setDropInfo should have been called before asyncDrop
00470     m_destURL = destItem->url();
00471 
00472     //kdDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destURL << endl;
00473     // Check what the destination is
00474     if ( destItem->isDir() )
00475     {
00476         doFileCopy();
00477         return;
00478     }
00479     if ( !m_destURL.isLocalFile() )
00480     {
00481         // We dropped onto a remote URL that is not a directory!
00482         // (e.g. an HTTP link in the sidebar).
00483         // Can't do that, but we can't prevent it before stating the dest....
00484         kdWarning(1203) << "Cannot drop onto " << m_destURL.prettyURL() << endl;
00485         delete this;
00486         return;
00487     }
00488     if ( destItem->mimetype() == "application/x-desktop")
00489     {
00490         // Local .desktop file. What type ?
00491         KDesktopFile desktopFile( m_destURL.path() );
00492         if ( desktopFile.hasApplicationType() )
00493         {
00494             QString error;
00495             QStringList stringList;
00496             KURL::List lst = m_info->lst;
00497             KURL::List::Iterator it = lst.begin();
00498             for ( ; it != lst.end() ; it++ )
00499             {
00500                 stringList.append((*it).url());
00501             }
00502             if ( KApplication::startServiceByDesktopPath( m_destURL.path(), stringList, &error ) > 0 )
00503                 KMessageBox::error( 0L, error );
00504         }
00505         else
00506         {
00507             // Device or Link -> adjust dest
00508             if ( desktopFile.hasDeviceType() && desktopFile.hasKey("MountPoint") ) {
00509                 QString point = desktopFile.readEntry( "MountPoint" );
00510                 m_destURL.setPath( point );
00511                 QString dev = desktopFile.readDevice();
00512                 QString mp = KIO::findDeviceMountPoint( dev );
00513                 // Is the device already mounted ?
00514                 if ( !mp.isNull() )
00515                     doFileCopy();
00516                 else
00517                 {
00518                     bool ro = desktopFile.readBoolEntry( "ReadOnly", false );
00519                     QString fstype = desktopFile.readEntry( "FSType" );
00520                     KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destURL.path(), false );
00521                     connect( am, SIGNAL( finished() ), this, SLOT( doFileCopy() ) );
00522                 }
00523                 return;
00524             }
00525             else if ( desktopFile.hasLinkType() && desktopFile.hasKey("URL") ) {
00526                 m_destURL = desktopFile.readPathEntry("URL");
00527                 doFileCopy();
00528                 return;
00529             }
00530             // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those.
00531         }
00532     }
00533     else
00534     {
00535         // Should be a local executable
00536         // (If this fails, there is a bug in KFileItem::acceptsDrops)
00537         kdDebug(1203) << "KonqOperations::doDrop " << m_destURL.path() << "should be an executable" << endl;
00538         Q_ASSERT ( access( QFile::encodeName(m_destURL.path()), X_OK ) == 0 );
00539         KProcess proc;
00540         proc << m_destURL.path() ;
00541         // Launch executable for each of the files
00542         KURL::List lst = m_info->lst;
00543         KURL::List::Iterator it = lst.begin();
00544         for ( ; it != lst.end() ; it++ )
00545             proc << (*it).path(); // assume local files
00546         kdDebug(1203) << "starting " << m_destURL.path() << " with " << lst.count() << " arguments" << endl;
00547         proc.start( KProcess::DontCare );
00548     }
00549     delete this;
00550 }
00551 
00552 void KonqOperations::doFileCopy()
00553 {
00554     assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop
00555     KURL::List lst = m_info->lst;
00556     QDropEvent::Action action = m_info->action;
00557 
00558     KURL::List mlst;
00559     for (KURL::List::ConstIterator it = lst.begin(); it != lst.end(); ++it)
00560         if ( KProtocolInfo::supportsDeleting( *it ) )
00561              mlst.append(*it);
00562 
00563     if ( !mlst.isEmpty() && m_destURL.path( 1 ) == KGlobalSettings::trashPath() )
00564     {
00565         if ( askDeleteConfirmation( mlst, DEFAULT_CONFIRMATION ) )
00566             action = QDropEvent::Move;
00567         else
00568         {
00569             delete this;
00570             return;
00571         }
00572     }
00573     else if ( ((m_info->keybstate & ControlMask) == 0) && ((m_info->keybstate & ShiftMask) == 0) )
00574     {
00575         KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
00576         bool bSetWallpaper = false;
00577         if (iconView && iconView->maySetWallpaper() &&
00578             (lst.count() == 1) &&
00579             ((!KImageIO::type(lst.first().path()).isEmpty()) ||
00580              (KImageIO::isSupported(KMimeType::findByURL(lst.first())->name(),
00581                                     KImageIO::Reading))))
00582         {
00583             bSetWallpaper = true;
00584         }
00585 
00586         // Check what the source can do
00587         KURL url = lst.first(); // we'll assume it's the same for all URLs (hack)
00588         bool sReading = KProtocolInfo::supportsReading( url );
00589         bool sDeleting = KProtocolInfo::supportsDeleting( url );
00590         bool sMoving = KProtocolInfo::supportsMoving( url );
00591         // Check what the destination can do
00592         bool dWriting = KProtocolInfo::supportsWriting( m_destURL );
00593         if ( !dWriting )
00594         {
00595             delete this;
00596             return;
00597         }
00598 
00599         // Nor control nor shift are pressed => show popup menu
00600         QPopupMenu popup;
00601         if ( sReading )
00602             popup.insertItem(SmallIconSet("editcopy"), i18n( "&Copy Here" ), 1 );
00603         if ( (sMoving || (sReading && sDeleting)) )
00604             popup.insertItem( i18n( "&Move Here" ), 2 );
00605         popup.insertItem(SmallIconSet("www"), i18n( "&Link Here" ), 3 );
00606         if (bSetWallpaper)
00607             popup.insertItem(SmallIconSet("background"), i18n( "Set as &Wallpaper" ), 4 );
00608         popup.insertSeparator();
00609         popup.insertItem(SmallIconSet("cancel"), i18n( "C&ancel" ), 5);
00610 
00611         int result = popup.exec( m_info->mousePos );
00612         switch (result) {
00613         case 1 : action = QDropEvent::Copy; break;
00614         case 2 : action = QDropEvent::Move; break;
00615         case 3 : action = QDropEvent::Link; break;
00616         case 4 :
00617         {
00618             kdDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url() << endl;
00619             if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first());
00620             delete this;
00621             return;
00622         }
00623         case 5 :
00624         default : delete this; return;
00625         }
00626     }
00627 
00628     KIO::Job * job = 0;
00629     switch ( action ) {
00630     case QDropEvent::Move :
00631         if (mlst.isEmpty())
00632             return;
00633         job = KIO::move( mlst, m_destURL );
00634         job->setMetaData( m_info->metaData );
00635         setOperation( job, MOVE, lst, m_destURL );
00636         (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, m_destURL, job );
00637         return; // we still have stuff to do -> don't delete ourselves
00638     case QDropEvent::Copy :
00639         job = KIO::copy( lst, m_destURL );
00640         job->setMetaData( m_info->metaData );
00641         setOperation( job, COPY, lst, m_destURL );
00642         (void) new KonqCommandRecorder( KonqCommand::COPY, lst, m_destURL, job );
00643         return;
00644     case QDropEvent::Link :
00645         kdDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count() << endl;
00646         job = KIO::link( lst, m_destURL );
00647         job->setMetaData( m_info->metaData );
00648         setOperation( job, LINK, lst, m_destURL );
00649         (void) new KonqCommandRecorder( KonqCommand::LINK, lst, m_destURL, job );
00650         return;
00651     default : kdError(1203) << "Unknown action " << (int)action << endl;
00652     }
00653     delete this;
00654 }
00655 
00656 void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const QString & name )
00657 {
00658     QString newPath = oldurl.directory(false,true) + name;
00659     kdDebug(1203) << "KonqOperations::rename " << oldurl.prettyURL() << " newPath=" << newPath << endl;
00660     KURL newurl(oldurl);
00661     newurl.setPath(newPath);
00662     if ( oldurl != newurl )
00663     {
00664         KURL::List lst;
00665         lst.append(oldurl);
00666         KIO::Job * job = KIO::moveAs( oldurl, newurl, !oldurl.isLocalFile() );
00667         KonqOperations * op = new KonqOperations( parent );
00668         op->setOperation( job, MOVE, lst, newurl );
00669         (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, newurl, job );
00670         // if old trash then update config file and emit
00671         if(oldurl.isLocalFile() && oldurl.path(1) == KGlobalSettings::trashPath() ) {
00672             kdDebug(1203) << "That rename was the Trashcan, updating config files" << endl;
00673             KConfig *globalConfig = KGlobal::config();
00674             KConfigGroupSaver cgs( globalConfig, "Paths" );
00675             globalConfig->writeEntry("Trash" , newurl.path(), true, true );
00676             globalConfig->sync();
00677             KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS);
00678         }
00679     }
00680 }
00681 
00682 void KonqOperations::setOperation( KIO::Job * job, int method, const KURL::List & /*src*/, const KURL & dest )
00683 {
00684   m_method = method;
00685   //m_srcURLs = src;
00686   m_destURL = dest;
00687   if ( job )
00688     connect( job, SIGNAL( result( KIO::Job * ) ),
00689              SLOT( slotResult( KIO::Job * ) ) );
00690   else // for link
00691     slotResult( 0L );
00692 }
00693 
00694 void KonqOperations::statURL( const KURL & url, const QObject *receiver, const char *member )
00695 {
00696     KonqOperations * op = new KonqOperations( 0L );
00697     op->_statURL( url, receiver, member );
00698     op->m_method = STAT;
00699 }
00700 
00701 void KonqOperations::_statURL( const KURL & url, const QObject *receiver, const char *member )
00702 {
00703     connect( this, SIGNAL( statFinished( const KFileItem * ) ), receiver, member );
00704     KIO::StatJob * job = KIO::stat( url /*, false?*/ );
00705     connect( job, SIGNAL( result( KIO::Job * ) ),
00706              SLOT( slotStatResult( KIO::Job * ) ) );
00707 }
00708 
00709 void KonqOperations::slotStatResult( KIO::Job * job )
00710 {
00711     if ( job->error())
00712         job->showErrorDialog( (QWidget*)parent() );
00713     else
00714     {
00715         KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
00716         KFileItem * item = new KFileItem( statJob->statResult(), statJob->url() );
00717         emit statFinished( item );
00718         delete item;
00719     }
00720     // If we're only here for a stat, we're done. But not if we used _statURL internally
00721     if ( m_method == STAT )
00722         delete this;
00723 }
00724 
00725 void KonqOperations::slotResult( KIO::Job * job )
00726 {
00727     if (job && job->error())
00728         job->showErrorDialog( (QWidget*)parent() );
00729 
00730     // Update trash bin icon if trashing files or emptying trash
00731     bool bUpdateTrash = m_method == TRASH || m_method == EMPTYTRASH;
00732     // ... or if creating a new file in the trash
00733     if ( m_method == MOVE || m_method == COPY || m_method == LINK )
00734     {
00735         KURL trash;
00736         trash.setPath( KGlobalSettings::trashPath() );
00737         if ( m_destURL.cmp( trash, true /*ignore trailing slash*/ ) )
00738             bUpdateTrash = true;
00739     }
00740     if (bUpdateTrash)
00741     {
00742         // Update trash bin icon
00743         KURL trash;
00744         trash.setPath( KGlobalSettings::trashPath() );
00745         KURL::List lst;
00746         lst.append(trash);
00747         KDirNotify_stub allDirNotify("*", "KDirNotify*");
00748         allDirNotify.FilesChanged( lst );
00749     }
00750     delete this;
00751 }
00752 
00753 #include <konq_operations.moc>
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Thu Jan 29 23:03:28 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001