From 23fff35aeb4143b73666471d7f79f30d808e2cf2 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Sat, 5 May 2012 21:38:01 +0200 Subject: [PATCH] Places Panel: Provide access to devices --- src/CMakeLists.txt | 12 ++- src/kitemviews/kstandarditem.cpp | 20 +++- src/kitemviews/kstandarditem.h | 9 +- src/panels/places/placesitem.cpp | 103 +++++++++++++++++++ src/panels/places/placesitem.h | 62 +++++++++++ src/panels/places/placesitemmodel.cpp | 141 ++++++++++++++++++-------- src/panels/places/placesitemmodel.h | 20 +++- src/panels/places/placespanel.cpp | 2 +- 8 files changed, 314 insertions(+), 55 deletions(-) create mode 100644 src/panels/places/placesitem.cpp create mode 100644 src/panels/places/placesitem.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 20bbf187a9..3a06d6093c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,7 +91,13 @@ kde4_add_kcfg_files(dolphinprivate_LIB_SRCS kde4_add_library(dolphinprivate SHARED ${dolphinprivate_LIB_SRCS}) -target_link_libraries(dolphinprivate ${KDE4_KFILE_LIBS} konq ${KDE4_KNEWSTUFF3_LIBS}) +target_link_libraries( + dolphinprivate + ${KDE4_KFILE_LIBS} + konq + ${KDE4_KNEWSTUFF3_LIBS} +) + if (Nepomuk_FOUND) target_link_libraries( dolphinprivate @@ -104,7 +110,7 @@ if (Nepomuk_FOUND) endif (Nepomuk_FOUND) if(X11_Xrender_FOUND) - target_link_libraries(dolphinprivate ${X11_Xrender_LIB} ) + target_link_libraries(dolphinprivate ${X11_Xrender_LIB}) endif(X11_Xrender_FOUND) set_target_properties(dolphinprivate PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} ) @@ -143,6 +149,7 @@ set(dolphin_SRCS panels/information/pixmapviewer.cpp panels/information/phononwidget.cpp panels/places/placespanel.cpp + panels/places/placesitem.cpp panels/places/placesitemeditdialog.cpp panels/places/placesitemlistgroupheader.cpp panels/places/placesitemlistwidget.cpp @@ -203,6 +210,7 @@ target_link_libraries(kdeinit_dolphin konq dolphinprivate knewstuff3 + ${KDE4_SOLID_LIBS} ${KDE4_PHONON_LIBS} ) diff --git a/src/kitemviews/kstandarditem.cpp b/src/kitemviews/kstandarditem.cpp index cce1dece1b..d7f9217bf1 100644 --- a/src/kitemviews/kstandarditem.cpp +++ b/src/kitemviews/kstandarditem.cpp @@ -39,7 +39,7 @@ KStandardItem::KStandardItem(const QString& text, KStandardItem* parent) : setText(text); } -KStandardItem::KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent) : +KStandardItem::KStandardItem(const QString& icon, const QString& text, KStandardItem* parent) : m_parent(parent), m_children(), m_model(0), @@ -71,14 +71,24 @@ QString KStandardItem::text() const return m_data["text"].toString(); } -void KStandardItem::setIcon(const QIcon& icon) +void KStandardItem::setIcon(const QString& icon) { - setDataValue("iconName", icon.name()); + setDataValue("iconName", icon); } -QIcon KStandardItem::icon() const +QString KStandardItem::icon() const { - return QIcon(m_data["iconName"].toString()); + return m_data["iconName"].toString(); +} + +void KStandardItem::setIconOverlays(const QStringList& overlays) +{ + setDataValue("iconOverlays", overlays); +} + +QStringList KStandardItem::iconOverlays() const +{ + return m_data["iconOverlays"].toStringList(); } void KStandardItem::setGroup(const QString& group) diff --git a/src/kitemviews/kstandarditem.h b/src/kitemviews/kstandarditem.h index 3628989a2d..f296c7666f 100644 --- a/src/kitemviews/kstandarditem.h +++ b/src/kitemviews/kstandarditem.h @@ -43,7 +43,7 @@ class LIBDOLPHINPRIVATE_EXPORT KStandardItem public: explicit KStandardItem(KStandardItem* parent = 0); explicit KStandardItem(const QString& text, KStandardItem* parent = 0); - KStandardItem(const QIcon& icon, const QString& text, KStandardItem* parent = 0); + KStandardItem(const QString& icon, const QString& text, KStandardItem* parent = 0); KStandardItem(const KStandardItem& item); virtual ~KStandardItem(); @@ -56,8 +56,11 @@ public: /** * Sets the icon for the "iconName"-role. */ - void setIcon(const QIcon& icon); - QIcon icon() const; + void setIcon(const QString& icon); + QString icon() const; + + void setIconOverlays(const QStringList& overlays); + QStringList iconOverlays() const; /** * Sets the group for the "group"-role. diff --git a/src/panels/places/placesitem.cpp b/src/panels/places/placesitem.cpp new file mode 100644 index 0000000000..11a7462c4b --- /dev/null +++ b/src/panels/places/placesitem.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz * + * * + * Based on KFilePlacesItem from kdelibs: * + * Copyright (C) 2007 Kevin Ottens * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "placesitem.h" + +#include +#include +#include +#include + +PlacesItem::PlacesItem(PlacesItem* parent) : + KStandardItem(parent) +{ +} + +PlacesItem::PlacesItem(const KBookmark& bookmark, const QString& udi, PlacesItem* parent) : + KStandardItem(parent), + m_device(udi), + m_access(), + m_volume(), + m_disc() +{ + setHidden(bookmark.metaDataItem("IsHidden") == QLatin1String("true")); + + if (udi.isEmpty()) { + setIcon(bookmark.icon()); + setText(bookmark.text()); + setUrl(bookmark.url()); + setDataValue("address", bookmark.address()); + setGroup(i18nc("@item", "Places")); + } else if (m_device.isValid()) { + m_access = m_device.as(); + m_volume = m_device.as(); + m_disc = m_device.as(); + + setText(m_device.description()); + setIcon(m_device.icon()); + setIconOverlays(m_device.emblems()); + setDataValue("udi", udi); + setGroup(i18nc("@item", "Devices")); + + if (m_access) { + setUrl(m_access->filePath()); + } else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio) != 0) { + const QString device = m_device.as()->device(); + setUrl(QString("audiocd:/?device=%1").arg(device)); + } + } +} + +PlacesItem::PlacesItem(const PlacesItem& item) : + KStandardItem(item), + m_device(), + m_access(), + m_volume(), + m_disc() +{ +} + +PlacesItem::~PlacesItem() +{ +} + +void PlacesItem::setUrl(const KUrl& url) +{ + setDataValue("url", url); +} + +KUrl PlacesItem::url() const +{ + return dataValue("url").value(); +} + +void PlacesItem::setHidden(bool hidden) +{ + setDataValue("isHidden", hidden); +} + +bool PlacesItem::isHidden() const +{ + return dataValue("isHidden").toBool(); +} + + diff --git a/src/panels/places/placesitem.h b/src/panels/places/placesitem.h new file mode 100644 index 0000000000..20289c95a6 --- /dev/null +++ b/src/panels/places/placesitem.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2012 by Peter Penz * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef PLACESITEM_H +#define PLACESITEM_H + +#include +#include +#include +#include +#include +#include +#include + +class KBookmark; + +/** + * @brief Extends KStandardItem by places-specific properties. + */ +class PlacesItem : public KStandardItem +{ + +public: + explicit PlacesItem(PlacesItem* parent = 0); + PlacesItem(const KBookmark& bookmark, + const QString& udi, + PlacesItem* parent = 0); + PlacesItem(const PlacesItem& item); + virtual ~PlacesItem(); + + void setUrl(const KUrl& url); + KUrl url() const; + + void setHidden(bool hidden); + bool isHidden() const; + +private: + Solid::Device m_device; + QPointer m_access; + QPointer m_volume; + QPointer m_disc; +}; + +#endif + + diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 2e8cb67b1d..aa0147e954 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -38,18 +38,21 @@ #include #include #include -#include -#include #include #include #include +#include "placesitem.h" #include +#include +#include + PlacesItemModel::PlacesItemModel(QObject* parent) : KStandardItemModel(parent), m_nepomukRunning(false), m_hiddenItemsShown(false), m_availableDevices(), + m_predicate(), m_bookmarkManager(0), m_systemBookmarks(), m_systemBookmarksIndexes(), @@ -62,6 +65,7 @@ PlacesItemModel::PlacesItemModel(QObject* parent) : m_bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces"); createSystemBookmarks(); + initializeAvailableDevices(); loadBookmarks(); } @@ -71,15 +75,20 @@ PlacesItemModel::~PlacesItemModel() m_hiddenItems.clear(); } +PlacesItem* PlacesItemModel::placesItem(int index) const +{ + return dynamic_cast(item(index)); +} + int PlacesItemModel::hiddenCount() const { int modelIndex = 0; int itemCount = 0; - foreach (const KStandardItem* hiddenItem, m_hiddenItems) { + foreach (const PlacesItem* hiddenItem, m_hiddenItems) { if (hiddenItem) { ++itemCount; } else { - if (item(modelIndex)->dataValue("isHidden").toBool()) { + if (placesItem(modelIndex)->isHidden()) { ++itemCount; } ++modelIndex; @@ -92,11 +101,11 @@ int PlacesItemModel::hiddenCount() const void PlacesItemModel::setItemHidden(int index, bool hide) { if (index >= 0 && index < count()) { - KStandardItem* shownItem = this->item(index); - shownItem->setDataValue("isHidden", hide); + PlacesItem* shownItem = placesItem(index); + shownItem->setHidden(true); if (!m_hiddenItemsShown && hide) { const int newIndex = hiddenIndex(index); - KStandardItem* hiddenItem = new KStandardItem(*shownItem); + PlacesItem* hiddenItem = new PlacesItem(*shownItem); removeItem(index); m_hiddenItems.insert(newIndex, hiddenItem); } @@ -125,7 +134,7 @@ void PlacesItemModel::setHiddenItemsShown(bool show) int modelIndex = 0; for (int hiddenIndex = 0; hiddenIndex < m_hiddenItems.count(); ++hiddenIndex) { if (m_hiddenItems[hiddenIndex]) { - KStandardItem* visibleItem = new KStandardItem(*m_hiddenItems[hiddenIndex]); + PlacesItem* visibleItem = new PlacesItem(*m_hiddenItems[hiddenIndex]); delete m_hiddenItems[hiddenIndex]; m_hiddenItems.removeAt(hiddenIndex); insertItem(modelIndex, visibleItem); @@ -138,9 +147,9 @@ void PlacesItemModel::setHiddenItemsShown(bool show) // m_hiddenItems. Q_ASSERT(m_hiddenItems.count() == count()); for (int i = count() - 1; i >= 0; --i) { - KStandardItem* visibleItem = item(i); - if (visibleItem->dataValue("isHidden").toBool()) { - KStandardItem* hiddenItem = new KStandardItem(*visibleItem); + PlacesItem* visibleItem = placesItem(i); + if (visibleItem->isHidden()) { + PlacesItem* hiddenItem = new PlacesItem(*visibleItem); removeItem(i); m_hiddenItems.insert(i, hiddenItem); } @@ -160,7 +169,7 @@ bool PlacesItemModel::hiddenItemsShown() const bool PlacesItemModel::isSystemItem(int index) const { if (index >= 0 && index < count()) { - const KUrl url = data(index).value("url").value(); + const KUrl url = placesItem(index)->url(); return m_systemBookmarksIndexes.contains(url); } return false; @@ -172,7 +181,7 @@ int PlacesItemModel::closestItem(const KUrl& url) const int maxLength = 0; for (int i = 0; i < count(); ++i) { - const KUrl itemUrl = data(i).value("url").value(); + const KUrl itemUrl = placesItem(i)->url(); if (itemUrl.isParentOf(url)) { const int length = itemUrl.prettyUrl().length(); if (length > maxLength) { @@ -245,6 +254,16 @@ void PlacesItemModel::onItemRemoved(int index) #endif } +void PlacesItemModel::slotDeviceAdded(const QString& udi) +{ + Q_UNUSED(udi); +} + +void PlacesItemModel::slotDeviceRemoved(const QString& udi) +{ + Q_UNUSED(udi); +} + void PlacesItemModel::loadBookmarks() { KBookmarkGroup root = m_bookmarkManager->root(); @@ -256,6 +275,12 @@ void PlacesItemModel::loadBookmarks() missingSystemBookmarks.insert(data.url); } + // The bookmarks might have a mixed order of "places" and "devices". In + // Dolphin's places panel the devices should always be appended as last + // group. + QList placesItems; + QList devicesItems; + while (!bookmark.isNull()) { const QString udi = bookmark.metaDataItem("UDI"); const KUrl url = bookmark.url(); @@ -266,61 +291,69 @@ void PlacesItemModel::loadBookmarks() && (m_nepomukRunning || url.protocol() != QLatin1String("timeline")); if ((udi.isEmpty() && allowedHere) || deviceAvailable) { - KStandardItem* item = new KStandardItem(); - item->setIcon(KIcon(bookmark.icon())); - item->setDataValue("address", bookmark.address()); - item->setDataValue("url", url); - - if (missingSystemBookmarks.contains(url)) { - missingSystemBookmarks.remove(url); - // Apply the translated text to the system bookmarks, otherwise an outdated - // translation might be shown. - const int index = m_systemBookmarksIndexes.value(url); - item->setText(m_systemBookmarks[index].text); - - // The system bookmarks don't contain "real" queries stored as URLs, so - // they must be translated first. - item->setDataValue("url", translatedSystemBookmarkUrl(url)); - } else { - item->setText(bookmark.text()); - } - + PlacesItem* item = new PlacesItem(bookmark, udi); if (deviceAvailable) { - item->setDataValue("udi", udi); - item->setGroup(i18nc("@item", "Devices")); + devicesItems.append(item); } else { - item->setGroup(i18nc("@item", "Places")); - } + placesItems.append(item); - if (bookmark.metaDataItem("IsHidden") == QLatin1String("true")) { - m_hiddenItems.append(item); - } else { - appendItem(item); + if (missingSystemBookmarks.contains(url)) { + missingSystemBookmarks.remove(url); + + // Apply the translated text to the system bookmarks, otherwise an outdated + // translation might be shown. + const int index = m_systemBookmarksIndexes.value(url); + item->setText(m_systemBookmarks[index].text); + + // The system bookmarks don't contain "real" queries stored as URLs, so + // they must be translated first. + item->setUrl(translatedSystemBookmarkUrl(url)); + } } } bookmark = root.next(bookmark); } + addItems(placesItems); + if (!missingSystemBookmarks.isEmpty()) { foreach (const SystemBookmarkData& data, m_systemBookmarks) { if (missingSystemBookmarks.contains(data.url)) { - KStandardItem* item = new KStandardItem(); - item->setIcon(KIcon(data.icon)); + PlacesItem* item = new PlacesItem(); + item->setIcon(data.icon); item->setText(data.text); - item->setDataValue("url", translatedSystemBookmarkUrl(data.url)); + item->setUrl(translatedSystemBookmarkUrl(data.url)); item->setGroup(data.group); appendItem(item); } } } + addItems(devicesItems); + + // TODO: add bookmarks for missing devices + // foreach (const QString &udi, devices) { + // bookmark = KFilePlacesItem::createDeviceBookmark(bookmarkManager, udi); + // ... + #ifdef PLACESITEMMODEL_DEBUG kDebug() << "Loaded bookmarks"; showModelState(); #endif } +void PlacesItemModel::addItems(const QList& items) +{ + foreach (PlacesItem* item, items) { + if (item->isHidden()) { + m_hiddenItems.append(item); + } else { + appendItem(item); + } + } +} + void PlacesItemModel::createSystemBookmarks() { Q_ASSERT(m_systemBookmarks.isEmpty()); @@ -390,6 +423,28 @@ void PlacesItemModel::createSystemBookmarks() } } +void PlacesItemModel::initializeAvailableDevices() +{ + m_predicate = Solid::Predicate::fromString( + "[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]" + " OR " + "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]" + " OR " + "OpticalDisc.availableContent & 'Audio' ]" + " OR " + "StorageAccess.ignored == false ]"); + Q_ASSERT(m_predicate.isValid()); + + Solid::DeviceNotifier* notifier = Solid::DeviceNotifier::instance(); + connect(notifier, SIGNAL(deviceAdded(QString)), this, SLOT(slotDeviceAdded(QString))); + connect(notifier, SIGNAL(deviceRemoved(QString)), this, SLOT(slotDeviceRemoved(QString))); + + const QList& deviceList = Solid::Device::listFromQuery(m_predicate); + foreach(const Solid::Device& device, deviceList) { + m_availableDevices << device.udi(); + } +} + int PlacesItemModel::hiddenIndex(int index) const { int hiddenIndex = 0; diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h index cd4fd2f75d..a50375a69a 100644 --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -28,8 +28,10 @@ #include #include #include +#include class KBookmarkManager; +class PlacesItem; class QAction; #ifdef HAVE_NEPOMUK @@ -58,6 +60,8 @@ public: explicit PlacesItemModel(QObject* parent = 0); virtual ~PlacesItemModel(); + PlacesItem* placesItem(int index) const; + void setHiddenItemsShown(bool show); bool hiddenItemsShown() const; @@ -94,9 +98,20 @@ protected: virtual void onItemInserted(int index); virtual void onItemRemoved(int index); +private slots: + void slotDeviceAdded(const QString& udi); + void slotDeviceRemoved(const QString& udi); + private: void loadBookmarks(); + /** + * Helper method for loadBookmarks(): Adds the items + * to the model if the "isHidden"-property is false, + * otherwise the items get added to m_hiddenItems. + */ + void addItems(const QList& items); + /** * Creates system bookmarks that are shown per default and can * only be hidden but not removed. The result will be stored @@ -104,6 +119,8 @@ private: */ void createSystemBookmarks(); + void initializeAvailableDevices(); + /** * @param index Item index related to the model. * @return Corresponding item index related to m_hiddenItems. @@ -153,6 +170,7 @@ private: bool m_hiddenItemsShown; QSet m_availableDevices; + Solid::Predicate m_predicate; KBookmarkManager* m_bookmarkManager; struct SystemBookmarkData @@ -171,7 +189,7 @@ private: QList m_systemBookmarks; QHash m_systemBookmarksIndexes; - QList m_hiddenItems; + QList m_hiddenItems; }; #endif diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index de5c95b77b..4fa1fa8523 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -360,7 +360,7 @@ KStandardItem* PlacesPanel::createStandardItemFromDialog(PlacesItemEditDialog* d const KUrl newUrl = dialog->url(); KStandardItem* item = new KStandardItem(); - item->setIcon(KIcon(dialog->icon())); + item->setIcon(dialog->icon()); item->setText(dialog->text()); item->setDataValue("url", newUrl); item->setGroup(m_model->groupName(newUrl));