From: Peter Penz Date: Fri, 18 May 2012 21:21:49 +0000 (+0200) Subject: Enable basic drag and drop support for the Places Panel X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/e9d29bcf30ccbd7c76ba37ce9efcfac1649fc46e?ds=sidebyside Enable basic drag and drop support for the Places Panel The dropping has not been implemented yet, however in the context of this step the creating of the drag-pixmap is now forwarded to the item-widgets. This allows creating some optimized dragging-pixmaps e.g. for the details-view, where only the name and icon should be provided as drag-pixmap. --- diff --git a/src/kitemviews/kfileitemlistview.cpp b/src/kitemviews/kfileitemlistview.cpp index b5cc343f4..e52865aa6 100644 --- a/src/kitemviews/kfileitemlistview.cpp +++ b/src/kitemviews/kfileitemlistview.cpp @@ -119,6 +119,9 @@ QPixmap KFileItemListView::createDragPixmap(const QSet& indexes) const const int itemCount = indexes.count(); Q_ASSERT(itemCount > 0); + if (itemCount == 1) { + return KItemListView::createDragPixmap(indexes); + } // If more than one item is dragged, align the items inside a // rectangular grid. The maximum grid size is limited to 5 x 5 items. diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 6045f5020..b8d719d3b 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -1063,6 +1063,11 @@ void KItemListController::startDragging() const QPixmap pixmap = m_view->createDragPixmap(selectedItems); drag->setPixmap(pixmap); + // TODO: The vertical hotspot of -24 should be replaced by the + // height of the QCursor-pixmap. + const QPoint hotSpot(pixmap.width() / 2, -24); + drag->setHotSpot(hotSpot); + drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::CopyAction); } diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 0f31cb5a1..ebcf48680 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -566,8 +567,21 @@ KItemListHeader* KItemListView::header() const QPixmap KItemListView::createDragPixmap(const QSet& indexes) const { - Q_UNUSED(indexes); - return QPixmap(); + QPixmap pixmap; + + if (indexes.count() == 1) { + KItemListWidget* item = m_visibleItems.value(indexes.toList().first()); + QGraphicsView* graphicsView = scene()->views()[0]; + if (item && graphicsView) { + pixmap = item->createDragPixmap(0, graphicsView); + } + } else { + // TODO: Not implemented yet. Probably extend the interface + // from KItemListWidget::createDragPixmap() to return a pixmap + // that can be used for multiple indexes. + } + + return pixmap; } void KItemListView::editRole(int index, const QByteArray& role) diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index dd67b941b..de2d2a6bb 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -257,8 +257,7 @@ public: /** * @return Pixmap that is used for a drag operation based on the - * items given by \a indexes. The default implementation returns - * a null-pixmap. + * items given by \a indexes. */ virtual QPixmap createDragPixmap(const QSet& indexes) const; diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index f304aa41d..45329afb3 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -360,6 +360,22 @@ QRectF KItemListWidget::expansionToggleRect() const return QRectF(); } +QPixmap KItemListWidget::createDragPixmap(const QStyleOptionGraphicsItem* option, + QWidget* widget) +{ + QPixmap pixmap(size().toSize()); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + + const bool oldAlternateBackground = m_alternateBackground; + setAlternateBackground(false); + paint(&painter, option, widget); + setAlternateBackground(oldAlternateBackground); + + return pixmap; +} + void KItemListWidget::dataChanged(const QHash& current, const QSet& roles) { diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h index fdb07d62e..55181faa8 100644 --- a/src/kitemviews/kitemlistwidget.h +++ b/src/kitemviews/kitemlistwidget.h @@ -175,6 +175,12 @@ public: */ virtual QRectF expansionToggleRect() const; + /** + * @return Pixmap that is used when dragging an item. Per default the current state of the + * widget is returned as pixmap. + */ + virtual QPixmap createDragPixmap(const QStyleOptionGraphicsItem* option, QWidget* widget = 0); + signals: void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); diff --git a/src/kitemviews/kitemmodelbase.h b/src/kitemviews/kitemmodelbase.h index 52fcaee36..129524b31 100644 --- a/src/kitemviews/kitemmodelbase.h +++ b/src/kitemviews/kitemmodelbase.h @@ -154,7 +154,8 @@ public: /** * @return MIME-data for the items given by \a indexes. The default implementation * returns 0. The ownership of the returned instance is in the hand of the - * caller of this method. + * caller of this method. The method must be implemented if dragging of + * items should be possible. */ virtual QMimeData* createMimeData(const QSet& indexes) const; diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 3f470b8cf..0cd11d363 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -405,6 +405,32 @@ QRectF KStandardItemListWidget::selectionToggleRect() const return QRectF(pos, QSizeF(toggleSize, toggleSize)); } +QPixmap KStandardItemListWidget::createDragPixmap(const QStyleOptionGraphicsItem* option, + QWidget* widget) +{ + QPixmap pixmap = KItemListWidget::createDragPixmap(option, widget); + if (m_layout != DetailsLayout || styleOption().extendedSelectionRegion) { + return pixmap; + } + + // Only return the content of the text-column as pixmap + const int leftClip = m_pixmapPos.x(); + + const TextInfo* textInfo = m_textInfo.value("text"); + const int rightClip = textInfo->pos.x() + + textInfo->staticText.size().width() + + 2 * styleOption().padding; + + QPixmap clippedPixmap(rightClip - leftClip + 1, pixmap.height()); + clippedPixmap.fill(Qt::transparent); + + QPainter painter(&clippedPixmap); + painter.drawPixmap(-leftClip, 0, pixmap); + + return clippedPixmap; +} + + KItemListWidgetInformant* KStandardItemListWidget::createInformant() { return new KStandardItemListWidgetInformant(); diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h index d942b89a9..90a6f5055 100644 --- a/src/kitemviews/kstandarditemlistwidget.h +++ b/src/kitemviews/kstandarditemlistwidget.h @@ -86,6 +86,7 @@ public: virtual QRectF textFocusRect() const; virtual QRectF expansionToggleRect() const; virtual QRectF selectionToggleRect() const; + virtual QPixmap createDragPixmap(const QStyleOptionGraphicsItem* option, QWidget* widget = 0); static KItemListWidgetInformant* createInformant(); diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 14ec54be8..68311bbab 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -37,6 +37,7 @@ #include "placesitem.h" #include #include +#include #include #include @@ -291,7 +292,9 @@ void PlacesItemModel::requestEject(int index) this, SLOT(slotStorageTeardownDone(Solid::ErrorType,QVariant))); drive->eject(); } else { - + const QString label = item->text(); + const QString message = i18nc("@info", "The device '%1' is not a disk and cannot be ejected.", label); + emit errorMessage(message); } } } @@ -305,14 +308,43 @@ void PlacesItemModel::requestTeardown(int index) connect(access, SIGNAL(teardownDone(Solid::ErrorType,QVariant,QString)), this, SLOT(slotStorageTeardownDone(Solid::ErrorType,QVariant))); access->teardown(); - } else { - const QString label = item->text(); - const QString message = i18nc("@info", "The device '%1' is not a disk and cannot be ejected.", label); - emit errorMessage(message); } } } +QMimeData* PlacesItemModel::createMimeData(const QSet& indexes) const +{ + KUrl::List urls; + QByteArray itemData; + + QDataStream stream(&itemData, QIODevice::WriteOnly); + + foreach (int index, indexes) { + const KUrl itemUrl = placesItem(index)->url(); + if (itemUrl.isValid()) { + urls << itemUrl; + } + stream << index; + } + + QMimeData* mimeData = new QMimeData(); + if (!urls.isEmpty()) { + urls.populateMimeData(mimeData); + } + + const QString internalMimeType = "application/x-dolphinplacesmodel-" + + QString::number((qptrdiff)this); + mimeData->setData(internalMimeType, itemData); + + return mimeData; +} + +bool PlacesItemModel::supportsDropping(int index) const +{ + Q_UNUSED(index); + return true; +} + KUrl PlacesItemModel::convertedUrl(const KUrl& url) { KUrl newUrl = url; diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h index 0f8f3025d..7225c04f4 100644 --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -105,6 +105,12 @@ public: void requestEject(int index); void requestTeardown(int index); + /** @reimp */ + virtual QMimeData* createMimeData(const QSet& indexes) const; + + /** @reimp */ + virtual bool supportsDropping(int index) const; + /** * @return Converts the URL, which contains "virtual" URLs for system-items like * "search:/documents" into a Nepomuk-Query-URL that will be handled by