Sun, 12 Feb 2017 16:59:35 +0200
Moved the definitions of all configuration options into a new text file and made the configuration collector read that.
--- a/CMakeLists.txt Sun Feb 12 16:02:44 2017 +0200 +++ b/CMakeLists.txt Sun Feb 12 16:59:35 2017 +0200 @@ -168,6 +168,10 @@ src/dialogs/openprogressdialog.ui ) +set (LDFORGE_OTHER_FILES + src/configurationoptions.txt +) + set (LDFORGE_RESOURCES ldforge.qrc) # set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lGLU") @@ -203,17 +207,18 @@ ${LDFORGE_QRC} ${LDFORGE_FORMS_HEADERS} ${CMAKE_BINARY_DIR}/configuration.cpp) -set_source_files_properties (${LDFORGE_HEADERS} PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties(${LDFORGE_HEADERS} PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties(${LDFORGE_OTHER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) set_target_properties (ldforge PROPERTIES AUTOMOC 1) target_link_libraries (ldforge Qt5::Widgets Qt5::Network Qt5::OpenGL ${OPENGL_LIBRARIES}) add_custom_target (config_collection ALL - COMMAND python + COMMAND python3 "${CMAKE_SOURCE_DIR}/tools/configcollector.py" --header ${CMAKE_BINARY_DIR}/configuration.h --source ${CMAKE_BINARY_DIR}/configuration.cpp --sourcedir ${CMAKE_SOURCE_DIR}/src - ${LDFORGE_SOURCES} + ${CMAKE_SOURCE_DIR}/src/configurationoptions.txt WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) add_custom_target(lengthcheck ALL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/configurationoptions.txt Sun Feb 12 16:59:35 2017 +0200 @@ -0,0 +1,79 @@ +# +# LDForge configuration option definitions +# +# Syntax: +# option OptionName = value +# option OptionName = type {value} +# # comment +# + +# Editing options +option Grid = 1 +option GridCoarseCoordinateSnap = 5.0 +option GridCoarseAngleSnap = 45.0 +option GridCoarseBezierCurveSegments = 8 +option GridMediumCoordinateSnap = 1.0 +option GridMediumAngleSnap = 22.5 +option GridMediumBezierCurveSegments = 16 +option GridFineCoordinateSnap = 0.1 +option GridFineAngleSnap = 7.5 +option GridFineBezierCurveSegments = 32 +option RotationPointType = 0 +option CustomRotationPoint = Vertex {} +option ColorizeObjectsList = true +option QuickColorToolbar = "4:25:14:27:2:3:11:1:22:|:0:72:71:15" +option ListImplicitFiles = false +option HiddenToolbars = QStringList {} +option RecentFiles = QStringList {} +option TryDownloadMissingFiles = false +option DefaultName = "" +option DefaultUser = "" +option UseCaLicense = true +option RoundPositionPrecision = 3 +option RoundMatrixPrecision = 4 +option SplitLinesSegments = 5 + +# External program options +option IsecalcPath = "" +option IntersectorPath = "" +option CovererPath = "" +option RectifierPath = "" +option YtruderPath = "" +option Edger2Path = "" +option IsecalcUsesWine = false +option IntersectorUsesWine = false +option CovererUsesWine = false +option YtruderUsesWine = false +option RectifierUsesWine = false +option Edger2UsesWine = false + +# Rendering options +option BackgroundColor = QColor {"#FFFFFF"} +option MainColor = QColor {"#A0A0A0"} +option MainColorAlpha = 1.0 +option SelectColorBlend = "#0080FF" +option LineThickness = 2 +option BfcRedGreenView = false +option Camera = 6 +option BlackEdges = false +option DrawAxes = false +option DrawWireframe = false +option UseLogoStuds = false +option AntiAliasedLines = true +option RandomColors = false +option HighlightObjectBelowCursor = true +option DrawSurfaces = true +option DrawEdgeLines = true +option DrawConditionalLines = true +option Lighting = true +option DrawLineLengths = true +option DrawAngles = false + +# File management options +option DownloadFilePath = "" +option GuessDownloadPaths = true +option AutoCloseDownloadDialog = true +option LDrawPath = "" + +# Other options +option FirstStart = true
--- a/src/documentmanager.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/documentmanager.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -25,8 +25,6 @@ #include "documentloader.h" #include "glRenderer.h" -ConfigOption (QStringList RecentFiles) -ConfigOption (bool TryDownloadMissingFiles = false) const QStringList DocumentManager::specialSubdirectories {"s", "48", "8"}; enum
--- a/src/editmodes/abstractEditMode.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/editmodes/abstractEditMode.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -32,9 +32,6 @@ #include "../miscallenous.h" #include "../grid.h" -ConfigOption (bool DrawLineLengths = true) -ConfigOption (bool DrawAngles = false) - /* * Base class constructor of the abstract editing mode. */
--- a/src/glCompiler.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/glCompiler.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -43,8 +43,6 @@ { GL_STACK_OVERFLOW, "The operation would have caused an overflow" }, }; -ConfigOption (QString SelectColorBlend = "#0080FF") - void CheckGLErrorImpl (const char* file, int line) { QString errmsg;
--- a/src/glRenderer.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/glRenderer.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -46,24 +46,6 @@ {{ 1, 0, 0 }, X, Z, false, false, false }, // free (defensive dummy data) }; -ConfigOption (QColor BackgroundColor = "#FFFFFF") -ConfigOption (QColor 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) -ConfigOption (bool Lighting = true) - const QPen GLRenderer::thinBorderPen {QColor {0, 0, 0, 208}, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin}; // ============================================================================= @@ -1097,4 +1079,4 @@ const Model* GLRenderer::model() const { return m_model; -} \ No newline at end of file +}
--- a/src/grid.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/grid.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -19,21 +19,6 @@ #include "grid.h" #include "configuration.h" - -ConfigOption (int Grid = 1) -ConfigOption (qreal GridCoarseCoordinateSnap = 5.0) -ConfigOption (qreal GridCoarseAngleSnap = 45.0) -ConfigOption (int GridCoarseBezierCurveSegments = 8) -ConfigOption (qreal GridMediumCoordinateSnap = 1.0) -ConfigOption (qreal GridMediumAngleSnap = 22.5) -ConfigOption (qreal GridMediumBezierCurveSegments = 16) -ConfigOption (qreal GridFineCoordinateSnap = 0.1) -ConfigOption (qreal GridFineAngleSnap = 7.5) -ConfigOption (qreal GridFineBezierCurveSegments = 32) -ConfigOption (int RotationPointType = 0) -ConfigOption (Vertex CustomRotationPoint = Origin) - - Grid::Grid(QObject* parent) : HierarchyElement(parent) {}
--- a/src/ldObject.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/ldObject.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -27,10 +27,6 @@ #include "colors.h" #include "glCompiler.h" -ConfigOption (QString DefaultName = "") -ConfigOption (QString DefaultUser = "") -ConfigOption (bool UseCaLicense = true) - // List of all LDObjects QMap<int32, LDObject*> g_allObjects;
--- a/src/ldpaths.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/ldpaths.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -21,8 +21,6 @@ #include "mainwindow.h" #include "dialogs/ldrawpathdialog.h" -ConfigOption (QString LDrawPath) - LDPaths::LDPaths (Configuration *config, QObject* parent) : QObject(parent), m_config(config),
--- a/src/macros.h Sun Feb 12 16:02:44 2017 +0200 +++ b/src/macros.h Sun Feb 12 16:59:35 2017 +0200 @@ -53,8 +53,6 @@ template<typename T> struct EnumLimits {}; -#define ConfigOption(...) - #define DEFINE_FLAG_ACCESS_METHODS(FLAGS) \ bool checkFlag(decltype(FLAGS) flag) const { return !!(FLAGS & flag); } \ void setFlag(decltype(FLAGS) flag) { FLAGS |= flag; } \
--- a/src/main.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/main.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -25,8 +25,6 @@ MainWindow* g_win = nullptr; const Vertex Origin (0.0f, 0.0f, 0.0f); -ConfigOption (bool FirstStart = true) - // ============================================================================= // int main (int argc, char* argv[])
--- a/src/mainwindow.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/mainwindow.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -47,11 +47,6 @@ Toolset* object; }; -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(class Configuration& config, QWidget* parent, Qt::WindowFlags flags) :
--- a/src/partdownloader.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/partdownloader.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -27,10 +27,6 @@ #include "glRenderer.h" #include "documentmanager.h" -ConfigOption(QString DownloadFilePath) -ConfigOption(bool GuessDownloadPaths = true) -ConfigOption (bool AutoCloseDownloadDialog = true) - const char* g_unofficialLibraryURL = "http://ldraw.org/library/unofficial/"; PartDownloader::PartDownloader (QWidget* parent)
--- a/src/toolsets/algorithmtoolset.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/toolsets/algorithmtoolset.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -40,10 +40,6 @@ #include "ui_addhistoryline.h" #include "algorithmtoolset.h" -ConfigOption (int RoundPositionPrecision = 3) -ConfigOption (int RoundMatrixPrecision = 4) -ConfigOption (int SplitLinesSegments = 5) - AlgorithmToolset::AlgorithmToolset (MainWindow* parent) : Toolset (parent) { @@ -571,4 +567,4 @@ // Failed to save. subfile->close(); } -} \ No newline at end of file +}
--- a/src/toolsets/extprogramtoolset.cpp Sun Feb 12 16:02:44 2017 +0200 +++ b/src/toolsets/extprogramtoolset.cpp Sun Feb 12 16:59:35 2017 +0200 @@ -44,21 +44,6 @@ #include "ui_isecalc.h" #include "ui_edger2.h" -// ============================================================================= -// -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) {
--- a/tools/configcollector.py Sun Feb 12 16:02:44 2017 +0200 +++ b/tools/configcollector.py Sun Feb 12 16:59:35 2017 +0200 @@ -1,7 +1,7 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding: utf-8 # -# Copyright 2015 Teemu Piippo +# Copyright 2015 - 2017 Teemu Piippo # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -37,117 +37,79 @@ import re from pprint import pprint -passbyvalue = {'int', 'bool', 'float', 'double' } -variantconversions = { - 'QString': 'toString', - 'bool': 'toBool', - 'int': 'toInt', - 'float': 'toFloat', - 'double': 'toDouble', - 'QChar': 'toChar', - 'QBitArray': 'toBitArray', - 'QDate': 'toDate', - 'QDateTime': 'toDateTime', - 'uint': 'toUInt', - 'unsigned int': 'toUInt', - 'QUrl': 'toUrl', - 'QTime': 'toTime', - 'QPoint': 'toPoint', - 'QPointF': 'toPointF', - 'QSize': 'toSize', - 'QSizeF': 'toSizeF', - 'qreal': 'toReal', - 'QRect': 'toRect', - 'QRectF': 'toRectF', - 'QLine': 'toLine', - 'QLineF': 'toLineF', - 'QEasingCurve': 'toEasingCurve', - 'qlonglong': 'toLongLong', - 'qulonglong': 'toULongLong', -} +passbyvalue = {'int', 'bool', 'float', 'double', 'qreal'} + +def deduce_type(value): + ''' + Try to determine the type of value from the value itself. + ''' + if value in ('true', 'false'): + return 'bool' + + if value.startswith('"') and value.endswith('"'): + return 'QString' + + try: + int(value) + return 'int' + except: + pass + + try: + float(value) + return 'double' + except: + pass + + if endswith(value, 'f'): + try: + float(value[:-1]) + return 'float' + except: + pass + + raise ValueError('unable to deduce type of %r' % value) 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) + def collect (self, filename): + with open(filename, 'r') as file: + for line in file: + line = line.strip() + if line and not line.startswith('#'): + match = re.search('^option (\w+) = (.+)$', line) + if not match: + raise ValueError('unable to parse: %r' % line) + name, value = match.groups() + match = re.search(r'^(\w+)\s*\{(.*)\}$', value) + try: + type, value = match.groups() + if not value: + value = type + ' {}' + except: + type = deduce_type(value) + self.add_config_declaration((name, type, value)) 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['toggler'] = 'toggle' + caseconversions.convert_case (decl['name'], style='camel') decl['typecref'] = 'const %s&' % decl['type'] if decl['type'] not in passbyvalue else decl['type'] - - try: - decl['valuefunc'] = variantconversions[decl['type']] - except KeyError: - decl['valuefunc'] = 'value<' + decl['type'] + '>' + decl['valuefunc'] = 'value<' + decl['type'] + '>' - if enumname not in self.enums: - self.enums[enumname] = dict ( - name = enumname, - typename = decl['type'], - values = [], - numvalues = 0, - highestkey = -1) + def add_config_declaration (self, decl): + declname, decltype, decldefault = decl + self.decls.append (dict (name=declname, type=decltype, default=decldefault)) - 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 + # 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\w+', decltype)) def write_header (self, fp): fp.write ('#pragma once\n') @@ -177,7 +139,6 @@ write ('private:\n') write ('\tQMap<QString, QVariant> m_defaults;\n') write ('\tclass QSettings* m_settings;\n') - write ('};\n') def write_source (self, fp, headername): @@ -246,14 +207,13 @@ def main(): parser = argparse.ArgumentParser (description='Collects a list of configuration objects') - parser.add_argument ('inputs', nargs='+') + parser.add_argument ('input') 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() + collector.collect (args.input) header = outputfile.OutputFile (args.header) source = outputfile.OutputFile (args.source) collector.write_source (source, headername=args.header)