]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Add the KFilePlacesModel class. It allows to list user's "places" (a mix
authorKevin Ottens <ervin@kde.org>
Sun, 1 Apr 2007 22:28:03 +0000 (22:28 +0000)
committerKevin Ottens <ervin@kde.org>
Sun, 1 Apr 2007 22:28:03 +0000 (22:28 +0000)
of bookmarks and volume devices). Still incomplete, for now it simply
list the places (drag and drop, and more interaction needs to be
implemented). It's supposed to move into kdelibs/kio soon.

svn path=/trunk/KDE/kdebase/apps/; revision=649038

src/CMakeLists.txt
src/dolphinmainwindow.cpp
src/kfileplacesitem.cpp [new file with mode: 0644]
src/kfileplacesitem_p.h [new file with mode: 0644]
src/kfileplacesmodel.cpp [new file with mode: 0644]
src/kfileplacesmodel.h [new file with mode: 0644]

index 90a4b121f75c8b578dfb40e36cb5c2e88ea4529c..015c71ee55dc4cafb6c693ba18ef9ca51e538bfd 100644 (file)
@@ -37,6 +37,8 @@ install(TARGETS dolphinprivate  DESTINATION ${LIB_INSTALL_DIR} )
 
 set(dolphin_SRCS
    applyviewpropsjob.cpp
+   kfileplacesmodel.cpp
+   kfileplacesitem.cpp
    bookmarkselector.cpp
    bookmarkssettingspage.cpp
    bookmarkssidebarpage.cpp
index 5a78ff98e634ebc9da3b8b1f65e00f18d1e8bac0..767db820d2468b7d32dcb8582635f77fd39e4efe 100644 (file)
@@ -35,6 +35,7 @@
 #include "urlnavigator.h"
 #include "viewpropertiesdialog.h"
 #include "viewproperties.h"
+#include "kfileplacesmodel.h"
 
 #include "dolphin_generalsettings.h"
 
@@ -1332,6 +1333,15 @@ void DolphinMainWindow::setupDockWidgets()
         infoDock->hide();
         treeViewDock->hide();
     }
+
+    // FIXME: To merge with the current bookmark sidebar
+    QDockWidget *placesDock = new QDockWidget(i18n("Places"));
+    placesDock->setObjectName("placesDock");
+    placesDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+    QListView *listView = new QListView(placesDock);
+    placesDock->setWidget(listView);
+    listView->setModel(new KFilePlacesModel(listView));
+    addDockWidget(Qt::LeftDockWidgetArea, placesDock);
 }
 
 void DolphinMainWindow::updateHistory()
diff --git a/src/kfileplacesitem.cpp b/src/kfileplacesitem.cpp
new file mode 100644 (file)
index 0000000..bbef32b
--- /dev/null
@@ -0,0 +1,56 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2 as published by the Free Software Foundation.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+
+*/
+
+#include "kfileplacesitem_p.h"
+
+KFilePlacesItem::KFilePlacesItem()
+    : m_isDevice(false)
+{
+}
+
+KFilePlacesItem::~KFilePlacesItem()
+{
+}
+
+bool KFilePlacesItem::isDevice() const
+{
+    return m_isDevice;
+}
+
+QString KFilePlacesItem::bookmarkAddress() const
+{
+    return m_bookmarkAddress;
+}
+
+void KFilePlacesItem::setBookmarkAddress(const QString &address)
+{
+    m_bookmarkAddress = address;
+}
+
+QPersistentModelIndex KFilePlacesItem::deviceIndex() const
+{
+    return m_deviceIndex;
+}
+
+void KFilePlacesItem::setDeviceIndex(const QPersistentModelIndex &index)
+{
+    m_deviceIndex = index;
+    m_isDevice = index.isValid();
+}
+
diff --git a/src/kfileplacesitem_p.h b/src/kfileplacesitem_p.h
new file mode 100644 (file)
index 0000000..e3aed78
--- /dev/null
@@ -0,0 +1,45 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2 as published by the Free Software Foundation.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+
+*/
+#ifndef KFILEPLACESITEM_P_H
+#define KFILEPLACESITEM_P_H
+
+#include <QString>
+#include <QPersistentModelIndex>
+
+class KFilePlacesItem
+{
+public:
+    KFilePlacesItem();
+    ~KFilePlacesItem();
+
+    bool isDevice() const;
+
+    QString bookmarkAddress() const;
+    void setBookmarkAddress(const QString &address);
+
+    QPersistentModelIndex deviceIndex() const;
+    void setDeviceIndex(const QPersistentModelIndex &index);
+
+private:
+    bool m_isDevice;
+    QString m_bookmarkAddress;
+    QPersistentModelIndex m_deviceIndex;
+};
+
+#endif
diff --git a/src/kfileplacesmodel.cpp b/src/kfileplacesmodel.cpp
new file mode 100644 (file)
index 0000000..00ee52d
--- /dev/null
@@ -0,0 +1,283 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
+    Copyright (C) 2007 David Faure <faure@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2 as published by the Free Software Foundation.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+
+*/
+#include "kfileplacesmodel.h"
+#include "kfileplacesitem_p.h"
+
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <kcomponentdata.h>
+#include <kicon.h>
+
+#include <kdevicelistmodel.h>
+#include <kbookmarkmanager.h>
+#include <kbookmark.h>
+
+#include <solid/volume.h>
+
+class KFilePlacesModel::Private
+{
+public:
+    Private(KFilePlacesModel *self) : q(self), deviceModel(0), bookmarkManager(0) {}
+
+
+    KFilePlacesModel *q;
+
+    QList<KFilePlacesItem*> items;
+    QMap<QString, QPersistentModelIndex> availableDevices;
+
+    KDeviceListModel *deviceModel;
+    KBookmarkManager *bookmarkManager;
+
+    QVariant bookmarkData(const QString &address, int role) const;
+    QVariant deviceData(const QPersistentModelIndex &index, int role) const;
+
+    void _k_devicesInserted(const QModelIndex &parent, int start, int end);
+    void _k_devicesRemoved(const QModelIndex &parent, int start, int end);
+    void _k_reloadBookmarks();
+};
+
+KFilePlacesModel::KFilePlacesModel(QObject *parent)
+    : QAbstractItemModel(parent), d(new Private(this))
+{
+    QString basePath = KGlobal::mainComponent().componentName();
+    basePath.append("/bookmarks.xml");
+    const QString file = KStandardDirs::locateLocal("data", basePath);
+
+    d->bookmarkManager = KBookmarkManager::managerForFile(file, "dolphin", false);
+
+    d->deviceModel = new KDeviceListModel("IS Volume", this);
+
+    connect(d->deviceModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
+            this, SLOT(_k_devicesInserted(const QModelIndex&, int, int)));
+    connect(d->deviceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
+            this, SLOT(_k_devicesRemoved(const QModelIndex&, int, int)));
+    connect(d->bookmarkManager, SIGNAL(changed(const QString&, const QString&)),
+            this, SLOT(_k_reloadBookmarks()));
+
+    d->_k_reloadBookmarks();
+}
+
+KFilePlacesModel::~KFilePlacesModel()
+{
+    delete d;
+}
+
+KUrl KFilePlacesModel::url(const QModelIndex &index) const
+{
+    return KUrl(data(index, UrlRole).toString());
+}
+
+bool KFilePlacesModel::mountNeeded(const QModelIndex &index) const
+{
+    return data(index, MountNeededRole).toBool();
+}
+
+QVariant KFilePlacesModel::data(const QModelIndex &index, int role) const
+{
+    if (!index.isValid())
+        return QVariant();
+
+    QVariant returnData;
+
+    KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
+
+    if (item->isDevice()) {
+        returnData = d->deviceData(item->deviceIndex(), role);
+    } else {
+        returnData = d->bookmarkData(item->bookmarkAddress(), role);
+    }
+
+    return returnData;
+}
+
+QModelIndex KFilePlacesModel::index(int row, int column, const QModelIndex &parent) const
+{
+    if (row<0 || column!=0 || row>=d->items.size())
+        return QModelIndex();
+
+    if (parent.isValid())
+        return QModelIndex();
+
+    return createIndex(row, column, d->items[row]);
+}
+
+QModelIndex KFilePlacesModel::parent(const QModelIndex &child) const
+{
+    return QModelIndex();
+}
+
+int KFilePlacesModel::rowCount(const QModelIndex &parent) const
+{
+    if (parent.isValid())
+        return 0;
+    else
+        return d->items.size();
+}
+
+int KFilePlacesModel::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent)
+    // We only know 1 information for a particualiar entry
+    return 1;
+}
+
+QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const
+{
+    int foundRow = -1;
+    int maxLength = 0;
+
+    // Search the item which is equal to the URL or at least is a parent URL.
+    // If there are more than one possible item URL candidates, choose the item
+    // which covers the bigger range of the URL.
+    for (int row = 0; row<d->items.size(); ++row) {
+        KFilePlacesItem *item = d->items[row];
+        KUrl itemUrl;
+
+        if (item->isDevice()) {
+            itemUrl = KUrl(d->deviceData(item->deviceIndex(), UrlRole).toString());
+        } else {
+            itemUrl = KUrl(d->bookmarkData(item->bookmarkAddress(), UrlRole).toString());
+        }
+
+        if (itemUrl.isParentOf(url)) {
+            const int length = itemUrl.prettyUrl().length();
+            if (length > maxLength) {
+                foundRow = row;
+                maxLength = length;
+            }
+        }
+    }
+
+    if (foundRow==-1)
+        return QModelIndex();
+    else
+        return createIndex(foundRow, 0, d->items[foundRow]);
+}
+
+QVariant KFilePlacesModel::Private::bookmarkData(const QString &address, int role) const
+{
+    KBookmark bookmark = bookmarkManager->findByAddress(address);
+
+    if (bookmark.isNull()) return QVariant();
+
+    switch (role)
+    {
+    case Qt::DisplayRole:
+        return bookmark.text();
+    case Qt::DecorationRole:
+        return KIcon(bookmark.icon());
+    case UrlRole:
+        return bookmark.url();
+    case MountNeededRole:
+        return false;
+    default:
+        return QVariant();
+    }
+}
+
+QVariant KFilePlacesModel::Private::deviceData(const QPersistentModelIndex &index, int role) const
+{
+    if (index.isValid()) {
+        switch (role)
+        {
+        case UrlRole:
+            return KUrl(deviceModel->deviceForIndex(index).as<Solid::Volume>()->mountPoint());
+        case MountNeededRole:
+            return !deviceModel->deviceForIndex(index).as<Solid::Volume>()->isMounted();
+        default:
+            return deviceModel->data(index, role);
+        }
+    } else {
+        return QVariant();
+    }
+}
+
+void KFilePlacesModel::Private::_k_devicesInserted(const QModelIndex &parent, int start, int end)
+{
+    for (int i = start; i<=end; ++i) {
+        QModelIndex index = parent.child(i, 0);
+        QString udi = deviceModel->deviceForIndex(index).udi();
+
+        availableDevices[udi] = index;
+    }
+
+    _k_reloadBookmarks();
+}
+
+void KFilePlacesModel::Private::_k_devicesRemoved(const QModelIndex &parent, int start, int end)
+{
+    for (int i = start; i<=end; ++i) {
+        QModelIndex index = parent.child(i, 0);
+        // Can't find by UDI since the device is already invalid.
+        availableDevices.remove(availableDevices.key(index));
+    }
+
+    _k_reloadBookmarks();
+}
+
+void KFilePlacesModel::Private::_k_reloadBookmarks()
+{
+    qDeleteAll(items);
+    items.clear();
+    q->reset();
+
+    KBookmarkGroup root = bookmarkManager->root();
+    KBookmark bookmark = root.first();
+    QMap<QString, QPersistentModelIndex> devices = availableDevices;
+
+    while (!bookmark.isNull()) {
+        QString udi = bookmark.metaDataItem("UDI");
+        QPersistentModelIndex index = devices.take(udi);
+
+        if (udi.isEmpty() || index.isValid()) {
+            q->beginInsertRows(QModelIndex(), items.size(), items.size());
+
+            KFilePlacesItem *item = new KFilePlacesItem();
+            item->setBookmarkAddress(bookmark.address());
+            if (index.isValid()) {
+                item->setDeviceIndex(index);
+                // TODO: Update bookmark internal element
+            }
+            items << item;
+
+            q->endInsertRows();
+        }
+
+        bookmark = root.next(bookmark);
+    }
+
+    // Add bookmarks for the remaining devices, they were previously unknown
+    foreach (QString udi, devices.keys()) {
+        bookmark = root.createNewSeparator();
+        bookmark.setMetaDataItem("UDI", udi);
+
+        q->beginInsertRows(QModelIndex(), items.size(), items.size());
+
+        KFilePlacesItem *item = new KFilePlacesItem();
+        item->setBookmarkAddress(bookmark.address());
+        item->setDeviceIndex(devices[udi]);
+        // TODO: Update bookmark internal element
+        items << item;
+
+        q->endInsertRows();
+    }
+}
+
+#include "kfileplacesmodel.moc"
diff --git a/src/kfileplacesmodel.h b/src/kfileplacesmodel.h
new file mode 100644 (file)
index 0000000..42c37aa
--- /dev/null
@@ -0,0 +1,106 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
+    Copyright (C) 2007 David Faure <faure@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2 as published by the Free Software Foundation.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+
+*/
+#ifndef KFILEPLACESMODEL_H
+#define KFILEPLACESMODEL_H
+
+#include <kdelibs_export.h>
+
+#include <QAbstractItemModel>
+#include <kurl.h>
+
+/**
+ * This class is a list view model. Each entry represents a "place"
+ * where user can access files. Only revelant when
+ * used with QListView or QTableView.
+ */
+class KIO_EXPORT KFilePlacesModel : public QAbstractItemModel
+{
+    Q_OBJECT
+public:
+    enum AdditionalRoles {
+        UrlRole = 0x069CD12B,
+        HiddenRole = 0x0741CAAC,
+        MountNeededRole = 0x059A935D
+    };
+
+    KFilePlacesModel(QObject *parent=0);
+    ~KFilePlacesModel();
+
+    KUrl url(const QModelIndex &index) const;
+    bool mountNeeded(const QModelIndex &index) const;
+
+    /**
+     * @brief Get a visible data based on Qt role for the given index.
+     * Return the device information for the give index.
+     *
+     * @param index The QModelIndex which contains the row, column to fetch the data.
+     * @param role The Interview data role(ex: Qt::DisplayRole).
+     *
+     * @return the data for the given index and role.
+     */
+    QVariant data(const QModelIndex &index, int role) const;
+
+    /**
+     * @brief Get the children model index for the given row and column.
+     */
+    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+
+    /**
+     * @brief Get the parent QModelIndex for the given model child.
+     */
+    QModelIndex parent(const QModelIndex &child) const;
+
+    /**
+     * @brief Get the number of rows for a model index.
+     */
+    int rowCount(const QModelIndex &parent = QModelIndex()) const;
+
+    /**
+     * @brief Get the number of columns for a model index.
+     */
+    int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+    /**
+     * Returns the closest item for the URL \a url.
+     * The closest item is defined as item which is equal to
+     * the URL or at least is a parent URL. If there are more than
+     * one possible parent URL candidates, the item which covers
+     * the bigger range of the URL is returned.
+     *
+     * Example: the url is '/home/peter/Documents/Music'.
+     * Available items are:
+     * - /home/peter
+     * - /home/peter/Documents
+     *
+     * The returned item will the one for '/home/peter/Documents'.
+     */
+    QModelIndex closestItem(const KUrl &url) const;
+
+private:
+    Q_PRIVATE_SLOT(d, void _k_devicesInserted(const QModelIndex&, int, int))
+    Q_PRIVATE_SLOT(d, void _k_devicesRemoved(const QModelIndex&, int, int))
+    Q_PRIVATE_SLOT(d, void _k_reloadBookmarks())
+
+    class Private;
+    Private * const d;
+    friend class Private;
+};
+
+#endif