[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kfile
From:       Kevin Ottens <ervin () kde ! org>
Date:       2007-04-05 14:11:05
Message-ID: 1175782265.101699.24808.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 650833 by ervin:

Add drag and drop support which covers most of the places management
tasks. Only miss a context menu to edit or remove fixed places.


 M  +143 -0    kfileplacesmodel.cpp  
 M  +9 -0      kfileplacesmodel.h  
 M  +7 -0      kfileplacesview.cpp  


--- trunk/KDE/kdelibs/kfile/kfileplacesmodel.cpp #650832:650833
@@ -20,10 +20,13 @@
 #include "kfileplacesmodel.h"
 #include "kfileplacesitem_p.h"
 
+#include <QMimeData>
+
 #include <kglobal.h>
 #include <kstandarddirs.h>
 #include <kcomponentdata.h>
 #include <kicon.h>
+#include <kmimetype.h>
 
 #include <kdevicelistmodel.h>
 #include <kbookmarkmanager.h>
@@ -314,4 +317,144 @@
     }
 }
 
+Qt::DropActions KFilePlacesModel::supportedDropActions() const
+{
+    return Qt::ActionMask;
+}
+
+Qt::ItemFlags KFilePlacesModel::flags(const QModelIndex &index) const
+{
+    Qt::ItemFlags res = Qt::ItemIsSelectable|Qt::ItemIsEnabled;
+
+    if (index.isValid())
+        res|= Qt::ItemIsDragEnabled;
+
+    if (!index.isValid() || url(index).isValid())
+        res|= Qt::ItemIsDropEnabled;
+
+    return res;
+}
+
+static QString _k_internalMimetype(const KFilePlacesModel * const self)
+{
+    return QString("application/x-kfileplacesmodel-")+QString::number((int)self);
+}
+
+QStringList KFilePlacesModel::mimeTypes() const
+{
+    QStringList types;
+
+    types << _k_internalMimetype(this) << "text/uri-list";
+
+    return types;
+}
+
+QMimeData *KFilePlacesModel::mimeData(const QModelIndexList &indexes) const
+{
+    KUrl::List urls;
+    QByteArray itemData;
+
+    QDataStream stream(&itemData, QIODevice::WriteOnly);
+
+    foreach (const QModelIndex &index, indexes) {
+        KUrl itemUrl = url(index);
+        if (itemUrl.isValid())
+            urls << itemUrl;
+        stream << index.row();
+    }
+
+    QMimeData *mimeData = new QMimeData();
+
+    if (!urls.isEmpty())
+        urls.populateMimeData(mimeData);
+
+    mimeData->setData(_k_internalMimetype(this), itemData);
+
+    return mimeData;
+}
+
+bool KFilePlacesModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
+                                    int row, int column, const QModelIndex &parent)
+{
+    if (action == Qt::IgnoreAction)
+        return true;
+
+    if (column > 0)
+        return false;
+
+    if (row==-1 && parent.isValid()) {
+        return false; // Don't allow to move an item onto another one,
+                      // too easy for the user to mess something up
+                      // If we really really want to allow copying files this way,
+                      // let's do it in the views to get the good old drop menu
+    }
+
+
+    KBookmark afterBookmark;
+
+    if (row==-1) {
+        // The dropped item is moved or added to the last position
+
+        KFilePlacesItem *lastItem = d->items.last();
+        afterBookmark = d->bookmarkManager->findByAddress(lastItem->bookmarkAddress());
+
+    } else {
+        // The dropped item is moved or added before position 'row', ie after position 'row-1'
+
+        if (row>0) {
+            KFilePlacesItem *afterItem = d->items[row-1];
+            afterBookmark = d->bookmarkManager->findByAddress(afterItem->bookmarkAddress());
+        }
+    }
+
+    if (data->hasFormat(_k_internalMimetype(this))) {
+        // The operation is an internal move
+        QByteArray itemData = data->data(_k_internalMimetype(this));
+        QDataStream stream(&itemData, QIODevice::ReadOnly);
+        int itemRow;
+
+        stream >> itemRow;
+
+        KFilePlacesItem *item = d->items[itemRow];
+        KBookmark bookmark = d->bookmarkManager->findByAddress(item->bookmarkAddress());
+
+        d->bookmarkManager->root().moveItem(bookmark, afterBookmark);
+
+    } else if (data->hasFormat("text/uri-list")) {
+        // The operation is an add
+        KUrl::List urls = KUrl::List::fromMimeData(data);
+
+        KBookmarkGroup group = d->bookmarkManager->root();
+
+        foreach (KUrl url, urls) {
+            KMimeType::Ptr mimetype = KMimeType::findByUrl(url);
+
+            if (!mimetype->is("inode/directory")) {
+                // Only directories are allowed
+                continue;
+            }
+
+            KBookmark bookmark = group.addBookmark(d->bookmarkManager,
+                                                   url.fileName(), url,
+                                                   mimetype->iconName());
+            group.moveItem(bookmark, afterBookmark);
+            afterBookmark = bookmark;
+        }
+
+    } else {
+        // Oops, shouldn't happen thanks to mimeTypes()
+        kWarning() << k_funcinfo << ": received wrong mimedata, " << data->formats() << endl;
+        return false;
+    }
+
+    bool signalsBlocked = blockSignals(true); // Avoid too much signaling...
+    // We reload here to avoid a transitional
+    // period where devices are seen as separators
+    d->_k_reloadBookmarks();
+    blockSignals(signalsBlocked);
+    d->bookmarkManager->emitChanged(d->bookmarkManager->root()); // ... we'll get relisted anyway
+
+    return true;
+}
+
 #include "kfileplacesmodel.moc"
--- trunk/KDE/kdelibs/kfile/kfileplacesmodel.h #650832:650833
@@ -28,6 +28,8 @@
 
 #include <solid/device.h>
 
+class QMimeData;
+
 /**
  * This class is a list view model. Each entry represents a "place"
  * where user can access files. Only revelant when
@@ -100,6 +102,13 @@
      */
     QModelIndex closestItem(const KUrl &url) const;
 
+
+    Qt::DropActions supportedDropActions() const;
+    Qt::ItemFlags flags(const QModelIndex &index) const;
+    QStringList mimeTypes() const;
+    QMimeData *mimeData(const QModelIndexList &indexes) const;
+    bool dropMimeData(const QMimeData *data, Qt::DropAction action,
+                      int row, int column, const QModelIndex &parent);
 private:
     Q_PRIVATE_SLOT(d, void _k_devicesInserted(const QModelIndex&, int, int))
     Q_PRIVATE_SLOT(d, void _k_devicesRemoved(const QModelIndex&, int, int))
--- trunk/KDE/kdelibs/kfile/kfileplacesview.cpp #650832:650833
@@ -39,6 +39,13 @@
 KFilePlacesView::KFilePlacesView(QWidget *parent)
     : QListView(parent), d(new Private(this))
 {
+    setSelectionRectVisible(false);
+    setSelectionMode(QAbstractItemView::SingleSelection);
+
+    setDragEnabled(true);
+    setAcceptDrops(true);
+    setDropIndicatorShown(true);
+
     connect(this, SIGNAL(clicked(const QModelIndex&)),
             this, SLOT(_k_placeClicked(const QModelIndex&)));
 }
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic