]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Enable basic drag and drop support for the Places Panel
authorPeter Penz <peter.penz19@gmail.com>
Fri, 18 May 2012 21:21:49 +0000 (23:21 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Fri, 18 May 2012 21:31:44 +0000 (23:31 +0200)
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.

src/kitemviews/kfileitemlistview.cpp
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistview.cpp
src/kitemviews/kitemlistview.h
src/kitemviews/kitemlistwidget.cpp
src/kitemviews/kitemlistwidget.h
src/kitemviews/kitemmodelbase.h
src/kitemviews/kstandarditemlistwidget.cpp
src/kitemviews/kstandarditemlistwidget.h
src/panels/places/placesitemmodel.cpp
src/panels/places/placesitemmodel.h

index b5cc343f40d73a27ee45159f5c8d5564c0c8b03b..e52865aa62c54f7069b316703489bb05ee139d1e 100644 (file)
@@ -119,6 +119,9 @@ QPixmap KFileItemListView::createDragPixmap(const QSet<int>& 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.
index 6045f5020c1e147741554c6e7d00b2219efadf3a..b8d719d3bb82c81debb60e01a6b6de3798cb4510 100644 (file)
@@ -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);
 }
 
index 0f31cb5a1fb7e86453bb95f77e7238e0952fcc57..ebcf48680388b28512b304b31d2be84afc0d82a7 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <QCursor>
 #include <QGraphicsSceneMouseEvent>
+#include <QGraphicsView>
 #include <QPainter>
 #include <QPropertyAnimation>
 #include <QStyle>
@@ -566,8 +567,21 @@ KItemListHeader* KItemListView::header() const
 
 QPixmap KItemListView::createDragPixmap(const QSet<int>& 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)
index dd67b941bbdb027d999d675622759b5d76c16091..de2d2a6bb243c8d431ef1504dd257f6e69d7ab13 100644 (file)
@@ -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<int>& indexes) const;
 
index f304aa41ddfbb6e994f4a997515a452ce9f3d09a..45329afb335b555f62b69cb14469005421490076 100644 (file)
@@ -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<QByteArray, QVariant>& current,
                                   const QSet<QByteArray>& roles)
 {
index fdb07d62e6ddb2d90a6f7bbf950954e8612f42ac..55181faa863c993e9362a464c4ca93b1b2ef2dc4 100644 (file)
@@ -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);
index 52fcaee36dcb08cb811d713c4909bf6ad577d897..129524b31d42e44ed0153b5b65fc2cb2d602c1f5 100644 (file)
@@ -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<int>& indexes) const;
 
index 3f470b8cf5097944bc9ca8be34e5433c7a2f34c1..0cd11d3637199993b711ac562ce26f9d7b8db8d9 100644 (file)
@@ -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();
index d942b89a99852c732bac85142b0d1be15280c3fb..90a6f505562a7c744cda12acd69a083ad3bc5f46 100644 (file)
@@ -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();
 
index 14ec54be81f495ab80ba4974fbd2b4bc1c014215..68311bbabcda465e6a836eb1bcee4b1c53082dbb 100644 (file)
@@ -37,6 +37,7 @@
 #include "placesitem.h"
 #include <QAction>
 #include <QDate>
+#include <QMimeData>
 #include <QTimer>
 
 #include <Solid/Device>
@@ -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<int>& 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;
index 0f8f3025d8c1a12fe1b85f1616ec3cd6d8ec73de..7225c04f47b3e9d5e2a18e19f2c1eaa95e6c9acc 100644 (file)
@@ -105,6 +105,12 @@ public:
     void requestEject(int index);
     void requestTeardown(int index);
 
+    /** @reimp */
+    virtual QMimeData* createMimeData(const QSet<int>& 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