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>
33 #include <kmessagebox.h>
34 #include <knotification.h>
38 #include <kshortcut.h>
39 #include <kprotocolmanager.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>
50 #include <kauthorized.h>
52 #include <kglobalsettings.h>
54 #include <kfileitem.h>
55 #include <kdesktopfile.h>
58 //#include <konq_iconviewwidget.h>
59 #include <QtDBus/QtDBus>
61 #include <QApplication>
69 #include <kconfiggroup.h>
71 KonqOperations::KonqOperations( QWidget
*parent
)
73 m_method( UNKNOWN
), m_info(0), m_pasteInfo(0)
75 setObjectName( "KonqOperations" );
78 KonqOperations::~KonqOperations()
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 !" ;
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
);
128 void KonqOperations::doPaste( QWidget
* parent
, const KUrl
& destUrl
, const QPoint
&pos
)
130 // move or not move ?
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
);
141 KonqOperations
* op
= new KonqOperations( parent
);
142 KIO::CopyJob
* copyJob
= static_cast<KIO::CopyJob
*>(job
);
143 KIOPasteInfo
* pi
= new KIOPasteInfo
;
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 !" ;
159 if ( selectedUrls
.isEmpty() )
161 kWarning(1203) << "Empty URL list !" ;
165 KonqOperations
* op
= new KonqOperations( parent
);
168 job
= KIO::link( selectedUrls
, destUrl
);
169 else if (method
== MOVE
)
170 job
= KIO::move( selectedUrls
, destUrl
);
172 job
= KIO::copy( selectedUrls
, destUrl
);
174 op
->setOperation( job
, method
, destUrl
);
177 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::COPY
, selectedUrls
, destUrl
, job
);
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()) {
193 if ( askDeleteConfirmation( selectedUrls
, method
, confirmation
, parentWidget() ) )
195 //m_srcUrls = selectedUrls;
202 job
= KIO::trash( selectedUrls
);
203 KonqFileUndoManager::self()->recordJob( KonqFileUndoManager::TRASH
, selectedUrls
, KUrl("trash:/"), job
);
208 // Same as in ktrash --empty
209 QByteArray packedArgs
;
210 QDataStream
stream( &packedArgs
, QIODevice::WriteOnly
);
212 job
= KIO::special( KUrl("trash:/"), packedArgs
);
213 KNotification::event("Trash: emptied", QString() , QPixmap() , 0l, KNotification::DefaultEvent
);
217 job
= KIO::del( selectedUrls
);
220 kWarning() << "Unknown operation: " << method
;
224 job
->ui()->setWindow(parentWidget());
225 connect( job
, SIGNAL( result( KJob
* ) ),
226 SLOT( slotResult( KJob
* ) ) );
231 void KonqOperations::_restoreTrashedItems( const KUrl::List
& urls
)
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
)
246 bool ask
= ( confirmation
== FORCE_CONFIRMATION
);
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
);
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]*-")) );
265 prettyList
.append( (*it
).pathOrUrl() );
272 result
= KMessageBox::warningContinueCancelList(
274 i18np( "Do you really want to delete this item?", "Do you really want to delete these %1 items?", prettyList
.count()),
276 i18n( "Delete Files" ),
277 KStandardGuiItem::del(),
278 KStandardGuiItem::cancel(),
279 keyName
, KMessageBox::Notify
| KMessageBox::Dangerous
);
284 result
= KMessageBox::warningContinueCancelList(
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()),
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);
302 KConfig
konq_config("konquerorrc", KConfig::NoGlobals
);
303 konq_config
.group("Trash").writeEntry( keyName
, false );
306 return (result
== KMessageBox::Continue
);
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
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();
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:" ),
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() )
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
;
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() )
415 const QStringList urlStrList
= m_info
->urls
.toStringList();
416 if ( KToolInvocation::startServiceByDesktopPath( m_destUrl
.path(), urlStrList
, &error
) > 0 )
417 KMessageBox::error( parentWidget(), error
);
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 ?
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() ) );
442 else if ( desktopFile
.hasLinkType() && desktopGroup
.hasKey("URL") ) {
443 m_destUrl
= desktopGroup
.readPathEntry("URL", QString());
447 // else, well: mimetype, service, servicetype or .directory. Can't really drop anything on those.
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
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
);
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() ))
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()) )
497 if ( !mlst
.isEmpty() && m_destUrl
.protocol() == "trash" )
499 if ( itemIsOnDesktop
&& !KAuthorized::authorizeKAction("editable_desktop_icons") )
506 if ( askDeleteConfirmation( mlst
, TRASH
, DEFAULT_CONFIRMATION
, parentWidget() ) )
507 action
= Qt::MoveAction
;
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
;
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...
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;
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
);
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();
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();
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
);
582 popup
.addAction(popupWallAction
);
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
;
597 else if(result
== popupWallAction
)
599 kDebug(1203) << "setWallpaper iconView=" << iconView
<< " url=" << lst
.first().url();
600 if (iconView
&& iconView
->isDesktop() ) iconView
->setWallpaper(lst
.first());
605 else if(result
== popupCancelAction
|| !result
)
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
);
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
);
635 default : kError(1203) << "Unknown action " << (int)action
<< endl
;
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
)
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
);
660 KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged
, KGlobalSettings::SETTINGS_PATHS
);
664 void KonqOperations::setOperation( KIO::Job
* job
, Operation method
, const KUrl
& dest
)
670 job
->ui()->setWindow(parentWidget());
671 connect( job
, SIGNAL( result( KJob
* ) ),
672 SLOT( slotResult( KJob
* ) ) );
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
> &)));
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
);
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
)
715 static_cast<KIO::Job
*>( job
)->ui()->showErrorMessage();
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
)
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...
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
)
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() )
761 if ((name
[0] == '/') || (name
[0] == '~'))
763 url
.setPath(KShell::tildeExpand(name
));
767 name
= KIO::encodeFileName( name
);
771 return KonqOperations::mkdir( parent
, url
);
778 KonqMultiRestoreJob::KonqMultiRestoreJob( const KUrl::List
& urls
)
780 m_urls( urls
), m_urlsIterator( m_urls
.begin() ),
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
;
797 if ( new_url
.protocol()=="system"
798 && new_url
.path().startsWith("/trash") )
800 QString path
= new_url
.path();
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
);
812 setProcessedAmount(KJob::Files
, processedAmount(KJob::Files
) + 1);
816 org::kde::KDirNotify::emitFilesRemoved(m_urls
.toStringList() );
821 void KonqMultiRestoreJob::slotResult( KJob
*job
)
825 KIO::Job::slotResult( job
); // will set the error and emit result(this)
829 // Move on to next one
832 //emit processedSize( this, m_progress );
833 emitPercent( m_progress
, m_urls
.count() );
837 QWidget
* KonqOperations::parentWidget() const
839 return static_cast<QWidget
*>( parent() );
842 #include "konq_operations.moc"