Add eject & umount options

This commit is contained in:
kateleet 2021-12-03 04:42:16 +08:00
parent d06a97f708
commit 02223a5d41
7 changed files with 110 additions and 4 deletions

View file

@ -20,6 +20,7 @@
#include "placesitem.h" #include "placesitem.h"
#include <QDebug> #include <QDebug>
#include <Solid/OpticalDisc>
#include <solid_version.h> #include <solid_version.h>
PlacesItem::PlacesItem(const QString &displayName, PlacesItem::PlacesItem(const QString &displayName,
@ -29,6 +30,7 @@ PlacesItem::PlacesItem(const QString &displayName,
, m_displayName(displayName) , m_displayName(displayName)
, m_url(url) , m_url(url)
, m_category("") , m_category("")
, m_isOpticalDisc(false)
, m_isAccessible(false) , m_isAccessible(false)
{ {
} }
@ -124,6 +126,11 @@ void PlacesItem::updateDeviceInfo(const QString &udi)
m_displayName = m_device.description(); m_displayName = m_device.description();
#endif #endif
if (m_device.is<Solid::OpticalDisc>()) {
m_isOpticalDisc = true;
emit itemChanged(this);
}
if (m_access) { if (m_access) {
m_url = QUrl::fromLocalFile(m_access->filePath()); m_url = QUrl::fromLocalFile(m_access->filePath());
connect(m_access.data(), &Solid::StorageAccess::accessibilityChanged, this, &PlacesItem::onAccessibilityChanged); connect(m_access.data(), &Solid::StorageAccess::accessibilityChanged, this, &PlacesItem::onAccessibilityChanged);
@ -150,3 +157,8 @@ void PlacesItem::setCategory(const QString &category)
{ {
m_category = category; m_category = category;
} }
bool PlacesItem::isOpticalDisc() const
{
return m_isOpticalDisc;
}

View file

@ -59,6 +59,8 @@ public:
QString category() const; QString category() const;
void setCategory(const QString &category); void setCategory(const QString &category);
bool isOpticalDisc() const;
signals: signals:
void itemChanged(PlacesItem *); void itemChanged(PlacesItem *);
@ -74,6 +76,7 @@ private:
QUrl m_url; QUrl m_url;
QString m_category; QString m_category;
bool m_isOpticalDisc;
bool m_isAccessible; bool m_isAccessible;
Solid::Device m_device; Solid::Device m_device;

View file

@ -117,6 +117,11 @@ PlacesModel::PlacesModel(QObject *parent)
deviceItem->setCategory(tr("Drives")); deviceItem->setCategory(tr("Drives"));
m_items.append(deviceItem); m_items.append(deviceItem);
} }
// Init Signals
for (PlacesItem *item : m_items) {
connect(item, &PlacesItem::itemChanged, this, &PlacesModel::onItemChanged);
}
} }
PlacesModel::~PlacesModel() PlacesModel::~PlacesModel()
@ -132,6 +137,7 @@ QHash<int, QByteArray> PlacesModel::roleNames() const
roleNames[PlacesModel::UrlRole] = "url"; roleNames[PlacesModel::UrlRole] = "url";
roleNames[PlacesModel::PathRole] = "path"; roleNames[PlacesModel::PathRole] = "path";
roleNames[PlacesModel::IsDeviceRole] = "isDevice"; roleNames[PlacesModel::IsDeviceRole] = "isDevice";
roleNames[PlacesModel::IsOpticalDisc] = "isOpticalDisc";
roleNames[PlacesModel::setupNeededRole] = "setupNeeded"; roleNames[PlacesModel::setupNeededRole] = "setupNeeded";
roleNames[PlacesModel::CategoryRole] = "category"; roleNames[PlacesModel::CategoryRole] = "category";
return roleNames; return roleNames;
@ -177,6 +183,9 @@ QVariant PlacesModel::data(const QModelIndex &index, int role) const
case PlacesModel::IsDeviceRole: case PlacesModel::IsDeviceRole:
return item->isDevice(); return item->isDevice();
break; break;
case PlacesModel::IsOpticalDisc:
return item->isOpticalDisc();
break;
case PlacesModel::setupNeededRole: case PlacesModel::setupNeededRole:
return item->setupNeeded(); return item->setupNeeded();
break; break;
@ -256,6 +265,20 @@ void PlacesModel::requestEject(const int &index)
} }
} }
void PlacesModel::requestTeardown(const int &index)
{
PlacesItem *item = m_items.at(index);
if (!item->udi().isEmpty()) {
Solid::Device device = Solid::Device(item->udi());
Solid::StorageAccess *access = device.as<Solid::StorageAccess>();
if (access != nullptr) {
access->teardown();
}
}
}
void PlacesModel::onDeviceAdded(const QString &udi) void PlacesModel::onDeviceAdded(const QString &udi)
{ {
if (m_predicate.matches(Solid::Device(udi))) { if (m_predicate.matches(Solid::Device(udi))) {
@ -265,6 +288,8 @@ void PlacesModel::onDeviceAdded(const QString &udi)
deviceItem->setCategory(tr("Drives")); deviceItem->setCategory(tr("Drives"));
m_items.append(deviceItem); m_items.append(deviceItem);
endInsertRows(); endInsertRows();
connect(deviceItem, &PlacesItem::itemChanged, this, &PlacesModel::onItemChanged);
} }
} }
@ -276,6 +301,20 @@ void PlacesModel::onDeviceRemoved(const QString &udi)
PlacesItem *item = m_items.at(i); PlacesItem *item = m_items.at(i);
m_items.removeOne(item); m_items.removeOne(item);
endRemoveRows(); endRemoveRows();
disconnect(item);
} }
} }
} }
void PlacesModel::onItemChanged(PlacesItem *item)
{
// 更新 item 数据
int index = m_items.indexOf(item);
if (index < 0 || index > m_items.size())
return;
QModelIndex idx = this->index(index, 0);
emit dataChanged(idx, idx);
}

View file

@ -36,6 +36,7 @@ public:
UrlRole, UrlRole,
PathRole, PathRole,
IsDeviceRole, IsDeviceRole,
IsOpticalDisc,
setupNeededRole, setupNeededRole,
CategoryRole CategoryRole
}; };
@ -56,6 +57,7 @@ public:
Q_INVOKABLE QVariantMap get(const int &index) const; Q_INVOKABLE QVariantMap get(const int &index) const;
Q_INVOKABLE void requestSetup(const int &index); Q_INVOKABLE void requestSetup(const int &index);
Q_INVOKABLE void requestEject(const int &index); Q_INVOKABLE void requestEject(const int &index);
Q_INVOKABLE void requestTeardown(const int &index);
signals: signals:
void deviceSetupDone(const QString &filePath); void deviceSetupDone(const QString &filePath);
@ -63,6 +65,7 @@ signals:
private slots: private slots:
void onDeviceAdded(const QString &udi); void onDeviceAdded(const QString &udi);
void onDeviceRemoved(const QString &udi); void onDeviceRemoved(const QString &udi);
void onItemChanged(PlacesItem *);
private: private:
QList<PlacesItem *> m_items; QList<PlacesItem *> m_items;

View file

@ -127,6 +127,35 @@ ListView {
sideBar.openInNewWindow(model.path ? model.path : model.url) sideBar.openInNewWindow(model.path ? model.path : model.url)
} }
} }
MenuSeparator {
Layout.fillWidth: true
visible: _ejectMenuItem.visible || _umountMenuItem.visible
}
MenuItem {
id: _ejectMenuItem
text: qsTr("Eject")
visible: model.isDevice &&
!model.setupNeeded &&
model.isOpticalDisc
onTriggered: {
placesModel.requestEject(index)
}
}
MenuItem {
id: _umountMenuItem
text: qsTr("Unmount")
visible: model.isDevice &&
!model.setupNeeded &&
!model.isOpticalDisc
onTriggered: {
placesModel.requestTeardown(index)
}
}
} }
Rectangle { Rectangle {

View file

@ -441,7 +441,7 @@
</message> </message>
<message> <message>
<location filename="../model/placesmodel.cpp" line="117"/> <location filename="../model/placesmodel.cpp" line="117"/>
<location filename="../model/placesmodel.cpp" line="265"/> <location filename="../model/placesmodel.cpp" line="288"/>
<source>Drives</source> <source>Drives</source>
<translation>Drives</translation> <translation>Drives</translation>
</message> </message>
@ -502,10 +502,20 @@
<translation type="unfinished">Open</translation> <translation type="unfinished">Open</translation>
</message> </message>
<message> <message>
<location filename="../qml/SideBar.qml" line="121"/> <location filename="../qml/SideBar.qml" line="124"/>
<source>Open in new window</source> <source>Open in new window</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<location filename="../qml/SideBar.qml" line="138"/>
<source>Eject</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../qml/SideBar.qml" line="150"/>
<source>Unmount</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>main</name> <name>main</name>

View file

@ -441,7 +441,7 @@
</message> </message>
<message> <message>
<location filename="../model/placesmodel.cpp" line="117"/> <location filename="../model/placesmodel.cpp" line="117"/>
<location filename="../model/placesmodel.cpp" line="265"/> <location filename="../model/placesmodel.cpp" line="288"/>
<source>Drives</source> <source>Drives</source>
<translation></translation> <translation></translation>
</message> </message>
@ -510,10 +510,20 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../qml/SideBar.qml" line="121"/> <location filename="../qml/SideBar.qml" line="124"/>
<source>Open in new window</source> <source>Open in new window</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../qml/SideBar.qml" line="138"/>
<source>Eject</source>
<translation></translation>
</message>
<message>
<location filename="../qml/SideBar.qml" line="150"/>
<source>Unmount</source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>main</name> <name>main</name>