Added docstrings to Gui classes.
This commit is contained in:
committed by
Yorik van Havre
parent
79337b998d
commit
bc6ff3690e
@@ -29,6 +29,11 @@ import PathScripts.PathOpGui as PathOpGui
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__title__ = "Base for Circular Hole based operations' UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Implementation of circular hole specific base geometry page controller."
|
||||
|
||||
if True:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
@@ -36,14 +41,21 @@ else:
|
||||
PathLog.setLevel(PathLog.Level.NOTICE, PathLog.thisModule())
|
||||
|
||||
class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
'''Controller class to be used for the BaseGeomtery page.
|
||||
Circular holes don't just disply the feature, they also add a column
|
||||
displaying the radius the feature describes. This page provides that
|
||||
UI and functionality for all circular hole based operations.'''
|
||||
|
||||
DataFeatureName = QtCore.Qt.ItemDataRole.UserRole
|
||||
DataObject = QtCore.Qt.ItemDataRole.UserRole + 1
|
||||
DataObjectSub = QtCore.Qt.ItemDataRole.UserRole + 2
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... load and return page'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageBaseHoleGeometryEdit.ui")
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... fill form with values from obj'''
|
||||
PathLog.track()
|
||||
self.form.baseList.blockSignals(True)
|
||||
self.form.baseList.clearContents()
|
||||
@@ -75,6 +87,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
self.form.baseList.blockSignals(False)
|
||||
|
||||
def itemActivated(self):
|
||||
'''itemActivated() ... callback when item in table is selected'''
|
||||
PathLog.track()
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
activatedRows = []
|
||||
@@ -92,6 +105,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
#FreeCADGui.updateGui()
|
||||
|
||||
def deleteBase(self):
|
||||
'''deleteBase() ... callback for push button'''
|
||||
PathLog.track()
|
||||
deletedRows = []
|
||||
selected = self.form.baseList.selectedItems()
|
||||
@@ -105,6 +119,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def updateBase(self):
|
||||
'''updateBase() ... helper function to transfer current table to obj'''
|
||||
PathLog.track()
|
||||
newlist = []
|
||||
for i in range(self.form.baseList.rowCount()):
|
||||
@@ -118,6 +133,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
self.obj.Base = newlist
|
||||
|
||||
def checkedChanged(self):
|
||||
'''checkeChanged() ... callback when checked status of a base feature changed'''
|
||||
PathLog.track()
|
||||
disabled = []
|
||||
for i in xrange(0, self.form.baseList.rowCount()):
|
||||
@@ -128,6 +144,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def registerSignalHandlers(self, obj):
|
||||
'''registerSignalHandlers(obj) ... setup signal handlers'''
|
||||
self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
|
||||
self.form.addBase.clicked.connect(self.addBase)
|
||||
self.form.deleteBase.clicked.connect(self.deleteBase)
|
||||
@@ -135,6 +152,7 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
self.form.baseList.itemChanged.connect(self.checkedChanged)
|
||||
|
||||
def resetBase(self):
|
||||
'''resetBase() ... push button callback'''
|
||||
self.obj.Base = []
|
||||
self.obj.Disabled = []
|
||||
|
||||
@@ -142,11 +160,14 @@ class TaskPanelHoleGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def updateData(self, obj, prop):
|
||||
'''updateData(obj, prop) ... callback whenever a property of the model changed'''
|
||||
if prop in ['Base', 'Disabled']:
|
||||
self.setFields(obj)
|
||||
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Base class for circular hole based operation's page controller.'''
|
||||
|
||||
def taskPanelBaseGeometryPage(self, obj, features):
|
||||
'''taskPanelBaseGeometryPage(obj, features) ... Return circular hole specific page controller for Base Geometry.'''
|
||||
return TaskPanelHoleGeometryPage(obj, features)
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ import PathScripts.PathOpGui as PathOpGui
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__title__ = "Path Drilling Operation UI."
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "UI and Command for Path Drilling Operation."
|
||||
|
||||
if True:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
@@ -39,11 +44,14 @@ else:
|
||||
|
||||
|
||||
class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
'''Controller for the drilling operation's page'''
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... return UI'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpDrillingEdit.ui")
|
||||
|
||||
def getFields(self, obj):
|
||||
'''setFields(obj) ... update obj's properties with values from the UI'''
|
||||
PathLog.track()
|
||||
self.updateInputField(obj, 'PeckDepth', self.form.peckDepth)
|
||||
self.updateInputField(obj, 'RetractHeight', self.form.retractHeight)
|
||||
@@ -59,6 +67,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... update UI with obj properties' values'''
|
||||
PathLog.track()
|
||||
|
||||
self.form.peckDepth.setText(FreeCAD.Units.Quantity(obj.PeckDepth.Value, FreeCAD.Units.Length).UserString)
|
||||
@@ -83,6 +92,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals which cause the receiver to update the model'''
|
||||
signals = []
|
||||
|
||||
signals.append(self.form.retractHeight.editingFinished)
|
||||
@@ -95,7 +105,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
|
||||
return signals
|
||||
|
||||
PathOpGui.SetupOperation('Drilling',
|
||||
Command = PathOpGui.SetupOperation('Drilling',
|
||||
PathDrilling.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Drilling',
|
||||
|
||||
@@ -31,33 +31,40 @@ import PathScripts.PathSelection as PathSelection
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__title__ = "Path Engrave Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Engrave operation page controller and command implementation."
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
FeaturePocket = 0x01
|
||||
FeatureFacing = 0x02
|
||||
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Page controller class for the Engrave operation.'''
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... returns UI'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpEngraveEdit.ui")
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
if obj.StartVertex != self.form.startVertex.value():
|
||||
obj.StartVertex = self.form.startVertex.value()
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
self.form.startVertex.setValue(obj.StartVertex)
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
signals.append(self.form.startVertex.editingFinished)
|
||||
signals.append(self.form.toolController.currentIndexChanged)
|
||||
return signals
|
||||
|
||||
PathOpGui.SetupOperation('Engrave',
|
||||
Command = PathOpGui.SetupOperation('Engrave',
|
||||
PathEngrave.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Engrave',
|
||||
|
||||
@@ -29,16 +29,32 @@ import FreeCADGui
|
||||
from PySide import QtCore, QtGui
|
||||
from pivy import coin
|
||||
|
||||
class TaskPanel:
|
||||
__title__ = "Path GetPoint UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Helper class to use FreeCADGUi.Snapper to let the user enter arbitray points while the task panel is active."
|
||||
|
||||
def __init__(self, formOrig, formPoint):
|
||||
self.formOrig = formOrig
|
||||
self.formPoint = formPoint
|
||||
class TaskPanel:
|
||||
'''Use an instance of this class in another TaskPanel to invoke the snapper.
|
||||
Create the instance in the TaskPanel's constructors and invoke getPoint(whenDone, start) whenever a new point is
|
||||
required or an existing point needs to be edited. The receiver is expected to have the same lifespan as the form
|
||||
provided in the constructor.
|
||||
The (only) public API function other than the constructor is getPoint(whenDone, start).
|
||||
'''
|
||||
def __init__(self, form):
|
||||
'''__init___(form) ... form will be replaced by PointEdit.ui while the Snapper is active.'''
|
||||
self.formOrig = form
|
||||
self.formPoint = FreeCADGui.PySideUic.loadUi(":/panels/PointEdit.ui")
|
||||
|
||||
self.formPoint.setParent(form.parent())
|
||||
form.parent().layout().addWidget(self.formPoint)
|
||||
self.formPoint.hide()
|
||||
|
||||
self.setupUi()
|
||||
self.buttonBox = None
|
||||
|
||||
def setupUi(self):
|
||||
'''setupUi() ... internal function - do not call.'''
|
||||
self.formPoint.buttonBox.accepted.connect(self.pointAccept)
|
||||
self.formPoint.buttonBox.rejected.connect(self.pointReject)
|
||||
|
||||
@@ -47,6 +63,7 @@ class TaskPanel:
|
||||
self.formPoint.ifValueZ.editingFinished.connect(self.updatePoint)
|
||||
|
||||
def addEscapeShortcut(self):
|
||||
'''addEscapeShortcut() ... internal function - do not call.'''
|
||||
# The only way I could get to intercept the escape key, or really any key was
|
||||
# by creating an action with a shortcut .....
|
||||
self.escape = QtGui.QAction(self.formPoint)
|
||||
@@ -56,11 +73,19 @@ class TaskPanel:
|
||||
self.formPoint.addAction(self.escape)
|
||||
|
||||
def removeEscapeShortcut(self):
|
||||
'''removeEscapeShortcut() ... internal function - do not call.'''
|
||||
if self.escape:
|
||||
self.formPoint.removeAction(self.escape)
|
||||
self.escape = None
|
||||
|
||||
def getPoint(self, whenDone, start=None):
|
||||
'''getPoint(whenDone, start=None) ... invoke Snapper and call whenDone when a point is entered or the user cancels the operation.
|
||||
whenDone(point, obj) is called either with a point and the object on which the point lies if the user set the point,
|
||||
or None and None if the user cancelled the operation.
|
||||
start is an optional Vector indicating from where to start Snapper. This is mostly used when editing existing points. Snapper also
|
||||
creates a dotted line indicating from where the original point started from.
|
||||
If start is specified the Snapper UI is closed on the first point the user enters. If start remains None, then Snapper is kept open
|
||||
until the user explicitly closes Snapper. This lets the user enter multiple points in quick succession.'''
|
||||
|
||||
def displayPoint(p):
|
||||
self.formPoint.ifValueX.setText(FreeCAD.Units.Quantity(p.x, FreeCAD.Units.Length).UserString)
|
||||
@@ -111,6 +136,7 @@ class TaskPanel:
|
||||
FreeCADGui.Snapper.forceGridOff=True
|
||||
|
||||
def pointFinish(self, ok, cleanup = True):
|
||||
'''pointFinish(ok, cleanup=True) ... internal function - do not call.'''
|
||||
obj = FreeCADGui.Snapper.lastSnappedObject
|
||||
|
||||
if cleanup:
|
||||
@@ -129,18 +155,23 @@ class TaskPanel:
|
||||
self.pointWhenDone(None, None)
|
||||
|
||||
def pointDone(self):
|
||||
'''pointDone() ... internal function - do not call.'''
|
||||
self.pointFinish(False)
|
||||
|
||||
def pointReject(self):
|
||||
'''pointReject() ... internal function - do not call.'''
|
||||
self.pointFinish(False)
|
||||
|
||||
def pointAccept(self):
|
||||
'''pointAccept() ... internal function - do not call.'''
|
||||
self.pointFinish(True)
|
||||
|
||||
def pointAcceptAndContinue(self):
|
||||
'''pointAcceptAndContinue() ... internal function - do not call.'''
|
||||
self.pointFinish(True, False)
|
||||
|
||||
def removeGlobalCallbacks(self):
|
||||
'''removeGlobalCallbacks() ... internal function - do not call.'''
|
||||
if hasattr(self, 'view') and self.view:
|
||||
if self.pointCbClick:
|
||||
self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), self.pointCbClick)
|
||||
@@ -151,6 +182,7 @@ class TaskPanel:
|
||||
self.view = None
|
||||
|
||||
def updatePoint(self):
|
||||
'''updatePoint() ... internal function - do not call.'''
|
||||
x = FreeCAD.Units.Quantity(self.formPoint.ifValueX.text()).Value
|
||||
y = FreeCAD.Units.Quantity(self.formPoint.ifValueY.text()).Value
|
||||
z = FreeCAD.Units.Quantity(self.formPoint.ifValueZ.text()).Value
|
||||
|
||||
@@ -31,6 +31,8 @@ import PathScripts.PathOpGui as PathOpGui
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__doc__ = "Helix operation page controller and command implementation."
|
||||
|
||||
if True:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
@@ -39,11 +41,14 @@ else:
|
||||
|
||||
|
||||
class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
'''Page controller class for Helix operations.'''
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... return UI'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpHelixEdit.ui")
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
PathLog.track()
|
||||
if obj.Direction != str(self.form.direction.currentText()):
|
||||
obj.Direction = str(self.form.direction.currentText())
|
||||
@@ -55,6 +60,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
PathLog.track()
|
||||
|
||||
self.form.stepOverPercent.setValue(obj.StepOver)
|
||||
@@ -64,6 +70,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
|
||||
signals.append(self.form.stepOverPercent.editingFinished)
|
||||
@@ -73,7 +80,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
|
||||
return signals
|
||||
|
||||
PathOpGui.SetupOperation('Helix',
|
||||
Command = PathOpGui.SetupOperation('Helix',
|
||||
PathHelix.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Helix',
|
||||
|
||||
@@ -30,12 +30,19 @@ import PathScripts.PathPocketBaseGui as PathPocketBaseGui
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Face Mill Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Face Mill operation page controller and command implementation."
|
||||
|
||||
class TaskPanelOpPage(PathPocketBaseGui.TaskPanelOpPage):
|
||||
'''Page controller class for the face milling operation.'''
|
||||
|
||||
def pocketFeatures(self):
|
||||
'''pocketFeatures() ... return FeatureFacing (see PathPocketBaseGui)'''
|
||||
return PathPocketBaseGui.FeatureFacing
|
||||
|
||||
PathOpGui.SetupOperation('MillFace',
|
||||
Command = PathOpGui.SetupOperation('MillFace',
|
||||
PathMillFace.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Face',
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -31,6 +31,11 @@ import PathScripts.PathSelection as PathSelection
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__title__ = "Path Pocket Base Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Base page controller and command implementation for path pocket operations."
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
@@ -38,8 +43,21 @@ FeaturePocket = 0x01
|
||||
FeatureFacing = 0x02
|
||||
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Page controller class for pocket operations, supports two different features:
|
||||
FeaturePocket ... used for pocketing operation
|
||||
FeatureFacing ... used for face milling operation
|
||||
'''
|
||||
|
||||
def pocketFeatures(self):
|
||||
'''pocketFeatures() ... return which features of the UI are supported by the operation.
|
||||
Typically one of the following is enabled:
|
||||
FeaturePocket ... used for pocketing operation
|
||||
FeatureFacing ... used for face milling operation
|
||||
Must be overwritten by subclasses'''
|
||||
pass
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... returns UI, adapted to the resutls from pocketFeatures()'''
|
||||
form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpPocketFullEdit.ui")
|
||||
|
||||
if not FeaturePocket & self.pocketFeatures():
|
||||
@@ -51,6 +69,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
return form
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
if obj.CutMode != str(self.form.cutMode.currentText()):
|
||||
obj.CutMode = str(self.form.cutMode.currentText())
|
||||
if obj.StepOver != self.form.stepOverPercent.value():
|
||||
@@ -72,6 +91,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
obj.BoundaryShape = str(self.form.boundaryShape.currentText())
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
self.form.zigZagAngle.setText(FreeCAD.Units.Quantity(obj.ZigZagAngle, FreeCAD.Units.Angle).UserString)
|
||||
self.form.stepOverPercent.setValue(obj.StepOver)
|
||||
|
||||
@@ -88,6 +108,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
self.selectInComboBox(obj.BoundaryShape, self.form.boundaryShape)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
|
||||
signals.append(self.form.cutMode.currentIndexChanged)
|
||||
|
||||
@@ -29,12 +29,19 @@ import PathScripts.PathPocketBaseGui as PathPocketBaseGui
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Pocket Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Pocket operation page controller and command implementation."
|
||||
|
||||
class TaskPanelOpPage(PathPocketBaseGui.TaskPanelOpPage):
|
||||
'''Page controller class for Pocket operation'''
|
||||
|
||||
def pocketFeatures(self):
|
||||
'''pocketFeatures() ... return FeaturePocket (see PathPocketBaseGui)'''
|
||||
return PathPocketBaseGui.FeaturePocket
|
||||
|
||||
PathOpGui.SetupOperation('Pocket',
|
||||
Command = PathOpGui.SetupOperation('Pocket',
|
||||
PathPocket.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Pocket',
|
||||
|
||||
@@ -31,6 +31,11 @@ import PathScripts.PathSelection as PathSelection
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Profile Operation Base UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Base page controller for profile operations."
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
@@ -38,8 +43,21 @@ FeatureSide = 0x01
|
||||
FeatureProcessing = 0x02
|
||||
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Base class for profile operation page controllers. Two sub features are
|
||||
support
|
||||
FeatureSide ... Is the Side property exposed in the UI
|
||||
FeatureProcessing ... Are the processing check boxes supported by the operation
|
||||
'''
|
||||
|
||||
def profileFeatures(self):
|
||||
'''profileFeatures() ... return which of the optional profile features are supported.
|
||||
Currently two features are supported:
|
||||
FeatureSide ... Is the Side property exposed in the UI
|
||||
FeatureProcessing ... Are the processing check boxes supported by the operation
|
||||
Must be overwritten by subclasses.'''
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... returns UI customized according to profileFeatures()'''
|
||||
form = FreeCADGui.PySideUic.loadUi(":/panels/PageOpProfileFullEdit.ui")
|
||||
|
||||
if not FeatureSide & self.profileFeatures():
|
||||
@@ -54,6 +72,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
return form
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
self.updateInputField(obj, 'OffsetExtra', self.form.extraOffset)
|
||||
if obj.UseComp != self.form.useCompensation.isChecked():
|
||||
obj.UseComp = self.form.useCompensation.isChecked()
|
||||
@@ -77,6 +96,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
obj.processCircles = self.form.processCircles.isChecked()
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
self.form.extraOffset.setText(FreeCAD.Units.Quantity(obj.OffsetExtra.Value, FreeCAD.Units.Length).UserString)
|
||||
self.form.useCompensation.setChecked(obj.UseComp)
|
||||
self.form.useStartPoint.setChecked(obj.UseStartPoint)
|
||||
@@ -93,6 +113,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
self.form.processCircles.setChecked(obj.processCircles)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
signals.append(self.form.direction.currentIndexChanged)
|
||||
signals.append(self.form.useCompensation.clicked)
|
||||
|
||||
@@ -29,13 +29,19 @@ import PathScripts.PathProfileContour as PathProfileContour
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Contour Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Contour operation page controller and command implementation."
|
||||
|
||||
class TaskPanelOpPage(PathProfileBaseGui.TaskPanelOpPage):
|
||||
'''Page controller for the contour operation UI.'''
|
||||
|
||||
def profileFeatures(self):
|
||||
# I know this looks bad, contour is just the most basic profile op there is
|
||||
'''profileFeatues() ... return 0 - profile doesn't support any of the optional UI features.'''
|
||||
return 0
|
||||
|
||||
PathOpGui.SetupOperation('Contour',
|
||||
Command = PathOpGui.SetupOperation('Contour',
|
||||
PathProfileContour.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Contour',
|
||||
|
||||
@@ -29,12 +29,20 @@ import PathScripts.PathProfileEdges as PathProfileEdges
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Profile based on edges Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Profile based on edges operation page controller and command implementation."
|
||||
|
||||
class TaskPanelOpPage(PathProfileBaseGui.TaskPanelOpPage):
|
||||
'''Page controller for profile based on edges operation.'''
|
||||
|
||||
def profileFeatures(self):
|
||||
'''profileFeatures() ... return FeatureSide
|
||||
See PathProfileBaseGui.py for details.'''
|
||||
return PathProfileBaseGui.FeatureSide
|
||||
|
||||
PathOpGui.SetupOperation('Profile Edges',
|
||||
Command = PathOpGui.SetupOperation('Profile Edges',
|
||||
PathProfileEdges.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Profile-Edges',
|
||||
|
||||
@@ -29,12 +29,20 @@ import PathScripts.PathProfileFaces as PathProfileFaces
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Profile based on faces Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Profile based on faces operation page controller and command implementation."
|
||||
|
||||
class TaskPanelOpPage(PathProfileBaseGui.TaskPanelOpPage):
|
||||
'''Page controller for profile based on faces operation.'''
|
||||
|
||||
def profileFeatures(self):
|
||||
'''profileFeatures() ... return FeatureSide | FeatureProcessing.
|
||||
See PathProfileBaseGui.py for details.'''
|
||||
return PathProfileBaseGui.FeatureSide | PathProfileBaseGui.FeatureProcessing
|
||||
|
||||
PathOpGui.SetupOperation('Profile Faces',
|
||||
Command = PathOpGui.SetupOperation('Profile Faces',
|
||||
PathProfileFaces.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Profile-Face',
|
||||
|
||||
Reference in New Issue
Block a user