Subject: Dialog notifying about running low on disk space From: Lubos Lunak Feature: bnc#199054 Patch-upstream: no Index: kioslave/media/medianotifier/Makefile.am =================================================================== --- kioslave/media/medianotifier/Makefile.am.orig +++ kioslave/media/medianotifier/Makefile.am @@ -5,7 +5,8 @@ kded_medianotifier_la_LDFLAGS = -module kded_medianotifier_la_LIBADD = ../libmediacommon/libmediacommon.la $(LIB_KDECORE) \ $(LIB_KDEUI) $(LIB_KIO) kded_medianotifier_la_SOURCES = medianotifier.cpp medianotifier.skel \ - notificationdialog.cpp notificationdialogview.ui + notificationdialog.cpp notificationdialogview.ui \ + freespacenotifier.cpp freespacewidget.ui noinst_HEADERS = medianotifier.h notificationdialog.h Index: kioslave/media/medianotifier/medianotifier.h =================================================================== --- kioslave/media/medianotifier/medianotifier.h.orig +++ kioslave/media/medianotifier/medianotifier.h @@ -27,6 +27,8 @@ #include #include +class FreeSpaceNotifier; + class MediaNotifier: public KDEDModule { Q_OBJECT @@ -52,6 +54,8 @@ private: const QString &autoopenFile ); QMap m_allowNotificationMap; + FreeSpaceNotifier* m_freeSpaceNotifier; }; + #endif Index: kioslave/media/medianotifier/medianotifier.cpp =================================================================== --- kioslave/media/medianotifier/medianotifier.cpp.orig +++ kioslave/media/medianotifier/medianotifier.cpp @@ -36,6 +36,7 @@ #include "notifiersettings.h" #include "notifieraction.h" #include "mediamanagersettings.h" +#include "freespacenotifier.h" MediaNotifier::MediaNotifier(const QCString &name) : KDEDModule(name) { @@ -44,6 +45,8 @@ MediaNotifier::MediaNotifier(const QCStr connectDCOPSignal( "kded", "mediamanager", "mediumChanged(QString, bool)", "onMediumChange(QString, bool)", true ); + + m_freeSpaceNotifier = new FreeSpaceNotifier( this ); } MediaNotifier::~MediaNotifier() @@ -53,6 +56,7 @@ MediaNotifier::~MediaNotifier() disconnectDCOPSignal( "kded", "mediamanager", "mediumChanged(QString, bool)", "onMediumChange(QString, bool)" ); + delete m_freeSpaceNotifier; } void MediaNotifier::onMediumChange( const QString &name, bool allowNotification ) Index: kioslave/media/medianotifier/freespacenotifier.cpp =================================================================== --- /dev/null +++ kioslave/media/medianotifier/freespacenotifier.cpp @@ -0,0 +1,159 @@ +/* This file is part of the KDE Project + Copyright (c) 2006 Lukas Tinkl + Copyright (c) 2008 Lubos Lunak + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "freespacenotifier.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "freespacewidget.h" + + +FreeSpaceNotifier::FreeSpaceNotifier( QObject* parent ) + : QObject( parent ) + , lastAvailTimer( NULL ) + , dialog( NULL ) + , lastAvail( -1 ) +{ + connect( &timer, SIGNAL( timeout() ), SLOT( checkFreeDiskSpace() ) ); + KConfig cfg( "lowspacesuse", true ); // read only + KConfigGroup group( &cfg, "General" ); + limit = group.readNumEntry( "WarnMinimumFreeSpace", 200 ); // MiB + if( limit != 0 ) + timer.start( 1000 * 60 /* 1 minute */ ); +} + +FreeSpaceNotifier::~FreeSpaceNotifier() +{ + delete dialog; +} + +void FreeSpaceNotifier::checkFreeDiskSpace() +{ + if ( dialog ) + return; + struct statfs sfs; + if ( statfs( QFile::encodeName( QDir::homeDirPath() ), &sfs ) == 0 ) + { + long avail = ( getuid() ? sfs.f_bavail : sfs.f_bfree ); + + if (avail < 0 || sfs.f_blocks <= 0) + return; // we better do not say anything about it + + int availpct = int( 100 * avail / sfs.f_blocks ); + avail = ((long long)avail) * sfs.f_bsize / ( 1024 * 1024 ); // to MiB + bool warn = false; + if( avail < limit ) // avail disk space dropped under a limit + { + if( lastAvail < 0 ) // always warn the first time + { + lastAvail = avail; + warn = true; + } + else if( avail > lastAvail ) // the user freed some space + lastAvail = avail; // so warn if it goes low again + else if( avail < lastAvail * 0.5 ) // available dropped to a half of previous one, warn again + { + warn = true; + lastAvail = avail; + } + // do not change lastAvail otherwise, to handle free space slowly going down + } + if ( warn ) + { + dialog = new KDialogBase( + i18n( "Low Disk Space" ), + KDialogBase::Yes | KDialogBase::No | KDialogBase::Cancel, + KDialogBase::Yes, KDialogBase::No, + 0, "lowdiskspacedialog", false, true, + i18n( "Open File Manager" ), i18n( "Do Nothing" ), i18n( "Disable Warning" )); + widget = new FreeSpaceWidget( dialog ); + dialog->setMainWidget( widget ); + + QString text = i18n( "You are running low on disk space on your home partition (currently %2%, %1 MiB free)." ) + .arg( avail ).arg( availpct ); + widget->warningLabel->setText( text ); + widget->spinbox->setMinValue( 0 ); + widget->spinbox->setMaxValue( 100000 ); + widget->spinbox->setValue( limit ); + connect( dialog, SIGNAL( yesClicked() ), SLOT( slotYes() ) ); + connect( dialog, SIGNAL( noClicked() ), SLOT( slotNo() ) ); + connect( dialog, SIGNAL( cancelClicked() ), SLOT( slotCancel() ) ); + dialog->show(); + } + } +} + +void FreeSpaceNotifier::slotYes() +{ + ( void ) new KRun( KURL::fromPathOrURL( QDir::homeDirPath() ) ); + cleanupDialog( widget->spinbox->value()); +} + +void FreeSpaceNotifier::slotNo() +{ + cleanupDialog( widget->spinbox->value()); +} + +void FreeSpaceNotifier::slotCancel() +{ + cleanupDialog( 0 ); // set limit to zero +} + +void FreeSpaceNotifier::cleanupDialog( long newLimit ) +{ + dialog->deleteLater(); + dialog = NULL; + if( limit != newLimit ) + { + KConfig cfg( "lowspacesuse" ); + KConfigGroup group( &cfg, "General" ); + limit = newLimit; + group.writeEntry( "WarnMinimumFreeSpace", limit ); + if( limit == 0 ) + timer.stop(); + } + if( limit != 0 ) + { // warn again if constanly below limit for too long + if( lastAvailTimer == NULL ) + { + lastAvailTimer = new QTimer( this ); + connect( lastAvailTimer, SIGNAL( timeout()), SLOT( resetLastAvailable())); + } + lastAvailTimer->start( 1000 * 60 * 60 /* 1 hour*/ ); + } +} + +void FreeSpaceNotifier::resetLastAvailable() +{ + lastAvail = -1; + lastAvailTimer->deleteLater(); + lastAvailTimer = NULL; +} + +#include "freespacenotifier.moc" Index: kioslave/media/medianotifier/freespacenotifier.h =================================================================== --- /dev/null +++ kioslave/media/medianotifier/freespacenotifier.h @@ -0,0 +1,51 @@ +/* This file is part of the KDE Project + Copyright (c) 2006 Lukas Tinkl + Copyright (c) 2008 Lubos Lunak + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _FREESPACENOTIFIER_H_ +#define _FREESPACENOTIFIER_H_ + +#include + +#include + +class FreeSpaceWidget; + +class FreeSpaceNotifier +: public QObject +{ + Q_OBJECT + public: + FreeSpaceNotifier( QObject* parent = NULL ); + virtual ~FreeSpaceNotifier(); + private slots: + void checkFreeDiskSpace(); + void resetLastAvailable(); + void slotYes(); + void slotNo(); + void slotCancel(); + private: + void cleanupDialog( long newLimit ); + QTimer timer; + QTimer* lastAvailTimer; + KDialogBase* dialog; + FreeSpaceWidget* widget; + long limit; + long lastAvail; // used to supress repeated warnings when available space hasn't changed +}; + +#endif Index: kioslave/media/medianotifier/freespacewidget.ui =================================================================== --- /dev/null +++ kioslave/media/medianotifier/freespacewidget.ui @@ -0,0 +1,118 @@ + +FreeSpaceWidget + + + Form1 + + + + 0 + 0 + 489 + 108 + + + + Form1 + + + + unnamed + + + + warningLabel + + + + + + + + textLabel2 + + + Would you like to run a file manager to free some disk space and fix the problem? + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + layout3 + + + + unnamed + + + + textLabel3 + + + Warn again when the free space is below + + + + + spinbox + + + MiB + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + +