From 34cf98102cc3d91828071df8d9fd3119a0413121 Mon Sep 17 00:00:00 2001 From: carlopav Date: Sat, 14 Mar 2020 12:24:10 +0100 Subject: [PATCH] [Draft] Dimension style object still have to split viewprovider from object. [Draft] Dimension Style code cleanup thx @vocx-fc for reviewing further cleanup [Draft] Dimension Style improvements Added a property to the dimension object to link the dimension style. Improved the update of dimensions when style changes. This can be done in 2 different ways: by setting AutoUpdate property to True or by activating Update function from the viewprovider context menu. --- src/Mod/Draft/Draft.py | 77 ++++-- src/Mod/Draft/InitGui.py | 1 + .../draftguitools/gui_style_dimension.py | 68 ++++++ src/Mod/Draft/draftobjects/style_dimension.py | 54 ++++ .../view_style_dimension.py | 230 ++++++++++++++++++ 5 files changed, 416 insertions(+), 14 deletions(-) create mode 100644 src/Mod/Draft/draftguitools/gui_style_dimension.py create mode 100644 src/Mod/Draft/draftobjects/style_dimension.py create mode 100644 src/Mod/Draft/draftviewproviders/view_style_dimension.py diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 23aea008eba3..9e9e22fa8d33 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -3372,27 +3372,75 @@ class _Dimension(_DraftObject): """The Draft Dimension object""" def __init__(self, obj): _DraftObject.__init__(self,obj,"Dimension") - obj.addProperty("App::PropertyVectorDistance","Start","Draft",QT_TRANSLATE_NOOP("App::Property","Startpoint of dimension")) - obj.addProperty("App::PropertyVectorDistance","End","Draft",QT_TRANSLATE_NOOP("App::Property","Endpoint of dimension")) - obj.addProperty("App::PropertyVector","Normal","Draft",QT_TRANSLATE_NOOP("App::Property","The normal direction of this dimension")) - obj.addProperty("App::PropertyVector","Direction","Draft",QT_TRANSLATE_NOOP("App::Property","The normal direction of this dimension")) - obj.addProperty("App::PropertyVectorDistance","Dimline","Draft",QT_TRANSLATE_NOOP("App::Property","Point through which the dimension line passes")) - obj.addProperty("App::PropertyLink","Support","Draft",QT_TRANSLATE_NOOP("App::Property","The object measured by this dimension")) - obj.addProperty("App::PropertyLinkSubList","LinkedGeometry","Draft",QT_TRANSLATE_NOOP("App::Property","The geometry this dimension is linked to")) - obj.addProperty("App::PropertyLength","Distance","Draft",QT_TRANSLATE_NOOP("App::Property","The measurement of this dimension")) - obj.addProperty("App::PropertyBool","Diameter","Draft",QT_TRANSLATE_NOOP("App::Property","For arc/circle measurements, false = radius, true = diameter")) + + # Annotation + obj.addProperty("App::PropertyLink","DimensionStyle", + "Annotation", + QT_TRANSLATE_NOOP("App::Property", + "Link dimension style")) + + # Draft + obj.addProperty("App::PropertyVectorDistance","Start", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "Startpoint of dimension")) + + obj.addProperty("App::PropertyVectorDistance","End", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "Endpoint of dimension")) + + obj.addProperty("App::PropertyVector","Normal", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "The normal direction of this dimension")) + + obj.addProperty("App::PropertyVector","Direction", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "The normal direction of this dimension")) + + obj.addProperty("App::PropertyVectorDistance","Dimline", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "Point through which the dimension line passes")) + + obj.addProperty("App::PropertyLink","Support", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "The object measured by this dimension")) + + obj.addProperty("App::PropertyLinkSubList","LinkedGeometry", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "The geometry this dimension is linked to")) + + obj.addProperty("App::PropertyLength","Distance", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "The measurement of this dimension")) + + obj.addProperty("App::PropertyBool","Diameter", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "For arc/circle measurements, false = radius, true = diameter")) obj.Start = FreeCAD.Vector(0,0,0) obj.End = FreeCAD.Vector(1,0,0) obj.Dimline = FreeCAD.Vector(0,1,0) obj.Normal = FreeCAD.Vector(0,0,1) def onChanged(self,obj,prop): - if hasattr(obj,"Distance"): - obj.setEditorMode('Distance',1) + if hasattr(obj, "Distance"): + obj.setEditorMode('Distance', 1) #if hasattr(obj,"Normal"): - # obj.setEditorMode('Normal',2) - if hasattr(obj,"Support"): - obj.setEditorMode('Support',2) + # obj.setEditorMode('Normal', 2) + if hasattr(obj, "Support"): + obj.setEditorMode('Support', 2) + if prop == "DimensionStyle": + if hasattr(obj, "DimensionStyle"): + from draftutils import gui_utils + gui_utils.format_object(target = obj, origin = obj.DimensionStyle) + def execute(self, obj): import DraftGeomUtils @@ -3503,6 +3551,7 @@ def __init__(self, obj): obj.addProperty("App::PropertyFloat","ScaleMultiplier", "Annotation",QT_TRANSLATE_NOOP("App::Property", "Dimension size overall multiplier")) + # text properties obj.addProperty("App::PropertyFont","FontName", "Text",QT_TRANSLATE_NOOP("App::Property","Font name")) diff --git a/src/Mod/Draft/InitGui.py b/src/Mod/Draft/InitGui.py index 0178ec4978c8..7513c3d3fe9d 100644 --- a/src/Mod/Draft/InitGui.py +++ b/src/Mod/Draft/InitGui.py @@ -86,6 +86,7 @@ def QT_TRANSLATE_NOOP(context, text): from draftguitools import gui_polararray from draftguitools import gui_orthoarray from draftguitools import gui_arrays + from draftguitools import gui_style_dimension FreeCADGui.addLanguagePath(":/translations") FreeCADGui.addIconPath(":/icons") except Exception as exc: diff --git a/src/Mod/Draft/draftguitools/gui_style_dimension.py b/src/Mod/Draft/draftguitools/gui_style_dimension.py new file mode 100644 index 000000000000..fcba6fa0f185 --- /dev/null +++ b/src/Mod/Draft/draftguitools/gui_style_dimension.py @@ -0,0 +1,68 @@ +# *************************************************************************** +# * (c) 2020 Carlo Pavan * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * 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. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +"""This module provides the Draft Dimension Style tool. +""" +## @package gui_style_dimension +# \ingroup DRAFT +# \brief This module provides the Draft Dimension Style tool. + +import FreeCAD as App +import FreeCADGui as Gui +from PySide import QtCore +from . import gui_base +from draftutils import utils +from draftobjects.style_dimension import make_dimension_style + +class GuiCommandDimensionStyle(gui_base.GuiCommandBase): + """ + The command creates a dimension style object + """ + + def GetResources(self): + _msg = ("Creates a new dimension style.\n" + "The object stores dimension preferences into the document." + ) + return {'Pixmap' : 'Draft_AutoGroup', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft", "Dimension Style"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft", _msg)} + + def IsActive(self): + if Gui.ActiveDocument: + return True + else: + return False + + def Activated(self): + sel = Gui.Selection.getSelection() + + if len(sel) == 1: + if utils.get_type(sel[0]) == 'Dimension': + make_dimension_style(sel[0]) + return self.finish() + + make_dimension_style() + return self.finish() + + +Gui.addCommand('Draft_DimensionStyle', GuiCommandDimensionStyle()) diff --git a/src/Mod/Draft/draftobjects/style_dimension.py b/src/Mod/Draft/draftobjects/style_dimension.py new file mode 100644 index 000000000000..c4f75d677816 --- /dev/null +++ b/src/Mod/Draft/draftobjects/style_dimension.py @@ -0,0 +1,54 @@ +# *************************************************************************** +# * (c) 2020 Carlo Pavan * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * 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. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +"""This module provides the object code for Draft DimensionStyle. +""" +## @package style_dimension +# \ingroup DRAFT +# \brief This module provides the object code for Draft DimensionStyle. + +import FreeCAD as App +import Draft +from Draft import _DraftObject +from PySide.QtCore import QT_TRANSLATE_NOOP + +if App.GuiUp: + import FreeCADGui as Gui + from draftviewproviders.view_style_dimension import ViewProviderDraftDimensionStyle + +def make_dimension_style(existing_dimension = None): + """ + Make dimension style + """ + if not App.ActiveDocument: + App.Console.PrintError("No active document. Aborting\n") + return + obj = App.ActiveDocument.addObject("App::FeaturePython","DimensionStyle") + DimensionStyle(obj) + if App.GuiUp: + ViewProviderDraftDimensionStyle(obj.ViewObject, existing_dimension) + return obj + +class DimensionStyle(_DraftObject): + def __init__(self, obj): + _DraftObject.__init__(self, obj, "DimensionStyle") \ No newline at end of file diff --git a/src/Mod/Draft/draftviewproviders/view_style_dimension.py b/src/Mod/Draft/draftviewproviders/view_style_dimension.py new file mode 100644 index 000000000000..aaae6fe778cc --- /dev/null +++ b/src/Mod/Draft/draftviewproviders/view_style_dimension.py @@ -0,0 +1,230 @@ +# *************************************************************************** +# * (c) 2020 Carlo Pavan * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * 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. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +"""This module provides the view provider code for Draft DimensionStyle. +""" +## @package polararray +# \ingroup DRAFT +# \brief This module provides the view provider code for Draft DimensionStyle. + +import FreeCAD as App +import Draft +from Draft import _ViewProviderDraft +from PySide.QtCore import QT_TRANSLATE_NOOP +import draftutils.utils as utils + +class ViewProviderDraftDimensionStyle(_ViewProviderDraft): + """ + Dimension style dont have a proper object but just a viewprovider. + It stores inside a document object dimension settings and restore them on demand. + """ + def __init__(self, vobj, existing_dimension = None): + """ + vobj properties type parameter type + ---------------------------------------------------------------------------------- + vobj.ScaleMultiplier" App::PropertyFloat "DraftAnnotationScale" Float + + vobj.FontName App::PropertyFont "textfont" Text + vobj.FontSize App::PropertyLength "textheight" Float + vobj.TextSpacing App::PropertyLength "dimspacing" Float + + vobj.Decimals App::PropertyInteger "dimPrecision" Integer + vobj.ShowUnit App::PropertyBool + vobj.UnitOverride App::PropertyString + + vobj.LineWidth App::PropertyFloat + vobj.LineColor App::PropertyColor + vobj.ArrowSize App::PropertyLength "arrowsize" Float + vobj.ArrowType App::PropertyEnumeration "dimsymbol" Integer + vobj.FlipArrows App::PropertyBool + vobj.DimOvershoot App::PropertyDistance "dimovershoot" Float + vobj.ExtLines App::PropertyDistance "extlines" Float + vobj.ExtOvershoot App::PropertyDistance "extovershoot" Float + vobj.ShowLine App::PropertyBool + """ + + # annotation properties + vobj.addProperty("App::PropertyFloat","ScaleMultiplier", + "Annotation", + QT_TRANSLATE_NOOP("App::Property", + "Dimension size overall multiplier")) + + vobj.addProperty("App::PropertyBool","AutoUpdate", + "Annotation", + QT_TRANSLATE_NOOP("App::Property", + "Auto update associated dimensions")) + + # text properties + vobj.addProperty("App::PropertyFont","FontName", + "Text", + QT_TRANSLATE_NOOP("App::Property","Font name")) + + vobj.addProperty("App::PropertyLength","FontSize", + "Text", + QT_TRANSLATE_NOOP("App::Property", + "Font size")) + + vobj.addProperty("App::PropertyLength","TextSpacing", + "Text", + QT_TRANSLATE_NOOP("App::Property", + "The spacing between the text and " + "the dimension line")) + + # units properties + vobj.addProperty("App::PropertyInteger","Decimals", + "Units", + QT_TRANSLATE_NOOP("App::Property", + "The number of decimals to show")) + + vobj.addProperty("App::PropertyBool","ShowUnit", + "Units", + QT_TRANSLATE_NOOP("App::Property", + "Show the unit suffix")) + + vobj.addProperty("App::PropertyString","UnitOverride", + "Units", + QT_TRANSLATE_NOOP("App::Property", + "A unit to express the measurement. " + "Leave blank for system default")) + + # graphics properties + vobj.addProperty("App::PropertyFloat","LineWidth", + "Graphics", + QT_TRANSLATE_NOOP("App::Property","Line width")) + + vobj.addProperty("App::PropertyColor","LineColor", + "Graphics", + QT_TRANSLATE_NOOP("App::Property","Line color")) + + vobj.addProperty("App::PropertyLength","ArrowSize", + "Graphics", + QT_TRANSLATE_NOOP("App::Property","Arrow size")) + + vobj.addProperty("App::PropertyEnumeration","ArrowType", + "Graphics", + QT_TRANSLATE_NOOP("App::Property","Arrow type")) + + vobj.addProperty("App::PropertyBool","FlipArrows", + "Graphics", + QT_TRANSLATE_NOOP("App::Property", + "Rotate the dimension arrows 180 degrees")) + + vobj.addProperty("App::PropertyDistance","DimOvershoot", + "Graphics", + QT_TRANSLATE_NOOP("App::Property", + "The distance the dimension line is " + "extended past the extension lines")) + + vobj.addProperty("App::PropertyDistance","ExtLines", + "Graphics", + QT_TRANSLATE_NOOP("App::Property", + "Length of the extension lines")) + + vobj.addProperty("App::PropertyDistance","ExtOvershoot", + "Graphics", + QT_TRANSLATE_NOOP("App::Property", + "Length of the extension line above " + "the dimension line")) + + vobj.addProperty("App::PropertyBool","ShowLine", + "Graphics", + QT_TRANSLATE_NOOP("App::Property", + "Shows dimension line and arrows")) + + self.init_properties(vobj, existing_dimension) + + _ViewProviderDraft.__init__(self,vobj) + + def init_properties(self, vobj, existing_dimension): + """ + Initializes Dimension Style properties + """ + # get the style from FreeCAD Draft Parameters + param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") + annotation_scale = param.GetFloat("DraftAnnotationScale", 1.0) + + vobj.ScaleMultiplier = 1 / annotation_scale + vobj.AutoUpdate = True + + vobj.FontName = utils.get_param("textfont","") + vobj.FontSize = utils.get_param("textheight",0.20) + vobj.TextSpacing = utils.get_param("dimspacing",0.05) + + vobj.Decimals = utils.get_param("dimPrecision",2) + vobj.ShowUnit = utils.get_param("showUnit",True) + + vobj.ArrowSize = utils.get_param("arrowsize",0.1) + vobj.ArrowType = utils.ARROW_TYPES + vobj.ArrowType = utils.ARROW_TYPES[utils.get_param("dimsymbol",0)] + vobj.DimOvershoot = utils.get_param("dimovershoot",0) + vobj.ExtLines = utils.get_param("extlines",0.3) + vobj.ExtOvershoot = utils.get_param("extovershoot",0) + vobj.ShowLine = True + + if existing_dimension and hasattr(existing_dimension, "ViewObject"): + # get the style from given dimension + from draftutils import gui_utils + gui_utils.format_object(target = vobj.Object, origin = existing_dimension) + + def onChanged(self, vobj, prop): + if hasattr(vobj, "AutoUpdate"): + if vobj.AutoUpdate: + self.update_related_dimensions(vobj) + + def doubleClicked(self,vobj): + self.set_current(vobj) + + def setupContextMenu(self,vobj,menu): + action1 = menu.addAction("Set current") + action1.triggered.connect(lambda f=self.set_current, arg=vobj:f(arg)) + action2 = menu.addAction("Update dimensions") + action2.triggered.connect(lambda f=self.update_related_dimensions, arg=vobj:f(arg)) + + def set_current(self, vobj): + """ + Sets the current dimension style as default for new created dimensions + """ + param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") + param.SetFloat("DraftAnnotationScale", 1 / vobj.ScaleMultiplier) + + param.SetString("textfont", vobj.FontName) + param.SetFloat("textheight", vobj.FontSize) + param.SetFloat("dimspacing", vobj.TextSpacing) + + param.SetInt("dimPrecision", vobj.Decimals) + + param.SetFloat("arrowsize", vobj.ArrowSize) + param.SetInt("dimsymbol", utils.ARROW_TYPES.index(vobj.ArrowType)) + param.SetFloat("dimovershoot", vobj.DimOvershoot) + param.SetFloat("extlines", vobj.ExtLines) + param.SetFloat("extovershoot", vobj.ExtOvershoot) + + App.Console.PrintMessage("Current dimension style set to " + str(vobj.Object.Label) + "\n") + + def update_related_dimensions(self, vobj): + """ + Apply the style to the related dimensions + """ + from draftutils import gui_utils + for dim in vobj.Object.InList: + gui_utils.format_object(target = dim, origin = vobj.Object)