Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic property container with editor, no adding of properties yet
- Loading branch information
Showing
8 changed files
with
807 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ui version="4.0"> | ||
<class>Form</class> | ||
<widget class="QWidget" name="Form"> | ||
<property name="geometry"> | ||
<rect> | ||
<x>0</x> | ||
<y>0</y> | ||
<width>552</width> | ||
<height>651</height> | ||
</rect> | ||
</property> | ||
<property name="windowTitle"> | ||
<string>Form</string> | ||
</property> | ||
<layout class="QVBoxLayout" name="verticalLayout"> | ||
<item> | ||
<widget class="QTableView" name="table"> | ||
<property name="editTriggers"> | ||
<set>QAbstractItemView::AllEditTriggers</set> | ||
</property> | ||
<attribute name="horizontalHeaderCascadingSectionResizes"> | ||
<bool>true</bool> | ||
</attribute> | ||
<attribute name="horizontalHeaderStretchLastSection"> | ||
<bool>true</bool> | ||
</attribute> | ||
<attribute name="verticalHeaderVisible"> | ||
<bool>false</bool> | ||
</attribute> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QWidget" name="widget" native="true"> | ||
<layout class="QHBoxLayout" name="horizontalLayout"> | ||
<item> | ||
<widget class="QPushButton" name="remove"> | ||
<property name="text"> | ||
<string>Remove</string> | ||
</property> | ||
</widget> | ||
</item> | ||
<item> | ||
<widget class="QPushButton" name="add"> | ||
<property name="text"> | ||
<string>Add</string> | ||
</property> | ||
</widget> | ||
</item> | ||
</layout> | ||
</widget> | ||
</item> | ||
</layout> | ||
</widget> | ||
<resources/> | ||
<connections/> | ||
</ui> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
# -*- coding: utf-8 -*- | ||
# *************************************************************************** | ||
# * Copyright (c) 2020 sliptonic <shopinthewoods@gmail.com> * | ||
# * * | ||
# * 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 * | ||
# * * | ||
# *************************************************************************** | ||
|
||
import PathScripts.PathLog as PathLog | ||
|
||
__title__ = "Property type abstraction for editing purposes" | ||
__author__ = "sliptonic (Brad Collette)" | ||
__url__ = "https://www.freecadweb.org" | ||
__doc__ = "Prototype objects to allow extraction of setup sheet values and editing." | ||
|
||
|
||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) | ||
#PathLog.trackModule(PathLog.thisModule()) | ||
|
||
class Property(object): | ||
'''Base class for all prototype properties''' | ||
def __init__(self, name, propType, category, info): | ||
self.name = name | ||
self.propType = propType | ||
self.category = category | ||
self.info = info | ||
self.editorMode = 0 | ||
self.value = None | ||
|
||
def setValue(self, value): | ||
self.value = value | ||
def getValue(self): | ||
return self.value | ||
|
||
def setEditorMode(self, mode): | ||
self.editorMode = mode | ||
|
||
def displayString(self): | ||
if self.value is None: | ||
t = self.typeString() | ||
p = 'an' if t[0] in ['A', 'E', 'I', 'O', 'U'] else 'a' | ||
return "%s %s" % (p, t) | ||
return self.value | ||
|
||
def typeString(self): | ||
return "Property" | ||
|
||
def setupProperty(self, obj, name, category, value): | ||
created = False | ||
if not hasattr(obj, name): | ||
obj.addProperty(self.propType, name, category, self.info) | ||
self.initProperty(obj, name) | ||
created = True | ||
setattr(obj, name, value) | ||
return created | ||
|
||
def initProperty(self, obj, name): | ||
pass | ||
|
||
def setValueFromString(self, string): | ||
self.setValue(self.valueFromString(string)) | ||
|
||
def valueFromString(self, string): | ||
return string | ||
|
||
class PropertyEnumeration(Property): | ||
def typeString(self): | ||
return "Enumeration" | ||
|
||
def setValue(self, value): | ||
if list == type(value): | ||
self.enums = value # pylint: disable=attribute-defined-outside-init | ||
else: | ||
super(PropertyEnumeration, self).setValue(value) | ||
|
||
def getEnumValues(self): | ||
return self.enums | ||
|
||
def initProperty(self, obj, name): | ||
setattr(obj, name, self.enums) | ||
|
||
class PropertyQuantity(Property): | ||
def displayString(self): | ||
if self.value is None: | ||
return Property.displayString(self) | ||
return self.value.getUserPreferred()[0] | ||
|
||
class PropertyAngle(PropertyQuantity): | ||
def typeString(self): | ||
return "Angle" | ||
|
||
class PropertyDistance(PropertyQuantity): | ||
def typeString(self): | ||
return "Distance" | ||
|
||
class PropertyLength(PropertyQuantity): | ||
def typeString(self): | ||
return "Length" | ||
|
||
class PropertyPercent(Property): | ||
def typeString(self): | ||
return "Percent" | ||
|
||
class PropertyFloat(Property): | ||
def typeString(self): | ||
return "Float" | ||
|
||
def valueFromString(self, string): | ||
return float(string) | ||
|
||
class PropertyInteger(Property): | ||
def typeString(self): | ||
return "Integer" | ||
|
||
def valueFromString(self, string): | ||
return int(string) | ||
|
||
class PropertyBool(Property): | ||
def typeString(self): | ||
return "Bool" | ||
|
||
def valueFromString(self, string): | ||
return bool(string) | ||
|
||
class PropertyString(Property): | ||
def typeString(self): | ||
return "String" | ||
|
||
class PropertyMap(Property): | ||
def typeString(self): | ||
return "Map" | ||
|
||
def displayString(self, value): | ||
return str(value) | ||
|
||
class OpPrototype(object): | ||
|
||
PropertyType = { | ||
'App::PropertyAngle': PropertyAngle, | ||
'App::PropertyBool': PropertyBool, | ||
'App::PropertyDistance': PropertyDistance, | ||
'App::PropertyEnumeration': PropertyEnumeration, | ||
'App::PropertyFile': PropertyString, | ||
'App::PropertyFloat': PropertyFloat, | ||
'App::PropertyFloatConstraint': Property, | ||
'App::PropertyFloatList': Property, | ||
'App::PropertyInteger': PropertyInteger, | ||
'App::PropertyIntegerList': PropertyInteger, | ||
'App::PropertyLength': PropertyLength, | ||
'App::PropertyLink': Property, | ||
'App::PropertyLinkList': Property, | ||
'App::PropertyLinkSubListGlobal': Property, | ||
'App::PropertyMap': PropertyMap, | ||
'App::PropertyPercent': PropertyPercent, | ||
'App::PropertyString': PropertyString, | ||
'App::PropertyStringList': Property, | ||
'App::PropertyVectorDistance': Property, | ||
'App::PropertyVectorList': Property, | ||
'Part::PropertyPartShape': Property, | ||
} | ||
|
||
def __init__(self, name): | ||
self.Label = name | ||
self.properties = {} | ||
self.DoNotSetDefaultValues = True | ||
self.Proxy = None | ||
|
||
def __setattr__(self, name, val): | ||
if name in ['Label', 'DoNotSetDefaultValues', 'properties', 'Proxy']: | ||
if name == 'Proxy': | ||
val = None # make sure the proxy is never set | ||
return super(OpPrototype, self).__setattr__(name, val) | ||
self.properties[name].setValue(val) | ||
|
||
def addProperty(self, typeString, name, category, info = None): | ||
prop = self.PropertyType[typeString](name, typeString, category, info) | ||
self.properties[name] = prop | ||
return self | ||
|
||
def setEditorMode(self, name, mode): | ||
self.properties[name].setEditorMode(mode) | ||
|
||
def getProperty(self, name): | ||
return self.properties[name] | ||
|
||
def setupProperties(self, setup): | ||
return [p for p in self.properties if p.name in setup] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# -*- coding: utf-8 -*- | ||
# *************************************************************************** | ||
# * Copyright (c) 2020 sliptonic <shopinthewoods@gmail.com> * | ||
# * * | ||
# * 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 * | ||
# * * | ||
# *************************************************************************** | ||
|
||
import FreeCAD | ||
import PySide | ||
|
||
__title__ = 'Generic property container to store some values.' | ||
__author__ = 'sliptonic (Brad Collette)' | ||
__url__ = 'https://www.freecadweb.org' | ||
__doc__ = 'A generic container for typed properties in arbitrary categories.' | ||
|
||
def translate(context, text, disambig=None): | ||
return PySide.QtCore.QCoreApplication.translate(context, text, disambig) | ||
|
||
|
||
class PropertyContainer(object): | ||
'''Property container object.''' | ||
|
||
CustomPropertyGroups = 'CustomPropertyGroups' | ||
CustomPropertyGroupDefault = 'User' | ||
|
||
def __init__(self, obj): | ||
self.obj = obj | ||
obj.addProperty('App::PropertyStringList', self.CustomPropertyGroups, 'Base', PySide.QtCore.QT_TRANSLATE_NOOP('PathPropertyContainer', 'List of custom property groups')) | ||
obj.setEditorMode(self.CustomPropertyGroups, 2) # hide | ||
|
||
def __getstate__(self): | ||
return None | ||
|
||
def __setstate__(self, state): | ||
for obj in FreeCAD.ActiveDocument.Objects: | ||
if hasattr(obj, 'Proxy') and obj.Proxy == self: | ||
self.obj = obj | ||
obj.setEditorMode(self.CustomPropertyGroups, 2) # hide | ||
break | ||
return None | ||
|
||
def onDocumentRestored(self, obj): | ||
obj.setEditorMode(self.CustomPropertyGroups, 2) # hide | ||
|
||
def getCustomProperties(self): | ||
'''Return a list of all custom properties created in this container.''' | ||
return [p for p in self.obj.PropertiesList if self.obj.getGroupOfProperty(p) in self.obj.CustomPropertyGroups] | ||
|
||
def addCustomProperty(self, propertyType, name, group=None, desc=None): | ||
'''addCustomProperty(propertyType, name, group=None, desc=None) ... adds a custom property and tracks its group.''' | ||
if desc is None: | ||
desc = '' | ||
if group is None: | ||
group = self.CustomPropertyGroupDefault | ||
groups = self.obj.CustomPropertyGroups | ||
if not group in groups: | ||
groups.append(group) | ||
self.obj.CustomPropertyGroups = groups | ||
self.obj.addProperty(propertyType, name, group, desc) | ||
|
||
def Create(name = 'PropertyContainer'): | ||
obj = FreeCAD.ActiveDocument.addObject('App::FeaturePython', name) | ||
obj.Proxy = PropertyContainer(obj) | ||
return obj | ||
|
||
def IsPropertyContainer(obj): | ||
'''Returns True if the supplied object is a property container (or its Proxy).''' | ||
|
||
if type(obj) == PropertyContainer: | ||
return True | ||
if hasattr(obj, 'Proxy'): | ||
return IsPropertyContainer(obj.Proxy) | ||
return False | ||
|
Oops, something went wrong.