diff options
| author | 2014-12-06 17:33:25 -0500 | |
|---|---|---|
| committer | 2014-12-06 17:33:25 -0500 | |
| commit | 7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch) | |
| tree | a35c14143716e1f2c98f808c81f89426045a946f /SQLiteStudio3/coreSQLiteStudio/config_builder | |
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/config_builder')
8 files changed, 686 insertions, 0 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgcategory.cpp b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgcategory.cpp new file mode 100644 index 0000000..a79e08a --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgcategory.cpp @@ -0,0 +1,99 @@ +#include "cfgcategory.h" +#include "config_builder/cfgmain.h" +#include "config_builder/cfgentry.h" + +CfgCategory* lastCreatedCfgCategory = nullptr; +extern CfgMain* lastCreatedCfgMain; + +CfgCategory::CfgCategory(const CfgCategory &other) : + QObject(), name(other.name), title(other.title), persistable(other.persistable), childs(other.childs) +{ + lastCreatedCfgCategory = this; + lastCreatedCfgMain->childs[name] = this; + cfgParent = lastCreatedCfgMain; + for (CfgEntry* entry : childs) + entry->parent = this; +} + +CfgCategory::CfgCategory(const QString &name, const QString &title) : + name(name), title(title) +{ + this->persistable = lastCreatedCfgMain->persistable; + lastCreatedCfgCategory = this; + cfgParent = lastCreatedCfgMain; + lastCreatedCfgMain->childs[name] = this; +} + +QString CfgCategory::toString() const +{ + return name; +} + +QHash<QString, CfgEntry *> &CfgCategory::getEntries() +{ + return childs; +} + +void CfgCategory::reset() +{ + for (CfgEntry* entry : childs) + entry->reset(); +} + +void CfgCategory::savepoint(bool transaction) +{ + for (CfgEntry* entry : childs) + entry->savepoint(transaction); +} + +void CfgCategory::restore() +{ + for (CfgEntry* entry : childs) + entry->restore(); +} + +void CfgCategory::release() +{ + for (CfgEntry* entry : childs) + entry->release(); +} + +void CfgCategory::commit() +{ + release(); +} + +void CfgCategory::rollback() +{ + rollback(); +} + +void CfgCategory::begin() +{ + savepoint(true); +} + +QString CfgCategory::getTitle() const +{ + return title; +} + +CfgMain*CfgCategory::getMain() const +{ + return cfgParent; +} + +CfgCategory::operator CfgCategory *() +{ + return this; +} + +void CfgCategory::handleEntryChanged() +{ + emit changed(dynamic_cast<CfgEntry*>(sender())); +} + +CfgCategory::operator QString() const +{ + return name; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgcategory.h b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgcategory.h new file mode 100644 index 0000000..2a6ccaf --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgcategory.h @@ -0,0 +1,53 @@ +#ifndef CFGCATEGORY_H +#define CFGCATEGORY_H + +#include "coreSQLiteStudio_global.h" +#include <QVariant> +#include <QHash> +#include <QString> +#include <QObject> + +class CfgEntry; +class CfgMain; + +class API_EXPORT CfgCategory : public QObject +{ + Q_OBJECT + + friend class CfgEntry; + + public: + CfgCategory(const CfgCategory& other); + CfgCategory(const QString& name, const QString& title); + + QString toString() const; + operator QString() const; + QHash<QString,CfgEntry*>& getEntries(); + void reset(); + void savepoint(bool transaction = false); + void restore(); + void release(); + void commit(); + void rollback(); + void begin(); + QString getTitle() const; + CfgMain* getMain() const; + operator CfgCategory*(); + + private: + QString name; + QString title; + CfgMain* cfgParent = nullptr; + bool persistable = true; + QHash<QString,CfgEntry*> childs; + + private slots: + void handleEntryChanged(); + + signals: + void changed(CfgEntry* entry); +}; + +Q_DECLARE_METATYPE(CfgCategory*) + +#endif // CFGCATEGORY_H diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgentry.cpp b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgentry.cpp new file mode 100644 index 0000000..6a5f6a4 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgentry.cpp @@ -0,0 +1,189 @@ +#include "cfgentry.h" +#include "config_builder/cfgmain.h" +#include "config_builder/cfgcategory.h" +#include "services/config.h" +#include <QDebug> + +extern CfgCategory* lastCreatedCfgCategory; + +CfgEntry::CfgEntry(const CfgEntry& other) : + QObject(), persistable(other.persistable), parent(other.parent), name(other.name), defValue(other.defValue), + title(other.title), defValueFunc(other.defValueFunc) +{ + connect(this, SIGNAL(changed(QVariant)), parent, SLOT(handleEntryChanged())); +} + +CfgEntry::CfgEntry(const QString &name, const QVariant &defValue, const QString &title) : + QObject(), name(name), defValue(defValue), title(title) +{ + if (lastCreatedCfgCategory == nullptr) + { + qCritical() << "No last created category while creating CfgEntry!"; + return; + } + + parent = lastCreatedCfgCategory; + persistable = parent->persistable; + parent->childs[name] = this; + connect(this, SIGNAL(changed(QVariant)), parent, SLOT(handleEntryChanged())); +} + +CfgEntry::~CfgEntry() +{ +} + +QVariant CfgEntry::get() const +{ + if (cached) + return cachedValue; + + QVariant cfgVal; + if (persistable) + cfgVal = CFG->get(parent->toString(), name); + + cachedValue = cfgVal; + cached = true; + if (!persistable || !cfgVal.isValid()) + { + if (defValueFunc) + cachedValue = (*defValueFunc)(); + else + cachedValue = defValue; + + return cachedValue; + } + + return cfgVal; +} + +QVariant CfgEntry::getDefultValue() const +{ + if (defValueFunc) + return (*defValueFunc)(); + else + return defValue; +} + +void CfgEntry::set(const QVariant &value) +{ + bool doPersist = persistable && !transaction; + bool wasChanged = (value != cachedValue); + + if (doPersist && wasChanged) + CFG->set(parent->toString(), name, value); + + if (wasChanged) + cachedValue = value; + + cached = true; + + if (wasChanged) + emit changed(value); + + if (doPersist) + emit persisted(value); +} + +void CfgEntry::defineDefaultValueFunction(CfgEntry::DefaultValueProviderFunc func) +{ + defValueFunc = func; +} + +QString CfgEntry::getFullKey() const +{ + return parent->toString()+"."+name; +} + +QString CfgEntry::getTitle() const +{ + return title; +} + +void CfgEntry::reset() +{ + set(getDefultValue()); +} + +bool CfgEntry::isPersistable() const +{ + return persistable; +} + +bool CfgEntry::isPersisted() const +{ + if (persistable) + return !CFG->get(parent->toString(), name).isNull(); + + return false; +} + +void CfgEntry::savepoint(bool transaction) +{ + backup = get(); + this->transaction = transaction; +} + +void CfgEntry::begin() +{ + savepoint(true); +} + +void CfgEntry::restore() +{ + cachedValue = backup; + cached = true; + transaction = false; +} + +void CfgEntry::release() +{ + backup.clear(); + if (transaction) + { + transaction = false; + if (cached) + { + QVariant valueToSet = cachedValue; + cachedValue = QVariant(); + cached = false; + set(valueToSet); + } + } + +} + +void CfgEntry::commit() +{ + if (!transaction) + return; + + release(); +} + +void CfgEntry::rollback() +{ + if (!transaction) + return; + + restore(); +} + +CfgCategory* CfgEntry::getCategory() const +{ + return parent; +} + +CfgMain* CfgEntry::getMain() const +{ + return parent->getMain(); +} + +CfgEntry::operator CfgEntry*() +{ + return this; +} + +CfgEntry::operator QString() const +{ + return name; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgentry.h b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgentry.h new file mode 100644 index 0000000..92b2a5f --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgentry.h @@ -0,0 +1,123 @@ +#ifndef CFGENTRY_H +#define CFGENTRY_H + +#include "coreSQLiteStudio_global.h" +#include <QString> +#include <QVariant> +#include <QObject> + +class CfgCategory; +class CfgMain; + +class API_EXPORT CfgEntry : public QObject +{ + Q_OBJECT + + friend class CfgCategory; + + public: + typedef QVariant (*DefaultValueProviderFunc)(); + + explicit CfgEntry(const CfgEntry& other); + CfgEntry(const QString& name, const QVariant& defValue, const QString& title); + virtual ~CfgEntry(); + + QVariant get() const; + QVariant getDefultValue() const; + void set(const QVariant& value); + operator QString() const; + void defineDefaultValueFunction(DefaultValueProviderFunc func); + QString getFullKey() const; + QString getTitle() const; + void reset(); + bool isPersistable() const; + bool isPersisted() const; + void savepoint(bool transaction = false); + void begin(); + void restore(); + void release(); + void commit(); + void rollback(); + CfgCategory* getCategory() const; + CfgMain* getMain() const; + + /** + * @brief operator CfgEntry * + * + * Allows implict casting from value object into pointer. It simply returns "this". + * It's useful to use config objects directly in QObject::connect() arguments, + * cause it accepts pointers, not values, but CfgEntry is usually accessed by value. + */ + operator CfgEntry*(); + + protected: + bool persistable = true; + CfgCategory* parent = nullptr; + QString name; + QVariant defValue; + QString title; + QVariant backup; + bool transaction = false; + mutable bool cached = false; + mutable QVariant cachedValue; + DefaultValueProviderFunc defValueFunc = nullptr; + + signals: + void changed(const QVariant& newValue); + void persisted(const QVariant& newValue); +}; + +template <class T> +class CfgTypedEntry : public CfgEntry +{ + public: + CfgTypedEntry(const QString& name, DefaultValueProviderFunc func, const QString& title) : + CfgEntry(name, QVariant(), title) + { + defineDefaultValueFunction(func); + } + + CfgTypedEntry(const QString& name, const T& defValue, const QString& title) : + CfgEntry(name, QVariant::fromValue(defValue), title) {} + + CfgTypedEntry(const QString& name, DefaultValueProviderFunc func) : + CfgTypedEntry(name, func, QString()) {} + + CfgTypedEntry(const QString& name, const T& defValue, bool persistable) : + CfgTypedEntry(name, defValue, QString()) + { + this->persistable = persistable; + } + + CfgTypedEntry(const QString& name, DefaultValueProviderFunc func, bool persistable) : + CfgTypedEntry(name, func, QString()) + { + this->persistable = persistable; + } + + CfgTypedEntry(const QString& name, const T& defValue) : + CfgTypedEntry(name, defValue, QString()) {} + + CfgTypedEntry(const QString& name) : + CfgEntry(name, QVariant(), QString()) {} + + CfgTypedEntry(const CfgTypedEntry& other) : + CfgEntry(other) {} + + T get() + { + QVariant v = CfgEntry::get(); + return v.value<T>(); + } + + void set(const T& value) + { + CfgEntry::set(QVariant::fromValue<T>(value)); + } +}; + +typedef CfgTypedEntry<QString> CfgStringEntry; + +Q_DECLARE_METATYPE(CfgEntry*) + +#endif // CFGENTRY_H diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfglazyinitializer.cpp b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfglazyinitializer.cpp new file mode 100644 index 0000000..7e554a8 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfglazyinitializer.cpp @@ -0,0 +1,28 @@ +#include "cfglazyinitializer.h" +#include "common/unused.h" + +QList<CfgLazyInitializer*>* CfgLazyInitializer::instances = nullptr; + +CfgLazyInitializer::CfgLazyInitializer(std::function<void ()> initFunc, const char *name) : + initFunc(initFunc) +{ + UNUSED(name); + if (!instances) + instances = new QList<CfgLazyInitializer*>(); + + *instances << this; +} + +void CfgLazyInitializer::init() +{ + if (!instances) + instances = new QList<CfgLazyInitializer*>(); + + for (CfgLazyInitializer* initializer : *instances) + initializer->doInitialize(); +} + +void CfgLazyInitializer::doInitialize() +{ + initFunc(); +} diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfglazyinitializer.h b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfglazyinitializer.h new file mode 100644 index 0000000..d97edc2 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfglazyinitializer.h @@ -0,0 +1,23 @@ +#ifndef CFGLAZYINITIALIZER_H +#define CFGLAZYINITIALIZER_H + +#include "coreSQLiteStudio_global.h" +#include <QList> +#include <functional> + +class API_EXPORT CfgLazyInitializer +{ + public: + CfgLazyInitializer(std::function<void(void)> initFunc, const char* name); + + static void init(); + + private: + void doInitialize(); + + std::function<void(void)> initFunc; + + static QList<CfgLazyInitializer*>* instances; +}; + +#endif // CFGLAZYINITIALIZER_H diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgmain.cpp b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgmain.cpp new file mode 100644 index 0000000..72fc0d0 --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgmain.cpp @@ -0,0 +1,120 @@ +#include "cfgmain.h" +#include "config_builder/cfgcategory.h" +#include "config_builder/cfgentry.h" + +CfgMain* lastCreatedCfgMain = nullptr; +QList<CfgMain*>* CfgMain::instances = nullptr; + +CfgMain::CfgMain(const QString& name, bool persistable, const char *metaName, const QString &title) : + name(name), metaName(metaName), title(title), persistable(persistable) +{ + lastCreatedCfgMain = this; + + if (!instances) + instances = new QList<CfgMain*>(); + + *instances << this; +} + +CfgMain::~CfgMain() +{ + if (!instances) + instances = new QList<CfgMain*>(); + + instances->removeOne(this); +} + +void CfgMain::staticInit() +{ + qRegisterMetaType<CfgMain*>("CfgMain*"); + qRegisterMetaType<CfgCategory*>("CfgCategory*"); + qRegisterMetaType<CfgEntry*>("CfgEntry*"); +} + +QList<CfgMain*> CfgMain::getInstances() +{ + if (!instances) + instances = new QList<CfgMain*>(); + + return *instances; +} + +QList<CfgMain*> CfgMain::getPersistableInstances() +{ + QList<CfgMain*> list; + for (CfgMain* main : getInstances()) + { + if (main->isPersistable()) + list << main; + } + return list; +} + +QHash<QString, CfgCategory *> &CfgMain::getCategories() +{ + return childs; +} + +void CfgMain::reset() +{ + for (CfgCategory* ctg : childs) + ctg->reset(); +} + +void CfgMain::savepoint(bool transaction) +{ + for (CfgCategory* ctg : childs) + ctg->savepoint(transaction); +} + +void CfgMain::restore() +{ + for (CfgCategory* ctg : childs) + ctg->restore(); +} + +void CfgMain::release() +{ + for (CfgCategory* ctg : childs) + ctg->release(); +} + +void CfgMain::begin() +{ + savepoint(true); +} + +void CfgMain::commit() +{ + release(); +} + +void CfgMain::rollback() +{ + restore(); +} + +bool CfgMain::isPersistable() const +{ + return persistable; +} + +QString CfgMain::getName() const +{ + return name; +} + +const char *CfgMain::getMetaName() const +{ + return metaName; +} + +QString CfgMain::getTitle() const +{ + return title; +} + +CfgMain::operator CfgMain*() +{ + return this; +} diff --git a/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgmain.h b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgmain.h new file mode 100644 index 0000000..bc9490d --- /dev/null +++ b/SQLiteStudio3/coreSQLiteStudio/config_builder/cfgmain.h @@ -0,0 +1,51 @@ +#ifndef CFGMAIN_H +#define CFGMAIN_H + +#include "coreSQLiteStudio_global.h" +#include <QVariant> +#include <QList> +#include <QHash> +#include <QString> + +class CfgCategory; + +class API_EXPORT CfgMain +{ + friend class CfgCategory; + + public: + CfgMain(const QString& name, bool persistable, const char* metaName, const QString& title); + ~CfgMain(); + + static void staticInit(); + static QList<CfgMain*> getInstances(); + static QList<CfgMain*> getPersistableInstances(); + + QHash<QString,CfgCategory*>& getCategories(); + void reset(); + void savepoint(bool transaction = false); + void restore(); + void release(); + void begin(); + void commit(); + void rollback(); + + bool isPersistable() const; + QString getName() const; + const char* getMetaName() const; + QString getTitle() const; + operator CfgMain*(); + + private: + QString name; + const char* metaName; + QString title; + bool persistable = true; + QHash<QString,CfgCategory*> childs; + + static QList<CfgMain*>* instances; +}; + +Q_DECLARE_METATYPE(CfgMain*) + +#endif // CFGMAIN_H |
