Add eject & umount options
This commit is contained in:
parent
d06a97f708
commit
02223a5d41
7 changed files with 110 additions and 4 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue