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
#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)
{
}
m_device(),
m_access(),
m_volume(),
- m_disc()
+ m_disc(),
+ m_accessListener(0)
{
setHidden(bookmark.metaDataItem("IsHidden") == QLatin1String("true"));
m_device(),
m_access(),
m_volume(),
- m_disc()
+ m_disc(),
+ m_accessListener(0)
{
initializeDevice(udi);
}
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)
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);
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());
+}
+
#include <Solid/StorageVolume>
class KBookmark;
+class PlacesItemStorageAccessListener;
/**
* @brief Extends KStandardItem by places-specific properties.
void setUrl(const KUrl& url);
KUrl url() const;
+ void setUdi(const QString& udi);
+ QString udi() const;
+
void setHidden(bool hidden);
bool isHidden() const;
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
#include <Solid/Device>
#include <Solid/DeviceNotifier>
+#include <Solid/OpticalDisc>
+#include <Solid/OpticalDrive>
+#include <Solid/StorageAccess>
+#include <Solid/StorageDrive>
PlacesItemModel::PlacesItemModel(QObject* parent) :
KStandardItemModel(parent),
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)
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()
#include <QList>
#include <QSet>
#include <Solid/Predicate>
+#include <Solid/StorageAccess>
class KBookmarkManager;
class PlacesItem;
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);
private slots:
void slotDeviceAdded(const QString& udi);
void slotDeviceRemoved(const QString& udi);
+ void slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData);
private:
void loadBookmarks();
--- /dev/null
+/***************************************************************************
+ * 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"
--- /dev/null
+/***************************************************************************
+ * 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
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>());
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);
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 {
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);
}
}