Browse Source

Implement enum support in CachedSettingValue

Enums are stored as strings, that improves configuration file
readability and maintainability. String values are obtained via
QMetaEnum, and since with Qt 5.5 QMetaEnum::fromType() includes a
static_assert, this has to be a safe method.
adaptive-webui-19844
Eugene Shalygin 8 years ago
parent
commit
a22d2f0139
  1. 45
      src/base/settingvalue.h
  2. 21
      src/base/torrentfileguard.cpp
  3. 10
      src/base/torrentfileguard.h
  4. 35
      src/gui/search/searchtab.cpp
  5. 9
      src/gui/search/searchtab.h

45
src/base/settingvalue.h

@ -30,7 +30,10 @@
#define SETTINGVALUE_H #define SETTINGVALUE_H
#include <functional> #include <functional>
#include <type_traits>
#include <QMetaEnum>
#include <QString> #include <QString>
#include <QVariant>
#include "settingsstorage.h" #include "settingsstorage.h"
@ -42,16 +45,14 @@ class CachedSettingValue
public: public:
explicit CachedSettingValue(const char *keyName, const T &defaultValue = T()) explicit CachedSettingValue(const char *keyName, const T &defaultValue = T())
: m_keyName(QLatin1String(keyName)) : m_keyName(QLatin1String(keyName))
, m_value(SettingsStorage::instance()->loadValue( , m_value(loadValue(defaultValue))
m_keyName, defaultValue).template value<T>())
{ {
} }
explicit CachedSettingValue(const char *keyName, const T &defaultValue explicit CachedSettingValue(const char *keyName, const T &defaultValue
, const ProxyFunc &proxyFunc) , const ProxyFunc &proxyFunc)
: m_keyName(QLatin1String(keyName)) : m_keyName(QLatin1String(keyName))
, m_value(proxyFunc(SettingsStorage::instance()->loadValue( , m_value(proxyFunc(loadValue(defaultValue)))
m_keyName, defaultValue).template value<T>()))
{ {
} }
@ -68,11 +69,45 @@ public:
CachedSettingValue<T> &operator=(const T &newValue) CachedSettingValue<T> &operator=(const T &newValue)
{ {
m_value = newValue; m_value = newValue;
SettingsStorage::instance()->storeValue(m_keyName, m_value); storeValue(m_value);
return *this; return *this;
} }
private: private:
// regular load/save pair
template <typename U, typename std::enable_if<!std::is_enum<U>::value, int>::type = 0>
U loadValue(const U &defaultValue)
{
return SettingsStorage::instance()->loadValue(m_keyName, defaultValue).template value<T>();
}
template <typename U, typename std::enable_if<!std::is_enum<U>::value, int>::type = 0>
void storeValue(const U &value)
{
SettingsStorage::instance()->storeValue(m_keyName, value);
}
// load/save pair for enum
// saves literal value of the enum constant, obtained from QMetaEnum
template <typename U, typename std::enable_if<std::is_enum<U>::value, int>::type = 0>
U loadValue(const U &defaultValue)
{
static_assert(std::is_same<int, typename std::underlying_type<U>::type>::value,
"Enumeration underlying type has to be int");
bool ok = false;
const U res = static_cast<U>(QMetaEnum::fromType<U>().keyToValue(
SettingsStorage::instance()->loadValue(m_keyName, QString()).toString().toLatin1().constData(), &ok));
return ok ? res : defaultValue;
}
template <typename U, typename std::enable_if<std::is_enum<U>::value, int>::type = 0>
void storeValue(const U &value)
{
SettingsStorage::instance()->storeValue(m_keyName,
QString::fromLatin1(QMetaEnum::fromType<U>().valueToKey(static_cast<int>(value))));
}
const QString m_keyName; const QString m_keyName;
T m_value; T m_value;
}; };

21
src/base/torrentfileguard.cpp

@ -28,15 +28,9 @@
#include "torrentfileguard.h" #include "torrentfileguard.h"
#include <QMetaEnum> #include "settingvalue.h"
#include "settingsstorage.h"
#include "utils/fs.h" #include "utils/fs.h"
namespace
{
const QLatin1String KEY_AUTO_DELETE_ENABLED ("Core/AutoDeleteAddedTorrentFile");
}
FileGuard::FileGuard(const QString &path) FileGuard::FileGuard(const QString &path)
: m_path {path} : m_path {path}
, m_remove {true} , m_remove {true}
@ -79,18 +73,17 @@ void TorrentFileGuard::markAsAddedToSession()
TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode() TorrentFileGuard::AutoDeleteMode TorrentFileGuard::autoDeleteMode()
{ {
QMetaEnum meta {modeMetaEnum()}; return autoDeleteModeSetting();
return static_cast<AutoDeleteMode>(meta.keyToValue(SettingsStorage::instance()->loadValue(
KEY_AUTO_DELETE_ENABLED, meta.valueToKey(Never)).toByteArray()));
} }
void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode) void TorrentFileGuard::setAutoDeleteMode(TorrentFileGuard::AutoDeleteMode mode)
{ {
QMetaEnum meta {modeMetaEnum()}; autoDeleteModeSetting() = mode;
SettingsStorage::instance()->storeValue(KEY_AUTO_DELETE_ENABLED, meta.valueToKey(mode));
} }
QMetaEnum TorrentFileGuard::modeMetaEnum() CachedSettingValue<TorrentFileGuard::AutoDeleteMode> &TorrentFileGuard::autoDeleteModeSetting()
{ {
return QMetaEnum::fromType<AutoDeleteMode>(); static CachedSettingValue<AutoDeleteMode> setting("Core/AutoDeleteAddedTorrentFile", AutoDeleteMode::Never);
return setting;
} }

10
src/base/torrentfileguard.h

@ -29,10 +29,11 @@
#ifndef TOFFENTFILEGURAD_H #ifndef TOFFENTFILEGURAD_H
#define TOFFENTFILEGURAD_H #define TOFFENTFILEGURAD_H
#include <QObject>
#include <QString> #include <QString>
#include <QMetaType>
class QMetaEnum; template <typename T> class CachedSettingValue;
/// Utility class to defer file deletion /// Utility class to defer file deletion
class FileGuard class FileGuard
{ {
@ -62,7 +63,7 @@ public:
void markAsAddedToSession(); void markAsAddedToSession();
using FileGuard::setAutoRemove; using FileGuard::setAutoRemove;
enum AutoDeleteMode // do not change these names: they are stored in config file enum AutoDeleteMode: int // do not change these names: they are stored in config file
{ {
Never, Never,
IfAdded, IfAdded,
@ -74,9 +75,8 @@ public:
static void setAutoDeleteMode(AutoDeleteMode mode); static void setAutoDeleteMode(AutoDeleteMode mode);
private: private:
static QMetaEnum modeMetaEnum();
TorrentFileGuard(const QString &path, AutoDeleteMode mode); TorrentFileGuard(const QString &path, AutoDeleteMode mode);
static CachedSettingValue<AutoDeleteMode> &autoDeleteModeSetting();
Q_ENUM(AutoDeleteMode) Q_ENUM(AutoDeleteMode)
AutoDeleteMode m_mode; AutoDeleteMode m_mode;

35
src/gui/search/searchtab.cpp

@ -31,7 +31,6 @@
#include <QApplication> #include <QApplication>
#include <QDir> #include <QDir>
#include <QMenu> #include <QMenu>
#include <QMetaEnum>
#include <QTreeView> #include <QTreeView>
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QHeaderView> #include <QHeaderView>
@ -43,7 +42,7 @@
#include "base/utils/misc.h" #include "base/utils/misc.h"
#include "base/preferences.h" #include "base/preferences.h"
#include "base/settingsstorage.h" #include "base/settingvalue.h"
#include "guiiconprovider.h" #include "guiiconprovider.h"
#include "searchsortmodel.h" #include "searchsortmodel.h"
#include "searchlistdelegate.h" #include "searchlistdelegate.h"
@ -51,13 +50,6 @@
#include "searchtab.h" #include "searchtab.h"
#include "ui_searchtab.h" #include "ui_searchtab.h"
namespace
{
#define SETTINGS_KEY(name) "Search/" name
const QString KEY_FILTER_MODE_SETTING_NAME = SETTINGS_KEY("FilteringMode");
}
SearchTab::SearchTab(SearchWidget *parent) SearchTab::SearchTab(SearchWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_ui(new Ui::SearchTab()) , m_ui(new Ui::SearchTab())
@ -216,15 +208,14 @@ void SearchTab::updateFilter()
{ {
using Utils::Misc::SizeUnit; using Utils::Misc::SizeUnit;
SearchSortModel* filterModel = getCurrentSearchListProxy(); SearchSortModel* filterModel = getCurrentSearchListProxy();
filterModel->enableNameFilter(filteringMode() == OnlyNames); filterModel->enableNameFilter(filteringMode() == NameFilteringMode::OnlyNames);
// we update size and seeds filter parameters in the model even if they are disabled // we update size and seeds filter parameters in the model even if they are disabled
filterModel->setSeedsFilter(m_ui->minSeeds->value(), m_ui->maxSeeds->value()); filterModel->setSeedsFilter(m_ui->minSeeds->value(), m_ui->maxSeeds->value());
filterModel->setSizeFilter( filterModel->setSizeFilter(
sizeInBytes(m_ui->minSize->value(), static_cast<SizeUnit>(m_ui->minSizeUnit->currentIndex())), sizeInBytes(m_ui->minSize->value(), static_cast<SizeUnit>(m_ui->minSizeUnit->currentIndex())),
sizeInBytes(m_ui->maxSize->value(), static_cast<SizeUnit>(m_ui->maxSizeUnit->currentIndex()))); sizeInBytes(m_ui->maxSize->value(), static_cast<SizeUnit>(m_ui->maxSizeUnit->currentIndex())));
SettingsStorage::instance()->storeValue(KEY_FILTER_MODE_SETTING_NAME, nameFilteringModeSetting() = filteringMode();
m_ui->filterMode->itemData(m_ui->filterMode->currentIndex()));
filterModel->invalidate(); filterModel->invalidate();
updateResultsCount(); updateResultsCount();
@ -255,14 +246,10 @@ void SearchTab::fillFilterComboBoxes()
m_ui->filterMode->clear(); m_ui->filterMode->clear();
QMetaEnum nameFilteringModeEnum = m_ui->filterMode->addItem(tr("Torrent names only"), static_cast<int>(NameFilteringMode::OnlyNames));
this->metaObject()->enumerator(this->metaObject()->indexOfEnumerator("NameFilteringMode")); m_ui->filterMode->addItem(tr("Everywhere"), static_cast<int>(NameFilteringMode::Everywhere));
m_ui->filterMode->addItem(tr("Torrent names only"), nameFilteringModeEnum.valueToKey(OnlyNames)); QVariant selectedMode = static_cast<int>(nameFilteringModeSetting().value());
m_ui->filterMode->addItem(tr("Everywhere"), nameFilteringModeEnum.valueToKey(Everywhere));
QVariant selectedMode = SettingsStorage::instance()->loadValue(
KEY_FILTER_MODE_SETTING_NAME, nameFilteringModeEnum.valueToKey(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);
} }
@ -305,9 +292,7 @@ QString SearchTab::statusIconName(SearchTab::Status st)
SearchTab::NameFilteringMode SearchTab::filteringMode() const SearchTab::NameFilteringMode SearchTab::filteringMode() const
{ {
QMetaEnum metaEnum = return static_cast<NameFilteringMode>(m_ui->filterMode->itemData(m_ui->filterMode->currentIndex()).toInt());
this->metaObject()->enumerator(this->metaObject()->indexOfEnumerator("NameFilteringMode"));
return static_cast<NameFilteringMode>(metaEnum.keyToValue(m_ui->filterMode->itemData(m_ui->filterMode->currentIndex()).toByteArray()));
} }
void SearchTab::loadSettings() void SearchTab::loadSettings()
@ -355,3 +340,9 @@ void SearchTab::displayToggleColumnsMenu(const QPoint&)
saveSettings(); saveSettings();
} }
} }
CachedSettingValue<SearchTab::NameFilteringMode> &SearchTab::nameFilteringModeSetting()
{
static CachedSettingValue<NameFilteringMode> setting("Search/FilteringMode", NameFilteringMode::OnlyNames);
return setting;
}

9
src/gui/search/searchtab.h

@ -31,7 +31,6 @@
#ifndef SEARCHTAB_H #ifndef SEARCHTAB_H
#define SEARCHTAB_H #define SEARCHTAB_H
#include <QVariant> // I don't know why <QMetaType> is not enought for Qt's 4.8.7 moc
#include <QWidget> #include <QWidget>
#define ENGINE_URL_COLUMN 4 #define ENGINE_URL_COLUMN 4
@ -44,6 +43,8 @@ class QHeaderView;
class QStandardItemModel; class QStandardItemModel;
class QVBoxLayout; class QVBoxLayout;
template <typename T> class CachedSettingValue;
class SearchSortModel; class SearchSortModel;
class SearchListDelegate; class SearchListDelegate;
class SearchWidget; class SearchWidget;
@ -59,13 +60,13 @@ class SearchTab: public QWidget
public: public:
enum NameFilteringMode enum class NameFilteringMode
{ {
Everywhere, Everywhere,
OnlyNames OnlyNames
}; };
Q_ENUMS(NameFilteringMode) Q_ENUM(NameFilteringMode)
explicit SearchTab(SearchWidget *parent); explicit SearchTab(SearchWidget *parent);
~SearchTab(); ~SearchTab();
@ -106,6 +107,8 @@ private:
static QString statusText(Status st); static QString statusText(Status st);
static QString statusIconName(Status st); static QString statusIconName(Status st);
static CachedSettingValue<NameFilteringMode>& nameFilteringModeSetting();
Ui::SearchTab *m_ui; Ui::SearchTab *m_ui;
QTreeView *m_resultsBrowser; QTreeView *m_resultsBrowser;
QStandardItemModel *m_searchListModel; QStandardItemModel *m_searchListModel;

Loading…
Cancel
Save