Browse Source

Add a thin layer around SettingsStorage class

This new layer would be handy for saving GUI widget states as they don't
need the value cached and they store/load rarely.
adaptive-webui-19844
Chocobo1 4 years ago
parent
commit
0b0597be0c
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 16
      src/base/bittorrent/session.cpp
  2. 100
      src/base/settingvalue.h
  3. 6
      src/base/torrentfileguard.cpp
  4. 4
      src/base/torrentfileguard.h
  5. 4
      src/gui/addnewtorrentdialog.h
  6. 2
      src/gui/previewselectdialog.cpp
  7. 4
      src/gui/previewselectdialog.h
  8. 6
      src/gui/search/searchjobwidget.cpp
  9. 4
      src/gui/search/searchjobwidget.h
  10. 20
      src/gui/torrentcreatordialog.cpp
  11. 28
      src/gui/torrentcreatordialog.h
  12. 2
      src/gui/trackerentriesdialog.h

16
src/base/bittorrent/session.cpp

@ -482,7 +482,7 @@ Session::Session(QObject *parent)
m_storedCategories = map_cast(m_categories); m_storedCategories = map_cast(m_categories);
} }
m_tags = List::toSet(m_storedTags.value()); m_tags = List::toSet(m_storedTags.get());
enqueueRefresh(); enqueueRefresh();
updateSeedingLimitTimer(); updateSeedingLimitTimer();
@ -1130,7 +1130,7 @@ void Session::initializeNativeSession()
void Session::processBannedIPs(lt::ip_filter &filter) void Session::processBannedIPs(lt::ip_filter &filter)
{ {
// First, import current filter // First, import current filter
for (const QString &ip : asConst(m_bannedIPs.value())) for (const QString &ip : asConst(m_bannedIPs.get()))
{ {
lt::error_code ec; lt::error_code ec;
const lt::address addr = lt::make_address(ip.toLatin1().constData(), ec); const lt::address addr = lt::make_address(ip.toLatin1().constData(), ec);
@ -3142,7 +3142,7 @@ void Session::setPeerTurnoverInterval(const int val)
int Session::asyncIOThreads() const int Session::asyncIOThreads() const
{ {
return qBound(1, m_asyncIOThreads.value(), 1024); return qBound(1, m_asyncIOThreads.get(), 1024);
} }
void Session::setAsyncIOThreads(const int num) void Session::setAsyncIOThreads(const int num)
@ -3156,7 +3156,7 @@ void Session::setAsyncIOThreads(const int num)
int Session::hashingThreads() const int Session::hashingThreads() const
{ {
return qBound(1, m_hashingThreads.value(), 1024); return qBound(1, m_hashingThreads.get(), 1024);
} }
void Session::setHashingThreads(const int num) void Session::setHashingThreads(const int num)
@ -3184,7 +3184,7 @@ void Session::setFilePoolSize(const int size)
int Session::checkingMemUsage() const int Session::checkingMemUsage() const
{ {
return qMax(1, m_checkingMemUsage.value()); return qMax(1, m_checkingMemUsage.get());
} }
void Session::setCheckingMemUsage(int size) void Session::setCheckingMemUsage(int size)
@ -3201,11 +3201,11 @@ void Session::setCheckingMemUsage(int size)
int Session::diskCacheSize() const int Session::diskCacheSize() const
{ {
#ifdef QBT_APP_64BIT #ifdef QBT_APP_64BIT
return qMin(m_diskCacheSize.value(), 33554431); // 32768GiB return qMin(m_diskCacheSize.get(), 33554431); // 32768GiB
#else #else
// When build as 32bit binary, set the maximum at less than 2GB to prevent crashes // When build as 32bit binary, set the maximum at less than 2GB to prevent crashes
// allocate 1536MiB and leave 512MiB to the rest of program data in RAM // allocate 1536MiB and leave 512MiB to the rest of program data in RAM
return qMin(m_diskCacheSize.value(), 1536); return qMin(m_diskCacheSize.get(), 1536);
#endif #endif
} }
@ -3737,7 +3737,7 @@ bool Session::isListening() const
MaxRatioAction Session::maxRatioAction() const MaxRatioAction Session::maxRatioAction() const
{ {
return static_cast<MaxRatioAction>(m_maxRatioAction.value()); return static_cast<MaxRatioAction>(m_maxRatioAction.get());
} }
void Session::setMaxRatioAction(const MaxRatioAction act) void Session::setMaxRatioAction(const MaxRatioAction act)

100
src/base/settingvalue.h

@ -30,80 +30,110 @@
#include <type_traits> #include <type_traits>
#include <QMetaEnum>
#include <QString> #include <QString>
#include "settingsstorage.h" #include "settingsstorage.h"
#include "utils/string.h" #include "utils/string.h"
// This is a thin/handy wrapper over `SettingsStorage`. Use it when store/load value
// rarely occurs, otherwise use `CachedSettingValue`.
template <typename T> template <typename T>
class CachedSettingValue class SettingValue
{ {
public: public:
explicit CachedSettingValue(const char *keyName, const T &defaultValue = T()) explicit SettingValue(const char *keyName)
: m_keyName(QLatin1String(keyName)) : m_keyName {QLatin1String {keyName}}
, m_value(loadValue(defaultValue))
{
}
// The signature of the ProxyFunc should be equivalent to the following:
// T proxyFunc(const T &a);
template <typename ProxyFunc>
explicit CachedSettingValue(const char *keyName, const T &defaultValue
, ProxyFunc &&proxyFunc)
: m_keyName(QLatin1String(keyName))
, m_value(proxyFunc(loadValue(defaultValue)))
{ {
} }
T value() const T get(const T &defaultValue = {}) const
{ {
return m_value; return load(defaultValue);
} }
operator T() const operator T() const
{ {
return value(); return get();
} }
CachedSettingValue<T> &operator=(const T &newValue) SettingValue<T> &operator=(const T &value)
{ {
if (m_value == newValue) store(value);
return *this;
m_value = newValue;
storeValue(m_value);
return *this; return *this;
} }
private: private:
// regular load/save pair // regular load/store pair
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0> template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
U loadValue(const U &defaultValue) U load(const U &defaultValue) const
{ {
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value<T>(); return SettingsStorage::instance()->loadValue(m_keyName, defaultValue)
.template value<U>();
} }
template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0> template <typename U, typename std::enable_if_t<!std::is_enum<U>::value, int> = 0>
void storeValue(const U &value) void store(const U &value)
{ {
SettingsStorage::instance()->storeValue(m_keyName, value); SettingsStorage::instance()->storeValue(m_keyName, value);
} }
// load/save pair for an enum // load/store pair for enum type, saves literal value of the enum constant
// saves literal value of the enum constant, obtained from QMetaEnum // TODO: merge the load/store functions with `if constexpr` in C++17
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0> template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
U loadValue(const U &defaultValue) U load(const U defaultValue) const
{ {
return Utils::String::toEnum(SettingsStorage::instance()->loadValue(m_keyName).toString(), defaultValue); return Utils::String::toEnum(load(QString {}), defaultValue);
} }
template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0> template <typename U, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
void storeValue(const U &value) void store(const U value)
{ {
SettingsStorage::instance()->storeValue(m_keyName, Utils::String::fromEnum(value)); store(Utils::String::fromEnum(value));
} }
const QString m_keyName; const QString m_keyName;
T m_value; };
template <typename T>
class CachedSettingValue
{
public:
explicit CachedSettingValue(const char *keyName, const T &defaultValue = {})
: m_setting {keyName}
, m_cache {m_setting.get(defaultValue)}
{
}
// The signature of the ProxyFunc should be equivalent to the following:
// T proxyFunc(const T &a);
template <typename ProxyFunc>
explicit CachedSettingValue(const char *keyName, const T &defaultValue, ProxyFunc &&proxyFunc)
: m_setting {keyName}
, m_cache {proxyFunc(m_setting.get(defaultValue))}
{
}
T get() const
{
return m_cache;
}
operator T() const
{
return get();
}
CachedSettingValue<T> &operator=(const T &value)
{
if (m_cache == value)
return *this;
m_setting = value;
m_cache = value;
return *this;
}
private:
SettingValue<T> m_setting;
T m_cache;
}; };

6
src/base/torrentfileguard.cpp

@ -73,7 +73,7 @@ void TorrentFileGuard::markAsAddedToSession()
TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode() TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode()
{ {
return autoDeleteModeSetting(); return autoDeleteModeSetting().get(AutoDeleteMode::Never);
} }
void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode) void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
@ -81,8 +81,8 @@ void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
autoDeleteModeSetting() = mode; autoDeleteModeSetting() = mode;
} }
CachedSettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting() SettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
{ {
static CachedSettingValue<AutoDeleteMode> setting("Core/AutoDeleteAddedTorrentFile", AutoDeleteMode::Never); static SettingValue<AutoDeleteMode> setting {"Core/AutoDeleteAddedTorrentFile"};
return setting; return setting;
} }

4
src/base/torrentfileguard.h

@ -31,7 +31,7 @@
#include <QObject> #include <QObject>
#include <QString> #include <QString>
template <typename T> class CachedSettingValue; template <typename T> class SettingValue;
/// Utility class to defer file deletion /// Utility class to defer file deletion
class FileGuard class FileGuard
@ -75,7 +75,7 @@ public:
private: private:
TorrentFileGuard(const QString &path, AutoDeleteMode mode); TorrentFileGuard(const QString &path, AutoDeleteMode mode);
static CachedSettingValue<AutoDeleteMode> &autoDeleteModeSetting(); static SettingValue<AutoDeleteMode> &autoDeleteModeSetting();
Q_ENUM(AutoDeleteMode) Q_ENUM(AutoDeleteMode)
AutoDeleteMode m_mode; AutoDeleteMode m_mode;

4
src/gui/addnewtorrentdialog.h

@ -118,6 +118,6 @@ private:
std::unique_ptr<TorrentFileGuard> m_torrentGuard; std::unique_ptr<TorrentFileGuard> m_torrentGuard;
BitTorrent::AddTorrentParams m_torrentParams; BitTorrent::AddTorrentParams m_torrentParams;
CachedSettingValue<QSize> m_storeDialogSize; SettingValue<QSize> m_storeDialogSize;
CachedSettingValue<QByteArray> m_storeSplitterState; SettingValue<QByteArray> m_storeSplitterState;
}; };

2
src/gui/previewselectdialog.cpp

@ -159,7 +159,7 @@ void PreviewSelectDialog::loadWindowState()
Utils::Gui::resize(this, m_storeDialogSize); Utils::Gui::resize(this, m_storeDialogSize);
// Restore TreeView Header state // Restore TreeView Header state
if (!m_storeTreeHeaderState.value().isEmpty()) if (!m_storeTreeHeaderState.get().isEmpty())
{ {
m_headerStateInitialized = m_ui->previewList->header()->restoreState(m_storeTreeHeaderState); m_headerStateInitialized = m_ui->previewList->header()->restoreState(m_storeTreeHeaderState);
} }

4
src/gui/previewselectdialog.h

@ -82,6 +82,6 @@ private:
bool m_headerStateInitialized = false; bool m_headerStateInitialized = false;
// Settings // Settings
CachedSettingValue<QSize> m_storeDialogSize; SettingValue<QSize> m_storeDialogSize;
CachedSettingValue<QByteArray> m_storeTreeHeaderState; SettingValue<QByteArray> m_storeTreeHeaderState;
}; };

6
src/gui/search/searchjobwidget.cpp

@ -358,7 +358,7 @@ void SearchJobWidget::fillFilterComboBoxes()
m_ui->filterMode->addItem(tr("Torrent names only"), static_cast<int>(NameFilteringMode::OnlyNames)); m_ui->filterMode->addItem(tr("Torrent names only"), static_cast<int>(NameFilteringMode::OnlyNames));
m_ui->filterMode->addItem(tr("Everywhere"), static_cast<int>(NameFilteringMode::Everywhere)); m_ui->filterMode->addItem(tr("Everywhere"), static_cast<int>(NameFilteringMode::Everywhere));
QVariant selectedMode = static_cast<int>(nameFilteringModeSetting().value()); QVariant selectedMode = static_cast<int>(nameFilteringModeSetting().get(NameFilteringMode::OnlyNames));
int index = m_ui->filterMode->findData(selectedMode); int index = m_ui->filterMode->findData(selectedMode);
m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index); m_ui->filterMode->setCurrentIndex((index == -1) ? 0 : index);
} }
@ -545,9 +545,9 @@ void SearchJobWidget::appendSearchResults(const QVector<SearchResult> &results)
updateResultsCount(); updateResultsCount();
} }
CachedSettingValue<SearchJobWidget::NameFilteringMode> &SearchJobWidget::nameFilteringModeSetting() SettingValue<SearchJobWidget::NameFilteringMode> &SearchJobWidget::nameFilteringModeSetting()
{ {
static CachedSettingValue<NameFilteringMode> setting("Search/FilteringMode", NameFilteringMode::OnlyNames); static SettingValue<NameFilteringMode> setting {"Search/FilteringMode"};
return setting; return setting;
} }

4
src/gui/search/searchjobwidget.h

@ -43,7 +43,7 @@ class SearchHandler;
class SearchSortModel; class SearchSortModel;
struct SearchResult; struct SearchResult;
template <typename T> class CachedSettingValue; template <typename T> class SettingValue;
namespace Ui namespace Ui
{ {
@ -117,7 +117,7 @@ private:
void copyField(int column) const; void copyField(int column) const;
static QString statusText(Status st); static QString statusText(Status st);
static CachedSettingValue<NameFilteringMode> &nameFilteringModeSetting(); static SettingValue<NameFilteringMode> &nameFilteringModeSetting();
Ui::SearchJobWidget *m_ui; Ui::SearchJobWidget *m_ui;
SearchHandler *m_searchHandler; SearchHandler *m_searchHandler;

20
src/gui/torrentcreatordialog.cpp

@ -54,16 +54,16 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const QString &defau
, m_storeStartSeeding(SETTINGS_KEY("StartSeeding")) , m_storeStartSeeding(SETTINGS_KEY("StartSeeding"))
, m_storeIgnoreRatio(SETTINGS_KEY("IgnoreRatio")) , m_storeIgnoreRatio(SETTINGS_KEY("IgnoreRatio"))
#if (LIBTORRENT_VERSION_NUM >= 20000) #if (LIBTORRENT_VERSION_NUM >= 20000)
, m_storeTorrentFormat(SETTINGS_KEY("TorrentFormat"), 1) , m_storeTorrentFormat(SETTINGS_KEY("TorrentFormat"))
#else #else
, m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment"), true) , m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment"))
, m_paddedFileSizeLimit(SETTINGS_KEY("PaddedFileSizeLimit"), -1) , m_paddedFileSizeLimit(SETTINGS_KEY("PaddedFileSizeLimit"))
#endif #endif
, m_storeLastAddPath(SETTINGS_KEY("LastAddPath"), QDir::homePath()) , m_storeLastAddPath(SETTINGS_KEY("LastAddPath"))
, m_storeTrackerList(SETTINGS_KEY("TrackerList")) , m_storeTrackerList(SETTINGS_KEY("TrackerList"))
, m_storeWebSeedList(SETTINGS_KEY("WebSeedList")) , m_storeWebSeedList(SETTINGS_KEY("WebSeedList"))
, m_storeComments(SETTINGS_KEY("Comments")) , m_storeComments(SETTINGS_KEY("Comments"))
, m_storeLastSavePath(SETTINGS_KEY("LastSavePath"), QDir::homePath()) , m_storeLastSavePath(SETTINGS_KEY("LastSavePath"))
, m_storeSource(SETTINGS_KEY("Source")) , m_storeSource(SETTINGS_KEY("Source"))
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@ -184,7 +184,7 @@ void TorrentCreatorDialog::onCreateButtonClicked()
input = fi.canonicalFilePath(); input = fi.canonicalFilePath();
// get save path // get save path
const QString savePath = QString(m_storeLastSavePath) + QLatin1Char('/') + fi.fileName() + QLatin1String(".torrent"); const QString savePath = m_storeLastSavePath.get(QDir::homePath()) + QLatin1Char('/') + fi.fileName() + QLatin1String(".torrent");
QString destination = QFileDialog::getSaveFileName(this, tr("Select where to save the new torrent"), savePath, tr("Torrent Files (*.torrent)")); QString destination = QFileDialog::getSaveFileName(this, tr("Select where to save the new torrent"), savePath, tr("Torrent Files (*.torrent)"));
if (destination.isEmpty()) if (destination.isEmpty())
return; return;
@ -324,7 +324,7 @@ void TorrentCreatorDialog::saveSettings()
void TorrentCreatorDialog::loadSettings() void TorrentCreatorDialog::loadSettings()
{ {
m_ui->textInputPath->setText(m_storeLastAddPath); m_ui->textInputPath->setText(m_storeLastAddPath.get(QDir::homePath()));
m_ui->comboPieceSize->setCurrentIndex(m_storePieceSize); m_ui->comboPieceSize->setCurrentIndex(m_storePieceSize);
m_ui->checkPrivate->setChecked(m_storePrivateTorrent); m_ui->checkPrivate->setChecked(m_storePrivateTorrent);
@ -332,10 +332,10 @@ void TorrentCreatorDialog::loadSettings()
m_ui->checkIgnoreShareLimits->setChecked(m_storeIgnoreRatio); m_ui->checkIgnoreShareLimits->setChecked(m_storeIgnoreRatio);
m_ui->checkIgnoreShareLimits->setEnabled(m_ui->checkStartSeeding->isChecked()); m_ui->checkIgnoreShareLimits->setEnabled(m_ui->checkStartSeeding->isChecked());
#if (LIBTORRENT_VERSION_NUM >= 20000) #if (LIBTORRENT_VERSION_NUM >= 20000)
m_ui->comboTorrentFormat->setCurrentIndex(m_storeTorrentFormat); m_ui->comboTorrentFormat->setCurrentIndex(m_storeTorrentFormat.get(1));
#else #else
m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment); m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment.get(true));
m_ui->spinPaddedFileSizeLimit->setValue(m_paddedFileSizeLimit); m_ui->spinPaddedFileSizeLimit->setValue(m_paddedFileSizeLimit.get(-1));
#endif #endif
m_ui->trackersList->setPlainText(m_storeTrackerList); m_ui->trackersList->setPlainText(m_storeTrackerList);

28
src/gui/torrentcreatordialog.h

@ -78,21 +78,21 @@ private:
BitTorrent::TorrentCreatorThread *m_creatorThread; BitTorrent::TorrentCreatorThread *m_creatorThread;
// settings // settings
CachedSettingValue<QSize> m_storeDialogSize; SettingValue<QSize> m_storeDialogSize;
CachedSettingValue<int> m_storePieceSize; SettingValue<int> m_storePieceSize;
CachedSettingValue<bool> m_storePrivateTorrent; SettingValue<bool> m_storePrivateTorrent;
CachedSettingValue<bool> m_storeStartSeeding; SettingValue<bool> m_storeStartSeeding;
CachedSettingValue<bool> m_storeIgnoreRatio; SettingValue<bool> m_storeIgnoreRatio;
#if (LIBTORRENT_VERSION_NUM >= 20000) #if (LIBTORRENT_VERSION_NUM >= 20000)
CachedSettingValue<int> m_storeTorrentFormat; SettingValue<int> m_storeTorrentFormat;
#else #else
CachedSettingValue<bool> m_storeOptimizeAlignment; SettingValue<bool> m_storeOptimizeAlignment;
CachedSettingValue<int> m_paddedFileSizeLimit; SettingValue<int> m_paddedFileSizeLimit;
#endif #endif
CachedSettingValue<QString> m_storeLastAddPath; SettingValue<QString> m_storeLastAddPath;
CachedSettingValue<QString> m_storeTrackerList; SettingValue<QString> m_storeTrackerList;
CachedSettingValue<QString> m_storeWebSeedList; SettingValue<QString> m_storeWebSeedList;
CachedSettingValue<QString> m_storeComments; SettingValue<QString> m_storeComments;
CachedSettingValue<QString> m_storeLastSavePath; SettingValue<QString> m_storeLastSavePath;
CachedSettingValue<QString> m_storeSource; SettingValue<QString> m_storeSource;
}; };

2
src/gui/trackerentriesdialog.h

@ -60,5 +60,5 @@ private:
void loadSettings(); void loadSettings();
Ui::TrackerEntriesDialog *m_ui; Ui::TrackerEntriesDialog *m_ui;
CachedSettingValue<QSize> m_storeDialogSize; SettingValue<QSize> m_storeDialogSize;
}; };

Loading…
Cancel
Save