Mon, 31 Aug 2015 20:50:12 +0300
Now compiles and links but crashes shortly after startup.
--- a/.hgignore Mon Aug 31 04:57:16 2015 +0300 +++ b/.hgignore Mon Aug 31 20:50:12 2015 +0300 @@ -12,3 +12,4 @@ *.rej *.orig CMakeLists.txt.user +*.pyc
--- a/CMakeLists.txt Mon Aug 31 04:57:16 2015 +0300 +++ b/CMakeLists.txt Mon Aug 31 20:50:12 2015 +0300 @@ -27,20 +27,12 @@ COMMAND python "${CMAKE_SOURCE_DIR}/tools/updaterevision.py" hginfo.h WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_custom_target (config_collection ALL - COMMAND python - "${CMAKE_SOURCE_DIR}/tools/configcollector.py" - --header configurationvaluebag.h - --source configurationvaluebag.cpp - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - include_directories (${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}) set (LDFORGE_SOURCES src/addObjectDialog.cpp src/basics.cpp src/colors.cpp - src/configuration.cpp src/configDialog.cpp src/crashCatcher.cpp src/dialogs.cpp @@ -48,9 +40,10 @@ src/editHistory.cpp src/glRenderer.cpp src/glCompiler.cpp + src/hierarchyelement.cpp src/ldDocument.cpp src/ldObject.cpp - src/ldObjectMath.cpp + src/ldObjectMath.cpp src/ldpaths.cpp src/main.cpp src/mainwindow.cpp @@ -79,6 +72,7 @@ src/toolsets/movetoolset.cpp src/toolsets/toolset.cpp src/toolsets/viewtoolset.cpp + ${CMAKE_BINARY_DIR}/configurationvaluebag.cpp ) set (LDFORGE_HEADERS @@ -102,11 +96,11 @@ src/configDialog.h src/glRenderer.h src/glCompiler.h - src/configuration.h src/mainwindow.h src/editHistory.h src/format.h src/ldpaths.h + src/hierarchyelement.h src/dialogs/colorselector.h src/dialogs/ldrawpathdialog.h src/dialogs/newpartdialog.h @@ -207,5 +201,14 @@ ) endif() +add_custom_target (config_collection ALL + COMMAND python + "${CMAKE_SOURCE_DIR}/tools/configcollector.py" + --header ${CMAKE_BINARY_DIR}/configurationvaluebag.h + --source ${CMAKE_BINARY_DIR}/configurationvaluebag.cpp + --sourcedir ${CMAKE_SOURCE_DIR}/src + ${LDFORGE_SOURCES} + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + add_dependencies (ldforge revision_check config_collection) install (TARGETS ldforge RUNTIME DESTINATION bin)
--- a/codegen/CMakeLists.txt Mon Aug 31 04:57:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -cmake_minimum_required (VERSION 2.4) -add_executable (codegen codegen.cpp) - -# -# LDForge uses alternative operators. GCC and Clang use these by default but MSVC does not. -# So we'll have to tell MSVC to use these alternative operators -# -if (MSVC) - set_target_properties (codegen PROPERTIES COMPILE_FLAGS "/Za") -endif()
--- a/codegen/codegen.cpp Mon Aug 31 04:57:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013 - 2015 Teemu Piippo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <sstream> -#include <fstream> -#include <string> -#include <cstring> -#include <iostream> -#include <vector> -#include <algorithm> - -using std::string; -using std::vector; -using std::ifstream; -using std::size_t; -using std::strncmp; -using std::getline; -using std::cout; -using std::endl; - -struct EntryType -{ - string name; - string type; - string defvalue; - - inline bool operator< (EntryType const& other) const - { - return name < other.name; - } - - inline bool operator== (EntryType const& other) const - { - return name == other.name and type == other.type; - } - - inline bool operator!= (EntryType const& other) const - { - return not operator== (other); - } -}; - -char AdvancePointer (char const*& ptr) -{ - char a = *ptr++; - - if (*ptr == '\0') - throw false; - - return a; -} - -void ReadConfigEntries (string const& filename, vector<EntryType>& entries, const char* macroname) -{ - ifstream is (filename.c_str()); - string line; - size_t const macrolen = strlen (macroname); - - while (getline (is, line)) - { - try - { - if (strncmp (line.c_str(), macroname, macrolen) != 0) - continue; - - char const* ptr = &line[macrolen]; - EntryType entry; - - // Skip to paren - while (*ptr != '(') - AdvancePointer (ptr); - - // Skip whitespace - while (isspace (*ptr)) - AdvancePointer (ptr); - - // Skip paren - AdvancePointer (ptr); - - // Read type - while (*ptr != ',') - entry.type += AdvancePointer (ptr); - - // Skip comma and whitespace - for (AdvancePointer (ptr); isspace (*ptr); AdvancePointer (ptr)) - ; - - // Read name - while (*ptr != ',') - entry.name += AdvancePointer (ptr); - - // Skip comma and whitespace - for (AdvancePointer (ptr); isspace (*ptr); AdvancePointer (ptr)) - ; - - // Read default - while (*ptr != ')') - entry.defvalue += AdvancePointer (ptr); - - entries.push_back (entry); - } - catch (bool) {} - } -} - -bool CheckEquality (vector<EntryType> a, vector<EntryType> b) -{ - if (a.size() != b.size()) - return false; - - std::sort (a.begin(), a.end()); - std::sort (b.begin(), b.end()); - - for (size_t i = 0; i < a.size(); ++i) - { - if (a[i] != b[i]) - return false; - } - - return true; -} - -int main (int argc, char* argv[]) -{ - vector<EntryType> entries; - vector<EntryType> oldentries; - ReadConfigEntries (argv[argc - 1], oldentries, "CODEGEN_CACHE"); - - for (int arg = 1; arg < argc - 1; ++arg) - ReadConfigEntries (argv[arg], entries, "CFGENTRY"); - - if (CheckEquality (entries, oldentries)) - { - cout << "Configuration options unchanged" << endl; - return 0; - } - - std::ofstream os (argv[argc - 1]); - os << "#pragma once" << endl; - os << "#define CODEGEN_CACHE(A,B,C)" << endl; - - for (vector<EntryType>::const_iterator it = entries.begin(); it != entries.end(); ++it) - { - os << "CODEGEN_CACHE (" << it->type << ", " << it->name << ", " << - it->defvalue << ")" << endl; - } - - os << endl; - for (vector<EntryType>::const_iterator it = entries.begin(); it != entries.end(); ++it) - os << "EXTERN_CFGENTRY (" << it->type << ", " << it->name << ")" << endl; - - os << endl; - os << "static void InitConfigurationEntry (AbstractConfigEntry* entry);" << endl; - os << "static void SetupConfigurationLists()" << endl; - os << "{" << endl; - - for (vector<EntryType>::const_iterator it = entries.begin(); it != entries.end(); ++it) - { - os << "\tInitConfigurationEntry (new " << it->type << "ConfigEntry (&cfg::" << - it->name << ", \"" << it->name << "\", " << it->defvalue << "));" << endl; - } - - os << "}" << endl; - cout << "Wrote configuration options list to " << argv[argc - 1] << "." << endl; - return 0; -}
--- a/src/addObjectDialog.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/addObjectDialog.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -254,7 +254,7 @@ // ============================================================================= void AddObjectDialog::slot_colorButtonClicked() { - ColorSelector::selectColor (m_color, m_color, this); + ColorSelector::selectColor (this, m_color, m_color); setButtonBackground (pb_color, m_color); }
--- a/src/configDialog.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/configDialog.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -29,10 +29,10 @@ #include <QDoubleSpinBox> #include <QLineEdit> #include <QCheckBox> +#include <QSettings> #include "main.h" #include "configDialog.h" #include "ldDocument.h" -#include "configuration.h" #include "miscallenous.h" #include "colors.h" #include "dialogs/colorselector.h" @@ -45,19 +45,19 @@ #endif "All files (*.*)(*.*)"; -// -// ConfigDialog::ConfigDialog (QWidget* parent, ConfigDialog::Tab defaulttab, Qt::WindowFlags f) : QDialog (parent, f), - HierarchyElement (parent) + HierarchyElement (parent), + m_settings (m_window->makeSettings (this)) { ui = new Ui_ConfigUI; ui->setupUi (this); // Set defaults - applyToWidgetOptions ([&](QWidget* wdg, AbstractConfigEntry* conf) + applyToWidgetOptions ( + [&](QWidget* widget, QString confname) { - QVariant value (conf->toVariant()); + QVariant value = m_settings->value (confname, m_config->defaultValueByName (confname)); QLineEdit* le; QSpinBox* spinbox; QDoubleSpinBox* doublespinbox; @@ -65,34 +65,34 @@ QCheckBox* checkbox; QPushButton* button; - if ((le = qobject_cast<QLineEdit*> (wdg)) != null) + if ((le = qobject_cast<QLineEdit*> (widget)) != null) { le->setText (value.toString()); } - else if ((spinbox = qobject_cast<QSpinBox*> (wdg)) != null) + else if ((spinbox = qobject_cast<QSpinBox*> (widget)) != null) { spinbox->setValue (value.toInt()); } - else if ((doublespinbox = qobject_cast<QDoubleSpinBox*> (wdg)) != null) + else if ((doublespinbox = qobject_cast<QDoubleSpinBox*> (widget)) != null) { doublespinbox->setValue (value.toDouble()); } - else if ((slider = qobject_cast<QSlider*> (wdg)) != null) + else if ((slider = qobject_cast<QSlider*> (widget)) != null) { slider->setValue (value.toInt()); } - else if ((checkbox = qobject_cast<QCheckBox*> (wdg)) != null) + else if ((checkbox = qobject_cast<QCheckBox*> (widget)) != null) { checkbox->setChecked (value.toBool()); } - else if ((button = qobject_cast<QPushButton*> (wdg)) != null) + else if ((button = qobject_cast<QPushButton*> (widget)) != null) { setButtonBackground (button, value.toString()); connect (button, SIGNAL (clicked()), this, SLOT (setButtonColor())); } else { - print ("Unknown widget of type %1\n", wdg->metaObject()->className()); + print ("Unknown widget of type %1\n", widget->metaObject()->className()); } }); @@ -124,15 +124,11 @@ connect (ui->m_pagelist, SIGNAL (currentRowChanged (int)), this, SLOT (selectPage (int))); } -// -// ConfigDialog::~ConfigDialog() { delete ui; } -// -// void ConfigDialog::selectPage (int row) { ui->m_pagelist->setCurrentRow (row); @@ -177,7 +173,7 @@ QPushButton* setPathButton = new QPushButton; icon->setPixmap (GetIcon (name.toLower())); - input->setText (*info.path); + input->setText (m_window->externalPrograms()->getPathSetting (program)); setPathButton->setIcon (GetIcon ("folder")); widgets.input = input; widgets.setPathButton = setPathButton; @@ -196,14 +192,12 @@ pathsLayout->addWidget (wineBox, row, 4); } #endif - ++row; } - ui->extProgs->setLayout (pathsLayout); } -void ConfigDialog::applyToWidgetOptions (std::function<void (QWidget*, AbstractConfigEntry*)> func) +void ConfigDialog::applyToWidgetOptions (std::function<void (QWidget*, QString)> func) { // Apply configuration for (QWidget* widget : findChildren<QWidget*>()) @@ -211,16 +205,12 @@ if (not widget->objectName().startsWith ("config")) continue; - QString confname (widget->objectName().mid (strlen ("config"))); - AbstractConfigEntry* conf (m_config->findByName (confname)); + QString optionname (widget->objectName().mid (strlen ("config"))); - if (conf == null) - { - print ("Couldn't find configuration entry named %1", confname); - continue; - } - - func (widget, conf); + if (m_settings->contains (optionname)) + func (widget, optionname); + else + print ("Couldn't find configuration entry named %1", optionname); } } @@ -229,9 +219,9 @@ // void ConfigDialog::applySettings() { - applyToWidgetOptions ([&](QWidget* widget, AbstractConfigEntry* conf) + applyToWidgetOptions ([&](QWidget* widget, QString confname) { - QVariant value (conf->toVariant()); + QVariant value; QLineEdit* le; QSpinBox* spinbox; QDoubleSpinBox* doublespinbox; @@ -252,14 +242,17 @@ else if ((button = qobject_cast<QPushButton*> (widget)) != null) value = m_buttonColors[button]; else + { print ("Unknown widget of type %1\n", widget->metaObject()->className()); + return; + } - conf->loadFromVariant (value); + m_settings->setValue (confname, value); }); // Rebuild the quick color toolbar m_window->setQuickColors (quickColors); - m_config->quickColorToolbar = quickColorString(); + m_config->setQuickColorToolbar (quickColorString()); // Ext program settings for (int i = 0; i < NumExternalPrograms; ++i) @@ -270,7 +263,7 @@ toolset->getPathSetting (program) = widgets.input->text(); if (widgets.wineBox) - toolset->getWineSetting (program) = widgets.wineBox->isChecked(); + toolset->setWineSetting (program, widgets.wineBox->isChecked()); } // Apply shortcuts @@ -280,7 +273,7 @@ item->action()->setShortcut (item->sequence()); } - Config::Save(); + m_window->syncSettings(); LDDocument::current()->reloadAllSubfiles(); LoadLogoStuds(); @@ -384,7 +377,7 @@ LDColor defaultValue = entry ? entry->color() : LDColor::nullColor(); LDColor value; - if (not ColorSelector::selectColor (value, defaultValue, this)) + if (not ColorSelector::selectColor (this, value, defaultValue)) return; if (entry != null)
--- a/src/configDialog.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/configDialog.h Mon Aug 31 20:50:12 2015 +0300 @@ -71,6 +71,7 @@ QList<QListWidgetItem*> quickColorItems; QMap<QPushButton*, QColor> m_buttonColors; ExternalProgramWidgets m_externalProgramWidgets[NumExternalPrograms]; + QSettings* m_settings; void applySettings(); void addShortcut (QAction* act); @@ -82,7 +83,7 @@ QListWidgetItem* getSelectedQuickColor(); QList<ShortcutListItem*> getShortcutSelection(); void initExtProgs(); - void applyToWidgetOptions (std::function<void (QWidget*, AbstractConfigEntry*)> func); + void applyToWidgetOptions (std::function<void (QWidget*, QString)> func); private slots: void setButtonColor();
--- a/src/configuration.cpp Mon Aug 31 04:57:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013 - 2015 Teemu Piippo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * ===================================================================== - * - * config.cxx: Configuration management. I don't like how unsafe QSettings - * is so this implements a type-safer and identifer-safer wrapping system of - * configuration variables. QSettings is used underlyingly, this is a matter - * of interface. - */ - -#include <errno.h> -#include <QDir> -#include <QTextStream> -#include <QSettings> -#include <QApplication> -#include "main.h" -#include "configuration.h" -#include "miscallenous.h" -#include "mainwindow.h" -#include "ldDocument.h" -#include "glRenderer.h" -#include "configuration.inc" - -#ifdef _WIN32 -# define EXTENSION ".ini" -#else -# define EXTENSION ".cfg" -#endif // _WIN32 - -#define MAX_CONFIG 512 - -static QMap<QString, AbstractConfigEntry*> EntriesByName; -static QList<AbstractConfigEntry*> ConfigurationEntries; - -AbstractConfigEntry::AbstractConfigEntry (QString name) : - m_name (name) {} - -void Config::Initialize() -{ - SetupConfigurationLists(); - print ("Configuration initialized with %1 entries\n", ConfigurationEntries.size()); -} - -static void InitConfigurationEntry (AbstractConfigEntry* entry) -{ - ConfigurationEntries << entry; - EntriesByName[entry->name()] = entry; -} - -// -// Load the configuration from file -// -bool Config::Load() -{ - QSettings* settings = SettingsObject(); - print ("Loading configuration file from %1\n", settings->fileName()); - - for (AbstractConfigEntry* cfg : ConfigurationEntries) - { - if (cfg == null) - break; - - QVariant val = settings->value (cfg->name(), cfg->getDefaultAsVariant()); - cfg->loadFromVariant (val); - } - - if (g_win != null) - g_win->loadShortcuts (settings); - - delete settings; - return true; -} - -// -// Save the configuration to disk -// -bool Config::Save() -{ - QSettings* settings = SettingsObject(); - - for (AbstractConfigEntry* cfg : ConfigurationEntries) - { - if (not cfg->isDefault()) - settings->setValue (cfg->name(), cfg->toVariant()); - else - settings->remove (cfg->name()); - } - - if (g_win != null) - g_win->saveShortcuts (settings); - - settings->sync(); - print ("Configuration saved to %1.\n", settings->fileName()); - delete settings; - return true; -} - -// -// Reset configuration to defaults. -// -void Config::ResetToDefaults() -{ - for (AbstractConfigEntry* cfg : ConfigurationEntries) - cfg->resetValue(); -} - -// -// Where is the configuration file located at? -// -QString Config::FilePath (QString file) -{ - return Config::DirectoryPath() + DIRSLASH + file; -} - -// -// Directory of the configuration file. -// -QString Config::DirectoryPath() -{ - QSettings* settings = SettingsObject(); - QString result = Dirname (settings->fileName()); - delete settings; - return result; -} - -// -// Accessor to the settings object -// -QSettings* Config::SettingsObject() -{ - QString path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION; - return new QSettings (path, QSettings::IniFormat); -} - -// -// Accessor to entry list -// -QList<AbstractConfigEntry*> const& Config::AllConfigEntries() -{ - return ConfigurationEntries; -} - -AbstractConfigEntry* Config::FindByName (QString const& name) -{ - auto it = EntriesByName.find (name); - return (it != EntriesByName.end()) ? *it : null; -} - -template<typename T> -static T* GetConfigByName (QString name, AbstractConfigEntry::Type type) -{ - auto it = EntriesByName.find (name); - - if (it == EntriesByName.end()) - return null; - - AbstractConfigEntry* cfg = it.value(); - - if (cfg->getType() != type) - { - fprint (stderr, "type of %1 is %2, not %3\n", name, cfg->getType(), type); - abort(); - } - - return reinterpret_cast<T*> (cfg); -} - -#undef IMPLEMENT_CONFIG - -#define IMPLEMENT_CONFIG(NAME) \ - NAME##ConfigEntry* NAME##ConfigEntry::getByName (QString name) \ - { \ - return GetConfigByName<NAME##ConfigEntry> (name, E##NAME##Type); \ - } - -IMPLEMENT_CONFIG (Int) -IMPLEMENT_CONFIG (String) -IMPLEMENT_CONFIG (Bool) -IMPLEMENT_CONFIG (Float) -IMPLEMENT_CONFIG (List) -IMPLEMENT_CONFIG (KeySequence) -IMPLEMENT_CONFIG (Vertex) - -void IntConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.toInt(); -} - -void StringConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.toString(); -} - -void BoolConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.toBool(); -} - -void ListConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.toList(); -} - -void KeySequenceConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.toString(); -} - -void FloatConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.toDouble(); -} - -void VertexConfigEntry::loadFromVariant (const QVariant& val) -{ - *m_valueptr = val.value<Vertex>(); -}
--- a/src/configuration.h Mon Aug 31 04:57:16 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013 - 2015 Teemu Piippo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once -#include <QString> -#include <QVariant> -#include <QKeySequence> -#include "macros.h" -#include "basics.h" - -class QSettings; -class AbstractConfigEntry; - -namespace Config -{ - void Initialize(); - bool Load(); - bool Save(); - void ResetToDefaults(); - QString DirectoryPath(); - QString FilePath (QString file); - QSettings* SettingsObject(); - QList<AbstractConfigEntry*> const& AllConfigEntries(); - AbstractConfigEntry* FindByName (QString const& name); -} - -class AbstractConfigEntry -{ - PROPERTY (private, QString, name, setName, STOCK_WRITE) - -public: - enum Type - { - EIntType, - EStringType, - EFloatType, - EBoolType, - EKeySequenceType, - EListType, - EVertexType, - }; - - using IntType = int; - using StringType = QString; - using FloatType = float; - using BoolType = bool; - using KeySequenceType = QKeySequence; - using ListType = QList<QVariant>; - using VertexType = Vertex; - - AbstractConfigEntry (QString name); - - virtual QVariant getDefaultAsVariant() const = 0; - virtual Type getType() const = 0; - virtual bool isDefault() const = 0; - virtual void loadFromVariant (const QVariant& val) = 0; - virtual void resetValue() = 0; - virtual QVariant toVariant() const = 0; -}; - -#define IMPLEMENT_CONFIG(NAME) \ -public: \ - using ValueType = AbstractConfigEntry::NAME##Type; \ - \ - NAME##ConfigEntry (ValueType* valueptr, QString name, ValueType def) : \ - AbstractConfigEntry (name), \ - m_valueptr (valueptr), \ - m_default (def) \ - { \ - *m_valueptr = def; \ - } \ - \ - inline ValueType getValue() const \ - { \ - return *m_valueptr; \ - } \ - \ - inline void setValue (ValueType val) \ - { \ - *m_valueptr = val; \ - } \ - \ - virtual AbstractConfigEntry::Type getType() const \ - { \ - return AbstractConfigEntry::E##NAME##Type; \ - } \ - \ - virtual void resetValue() \ - { \ - *m_valueptr = m_default; \ - } \ - \ - virtual const ValueType& getDefault() const \ - { \ - return m_default; \ - } \ - \ - virtual bool isDefault() const \ - { \ - return *m_valueptr == m_default; \ - } \ - \ - virtual void loadFromVariant (const QVariant& val); \ - \ - virtual QVariant toVariant() const \ - { \ - return QVariant::fromValue<ValueType> (*m_valueptr); \ - } \ - \ - virtual QVariant getDefaultAsVariant() const \ - { \ - return QVariant::fromValue<ValueType> (m_default); \ - } \ - \ - static NAME##ConfigEntry* getByName (QString name); \ - \ -private: \ - ValueType* m_valueptr; \ - ValueType m_default; - -class IntConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (Int) -}; - -class StringConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (String) -}; - -class FloatConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (Float) -}; - -class BoolConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (Bool) -}; - -class KeySequenceConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (KeySequence) -}; - -class ListConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (List) -}; - -class VertexConfigEntry : public AbstractConfigEntry -{ - IMPLEMENT_CONFIG (Vertex) -};
--- a/src/dialogs/colorselector.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/dialogs/colorselector.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -24,7 +24,6 @@ #include "../main.h" #include "../mainwindow.h" #include "../colors.h" -#include "../configuration.h" #include "../miscallenous.h" #include "colorselector.h" #include "ui_colorselector.h" @@ -55,8 +54,8 @@ if (ldcolor == MainColor) { - color = QColor (m_config->mainColor); - color.setAlphaF (m_config->mainColorAlpha); + color = QColor (m_config->mainColor()); + color.setAlphaF (m_config->mainColorAlpha()); } QString color2name (Luma (color) < 80 ? "white" : "black");
--- a/src/dialogs/ldrawpathdialog.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/dialogs/ldrawpathdialog.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -44,7 +44,7 @@ connect (ui.path, SIGNAL (textChanged (QString)), this, SIGNAL (pathChanged (QString))); connect (ui.searchButton, SIGNAL (clicked()), this, SLOT (searchButtonClicked())); connect (ui.buttonBox, SIGNAL (rejected()), this, validDefault ? SLOT (reject()) : SLOT (slot_exit())); - connect (ui.buttonBox, SIGNAL (accepted()), this, SLOT (slot_accept())); + connect (ui.buttonBox, SIGNAL (accepted()), this, SLOT (accept())); setPath (defaultPath); } @@ -98,10 +98,4 @@ .arg (ok ? "#700" : "#270") .arg (statusText)); } -} - -void LDrawPathDialog::slot_accept() -{ - Config::Save(); - accept(); } \ No newline at end of file
--- a/src/dialogs/ldrawpathdialog.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/dialogs/ldrawpathdialog.h Mon Aug 31 20:50:12 2015 +0300 @@ -43,5 +43,4 @@ private slots: void searchButtonClicked(); void slot_exit(); - void slot_accept(); };
--- a/src/dialogs/newpartdialog.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/dialogs/newpartdialog.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -31,13 +31,13 @@ { ui.setupUi (this); - QString authortext = m_config->defaultName; + QString authortext = m_config->defaultName(); - if (not m_config->defaultUser.isEmpty()) - authortext.append (format (" [%1]", m_config->defaultUser)); + if (not m_config->defaultUser().isEmpty()) + authortext.append (format (" [%1]", m_config->defaultUser())); ui.author->setText (authortext); - ui.useCaLicense->setChecked (m_config->useCaLicense); + ui.useCaLicense->setChecked (m_config->useCaLicense()); } BFCStatement NewPartDialog::getWinding() const
--- a/src/editmodes/abstractEditMode.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/editmodes/abstractEditMode.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -183,7 +183,7 @@ void AbstractDrawMode::drawLength (QPainter &painter, const Vertex &v0, const Vertex &v1, const QPointF& v0p, const QPointF& v1p) const { - if (not m_config->drawLineLengths) + if (not m_config->drawLineLengths()) return; const QString label = QString::number ((v1 - v0).length()); @@ -230,7 +230,7 @@ if (withlengths) drawLength (painter, poly3d[i], poly3d[j], poly[i], poly[j]); - if (withangles and m_config->drawAngles) + if (withangles and m_config->drawAngles()) { QLineF l0 (poly[h], poly[i]), l1 (poly[i], poly[j]);
--- a/src/glCompiler.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/glCompiler.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -78,7 +78,7 @@ // ============================================================================= // GLCompiler::GLCompiler (GLRenderer* renderer) : - HierarchyElement (parent), + HierarchyElement (renderer), m_renderer (renderer) { needMerge(); @@ -161,13 +161,13 @@ if (poly.color == MainColor) { if (topobj->color() == MainColor) - qcol = GLRenderer::getMainColor(); + qcol = m_renderer->getMainColor(); else qcol = topobj->color().faceColor(); } else if (poly.color == EdgeColor) { - qcol = Luma (QColor (m_config->backgroundColor)) > 40 ? Qt::black : Qt::white; + qcol = Luma (QColor (m_config->backgroundColor())) > 40 ? Qt::black : Qt::white; } else { @@ -184,7 +184,7 @@ // The color was unknown. Use main color to make the polygon at least // not appear pitch-black. if (poly.num != 2 and poly.num != 5) - qcol = GLRenderer::getMainColor(); + qcol = m_renderer->getMainColor(); else qcol = Qt::black; @@ -207,7 +207,7 @@ if (blendAlpha != 0.0) { - QColor selcolor (m_config->selectColorBlend); + QColor selcolor (m_config->selectColorBlend()); double denom = blendAlpha + 1.0; qcol.setRed ((qcol.red() + (selcolor.red() * blendAlpha)) / denom); qcol.setGreen ((qcol.green() + (selcolor.green() * blendAlpha)) / denom);
--- a/src/glRenderer.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/glRenderer.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -29,7 +29,6 @@ #include <QTimer> #include <GL/glu.h> #include "main.h" -#include "configuration.h" #include "ldDocument.h" #include "glRenderer.h" #include "colors.h" @@ -104,7 +103,7 @@ HierarchyElement (parent) { m_isPicking = false; - m_camera = (ECamera) m_config->camera; + m_camera = (ECamera) m_config->camera(); m_drawToolTip = false; m_editmode = AbstractEditMode::createByType (this, EditModeType::Select); m_panning = false; @@ -195,7 +194,7 @@ glShadeModel (GL_SMOOTH); glEnable (GL_MULTISAMPLE); - if (m_config->antiAliasedLines) + if (m_config->antiAliasedLines()) { glEnable (GL_LINE_SMOOTH); glEnable (GL_POLYGON_SMOOTH); @@ -249,7 +248,7 @@ initializeOpenGLFunctions(); #endif setBackground(); - glLineWidth (m_config->lineThickness); + glLineWidth (m_config->lineThickness()); glLineStipple (1, 0x6666); setAutoFillBackground (false); setMouseTracking (true); @@ -296,12 +295,12 @@ // QColor GLRenderer::getMainColor() { - QColor col (m_config->mainColor); + QColor col (m_config->mainColor()); if (not col.isValid()) return QColor (0, 0, 0); - col.setAlpha (m_config->mainColorAlpha * 255.f); + col.setAlpha (m_config->mainColorAlpha() * 255.f); return col; } @@ -315,7 +314,7 @@ return; } - QColor col (m_config->backgroundColor); + QColor col (m_config->backgroundColor()); if (not col.isValid()) return; @@ -377,7 +376,7 @@ zoomAllToFit(); } - if (m_config->drawWireframe and not isPicking()) + if (m_config->drawWireframe() and not isPicking()) glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -431,7 +430,7 @@ } else { - if (m_config->bfcRedGreenView) + if (m_config->bfcRedGreenView()) { glEnable (GL_CULL_FACE); glCullFace (GL_BACK); @@ -444,7 +443,7 @@ } else { - EVBOComplement colors = (m_config->randomColors) ? VBOCM_RandomColors : VBOCM_NormalColors; + EVBOComplement colors = (m_config->randomColors()) ? VBOCM_RandomColors : VBOCM_NormalColors; drawVBOs (VBOSF_Triangles, colors, GL_TRIANGLES); drawVBOs (VBOSF_Quads, colors, GL_QUADS); } @@ -454,7 +453,7 @@ drawVBOs (VBOSF_CondLines, VBOCM_NormalColors, GL_LINES); glDisable (GL_LINE_STIPPLE); - if (m_config->drawAxes) + if (m_config->drawAxes()) { glBindBuffer (GL_ARRAY_BUFFER, m_axesVBO); glVertexPointer (3, GL_FLOAT, 0, NULL); @@ -480,9 +479,9 @@ void GLRenderer::drawVBOs (EVBOSurface surface, EVBOComplement colors, GLenum type) { // Filter this through some configuration options - if ((isOneOf (surface, VBOSF_Quads, VBOSF_Triangles) and m_config->drawSurfaces == false) or - (surface == VBOSF_Lines and m_config->drawEdgeLines == false) or - (surface == VBOSF_CondLines and m_config->drawConditionalLines == false)) + if ((isOneOf (surface, VBOSF_Quads, VBOSF_Triangles) and m_config->drawSurfaces() == false) or + (surface == VBOSF_Lines and m_config->drawEdgeLines() == false) or + (surface == VBOSF_CondLines and m_config->drawConditionalLines() == false)) { return; } @@ -895,7 +894,7 @@ return; m_camera = cam; - m_config->camera = (int) cam; + m_config->setCamera ((int) cam); m_window->updateEditModeActions(); } @@ -1077,14 +1076,14 @@ glDisable (GL_DITHER); // Use particularly thick lines while picking ease up selecting lines. - glLineWidth (qMax<double> (m_config->lineThickness, 6.5)); + glLineWidth (qMax<double> (m_config->lineThickness(), 6.5)); } else { glEnable (GL_DITHER); // Restore line thickness - glLineWidth (m_config->lineThickness); + glLineWidth (m_config->lineThickness()); } } @@ -1529,14 +1528,14 @@ // void GLRenderer::highlightCursorObject() { - if (not m_config->highlightObjectBelowCursor and objectAtCursor() == null) + if (not m_config->highlightObjectBelowCursor() and objectAtCursor() == null) return; LDObject* newObject = nullptr; LDObject* oldObject = objectAtCursor(); qint32 newIndex; - if (isCameraMoving() or not m_config->highlightObjectBelowCursor) + if (isCameraMoving() or not m_config->highlightObjectBelowCursor()) { newIndex = 0; }
--- a/src/glRenderer.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/glRenderer.h Mon Aug 31 20:50:12 2015 +0300 @@ -195,7 +195,7 @@ void updateOverlayObjects(); void zoomNotch (bool inward); - static QColor getMainColor(); + QColor getMainColor(); protected: void contextMenuEvent (QContextMenuEvent* ev);
--- a/src/ldDocument.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/ldDocument.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -22,7 +22,6 @@ #include <QTime> #include <QApplication> #include "main.h" -#include "configuration.h" #include "ldDocument.h" #include "miscallenous.h" #include "mainwindow.h" @@ -223,7 +222,7 @@ return relpath; // Try with just the LDraw path first - fullPath = format ("%1" DIRSLASH "%2", g_win->configBag()->lDrawPath, relpath); + fullPath = format ("%1" DIRSLASH "%2", g_win->configBag()->lDrawPath(), relpath); if (QFile::exists (fullPath)) return fullPath; @@ -232,7 +231,7 @@ { // Look in sub-directories: parts and p. Also look in net_downloadpath, since that's // where we download parts from the PT to. - QStringList dirs = { g_win->configBag()->lDrawPath, g_win->configBag()->downloadFilePath }; + QStringList dirs = { g_win->configBag()->lDrawPath(), g_win->configBag()->downloadFilePath() }; for (const QString& topdir : dirs) { for (const QString& subdir : QStringList ({ "parts", "p" })) @@ -572,7 +571,7 @@ // void AddRecentFile (QString path) { - QStringList& recentFiles = g_win->configBag()->recentFiles; + QStringList recentFiles = g_win->configBag()->recentFiles(); int idx = recentFiles.indexOf (path); // If this file already is in the list, pop it out. @@ -590,7 +589,8 @@ // Add the file recentFiles << path; - Config::Save(); + g_win->configBag()->setRecentFiles (recentFiles); + g_win->syncSettings(); g_win->updateRecentFilesMenu(); } @@ -669,7 +669,7 @@ unknowns << static_cast<LDError*> (obj)->fileReferenced(); } - if (g_win->configBag()->tryDownloadMissingFiles and not unknowns.isEmpty()) + if (g_win->configBag()->tryDownloadMissingFiles() and not unknowns.isEmpty()) { PartDownloader dl; @@ -1268,7 +1268,7 @@ // Possibly substitute with logoed studs: // stud.dat -> stud-logo.dat // stud2.dat -> stud-logo2.dat - if (g_win->configBag()->useLogoStuds and renderinline) + if (g_win->configBag()->useLogoStuds() and renderinline) { // Ensure logoed studs are loaded first LoadLogoStuds();
--- a/src/ldObject.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/ldObject.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -859,7 +859,7 @@ // QString PreferredLicenseText() { - return (g_win->configBag()->useCaLicense ? CALicenseText : ""); + return g_win->configBag()->useCaLicense() ? CALicenseText : ""; } // =============================================================================
--- a/src/ldpaths.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/ldpaths.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -12,7 +12,7 @@ void LDPaths::checkPaths() { - QString& pathconfig = m_config->lDrawPath; + QString pathconfig = m_config->lDrawPath(); if (not configurePaths (pathconfig)) { @@ -22,7 +22,7 @@ if (not m_dialog->exec()) Exit(); else - pathconfig = m_dialog->path(); + m_config->setLDrawPath (m_dialog->path()); } }
--- a/src/main.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/main.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -25,12 +25,10 @@ #include "mainwindow.h" #include "ldDocument.h" #include "miscallenous.h" -#include "configuration.h" #include "colors.h" #include "basics.h" #include "primitives.h" #include "glRenderer.h" -#include "configDialog.h" #include "dialogs.h" #include "crashCatcher.h" #include "ldpaths.h" @@ -42,7 +40,7 @@ const Vertex Origin (0.0f, 0.0f, 0.0f); const Matrix IdentityMatrix ({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); -ConfigOption (bool firstStart = true) +ConfigOption (bool FirstStart = true) // ============================================================================= // @@ -52,19 +50,6 @@ app.setOrganizationName (APPNAME); app.setApplicationName (APPNAME); initCrashCatcher(); - Config::Initialize(); - - // Load or create the configuration - if (not Config::Load()) - { - print ("Creating configuration file...\n"); - - if (Config::Save()) - print ("Configuration file successfully created.\n"); - else - Critical ("Failed to create configuration file!\n"); - } - MainWindow* win = new MainWindow; LDPaths* paths = new LDPaths (win); paths->checkPaths(); @@ -74,15 +59,6 @@ newFile(); win->show(); - // If this is the first start, get the user to configuration. Especially point - // them to the profile tab, it's the most important form to fill in. - if (win->configBag()->firstStart) - { - (new ConfigDialog (ConfigDialog::ProfileTab))->exec(); - win->configBag()->firstStart = false; - Config::Save(); - } - // Process the command line for (int arg = 1; arg < argc; ++arg) OpenMainModel (QString::fromLocal8Bit (argv[arg]));
--- a/src/main.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/main.h Mon Aug 31 20:50:12 2015 +0300 @@ -29,7 +29,6 @@ #include <QTextFormat> #include "macros.h" #include "version.h" -#include "configuration.h" #include "format.h" #include "hierarchyelement.h"
--- a/src/mainwindow.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/mainwindow.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -40,14 +40,13 @@ #include "glRenderer.h" #include "mainwindow.h" #include "ldDocument.h" -#include "configuration.h" #include "miscallenous.h" #include "colors.h" #include "editHistory.h" #include "radioGroup.h" #include "addObjectDialog.h" #include "messageLog.h" -#include "configuration.h" +#include "configDialog.h" #include "ui_mainwindow.h" #include "primitives.h" #include "editmodes/abstractEditMode.h" @@ -62,12 +61,14 @@ ConfigOption (bool listImplicitFiles = false) ConfigOption (QStringList hiddenToolbars) -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // MainWindow::MainWindow (QWidget* parent, Qt::WindowFlags flags) : QMainWindow (parent, flags), + m_configOptions (this), ui (*new Ui_MainWindow), - m_externalPrograms (nullptr) + m_externalPrograms (nullptr), + m_settings (makeSettings (this)) { g_win = this; ui.setupUi (this); @@ -111,7 +112,7 @@ updateRecentFilesMenu(); updateColorToolbar(); updateTitle(); - loadShortcuts (Config::SettingsObject()); + loadShortcuts(); setMinimumSize (300, 200); connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); connect (ui.ringToolHiRes, SIGNAL (clicked (bool)), this, SLOT (ringToolHiResClicked (bool))); @@ -133,8 +134,8 @@ { const QMetaObject* meta = toolset->metaObject(); - if (qobject_cast<ExtProgramToolset*> (meta)) - m_externalPrograms = meta; + if (qobject_cast<ExtProgramToolset*> (toolset)) + m_externalPrograms = static_cast<ExtProgramToolset*> (toolset); for (int i = 0; i < meta->methodCount(); ++i) { @@ -156,13 +157,22 @@ } } - for (QVariant const& toolbarname : m_configOptions.hiddenToolbars) + for (QVariant const& toolbarname : m_configOptions.hiddenToolbars()) { QToolBar* toolbar = findChild<QToolBar*> (toolbarname.toString()); if (toolbar != null) toolbar->hide(); } + + // If this is the first start, get the user to configuration. Especially point + // them to the profile tab, it's the most important form to fill in. + if (m_configOptions.firstStart()) + { + (new ConfigDialog (this, ConfigDialog::ProfileTab))->exec(); + m_configOptions.setFirstStart (false); + syncSettings(); + } } MainWindow::~MainWindow() @@ -170,7 +180,7 @@ g_win = null; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::slot_action() { @@ -192,7 +202,7 @@ endAction(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::endAction() { @@ -205,7 +215,7 @@ refresh(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::slot_lastSecondCleanup() { @@ -213,19 +223,19 @@ delete &ui; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateRecentFilesMenu() { // First, clear any items in the recent files menu -for (QAction * recent : m_recentFiles) + for (QAction* recent : m_recentFiles) delete recent; m_recentFiles.clear(); QAction* first = null; - for (const QVariant& it : m_configOptions.recentFiles) + for (const QVariant& it : m_configOptions.recentFiles()) { QString file = it.toString(); QAction* recent = new QAction (GetIcon ("open-recent"), file, this); @@ -237,13 +247,13 @@ } } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // QList<LDQuickColor> LoadQuickColorList() { QList<LDQuickColor> colors; - for (QString colorname : m_configOptions.quickColorToolbar.split (":")) + for (QString colorname : g_win->configBag()->quickColorToolbar().split (":")) { if (colorname == "|") colors << LDQuickColor::getSeparator(); @@ -259,7 +269,7 @@ return colors; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateColorToolbar() { @@ -292,17 +302,18 @@ updateGridToolBar(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateGridToolBar() { // Ensure that the current grid - and only the current grid - is selected. - ui.actionGridCoarse->setChecked (m_configOptions.grid == Grid::Coarse); - ui.actionGridMedium->setChecked (m_configOptions.grid == Grid::Medium); - ui.actionGridFine->setChecked (m_configOptions.grid == Grid::Fine); + int grid = m_configOptions.grid(); + ui.actionGridCoarse->setChecked (grid == Grid::Coarse); + ui.actionGridMedium->setChecked (grid == Grid::Medium); + ui.actionGridFine->setChecked (grid == Grid::Fine); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateTitle() { @@ -338,7 +349,7 @@ setWindowTitle (title); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // int MainWindow::deleteSelection() { @@ -355,7 +366,7 @@ return selCopy.size(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::buildObjList() { @@ -465,7 +476,7 @@ item->setBackground (QColor ("#AA0000")); item->setForeground (QColor ("#FFAA00")); } - else if (m_configOptions.colorizeObjectsList + else if (m_configOptions.colorizeObjectsList() and obj->isColored() and obj->color().isValid() and obj->color() != MainColor @@ -484,7 +495,7 @@ scrollToSelection(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::scrollToSelection() { @@ -495,7 +506,7 @@ ui.objectList->scrollToItem (obj->qObjListEntry); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::slot_selectionChanged() { @@ -534,7 +545,7 @@ R()->update(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::slot_recentFile() { @@ -542,7 +553,7 @@ OpenMainModel (qAct->text()); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::slot_quickColor() { @@ -574,7 +585,7 @@ refresh(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // int MainWindow::getInsertionPoint() { @@ -586,7 +597,7 @@ return CurrentDocument()->getObjectCount(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::doFullRefresh() { @@ -594,7 +605,7 @@ m_renderer->hardRefresh(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::refresh() { @@ -602,7 +613,7 @@ m_renderer->update(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateSelection() { @@ -645,7 +656,7 @@ g_isSelectionLocked = false; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // LDColor MainWindow::getSelectedColor() { @@ -666,7 +677,7 @@ return result; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::closeEvent (QCloseEvent* ev) { @@ -678,20 +689,21 @@ } // Save the toolbar set - m_configOptions.hiddenToolbars.clear(); + QStringList hiddenToolbars; for (QToolBar* toolbar : findChildren<QToolBar*>()) { if (toolbar->isHidden()) - m_configOptions.hiddenToolbars << toolbar->objectName(); + hiddenToolbars << toolbar->objectName(); } // Save the configuration before leaving. - Config::Save(); + m_configOptions.setHiddenToolbars (hiddenToolbars); + syncSettings(); ev->accept(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::spawnContextMenu (const QPoint pos) { @@ -757,7 +769,7 @@ contextMenu->exec (pos); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::deleteByColor (LDColor color) { @@ -775,7 +787,7 @@ obj->destroy(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateEditModeActions() { @@ -788,7 +800,7 @@ ui.actionModeLinePath->setChecked (mode == EditModeType::LinePath); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::slot_editObject (QListWidgetItem* listitem) { @@ -802,7 +814,7 @@ } } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // bool MainWindow::save (LDDocument* doc, bool saveAs) { @@ -819,7 +831,7 @@ name = doc->name(); name.replace ("\\", "/"); - path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), + path = QFileDialog::getSaveFileName (this, tr ("Save As"), name, tr ("LDraw files (*.dat *.ldr)")); if (path.isEmpty()) @@ -844,7 +856,7 @@ QString message = format (tr ("Failed to save to %1: %2"), path, strerror (errno)); // Tell the user the save failed, and give the option for saving as with it. - QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win); + QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, this); // Add a save-as button QPushButton* saveAsBtn = new QPushButton (tr ("Save As")); @@ -870,21 +882,21 @@ g_win->spawnContextMenu (ev->globalPos()); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // QPixmap GetIcon (QString iconName) { return (QPixmap (format (":/icons/%1.png", iconName))); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // bool Confirm (const QString& message) { return Confirm (MainWindow::tr ("Confirm"), message); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // bool Confirm (const QString& title, const QString& message) { @@ -892,7 +904,7 @@ (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void Critical (const QString& message) { @@ -900,7 +912,7 @@ (QMessageBox::Close), QMessageBox::Close); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // QIcon MakeColorIcon (LDColor colinfo, const int size) { @@ -912,8 +924,8 @@ if (colinfo == MainColor) { // Use the user preferences for main color here - col = g_win->configBag()->mainColor; - col.setAlphaF (g_win->configBag()->mainColorAlpha); + col = g_win->configBag()->mainColor(); + col.setAlphaF (g_win->configBag()->mainColorAlpha()); } // Paint the icon border @@ -927,7 +939,7 @@ return QIcon (QPixmap::fromImage (img)); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MakeColorComboBox (QComboBox* box) { @@ -958,7 +970,7 @@ } } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateDocumentList() { @@ -978,7 +990,7 @@ m_updatingTabs = false; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateDocumentListItem (LDDocument* doc) { @@ -1006,7 +1018,7 @@ m_updatingTabs = oldUpdatingTabs; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // // A file is selected from the list of files on the left of the screen. Find out // which file was picked and change to it. @@ -1037,7 +1049,7 @@ LDDocument::setCurrent (file); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::refreshObjectList() { @@ -1053,7 +1065,7 @@ buildObjList(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updateActions() { @@ -1065,24 +1077,24 @@ ui.actionRedo->setEnabled (pos < (long) his->getSize() - 1); } - ui.actionWireframe->setChecked (m_configOptions.drawWireframe); - ui.actionAxes->setChecked (m_configOptions.drawAxes); - ui.actionBfcView->setChecked (m_configOptions.bfcRedGreenView); - ui.actionRandomColors->setChecked (m_configOptions.randomColors); - ui.actionDrawAngles->setChecked (m_configOptions.drawAngles); - ui.actionDrawSurfaces->setChecked (m_configOptions.drawSurfaces); - ui.actionDrawEdgeLines->setChecked (m_configOptions.drawEdgeLines); - ui.actionDrawConditionalLines->setChecked (m_configOptions.drawConditionalLines); + ui.actionWireframe->setChecked (m_configOptions.drawWireframe()); + ui.actionAxes->setChecked (m_configOptions.drawAxes()); + ui.actionBfcView->setChecked (m_configOptions.bfcRedGreenView()); + ui.actionRandomColors->setChecked (m_configOptions.randomColors()); + ui.actionDrawAngles->setChecked (m_configOptions.drawAngles()); + ui.actionDrawSurfaces->setChecked (m_configOptions.drawSurfaces()); + ui.actionDrawEdgeLines->setChecked (m_configOptions.drawEdgeLines()); + ui.actionDrawConditionalLines->setChecked (m_configOptions.drawConditionalLines()); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::updatePrimitives() { PopulatePrimitives (ui.primitives); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::closeTab (int tabindex) { @@ -1094,33 +1106,37 @@ doc->dismiss(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // -void MainWindow::loadShortcuts (QSettings const* settings) +void MainWindow::loadShortcuts() { for (QAction* act : findChildren<QAction*>()) { - QKeySequence seq = settings->value ("shortcut_" + act->objectName(), act->shortcut()).value<QKeySequence>(); + QKeySequence seq = m_settings->value ("shortcut_" + act->objectName(), act->shortcut()).value<QKeySequence>(); act->setShortcut (seq); } + + m_settings->deleteLater(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // -void MainWindow::saveShortcuts (QSettings* settings) +void MainWindow::saveShortcuts() { applyToActions ([&](QAction* act) { QString const key = "shortcut_" + act->objectName(); if (g_defaultShortcuts[act] != act->shortcut()) - settings->setValue (key, act->shortcut()); + m_settings->setValue (key, act->shortcut()); else - settings->remove (key); + m_settings->remove (key); }); + + m_settings->deleteLater(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::applyToActions (std::function<void(QAction*)> function) { @@ -1131,35 +1147,35 @@ } } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // QTreeWidget* MainWindow::getPrimitivesTree() const { return ui.primitives; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // QKeySequence MainWindow::defaultShortcut (QAction* act) // [static] { return g_defaultShortcuts[act]; } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // bool MainWindow::ringToolHiRes() const { return ui.ringToolHiRes->isChecked(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // int MainWindow::ringToolSegments() const { return ui.ringToolSegments->value(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::ringToolHiResClicked (bool checked) { @@ -1175,7 +1191,7 @@ } } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // void MainWindow::circleToolSegmentsChanged() { @@ -1185,36 +1201,29 @@ ui.ringToolSegmentsLabel->setText (format ("%1 / %2", numerator, denominator)); } - -// -// Where is the configuration file located at? -// -QString MainWindow::configFilePath (QString file) -{ - return Config::DirectoryPath() + DIRSLASH + file; -} - -// -// Directory of the configuration file. -// -QString Config::DirectoryPath() -{ - QSettings* settings = SettingsObject(); - QString result = Dirname (settings->fileName()); - delete settings; - return result; -} - +// --------------------------------------------------------------------------------------------------------------------- // // Accessor to the settings object // -QSettings* Config::SettingsObject() +QSettings* MainWindow::makeSettings (QObject* parent) { QString path = qApp->applicationDirPath() + "/" UNIXNAME ".ini"; - return new QSettings (path, QSettings::IniFormat); + return new QSettings (path, QSettings::IniFormat, parent); } -// ============================================================================= +void MainWindow::syncSettings() +{ + m_settings->sync(); + m_settings->deleteLater(); +} + +QVariant MainWindow::getConfigValue (QString name) +{ + QVariant value = m_settings->value (name, m_configOptions.defaultValueByName (name)); + return value; +} + +// --------------------------------------------------------------------------------------------------------------------- // QImage GetImageFromScreencap (uchar* data, int w, int h) { @@ -1222,26 +1231,28 @@ return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // LDQuickColor::LDQuickColor (LDColor color, QToolButton* toolButton) : m_color (color), m_toolButton (toolButton) {} -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // LDQuickColor LDQuickColor::getSeparator() { return LDQuickColor (LDColor::nullColor(), null); } -// ============================================================================= +// --------------------------------------------------------------------------------------------------------------------- // bool LDQuickColor::isSeparator() const { return color() == LDColor::nullColor(); } +// --------------------------------------------------------------------------------------------------------------------- +// void PopulatePrimitives (QTreeWidget* tw, QString const& selectByDefault) { tw->clear();
--- a/src/mainwindow.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/mainwindow.h Mon Aug 31 20:50:12 2015 +0300 @@ -24,7 +24,6 @@ #include <QRadioButton> #include <QTreeWidget> #include <QMetaMethod> -#include "configuration.h" #include "ldObject.h" #include "colors.h" #include "configurationvaluebag.h" @@ -157,19 +156,17 @@ void endAction(); QTreeWidget* getPrimitivesTree() const; static QKeySequence defaultShortcut (QAction* act); - void loadShortcuts (QSettings const* settings); - void saveShortcuts (QSettings* settings); + void loadShortcuts(); + void saveShortcuts(); void applyToActions (std::function<void(QAction*)> function); bool ringToolHiRes() const; int ringToolSegments() const; - ConfigurationValueBag* configBag() const { return m_configOptions; } - - template<typename T> - auto& config (T key) - { - return m_configOptions.get (key); - } + ConfigurationValueBag* configBag() { return &m_configOptions; } + class QSettings* makeSettings (QObject* parent = nullptr); + void syncSettings(); + QVariant getConfigValue (QString name); + class QSettings* getSettings() { return m_settings; } class ExtProgramToolset* externalPrograms() { @@ -203,6 +200,7 @@ QVector<Toolset*> m_toolsets; QMap<QAction*, ToolInfo> m_toolmap; class ExtProgramToolset* m_externalPrograms; + class QSettings* m_settings; private slots: void slot_selectionChanged();
--- a/src/miscallenous.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/miscallenous.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -95,16 +95,32 @@ ConfigOption (int RotationPointType = 0) ConfigOption (Vertex CustomRotationPoint = Origin) -const GridData Grids[3] = +float gridCoordinateSnap() { - { "Coarse", cfg::GRID_COARSE_COORDINATE_SNAP, cfg::GRID_COARSE_ANGLE_SNAP }, - { "Medium", cfg::GRID_MEDIUM_COORDINATE_SNAP, cfg::GRID_MEDIUM_ANGLE_SNAP }, - { "Fine", cfg::GRID_FINE_COORDINATE_SNAP, cfg::GRID_FINE_ANGLE_SNAP }, -}; + ConfigurationValueBag* config = g_win->configBag(); + + switch (config->grid()) + { + case Grid::Coarse: return config->gridCoarseCoordinateSnap(); + case Grid::Medium: return config->gridMediumCoordinateSnap(); + case Grid::Fine: return config->gridFineCoordinateSnap(); + } + + return 1.0f; +} -const GridData& CurrentGrid() +float gridAngleSnap() { - return Grids[g_win->configBag()->grid]; + ConfigurationValueBag* config = g_win->configBag(); + + switch (config->grid()) + { + case Grid::Coarse: return config->gridCoarseAngleSnap(); + case Grid::Medium: return config->gridMediumAngleSnap(); + case Grid::Fine: return config->gridFineAngleSnap(); + } + + return 45.0f; } // ============================================================================= @@ -113,7 +129,7 @@ // double Grid::Snap (double value, const Grid::Config type) { - double snapvalue = g_win->config ((type == Coordinate) ? CurrentGrid().coordinateSnap : CurrentGrid().angleSnap); + double snapvalue = (type == Coordinate) ? gridCoordinateSnap() : gridAngleSnap(); double mult = floor (qAbs<double> (value / snapvalue)); double out = mult * snapvalue; @@ -158,7 +174,7 @@ // Vertex GetRotationPoint (const LDObjectList& objs) { - switch (RotationPoint (g_win->configBag()->rotationPointType)) + switch (RotationPoint (g_win->configBag()->rotationPointType())) { case RotationPoint::ObjectOrigin: { @@ -180,7 +196,7 @@ return Origin; case RotationPoint::CustomPoint: - return g_win->configBag()->customRotationPoint; + return g_win->configBag()->customRotationPoint(); case RotationPoint::NumValues: break; @@ -197,7 +213,7 @@ Ui::RotPointUI ui; ui.setupUi (dlg); - switch (RotationPoint (g_win->configBag()->rotationPointType)) + switch (RotationPoint (g_win->configBag()->rotationPointType())) { case RotationPoint::ObjectOrigin: ui.objectPoint->setChecked (true); @@ -215,7 +231,7 @@ break; } - Vertex& custompoint = g_win->configBag()->customRotationPoint; + Vertex custompoint = g_win->configBag()->customRotationPoint(); ui.customX->setValue (custompoint.x()); ui.customY->setValue (custompoint.y()); ui.customZ->setValue (custompoint.z()); @@ -223,14 +239,15 @@ if (not dlg->exec()) return; - g_win->configBag()->rotationPointType = + g_win->configBag()->setRotationPointType (int ( (ui.objectPoint->isChecked()) ? RotationPoint::ObjectOrigin : (ui.worldPoint->isChecked()) ? RotationPoint::WorldOrigin : - RotationPoint::CustomPoint; + RotationPoint::CustomPoint)); custompoint.setX (ui.customX->value()); custompoint.setY (ui.customY->value()); custompoint.setZ (ui.customZ->value()); + g_win->configBag()->setCustomRotationPoint (custompoint); } // =============================================================================
--- a/src/miscallenous.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/miscallenous.h Mon Aug 31 20:50:12 2015 +0300 @@ -19,7 +19,6 @@ #pragma once #include <QVector> #include <functional> -#include "configuration.h" #include "main.h" #include "basics.h" #include "configurationvaluebag.h" @@ -44,15 +43,8 @@ QString Join (QList<StringFormatArg> vals, QString delim = " "); // Grid stuff -struct GridData -{ - const char* name; - CONFIG_KEY_TYPE(float) coordinateSnap; - CONFIG_KEY_TYPE(float) angleSnap; -}; - -extern const GridData Grids[3]; -const GridData& CurrentGrid(); +float gridCoordinateSnap(); +float gridAngleSnap(); // ============================================================================= enum class RotationPoint
--- a/src/partDownloader.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/partDownloader.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -53,7 +53,7 @@ // QString PartDownloader::getDownloadPath() { - QString path = m_config->downloadFilePath; + QString path = m_config->downloadFilePath(); if (DIRSLASH[0] != '/') path.replace (DIRSLASH, "/"); @@ -109,7 +109,7 @@ if (path.isEmpty()) return false; - m_config->downloadFilePath = path; + m_config->setDownloadFilePath (path); } return true; @@ -145,7 +145,7 @@ dest = dest.simplified(); // If the user doesn't want us to guess, stop right here. - if (not m_config->guessDownloadPaths) + if (not m_config->guessDownloadPaths()) return; // Ensure .dat extension @@ -254,7 +254,7 @@ modifyDestination (dest); - if (QFile::exists (PartDownloader::getDownloadPath() + DIRSLASH + dest)) + if (QFile::exists (getDownloadPath() + DIRSLASH + dest)) { const QString overwritemsg = format (tr ("%1 already exists in download directory. Overwrite?"), dest); if (not Confirm (tr ("Overwrite?"), overwritemsg)) @@ -332,7 +332,7 @@ for (LDDocument* f : m_files) f->reloadAllSubfiles(); - if (m_config->autoCloseDownloadDialog and not failed) + if (m_config->autoCloseDownloadDialog() and not failed) { // Close automatically if desired. accept(); @@ -372,7 +372,7 @@ m_prompt (parent), m_url (url), m_destinaton (dest), - m_filePath (PartDownloader::getDownloadPath() + DIRSLASH + dest), + m_filePath (parent->getDownloadPath() + DIRSLASH + dest), m_networkManager (new QNetworkAccessManager), m_isFirstUpdate (true), m_isPrimary (primary),
--- a/src/partDownloader.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/partDownloader.h Mon Aug 31 20:50:12 2015 +0300 @@ -79,7 +79,7 @@ void setSource (Source src); void modifyDestination (QString& dest) const; - static QString getDownloadPath(); + QString getDownloadPath(); static void staticBegin(); public slots:
--- a/src/primitives.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/primitives.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -47,12 +47,17 @@ return g_activeScanner; } +QString getPrimitivesCfgPath() +{ + return qApp->applicationDirPath() + DIRSLASH "prims.cfg"; +} + // ============================================================================= // void LoadPrimitives() { // Try to load prims.cfg - QFile conf (Config::FilePath ("prims.cfg")); + QFile conf (getPrimitivesCfgPath()); if (not conf.open (QIODevice::ReadOnly)) { @@ -160,7 +165,7 @@ if (m_i == m_files.size()) { // Done with primitives, now save to a config file - QString path = Config::FilePath ("prims.cfg"); + QString path = getPrimitivesCfgPath(); QFile conf (path); if (not conf.open (QIODevice::WriteOnly | QIODevice::Text)) @@ -279,11 +284,7 @@ delete cat; g_PrimitiveCategories.clear(); - QString path = Config::DirectoryPath() + "primregexps.cfg"; - - if (not QFile::exists (path)) - path = ":/data/primitive-categories.cfg"; - + QString path = ":/data/primitive-categories.cfg"; QFile f (path); if (not f.open (QIODevice::ReadOnly)) @@ -618,10 +619,10 @@ QString author = APPNAME; QString license = ""; - if (not g_win->configBag()->defaultName.isEmpty()) + if (not g_win->configBag()->defaultName().isEmpty()) { license = PreferredLicenseText(); - author = format ("%1 [%2]", g_win->configBag()->defaultName, g_win->configBag()->defaultUser); + author = format ("%1 [%2]", g_win->configBag()->defaultName(), g_win->configBag()->defaultUser()); } LDObjectList objs;
--- a/src/toolsets/algorithmtoolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/algorithmtoolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -158,14 +158,14 @@ Vertex v = mo->position(); Matrix t = mo->transform(); - v.apply ([](Axis, double& a) + v.apply ([&](Axis, double& a) { - RoundToDecimals (a, m_config->roundPositionPrecision); + RoundToDecimals (a, m_config->roundPositionPrecision()); }); - ApplyToMatrix (t, [](int, double& a) + ApplyToMatrix (t, [&](int, double& a) { - RoundToDecimals (a, m_config->roundMatrixPrecision); + RoundToDecimals (a, m_config->roundMatrixPrecision()); }); mo->setPosition (v); @@ -177,9 +177,9 @@ for (int i = 0; i < obj->numVertices(); ++i) { Vertex v = obj->vertex (i); - v.apply ([](Axis, double& a) + v.apply ([&](Axis, double& a) { - RoundToDecimals (a, m_config->roundPositionPrecision); + RoundToDecimals (a, m_config->roundPositionPrecision()); }); obj->setVertex (i, v); num += 3; @@ -332,7 +332,7 @@ QDialog* dlg = new QDialog; Ui_AddHistoryLine* ui = new Ui_AddHistoryLine; ui->setupUi (dlg); - ui->m_username->setText (m_config->defaultUser); + ui->m_username->setText (m_config->defaultUser()); ui->m_date->setDate (QDate::currentDate()); ui->m_comment->setFocus(); @@ -377,13 +377,12 @@ { bool ok; int segments = QInputDialog::getInt (m_window, APPNAME, "Amount of segments:", - m_window->config (m_config->splitLinesSegments), 0, - std::numeric_limits<int>::max(), 1, &ok); + m_config->splitLinesSegments(), 0, std::numeric_limits<int>::max(), 1, &ok); if (not ok) return; - m_config->splitLinesSegments = segments; + m_config->setSplitLinesSegments (segments); for (LDObject* obj : Selection()) { @@ -544,7 +543,7 @@ LDObjectList objs; objs << LDSpawn<LDComment> (subtitle); objs << LDSpawn<LDComment> ("Name: "); // This gets filled in when the subfile is saved - objs << LDSpawn<LDComment> (format ("Author: %1 [%2]", m_config->defaultName, m_config->defaultUser)); + objs << LDSpawn<LDComment> (format ("Author: %1 [%2]", m_config->defaultName(), m_config->defaultUser())); objs << LDSpawn<LDComment> ("!LDRAW_ORG Unofficial_Subpart"); if (not license.isEmpty())
--- a/src/toolsets/basictoolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/basictoolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -208,7 +208,7 @@ LDColor defaultcol = m_window->getSelectedColor(); // Show the dialog to the user now and ask for a color. - if (ColorSelector::selectColor (color, defaultcol, m_window)) + if (ColorSelector::selectColor (m_window, color, defaultcol)) { for (LDObject* obj : objs) {
--- a/src/toolsets/extprogramtoolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/extprogramtoolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -24,9 +24,9 @@ #include <QCheckBox> #include <QComboBox> #include <QGridLayout> +#include <QSettings> #include <QFileInfo> #include "../main.h" -#include "../configuration.h" #include "../miscallenous.h" #include "../mainwindow.h" #include "../ldDocument.h" @@ -60,23 +60,11 @@ Toolset (parent) { extProgramInfo[Isecalc].name = "Isecalc"; - extProgramInfo[Isecalc].path = &m_config->isecalcPath; - extProgramInfo[Isecalc].wine = &m_config->isecalcUsesWine; extProgramInfo[Intersector].name = "Intersector"; - extProgramInfo[Intersector].path = &m_config->intersectorPath; - extProgramInfo[Intersector].wine = &m_config->intersectorUsesWine; extProgramInfo[Coverer].name = "Coverer"; - extProgramInfo[Coverer].path = &m_config->covererPath; - extProgramInfo[Coverer].wine = &m_config->covererUsesWine; extProgramInfo[Ytruder].name = "Ytruder"; - extProgramInfo[Ytruder].path = &m_config->ytruderPath; - extProgramInfo[Ytruder].wine = &m_config->ytruderUsesWine; extProgramInfo[Rectifier].name = "Rectifier"; - extProgramInfo[Rectifier].path = &m_config->rectifierPath; - extProgramInfo[Rectifier].wine = &m_config->rectifierUsesWine; extProgramInfo[Edger2].name = "Edger2"; - extProgramInfo[Edger2].path = &m_config->edger2Path; - extProgramInfo[Edger2].wine = &m_config->edger2UsesWine; } bool ExtProgramToolset::makeTempFile (QTemporaryFile& tmp, QString& fname) @@ -98,14 +86,24 @@ #endif } -bool& ExtProgramToolset::getWineSetting (ExtProgramType program) +bool ExtProgramToolset::getWineSetting (ExtProgramType program) { - return *extProgramInfo[program].wine; + return m_window->getConfigValue (externalProgramName (program) + "UsesWine").toBool(); } QString ExtProgramToolset::getPathSetting (ExtProgramType program) { - return *extProgramInfo[program].path; + return m_window->getConfigValue (externalProgramName (program) + "Path").toString(); +} + +void ExtProgramToolset::setPathSetting (ExtProgramType program, QString value) +{ + m_window->getSettings()->setValue (externalProgramName (program) + "Path", QVariant::fromValue (value)); +} + +void ExtProgramToolset::setWineSetting (ExtProgramType program, bool value) +{ + m_window->getSettings()->setValue (externalProgramName (program) + "UsesWine", QVariant::fromValue (value)); } QString ExtProgramToolset::externalProgramName (ExtProgramType program) @@ -113,18 +111,18 @@ return extProgramInfo[program].name; } -QString ExtProgramToolset::checkExtProgramPath(ExtProgramType program) +bool ExtProgramToolset::checkExtProgramPath (ExtProgramType program) { - QString& path = getPathSetting (program); + QString path = getPathSetting (program); if (not path.isEmpty()) return true; - ExtProgPathPrompt* dlg = new ExtProgPathPrompt (externalProgramName (program)); + ExtProgPathPrompt* dialog = new ExtProgPathPrompt (externalProgramName (program)); - if (dlg->exec() and not dlg->getPath().isEmpty()) + if (dialog->exec() and not dialog->getPath().isEmpty()) { - path = dlg->getPath(); + setPathSetting (program, dialog->getPath()); return true; } @@ -392,12 +390,12 @@ outDATName }); - WriteSelection (inDATName); + writeSelection (inDATName); if (not runExtProgram (Ytruder, argv)) return; - InsertOutput (outDATName, false, {}); + insertOutput (outDATName, false, {}); } // ============================================================================= @@ -437,12 +435,12 @@ outDATName }); - WriteSelection (inDATName); + writeSelection (inDATName); if (not runExtProgram (Rectifier, argv)) return; - InsertOutput (outDATName, true, {}); + insertOutput (outDATName, true, {}); } // =============================================================================
--- a/src/toolsets/extprogramtoolset.h Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/extprogramtoolset.h Mon Aug 31 20:50:12 2015 +0300 @@ -35,12 +35,12 @@ struct ExtProgramInfo { QString name; - QString* path; - bool* wine; }; class ExtProgramToolset : public Toolset { + Q_OBJECT + public: ExtProgramToolset (MainWindow* parent); @@ -50,12 +50,17 @@ Q_INVOKABLE void isecalc(); Q_INVOKABLE void rectifier(); Q_INVOKABLE void ytruder(); + + bool programUsesWine (ExtProgramType program); + QString externalProgramName (ExtProgramType program); + QString getPathSetting (ExtProgramType program); + bool getWineSetting (ExtProgramType program); + void setPathSetting (ExtProgramType program, QString value); + void setWineSetting (ExtProgramType program, bool value); private: - QString externalProgramName (ExtProgramType program); - bool programUsesWine (ExtProgramType program); - QString checkExtProgramPath (ExtProgramType program); - bool makeTempFile (QTemporaryFile& tmp, QString& fname); + bool checkExtProgramPath(ExtProgramType program); + bool makeTempFile (class QTemporaryFile& tmp, QString& fname); bool runExtProgram (ExtProgramType prog, QString argvstr); QString errorCodeString (ExtProgramType program, class QProcess& process); void insertOutput (QString fname, bool replace, QList<LDColor> colorsToReplace); @@ -63,8 +68,6 @@ void writeObjects (const LDObjectList& objects, QFile& f); void writeObjects (const LDObjectList& objects, QString fname); void writeSelection (QString fname); - bool& getWineSetting (ExtProgramType program); - QString getPathSetting (ExtProgramType program); ExtProgramInfo extProgramInfo[NumExternalPrograms]; };
--- a/src/toolsets/filetoolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/filetoolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -99,7 +99,10 @@ void FileToolset::setLDrawPath() { - (new LDrawPathDialog (m_config->ldrawPath, true))->exec(); + LDrawPathDialog* dialog = new LDrawPathDialog (m_config->lDrawPath(), true); + + if (dialog->exec()) + m_config->setLDrawPath (dialog->path()); } void FileToolset::exit()
--- a/src/toolsets/movetoolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/movetoolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -44,26 +44,26 @@ void MoveToolset::gridCoarse() { - m_config->grid = Grid::Coarse; + m_config->setGrid (Grid::Coarse); m_window->updateGridToolBar(); } void MoveToolset::gridMedium() { - m_config->grid = Grid::Medium; + m_config->setGrid (Grid::Medium); m_window->updateGridToolBar(); } void MoveToolset::gridFine() { - m_config->grid = Grid::Fine; + m_config->setGrid (Grid::Fine); m_window->updateGridToolBar(); } void MoveToolset::moveObjects (Vertex vect) { // Apply the grid values - vect *= m_window->config (CurrentGrid().coordinateSnap); + vect *= gridCoordinateSnap(); for (LDObject* obj : Selection()) obj->move (vect); @@ -101,7 +101,7 @@ double MoveToolset::getRotateActionAngle() { - return (Pi * m_window->config (CurrentGrid().angleSnap)) / 180; + return (Pi * gridAngleSnap()) / 180; } void MoveToolset::rotateXPos()
--- a/src/toolsets/toolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/toolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -27,8 +27,7 @@ Toolset::Toolset (MainWindow* parent) : QObject (parent), - HierarchyElement (parent), - m_window (parent) {} + HierarchyElement (parent) {} QVector<Toolset*> Toolset::createToolsets (MainWindow* parent) {
--- a/src/toolsets/viewtoolset.cpp Mon Aug 31 04:57:16 2015 +0300 +++ b/src/toolsets/viewtoolset.cpp Mon Aug 31 20:50:12 2015 +0300 @@ -126,7 +126,7 @@ void ViewToolset::axes() { - m_config->drawAxes = not m_config->drawAxes; + m_config->setDrawAxes (not m_config->drawAxes()); m_window->updateActions(); m_window->R()->update(); } @@ -151,7 +151,7 @@ void ViewToolset::wireframe() { - m_config->drawWireframe = not m_config->drawWireframe; + m_config->setDrawWireframe (not m_config->drawWireframe()); m_window->R()->refresh(); } @@ -173,7 +173,7 @@ void ViewToolset::drawAngles() { - m_config->drawAngles = not m_config->drawAngles; + m_config->setDrawAngles (not m_config->drawAngles()); m_window->R()->refresh(); } @@ -242,10 +242,10 @@ void ViewToolset::bfcView() { - m_config->bfcRedGreenView = not m_config->bfcRedGreenView; + m_config->setBfcRedGreenView (not m_config->bfcRedGreenView()); - if (m_config->bfcRedGreenView) - m_config->randomColors = false; + if (m_config->bfcRedGreenView()) + m_config->setRandomColors (false); m_window->updateActions(); m_window->R()->refresh(); @@ -273,10 +273,10 @@ void ViewToolset::randomColors() { - m_config->randomColors = not m_config->randomColors; + m_config->setRandomColors (not m_config->randomColors()); - if (m_config->randomColors) - m_config->bfcRedGreenView = false; + if (m_config->randomColors()) + m_config->setBfcRedGreenView (false); m_window->updateActions(); m_window->R()->refresh(); @@ -284,18 +284,18 @@ void ViewToolset::drawSurfaces() { - m_config->drawSurfaces = not m_config->drawSurfaces; + m_config->setDrawSurfaces (not m_config->drawSurfaces()); m_window->updateActions(); } void ViewToolset::drawEdgeLines() { - m_config->drawEdgeLines = not m_config->drawEdgeLines; + m_config->setDrawEdgeLines (not m_config->drawEdgeLines()); m_window->updateActions(); } void ViewToolset::drawConditionalLines() { - m_config->drawConditionalLines = not m_config->drawConditionalLines; + m_config->setDrawConditionalLines (not m_config->drawConditionalLines()); m_window->updateActions(); } \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/caseconversions.py Mon Aug 31 20:50:12 2015 +0300 @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# coding: utf-8 + +''' +Provides facilities to converting identifier cases. +''' + +# +# Copyright 2015 Teemu Piippo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +import string +import re + +def to_one_case (name, tolower): + ''' + Convers name to either all uppercase or all lowercase (depending on the truth value of tolower), using underscores + as delimiters. + ''' + result = "" + targetSet = (string.ascii_lowercase if tolower else string.ascii_uppercase) + string.digits + inverseSet = (string.ascii_uppercase if tolower else string.ascii_lowercase) + isUnderscorable = lambda ch: ch in string.ascii_uppercase \ + or ch in string.whitespace or ch in string.punctuation + previousWasUnderscorable = isUnderscorable (name[0]) + + for ch in name: + if isUnderscorable (ch) and result != "" and not previousWasUnderscorable: + result += "_" + + if ch in inverseSet: + result += (ch.lower() if tolower else ch.upper()) + elif ch in targetSet: + result += ch + previousWasUnderscorable = isUnderscorable (ch) + + return result + +def to_camel_case (name, java = False): + ''' + Converts name to camelcase. If java is False, the first letter will be lowercase, otherwise it will be uppercase. + ''' + result = "" + wantUpperCase = False + + # If it's all uppercase, make it all lowercase so that this algorithm can digest it + if name == name.upper(): + name = name.lower() + + for ch in name: + if ch == '_': + wantUpperCase = True + continue + + if wantUpperCase: + if ch in string.ascii_lowercase: + ch = ch.upper() + wantUpperCase = False + + result += ch + + if java: + match = re.match (r'^([A-Z]+)([A-Z].+)$', result) + if match: + result = match.group (1).lower() + match.group (2) + else: + result = result[0].lower() + result[1:] + else: + result = result[0].upper() + result[1:] + return result + +case_styles = { + 'lower': lambda name: to_one_case (name, tolower=True), + 'upper': lambda name: to_one_case (name, tolower=False), + 'camel': lambda name: to_camel_case (name, java=False), + 'java': lambda name: to_camel_case (name, java=True), +} + +def convert_case (name, style): + ''' + Converts name to the given style. Style may be one of: + - 'lower': 'foo_barBaz' -> 'foo_bar_baz' + - 'upper': 'foo_barBaz' -> 'FOO_BAR_BAZ' + - 'camel': 'foo_barBaz' -> 'FooBarBaz' + - 'java': 'foo_barBaz' -> 'fooBarBaz' + ''' + try: + stylefunc = case_styles[style] + except KeyError: + validstyles = ', '.join (sorted (case_styles.keys())) + raise ValueError ('Unknown style "%s", should be one of: %s' % (style, validstyles)) + else: + return stylefunc (name) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/configcollector.py Mon Aug 31 20:50:12 2015 +0300 @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# Copyright 2015 Teemu Piippo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +import argparse +import caseconversions +import collections +import outputfile +import re +from pprint import pprint + +passbyvalue = {'int', 'bool', 'float', 'double' } + +class ConfigCollector (object): + def __init__ (self, args): + self.pattern = re.compile (r'\s*ConfigOption\s*\((.+)\)\s*') + self.declpattern = re.compile (r'^([A-Za-z0-9,<>\[\]\(\)\{\}\s]+)\s+(\w+)(\s*=\s*(.+))?$') + self.decls = [] + self.qttypes = set() + self.args = args + + def collect (self, filenames): + for filename in filenames: + with open (filename, 'r') as fp: + lines = fp.read().splitlines() + + for line in lines: + matches = self.pattern.findall (line) + for match in matches: + match = match.strip() + declarations = self.declpattern.findall (match) + for decl in declarations: + self.add_config_declaration (decl) + + self.decls.sort (key=lambda x: x['name'].upper()) + + def add_config_declaration (self, decl): + decltype, declname, junk, decldefault = decl + if not decldefault: + if decltype == 'int': + decldefault = '0' + elif decltype == 'float': + decldefault = '0.0f' + elif decltype == 'double': + decldefault = '0.0' + elif decltype == 'bool': + raise TypeError ('bool entries must provide a default value') + else: + decldefault = decltype + '()' + + self.decls.append (dict (name=declname, type=decltype, default=decldefault)) + + # Take note of any Qt types we may want to #include in our source file (we'll need to #include them). + self.qttypes.update (re.findall (r'(Q[A-Za-z]+)', decltype)) + + def make_config_key_type (self, basetype): + result = 'ConfigTypeKey_' + basetype + result = re.sub (r'[^\w]+', '_', result) + return result + + def make_enums (self): + self.enums = collections.OrderedDict() + + for decl in self.decls: + enumname = self.make_config_key_type (decl['type']) + decl['enumerator'] = caseconversions.convert_case (decl['name'], style='upper') + decl['enumname'] = enumname + decl['getter'] = caseconversions.convert_case (decl['name'], style='java') + decl['varname'] = 'm_' + decl['getter'] + decl['setter'] = 'set' + caseconversions.convert_case (decl['name'], style='camel') + decl['typecref'] = 'const %s&' % decl['type'] if decl['type'] not in passbyvalue else decl['type'] + + if enumname not in self.enums: + self.enums[enumname] = dict ( + name = enumname, + typename = decl['type'], + values = [], + numvalues = 0, + highestkey = -1) + + self.enums[enumname]['values'].append (decl) + self.enums[enumname]['numvalues'] += 1 + self.enums[enumname]['highestkey'] += 1 + + self.enums = collections.OrderedDict (sorted (self.enums.items(), key=lambda x: x[0].upper())) + + for name, enum in self.enums.items(): + for i, value in enumerate (enum['values']): + value['index'] = i + + def write_header (self, fp): + fp.write ('#pragma once\n') + for qttype in sorted (self.qttypes): + fp.write ('#include <%s>\n' % qttype) + formatargs = {} + write = lambda value: fp.write (value) + write ('class ConfigurationValueBag\n') + write ('{\n') + write ('public:\n') + write ('\tConfigurationValueBag (class MainWindow* window);\n') + write ('\t~ConfigurationValueBag();\n') + write ('\tQVariant defaultValueByName (const QString& name);\n') + + for decl in self.decls: + write ('\t{type} {getter}();\n'.format (**decl)) + for decl in self.decls: + write ('\tvoid {setter} ({typecref} value);\n'.format (**decl)) + + write ('\n') + write ('private:\n') + write ('\tclass MainWindow* m_window;\n') + write ('\tclass QSettings* m_settings;\n') + + write ('};\n') + + def write_source (self, fp, headername): + fp.write ('#include <QSet>\n') + fp.write ('#include <QSettings>\n') + fp.write ('#include <QVariant>\n') + fp.write ('#include "%s/mainwindow.h"\n' % (self.args.sourcedir)) + fp.write ('#include "%s"\n' % headername) + + fp.write ( + '\n' + 'ConfigurationValueBag::ConfigurationValueBag (MainWindow* window) :\n' + '\tm_window (window),\n' + '\tm_settings (window->makeSettings (nullptr)) {}\n' + '\n' + 'ConfigurationValueBag::~ConfigurationValueBag()\n' + '{\n' + '\tm_settings->deleteLater();\n' + '}\n' + '\n') + + maptype = 'QMap<QString, QVariant>' + fp.write ('QVariant ConfigurationValueBag::defaultValueByName (const QString& name)\n') + fp.write ('{\n') + fp.write ('\tstatic %s defaults;\n' % maptype) + fp.write ('\tif (defaults.isEmpty())\n') + fp.write ('\t{\n') + + for decl in self.decls: + fp.write ('\t\tdefaults["{name}"] = QVariant::fromValue<{type}> ({default});\n'.format (**decl)) + + fp.write ('\t}\n') + fp.write ('\n') + fp.write ('\t%s::iterator it = defaults.find (name);\n' % maptype) + fp.write ('\tif (it != defaults.end())\n') + fp.write ('\t\treturn *it;\n') + fp.write ('\treturn QVariant();\n') + fp.write ('}\n') + fp.write ('\n') + + for decl in self.decls: + fp.write ('{type} ConfigurationValueBag::{getter}()\n'.format (**decl)) + fp.write ('{\n') + fp.write ('\tstatic QVariant defaultvalue = QVariant::fromValue<{type}> ({default});\n'.format (**decl)) + fp.write ('\treturn m_settings->value ("{name}", defaultvalue).value<{type}>();\n'.format (**decl)) + fp.write ('}\n') + fp.write ('\n') + + for decl in self.decls: + fp.write ('void ConfigurationValueBag::{setter} ({typecref} value)\n'.format (**decl)) + fp.write ('{\n') + fp.write ('\tif (value != {default})\n'.format (**decl)) + fp.write ('\t\tm_settings->setValue ("{name}", QVariant::fromValue<{type}> (value));\n'.format (**decl)) + fp.write ('\telse\n') + fp.write ('\t\tm_settings->remove ("{name}");\n'.format (**decl)) + fp.write ('}\n') + fp.write ('\n') + +def main(): + parser = argparse.ArgumentParser (description='Collects a list of configuration objects') + parser.add_argument ('inputs', nargs='+') + parser.add_argument ('--header', required=True) + parser.add_argument ('--source', required=True) + parser.add_argument ('--sourcedir', required=True) + args = parser.parse_args() + collector = ConfigCollector (args) + collector.collect (args.inputs) + collector.make_enums() + header = outputfile.OutputFile (args.header) + source = outputfile.OutputFile (args.source) + collector.write_source (source, headername=args.header) + collector.write_header (header) + header.save (verbose = True) + source.save (verbose = True) + +if __name__ == '__main__': + main() \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/outputfile.py Mon Aug 31 20:50:12 2015 +0300 @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# coding: utf-8 +# +# Copyright 2015 Teemu Piippo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +import hashlib +import sys + +class OutputFile: + def __init__ (self, filename): + self.filename = filename + try: + with open (self.filename, "r") as fp: + self.oldsum = fp.readline().replace ('\n', '').replace ('// ', '') + except IOError: + self.oldsum = '' + + self.body = '' + + def write (self, a): + self.body += a + + def save (self, verbose = False): + if sys.version_info >= (3, 0): + checksum = hashlib.md5 (bytes (self.body, 'utf-8')).hexdigest() + else: + checksum = hashlib.md5 (self.body).hexdigest() + + if checksum == self.oldsum: + print ('%s is up to date' % self.filename) + return False + + with open (self.filename, "w") as fp: + fp.write ('// %s\n' % checksum) + fp.write ('// This file has been automatically generated. Do not edit by hand\n') + fp.write ('\n') + fp.write (self.body) + + if verbose: + print ('%s written' % self.filename) + return True
--- a/tools/updaterevision.py Mon Aug 31 04:57:16 2015 +0300 +++ b/tools/updaterevision.py Mon Aug 31 20:50:12 2015 +0300 @@ -36,10 +36,10 @@ def main(): import subprocess from datetime import datetime - parser = argparser.ArgumentParser (description='Writes a header file with Hg commit information') + parser = argparse.ArgumentParser (description='Writes a header file with Hg commit information') parser.add_argument ('output') args = parser.parse_args() - f = OutputFile (args.output) + f = outputfile.OutputFile (args.output) data = subprocess.check_output (['hg', 'log', '-r.', '--template', '{node|short} {branch} {date|hgdate}']).replace ('\n', '').split (' ') @@ -64,4 +64,4 @@ print '%s updated to %s' % (f.filename, rev) if __name__ == '__main__': - main() \ No newline at end of file + main()