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
public:
KFreeSpaceBox(QWidget *parent,
const QString &udi, const QString &title,
const Solid::Device &soliddevice,
bool watch, qulonglong checktime, qulonglong freespace);
@ -59,22 +59,23 @@ private Q_SLOTS:
void slotFreeSpace();
private:
QString m_udi;
Solid::Device m_soliddevice;
QCheckBox* m_watchbox;
KIntNumInput* m_checktimeinput;
KIntNumInput* m_freespaceinput;
};
KFreeSpaceBox::KFreeSpaceBox(QWidget *parent,
const QString &udi, const QString &title,
const Solid::Device &soliddevice,
bool watch, qulonglong checktime, qulonglong freespace)
: QGroupBox(parent),
m_udi(udi),
m_soliddevice(soliddevice),
m_watchbox(nullptr),
m_checktimeinput(nullptr),
m_freespaceinput(nullptr)
{
setTitle(title);
setTitle(m_soliddevice.description());
QGridLayout* devicelayout = new QGridLayout(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
{
return m_udi;
return m_soliddevice.udi();
}
bool KFreeSpaceBox::watch() const
@ -203,7 +204,8 @@ void KCMFreeSpace::load()
Q_ASSERT(m_spacer == nullptr);
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>();
if (!solidaccess) {
continue;
@ -212,12 +214,6 @@ void KCMFreeSpace::load()
continue;
}
const QString kfreespacedirpath = solidaccess->filePath();
if (kfreespacedirpath.isEmpty()) {
kDebug() << "Not accessible" << soliddevice.udi();
continue;
}
// qDebug() << Q_FUNC_INFO << soliddevice.udi();
KConfigGroup kfreespacegroup = kfreespaceconfig.group(soliddevice.udi());
const bool kfreespacewatch = kfreespacegroup.readEntry("watch", s_kfreespacewatch);
@ -226,7 +222,7 @@ void KCMFreeSpace::load()
KFreeSpaceBox* devicebox = new KFreeSpaceBox(
this,
soliddevice.udi(), soliddevice.description(),
soliddevice,
kfreespacewatch, kfreespacechecktime, kfreespacefreespace
);
m_deviceboxes.append(devicebox);

View file

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

View file

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

View file

@ -24,10 +24,10 @@
#include <kdiskfreespaceinfo.h>
#include <knotification.h>
#include <kdebug.h>
#include <solid/storageaccess.h>
KFreeSpaceImpl::KFreeSpaceImpl(QObject *parent)
: QObject(parent),
m_directory(QDir::homePath()),
m_checktime(s_kfreespacechecktime),
m_freespace(s_kfreespacefreespace),
m_timerid(0)
@ -42,23 +42,17 @@ KFreeSpaceImpl::~KFreeSpaceImpl()
}
}
bool KFreeSpaceImpl::watch(const QString &dirpath,
const qulonglong checktime, const qulonglong freespace,
const QString &description)
bool KFreeSpaceImpl::watch(const Solid::Device &soliddevice,
const qulonglong checktime, const qulonglong freespace)
{
// qDebug() << Q_FUNC_INFO << dirpath << checktime << freespace;
m_directory = dirpath;
// qDebug() << Q_FUNC_INFO << soliddevice.udi() << checktime << freespace;
m_soliddevice = soliddevice;
// NOTE: time from config is in seconds, has to be in ms here
m_checktime = (qBound(s_kfreespacechecktimemin, checktime, s_kfreespacechecktimemax) * 1000);
// NOTE: size from config is in MB, has to be in bytes here
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);
kDebug() << "Checking" << m_directory
kDebug() << "Checking" << m_soliddevice.udi()
<< "every" << (m_checktime / 1000)
<< "if space is less or equal to" << KGlobal::locale()->formatByteSize(m_freespace);
return true;
@ -69,23 +63,24 @@ void KFreeSpaceImpl::timerEvent(QTimerEvent *event)
if (event->timerId() == m_timerid) {
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()) {
kWarning() << "Disk info is not valid for" << m_directory;
killTimer(m_timerid);
m_timerid = 0;
kDebug() << "Disk info is not valid for" << mountpoint;
return;
}
const qulonglong freespace = kdiskinfo.available();
const QString freespacestring = KGlobal::locale()->formatByteSize(freespace);
kDebug() << "Current" << m_directory
kDebug() << "Current" << m_soliddevice.udi()
<< "space is" << freespacestring;
if (freespace <= m_freespace) {
KNotification *knotification = new KNotification("WatchLow");
knotification->setComponentData(KComponentData("kfreespace"));
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();
}
} else {

View file

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