Add (and install) svg for the new krunner interface.
[kdebase/uwolfer.git] / apps / lib / konq / konq_operations.cpp
blob768e25e7eaf011a6af23000ddc9243757742d11e
1 /* This file is part of the KDE project
2 Copyright 2000-2007 David Faure <faure@kde.org>
3 Copyright 2003 Waldo Bastian <bastian@kde.org>
4 Copyright 2002 Michael Brade <brade@kde.org>
5 Copyright 2001-2002 Alexander Neundorf <neundorf@kde.org>
6 Copyright 2000-2001 Simon Hausmann <hausmann@kde.org>
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) version 3.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "konq_operations.h"
24 #include "konq_fileundomanager.h"
25 #include "konq_defaults.h"
26 #include "konqmimedata.h"
28 #include <ktoolinvocation.h>
29 #include <kautomount.h>
30 #include <kmountpoint.h>
31 #include <kinputdialog.h>
32 #include <klocale.h>
33 #include <kmessagebox.h>
34 #include <knotification.h>
35 #include <krun.h>
36 #include <kshell.h>
37 #include <kprocess.h>
38 #include <kshortcut.h>
39 #include <kprotocolmanager.h>
40 #include <kio/job.h>
41 #include <kio/deletejob.h>
42 #include <kio/jobuidelegate.h>
43 #include <kio/jobclasses.h>
44 #include <kio/copyjob.h>
45 #include <kio/paste.h>
46 #include <kio/renamedialog.h>
47 #include <kdirnotify.h>
48 #include <kuiserverjobtracker.h>
49 // For doDrop
50 #include <kauthorized.h>
51 #include <kglobal.h>
52 #include <kglobalsettings.h>
53 #include <kdebug.h>
54 #include <kfileitem.h>
55 #include <kdesktopfile.h>
56 #include <kimageio.h>
58 //#include <konq_iconviewwidget.h>
59 #include <QtDBus/QtDBus>
60 #include <QMenu>
61 #include <QApplication>
62 #include <QClipboard>
63 #include <QDropEvent>
64 #include <QList>
65 #include <QDir>
67 #include <assert.h>
68 #include <unistd.h>
69 #include <kconfiggroup.h>
71 KonqOperations::KonqOperations( QWidget *parent )
72 : QObject( parent ),
73 m_method( UNKNOWN ), m_info(0), m_pasteInfo(0)
75 setObjectName( "KonqOperations" );
78 KonqOperations::~KonqOperations()
80 delete m_info;
81 delete m_pasteInfo;
84 void KonqOperations::editMimeType( const QString & mimeType, QWidget* parent )
86 QString keditfiletype = QLatin1String("keditfiletype");
87 KRun::runCommand( keditfiletype
88 + " --parent " + QString::number( (long)parent->winId())
89 + ' ' + KShell::quoteArg(mimeType),
90 keditfiletype, keditfiletype /*unused*/, parent );
93 void KonqOperations::del( QWidget * parent, Operation method, const KUrl::List & selectedUrls )
95 kDebug(1203) << "KonqOperations::del " << parent->metaObject()->className();
96 if ( selectedUrls.isEmpty() )
98 kWarning(1203) << "Empty URL list !" ;
99 return;
102 KonqOperations * op = new KonqOperations( parent );
103 ConfirmationType confirmation = DEFAULT_CONFIRMATION;
104 op->_del( method, selectedUrls, confirmation );
107 void KonqOperations::emptyTrash( QWidget* parent )
109 KonqOperations *op = new KonqOperations( parent );
110 op->_del( EMPTYTRASH, KUrl("trash:/"), SKIP_CONFIRMATION );
113 void KonqOperations::restoreTrashedItems( const KUrl::List& urls, QWidget* parent )
115 KonqOperations *op = new KonqOperations( parent );
116 op->_restoreTrashedItems( urls );
119 KIO::SimpleJob* KonqOperations::mkdir( QWidget *parent, const KUrl & url )
121 KIO::SimpleJob * job = KIO::mkdir(url);
122 job->ui()->setWindow(parent);
123 job->ui()->setAutoErrorHandlingEnabled(true);
124 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::MKDIR, KUrl(), url, job );
125 return job;
128 void KonqOperations::doPaste( QWidget * parent, const KUrl & destUrl, const QPoint &pos )
130 // move or not move ?
131 bool move = false;
132 const QMimeData *data = QApplication::clipboard()->mimeData();
133 if ( data->hasFormat( "application/x-kde-cutselection" ) ) {
134 move = KonqMimeData::decodeIsCutSelection( data );
135 kDebug(1203) << "move (from clipboard data) = " << move;
138 KIO::Job *job = KIO::pasteClipboard( destUrl, parent, move );
139 if ( job )
141 KonqOperations * op = new KonqOperations( parent );
142 KIO::CopyJob * copyJob = static_cast<KIO::CopyJob *>(job);
143 KIOPasteInfo * pi = new KIOPasteInfo;
144 pi->mousePos = pos;
145 op->setPasteInfo( pi );
146 op->setOperation( job, move ? MOVE : COPY, copyJob->destUrl() );
147 KonqFileUndoManager::self()->recordJob( move ? KonqFileUndoManager::MOVE : KonqFileUndoManager::COPY, KUrl::List(), destUrl, job );
151 void KonqOperations::copy( QWidget * parent, Operation method, const KUrl::List & selectedUrls, const KUrl& destUrl )
153 kDebug(1203) << "KonqOperations::copy() " << parent->metaObject()->className();
154 if ((method!=COPY) && (method!=MOVE) && (method!=LINK))
156 kWarning(1203) << "Illegal copy method !" ;
157 return;
159 if ( selectedUrls.isEmpty() )
161 kWarning(1203) << "Empty URL list !" ;
162 return;
165 KonqOperations * op = new KonqOperations( parent );
166 KIO::Job* job(0);
167 if (method == LINK)
168 job = KIO::link( selectedUrls, destUrl );
169 else if (method == MOVE)
170 job = KIO::move( selectedUrls, destUrl );
171 else
172 job = KIO::copy( selectedUrls, destUrl );
174 op->setOperation( job, method, destUrl );
176 if (method == COPY)
177 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::COPY, selectedUrls, destUrl, job );
178 else
179 KonqFileUndoManager::self()->recordJob( method==MOVE?KonqFileUndoManager::MOVE:KonqFileUndoManager::LINK, selectedUrls, destUrl, job );
182 void KonqOperations::_del( Operation method, const KUrl::List & _selectedUrls, ConfirmationType confirmation )
184 KUrl::List selectedUrls;
185 for (KUrl::List::ConstIterator it = _selectedUrls.begin(); it != _selectedUrls.end(); ++it)
186 if (KProtocolManager::supportsDeleting(*it))
187 selectedUrls.append(*it);
188 if (selectedUrls.isEmpty()) {
189 delete this;
190 return;
193 if ( askDeleteConfirmation( selectedUrls, method, confirmation, parentWidget() ) )
195 //m_srcUrls = selectedUrls;
196 KIO::Job *job;
197 m_method = method;
198 switch( method )
200 case TRASH:
202 job = KIO::trash( selectedUrls );
203 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::TRASH, selectedUrls, KUrl("trash:/"), job );
204 break;
206 case EMPTYTRASH:
208 // Same as in ktrash --empty
209 QByteArray packedArgs;
210 QDataStream stream( &packedArgs, QIODevice::WriteOnly );
211 stream << (int)1;
212 job = KIO::special( KUrl("trash:/"), packedArgs );
213 KNotification::event("Trash: emptied", QString() , QPixmap() , 0l, KNotification::DefaultEvent );
214 break;
216 case DEL:
217 job = KIO::del( selectedUrls );
218 break;
219 default:
220 kWarning() << "Unknown operation: " << method ;
221 delete this;
222 return;
224 job->ui()->setWindow(parentWidget());
225 connect( job, SIGNAL( result( KJob * ) ),
226 SLOT( slotResult( KJob * ) ) );
227 } else
228 delete this;
231 void KonqOperations::_restoreTrashedItems( const KUrl::List& urls )
233 m_method = RESTORE;
234 KonqMultiRestoreJob* job = new KonqMultiRestoreJob( urls );
235 job->ui()->setWindow(parentWidget());
236 KIO::getJobTracker()->registerJob(job);
237 connect( job, SIGNAL( result( KJob * ) ),
238 SLOT( slotResult( KJob * ) ) );
241 bool KonqOperations::askDeleteConfirmation( const KUrl::List & selectedUrls, int method, ConfirmationType confirmation, QWidget* widget )
243 if ( confirmation == SKIP_CONFIRMATION )
244 return true;
245 QString keyName;
246 bool ask = ( confirmation == FORCE_CONFIRMATION );
247 if ( !ask )
249 KConfig config( "konquerorrc", KConfig::NoGlobals );
250 keyName = ( method == DEL ? "ConfirmDelete" : "ConfirmTrash" );
251 bool defaultValue = ( method == DEL ? DEFAULT_CONFIRMDELETE : DEFAULT_CONFIRMTRASH );
252 ask = config.group("Trash").readEntry( keyName, defaultValue );
254 if ( ask )
256 KUrl::List::ConstIterator it = selectedUrls.begin();
257 QStringList prettyList;
258 for ( ; it != selectedUrls.end(); ++it ) {
259 if ( (*it).protocol() == "trash" ) {
260 QString path = (*it).path();
261 // HACK (#98983): remove "0-foo". Note that it works better than
262 // displaying KFileItem::name(), for files under a subdir.
263 prettyList.append( path.remove(QRegExp("^/[0-9]*-")) );
264 } else
265 prettyList.append( (*it).pathOrUrl() );
268 int result;
269 switch(method)
271 case DEL:
272 result = KMessageBox::warningContinueCancelList(
273 widget,
274 i18np( "Do you really want to delete this item?", "Do you really want to delete these %1 items?", prettyList.count()),
275 prettyList,
276 i18n( "Delete Files" ),
277 KStandardGuiItem::del(),
278 KStandardGuiItem::cancel(),
279 keyName, KMessageBox::Notify | KMessageBox::Dangerous);
280 break;
282 case MOVE:
283 default:
284 result = KMessageBox::warningContinueCancelList(
285 widget,
286 i18np( "Do you really want to move this item to the trash?", "Do you really want to move these %1 items to the trash?", prettyList.count()),
287 prettyList,
288 i18n( "Move to Trash" ),
289 KGuiItem( i18nc( "Verb", "&Trash" ), "user-trash"),
290 KStandardGuiItem::cancel(),
291 keyName, KMessageBox::Notify | KMessageBox::Dangerous);
293 if (!keyName.isEmpty())
295 // Check kmessagebox setting... erase & copy to konquerorrc.
296 KSharedConfig::Ptr config = KGlobal::config();
297 KConfigGroup saver(config, "Notification Messages");
298 if (!saver.readEntry(keyName, QVariant(true)).toBool())
300 saver.writeEntry(keyName, true);
301 saver.sync();
302 KConfig konq_config("konquerorrc", KConfig::NoGlobals);
303 konq_config.group("Trash").writeEntry( keyName, false );
306 return (result == KMessageBox::Continue);
308 return true;
311 void KonqOperations::doDrop( const KFileItem & destItem, const KUrl & dest, QDropEvent * ev, QWidget * parent )
313 kDebug(1203) << "doDrop: dest : " << dest.url();
314 QMap<QString, QString> metaData;
315 const KUrl::List lst = KUrl::List::fromMimeData( ev->mimeData(), &metaData );
316 if ( !lst.isEmpty() ) // Are they urls ?
318 kDebug(1203) << "KonqOperations::doDrop metaData: " << metaData.count() << " entries.";
319 QMap<QString,QString>::ConstIterator mit;
320 for( mit = metaData.begin(); mit != metaData.end(); ++mit )
322 kDebug(1203) << "metaData: key=" << mit.key() << " value=" << mit.value();
324 // Check if we dropped something on itself
325 KUrl::List::ConstIterator it = lst.begin();
326 for ( ; it != lst.end() ; it++ )
328 kDebug(1203) << "URL : " << (*it).url();
329 if ( dest.equals( *it, KUrl::CompareWithoutTrailingSlash ) )
331 // The event source may be the view or an item (icon)
332 // Note: ev->source() can be 0L! (in case of kdesktop) (Simon)
333 if ( !ev->source() || ev->source() != parent && ev->source()->parent() != parent )
334 KMessageBox::sorry( parent, i18n("You cannot drop a folder on to itself") );
335 kDebug(1203) << "Dropped on itself";
336 ev->setAccepted( false );
337 return; // do nothing instead of displaying kfm's annoying error box
341 // Check the state of the modifiers key at the time of the drop
342 Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers();
344 Qt::DropAction action = ev->dropAction();
345 // Check for the drop of a bookmark -> we want a Link action
346 if ( ev->provides("application/x-xbel") )
348 modifiers |= Qt::ControlModifier | Qt::ShiftModifier;
349 action = Qt::LinkAction;
350 kDebug(1203) << "KonqOperations::doDrop Bookmark -> emulating Link";
353 KonqOperations * op = new KonqOperations(parent);
354 op->setDropInfo( new DropInfo( modifiers, lst, metaData, ev->pos(), action ) );
356 // Ok, now we need destItem.
357 if ( !destItem.isNull() )
359 op->asyncDrop( destItem ); // we have it already
361 else
363 // we need to stat to get it.
364 op->_statUrl( dest, op, SLOT( asyncDrop( const KFileItem & ) ) );
366 // In both cases asyncDrop will delete op when done
368 ev->acceptProposedAction();
370 else
372 //kDebug(1203) << "Pasting to " << dest.url();
373 KonqOperations * op = new KonqOperations(parent);
374 KIO::CopyJob* job = KIO::pasteMimeSource( ev->mimeData(), dest,
375 i18n( "File name for dropped contents:" ),
376 parent );
377 if ( job ) // 0 if canceled by user
379 op->setOperation( job, COPY, job->destUrl() );
380 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::COPY, KUrl::List(), dest, job );
382 ev->acceptProposedAction();
386 void KonqOperations::asyncDrop( const KFileItem & destItem )
388 assert(m_info); // setDropInfo should have been called before asyncDrop
389 m_destUrl = destItem.url();
391 //kDebug(1203) << "KonqOperations::asyncDrop destItem->mode=" << destItem->mode() << " url=" << m_destUrl;
392 // Check what the destination is
393 if ( destItem.isDir() )
395 doDropFileCopy();
396 return;
398 if ( !m_destUrl.isLocalFile() )
400 // We dropped onto a remote URL that is not a directory!
401 // (e.g. an HTTP link in the sidebar).
402 // Can't do that, but we can't prevent it before stating the dest....
403 kWarning(1203) << "Cannot drop onto " << m_destUrl ;
404 delete this;
405 return;
407 if ( destItem.mimetype() == "application/x-desktop")
409 // Local .desktop file. What type ?
410 KDesktopFile desktopFile( m_destUrl.path() );
411 KConfigGroup desktopGroup = desktopFile.desktopGroup();
412 if ( desktopFile.hasApplicationType() )
414 QString error;
415 const QStringList urlStrList = m_info->urls.toStringList();
416 if ( KToolInvocation::startServiceByDesktopPath( m_destUrl.path(), urlStrList, &error ) > 0 )
417 KMessageBox::error( parentWidget(), error );
419 else
421 // Device or Link -> adjust dest
422 if ( desktopFile.hasDeviceType() && desktopGroup.hasKey("MountPoint") ) {
423 QString point = desktopGroup.readEntry( "MountPoint" );
424 m_destUrl.setPath( point );
425 QString dev = desktopFile.readDevice();
426 KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByDevice( dev );
427 // Is the device already mounted ?
428 if ( mp ) {
429 doDropFileCopy();
431 #ifndef Q_WS_WIN
432 else
434 const bool ro = desktopGroup.readEntry( "ReadOnly", false );
435 const QByteArray fstype = desktopGroup.readEntry( "FSType" ).toLatin1();
436 KAutoMount* am = new KAutoMount( ro, fstype, dev, point, m_destUrl.path(), false );
437 connect( am, SIGNAL( finished() ), this, SLOT( doDropFileCopy() ) );
439 #endif
440 return;
442 else if ( desktopFile.hasLinkType() && desktopGroup.hasKey("URL") ) {
443 m_destUrl = desktopGroup.readPathEntry("URL", QString());
444 doDropFileCopy();
445 return;
447 // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those.
450 else
452 // Should be a local executable
453 // (If this fails, there is a bug in KFileItem::acceptsDrops / KDirModel::flags)
454 kDebug(1203) << "KonqOperations::doDrop " << m_destUrl.path() << "should be an executable";
455 Q_ASSERT ( access( QFile::encodeName(m_destUrl.path()), X_OK ) == 0 );
456 // Launch executable for each of the files
457 QStringList args;
458 KUrl::List lst = m_info->urls;
459 KUrl::List::Iterator it = lst.begin();
460 for ( ; it != lst.end() ; it++ )
461 args << (*it).path(); // assume local files
462 kDebug(1203) << "starting " << m_destUrl.path() << " with " << lst.count() << " arguments";
463 KProcess::startDetached( m_destUrl.path(), args );
465 delete this;
468 void KonqOperations::doDropFileCopy()
470 assert(m_info); // setDropInfo - and asyncDrop - should have been called before asyncDrop
471 const KUrl::List lst = m_info->urls;
472 Qt::DropAction action = m_info->action;
473 bool isDesktopFile = false;
474 bool itemIsOnDesktop = false;
475 bool allItemsAreFromTrash = true;
476 KUrl::List mlst; // list of items that can be moved
477 for (KUrl::List::ConstIterator it = lst.begin(); it != lst.end(); ++it)
479 bool local = (*it).isLocalFile();
480 if ( KProtocolManager::supportsDeleting( *it ) && (!local || QFileInfo((*it).directory()).isWritable() ))
481 mlst.append(*it);
482 if ( local && KDesktopFile::isDesktopFile((*it).path()))
483 isDesktopFile = true;
484 if ( local && (*it).path().startsWith(KGlobalSettings::desktopPath()))
485 itemIsOnDesktop = true;
486 if ( local || (*it).protocol() != "trash" )
487 allItemsAreFromTrash = false;
490 bool linkOnly = false;
491 if (isDesktopFile && !KAuthorized::authorizeKAction("run_desktop_files") &&
492 (m_destUrl.path( KUrl::AddTrailingSlash ) == KGlobalSettings::desktopPath()) )
494 linkOnly = true;
497 if ( !mlst.isEmpty() && m_destUrl.protocol() == "trash" )
499 if ( itemIsOnDesktop && !KAuthorized::authorizeKAction("editable_desktop_icons") )
501 delete this;
502 return;
505 m_method = TRASH;
506 if ( askDeleteConfirmation( mlst, TRASH, DEFAULT_CONFIRMATION, parentWidget() ) )
507 action = Qt::MoveAction;
508 else
510 delete this;
511 return;
514 else if ( allItemsAreFromTrash || m_destUrl.protocol() == "trash" ) {
515 // No point in asking copy/move/link when using dnd from or to the trash.
516 action = Qt::MoveAction;
518 else if ( (
519 ((m_info->keyboardModifiers & Qt::ControlModifier) == 0) &&
520 ((m_info->keyboardModifiers & Qt::ShiftModifier) == 0) &&
521 ((m_info->keyboardModifiers & Qt::AltModifier) == 0) ) || linkOnly )
523 // Neither control, shift or alt are pressed => show popup menu
525 // TODO move this code out somehow. Allow user of KonqOperations to add his own actions...
526 #if 0
527 KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
528 bool bSetWallpaper = false;
529 if ( iconView && iconView->maySetWallpaper() && lst.count() == 1 )
531 KUrl url = lst.first();
532 KMimeType::Ptr mime = KMimeType::findByUrl( url );
533 if ( mime && ( ( KImageIO::isSupported(mime->name(), KImageIO::Reading) ) ||
534 mime->is( "image/svg+xml" ) ) )
536 bSetWallpaper = true;
539 #endif
541 // Check what the source can do
542 KUrl url = lst.first(); // we'll assume it's the same for all URLs (hack)
543 bool sReading = KProtocolManager::supportsReading( url );
544 bool sDeleting = KProtocolManager::supportsDeleting( url );
545 bool sMoving = KProtocolManager::supportsMoving( url );
546 // Check what the destination can do
547 bool dWriting = KProtocolManager::supportsWriting( m_destUrl );
548 if ( !dWriting )
550 delete this;
551 return;
554 QMenu popup;
555 QString seq = QKeySequence( Qt::ShiftModifier ).toString();
556 seq.chop(1); // chop superfluous '+'
557 QAction* popupMoveAction = new QAction(i18n( "&Move Here" ) + '\t' + seq, this);
558 popupMoveAction->setIcon(KIcon("goto-page"));
559 seq = QKeySequence( Qt::ControlModifier ).toString();
560 seq.chop(1);
561 QAction* popupCopyAction = new QAction(i18n( "&Copy Here" ) + '\t' + seq, this);
562 popupCopyAction->setIcon(KIcon("edit-copy"));
563 seq = QKeySequence( Qt::ControlModifier + Qt::ShiftModifier ).toString();
564 seq.chop(1);
565 QAction* popupLinkAction = new QAction(i18n( "&Link Here" ) + '\t' + seq, this);
566 popupLinkAction->setIcon(KIcon("www"));
567 QAction* popupWallAction = new QAction( i18n( "Set as &Wallpaper" ), this );
568 popupWallAction->setIcon(KIcon("background"));
569 QAction* popupCancelAction = new QAction(i18n( "C&ancel" ) + '\t' + QKeySequence( Qt::Key_Escape ).toString(), this);
570 popupCancelAction->setIcon(KIcon("cancel"));
572 if ( sReading && !linkOnly)
573 popup.addAction(popupCopyAction);
575 if (!mlst.isEmpty() && (sMoving || (sReading && sDeleting)) && !linkOnly )
576 popup.addAction(popupMoveAction);
578 popup.addAction(popupLinkAction);
580 #if 0
581 if (bSetWallpaper)
582 popup.addAction(popupWallAction);
583 #endif
585 popup.addSeparator();
586 popup.addAction(popupCancelAction);
588 QAction* result = popup.exec( m_info->mousePos );
590 if(result == popupCopyAction)
591 action = Qt::CopyAction;
592 else if(result == popupMoveAction)
593 action = Qt::MoveAction;
594 else if(result == popupLinkAction)
595 action = Qt::LinkAction;
596 #if 0
597 else if(result == popupWallAction)
599 kDebug(1203) << "setWallpaper iconView=" << iconView << " url=" << lst.first().url();
600 if (iconView && iconView->isDesktop() ) iconView->setWallpaper(lst.first());
601 delete this;
602 return;
604 #endif
605 else if(result == popupCancelAction || !result)
607 delete this;
608 return;
612 KIO::Job * job = 0;
613 switch ( action ) {
614 case Qt::MoveAction :
615 job = KIO::move( lst, m_destUrl );
616 job->setMetaData( m_info->metaData );
617 setOperation( job, m_method == TRASH ? TRASH : MOVE, m_destUrl );
618 KonqFileUndoManager::self()->recordJob(
619 m_method == TRASH ? KonqFileUndoManager::TRASH : KonqFileUndoManager::MOVE,
620 lst, m_destUrl, job );
621 return; // we still have stuff to do -> don't delete ourselves
622 case Qt::CopyAction :
623 job = KIO::copy( lst, m_destUrl );
624 job->setMetaData( m_info->metaData );
625 setOperation( job, COPY, m_destUrl );
626 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::COPY, lst, m_destUrl, job );
627 return;
628 case Qt::LinkAction :
629 kDebug(1203) << "KonqOperations::asyncDrop lst.count=" << lst.count();
630 job = KIO::link( lst, m_destUrl );
631 job->setMetaData( m_info->metaData );
632 setOperation( job, LINK, m_destUrl );
633 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::LINK, lst, m_destUrl, job );
634 return;
635 default : kError(1203) << "Unknown action " << (int)action << endl;
637 delete this;
640 void KonqOperations::rename( QWidget * parent, const KUrl & oldurl, const KUrl& newurl )
642 kDebug(1203) << "KonqOperations::rename oldurl=" << oldurl << " newurl=" << newurl;
643 if ( oldurl == newurl )
644 return;
646 KUrl::List lst;
647 lst.append(oldurl);
648 KIO::Job * job = KIO::moveAs( oldurl, newurl, oldurl.isLocalFile() ? KIO::HideProgressInfo : KIO::DefaultFlags );
649 KonqOperations * op = new KonqOperations( parent );
650 op->setOperation( job, MOVE, newurl );
651 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::RENAME, lst, newurl, job );
652 // if moving the desktop then update config file and emit
653 if ( oldurl.isLocalFile() && oldurl.path( KUrl::AddTrailingSlash ) == KGlobalSettings::desktopPath() )
655 kDebug(1203) << "That rename was the Desktop path, updating config files";
656 KSharedConfig::Ptr globalConfig = KGlobal::config();
657 KConfigGroup cgs( globalConfig, "Paths" );
658 cgs.writePathEntry("Desktop" , newurl.path(), KConfigBase::Persistent|KConfigBase::Global );
659 cgs.sync();
660 KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_PATHS);
664 void KonqOperations::setOperation( KIO::Job * job, Operation method, const KUrl & dest )
666 m_method = method;
667 m_destUrl = dest;
668 if ( job )
670 job->ui()->setWindow(parentWidget());
671 connect( job, SIGNAL( result( KJob * ) ),
672 SLOT( slotResult( KJob * ) ) );
673 #if 0
674 KIO::CopyJob *copyJob = dynamic_cast<KIO::CopyJob*>(job);
675 KonqIconViewWidget *iconView = dynamic_cast<KonqIconViewWidget*>(parent());
676 if (copyJob && iconView)
678 connect(copyJob, SIGNAL(aboutToCreate(KIO::Job *,const QList<KIO::CopyInfo> &)),
679 this, SLOT(slotAboutToCreate(KIO::Job *,const QList<KIO::CopyInfo> &)));
680 // TODO move this connect into the iconview!
681 connect(this, SIGNAL(aboutToCreate(const QPoint &, const QList<KIO::CopyInfo> &)),
682 iconView, SLOT(slotAboutToCreate(const QPoint &, const QList<KIO::CopyInfo> &)));
684 #endif
686 else // for link
687 slotResult( 0L );
690 void KonqOperations::slotAboutToCreate(KIO::Job *, const QList<KIO::CopyInfo> &files)
692 emit aboutToCreate( m_info ? m_info->mousePos : m_pasteInfo ? m_pasteInfo->mousePos : QPoint(), files);
695 void KonqOperations::statUrl( const KUrl & url, const QObject *receiver, const char *member, QWidget* parent )
697 KonqOperations * op = new KonqOperations( parent );
698 op->m_method = STAT;
699 op->_statUrl( url, receiver, member );
702 void KonqOperations::_statUrl( const KUrl & url, const QObject *receiver, const char *member )
704 connect( this, SIGNAL( statFinished( const KFileItem & ) ), receiver, member );
705 KIO::StatJob * job = KIO::stat( url /*, KIO::HideProgressInfo?*/ );
706 job->ui()->setWindow(parentWidget());
707 connect( job, SIGNAL( result( KJob * ) ),
708 SLOT( slotStatResult( KJob * ) ) );
711 void KonqOperations::slotStatResult( KJob * job )
713 if ( job->error())
715 static_cast<KIO::Job*>( job )->ui()->showErrorMessage();
717 else
719 KIO::StatJob * statJob = static_cast<KIO::StatJob*>(job);
720 KFileItem item( statJob->statResult(), statJob->url() );
721 emit statFinished( item );
723 // If we're only here for a stat, we're done. But not if we used _statUrl internally
724 if ( m_method == STAT )
725 delete this;
728 void KonqOperations::slotResult( KJob * job )
730 if (job && job->error())
732 static_cast<KIO::Job*>( job )->ui()->showErrorMessage();
734 if ( m_method == EMPTYTRASH ) {
735 // Update konq windows opened on trash:/
736 org::kde::KDirNotify::emitFilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones...
738 delete this;
741 void KonqOperations::rename( QWidget * parent, const KUrl & oldurl, const QString & name )
743 KUrl newurl( oldurl );
744 newurl.setPath( oldurl.directory( KUrl::AppendTrailingSlash ) + name );
745 kDebug(1203) << "KonqOperations::rename("<<name<<") called. newurl=" << newurl;
746 rename( parent, oldurl, newurl );
749 KIO::SimpleJob* KonqOperations::newDir( QWidget * parent, const KUrl & baseUrl )
751 bool ok;
752 QString name = i18n( "New Folder" );
753 if ( baseUrl.isLocalFile() && QFileInfo( baseUrl.path( KUrl::AddTrailingSlash ) + name ).exists() )
754 name = KIO::RenameDialog::suggestName( baseUrl, i18n( "New Folder" ) );
756 name = KInputDialog::getText ( i18n( "New Folder" ),
757 i18n( "Enter folder name:" ), name, &ok, parent );
758 if ( ok && !name.isEmpty() )
760 KUrl url;
761 if ((name[0] == '/') || (name[0] == '~'))
763 url.setPath(KShell::tildeExpand(name));
765 else
767 name = KIO::encodeFileName( name );
768 url = baseUrl;
769 url.addPath( name );
771 return KonqOperations::mkdir( parent, url );
773 return 0;
776 ////
778 KonqMultiRestoreJob::KonqMultiRestoreJob( const KUrl::List& urls )
779 : KIO::Job(),
780 m_urls( urls ), m_urlsIterator( m_urls.begin() ),
781 m_progress( 0 )
783 QTimer::singleShot(0, this, SLOT(slotStart()));
784 setUiDelegate(new KIO::JobUiDelegate);
787 void KonqMultiRestoreJob::slotStart()
789 if ( m_urlsIterator == m_urls.begin() ) // first time: emit total
790 setTotalAmount( KJob::Files, m_urls.count() );
792 if ( m_urlsIterator != m_urls.end() )
794 const KUrl& url = *m_urlsIterator;
796 KUrl new_url = url;
797 if ( new_url.protocol()=="system"
798 && new_url.path().startsWith("/trash") )
800 QString path = new_url.path();
801 path.remove(0, 6);
802 new_url.setProtocol("trash");
803 new_url.setPath(path);
806 Q_ASSERT( new_url.protocol() == "trash" );
807 QByteArray packedArgs;
808 QDataStream stream( &packedArgs, QIODevice::WriteOnly );
809 stream << (int)3 << new_url;
810 KIO::Job* job = KIO::special( new_url, packedArgs, KIO::HideProgressInfo );
811 addSubjob( job );
812 setProcessedAmount(KJob::Files, processedAmount(KJob::Files) + 1);
814 else // done!
816 org::kde::KDirNotify::emitFilesRemoved(m_urls.toStringList() );
817 emitResult();
821 void KonqMultiRestoreJob::slotResult( KJob *job )
823 if ( job->error() )
825 KIO::Job::slotResult( job ); // will set the error and emit result(this)
826 return;
828 removeSubjob(job);
829 // Move on to next one
830 ++m_urlsIterator;
831 ++m_progress;
832 //emit processedSize( this, m_progress );
833 emitPercent( m_progress, m_urls.count() );
834 slotStart();
837 QWidget* KonqOperations::parentWidget() const
839 return static_cast<QWidget *>( parent() );
842 #include "konq_operations.moc"