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.
This commit is contained in:
vocx-fc
2020-06-16 10:40:16 -05:00
committed by Yorik van Havre
parent 4909abf458
commit 245fa7af0f
2 changed files with 188 additions and 68 deletions

View File

@@ -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.

View File

@@ -1,4 +1,6 @@
# ***************************************************************************
# * Copyright (c) 2020 Carlo Pavan <carlopav@gmail.com> *
# * Copyright (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
# * *
# * 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