From ed03e8ded59368950587f598dd00a12b33456ed7 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 16 Nov 2021 15:37:04 +0100 Subject: [PATCH] Gui: allow to configure the checks of the cache directory --- src/Gui/Application.cpp | 2 + src/Gui/CMakeLists.txt | 4 + src/Gui/DlgSettingsCacheDirectory.cpp | 391 ++++++++++++++++++++++++++ src/Gui/DlgSettingsCacheDirectory.h | 109 +++++++ src/Gui/DlgSettingsCacheDirectory.ui | 201 +++++++++++++ src/Gui/DocumentRecovery.cpp | 167 ++--------- src/Gui/DocumentRecovery.h | 33 +-- src/Gui/resource.cpp | 2 + 8 files changed, 737 insertions(+), 172 deletions(-) create mode 100644 src/Gui/DlgSettingsCacheDirectory.cpp create mode 100644 src/Gui/DlgSettingsCacheDirectory.h create mode 100644 src/Gui/DlgSettingsCacheDirectory.ui diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index a675db131c..7e197b646c 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -93,6 +93,7 @@ #include "SpaceballEvent.h" #include "Control.h" #include "DocumentRecovery.h" +#include "DlgSettingsCacheDirectory.h" #include "TransactionObject.h" #include "FileDialog.h" #include "ExpressionBindingPy.h" @@ -2422,6 +2423,7 @@ void Application::checkForPreviousCrashes() // If the recovery dialog wasn't shown check the cache size periodically Gui::Dialog::ApplicationCache cache; + cache.applyUserSettings(); if (cache.periodicCheckOfSize()) { qint64 total = cache.size(); cache.performAction(total); diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 8990d7af4f..50a596949b 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -328,6 +328,7 @@ SET(Gui_UIC_SRCS DlgPropertyLink.ui DlgReportView.ui DlgSettings3DView.ui + DlgSettingsCacheDirectory.ui DlgSettingsNavigation.ui DlgSettingsSelection.ui DlgSettingsUnits.ui @@ -563,6 +564,7 @@ SET(Dialog_Settings_CPP_SRCS DlgPreferencesImp.cpp DlgReportViewImp.cpp DlgSettings3DViewImp.cpp + DlgSettingsCacheDirectory.cpp DlgSettingsNavigation.cpp DlgSettingsSelection.cpp DlgSettingsUnitsImp.cpp @@ -580,6 +582,7 @@ SET(Dialog_Settings_HPP_SRCS DlgPreferencesImp.h DlgReportViewImp.h DlgSettings3DViewImp.h + DlgSettingsCacheDirectory.h DlgSettingsNavigation.h DlgSettingsSelection.h DlgSettingsUnitsImp.h @@ -599,6 +602,7 @@ SET(Dialog_Settings_SRCS DlgPreferences.ui DlgReportView.ui DlgSettings3DView.ui + DlgSettingsCacheDirectory.ui DlgSettingsNavigation.ui DlgSettingsSelection.ui DlgSettingsUnits.ui diff --git a/src/Gui/DlgSettingsCacheDirectory.cpp b/src/Gui/DlgSettingsCacheDirectory.cpp new file mode 100644 index 0000000000..c01c4391dd --- /dev/null +++ b/src/Gui/DlgSettingsCacheDirectory.cpp @@ -0,0 +1,391 @@ +/*************************************************************************** + * Copyright (c) 2021 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * 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., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "DlgSettingsCacheDirectory.h" +#include "ui_DlgSettingsCacheDirectory.h" +#include "DocumentRecovery.h" +#include "MainWindow.h" +#include +#include + +using namespace Gui::Dialog; + +/* TRANSLATOR Gui::Dialog::DlgSettingsCacheDirectory */ + +QString DlgSettingsCacheDirectory::currentSize; + +DlgSettingsCacheDirectory::DlgSettingsCacheDirectory(QWidget* parent) + : PreferencePage(parent) + , ui(new Ui_DlgSettingsCacheDirectory) +{ + ui->setupUi(this); + ui->labelCache->setToolTip(tr("Notify the user if the cache size exceeds the specified limit")); + if (currentSize.isEmpty()) + currentSize = tr("Unknown"); + setCurrentCacheSize(currentSize); + + QString path = QString::fromStdString(App::Application::getUserCachePath()); + ui->cacheLocation->setText(path); + + ui->comboBoxLimit->addItem(QString::fromLatin1("100 MB"), 100); + ui->comboBoxLimit->addItem(QString::fromLatin1("300 MB"), 300); + ui->comboBoxLimit->addItem(QString::fromLatin1("500 MB"), 500); + ui->comboBoxLimit->addItem(QString::fromLatin1("1 GB"), 1024); + ui->comboBoxLimit->addItem(QString::fromLatin1("2 GB"), 2048); + ui->comboBoxLimit->addItem(QString::fromLatin1("3 GB"), 3072); + + connect(ui->pushButtonCheck, &QPushButton::clicked, this, &DlgSettingsCacheDirectory::runCheck); + connect(ui->openButton, &QPushButton::clicked, this, &DlgSettingsCacheDirectory::openDirectory); +} + +DlgSettingsCacheDirectory::~DlgSettingsCacheDirectory() +{ +} + +void DlgSettingsCacheDirectory::saveSettings() +{ + ApplicationCacheSettings::setCheckPeriod(ui->comboBoxPeriod->currentIndex()); + ApplicationCacheSettings::setCacheSizeLimit(ui->comboBoxLimit->currentData().toUInt()); +} + +void DlgSettingsCacheDirectory::loadSettings() +{ + int period = ApplicationCacheSettings::getCheckPeriod(); + if (period >= 0 && period < ui->comboBoxPeriod->count()) + ui->comboBoxPeriod->setCurrentIndex(period); + unsigned int limit = ApplicationCacheSettings::getCacheSizeLimit(); + int index = ui->comboBoxLimit->findData(limit); + + // if not found then add a new item with this value + if (index < 0) { + ui->comboBoxLimit->addItem(QString::fromLatin1("%1 MB").arg(limit), limit); + index = ui->comboBoxLimit->count() - 1; + } + ui->comboBoxLimit->setCurrentIndex(index); +} + +void DlgSettingsCacheDirectory::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + int period = ui->comboBoxPeriod->currentIndex(); + ui->retranslateUi(this); + ui->comboBoxPeriod->setCurrentIndex(period); + setCurrentCacheSize(currentSize); + } + QWidget::changeEvent(e); +} + +void DlgSettingsCacheDirectory::setCurrentCacheSize(const QString& str) +{ + currentSize = str; + ui->labelCurrentCache->setText(tr("Current cache size: %1").arg(str)); +} + +void DlgSettingsCacheDirectory::runCheck() +{ + Gui::Dialog::ApplicationCache cache; + unsigned int sizeInMB = ui->comboBoxLimit->currentData().toUInt(); + cache.setLimit(ApplicationCache::toBytes(sizeInMB)); + qint64 total = cache.size(); + setCurrentCacheSize(ApplicationCache::toString(total)); + + // When performing the clean-up then recompute the new cache size + if (cache.performAction(total)) { + total = cache.size(); + setCurrentCacheSize(ApplicationCache::toString(total)); + } +} + +void DlgSettingsCacheDirectory::openDirectory() +{ + QString path = QString::fromStdString(App::Application::getUserCachePath()); + QUrl url = QUrl::fromLocalFile(path); + QDesktopServices::openUrl(url); +} + +// ---------------------------------------------------------------------------- + +ApplicationCache::ApplicationCache() +{ + limit = std::pow(1024, 3); + setPeriod(Period::Weekly); +} + +/*! + * \brief ApplicationCache::setPeriod + * Set the period to check for the cache size + * \param period + */ +void ApplicationCache::setPeriod(ApplicationCache::Period period) +{ + switch (period) { + case Period::Always: + numDays = -1; + break; + case Period::Daily: + numDays = 1; + break; + case Period::Weekly: + numDays = 7; + break; + case Period::Monthly: + numDays = 31; + break; + case Period::Yearly: + numDays = 365; + break; + case Period::Never: + numDays = INT_MAX; + break; + } +} + +/*! + * \brief ApplicationCache::setLimit + * Set the limit in bytes to perform a check + * \param value + */ +void ApplicationCache::setLimit(qint64 value) +{ + limit = value; +} + +/*! + * \brief ApplicationCache::periodicCheckOfSize + * Checks if the periodic check should be performed now + * \return + */ +bool ApplicationCache::periodicCheckOfSize() const +{ + QString vendor = QString::fromLatin1(App::Application::Config()["ExeVendor"].c_str()); + QString application = QString::fromStdString(App::Application::getExecutableName()); + + QSettings settings(vendor, application); + QString key = QString::fromLatin1("LastCacheCheck"); + QDate date = settings.value(key).toDate(); + QDate now = QDate::currentDate(); + + // get the days since the last check + int days = date.daysTo(now); + if (date.isNull()) { + days = 1000; + } + + if (days >= numDays) { + settings.setValue(key, now); + return true; + } + + return false; +} + +/*! + * \brief ApplicationCache::performAction + * If the cache size \a total is higher than the limit then show a dialog to the user + * \param total + */ +bool ApplicationCache::performAction(qint64 total) +{ + bool performed = false; + if (total > limit) { + QString path = QString::fromStdString(App::Application::getUserCachePath()); + QMessageBox msgBox(Gui::getMainWindow()); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle(tr("Cache directory")); + + QString hint = tr("The cache directory %1 exceeds the size of %2.").arg(path, ApplicationCache::toString(limit)); + QString ask = tr("Do you want to clear it now?"); + QString warn = tr("Warning: Please make sure that this is the only running %1 instance " + "and that no documents are opened as this may result into data loss!").arg(QCoreApplication::applicationName()); + + msgBox.setText(QString::fromLatin1("%1 %2\n\n\n%3").arg(hint, ask, warn)); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Open); + msgBox.setDefaultButton(QMessageBox::No); + + while (true) { + int ret = msgBox.exec(); + if (ret == QMessageBox::Open) { + QUrl url = QUrl::fromLocalFile(path); + QDesktopServices::openUrl(url); + } + else { + if (ret == QMessageBox::Yes) { + clearDirectory(path); + performed = true; + } + break; + } + } + } + + return performed; +} + +/*! + * \brief ApplicationCache::size + * Determines the size of the cache. + * \return + */ +qint64 ApplicationCache::size() const +{ + // QDirIterator lists some directories twice +#if 0 + QDir cache = QString::fromStdString(App::Application::getUserCachePath()); + QDirIterator it(cache, QDirIterator::Subdirectories); + qint64 total = 0; + while (it.hasNext()) { + it.next(); + total += it.fileInfo().size(); + } + + return total; +#else + qint64 total = dirSize(QString::fromStdString(App::Application::getUserCachePath())); + return total; +#endif +} + +/*! + * \internal + */ +void ApplicationCache::clearDirectory(const QString& path) +{ + // Add the transient directories and the lock files to the ignore list + QDir tmp = QString::fromUtf8(App::Application::getUserCachePath().c_str()); + tmp.setNameFilters(QStringList() << QString::fromLatin1("*.lock")); + tmp.setFilter(QDir::Files); + + QList dirs; + std::vector docs = App::GetApplication().getDocuments(); + for (auto it : docs) { + QDir dir(QString::fromStdString(it->TransientDir.getStrValue())); + QFileInfo fi(dir.absolutePath()); + dirs.append(fi); + } + + DocumentRecoveryCleaner cleaner; + cleaner.setIgnoreFiles(tmp.entryList()); + cleaner.setIgnoreDirectories(dirs); + cleaner.clearDirectory(QFileInfo(path)); +} + +/*! + * \internal + */ +qint64 ApplicationCache::dirSize(QString dirPath) const +{ + qint64 total = 0; + QDir dir(dirPath); + + QDir::Filters fileFilters = QDir::Files; + for (QString filePath : dir.entryList(fileFilters)) { + QFileInfo fi(dir, filePath); + total += fi.size(); + } + + // traverse sub-directories recursively + QDir::Filters dirFilters = QDir::Dirs | QDir::NoDotAndDotDot; + for (QString subDirPath : dir.entryList(dirFilters)) + total += dirSize(dirPath + QDir::separator() + subDirPath); + return total; +} + +/*! + * \brief ApplicationCache::applyUserSettings + * Set period and limit according to user settings + */ +void ApplicationCache::applyUserSettings() +{ + int period = ApplicationCacheSettings::getCheckPeriod(); + setPeriod(static_cast(period)); + + unsigned int sizeInMB = ApplicationCacheSettings::getCacheSizeLimit(); + setLimit(ApplicationCache::toBytes(sizeInMB)); +} + +qint64 ApplicationCache::toBytes(unsigned int sizeInMB) +{ + qint64 value = static_cast(sizeInMB) * 1024 * 1024; + return value; +} + +QString ApplicationCache::toString(qint64 size) +{ + QStringList units = {QString::fromLatin1("Bytes"), + QString::fromLatin1("KB"), + QString::fromLatin1("MB"), + QString::fromLatin1("GB")}; + int i; + double outputSize = size; + for (i=0; iGetGroup("CacheDirectory"); + return hGrp->GetUnsigned("Limit", 500); +} + +void ApplicationCacheSettings::setCacheSizeLimit(unsigned int limit) +{ + ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("CacheDirectory"); + hGrp->SetUnsigned("Limit", limit); +} + +int ApplicationCacheSettings::getCheckPeriod() +{ + ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("CacheDirectory"); + return hGrp->GetInt("Period", static_cast(ApplicationCache::Period::Weekly)); +} + +void ApplicationCacheSettings::setCheckPeriod(int period) +{ + ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("CacheDirectory"); + hGrp->SetInt("Period", period); +} + + +#include "moc_DlgSettingsCacheDirectory.cpp" diff --git a/src/Gui/DlgSettingsCacheDirectory.h b/src/Gui/DlgSettingsCacheDirectory.h new file mode 100644 index 0000000000..6701bf3801 --- /dev/null +++ b/src/Gui/DlgSettingsCacheDirectory.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (c) 2021 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * 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., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_DIALOG_DLGSETTINGSCACHEDIRECTORY_H +#define GUI_DIALOG_DLGSETTINGSCACHEDIRECTORY_H + +#include "PropertyPage.h" +#include + +namespace Gui { +namespace Dialog { +class Ui_DlgSettingsCacheDirectory; + +/** + * The DlgSettingsCacheDirectory class implements a preference page to change settings + * for the cache directory handling. + * @author Werner Mayer + */ +class DlgSettingsCacheDirectory : public PreferencePage +{ + Q_OBJECT + +public: + DlgSettingsCacheDirectory(QWidget* parent = nullptr); + ~DlgSettingsCacheDirectory(); + + void saveSettings(); + void loadSettings(); + +protected: + void changeEvent(QEvent *e); + +private: + void runCheck(); + void openDirectory(); + void setCurrentCacheSize(const QString&); + +private: + static QString currentSize; + std::unique_ptr ui; +}; + +class ApplicationCache : public QObject +{ + Q_OBJECT + +public: + enum class Period { + Always, + Daily, + Weekly, + Monthly, + Yearly, + Never + }; + + ApplicationCache(); + void applyUserSettings(); + void setPeriod(Period); + void setLimit(qint64); + bool periodicCheckOfSize() const; + qint64 size() const; + bool performAction(qint64); + + static QString toString(qint64 size); + static qint64 toBytes(unsigned int); + +private: + void clearDirectory(const QString& path); + qint64 dirSize(QString dirPath) const; + +private: + qint64 limit; + int numDays; +}; + +class ApplicationCacheSettings +{ +public: + static unsigned int getCacheSizeLimit(); + static void setCacheSizeLimit(unsigned int); + static int getCheckPeriod(); + static void setCheckPeriod(int); +}; + +} // namespace Dialog +} // namespace Gui + +#endif // GUI_DIALOG_DLGSETTINGSCACHEDIRECTORY_H diff --git a/src/Gui/DlgSettingsCacheDirectory.ui b/src/Gui/DlgSettingsCacheDirectory.ui new file mode 100644 index 0000000000..8cd6560015 --- /dev/null +++ b/src/Gui/DlgSettingsCacheDirectory.ui @@ -0,0 +1,201 @@ + + + Gui::Dialog::DlgSettingsCacheDirectory + + + + 0 + 0 + 488 + 360 + + + + Cache + + + + + + Cache directory + + + + + + + + Location: + + + + + + + true + + + + + + + + 0 + 0 + + + + + :/icons/document-open.svg:/icons/document-open.svg + + + + + + + Check periodically at program start: + + + + + + + Qt::Horizontal + + + + 118 + 20 + + + + + + + + + 0 + 0 + + + + + Always + + + + + Daily + + + + + Weekly + + + + + Monthly + + + + + Yearly + + + + + Never + + + + + + + + Cache size limit: + + + + + + + Qt::Horizontal + + + + 118 + 20 + + + + + + + + + 0 + 0 + + + + + + + + + + + 0 + 0 + + + + Current cache size: + + + + + + + Check now... + + + + + + + Qt::Horizontal + + + + 150 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 169 + + + + + + + + + + + + diff --git a/src/Gui/DocumentRecovery.cpp b/src/Gui/DocumentRecovery.cpp index d1aa4dc6ad..aea8bee3c4 100644 --- a/src/Gui/DocumentRecovery.cpp +++ b/src/Gui/DocumentRecovery.cpp @@ -30,10 +30,8 @@ #ifndef _PreComp_ # include # include -# include # include # include -# include # include # include # include @@ -41,14 +39,12 @@ # include # include # include -# include # include # include # include +# include # include # include -# include -# include # include #endif @@ -341,7 +337,7 @@ void DocumentRecovery::accept() << docs[i]->Label.getValue() << "'"); } else { - DocumentRecoveryCleaner::clearDirectory(xfi.absolutePath()); + DocumentRecoveryCleaner().clearDirectory(xfi.absolutePath()); QDir().rmdir(xfi.absolutePath()); } @@ -531,7 +527,7 @@ void DocumentRecovery::onDeleteSection() QTreeWidgetItem* item = d_ptr->ui.treeWidget->takeTopLevelItem(index); QString projectFile = item->toolTip(0); - DocumentRecoveryCleaner::clearDirectory(QFileInfo(tmp.filePath(projectFile))); + DocumentRecoveryCleaner().clearDirectory(QFileInfo(tmp.filePath(projectFile))); tmp.rmdir(projectFile); delete item; } @@ -570,7 +566,7 @@ void DocumentRecovery::cleanup(QDir& tmp, const QList& dirs, const QS { if (!dirs.isEmpty()) { for (QList::const_iterator jt = dirs.cbegin(); jt != dirs.cend(); ++jt) { - DocumentRecoveryCleaner::clearDirectory(*jt); + DocumentRecoveryCleaner().clearDirectory(*jt); tmp.rmdir(jt->fileName()); } } @@ -691,6 +687,7 @@ void DocumentRecoveryCleaner::clearDirectory(const QFileInfo& dir) // Remove all files in this directory qThisDir.setFilter(QDir::Files); QStringList files = qThisDir.entryList(); + subtractFiles(files); for (QStringList::iterator it = files.begin(); it != files.end(); ++it) { QString file = *it; qThisDir.remove(file); @@ -699,164 +696,40 @@ void DocumentRecoveryCleaner::clearDirectory(const QFileInfo& dir) // Clear this directory of any sub-directories qThisDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QFileInfoList subdirs = qThisDir.entryInfoList(); + subtractDirs(subdirs); for (QFileInfoList::iterator it = subdirs.begin(); it != subdirs.end(); ++it) { clearDirectory(*it); qThisDir.rmdir(it->fileName()); } } -// ---------------------------------------------------------------------------- - -ApplicationCache::ApplicationCache() +void DocumentRecoveryCleaner::subtractFiles(QStringList& files) { - limit = std::pow(1024, 3); - setPeriod(Period::Weekly); -} - -/*! - * \brief ApplicationCache::setPeriod - * Set the period to check for the cache size - * \param period - */ -void ApplicationCache::setPeriod(ApplicationCache::Period period) -{ - switch (period) { - case Period::Always: - numDays = -1; - break; - case Period::Daily: - numDays = 1; - break; - case Period::Weekly: - numDays = 7; - break; - case Period::Monthly: - numDays = 31; - break; - case Period::Yearly: - numDays = 365; - break; - case Period::Never: - numDays = INT_MAX; - break; + if (!ignoreFiles.isEmpty() && !files.isEmpty()) { + QSet set1 = files.toSet(); + QSet set2 = ignoreFiles.toSet(); + set1.subtract(set2); + files = set1.toList(); } } -/*! - * \brief ApplicationCache::setLimit - * Set the limit in bytes to perform a check - * \param value - */ -void ApplicationCache::setLimit(qint64 value) +void DocumentRecoveryCleaner::subtractDirs(QFileInfoList& dirs) { - limit = value; -} - -/*! - * \brief ApplicationCache::periodicCheckOfSize - * Checks if the periodic check should be performed now - * \return - */ -bool ApplicationCache::periodicCheckOfSize() const -{ - QString vendor = QString::fromLatin1(App::Application::Config()["ExeVendor"].c_str()); - QString application = QString::fromStdString(App::Application::getExecutableName()); - - QSettings settings(vendor, application); - QString key = QString::fromLatin1("LastCacheCheck"); - QDate date = settings.value(key).toDate(); - QDate now = QDate::currentDate(); - - // get the days since the last check - int days = date.daysTo(now); - if (date.isNull()) { - days = 1000; - } - - if (days >= numDays) { - settings.setValue(key, now); - return true; - } - - return false; -} - -/*! - * \brief ApplicationCache::performAction - * If the cache size \a total is higher than the limit then show a dialog to the user - * \param total - */ -void ApplicationCache::performAction(qint64 total) -{ - if (total > limit) { - QString path = QString::fromStdString(App::Application::getUserCachePath()); - QMessageBox msgBox(Gui::getMainWindow()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setWindowTitle(tr("Cache directory")); - msgBox.setText(tr("The cache directory %1 exceeds the size of %2 GB.\n" - "Do you want to clear it now?").arg(path).arg(1)); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Open); - msgBox.setDefaultButton(QMessageBox::No); - - while (true) { - int ret = msgBox.exec(); - if (ret == QMessageBox::Open) { - QUrl url = QUrl::fromLocalFile(path); - QDesktopServices::openUrl(url); - } - else { - if (ret == QMessageBox::Yes) { - DocumentRecoveryCleaner::clearDirectory(QFileInfo(path)); - } - break; - } + if (!ignoreDirs.isEmpty() && !dirs.isEmpty()) { + for (const auto& it : ignoreDirs) { + dirs.removeOne(it); } } } -/*! - * \brief ApplicationCache::size - * Determines the size of the cache. - * \return - */ -qint64 ApplicationCache::size() const +void DocumentRecoveryCleaner::setIgnoreFiles(const QStringList& list) { - // QDirIterator lists some directories twice -#if 0 - QDir cache = QString::fromStdString(App::Application::getUserCachePath()); - QDirIterator it(cache, QDirIterator::Subdirectories); - qint64 total = 0; - while (it.hasNext()) { - it.next(); - total += it.fileInfo().size(); - } - - return total; -#else - qint64 total = dirSize(QString::fromStdString(App::Application::getUserCachePath())); - return total; -#endif + ignoreFiles = list; } -/*! - * \internal - */ -qint64 ApplicationCache::dirSize(QString dirPath) const +void DocumentRecoveryCleaner::setIgnoreDirectories(const QFileInfoList& list) { - qint64 total = 0; - QDir dir(dirPath); - - QDir::Filters fileFilters = QDir::Files; - for (QString filePath : dir.entryList(fileFilters)) { - QFileInfo fi(dir, filePath); - total += fi.size(); - } - - // traverse sub-directories recursively - QDir::Filters dirFilters = QDir::Dirs | QDir::NoDotAndDotDot; - for (QString subDirPath : dir.entryList(dirFilters)) - total += dirSize(dirPath + QDir::separator() + subDirPath); - return total; + ignoreDirs = list; } #include "moc_DocumentRecovery.cpp" diff --git a/src/Gui/DocumentRecovery.h b/src/Gui/DocumentRecovery.h index 74859c32d8..8fb498123b 100644 --- a/src/Gui/DocumentRecovery.h +++ b/src/Gui/DocumentRecovery.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -85,35 +86,17 @@ public: class DocumentRecoveryCleaner { public: - static void clearDirectory(const QFileInfo& dir); -}; - -class ApplicationCache : public QObject { - Q_OBJECT - -public: - enum class Period { - Always, - Daily, - Weekly, - Monthly, - Yearly, - Never - }; - - ApplicationCache(); - void setPeriod(Period); - void setLimit(qint64); - bool periodicCheckOfSize() const; - qint64 size() const; - void performAction(qint64); + void clearDirectory(const QFileInfo& dir); + void setIgnoreFiles(const QStringList&); + void setIgnoreDirectories(const QFileInfoList&); private: - qint64 dirSize(QString dirPath) const; + void subtractFiles(QStringList&); + void subtractDirs(QFileInfoList&); private: - qint64 limit; - int numDays; + QStringList ignoreFiles; + QFileInfoList ignoreDirs; }; } //namespace Dialog diff --git a/src/Gui/resource.cpp b/src/Gui/resource.cpp index 10391bffbb..a2720ee47a 100644 --- a/src/Gui/resource.cpp +++ b/src/Gui/resource.cpp @@ -50,6 +50,7 @@ #include "DlgKeyboardImp.h" #include "DlgCustomizeSpaceball.h" #include "DlgCustomizeSpNavSettings.h" +#include "DlgSettingsCacheDirectory.h" #include "InputField.h" #include "QuantitySpinBox.h" #include "PrefWidgets.h" @@ -69,6 +70,7 @@ WidgetFactorySupplier::WidgetFactorySupplier() //new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); + new PrefPageProducer( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","General") );