From 5c273e7593ecf7c2d12d1ee7d52a4208a15e27a2 Mon Sep 17 00:00:00 2001 From: vocx-fc Date: Tue, 19 May 2020 01:44:50 -0500 Subject: [PATCH] Draft: clean up code, PEP8, and docstrings for DraftLink This class was created by realthunder during the `LinkMerge`, in de66e563e0, to demonstrate how to use the `App::Link` objects to create Link aware arrays. It is used by `draftobject.array` (ortho, polar, circular) and `draftobject.patharray` to create respective Link arrays. This class is a bit mysterious. We need more documentation on how the properties are being set, and how the code interacts with the arrays that use it. --- src/Mod/Draft/draftobjects/draftlink.py | 159 +++++++++++++++--------- 1 file changed, 100 insertions(+), 59 deletions(-) diff --git a/src/Mod/Draft/draftobjects/draftlink.py b/src/Mod/Draft/draftobjects/draftlink.py index 32e4891a4f..5081255577 100644 --- a/src/Mod/Draft/draftobjects/draftlink.py +++ b/src/Mod/Draft/draftobjects/draftlink.py @@ -1,7 +1,5 @@ # *************************************************************************** -# * Copyright (c) 2009, 2010 Yorik van Havre * -# * Copyright (c) 2009, 2010 Ken Cline * -# * Copyright (c) 2020 FreeCAD Developers * +# * Copyright (c) 2019 Zheng, Lei (realthunder)* # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * @@ -20,79 +18,113 @@ # * USA * # * * # *************************************************************************** -"""This module provides the object code for the Draft Link object. +"""Provides the object code for the Draft Link object. + +This class was created by realthunder during the `LinkMerge` +to demonstrate how to use the `App::Link` objects to create +Link aware arrays. +It is used by `draftobject.array` (ortho, polar, circular) +and `draftobject.patharray` to create respective Link arrays. + +NOTE: this class is a bit mysterious. We need more documentation +on how the properties are being set, and how the code interacts with +the arrays that use it. """ ## @package draftlink # \ingroup DRAFT -# \brief This module provides the object code for the Draft Link object. +# \brief Provides the object code for the Draft Link object. from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD as App - -from draftutils.utils import get_param +import lazy_loader.lazy_loader as lz from draftobjects.base import DraftObject +from draftutils.messages import _wrn + +# Delay import of module until first use because it is heavy +Part = lz.LazyLoader("Part", globals(), "Part") +DraftGeomUtils = lz.LazyLoader("DraftGeomUtils", globals(), "DraftGeomUtils") class DraftLink(DraftObject): - """ - Documentation needed. - DraftLink was introduced by Realthunder to allow the use of new - App::Link object into Draft Array objects during version 0.19 development - cycle. + """New class to use the App::Link objects in arrays. + + Introduced by realthunder. + This is subclassed by `draftobjects.array.Array` + and by `draftobjects.patharray.PathArray`. """ - def __init__(self,obj,tp): + def __init__(self, obj, tp): self.use_link = False if obj else True super(DraftLink, self).__init__(obj, tp) if obj: self.attach(obj) def __getstate__(self): + """Return a tuple of all serializable objects or None.""" return self.__dict__ - def __setstate__(self,state): - if isinstance(state,dict): + def __setstate__(self, state): + """Set some internal properties for all restored objects.""" + if isinstance(state, dict): self.__dict__ = state else: self.use_link = False super(DraftLink, self).__setstate__(state) - def attach(self,obj): + def attach(self, obj): + """Set up the properties when the object is attached.""" if self.use_link: obj.addExtension('App::LinkExtensionPython', None) self.linkSetup(obj) - def canLinkProperties(self,_obj): + def canLinkProperties(self, _obj): + """Link properties. + + TODO: add more explanation. C++ override???""" return False - def linkSetup(self,obj): - obj.configLinkProperty('Placement',LinkedObject='Base') - if hasattr(obj,'ShowElement'): - # rename 'ShowElement' property to 'ExpandArray' to avoid conflict + def linkSetup(self, obj): + """Set up the link properties on attachment.""" + obj.configLinkProperty('Placement', LinkedObject='Base') + if hasattr(obj, 'ShowElement'): + # Rename 'ShowElement' property to 'ExpandArray' to avoid conflict # with native App::Link obj.configLinkProperty('ShowElement') showElement = obj.ShowElement - obj.addProperty("App::PropertyBool","ExpandArray","Draft", - QT_TRANSLATE_NOOP("App::Property","Show array element as children object")) + obj.addProperty("App::PropertyBool", + "ExpandArray", + "Draft", + QT_TRANSLATE_NOOP("App::Property", + "Show array element as " + "children object")) obj.ExpandArray = showElement obj.configLinkProperty(ShowElement='ExpandArray') obj.removeProperty('ShowElement') else: obj.configLinkProperty(ShowElement='ExpandArray') - if getattr(obj,'ExpandArray',False): - obj.setPropertyStatus('PlacementList','Immutable') - else: - obj.setPropertyStatus('PlacementList','-Immutable') - if not hasattr(obj,'LinkTransform'): - obj.addProperty('App::PropertyBool','LinkTransform',' Link') - if not hasattr(obj,'ColoredElements'): - obj.addProperty('App::PropertyLinkSubHidden','ColoredElements',' Link') - obj.setPropertyStatus('ColoredElements','Hidden') - obj.configLinkProperty('LinkTransform','ColoredElements') - def getViewProviderName(self,_obj): + if getattr(obj, 'ExpandArray', False): + obj.setPropertyStatus('PlacementList', 'Immutable') + else: + obj.setPropertyStatus('PlacementList', '-Immutable') + + if not hasattr(obj, 'LinkTransform'): + obj.addProperty('App::PropertyBool', + 'LinkTransform', + ' Link') + + if not hasattr(obj, 'ColoredElements'): + obj.addProperty('App::PropertyLinkSubHidden', + 'ColoredElements', + ' Link') + obj.setPropertyStatus('ColoredElements', 'Hidden') + + obj.configLinkProperty('LinkTransform', 'ColoredElements') + + def getViewProviderName(self, _obj): + """Override the view provider name.""" if self.use_link: return 'Gui::ViewProviderLinkPython' return '' @@ -109,50 +141,55 @@ class DraftLink(DraftObject): # all models should use 'use_link' by default # and this won't be run. self.use_link = bool(self.useLink) - App.Console.PrintWarning("Migrating 'useLink' to 'use_link', " - "{} ({})\n".format(obj.Label, - obj.TypeId)) + _wrn("Migrating 'useLink' to 'use_link', " + "{} ({})\n".format(obj.Label, obj.TypeId)) del self.useLink def onDocumentRestored(self, obj): + """Execute code when the document in restored.""" self.migrate_attributes(obj) + if self.use_link: self.linkSetup(obj) else: - obj.setPropertyStatus('Shape','-Transient') + obj.setPropertyStatus('Shape', '-Transient') + if obj.Shape.isNull(): - if getattr(obj,'PlacementList',None): - self.buildShape(obj,obj.Placement,obj.PlacementList) + if getattr(obj, 'PlacementList', None): + self.buildShape(obj, obj.Placement, obj.PlacementList) else: self.execute(obj) - def buildShape(self,obj,pl,pls): - import Part - import DraftGeomUtils - + def buildShape(self, obj, pl, pls): + """Build the shape of the link object.""" if self.use_link: - if not getattr(obj,'ExpandArray',True) or obj.Count != len(pls): - obj.setPropertyStatus('PlacementList','-Immutable') + if not getattr(obj, 'ExpandArray', True) or obj.Count != len(pls): + obj.setPropertyStatus('PlacementList', '-Immutable') obj.PlacementList = pls - obj.setPropertyStatus('PlacementList','Immutable') + obj.setPropertyStatus('PlacementList', 'Immutable') obj.Count = len(pls) if obj.Base: shape = Part.getShape(obj.Base) if shape.isNull(): - raise RuntimeError("'{}' cannot build shape of '{}'\n".format( - obj.Name,obj.Base.Name)) + _err_msg = ("'{}' cannot build shape " + "from '{}'\n".format(obj.Label, obj.Base.Label)) + raise RuntimeError(_err_msg) else: shape = shape.copy() shape.Placement = App.Placement() base = [] - for i,pla in enumerate(pls): - vis = getattr(obj,'VisibilityList',[]) - if len(vis)>i and not vis[i]: + for i, pla in enumerate(pls): + vis = getattr(obj, 'VisibilityList', []) + if len(vis) > i and not vis[i]: continue - # 'I' is a prefix for disambiguation when mapping element names - base.append(shape.transformed(pla.toMatrix(), op='I{}'.format(i))) - if getattr(obj,'Fuse',False) and len(base) > 1: + + # 'I' is a prefix for disambiguation + # when mapping element names + base.append(shape.transformed(pla.toMatrix(), + op='I{}'.format(i))) + + if getattr(obj, 'Fuse', False) and len(base) > 1: obj.Shape = base[0].multiFuse(base[1:]).removeSplitter() else: obj.Shape = Part.makeCompound(base) @@ -161,20 +198,24 @@ class DraftLink(DraftObject): obj.Placement = pl if self.use_link: - return False # return False to call LinkExtension::execute() + return False # return False to call LinkExtension::execute() def onChanged(self, obj, prop): + """Execute when a property changes.""" if not getattr(self, 'use_link', False): return + if prop == 'Fuse': if obj.Fuse: obj.setPropertyStatus('Shape', '-Transient') else: obj.setPropertyStatus('Shape', 'Transient') elif prop == 'ExpandArray': - if hasattr(obj,'PlacementList'): - obj.setPropertyStatus('PlacementList', - '-Immutable' if obj.ExpandArray else 'Immutable') + if hasattr(obj, 'PlacementList'): + if obj.ExpandArray: + obj.setPropertyStatus('PlacementList', '-Immutable') + else: + obj.setPropertyStatus('PlacementList', 'Immutable') _DraftLink = DraftLink