File indexing completed on 2024-05-05 16:13:52
0001 /* 0002 SPDX-FileCopyrightText: 2008 Tobias Koenig <tokoe@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kcmtrash.h" 0008 #include "discspaceutil.h" 0009 #include "trashimpl.h" 0010 0011 #include <QCheckBox> 0012 #include <QComboBox> 0013 #include <QDoubleSpinBox> 0014 #include <QFormLayout> 0015 #include <QLabel> 0016 #include <QListWidget> 0017 #include <QListWidgetItem> 0018 0019 #include <KConfig> 0020 #include <KConfigGroup> 0021 #include <KFormat> 0022 #include <KLocalizedString> 0023 #include <KPluginFactory> 0024 #include <QDialog> 0025 #include <QIcon> 0026 #include <QSpinBox> 0027 0028 K_PLUGIN_CLASS_WITH_JSON(TrashConfigModule, "kcmtrash.json") 0029 0030 TrashConfigModule::TrashConfigModule(QWidget *parent, const QVariantList &args) 0031 : KCModule(parent, args) 0032 , trashInitialize(false) 0033 { 0034 mTrashImpl = new TrashImpl(); 0035 mTrashImpl->init(); 0036 0037 readConfig(); 0038 0039 setupGui(); 0040 0041 useTypeChanged(); 0042 0043 connect(mUseTimeLimit, &QAbstractButton::toggled, this, &TrashConfigModule::markAsChanged); 0044 connect(mUseTimeLimit, &QAbstractButton::toggled, this, &TrashConfigModule::useTypeChanged); 0045 connect(mDays, qOverload<int>(&QSpinBox::valueChanged), this, &TrashConfigModule::markAsChanged); 0046 connect(mUseSizeLimit, &QAbstractButton::toggled, this, &TrashConfigModule::markAsChanged); 0047 connect(mUseSizeLimit, &QAbstractButton::toggled, this, &TrashConfigModule::useTypeChanged); 0048 connect(mPercent, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TrashConfigModule::percentChanged); 0049 connect(mPercent, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TrashConfigModule::markAsChanged); 0050 connect(mLimitReachedAction, qOverload<int>(&QComboBox::currentIndexChanged), this, &TrashConfigModule::markAsChanged); 0051 0052 trashChanged(0); 0053 trashInitialize = true; 0054 } 0055 0056 TrashConfigModule::~TrashConfigModule() 0057 { 0058 } 0059 0060 void TrashConfigModule::save() 0061 { 0062 if (!mCurrentTrash.isEmpty()) { 0063 ConfigEntry entry; 0064 entry.useTimeLimit = mUseTimeLimit->isChecked(); 0065 entry.days = mDays->value(); 0066 entry.useSizeLimit = mUseSizeLimit->isChecked(); 0067 entry.percent = mPercent->value(), entry.actionType = mLimitReachedAction->currentIndex(); 0068 mConfigMap.insert(mCurrentTrash, entry); 0069 } 0070 0071 writeConfig(); 0072 } 0073 0074 void TrashConfigModule::defaults() 0075 { 0076 ConfigEntry entry; 0077 entry.useTimeLimit = false; 0078 entry.days = 7; 0079 entry.useSizeLimit = true; 0080 entry.percent = 10.0; 0081 entry.actionType = 0; 0082 mConfigMap.insert(mCurrentTrash, entry); 0083 trashInitialize = false; 0084 trashChanged(0); 0085 } 0086 0087 void TrashConfigModule::percentChanged(double percent) 0088 { 0089 DiscSpaceUtil util(mCurrentTrash); 0090 0091 qint64 partitionSize = util.size(); 0092 double size = static_cast<double>(partitionSize / 100) * percent; 0093 0094 KFormat format; 0095 mSizeLabel->setText(QLatin1Char('(') + format.formatByteSize(size, 2) + QLatin1Char(')')); 0096 } 0097 0098 void TrashConfigModule::trashChanged(QListWidgetItem *item) 0099 { 0100 trashChanged(item->data(Qt::UserRole).toInt()); 0101 } 0102 0103 void TrashConfigModule::trashChanged(int value) 0104 { 0105 const TrashImpl::TrashDirMap map = mTrashImpl->trashDirectories(); 0106 0107 if (!mCurrentTrash.isEmpty() && trashInitialize) { 0108 ConfigEntry entry; 0109 entry.useTimeLimit = mUseTimeLimit->isChecked(); 0110 entry.days = mDays->value(); 0111 entry.useSizeLimit = mUseSizeLimit->isChecked(); 0112 entry.percent = mPercent->value(), entry.actionType = mLimitReachedAction->currentIndex(); 0113 mConfigMap.insert(mCurrentTrash, entry); 0114 } 0115 0116 mCurrentTrash = map[value]; 0117 const auto currentTrashIt = mConfigMap.constFind(mCurrentTrash); 0118 if (currentTrashIt != mConfigMap.constEnd()) { 0119 const ConfigEntry &entry = *currentTrashIt; 0120 mUseTimeLimit->setChecked(entry.useTimeLimit); 0121 mDays->setValue(entry.days); 0122 mUseSizeLimit->setChecked(entry.useSizeLimit); 0123 mPercent->setValue(entry.percent); 0124 mLimitReachedAction->setCurrentIndex(entry.actionType); 0125 } else { 0126 mUseTimeLimit->setChecked(false); 0127 mDays->setValue(7); 0128 mUseSizeLimit->setChecked(true); 0129 mPercent->setValue(10.0); 0130 mLimitReachedAction->setCurrentIndex(0); 0131 } 0132 mDays->setSuffix(i18n(" days")); // missing in Qt: plural form handling 0133 0134 percentChanged(mPercent->value()); 0135 } 0136 0137 void TrashConfigModule::useTypeChanged() 0138 { 0139 mDays->setEnabled(mUseTimeLimit->isChecked()); 0140 mPercent->setEnabled(mUseSizeLimit->isChecked()); 0141 mSizeLabel->setEnabled(mUseSizeLimit->isChecked()); 0142 } 0143 0144 void TrashConfigModule::readConfig() 0145 { 0146 KConfig config(QStringLiteral("ktrashrc")); 0147 mConfigMap.clear(); 0148 0149 const QStringList groups = config.groupList(); 0150 for (const auto &name : groups) { 0151 if (name.startsWith(QLatin1Char('/'))) { 0152 const KConfigGroup group = config.group(name); 0153 0154 ConfigEntry entry; 0155 entry.useTimeLimit = group.readEntry("UseTimeLimit", false); 0156 entry.days = group.readEntry("Days", 7); 0157 entry.useSizeLimit = group.readEntry("UseSizeLimit", true); 0158 entry.percent = group.readEntry("Percent", 10.0); 0159 entry.actionType = group.readEntry("LimitReachedAction", 0); 0160 mConfigMap.insert(name, entry); 0161 } 0162 } 0163 } 0164 0165 void TrashConfigModule::writeConfig() 0166 { 0167 KConfig config(QStringLiteral("ktrashrc")); 0168 0169 // first delete all existing groups 0170 const QStringList groups = config.groupList(); 0171 for (const auto &name : groups) { 0172 if (name.startsWith(QLatin1Char('/'))) { 0173 config.deleteGroup(name); 0174 } 0175 } 0176 0177 QMapIterator<QString, ConfigEntry> it(mConfigMap); 0178 while (it.hasNext()) { 0179 it.next(); 0180 KConfigGroup group = config.group(it.key()); 0181 0182 const ConfigEntry entry = it.value(); 0183 group.writeEntry("UseTimeLimit", entry.useTimeLimit); 0184 group.writeEntry("Days", entry.days); 0185 group.writeEntry("UseSizeLimit", entry.useSizeLimit); 0186 group.writeEntry("Percent", entry.percent); 0187 group.writeEntry("LimitReachedAction", entry.actionType); 0188 } 0189 config.sync(); 0190 } 0191 0192 void TrashConfigModule::setupGui() 0193 { 0194 QVBoxLayout *layout = new QVBoxLayout(this); 0195 0196 #ifdef Q_OS_OSX 0197 QLabel *infoText = new QLabel(i18n("<para>KDE's wastebin is configured to use the <b>Finder</b>'s Trash.<br></para>")); 0198 infoText->setWhatsThis(i18nc("@info:whatsthis", 0199 "<para>Emptying KDE's wastebin will remove only KDE's trash items, while<br>" 0200 "emptying the Trash through the Finder will delete everything.</para>" 0201 "<para>KDE's trash items will show up in a folder called KDE.trash, in the Trash can.</para>")); 0202 layout->addWidget(infoText); 0203 #endif 0204 0205 TrashImpl::TrashDirMap map = mTrashImpl->trashDirectories(); 0206 if (map.count() != 1) { 0207 // If we have multiple trashes, we setup a widget to choose 0208 // which trash to configure 0209 QListWidget *mountPoints = new QListWidget(this); 0210 layout->addWidget(mountPoints); 0211 0212 QMapIterator<int, QString> it(map); 0213 while (it.hasNext()) { 0214 it.next(); 0215 DiscSpaceUtil util(it.value()); 0216 QListWidgetItem *item = new QListWidgetItem(QIcon(QStringLiteral("folder")), util.mountPoint()); 0217 item->setData(Qt::UserRole, it.key()); 0218 0219 mountPoints->addItem(item); 0220 } 0221 0222 mountPoints->setCurrentRow(0); 0223 0224 connect(mountPoints, &QListWidget::currentItemChanged, this, qOverload<QListWidgetItem *>(&TrashConfigModule::trashChanged)); 0225 } else { 0226 mCurrentTrash = map.value(0); 0227 } 0228 0229 QFormLayout *formLayout = new QFormLayout(); 0230 layout->addLayout(formLayout); 0231 0232 QHBoxLayout *daysLayout = new QHBoxLayout(); 0233 0234 mUseTimeLimit = new QCheckBox(i18n("Delete files older than"), this); 0235 mUseTimeLimit->setWhatsThis( 0236 xi18nc("@info:whatsthis", 0237 "<para>Check this box to allow <emphasis strong='true'>automatic deletion</emphasis> of files that are older than the value specified. " 0238 "Leave this disabled to <emphasis strong='true'>not</emphasis> automatically delete any items after a certain timespan</para>")); 0239 daysLayout->addWidget(mUseTimeLimit); 0240 mDays = new QSpinBox(this); 0241 0242 mDays->setRange(1, 365); 0243 mDays->setSingleStep(1); 0244 mDays->setSuffix(i18np(" day", " days", mDays->value())); 0245 mDays->setWhatsThis(xi18nc("@info:whatsthis", 0246 "<para>Set the number of days that files can remain in the trash. " 0247 "Any files older than this will be automatically deleted.</para>")); 0248 daysLayout->addWidget(mDays); 0249 daysLayout->addStretch(); 0250 formLayout->addRow(i18n("Cleanup:"), daysLayout); 0251 0252 QHBoxLayout *maximumSizeLayout = new QHBoxLayout(); 0253 mUseSizeLimit = new QCheckBox(i18n("Limit to"), this); 0254 mUseSizeLimit->setWhatsThis(xi18nc("@info:whatsthis", 0255 "<para>Check this box to limit the trash to the maximum amount of disk space that you specify below. " 0256 "Otherwise, it will be unlimited.</para>")); 0257 maximumSizeLayout->addWidget(mUseSizeLimit); 0258 formLayout->addRow(i18n("Size:"), maximumSizeLayout); 0259 0260 mPercent = new QDoubleSpinBox(this); 0261 mPercent->setRange(0.01, 100); 0262 mPercent->setDecimals(2); 0263 mPercent->setSingleStep(1); 0264 mPercent->setSuffix(QStringLiteral(" %")); 0265 mPercent->setWhatsThis(xi18nc("@info:whatsthis", "<para>This is the maximum percent of disk space that will be used for the trash.</para>")); 0266 maximumSizeLayout->addWidget(mPercent); 0267 0268 mSizeLabel = new QLabel(this); 0269 mSizeLabel->setWhatsThis( 0270 xi18nc("@info:whatsthis", "<para>This is the calculated amount of disk space that will be allowed for the trash, the maximum.</para>")); 0271 maximumSizeLayout->addWidget(mSizeLabel); 0272 0273 mLimitReachedAction = new QComboBox(); 0274 mLimitReachedAction->addItem(i18n("Show a Warning")); 0275 mLimitReachedAction->addItem(i18n("Delete Oldest Files From Trash")); 0276 mLimitReachedAction->addItem(i18n("Delete Biggest Files From Trash")); 0277 mLimitReachedAction->setWhatsThis(xi18nc("@info:whatsthis", 0278 "<para>When the size limit is reached, it will prefer to delete the type of files that you specify, first. " 0279 "If this is set to warn you, it will do so instead of automatically deleting files.</para>")); 0280 formLayout->addRow(i18n("Full Trash:"), mLimitReachedAction); 0281 0282 layout->addStretch(); 0283 } 0284 0285 #include "kcmtrash.moc" 0286 #include "moc_kcmtrash.cpp"