Moved the definitions of all configuration options into a new text file and made the configuration collector read that.

Sun, 12 Feb 2017 16:59:35 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 12 Feb 2017 16:59:35 +0200
changeset 1125
d8f94e56d42e
parent 1124
bd151d5c42e6
child 1126
508950e27fcd

Moved the definitions of all configuration options into a new text file and made the configuration collector read that.

CMakeLists.txt file | annotate | diff | comparison | revisions
src/configurationoptions.txt file | annotate | diff | comparison | revisions
src/documentmanager.cpp file | annotate | diff | comparison | revisions
src/editmodes/abstractEditMode.cpp file | annotate | diff | comparison | revisions
src/glCompiler.cpp file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/grid.cpp file | annotate | diff | comparison | revisions
src/ldObject.cpp file | annotate | diff | comparison | revisions
src/ldpaths.cpp file | annotate | diff | comparison | revisions
src/macros.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/partdownloader.cpp file | annotate | diff | comparison | revisions
src/toolsets/algorithmtoolset.cpp file | annotate | diff | comparison | revisions
src/toolsets/extprogramtoolset.cpp file | annotate | diff | comparison | revisions
tools/configcollector.py file | annotate | diff | comparison | revisions
--- 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)

mercurial