diff --git a/icons/license.txt b/icons/license.txt new file mode 100644 index 00000000..97e6931b --- /dev/null +++ b/icons/license.txt @@ -0,0 +1,3 @@ +Taken from http://tango.freedesktop.org/Tango_Icon_Library, version 0.8.90 / public domain: + +- prefsFeatures.png (converted from preferences-system.svg) diff --git a/icons/prefsFeatures.png b/icons/prefsFeatures.png new file mode 100644 index 00000000..2fb0a558 Binary files /dev/null and b/icons/prefsFeatures.png differ diff --git a/openscad.qrc b/openscad.qrc index 28b6a72d..6fd7e479 100644 --- a/openscad.qrc +++ b/openscad.qrc @@ -1,5 +1,6 @@ + icons/prefsFeatures.png icons/stopbutton.png icons/prefsAdvanced.png icons/prefs3DView.png diff --git a/src/Preferences.cc b/src/Preferences.cc index 0f3115e8..6ec9c9d6 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -35,6 +35,7 @@ #include "AutoUpdater.h" #ifdef ENABLE_CGAL #include "CGALCache.h" +#include "feature.h" #endif Preferences *Preferences::instance = NULL; @@ -86,13 +87,13 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->defaultmap["advanced/openCSGLimit"] = RenderSettings::inst()->openCSGTermLimit; this->defaultmap["advanced/forceGoldfeather"] = false; - // Toolbar QActionGroup *group = new QActionGroup(this); - group->addAction(prefsAction3DView); - group->addAction(prefsActionEditor); - group->addAction(prefsActionUpdate); - group->addAction(prefsActionAdvanced); + addPrefPage(group, prefsAction3DView, page3DView); + addPrefPage(group, prefsActionEditor, pageEditor); + addPrefPage(group, prefsActionUpdate, pageUpdate); + addPrefPage(group, prefsActionFeatures, pageFeatures); + addPrefPage(group, prefsActionAdvanced, pageAdvanced); connect(group, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); prefsAction3DView->setChecked(true); @@ -140,6 +141,7 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->polysetCacheSizeEdit->setValidator(validator); this->opencsgLimitEdit->setValidator(validator); + setupFeaturesPage(); updateGUI(); RenderSettings::inst()->setColors(this->colorschemes[getValue("3dview/colorscheme").toString()]); @@ -150,21 +152,42 @@ Preferences::~Preferences() removeDefaultSettings(); } +void +Preferences::addPrefPage(QActionGroup *group, QAction *action, QWidget *widget) +{ + group->addAction(action); + prefPages[action] = widget; +} void Preferences::actionTriggered(QAction *action) { - if (action == this->prefsAction3DView) { - this->stackedWidget->setCurrentWidget(this->page3DView); - } - else if (action == this->prefsActionEditor) { - this->stackedWidget->setCurrentWidget(this->pageEditor); - } - else if (action == this->prefsActionUpdate) { - this->stackedWidget->setCurrentWidget(this->pageUpdate); - } - else if (action == this->prefsActionAdvanced) { - this->stackedWidget->setCurrentWidget(this->pageAdvanced); + this->stackedWidget->setCurrentWidget(prefPages[action]); +} + +void +Preferences::setupFeaturesPage() +{ + int row = 0; + for (Feature::const_iterator it = Feature::begin();it != Feature::end();it++) { + gridLayoutExperimentalFeatures->addItem(new QSpacerItem(1, 8, QSizePolicy::Expanding, QSizePolicy::Fixed), row, 1, 1, 1, Qt::AlignCenter); + row++; + const Feature *feature = (*it); + QCheckBox *cb = new QCheckBox(feature->get_name().c_str(), pageFeatures); + QFont bold_font(cb->font()); + bold_font.setBold(true); + cb->setFont(bold_font); + gridLayoutExperimentalFeatures->addWidget(cb, row, 0, 1, 2, Qt::AlignLeading); + row++; + QLabel *l = new QLabel(feature->get_description().c_str(), pageFeatures); + l->setTextFormat(Qt::RichText); + gridLayoutExperimentalFeatures->addWidget(l, row, 1, 1, 1, Qt::AlignLeading); + row++; } + // Force fixed indentation, the checkboxes use column span of 2 so + // first row is not constrained in size by the visible controls. The + // fixed size space essentially gives the first row the width of the + // spacer item itself. + gridLayoutExperimentalFeatures->addItem(new QSpacerItem(20, 0, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 0, 1, 1, Qt::AlignLeading); } void Preferences::on_colorSchemeChooser_itemSelectionChanged() diff --git a/src/Preferences.h b/src/Preferences.h index 46567939..addb7e52 100644 --- a/src/Preferences.h +++ b/src/Preferences.h @@ -44,9 +44,12 @@ private: void keyPressEvent(QKeyEvent *e); void updateGUI(); void removeDefaultSettings(); + void setupFeaturesPage(); + void addPrefPage(QActionGroup *group, QAction *action, QWidget *widget); QSettings::SettingsMap defaultmap; QHash > colorschemes; + QHash prefPages; static Preferences *instance; }; diff --git a/src/Preferences.ui b/src/Preferences.ui index d67db6a5..78a1cf6a 100644 --- a/src/Preferences.ui +++ b/src/Preferences.ui @@ -6,8 +6,8 @@ 0 0 - 473 - 320 + 823 + 433 @@ -27,7 +27,7 @@ - 2 + 3 @@ -136,7 +136,7 @@ - Monaco + DejaVu Sans 12 @@ -323,6 +323,78 @@ + + + + 0 + + + + + + + + 75 + true + + + + Features + + + + + + + QFrame::NoFrame + + + QFrame::Plain + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 803 + 311 + + + + + + + 8 + + + + + + + Qt::Vertical + + + + 20 + 282 + + + + + + + + + + + + @@ -465,6 +537,7 @@ + @@ -515,6 +588,21 @@ Update + + + true + + + + :/icons/prefsFeatures.png:/icons/prefsFeatures.png + + + Features + + + Enable/Disable experimental features + + diff --git a/src/feature.cc b/src/feature.cc index 5beece10..7f36547d 100644 --- a/src/feature.cc +++ b/src/feature.cc @@ -4,23 +4,26 @@ #include #include "feature.h" +#include "printutils.h" /** - * Feature registration map for later lookup. This must be initialized + * Feature registration map/list for later lookup. This must be initialized * before the static feature instances as those register with this map. */ -std::map Feature::feature_map; +Feature::map_t Feature::feature_map; +Feature::list_t Feature::feature_list; /* * List of features, the names given here are used in both command line * argument to enable the option and for saving the option value in GUI * context. */ -const Feature Feature::ExperimentalConcatFunction("concat"); +const Feature Feature::ExperimentalConcatFunction("experimental/concat-function", "Enable the concat() function."); -Feature::Feature(std::string name) : enabled_cmdline(false), enabled_options(false), name(name) +Feature::Feature(const std::string name, const std::string description) : enabled_cmdline(false), enabled_options(false), name(name), description(description) { feature_map[name] = this; + feature_list.push_back(this); } Feature::~Feature() @@ -32,6 +35,11 @@ const std::string& Feature::get_name() const return name; } +const std::string& Feature::get_description() const +{ + return description; +} + void Feature::set_enable_cmdline() { enabled_cmdline = true; @@ -49,15 +57,10 @@ bool Feature::is_enabled() const } return enabled_options; } - -bool operator ==(const Feature& lhs, const Feature& rhs) -{ - return lhs.get_name() == rhs.get_name(); -} -bool operator !=(const Feature& lhs, const Feature& rhs) +void Feature::enable(bool status) { - return !(lhs == rhs); + set_enable_options(status); } void Feature::enable_feature(std::string feature_name) @@ -65,6 +68,8 @@ void Feature::enable_feature(std::string feature_name) map_t::iterator it = feature_map.find(feature_name); if (it != feature_map.end()) { (*it).second->set_enable_cmdline(); + } else { + PRINTB("WARNING: Ignoring request to enable unknown feature '%s'.", feature_name); } } @@ -76,6 +81,16 @@ void Feature::enable_feature(std::string feature_name, bool status) } } +Feature::iterator Feature::begin() +{ + return feature_list.begin(); +} + +Feature::iterator Feature::end() +{ + return feature_list.end(); +} + void Feature::dump_features() { for (map_t::iterator it = feature_map.begin(); it != feature_map.end(); it++) { diff --git a/src/feature.h b/src/feature.h index 3c97edca..77e283ca 100644 --- a/src/feature.h +++ b/src/feature.h @@ -5,8 +5,13 @@ #include #include #include +#include class Feature { +public: + typedef std::vector list_t; + typedef list_t::iterator iterator; + private: /** * Set to true in case the matching feature was given as commandline @@ -19,12 +24,14 @@ private: */ bool enabled_options; - std::string name; + const std::string name; + const std::string description; typedef std::map map_t; static map_t feature_map; - - Feature(std::string name); + static list_t feature_list; + + Feature(std::string name, std::string description); virtual ~Feature(); virtual void set_enable_cmdline(); virtual void set_enable_options(bool status); @@ -33,11 +40,13 @@ public: static const Feature ExperimentalConcatFunction; const std::string& get_name() const; + const std::string& get_description() const; bool is_enabled() const; - - friend bool operator ==(const Feature& lhs, const Feature& rhs); - friend bool operator !=(const Feature& lhs, const Feature& rhs); + void enable(bool status); + + static iterator begin(); + static iterator end(); static void dump_features(); static void enable_feature(std::string feature_name);