]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Places Panel: Implement eject and teardown actions
authorPeter Penz <peter.penz19@gmail.com>
Fri, 11 May 2012 21:00:26 +0000 (23:00 +0200)
committerPeter Penz <peter.penz19@gmail.com>
Fri, 11 May 2012 21:02:14 +0000 (23:02 +0200)
Further fixes:
- Add/remove item when device has been added/removed
- Update emblem if the accessibility-state has been changed

src/CMakeLists.txt
src/panels/places/placesitem.cpp
src/panels/places/placesitem.h
src/panels/places/placesitemmodel.cpp
src/panels/places/placesitemmodel.h
src/panels/places/placesitemstorageaccesslistener.cpp [new file with mode: 0644]
src/panels/places/placesitemstorageaccesslistener.h [new file with mode: 0644]
src/panels/places/placespanel.cpp

index c00d29c20948f01c16ce2e7dfcf1e1bfe6d9ab66..dfdde9ba0fb18aaae5d8d885a917a8966ef30c3b 100644 (file)
@@ -162,6 +162,7 @@ set(dolphin_SRCS
     panels/places/placesitemlistgroupheader.cpp
     panels/places/placesitemlistwidget.cpp
     panels/places/placesitemmodel.cpp
+    panels/places/placesitemstorageaccesslistener.cpp
     panels/panel.cpp
     panels/folders/treeviewcontextmenu.cpp
     panels/folders/folderspanel.cpp
index 33af8a820f27381bf4ed0ea3c53b10870cc9887a..c865aa11db5e38467abf5751493c8be62818bdc9 100644 (file)
 #include <KBookmark>
 #include <KIcon>
 #include <KLocale>
+#include "placesitemstorageaccesslistener.h"
 #include <Solid/Block>
 
 PlacesItem::PlacesItem(PlacesItem* parent) :
-    KStandardItem(parent)
+    KStandardItem(parent),
+    m_device(),
+    m_access(),
+    m_volume(),
+    m_disc(),
+    m_accessListener(0)
 {
 }
 
@@ -37,7 +43,8 @@ PlacesItem::PlacesItem(const KBookmark& bookmark, PlacesItem* parent) :
     m_device(),
     m_access(),
     m_volume(),
-    m_disc()
+    m_disc(),
+    m_accessListener(0)
 {
     setHidden(bookmark.metaDataItem("IsHidden") == QLatin1String("true"));
 
@@ -58,7 +65,8 @@ PlacesItem::PlacesItem(const QString& udi, PlacesItem* parent) :
     m_device(),
     m_access(),
     m_volume(),
-    m_disc()
+    m_disc(),
+    m_accessListener(0)
 {
     initializeDevice(udi);
 }
@@ -68,12 +76,15 @@ PlacesItem::PlacesItem(const PlacesItem& item) :
     m_device(),
     m_access(),
     m_volume(),
-    m_disc()
+    m_disc(),
+    m_accessListener(0)
 {
 }
 
 PlacesItem::~PlacesItem()
 {
+    delete m_accessListener;
+    m_accessListener = 0;
 }
 
 void PlacesItem::setUrl(const KUrl& url)
@@ -86,6 +97,16 @@ KUrl PlacesItem::url() const
     return dataValue("url").value<KUrl>();
 }
 
+void PlacesItem::setUdi(const QString& udi)
+{
+    setDataValue("udi", udi);
+}
+
+QString PlacesItem::udi() const
+{
+    return dataValue("udi").toString();
+}
+
 void PlacesItem::setHidden(bool hidden)
 {
     setDataValue("isHidden", hidden);
@@ -115,14 +136,24 @@ void PlacesItem::initializeDevice(const QString& udi)
     setText(m_device.description());
     setIcon(m_device.icon());
     setIconOverlays(m_device.emblems());
-    setDataValue("udi", udi);
+    setUdi(udi);
     setGroup(i18nc("@item", "Devices"));
 
     if (m_access) {
         setUrl(m_access->filePath());
+
+        // The access listener takes care to call PlacesItem::onAccessibilityChanged()
+        // in case if the accessibility of m_access has been changed.
+        Q_ASSERT(!m_accessListener);
+        m_accessListener = new PlacesItemStorageAccessListener(this);
     } else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio) != 0) {
         const QString device = m_device.as<Solid::Block>()->device();
         setUrl(QString("audiocd:/?device=%1").arg(device));
     }
 }
 
+void PlacesItem::onAccessibilityChanged()
+{
+    setIconOverlays(m_device.emblems());
+}
+
index 5c698842485078cecc72ebd1126860e14571c9d4..878d14a7d00abc40f872173fd908efd8e8920a61 100644 (file)
@@ -29,6 +29,7 @@
 #include <Solid/StorageVolume>
 
 class KBookmark;
+class PlacesItemStorageAccessListener;
 
 /**
  * @brief Extends KStandardItem by places-specific properties.
@@ -46,6 +47,9 @@ public:
     void setUrl(const KUrl& url);
     KUrl url() const;
 
+    void setUdi(const QString& udi);
+    QString udi() const;
+
     void setHidden(bool hidden);
     bool isHidden() const;
 
@@ -54,11 +58,20 @@ public:
 private:
     void initializeDevice(const QString& udi);
 
+    /**
+     * Is invoked by m_accessListener if the accessibility
+     * of the storage access m_access has been changed.
+     */
+    void onAccessibilityChanged();
+
 private:
     Solid::Device m_device;
     QPointer<Solid::StorageAccess> m_access;
     QPointer<Solid::StorageVolume> m_volume;
     QPointer<Solid::OpticalDisc> m_disc;
+    PlacesItemStorageAccessListener* m_accessListener;
+
+    friend class PlacesItemStorageAccessListener; // Calls onAccessibilityChanged()
 };
 
 #endif
index 48f54b2768c13098e948658f5f042ea9798b9085..81533876343f1e9e21d98e3d80b1b965844dc0c2 100644 (file)
 
 #include <Solid/Device>
 #include <Solid/DeviceNotifier>
+#include <Solid/OpticalDisc>
+#include <Solid/OpticalDrive>
+#include <Solid/StorageAccess>
+#include <Solid/StorageDrive>
 
 PlacesItemModel::PlacesItemModel(QObject* parent) :
     KStandardItemModel(parent),
@@ -221,31 +225,82 @@ QAction* PlacesItemModel::ejectAction(int index) const
     return 0;
 }
 
-QAction* PlacesItemModel::tearDownAction(int index) const
+QAction* PlacesItemModel::teardownAction(int index) const
 {
-    // TODO: This is a dummy-implementation to have at least all
-    // translation-strings as part of the code before the freeze
+    const PlacesItem* item = placesItem(index);
+    if (!item) {
+        return 0;
+    }
+
+    Solid::Device device = item->device();
+    const bool providesTearDown = device.is<Solid::StorageAccess>() &&
+                                  device.as<Solid::StorageAccess>()->isAccessible();
+    if (!providesTearDown) {
+        return 0;
+    }
+
+    Solid::StorageDrive* drive = device.as<Solid::StorageDrive>();
+    if (!drive) {
+        drive = device.parent().as<Solid::StorageDrive>();
+    }
+
+    bool hotPluggable = false;
+    bool removable = false;
+    if (drive) {
+        hotPluggable = drive->isHotpluggable();
+        removable = drive->isRemovable();
+    }
+
     QString iconName;
     QString text;
-    QString label;
-    switch (index) {
-    case 0:
+    const QString label = item->text();
+    if (device.is<Solid::OpticalDisc>()) {
         text = i18nc("@item", "Release '%1'", label);
-        break;
-    case 1:
+    } else if (removable || hotPluggable) {
         text = i18nc("@item", "Safely Remove '%1'", label);
         iconName = "media-eject";
-        break;
-    case 2:
+    } else {
         text = i18nc("@item", "Unmount '%1'", label);
         iconName = "media-eject";
-        break;
-    default:
-        break;
     }
 
-    //return new QAction(KIcon(iconName), text, 0);
-    return 0;
+    if (iconName.isEmpty()) {
+        return new QAction(text, 0);
+    }
+
+    return new QAction(KIcon(iconName), text, 0);
+}
+
+void PlacesItemModel::requestEject(int index)
+{
+    const PlacesItem* item = placesItem(index);
+    if (item) {
+        Solid::OpticalDrive* drive = item->device().parent().as<Solid::OpticalDrive>();
+        if (drive) {
+            connect(drive, SIGNAL(ejectDone(Solid::ErrorType,QVariant,QString)),
+                    this, SLOT(slotStorageTeardownDone(Solid::ErrorType,QVariant)));
+            drive->eject();
+        } else {
+
+        }
+    }
+}
+
+void PlacesItemModel::requestTeardown(int index)
+{
+    const PlacesItem* item = placesItem(index);
+    if (item) {
+        Solid::StorageAccess* access = item->device().as<Solid::StorageAccess>();
+        if (access) {
+            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);
+        }
+    }
 }
 
 void PlacesItemModel::onItemInserted(int index)
@@ -283,12 +338,33 @@ void PlacesItemModel::onItemRemoved(int index)
 
 void PlacesItemModel::slotDeviceAdded(const QString& udi)
 {
-    Q_UNUSED(udi);
+    appendItem(new PlacesItem(udi));
 }
 
 void PlacesItemModel::slotDeviceRemoved(const QString& udi)
 {
-    Q_UNUSED(udi);
+     for (int i = 0; i < m_hiddenItems.count(); ++i) {
+         PlacesItem* item = m_hiddenItems[i];
+         if (item && item->udi() == udi) {
+             m_hiddenItems.removeAt(i);
+             delete item;
+             return;
+         }
+     }
+
+     for (int i = 0; i < count(); ++i) {
+         if (placesItem(i)->udi() == udi) {
+             removeItem(i);
+             return;
+         }
+     }
+}
+
+void PlacesItemModel::slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData)
+{
+    if (error && errorData.isValid()) {
+        emit errorMessage(errorData.toString());
+    }
 }
 
 void PlacesItemModel::loadBookmarks()
index a50375a69a90063735a5dd08becc129eecda3dcd..ae111a58dd4855d9c6d70ef52b539241f488f347 100644 (file)
@@ -29,6 +29,7 @@
 #include <QList>
 #include <QSet>
 #include <Solid/Predicate>
+#include <Solid/StorageAccess>
 
 class KBookmarkManager;
 class PlacesItem;
@@ -92,7 +93,13 @@ public:
     QString groupName(const KUrl& url) const;
 
     QAction* ejectAction(int index) const;
-    QAction* tearDownAction(int index) const;
+    QAction* teardownAction(int index) const;
+
+    void requestEject(int index);
+    void requestTeardown(int index);
+
+signals:
+    void errorMessage(const QString& message);
 
 protected:
     virtual void onItemInserted(int index);
@@ -101,6 +108,7 @@ protected:
 private slots:
     void slotDeviceAdded(const QString& udi);
     void slotDeviceRemoved(const QString& udi);
+    void slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData);
 
 private:
     void loadBookmarks();
diff --git a/src/panels/places/placesitemstorageaccesslistener.cpp b/src/panels/places/placesitemstorageaccesslistener.cpp
new file mode 100644 (file)
index 0000000..26981f0
--- /dev/null
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
+ *                                                                         *
+ *   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 "placesitemstorageaccesslistener.h"
+
+#include "placesitem.h"
+#include <Solid/StorageAccess>
+
+PlacesItemStorageAccessListener::PlacesItemStorageAccessListener(PlacesItem* item,
+                                                                 QObject* parent) :
+    QObject(parent),
+    m_item(item)
+{
+    if (item) {
+        connect(item->m_access, SIGNAL(accessibilityChanged(bool,QString)),
+                this, SLOT(onAccessibilityChanged()));
+    }
+}
+
+PlacesItemStorageAccessListener::~PlacesItemStorageAccessListener()
+{
+}
+
+void PlacesItemStorageAccessListener::slotOnAccessibilityChanged()
+{
+    m_item->onAccessibilityChanged();
+}
+
+#include "placesitemstorageaccesslistener.moc"
diff --git a/src/panels/places/placesitemstorageaccesslistener.h b/src/panels/places/placesitemstorageaccesslistener.h
new file mode 100644 (file)
index 0000000..46b943d
--- /dev/null
@@ -0,0 +1,50 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com>             *
+ *                                                                         *
+ *   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 PLACESITEMSTORAGEACCESSLISTENER_H
+#define PLACESITEMSTORAGEACCESSLISTENER_H
+
+#include <QObject>
+
+class PlacesItem;
+
+/**
+ * @brief Helper class for PlacesItem to listen to accessibility changes
+ *        of the storage access.
+ *
+ * Connects to the storage access from the given places item and
+ * calls PlacesItem::onAccessibilityChanged() in case if the accessibility
+ * has been changed.
+ */
+class PlacesItemStorageAccessListener: public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit PlacesItemStorageAccessListener(PlacesItem* item, QObject* parent = 0);
+    virtual ~PlacesItemStorageAccessListener();
+
+private slots:
+    void slotOnAccessibilityChanged();
+
+private:
+    PlacesItem* m_item;
+};
+
+#endif
index 4fa1fa852307726d94703d8c4d8c6da844a69807..979ef25a64460a7a27d6088cb56eb6271b0bdfa1 100644 (file)
@@ -76,6 +76,8 @@ void PlacesPanel::showEvent(QShowEvent* event)
         m_model = new PlacesItemModel(this);
         m_model->setGroupedSorting(true);
         m_model->setSortRole("group");
+        connect(m_model, SIGNAL(errorMessage(QString)),
+                this, SIGNAL(errorMessage(QString)));
 
         KStandardItemListView* view = new KStandardItemListView();
         view->setWidgetCreator(new KItemListWidgetCreator<PlacesItemListWidget>());
@@ -128,7 +130,7 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
     QAction* addAction = 0;
     QAction* mainSeparator = 0;
     QAction* editAction = 0;
-    QAction* tearDownAction = 0;
+    QAction* teardownAction = 0;
     QAction* ejectAction = 0;
 
     const bool isSystemItem = m_model->isSystemItem(index);
@@ -140,13 +142,13 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
             menu.addAction(ejectAction);
         }
 
-        tearDownAction = m_model->tearDownAction(index);
-        if (tearDownAction) {
-            tearDownAction->setParent(&menu);
-            menu.addAction(tearDownAction);
+        teardownAction = m_model->teardownAction(index);
+        if (teardownAction) {
+            teardownAction->setParent(&menu);
+            menu.addAction(teardownAction);
         }
 
-        if (tearDownAction || ejectAction) {
+        if (teardownAction || ejectAction) {
             mainSeparator = menu.addSeparator();
         }
     } else {
@@ -209,8 +211,10 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
             emit placeMiddleClicked(url);
         } else if (action == showAllAction) {
             m_model->setHiddenItemsShown(showAllAction->isChecked());
-        } else if (action == tearDownAction) {
+        } else if (action == teardownAction) {
+            m_model->requestTeardown(index);
         } else if (action == ejectAction) {
+            m_model->requestEject(index);
         }
     }