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