]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Improved drag and drop support
authorPeter Penz <peter.penz19@gmail.com>
Sun, 4 Sep 2011 15:40:44 +0000 (17:40 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Sun, 4 Sep 2011 15:41:15 +0000 (17:41 +0200)
src/CMakeLists.txt
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemlistcontroller.h
src/kitemviews/kitemmodelbase.cpp
src/kitemviews/kitemmodelbase.h
src/views/dolphinview.cpp
src/views/dolphinview.h
src/views/draganddrophelper.cpp
src/views/draganddrophelper.h

index 7826ee00fa5f460e403f6627b59a0906b2538d4c..62d59d99006d0db071f3991a02fcf0fca57029e1 100644 (file)
@@ -49,6 +49,7 @@ set(dolphinprivate_LIB_SRCS
     views/dolphinremoteencoding.cpp
     views/dolphinviewactionhandler.cpp
     views/dolphinviewautoscroller.cpp
+    views/draganddrophelper.cpp
     views/folderexpander.cpp
     views/renamedialog.cpp
     views/tooltips/filemetadatatooltip.cpp
index 33dc9979b6f7667dacfcb4a2d6b7599e988165ae..401ba218d1e1b323bb64e412e7a3c226d9abd161 100644 (file)
@@ -123,24 +123,6 @@ bool KFileItemModel::setData(int index, const QHash<QByteArray, QVariant>& value
     return false;
 }
 
-int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
-{
-    startFromIndex = qMax(0, startFromIndex);
-    for (int i = startFromIndex; i < count(); i++) {
-        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
-            kDebug() << data(i)["name"].toString();
-            return i;
-        }
-    }
-    for (int i = 0; i < startFromIndex; i++) {
-        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
-            kDebug() << data(i)["name"].toString();
-            return i;
-        }
-    }
-    return -1;
-}
-
 bool KFileItemModel::supportsGrouping() const
 {
     return true;
@@ -189,6 +171,30 @@ QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
     return data;
 }
 
+int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
+{
+    startFromIndex = qMax(0, startFromIndex);
+    for (int i = startFromIndex; i < count(); i++) {
+        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+            kDebug() << data(i)["name"].toString();
+            return i;
+        }
+    }
+    for (int i = 0; i < startFromIndex; i++) {
+        if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
+            kDebug() << data(i)["name"].toString();
+            return i;
+        }
+    }
+    return -1;
+}
+
+bool KFileItemModel::supportsDropping(int index) const
+{
+    const KFileItem item = fileItem(index);
+    return item.isNull() ? false : item.isDir();
+}
+
 KFileItem KFileItemModel::fileItem(int index) const
 {
     if (index >= 0 && index < count()) {
index 839d4e724930afa7c9fcdbc4dbae60a2587bad5a..c70892dd3d150a2f85462e819568b0fb68f96cef 100644 (file)
@@ -54,10 +54,6 @@ public:
     virtual QHash<QByteArray, QVariant> data(int index) const;
     virtual bool setData(int index, const QHash<QByteArray, QVariant> &values);
 
-    /**
-     * @reimp
-     */
-    virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
     /**
      * @return True
      * @reimp
@@ -73,6 +69,12 @@ public:
     /** @reimp */
     virtual QMimeData* createMimeData(const QSet<int>& indexes) const;
 
+    /** @reimp */
+    virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
+
+    /** @reimp */
+    virtual bool supportsDropping(int index) const;
+
     /**
      * @return The file-item for the index \a index. If the index is in a valid
      *         range it is assured that the file-item is not null. The runtime
index 025249a34a4df329c9590a6b9bbcc83838c103ae..ed23dd1f7116d4d44cc44521b8686c87e84785cb 100644 (file)
@@ -482,16 +482,43 @@ bool KItemListController::dragLeaveEvent(QGraphicsSceneDragDropEvent* event, con
 
 bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform)
 {
-    Q_UNUSED(event);
     Q_UNUSED(transform);
+    if (!m_model || !m_view) {
+        return false;
+    }
+
+    KItemListWidget* oldHoveredWidget = hoveredWidget();
+    KItemListWidget* newHoveredWidget = widgetForPos(event->pos());
+    if (oldHoveredWidget != newHoveredWidget) {
+        if (oldHoveredWidget) {
+            oldHoveredWidget->setHovered(false);
+            emit itemUnhovered(oldHoveredWidget->index());
+        }
+
+        if (newHoveredWidget) {
+            const int index = newHoveredWidget->index();
+            if (m_model->supportsDropping(index)) {
+                newHoveredWidget->setHovered(true);
+            }
+            emit itemHovered(index);
+        }
+    }
+
     return false;
 }
 
 bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform)
 {
-    Q_UNUSED(event);
-    Q_UNUSED(transform);
-    return false;
+    Q_UNUSED(transform)
+    if (!m_view) {
+        return false;
+    }
+
+    const QPointF pos = transform.map(event->pos());
+    const int index = m_view->itemAt(pos);
+    emit itemDropEvent(index, event);
+
+    return true;
 }
 
 bool KItemListController::hoverEnterEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform)
@@ -503,46 +530,22 @@ bool KItemListController::hoverEnterEvent(QGraphicsSceneHoverEvent* event, const
 
 bool KItemListController::hoverMoveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform)
 {
-    // The implementation assumes that only one item can get hovered no matter
-    // whether they overlap or not.
-
     Q_UNUSED(transform);
     if (!m_model || !m_view) {
         return false;
     }
 
-    // Search the previously hovered item that might get unhovered
-    KItemListWidget* unhoveredWidget = 0;
-    foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
-        if (widget->isHovered()) {
-            unhoveredWidget = widget;
-            break;
+    KItemListWidget* oldHoveredWidget = hoveredWidget();
+    KItemListWidget* newHoveredWidget = widgetForPos(event->pos());
+    if (oldHoveredWidget != newHoveredWidget) {
+        if (oldHoveredWidget) {
+            oldHoveredWidget->setHovered(false);
+            emit itemUnhovered(oldHoveredWidget->index());
         }
-    }
 
-    // Search the currently hovered item
-    KItemListWidget* hoveredWidget = 0;
-    foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
-        const QPointF mappedPos = widget->mapFromItem(m_view, event->pos());
-
-        const bool hovered = widget->contains(mappedPos) &&
-                             !widget->expansionToggleRect().contains(mappedPos) &&
-                             !widget->selectionToggleRect().contains(mappedPos);
-        if (hovered) {
-            hoveredWidget = widget;
-            break;
-        }
-    }
-
-    if (unhoveredWidget != hoveredWidget) {
-        if (unhoveredWidget) {
-            unhoveredWidget->setHovered(false);
-            emit itemUnhovered(unhoveredWidget->index());
-        }
-
-        if (hoveredWidget) {
-            hoveredWidget->setHovered(true);
-            emit itemHovered(hoveredWidget->index());
+        if (newHoveredWidget) {
+            newHoveredWidget->setHovered(true);
+            emit itemHovered(newHoveredWidget->index());
         }
     }
 
@@ -755,4 +758,35 @@ void KItemListController::startDragging()
     drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::IgnoreAction);
 }
 
+KItemListWidget* KItemListController::hoveredWidget() const
+{
+    Q_ASSERT(m_view);
+
+    foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
+        if (widget->isHovered()) {
+            return widget;
+        }
+    }
+
+    return 0;
+}
+
+KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const
+{
+    Q_ASSERT(m_view);
+
+    foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
+        const QPointF mappedPos = widget->mapFromItem(m_view, pos);
+
+        const bool hovered = widget->contains(mappedPos) &&
+                             !widget->expansionToggleRect().contains(mappedPos) &&
+                             !widget->selectionToggleRect().contains(mappedPos);
+        if (hovered) {
+            return widget;
+        }
+    }
+
+    return 0;
+}
+
 #include "kitemlistcontroller.moc"
index 8ac2b554b14609d841eb272ac6175c613c4511cb..80c7505817233b544ac9e5ebe1e17d24b3f26114 100644 (file)
@@ -34,6 +34,7 @@ class KItemModelBase;
 class KItemListKeyboardSearchManager;
 class KItemListSelectionManager;
 class KItemListView;
+class KItemListWidget;
 class QGraphicsSceneHoverEvent;
 class QGraphicsSceneDragDropEvent;
 class QGraphicsSceneMouseEvent;
@@ -113,6 +114,7 @@ signals:
      * Is emitted if the item with the index \p index gets hovered.
      */
     void itemHovered(int index);
+
     /**
      * Is emitted if the item with the index \p index gets unhovered.
      * It is assured that the signal itemHovered() for this index
@@ -122,6 +124,13 @@ signals:
 
     void itemExpansionToggleClicked(int index);
 
+    /**
+     * Is emitted if a drop event is done above the item with the index
+     * \a index. If \a index is < 0 the drop event is done above an
+     * empty area of the view.
+     */
+    void itemDropEvent(int index, QGraphicsSceneDragDropEvent* event);
+
     void modelChanged(KItemModelBase* current, KItemModelBase* previous);
     void viewChanged(KItemListView* current, KItemListView* previous);
 
@@ -142,6 +151,18 @@ private:
      */
     void startDragging();
 
+    /**
+     * @return Widget that is currently in the hovered state. 0 is returned
+     *         if no widget is marked as hovered.
+     */
+    KItemListWidget* hoveredWidget() const;
+
+    /**
+     * @return Widget that is below the position \a pos. 0 is returned
+     *         if no widget is below the position.
+     */
+    KItemListWidget* widgetForPos(const QPointF& pos) const;
+
 private:
     SelectionBehavior m_selectionBehavior;
     KItemModelBase* m_model;
index 79766fae157b3de6af0a1096a19e71c42d66b32b..541f802e3253e52789d6f4eb9ae24ee646d238b4 100644 (file)
@@ -116,6 +116,12 @@ int KItemModelBase::indexForKeyboardSearch(const QString& text, int startFromInd
     return -1;
 }
 
+bool KItemModelBase::supportsDropping(int index) const
+{
+    Q_UNUSED(index);
+    return false;
+}
+
 void KItemModelBase::onGroupRoleChanged(const QByteArray& current, const QByteArray& previous)
 {
     Q_UNUSED(current);
index c4e0464022f449a25f26ff4cef1019f67ea5e800..de6e1bb1ddfe7cf518048d3058f60fec50d71ccc 100644 (file)
@@ -123,6 +123,20 @@ public:
      * @param startFromIndex    the index from which to start searching from
      */
     virtual int indexForKeyboardSearch(const QString& text, int startFromIndex = 0) const;
+
+    /**
+     * @return True, if the item with the index \a index basically supports dropping.
+     *         Per default false is returned.
+     *
+     *         The information is used only to give a visual feedback during a drag operation
+     *         and not to decide whether a drop event gets emitted. It is it is still up to
+     *         the receiver of KItemListController::itemDropEvent() to decide how to handle
+     *         the drop event.
+     */
+    // TODO: Should the MIME-data be passed too so that the model can do a more specific
+    // decision whether it accepts the drop?
+    virtual bool supportsDropping(int index) const;
+
 signals:
     /**
      * Is emitted if one or more items have been inserted. Each item-range consists
index 53171966c89f7f8e75a0de2d8bad4b56ed8101f0..200de79041b23742dac557ddb0c3ce4e88a454ad 100644 (file)
 
 #include <QAbstractItemView>
 #include <QApplication>
+#include <QBoxLayout>
 #include <QClipboard>
+#include <QDropEvent>
+#include <QGraphicsSceneDragDropEvent>
 #include <QKeyEvent>
 #include <QItemSelection>
-#include <QBoxLayout>
 #include <QTimer>
 #include <QScrollBar>
 
@@ -60,6 +62,7 @@
 #include "dolphin_detailsmodesettings.h"
 #include "dolphin_generalsettings.h"
 #include "dolphinitemlistcontainer.h"
+#include "draganddrophelper.h"
 #include "renamedialog.h"
 #include "settings/dolphinsettings.h"
 #include "viewmodecontroller.h"
@@ -172,6 +175,7 @@ DolphinView::DolphinView(const KUrl& url, QWidget* parent) :
     connect(controller, SIGNAL(itemExpansionToggleClicked(int)), this, SLOT(slotItemExpansionToggleClicked(int)));
     connect(controller, SIGNAL(itemHovered(int)), this, SLOT(slotItemHovered(int)));
     connect(controller, SIGNAL(itemUnhovered(int)), this, SLOT(slotItemUnhovered(int)));
+    connect(controller, SIGNAL(itemDropEvent(int,QGraphicsSceneDragDropEvent*)), this, SLOT(slotItemDropEvent(int,QGraphicsSceneDragDropEvent*)));
 
     KItemListSelectionManager* selectionManager = controller->selectionManager();
     connect(selectionManager, SIGNAL(selectionChanged(QSet<int>,QSet<int>)),
@@ -776,6 +780,19 @@ void DolphinView::slotItemUnhovered(int index)
     emit requestItemInfo(KFileItem());
 }
 
+void DolphinView::slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event)
+{
+    const KFileItem destItem = fileItemModel()->fileItem(index);
+
+    QDropEvent dropEvent(event->pos().toPoint(),
+                         event->possibleActions(),
+                         event->mimeData(),
+                         event->buttons(),
+                         event->modifiers());
+
+    DragAndDropHelper::dropUrls(destItem, url(), &dropEvent, this);
+}
+
 void DolphinView::slotSelectionChanged(const QSet<int>& current, const QSet<int>& previous)
 {
     const int currentCount = current.count();
index 085de332d5f5173849eba75855c25196409dff71..49da948d61fd48f5537f84352e1eb77e7bef6667 100644 (file)
@@ -18,7 +18,6 @@
  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
  ***************************************************************************/
 
-
 #ifndef DOLPHINVIEW_H
 #define DOLPHINVIEW_H
 
@@ -48,6 +47,7 @@ class KFileItemModel;
 class KUrl;
 class ToolTipManager;
 class ViewProperties;
+class QGraphicsSceneDragDropEvent;
 class QRegExp;
 
 /**
@@ -559,6 +559,7 @@ private slots:
     void slotItemExpansionToggleClicked(int index);
     void slotItemHovered(int index);
     void slotItemUnhovered(int index);
+    void slotItemDropEvent(int index, QGraphicsSceneDragDropEvent* event);
 
     /**
      * Emits the signal \a selectionChanged() with a small delay. This is
index bc1361b9a729ff335b202f9de818246e4c1247c2..6cd17b6ba4fc99249129ed85b349b4fde60deadb 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2007 by Peter Penz <peter.penz19@gmail.com>             *
+ *   Copyright (C) 2007-2011 by Peter Penz <peter.penz19@gmail.com>        *
  *   Copyright (C) 2007 by David Faure <faure@kde.org>                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 
 #include "draganddrophelper.h"
 
-#include <KDirModel>
 #include <KFileItem>
-#include <KIcon>
 #include <KLocale>
 #include <konq_operations.h>
-
-#include "views/dolphiniconsview.h"
-#include "views/dolphinviewcontroller.h"
-
-#include <QAbstractItemView>
-#include <QAbstractProxyModel>
+#include <KUrl>
 #include <QtDBus>
-#include <QDrag>
-#include <QPainter>
-
-class DragAndDropHelperSingleton
-{
-public:
-    DragAndDropHelper instance;
-};
-K_GLOBAL_STATIC(DragAndDropHelperSingleton, s_dragAndDropHelper)
-
-DragAndDropHelper& DragAndDropHelper::instance()
-{
-    return s_dragAndDropHelper->instance;
-}
-
-void DragAndDropHelper::startDrag(QAbstractItemView* itemView,
-                                  Qt::DropActions supportedActions,
-                                  DolphinViewController* dolphinViewController)
-{
-    // Do not start a new drag until the previous one has been finished.
-    // This is a (possibly temporary) fix for bug #187884.
-    static bool isDragging = false;
-    if (isDragging) {
-        return;
-    }
-    isDragging = true;
-
-    const QModelIndexList indexes = itemView->selectionModel()->selectedIndexes();
-    if (!indexes.isEmpty()) {
-        QMimeData *data = itemView->model()->mimeData(indexes);
-        if (!data) {
-            return;
-        }
-
-        if (dolphinViewController) {
-            dolphinViewController->requestToolTipHiding();
-        }
-
-        QDrag* drag = new QDrag(itemView);
-        drag->setPixmap(createDragPixmap(itemView));
-        drag->setMimeData(data);
-
-        m_dragSource = itemView;
-        drag->exec(supportedActions, Qt::IgnoreAction);
-        m_dragSource = 0;
-    }
-    isDragging = false;
-}
-
-bool DragAndDropHelper::isDragSource(QAbstractItemView* itemView) const
-{
-    return m_dragSource && (m_dragSource == itemView);
-}
+#include <QDropEvent>
+#include <QWidget>
 
-void DragAndDropHelper::dropUrls(const KFileItem& destItem,
-                                 const KUrl& destPath,
-                                 QDropEvent* event,
-                                 QWidget* widget)
+QString DragAndDropHelper::dropUrls(const KFileItem& destItem,
+                                    const KUrl& destPath,
+                                    QDropEvent* event,
+                                    QWidget* widget)
 {
     const bool dropToItem = !destItem.isNull() && (destItem.isDir() || destItem.isDesktopFile());
     const KUrl destination = dropToItem ? destItem.url() : destPath;
 
     const QMimeData* mimeData = event->mimeData();
     if (mimeData->hasFormat("application/x-kde-dndextract")) {
-        QString remoteDBusClient = mimeData->data("application/x-kde-dndextract");
+        const QString remoteDBusClient = mimeData->data("application/x-kde-dndextract");
         QDBusMessage message = QDBusMessage::createMethodCall(remoteDBusClient, "/DndExtract",
                                                               "org.kde.DndExtract", "extractSelectedFilesTo");
         message.setArguments(QVariantList() << destination.pathOrUrl());
@@ -104,79 +46,15 @@ void DragAndDropHelper::dropUrls(const KFileItem& destItem,
     } else {
         const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
         const int urlsCount = urls.count();
-        if ((urlsCount == 1) && (urls.first() == destination)) {
-            emit errorMessage(i18nc("@info:status", "A folder cannot be dropped into itself"));
+        if (urlsCount == 1 && urls.first() == destination) {
+            return i18nc("@info:status", "A folder cannot be dropped into itself");
         } else if (dropToItem) {
             KonqOperations::doDrop(destItem, destination, event, widget);
         } else {
             KonqOperations::doDrop(KFileItem(), destination, event, widget);
         }
     }
-}
-
-DragAndDropHelper::DragAndDropHelper()
-    : m_dragSource(0)
-{
-}
-
-QPixmap DragAndDropHelper::createDragPixmap(QAbstractItemView* itemView) const
-{
-    const QModelIndexList selectedIndexes = itemView->selectionModel()->selectedIndexes();
-    Q_ASSERT(!selectedIndexes.isEmpty());
-
-    QAbstractProxyModel* proxyModel = static_cast<QAbstractProxyModel*>(itemView->model());
-    KDirModel* dirModel = static_cast<KDirModel*>(proxyModel->sourceModel());
-
-    const int itemCount = selectedIndexes.count();
-
-    // 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.
-    int xCount = 3;
-    int size = KIconLoader::SizeMedium;
-    if (itemCount > 16) {
-        xCount = 5;
-        size = KIconLoader::SizeSmall;
-    } else if (itemCount > 9) {
-        xCount = 4;
-        size = KIconLoader::SizeSmallMedium;
-    }
-
-    if (itemCount < xCount) {
-        xCount = itemCount;
-    }
-
-    int yCount = itemCount / xCount;
-    if (itemCount % xCount != 0) {
-        ++yCount;
-    }
-    if (yCount > xCount) {
-        yCount = xCount;
-    }
-
-    // Draw the selected items into the grid cells
-    QPixmap dragPixmap(xCount * size + xCount - 1, yCount * size + yCount - 1);
-    dragPixmap.fill(Qt::transparent);
-
-    QPainter painter(&dragPixmap);
-    int x = 0;
-    int y = 0;
-    foreach (const QModelIndex& selectedIndex, selectedIndexes) {
-        const QModelIndex index = proxyModel->mapToSource(selectedIndex);
-        const KFileItem item = dirModel->itemForIndex(index);
-        const QPixmap pixmap = item.pixmap(size, size);
-        painter.drawPixmap(x, y, pixmap);
-
-        x += size + 1;
-        if (x >= dragPixmap.width()) {
-            x = 0;
-            y += size + 1;
-        }
-        if (y >= dragPixmap.height()) {
-            break;
-        }
-    }
 
-    return dragPixmap;
+    return QString();
 }
 
-#include "draganddrophelper.moc"
index b107efc1884cbbe37cd204a86b2f1f80123a1aa6..85e47077d289bfa337c2ce2af12dad7bd89f1a0e 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2007 by Peter Penz <peter.penz19@gmail.com>             *
+ *   Copyright (C) 2007-2011 by Peter Penz <peter.penz19@gmail.com>        *
  *   Copyright (C) 2007 by David Faure <faure@kde.org>                     *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #define DRAGANDDROPHELPER_H
 
 #include "libdolphin_export.h"
-#include <QObject>
-#include <QPixmap>
 
-class DolphinViewController;
+#include <QString>
+
 class KFileItem;
 class KUrl;
 class QDropEvent;
-class QAbstractItemView;
-class QMimeData;
 class QWidget;
 
-/**
- * @brief Helper class for having a common drag and drop behavior.
- *
- * The class is used by DolphinIconsView, DolphinDetailsView,
- * DolphinColumnView and PanelTreeView to have a consistent
- * drag and drop behavior between all views.
- */
-class LIBDOLPHINPRIVATE_EXPORT DragAndDropHelper : public QObject
+class LIBDOLPHINPRIVATE_EXPORT DragAndDropHelper
 {
-    Q_OBJECT
-
 public:
-    static DragAndDropHelper& instance();
-
-    /**
-     * Creates a drag object for the view \a itemView for all selected items.
-     */
-    void startDrag(QAbstractItemView* itemView,
-                   Qt::DropActions supportedActions,
-                   DolphinViewController* dolphinViewController = 0);
-
-    /**
-     * Returns true if and only if the view \a itemView was the last view to
-     * be passed to startDrag(...), and that drag is still in progress.
-     */
-    bool isDragSource(QAbstractItemView* itemView) const;
-
     /**
      * Handles the dropping of URLs to the given
      * destination. A context menu with the options
@@ -69,28 +42,13 @@ public:
      * @param destPath  Path of the destination.
      * @param event     Drop event.
      * @param widget    Source widget where the dragging has been started.
+     * @return          Error message if dropping is not possible. If an empty string
+     *                  is returned, the dropping has been successful.
      */
-    void dropUrls(const KFileItem& destItem,
-                  const KUrl& destPath,
-                  QDropEvent* event,
-                  QWidget* widget);
-signals:
-    void errorMessage(const QString& msg);
-
-private:
-    DragAndDropHelper();
-
-    /**
-     * Creates a pixmap the contains the all icons of the items
-     * that are dragged.
-     */
-    QPixmap createDragPixmap(QAbstractItemView* itemView) const;
-
-    // The last view passed in startDrag(...), or 0 if
-    // no startDrag(...) initiated drag is in progress.
-    QAbstractItemView *m_dragSource;
-
-    friend class DragAndDropHelperSingleton;
+    static QString dropUrls(const KFileItem& destItem,
+                            const KUrl& destPath,
+                            QDropEvent* event,
+                            QWidget* widget);
 };
 
 #endif