diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -73,7 +73,7 @@ * the root-parent of all items. * @see rootItem() */ - QUrl directory() const; + QUrl directory() const Q_DECL_OVERRIDE; /** * Cancels the loading of a directory which has been started by either @@ -145,6 +145,8 @@ */ KFileItem rootItem() const; + QUrl indexGetUrl(int index) const Q_DECL_OVERRIDE; + /** * Clears all items of the model. */ diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -2381,3 +2381,8 @@ return true; } + +QUrl KFileItemModel::indexGetUrl(int index) const +{ + return fileItem(index).url(); +} diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h --- a/src/kitemviews/kitemlistcontroller.h +++ b/src/kitemviews/kitemlistcontroller.h @@ -257,6 +257,11 @@ void startDragging(); /** + * @return True, if destUrl is contained in the url list. + */ + bool urlListMatchesUrl(const QList& urls, const QUrl& destUrl); + + /** * @return Widget that is currently in the hovered state. 0 is returned * if no widget is marked as hovered. */ diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -882,6 +882,10 @@ if (!droppingBetweenItems) { if (m_model->supportsDropping(index)) { // Something has been dragged on an item. + + // check if the we're dragging the same item onto itself. + event->setAccepted(!urlListMatchesUrl(event->mimeData()->urls(), m_model->indexGetUrl(index))); + m_view->hideDropIndicator(); if (!newHoveredWidget->isHovered()) { newHoveredWidget->setHovered(true); @@ -901,6 +905,9 @@ } } } else { + // We're hovering over the directory, check if we're dropping onto itself. + event->setAccepted(!urlListMatchesUrl(event->mimeData()->urls(), m_model->directory())); + m_view->hideDropIndicator(); } @@ -1326,3 +1333,13 @@ } } +bool KItemListController::urlListMatchesUrl(const QList& urls, const QUrl& destUrl) +{ + foreach(QUrl url, urls) { + if (url.matches(destUrl, QUrl::StripTrailingSlash)) { + return true; + } + } + + return false; +} diff --git a/src/kitemviews/kitemmodelbase.h b/src/kitemviews/kitemmodelbase.h --- a/src/kitemviews/kitemmodelbase.h +++ b/src/kitemviews/kitemmodelbase.h @@ -182,6 +182,16 @@ */ QString blacklistItemDropEventMimeType() const; + /** + * @return URL of the item at the specified index + */ + virtual QUrl indexGetUrl(int index) const; + + /** + * @return Parent directory of the items that are shown + */ + virtual QUrl directory() const; + signals: /** * Is emitted if one or more items have been inserted. Each item-range consists diff --git a/src/kitemviews/kitemmodelbase.cpp b/src/kitemviews/kitemmodelbase.cpp --- a/src/kitemviews/kitemmodelbase.cpp +++ b/src/kitemviews/kitemmodelbase.cpp @@ -164,3 +164,13 @@ Q_UNUSED(previous); } +QUrl KItemModelBase::indexGetUrl(int index) const +{ + Q_UNUSED(index); + return QUrl(); +} + +QUrl KItemModelBase::directory() const +{ + return QUrl(); +} diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -130,6 +130,8 @@ */ void saveBookmarks(); + virtual QUrl indexGetUrl(int index) const Q_DECL_OVERRIDE; + signals: void errorMessage(const QString& message); void storageSetupDone(int index, bool success); diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -1135,6 +1135,17 @@ return date; } +QUrl PlacesItemModel::indexGetUrl(int index) const +{ + const PlacesItem* item = placesItem(index); + + if (item) { + return item->url(); + } + + return KItemModelBase::indexGetUrl(index); +} + QUrl PlacesItemModel::createSearchUrl(const QUrl& url) { QUrl searchUrl;