QortalOS Brooklyn for Raspberry Pi 4
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

154 lines
4.9 KiB

/*
SPDX-FileCopyrightText: 2006 Lukas Tinkl <[email protected]>
SPDX-FileCopyrightText: 2008 Lubos Lunak <[email protected]>
SPDX-FileCopyrightText: 2009 Ivo Anjo <[email protected]>
SPDX-FileCopyrightText: 2020 Kai Uwe Broulik <[email protected]>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "freespacenotifier.h"
#include <KNotification>
#include <KNotificationJobUiDelegate>
#include <KIO/ApplicationLauncherJob>
#include <KIO/FileSystemFreeSpaceJob>
#include <KIO/OpenUrlJob>
#include <chrono>
#include "settings.h"
FreeSpaceNotifier::FreeSpaceNotifier(const QString &path, const KLocalizedString &notificationText, QObject *parent)
: QObject(parent)
, m_path(path)
, m_notificationText(notificationText)
{
connect(&m_timer, &QTimer::timeout, this, &FreeSpaceNotifier::checkFreeDiskSpace);
m_timer.start(std::chrono::minutes(1));
}
FreeSpaceNotifier::~FreeSpaceNotifier()
{
if (m_notification) {
m_notification->close();
}
}
void FreeSpaceNotifier::checkFreeDiskSpace()
{
if (!FreeSpaceNotifierSettings::enableNotification()) {
// do nothing if notifying is disabled;
// also stop the timer that probably got us here in the first place
m_timer.stop();
return;
}
auto *job = KIO::fileSystemFreeSpace(QUrl::fromLocalFile(m_path));
connect(job, &KIO::FileSystemFreeSpaceJob::result, this, [this](KIO::Job *job, KIO::filesize_t size, KIO::filesize_t available) {
if (job->error()) {
return;
}
const int limit = FreeSpaceNotifierSettings::minimumSpace(); // MiB
const qint64 avail = available / (1024 * 1024); // to MiB
if (avail >= limit) {
if (m_notification) {
m_notification->close();
}
return;
}
const int availPercent = int(100 * available / size);
const QString text = m_notificationText.subs(avail).subs(availPercent).toString();
// Make sure the notification text is always up to date whenever we checked free space
if (m_notification) {
m_notification->setText(text);
}
// User freed some space, warn if it goes low again
if (m_lastAvail > -1 && avail > m_lastAvail) {
m_lastAvail = avail;
return;
}
// Always warn the first time or when available space dropped to half of the previous time
const bool warn = (m_lastAvail < 0 || avail < m_lastAvail / 2);
if (!warn) {
return;
}
m_lastAvail = avail;
if (!m_notification) {
m_notification = new KNotification(QStringLiteral("freespacenotif"));
m_notification->setComponentName(QStringLiteral("freespacenotifier"));
m_notification->setText(text);
QStringList actions = {i18n("Configure Warning…")};
auto filelight = filelightService();
if (filelight) {
actions.prepend(i18n("Open in Filelight"));
} else {
// Do we really want the user opening Root in a file manager?
actions.prepend(i18n("Open in File Manager"));
}
m_notification->setActions(actions);
connect(m_notification, &KNotification::activated, this, [this](uint actionId) {
if (actionId == 1) {
exploreDrive();
// TODO once we have "configure" action support in KNotification, wire it up instead of a button
} else if (actionId == 2) {
Q_EMIT configureRequested();
}
});
connect(m_notification, &KNotification::closed, this, &FreeSpaceNotifier::onNotificationClosed);
m_notification->sendEvent();
}
});
}
KService::Ptr FreeSpaceNotifier::filelightService() const
{
return KService::serviceByDesktopName(QStringLiteral("org.kde.filelight"));
}
void FreeSpaceNotifier::exploreDrive()
{
auto service = filelightService();
if (!service) {
auto *job = new KIO::OpenUrlJob({QUrl::fromLocalFile(m_path)});
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoErrorHandlingEnabled));
job->start();
return;
}
auto *job = new KIO::ApplicationLauncherJob(service);
job->setUrls({QUrl::fromLocalFile(m_path)});
job->setUiDelegate(new KNotificationJobUiDelegate(KJobUiDelegate::AutoErrorHandlingEnabled));
job->start();
}
void FreeSpaceNotifier::onNotificationClosed()
{
// warn again if constantly below limit for too long
if (!m_lastAvailTimer) {
m_lastAvailTimer = new QTimer(this);
connect(m_lastAvailTimer, &QTimer::timeout, this, &FreeSpaceNotifier::resetLastAvailable);
}
m_lastAvailTimer->start(std::chrono::hours(1));
}
void FreeSpaceNotifier::resetLastAvailable()
{
m_lastAvail = -1;
m_lastAvailTimer->deleteLater();
m_lastAvailTimer = nullptr;
}