Improved code for trash bin management.

1. When size limit is used, a file bigger than the trash size can't be
trashed anymore (a warning message is shown).
2. When size limit is used and warning policy selected, files can't be
trashed anymore if the total size of the trash will exceed the set size
(a warning message is shown).
3. When the trash size settings are modified, the content of the trash
is adjusted based on the new settings.
4. Fixed load/saving of trash options when more than one trash folder exists.

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/34/head
Michele Calgaro 6 years ago
parent 691c9204a1
commit c53dbf95cb
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -241,6 +241,13 @@ void KTrashPropsDlgPlugin::applyChanges()
} }
writeConfig(); writeConfig();
// Adjust trash size if necessary
TrashImpl::TrashDirMap trashDirs = mTrashImpl->trashDirectories();
for (TrashImpl::TrashDirMap::ConstIterator it = trashDirs.begin(); it != trashDirs.end(); ++it)
{
mTrashImpl->resizeTrash(it.key());
}
} }
void KTrashPropsDlgPlugin::percentSizeChanged( double percent ) void KTrashPropsDlgPlugin::percentSizeChanged( double percent )
@ -370,7 +377,7 @@ void KTrashPropsDlgPlugin::trashChanged( int value )
mUseTimeLimit->setChecked( entry.useTimeLimit ); mUseTimeLimit->setChecked( entry.useTimeLimit );
mDays->setValue( entry.days ); mDays->setValue( entry.days );
mUseSizeLimit->setChecked( entry.useSizeLimit ); mUseSizeLimit->setChecked( entry.useSizeLimit );
if ( mSizeLimitType == SIZE_LIMIT_FIXED ) if ( entry.sizeLimitType == SIZE_LIMIT_FIXED )
{ {
mRbFixedSize->setChecked( true ); mRbFixedSize->setChecked( true );
} }
@ -414,13 +421,13 @@ void KTrashPropsDlgPlugin::readConfig()
config.setGroup( groups[ i ] ); config.setGroup( groups[ i ] );
ConfigEntry entry; ConfigEntry entry;
entry.useTimeLimit = config.readBoolEntry( "UseTimeLimit", false ); entry.useTimeLimit = config.readBoolEntry( "UseTimeLimit", false );
entry.days = config.readNumEntry( "Days", 7 ); entry.days = config.readNumEntry( "Days", 32000 );
entry.useSizeLimit = config.readBoolEntry( "UseSizeLimit", true ); entry.useSizeLimit = config.readBoolEntry( "UseSizeLimit", true );
entry.sizeLimitType = config.readNumEntry( "SizeLimitType", SIZE_LIMIT_PERCENT ); entry.sizeLimitType = config.readNumEntry( "SizeLimitType", SIZE_LIMIT_PERCENT );
entry.percent = config.readDoubleNumEntry( "Percent", 10 ); entry.percent = config.readDoubleNumEntry( "Percent", 10 );
entry.fixedSize = config.readDoubleNumEntry( "FixedSize", 500 ); entry.fixedSize = config.readDoubleNumEntry( "FixedSize", 500 );
entry.fixedSizeUnit = config.readNumEntry( "FixedSizeUnit", SIZE_ID_MB ); entry.fixedSizeUnit = config.readNumEntry( "FixedSizeUnit", SIZE_ID_MB );
entry.actionType = config.readNumEntry( "LimitReachedAction", 0 ); entry.actionType = config.readNumEntry( "LimitReachedAction", TrashConstant::ACTION_WARNING );
mConfigMap.insert( groups[ i ], entry ); mConfigMap.insert( groups[ i ], entry );
} }
} }

@ -62,7 +62,6 @@ KTrashPropsWidget::KTrashPropsWidget(TQWidget *parent, const char *name)
inhibitChangedSignal = true; inhibitChangedSignal = true;
load(); load();
trashChanged(0);
} }
KTrashPropsWidget::~KTrashPropsWidget() KTrashPropsWidget::~KTrashPropsWidget()
@ -90,11 +89,8 @@ void KTrashPropsWidget::setupGui()
mountPoints->setCurrentItem(0); mountPoints->setCurrentItem(0);
connect(mountPoints, TQT_SIGNAL(highlighted(int)), TQT_SLOT(trashChanged(int))); connect(mountPoints, TQT_SIGNAL(highlighted(int)), TQT_SLOT(trashChanged(int)));
} }
else
{
mCurrentTrash = map[0];
}
mCurrentTrash = map[0];
mUseTimeLimit = new TQCheckBox(i18n("Delete files older than:"), this); mUseTimeLimit = new TQCheckBox(i18n("Delete files older than:"), this);
wlayout->addMultiCellWidget(mUseTimeLimit, multiTrashRow + 0, multiTrashRow + 0, 0, 1); wlayout->addMultiCellWidget(mUseTimeLimit, multiTrashRow + 0, multiTrashRow + 0, 0, 1);
mDays = new TQSpinBox(1, 365, 1, this); mDays = new TQSpinBox(1, 365, 1, this);
@ -150,28 +146,36 @@ void KTrashPropsWidget::setDirty()
void KTrashPropsWidget::load() void KTrashPropsWidget::load()
{ {
readConfig(); inhibitChangedSignal = true;
mUseTimeLimit->setChecked(mConfigMap[mCurrentTrash].useTimeLimit); readConfig();
mUseSizeLimit->setChecked(mConfigMap[mCurrentTrash].useSizeLimit); if (mConfigMap.contains(mCurrentTrash))
mSizeLimitType = mConfigMap[mCurrentTrash].sizeLimitType;
if (mSizeLimitType == SIZE_LIMIT_FIXED)
{ {
mRbFixedSize->setChecked(true); mUseTimeLimit->setChecked(mConfigMap[mCurrentTrash].useTimeLimit);
mUseSizeLimit->setChecked(mConfigMap[mCurrentTrash].useSizeLimit);
mSizeLimitType = mConfigMap[mCurrentTrash].sizeLimitType;
if (mSizeLimitType == SIZE_LIMIT_FIXED)
{
mRbFixedSize->setChecked(true);
}
else
{
mRbPercentSize->setChecked(true);
}
mDays->setValue(mConfigMap[mCurrentTrash].days);
mPercentSize->setValue(mConfigMap[mCurrentTrash].percent);
mFixedSize->setValue(mConfigMap[mCurrentTrash].fixedSize);
mFixedSizeUnit->setCurrentItem(mConfigMap[mCurrentTrash].fixedSizeUnit);
mLimitReachedAction->setCurrentItem(mConfigMap[mCurrentTrash].actionType);
percentSizeChanged(mPercentSize->value());
fixedSizeChanged(mFixedSize->value());
} }
else else
{ {
mRbPercentSize->setChecked(true); setDefaultValues();
} }
mDays->setValue(mConfigMap[mCurrentTrash].days);
mPercentSize->setValue(mConfigMap[mCurrentTrash].percent);
mFixedSize->setValue(mConfigMap[mCurrentTrash].fixedSize);
mFixedSizeUnit->setCurrentItem(mConfigMap[mCurrentTrash].fixedSizeUnit);
mLimitReachedAction->setCurrentItem(mConfigMap[mCurrentTrash].actionType);
percentSizeChanged(mPercentSize->value());
fixedSizeChanged(mFixedSize->value());
useTypeChanged();
useTypeChanged();
inhibitChangedSignal = false; inhibitChangedSignal = false;
} }
@ -199,6 +203,13 @@ void KTrashPropsWidget::save()
} }
writeConfig(); writeConfig();
// Adjust trash size if necessary
TrashImpl::TrashDirMap trashDirs = mTrashImpl->trashDirectories();
for (TrashImpl::TrashDirMap::ConstIterator it = trashDirs.begin(); it != trashDirs.end(); ++it)
{
mTrashImpl->resizeTrash(it.key());
}
} }
void KTrashPropsWidget::setDefaultValues() void KTrashPropsWidget::setDefaultValues()
@ -214,7 +225,6 @@ void KTrashPropsWidget::setDefaultValues()
{ {
mRbPercentSize->setChecked(true); mRbPercentSize->setChecked(true);
} }
mDays->setValue(mConfigMap[mCurrentTrash].days); mDays->setValue(mConfigMap[mCurrentTrash].days);
mPercentSize->setValue(1); mPercentSize->setValue(1);
mFixedSize->setValue(500); mFixedSize->setValue(500);
@ -363,7 +373,7 @@ void KTrashPropsWidget::trashChanged(int value)
mUseTimeLimit->setChecked(entry.useTimeLimit); mUseTimeLimit->setChecked(entry.useTimeLimit);
mDays->setValue(entry.days); mDays->setValue(entry.days);
mUseSizeLimit->setChecked(entry.useSizeLimit); mUseSizeLimit->setChecked(entry.useSizeLimit);
if (mSizeLimitType == SIZE_LIMIT_FIXED) if (entry.sizeLimitType == SIZE_LIMIT_FIXED)
{ {
mRbFixedSize->setChecked(true); mRbFixedSize->setChecked(true);
} }
@ -419,13 +429,13 @@ void KTrashPropsWidget::readConfig()
config.setGroup(groups[i]); config.setGroup(groups[i]);
ConfigEntry entry; ConfigEntry entry;
entry.useTimeLimit = config.readBoolEntry("UseTimeLimit", false); entry.useTimeLimit = config.readBoolEntry("UseTimeLimit", false);
entry.days = config.readNumEntry("Days", 7); entry.days = config.readNumEntry("Days", 32000);
entry.useSizeLimit = config.readBoolEntry("UseSizeLimit", true); entry.useSizeLimit = config.readBoolEntry("UseSizeLimit", true);
entry.sizeLimitType = config.readNumEntry("SizeLimitType", SIZE_LIMIT_PERCENT); entry.sizeLimitType = config.readNumEntry("SizeLimitType", SIZE_LIMIT_PERCENT);
entry.percent = config.readDoubleNumEntry("Percent", 10); entry.percent = config.readDoubleNumEntry("Percent", 10);
entry.fixedSize = config.readDoubleNumEntry("FixedSize", 500); entry.fixedSize = config.readDoubleNumEntry("FixedSize", 500);
entry.fixedSizeUnit = config.readNumEntry("FixedSizeUnit", SIZE_ID_MB); entry.fixedSizeUnit = config.readNumEntry("FixedSizeUnit", SIZE_ID_MB);
entry.actionType = config.readNumEntry("LimitReachedAction", 0); entry.actionType = config.readNumEntry("LimitReachedAction", ACTION_WARNING);
mConfigMap.insert(groups[i], entry); mConfigMap.insert(groups[i], entry);
} }
} }

@ -36,6 +36,13 @@ namespace TrashConstant
SIZE_ID_GB = 3, SIZE_ID_GB = 3,
SIZE_ID_TB = 4 SIZE_ID_TB = 4
}; };
enum
{
ACTION_WARNING = 0,
ACTION_DELETE_OLDEST = 1,
ACTION_DELETE_BIGGEST = 2
};
} }
#endif #endif

@ -19,6 +19,7 @@
#include "trashimpl.h" #include "trashimpl.h"
#include "discspaceutil.h" #include "discspaceutil.h"
#include "trash_constant.h"
#include <tdelocale.h> #include <tdelocale.h>
#include <klargefile.h> #include <klargefile.h>
@ -31,6 +32,7 @@
#include <kstandarddirs.h> #include <kstandarddirs.h>
#include <tdeglobalsettings.h> #include <tdeglobalsettings.h>
#include <kmountpoint.h> #include <kmountpoint.h>
#include <tdemessagebox.h>
#include <tdefileitem.h> #include <tdefileitem.h>
#include <tdeio/chmodjob.h> #include <tdeio/chmodjob.h>
@ -48,8 +50,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include "trash_constant.h"
TrashImpl::TrashImpl() : TrashImpl::TrashImpl() :
TQObject(), TQObject(),
m_lastErrorCode( 0 ), m_lastErrorCode( 0 ),
@ -977,10 +977,10 @@ bool TrashImpl::adaptTrashSize( const TQString& origPath, int trashId )
double percent = config.readDoubleNumEntry( "Percent", 10 ); double percent = config.readDoubleNumEntry( "Percent", 10 );
double fixedSize = config.readDoubleNumEntry( "FixedSize", 500 ); double fixedSize = config.readDoubleNumEntry( "FixedSize", 500 );
int fixedSizeUnit = config.readNumEntry( "FixedSizeUnit", TrashConstant::SIZE_ID_MB ); int fixedSizeUnit = config.readNumEntry( "FixedSizeUnit", TrashConstant::SIZE_ID_MB );
int actionType = config.readNumEntry( "LimitReachedAction", 0 ); int actionType = config.readNumEntry( "LimitReachedAction", TrashConstant::ACTION_WARNING );
if ( useTimeLimit ) { // delete all files in trash older than X days if ( useTimeLimit ) { // delete all files in trash older than X days
const int maxDays = config.readNumEntry( "Days", 7 ); const int maxDays = config.readNumEntry( "Days", 32000 );
const TQDateTime currentDate = TQDateTime::currentDateTime(); const TQDateTime currentDate = TQDateTime::currentDateTime();
const TrashedFileInfoList trashedFiles = list(); const TrashedFileInfoList trashedFiles = list();
@ -992,9 +992,6 @@ bool TrashImpl::adaptTrashSize( const TQString& origPath, int trashId )
if ( info.deletionDate.daysTo( currentDate ) > maxDays ) if ( info.deletionDate.daysTo( currentDate ) > maxDays )
del( info.trashId, info.fileId ); del( info.trashId, info.fileId );
} }
return true;
} }
if ( useSizeLimit ) { // check if size limit exceeded if ( useSizeLimit ) { // check if size limit exceeded
@ -1018,20 +1015,29 @@ bool TrashImpl::adaptTrashSize( const TQString& origPath, int trashId )
} }
trashLimit = (unsigned long)trashLimitTemp; trashLimit = (unsigned long)trashLimitTemp;
} }
if ( requiredTrashSpace > trashLimit ) { if ( additionalSize > trashLimit ) {
if ( actionType == 0 ) { // warn the user only m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED;
m_lastErrorMessage = i18n( "The file '%1' is bigger than the '%2' trash bin size.\n"
"It cannot be trashed." ).arg(origPath).arg(util.mountPoint());
return false;
} else if ( requiredTrashSpace > trashLimit ) {
if ( actionType == TrashConstant::ACTION_WARNING ) { // warn the user only
m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED; m_lastErrorCode = TDEIO::ERR_SLAVE_DEFINED;
m_lastErrorMessage = i18n( "The trash has reached its maximum size!\nClean the trash manually." ); m_lastErrorMessage = i18n( "There is not enough space left in trash folder '%1'.\n"
"The file cannot be trashed. Clean the trash manually and try again.")
.arg(util.mountPoint());
return false; return false;
} else { } else {
TQDir dir( trashPath + "/files" ); TQDir dir( trashPath + "/files" );
const TQFileInfoList *infos = 0; const TQFileInfoList *infos = 0;
if ( actionType == 1 ) // delete oldest files first if ( actionType == TrashConstant::ACTION_DELETE_OLDEST ) // delete oldest files first
infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs, TQDir::Time | TQDir::Reversed ); infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs, TQDir::Time | TQDir::Reversed );
else if ( actionType == 2 ) // delete biggest files first else if ( actionType == TrashConstant::ACTION_DELETE_BIGGEST ) // delete biggest files first
infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs, TQDir::Size ); infos = dir.entryInfoList( TQDir::Files | TQDir::Dirs, TQDir::Size );
else else {
tqWarning( "Should never happen!" ); tqWarning( "<TrashImpl::adaptTrashSize> Should never happen!" );
return false;
}
TQFileInfoListIterator it( *infos ); TQFileInfoListIterator it( *infos );
TQFileInfo *info; TQFileInfo *info;
@ -1051,4 +1057,109 @@ bool TrashImpl::adaptTrashSize( const TQString& origPath, int trashId )
return true; return true;
} }
void TrashImpl::resizeTrash(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);
int sizeLimitType = config.readNumEntry("SizeLimitType", TrashConstant::SIZE_LIMIT_PERCENT);
double percent = config.readDoubleNumEntry("Percent", 10);
double fixedSize = config.readDoubleNumEntry("FixedSize", 500);
int fixedSizeUnit = config.readNumEntry("FixedSizeUnit", TrashConstant::SIZE_ID_MB);
int actionType = config.readNumEntry("LimitReachedAction", 0);
if (useTimeLimit)
{
// delete all files in trash older than X days
const int maxDays = config.readNumEntry("Days", 32000);
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);
}
}
}
if (useSizeLimit)
{
// check if size limit exceeded
TQString trashPathName = trashPath + "/files/";
DiscSpaceUtil util(trashPathName);
unsigned long currTrashSize = util.sizeOfPath(trashPathName);
unsigned long trashLimit = 0;
if (sizeLimitType == TrashConstant::SIZE_LIMIT_PERCENT)
{
trashLimit = (unsigned long)(1024 * percent * util.size() / 100.0);
}
else if (sizeLimitType == TrashConstant::SIZE_LIMIT_FIXED)
{
double trashLimitTemp = fixedSize;
while (fixedSizeUnit > TrashConstant::SIZE_ID_B)
{
trashLimitTemp *= 1024;
--fixedSizeUnit;
}
trashLimit = (unsigned long)trashLimitTemp;
}
if (currTrashSize > trashLimit)
{
if (actionType == TrashConstant::ACTION_WARNING)
{
// warn the user only
KMessageBox::error(0, i18n("The current size of trash folder '%1' is bigger than the allowed size.\n"
"Clean the trash manually.").arg(util.mountPoint()));
return;
}
else
{
TQDir dir(trashPath + "/files");
const TQFileInfoList *infos = 0;
if (actionType == TrashConstant::ACTION_DELETE_OLDEST)
{
// delete oldest files first
infos = dir.entryInfoList(TQDir::Files | TQDir::Dirs, TQDir::Time | TQDir::Reversed);
}
else if (actionType == TrashConstant::ACTION_DELETE_BIGGEST)
{
// delete biggest files first
infos = dir.entryInfoList(TQDir::Files | TQDir::Dirs, TQDir::Size);
}
else
{
tqWarning("<TrashImpl::resizeTrash> Should never happen!");
return;
}
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.sizeOfPath(trashPathName)) < trashLimit)
{
// check whether we have enough space now
deleteFurther = false;
}
}
++it;
}
}
}
}
}
#include "trashimpl.moc" #include "trashimpl.moc"

@ -95,6 +95,9 @@ public:
/// Move data from the old trash system to the new one /// Move data from the old trash system to the new one
void migrateOldTrash(); void migrateOldTrash();
/// Resize the trash based on the current settings if necessary
void resizeTrash(int trashId);
/// TDEIO error code /// TDEIO error code
int lastErrorCode() const { return m_lastErrorCode; } int lastErrorCode() const { return m_lastErrorCode; }
TQString lastErrorMessage() const { return m_lastErrorMessage; } TQString lastErrorMessage() const { return m_lastErrorMessage; }

Loading…
Cancel
Save