From c61d717e41836c11f5c8881fb9dbb1d65b9f541b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 8 Dec 2015 17:21:58 +0100 Subject: [PATCH] added integer settings --- apps/opencs/CMakeLists.txt | 4 +- apps/opencs/model/prefs/category.cpp | 20 +++++++ apps/opencs/model/prefs/category.hpp | 19 ++++++- apps/opencs/model/prefs/intsetting.cpp | 69 +++++++++++++++++++++++ apps/opencs/model/prefs/intsetting.hpp | 39 +++++++++++++ apps/opencs/model/prefs/setting.cpp | 32 +++++++++++ apps/opencs/model/prefs/setting.hpp | 53 ++++++++++++++++++ apps/opencs/model/prefs/state.cpp | 76 ++++++++++++++++++++++++++ apps/opencs/model/prefs/state.hpp | 13 +++++ apps/opencs/view/prefs/dialogue.cpp | 11 +++- apps/opencs/view/prefs/dialogue.hpp | 4 ++ apps/opencs/view/prefs/page.cpp | 40 ++++++++++++++ apps/opencs/view/prefs/page.hpp | 29 ++++++++++ apps/opencs/view/prefs/pagebase.cpp | 8 +-- 14 files changed, 405 insertions(+), 12 deletions(-) create mode 100644 apps/opencs/model/prefs/intsetting.cpp create mode 100644 apps/opencs/model/prefs/intsetting.hpp create mode 100644 apps/opencs/model/prefs/setting.cpp create mode 100644 apps/opencs/model/prefs/setting.hpp create mode 100644 apps/opencs/view/prefs/page.cpp create mode 100644 apps/opencs/view/prefs/page.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1e666c77d..003fd657b 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -124,7 +124,7 @@ opencs_units_noqt (view/settings ) opencs_units (view/prefs - dialogue pagebase + dialogue pagebase page ) opencs_units (model/settings @@ -138,7 +138,7 @@ opencs_hdrs_noqt (model/settings ) opencs_units (model/prefs - state + state setting intsetting ) opencs_units_noqt (model/prefs diff --git a/apps/opencs/model/prefs/category.cpp b/apps/opencs/model/prefs/category.cpp index 8143a19e5..b001586b5 100644 --- a/apps/opencs/model/prefs/category.cpp +++ b/apps/opencs/model/prefs/category.cpp @@ -9,3 +9,23 @@ const std::string& CSMPrefs::Category::getKey() const { return mKey; } + +CSMPrefs::State *CSMPrefs::Category::getState() const +{ + return mParent; +} + +void CSMPrefs::Category::addSetting (Setting *setting) +{ + mSettings.push_back (setting); +} + +CSMPrefs::Category::Iterator CSMPrefs::Category::begin() +{ + return mSettings.begin(); +} + +CSMPrefs::Category::Iterator CSMPrefs::Category::end() +{ + return mSettings.end(); +} diff --git a/apps/opencs/model/prefs/category.hpp b/apps/opencs/model/prefs/category.hpp index 23caba5e4..0b8e45d56 100644 --- a/apps/opencs/model/prefs/category.hpp +++ b/apps/opencs/model/prefs/category.hpp @@ -1,16 +1,26 @@ -#ifndef CSV_PREFS_CATEGORY_H +#ifndef CSM_PREFS_CATEGORY_H #define CSM_PREFS_CATEGORY_H #include +#include namespace CSMPrefs { class State; + class Setting; class Category { + public: + + typedef std::vector Container; + typedef Container::iterator Iterator; + + private: + State *mParent; std::string mKey; + Container mSettings; public: @@ -18,6 +28,13 @@ namespace CSMPrefs const std::string& getKey() const; + State *getState() const; + + void addSetting (Setting *setting); + + Iterator begin(); + + Iterator end(); }; } diff --git a/apps/opencs/model/prefs/intsetting.cpp b/apps/opencs/model/prefs/intsetting.cpp new file mode 100644 index 000000000..83fb495c5 --- /dev/null +++ b/apps/opencs/model/prefs/intsetting.cpp @@ -0,0 +1,69 @@ + +#include "intsetting.hpp" + +#include + +#include +#include + +#include + +#include "category.hpp" +#include "state.hpp" + +CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values, + const std::string& key, const std::string& label, int default_) +: Setting (parent, values, key, label), mMin (0), mMax (std::numeric_limits::max()), + mDefault (default_) +{} + +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange (int min, int max) +{ + mMin = min; + mMax = max; + return *this; +} + +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMin (int min) +{ + mMin = min; + return *this; +} + +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMax (int max) +{ + mMax = max; + return *this; +} + +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setTooltip (const std::string& tooltip) +{ + mTooltip = tooltip; + return *this; +} + +std::pair CSMPrefs::IntSetting::makeWidgets (QWidget *parent) +{ + QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent); + + QSpinBox *widget = new QSpinBox (parent); + widget->setRange (mMin, mMax); + widget->setValue (mDefault); + + if (!mTooltip.empty()) + { + QString tooltip = QString::fromUtf8 (mTooltip.c_str()); + label->setToolTip (tooltip); + widget->setToolTip (tooltip); + } + + connect (widget, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int))); + + return std::make_pair (label, widget); +} + +void CSMPrefs::IntSetting::valueChanged (int value) +{ + getValues().setInt (getKey(), getParent()->getKey(), value); + getParent()->getState()->update (*this); +} diff --git a/apps/opencs/model/prefs/intsetting.hpp b/apps/opencs/model/prefs/intsetting.hpp new file mode 100644 index 000000000..314e68b37 --- /dev/null +++ b/apps/opencs/model/prefs/intsetting.hpp @@ -0,0 +1,39 @@ +#ifndef CSM_PREFS_INTSETTING_H +#define CSM_PREFS_INTSETTING_H + +#include "setting.hpp" + +namespace CSMPrefs +{ + class IntSetting : public Setting + { + Q_OBJECT + + int mMin; + int mMax; + std::string mTooltip; + int mDefault; + + public: + + IntSetting (Category *parent, Settings::Manager *values, + const std::string& key, const std::string& label, int default_); + + IntSetting& setRange (int min, int max); + + IntSetting& setMin (int min); + + IntSetting& setMax (int max); + + IntSetting& setTooltip (const std::string& tooltip); + + /// Return label, input widget. + virtual std::pair makeWidgets (QWidget *parent); + + private slots: + + void valueChanged (int value); + }; +} + +#endif diff --git a/apps/opencs/model/prefs/setting.cpp b/apps/opencs/model/prefs/setting.cpp new file mode 100644 index 000000000..70dbbc745 --- /dev/null +++ b/apps/opencs/model/prefs/setting.cpp @@ -0,0 +1,32 @@ + +#include "setting.hpp" + +#include "category.hpp" +#include "state.hpp" + +Settings::Manager& CSMPrefs::Setting::getValues() +{ + return *mValues; +} + +CSMPrefs::Setting::Setting (Category *parent, Settings::Manager *values, + const std::string& key, const std::string& label) +: QObject (parent->getState()), mParent (parent), mValues (values), mKey (key), mLabel (label) +{} + +CSMPrefs::Setting:: ~Setting() {} + +const CSMPrefs::Category *CSMPrefs::Setting::getParent() const +{ + return mParent; +} + +const std::string& CSMPrefs::Setting::getKey() const +{ + return mKey; +} + +const std::string& CSMPrefs::Setting::getLabel() const +{ + return mLabel; +} diff --git a/apps/opencs/model/prefs/setting.hpp b/apps/opencs/model/prefs/setting.hpp new file mode 100644 index 000000000..148c64292 --- /dev/null +++ b/apps/opencs/model/prefs/setting.hpp @@ -0,0 +1,53 @@ +#ifndef CSM_PREFS_SETTING_H +#define CSM_PREFS_SETTING_H + +#include +#include + +#include + +class QWidget; + +namespace Settings +{ + class Manager; +} + +namespace CSMPrefs +{ + class Category; + + class Setting : public QObject + { + Q_OBJECT + + Category *mParent; + Settings::Manager *mValues; + std::string mKey; + std::string mLabel; + + protected: + + Settings::Manager& getValues(); + + public: + + Setting (Category *parent, Settings::Manager *values, const std::string& key, const std::string& label); + + virtual ~Setting(); + + /// Return label, input widget. + /// + /// \note first can be a 0-pointer, which means that the label is part of the input + /// widget. + virtual std::pair makeWidgets (QWidget *parent) = 0; + + const Category *getParent() const; + + const std::string& getKey() const; + + const std::string& getLabel() const; + }; +} + +#endif diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index c484a98d6..dfc460528 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -3,6 +3,9 @@ #include #include +#include + +#include "intsetting.hpp" CSMPrefs::State *CSMPrefs::State::sThis = 0; @@ -29,6 +32,24 @@ void CSMPrefs::State::load() void CSMPrefs::State::declare() { declareCategory ("Windows"); + declareInt ("default-width", "Default window width", 800). + setTooltip ("Newly opened top-level windows will open with this width."). + setMin (80); + declareInt ("default-height", "Default window height", 600). + setTooltip ("Newly opened top-level windows will open with this height."). + setMin (80); + // reuse + // show-statusbar + declareInt ("max-subviews", "Maximum number of subviews per top-level window", 256). + setTooltip ("If the maximum number is reached and a new subview is opened " + "it will be placed into a new top-level window."). + setRange (1, 256); + // hide-subview + declareInt ("minimum-width", "Minimum subview width", 325). + setTooltip ("Minimum width of subviews."). + setRange (50, 10000); + // mainwindow-scrollbar + // grow-limit declareCategory ("Records"); @@ -39,14 +60,33 @@ void CSMPrefs::State::declare() declareCategory ("Reports"); declareCategory ("Search & Replace"); + declareInt ("char-before", "Characters before search string", 10). + setTooltip ("Maximum number of character to display in search result before the searched text"); + declareInt ("char-after", "Characters after search string", 10). + setTooltip ("Maximum number of character to display in search result after the searched text"); + // auto-delete declareCategory ("Scripts"); + // show-linenum + // mono-font + // warnings + // toolbar + declareInt ("compile-delay", "Delay between updating of source errors", 100). + setTooltip ("Delay in milliseconds"). + setRange (0, 10000); + declareInt ("error-height", "Initial height of the error panel", 100). + setRange (100, 10000); + // syntax-colouring declareCategory ("General Input"); declareCategory ("3D Scene Input"); declareCategory ("Tooltips"); + // scene + // scene-hide-basic + declareInt ("scene-delay", "Tooltip delay in milliseconds", 500). + setMin (1); } void CSMPrefs::State::declareCategory (const std::string& key) @@ -64,6 +104,37 @@ void CSMPrefs::State::declareCategory (const std::string& key) } } +CSMPrefs::IntSetting& CSMPrefs::State::declareInt (const std::string& key, + const std::string& label, int default_) +{ + if (mCurrentCategory==mCategories.end()) + throw std::logic_error ("no category for setting"); + + std::ostringstream stream; + stream << default_; + setDefault (key, stream.str()); + + default_ = mSettings.getInt (key, mCurrentCategory->second.getKey()); + + CSMPrefs::IntSetting *setting = + new CSMPrefs::IntSetting (&mCurrentCategory->second, &mSettings, key, label, default_); + + mCurrentCategory->second.addSetting (setting); + + return *setting; +} + +void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_) +{ + Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key); + + Settings::CategorySettingValueMap::iterator iter = + mSettings.mDefaultSettings.find (fullKey); + + if (iter==mSettings.mDefaultSettings.end()) + mSettings.mDefaultSettings.insert (std::make_pair (fullKey, default_)); +} + CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager) : mConfigFile ("opencs.ini"), mConfigurationManager (configurationManager), mCurrentCategory (mCategories.end()) @@ -108,6 +179,11 @@ CSMPrefs::Category& CSMPrefs::State::getCategory (const std::string& key) return iter->second; } +void CSMPrefs::State::update (const Setting& setting) +{ + emit (settingChanged (setting)); +} + CSMPrefs::State& CSMPrefs::State::get() { if (!sThis) diff --git a/apps/opencs/model/prefs/state.hpp b/apps/opencs/model/prefs/state.hpp index a2e7aa038..c38f42049 100644 --- a/apps/opencs/model/prefs/state.hpp +++ b/apps/opencs/model/prefs/state.hpp @@ -13,9 +13,12 @@ #include #include "category.hpp" +#include "setting.hpp" namespace CSMPrefs { + class IntSetting; + class State : public QObject { Q_OBJECT @@ -47,6 +50,10 @@ namespace CSMPrefs void declareCategory (const std::string& key); + IntSetting& declareInt (const std::string& key, const std::string& label, int default_); + + void setDefault (const std::string& key, const std::string& default_); + public: State (const Files::ConfigurationManager& configurationManager); @@ -61,7 +68,13 @@ namespace CSMPrefs Category& getCategory (const std::string& key); + void update (const Setting& setting); + static State& get(); + + signals: + + void settingChanged (const Setting& setting); }; // convenience function diff --git a/apps/opencs/view/prefs/dialogue.cpp b/apps/opencs/view/prefs/dialogue.cpp index c4480fec4..6135afde7 100644 --- a/apps/opencs/view/prefs/dialogue.cpp +++ b/apps/opencs/view/prefs/dialogue.cpp @@ -10,7 +10,7 @@ #include "../../model/prefs/state.hpp" -#include "pagebase.hpp" +#include "page.hpp" void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main) { @@ -49,6 +49,13 @@ void CSVPrefs::Dialogue::buildContentArea (QSplitter *main) main->addWidget (mContent); } +CSVPrefs::PageBase *CSVPrefs::Dialogue::makePage (const std::string& key) +{ + // special case page code goes here + + return new Page (CSMPrefs::get().getCategory (key), mContent); +} + CSVPrefs::Dialogue::Dialogue() { setWindowTitle ("User Settings"); @@ -107,7 +114,7 @@ void CSVPrefs::Dialogue::selectionChanged (QListWidgetItem *current, QListWidget } } - PageBase *page = new PageBase (CSMPrefs::get().getCategory (key), mContent); + PageBase *page = makePage (key); mContent->setCurrentIndex (mContent->addWidget (page)); } } diff --git a/apps/opencs/view/prefs/dialogue.hpp b/apps/opencs/view/prefs/dialogue.hpp index 6bee54eb8..3965800db 100644 --- a/apps/opencs/view/prefs/dialogue.hpp +++ b/apps/opencs/view/prefs/dialogue.hpp @@ -10,6 +10,8 @@ class QListWidgetItem; namespace CSVPrefs { + class PageBase; + class Dialogue : public QMainWindow { Q_OBJECT @@ -23,6 +25,8 @@ namespace CSVPrefs void buildContentArea (QSplitter *main); + PageBase *makePage (const std::string& key); + public: Dialogue(); diff --git a/apps/opencs/view/prefs/page.cpp b/apps/opencs/view/prefs/page.cpp new file mode 100644 index 000000000..181ae40fa --- /dev/null +++ b/apps/opencs/view/prefs/page.cpp @@ -0,0 +1,40 @@ + +#include "page.hpp" + +#include + +#include "../../model/prefs/setting.hpp" +#include "../../model/prefs/category.hpp" + +CSVPrefs::Page::Page (CSMPrefs::Category& category, QWidget *parent) +: PageBase (category, parent) +{ + QWidget *widget = new QWidget (parent); + mGrid = new QGridLayout (widget); + + for (CSMPrefs::Category::Iterator iter = category.begin(); iter!=category.end(); ++iter) + addSetting (*iter); + + setWidget (widget); +} + +void CSVPrefs::Page::addSetting (CSMPrefs::Setting *setting) +{ + std::pair widgets = setting->makeWidgets (this); + + int next = mGrid->rowCount(); + + if (widgets.first) + { + mGrid->addWidget (widgets.first, next, 0); + mGrid->addWidget (widgets.second, next, 1); + } + else if (widgets.second) + { + mGrid->addWidget (widgets.second, next, 0, next, 1); + } + else + { + mGrid->addWidget (new QWidget (this), next, 0); + } +} diff --git a/apps/opencs/view/prefs/page.hpp b/apps/opencs/view/prefs/page.hpp new file mode 100644 index 000000000..ce13e5d9b --- /dev/null +++ b/apps/opencs/view/prefs/page.hpp @@ -0,0 +1,29 @@ +#ifndef CSV_PREFS_PAGE_H +#define CSV_PREFS_PAGE_H + +#include "pagebase.hpp" + +class QGridLayout; + +namespace CSMPrefs +{ + class Setting; +} + +namespace CSVPrefs +{ + class Page : public PageBase + { + Q_OBJECT + + QGridLayout *mGrid; + + public: + + Page (CSMPrefs::Category& category, QWidget *parent); + + void addSetting (CSMPrefs::Setting *setting); + }; +} + +#endif diff --git a/apps/opencs/view/prefs/pagebase.cpp b/apps/opencs/view/prefs/pagebase.cpp index 28c33a94a..16684a69d 100644 --- a/apps/opencs/view/prefs/pagebase.cpp +++ b/apps/opencs/view/prefs/pagebase.cpp @@ -1,17 +1,11 @@ #include "pagebase.hpp" -#include - #include "../../model/prefs/category.hpp" CSVPrefs::PageBase::PageBase (CSMPrefs::Category& category, QWidget *parent) : QScrollArea (parent), mCategory (category) -{ -QLabel *temp = new QLabel (category.getKey().c_str(), this); -setWidget (temp); - -} +{} CSMPrefs::Category& CSVPrefs::PageBase::getCategory() {