summaryrefslogtreecommitdiffstats
path: root/libkonq/konq_operations.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libkonq/konq_operations.cc')
-rw-r--r--libkonq/konq_operations.cc817
1 files changed, 817 insertions, 0 deletions
diff --git a/libkonq/konq_operations.cc b/libkonq/konq_operations.cc
new file mode 100644
index 000000000..5e9e8269b
--- /dev/null
+++ b/libkonq/konq_operations.cc
@@ -0,0 +1,817 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 David Faure <[email protected]>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <qclipboard.h>
+#include "konq_operations.h"
+
+#include <kautomount.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <knotifyclient.h>
+#include <krun.h>
+#include <kshell.h>
+#include <kshortcut.h>
+
+#include <kdirnotify_stub.h>
+
+#include <dcopclient.h>
+#include "konq_undo.h"
+#include "konq_defaults.h"
+#include "konqbookmarkmanager.h"
+
+// For doDrop
+#include <qdir.h>//first
+#include <assert.h>
+#include <kapplication.h>
+#include <kipc.h>
+#include <kdebug.h>
+#include <kfileitem.h>
+#include <kdesktopfile.h>
+#include <kurldrag.h>
+#include <kglobalsettings.h>
+#include <kimageio.h>
+#include <kio/job.h>
+#include <kio/jobclasses.h>
+#include <kio/paste.h>
+#include <kio/netaccess.h>
+#include <kio/renamedlg.h>
+#include <konq_drag.h>
+#include <konq_iconviewwidget.h>
+#include <kprotocolinfo.h>
+#include <kprocess.h>
+#include <kstringhandler.h>
+#include <qpopupmenu.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+
+KBookmarkManager * KonqBookmarkManager::s_bookmarkManager;
+
+KonqOperations::KonqOperations( QWidget *parent )
+ : QObject( parent, "KonqOperations" ),
+ m_method( UNKNOWN ), m_info(0L), m_pasteInfo(0L)
+{
+}
+
+KonqOperations::~KonqOperations()
+{
+ delete m_info;
+ delete m_pasteInfo;
+}
+
+void KonqOperations::editMimeType( const QString & mimeType )
+{
+ QString keditfiletype = QString::fromLatin1("keditfiletype");
+ KRun::runCommand( keditfiletype + " " + KProcess::quote(mimeType),
+ keditfiletype, keditfiletype /*unused*/);
+}
+
+void KonqOperations::del( QWidget * parent, int method, const KURL::List & selectedURLs )
+{
+ kdDebug(1203) << "KonqOperations::del " << parent->className() << endl;
+ if ( selectedURLs.isEmpty() )
+ {
+ kdWarning(1203) << "Empty URL list !" << endl;
+ return;
+ }
+
+ KonqOperations * op = new KonqOperations( parent );
+ ConfirmationType confirmation = DEFAULT_CONFIRMATION;
+ op->_del( method, selectedURLs, confirmation );
+}
+
+void KonqOperations::emptyTrash()
+{
+ KonqOperations *op = new KonqOperations( 0L );
+ op->_del( EMPTYTRASH, KURL("trash:/"), SKIP_CONFIRMATION );
+}
+
+void KonqOperations::restoreTrashedItems( const KURL::List& urls )
+{
+ KonqOperations *op = new KonqOperations( 0L );
+ op->_restoreTrashedItems( urls );
+}
+
+void KonqOperations::mkdir( QWidget *parent, const KURL & url )
+{
+ KIO::Job * job = KIO::mkdir( url );
+ KonqOperations * op = new KonqOperations( parent );
+ op->setOperation( job, MKDIR, KURL::List(), url );
+ (void) new KonqCommandRecorder( KonqCommand::MKDIR, KURL(), url, job ); // no support yet, apparently
+}
+
+void KonqOperations::doPaste( QWidget * parent, const KURL & destURL )
+{
+ doPaste(parent, destURL, QPoint());
+}
+
+void KonqOperations::doPaste( QWidget * parent, const KURL & destURL, const QPoint &pos )
+{
+ // move or not move ?
+ bool move = false;
+ QMimeSource *data = QApplication::clipboard()->data();
+ if ( data->provides( "application/x-kde-cutselection" ) ) {
+ move = KonqDrag::decodeIsCutSelection( data );
+ kdDebug(1203) << "move (from clipboard data) = " << move << endl;
+ }
+
+ KIO::Job *job = KIO::pasteClipboard( destURL, move );
+ if ( job )
+ {
+ KonqOperations * op = new KonqOperations( parent );
+ KIO::CopyJob * copyJob = static_cast<KIO::CopyJob *>(job);
+ KIOPasteInfo * pi = new KIOPasteInfo;
+ pi->mousePos = pos;
+ op->setPasteInfo( pi );
+ op->setOperation( job, move ? MOVE : COPY, copyJob->srcURLs(), copyJob->destURL() );
+ (void) new KonqCommandRecorder( move ? KonqCommand::MOVE : KonqCommand::COPY, KURL::List(), destURL, job );
+ }
+}
+
+void KonqOperations::copy( QWidget * parent, int method, const KURL::List & selectedURLs, const KURL& destUrl )
+{
+ kdDebug(1203) << "KonqOperations::copy() " << parent->className() << endl;
+ if ((method!=COPY) && (method!=MOVE) && (method!=LINK))
+ {
+ kdWarning(1203) << "Illegal copy method !" << endl;
+ return;
+ }
+ if ( selectedURLs.isEmpty() )
+ {
+ kdWarning(1203) << "Empty URL list !" << endl;
+ return;
+ }
+
+ KonqOperations * op = new KonqOperations( parent );
+ KIO::Job* job(0);
+ if (method==LINK)
+ job= KIO::link( selectedURLs, destUrl);
+ else if (method==MOVE)
+ job= KIO::move( selectedURLs, destUrl);
+ else
+ job= KIO::copy( selectedURLs, destUrl);
+
+ op->setOperation( job, method, selectedURLs, destUrl );
+
+ if (method==COPY)
+ (void) new KonqCommandRecorder( KonqCommand::COPY, selectedURLs, destUrl, job );
+ else
+ (void) new KonqCommandRecorder( method==MOVE?KonqCommand::MOVE:KonqCommand::LINK, selectedURLs, destUrl, job );
+}
+
+void KonqOperations::_del( int method, const KURL::List & _selectedURLs, ConfirmationType confirmation )
+{
+ KURL::List selectedURLs;
+ for (KURL::List::ConstIterator it = _selectedURLs.begin(); it != _selectedURLs.end(); ++it)
+ if (KProtocolInfo::supportsDeleting(*it))
+ selectedURLs.append(*it);
+ if (selectedURLs.isEmpty()) {
+ delete this;
+ return;
+ }
+
+ if ( askDeleteConfirmation( selectedURLs, method, confirmation, parentWidget() ) )
+ {
+ //m_srcURLs = selectedURLs;
+ KIO::Job *job;
+ m_method = method;
+ switch( method )
+ {
+ case TRASH:
+ {
+ job = KIO::trash( selectedURLs );
+ (void) new KonqCommandRecorder( KonqCommand::TRASH, selectedURLs, "trash:/", job );
+ break;
+ }
+ case EMPTYTRASH:
+ {
+ // Same as in ktrash --empty
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)1;
+ job = KIO::special( "trash:/", packedArgs );
+ KNotifyClient::event(0, "Trash: emptied");
+ break;
+ }
+ case DEL:
+ job = KIO::del( selectedURLs );
+ break;
+ case SHRED:
+ job = KIO::del( selectedURLs, true );
+ break;
+ default:
+ kdWarning() << "Unknown operation: " << method << endl;
+ delete this;
+ return;
+ }
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotResult( KIO::Job * ) ) );
+ } else
+ delete this;
+}
+
+void KonqOperations::_restoreTrashedItems( const KURL::List& urls )
+{
+ m_method = RESTORE;
+ KonqMultiRestoreJob* job = new KonqMultiRestoreJob( urls, true );
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotResult( KIO::Job * ) ) );
+}
+
+bool KonqOperations::askDeleteConfirmation( const KURL::List & selectedURLs, int method, ConfirmationType confirmation, QWidget* widget )
+{
+ if ( confirmation == SKIP_CONFIRMATION )
+ return true;
+ QString keyName;
+ bool ask = ( confirmation == FORCE_CONFIRMATION );
+ if ( !ask )
+ {
+ KConfig config("konquerorrc", true, false);
+ config.setGroup( "Trash" );
+ keyName = ( method == DEL ? "ConfirmDelete" : method == SHRED ? "ConfirmShred" : "ConfirmTrash" );
+ bool defaultValue = ( method == DEL ? DEFAULT_CONFIRMDELETE : method == SHRED ? DEFAULT_CONFIRMSHRED : DEFAULT_CONFIRMTRASH );
+ ask = config.readBoolEntry( keyName, defaultValue );
+ }
+ if ( ask )
+ {
+ KURL::List::ConstIterator it = selectedURLs.begin();
+ QStringList prettyList;
+ for ( ; it != selectedURLs.end(); ++it ) {
+ if ( (*it).protocol() == "trash" ) {
+ QString path = (*it).path();
+ // HACK (#98983): remove "0-foo". Note that it works better than
+ // displaying KFileItem::name(), for files under a subdir.
+ prettyList.append( path.remove(QRegExp("^/[0-9]*-")) );
+ } else
+ prettyList.append( (*it).pathOrURL() );
+ }
+
+ int result;
+ switch(method)
+ {
+ case DEL:
+ result = KMessageBox::warningContinueCancelList( widget,
+ i18n( "Do you really want to delete this item?", "Do you really want to delete these %n items?", prettyList.count()),
+ prettyList,
+ i18n( "Delete Files" ),
+ KStdGuiItem::del(),
+ keyName, KMessageBox::Dangerous);
+ break;
+
+ case SHRED:
+ result = KMessageBox::warningContinueCancelList( widget,
+ i18n( "Do you really want to shred this item?", "Do you really want to shred these %n items?", prettyList.count()),
+ prettyList,
+ i18n( "Shred Files" ),
+ KGuiItem( i18n( "Shred" ), "editshred" ),
+ keyName, KMessageBox::Dangerous);
+ break;
+
+ case MOVE:
+ default:
+ result = KMessageBox::warningContinueCancelList( widget,
+ 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()),
+ prettyList,
+ i18n( "Move to Trash" ),
+ KGuiItem( i18n( "Verb", "&Trash" ), "edittrash"),
+ keyName, KMessageBox::Dangerous);
+ }
+ if (!keyName.isEmpty())
+ {
+ // Check kmessagebox setting... erase & copy to konquerorrc.
+ KConfig *config = kapp->config();
+ KConfigGroupSaver saver(config, "Notification Messages");
+ if (!config->readBoolEntry(keyName, true))
+ {
+ config->writeEntry(keyName, true);
+ config->sync();
+ KConfig konq_config("konquerorrc", false);
+ konq_config.setGroup( "Trash" );
+ konq_config.writeEntry( keyName, false );
+ }
+ }
+ return (result == KMessageBox::Continue);
+ }
+ return true;
+}
+
+void KonqOperations::doDrop( const KFileItem * destItem, const KURL & dest, QDropEvent * ev, QWidget * parent )
+{
+ kdDebug(1203) << "doDrop: dest : " << dest.url() << endl;
+ KURL::List lst;
+ QMap<QString, QString> metaData;
+ if ( KURLDrag::decode( ev, lst, metaData ) ) // Are they urls ?
+ {
+ if( lst.count() == 0 )
+ {
+ kdWarning(1203) << "Oooops, no data ...." << endl;
+ ev->accept(false);
+ return;
+ }
+ kdDebug(1203) << "KonqOperations::doDrop metaData: " << metaData.count() << " entries." << endl;
+ QMap<QString,QString>::ConstIterator mit;
+ for( mit = metaData.begin(); mit != metaData.end(); ++mit )
+ {
+ kdDebug(1203) << "metaData: key=" << mit.key() << " value=" << mit.data() << endl;
+ }
+ // Check if we dropped something on itself
+ KURL::List::Iterator it = lst.begin();
+ for ( ; it != lst.end() ; it++ )
+ {
+ kdDebug(1203) << "URL : " << (*it).url() << endl;
+ if ( dest.equals( *it, true /*ignore trailing slashes*/ ) )
+ {
+ // The event source may be the view or an item (icon)
+ // Note: ev->source() can be 0L! (in case of kdesktop) (Simon)
+ if ( !ev->source() || ev->source() != parent && ev->source()->parent() != parent )
+ KMessageBox::sorry( parent, i18n("You cannot drop a folder on to itself") );
+ kdDebug(1203) << "Dropped on itself" << endl;
+ ev->accept(false);
+ return; // do nothing instead of displaying kfm's annoying error box
+ }
+ }
+
+ // Check the state of the modifiers key at the time of the drop
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint keybstate;
+ XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &keybstate );
+
+ QDropEvent::Action action = ev->action();
+ // Check for the drop of a bookmark -> we want a Link action
+ if ( ev->provides("application/x-xbel") )
+ {
+ keybstate |= ControlMask | ShiftMask;
+ action = QDropEvent::Link;
+ kdDebug(1203) << "KonqOperations::doDrop Bookmark -> emulating Link" << endl;
+ }
+
+ KonqOperations * op = new KonqOperations(parent);
+ op->setDropInfo( new DropInfo( keybstate, lst, metaData, win_x, win_y, action ) );
+
+ // Ok, now we need destItem.
+ if ( destItem )
+ {
+ op->asyncDrop( destItem ); // we have it already
+ }
+ else
+ {
+ // we need to stat to get it.
+ op->_statURL( dest, op, SLOT( asyncDrop( const KFileItem * ) ) );
+ }
+ // In both cases asyncDrop will delete op when done
+
+ ev->acceptAction();
+ }
+ else
+ {
+ //kdDebug(1203) << "Pasting to " << dest.url() << endl;
+ KonqOperations * op = new KonqOperations(parent);
+ KIO::CopyJob* job = KIO::pasteMimeSource( ev, dest,
+ i18n( "File name for dropped contents:" ),
+ parent );
+ if ( job ) // 0 if canceled by user
+ {
+ op->setOperation( job, COPY, KURL::List(), job->destURL() );
+ (void) new KonqCommandRecorder( KonqCommand::COPY, KURL::List(), dest, job );
+ }
+ ev->acceptAction();
+ }
+}
+
+void KonqOperations::asyncDrop( const KFileItem * destItem )
+{
+ assert(m_info); // setDropInfo should have been called before asyncDrop
+ m_destURL = destItem->url();
+
+ //kdDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destURL << endl;
+ // Check what the destination is
+ if ( destItem->isDir() )
+ {
+ doFileCopy();
+ return;
+ }
+ if ( !m_destURL.isLocalFile() )
+ {
+ // We dropped onto a remote URL that is not a directory!
+ // (e.g. an HTTP link in the sidebar).
+ // Can't do that, but we can't prevent it before stating the dest....
+ kdWarning(1203) << "Cannot drop onto " << m_destURL << endl;
+ delete this;
+ return;
+ }
+ if ( destItem->mimetype() == "application/x-desktop")
+ {
+ // Local .desktop file. What type ?
+ KDesktopFile desktopFile( m_destURL.path() );
+ if ( desktopFile.hasApplicationType() )
+ {
+ QString error;
+ QStringList stringList;
+ KURL::List lst = m_info->lst;
+ KURL::List::Iterator it = lst.begin();
+ for ( ; it != lst.end() ; it++ )
+ {
+ stringList.append((*it).url());
+ }
+ if ( KApplication::startServiceByDesktopPath( m_destURL.path(), stringList, &error ) > 0 )
+ KMessageBox::error( 0L, error );
+ }
+ else
+ {
+ // Device or Link -> adjust dest
+ if ( desktopFile.hasDeviceType() && desktopFile.hasKey("MountPoint") ) {
+ QString point = desktopFile.readEntry( "MountPoint" );
+ m_destURL.setPath( point );
+ QString dev = desktopFile.readDevice();
+ QString mp = KIO::findDeviceMountPoint( dev );
+ // Is the device already mounted ?
+ if ( !mp.isNull() )
+ doFileCopy();
+ else
+ {
+ bool ro = desktopFile.readBoolEntry( "ReadOnly", false );
+ QString fstype = desktopFile.readEntry( "FSType" );
+ KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destURL.path(), false );
+ connect( am, SIGNAL( finished() ), this, SLOT( doFileCopy() ) );
+ }
+ return;
+ }
+ else if ( desktopFile.hasLinkType() && desktopFile.hasKey("URL") ) {
+ m_destURL = desktopFile.readPathEntry("URL");
+ doFileCopy();
+ return;
+ }
+ // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those.
+ }
+ }
+ else
+ {
+ // Should be a local executable
+ // (If this fails, there is a bug in KFileItem::acceptsDrops)
+ kdDebug(1203) << "KonqOperations::doDrop " << m_destURL.path() << "should be an executable" << endl;
+ Q_ASSERT ( access( QFile::encodeName(m_destURL.path()), X_OK ) == 0 );
+ KProcess proc;
+ proc << m_destURL.path() ;
+ // Launch executable for each of the files
+ KURL::List lst = m_info->lst;
+ KURL::List::Iterator it = lst.begin();
+ for ( ; it != lst.end() ; it++ )
+ proc << (*it).path(); // assume local files
+ kdDebug(1203) << "starting " << m_destURL.path() << " with " << lst.count() << " arguments" << endl;
+ proc.start( KProcess::DontCare );
+ }
+ delete this;
+}
+
+void KonqOperations::doFileCopy()
+{
+ assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop
+ KURL::List lst = m_info->lst;
+ QDropEvent::Action action = m_info->action;
+ bool isDesktopFile = false;
+ bool itemIsOnDesktop = false;
+ bool allItemsAreFromTrash = true;
+ KURL::List mlst; // list of items that can be moved
+ for (KURL::List::ConstIterator it = lst.begin(); it != lst.end(); ++it)
+ {
+ bool local = (*it).isLocalFile();
+ if ( KProtocolInfo::supportsDeleting( *it ) && (!local || QFileInfo((*it).directory()).isWritable() ))
+ mlst.append(*it);
+ if ( local && KDesktopFile::isDesktopFile((*it).path()))
+ isDesktopFile = true;
+ if ( local && (*it).path().startsWith(KGlobalSettings::desktopPath()))
+ itemIsOnDesktop = true;
+ if ( local || (*it).protocol() != "trash" )
+ allItemsAreFromTrash = false;
+ }
+
+ bool linkOnly = false;
+ if (isDesktopFile && !kapp->authorize("run_desktop_files") &&
+ (m_destURL.path(1) == KGlobalSettings::desktopPath()) )
+ {
+ linkOnly = true;
+ }
+
+ if ( !mlst.isEmpty() && m_destURL.protocol() == "trash" )
+ {
+ if ( itemIsOnDesktop && !kapp->authorize("editable_desktop_icons") )
+ {
+ delete this;
+ return;
+ }
+
+ m_method = TRASH;
+ if ( askDeleteConfirmation( mlst, TRASH, DEFAULT_CONFIRMATION, parentWidget() ) )
+ action = QDropEvent::Move;
+ else
+ {
+ delete this;
+ return;
+ }
+ }
+ else if ( allItemsAreFromTrash || m_destURL.protocol() == "trash" ) {
+ // No point in asking copy/move/link when using dnd from or to the trash.
+ action = QDropEvent::Move;
+ }
+ else if ( (((m_info->keybstate & ControlMask) == 0) && ((m_info->keybstate & ShiftMask) == 0)) ||
+ linkOnly )
+ {
+ // Neither control nor shift are pressed => show popup menu
+ KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
+ bool bSetWallpaper = false;
+ if ( iconView && iconView->maySetWallpaper() && lst.count() == 1 )
+ {
+ KURL url = lst.first();
+ KMimeType::Ptr mime = KMimeType::findByURL( url );
+ if ( ( !KImageIO::type(url.path()).isEmpty() ) ||
+ ( KImageIO::isSupported(mime->name(), KImageIO::Reading) ) ||
+ mime->is( "image/svg+xml" ) )
+ {
+ bSetWallpaper = true;
+ }
+ }
+
+ // Check what the source can do
+ KURL url = lst.first(); // we'll assume it's the same for all URLs (hack)
+ bool sReading = KProtocolInfo::supportsReading( url );
+ bool sDeleting = KProtocolInfo::supportsDeleting( url );
+ bool sMoving = KProtocolInfo::supportsMoving( url );
+ // Check what the destination can do
+ bool dWriting = KProtocolInfo::supportsWriting( m_destURL );
+ if ( !dWriting )
+ {
+ delete this;
+ return;
+ }
+
+ QPopupMenu popup;
+ if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly )
+ popup.insertItem(SmallIconSet("goto"), i18n( "&Move Here" ) + "\t" + KKey::modFlagLabel( KKey::SHIFT ), 2 );
+ if ( sReading && !linkOnly)
+ popup.insertItem(SmallIconSet("editcopy"), i18n( "&Copy Here" ) + "\t" + KKey::modFlagLabel( KKey::CTRL ), 1 );
+ popup.insertItem(SmallIconSet("www"), i18n( "&Link Here" ) + "\t" + KKey::modFlagLabel( (KKey::ModFlag)( KKey::CTRL|KKey::SHIFT ) ), 3 );
+ if (bSetWallpaper)
+ popup.insertItem(SmallIconSet("background"), i18n( "Set as &Wallpaper" ), 4 );
+ popup.insertSeparator();
+ popup.insertItem(SmallIconSet("cancel"), i18n( "C&ancel" ) + "\t" + KKey( Qt::Key_Escape ).toString(), 5);
+
+ int result = popup.exec( m_info->mousePos );
+
+ switch (result) {
+ case 1 : action = QDropEvent::Copy; break;
+ case 2 : action = QDropEvent::Move; break;
+ case 3 : action = QDropEvent::Link; break;
+ case 4 :
+ {
+ kdDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url() << endl;
+ if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first());
+ delete this;
+ return;
+ }
+ case 5 :
+ default : delete this; return;
+ }
+ }
+
+ KIO::Job * job = 0;
+ switch ( action ) {
+ case QDropEvent::Move :
+ job = KIO::move( lst, m_destURL );
+ job->setMetaData( m_info->metaData );
+ setOperation( job, m_method == TRASH ? TRASH : MOVE, lst, m_destURL );
+ (void) new KonqCommandRecorder(
+ m_method == TRASH ? KonqCommand::TRASH : KonqCommand::MOVE,
+ lst, m_destURL, job );
+ return; // we still have stuff to do -> don't delete ourselves
+ case QDropEvent::Copy :
+ job = KIO::copy( lst, m_destURL );
+ job->setMetaData( m_info->metaData );
+ setOperation( job, COPY, lst, m_destURL );
+ (void) new KonqCommandRecorder( KonqCommand::COPY, lst, m_destURL, job );
+ return;
+ case QDropEvent::Link :
+ kdDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count() << endl;
+ job = KIO::link( lst, m_destURL );
+ job->setMetaData( m_info->metaData );
+ setOperation( job, LINK, lst, m_destURL );
+ (void) new KonqCommandRecorder( KonqCommand::LINK, lst, m_destURL, job );
+ return;
+ default : kdError(1203) << "Unknown action " << (int)action << endl;
+ }
+ delete this;
+}
+
+void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const KURL& newurl )
+{
+ kdDebug(1203) << "KonqOperations::rename oldurl=" << oldurl << " newurl=" << newurl << endl;
+ if ( oldurl == newurl )
+ return;
+
+ KURL::List lst;
+ lst.append(oldurl);
+ KIO::Job * job = KIO::moveAs( oldurl, newurl, !oldurl.isLocalFile() );
+ KonqOperations * op = new KonqOperations( parent );
+ op->setOperation( job, MOVE, lst, newurl );
+ (void) new KonqCommandRecorder( KonqCommand::MOVE, lst, newurl, job );
+ // if moving the desktop then update config file and emit
+ if ( oldurl.isLocalFile() && oldurl.path(1) == KGlobalSettings::desktopPath() )
+ {
+ kdDebug(1203) << "That rename was the Desktop path, updating config files" << endl;
+ KConfig *globalConfig = KGlobal::config();
+ KConfigGroupSaver cgs( globalConfig, "Paths" );
+ globalConfig->writePathEntry("Desktop" , newurl.path(), true, true );
+ globalConfig->sync();
+ KIPC::sendMessageAll(KIPC::SettingsChanged, KApplication::SETTINGS_PATHS);
+ }
+}
+
+void KonqOperations::setOperation( KIO::Job * job, int method, const KURL::List & /*src*/, const KURL & dest )
+{
+ m_method = method;
+ //m_srcURLs = src;
+ m_destURL = dest;
+ if ( job )
+ {
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotResult( KIO::Job * ) ) );
+ KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job);
+ KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
+ if (copyJob && iconView)
+ {
+ connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)),
+ this, SLOT(slotAboutToCreate(KIO::Job *,const QValueList<KIO::CopyInfo> &)));
+ connect(this, SIGNAL(aboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)),
+ iconView, SLOT(slotAboutToCreate(const QPoint &, const QValueList<KIO::CopyInfo> &)));
+ }
+ }
+ else // for link
+ slotResult( 0L );
+}
+
+void KonqOperations::slotAboutToCreate(KIO::Job *, const QValueList<KIO::CopyInfo> &files)
+{
+ emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files);
+}
+
+void KonqOperations::statURL( const KURL & url, const QObject *receiver, const char *member )
+{
+ KonqOperations * op = new KonqOperations( 0L );
+ op->_statURL( url, receiver, member );
+ op->m_method = STAT;
+}
+
+void KonqOperations::_statURL( const KURL & url, const QObject *receiver, const char *member )
+{
+ connect( this, SIGNAL( statFinished( const KFileItem * ) ), receiver, member );
+ KIO::StatJob * job = KIO::stat( url /*, false?*/ );
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotStatResult( KIO::Job * ) ) );
+}
+
+void KonqOperations::slotStatResult( KIO::Job * job )
+{
+ if ( job->error())
+ job->showErrorDialog( (QWidget*)parent() );
+ else
+ {
+ KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
+ KFileItem * item = new KFileItem( statJob->statResult(), statJob->url() );
+ emit statFinished( item );
+ delete item;
+ }
+ // If we're only here for a stat, we're done. But not if we used _statURL internally
+ if ( m_method == STAT )
+ delete this;
+}
+
+void KonqOperations::slotResult( KIO::Job * job )
+{
+ if (job && job->error())
+ job->showErrorDialog( (QWidget*)parent() );
+ if ( m_method == EMPTYTRASH ) {
+ // Update konq windows opened on trash:/
+ KDirNotify_stub allDirNotify("*", "KDirNotify*");
+ allDirNotify.FilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones...
+ }
+ delete this;
+}
+
+void KonqOperations::rename( QWidget * parent, const KURL & oldurl, const QString & name )
+{
+ KURL newurl( oldurl );
+ newurl.setPath( oldurl.directory(false, true) + name );
+ kdDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl << endl;
+ rename( parent, oldurl, newurl );
+}
+
+void KonqOperations::newDir( QWidget * parent, const KURL & baseURL )
+{
+ bool ok;
+ QString name = i18n( "New Folder" );
+ if ( baseURL.isLocalFile() && QFileInfo( baseURL.path(+1) + name ).exists() )
+ name = KIO::RenameDlg::suggestName( baseURL, i18n( "New Folder" ) );
+
+ name = KInputDialog::getText ( i18n( "New Folder" ),
+ i18n( "Enter folder name:" ), name, &ok, parent );
+ if ( ok && !name.isEmpty() )
+ {
+ KURL url;
+ if ((name[0] == '/') || (name[0] == '~'))
+ {
+ url.setPath(KShell::tildeExpand(name));
+ }
+ else
+ {
+ name = KIO::encodeFileName( name );
+ url = baseURL;
+ url.addPath( name );
+ }
+ KonqOperations::mkdir( 0L, url );
+ }
+}
+
+////
+
+KonqMultiRestoreJob::KonqMultiRestoreJob( const KURL::List& urls, bool showProgressInfo )
+ : KIO::Job( showProgressInfo ),
+ m_urls( urls ), m_urlsIterator( m_urls.begin() ),
+ m_progress( 0 )
+{
+ QTimer::singleShot(0, this, SLOT(slotStart()));
+}
+
+void KonqMultiRestoreJob::slotStart()
+{
+ // Well, it's not a total in bytes, so this would look weird
+ //if ( m_urlsIterator == m_urls.begin() ) // first time: emit total
+ // emit totalSize( m_urls.count() );
+
+ if ( m_urlsIterator != m_urls.end() )
+ {
+ const KURL& url = *m_urlsIterator;
+
+ KURL new_url = url;
+ if ( new_url.protocol()=="system"
+ && new_url.path().startsWith("/trash") )
+ {
+ QString path = new_url.path();
+ path.remove(0, 6);
+ new_url.setProtocol("trash");
+ new_url.setPath(path);
+ }
+
+ Q_ASSERT( new_url.protocol() == "trash" );
+ QByteArray packedArgs;
+ QDataStream stream( packedArgs, IO_WriteOnly );
+ stream << (int)3 << new_url;
+ KIO::Job* job = KIO::special( new_url, packedArgs );
+ addSubjob( job );
+ }
+ else // done!
+ {
+ KDirNotify_stub allDirNotify("*", "KDirNotify*");
+ allDirNotify.FilesRemoved( m_urls );
+ emitResult();
+ }
+}
+
+void KonqMultiRestoreJob::slotResult( KIO::Job *job )
+{
+ if ( job->error() )
+ {
+ KIO::Job::slotResult( job ); // will set the error and emit result(this)
+ return;
+ }
+ subjobs.remove( job );
+ // Move on to next one
+ ++m_urlsIterator;
+ ++m_progress;
+ //emit processedSize( this, m_progress );
+ emitPercent( m_progress, m_urls.count() );
+ slotStart();
+}
+
+QWidget* KonqOperations::parentWidget() const
+{
+ return static_cast<QWidget *>( parent() );
+}
+
+#include "konq_operations.moc"