Fix Bug 233335 - Wrong icons selected after pasting files and renaming them (because there exists items with it's names

Fixed the "same" buggy behavior when dropping files/folders

Select also putted files (PUT operation - SimpleJob) - e.g. Paste content from clipboard

BUG: 233335
REVIEW: 107351
This commit is contained in:
Emmanuel Pescosta 2013-01-09 15:16:30 +01:00
parent 7745911c7b
commit fd65a97b07
10 changed files with 138 additions and 59 deletions

View file

@ -1276,7 +1276,8 @@ void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event)
const ViewTab& viewTab = m_viewTab[tab]; const ViewTab& viewTab = m_viewTab[tab];
const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view() const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view()
: viewTab.secondaryView->view(); : viewTab.secondaryView->view();
const QString error = DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event); QString error;
DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event, error);
if (!error.isEmpty()) { if (!error.isEmpty()) {
activeViewContainer()->showMessage(error, DolphinViewContainer::Error); activeViewContainer()->showMessage(error, DolphinViewContainer::Error);
} }

View file

@ -620,7 +620,8 @@ void DolphinViewContainer::slotUrlNavigatorLocationChanged(const KUrl& url)
void DolphinViewContainer::dropUrls(const KUrl& destination, QDropEvent* event) void DolphinViewContainer::dropUrls(const KUrl& destination, QDropEvent* event)
{ {
const QString error = DragAndDropHelper::dropUrls(KFileItem(), destination, event); QString error;
DragAndDropHelper::dropUrls(KFileItem(), destination, event, error);
if (!error.isEmpty()) { if (!error.isEmpty()) {
showMessage(error, Error); showMessage(error, Error);
} }

View file

@ -236,7 +236,8 @@ void FoldersPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* eve
event->buttons(), event->buttons(),
event->modifiers()); event->modifiers());
const QString error = DragAndDropHelper::dropUrls(destItem, destItem.url(), &dropEvent); QString error;
DragAndDropHelper::dropUrls(destItem, destItem.url(), &dropEvent, error);
if (!error.isEmpty()) { if (!error.isEmpty()) {
emit errorMessage(error); emit errorMessage(error);
} }

View file

@ -352,7 +352,11 @@ void PlacesPanel::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even
event->buttons(), event->buttons(),
event->modifiers()); event->modifiers());
DragAndDropHelper::dropUrls(KFileItem(), destUrl, &dropEvent); QString error;
DragAndDropHelper::dropUrls(KFileItem(), destUrl, &dropEvent, error);
if (!error.isEmpty()) {
emit errorMessage(error);
}
} }
void PlacesPanel::slotItemDropEventStorageSetupDone(int index, bool success) void PlacesPanel::slotItemDropEventStorageSetupDone(int index, bool success)
@ -364,7 +368,11 @@ void PlacesPanel::slotItemDropEventStorageSetupDone(int index, bool success)
if (success) { if (success) {
KUrl destUrl = m_model->placesItem(index)->url(); KUrl destUrl = m_model->placesItem(index)->url();
DragAndDropHelper::dropUrls(KFileItem(), destUrl, m_itemDropEvent); QString error;
DragAndDropHelper::dropUrls(KFileItem(), destUrl, m_itemDropEvent, error);
if (!error.isEmpty()) {
emit errorMessage(error);
}
} }
delete m_itemDropEventMimeData; delete m_itemDropEventMimeData;
@ -384,7 +392,8 @@ void PlacesPanel::slotAboveItemDropEvent(int index, QGraphicsSceneDragDropEvent*
void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent) void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
const QString error = DragAndDropHelper::dropUrls(KFileItem(), dest, event); QString error;
DragAndDropHelper::dropUrls(KFileItem(), dest, event, error);
if (!error.isEmpty()) { if (!error.isEmpty()) {
emit errorMessage(error); emit errorMessage(error);
} }

View file

@ -1023,14 +1023,16 @@ void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* even
event->buttons(), event->buttons(),
event->modifiers()); event->modifiers());
const QString error = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent); QString error;
KonqOperations* op = DragAndDropHelper::dropUrls(destItem, destUrl, &dropEvent, error);
if (!error.isEmpty()) { if (!error.isEmpty()) {
emit errorMessage(error); emit errorMessage(error);
} }
if (destUrl == url()) { if (op && destUrl == url()) {
// Mark the dropped urls as selected. // Mark the dropped urls as selected.
markPastedUrlsAsSelected(event->mimeData()); m_clearSelectionBeforeSelectingNewItems = true;
connect(op, SIGNAL(urlPasted(KUrl)), this, SLOT(slotUrlPasted(KUrl)));
} }
} }
@ -1066,6 +1068,11 @@ void DolphinView::slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons
} }
} }
void DolphinView::slotAboutToCreate(const KUrl::List& urls)
{
m_selectedUrls << urls;
}
void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous) void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
{ {
const int currentCount = current.count(); const int currentCount = current.count();
@ -1523,8 +1530,11 @@ void DolphinView::applyModeToView()
void DolphinView::pasteToUrl(const KUrl& url) void DolphinView::pasteToUrl(const KUrl& url)
{ {
markPastedUrlsAsSelected(QApplication::clipboard()->mimeData()); KonqOperations* op = KonqOperations::doPasteV2(this, url);
KonqOperations::doPaste(this, url); if (op) {
m_clearSelectionBeforeSelectingNewItems = true;
connect(op, SIGNAL(aboutToCreate(KUrl::List)), this, SLOT(slotAboutToCreate(KUrl::List)));
}
} }
KUrl::List DolphinView::simplifiedSelectedUrls() const KUrl::List DolphinView::simplifiedSelectedUrls() const
@ -1552,18 +1562,6 @@ QMimeData* DolphinView::selectionMimeData() const
return m_model->createMimeData(selectedIndexes); return m_model->createMimeData(selectedIndexes);
} }
void DolphinView::markPastedUrlsAsSelected(const QMimeData* mimeData)
{
const KUrl::List sourceUrls = KUrl::List::fromMimeData(mimeData);
KUrl::List destUrls;
foreach (const KUrl& source, sourceUrls) {
KUrl destination(url().url() + '/' + source.fileName());
destUrls << destination;
}
markUrlsAsSelected(destUrls);
m_clearSelectionBeforeSelectingNewItems = true;
}
void DolphinView::updateWritableState() void DolphinView::updateWritableState()
{ {
const bool wasFolderWritable = m_isFolderWritable; const bool wasFolderWritable = m_isFolderWritable;

View file

@ -566,6 +566,11 @@ private slots:
void slotModelChanged(KItemModelBase* current, KItemModelBase* previous); void slotModelChanged(KItemModelBase* current, KItemModelBase* previous);
void slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons); void slotMouseButtonPressed(int itemIndex, Qt::MouseButtons buttons);
/*
* Is called when new items get pasted or dropped.
*/
void slotAboutToCreate(const KUrl::List& urls);
/** /**
* Emits the signal \a selectionChanged() with a small delay. This is * Emits the signal \a selectionChanged() with a small delay. This is
* because getting all file items for the selection can be an expensive * because getting all file items for the selection can be an expensive
@ -721,14 +726,6 @@ private:
*/ */
QMimeData* selectionMimeData() const; QMimeData* selectionMimeData() const;
/**
* Is invoked after a paste operation or a drag & drop
* operation and URLs from \a mimeData as selected.
* This allows to select all newly pasted
* items in restoreViewState().
*/
void markPastedUrlsAsSelected(const QMimeData* mimeData);
/** /**
* Updates m_isFolderWritable dependent on whether the folder represented by * Updates m_isFolderWritable dependent on whether the folder represented by
* the current URL is writable. If the state has changed, the signal * the current URL is writable. If the state has changed, the signal

View file

@ -28,10 +28,13 @@
#include <QtDBus> #include <QtDBus>
#include <QDropEvent> #include <QDropEvent>
QString DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destUrl, QDropEvent* event) KonqOperations* DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destUrl, QDropEvent* event, QString& error)
{ {
error.clear();
if (!destItem.isNull() && !destItem.isWritable()) { if (!destItem.isNull() && !destItem.isWritable()) {
return i18nc("@info:status", "Access denied. Could not write to <filename>%1</filename>", destUrl.pathOrUrl()); error = i18nc("@info:status", "Access denied. Could not write to <filename>%1</filename>", destUrl.pathOrUrl());
return 0;
} }
const QMimeData* mimeData = event->mimeData(); const QMimeData* mimeData = event->mimeData();
@ -49,15 +52,16 @@ QString DragAndDropHelper::dropUrls(const KFileItem& destItem, const KUrl& destU
const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
foreach (const KUrl& url, urls) { foreach (const KUrl& url, urls) {
if (url == destUrl) { if (url == destUrl) {
return i18nc("@info:status", "A folder cannot be dropped into itself"); error = i18nc("@info:status", "A folder cannot be dropped into itself");
return 0;
} }
} }
KonqOperations::doDrop(destItem, destUrl, event, QApplication::activeWindow()); return KonqOperations::doDrop(destItem, destUrl, event, QApplication::activeWindow(), QList<QAction*>());
} else { } else {
KonqOperations::doDrop(KFileItem(), destUrl, event, QApplication::activeWindow()); return KonqOperations::doDrop(KFileItem(), destUrl, event, QApplication::activeWindow(), QList<QAction*>());
} }
return QString(); return 0;
} }

View file

@ -29,6 +29,7 @@ class KFileItem;
class KUrl; class KUrl;
class QDropEvent; class QDropEvent;
class QWidget; class QWidget;
class KonqOperations;
class LIBDOLPHINPRIVATE_EXPORT DragAndDropHelper class LIBDOLPHINPRIVATE_EXPORT DragAndDropHelper
{ {
@ -46,13 +47,15 @@ public:
* @param destUrl URL of the item destination. Is used only if destItem::isNull() * @param destUrl URL of the item destination. Is used only if destItem::isNull()
* is true. * is true.
* @param event Drop event. * @param event Drop event.
* @return Error message intended to be shown for users if dropping is not * @param error Error message intended to be shown for users if dropping is not
* possible. If an empty string is returned, the dropping has been * possible. If an empty string is returned, the dropping has been
* successful. * successful.
* @return KonqOperations pointer
*/ */
static QString dropUrls(const KFileItem& destItem, static KonqOperations* dropUrls(const KFileItem& destItem,
const KUrl& destUrl, const KUrl& destUrl,
QDropEvent* event); QDropEvent* event,
QString& error);
}; };
#endif #endif

View file

@ -133,25 +133,37 @@ KIO::SimpleJob* KonqOperations::mkdir( QWidget *parent, const KUrl & url )
void KonqOperations::doPaste( QWidget * parent, const KUrl & destUrl, const QPoint &pos ) void KonqOperations::doPaste( QWidget * parent, const KUrl & destUrl, const QPoint &pos )
{ {
QClipboard* clipboard = QApplication::clipboard(); (void) KonqOperations::doPasteV2( parent, destUrl, pos );
}
KonqOperations *KonqOperations::doPasteV2(QWidget *parent, const KUrl &destUrl, const QPoint &pos)
{
QClipboard *clipboard = QApplication::clipboard();
const QMimeData *data = clipboard->mimeData(); const QMimeData *data = clipboard->mimeData();
const bool move = KonqMimeData::decodeIsCutSelection(data); const bool move = KonqMimeData::decodeIsCutSelection(data);
KIO::Job *job = KIO::pasteClipboard( destUrl, parent, move ); KIO::Job *job = KIO::pasteClipboard(destUrl, parent, move);
if (job) { if (job) {
KonqOperations * op = new KonqOperations( parent ); KonqOperations *op = new KonqOperations(parent);
KIOPasteInfo * pi = new KIOPasteInfo; KIOPasteInfo *pi = new KIOPasteInfo;
pi->mousePos = pos; pi->mousePos = pos;
op->setPasteInfo( pi ); op->setPasteInfo(pi);
KIO::CopyJob * copyJob = qobject_cast<KIO::CopyJob *>(job); KIO::CopyJob *copyJob = qobject_cast<KIO::CopyJob*>(job);
if (copyJob) { if (copyJob) {
op->setOperation( job, move ? MOVE : COPY, copyJob->destUrl() ); op->setOperation(job, move ? MOVE : COPY, copyJob->destUrl());
KIO::FileUndoManager::self()->recordJob( move ? KIO::FileUndoManager::Move : KIO::FileUndoManager::Copy, KUrl::List(), destUrl, job ); KIO::FileUndoManager::self()->recordJob(move ? KIO::FileUndoManager::Move : KIO::FileUndoManager::Copy, KUrl::List(), destUrl, job);
} else if (KIO::SimpleJob* simpleJob = qobject_cast<KIO::SimpleJob *>(job)) { connect(copyJob, SIGNAL(copyingDone(KIO::Job*,KUrl,KUrl,time_t,bool,bool)),
op, SLOT(slotCopyingDone(KIO::Job*,KUrl,KUrl)));
connect(copyJob, SIGNAL(copyingLinkDone(KIO::Job*,KUrl,QString,KUrl)),
op, SLOT(slotCopyingLinkDone(KIO::Job*,KUrl,QString,KUrl)));
} else if (KIO::SimpleJob *simpleJob = qobject_cast<KIO::SimpleJob*>(job)) {
op->setOperation(job, PUT, simpleJob->url()); op->setOperation(job, PUT, simpleJob->url());
KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Put, KUrl::List(), simpleJob->url(), job); KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Put, KUrl::List(), simpleJob->url(), job);
} }
return op;
} }
return 0;
} }
void KonqOperations::copy( QWidget * parent, Operation method, const KUrl::List & selectedUrls, const KUrl& destUrl ) void KonqOperations::copy( QWidget * parent, Operation method, const KUrl::List & selectedUrls, const KUrl& destUrl )
@ -177,6 +189,11 @@ void KonqOperations::copy( QWidget * parent, Operation method, const KUrl::List
else else
job = KIO::copy( selectedUrls, destUrl ); job = KIO::copy( selectedUrls, destUrl );
connect(job, SIGNAL(copyingDone(KIO::Job*,KUrl,KUrl,time_t,bool,bool)),
op, SLOT(slotCopyingDone(KIO::Job*,KUrl,KUrl)));
connect(job, SIGNAL(copyingLinkDone(KIO::Job*,KUrl,QString,KUrl)),
op, SLOT(slotCopyingLinkDone(KIO::Job*,KUrl,QString,KUrl)));
op->setOperation( job, method, destUrl ); op->setOperation( job, method, destUrl );
KIO::FileUndoManager::self()->recordCopyJob(job); KIO::FileUndoManager::self()->recordCopyJob(job);
@ -635,25 +652,42 @@ void KonqOperations::doDropFileCopy()
KIO::FileUndoManager::self()->recordJob( KIO::FileUndoManager::self()->recordJob(
m_method == TRASH ? KIO::FileUndoManager::Trash : KIO::FileUndoManager::Move, m_method == TRASH ? KIO::FileUndoManager::Trash : KIO::FileUndoManager::Move,
lst, m_destUrl, job ); lst, m_destUrl, job );
return; // we still have stuff to do -> don't delete ourselves break;
case Qt::CopyAction : case Qt::CopyAction :
job = KIO::copy( lst, m_destUrl ); job = KIO::copy( lst, m_destUrl );
job->setMetaData( m_info->metaData ); job->setMetaData( m_info->metaData );
setOperation( job, COPY, m_destUrl ); setOperation( job, COPY, m_destUrl );
KIO::FileUndoManager::self()->recordCopyJob(job); KIO::FileUndoManager::self()->recordCopyJob(job);
return; break;
case Qt::LinkAction : case Qt::LinkAction :
kDebug(1203) << "lst.count=" << lst.count(); kDebug(1203) << "lst.count=" << lst.count();
job = KIO::link( lst, m_destUrl ); job = KIO::link( lst, m_destUrl );
job->setMetaData( m_info->metaData ); job->setMetaData( m_info->metaData );
setOperation( job, LINK, m_destUrl ); setOperation( job, LINK, m_destUrl );
KIO::FileUndoManager::self()->recordCopyJob(job); KIO::FileUndoManager::self()->recordCopyJob(job);
return; break;
default : kError(1203) << "Unknown action " << (int)action << endl; default : kError(1203) << "Unknown action " << (int)action << endl;
} }
if (job) {
connect(job, SIGNAL(copyingDone(KIO::Job*,KUrl,KUrl,time_t,bool,bool)),
this, SLOT(slotCopyingDone(KIO::Job*,KUrl,KUrl)));
connect(job, SIGNAL(copyingLinkDone(KIO::Job*,KUrl,QString,KUrl)),
this, SLOT(slotCopyingLinkDone(KIO::Job*,KUrl,QString,KUrl)));
return; // we still have stuff to do -> don't delete ourselves
}
deleteLater(); deleteLater();
} }
void KonqOperations::slotCopyingDone( KIO::Job*, const KUrl&, const KUrl &to)
{
m_createdUrls << to;
}
void KonqOperations::slotCopyingLinkDone(KIO::Job*, const KUrl&, const QString&, const KUrl &to)
{
m_createdUrls << to;
}
void KonqOperations::_addPluginActions(QList<QAction*>& pluginActions,const KUrl& destination, const KFileItemListProperties& info) void KonqOperations::_addPluginActions(QList<QAction*>& pluginActions,const KUrl& destination, const KFileItemListProperties& info)
{ {
kDebug(1203); kDebug(1203);
@ -803,16 +837,33 @@ void KonqOperations::slotStatResult( KJob * job )
deleteLater(); deleteLater();
} }
void KonqOperations::slotResult( KJob * job ) void KonqOperations::slotResult(KJob *job)
{ {
if (job && job->error()) if (job && job->error()) {
{ static_cast<KIO::Job*>(job)->ui()->showErrorMessage();
static_cast<KIO::Job*>( job )->ui()->showErrorMessage(); job = 0; // The job failed, so set it to 0. All further job related codepaths become disabled
} }
if ( m_method == EMPTYTRASH ) {
switch (m_method) {
case PUT: {
KIO::SimpleJob *simpleJob = qobject_cast<KIO::SimpleJob*>(job);
if (simpleJob) {
m_createdUrls << simpleJob->url();
}
}
break;
case EMPTYTRASH:
// Update konq windows opened on trash:/ // Update konq windows opened on trash:/
org::kde::KDirNotify::emitFilesAdded( "trash:/" ); // yeah, files were removed, but we don't know which ones... org::kde::KDirNotify::emitFilesAdded("trash:/"); // yeah, files were removed, but we don't know which ones...
break;
} }
if (!m_createdUrls.isEmpty()) {
// Inform the application about all created urls
emit aboutToCreate(m_createdUrls);
m_createdUrls.clear();
}
deleteLater(); deleteLater();
} }

View file

@ -118,6 +118,16 @@ public:
*/ */
static void doPaste( QWidget * parent, const KUrl & destUrl, const QPoint &pos = QPoint() ); static void doPaste( QWidget * parent, const KUrl & destUrl, const QPoint &pos = QPoint() );
/**
* Paste the clipboard contents
*
* @return The KonqOperations object
* @since 4.10
*
* @todo TODO KDE 5,0 - Merge doPaste and doPasteV2
*/
static KonqOperations *doPasteV2(QWidget * parent, const KUrl & destUrl, const QPoint &pos = QPoint());
/** /**
* Returns the state of the paste action: * Returns the state of the paste action:
* first is whether the action should be enabled * first is whether the action should be enabled
@ -218,6 +228,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void statFinished( const KFileItem & item ); void statFinished( const KFileItem & item );
void aboutToCreate(const QPoint &pos, const QList<KIO::CopyInfo> &files); void aboutToCreate(const QPoint &pos, const QList<KIO::CopyInfo> &files);
void aboutToCreate(const KUrl::List &urls);
private: private:
QWidget* parentWidget() const; QWidget* parentWidget() const;
@ -259,10 +270,13 @@ protected Q_SLOTS:
void slotStatResult( KJob * job ); void slotStatResult( KJob * job );
void asyncDrop( const KFileItem & item ); void asyncDrop( const KFileItem & item );
void doDropFileCopy(); void doDropFileCopy();
void slotCopyingDone(KIO::Job *job, const KUrl &from, const KUrl &to);
void slotCopyingLinkDone(KIO::Job *job, const KUrl &from, const QString &target, const KUrl &to);
private: private:
Operation m_method; Operation m_method;
//KUrl::List m_srcUrls; //KUrl::List m_srcUrls;
KUrl::List m_createdUrls;
KUrl m_destUrl; KUrl m_destUrl;
// for doDrop // for doDrop
DropInfo * m_info; DropInfo * m_info;