From 93e9f529af68f6f5128514637496cb29629f3828 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Tue, 23 Jul 2019 15:30:14 +0800 Subject: [PATCH] file info and mount operation support --- CMakeLists.txt | 7 ++- gio-qt/CMakeLists.txt | 6 +- gio-qt/dgiofile.cpp | 21 +++++++ gio-qt/dgiofile.h | 2 + gio-qt/dgiofileinfo.cpp | 89 ++++++++++++++++++++++++++++ gio-qt/dgiofileinfo.h | 31 ++++++++++ gio-qt/dgiomount.cpp | 28 ++++++++- gio-qt/dgiomount.h | 3 + gio-qt/dgiomountoperation.cpp | 105 ++++++++++++++++++++++++++++++++++ gio-qt/dgiomountoperation.h | 47 +++++++++++++++ gio-qt/dgiovolume.cpp | 21 ++++++- gio-qt/dgiovolume.h | 3 + gio-qt/dgiovolumemanager.cpp | 1 + qgio-tools/main.cpp | 27 +++++++-- 14 files changed, 379 insertions(+), 12 deletions(-) create mode 100644 gio-qt/dgiofileinfo.cpp create mode 100644 gio-qt/dgiofileinfo.h create mode 100644 gio-qt/dgiomountoperation.cpp create mode 100644 gio-qt/dgiomountoperation.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d453899..9e029fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,11 +11,16 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_CXX_FLAGS "-g -Wall") set(QT_MINIMUM_VERSION "5.6.3") +# Install settings +if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX /usr) +endif () + # Find the QtWidgets library find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Core) find_package(PkgConfig) -pkg_check_modules(GTKMM gtkmm-3.0) # look into FindPkgConfig.cmake, +pkg_check_modules(GIOMM giomm-2.4) # look into FindPkgConfig.cmake, add_subdirectory (gio-qt) diff --git a/gio-qt/CMakeLists.txt b/gio-qt/CMakeLists.txt index 042509f..7ddc5c6 100644 --- a/gio-qt/CMakeLists.txt +++ b/gio-qt/CMakeLists.txt @@ -2,16 +2,20 @@ # TODO: portable headers? set (QGIO_PUBLIC_HEADER_FILES dgiovolumemanager.h + dgiomountoperation.h dgiomount.h dgiovolume.h dgiofile.h + dgiofileinfo.h ) set (QGIO_PRIVATE_CPP_FILES dgiovolumemanager.cpp + dgiomountoperation.cpp dgiomount.cpp dgiovolume.cpp dgiofile.cpp + dgiofileinfo.cpp ) # Library @@ -22,7 +26,7 @@ add_library (gio-qt STATIC target_include_directories(gio-qt PRIVATE - ${GTKMM_INCLUDE_DIRS} + ${GIOMM_INCLUDE_DIRS} PUBLIC ${CMAKE_CURRENT_LIST_DIR} ) diff --git a/gio-qt/dgiofile.cpp b/gio-qt/dgiofile.cpp index f898bb6..dec6298 100644 --- a/gio-qt/dgiofile.cpp +++ b/gio-qt/dgiofile.cpp @@ -1,10 +1,13 @@ #include "dgiofile.h" +#include "dgiofileinfo.h" #include #include #include +#include + using namespace Gio; class DGioFilePrivate @@ -69,6 +72,7 @@ DGioFile *DGioFile::createFromPath(QString path, QObject *parent) // ensure GIO got initialized Gio::init(); + // File::create_for_path never falls. Glib::RefPtr gmmFile = File::create_for_path(path.toStdString()); return new DGioFile(gmmFile.release(), parent); @@ -94,3 +98,20 @@ QString DGioFile::uri() const return d->uri(); } + +QExplicitlySharedDataPointer DGioFile::createFileSystemInfo() +{ + Q_D(DGioFile); + + try { + Glib::RefPtr gmmFileInfo = d->getGmmFileInstance()->query_filesystem_info("filesystem::*"); + if (gmmFileInfo) { + QExplicitlySharedDataPointer fileInfoPtr(new DGioFileInfo(gmmFileInfo.release())); + return fileInfoPtr; + } + } catch (Glib::Error error) { + qDebug() << QString::fromStdString(error.what().raw()); + } + + return QExplicitlySharedDataPointer(nullptr); +} diff --git a/gio-qt/dgiofile.h b/gio-qt/dgiofile.h index 99e9bef..8b76f28 100644 --- a/gio-qt/dgiofile.h +++ b/gio-qt/dgiofile.h @@ -8,6 +8,7 @@ namespace Gio { class File; } +class DGioFileInfo; class DGioFilePrivate; class DGioFile : public QObject, public QSharedData { @@ -21,6 +22,7 @@ public: QString basename() const; QString path() const; QString uri() const; + QExplicitlySharedDataPointer createFileSystemInfo(); private: QScopedPointer d_ptr; diff --git a/gio-qt/dgiofileinfo.cpp b/gio-qt/dgiofileinfo.cpp new file mode 100644 index 0000000..758b774 --- /dev/null +++ b/gio-qt/dgiofileinfo.cpp @@ -0,0 +1,89 @@ +#include "dgiofileinfo.h" + +#include + +using namespace Gio; + +class DGioFileInfoPrivate +{ +public: + DGioFileInfoPrivate(DGioFileInfo *qq, FileInfo *gmmFileInfoPtr); + + Glib::RefPtr getGmmFileInfoInstance() const; + + bool getAttributeBoolean(const std::string &attribute) const; + quint64 getAttributeUint64(const std::string &attribute) const; + +private: + Glib::RefPtr m_gmmFileInfoPtr; + + QString uri() const; + + DGioFileInfo *q_ptr; + + Q_DECLARE_PUBLIC(DGioFileInfo) +}; + +DGioFileInfoPrivate::DGioFileInfoPrivate(DGioFileInfo *qq, FileInfo *gmmFileInfoPtr) + : m_gmmFileInfoPtr(gmmFileInfoPtr) + , q_ptr(qq) +{ + +} + +Glib::RefPtr DGioFileInfoPrivate::getGmmFileInfoInstance() const +{ + return m_gmmFileInfoPtr; +} + +bool DGioFileInfoPrivate::getAttributeBoolean(const std::string &attribute) const +{ + return m_gmmFileInfoPtr->get_attribute_boolean(attribute); +} + +quint64 DGioFileInfoPrivate::getAttributeUint64(const std::string &attribute) const +{ + return m_gmmFileInfoPtr->get_attribute_uint64(attribute); +} + +// ------------------------------------------------------------- + +DGioFileInfo::DGioFileInfo(FileInfo *gmmFileInfoInfoPtr, QObject *parent) + : QObject(parent) + , d_ptr(new DGioFileInfoPrivate(this, gmmFileInfoInfoPtr)) +{ + +} + +DGioFileInfo::~DGioFileInfo() +{ + +} + +bool DGioFileInfo::isReadOnly() const +{ + Q_D(const DGioFileInfo); + + return d->getAttributeBoolean(G_FILE_ATTRIBUTE_FILESYSTEM_READONLY); +} + +quint64 DGioFileInfo::fsTotalBytes() const +{ + Q_D(const DGioFileInfo); + + return d->getAttributeUint64(G_FILE_ATTRIBUTE_FILESYSTEM_SIZE); +} + +quint64 DGioFileInfo::fsUsedBytes() const +{ + Q_D(const DGioFileInfo); + + return d->getAttributeUint64(G_FILE_ATTRIBUTE_FILESYSTEM_USED); +} + +quint64 DGioFileInfo::fsFreeBytes() const +{ + Q_D(const DGioFileInfo); + + return d->getAttributeUint64(G_FILE_ATTRIBUTE_FILESYSTEM_FREE); +} diff --git a/gio-qt/dgiofileinfo.h b/gio-qt/dgiofileinfo.h new file mode 100644 index 0000000..f2ac0f2 --- /dev/null +++ b/gio-qt/dgiofileinfo.h @@ -0,0 +1,31 @@ +#ifndef DGIOFILEINFO_H +#define DGIOFILEINFO_H + +#include +#include + +namespace Gio { +class FileInfo; +} + +class DGioFileInfoPrivate; +class DGioFileInfo : public QObject, public QSharedData +{ + Q_OBJECT +public: + explicit DGioFileInfo(Gio::FileInfo *gmmFileInfoInfoPtr, QObject *parent = nullptr); + ~DGioFileInfo(); + + bool isReadOnly() const; + + quint64 fsTotalBytes() const; + quint64 fsUsedBytes() const; + quint64 fsFreeBytes() const; + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DGioFileInfo) +}; + +#endif // DGIOFILEINFO_H diff --git a/gio-qt/dgiomount.cpp b/gio-qt/dgiomount.cpp index 9765a0e..8b095b3 100644 --- a/gio-qt/dgiomount.cpp +++ b/gio-qt/dgiomount.cpp @@ -1,5 +1,6 @@ #include "dgiomount.h" #include "dgiovolume.h" +#include "dgiofile.h" #include @@ -198,13 +199,36 @@ void DGioMount::unmount(bool forceUnmount) return d->getGmmMountInstance()->unmount(forceUnmount ? MOUNT_UNMOUNT_FORCE : MOUNT_UNMOUNT_NONE); } +QExplicitlySharedDataPointer DGioMount::getRootFile() +{ + Q_D(const DGioMount); + + Glib::RefPtr file = d->getGmmMountInstance()->get_root(); + QExplicitlySharedDataPointer filePtr(new DGioFile(file.release())); + + return filePtr; +} + +QExplicitlySharedDataPointer DGioMount::getDefaultLocationFile() +{ + Q_D(const DGioMount); + + Glib::RefPtr file = d->getGmmMountInstance()->get_default_location(); + QExplicitlySharedDataPointer filePtr(new DGioFile(file.release())); + + return filePtr; +} + QExplicitlySharedDataPointer DGioMount::getVolume() { Q_D(const DGioMount); Glib::RefPtr vol = d->getGmmMountInstance()->get_volume(); - QExplicitlySharedDataPointer volPtr(new DGioVolume(vol.release())); + if (vol) { + QExplicitlySharedDataPointer volPtr(new DGioVolume(vol.release())); + return volPtr; + } - return volPtr; + return QExplicitlySharedDataPointer(nullptr); } diff --git a/gio-qt/dgiomount.h b/gio-qt/dgiomount.h index 1157809..12873d4 100644 --- a/gio-qt/dgiomount.h +++ b/gio-qt/dgiomount.h @@ -8,6 +8,7 @@ namespace Gio { class Mount; } +class DGioFile; class DGioVolume; class DGioMountPrivate; class DGioMount : public QObject, public QSharedData @@ -28,6 +29,8 @@ public: void unmount(bool forceUnmount = false); + QExplicitlySharedDataPointer getRootFile(); + QExplicitlySharedDataPointer getDefaultLocationFile(); QExplicitlySharedDataPointer getVolume(); private: diff --git a/gio-qt/dgiomountoperation.cpp b/gio-qt/dgiomountoperation.cpp new file mode 100644 index 0000000..9526eea --- /dev/null +++ b/gio-qt/dgiomountoperation.cpp @@ -0,0 +1,105 @@ +#include "dgiomountoperation.h" + +#include + +using namespace Gio; + +class DGioMountOperationPrivate +{ + DGioMountOperationPrivate(DGioMountOperation *qq); + + Glib::RefPtr getGmmMountOperationInstance() const; + + QString username() const; + + void slot_askPassword(const Glib::ustring& message, const Glib::ustring& default_user, const Glib::ustring& default_domain, AskPasswordFlags flags); + void slot_askQuestion(const Glib::ustring& message, const Glib::StringArrayHandle& choices); + void slot_showUnmountProgress(const Glib::ustring &message, gint64 time_left, gint64 bytes_left); + +private: + Glib::RefPtr m_gmmMountOperationPtr; + + DGioMountOperation *q_ptr; + + Q_DECLARE_PUBLIC(DGioMountOperation) +}; + +DGioMountOperationPrivate::DGioMountOperationPrivate(DGioMountOperation *qq) + : q_ptr(qq) +{ + m_gmmMountOperationPtr = Gio::MountOperation::create(); + + m_gmmMountOperationPtr->signal_ask_password().connect(sigc::mem_fun(*this, &DGioMountOperationPrivate::slot_askPassword)); + m_gmmMountOperationPtr->signal_ask_question().connect(sigc::mem_fun(*this, &DGioMountOperationPrivate::slot_askQuestion)); + m_gmmMountOperationPtr->signal_show_unmount_progress().connect(sigc::mem_fun(*this, &DGioMountOperationPrivate::slot_showUnmountProgress)); +} + +Glib::RefPtr DGioMountOperationPrivate::getGmmMountOperationInstance() const +{ + return m_gmmMountOperationPtr; +} + +QString DGioMountOperationPrivate::username() const +{ + return QString::fromStdString(m_gmmMountOperationPtr->get_username().raw()); +} + +void DGioMountOperationPrivate::slot_askPassword(const Glib::ustring &message, const Glib::ustring &default_user, const Glib::ustring &default_domain, AskPasswordFlags flags) +{ + Q_Q(DGioMountOperation); + + QString msg = QString::fromStdString(message.raw()); + QString defaultUser = QString::fromStdString(default_user.raw()); + QString defaultDomain = QString::fromStdString(default_domain.raw()); + DGioAskPasswordFlags askPasswordFlags = static_cast(flags); + + Q_EMIT q->askPassword(msg, defaultUser, defaultDomain, askPasswordFlags); +} + +void DGioMountOperationPrivate::slot_askQuestion(const Glib::ustring &message, const Glib::StringArrayHandle &choices) +{ + Q_Q(DGioMountOperation); + + QString msg = QString::fromStdString(message.raw()); + QStringList choiceList; + for (auto oneChoice : choices) { + choiceList.append(QString::fromStdString(oneChoice.raw())); + } + + Q_EMIT q->askQuestion(msg, choiceList); +} + +void DGioMountOperationPrivate::slot_showUnmountProgress(const Glib::ustring& message, gint64 time_left, gint64 bytes_left) +{ + Q_Q(DGioMountOperation); + + Q_EMIT q->showUnmountProgress(QString::fromStdString(message.raw()), time_left, bytes_left); +} + +// ------------------------------------------------------------- + +DGioMountOperation::DGioMountOperation(QObject *parent) + : QObject(parent) + , d_ptr(new DGioMountOperationPrivate(this)) +{ + +} + +DGioMountOperation::~DGioMountOperation() +{ + +} + +QString DGioMountOperation::username() const +{ + Q_D(const DGioMountOperation); + + return d->username(); +} + +void DGioMountOperation::reply(DGioMountOperationResult result) +{ + Q_D(DGioMountOperation); + + d->getGmmMountOperationInstance()->reply(static_cast(result)); +} diff --git a/gio-qt/dgiomountoperation.h b/gio-qt/dgiomountoperation.h new file mode 100644 index 0000000..dc1f583 --- /dev/null +++ b/gio-qt/dgiomountoperation.h @@ -0,0 +1,47 @@ +#ifndef DGIOMOUNTOPERATION_H +#define DGIOMOUNTOPERATION_H + +#include + +enum DGioAskPasswordFlag +{ + ASK_PASSWORD_NEED_PASSWORD = (1 << 0), + ASK_PASSWORD_NEED_USERNAME = (1 << 1), + ASK_PASSWORD_NEED_DOMAIN = (1 << 2), + ASK_PASSWORD_SAVING_SUPPORTED = (1 << 3), + ASK_PASSWORD_ANONYMOUS_SUPPORTED = (1 << 4) +}; +Q_DECLARE_FLAGS(DGioAskPasswordFlags, DGioAskPasswordFlag) + +enum DGioMountOperationResult +{ + MOUNT_OPERATION_HANDLED, + MOUNT_OPERATION_ABORTED, + MOUNT_OPERATION_UNHANDLED +}; +Q_ENUMS(DGioMountOperationResult); + +class DGioMountOperationPrivate; +class DGioMountOperation : public QObject +{ + Q_OBJECT +public: + explicit DGioMountOperation(QObject *parent); + ~DGioMountOperation(); + + QString username() const; + + void reply(DGioMountOperationResult result); + +Q_SIGNALS: + void askPassword(QString message, QString defaultUser, QString defaultDomain, DGioAskPasswordFlags flags); + void askQuestion(QString message, QStringList choices); + void showUnmountProgress(QString message, qint64 timeLeftMs, qint64 bytesLeft); + +private: + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(DGioMountOperation) +}; + +#endif // DGIOMOUNTOPERATION_H diff --git a/gio-qt/dgiovolume.cpp b/gio-qt/dgiovolume.cpp index a156cbf..4a4f54f 100644 --- a/gio-qt/dgiovolume.cpp +++ b/gio-qt/dgiovolume.cpp @@ -1,3 +1,4 @@ +#include "dgiomount.h" #include "dgiovolume.h" #include @@ -12,7 +13,7 @@ class DGioVolumePrivate public: DGioVolumePrivate(DGioVolume *qq, Volume *gmmVolumePtr); - Glib::RefPtr getGmmVolumeInstance() const; + Glib::RefPtr getGmmVolumeInstance() const; QString name() const; @@ -28,7 +29,12 @@ DGioVolumePrivate::DGioVolumePrivate(DGioVolume *qq, Volume *gmmVolumePtr) : m_gmmVolumePtr(gmmVolumePtr) , q_ptr(qq) { -// m_gvolumePtr = Glib::wrap(gvolumePtr); + // m_gvolumePtr = Glib::wrap(gvolumePtr); +} + +Glib::RefPtr DGioVolumePrivate::getGmmVolumeInstance() const +{ + return m_gmmVolumePtr; } QString DGioVolumePrivate::name() const @@ -57,3 +63,14 @@ QString DGioVolume::name() const return d->name(); } + +// Return value can be nullptr +QExplicitlySharedDataPointer DGioVolume::getMount() +{ + Q_D(DGioVolume); + + Glib::RefPtr mnt = d->getGmmVolumeInstance()->get_mount(); + QExplicitlySharedDataPointer mntPtr(new DGioMount(mnt.release())); + + return mntPtr; +} diff --git a/gio-qt/dgiovolume.h b/gio-qt/dgiovolume.h index cae99a9..a8e08c1 100644 --- a/gio-qt/dgiovolume.h +++ b/gio-qt/dgiovolume.h @@ -8,6 +8,7 @@ namespace Gio { class Volume; } +class DGioMount; class DGioVolumePrivate; class DGioVolume : public QObject, public QSharedData { @@ -18,6 +19,8 @@ public: QString name() const; + QExplicitlySharedDataPointer getMount(); + private: QScopedPointer d_ptr; diff --git a/gio-qt/dgiovolumemanager.cpp b/gio-qt/dgiovolumemanager.cpp index 3f94f12..c39f9d4 100644 --- a/gio-qt/dgiovolumemanager.cpp +++ b/gio-qt/dgiovolumemanager.cpp @@ -85,6 +85,7 @@ void DGioVolumeManagerPrivate::slot_mountChanged(const Glib::RefPtr &gmmM Q_EMIT q->mountChanged(mount); } +// ------------------------------------------------------------- DGioVolumeManager::DGioVolumeManager(QObject *parent) : QObject(parent) diff --git a/qgio-tools/main.cpp b/qgio-tools/main.cpp index 5c696dc..fa2ce0b 100644 --- a/qgio-tools/main.cpp +++ b/qgio-tools/main.cpp @@ -6,26 +6,41 @@ #include #include #include +#include int main(int argc, char * argv[]) { - DGioMount * m = DGioMount::createFromPath("/media/wzc/aaaaaaaaaaaaaaaa"); - if (m) { - qDebug() << m->name() << m->themedIconNames(); - delete m; - } - DGioFile * f = DGioFile::createFromPath("/media/wzc/aaaaaaaaaaaaaaaa"); if (f) { qDebug() << f->basename() << f->path() << f->uri(); + QExplicitlySharedDataPointer fi = f->createFileSystemInfo(); + if (fi) { + qDebug() << fi->fsFreeBytes() << fi->fsUsedBytes() << fi->fsTotalBytes(); + } delete f; } qDebug() << "----------------------"; + DGioMount * m = DGioMount::createFromPath("/media/wzc/aaaaaaaaaaaaaaaa"); + if (m) { + QExplicitlySharedDataPointer f = m->getRootFile(); + QExplicitlySharedDataPointer f2 = m->getDefaultLocationFile(); + qDebug() << m->name() << m->themedIconNames() << f->createFileSystemInfo()->fsTotalBytes() << f->uri() << f2->uri(); + qDebug() << m->name() << m->themedIconNames() << f->createFileSystemInfo()->fsTotalBytes() << f->uri() << f2->uri(); +// m->unmount(); + delete m; + } + + qDebug() << "----------------------"; + const QList > mnts = DGioVolumeManager::getMounts(); for (const QExplicitlySharedDataPointer &p : mnts) { + QExplicitlySharedDataPointer f = p->getRootFile(); + QExplicitlySharedDataPointer f2 = p->getDefaultLocationFile(); + qDebug() << f->uri() << f2->uri() << f->path() << f2->path(); + qDebug() << f->uri() << f2->uri(); qDebug() << p->name() << p->uuid() << p->canUnmount() << p->themedIconNames() << p->themedIconNames(); }