diff options
author | Emanoil Kotsev <deloptes@gmail.com> | 2016-10-12 15:20:02 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2016-10-12 15:20:02 +0900 |
commit | ee3091bc41f5cae8be2ba5f8335e0b866edb4711 (patch) | |
tree | 8ffc7ba391bb968e9de33674fa6caf5e9166e5eb | |
parent | 443c910570647f415838e65a1b8add30b00b7dbb (diff) | |
download | tdebase-ee3091bc41f5cae8be2ba5f8335e0b866edb4711.tar.gz tdebase-ee3091bc41f5cae8be2ba5f8335e0b866edb4711.zip |
Added trash limit configuration option
This work is based on original patch created by Tobias Koenig <tokoe@kde.org> for KDE 3.5.9 and later added to KDE 4.2, and available under GPL version 2 License, or any later version.
See also http://tokoe-kde.blogspot.com/2008/08/size-limits-for-trash.html
This relates to bug 1923.
Signed-off-by: Emanoil Kotsev <deloptes@gmail.com>
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
-rw-r--r-- | tdeioslave/trash/CMakeLists.txt | 19 | ||||
-rw-r--r-- | tdeioslave/trash/Makefile.am | 13 | ||||
-rw-r--r-- | tdeioslave/trash/discspaceutil.cpp | 112 | ||||
-rw-r--r-- | tdeioslave/trash/discspaceutil.h | 81 | ||||
-rw-r--r-- | tdeioslave/trash/ktrashpropsdlgplugin.cpp | 316 | ||||
-rw-r--r-- | tdeioslave/trash/ktrashpropsdlgplugin.desktop | 6 | ||||
-rw-r--r-- | tdeioslave/trash/ktrashpropsdlgplugin.h | 78 | ||||
-rw-r--r-- | tdeioslave/trash/testtrash.cpp | 2 | ||||
-rw-r--r-- | tdeioslave/trash/trash.protocol | 2 | ||||
-rw-r--r-- | tdeioslave/trash/trashimpl.cpp | 95 | ||||
-rw-r--r-- | tdeioslave/trash/trashimpl.h | 2 |
11 files changed, 720 insertions, 6 deletions
diff --git a/tdeioslave/trash/CMakeLists.txt b/tdeioslave/trash/CMakeLists.txt index 1569d07ca..1082b57af 100644 --- a/tdeioslave/trash/CMakeLists.txt +++ b/tdeioslave/trash/CMakeLists.txt @@ -25,7 +25,7 @@ link_directories( ##### other data ################################ -install( FILES trash.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) +install( FILES ktrashpropsdlgplugin.desktop trash.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) ##### trashcommon (static) ###################### @@ -33,7 +33,7 @@ install( FILES trash.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) set( target trashcommon ) tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES trashimpl.cpp + SOURCES trashimpl.cpp discspaceutil.cpp ) @@ -47,6 +47,15 @@ tde_add_kpart( ${target} AUTOMOC DESTINATION ${PLUGIN_INSTALL_DIR} ) +##### ktrashpropsdlgplugin (module) ######################## + +set( target ktrashpropsdlgplugin ) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ktrashpropsdlgplugin.cpp + LINK trashcommon-static tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) ##### ktrash (executable) ####################### @@ -57,3 +66,9 @@ tde_add_executable( ${target} LINK tdeio-shared DESTINATION ${BIN_INSTALL_DIR} ) + +##### testtrash (executable) ####################### +tde_add_executable( testtrash + SOURCES testtrash.cpp AUTOMOC + LINK trashcommon-static tdeio-shared +) diff --git a/tdeioslave/trash/Makefile.am b/tdeioslave/trash/Makefile.am index 02b43e90a..a3c8253e0 100644 --- a/tdeioslave/trash/Makefile.am +++ b/tdeioslave/trash/Makefile.am @@ -3,7 +3,7 @@ METASOURCES = AUTO SUBDIRS = . tdefile-plugin -kde_module_LTLIBRARIES = tdeio_trash.la +kde_module_LTLIBRARIES = tdeio_trash.la ktrashpropsdlgplugin.la tdeio_trash_la_SOURCES = tdeio_trash.cpp tdeio_trash_la_LIBADD = libtrashcommon.la $(LIB_TDEIO) @@ -17,7 +17,7 @@ ktrash_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $ kde_services_DATA = trash.protocol noinst_LTLIBRARIES = libtrashcommon.la -libtrashcommon_la_SOURCES = trashimpl.cpp +libtrashcommon_la_SOURCES = trashimpl.cpp discspaceutil.cpp check_PROGRAMS = testtrash testtrash_SOURCES = testtrash.cpp @@ -29,3 +29,12 @@ TESTS = testtrash messages: $(XGETTEXT) `find . -name "*.cc" -o -name "*.cpp" -o -name "*.h"` -o $(podir)/tdeio_trash.pot +# ktrashpropsdlgplugin target +noinst_HEADERS = ktrashpropsdlgplugin.h discspaceutil.h + +ktrashpropsdlgplugin_la_SOURCES = ktrashpropsdlgplugin.cpp discspaceutil.cpp trashimpl.cpp +ktrashpropsdlgplugin_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +ktrashpropsdlgplugin_la_LIBADD = $(LIB_TDEIO) + +services_DATA = ktrashpropsdlgplugin.desktop +servicesdir = $(kde_servicesdir) diff --git a/tdeioslave/trash/discspaceutil.cpp b/tdeioslave/trash/discspaceutil.cpp new file mode 100644 index 000000000..a771638fc --- /dev/null +++ b/tdeioslave/trash/discspaceutil.cpp @@ -0,0 +1,112 @@ +/* + This file is part of the KDE project + + Copyright (C) 2008 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <tqapplication.h> +#include <tqdir.h> +#include <tqeventloop.h> +#include <tqfileinfo.h> + +#include <kdiskfreesp.h> +#include <kdebug.h> + +#include "discspaceutil.h" + +DiscSpaceUtil::DiscSpaceUtil( const TQString &directory, TQObject *parent ) + : TQObject( parent ), + mDirectory( directory ), + mFullSize( 0 ) +{ + calculateFullSize(); +} + +unsigned long DiscSpaceUtil::sizeOfPath( const TQString &path ) +{ + TQFileInfo info( path ); + if ( !info.exists() ) { + return 0; + } + + if ( info.isFile() ) { + return info.size(); + } else if ( info.isDir() ) { + TQDir dir( path ); + const TQFileInfoList *infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs | TQDir::NoSymLinks ); + TQFileInfoListIterator it( *infos ); + + unsigned long sum = 0; + TQFileInfo *info = 0; + while ( (info = it.current()) != 0 ) { + if ( info->fileName() != "." && info->fileName() != ".." ) + sum += sizeOfPath( info->absFilePath() ); + ++it; + } + + return sum; + } else { + return 0; + } +} + +double DiscSpaceUtil::usage( unsigned long additional ) const +{ + if ( mFullSize == 0 ) + return 0; + + unsigned long sum = sizeOfPath( mDirectory ); + sum += additional; + + sum = sum/1024; // convert to kB + + return (((double)sum*100)/(double)mFullSize); +} + +unsigned long DiscSpaceUtil::size() const +{ + return mFullSize; +} + +TQString DiscSpaceUtil::mountPoint() const +{ + return mMountPoint; +} + +void DiscSpaceUtil::foundMountPoint( const TQString &mountPoint, unsigned long kbSize, unsigned long, unsigned long ) +{ + mFullSize = kbSize; + mMountPoint = mountPoint; +} + +void DiscSpaceUtil::done() +{ + tqApp->eventLoop()->exitLoop(); +} + +void DiscSpaceUtil::calculateFullSize() +{ + KDiskFreeSp *sp = KDiskFreeSp::findUsageInfo( mDirectory ); + connect( sp, SIGNAL( foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ) ), + this, SLOT( foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ) ) ); + connect( sp, SIGNAL( done() ), this, SLOT( done() ) ); + + tqApp->eventLoop()->enterLoop(); +} + +#include "discspaceutil.moc" diff --git a/tdeioslave/trash/discspaceutil.h b/tdeioslave/trash/discspaceutil.h new file mode 100644 index 000000000..a43b7b2cd --- /dev/null +++ b/tdeioslave/trash/discspaceutil.h @@ -0,0 +1,81 @@ +/* + This file is part of the KDE project + + Copyright (C) 2008 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef DISCSPACEUTIL_H +#define DISCSPACEUTIL_H + +#include <tqobject.h> +#include <tqstring.h> + +/** + * A small utility class to access and calculate + * size and usage of mount points. + */ +class DiscSpaceUtil : public TQObject +{ + Q_OBJECT + + public: + /** + * Creates a new disc space util. + * + * @param directory A directory the util shall work on. + * @param parent The parent object. + */ + explicit DiscSpaceUtil( const TQString &directory, TQObject *parent = 0 ); + + /** + * Returns the usage of the directory pass in the constructor on this + * mount point in percent. + * + * @param additional An additional amount of bytes that is added to the + * directory size before the usage is calculated. + */ + double usage( unsigned long additional = 0 ) const; + + /** + * Returns the size of the partition in kilo bytes. + */ + unsigned long size() const; + + /** + * Returns the mount point of the directory. + */ + TQString mountPoint() const; + + /** + * Returns the size of the given path in bytes. + */ + static unsigned long sizeOfPath( const TQString &path ); + + private slots: + void foundMountPoint( const TQString&, unsigned long, unsigned long, unsigned long ); + void done(); + + private: + void calculateFullSize(); + + TQString mDirectory; + unsigned long mFullSize; + TQString mMountPoint; +}; + +#endif diff --git a/tdeioslave/trash/ktrashpropsdlgplugin.cpp b/tdeioslave/trash/ktrashpropsdlgplugin.cpp new file mode 100644 index 000000000..9d18f2acf --- /dev/null +++ b/tdeioslave/trash/ktrashpropsdlgplugin.cpp @@ -0,0 +1,316 @@ +/* + This file is part of the KDE project + + Copyright (C) 2008 Tobias Koenig <tokoe@kde.org> + Copyright (C) 2016 Emanoil Kotsev <deloptes@yahoo.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ktrashpropsdlgplugin.h" +#include "discspaceutil.h" +#include "trashimpl.h" + +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqlistbox.h> +#include <tqspinbox.h> + +#include <kdesktopfile.h> +#include <kgenericfactory.h> +#include <tdeglobal.h> +#include <kiconloader.h> +#include <tdelocale.h> +#include <knuminput.h> + +#include <kdebug.h> + +typedef KGenericFactory<KTrashPropsDlgPlugin, KPropertiesDialog> Factory; +K_EXPORT_COMPONENT_FACTORY( ktrashpropsdlgplugin, Factory( "ktrashpropsdlgplugin" ) ) + +KTrashPropsDlgPlugin::KTrashPropsDlgPlugin( KPropertiesDialog *dialog, const char*, const TQStringList& ) + : KPropsDlgPlugin( dialog ) +{ + kdDebug() << "KTrashPropsDlgPlugin::KTrashPropsDlgPlugin called" << endl; + if ( dialog->items().count() != 1 ) + return; + + KFileItem *item = dialog->items().first(); + + if ( !KPropsDlgPlugin::isDesktopFile( item ) ) + return; + + kdDebug() << "KPropsDlgPlugin::isDesktopFile( item ) passed" << endl; + KDesktopFile deskFile( item->url().path(), true /* readonly */ ); + + if ( deskFile.readURL() != "trash:/" ) + return; + + kdDebug() << "deskFile.readURL() != \"trash:/\") passed" << endl; + TDEGlobal::locale()->insertCatalogue( "tdeio_trash" ); + + mTrashImpl = new TrashImpl(); + mTrashImpl->init(); + + readConfig(); + + TQFrame *frame = dialog->addPage( i18n( "Size Limits" ) ); + setupGui( frame ); + + + mUseTimeLimit->setChecked( mConfigMap[ mCurrentTrash ].useTimeLimit ); + mUseSizeLimit->setChecked( mConfigMap[ mCurrentTrash ].useSizeLimit ); + mDays->setValue( mConfigMap[ mCurrentTrash ].days ); + mPercent->setValue( mConfigMap[ mCurrentTrash ].percent ); + mPercent->setPrecision(3); + mLimitReachedAction->setCurrentItem( mConfigMap[ mCurrentTrash ].actionType ); + percentChanged(mPercent->value()); + + useTypeChanged(); + + connect( mUseTimeLimit, SIGNAL( toggled( bool ) ), + this, SLOT( setDirty() ) ); + connect( mUseTimeLimit, SIGNAL( toggled( bool ) ), + this, SLOT( useTypeChanged() ) ); + connect( mDays, SIGNAL( valueChanged( int ) ), + this, SLOT( setDirty() ) ); + connect( mUseSizeLimit, SIGNAL( toggled( bool ) ), + this, SLOT( setDirty() ) ); + connect( mUseSizeLimit, SIGNAL( toggled( bool ) ), + this, SLOT( useTypeChanged() ) ); + connect( mPercent, SIGNAL( valueChanged( double ) ), + this, SLOT( percentChanged( double ) ) ); + connect( mPercent, SIGNAL( valueChanged( double ) ), + this, SLOT( setDirty() ) ); + connect( mLimitReachedAction, SIGNAL( activated( int ) ), + this, SLOT( setDirty() ) ); + + trashChanged( 0 ); +} + +KTrashPropsDlgPlugin::~KTrashPropsDlgPlugin() +{ +} + +void KTrashPropsDlgPlugin::applyChanges() +{ + if ( !mCurrentTrash.isEmpty() ) { + ConfigEntry entry; + entry.useTimeLimit = mUseTimeLimit->isChecked(); + entry.days = mDays->value(); + entry.useSizeLimit = mUseSizeLimit->isChecked(); + entry.percent = mPercent->value(), + entry.actionType = mLimitReachedAction->currentItem(); + mConfigMap.insert( mCurrentTrash, entry ); + } + + writeConfig(); +} + +void KTrashPropsDlgPlugin::percentChanged( double percent ) +{ + DiscSpaceUtil util( mCurrentTrash ); + + double partitionSize = util.size() * 1024.0; // convert to byte + + double size = partitionSize*(percent/100.0); + +// Step should be depending on size +// https://api.kde.org/3.5-api/kdelibs-apidocs/kdeui/html/classKDoubleSpinBox.html +// https://api.kde.org/3.5-api/kdelibs-apidocs/kdeui/html/knuminput_8cpp_source.html + mPercent->setPrecision(3); + + TQString unit = i18n( "Byte" ); + if ( size > 1024 ) { + unit = i18n( "KByte" ); + size = size/1024.0; + mPercent->setLineStep(0.001); + } + if ( size > 1024 ) { + unit = i18n( "MByte" ); + size = size/1024.0; + mPercent->setLineStep(0.01); + } + if ( size > 1024 ) { + unit = i18n( "GByte" ); + size = size/1024.0; + mPercent->setLineStep(0.1); + } + if ( size > 1024 ) { + unit = i18n( "TByte" ); + size = size/1024.0; + mPercent->setLineStep(1); + } + + mSizeLabel->setText( i18n( "(%1 %2)" ).arg( TQString::number( size, 'f', 2 ) ).arg( unit ) ); + +} + +void KTrashPropsDlgPlugin::trashChanged( int value ) +{ + const TrashImpl::TrashDirMap map = mTrashImpl->trashDirectories(); + + if ( !mCurrentTrash.isEmpty() ) { + ConfigEntry entry; + entry.useTimeLimit = mUseTimeLimit->isChecked(); + entry.days = mDays->value(); + entry.useSizeLimit = mUseSizeLimit->isChecked(); + entry.percent = mPercent->value(), + entry.actionType = mLimitReachedAction->currentItem(); + mConfigMap.insert( mCurrentTrash, entry ); + } + + mCurrentTrash = map[ value ]; + + if ( mConfigMap.contains( mCurrentTrash ) ) { + const ConfigEntry entry = mConfigMap[ mCurrentTrash ]; + mUseTimeLimit->setChecked( entry.useTimeLimit ); + mDays->setValue( entry.days ); + mUseSizeLimit->setChecked( entry.useSizeLimit ); + mPercent->setValue( entry.percent ); + mLimitReachedAction->setCurrentItem( entry.actionType ); + } else { + mUseTimeLimit->setChecked( false ); + mDays->setValue( 7 ); + mUseSizeLimit->setChecked( true ); + mPercent->setValue( 10.0 ); + mLimitReachedAction->setCurrentItem( 0 ); + } + + percentChanged( mPercent->value() ); +} + +void KTrashPropsDlgPlugin::useTypeChanged() +{ + mDays->setEnabled( mUseTimeLimit->isChecked() ); + mSizeWidget->setEnabled( mUseSizeLimit->isChecked() ); +} + +void KTrashPropsDlgPlugin::readConfig() +{ + kdDebug() << "KTrashPropsDlgPlugin::readConfig() called" << endl; + TDEConfig config( "trashrc" ); + mConfigMap.clear(); + + const TQStringList groups = config.groupList(); + for ( uint i = 0; i < groups.count(); ++i ) { + if ( groups[ i ].startsWith( "/" ) ) { + config.setGroup( groups[ i ] ); + ConfigEntry entry; + entry.useTimeLimit = config.readBoolEntry( "UseTimeLimit", false ); + entry.days = config.readNumEntry( "Days", 7 ); + entry.useSizeLimit = config.readBoolEntry( "UseSizeLimit", true ); + entry.percent = config.readDoubleNumEntry( "Percent", 10 ); + entry.actionType = config.readNumEntry( "LimitReachedAction", 0 ); + mConfigMap.insert( groups[ i ], entry ); + } + } +} + +void KTrashPropsDlgPlugin::writeConfig() +{ + kdDebug() << "KTrashPropsDlgPlugin::writeConfig() called" << endl; + TDEConfig config( "trashrc" ); + + // first delete all existing groups + const TQStringList groups = config.groupList(); + for ( uint i = 0; i < groups.count(); ++i ) + if ( groups[ i ].startsWith( "/" ) ) + config.deleteGroup( groups[ i ] ); + + TQMapConstIterator<TQString, ConfigEntry> it; + for ( it = mConfigMap.begin(); it != mConfigMap.end(); ++it ) { + config.setGroup( it.key() ); + config.writeEntry( "UseTimeLimit", it.data().useTimeLimit ); + config.writeEntry( "Days", it.data().days ); + config.writeEntry( "UseSizeLimit", it.data().useSizeLimit ); + config.writeEntry( "Percent", it.data().percent ); + config.writeEntry( "LimitReachedAction", it.data().actionType ); + } + + config.sync(); +} + +void KTrashPropsDlgPlugin::setupGui( TQFrame *frame ) +{ + kdDebug() << "KTrashPropsDlgPlugin::setupGui( TQFrame *frame )" << endl; + TQVBoxLayout *layout = new TQVBoxLayout( frame, 11, 6 ); + + TrashImpl::TrashDirMap map = mTrashImpl->trashDirectories(); + if ( map.count() != 1 ) { + // If we have multiple trashes, we setup a widget to choose + // which trash to configure + TQListBox *mountPoints = new TQListBox( frame ); + layout->addWidget( mountPoints ); + + const TQPixmap folderPixmap = TDEGlobal::iconLoader()->loadIcon( "folder", TDEIcon::Small ); + TQMapConstIterator<int, TQString> it; + for ( it = map.begin(); it != map.end(); ++it ) { + DiscSpaceUtil util( it.data() ); + mountPoints->insertItem( folderPixmap, util.mountPoint(), it.key() ); + } + + mountPoints->setCurrentItem( 0 ); + + connect( mountPoints, SIGNAL( highlighted( int ) ), SLOT( trashChanged( int ) ) ); + } else { + mCurrentTrash = map[0]; + } + + TQHBoxLayout *daysLayout = new TQHBoxLayout( layout ); + + mUseTimeLimit = new TQCheckBox( i18n( "Delete files older than:" ), frame ); + daysLayout->addWidget( mUseTimeLimit ); + mDays = new TQSpinBox( 1, 365, 1, frame ); + mDays->setSuffix( " days" ); + daysLayout->addWidget( mDays ); + + TQGridLayout *sizeLayout = new TQGridLayout( layout, 2, 2 ); + mUseSizeLimit = new TQCheckBox( i18n( "Limit to maximum size" ), frame ); + sizeLayout->addMultiCellWidget( mUseSizeLimit, 0, 0, 0, 1 ); + + mSizeWidget = new TQWidget( frame ); + sizeLayout->setColSpacing( 0, 30 ); + sizeLayout->addWidget( mSizeWidget, 1, 1 ); + + TQGridLayout *sizeWidgetLayout = new TQGridLayout( mSizeWidget, 2, 3, 11, 6 ); + + TQLabel *label = new TQLabel( i18n( "Maximum Size:" ), mSizeWidget ); + sizeWidgetLayout->addWidget( label, 0, 0 ); + + mPercent = new KDoubleSpinBox( 0.001, 100, 1, 10, 3, mSizeWidget ); + mPercent->setSuffix( " %" ); + sizeWidgetLayout->addWidget( mPercent, 0, 1 ); + + mSizeLabel = new TQLabel( mSizeWidget ); + sizeWidgetLayout->addWidget( mSizeLabel, 0, 2 ); + + label = new TQLabel( i18n( "When limit reached:" ), mSizeWidget ); + sizeWidgetLayout->addWidget( label, 1, 0 ); + + mLimitReachedAction = new TQComboBox( mSizeWidget ); + mLimitReachedAction->insertItem( i18n( "Warn me" ) ); + mLimitReachedAction->insertItem( i18n( "Delete oldest files from trash" ) ); + mLimitReachedAction->insertItem( i18n( "Delete biggest files from trash" ) ); + sizeWidgetLayout->addMultiCellWidget( mLimitReachedAction, 1, 1, 1, 2 ); + + layout->addStretch(); + +} + +#include "ktrashpropsdlgplugin.moc" diff --git a/tdeioslave/trash/ktrashpropsdlgplugin.desktop b/tdeioslave/trash/ktrashpropsdlgplugin.desktop new file mode 100644 index 000000000..91f0632b0 --- /dev/null +++ b/tdeioslave/trash/ktrashpropsdlgplugin.desktop @@ -0,0 +1,6 @@ +[Desktop Entry] +Type=Service +Name=Trash Properties Page +Name[bg]=Свойства на кошчето +X-TDE-Library=ktrashpropsdlgplugin +X-TDE-ServiceTypes=KPropsDlg/Plugin,media/builtin-trash diff --git a/tdeioslave/trash/ktrashpropsdlgplugin.h b/tdeioslave/trash/ktrashpropsdlgplugin.h new file mode 100644 index 000000000..d47e75dd3 --- /dev/null +++ b/tdeioslave/trash/ktrashpropsdlgplugin.h @@ -0,0 +1,78 @@ +/* + This file is part of the KDE project + + Copyright (C) 2008 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KTRASHPROPSDLGPLUGIN_H +#define KTRASHPROPSDLGPLUGIN_H + +#include <kpropertiesdialog.h> + +class KDoubleSpinBox; +class TQCheckBox; +class TQComboBox; +class TQFrame; +class TQLabel; +class TQSpinBox; +class TrashImpl; + +class KTrashPropsDlgPlugin : public KPropsDlgPlugin +{ + Q_OBJECT + + public: + KTrashPropsDlgPlugin( KPropertiesDialog *dialog, const char*, const TQStringList& ); + ~KTrashPropsDlgPlugin(); + + virtual void applyChanges(); + + private slots: + void percentChanged( double ); + void trashChanged( int ); + void useTypeChanged(); + + private: + void readConfig(); + void writeConfig(); + void setupGui( TQFrame *frame ); + + TQCheckBox *mUseTimeLimit; + TQSpinBox *mDays; + TQCheckBox *mUseSizeLimit; + TQWidget *mSizeWidget; + KDoubleSpinBox *mPercent; + TQLabel *mSizeLabel; + TQComboBox *mLimitReachedAction; + + TrashImpl *mTrashImpl; + TQString mCurrentTrash; + + typedef struct { + bool useTimeLimit; + int days; + bool useSizeLimit; + double percent; + int actionType; + } ConfigEntry; + + typedef TQMap<TQString, ConfigEntry> ConfigMap; + ConfigMap mConfigMap; +}; + +#endif diff --git a/tdeioslave/trash/testtrash.cpp b/tdeioslave/trash/testtrash.cpp index db2e73fb3..fc5b358af 100644 --- a/tdeioslave/trash/testtrash.cpp +++ b/tdeioslave/trash/testtrash.cpp @@ -24,7 +24,7 @@ #include "tdeio_trash.h" #include "testtrash.h" -#include <config.h> +// #include <config.h> #include <kurl.h> #include <tdelocale.h> diff --git a/tdeioslave/trash/trash.protocol b/tdeioslave/trash/trash.protocol index ba3fd5dc7..e1029d038 100644 --- a/tdeioslave/trash/trash.protocol +++ b/tdeioslave/trash/trash.protocol @@ -86,4 +86,4 @@ ExtraNames[vi]=Đường dẫn Trước khi vứt,Ngày Vứt ExtraNames[wa]=Oridjinå tchmin,Date di disfaçaedje ExtraNames[zh_CN]=原始路径,删除日期 ExtraNames[zh_TW]=原始路徑,刪除日期 -ExtraTypes=QString,QDateTime +ExtraTypes=TQString,TQDateTime diff --git a/tdeioslave/trash/trashimpl.cpp b/tdeioslave/trash/trashimpl.cpp index c96d15d3a..1b67e5949 100644 --- a/tdeioslave/trash/trashimpl.cpp +++ b/tdeioslave/trash/trashimpl.cpp @@ -18,6 +18,8 @@ */ #include "trashimpl.h" +#include "discspaceutil.h" + #include <tdelocale.h> #include <klargefile.h> #include <tdeio/global.h> @@ -322,6 +324,9 @@ bool TrashImpl::deleteInfo( int trashId, const TQString& fileId ) bool TrashImpl::moveToTrash( const TQString& origPath, int trashId, const TQString& fileId ) { kdDebug() << k_funcinfo << endl; + if ( !adaptTrashSize( origPath, trashId ) ) + return false; + const TQString dest = filesPath( trashId, fileId ); if ( !move( origPath, dest ) ) { // Maybe the move failed due to no permissions to delete source. @@ -387,6 +392,9 @@ void TrashImpl::jobFinished(TDEIO::Job* job) bool TrashImpl::copyToTrash( const TQString& origPath, int trashId, const TQString& fileId ) { kdDebug() << k_funcinfo << endl; + if ( !adaptTrashSize( origPath, trashId ) ) + return false; + const TQString dest = filesPath( trashId, fileId ); if ( !copy( origPath, dest ) ) return false; @@ -959,4 +967,91 @@ bool TrashImpl::parseURL( const KURL& url, int& trashId, TQString& fileId, TQStr return true; } +bool TrashImpl::adaptTrashSize( const TQString& origPath, int trashId ) +{ + TDEConfig config( "trashrc" ); + + const TQString trashPath = trashDirectoryPath( trashId ); + config.setGroup( trashPath ); + + bool useTimeLimit = config.readBoolEntry( "UseTimeLimit", false ); + bool useSizeLimit = config.readBoolEntry( "UseSizeLimit", true ); + double percent = config.readDoubleNumEntry( "Percent", 10 ); + int actionType = config.readNumEntry( "LimitReachedAction", 0 ); + + if ( useTimeLimit ) { // delete all files in trash older than X days + const int maxDays = config.readNumEntry( "Days", 7 ); + const TQDateTime currentDate = TQDateTime::currentDateTime(); + + const TrashedFileInfoList trashedFiles = list(); + for ( uint i = 0; i < trashedFiles.count(); ++i ) { + struct TrashedFileInfo info = trashedFiles[ i ]; + if ( info.trashId != trashId ) + continue; + + if ( info.deletionDate.daysTo( currentDate ) > maxDays ) + del( info.trashId, info.fileId ); + } + + return true; + + } + + if ( useSizeLimit ) { // check if size limit exceeded + + // calculate size of the files to be put into the trash + unsigned long additionalSize = DiscSpaceUtil::sizeOfPath( origPath ); + + DiscSpaceUtil util( trashPath + "/files/" ); + if ( util.usage( additionalSize ) >= percent ) { + if ( actionType == 0 ) { // warn the user only + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n( "The trash has reached its maximum size!\nClean the trash manually." ); + return false; + } else { + // before we start to remove any files from the trash, + // check whether the new file will fit into the trash + // at all... + + unsigned long partitionSize = util.size(); // in kB + unsigned long fileSize = additionalSize/1024; // convert to kB + + if ( ((double)fileSize*100/(double)partitionSize) >= percent ) { + m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; + m_lastErrorMessage = i18n( "The file is too large to be trashed." ); + return false; + } + + // the size of the to be trashed file is ok, so lets start removing + // some other files from the trash + + TQDir dir( trashPath + "/files" ); + const TQFileInfoList *infos = 0; + if ( actionType == 1 ) // delete oldest files first + infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs, TQDir::Time | TQDir::Reversed ); + else if ( actionType == 2 ) // delete biggest files first + infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs, TQDir::Size ); + else + tqWarning( "Should never happen!" ); + + TQFileInfoListIterator it( *infos ); + TQFileInfo *info; + bool deleteFurther = true; + while ( ((info = it.current()) != 0) && deleteFurther ) { + + if ( info->fileName() != "." && info->fileName() != ".." ) { + del( trashId, info->fileName() ); // delete trashed file + + if ( util.usage( additionalSize ) < percent ) // check whether we have enough space now + deleteFurther = false; + } + ++it; + } + } + } + } + + return true; +} + #include "trashimpl.moc" diff --git a/tdeioslave/trash/trashimpl.h b/tdeioslave/trash/trashimpl.h index 3a06dd9e8..b02ae4709 100644 --- a/tdeioslave/trash/trashimpl.h +++ b/tdeioslave/trash/trashimpl.h @@ -123,6 +123,8 @@ private: void fileAdded(); void fileRemoved(); + bool adaptTrashSize( const TQString& origPath, int trashId ); + // Warning, returns error code, not a bool int testDir( const TQString& name ) const; void error( int e, const TQString& s ); |