From 245fa7af0fdcf809b92bb6f811330e6c4d2ece02 Mon Sep 17 00:00:00 2001 From: vocx-fc Date: Tue, 16 Jun 2020 10:40:16 -0500 Subject: [PATCH] Draft: clean up the ViewProviderDraftAnnotation class This class is the base of the viewproviders of annotation-type objects like dimensions (linear, radial, angular), labels, and texts. The basic properties of `ViewProviderDraftAnnotation` are set up by a method `set_properties`, which can be called in the derived classes. In the general proxy object `DraftAnnotation` we implement the `onDocumentRestored` method in order to add the missing view property `AnnotationStyle` to older objects. --- .../Draft/draftobjects/draft_annotation.py | 44 +++- .../view_draft_annotation.py | 212 +++++++++++++----- 2 files changed, 188 insertions(+), 68 deletions(-) diff --git a/src/Mod/Draft/draftobjects/draft_annotation.py b/src/Mod/Draft/draftobjects/draft_annotation.py index ff6f12f433..c8e55b7f06 100644 --- a/src/Mod/Draft/draftobjects/draft_annotation.py +++ b/src/Mod/Draft/draftobjects/draft_annotation.py @@ -63,15 +63,21 @@ class DraftAnnotation(object): Check if new properties are present after the object is restored in order to migrate older objects. """ - self.add_missing_properties_0v19(obj) - - def add_missing_properties_0v19(self, obj): - """Provide missing annotation properties, if they don't exist.""" - if (hasattr(obj, "ViewObject") and obj.ViewObject - and not hasattr(obj.ViewObject, 'ScaleMultiplier')): + if hasattr(obj, "ViewObject") and obj.ViewObject: vobj = obj.ViewObject + self.add_missing_properties_0v19(obj, vobj) + + def add_missing_properties_0v19(self, obj, vobj): + """Provide missing annotation properties, if they don't exist.""" + vproperties = vobj.PropertiesList + + if 'ScaleMultiplier' not in vproperties: _tip = QT_TRANSLATE_NOOP("App::Property", - "Dimension size overall multiplier") + "General scaling factor that affects " + "the annotation consistently\n" + "because it scales the text, " + "and the line decorations, if any,\n" + "in the same proportion.") vobj.addProperty("App::PropertyFloat", "ScaleMultiplier", "Annotation", @@ -81,6 +87,30 @@ class DraftAnnotation(object): _info = "added view property 'ScaleMultiplier'" _wrn("v0.19, " + obj.Label + ", " + _tr(_info)) + if 'AnnotationStyle' not in vproperties: + _tip = QT_TRANSLATE_NOOP("App::Property", + "Annotation style to apply " + "to this object.\n" + "When using a saved style " + "some of the view properties " + "will become read-only;\n" + "they will only be editable by changing " + "the style through " + "the 'Annotation style editor' tool.") + vobj.addProperty("App::PropertyEnumeration", + "AnnotationStyle", + "Annotation", + _tip) + styles = [] + for key in obj.Document.Meta.keys(): + if key.startswith("Draft_Style_"): + styles.append(key[12:]) + + vobj.AnnotationStyle = [""] + styles + + _info = "added view property 'AnnotationStyle'" + _wrn("v0.19, " + obj.Label + ", " + _tr(_info)) + def __getstate__(self): """Return a tuple of objects to save or None. diff --git a/src/Mod/Draft/draftviewproviders/view_draft_annotation.py b/src/Mod/Draft/draftviewproviders/view_draft_annotation.py index a5804ae24a..cea81f7054 100644 --- a/src/Mod/Draft/draftviewproviders/view_draft_annotation.py +++ b/src/Mod/Draft/draftviewproviders/view_draft_annotation.py @@ -1,4 +1,6 @@ # *************************************************************************** +# * Copyright (c) 2020 Carlo Pavan * +# * Copyright (c) 2020 Eliud Cabrera Castillo * # * * # * This file is part of the FreeCAD CAx development system. * # * * @@ -19,127 +21,215 @@ # * USA * # * * # *************************************************************************** -"""This module provides the Draft Annotations view provider base class -""" -## @package annotation -# \ingroup DRAFT -# \brief This module provides the Draft Annotations view provider base class +"""Provides the base class for many annotation viewproviders. +This is inherited and used by many viewproviders that show dimensions +and text created on screen through Coin (pivy). +- DimensionBase +- LinearDimension +- AngularDimension +- Label +- Text + +Its edit mode launches the `Draft_Edit` command. +""" +## @package view_draft_annotation +# \ingroup DRAFT +# \brief Provides the base class for many annotation viewproviders. + +import json +from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD as App -from PySide.QtCore import QT_TRANSLATE_NOOP +import draftutils.utils as utils +from draftutils.messages import _msg if App.GuiUp: import FreeCADGui as Gui +param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") + class ViewProviderDraftAnnotation(object): - """ - The base class for Draft Annotation Viewproviders - This class is not used directly, but inherited by all annotation - view providers. + """The base class for Draft Annotation viewproviders. + + This class is intended to be inherited by more specialized viewproviders, + for example, `Text`, `LinearDimension`, `RadialDimension`, and `Label`. """ def __init__(self, vobj): - #vobj.Proxy = self - #self.Object = vobj.Object + self.set_properties(vobj) + self.Object = vobj.Object + vobj.Proxy = self - # annotation properties - vobj.addProperty("App::PropertyFloat","ScaleMultiplier", - "Annotation",QT_TRANSLATE_NOOP("App::Property", - "Dimension size overall multiplier")) - vobj.addProperty("App::PropertyEnumeration", "AnnotationStyle", - "Annotation", QT_TRANSLATE_NOOP("App::Property", - "Annotation style")) + def set_properties(self, vobj): + """Set the properties only if they don't already exist.""" + properties = vobj.PropertiesList + self.set_annotation_properties(vobj, properties) + self.set_graphics_properties(vobj, properties) - # 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")) + def set_annotation_properties(self, vobj, properties): + """Set annotation properties only if they don't already exist.""" + if "ScaleMultiplier" not in properties: + _tip = QT_TRANSLATE_NOOP("App::Property", + "General scaling factor that affects " + "the annotation consistently\n" + "because it scales the text, " + "and the line decorations, if any,\n" + "in the same proportion.") + vobj.addProperty("App::PropertyFloat", + "ScaleMultiplier", + "Annotation", + _tip) + annotation_scale = param.GetFloat("DraftAnnotationScale", 1.0) + if annotation_scale != 0: + vobj.ScaleMultiplier = 1 / annotation_scale - param = App.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft") - annotation_scale = param.GetFloat("DraftAnnotationScale", 1.0) - if annotation_scale != 0: - vobj.ScaleMultiplier = 1 / annotation_scale - styles = [key[12:] for key in vobj.Object.Document.Meta.keys() if key.startswith("Draft_Style_")] - vobj.AnnotationStyle = [""] + styles + if "AnnotationStyle" not in properties: + _tip = QT_TRANSLATE_NOOP("App::Property", + "Annotation style to apply " + "to this object.\n" + "When using a saved style " + "some of the view properties " + "will become read-only;\n" + "they will only be editable by changing " + "the style through " + "the 'Annotation style editor' tool.") + vobj.addProperty("App::PropertyEnumeration", + "AnnotationStyle", + "Annotation", + _tip) + styles = [] + for key in vobj.Object.Document.Meta.keys(): + if key.startswith("Draft_Style_"): + styles.append(key[12:]) + vobj.AnnotationStyle = [""] + styles + + def set_graphics_properties(self, vobj, properties): + """Set graphics properties only if they don't already exist.""" + if "LineWidth" not in properties: + _tip = QT_TRANSLATE_NOOP("App::Property", "Line width") + vobj.addProperty("App::PropertyFloat", + "LineWidth", + "Graphics", + _tip) + + if "LineColor" not in properties: + _tip = QT_TRANSLATE_NOOP("App::Property", "Line color") + vobj.addProperty("App::PropertyColor", + "LineColor", + "Graphics", + _tip) def __getstate__(self): + """Return a tuple of objects to save or None.""" return None def __setstate__(self, state): + """Set the internal properties from the restored state.""" return None - def attach(self,vobj): + def attach(self, vobj): + """Set up the scene sub-graph of the view provider.""" self.Object = vobj.Object - return def updateData(self, obj, prop): + """Execute when a property from the Proxy class is changed.""" return def getDisplayModes(self, vobj): - modes=[] + """Return the display modes that this viewprovider supports.""" + modes = [] return modes def setDisplayMode(self, mode): + """Return the saved display mode.""" return mode def onChanged(self, vobj, prop): - if (prop == "AnnotationStyle") and hasattr(vobj,"AnnotationStyle"): - import gui_annotationstyleeditor - if (not vobj.AnnotationStyle) or (vobj.AnnotationStyle == " "): + """Execute when a view property is changed.""" + properties = vobj.PropertiesList + meta = vobj.Object.Document.Meta + + if prop == "AnnotationStyle" and "AnnotationStyle" in properties: + if not vobj.AnnotationStyle or vobj.AnnotationStyle == " ": # unset style - for visprop in gui_annotationstyleeditor.DEFAULT.keys(): - if visprop in vobj.PropertiesList: + _msg(16 * "-") + _msg("Unset style") + for visprop in utils.ANNOTATION_STYLE.keys(): + if visprop in properties: # make property writable - vobj.setEditorMode(visprop,0) + vobj.setPropertyStatus(visprop, '-ReadOnly') else: # set style - import json styles = {} - for key, value in vobj.Object.Document.Meta.items(): + for key, value in meta.items(): if key.startswith("Draft_Style_"): - styles[key[12:]] = json.loads(value) - if prop.AnnotationStyle in styles: - style = styles[prop.AnnotationStyle] - for visprop in style.keys(): - if visprop in vobj.PropertiesList: - try: - getattr(vobj,visprop).setValue(style[visprop]) - except: - setattr(vobj,visprop,style[visprop]) - # make property read-only - vobj.setEditorMode(visprop,1) + styles[key[12:]] = json.loads(value) - def execute(self,vobj): + if vobj.AnnotationStyle in styles: + _msg(16 * "-") + _msg("Style: {}".format(vobj.AnnotationStyle)) + style = styles[vobj.AnnotationStyle] + for visprop in style.keys(): + if visprop in properties: + try: + getattr(vobj, visprop).setValue(style[visprop]) + _msg("setValue: " + "'{}', '{}'".format(visprop, + style[visprop])) + except AttributeError: + setattr(vobj, visprop, style[visprop]) + _msg("setattr: " + "'{}', '{}'".format(visprop, + style[visprop])) + # make property read-only + vobj.setPropertyStatus(visprop, 'ReadOnly') + + def execute(self, vobj): + """Execute when the object is created or recomputed.""" return - def setEdit(self,vobj,mode=0): + def setEdit(self, vobj, mode=0): + """Execute the code when entering the specific edit mode. + + Currently only mode 0 works. + """ if mode == 0: Gui.runCommand("Draft_Edit") return True return False - def unsetEdit(self,vobj,mode=0): + def unsetEdit(self, vobj, mode=0): + """Execute the code when leaving the specific edit mode. + + Currently only mode 0 works. + It runs the finish method of the currently active command, and close + the task panel if any. + """ if App.activeDraftCommand: App.activeDraftCommand.finish() Gui.Control.closeDialog() return False def getIcon(self): - return ":/icons/Draft_Draft.svg" + """Return the path to the icon used by the view provider.""" + return ":/icons/Draft_Text.svg" def claimChildren(self): - """perhaps this is not useful???""" + """Return objects that will be placed under it in the tree view. + + Editor: perhaps this is not useful??? + """ objs = [] - if hasattr(self.Object,"Base"): + if hasattr(self.Object, "Base"): objs.append(self.Object.Base) - if hasattr(self.Object,"Objects"): + if hasattr(self.Object, "Objects"): objs.extend(self.Object.Objects) - if hasattr(self.Object,"Components"): + if hasattr(self.Object, "Components"): objs.extend(self.Object.Components) - if hasattr(self.Object,"Group"): + if hasattr(self.Object, "Group"): objs.extend(self.Object.Group) + return objs