diff --git a/src/partition.h b/src/partition.h index feabdf0..7c57be0 100644 --- a/src/partition.h +++ b/src/partition.h @@ -73,7 +73,8 @@ class SYSTEMSETTINGS_EXPORT Partition Unlocking, Unlocked, Locking, - Locked + Locked, + Renaming }; Q_DECLARE_FLAGS(StorageTypes, StorageType) diff --git a/src/partitionmanager.cpp b/src/partitionmanager.cpp index 6724a31..b5e9c28 100644 --- a/src/partitionmanager.cpp +++ b/src/partitionmanager.cpp @@ -66,6 +66,7 @@ PartitionManagerPrivate::PartitionManagerPrivate() connect(m_udisksMonitor.data(), &UDisks2::Monitor::mountError, this, &PartitionManagerPrivate::mountError); connect(m_udisksMonitor.data(), &UDisks2::Monitor::unmountError, this, &PartitionManagerPrivate::unmountError); connect(m_udisksMonitor.data(), &UDisks2::Monitor::formatError, this, &PartitionManagerPrivate::formatError); + connect(m_udisksMonitor.data(), &UDisks2::Monitor::setLabelError, this, &PartitionManagerPrivate::setLabelError); connect(UDisks2::BlockDevices::instance(), &UDisks2::BlockDevices::externalStoragesPopulated, this, &PartitionManagerPrivate::externalStoragesPopulatedChanged); @@ -344,6 +345,16 @@ void PartitionManagerPrivate::unmount(const Partition &partition) } } +void PartitionManagerPrivate::setLabel(const Partition &partition, const QString &label) +{ + qCInfo(lcMemoryCardLog) << "Can setLabel:" << externalMedia.match(partition.deviceName()).hasMatch() << partition.devicePath(); + if (externalMedia.match(partition.deviceName()).hasMatch()) { + m_udisksMonitor->setLabel(partition.devicePath(), label); + } else { + qCWarning(lcMemoryCardLog) << "SetLabel allowed only for external memory cards," << partition.devicePath() << "is not allowed"; + } +} + void PartitionManagerPrivate::format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments) { QString deviceName = devicePath.section(QChar('/'), 2); diff --git a/src/partitionmanager_p.h b/src/partitionmanager_p.h index 30130ed..b7339b3 100644 --- a/src/partitionmanager_p.h +++ b/src/partitionmanager_p.h @@ -71,6 +71,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData void mount(const Partition &partition); void unmount(const Partition &partition); void format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments); + void setLabel(const Partition &partition, const QString &label); QString objectPath(const QString &devicePath) const; @@ -90,6 +91,7 @@ class PartitionManagerPrivate : public QObject, public QSharedData void mountError(Partition::Error error); void unmountError(Partition::Error error); void formatError(Partition::Error error); + void setLabelError(Partition::Error error); private: // TODO: This is leaking (Disks2::Monitor is never free'ed). diff --git a/src/partitionmodel.cpp b/src/partitionmodel.cpp index 0791936..8b767d8 100644 --- a/src/partitionmodel.cpp +++ b/src/partitionmodel.cpp @@ -69,6 +69,9 @@ PartitionModel::PartitionModel(QObject *parent) connect(m_manager.data(), &PartitionManagerPrivate::formatError, this, [this](Partition::Error error) { emit formatError(static_cast(error)); }); + connect(m_manager.data(), &PartitionManagerPrivate::setLabelError, this, [this](Partition::Error error) { + emit setLabelError(static_cast(error)); + }); } PartitionModel::~PartitionModel() @@ -162,6 +165,16 @@ void PartitionModel::unmount(const QString &devicePath) } } +void PartitionModel::setLabel(const QString &devicePath, const QString &label) +{ + qCInfo(lcMemoryCardLog) << Q_FUNC_INFO << devicePath << m_partitions.count(); + if (const Partition *partition = getPartition(devicePath)) { + m_manager->setLabel(*partition, label); + } else { + qCWarning(lcMemoryCardLog) << "Unable to rename unknown device:" << devicePath; + } +} + void PartitionModel::format(const QString &devicePath, const QVariantMap &arguments) { QString filesystemType = arguments.value(QLatin1String("filesystemType"), QString()).toString(); diff --git a/src/partitionmodel.h b/src/partitionmodel.h index 27d3dd3..3792b6e 100644 --- a/src/partitionmodel.h +++ b/src/partitionmodel.h @@ -143,6 +143,7 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel Q_INVOKABLE void mount(const QString &devicePath); Q_INVOKABLE void unmount(const QString &devicePath); Q_INVOKABLE void format(const QString &devicePath, const QVariantMap &arguments); + Q_INVOKABLE void setLabel(const QString &devicePath, const QString &label); Q_INVOKABLE QString objectPath(const QString &devicePath) const; @@ -162,6 +163,7 @@ class SYSTEMSETTINGS_EXPORT PartitionModel : public QAbstractListModel void mountError(Error error); void unmountError(Error error); void formatError(Error error); + void setLabelError(Error error); private: void update(); diff --git a/src/udisks2defines.h b/src/udisks2defines.h index b1f66bb..c103fb7 100644 --- a/src/udisks2defines.h +++ b/src/udisks2defines.h @@ -64,18 +64,19 @@ Q_DECLARE_METATYPE(UDisks2::InterfacePropertyMap) #define UDISKS2_JOB_INTERFACE QLatin1String("org.freedesktop.UDisks2.Job") // Jobs -#define UDISKS2_JOB_OP_ENC_LOCK QLatin1String("encrypted-lock") -#define UDISKS2_JOB_OP_ENC_UNLOCK QLatin1String("encrypted-unlock") -#define UDISKS2_JOB_OP_FS_UNMOUNT QLatin1String("filesystem-unmount") -#define UDISKS2_JOB_OP_FS_MOUNT QLatin1String("filesystem-mount") -#define UDISKS2_JOB_OP_CLEANUP QLatin1String("cleanup") -#define UDISKS2_JOB_OF_FS_FORMAT QLatin1String("format-mkfs") +#define UDISKS2_JOB_OP_ENC_LOCK QLatin1String("encrypted-lock") +#define UDISKS2_JOB_OP_ENC_UNLOCK QLatin1String("encrypted-unlock") +#define UDISKS2_JOB_OP_FS_UNMOUNT QLatin1String("filesystem-unmount") +#define UDISKS2_JOB_OP_FS_MOUNT QLatin1String("filesystem-mount") +#define UDISKS2_JOB_OP_FS_SETLABEL QLatin1String("filesystem-setlabel") +#define UDISKS2_JOB_OP_CLEANUP QLatin1String("cleanup") +#define UDISKS2_JOB_OF_FS_FORMAT QLatin1String("format-mkfs") // Job keys #define UDISKS2_JOB_KEY_OPERATION QLatin1String("Operation") #define UDISKS2_JOB_KEY_OBJECTS QLatin1String("Objects") -// Lock, Unlock, Mount, Unmount, Format +// Lock, Unlock, Mount, Unmount, Format, SetLabel #define UDISKS2_BLOCK_DEVICE_PATH QString(QLatin1String("/org/freedesktop/UDisks2/block_devices/%1")) #define UDISKS2_BLOCK_FORMAT QLatin1String("Format") #define UDISKS2_ENCRYPTED_LOCK QLatin1String("Lock") @@ -83,6 +84,7 @@ Q_DECLARE_METATYPE(UDisks2::InterfacePropertyMap) #define UDISKS2_FILESYSTEM_MOUNT QLatin1String("Mount") #define UDISKS2_FILESYSTEM_UNMOUNT QLatin1String("Unmount") #define UDISKS2_BLOCK_RESCAN QLatin1String("Rescan") +#define UDISKS2_BLOCK_SETLABEL QLatin1String("SetLabel") // Errors #define UDISKS2_ERROR_DEVICE_BUSY QLatin1String("org.freedesktop.UDisks2.Error.DeviceBusy") diff --git a/src/udisks2job.cpp b/src/udisks2job.cpp index 4f28829..867ef8e 100644 --- a/src/udisks2job.cpp +++ b/src/udisks2job.cpp @@ -132,6 +132,8 @@ UDisks2::Job::Operation UDisks2::Job::operation() const return Lock; } else if (operation == UDISKS2_JOB_OP_ENC_UNLOCK) { return Unlock; + } else if (operation == UDISKS2_JOB_OP_FS_SETLABEL) { + return SetLabel; } else { return Unknown; } diff --git a/src/udisks2job_p.h b/src/udisks2job_p.h index c8dbd26..dee009c 100644 --- a/src/udisks2job_p.h +++ b/src/udisks2job_p.h @@ -58,6 +58,7 @@ class Job : public QObject Mount, Unmount, Format, + SetLabel, Unknown }; Q_ENUM(Operation) diff --git a/src/udisks2monitor.cpp b/src/udisks2monitor.cpp index add4be1..c6115b4 100644 --- a/src/udisks2monitor.cpp +++ b/src/udisks2monitor.cpp @@ -203,6 +203,26 @@ void UDisks2::Monitor::unmount(const QString &devicePath) startMountOperation(devicePath, UDISKS2_FILESYSTEM_UNMOUNT, m_blockDevices->objectPath(devicePath), arguments); } +void UDisks2::Monitor::setLabel(const QString &devicePath, const QString &label) +{ + if (devicePath.isEmpty()) { + qCCritical(lcMemoryCardLog) << "Cannot set label without device name"; + return; + } + + if (m_blockDevices->find(devicePath)) { + QVariantList arguments; + arguments << label; + QVariantMap options; + arguments << options; + + doSetLabel(devicePath, m_blockDevices->objectPath(devicePath), arguments); + } + else { + qCWarning(lcMemoryCardLog) << "Block device" << devicePath << "not found"; + } +} + void UDisks2::Monitor::format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments) { if (devicePath.isEmpty()) { @@ -651,6 +671,45 @@ void UDisks2::Monitor::doFormat(const QString &devicePath, const QString &dbusOb }); } +void UDisks2::Monitor::doSetLabel(const QString &devicePath, const QString &dbusObjectPath, const QVariantList &arguments) +{ + const QString dbusMethod = UDISKS2_BLOCK_SETLABEL; + if (devicePath.isEmpty()) { + qCCritical(lcMemoryCardLog) << "Cannot" << dbusMethod.toLower() << "without device name"; + return; + } + + QDBusMessage method = QDBusMessage::createMethodCall( + UDISKS2_SERVICE, + dbusObjectPath, + UDISKS2_FILESYSTEM_INTERFACE, + dbusMethod); + method.setArguments(arguments); + QDBusPendingCall pendingCall = QDBusConnection::systemBus().asyncCall(method); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, [this, devicePath, dbusMethod](QDBusPendingCallWatcher *watcher) { + if (watcher->isError()) { + QDBusError error = watcher->error(); + QByteArray errorData = error.name().toLocal8Bit(); + const char *errorCStr = errorData.constData(); + qCWarning(lcMemoryCardLog) << dbusMethod << "error:" << errorCStr; + + for (uint i = 0; i < sizeof(dbus_error_entries) / sizeof(ErrorEntry); i++) { + if (strcmp(dbus_error_entries[i].dbusErrorName, errorCStr) == 0) { + emit setLabelError(dbus_error_entries[i].errorCode); + break; + } + } + } + + emit status(devicePath, Partition::Unmounted); + watcher->deleteLater(); + }); + + emit status(devicePath, Partition::Renaming); +} + void UDisks2::Monitor::getBlockDevices() { QDBusInterface managerInterface(UDISKS2_SERVICE, diff --git a/src/udisks2monitor_p.h b/src/udisks2monitor_p.h index c2af9cd..b3ba437 100644 --- a/src/udisks2monitor_p.h +++ b/src/udisks2monitor_p.h @@ -86,6 +86,7 @@ class Monitor : public QObject void unmount(const QString &devicePath); void format(const QString &devicePath, const QString &filesystemType, const QVariantMap &arguments); + void setLabel(const QString &devicePath, const QString &label); signals: void status(const QString &devicePath, Partition::Status); @@ -95,12 +96,14 @@ class Monitor : public QObject void mountError(Partition::Error error); void unmountError(Partition::Error error); void formatError(Partition::Error error); + void setLabelError(Partition::Error error); private slots: void interfacesAdded(const QDBusObjectPath &objectPath, const UDisks2::InterfacePropertyMap &interfaces); void interfacesRemoved(const QDBusObjectPath &objectPath, const QStringList &interfaces); void doFormat(const QString &devicePath, const QString &dbusObjectPath, const QString &filesystemType, const QVariantMap &arguments); void handleNewBlock(UDisks2::Block *block); + void doSetLabel(const QString &devicePath, const QString &dbusObjectPath, const QVariantList &arguments); private: void setPartitionProperties(QExplicitlySharedDataPointer &partition, const Block *blockDevice);