basic volume and mount info support

This commit is contained in:
Gary Wang 2019-07-20 15:16:36 +08:00
parent eb1e0416af
commit 7dfe0ef097
10 changed files with 474 additions and 43 deletions

View File

@ -4,12 +4,14 @@ set (QGIO_PUBLIC_HEADER_FILES
dgiovolumemanager.h
dgiomount.h
dgiovolume.h
dgiofile.h
)
set (QGIO_PRIVATE_CPP_FILES
dgiovolumemanager.cpp
dgiomount.cpp
dgiovolume.cpp
dgiofile.cpp
)
# Library

96
gio-qt/dgiofile.cpp Normal file
View File

@ -0,0 +1,96 @@
#include "dgiofile.h"
#include <glibmm/refptr.h>
#include <giomm/init.h>
#include <giomm/file.h>
using namespace Gio;
class DGioFilePrivate
{
public:
DGioFilePrivate(DGioFile *qq, File *gmmFilePtr);
Glib::RefPtr<File> getGmmFileInstance() const;
private:
Glib::RefPtr<File> m_gmmFilePtr;
QString uri() const;
DGioFile *q_ptr;
Q_DECLARE_PUBLIC(DGioFile)
};
DGioFilePrivate::DGioFilePrivate(DGioFile *qq, File *gmmFilePtr)
: m_gmmFilePtr(gmmFilePtr)
, q_ptr(qq)
{
}
Glib::RefPtr<File> DGioFilePrivate::getGmmFileInstance() const
{
return m_gmmFilePtr;
}
QString DGioFilePrivate::uri() const
{
return QString::fromStdString(m_gmmFilePtr->get_uri());
}
// -------------------------------------------------------------
DGioFile::DGioFile(File* gmmFilePtr, QObject *parent)
: QObject(parent)
, d_ptr(new DGioFilePrivate(this, gmmFilePtr))
{
// gmountPtr must be vaild;
Q_CHECK_PTR(gmmFilePtr);
}
DGioFile::~DGioFile()
{
}
/*!
* \brief Create a DGioFile instance by given \a path
*
* This operation never fails since Gio::File::create_for_path never fails, but the returned
* object might not support any I/O operation if path is malformed.
*
* \return the created DGioFile instance
*/
DGioFile *DGioFile::createFromPath(QString path, QObject *parent)
{
// ensure GIO got initialized
Gio::init();
Glib::RefPtr<File> gmmFile = File::create_for_path(path.toStdString());
return new DGioFile(gmmFile.release(), parent);
}
QString DGioFile::basename() const
{
Q_D(const DGioFile);
return QString::fromStdString(d->getGmmFileInstance()->get_basename());
}
QString DGioFile::path() const
{
Q_D(const DGioFile);
return QString::fromStdString(d->getGmmFileInstance()->get_path());
}
QString DGioFile::uri() const
{
Q_D(const DGioFile);
return d->uri();
}

31
gio-qt/dgiofile.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef DGIOFILE_H
#define DGIOFILE_H
#include <QObject>
#include <QSharedData>
namespace Gio {
class File;
}
class DGioFilePrivate;
class DGioFile : public QObject, public QSharedData
{
Q_OBJECT
public:
explicit DGioFile(Gio::File *gmmFilePtr, QObject *parent = nullptr);
~DGioFile();
static DGioFile * createFromPath(QString path, QObject *parent = nullptr);
QString basename() const;
QString path() const;
QString uri() const;
private:
QScopedPointer<DGioFilePrivate> d_ptr;
Q_DECLARE_PRIVATE(DGioFile)
};
#endif // DGIOFILE_H

View File

@ -1,7 +1,12 @@
#include "dgiomount.h"
#include "dgiovolume.h"
#include <glibmm/refptr.h>
#include <giomm/init.h>
#include <giomm/file.h>
#include <giomm/volume.h>
#include <giomm/themedicon.h>
#include <QDebug>
@ -10,9 +15,9 @@ using namespace Gio;
class DGioMountPrivate
{
public:
DGioMountPrivate(DGioMount *qq, Mount *gmountPtr);
DGioMountPrivate(DGioMount *qq, Mount *gmmMountPtr);
Glib::RefPtr<Mount> getGMountInstance() const;
Glib::RefPtr<Mount> getGmmMountInstance() const;
QString name() const;
QString uuid() const;
@ -20,43 +25,43 @@ public:
bool canEject() const;
private:
Glib::RefPtr<Mount> m_gmountPtr;
Glib::RefPtr<Mount> m_gmmMountPtr;
DGioMount *q_ptr;
Q_DECLARE_PUBLIC(DGioMount)
};
DGioMountPrivate::DGioMountPrivate(DGioMount *qq, Mount *gmountPtr)
: m_gmountPtr(gmountPtr)
DGioMountPrivate::DGioMountPrivate(DGioMount *qq, Mount *gmmMountPtr)
: m_gmmMountPtr(gmmMountPtr)
, q_ptr(qq)
{
}
Glib::RefPtr<Mount> DGioMountPrivate::getGMountInstance() const
Glib::RefPtr<Mount> DGioMountPrivate::getGmmMountInstance() const
{
return m_gmountPtr;
return m_gmmMountPtr;
}
QString DGioMountPrivate::name() const
{
return QString::fromStdString(m_gmountPtr->get_name());
return QString::fromStdString(m_gmmMountPtr->get_name());
}
QString DGioMountPrivate::uuid() const
{
return QString::fromStdString(m_gmountPtr->get_uuid());
return QString::fromStdString(m_gmmMountPtr->get_uuid());
}
// -------------------------------------------------------------
DGioMount::DGioMount(Mount* gmountPtr, QObject *parent)
DGioMount::DGioMount(Mount* gmmMountPtr, QObject *parent)
: QObject(parent)
, d_ptr(new DGioMountPrivate(this, gmountPtr))
, d_ptr(new DGioMountPrivate(this, gmmMountPtr))
{
// gmountPtr must be vaild;
Q_CHECK_PTR(gmountPtr);
Q_CHECK_PTR(gmmMountPtr);
}
DGioMount::~DGioMount()
@ -64,13 +69,21 @@ DGioMount::~DGioMount()
}
/*!
* \brief Create a DGioMount instance by a given \a path
*
* \return the created DGioMount instance or nullptr if failed.
*/
DGioMount *DGioMount::createFromPath(QString path, QObject *parent)
{
Glib::RefPtr<File> gfile = File::create_for_path(path.toStdString());
// ensure GIO got initialized
Gio::init();
Glib::RefPtr<File> gmmFile = File::create_for_path(path.toStdString());
try {
Glib::RefPtr<Mount> gmount = gfile->find_enclosing_mount();
if (gmount) {
return new DGioMount(gmount.release(), parent);
Glib::RefPtr<Mount> gmmMount = gmmFile->find_enclosing_mount();
if (gmmMount) {
return new DGioMount(gmmMount.release(), parent);
}
} catch (Glib::Error error) {
qDebug() << QString::fromStdString(error.what().raw());
@ -93,17 +106,105 @@ QString DGioMount::uuid() const
return d->uuid();
}
/*!
* \brief Determines if mount is shadowed.
*
* A mount is said to be shadowed if there exists one or more user visible objects (currently Mount objects)
* with a root that is inside the root of mount.
*
* One application of shadow mounts is when exposing a single file system that is used to address several
* logical volumes. In this situation, a Gio::VolumeMonitor implementation would create two Gio::Volume
* objects, in gio-qt, DGioVolumeManager will create two DGioVolume objects.
*
* For example, one for the camera functionality of the device and one for a SD card reader on the device) with
* activation URIs gphoto2://[usb:001,002]/store1/ and gphoto2://[usb:001,002]/store2/. When the underlying
* mount (with root gphoto2://[usb:001,002]/) is mounted, said VolumeMonitor implementation would create two
* Mount objects (each with their root matching the corresponding volume activation root) that would shadow
* the original mount.
*
* \return true if mount is shadowed
*/
bool DGioMount::isShadowed() const
{
Q_D(const DGioMount);
return d->getGmmMountInstance()->is_shadowed();
}
bool DGioMount::canUnmount() const
{
Q_D(const DGioMount);
return d->getGMountInstance()->can_unmount();
return d->getGmmMountInstance()->can_unmount();
}
bool DGioMount::canEject() const
{
Q_D(const DGioMount);
return d->getGMountInstance()->can_eject();
return d->getGmmMountInstance()->can_eject();
}
QStringList DGioMount::themedIconNames() const
{
Q_D(const DGioMount);
QStringList iconNames;
Glib::RefPtr<const Icon> icon = d->getGmmMountInstance()->get_icon();
Glib::RefPtr<const ThemedIcon> themedIcon = Glib::RefPtr<const ThemedIcon>::cast_dynamic(icon);
// if (G_IS_THEMED_ICON(themedIcon->gobj()) ) {
// qDebug() << "Yes and";
// }
// if (themedIcon) {
// qDebug() << "Yes";
// }
if (themedIcon) {
QStringList iconNames;
char **names;
char **iter;
names = NULL;
g_object_get(G_THEMED_ICON(themedIcon->gobj()), "names", &names, NULL);
for (iter = names; *iter; iter++) {
iconNames.append(QString(*iter));
}
g_strfreev(names);
return iconNames;
}
// return {QStringList::fromStdList(themedIcon->get_names())};
// char* name = 0;
// g_object_get(G_OBJECT(themedIcon->gobj()), "name", &name, NULL);
// return {QString(name)};
// if (themedIcon) {
// auto ustring_names = themedIcon->get_names();
//// for (const Glib::ustring &str : ustring_names) {
//// iconNames.append(QString::fromStdString(str.raw()));
//// }
// }
return iconNames;
}
void DGioMount::unmount(bool forceUnmount)
{
Q_D(const DGioMount);
return d->getGmmMountInstance()->unmount(forceUnmount ? MOUNT_UNMOUNT_FORCE : MOUNT_UNMOUNT_NONE);
}
QExplicitlySharedDataPointer<DGioVolume> DGioMount::getVolume()
{
Q_D(const DGioMount);
Glib::RefPtr<Volume> vol = d->getGmmMountInstance()->get_volume();
QExplicitlySharedDataPointer<DGioVolume> volPtr(new DGioVolume(vol.release()));
return volPtr;
}

View File

@ -8,20 +8,27 @@ namespace Gio {
class Mount;
}
class DGioVolume;
class DGioMountPrivate;
class DGioMount : public QObject, public QSharedData
{
Q_OBJECT
public:
explicit DGioMount(Gio::Mount *gmountPtr, QObject *parent = nullptr);
explicit DGioMount(Gio::Mount *gmmMountPtr, QObject *parent = nullptr);
~DGioMount();
static DGioMount * createFromPath(QString path, QObject *parent = nullptr);
QString name() const;
QString uuid() const;
bool isShadowed() const;
bool canUnmount() const;
bool canEject() const;
QStringList themedIconNames() const;
void unmount(bool forceUnmount = false);
QExplicitlySharedDataPointer<DGioVolume> getVolume();
private:
QScopedPointer<DGioMountPrivate> d_ptr;

View File

@ -1,6 +1,59 @@
#include "dgiovolume.h"
DGioVolume::DGioVolume()
#include <glibmm/refptr.h>
#include <giomm/volume.h>
#include <QDebug>
using namespace Gio;
class DGioVolumePrivate
{
public:
DGioVolumePrivate(DGioVolume *qq, Volume *gmmVolumePtr);
Glib::RefPtr<Mount> getGmmVolumeInstance() const;
QString name() const;
private:
Glib::RefPtr<Volume> m_gmmVolumePtr;
DGioVolume *q_ptr;
Q_DECLARE_PUBLIC(DGioVolume)
};
DGioVolumePrivate::DGioVolumePrivate(DGioVolume *qq, Volume *gmmVolumePtr)
: m_gmmVolumePtr(gmmVolumePtr)
, q_ptr(qq)
{
// m_gvolumePtr = Glib::wrap(gvolumePtr);
}
QString DGioVolumePrivate::name() const
{
return QString::fromStdString(m_gmmVolumePtr->get_name());
}
// -------------------------------------------------------------
DGioVolume::DGioVolume(Volume* gmmVolumePtr, QObject *parent)
: QObject(parent)
, d_ptr(new DGioVolumePrivate(this, gmmVolumePtr))
{
// gvolumePtr must be vaild;
Q_CHECK_PTR(gmmVolumePtr);
}
DGioVolume::~DGioVolume()
{
}
QString DGioVolume::name() const
{
Q_D(const DGioVolume);
return d->name();
}

View File

@ -1,11 +1,27 @@
#ifndef DGIOVOLUME_H
#define DGIOVOLUME_H
#include <QObject>
#include <QSharedData>
class DGioVolume
namespace Gio {
class Volume;
}
class DGioVolumePrivate;
class DGioVolume : public QObject, public QSharedData
{
Q_OBJECT
public:
DGioVolume();
explicit DGioVolume(Gio::Volume *gmmVolumePtr, QObject *parent = nullptr);
~DGioVolume();
QString name() const;
private:
QScopedPointer<DGioVolumePrivate> d_ptr;
Q_DECLARE_PRIVATE(DGioVolume)
};
#endif // DGIOVOLUME_H

View File

@ -1,10 +1,10 @@
#include "dgiomount.h"
#include "dgiovolume.h"
#include "dgiovolumemanager.h"
#include <glibmm.h>
#include <giomm.h>
#include <glibmm/refptr.h>
#include <giomm/init.h>
#include <giomm/volumemonitor.h>
using namespace Gio;
@ -14,15 +14,75 @@ class DGioVolumeManagerPrivate
DGioVolumeManagerPrivate(DGioVolumeManager *qq);
private:
Glib::RefPtr<VolumeMonitor> m_gmmVolumeMonitorPtr;
DGioVolumeManager *q_ptr;
void slot_mountAdded(const Glib::RefPtr< Mount >& gmmMount);
void slot_mountRemoved(const Glib::RefPtr< Mount >& gmmMount);
void slot_mountPreRemoved(const Glib::RefPtr< Mount >& gmmMount);
void slot_mountChanged(const Glib::RefPtr< Mount >& gmmMount);
Q_DECLARE_PUBLIC(DGioVolumeManager)
};
DGioVolumeManagerPrivate::DGioVolumeManagerPrivate(DGioVolumeManager *qq)
: q_ptr(qq)
{
// Do Gio's init or things like Gio::VolumeMonitor::get() won't working
// Gio::init() will also call Glib::init() so we don't need to call it again.
Gio::init();
m_gmmVolumeMonitorPtr = VolumeMonitor::get();
m_gmmVolumeMonitorPtr->signal_mount_added().connect(sigc::mem_fun(*this, &DGioVolumeManagerPrivate::slot_mountAdded));
m_gmmVolumeMonitorPtr->signal_mount_removed().connect(sigc::mem_fun(*this, &DGioVolumeManagerPrivate::slot_mountRemoved));
m_gmmVolumeMonitorPtr->signal_mount_pre_unmount().connect(sigc::mem_fun(*this, &DGioVolumeManagerPrivate::slot_mountPreRemoved));
m_gmmVolumeMonitorPtr->signal_mount_changed().connect(sigc::mem_fun(*this, &DGioVolumeManagerPrivate::slot_mountChanged));
}
void DGioVolumeManagerPrivate::slot_mountAdded(const Glib::RefPtr<Mount> &gmmMount)
{
Q_Q(DGioVolumeManager);
Glib::RefPtr<Mount> copy(gmmMount);
QExplicitlySharedDataPointer<DGioMount> mount(new DGioMount(copy.release()));
Q_EMIT q->mountAdded(mount);
}
void DGioVolumeManagerPrivate::slot_mountRemoved(const Glib::RefPtr<Mount> &gmmMount)
{
Q_Q(DGioVolumeManager);
Glib::RefPtr<Mount> copy(gmmMount);
QExplicitlySharedDataPointer<DGioMount> mount(new DGioMount(copy.release()));
Q_EMIT q->mountRemoved(mount);
}
void DGioVolumeManagerPrivate::slot_mountPreRemoved(const Glib::RefPtr<Mount> &gmmMount)
{
Q_Q(DGioVolumeManager);
Glib::RefPtr<Mount> copy(gmmMount);
QExplicitlySharedDataPointer<DGioMount> mount(new DGioMount(copy.release()));
Q_EMIT q->mountPreRemoved(mount);
}
void DGioVolumeManagerPrivate::slot_mountChanged(const Glib::RefPtr<Mount> &gmmMount)
{
Q_Q(DGioVolumeManager);
Glib::RefPtr<Mount> copy(gmmMount);
QExplicitlySharedDataPointer<DGioMount> mount(new DGioMount(copy.release()));
Q_EMIT q->mountChanged(mount);
}
@ -30,24 +90,24 @@ DGioVolumeManager::DGioVolumeManager(QObject *parent)
: QObject(parent)
, d_ptr(new DGioVolumeManagerPrivate(this))
{
// Do Gio's init or things like Gio::VolumeMonitor::get() won't working
// can we init it multiple times?
Glib::init();
Gio::init();
}
DGioVolumeManager::~DGioVolumeManager()
{
//
}
const QList<QExplicitlySharedDataPointer<DGioMount> > DGioVolumeManager::getMounts()
{
// ensure GIO got initialized
Gio::init();
QList<QExplicitlySharedDataPointer<DGioMount> > mounts;
Glib::RefPtr<VolumeMonitor> vm = Gio::VolumeMonitor::get();
Glib::ListHandle<Glib::RefPtr<Mount>> mnt = vm->get_mounts();
Glib::ListHandle<Glib::RefPtr<Mount> > mnt = vm->get_mounts();
for (Glib::RefPtr<Mount> oneMnt : mnt) {
QExplicitlySharedDataPointer<DGioMount> mntPtr(new DGioMount(oneMnt.release()));
@ -56,3 +116,22 @@ const QList<QExplicitlySharedDataPointer<DGioMount> > DGioVolumeManager::getMoun
return mounts;
}
const QList<QExplicitlySharedDataPointer<DGioVolume> > DGioVolumeManager::getVolumes()
{
// ensure GIO got initialized
Gio::init();
QList<QExplicitlySharedDataPointer<DGioVolume> > volumes;
Glib::RefPtr<VolumeMonitor> vm = Gio::VolumeMonitor::get();
Glib::ListHandle<Glib::RefPtr<Volume> > vol = vm->get_volumes();
for (Glib::RefPtr<Volume> oneVol : vol) {
QExplicitlySharedDataPointer<DGioVolume> volPtr(new DGioVolume(oneVol.release()));
volumes.append(volPtr);
}
return volumes;
}

View File

@ -4,10 +4,6 @@
#include <QExplicitlySharedDataPointer>
#include <QObject>
namespace Gio {
class Mount;
}
class DGioMount;
class DGioVolume;
class DGioVolumeManagerPrivate;
@ -18,7 +14,14 @@ public:
explicit DGioVolumeManager(QObject *parent = nullptr);
~DGioVolumeManager();
const QList<QExplicitlySharedDataPointer<DGioMount> > getMounts();
static const QList<QExplicitlySharedDataPointer<DGioMount> > getMounts();
static const QList<QExplicitlySharedDataPointer<DGioVolume> > getVolumes();
Q_SIGNALS:
void mountAdded(QExplicitlySharedDataPointer<DGioMount> mount);
void mountRemoved(QExplicitlySharedDataPointer<DGioMount> mount);
void mountPreRemoved(QExplicitlySharedDataPointer<DGioMount> mount);
void mountChanged(QExplicitlySharedDataPointer<DGioMount> mount);
private:
QScopedPointer<DGioVolumeManagerPrivate> d_ptr;

View File

@ -1,22 +1,65 @@
#include <QDebug>
#include <QCoreApplication>
#include <QExplicitlySharedDataPointer>
#include <dgiofile.h>
#include <dgiomount.h>
#include <dgiovolume.h>
#include <dgiovolumemanager.h>
int main()
int main(int argc, char * argv[])
{
DGioMount * m = DGioMount::createFromPath("/media/wzc/aaaaaaaaaaaaaaaa");
if (m) {
qDebug() << m->name();
qDebug() << m->name() << m->themedIconNames();
delete m;
}
DGioVolumeManager mgr;
const QList<QExplicitlySharedDataPointer<DGioMount> > lst = mgr.getMounts();
for (const QExplicitlySharedDataPointer<DGioMount> &p : lst) {
qDebug() << p->name() << m->uuid() << m->canUnmount();
DGioFile * f = DGioFile::createFromPath("/media/wzc/aaaaaaaaaaaaaaaa");
if (f) {
qDebug() << f->basename() << f->path() << f->uri();
delete f;
}
qDebug() << "----------------------";
const QList<QExplicitlySharedDataPointer<DGioMount> > mnts = DGioVolumeManager::getMounts();
for (const QExplicitlySharedDataPointer<DGioMount> &p : mnts) {
qDebug() << p->name() << p->uuid() << p->canUnmount() << p->themedIconNames() << p->themedIconNames();
}
qDebug() << "----------------------";
const QList<QExplicitlySharedDataPointer<DGioVolume> > vols = DGioVolumeManager::getVolumes();
for (const QExplicitlySharedDataPointer<DGioVolume> &p : vols) {
qDebug() << p->name();
}
qDebug() << "----------------------";
QCoreApplication app(argc, argv);
DGioVolumeManager vm;
QObject::connect(&vm, &DGioVolumeManager::mountAdded, [](QExplicitlySharedDataPointer<DGioMount> mnt){
qDebug() << "MountAdded" << mnt->name();
});
QObject::connect(&vm, &DGioVolumeManager::mountPreRemoved, [](QExplicitlySharedDataPointer<DGioMount> mnt){
qDebug() << "MountPreRemoved" << mnt->name();
});
QObject::connect(&vm, &DGioVolumeManager::mountRemoved, [](QExplicitlySharedDataPointer<DGioMount> mnt){
qDebug() << "MountRemoved" << mnt->name();
});
QObject::connect(&vm, &DGioVolumeManager::mountChanged, [](QExplicitlySharedDataPointer<DGioMount> mnt){
qDebug() << "MountChanged" << mnt->name();
});
app.exec();
return 0;
}