Mon, 31 Aug 2015 04:57:16 +0300
Commit configuration rework (doesn't work yet, more than most probably doesn't compile either)
--- a/CMakeLists.txt Sun Aug 30 17:20:55 2015 +0300 +++ b/CMakeLists.txt Mon Aug 31 04:57:16 2015 +0300 @@ -6,7 +6,6 @@ ###################################################################### project (ldforge) -add_subdirectory (codegen) cmake_minimum_required (VERSION 2.6) option (TRANSPARENT_DIRECT_COLORS "Enables non-standard transparent direct colors" OFF) @@ -24,10 +23,15 @@ find_package (OpenGL REQUIRED) -get_target_property (CODEGEN_EXE codegen LOCATION) +add_custom_target (revision_check ALL + COMMAND python "${CMAKE_SOURCE_DIR}/tools/updaterevision.py" hginfo.h + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -add_custom_target (revision_check ALL - COMMAND python "${CMAKE_SOURCE_DIR}/updaterevision.py" hginfo.h +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}) @@ -148,11 +152,6 @@ src/dialogs/openprogressdialog.ui ) -add_custom_target (codegeneration ALL - COMMAND ${CODEGEN_EXE} ${LDFORGE_SOURCES} ${CMAKE_BINARY_DIR}/configuration.inc - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - DEPENDS codegen) - set (LDFORGE_RESOURCES ldforge.qrc) # set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lGLU") @@ -208,5 +207,5 @@ ) endif() -add_dependencies (ldforge revision_check codegeneration) +add_dependencies (ldforge revision_check config_collection) install (TARGETS ldforge RUNTIME DESTINATION bin)
--- a/src/configDialog.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/configDialog.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -39,20 +39,6 @@ #include "glRenderer.h" #include "ui_config.h" -EXTERN_CFGENTRY (String, YtruderPath) -EXTERN_CFGENTRY (String, RectifierPath) -EXTERN_CFGENTRY (String, IntersectorPath) -EXTERN_CFGENTRY (String, CovererPath) -EXTERN_CFGENTRY (String, IsecalcPath) -EXTERN_CFGENTRY (String, Edger2Path) -EXTERN_CFGENTRY (Bool, YtruderUsesWine) -EXTERN_CFGENTRY (Bool, RectifierUsesWine) -EXTERN_CFGENTRY (Bool, IntersectorUsesWine) -EXTERN_CFGENTRY (Bool, CovererUsesWine) -EXTERN_CFGENTRY (Bool, IsecalcUsesWine) -EXTERN_CFGENTRY (Bool, Edger2UsesWine) -EXTERN_CFGENTRY (String, QuickColorToolbar) - const char* g_extProgPathFilter = #ifdef _WIN32 "Applications (*.exe)(*.exe);;" @@ -61,42 +47,15 @@ // // -static struct LDExtProgInfo -{ - QString const name; - QString const iconname; - QString* const path; - QLineEdit* input; - QPushButton* setPathButton; - bool* const wine; - QCheckBox* wineBox; -} g_LDExtProgInfo[] = -{ -#ifndef _WIN32 -# define EXTPROG(NAME, LOWNAME) { #NAME, #LOWNAME, &cfg::NAME##Path, null, null, \ - &cfg::NAME##UsesWine, null }, -#else -# define EXTPROG(NAME, LOWNAME) { #NAME, #LOWNAME, &cfg::NAME##Path, null, null, null, null }, -#endif - EXTPROG (Ytruder, ytruder) - EXTPROG (Rectifier, rectifier) - EXTPROG (Intersector, intersector) - EXTPROG (Isecalc, isecalc) - EXTPROG (Coverer, coverer) - EXTPROG (Edger2, edger2) -#undef EXTPROG -}; - -// -// -ConfigDialog::ConfigDialog (ConfigDialog::Tab deftab, QWidget* parent, Qt::WindowFlags f) : - QDialog (parent, f) +ConfigDialog::ConfigDialog (QWidget* parent, ConfigDialog::Tab defaulttab, Qt::WindowFlags f) : + QDialog (parent, f), + HierarchyElement (parent) { ui = new Ui_ConfigUI; ui->setupUi (this); // Set defaults - m_applyToWidgetOptions ([&](QWidget* wdg, AbstractConfigEntry* conf) + applyToWidgetOptions ([&](QWidget* wdg, AbstractConfigEntry* conf) { QVariant value (conf->toVariant()); QLineEdit* le; @@ -137,20 +96,17 @@ } }); - if (g_win) + m_window->applyToActions ([&](QAction* act) { - g_win->applyToActions ([&](QAction* act) - { - addShortcut (act); - }); - } + addShortcut (act); + }); ui->shortcutsList->setSortingEnabled (true); ui->shortcutsList->sortItems(); quickColors = LoadQuickColorList(); updateQuickColorList(); initExtProgs(); - selectPage (deftab); + selectPage (defaulttab); connect (ui->shortcut_set, SIGNAL (clicked()), this, SLOT (slot_setShortcut())); connect (ui->shortcut_reset, SIGNAL (clicked()), this, SLOT (slot_resetShortcut())); connect (ui->shortcut_clear, SIGNAL (clicked()), this, SLOT (slot_clearShortcut())); @@ -210,33 +166,36 @@ QGridLayout* pathsLayout = new QGridLayout; int row = 0; - for (LDExtProgInfo& info : g_LDExtProgInfo) + for (int i = 0; i < NumExternalPrograms; ++i) { - QLabel* icon = new QLabel, - *progLabel = new QLabel (info.name); + ExtProgramType program = (ExtProgramType) i; + ExternalProgramWidgets& widgets = m_externalProgramWidgets[i]; + QString name = m_window->externalPrograms()->externalProgramName (program); + QLabel* icon = new QLabel; + QLabel* progLabel = new QLabel (name); QLineEdit* input = new QLineEdit; QPushButton* setPathButton = new QPushButton; - icon->setPixmap (GetIcon (info.iconname)); + icon->setPixmap (GetIcon (name.toLower())); input->setText (*info.path); setPathButton->setIcon (GetIcon ("folder")); - info.input = input; - info.setPathButton = setPathButton; - + widgets.input = input; + widgets.setPathButton = setPathButton; + widgets.wineBox = nullptr; connect (setPathButton, SIGNAL (clicked()), this, SLOT (slot_setExtProgPath())); - pathsLayout->addWidget (icon, row, 0); pathsLayout->addWidget (progLabel, row, 1); pathsLayout->addWidget (input, row, 2); pathsLayout->addWidget (setPathButton, row, 3); - if (info.wine != null) +#ifdef Q_OS_UNIX { QCheckBox* wineBox = new QCheckBox ("Wine"); - wineBox->setChecked (*info.wine); - info.wineBox = wineBox; + wineBox->setChecked (m_window->externalPrograms()->programUsesWine (program)); + widgets.wineBox = wineBox; pathsLayout->addWidget (wineBox, row, 4); } +#endif ++row; } @@ -244,7 +203,7 @@ ui->extProgs->setLayout (pathsLayout); } -void ConfigDialog::m_applyToWidgetOptions (std::function<void (QWidget*, AbstractConfigEntry*)> func) +void ConfigDialog::applyToWidgetOptions (std::function<void (QWidget*, AbstractConfigEntry*)> func) { // Apply configuration for (QWidget* widget : findChildren<QWidget*>()) @@ -253,7 +212,7 @@ continue; QString confname (widget->objectName().mid (strlen ("config"))); - AbstractConfigEntry* conf (Config::FindByName (confname)); + AbstractConfigEntry* conf (m_config->findByName (confname)); if (conf == null) { @@ -270,7 +229,7 @@ // void ConfigDialog::applySettings() { - m_applyToWidgetOptions ([&](QWidget* widget, AbstractConfigEntry* conf) + applyToWidgetOptions ([&](QWidget* widget, AbstractConfigEntry* conf) { QVariant value (conf->toVariant()); QLineEdit* le; @@ -299,18 +258,19 @@ }); // Rebuild the quick color toolbar - if (g_win) - g_win->setQuickColors (quickColors); - - cfg::QuickColorToolbar = quickColorString(); + m_window->setQuickColors (quickColors); + m_config->quickColorToolbar = quickColorString(); // Ext program settings - for (const LDExtProgInfo& info : g_LDExtProgInfo) + for (int i = 0; i < NumExternalPrograms; ++i) { - *info.path = info.input->text(); + ExtProgramType program = (ExtProgramType) i; + ExtProgramToolset* toolset = m_window->externalPrograms(); + ExternalProgramWidgets& widgets = m_externalProgramWidgets[i]; + toolset->getPathSetting (program) = widgets.input->text(); - if (info.wine != null) - *info.wine = info.wineBox->isChecked(); + if (widgets.wineBox) + toolset->getWineSetting (program) = widgets.wineBox->isChecked(); } // Apply shortcuts @@ -324,12 +284,9 @@ LDDocument::current()->reloadAllSubfiles(); LoadLogoStuds(); - if (g_win) - { - g_win->R()->setBackground(); - g_win->doFullRefresh(); - g_win->updateDocumentList(); - } + m_window->R()->setBackground(); + m_window->doFullRefresh(); + m_window->updateDocumentList(); } // @@ -624,26 +581,29 @@ // void ConfigDialog::slot_setExtProgPath() { - const LDExtProgInfo* info = null; + ExtProgramType program = NumExternalPrograms; - for (const LDExtProgInfo& it : g_LDExtProgInfo) + for (int i = 0; i < NumExternalPrograms; ++i) { - if (it.setPathButton == sender()) + if (m_externalProgramWidgets[i].setPathButton == sender()) { - info = ⁢ + program = (ExtProgramType) i; break; } } - if (info != null) + if (program != NumExternalPrograms) { + ExtProgramToolset* toolset = m_window->externalPrograms(); + ExternalProgramWidgets& widgets = m_externalProgramWidgets[program]; QString filepath = QFileDialog::getOpenFileName (this, - format ("Path to %1", info->name), *info->path, g_extProgPathFilter); + format ("Path to %1", toolset->externalProgramName (program)), + widgets.input->text(), g_extProgPathFilter); if (filepath.isEmpty()) return; - info->input->setText (filepath); + widgets.input->setText (filepath); } }
--- a/src/configDialog.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/configDialog.h Mon Aug 31 04:57:16 2015 +0300 @@ -18,6 +18,7 @@ #pragma once #include "mainwindow.h" +#include "toolsets/extprogramtoolset.h" #include <QDialog> class Ui_ConfigUI; @@ -35,8 +36,15 @@ QListWidgetItem (view, type) {} }; +struct ExternalProgramWidgets +{ + class QLineEdit* input; + class QPushButton* setPathButton; + class QCheckBox* wineBox; +}; + // ============================================================================= -class ConfigDialog : public QDialog +class ConfigDialog : public QDialog, public HierarchyElement { Q_OBJECT @@ -53,7 +61,7 @@ DownloadTab }; - explicit ConfigDialog (Tab deftab = InterfaceTab, QWidget* parent = null, Qt::WindowFlags f = 0); + explicit ConfigDialog (QWidget* parent = nullptr, Tab defaulttab = (Tab) 0, Qt::WindowFlags f = 0); virtual ~ConfigDialog(); QList<LDQuickColor> quickColors; @@ -62,6 +70,7 @@ Ui_ConfigUI* ui; QList<QListWidgetItem*> quickColorItems; QMap<QPushButton*, QColor> m_buttonColors; + ExternalProgramWidgets m_externalProgramWidgets[NumExternalPrograms]; void applySettings(); void addShortcut (QAction* act); @@ -73,7 +82,7 @@ QListWidgetItem* getSelectedQuickColor(); QList<ShortcutListItem*> getShortcutSelection(); void initExtProgs(); - void m_applyToWidgetOptions (std::function<void (QWidget*, AbstractConfigEntry*)> func); + void applyToWidgetOptions (std::function<void (QWidget*, AbstractConfigEntry*)> func); private slots: void setButtonColor();
--- a/src/configuration.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/configuration.h Mon Aug 31 04:57:16 2015 +0300 @@ -26,9 +26,6 @@ class QSettings; class AbstractConfigEntry; -#define CFGENTRY(T, NAME, DEFAULT) namespace cfg { AbstractConfigEntry::T##Type NAME; } -#define EXTERN_CFGENTRY(T, NAME) namespace cfg { extern AbstractConfigEntry::T##Type NAME; } - namespace Config { void Initialize();
--- a/src/dialogs.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/dialogs.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -42,7 +42,6 @@ #include "ui_about.h" extern const char* g_extProgPathFilter; -EXTERN_CFGENTRY (String, LDrawPath) // ============================================================================= // =============================================================================
--- a/src/dialogs/colorselector.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/dialogs/colorselector.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -31,11 +31,9 @@ enum { NUM_COLUMNS = 16 }; -EXTERN_CFGENTRY (String, MainColor) -EXTERN_CFGENTRY (Float, MainColorAlpha) - -ColorSelector::ColorSelector (LDColor defaultvalue, QWidget* parent) : +ColorSelector::ColorSelector (QWidget* parent, LDColor defaultvalue) : QDialog (parent), + HierarchyElement (parent), ui (*new Ui_ColorSelUi) { m_firstResize = true; @@ -57,8 +55,8 @@ if (ldcolor == MainColor) { - color = QColor (cfg::MainColor); - color.setAlphaF (cfg::MainColorAlpha); + color = QColor (m_config->mainColor); + color.setAlphaF (m_config->mainColorAlpha); } QString color2name (Luma (color) < 80 ? "white" : "black"); @@ -178,9 +176,9 @@ selectDirectColor (selection().faceColor()); } -bool ColorSelector::selectColor (LDColor& val, LDColor defval, QWidget* parent) +bool ColorSelector::selectColor (QWidget* parent, LDColor& val, LDColor defaultvalue) { - ColorSelector dlg (defval, parent); + ColorSelector dlg (parent, defaultvalue); if (dlg.exec() and dlg.selection().isValid()) {
--- a/src/dialogs/colorselector.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/dialogs/colorselector.h Mon Aug 31 04:57:16 2015 +0300 @@ -21,15 +21,15 @@ #include "../main.h" #include "../colors.h" -class ColorSelector : public QDialog +class ColorSelector : public QDialog, public HierarchyElement { Q_OBJECT PROPERTY (private, LDColor, selection, setSelection, STOCK_WRITE) public: - explicit ColorSelector (LDColor defaultvalue = LDColor::nullColor(), QWidget* parent = null); + explicit ColorSelector (QWidget* parent, LDColor defaultvalue = LDColor::nullColor()); virtual ~ColorSelector(); - static bool selectColor (LDColor& val, LDColor defval = LDColor::nullColor(), QWidget* parent = null); + static bool selectColor (QWidget* parent, LDColor& val, LDColor defval = LDColor::nullColor()); private: class Ui_ColorSelUi& ui;
--- a/src/dialogs/newpartdialog.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/dialogs/newpartdialog.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -20,26 +20,24 @@ #include <QRadioButton> #include <QCheckBox> #include "../ldDocument.h" +#include "../mainwindow.h" #include "newpartdialog.h" #include "ui_newpartdialog.h" -EXTERN_CFGENTRY (String, DefaultName) -EXTERN_CFGENTRY (String, DefaultUser) -EXTERN_CFGENTRY (Bool, UseCALicense) - NewPartDialog::NewPartDialog (QWidget *parent) : QDialog (parent), + HierarchyElement (parent), ui (*new Ui_NewPart) { ui.setupUi (this); - QString authortext = cfg::DefaultName; + QString authortext = m_config->defaultName; - if (not cfg::DefaultUser.isEmpty()) - authortext.append (format (" [%1]", cfg::DefaultUser)); + if (not m_config->defaultUser.isEmpty()) + authortext.append (format (" [%1]", m_config->defaultUser)); ui.author->setText (authortext); - ui.useCaLicense->setChecked (cfg::UseCALicense); + ui.useCaLicense->setChecked (m_config->useCaLicense); } BFCStatement NewPartDialog::getWinding() const
--- a/src/dialogs/newpartdialog.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/dialogs/newpartdialog.h Mon Aug 31 04:57:16 2015 +0300 @@ -21,11 +21,11 @@ #include "../main.h" #include "../ldObject.h" -class NewPartDialog : public QDialog +class NewPartDialog : public QDialog, HierarchyElement { Q_OBJECT public: - NewPartDialog (QWidget *parent = nullptr); + NewPartDialog (QWidget *parent); QString author() const; void fillHeader (LDDocument* newdoc) const;
--- a/src/editmodes/abstractEditMode.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/editmodes/abstractEditMode.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -28,10 +28,12 @@ #include "../mainwindow.h" #include "../glRenderer.h" -CFGENTRY (Bool, DrawLineLengths, true) -CFGENTRY (Bool, DrawAngles, false) +ConfigOption (bool DrawLineLengths = true) +ConfigOption (bool DrawAngles = false) AbstractEditMode::AbstractEditMode (GLRenderer* renderer) : + QObject (renderer), + HierarchyElement (renderer), m_renderer (renderer) {} AbstractEditMode::~AbstractEditMode() {} @@ -40,12 +42,12 @@ { switch (type) { - case EditModeType::Select: return new SelectMode (renderer); - case EditModeType::Draw: return new DrawMode (renderer); - case EditModeType::Rectangle: return new RectangleMode (renderer); - case EditModeType::Circle: return new CircleMode (renderer); - case EditModeType::MagicWand: return new MagicWandMode (renderer); - case EditModeType::LinePath: return new LinePathMode (renderer); + case EditModeType::Select: return new SelectMode (renderer); + case EditModeType::Draw: return new DrawMode (renderer); + case EditModeType::Rectangle: return new RectangleMode (renderer); + case EditModeType::Circle: return new CircleMode (renderer); + case EditModeType::MagicWand: return new MagicWandMode (renderer); + case EditModeType::LinePath: return new LinePathMode (renderer); } throw std::logic_error ("bad type given to AbstractEditMode::createByType"); @@ -70,7 +72,7 @@ // Clear the selection when beginning to draw. CurrentDocument()->clearSelection(); - g_win->updateSelection(); + m_window->updateSelection(); m_drawedVerts.clear(); } @@ -161,7 +163,7 @@ void AbstractDrawMode::finishDraw (LDObjectList const& objs) { - int pos = g_win->getInsertionPoint(); + int pos = m_window->getInsertionPoint(); if (objs.size() > 0) { @@ -171,8 +173,8 @@ renderer()->compileObject (obj); } - g_win->refresh(); - g_win->endAction(); + m_window->refresh(); + m_window->endAction(); } m_drawedVerts.clear(); @@ -181,7 +183,7 @@ void AbstractDrawMode::drawLength (QPainter &painter, const Vertex &v0, const Vertex &v1, const QPointF& v0p, const QPointF& v1p) const { - if (not cfg::DrawLineLengths) + if (not m_config->drawLineLengths) return; const QString label = QString::number ((v1 - v0).length()); @@ -228,7 +230,7 @@ if (withlengths) drawLength (painter, poly3d[i], poly3d[j], poly[i], poly[j]); - if (withangles and cfg::DrawAngles) + if (withangles and m_config->drawAngles) { QLineF l0 (poly[h], poly[i]), l1 (poly[i], poly[j]);
--- a/src/editmodes/abstractEditMode.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/editmodes/abstractEditMode.h Mon Aug 31 04:57:16 2015 +0300 @@ -34,9 +34,9 @@ LinePath, }; -class AbstractEditMode +class AbstractEditMode : public QObject, public HierarchyElement { - GLRenderer* m_renderer; + Q_OBJECT public: struct MouseEventData @@ -61,6 +61,9 @@ virtual bool keyReleased (QKeyEvent*) { return false; } static AbstractEditMode* createByType (GLRenderer* renderer, EditModeType type); + +private: + GLRenderer* m_renderer; }; //
--- a/src/glCompiler.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/glCompiler.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -45,9 +45,7 @@ { GL_STACK_OVERFLOW, "The operation would have caused an overflow" }, }; -CFGENTRY (String, SelectColorBlend, "#0080FF") -EXTERN_CFGENTRY (Bool, BlackEdges) -EXTERN_CFGENTRY (String, BackgroundColor) +ConfigOption (QString SelectColorBlend = "#0080FF") static QList<int> g_warnedColors; static const QColor g_BFCFrontColor (64, 192, 80); @@ -80,6 +78,7 @@ // ============================================================================= // GLCompiler::GLCompiler (GLRenderer* renderer) : + HierarchyElement (parent), m_renderer (renderer) { needMerge(); @@ -168,7 +167,7 @@ } else if (poly.color == EdgeColor) { - qcol = Luma (QColor (cfg::BackgroundColor)) > 40 ? Qt::black : Qt::white; + qcol = Luma (QColor (m_config->backgroundColor)) > 40 ? Qt::black : Qt::white; } else { @@ -208,7 +207,7 @@ if (blendAlpha != 0.0) { - QColor selcolor (cfg::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/glCompiler.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/glCompiler.h Mon Aug 31 04:57:16 2015 +0300 @@ -24,7 +24,7 @@ // ============================================================================= // -class GLCompiler : protected QOpenGLFunctions +class GLCompiler : public HierarchyElement, protected QOpenGLFunctions { public: struct ObjectVBOInfo
--- a/src/glRenderer.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/glRenderer.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -52,22 +52,22 @@ {{ 0, -1, 0 }, Z, Y, false, true, true }, // right }; -CFGENTRY (String, BackgroundColor, "#FFFFFF") -CFGENTRY (String, MainColor, "#A0A0A0") -CFGENTRY (Float, MainColorAlpha, 1.0) -CFGENTRY (Int, LineThickness, 2) -CFGENTRY (Bool, BFCRedGreenView, false) -CFGENTRY (Int, Camera, EFreeCamera) -CFGENTRY (Bool, BlackEdges, false) -CFGENTRY (Bool, DrawAxes, false) -CFGENTRY (Bool, DrawWireframe, false) -CFGENTRY (Bool, UseLogoStuds, false) -CFGENTRY (Bool, AntiAliasedLines, true) -CFGENTRY (Bool, RandomColors, false) -CFGENTRY (Bool, HighlightObjectBelowCursor, true) -CFGENTRY (Bool, DrawSurfaces, true) -CFGENTRY (Bool, DrawEdgeLines, true) -CFGENTRY (Bool, DrawConditionalLines, true) +ConfigOption (QString BackgroundColor = "#FFFFFF") +ConfigOption (QString MainColor = "#A0A0A0") +ConfigOption (float MainColorAlpha = 1.0) +ConfigOption (int LineThickness = 2) +ConfigOption (bool BfcRedGreenView = false) +ConfigOption (int Camera = 6) +ConfigOption (bool BlackEdges = false) +ConfigOption (bool DrawAxes = false) +ConfigOption (bool DrawWireframe = false) +ConfigOption (bool UseLogoStuds = false) +ConfigOption (bool AntiAliasedLines = true) +ConfigOption (bool RandomColors = false) +ConfigOption (bool HighlightObjectBelowCursor = true) +ConfigOption (bool DrawSurfaces = true) +ConfigOption (bool DrawEdgeLines = true) +ConfigOption (bool DrawConditionalLines = true) // argh const char* g_CameraNames[7] = @@ -99,10 +99,12 @@ // ============================================================================= // -GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) +GLRenderer::GLRenderer (QWidget* parent) : + QGLWidget (parent), + HierarchyElement (parent) { m_isPicking = false; - m_camera = (ECamera) cfg::Camera; + m_camera = (ECamera) m_config->camera; m_drawToolTip = false; m_editmode = AbstractEditMode::createByType (this, EditModeType::Select); m_panning = false; @@ -193,7 +195,7 @@ glShadeModel (GL_SMOOTH); glEnable (GL_MULTISAMPLE); - if (cfg::AntiAliasedLines) + if (m_config->antiAliasedLines) { glEnable (GL_LINE_SMOOTH); glEnable (GL_POLYGON_SMOOTH); @@ -247,7 +249,7 @@ initializeOpenGLFunctions(); #endif setBackground(); - glLineWidth (cfg::LineThickness); + glLineWidth (m_config->lineThickness); glLineStipple (1, 0x6666); setAutoFillBackground (false); setMouseTracking (true); @@ -294,12 +296,12 @@ // QColor GLRenderer::getMainColor() { - QColor col (cfg::MainColor); + QColor col (m_config->mainColor); if (not col.isValid()) return QColor (0, 0, 0); - col.setAlpha (cfg::MainColorAlpha * 255.f); + col.setAlpha (m_config->mainColorAlpha * 255.f); return col; } @@ -313,7 +315,7 @@ return; } - QColor col (cfg::BackgroundColor); + QColor col (m_config->backgroundColor); if (not col.isValid()) return; @@ -375,7 +377,7 @@ zoomAllToFit(); } - if (cfg::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); @@ -429,7 +431,7 @@ } else { - if (cfg::BFCRedGreenView) + if (m_config->bfcRedGreenView) { glEnable (GL_CULL_FACE); glCullFace (GL_BACK); @@ -442,16 +444,9 @@ } else { - if (cfg::RandomColors) - { - drawVBOs (VBOSF_Triangles, VBOCM_RandomColors, GL_TRIANGLES); - drawVBOs (VBOSF_Quads, VBOCM_RandomColors, GL_QUADS); - } - else - { - drawVBOs (VBOSF_Triangles, VBOCM_NormalColors, GL_TRIANGLES); - drawVBOs (VBOSF_Quads, VBOCM_NormalColors, GL_QUADS); - } + EVBOComplement colors = (m_config->randomColors) ? VBOCM_RandomColors : VBOCM_NormalColors; + drawVBOs (VBOSF_Triangles, colors, GL_TRIANGLES); + drawVBOs (VBOSF_Quads, colors, GL_QUADS); } drawVBOs (VBOSF_Lines, VBOCM_NormalColors, GL_LINES); @@ -459,7 +454,7 @@ drawVBOs (VBOSF_CondLines, VBOCM_NormalColors, GL_LINES); glDisable (GL_LINE_STIPPLE); - if (cfg::DrawAxes) + if (m_config->drawAxes) { glBindBuffer (GL_ARRAY_BUFFER, m_axesVBO); glVertexPointer (3, GL_FLOAT, 0, NULL); @@ -485,9 +480,9 @@ void GLRenderer::drawVBOs (EVBOSurface surface, EVBOComplement colors, GLenum type) { // Filter this through some configuration options - if ((isOneOf (surface, VBOSF_Quads, VBOSF_Triangles) and cfg::DrawSurfaces == false) or - (surface == VBOSF_Lines and cfg::DrawEdgeLines == false) or - (surface == VBOSF_CondLines and cfg::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; } @@ -888,7 +883,7 @@ // void GLRenderer::contextMenuEvent (QContextMenuEvent* ev) { - g_win->spawnContextMenu (ev->globalPos()); + m_window->spawnContextMenu (ev->globalPos()); } // ============================================================================= @@ -900,8 +895,8 @@ return; m_camera = cam; - cfg::Camera = (int) cam; - g_win->updateEditModeActions(); + m_config->camera = (int) cam; + m_window->updateEditModeActions(); } // ============================================================================= @@ -996,7 +991,7 @@ delete[] pixeldata; // Update everything now. - g_win->updateSelection(); + m_window->updateSelection(); // Recompile the objects now to update their color for (LDObject* obj : Selection()) @@ -1039,7 +1034,7 @@ if (camera() == EFreeCamera and not m_editmode->allowFreeCamera()) setCamera (ETopCamera); - g_win->updateEditModeActions(); + m_window->updateEditModeActions(); update(); } @@ -1082,14 +1077,14 @@ glDisable (GL_DITHER); // Use particularly thick lines while picking ease up selecting lines. - glLineWidth (qMax<double> (cfg::LineThickness, 6.5)); + glLineWidth (qMax<double> (m_config->lineThickness, 6.5)); } else { glEnable (GL_DITHER); // Restore line thickness - glLineWidth (cfg::LineThickness); + glLineWidth (m_config->lineThickness); } } @@ -1526,22 +1521,22 @@ } } - if (g_win->R() == this) - g_win->refresh(); + if (m_window->R() == this) + m_window->refresh(); } // ============================================================================= // void GLRenderer::highlightCursorObject() { - if (not cfg::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 cfg::HighlightObjectBelowCursor) + if (isCameraMoving() or not m_config->highlightObjectBelowCursor) { newIndex = 0; } @@ -1575,24 +1570,24 @@ void GLRenderer::dragEnterEvent (QDragEnterEvent* ev) { - if (g_win != null and ev->source() == g_win->getPrimitivesTree() and g_win->getPrimitivesTree()->currentItem() != null) + if (m_window != null and ev->source() == m_window->getPrimitivesTree() and m_window->getPrimitivesTree()->currentItem() != null) ev->acceptProposedAction(); } void GLRenderer::dropEvent (QDropEvent* ev) { - if (g_win != null and ev->source() == g_win->getPrimitivesTree()) + if (m_window != null and ev->source() == m_window->getPrimitivesTree()) { - QString primName = static_cast<SubfileListItem*> (g_win->getPrimitivesTree()->currentItem())->primitive()->name; + QString primName = static_cast<SubfileListItem*> (m_window->getPrimitivesTree()->currentItem())->primitive()->name; LDSubfile* ref = LDSpawn<LDSubfile>(); ref->setColor (MainColor); ref->setFileInfo (GetDocument (primName)); ref->setPosition (Origin); ref->setTransform (IdentityMatrix); - LDDocument::current()->insertObj (g_win->getInsertionPoint(), ref); + LDDocument::current()->insertObj (m_window->getInsertionPoint(), ref); ref->select(); - g_win->buildObjList(); - g_win->R()->refresh(); + m_window->buildObjList(); + m_window->R()->refresh(); ev->acceptProposedAction(); } }
--- a/src/glRenderer.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/glRenderer.h Mon Aug 31 04:57:16 2015 +0300 @@ -135,7 +135,7 @@ // and selection picking. The instance of GLRenderer is accessible as // g_win->R() // -class GLRenderer : public QGLWidget, protected QOpenGLFunctions +class GLRenderer : public QGLWidget, protected QOpenGLFunctions, public HierarchyElement { public: Q_OBJECT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hierarchyelement.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -0,0 +1,28 @@ +#include <stdio.h> +#include <QMetaObject> +#include "hierarchyelement.h" +#include "mainwindow.h" + +HierarchyElement::HierarchyElement (QObject* parent) : + m_window (nullptr), + m_config (nullptr) +{ + if (parent) + { + while (parent->parent() != nullptr) + parent = parent->parent(); + + m_window = qobject_cast<MainWindow*> (parent); + } + + if (m_window == nullptr) + { + fprintf (stderr, "FATAL ERROR: Hierarchy element instance %p should be in the hierarchy of a " + "MainWindow but isn't.", this); + abort(); + } + else + { + m_config = m_window->configBag(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hierarchyelement.h Mon Aug 31 04:57:16 2015 +0300 @@ -0,0 +1,19 @@ +#pragma once +#include <QObject> + +class MainWindow; +class ConfigurationValueBag; + +// +// Objects that are to take part in the MainWindow's hierarchy multiple-inherit from this class to get a few useful +// pointer members. +// +class HierarchyElement +{ +public: + HierarchyElement (QObject* parent); + +protected: + MainWindow* m_window; + ConfigurationValueBag* m_config; +};
--- a/src/ldDocument.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/ldDocument.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -33,11 +33,8 @@ #include "ldpaths.h" #include "dialogs/openprogressdialog.h" -CFGENTRY (List, RecentFiles, {}) -CFGENTRY (Bool, TryDownloadMissingFiles, false) -EXTERN_CFGENTRY (String, DownloadFilePath) -EXTERN_CFGENTRY (Bool, UseLogoStuds) -EXTERN_CFGENTRY (String, LDrawPath) +ConfigOption (QStringList RecentFiles) +ConfigOption (bool TryDownloadMissingFiles = false) static bool g_loadingMainFile = false; static const int g_maxRecentFiles = 10; @@ -226,7 +223,7 @@ return relpath; // Try with just the LDraw path first - fullPath = format ("%1" DIRSLASH "%2", cfg::LDrawPath, relpath); + fullPath = format ("%1" DIRSLASH "%2", g_win->configBag()->lDrawPath, relpath); if (QFile::exists (fullPath)) return fullPath; @@ -235,9 +232,10 @@ { // Look in sub-directories: parts and p. Also look in net_downloadpath, since that's // where we download parts from the PT to. - for (const QString& topdir : QList<QString> ({ cfg::LDrawPath, cfg::DownloadFilePath })) + QStringList dirs = { g_win->configBag()->lDrawPath, g_win->configBag()->downloadFilePath }; + for (const QString& topdir : dirs) { - for (const QString& subdir : QList<QString> ({ "parts", "p" })) + for (const QString& subdir : QStringList ({ "parts", "p" })) { fullPath = format ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath); @@ -574,24 +572,24 @@ // void AddRecentFile (QString path) { - int idx = cfg::RecentFiles.indexOf (path); + QStringList& recentFiles = g_win->configBag()->recentFiles; + int idx = recentFiles.indexOf (path); // If this file already is in the list, pop it out. if (idx != -1) { - if (idx == cfg::RecentFiles.size() - 1) + if (idx == recentFiles.size() - 1) return; // first recent file - abort and do nothing - cfg::RecentFiles.removeAt (idx); + recentFiles.removeAt (idx); } // If there's too many recent files, drop one out. - while (cfg::RecentFiles.size() > (g_maxRecentFiles - 1)) - cfg::RecentFiles.removeAt (0); + while (recentFiles.size() > (g_maxRecentFiles - 1)) + recentFiles.removeAt (0); // Add the file - cfg::RecentFiles << path; - + recentFiles << path; Config::Save(); g_win->updateRecentFilesMenu(); } @@ -671,7 +669,7 @@ unknowns << static_cast<LDError*> (obj)->fileReferenced(); } - if (cfg::TryDownloadMissingFiles and not unknowns.isEmpty()) + if (g_win->configBag()->tryDownloadMissingFiles and not unknowns.isEmpty()) { PartDownloader dl; @@ -1270,7 +1268,7 @@ // Possibly substitute with logoed studs: // stud.dat -> stud-logo.dat // stud2.dat -> stud-logo2.dat - if (cfg::UseLogoStuds and renderinline) + if (g_win->configBag()->useLogoStuds and renderinline) { // Ensure logoed studs are loaded first LoadLogoStuds();
--- a/src/ldObject.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/ldObject.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -27,9 +27,9 @@ #include "colors.h" #include "glCompiler.h" -CFGENTRY (String, DefaultName, "") -CFGENTRY (String, DefaultUser, "") -CFGENTRY (Bool, UseCALicense, true) +ConfigOption (QString DefaultName = "") +ConfigOption (QString DefaultUser = "") +ConfigOption (bool UseCaLicense = true) // List of all LDObjects QMap<int32, LDObject*> g_allObjects; @@ -859,7 +859,7 @@ // QString PreferredLicenseText() { - return (cfg::UseCALicense ? CALicenseText : ""); + return (g_win->configBag()->useCaLicense ? CALicenseText : ""); } // =============================================================================
--- a/src/ldpaths.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/ldpaths.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -1,24 +1,28 @@ #include <QDir> #include "ldpaths.h" +#include "mainwindow.h" #include "dialogs/ldrawpathdialog.h" -CFGENTRY (String, LDrawPath, "") +ConfigOption (QString LDrawPath) LDPaths::LDPaths (QObject* parent) : QObject (parent), + HierarchyElement (parent), m_dialog (nullptr) {} void LDPaths::checkPaths() { - if (not configurePaths (cfg::LDrawPath)) + QString& pathconfig = m_config->lDrawPath; + + if (not configurePaths (pathconfig)) { - m_dialog = new LDrawPathDialog (cfg::LDrawPath, false); + m_dialog = new LDrawPathDialog (pathconfig, false); connect (m_dialog, SIGNAL (pathChanged(QString)), this, SLOT (configurePaths (QString))); if (not m_dialog->exec()) Exit(); else - cfg::LDrawPath = m_dialog->path(); + pathconfig = m_dialog->path(); } }
--- a/src/ldpaths.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/ldpaths.h Mon Aug 31 04:57:16 2015 +0300 @@ -2,13 +2,14 @@ #include "main.h" class QDir; +class MainWindow; -class LDPaths : public QObject +class LDPaths : public QObject, public HierarchyElement { Q_OBJECT public: - LDPaths (QObject* parent = nullptr); + LDPaths (QObject* parent); void checkPaths(); bool isValid (const class QDir& path) const;
--- a/src/macros.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/macros.h Mon Aug 31 04:57:16 2015 +0300 @@ -84,3 +84,5 @@ ++FOR_ENUM_NAME (__LINE__)) \ for (ENUM NAME = ENUM (FOR_ENUM_NAME (__LINE__)); NAME != ENUM::NumValues; \ NAME = ENUM::NumValues) + +#define ConfigOption(...)
--- a/src/main.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/main.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -42,7 +42,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}); -CFGENTRY (Bool, FirstStart, true) +ConfigOption (bool firstStart = true) // ============================================================================= // @@ -64,22 +64,22 @@ else Critical ("Failed to create configuration file!\n"); } - - LDPaths* paths = new LDPaths; + + MainWindow* win = new MainWindow; + LDPaths* paths = new LDPaths (win); paths->checkPaths(); paths->deleteLater(); InitColors(); LoadPrimitives(); - MainWindow* win = new MainWindow; 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 (cfg::FirstStart) + if (win->configBag()->firstStart) { (new ConfigDialog (ConfigDialog::ProfileTab))->exec(); - cfg::FirstStart = false; + win->configBag()->firstStart = false; Config::Save(); }
--- a/src/main.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/main.h Mon Aug 31 04:57:16 2015 +0300 @@ -31,6 +31,7 @@ #include "version.h" #include "configuration.h" #include "format.h" +#include "hierarchyelement.h" // Null pointer static const std::nullptr_t null = nullptr;
--- a/src/mainwindow.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/mainwindow.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -51,32 +51,23 @@ #include "ui_mainwindow.h" #include "primitives.h" #include "editmodes/abstractEditMode.h" +#include "toolsets/extprogramtoolset.h" #include "toolsets/toolset.h" static bool g_isSelectionLocked = false; static QMap<QAction*, QKeySequence> g_defaultShortcuts; -CFGENTRY (Bool, ColorizeObjectsList, true) -CFGENTRY (String, QuickColorToolbar, "4:25:14:27:2:3:11:1:22:|:0:72:71:15") -CFGENTRY (Bool, ListImplicitFiles, false) -CFGENTRY (List, HiddenToolbars, {}) -EXTERN_CFGENTRY (List, RecentFiles) -EXTERN_CFGENTRY (Bool, DrawAxes) -EXTERN_CFGENTRY (String, MainColor) -EXTERN_CFGENTRY (Float, MainColorAlpha) -EXTERN_CFGENTRY (Bool, DrawWireframe) -EXTERN_CFGENTRY (Bool, BFCRedGreenView) -EXTERN_CFGENTRY (Bool, DrawAngles) -EXTERN_CFGENTRY (Bool, RandomColors) -EXTERN_CFGENTRY (Bool, DrawSurfaces) -EXTERN_CFGENTRY (Bool, DrawEdgeLines) -EXTERN_CFGENTRY (Bool, DrawConditionalLines) +ConfigOption (bool colorizeObjectsList = true) +ConfigOption (QString quickColorToolbar = "4:25:14:27:2:3:11:1:22:|:0:72:71:15") +ConfigOption (bool listImplicitFiles = false) +ConfigOption (QStringList hiddenToolbars) // ============================================================================= // MainWindow::MainWindow (QWidget* parent, Qt::WindowFlags flags) : QMainWindow (parent, flags), - ui (*new Ui_MainWindow) + ui (*new Ui_MainWindow), + m_externalPrograms (nullptr) { g_win = this; ui.setupUi (this); @@ -142,6 +133,9 @@ { const QMetaObject* meta = toolset->metaObject(); + if (qobject_cast<ExtProgramToolset*> (meta)) + m_externalPrograms = meta; + for (int i = 0; i < meta->methodCount(); ++i) { ToolInfo info; @@ -162,7 +156,7 @@ } } - for (QVariant const& toolbarname : cfg::HiddenToolbars) + for (QVariant const& toolbarname : m_configOptions.hiddenToolbars) { QToolBar* toolbar = findChild<QToolBar*> (toolbarname.toString()); @@ -231,7 +225,7 @@ QAction* first = null; - for (const QVariant& it : cfg::RecentFiles) + for (const QVariant& it : m_configOptions.recentFiles) { QString file = it.toString(); QAction* recent = new QAction (GetIcon ("open-recent"), file, this); @@ -249,7 +243,7 @@ { QList<LDQuickColor> colors; - for (QString colorname : cfg::QuickColorToolbar.split (":")) + for (QString colorname : m_configOptions.quickColorToolbar.split (":")) { if (colorname == "|") colors << LDQuickColor::getSeparator(); @@ -303,9 +297,9 @@ void MainWindow::updateGridToolBar() { // Ensure that the current grid - and only the current grid - is selected. - ui.actionGridCoarse->setChecked (cfg::Grid == Grid::Coarse); - ui.actionGridMedium->setChecked (cfg::Grid == Grid::Medium); - ui.actionGridFine->setChecked (cfg::Grid == Grid::Fine); + ui.actionGridCoarse->setChecked (m_configOptions.grid == Grid::Coarse); + ui.actionGridMedium->setChecked (m_configOptions.grid == Grid::Medium); + ui.actionGridFine->setChecked (m_configOptions.grid == Grid::Fine); } // ============================================================================= @@ -471,8 +465,11 @@ item->setBackground (QColor ("#AA0000")); item->setForeground (QColor ("#FFAA00")); } - else if (cfg::ColorizeObjectsList and obj->isColored() and - obj->color().isValid() and obj->color() != MainColor and obj->color() != EdgeColor) + else if (m_configOptions.colorizeObjectsList + and obj->isColored() + and obj->color().isValid() + and obj->color() != MainColor + and obj->color() != EdgeColor) { // If the object isn't in the main or edge color, draw this list entry in that color. item->setForeground (obj->color().faceColor()); @@ -681,12 +678,12 @@ } // Save the toolbar set - cfg::HiddenToolbars.clear(); + m_configOptions.hiddenToolbars.clear(); for (QToolBar* toolbar : findChildren<QToolBar*>()) { if (toolbar->isHidden()) - cfg::HiddenToolbars << toolbar->objectName(); + m_configOptions.hiddenToolbars << toolbar->objectName(); } // Save the configuration before leaving. @@ -915,8 +912,8 @@ if (colinfo == MainColor) { // Use the user preferences for main color here - col = cfg::MainColor; - col.setAlphaF (cfg::MainColorAlpha); + col = g_win->configBag()->mainColor; + col.setAlphaF (g_win->configBag()->mainColorAlpha); } // Paint the icon border @@ -1068,14 +1065,14 @@ ui.actionRedo->setEnabled (pos < (long) his->getSize() - 1); } - ui.actionWireframe->setChecked (cfg::DrawWireframe); - ui.actionAxes->setChecked (cfg::DrawAxes); - ui.actionBfcView->setChecked (cfg::BFCRedGreenView); - ui.actionRandomColors->setChecked (cfg::RandomColors); - ui.actionDrawAngles->setChecked (cfg::DrawAngles); - ui.actionDrawSurfaces->setChecked (cfg::DrawSurfaces); - ui.actionDrawEdgeLines->setChecked (cfg::DrawEdgeLines); - ui.actionDrawConditionalLines->setChecked (cfg::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); } // ============================================================================= @@ -1188,6 +1185,35 @@ 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() +{ + QString path = qApp->applicationDirPath() + "/" UNIXNAME ".ini"; + return new QSettings (path, QSettings::IniFormat); +} + // ============================================================================= // QImage GetImageFromScreencap (uchar* data, int w, int h)
--- a/src/mainwindow.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/mainwindow.h Mon Aug 31 04:57:16 2015 +0300 @@ -27,6 +27,7 @@ #include "configuration.h" #include "ldObject.h" #include "colors.h" +#include "configurationvaluebag.h" class MessageManager; class MainWindow; @@ -162,6 +163,18 @@ bool ringToolHiRes() const; int ringToolSegments() const; + ConfigurationValueBag* configBag() const { return m_configOptions; } + + template<typename T> + auto& config (T key) + { + return m_configOptions.get (key); + } + + class ExtProgramToolset* externalPrograms() + { + return m_externalPrograms; + } public slots: void updatePrimitives(); @@ -177,6 +190,7 @@ private: struct ToolInfo { QMetaMethod method; Toolset* object; }; + ConfigurationValueBag m_configOptions; GLRenderer* m_renderer; LDObjectList m_sel; QList<LDQuickColor> m_quickColors; @@ -188,6 +202,7 @@ bool m_updatingTabs; QVector<Toolset*> m_toolsets; QMap<QAction*, ToolInfo> m_toolmap; + class ExtProgramToolset* m_externalPrograms; private slots: void slot_selectionChanged();
--- a/src/miscallenous.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/miscallenous.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -85,30 +85,35 @@ // // Grid stuff // -CFGENTRY (Int, Grid, Grid::Medium) -CFGENTRY (Float, GridCoarseCoordinateSnap, 5.0f) -CFGENTRY (Float, GridCoarseAngleSnap, 45.0f) -CFGENTRY (Float, GridMediumCoordinateSnap, 1.0f) -CFGENTRY (Float, GridMediumAngleSnap, 22.5f) -CFGENTRY (Float, GridFineCoordinateSnap, 0.1f) -CFGENTRY (Float, GridFineAngleSnap, 7.5f) -CFGENTRY (Int, RotationPointType, 0) -CFGENTRY (Vertex, CustomRotationPoint, Origin) +ConfigOption (int Grid = 1) +ConfigOption (float GridCoarseCoordinateSnap = 5.0f) +ConfigOption (float GridCoarseAngleSnap = 45.0f) +ConfigOption (float GridMediumCoordinateSnap = 1.0f) +ConfigOption (float GridMediumAngleSnap = 22.5f) +ConfigOption (float GridFineCoordinateSnap = 0.1f) +ConfigOption (float GridFineAngleSnap = 7.5f) +ConfigOption (int RotationPointType = 0) +ConfigOption (Vertex CustomRotationPoint = Origin) const GridData Grids[3] = { - { "Coarse", &cfg::GridCoarseCoordinateSnap, &cfg::GridCoarseAngleSnap }, - { "Medium", &cfg::GridMediumCoordinateSnap, &cfg::GridMediumAngleSnap }, - { "Fine", &cfg::GridFineCoordinateSnap, &cfg::GridFineAngleSnap }, + { "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 }, }; +const GridData& CurrentGrid() +{ + return Grids[g_win->configBag()->grid]; +} + // ============================================================================= // // Snap the given coordinate value on the current grid's given axis. // double Grid::Snap (double value, const Grid::Config type) { - double snapvalue = (type == Coordinate) ? *CurrentGrid().coordinateSnap : *CurrentGrid().angleSnap; + double snapvalue = g_win->config ((type == Coordinate) ? CurrentGrid().coordinateSnap : CurrentGrid().angleSnap); double mult = floor (qAbs<double> (value / snapvalue)); double out = mult * snapvalue; @@ -153,9 +158,9 @@ // Vertex GetRotationPoint (const LDObjectList& objs) { - switch (RotationPoint (cfg::RotationPointType)) + switch (RotationPoint (g_win->configBag()->rotationPointType)) { - case RotationPoint::ObjectOrigin: + case RotationPoint::ObjectOrigin: { LDBoundingBox box; @@ -171,13 +176,14 @@ return box.center(); } - case RotationPoint::WorldOrigin: - return Origin; + case RotationPoint::WorldOrigin: + return Origin; - case RotationPoint::CustomPoint: - return cfg::CustomRotationPoint; + case RotationPoint::CustomPoint: + return g_win->configBag()->customRotationPoint; - case RotationPoint::NumValues: break; + case RotationPoint::NumValues: + break; } return Vertex(); @@ -191,38 +197,40 @@ Ui::RotPointUI ui; ui.setupUi (dlg); - switch (RotationPoint (cfg::RotationPointType)) + switch (RotationPoint (g_win->configBag()->rotationPointType)) { - case RotationPoint::ObjectOrigin: - ui.objectPoint->setChecked (true); - break; + case RotationPoint::ObjectOrigin: + ui.objectPoint->setChecked (true); + break; - case RotationPoint::WorldOrigin: - ui.worldPoint->setChecked (true); - break; + case RotationPoint::WorldOrigin: + ui.worldPoint->setChecked (true); + break; - case RotationPoint::CustomPoint: - ui.customPoint->setChecked (true); - break; + case RotationPoint::CustomPoint: + ui.customPoint->setChecked (true); + break; - case RotationPoint::NumValues: break; + case RotationPoint::NumValues: + break; } - ui.customX->setValue (cfg::CustomRotationPoint.x()); - ui.customY->setValue (cfg::CustomRotationPoint.y()); - ui.customZ->setValue (cfg::CustomRotationPoint.z()); + Vertex& custompoint = g_win->configBag()->customRotationPoint; + ui.customX->setValue (custompoint.x()); + ui.customY->setValue (custompoint.y()); + ui.customZ->setValue (custompoint.z()); if (not dlg->exec()) return; - cfg::RotationPointType = int ( + g_win->configBag()->rotationPointType = (ui.objectPoint->isChecked()) ? RotationPoint::ObjectOrigin : (ui.worldPoint->isChecked()) ? RotationPoint::WorldOrigin : - RotationPoint::CustomPoint); + RotationPoint::CustomPoint; - cfg::CustomRotationPoint.setX (ui.customX->value()); - cfg::CustomRotationPoint.setY (ui.customY->value()); - cfg::CustomRotationPoint.setZ (ui.customZ->value()); + custompoint.setX (ui.customX->value()); + custompoint.setY (ui.customY->value()); + custompoint.setZ (ui.customZ->value()); } // =============================================================================
--- a/src/miscallenous.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/miscallenous.h Mon Aug 31 04:57:16 2015 +0300 @@ -22,6 +22,7 @@ #include "configuration.h" #include "main.h" #include "basics.h" +#include "configurationvaluebag.h" class LDDocument; class QColor; @@ -46,17 +47,12 @@ struct GridData { const char* name; - float* coordinateSnap; - float* angleSnap; + CONFIG_KEY_TYPE(float) coordinateSnap; + CONFIG_KEY_TYPE(float) angleSnap; }; -EXTERN_CFGENTRY (Int, Grid) extern const GridData Grids[3]; - -inline const GridData& CurrentGrid() -{ - return Grids[cfg::Grid]; -} +const GridData& CurrentGrid(); // ============================================================================= enum class RotationPoint
--- a/src/partDownloader.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/partDownloader.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -31,17 +31,17 @@ #include "ldDocument.h" #include "glRenderer.h" -CFGENTRY (String, DownloadFilePath, "") -CFGENTRY (Bool, GuessDownloadPaths, true) -CFGENTRY (Bool, AutoCloseDownloadDialog, true) +ConfigOption (QString DownloadFilePath) +ConfigOption (bool GuessDownloadPaths = true) +ConfigOption (bool AutoCloseDownloadDialog = true) -const QString g_unofficialLibraryURL ("http://ldraw.org/library/unofficial/"); +const char* g_unofficialLibraryURL = "http://ldraw.org/library/unofficial/"; // ============================================================================= // void PartDownloader::staticBegin() { - PartDownloader dlg; + PartDownloader dlg (g_win); if (not dlg.checkValidPath()) return; @@ -53,7 +53,7 @@ // QString PartDownloader::getDownloadPath() { - QString path = cfg::DownloadFilePath; + QString path = m_config->downloadFilePath; if (DIRSLASH[0] != '/') path.replace (DIRSLASH, "/"); @@ -65,6 +65,7 @@ // PartDownloader::PartDownloader (QWidget* parent) : QDialog (parent), + HierarchyElement (parent), m_source (Source (0)) { setForm (new Ui_DownloadFrom); @@ -108,7 +109,7 @@ if (path.isEmpty()) return false; - cfg::DownloadFilePath = path; + m_config->downloadFilePath = path; } return true; @@ -144,7 +145,7 @@ dest = dest.simplified(); // If the user doesn't want us to guess, stop right here. - if (not cfg::GuessDownloadPaths) + if (not m_config->guessDownloadPaths) return; // Ensure .dat extension @@ -331,7 +332,7 @@ for (LDDocument* f : m_files) f->reloadAllSubfiles(); - if (cfg::AutoCloseDownloadDialog and not failed) + if (m_config->autoCloseDownloadDialog and not failed) { // Close automatically if desired. accept();
--- a/src/partDownloader.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/partDownloader.h Mon Aug 31 04:57:16 2015 +0300 @@ -33,7 +33,7 @@ // ============================================================================= // -class PartDownloader : public QDialog +class PartDownloader : public QDialog, public HierarchyElement { public: enum Source
--- a/src/primitives.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/primitives.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -32,10 +32,6 @@ static PrimitiveScanner* g_activeScanner = null; PrimitiveCategory* g_unmatched = null; -EXTERN_CFGENTRY (String, DefaultName) -EXTERN_CFGENTRY (String, DefaultUser) -EXTERN_CFGENTRY (Int, DefaultLicense) - static const QStringList g_radialNameRoots = { "edge", @@ -622,10 +618,10 @@ QString author = APPNAME; QString license = ""; - if (not cfg::DefaultName.isEmpty()) + if (not g_win->configBag()->defaultName.isEmpty()) { license = PreferredLicenseText(); - author = format ("%1 [%2]", cfg::DefaultName, cfg::DefaultUser); + author = format ("%1 [%2]", g_win->configBag()->defaultName, g_win->configBag()->defaultUser); } LDObjectList objs;
--- a/src/toolsets/algorithmtoolset.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/algorithmtoolset.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -38,14 +38,9 @@ #include "ui_addhistoryline.h" #include "algorithmtoolset.h" -EXTERN_CFGENTRY (String, DefaultUser) - -CFGENTRY (Int, RoundPosition, 3) -CFGENTRY (Int, RoundMatrix, 4) -CFGENTRY (Int, SplitLinesSegments, 5) -EXTERN_CFGENTRY (String, DefaultName) -EXTERN_CFGENTRY (String, DefaultUser) -EXTERN_CFGENTRY (Bool, UseCALicense) +ConfigOption (int roundPositionPrecision = 3) +ConfigOption (int roundMatrixPrecision = 4) +ConfigOption (int splitLinesSegments = 5) AlgorithmToolset::AlgorithmToolset (MainWindow* parent) : Toolset (parent) @@ -163,9 +158,15 @@ Vertex v = mo->position(); Matrix t = mo->transform(); - // Note: matrix values are to be rounded to 4 decimals. - v.apply ([](Axis, double& a) { RoundToDecimals (a, cfg::RoundPosition); }); - ApplyToMatrix (t, [](int, double& a) { RoundToDecimals (a, cfg::RoundMatrix); }); + v.apply ([](Axis, double& a) + { + RoundToDecimals (a, m_config->roundPositionPrecision); + }); + + ApplyToMatrix (t, [](int, double& a) + { + RoundToDecimals (a, m_config->roundMatrixPrecision); + }); mo->setPosition (v); mo->setTransform (t); @@ -176,7 +177,10 @@ for (int i = 0; i < obj->numVertices(); ++i) { Vertex v = obj->vertex (i); - v.apply ([](Axis, double& a) { RoundToDecimals (a, cfg::RoundPosition); }); + v.apply ([](Axis, double& a) + { + RoundToDecimals (a, m_config->roundPositionPrecision); + }); obj->setVertex (i, v); num += 3; } @@ -328,7 +332,7 @@ QDialog* dlg = new QDialog; Ui_AddHistoryLine* ui = new Ui_AddHistoryLine; ui->setupUi (dlg); - ui->m_username->setText (cfg::DefaultUser); + ui->m_username->setText (m_config->defaultUser); ui->m_date->setDate (QDate::currentDate()); ui->m_comment->setFocus(); @@ -372,13 +376,14 @@ void AlgorithmToolset::splitLines() { bool ok; - int segments = QInputDialog::getInt (m_window, APPNAME, "Amount of segments:", cfg::SplitLinesSegments, 0, + int segments = QInputDialog::getInt (m_window, APPNAME, "Amount of segments:", + m_window->config (m_config->splitLinesSegments), 0, std::numeric_limits<int>::max(), 1, &ok); if (not ok) return; - cfg::SplitLinesSegments = segments; + m_config->splitLinesSegments = segments; for (LDObject* obj : Selection()) { @@ -539,7 +544,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]", cfg::DefaultName, cfg::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/extprogramtoolset.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/extprogramtoolset.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -41,68 +41,45 @@ #include "ui_isecalc.h" #include "ui_edger2.h" -enum ExtProgramType -{ - Isecalc, - Intersector, - Coverer, - Ytruder, - Rectifier, - Edger2, -}; - // ============================================================================= // -CFGENTRY (String, IsecalcPath, "") -CFGENTRY (String, IntersectorPath, "") -CFGENTRY (String, CovererPath, "") -CFGENTRY (String, YtruderPath, "") -CFGENTRY (String, RectifierPath, "") -CFGENTRY (String, Edger2Path, "") - -QString* const g_extProgPaths[] = -{ - &cfg::IsecalcPath, - &cfg::IntersectorPath, - &cfg::CovererPath, - &cfg::YtruderPath, - &cfg::RectifierPath, - &cfg::Edger2Path, -}; - -CFGENTRY (Bool, IsecalcUsesWine, false) -CFGENTRY (Bool, IntersectorUsesWine, false) -CFGENTRY (Bool, CovererUsesWine, false) -CFGENTRY (Bool, YtruderUsesWine, false) -CFGENTRY (Bool, RectifierUsesWine, false) -CFGENTRY (Bool, Edger2UsesWine, false) - -bool* const g_extProgWine[] = -{ - &cfg::IsecalcUsesWine, - &cfg::IntersectorUsesWine, - &cfg::CovererUsesWine, - &cfg::YtruderUsesWine, - &cfg::RectifierUsesWine, - &cfg::Edger2UsesWine, -}; - -const char* g_extProgNames[] = -{ - "Isecalc", - "Intersector", - "Coverer", - "Ytruder", - "Rectifier", - "Edger2" -}; +ConfigOption (QString IsecalcPath) +ConfigOption (QString IntersectorPath) +ConfigOption (QString CovererPath) +ConfigOption (QString RectifierPath) +ConfigOption (QString YtruderPath) +ConfigOption (QString Edger2Path) +ConfigOption (bool IsecalcUsesWine = false) +ConfigOption (bool IntersectorUsesWine = false) +ConfigOption (bool CovererUsesWine = false) +ConfigOption (bool YtruderUsesWine = false) +ConfigOption (bool RectifierUsesWine = false) +ConfigOption (bool Edger2UsesWine = false) ExtProgramToolset::ExtProgramToolset (MainWindow* parent) : - Toolset (parent) {} + 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; +} -// ============================================================================= -// -static bool MakeTempFile (QTemporaryFile& tmp, QString& fname) +bool ExtProgramToolset::makeTempFile (QTemporaryFile& tmp, QString& fname) { if (not tmp.open()) return false; @@ -112,16 +89,38 @@ return true; } -// ============================================================================= -// -static bool CheckExtProgramPath (ExtProgramType program) +bool ExtProgramToolset::programUsesWine (ExtProgramType program) +{ +#ifndef Q_OS_WIN32 + return getWineSetting (program); +#else + return false; +#endif +} + +bool& ExtProgramToolset::getWineSetting (ExtProgramType program) { - QString& path = *g_extProgPaths[program]; + return *extProgramInfo[program].wine; +} + +QString ExtProgramToolset::getPathSetting (ExtProgramType program) +{ + return *extProgramInfo[program].path; +} + +QString ExtProgramToolset::externalProgramName (ExtProgramType program) +{ + return extProgramInfo[program].name; +} + +QString ExtProgramToolset::checkExtProgramPath(ExtProgramType program) +{ + QString& path = getPathSetting (program); if (not path.isEmpty()) return true; - ExtProgPathPrompt* dlg = new ExtProgPathPrompt (g_extProgNames[program]); + ExtProgPathPrompt* dlg = new ExtProgPathPrompt (externalProgramName (program)); if (dlg->exec() and not dlg->getPath().isEmpty()) { @@ -134,36 +133,28 @@ // ============================================================================= // -static QString ProcessExtProgError (ExtProgramType prog, QProcess& proc) +QString ExtProgramToolset::errorCodeString (ExtProgramType program, QProcess& process) { - switch (proc.error()) + switch (process.error()) { case QProcess::FailedToStart: - { - QString winemessage; + if (programUsesWine (program)) + return tr ("Program failed to start, make sure that Wine is installed and check your permissions."); -#ifndef _WIN32 - if (*g_extProgWine[prog]) - winemessage = "make sure Wine is installed and "; -#else - Q_UNUSED (prog); -#endif - - return format ("Program failed to start, %1check your permissions", winemessage); - } break; + return tr ("Program failed to start, %1check your permissions"); case QProcess::Crashed: - return "Crashed."; + return tr ("Crashed."); case QProcess::WriteError: case QProcess::ReadError: - return "I/O error."; + return tr ("I/O error."); case QProcess::UnknownError: - return "Unknown error"; + return tr ("Unknown error"); case QProcess::Timedout: - return "Timed out (30 seconds)"; + return tr ("Timed out (30 seconds)"); } return ""; @@ -171,7 +162,7 @@ // ============================================================================= // -static void WriteObjects (const LDObjectList& objects, QFile& f) +void ExtProgramToolset::writeObjects (const LDObjectList& objects, QFile& f) { for (LDObject* obj : objects) { @@ -180,7 +171,7 @@ LDSubfile* ref = static_cast<LDSubfile*> (obj); LDObjectList objs = ref->inlineContents (true, false); - WriteObjects (objs, f); + writeObjects (objs, f); for (LDObject* obj : objs) obj->destroy(); @@ -192,7 +183,7 @@ // ============================================================================= // -static void WriteObjects (const LDObjectList& objects, QString fname) +void ExtProgramToolset::writeObjects (const LDObjectList& objects, QString fname) { // Write the input file QFile f (fname); @@ -203,7 +194,7 @@ return; } - WriteObjects (objects, f); + writeObjects (objects, f); f.close(); #ifdef DEBUG @@ -213,14 +204,14 @@ // ============================================================================= // -void WriteSelection (QString fname) +void ExtProgramToolset::writeSelection (QString fname) { - WriteObjects (Selection(), fname); + writeObjects (Selection(), fname); } // ============================================================================= // -void WriteColorGroup (LDColor color, QString fname) +void ExtProgramToolset::writeColorGroup (LDColor color, QString fname) { LDObjectList objects; @@ -232,38 +223,40 @@ objects << obj; } - WriteObjects (objects, fname); + writeObjects (objects, fname); } // ============================================================================= // -bool RunExtProgram (ExtProgramType prog, QString path, QString argvstr) +bool ExtProgramToolset::runExtProgram (ExtProgramType program, QString argvstr) { + QString path = getPathSetting (program); QTemporaryFile input; QStringList argv = argvstr.split (" ", QString::SkipEmptyParts); -#ifndef _WIN32 - if (*g_extProgWine[prog]) +#ifndef Q_OS_WIN32 + if (programUsesWine (program)) { argv.insert (0, path); path = "wine"; } -#endif // _WIN32 +#endif // Q_OS_WIN32 print ("Running command: %1 %2\n", path, argv.join (" ")); if (not input.open()) return false; - QProcess proc; + QProcess process; // Begin! - proc.setStandardInputFile (input.fileName()); - proc.start (path, argv); + process.setStandardInputFile (input.fileName()); + process.start (path, argv); - if (not proc.waitForStarted()) + if (not process.waitForStarted()) { - Critical (format ("Couldn't start %1: %2\n", g_extProgNames[prog], ProcessExtProgError (prog, proc))); + Critical (format ("Couldn't start %1: %2\n", externalProgramName (program), + errorCodeString (program, process))); return false; } @@ -271,27 +264,27 @@ input.write ("\n"); // Wait while it runs - proc.waitForFinished(); + process.waitForFinished(); QString err = ""; - if (proc.exitStatus() != QProcess::NormalExit) - err = ProcessExtProgError (prog, proc); + if (process.exitStatus() != QProcess::NormalExit) + err = errorCodeString (program, process); // Check the return code - if (proc.exitCode() != 0) - err = format ("Program exited abnormally (return code %1).", proc.exitCode()); + if (process.exitCode() != 0) + err = format ("Program exited abnormally (return code %1).", process.exitCode()); if (not err.isEmpty()) { - Critical (format ("%1 failed: %2\n", g_extProgNames[prog], err)); + Critical (format ("%1 failed: %2\n", externalProgramName (program), err)); QString filename ("externalProgramOutput.txt"); QFile file (filename); if (file.open (QIODevice::WriteOnly | QIODevice::Text)) { - file.write (proc.readAllStandardOutput()); - file.write (proc.readAllStandardError()); + file.write (process.readAllStandardOutput()); + file.write (process.readAllStandardError()); print ("Wrote output and error logs to %1", QFileInfo (file).absoluteFilePath()); } else @@ -308,11 +301,11 @@ // ============================================================================= // -static void InsertOutput (QString fname, bool replace, QList<LDColor> colorsToReplace) +void ExtProgramToolset::insertOutput (QString fname, bool replace, QList<LDColor> colorsToReplace) { #ifdef DEBUG QFile::copy (fname, "./debug_lastOutput"); -#endif // RELEASE +#endif // Read the output file QFile f (fname); @@ -327,10 +320,10 @@ // If we replace the objects, delete the selection now. if (replace) - g_win->deleteSelection(); + m_window->deleteSelection(); for (LDColor color : colorsToReplace) - g_win->deleteByColor (color); + m_window->deleteByColor (color); // Insert the new objects CurrentDocument()->clearSelection(); @@ -347,7 +340,7 @@ obj->select(); } - g_win->doFullRefresh(); + m_window->doFullRefresh(); } // ============================================================================= @@ -357,7 +350,7 @@ { setlocale (LC_ALL, "C"); - if (not CheckExtProgramPath (Ytruder)) + if (not checkExtProgramPath (Ytruder)) return; QDialog* dlg = new QDialog; @@ -384,7 +377,7 @@ QString inDATName, outDATName; // Make temp files for the input and output files - if (not MakeTempFile (indat, inDATName) or not MakeTempFile (outdat, outDATName)) + if (not makeTempFile (indat, inDATName) or not makeTempFile (outdat, outDATName)) return; // Compose the command-line arguments @@ -401,7 +394,7 @@ WriteSelection (inDATName); - if (not RunExtProgram (Ytruder, cfg::YtruderPath, argv)) + if (not runExtProgram (Ytruder, argv)) return; InsertOutput (outDATName, false, {}); @@ -414,7 +407,7 @@ { setlocale (LC_ALL, "C"); - if (not CheckExtProgramPath (Rectifier)) + if (not checkExtProgramPath (Rectifier)) return; QDialog* dlg = new QDialog; @@ -428,7 +421,7 @@ QString inDATName, outDATName; // Make temp files for the input and output files - if (not MakeTempFile (indat, inDATName) or not MakeTempFile (outdat, outDATName)) + if (not makeTempFile (indat, inDATName) or not makeTempFile (outdat, outDATName)) return; // Compose arguments @@ -446,7 +439,7 @@ WriteSelection (inDATName); - if (not RunExtProgram (Rectifier, cfg::RectifierPath, argv)) + if (not runExtProgram (Rectifier, argv)) return; InsertOutput (outDATName, true, {}); @@ -459,7 +452,7 @@ { setlocale (LC_ALL, "C"); - if (not CheckExtProgramPath (Intersector)) + if (not checkExtProgramPath (Intersector)) return; QDialog* dlg = new QDialog; @@ -501,11 +494,11 @@ QTemporaryFile indat, cutdat, outdat, outdat2, edgesdat; QString inDATName, cutDATName, outDATName, outDAT2Name, edgesDATName; - if (not MakeTempFile (indat, inDATName) or - not MakeTempFile (cutdat, cutDATName) or - not MakeTempFile (outdat, outDATName) or - not MakeTempFile (outdat2, outDAT2Name) or - not MakeTempFile (edgesdat, edgesDATName)) + if (not makeTempFile (indat, inDATName) or + not makeTempFile (cutdat, cutDATName) or + not makeTempFile (outdat, outDATName) or + not makeTempFile (outdat2, outDAT2Name) or + not makeTempFile (edgesdat, edgesDATName)) { return; } @@ -534,21 +527,22 @@ outDAT2Name }); - WriteColorGroup (inCol, inDATName); - WriteColorGroup (cutCol, cutDATName); + writeColorGroup (inCol, inDATName); + writeColorGroup (cutCol, cutDATName); - if (not RunExtProgram (Intersector, cfg::IntersectorPath, argv_normal)) + if (not runExtProgram (Intersector, argv_normal)) return; - InsertOutput (outDATName, false, {inCol}); + insertOutput (outDATName, false, {inCol}); - if (repeatInverse and RunExtProgram (Intersector, cfg::IntersectorPath, argv_inverse)) - InsertOutput (outDAT2Name, false, {cutCol}); + if (repeatInverse and runExtProgram (Intersector, argv_inverse)) + insertOutput (outDAT2Name, false, {cutCol}); - if (ui.cb_edges->isChecked() and CheckExtProgramPath (Isecalc) and - RunExtProgram (Isecalc, cfg::IsecalcPath, Join ({inDATName, cutDATName, edgesDATName}))) + if (ui.cb_edges->isChecked() + and checkExtProgramPath (Isecalc) + and runExtProgram (Isecalc, Join ({inDATName, cutDATName, edgesDATName}))) { - InsertOutput (edgesDATName, false, {}); + insertOutput (edgesDATName, false, {}); } } @@ -558,7 +552,7 @@ { setlocale (LC_ALL, "C"); - if (not CheckExtProgramPath (Coverer)) + if (not checkExtProgramPath (Coverer)) return; QDialog* dlg = new QDialog; @@ -589,9 +583,9 @@ QTemporaryFile in1dat, in2dat, outdat; QString in1DATName, in2DATName, outDATName; - if (not MakeTempFile (in1dat, in1DATName) or - not MakeTempFile (in2dat, in2DATName) or - not MakeTempFile (outdat, outDATName)) + if (not makeTempFile (in1dat, in1DATName) or + not makeTempFile (in2dat, in2DATName) or + not makeTempFile (outdat, outDATName)) { return; } @@ -607,13 +601,13 @@ outDATName }); - WriteColorGroup (in1Col, in1DATName); - WriteColorGroup (in2Col, in2DATName); + writeColorGroup (in1Col, in1DATName); + writeColorGroup (in2Col, in2DATName); - if (not RunExtProgram (Coverer, cfg::CovererPath, argv)) + if (not runExtProgram (Coverer, argv)) return; - InsertOutput (outDATName, false, {}); + insertOutput (outDATName, false, {}); } // ============================================================================= @@ -622,7 +616,7 @@ { setlocale (LC_ALL, "C"); - if (not CheckExtProgramPath (Isecalc)) + if (not checkExtProgramPath (Isecalc)) return; Ui::IsecalcUI ui; @@ -655,9 +649,9 @@ QTemporaryFile in1dat, in2dat, outdat; QString in1DATName, in2DATName, outDATName; - if (not MakeTempFile (in1dat, in1DATName) or - not MakeTempFile (in2dat, in2DATName) or - not MakeTempFile (outdat, outDATName)) + if (not makeTempFile (in1dat, in1DATName) or + not makeTempFile (in2dat, in2DATName) or + not makeTempFile (outdat, outDATName)) { return; } @@ -669,10 +663,10 @@ outDATName }); - WriteColorGroup (in1Col, in1DATName); - WriteColorGroup (in2Col, in2DATName); - RunExtProgram (Isecalc, cfg::IsecalcPath, argv); - InsertOutput (outDATName, false, {}); + writeColorGroup (in1Col, in1DATName); + writeColorGroup (in2Col, in2DATName); + runExtProgram (Isecalc, argv); + insertOutput (outDATName, false, {}); } // ============================================================================= @@ -681,7 +675,7 @@ { setlocale (LC_ALL, "C"); - if (not CheckExtProgramPath (Edger2)) + if (not checkExtProgramPath (Edger2)) return; QDialog* dlg = new QDialog; @@ -694,7 +688,7 @@ QTemporaryFile in, out; QString inName, outName; - if (not MakeTempFile (in, inName) or not MakeTempFile (out, outName)) + if (not makeTempFile (in, inName) or not makeTempFile (out, outName)) return; int unmatched = ui.unmatched->currentIndex(); @@ -716,10 +710,10 @@ outName, }); - WriteSelection (inName); + writeSelection (inName); - if (not RunExtProgram (Edger2, cfg::Edger2Path, argv)) + if (not runExtProgram (Edger2, argv)) return; - InsertOutput (outName, true, {}); + insertOutput (outName, true, {}); }
--- a/src/toolsets/extprogramtoolset.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/extprogramtoolset.h Mon Aug 31 04:57:16 2015 +0300 @@ -18,6 +18,26 @@ #pragma once #include "toolset.h" +#include "configurationvaluebag.h" + +enum ExtProgramType +{ + Isecalc, + Intersector, + Coverer, + Ytruder, + Rectifier, + Edger2, + + NumExternalPrograms, +}; + +struct ExtProgramInfo +{ + QString name; + QString* path; + bool* wine; +}; class ExtProgramToolset : public Toolset { @@ -30,4 +50,21 @@ Q_INVOKABLE void isecalc(); Q_INVOKABLE void rectifier(); Q_INVOKABLE void ytruder(); + +private: + QString externalProgramName (ExtProgramType program); + bool programUsesWine (ExtProgramType program); + QString checkExtProgramPath (ExtProgramType program); + bool makeTempFile (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); + void writeColorGroup (LDColor color, QString fname); + 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 Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/filetoolset.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -30,8 +30,6 @@ #include "filetoolset.h" #include "ui_makeprim.h" -EXTERN_CFGENTRY (String, LDrawPath) - FileToolset::FileToolset (MainWindow* parent) : Toolset (parent) {} @@ -101,7 +99,7 @@ void FileToolset::setLDrawPath() { - (new LDrawPathDialog (cfg::LDrawPath, true))->exec(); + (new LDrawPathDialog (m_config->ldrawPath, true))->exec(); } void FileToolset::exit()
--- a/src/toolsets/movetoolset.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/movetoolset.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -23,9 +23,7 @@ #include "movetoolset.h" MoveToolset::MoveToolset (MainWindow* parent) : - Toolset (parent) -{ -} + Toolset (parent) {} void MoveToolset::moveSelection (bool up) { @@ -46,26 +44,26 @@ void MoveToolset::gridCoarse() { - cfg::Grid = Grid::Coarse; + m_config->grid = Grid::Coarse; m_window->updateGridToolBar(); } void MoveToolset::gridMedium() { - cfg::Grid = Grid::Medium; + m_config->grid = Grid::Medium; m_window->updateGridToolBar(); } void MoveToolset::gridFine() { - cfg::Grid = Grid::Fine; + m_config->grid = Grid::Fine; m_window->updateGridToolBar(); } void MoveToolset::moveObjects (Vertex vect) { // Apply the grid values - vect *= *CurrentGrid().coordinateSnap; + vect *= m_window->config (CurrentGrid().coordinateSnap); for (LDObject* obj : Selection()) obj->move (vect); @@ -101,34 +99,39 @@ moveObjects ({0, 0, 1}); } -static double GetRotateActionAngle() +double MoveToolset::getRotateActionAngle() { - return (Pi * *CurrentGrid().angleSnap) / 180; + return (Pi * m_window->config (CurrentGrid().angleSnap)) / 180; } void MoveToolset::rotateXPos() { - RotateObjects (1, 0, 0, GetRotateActionAngle(), Selection()); + RotateObjects (1, 0, 0, getRotateActionAngle(), Selection()); } + void MoveToolset::rotateYPos() { - RotateObjects (0, 1, 0, GetRotateActionAngle(), Selection()); + RotateObjects (0, 1, 0, getRotateActionAngle(), Selection()); } + void MoveToolset::rotateZPos() { - RotateObjects (0, 0, 1, GetRotateActionAngle(), Selection()); + RotateObjects (0, 0, 1, getRotateActionAngle(), Selection()); } + void MoveToolset::rotateXNeg() { - RotateObjects (-1, 0, 0, GetRotateActionAngle(), Selection()); + RotateObjects (-1, 0, 0, getRotateActionAngle(), Selection()); } + void MoveToolset::rotateYNeg() { - RotateObjects (0, -1, 0, GetRotateActionAngle(), Selection()); + RotateObjects (0, -1, 0, getRotateActionAngle(), Selection()); } + void MoveToolset::rotateZNeg() { - RotateObjects (0, 0, -1, GetRotateActionAngle(), Selection()); + RotateObjects (0, 0, -1, getRotateActionAngle(), Selection()); } void MoveToolset::configureRotationPoint()
--- a/src/toolsets/movetoolset.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/movetoolset.h Mon Aug 31 04:57:16 2015 +0300 @@ -48,4 +48,5 @@ private: void moveSelection (bool up); void moveObjects (Vertex vect); + double getRotateActionAngle(); };
--- a/src/toolsets/toolset.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/toolset.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -27,6 +27,7 @@ Toolset::Toolset (MainWindow* parent) : QObject (parent), + HierarchyElement (parent), m_window (parent) {} QVector<Toolset*> Toolset::createToolsets (MainWindow* parent)
--- a/src/toolsets/toolset.h Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/toolset.h Mon Aug 31 04:57:16 2015 +0300 @@ -22,14 +22,11 @@ class MainWindow; -class Toolset : public QObject +class Toolset : public QObject, public HierarchyElement { Q_OBJECT public: Toolset (MainWindow* parent); static QVector<Toolset*> createToolsets (MainWindow* parent); - -protected: - MainWindow* m_window; };
--- a/src/toolsets/viewtoolset.cpp Sun Aug 30 17:20:55 2015 +0300 +++ b/src/toolsets/viewtoolset.cpp Mon Aug 31 04:57:16 2015 +0300 @@ -28,15 +28,6 @@ #include "../glCompiler.h" #include "viewtoolset.h" -EXTERN_CFGENTRY (Bool, DrawWireframe) -EXTERN_CFGENTRY (Bool, BFCRedGreenView) -EXTERN_CFGENTRY (Bool, DrawAngles) -EXTERN_CFGENTRY (Bool, RandomColors) -EXTERN_CFGENTRY (Bool, DrawSurfaces) -EXTERN_CFGENTRY (Bool, DrawEdgeLines) -EXTERN_CFGENTRY (Bool, DrawConditionalLines) -EXTERN_CFGENTRY (Bool, DrawAxes) - ViewToolset::ViewToolset (MainWindow *parent) : Toolset (parent) {} @@ -135,7 +126,7 @@ void ViewToolset::axes() { - cfg::DrawAxes = not cfg::DrawAxes; + m_config->drawAxes = not m_config->drawAxes; m_window->updateActions(); m_window->R()->update(); } @@ -160,7 +151,7 @@ void ViewToolset::wireframe() { - cfg::DrawWireframe = not cfg::DrawWireframe; + m_config->drawWireframe = not m_config->drawWireframe; m_window->R()->refresh(); } @@ -182,7 +173,7 @@ void ViewToolset::drawAngles() { - cfg::DrawAngles = not cfg::DrawAngles; + m_config->drawAngles = not m_config->drawAngles; m_window->R()->refresh(); } @@ -251,10 +242,10 @@ void ViewToolset::bfcView() { - cfg::BFCRedGreenView = not cfg::BFCRedGreenView; + m_config->bfcRedGreenView = not m_config->bfcRedGreenView; - if (cfg::BFCRedGreenView) - cfg::RandomColors = false; + if (m_config->bfcRedGreenView) + m_config->randomColors = false; m_window->updateActions(); m_window->R()->refresh(); @@ -282,10 +273,10 @@ void ViewToolset::randomColors() { - cfg::RandomColors = not cfg::RandomColors; + m_config->randomColors = not m_config->randomColors; - if (cfg::RandomColors) - cfg::BFCRedGreenView = false; + if (m_config->randomColors) + m_config->bfcRedGreenView = false; m_window->updateActions(); m_window->R()->refresh(); @@ -293,18 +284,18 @@ void ViewToolset::drawSurfaces() { - cfg::DrawSurfaces = not cfg::DrawSurfaces; + m_config->drawSurfaces = not m_config->drawSurfaces; m_window->updateActions(); } void ViewToolset::drawEdgeLines() { - cfg::DrawEdgeLines = not cfg::DrawEdgeLines; + m_config->drawEdgeLines = not m_config->drawEdgeLines; m_window->updateActions(); } void ViewToolset::drawConditionalLines() { - cfg::DrawConditionalLines = not cfg::DrawConditionalLines; + m_config->drawConditionalLines = 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/updaterevision.py Mon Aug 31 04:57:16 2015 +0300 @@ -0,0 +1,67 @@ +#!/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 outputfile + +def main(): + import subprocess + from datetime import datetime + parser = argparser.ArgumentParser (description='Writes a header file with Hg commit information') + parser.add_argument ('output') + args = parser.parse_args() + f = OutputFile (args.output) + data = subprocess.check_output (['hg', 'log', '-r.', '--template', + '{node|short} {branch} {date|hgdate}']).replace ('\n', '').split (' ') + + rev = data[0] + branch = data[1] + timestamp = int (data[2]) + date = datetime.utcfromtimestamp (timestamp) + datestring = date.strftime ('%y%m%d-%H%M') if date.year >= 2000 else '000000-0000' + + if len(rev) > 7: + rev = rev[0:7] + + if subprocess.check_output (['hg', 'id', '-n']).replace ('\n', '')[-1] == '+': + rev += '+' + + f.write ('#define HG_NODE "%s"\n' % rev) + f.write ('#define HG_BRANCH "%s"\n' % branch) + f.write ('#define HG_DATE_VERSION "%s"\n' % datestring) + f.write ('#define HG_DATE_STRING "%s"\n' % date.strftime ('%d %b %Y')) + f.write ('#define HG_DATE_TIME %d\n' % int (timestamp)) + if f.save(): + print '%s updated to %s' % (f.filename, rev) + +if __name__ == '__main__': + main() \ No newline at end of file
--- a/updaterevision.py Sun Aug 30 17:20:55 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -# -# Copyright 2014 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 sys -import subprocess -from datetime import datetime - -if len (sys.argv) != 2: - print 'usage: %s <output>' % sys.argv[0] - quit (1) - -oldrev = '' - -try: - with open (sys.argv[1]) as fp: - oldrev = fp.readline().replace ('\n', '').replace ('// ', '') -except IOError: - pass - -delim='@'*10 -rev, branch, timestampstr, tags = subprocess.check_output (['hg', 'log', '-r.', '--template', - delim.join (['{node|short}', '{branch}', '{date|hgdate}', '{tags}'])]).replace ('\n', '').split (delim) - -timestamp = int (timestampstr.split(' ')[0]) -date = datetime.utcfromtimestamp (timestamp) -datestring = date.strftime ('%y%m%d-%H%M') if date.year >= 2000 else '000000-0000' - -if len(rev) > 7: - rev = rev[0:7] - -if subprocess.check_output (['hg', 'id', '-n']).replace ('\n', '')[-1] == '+': - rev += '+' - -if rev == oldrev: - print "%s is up to date at %s" % (sys.argv[1], rev) - quit (0) - -with open (sys.argv[1], 'w') as fp: - fp.write ('// %s\n' % rev) - fp.write ('#define HG_NODE "%s"\n' % rev) - fp.write ('#define HG_BRANCH "%s"\n' % branch) - fp.write ('#define HG_DATE_VERSION "%s"\n' % datestring) - fp.write ('#define HG_DATE_STRING "%s"\n' % date.strftime ('%d %b %Y')) - fp.write ('#define HG_DATE_TIME %d\n' % int (timestamp)) - - if tags and tags != 'tip': - fp.write ('#define HG_TAG "%s"\n' % tags.split(' ')[0]) - - print '%s updated to %s' % (sys.argv[1], rev)