Gui: allow to configure the checks of the cache directory

This commit is contained in:
wmayer
2021-11-16 15:37:04 +01:00
parent e953dc1c2a
commit ed03e8ded5
8 changed files with 737 additions and 172 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -0,0 +1,391 @@
/***************************************************************************
* Copyright (c) 2021 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 <QCoreApplication>
# include <QDate>
# include <QDesktopServices>
# include <QDir>
# include <QLocale>
# include <QMessageBox>
# include <QSettings>
# include <QUrl>
# include <climits>
# include <cmath>
#endif
#include "DlgSettingsCacheDirectory.h"
#include "ui_DlgSettingsCacheDirectory.h"
#include "DocumentRecovery.h"
#include "MainWindow.h"
#include <App/Application.h>
#include <App/Document.h>
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<QFileInfo> dirs;
std::vector<App::Document*> 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>(period));
unsigned int sizeInMB = ApplicationCacheSettings::getCacheSizeLimit();
setLimit(ApplicationCache::toBytes(sizeInMB));
}
qint64 ApplicationCache::toBytes(unsigned int sizeInMB)
{
qint64 value = static_cast<qint64>(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; i<units.size()-1; i++) {
if (outputSize < 1024)
break;
outputSize /= 1024;
}
return QString::fromLatin1("%1 %2").arg(QLocale().toString(outputSize, 'f', 2), units[i]);
}
// ----------------------------------------------------------------------------
unsigned int ApplicationCacheSettings::getCacheSizeLimit()
{
ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("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<int>(ApplicationCache::Period::Weekly));
}
void ApplicationCacheSettings::setCheckPeriod(int period)
{
ParameterGrp::handle hGrp = WindowParameter::getDefaultParameter()->GetGroup("CacheDirectory");
hGrp->SetInt("Period", period);
}
#include "moc_DlgSettingsCacheDirectory.cpp"

View File

@@ -0,0 +1,109 @@
/***************************************************************************
* Copyright (c) 2021 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 <memory>
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_DlgSettingsCacheDirectory> 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

View File

@@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgSettingsCacheDirectory</class>
<widget class="QWidget" name="Gui::Dialog::DlgSettingsCacheDirectory">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>488</width>
<height>360</height>
</rect>
</property>
<property name="windowTitle">
<string>Cache</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QGroupBox" name="GroupBox5">
<property name="title">
<string>Cache directory</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="3">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="cacheLocation">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="openButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="icon">
<iconset resource="Icons/resource.qrc">
<normaloff>:/icons/document-open.svg</normaloff>:/icons/document-open.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelPeriod">
<property name="text">
<string>Check periodically at program start:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>118</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="comboBoxPeriod">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Always</string>
</property>
</item>
<item>
<property name="text">
<string>Daily</string>
</property>
</item>
<item>
<property name="text">
<string>Weekly</string>
</property>
</item>
<item>
<property name="text">
<string>Monthly</string>
</property>
</item>
<item>
<property name="text">
<string>Yearly</string>
</property>
</item>
<item>
<property name="text">
<string>Never</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelCache">
<property name="text">
<string>Cache size limit:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>118</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2" colspan="2">
<widget class="QComboBox" name="comboBoxLimit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelCurrentCache">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">Current cache size:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButtonCheck">
<property name="text">
<string>Check now...</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>150</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>169</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="Icons/resource.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -30,10 +30,8 @@
#ifndef _PreComp_
# include <QApplication>
# include <QCloseEvent>
# include <QDate>
# include <QDateTime>
# include <QDebug>
# include <QDesktopServices>
# include <QDir>
# include <QFile>
# include <QFileInfo>
@@ -41,14 +39,12 @@
# include <QMenu>
# include <QMessageBox>
# include <QPushButton>
# include <QSettings>
# include <QTextStream>
# include <QTreeWidgetItem>
# include <QMap>
# include <QSet>
# include <QList>
# include <QVector>
# include <climits>
# include <cmath>
# include <sstream>
#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<QFileInfo>& dirs, const QS
{
if (!dirs.isEmpty()) {
for (QList<QFileInfo>::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<QString> set1 = files.toSet();
QSet<QString> 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"

View File

@@ -28,6 +28,7 @@
#include <QScopedPointer>
#include <QList>
#include <QFileInfo>
#include <QFileInfoList>
#include <string>
#include <functional>
@@ -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

View File

@@ -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<DlgOnlineHelpImp> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettingsDocumentImp> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettingsSelection> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettingsCacheDirectory>( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettingsEditorImp> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgReportViewImp> ( QT_TRANSLATE_NOOP("QObject","General") );
new PrefPageProducer<DlgSettingsMacroImp> ( QT_TRANSLATE_NOOP("QObject","General") );