kfreespace: rework to be able to setup watch for devices that are not mounted yet

to be able to watch devices that may be mounted and unmounted at any time
such as removable devices

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-13 19:53:01 +03:00
parent 8dbfa6c2f4
commit 99cca218ec
5 changed files with 35 additions and 67 deletions

View file

@ -38,7 +38,7 @@ class KFreeSpaceBox : public QGroupBox
Q_OBJECT Q_OBJECT
public: public:
KFreeSpaceBox(QWidget *parent, KFreeSpaceBox(QWidget *parent,
const QString &udi, const QString &title, const Solid::Device &soliddevice,
bool watch, qulonglong checktime, qulonglong freespace); bool watch, qulonglong checktime, qulonglong freespace);
@ -59,22 +59,23 @@ private Q_SLOTS:
void slotFreeSpace(); void slotFreeSpace();
private: private:
QString m_udi; Solid::Device m_soliddevice;
QCheckBox* m_watchbox; QCheckBox* m_watchbox;
KIntNumInput* m_checktimeinput; KIntNumInput* m_checktimeinput;
KIntNumInput* m_freespaceinput; KIntNumInput* m_freespaceinput;
}; };
KFreeSpaceBox::KFreeSpaceBox(QWidget *parent, KFreeSpaceBox::KFreeSpaceBox(QWidget *parent,
const QString &udi, const QString &title, const Solid::Device &soliddevice,
bool watch, qulonglong checktime, qulonglong freespace) bool watch, qulonglong checktime, qulonglong freespace)
: QGroupBox(parent), : QGroupBox(parent),
m_udi(udi), m_soliddevice(soliddevice),
m_watchbox(nullptr), m_watchbox(nullptr),
m_checktimeinput(nullptr), m_checktimeinput(nullptr),
m_freespaceinput(nullptr) m_freespaceinput(nullptr)
{ {
setTitle(title); setTitle(m_soliddevice.description());
QGridLayout* devicelayout = new QGridLayout(this); QGridLayout* devicelayout = new QGridLayout(this);
m_watchbox = new QCheckBox(i18n("Notify when the device free space is low"), this); m_watchbox = new QCheckBox(i18n("Notify when the device free space is low"), this);
@ -114,7 +115,7 @@ KFreeSpaceBox::KFreeSpaceBox(QWidget *parent,
QString KFreeSpaceBox::udi() const QString KFreeSpaceBox::udi() const
{ {
return m_udi; return m_soliddevice.udi();
} }
bool KFreeSpaceBox::watch() const bool KFreeSpaceBox::watch() const
@ -203,7 +204,8 @@ void KCMFreeSpace::load()
Q_ASSERT(m_spacer == nullptr); Q_ASSERT(m_spacer == nullptr);
KConfig kfreespaceconfig("kfreespacerc", KConfig::SimpleConfig); KConfig kfreespaceconfig("kfreespacerc", KConfig::SimpleConfig);
foreach (const Solid::Device soliddevice, Solid::Device::allDevices()) { const QList<Solid::Device> storagedevices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
foreach (const Solid::Device soliddevice, storagedevices) {
const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>(); const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>();
if (!solidaccess) { if (!solidaccess) {
continue; continue;
@ -212,12 +214,6 @@ void KCMFreeSpace::load()
continue; continue;
} }
const QString kfreespacedirpath = solidaccess->filePath();
if (kfreespacedirpath.isEmpty()) {
kDebug() << "Not accessible" << soliddevice.udi();
continue;
}
// qDebug() << Q_FUNC_INFO << soliddevice.udi(); // qDebug() << Q_FUNC_INFO << soliddevice.udi();
KConfigGroup kfreespacegroup = kfreespaceconfig.group(soliddevice.udi()); KConfigGroup kfreespacegroup = kfreespaceconfig.group(soliddevice.udi());
const bool kfreespacewatch = kfreespacegroup.readEntry("watch", s_kfreespacewatch); const bool kfreespacewatch = kfreespacegroup.readEntry("watch", s_kfreespacewatch);
@ -226,7 +222,7 @@ void KCMFreeSpace::load()
KFreeSpaceBox* devicebox = new KFreeSpaceBox( KFreeSpaceBox* devicebox = new KFreeSpaceBox(
this, this,
soliddevice.udi(), soliddevice.description(), soliddevice,
kfreespacewatch, kfreespacechecktime, kfreespacefreespace kfreespacewatch, kfreespacechecktime, kfreespacefreespace
); );
m_deviceboxes.append(devicebox); m_deviceboxes.append(devicebox);

View file

@ -47,8 +47,6 @@ KFreeSpaceModule::KFreeSpaceModule(QObject *parent, const QList<QVariant> &args)
m_dirwatch->addFile(kfreespacercfile); m_dirwatch->addFile(kfreespacercfile);
connect(m_dirwatch, SIGNAL(dirty(QString)), this, SLOT(slotInit())); connect(m_dirwatch, SIGNAL(dirty(QString)), this, SLOT(slotInit()));
// TODO: test it
#if 0
Solid::DeviceNotifier* solidnotifier = Solid::DeviceNotifier::instance(); Solid::DeviceNotifier* solidnotifier = Solid::DeviceNotifier::instance();
connect( connect(
solidnotifier, SIGNAL(deviceAdded(QString)), solidnotifier, SIGNAL(deviceAdded(QString)),
@ -58,7 +56,6 @@ KFreeSpaceModule::KFreeSpaceModule(QObject *parent, const QList<QVariant> &args)
solidnotifier, SIGNAL(deviceRemoved(QString)), solidnotifier, SIGNAL(deviceRemoved(QString)),
this, SLOT(slotDeviceRemoved(QString)) this, SLOT(slotDeviceRemoved(QString))
); );
#endif
} }
KFreeSpaceModule::~KFreeSpaceModule() KFreeSpaceModule::~KFreeSpaceModule()
@ -76,7 +73,8 @@ void KFreeSpaceModule::slotInit()
KConfig kfreespaceconfig("kfreespacerc", KConfig::SimpleConfig); KConfig kfreespaceconfig("kfreespacerc", KConfig::SimpleConfig);
bool watcherror = false; bool watcherror = false;
foreach (const Solid::Device soliddevice, Solid::Device::allDevices()) { const QList<Solid::Device> storagedevices = Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess);
foreach (const Solid::Device soliddevice, storagedevices) {
const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>(); const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>();
if (!solidaccess) { if (!solidaccess) {
continue; continue;
@ -85,12 +83,6 @@ void KFreeSpaceModule::slotInit()
continue; continue;
} }
const QString kfreespacedirpath = solidaccess->filePath();
if (kfreespacedirpath.isEmpty()) {
kDebug() << "Not accessible" << soliddevice.udi();
continue;
}
// qDebug() << Q_FUNC_INFO << soliddevice.udi(); // qDebug() << Q_FUNC_INFO << soliddevice.udi();
KConfigGroup kfreespacegroup = kfreespaceconfig.group(soliddevice.udi()); KConfigGroup kfreespacegroup = kfreespaceconfig.group(soliddevice.udi());
const bool kfreespacewatch = kfreespacegroup.readEntry("watch", s_kfreespacewatch); const bool kfreespacewatch = kfreespacegroup.readEntry("watch", s_kfreespacewatch);
@ -103,9 +95,8 @@ void KFreeSpaceModule::slotInit()
const qulonglong kfreespacefreespace = kfreespacegroup.readEntry("freespace", s_kfreespacefreespace); const qulonglong kfreespacefreespace = kfreespacegroup.readEntry("freespace", s_kfreespacefreespace);
KFreeSpaceImpl* kfreespaceimpl = new KFreeSpaceImpl(this); KFreeSpaceImpl* kfreespaceimpl = new KFreeSpaceImpl(this);
const bool kfreespacestatus = kfreespaceimpl->watch( const bool kfreespacestatus = kfreespaceimpl->watch(
kfreespacedirpath, soliddevice,
kfreespacechecktime, kfreespacefreespace, kfreespacechecktime, kfreespacefreespace
soliddevice.description()
); );
if (!kfreespacestatus) { if (!kfreespacestatus) {
delete kfreespaceimpl; delete kfreespaceimpl;
@ -129,25 +120,13 @@ void KFreeSpaceModule::slotDeviceAdded(const QString &udi)
const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>(); const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>();
if (solidaccess) { if (solidaccess) {
kDebug() << "Storage access added" << udi; kDebug() << "Storage access added" << udi;
connect( slotInit();
solidaccess, SIGNAL(accessibilityChanged(bool,QString)),
this, SLOT(slotAccessibilityChanged(bool,QString))
);
} }
} }
void KFreeSpaceModule::slotDeviceRemoved(const QString &udi) void KFreeSpaceModule::slotDeviceRemoved(const QString &udi)
{ {
Solid::Device soliddevice(udi); // NOTE: at that point obtaining valid device is impossible
const Solid::StorageAccess* solidaccess = soliddevice.as<Solid::StorageAccess>(); kDebug() << "Solid device removed" << udi;
if (solidaccess) {
kDebug() << "Storage access removed" << udi;
disconnect(solidaccess, 0, this, 0);
}
}
void KFreeSpaceModule::slotAccessibilityChanged(bool accessible, const QString &udi)
{
kDebug() << "Storage accessibility changed" << udi << accessible;
slotInit(); slotInit();
} }

View file

@ -40,7 +40,6 @@ private Q_SLOTS:
void slotInit(); void slotInit();
void slotDeviceAdded(const QString &udi); void slotDeviceAdded(const QString &udi);
void slotDeviceRemoved(const QString &udi); void slotDeviceRemoved(const QString &udi);
void slotAccessibilityChanged(bool accessible, const QString &udi);
private: private:
KDirWatch* m_dirwatch; KDirWatch* m_dirwatch;

View file

@ -24,10 +24,10 @@
#include <kdiskfreespaceinfo.h> #include <kdiskfreespaceinfo.h>
#include <knotification.h> #include <knotification.h>
#include <kdebug.h> #include <kdebug.h>
#include <solid/storageaccess.h>
KFreeSpaceImpl::KFreeSpaceImpl(QObject *parent) KFreeSpaceImpl::KFreeSpaceImpl(QObject *parent)
: QObject(parent), : QObject(parent),
m_directory(QDir::homePath()),
m_checktime(s_kfreespacechecktime), m_checktime(s_kfreespacechecktime),
m_freespace(s_kfreespacefreespace), m_freespace(s_kfreespacefreespace),
m_timerid(0) m_timerid(0)
@ -42,23 +42,17 @@ KFreeSpaceImpl::~KFreeSpaceImpl()
} }
} }
bool KFreeSpaceImpl::watch(const QString &dirpath, bool KFreeSpaceImpl::watch(const Solid::Device &soliddevice,
const qulonglong checktime, const qulonglong freespace, const qulonglong checktime, const qulonglong freespace)
const QString &description)
{ {
// qDebug() << Q_FUNC_INFO << dirpath << checktime << freespace; // qDebug() << Q_FUNC_INFO << soliddevice.udi() << checktime << freespace;
m_directory = dirpath; m_soliddevice = soliddevice;
// NOTE: time from config is in seconds, has to be in ms here // NOTE: time from config is in seconds, has to be in ms here
m_checktime = (qBound(s_kfreespacechecktimemin, checktime, s_kfreespacechecktimemax) * 1000); m_checktime = (qBound(s_kfreespacechecktimemin, checktime, s_kfreespacechecktimemax) * 1000);
// NOTE: size from config is in MB, has to be in bytes here // NOTE: size from config is in MB, has to be in bytes here
m_freespace = (qBound(s_kfreespacefreespacemin, freespace, s_kfreespacefreespacemax) * 1024 * 1024); m_freespace = (qBound(s_kfreespacefreespacemin, freespace, s_kfreespacefreespacemax) * 1024 * 1024);
m_description = description;
if (!QDir(m_directory).exists()) {
kWarning() << "Directory does not exist" << m_directory;
return false;
}
m_timerid = startTimer(m_checktime); m_timerid = startTimer(m_checktime);
kDebug() << "Checking" << m_directory kDebug() << "Checking" << m_soliddevice.udi()
<< "every" << (m_checktime / 1000) << "every" << (m_checktime / 1000)
<< "if space is less or equal to" << KGlobal::locale()->formatByteSize(m_freespace); << "if space is less or equal to" << KGlobal::locale()->formatByteSize(m_freespace);
return true; return true;
@ -69,23 +63,24 @@ void KFreeSpaceImpl::timerEvent(QTimerEvent *event)
if (event->timerId() == m_timerid) { if (event->timerId() == m_timerid) {
event->accept(); event->accept();
const KDiskFreeSpaceInfo kdiskinfo = KDiskFreeSpaceInfo::freeSpaceInfo(m_directory); const Solid::StorageAccess* solidaccess = m_soliddevice.as<Solid::StorageAccess>();
Q_ASSERT(solidaccess);
const QString mountpoint = solidaccess->filePath();
const KDiskFreeSpaceInfo kdiskinfo = KDiskFreeSpaceInfo::freeSpaceInfo(mountpoint);
if (!kdiskinfo.isValid()) { if (!kdiskinfo.isValid()) {
kWarning() << "Disk info is not valid for" << m_directory; kDebug() << "Disk info is not valid for" << mountpoint;
killTimer(m_timerid);
m_timerid = 0;
return; return;
} }
const qulonglong freespace = kdiskinfo.available(); const qulonglong freespace = kdiskinfo.available();
const QString freespacestring = KGlobal::locale()->formatByteSize(freespace); const QString freespacestring = KGlobal::locale()->formatByteSize(freespace);
kDebug() << "Current" << m_directory kDebug() << "Current" << m_soliddevice.udi()
<< "space is" << freespacestring; << "space is" << freespacestring;
if (freespace <= m_freespace) { if (freespace <= m_freespace) {
KNotification *knotification = new KNotification("WatchLow"); KNotification *knotification = new KNotification("WatchLow");
knotification->setComponentData(KComponentData("kfreespace")); knotification->setComponentData(KComponentData("kfreespace"));
knotification->setTitle(i18n("Low Disk Space")); knotification->setTitle(i18n("Low Disk Space"));
knotification->setText(i18n("%1 has %2 free space", m_description, freespacestring)); knotification->setText(i18n("%1 has %2 free space", m_soliddevice.description(), freespacestring));
knotification->sendEvent(); knotification->sendEvent();
} }
} else { } else {

View file

@ -21,6 +21,7 @@
#include <QObject> #include <QObject>
#include <QTimerEvent> #include <QTimerEvent>
#include <solid/device.h>
class KFreeSpaceImpl : public QObject class KFreeSpaceImpl : public QObject
{ {
@ -29,19 +30,17 @@ public:
KFreeSpaceImpl(QObject *parent = nullptr); KFreeSpaceImpl(QObject *parent = nullptr);
~KFreeSpaceImpl(); ~KFreeSpaceImpl();
bool watch(const QString &dirpath, bool watch(const Solid::Device &soliddevice,
const qulonglong checktime, const qulonglong freespace, const qulonglong checktime, const qulonglong freespace);
const QString &description);
protected: protected:
// reimplementation // reimplementation
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event);
private: private:
QString m_directory; Solid::Device m_soliddevice;
qulonglong m_checktime; qulonglong m_checktime;
qulonglong m_freespace; qulonglong m_freespace;
QString m_description;
int m_timerid; int m_timerid;
}; };