Added docstrings to Gui classes.
This commit is contained in:
committed by
Yorik van Havre
parent
79337b998d
commit
bc6ff3690e
@@ -33,6 +33,11 @@ import importlib
|
||||
from PathScripts import PathUtils
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__title__ = "Path Operation UI base classes"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Base classes and framework for Path operation's UI"
|
||||
|
||||
# TaskPanelLayout
|
||||
# 0 ... existing toolbox layout
|
||||
# 1 ... reverse order
|
||||
@@ -52,6 +57,11 @@ def translate(context, text, disambig=None):
|
||||
|
||||
|
||||
class ViewProvider(object):
|
||||
'''Generic view provider for path objects.
|
||||
Deducts the icon name from operation name, brings up the TaskPanel
|
||||
with pages corresponding to the operation's opFeatures() and forwards
|
||||
property change notifications to the page controllers.
|
||||
'''
|
||||
|
||||
def __init__(self, vobj, resources):
|
||||
PathLog.track()
|
||||
@@ -69,10 +79,15 @@ class ViewProvider(object):
|
||||
return
|
||||
|
||||
def deleteObjectsOnReject(self):
|
||||
'''deleteObjectsOnReject() ... return true if all objects should
|
||||
be created if the user hits cancel. This is used during the initial
|
||||
edit session, if the user does not press OK, it is assumed they've
|
||||
changed their mind about creating the operation.'''
|
||||
PathLog.track()
|
||||
return hasattr(self, 'deleteOnReject') and self.deleteOnReject
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
'''setEdit(vobj, mode=0) ... initiate editing of receivers model.'''
|
||||
PathLog.track()
|
||||
page = self.getTaskPanelOpPage(vobj.Object)
|
||||
selection = self.getSelectionFactory()
|
||||
@@ -81,15 +96,19 @@ class ViewProvider(object):
|
||||
return True
|
||||
|
||||
def setupTaskPanel(self, panel):
|
||||
'''setupTaskPanel(panel) ... internal function to start the editor.'''
|
||||
self.panel = panel
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCADGui.Control.showDialog(panel)
|
||||
panel.setupUi()
|
||||
|
||||
def clearTaskPanel(self):
|
||||
'''clearTaskPanel() ... internal callback function when editing has finished.'''
|
||||
self.panel = None
|
||||
|
||||
def __getstate__(self):
|
||||
'''__getstate__() ... callback before receiver is saved to a file.
|
||||
Returns a dictionary with the receiver's resources as strings.'''
|
||||
PathLog.track()
|
||||
state = {}
|
||||
state['OpName'] = self.OpName
|
||||
@@ -99,31 +118,41 @@ class ViewProvider(object):
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
'''__setstate__(state) ... callback on restoring a saved instance, pendant to __getstate__()
|
||||
state is the dictionary returned by __getstate__().'''
|
||||
self.OpName = state['OpName']
|
||||
self.OpIcon = state['OpIcon']
|
||||
self.OpPageModule = state['OpPageModule']
|
||||
self.OpPageClass = state['OpPageClass']
|
||||
|
||||
def getIcon(self):
|
||||
'''getIcon() ... the icon used in the object tree'''
|
||||
return self.OpIcon
|
||||
|
||||
def getTaskPanelOpPage(self, obj):
|
||||
'''getTaskPanelOpPage(obj) ... use the stored information to instanciate the receiver op's page controller.'''
|
||||
mod = importlib.import_module(self.OpPageModule)
|
||||
cls = getattr(mod, self.OpPageClass)
|
||||
return cls(obj, 0)
|
||||
|
||||
def getSelectionFactory(self):
|
||||
'''getSelectionFactory() ... return a factory function that can be used to create the selection observer.'''
|
||||
return PathSelection.select(self.OpName)
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
'''updateData(obj, prop) ... callback whenever a property of the receiver's model is assigned.
|
||||
The callback is forwarded to the task panel - in case an editing session is ongoing.'''
|
||||
# PathLog.track(obj.Label, prop) # Creates a lot of noise
|
||||
if self.panel:
|
||||
self.panel.updateData(obj, prop)
|
||||
|
||||
class TaskPanelPage(object):
|
||||
'''Base class for all task panel pages.'''
|
||||
|
||||
# task panel interaction framework
|
||||
def __init__(self, obj, features):
|
||||
'''__init__(obj, features) ... framework initialisation.
|
||||
Do not overwrite, implement initPage(obj) instead.'''
|
||||
self.obj = obj
|
||||
self.form = self.getForm()
|
||||
self.setDirty()
|
||||
@@ -131,50 +160,94 @@ class TaskPanelPage(object):
|
||||
self.features = features
|
||||
|
||||
def setDirty(self):
|
||||
'''setDirty() ... mark receiver as dirty, causing the model to be recalculated if OK or Apply is pressed.'''
|
||||
self.isdirty = True
|
||||
def setClean(self):
|
||||
'''setClean() ... mark receiver as clean, indicating there is no need to recalculate the model even if the user presses OK or Apply.'''
|
||||
self.isdirty = False
|
||||
|
||||
def pageGetFields(self):
|
||||
'''pageGetFields() ... internal callback.
|
||||
Do not overwrite, implement getFields(obj) instead.'''
|
||||
self.getFields(self.obj)
|
||||
self.setDirty()
|
||||
|
||||
def pageSetFields(self):
|
||||
'''pageSetFields() ... internal callback.
|
||||
Do not overwrite, implement setFields(obj) instead.'''
|
||||
self.setFields(self.obj)
|
||||
|
||||
def pageRegisterSignalHandlers(self):
|
||||
'''pageRegisterSignalHandlers() .. internal callback.
|
||||
Registers a callback for all signals returned by getSignalsForUpdate(obj).
|
||||
Do not overwrite, implement getSignalsForUpdate(obj) and/or registerSignalHandlers(obj) instead.'''
|
||||
for signal in self.getSignalsForUpdate(self.obj):
|
||||
signal.connect(self.pageGetFields)
|
||||
self.registerSignalHandlers(self.obj)
|
||||
|
||||
def pageUpdateData(self, obj, prop):
|
||||
'''pageUpdateData(obj, prop) ... internal callback.
|
||||
Do not overwrite, implement updateData(obj) instaed.'''
|
||||
self.updateData(obj, prop)
|
||||
|
||||
def setTitle(self, title):
|
||||
'''setTitle(title) ... sets a title for the page.'''
|
||||
self.title = title
|
||||
def getTitle(self, obj):
|
||||
'''getTitle(obj) ... return title to be used for the receiver page.
|
||||
The default implementation returns what was previously set with setTitle(title).
|
||||
Can safely be overwritten by subclasses.'''
|
||||
return self.title
|
||||
|
||||
# subclass interface
|
||||
def initPage(self, obj):
|
||||
'''initPage(obj) ... overwrite to customize UI for specific model.
|
||||
Note that this function is invoked after all page controllers have been created.
|
||||
Should be overwritten by subclasses.'''
|
||||
pass
|
||||
def modifyStandardButtons(self, buttonBox):
|
||||
'''modifyStandardButtons(buttonBox) ... overwrite if the task panel standard buttons need to be modified.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
pass
|
||||
def getForm(self):
|
||||
'''getForm() ... return UI form for this page.
|
||||
Must be overwritten by subclasses.'''
|
||||
pass
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... overwrite to transfer values from UI to obj's properties.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
pass
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... overwrite to transfer obj's property values to UI.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
pass
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return signals which, when triggered, cause the receiver to update the model.
|
||||
See also registerSignalHandlers(obj)
|
||||
Can safely be overwritten by subclasses.'''
|
||||
return []
|
||||
def registerSignalHandlers(self, obj):
|
||||
'''registerSignalHandlers(obj) ... overwrite to register custom signal handlers.
|
||||
In case an update of a model is not the desired operation of a signal invocation
|
||||
(see getSignalsForUpdate(obj)) this function can be used to register signal handlers
|
||||
manually.
|
||||
Can safely be overwritten by subclasses.'''
|
||||
pass
|
||||
def updateData(self, obj, prop):
|
||||
'''updateData(obj, prop) ... overwrite if the receiver needs to react to property changes that might not have been caused by the receiver itself.
|
||||
Sometimes a model will recalculate properties based on a change of another property. In order to keep the UI up to date with such changes this
|
||||
function can be used.
|
||||
Please note that the callback is synchronous with the property assignment operation. Also note that the notification is invoked regardless of the
|
||||
actual value of the property assignment. In other words it also fires if a property gets assigned the same value it already has.
|
||||
Taking above observations into account the implementation has to take care that it doesn't overwrite modified UI values by invoking setFields(obj).
|
||||
This can happen if a subclass unconditionally transfers all values in getFields(obj) to the model and just calls setFields(obj) in this callback.
|
||||
In such a scenario the first property assignment will cause all changes in the UI of the other fields to be overwritten by setFields(obj).
|
||||
You have been warned.'''
|
||||
pass
|
||||
|
||||
# helpers
|
||||
def selectInComboBox(self, name, combo):
|
||||
'''selectInComboBox(name, combo) ... helper function to select a specific value in a combo box.'''
|
||||
index = combo.findText(name, QtCore.Qt.MatchFixedString)
|
||||
if index >= 0:
|
||||
combo.blockSignals(True)
|
||||
@@ -182,6 +255,7 @@ class TaskPanelPage(object):
|
||||
combo.blockSignals(False)
|
||||
|
||||
def setupToolController(self, obj, combo):
|
||||
'''setupToolController(obj, combo) ... helper function to setup obj's ToolController in the given combo box.'''
|
||||
controllers = PathUtils.getToolControllers(self.obj)
|
||||
labels = [c.Label for c in controllers]
|
||||
combo.blockSignals(True)
|
||||
@@ -194,17 +268,20 @@ class TaskPanelPage(object):
|
||||
self.selectInComboBox(obj.ToolController.Label, combo)
|
||||
|
||||
def updateToolController(self, obj, combo):
|
||||
'''updateToolController(obj, combo) ... helper function to update obj's ToolController property if a different one has been selected in the combo box.'''
|
||||
tc = PathUtils.findToolController(obj, combo.currentText())
|
||||
if obj.ToolController != tc:
|
||||
obj.ToolController = tc
|
||||
|
||||
def updateInputField(self, obj, prop, widget):
|
||||
'''updateInputField(obj, prop, widget) ... helper function to update obj's property named prop with the value from widget, if it has changed.'''
|
||||
value = FreeCAD.Units.Quantity(widget.text()).Value
|
||||
if getattr(obj, prop) != value:
|
||||
PathLog.debug("updateInputField(%s, %s): %.2f -> %.2f" % (obj.Label, prop, getattr(obj, prop), value))
|
||||
setattr(obj, prop, value)
|
||||
|
||||
class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
'''Page controller for the base geometry.'''
|
||||
DataObject = QtCore.Qt.ItemDataRole.UserRole
|
||||
DataObjectSub = QtCore.Qt.ItemDataRole.UserRole + 1
|
||||
|
||||
@@ -323,17 +400,14 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
|
||||
|
||||
class TaskPanelBaseLocationPage(TaskPanelPage):
|
||||
'''Page controller for base locations. Uses PathGetPoint.'''
|
||||
|
||||
DataLocation = QtCore.Qt.ItemDataRole.UserRole
|
||||
|
||||
def getForm(self):
|
||||
self.formLoc = FreeCADGui.PySideUic.loadUi(":/panels/PageBaseLocationEdit.ui")
|
||||
self.formPts = FreeCADGui.PySideUic.loadUi(":/panels/PointEdit.ui")
|
||||
self.formLoc.baseList.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
|
||||
self.formPts.setParent(self.formLoc.addRemoveEdit.parent())
|
||||
self.formLoc.addRemoveEdit.parent().layout().addWidget(self.formPts)
|
||||
self.formPts.hide()
|
||||
self.getPoint = PathGetPoint.TaskPanel(self.formLoc.addRemoveEdit, self.formPts)
|
||||
self.getPoint = PathGetPoint.TaskPanel(self.formLoc.addRemoveEdit)
|
||||
return self.formLoc
|
||||
|
||||
def modifyStandardButtons(self, buttonBox):
|
||||
@@ -430,10 +504,11 @@ class TaskPanelBaseLocationPage(TaskPanelPage):
|
||||
|
||||
|
||||
class TaskPanelHeightsPage(TaskPanelPage):
|
||||
'''Page controller for heights.'''
|
||||
def getForm(self):
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageHeightsEdit.ui")
|
||||
def getTitle(self, obj):
|
||||
return translate("Path_AreaOp", "Heights")
|
||||
return translate("Path", "Heights")
|
||||
def getFields(self, obj):
|
||||
self.updateInputField(obj, 'SafeHeight', self.form.safeHeight)
|
||||
self.updateInputField(obj, 'ClearanceHeight', self.form.clearanceHeight)
|
||||
@@ -452,10 +527,9 @@ class TaskPanelHeightsPage(TaskPanelPage):
|
||||
|
||||
|
||||
class TaskPanelDepthsPage(TaskPanelPage):
|
||||
|
||||
'''Page controller for depths.'''
|
||||
def getForm(self):
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageDepthsEdit.ui")
|
||||
|
||||
def initPage(self, obj):
|
||||
if not PathOp.FeatureStepDown & self.features:
|
||||
self.form.stepDown.hide()
|
||||
@@ -464,10 +538,8 @@ class TaskPanelDepthsPage(TaskPanelPage):
|
||||
if not PathOp.FeatureFinishDepth & self.features:
|
||||
self.form.finishDepth.hide()
|
||||
self.form.finishDepthLabel.hide()
|
||||
|
||||
def getTitle(self, obj):
|
||||
return translate("PathOp", "Depths")
|
||||
|
||||
def getFields(self, obj):
|
||||
self.updateInputField(obj, 'StartDepth', self.form.startDepth)
|
||||
self.updateInputField(obj, 'FinalDepth', self.form.finalDepth)
|
||||
@@ -491,16 +563,23 @@ class TaskPanelDepthsPage(TaskPanelPage):
|
||||
if PathOp.FeatureFinishDepth & self.features:
|
||||
signals.append(self.form.finishDepth.editingFinished)
|
||||
return signals
|
||||
|
||||
def pageUpdateData(self, obj, prop):
|
||||
if prop in ['StartDepth', 'FinalDepth', 'StepDown', 'FinishDepth']:
|
||||
self.setFields(obj)
|
||||
|
||||
class TaskPanel(object):
|
||||
|
||||
'''
|
||||
Generic TaskPanel implementation handling the standard Path operation layout.
|
||||
This class only implements the framework and takes care of bringing all pages up and down in a controller fashion.
|
||||
It implements the standard editor behaviour for OK, Cancel and Apply and tracks if the model is still in sync with
|
||||
the UI.
|
||||
However, all display and processing of fields is handled by the page contollers which are managed in a list. All
|
||||
event callbacks and framework actions are forwarded to the page controllers in turn and each page controller is
|
||||
expected to process all events concerning the data it manages.
|
||||
'''
|
||||
def __init__(self, obj, deleteOnReject, opPage, selectionFactory):
|
||||
PathLog.track(obj.Label, deleteOnReject, opPage, selectionFactory)
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_AreaOp", "AreaOp Operation"))
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path", "AreaOp Operation"))
|
||||
self.deleteOnReject = deleteOnReject
|
||||
self.featurePages = []
|
||||
|
||||
@@ -564,17 +643,20 @@ class TaskPanel(object):
|
||||
self.isdirty = True
|
||||
|
||||
def isDirty(self):
|
||||
'''isDirty() ... returns true if the model is not in sync with the UI anymore.'''
|
||||
for page in self.featurePages:
|
||||
if page.isdirty:
|
||||
return True
|
||||
return self.isdirty
|
||||
|
||||
def setClean(self):
|
||||
'''setClean() ... set the reciever and all its pages clean.'''
|
||||
self.isdirty = False
|
||||
for page in self.featurePages:
|
||||
page.setClean()
|
||||
|
||||
def accept(self):
|
||||
'''accept() ... callback invoked when user presses the task panel OK button.'''
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
self.cleanup()
|
||||
if self.isDirty:
|
||||
@@ -582,49 +664,58 @@ class TaskPanel(object):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def reject(self):
|
||||
'''reject() ... callback invoked when user presses the task panel Cancel button.'''
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
self.cleanup()
|
||||
if self.deleteOnReject:
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_AreaOp", "Uncreate AreaOp Operation"))
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path", "Uncreate AreaOp Operation"))
|
||||
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def cleanup(self):
|
||||
'''cleanup() ... implements common cleanup tasks.'''
|
||||
self.obj.ViewObject.Proxy.clearTaskPanel()
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
FreeCADGui.Selection.removeObserver(self.s)
|
||||
|
||||
def clicked(self, button):
|
||||
'''clicked(button) ... callback invoked when the user presses any of the task panel buttons.'''
|
||||
if button == QtGui.QDialogButtonBox.Apply:
|
||||
self.panelGetFields()
|
||||
self.setClean()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def modifyStandardButtons(self, buttonBox):
|
||||
'''modifyStandarButtons(buttonBox) ... callback in case the task panel buttons need to be modified.'''
|
||||
for page in self.featurePages:
|
||||
page.modifyStandardButtons(buttonBox)
|
||||
|
||||
def panelGetFields(self):
|
||||
'''panelGetFields() ... invoked to trigger a complete transfer of UI data to the model.'''
|
||||
PathLog.track()
|
||||
for page in self.featurePages:
|
||||
page.pageGetFields()
|
||||
|
||||
def panelSetFields(self):
|
||||
'''panelSetFields() ... invoked to trigger a complete transfer of the model's propeties to the UI.'''
|
||||
PathLog.track()
|
||||
for page in self.featurePages:
|
||||
page.pageSetFields()
|
||||
|
||||
def open(self):
|
||||
'''open() ... callback invoked when the task panel is opened.'''
|
||||
self.s = SelObserver(self.selectionFactory)
|
||||
# install the function mode resident
|
||||
FreeCADGui.Selection.addObserver(self.s)
|
||||
|
||||
def getStandardButtons(self):
|
||||
'''getStandardButtons() ... returns the Buttons for the task panel.'''
|
||||
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Apply | QtGui.QDialogButtonBox.Cancel)
|
||||
|
||||
def setupUi(self):
|
||||
'''setupUi() ... internal function to initialise all pages.'''
|
||||
PathLog.track(self.deleteOnReject)
|
||||
|
||||
if self.deleteOnReject and PathOp.FeatureBaseGeometry & self.obj.Proxy.opFeatures(self.obj):
|
||||
@@ -639,6 +730,7 @@ class TaskPanel(object):
|
||||
page.pageRegisterSignalHandlers()
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
'''updateDate(obj, prop) ... callback invoked whenever a model's property is assigned a value.'''
|
||||
# PathLog.track(obj.Label, prop) # creates a lot of noise
|
||||
for page in self.featurePages:
|
||||
page.pageUpdateData(obj, prop)
|
||||
@@ -647,7 +739,8 @@ class TaskPanel(object):
|
||||
return True
|
||||
|
||||
class SelObserver:
|
||||
|
||||
'''Implementation of the selection observer used by the task panel.
|
||||
Its specific behaviour is determined by the factory function.'''
|
||||
def __init__(self, factory):
|
||||
factory()
|
||||
|
||||
@@ -658,11 +751,12 @@ class SelObserver:
|
||||
FreeCADGui.doCommand('Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj + ')')
|
||||
FreeCADGui.updateGui()
|
||||
|
||||
class _CommandSetStartPoint:
|
||||
class CommandSetStartPoint:
|
||||
'''Command to set the start point for an operation.'''
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-StartPoint',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_AreaOp", "Pick Start Point"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_AreaOp", "Pick Start Point")}
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path", "Pick Start Point"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path", "Pick Start Point")}
|
||||
|
||||
def IsActive(self):
|
||||
if FreeCAD.ActiveDocument is None:
|
||||
@@ -683,6 +777,10 @@ class _CommandSetStartPoint:
|
||||
FreeCADGui.Snapper.getPoint(callback=self.setpoint)
|
||||
|
||||
def Create(res):
|
||||
'''Create(res) ... generic implementation of a create function.
|
||||
res is an instance of CommandResources. It is not excpected that the user invokes
|
||||
this function directly, but calls the Activated() function of the Command object
|
||||
that is created in each operations Gui implementation.'''
|
||||
FreeCAD.ActiveDocument.openTransaction("Create %s" % res.name)
|
||||
obj = res.objFactory(res.name)
|
||||
vobj = ViewProvider(obj.ViewObject, res)
|
||||
@@ -692,6 +790,10 @@ def Create(res):
|
||||
return obj
|
||||
|
||||
class CommandPathOp:
|
||||
'''Generic, data driven implementation of a Path operation creation command.
|
||||
Instances of this class are stored in all Path operation Gui modules and can
|
||||
be used to create said operations with view providers and all.'''
|
||||
|
||||
def __init__(self, resources):
|
||||
self.res = resources
|
||||
|
||||
@@ -714,6 +816,7 @@ class CommandPathOp:
|
||||
return Create(self.res)
|
||||
|
||||
class CommandResources:
|
||||
'''POD class to hold command specific resources.'''
|
||||
def __init__(self, name, objFactory, opPageClass, pixmap, menuText, accelKey, toolTip):
|
||||
self.name = name
|
||||
self.objFactory = objFactory
|
||||
@@ -730,11 +833,21 @@ def SetupOperation(name,
|
||||
menuText,
|
||||
toolTip,
|
||||
accelKey = None):
|
||||
'''SetupOperation(name, objFactory, opPageClass, pixmap, menuText, toolTip, accelKey=None)
|
||||
Creates an instance of CommandPathOp with the given parameters and registers the command with FreeCAD.
|
||||
When activated it creates a model with proxy (by invoking objFactory), assign a view provider to it
|
||||
(see ViewProvider in this module) and starts the editor specif for theis operation (driven by opPageClass).
|
||||
This is an internal function that is automatically called by the intialisation code for each operation.
|
||||
It is not expected to be called manually.
|
||||
'''
|
||||
|
||||
res = CommandResources(name, objFactory, opPageClass, pixmap, menuText, accelKey, toolTip)
|
||||
|
||||
FreeCADGui.addCommand("Path_%s" % name.replace(' ', '_'), CommandPathOp(res))
|
||||
command = CommandPathOp(res)
|
||||
FreeCADGui.addCommand("Path_%s" % name.replace(' ', '_'), command)
|
||||
return command
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Set_StartPoint', _CommandSetStartPoint())
|
||||
FreeCADGui.addCommand('Set_StartPoint', CommandSetStartPoint())
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathOpGui... done\n")
|
||||
|
||||
Reference in New Issue
Block a user