diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -91,9 +91,11 @@ QAction* ejectAction(int index) const; QAction* teardownAction(int index) const; + QAction* changeLabelAction(int index) const; void requestEject(int index); void requestTearDown(int index); + void requestChangeLabel(int index); bool storageSetupNeeded(int index) const; void requestStorageSetup(int index); diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -36,12 +36,19 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include +#include +#include + namespace { static QList balooURLs = { QUrl(QStringLiteral("timeline:/today")), @@ -249,6 +256,16 @@ return new QAction(QIcon::fromTheme(iconName), text, nullptr); } +QAction* PlacesItemModel::changeLabelAction(int index) const +{ + const PlacesItem* item = placesItem(index); + if (item && item->device().is() && item->device().as()->usage() == Solid::StorageVolume::FileSystem) { + return new QAction(QIcon::fromTheme(QStringLiteral("edit-entry")), i18nc("@item", "Change Label"), nullptr); + } + + return nullptr; +} + void PlacesItemModel::requestEject(int index) { const PlacesItem* item = placesItem(index); @@ -283,6 +300,48 @@ } } +void PlacesItemModel::requestChangeLabel(int index) +{ + PlacesItem* item = placesItem(index); + if (item) { + Solid::Block *blk = item->device().as(); + if (blk) { + bool ok; + const QString oldLabel = item->text(); + const QString newLabel = QInputDialog::getText(nullptr, i18n("Enter filesystem label"), + i18n("Label:"), QLineEdit::Normal, + oldLabel, &ok); + + if (newLabel == oldLabel || !ok || newLabel.isEmpty()) { + return; + } + + const QString devFile = blk->device().split('/').last(); + QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.UDisks2"), + QStringLiteral("/org/freedesktop/UDisks2/block_devices/%1").arg(devFile), + QStringLiteral("org.freedesktop.UDisks2.Filesystem"), + QStringLiteral("SetLabel")); + QVariantList argList; + argList << newLabel << QVariantMap(); + msg.setArguments(argList); + QDBusPendingCall async = QDBusConnection::systemBus().asyncCall(msg); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, [this, item, oldLabel, newLabel](QDBusPendingCallWatcher* watcher) { + if (!(*watcher).isError()) { + item->setText(newLabel); + refresh(); + } else { + emit errorMessage(i18nc("@info", "An error occurred while renaming '%1' to '%2', the system responded: %3", + oldLabel, newLabel, + (*watcher).error().message())); + } + watcher->deleteLater(); + }); + } + } +} + bool PlacesItemModel::storageSetupNeeded(int index) const { const PlacesItem* item = placesItem(index); diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -172,6 +172,7 @@ QAction* teardownAction = nullptr; QAction* ejectAction = nullptr; QAction* mountAction = nullptr; + QAction* changeLabelAction = nullptr; const bool isDevice = !item->udi().isEmpty(); const bool isTrash = (item->url().scheme() == QLatin1String("trash")); @@ -202,7 +203,13 @@ mountAction = menu.addAction(QIcon::fromTheme(QStringLiteral("media-mount")), i18nc("@action:inmenu", "Mount")); } - if (teardownAction || ejectAction || mountAction) { + changeLabelAction = m_model->changeLabelAction(index); + if (changeLabelAction) { + changeLabelAction->setParent(&menu); + menu.addAction(changeLabelAction); + } + + if (teardownAction || ejectAction || mountAction || changeLabelAction) { menu.addSeparator(); } } else { @@ -273,6 +280,8 @@ m_model->requestTearDown(index); } else if (action == ejectAction) { m_model->requestEject(index); + } else if (action == changeLabelAction) { + m_model->requestChangeLabel(index); } else if (action == propertiesAction) { KPropertiesDialog* dialog = new KPropertiesDialog(item->url(), this); dialog->setAttribute(Qt::WA_DeleteOnClose);