Draft: new get_param function with defaults
This PR introduces a new get_param function. For its default values it checks a dictionary largely filled by reading the preferences UI files. The goal is to have all defaults in one place to avoid inconsistencies. The dictionary is created once and then stored in a global variable. Once merged this function will be implemented in Draft and Arch. The get_param function in utils.py will become obsolete. Related issue: #10176
This commit is contained in:
@@ -21,17 +21,23 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
""" Contains a parameter observer class and several related functions."""
|
||||
""" Contains a parameter observer class and parameter related functions."""
|
||||
|
||||
import PySide.QtCore as QtCore
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
from PySide import QtGui
|
||||
import Draft_rc
|
||||
import Arch_rc
|
||||
|
||||
from draftutils import init_draft_statusbar
|
||||
from draftutils import utils
|
||||
from draftutils.translate import translate
|
||||
from draftviewproviders import view_base
|
||||
|
||||
if App.GuiUp:
|
||||
import FreeCADGui as Gui
|
||||
from PySide import QtGui
|
||||
|
||||
class ParamObserverDraft:
|
||||
|
||||
@@ -193,8 +199,9 @@ of existing objects in all opened documents?""")
|
||||
|
||||
|
||||
def _param_observer_start():
|
||||
_param_observer_start_draft()
|
||||
_param_observer_start_view()
|
||||
if App.GuiUp:
|
||||
_param_observer_start_draft()
|
||||
_param_observer_start_view()
|
||||
|
||||
|
||||
def _param_observer_start_draft(param_grp = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")):
|
||||
@@ -203,3 +210,331 @@ def _param_observer_start_draft(param_grp = App.ParamGet("User parameter:BaseApp
|
||||
|
||||
def _param_observer_start_view(param_grp = App.ParamGet("User parameter:BaseApp/Preferences/View")):
|
||||
param_grp.AttachManager(ParamObserverView())
|
||||
|
||||
|
||||
def _param_from_PrefCheckBox(widget):
|
||||
value = False
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "checked": # Can be missing.
|
||||
value = elem.find("bool").text == "true"
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefRadioButton(widget):
|
||||
return _param_from_PrefCheckBox(widget)
|
||||
|
||||
|
||||
def _param_from_PrefComboBox(widget):
|
||||
value = 0
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "currentIndex": # Can be missing.
|
||||
value = int(elem.find("number").text)
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefSpinBox(widget):
|
||||
value = 0
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "value": # Can be missing.
|
||||
value = int(elem.find("number").text)
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefDoubleSpinBox(widget):
|
||||
value = 0.0
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "value": # Can be missing.
|
||||
value = float(elem.find("double").text)
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefUnitSpinBox(widget):
|
||||
return _param_from_PrefDoubleSpinBox(widget)
|
||||
|
||||
|
||||
def _param_from_PrefQuantitySpinBox(widget):
|
||||
value = "0"
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "rawValue": # Not sure if this can be missing.
|
||||
value = elem.find("double").text.rstrip(".0")
|
||||
elif att_name == "unit":
|
||||
unit = elem.find("string").text
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
value = value + " " + unit
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefColorButton(widget):
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "color":
|
||||
sub = list(elem)[0]
|
||||
r = int(sub.find("red").text)
|
||||
g = int(sub.find("green").text)
|
||||
b = int(sub.find("blue").text)
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
value = (r << 24) + (g << 16) + (b << 8) + 255
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefLineEdit(widget):
|
||||
value = None
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "text": # Can be missing.
|
||||
value = elem.find("string").text # If text is missing value will be None here.
|
||||
elif att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
if value is None:
|
||||
value = ""
|
||||
return path, entry, value
|
||||
|
||||
|
||||
def _param_from_PrefFileChooser(widget):
|
||||
for elem in list(widget):
|
||||
if "name" in elem.keys():
|
||||
att_name = elem.attrib["name"]
|
||||
if att_name == "prefEntry":
|
||||
entry = elem.find("cstring").text
|
||||
elif att_name == "prefPath":
|
||||
path = elem.find("cstring").text
|
||||
return path, entry, ""
|
||||
|
||||
|
||||
def _get_param_dictionary():
|
||||
|
||||
# print("Creating preferences dictionary...")
|
||||
|
||||
param_dict = {}
|
||||
|
||||
# Draft parameters that are not in the preferences:
|
||||
param_dict["Mod/Draft"] = {
|
||||
"DefaultAnnoDisplayMode": ("int", 0),
|
||||
"DefaultDisplayMode": ("int", 0),
|
||||
"DefaultDrawStyle": ("int", 0),
|
||||
"Draft_array_fuse": ("bool", False),
|
||||
"Draft_array_Link": ("bool", True),
|
||||
"fillmode": ("bool", True),
|
||||
"HatchPatternResolution": ("int", 128),
|
||||
"labeltype": ("string", "Custom"),
|
||||
"snapModes": ("string", "100000000000000"),
|
||||
"snapRange": ("int", 8),
|
||||
|
||||
|
||||
}
|
||||
|
||||
# Arch parameters that are not in the preferences:
|
||||
param_dict["Mod/Arch"] = {
|
||||
|
||||
|
||||
}
|
||||
|
||||
# For the View parameters we do not check the preferences:
|
||||
param_dict["View"] = {
|
||||
"DefaultShapeColor": ("unsigned", 3435973887),
|
||||
"DefaultShapeLineColor": ("unsigned", 255),
|
||||
"DefaultShapeLineWidth": ("int", 2),
|
||||
"DefaultShapePointSize": ("int", 2),
|
||||
"DefaultShapeTransparency": ("int", 0),
|
||||
"DefaultShapeVertexColor": ("unsigned", 255),
|
||||
}
|
||||
|
||||
# Preferences ui files are stored in resource files.
|
||||
# For the Draft Workbench: /Mod/Draft/Draft_rc.py
|
||||
# For the Arch Workbench: /Mod/Arch/Arch_rc.py
|
||||
for fnm in (":/ui/preferences-draft.ui",
|
||||
":/ui/preferences-draftinterface.ui",
|
||||
":/ui/preferences-draftsnap.ui",
|
||||
":/ui/preferences-drafttexts.ui",
|
||||
":/ui/preferences-draftvisual.ui",
|
||||
":/ui/preferences-dwg.ui",
|
||||
":/ui/preferences-dxf.ui",
|
||||
":/ui/preferences-oca.ui",
|
||||
":/ui/preferences-svg.ui",
|
||||
":/ui/preferences-arch.ui",
|
||||
":/ui/preferences-archdefaults.ui",
|
||||
":/ui/preferences-dae.ui",
|
||||
":/ui/preferences-ifc.ui",
|
||||
":/ui/preferences-ifc-export.ui"):
|
||||
|
||||
# https://stackoverflow.com/questions/14750997/load-txt-file-from-resources-in-python
|
||||
fd = QtCore.QFile(fnm)
|
||||
if fd.open(QtCore.QIODevice.ReadOnly | QtCore.QFile.Text):
|
||||
text = QtCore.QTextStream(fd).readAll()
|
||||
fd.close()
|
||||
else:
|
||||
print("Preferences file " + fnm + " not found")
|
||||
continue
|
||||
|
||||
# https://docs.python.org/3/library/xml.etree.elementtree.html
|
||||
root = ET.fromstring(text)
|
||||
|
||||
# Get all preference widgets:
|
||||
# pref_widgets = [wid for wid in root.iter("widget") if "Gui::Pref" in wid.attrib["class"]]
|
||||
|
||||
for widget in root.iter("widget"):
|
||||
if "class" in widget.keys():
|
||||
path = None
|
||||
att_class = widget.attrib["class"]
|
||||
|
||||
if att_class == "Gui::PrefCheckBox":
|
||||
path, entry, value = _param_from_PrefCheckBox(widget)
|
||||
typ = "bool"
|
||||
elif att_class == "Gui::PrefRadioButton":
|
||||
path, entry, value = _param_from_PrefRadioButton(widget)
|
||||
typ = "bool"
|
||||
elif att_class == "Gui::PrefComboBox":
|
||||
path, entry, value = _param_from_PrefComboBox(widget)
|
||||
typ = "int"
|
||||
elif att_class == "Gui::PrefSpinBox":
|
||||
path, entry, value = _param_from_PrefSpinBox(widget)
|
||||
typ = "int"
|
||||
elif att_class == "Gui::PrefDoubleSpinBox":
|
||||
path, entry, value = _param_from_PrefDoubleSpinBox(widget)
|
||||
typ = "float"
|
||||
elif att_class == "Gui::PrefUnitSpinBox":
|
||||
path, entry, value = _param_from_PrefUnitSpinBox(widget)
|
||||
typ = "float"
|
||||
elif att_class == "Gui::PrefQuantitySpinBox":
|
||||
path, entry, value = _param_from_PrefQuantitySpinBox(widget)
|
||||
typ = "string"
|
||||
elif att_class == "Gui::PrefColorButton":
|
||||
path, entry, value = _param_from_PrefColorButton(widget)
|
||||
typ = "unsigned"
|
||||
elif att_class == "Gui::PrefLineEdit":
|
||||
path, entry, value = _param_from_PrefLineEdit(widget)
|
||||
typ = "string"
|
||||
elif att_class == "Gui::PrefFileChooser":
|
||||
path, entry, value = _param_from_PrefFileChooser(widget)
|
||||
typ = "string"
|
||||
|
||||
if path is not None:
|
||||
if path in param_dict:
|
||||
param_dict[path][entry] = (typ, value)
|
||||
else:
|
||||
param_dict[path] = {entry: (typ, value)}
|
||||
|
||||
return param_dict
|
||||
|
||||
|
||||
PARAM_DICT = _get_param_dictionary()
|
||||
|
||||
|
||||
# get_param("gridSpacing")
|
||||
def get_param(entry, path="Mod/Draft"):
|
||||
"""Return a stored parameter value or its default.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
entry: str
|
||||
Name of the parameter.
|
||||
path: str, optional
|
||||
Defaults to "Mod/Draft".
|
||||
The path where the parameter can be found.
|
||||
This string is appended to "User parameter:BaseApp/Preferences/".
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool, float, int or str (if successful) or `None`.
|
||||
"""
|
||||
if path not in PARAM_DICT:
|
||||
return None
|
||||
if entry not in PARAM_DICT[path]:
|
||||
return None
|
||||
param = App.ParamGet("User parameter:BaseApp/Preferences/" + path)
|
||||
typ, default = PARAM_DICT[path][entry]
|
||||
if typ == "bool":
|
||||
return param.GetBool(entry, default)
|
||||
if typ == "float":
|
||||
return param.GetFloat(entry, default)
|
||||
if typ == "int":
|
||||
return param.GetInt(entry, default)
|
||||
if typ == "string":
|
||||
return param.GetString(entry, default)
|
||||
if typ == "unsigned":
|
||||
return param.GetUnsigned(entry, default)
|
||||
return None
|
||||
|
||||
|
||||
def get_param_arch(entry):
|
||||
return get_param(entry, path="Mod/Arch")
|
||||
|
||||
|
||||
def set_param(entry, value, path="Mod/Draft"):
|
||||
"""Store a parameter value.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
entry: str
|
||||
Name of the parameter.
|
||||
value: bool, float, int or str
|
||||
New value of the correct type.
|
||||
path: str, optional
|
||||
Defaults to "Mod/Draft".
|
||||
The path where the parameter can be found.
|
||||
This string is appended to "User parameter:BaseApp/Preferences/".
|
||||
|
||||
Returns
|
||||
-------
|
||||
`True` (if successful) or `False`.
|
||||
"""
|
||||
if path not in PARAM_DICT:
|
||||
return False
|
||||
if entry not in PARAM_DICT[path]:
|
||||
return False
|
||||
param = App.ParamGet("User parameter:BaseApp/Preferences/" + path)
|
||||
typ = PARAM_DICT[path][entry][0]
|
||||
ret = True
|
||||
if typ == "bool":
|
||||
param.SetBool(entry, value)
|
||||
elif typ == "float":
|
||||
param.SetFloat(entry, value)
|
||||
elif typ == "int":
|
||||
param.SetInt(entry, value)
|
||||
elif typ == "string":
|
||||
param.SetString(entry, value)
|
||||
elif typ == "unsigned":
|
||||
param.SetUnsigned(entry, value)
|
||||
else:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
|
||||
def set_param_arch(entry, value):
|
||||
return set_param(entry, value, path="Mod/Arch")
|
||||
|
||||
Reference in New Issue
Block a user