Download src/Mod/Draft/draftutils/params.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 34.3 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Draft/draftutils/params.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Draft/draftutils/params.py
-
curl -L -o params.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Draft/draftutils/params.py
34.3 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # *************************************************************************** | |
| # * * | |
| # * Copyright (c) 2023 FreeCAD Project Association * | |
| # * * | |
| # * This file is part of FreeCAD. * | |
| # * * | |
| # * FreeCAD is free software: you can redistribute it and/or modify it * | |
| # * under the terms of the GNU Lesser General Public License as * | |
| # * published by the Free Software Foundation, either version 2.1 of the * | |
| # * License, or (at your option) any later version. * | |
| # * * | |
| # * FreeCAD is distributed in the hope that it will be useful, but * | |
| # * WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * | |
| # * Lesser General Public License for more details. * | |
| # * * | |
| # * You should have received a copy of the GNU Lesser General Public * | |
| # * License along with FreeCAD. If not, see * | |
| # * <https://www.gnu.org/licenses/>. * | |
| # * * | |
| # *************************************************************************** | |
| """Contains a parameter observer class and parameter related functions.""" | |
| import os | |
| import PySide.QtCore as QtCore | |
| import xml.etree.ElementTree as ET | |
| import FreeCAD as App | |
| import Draft_rc | |
| try: | |
| import Arch_rc | |
| except ModuleNotFoundError: | |
| pass | |
| from draftutils.translate import translate | |
| if App.GuiUp: | |
| import FreeCADGui as Gui | |
| from PySide import QtWidgets | |
| class ParamObserverDraft: | |
| def slotParamChanged(self, param_grp, typ, entry, value): | |
| if entry == "textheight": | |
| _param_observer_callback_tray() | |
| return | |
| if entry in ( | |
| "gridBorder", | |
| "gridShowHuman", | |
| "coloredGridAxes", | |
| "gridEvery", | |
| "gridSpacing", | |
| "gridSize", | |
| "gridTransparency", | |
| "gridColor", | |
| ): | |
| _param_observer_callback_grid() | |
| return | |
| if entry == "DefaultAnnoScaleMultiplier": | |
| _param_observer_callback_scalemultiplier(value) | |
| return | |
| if entry == "SnapBarShowOnlyDuringCommands": | |
| _param_observer_callback_snapbar(value) | |
| return | |
| if entry == "DisplayStatusbarSnapWidget": | |
| _param_observer_callback_snapwidget() | |
| return | |
| if entry == "DisplayStatusbarScaleWidget": | |
| _param_observer_callback_scalewidget() | |
| return | |
| if entry == "snapStyle": | |
| _param_observer_callback_snapstyle() | |
| return | |
| if entry == "snapcolor": | |
| _param_observer_callback_snapcolor() | |
| return | |
| if entry == "patternFile": | |
| _param_observer_callback_svg_pattern() | |
| return | |
| class ParamObserverView: | |
| def slotParamChanged(self, param_grp, typ, entry, value): | |
| if entry in ("DefaultShapeColor", "DefaultShapeLineColor", "DefaultShapeLineWidth"): | |
| _param_observer_callback_tray() | |
| return | |
| if entry == "MarkerSize": | |
| _param_observer_callback_snaptextsize() | |
| return | |
| def _param_observer_callback_tray(): | |
| if not hasattr(Gui, "draftToolBar"): | |
| return | |
| tray = Gui.draftToolBar.tray | |
| if tray is None: | |
| return | |
| Gui.draftToolBar.setStyleButton() | |
| def _param_observer_callback_scalemultiplier(value): | |
| # value is a string. | |
| # import has to happen here to avoid circular imports | |
| from draftutils import init_draft_statusbar | |
| if not value: | |
| return | |
| value = float(value) | |
| if value <= 0: | |
| return | |
| mw = Gui.getMainWindow() | |
| sb = mw.statusBar() | |
| scale_widget = sb.findChild(QtWidgets.QToolBar, "draft_scale_widget") | |
| if scale_widget is not None: | |
| scale_label = init_draft_statusbar.scale_to_label(1 / value) | |
| scale_widget.scaleLabel.setText(scale_label) | |
| def _param_observer_callback_grid(): | |
| if hasattr(App, "draft_working_planes") and hasattr(Gui, "Snapper"): | |
| try: | |
| trackers = Gui.Snapper.trackers | |
| for wp in App.draft_working_planes[1]: | |
| view = wp._view | |
| if view in trackers[0]: | |
| i = trackers[0].index(view) | |
| grid = trackers[1][i] | |
| grid.pts = [] | |
| grid.reset() | |
| grid.displayHumanFigure(wp) | |
| grid.setAxesColor(wp) | |
| except Exception: | |
| pass | |
| def _param_observer_callback_snapbar(value): | |
| if Gui.activeWorkbench().name() not in ("DraftWorkbench", "ArchWorkbench", "BIMWorkbench"): | |
| return | |
| if hasattr(Gui, "Snapper"): | |
| toolbar = Gui.Snapper.get_snap_toolbar() | |
| if toolbar is not None: | |
| toolbar.setVisible(value == "0") # value is a string: "0" or "1" | |
| def _param_observer_callback_snapwidget(): | |
| # import has to happen here to avoid circular imports | |
| from draftutils import init_draft_statusbar | |
| if Gui.activeWorkbench().name() == "DraftWorkbench": | |
| init_draft_statusbar.hide_draft_statusbar() | |
| init_draft_statusbar.show_draft_statusbar() | |
| def _param_observer_callback_scalewidget(): | |
| # import has to happen here to avoid circular imports | |
| from draftutils import init_draft_statusbar | |
| if Gui.activeWorkbench().name() == "DraftWorkbench": | |
| init_draft_statusbar.hide_draft_statusbar() | |
| init_draft_statusbar.show_draft_statusbar() | |
| def _param_observer_callback_snapstyle(): | |
| if hasattr(Gui, "Snapper"): | |
| Gui.Snapper.set_snap_style() | |
| def _param_observer_callback_snapcolor(): | |
| if hasattr(Gui, "Snapper"): | |
| tracker_list = [2, 5, 6] | |
| for each_tracker in tracker_list: | |
| for snap_track in Gui.Snapper.trackers[each_tracker]: | |
| snap_track.setColor() | |
| def _param_observer_callback_snaptextsize(): | |
| if hasattr(Gui, "Snapper"): | |
| tracker_list = [5, 6] | |
| for each_tracker in tracker_list: | |
| for snap_track in Gui.Snapper.trackers[each_tracker]: | |
| snap_track.setSize() | |
| def _param_observer_callback_svg_pattern(): | |
| # imports have to happen here to avoid circular imports | |
| from draftutils import utils | |
| from draftviewproviders import view_base | |
| utils.load_svg_patterns() | |
| if App.ActiveDocument is None: | |
| return | |
| pats = list(utils.svg_patterns()) | |
| pats.sort() | |
| pats = ["None"] + pats | |
| data = [] | |
| for doc in App.listDocuments().values(): | |
| vobjs = [] | |
| for obj in doc.Objects: | |
| if hasattr(obj, "ViewObject"): | |
| vobj = obj.ViewObject | |
| if ( | |
| hasattr(vobj, "Pattern") | |
| and hasattr(vobj, "Proxy") | |
| and isinstance(vobj.Proxy, view_base.ViewProviderDraft) | |
| and vobj.getEnumerationsOfProperty("Pattern") != pats | |
| ): | |
| vobjs.append(vobj) | |
| if vobjs: | |
| data.append([doc, vobjs]) | |
| if not data: | |
| return | |
| msg = translate( | |
| "draft", | |
| """Do you want to update the SVG pattern options | |
| of existing objects in all opened documents?""", | |
| ) | |
| res = QtWidgets.QMessageBox.question( | |
| None, | |
| "Update SVG patterns", | |
| msg, | |
| QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, | |
| QtWidgets.QMessageBox.No, | |
| ) | |
| if res == QtWidgets.QMessageBox.No: | |
| return | |
| for doc, vobjs in data: | |
| doc.openTransaction("SVG pattern update") | |
| for vobj in vobjs: | |
| old = vobj.Pattern | |
| if old in pats: | |
| vobj.Pattern = pats | |
| else: | |
| tmp_pats = [old] + pats[1:] | |
| tmp_pats.sort() | |
| vobj.Pattern = ["None"] + tmp_pats | |
| vobj.Pattern = old | |
| doc.commitTransaction() | |
| def _param_observer_start(): | |
| 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"), | |
| ): | |
| param_grp.AttachManager(ParamObserverDraft()) | |
| 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): | |
| value = 0.0 | |
| for elem in list(widget): | |
| if "name" in elem.keys(): | |
| att_name = elem.attrib["name"] | |
| if att_name == "rawValue": # 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_PrefQuantitySpinBox(widget): | |
| value = "0" | |
| for elem in list(widget): | |
| if "name" in elem.keys(): | |
| att_name = elem.attrib["name"] | |
| if att_name == "rawValue": # 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): | |
| # Does not occur in Draft preferences anymore. | |
| 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 _param_from_PrefFontBox(widget): | |
| if App.GuiUp: | |
| from PySide import QtGui | |
| font = QtGui.QFont() | |
| font.setStyleHint(QtGui.QFont.StyleHint.SansSerif) | |
| value = font.defaultFamily() | |
| else: | |
| value = "" | |
| 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 | |
| # We must set the parameter if it does not exist, else | |
| # the Gui::PrefFontBox will show the wrong value. | |
| param_grp = App.ParamGet("User parameter:BaseApp/Preferences/" + path) | |
| if entry not in param_grp.GetStrings(): | |
| param_grp.SetString(entry, value) | |
| return path, entry, value | |
| def _get_shape_string_font_file(): | |
| """Try to get the file name of a sans serif font (TTC or TTF) from the OS.""" | |
| # https://forum.freecad.org/viewtopic.php?t=96770 | |
| # Windows font: "arial" | |
| # Mac fonts: "geneva" and "helvetica" | |
| # Linux fonts: "dejavusans" and "freesans" | |
| favorite_names = ("arial", "geneva", "helvetica", "dejavusans", "freesans") | |
| font_file_sans = None # Font with name containing "sans". 1st fallback. | |
| font_file_alpha = None # Font with name starting with a letter. 2nd fallback. | |
| # Reverse the order of the paths so that user related paths come last: | |
| for path in QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.FontsLocation)[::-1]: | |
| # We don't use os.path.join as dir_path has forward slashes even on Windows. | |
| for dir_path, dir_names, file_names in os.walk(path): | |
| for file_name in file_names: | |
| base_name, ext = [s.lower() for s in os.path.splitext(file_name)] | |
| if not ext in (".ttc", ".ttf"): | |
| continue | |
| if base_name in favorite_names: | |
| return dir_path + "/" + file_name | |
| if font_file_sans is None and "sans" in base_name: | |
| font_file_sans = dir_path + "/" + file_name | |
| if font_file_alpha is None and base_name[0].isalpha(): | |
| font_file_alpha = dir_path + "/" + file_name | |
| if font_file_sans is not None: | |
| return font_file_sans | |
| if font_file_alpha is not None: | |
| return font_file_alpha | |
| return "" | |
| def _get_param_dictionary(): | |
| # print("Creating preferences dictionary...") | |
| param_dict = {} | |
| hatch_pattern_file = ( | |
| App.getResourceDir().replace("\\", "/").rstrip("/") + "/Mod/TechDraw/PAT/FCPAT.pat" | |
| ) | |
| # Draft parameters that are not in the preferences: | |
| # fmt: off | |
| param_dict["Mod/Draft"] = { | |
| "AnnotationStyleEditorHeight": ("int", 450), | |
| "AnnotationStyleEditorWidth": ("int", 600), | |
| "CenterPlaneOnView": ("bool", False), | |
| "ChainedMode": ("bool", False), | |
| "CopyMode": ("bool", False), | |
| "DefaultAnnoDisplayMode": ("int", 0), | |
| "DefaultDisplayMode": ("int", 0), | |
| "DefaultDrawStyle": ("int", 0), | |
| "DefaultPrintColor": ("unsigned", 255), | |
| "DimAutoFlipText": ("bool", True), | |
| "Draft_array_fuse": ("bool", False), | |
| "Draft_array_Link": ("bool", True), | |
| "FilletChamferMode": ("bool", False), | |
| "FilletDeleteMode": ("bool", False), | |
| "FilletRadius": ("float", 100.0), | |
| "GlobalMode": ("bool", False), | |
| "GridHideInOtherWorkbenches": ("bool", True), | |
| "HatchPatternFile": ("string", hatch_pattern_file), | |
| "HatchPatternName": ("string", "Diamond"), | |
| "HatchPatternResolution": ("int", 128), # used for SVG patterns | |
| "HatchPatternRotation": ("float", 0.0), | |
| "HatchPatternScale": ("float", 100.0), | |
| "HatchPatternTranslate": ("bool", True), | |
| "labeltype": ("string", "Custom"), | |
| "LayersManagerHeight": ("int", 320), | |
| "LayersManagerWidth": ("int", 640), | |
| "MakeFaceMode": ("bool", True), | |
| "maxSnapEdges": ("int", 0), | |
| "OffsetCopyMode": ("bool", False), | |
| "Offset_OCC": ("bool", False), | |
| "RelativeMode": ("bool", True), | |
| "ScaleClone": ("bool", False), | |
| "ScaleCopy": ("bool", False), | |
| "ScaleRelative": ("bool", False), | |
| "ScaleUniform": ("bool", False), | |
| "ShapeStringFontFile": ("string", _get_shape_string_font_file()), | |
| "ShapeStringHeight": ("float", 10.0), | |
| "ShapeStringText": ("string", translate("draft", "Default")), | |
| "snapModes": ("string", "100000000000000"), | |
| "snapRange": ("int", 8), | |
| "SubelementMode": ("bool", False), | |
| "SvgLinesBlack": ("bool", True), | |
| "useSupport": ("bool", False), | |
| } | |
| param_dict["Mod/Draft/ContinueMode"] = { | |
| # Draft | |
| "Arc": ("bool", False), | |
| "Arc_3Points": ("bool", False), | |
| "BezCurve": ("bool", False), | |
| "Bspline": ("bool", False), | |
| "Circle": ("bool", False), | |
| "CubicBezCurve": ("bool", False), | |
| "Dimension": ("bool", False), | |
| "Ellipse": ("bool", False), | |
| "Line": ("bool", False), | |
| "Point": ("bool", False), | |
| "Polygon": ("bool", False), | |
| "Polyline": ("bool", False), | |
| "Rectangle": ("bool", False), | |
| "Text": ("bool", False), | |
| # Standard operations (Draft) | |
| "Copy": ("bool", False), | |
| "Move": ("bool", False), | |
| "Rotate": ("bool", False), | |
| # Arch/BIM | |
| "Beam": ("bool", False), | |
| "Column": ("bool", False), | |
| "Panel": ("bool", False), | |
| "Wall": ("bool", False), | |
| } | |
| start_val = App.Units.Quantity(100.0, App.Units.Length).Value | |
| param_dict["Mod/Draft/OrthoArrayLinearMode"] = { | |
| "LinearModeOn": ("bool", True), | |
| "AxisSelected": ("string", "X"), | |
| "XInterval": ("float", start_val), | |
| "YInterval": ("float", start_val), | |
| "ZInterval": ("float", start_val), | |
| "XNumOfElements": ("int", 2), | |
| "YNumOfElements": ("int", 2), | |
| "ZNumOfElements": ("int", 2) | |
| } | |
| # Arch parameters that are not in the preferences: | |
| param_dict["Mod/Arch"] = { | |
| "applyConstructionStyle": ("bool", True), | |
| "ClaimHosted": ("bool", True), | |
| "CustomIfcSchema": ("string", ""), # importIFClegacy.py | |
| "createIfcGroups": ("bool", False), # importIFClegacy.py | |
| "DoorHeight": ("float", 2100.0), | |
| "DoorPreset": ("int", 5), | |
| "DoorSill": ("float", 0.0), | |
| "DoorWidth": ("float", 1000.0), | |
| "FreeLinking": ("bool", False), | |
| "forceIfcPythonParser": ("bool", False), # importIFClegacy.py | |
| "getStandardType": ("bool", False), | |
| "ifcAggregateWindows": ("bool", False), # importIFClegacy.py | |
| "ifcAsMesh": ("string", ""), # importIFClegacy.py | |
| "IfcExportList": ("bool", False), # importIFClegacy.py | |
| "ifcImportLayer": ("bool", True), | |
| "ifcJoinSolids": ("bool", False), # importIFClegacy.py | |
| "ifcMergeProfiles": ("bool", False), | |
| "IfcScalingFactor": ("float", 1.0), # importIFClegacy.py | |
| "ifcSeparatePlacements": ("bool", False), # importIFClegacy.py | |
| "MultiMaterialColumnWidth0": ("int", 120), | |
| "MultiMaterialColumnWidth1": ("int", 120), | |
| "PanelLength": ("float", 1000.0), | |
| "PanelThickness": ("float", 10.0), | |
| "PanelWidth": ("float", 1000.0), | |
| "PrecastBase": ("float", 0.0), | |
| "PrecastChamfer": ("float", 0.0), | |
| "PrecastDentHeight": ("float", 0.0), | |
| "PrecastDentLength": ("float", 0.0), | |
| "PrecastDentWidth": ("float", 0.0), | |
| "PrecastDownLength": ("float", 0.0), | |
| "PrecastGrooveDepth": ("float", 0.0), | |
| "PrecastGrooveHeight": ("float", 0.0), | |
| "PrecastGrooveSpacing": ("float", 0.0), | |
| "PrecastHoleMajor": ("float", 0.0), | |
| "PrecastHoleMinor": ("float", 0.0), | |
| "PrecastHoleSpacing": ("float", 0.0), | |
| "PrecastRiser": ("float", 0.0), | |
| "PrecastTread": ("float", 0.0), | |
| "ProfilePreset": ("string", ""), | |
| "ScheduleColumnWidth0": ("int", 100), | |
| "ScheduleColumnWidth1": ("int", 100), | |
| "ScheduleColumnWidth2": ("int", 50), | |
| "ScheduleColumnWidth3": ("int", 100), | |
| "ScheduleDialogHeight": ("int", 200), | |
| "ScheduleDialogWidth": ("int", 300), | |
| "StructureHeight": ("float", 1000.0), | |
| "StructureLength": ("float", 100.0), | |
| "StructurePreset": ("string", ""), | |
| "StructureWidth": ("float", 100.0), | |
| "swallowAdditions": ("bool", True), | |
| "swallowSubtractions": ("bool", True), | |
| "WallAlignment": ("int", 0), | |
| "WallHeight": ("float", 3000.0), | |
| "WallWidth": ("float", 200.0), | |
| "WallOffset": ("float", 0.0), | |
| "WindowH1": ("float", 50.0), | |
| "WindowH2": ("float", 50.0), | |
| "WindowH3": ("float", 50.0), | |
| "WindowHeight": ("float", 1000.0), | |
| "WindowO1": ("float", 0.0), | |
| "WindowO2": ("float", 50.0), | |
| "WindowPreset": ("int", 0), | |
| "WindowSill": ("float", 0.0), | |
| "WindowW1": ("float", 100.0), | |
| "WindowW2": ("float", 50.0), | |
| "WindowWidth": ("float", 1000.0), | |
| } | |
| # BIM parameters that are not in the preferences: | |
| # Note: incomplete! | |
| param_dict["Mod/BIM"] = { | |
| "BIMSketchPlacementOnly": ("bool", False), | |
| "WallBaseline": ("int", 0), | |
| } | |
| # For the Mod/Mesh parameters we do not check the preferences: | |
| param_dict["Mod/Mesh"] = { | |
| "MaxDeviationExport": ("float", 0.1), | |
| } | |
| # For the General parameters we do not check the preferences: | |
| param_dict["General"] = { | |
| "ToolbarIconSize": ("int", 24), | |
| } | |
| # For the Units parameters we do not check the preferences: | |
| param_dict["Units"] = { | |
| "Decimals": ("int", 2), | |
| "UserSchema": ("int", 0), | |
| } | |
| # For the View parameters we do not check the preferences: | |
| param_dict["View"] = { | |
| "BackgroundColor": ("unsigned", 336897023), | |
| "BackgroundColor2": ("unsigned", 859006463), | |
| "BackgroundColor3": ("unsigned", 2543299327), | |
| "DefaultAmbientColor": ("unsigned", 1431655935), | |
| "DefaultEmissiveColor": ("unsigned", 255), | |
| "DefaultShapeColor": ("unsigned", 3435980543), | |
| "DefaultShapeLineColor": ("unsigned", 421075455), | |
| "DefaultShapeLineWidth": ("int", 2), | |
| "DefaultShapePointSize": ("int", 2), | |
| "DefaultShapeShininess": ("int", 90), | |
| "DefaultShapeTransparency": ("int", 0), | |
| "DefaultShapeVertexColor": ("unsigned", 421075455), | |
| "DefaultSpecularColor": ("unsigned", 2290649343), | |
| "EnableSelection": ("bool", True), | |
| "Gradient": ("bool", True), | |
| "MarkerSize": ("int", 9), | |
| "NewDocumentCameraScale": ("float", 100.0), | |
| } | |
| # fmt: on | |
| # 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", | |
| ":/ui/preferences-sh3d-import.ui", | |
| ":/ui/preferences-webgl.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: | |
| 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" | |
| elif att_class == "Gui::PrefFontBox": | |
| path, entry, value = _param_from_PrefFontBox(widget) | |
| typ = "string" | |
| elif att_class == "Gui::PrefCheckableGroupBox": | |
| # It's a boolean preference, so we can reuse the parsing logic | |
| # from _param_from_PrefCheckBox, which looks for <property name="checked">. | |
| path, entry, value = _param_from_PrefCheckBox(widget) | |
| typ = "bool" | |
| 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() | |
| def get_param(entry, path="Mod/Draft", ret_default=False, silent=False): | |
| """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/". | |
| ret_default: bool, optional | |
| Defaults to `False`. | |
| If `True`, always return the default value even if a stored value is available. | |
| silent: bool, optional | |
| Defaults to `False`. | |
| If `True`, do not log anything if entry wasn't found. | |
| Returns | |
| ------- | |
| bool, float, int or str (if successful) or `None`. | |
| """ | |
| if path not in PARAM_DICT or entry not in PARAM_DICT[path]: | |
| if not silent: | |
| print(f"draftutils.params.get_param: Unable to find '{entry}' in '{path}'") | |
| return None | |
| param_grp = App.ParamGet("User parameter:BaseApp/Preferences/" + path) | |
| typ, default = PARAM_DICT[path][entry] | |
| if ret_default: | |
| return default | |
| if typ == "bool": | |
| return param_grp.GetBool(entry, default) | |
| if typ == "float": | |
| return param_grp.GetFloat(entry, default) | |
| if typ == "int": | |
| return param_grp.GetInt(entry, default) | |
| if typ == "string": | |
| return param_grp.GetString(entry, default) | |
| if typ == "unsigned": | |
| return param_grp.GetUnsigned(entry, default) | |
| return None | |
| def get_param_arch(entry, ret_default=False): | |
| return get_param(entry, path="Mod/Arch", ret_default=ret_default) | |
| def get_param_view(entry, ret_default=False): | |
| return get_param(entry, path="View", ret_default=ret_default) | |
| 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 or entry not in PARAM_DICT[path]: | |
| print(f"draftutils.params.set_param: Unable to find '{entry}' in '{path}'") | |
| return False | |
| param_grp = App.ParamGet("User parameter:BaseApp/Preferences/" + path) | |
| typ = PARAM_DICT[path][entry][0] | |
| ret = True | |
| if typ == "bool": | |
| param_grp.SetBool(entry, value) | |
| elif typ == "float": | |
| param_grp.SetFloat(entry, value) | |
| elif typ == "int": | |
| param_grp.SetInt(entry, value) | |
| elif typ == "string": | |
| param_grp.SetString(entry, value) | |
| elif typ == "unsigned": | |
| param_grp.SetUnsigned(entry, value) | |
| else: | |
| ret = False | |
| return ret | |
| def set_param_arch(entry, value): | |
| return set_param(entry, value, path="Mod/Arch") | |
| def set_param_view(entry, value): | |
| return set_param(entry, value, path="View") | |