# SPDX-License-Identifier: LGPL-2.1-or-later # *************************************************************************** # * Copyright (c) 2020 Yorik van Havre * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * # * as published by the Free Software Foundation; either version 2 of * # * the License, or (at your option) any later version. * # * for detail see the LICENCE text file. * # * * # * This program 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 Library General Public License for more details. * # * * # * You should have received a copy of the GNU Library General Public * # * License along with this program; if not, write to the Free Software * # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # * USA * # * * # *************************************************************************** """Provides GUI tools to set up default styles.""" ## @package gui_setstyle # \ingroup draftguitools # \brief Provides GUI tools to set Draft styles such as color or line width ## \addtogroup draftguitools # @{ import os from PySide import QtCore from PySide import QtGui from PySide import QtWidgets import FreeCAD as App import FreeCADGui as Gui import Draft_rc from FreeCAD import Units as U from draftutils import params from draftutils import utils def QT_TRANSLATE_NOOP(ctx, txt): return txt translate = App.Qt.translate __title__ = "FreeCAD Draft Workbench GUI Tools - Styling tools" __author__ = "Yorik van Havre" __url__ = "https://www.freecad.org" PRESETPATH = os.path.join(App.getUserAppDataDir(), "Draft", "StylePresets.json") class Draft_SetStyle: """The Draft_SetStyle FreeCAD command definition.""" def GetResources(self): return { "Pixmap": "Draft_Apply", "Accel": "S, S", "MenuText": QT_TRANSLATE_NOOP("Draft_SetStyle", "Set Style"), "ToolTip": QT_TRANSLATE_NOOP( "Draft_SetStyle", "Sets the default style and can apply the style to objects" ), } def Activated(self): Gui.Control.showDialog(Draft_SetStyle_TaskPanel()) class Draft_SetStyle_TaskPanel: """The task panel for the Draft_SetStyle command""" def __init__(self): self.form = Gui.PySideUic.loadUi(":/ui/TaskPanel_SetStyle.ui") self.form.setWindowIcon( QtGui.QIcon.fromTheme("gtk-apply", QtGui.QIcon(":/icons/Draft_Apply.svg")) ) self.form.saveButton.setIcon( QtGui.QIcon.fromTheme("gtk-save", QtGui.QIcon(":/icons/document-save.svg")) ) self.form.applyButton.setIcon( QtGui.QIcon.fromTheme("gtk-apply", QtGui.QIcon(":/icons/Draft_Apply.svg")) ) self.form.annotButton.setIcon(QtGui.QIcon(":/icons/Draft_Text.svg")) self.form.ShapeColor.setProperty( "color", self.getColor(params.get_param_view("DefaultShapeColor")) ) self.form.AmbientColor.setProperty( "color", self.getColor(params.get_param_view("DefaultAmbientColor")) ) self.form.EmissiveColor.setProperty( "color", self.getColor(params.get_param_view("DefaultEmissiveColor")) ) self.form.SpecularColor.setProperty( "color", self.getColor(params.get_param_view("DefaultSpecularColor")) ) self.form.Transparency.setValue(params.get_param_view("DefaultShapeTransparency")) self.form.Shininess.setValue(params.get_param_view("DefaultShapeShininess")) self.form.LineColor.setProperty( "color", self.getColor(params.get_param_view("DefaultShapeLineColor")) ) self.form.LineWidth.setValue(params.get_param_view("DefaultShapeLineWidth")) self.form.PointColor.setProperty( "color", self.getColor(params.get_param_view("DefaultShapeVertexColor")) ) self.form.PointSize.setValue(params.get_param_view("DefaultShapePointSize")) self.form.DrawStyle.setCurrentIndex(params.get_param("DefaultDrawStyle")) self.form.DisplayMode.setCurrentIndex(params.get_param("DefaultDisplayMode")) self.form.TextColor.setProperty( "color", self.getColor(params.get_param("DefaultTextColor")) ) self.form.TextFont.setCurrentFont(QtGui.QFont(params.get_param("textfont"))) self.form.TextSize.setText(U.Quantity(params.get_param("textheight"), U.Length).UserString) self.form.LineSpacing.setValue(params.get_param("LineSpacing")) self.form.ScaleMultiplier.setValue(params.get_param("DefaultAnnoScaleMultiplier")) self.form.AnnoLineColor.setProperty( "color", self.getColor(params.get_param("DefaultAnnoLineColor")) ) self.form.AnnoLineWidth.setValue(params.get_param("DefaultAnnoLineWidth")) self.form.ArrowStyleStart.setCurrentIndex(params.get_param("dimsymbolstart")) self.form.ArrowSizeStart.setText( U.Quantity(params.get_param("arrowsizestart"), U.Length).UserString ) self.form.ArrowStyleEnd.setCurrentIndex(params.get_param("dimsymbolend")) self.form.ArrowSizeEnd.setText( U.Quantity(params.get_param("arrowsizeend"), U.Length).UserString ) self.form.ShowUnit.setChecked(params.get_param("showUnit")) self.form.UnitOverride.setText(params.get_param("overrideUnit")) self.form.DimOvershoot.setText( U.Quantity(params.get_param("dimovershoot"), U.Length).UserString ) self.form.ExtLines.setText(U.Quantity(params.get_param("extlines"), U.Length).UserString) self.form.ExtOvershoot.setText( U.Quantity(params.get_param("extovershoot"), U.Length).UserString ) self.form.TextSpacing.setText( U.Quantity(params.get_param("dimspacing"), U.Length).UserString ) self.form.saveButton.clicked.connect(self.onSaveStyle) self.form.applyButton.clicked.connect(self.onApplyStyle) self.form.annotButton.clicked.connect(self.onApplyAnnot) self.form.comboPresets.currentIndexChanged.connect(self.onLoadStyle) self.loadDefaults() def loadDefaults(self): presets = [self.form.comboPresets.itemText(0)] self.form.comboPresets.clear() pdict = self.load() pdict_keys = list(pdict) presets.extend(pdict_keys) self.form.comboPresets.addItems(presets) current = self.getValues() for name, preset in pdict.items(): if all(item in current.items() for item in preset.items()): # if preset == current: self.form.comboPresets.setCurrentIndex(1 + (pdict_keys.index(name))) break def getColor(self, c): return QtGui.QColor(utils.rgba_to_argb(c)) def getValues(self): return { "ShapeColor": utils.argb_to_rgba(self.form.ShapeColor.property("color").rgba()), "AmbientColor": utils.argb_to_rgba(self.form.AmbientColor.property("color").rgba()), "EmissiveColor": utils.argb_to_rgba(self.form.EmissiveColor.property("color").rgba()), "SpecularColor": utils.argb_to_rgba(self.form.SpecularColor.property("color").rgba()), "Transparency": self.form.Transparency.value(), "Shininess": self.form.Shininess.value(), "LineColor": utils.argb_to_rgba(self.form.LineColor.property("color").rgba()), "LineWidth": self.form.LineWidth.value(), "PointColor": utils.argb_to_rgba(self.form.PointColor.property("color").rgba()), "PointSize": self.form.PointSize.value(), "DrawStyle": self.form.DrawStyle.currentIndex(), "DisplayMode": self.form.DisplayMode.currentIndex(), "TextColor": utils.argb_to_rgba(self.form.TextColor.property("color").rgba()), "TextFont": self.form.TextFont.currentFont().family(), "TextSize": U.Quantity(self.form.TextSize.text()).Value, "LineSpacing": self.form.LineSpacing.value(), "ScaleMultiplier": self.form.ScaleMultiplier.value(), "AnnoLineColor": utils.argb_to_rgba(self.form.AnnoLineColor.property("color").rgba()), "AnnoLineWidth": self.form.AnnoLineWidth.value(), "ArrowStyleStart": self.form.ArrowStyleStart.currentIndex(), "ArrowSizeStart": U.Quantity(self.form.ArrowSizeStart.text()).Value, "ArrowStyleEnd": self.form.ArrowStyleEnd.currentIndex(), "ArrowSizeEnd": U.Quantity(self.form.ArrowSizeEnd.text()).Value, "ShowUnit": self.form.ShowUnit.isChecked(), "UnitOverride": self.form.UnitOverride.text(), "DimOvershoot": U.Quantity(self.form.DimOvershoot.text()).Value, "ExtLines": U.Quantity(self.form.ExtLines.text()).Value, "ExtOvershoot": U.Quantity(self.form.ExtOvershoot.text()).Value, "TextSpacing": U.Quantity(self.form.TextSpacing.text()).Value, } def setValues(self, preset): # For compatibility with <= V0.21 some properties, if missing, reference others: # 'new' prop -> old prop # --------------------------- # PointColor -> LineColor # PointSize -> LineWidth # AnnoLineColor -> LineColor # AnnoLineWidth -> LineWidth def getDefDraft(entry): return params.get_param(entry, ret_default=True) def getDefView(entry): return params.get_param_view(entry, ret_default=True) # --------------------------------------------------------------------- self.form.ShapeColor.setProperty( "color", self.getColor(preset.get("ShapeColor", getDefView("DefaultShapeColor"))) ) self.form.AmbientColor.setProperty( "color", self.getColor(preset.get("AmbientColor", getDefView("DefaultAmbientColor"))) ) self.form.EmissiveColor.setProperty( "color", self.getColor(preset.get("EmissiveColor", getDefView("DefaultEmissiveColor"))) ) self.form.SpecularColor.setProperty( "color", self.getColor(preset.get("SpecularColor", getDefView("DefaultSpecularColor"))) ) self.form.Transparency.setValue( preset.get("Transparency", getDefView("DefaultShapeTransparency")) ) self.form.Shininess.setValue(preset.get("Shininess", getDefView("DefaultShapeShininess"))) # --------------------------------------------------------------------- self.form.LineColor.setProperty( "color", self.getColor(preset.get("LineColor", getDefView("DefaultShapeLineColor"))) ) self.form.LineWidth.setValue(preset.get("LineWidth", getDefView("DefaultShapeLineWidth"))) self.form.PointColor.setProperty( "color", self.getColor( preset.get( "PointColor", preset.get("LineColor", getDefView("DefaultShapeVertexColor")) ) ), ) self.form.PointSize.setValue( preset.get("PointSize", preset.get("LineWidth", getDefView("DefaultShapePointSize"))) ) self.form.DrawStyle.setCurrentIndex( preset.get("DrawStyle", getDefDraft("DefaultDrawStyle")) ) self.form.DisplayMode.setCurrentIndex( preset.get("DisplayMode", getDefDraft("DefaultDisplayMode")) ) # --------------------------------------------------------------------- self.form.TextColor.setProperty( "color", self.getColor(preset.get("TextColor", getDefDraft("DefaultTextColor"))) ) self.form.TextFont.setCurrentFont( QtGui.QFont(preset.get("TextFont", getDefDraft("textfont"))) ) self.form.TextSize.setText( U.Quantity(preset.get("TextSize", getDefDraft("textheight")), U.Length).UserString ) self.form.LineSpacing.setValue(preset.get("LineSpacing", getDefDraft("LineSpacing"))) self.form.ScaleMultiplier.setValue( preset.get("ScaleMultiplier", getDefDraft("DefaultAnnoScaleMultiplier")) ) # --------------------------------------------------------------------- self.form.AnnoLineColor.setProperty( "color", self.getColor( preset.get( "AnnoLineColor", preset.get("LineColor", getDefDraft("DefaultAnnoLineColor")) ) ), ) self.form.AnnoLineWidth.setValue( preset.get( "AnnoLineWidth", preset.get("LineWidth", getDefDraft("DefaultAnnoLineWidth")) ) ) self.form.ArrowStyleStart.setCurrentIndex( preset.get("ArrowStyleStart", getDefDraft("dimsymbolstart")) ) self.form.ArrowSizeStart.setText( U.Quantity( preset.get("ArrowSizeStart", getDefDraft("arrowsizestart")), U.Length ).UserString ) self.form.ArrowStyleEnd.setCurrentIndex( preset.get("ArrowStyleEnd", getDefDraft("dimsymbolend")) ) self.form.ArrowSizeEnd.setText( U.Quantity(preset.get("ArrowSizeEnd", getDefDraft("arrowsizeend")), U.Length).UserString ) self.form.ShowUnit.setChecked(preset.get("ShowUnit", getDefDraft("showUnit"))) self.form.UnitOverride.setText(preset.get("UnitOverride", getDefDraft("overrideUnit"))) self.form.DimOvershoot.setText( U.Quantity(preset.get("DimOvershoot", getDefDraft("dimovershoot")), U.Length).UserString ) self.form.ExtLines.setText( U.Quantity(preset.get("ExtLines", getDefDraft("extlines")), U.Length).UserString ) self.form.ExtOvershoot.setText( U.Quantity(preset.get("ExtOvershoot", getDefDraft("extovershoot")), U.Length).UserString ) self.form.TextSpacing.setText( U.Quantity(preset.get("TextSpacing", getDefDraft("dimspacing")), U.Length).UserString ) def reject(self): Gui.Control.closeDialog() def accept(self): params.set_param_view( "DefaultShapeColor", utils.argb_to_rgba(self.form.ShapeColor.property("color").rgba()) ) params.set_param_view( "DefaultAmbientColor", utils.argb_to_rgba(self.form.AmbientColor.property("color").rgba()), ) params.set_param_view( "DefaultEmissiveColor", utils.argb_to_rgba(self.form.EmissiveColor.property("color").rgba()), ) params.set_param_view( "DefaultSpecularColor", utils.argb_to_rgba(self.form.SpecularColor.property("color").rgba()), ) params.set_param_view("DefaultShapeTransparency", self.form.Transparency.value()) params.set_param_view("DefaultShapeShininess", self.form.Shininess.value()) params.set_param_view( "DefaultShapeLineColor", utils.argb_to_rgba(self.form.LineColor.property("color").rgba()), ) params.set_param_view("DefaultShapeLineWidth", self.form.LineWidth.value()) params.set_param_view( "DefaultShapeVertexColor", utils.argb_to_rgba(self.form.PointColor.property("color").rgba()), ) params.set_param_view("DefaultShapePointSize", self.form.PointSize.value()) params.set_param("DefaultDrawStyle", self.form.DrawStyle.currentIndex()) params.set_param("DefaultDisplayMode", self.form.DisplayMode.currentIndex()) params.set_param( "DefaultTextColor", utils.argb_to_rgba(self.form.TextColor.property("color").rgba()) ) params.set_param("textfont", self.form.TextFont.currentFont().family()) params.set_param("textheight", U.Quantity(self.form.TextSize.text()).Value) params.set_param("LineSpacing", self.form.LineSpacing.value()) params.set_param("DefaultAnnoScaleMultiplier", self.form.ScaleMultiplier.value()) params.set_param( "DefaultAnnoLineColor", utils.argb_to_rgba(self.form.AnnoLineColor.property("color").rgba()), ) params.set_param("DefaultAnnoLineWidth", self.form.AnnoLineWidth.value()) params.set_param("dimsymbolstart", self.form.ArrowStyleStart.currentIndex()) params.set_param("arrowsizestart", U.Quantity(self.form.ArrowSizeStart.text()).Value) params.set_param("dimsymbolend", self.form.ArrowStyleEnd.currentIndex()) params.set_param("arrowsizeend", U.Quantity(self.form.ArrowSizeEnd.text()).Value) params.set_param("showUnit", self.form.ShowUnit.isChecked()) params.set_param("overrideUnit", self.form.UnitOverride.text()) params.set_param("dimovershoot", U.Quantity(self.form.DimOvershoot.text()).Value) params.set_param("extlines", U.Quantity(self.form.ExtLines.text()).Value) params.set_param("extovershoot", U.Quantity(self.form.ExtOvershoot.text()).Value) params.set_param("dimspacing", U.Quantity(self.form.TextSpacing.text()).Value) self.reject() def onApplyStyle(self): for obj in Gui.Selection.getSelection(): self.apply_style_to_obj(obj) def onApplyAnnot(self): if App.ActiveDocument is not None: # Command can be called without a document. objs = App.ActiveDocument.Objects typs = [ "Dimension", "LinearDimension", "AngularDimension", "Text", "DraftText", "Label", ] for obj in objs: if utils.get_type(obj) in typs: self.apply_style_to_obj(obj) def apply_style_to_obj(self, obj): vobj = obj.ViewObject if not vobj: return properties = vobj.PropertiesList if "FontName" not in properties: # Shapes if "AutoColor" in properties: # For sketches. vobj.AutoColor = False if "ShapeAppearance" in properties: material = App.Material() material.DiffuseColor = self.form.ShapeColor.property("color").getRgbF()[ :3 ] # Remove Alpha (which is 1 instead of 0). material.AmbientColor = self.form.AmbientColor.property("color").getRgbF()[:3] material.EmissiveColor = self.form.EmissiveColor.property("color").getRgbF()[:3] material.SpecularColor = self.form.SpecularColor.property("color").getRgbF()[:3] material.Transparency = self.form.Transparency.value() / 100 material.Shininess = self.form.Shininess.value() / 100 vobj.ShapeAppearance = (material,) if "LineColor" in properties: vobj.LineColor = self.form.LineColor.property("color").getRgbF()[:3] if "LineWidth" in properties: vobj.LineWidth = self.form.LineWidth.value() if "PointColor" in properties: vobj.PointColor = self.form.PointColor.property("color").getRgbF()[:3] if "PointSize" in properties: vobj.PointSize = self.form.PointSize.value() if "DrawStyle" in properties: vobj.DrawStyle = utils.DRAW_STYLES[self.form.DrawStyle.currentIndex()] if "DisplayMode" in properties: dm = utils.DISPLAY_MODES[self.form.DisplayMode.currentIndex()] if dm in vobj.listDisplayModes(): vobj.DisplayMode = dm else: # Annotations if "TextColor" in properties: vobj.TextColor = self.form.TextColor.property("color").getRgbF()[:3] if "FontName" in properties: vobj.FontName = self.form.TextFont.currentFont().family() if "FontSize" in properties: vobj.FontSize = U.Quantity(self.form.TextSize.text()).Value if "LineSpacing" in properties: vobj.LineSpacing = self.form.LineSpacing.value() if "ScaleMultiplier" in properties: vobj.ScaleMultiplier = self.form.ScaleMultiplier.value() if "LineColor" in properties: vobj.LineColor = self.form.AnnoLineColor.property("color").getRgbF()[:3] if "LineWidth" in properties: vobj.LineWidth = self.form.AnnoLineWidth.value() if "ArrowTypeStart" in properties: vobj.ArrowTypeStart = utils.ARROW_TYPES[self.form.ArrowStyleStart.currentIndex()] if "ArrowSizeStart" in properties: vobj.ArrowSizeStart = U.Quantity(self.form.ArrowSizeStart.text()).Value if "ArrowTypeEnd" in properties: vobj.ArrowTypeEnd = utils.ARROW_TYPES[self.form.ArrowStyleEnd.currentIndex()] if "ArrowSizeEnd" in properties: vobj.ArrowSizeEnd = U.Quantity(self.form.ArrowSizeEnd.text()).Value if "ShowUnit" in properties: vobj.ShowUnit = self.form.ShowUnit.isChecked() if "UnitOverride" in properties: vobj.UnitOverride = self.form.UnitOverride.text() if "DimOvershoot" in properties: vobj.DimOvershoot = U.Quantity(self.form.DimOvershoot.text()).Value if "ExtLines" in properties: vobj.ExtLines = U.Quantity(self.form.ExtLines.text()).Value if "ExtOvershoot" in properties: vobj.ExtOvershoot = U.Quantity(self.form.ExtOvershoot.text()).Value if "TextSpacing" in properties: vobj.TextSpacing = U.Quantity(self.form.TextSpacing.text()).Value def onLoadStyle(self, index): if index > 0: pdict = self.load() if self.form.comboPresets.itemText(index) in pdict: preset = pdict[self.form.comboPresets.itemText(index)] self.setValues(preset) def onSaveStyle(self): reply = QtWidgets.QInputDialog.getText( None, translate("Draft", "Save style"), translate("Draft", "Name of this new style") ) if reply[1]: name = reply[0] pdict = self.load() if pdict: if name in pdict: reply = QtWidgets.QMessageBox.question( None, translate("Draft", "Warning"), translate("Draft", "Name exists. Overwrite?"), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No, ) if reply == QtWidgets.QMessageBox.No: return preset = self.getValues() pdict[name] = preset self.save(pdict) self.loadDefaults() def load(self): """loads the presets json file, returns a dict""" pdict = {} try: import json from json.decoder import JSONDecodeError except Exception: App.Console.PrintError( translate("Draft", "Error: json module not found. Unable to load style") + "\n" ) return if os.path.exists(PRESETPATH): with open(PRESETPATH, "r") as f: try: pdict = json.load(f) except JSONDecodeError: return {} return pdict def save(self, d): """saves the given dict to the presets json file""" try: import json except Exception: App.Console.PrintError( translate("Draft", "Error: json module not found. Unable to save style") + "\n" ) return folder = os.path.dirname(PRESETPATH) if not os.path.exists(folder): os.makedirs(folder) with open(PRESETPATH, "w") as f: json.dump(d, f, indent=4) Gui.addCommand("Draft_SetStyle", Draft_SetStyle()) ## @}