# SPDX-License-Identifier: LGPL-2.1-or-later # *************************************************************************** # * Copyright (c) 2020 Russell Johnson (russ4262) * # * * # * 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 FreeCADGui import Path.Base.Gui.Util as PathGuiUtil import Path.Op.Gui.Base as PathOpGui import Path.Op.Slot as PathSlot import PathGui from PySide import QtCore __title__ = "CAM Slot Operation UI" __author__ = "russ4262 (Russell Johnson)" __url__ = "https://www.freecad.org" __doc__ = "Slot operation page controller and command implementation." __contributors__ = "" DEBUG = False def debugMsg(msg): global DEBUG if DEBUG: FreeCAD.Console.PrintMessage("PathSlotGui:: " + msg + "\n") class TaskPanelOpPage(PathOpGui.TaskPanelPage): """Page controller class for the Slot operation.""" def getForm(self): """getForm() ... returns UI""" debugMsg("getForm()") return FreeCADGui.PySideUic.loadUi(":/panels/PageOpSlotEdit.ui") def initPage(self, obj): """initPage(obj) ... Is called after getForm() to initiate the task panel.""" debugMsg("initPage()") self.CATS = [None, None] self.propEnums = PathSlot.ObjectSlot.propertyEnumerations(dataType="raw") self.ENUMS = dict() self.setTitle("Slot - " + obj.Label) # retrieve property enumerations # Requirements due to Gui::QuantitySpinBox class use in UI panel self.geo1Extension = PathGuiUtil.QuantitySpinBox( self.form.geo1Extension, obj, "ExtendPathStart" ) self.geo2Extension = PathGuiUtil.QuantitySpinBox( self.form.geo2Extension, obj, "ExtendPathEnd" ) def setFields(self, obj): """setFields(obj) ... transfers obj's property values to UI""" debugMsg("setFields()") debugMsg("... calling updateVisibility()") self.updateVisibility() self.updateQuantitySpinBoxes() self.setupToolController(obj, self.form.toolController) self.setupCoolant(obj, self.form.coolantController) enums = [t[1] for t in self.propEnums["Reference1"]] if "Reference1" in self.ENUMS: enums = self.ENUMS["Reference1"] debugMsg(" -enums1: {}".format(enums)) idx = 0 if obj.Reference1 in enums: idx = enums.index(obj.Reference1) self.form.geo1Reference.setCurrentIndex(idx) enums = [t[1] for t in self.propEnums["Reference2"]] if "Reference2" in self.ENUMS: enums = self.ENUMS["Reference2"] debugMsg(" -enums2: {}".format(enums)) idx = 0 if obj.Reference2 in enums: idx = enums.index(obj.Reference2) self.form.geo2Reference.setCurrentIndex(idx) self.selectInComboBox(obj.LayerMode, self.form.layerMode) self.selectInComboBox(obj.PathOrientation, self.form.pathOrientation) if obj.ReverseDirection: self.form.reverseDirection.setCheckState(QtCore.Qt.Checked) else: self.form.reverseDirection.setCheckState(QtCore.Qt.Unchecked) def updateQuantitySpinBoxes(self): self.geo1Extension.updateWidget() self.geo2Extension.updateWidget() def getFields(self, obj): """getFields(obj) ... transfers values from UI to obj's properties""" debugMsg("getFields()") self.updateToolController(obj, self.form.toolController) self.updateCoolant(obj, self.form.coolantController) val = obj.getEnumerationsOfProperty("Reference1")[self.form.geo1Reference.currentIndex()] obj.Reference1 = val self.geo1Extension.updateProperty() val = obj.getEnumerationsOfProperty("Reference2")[self.form.geo2Reference.currentIndex()] obj.Reference2 = val self.geo2Extension.updateProperty() val = self.propEnums["LayerMode"][self.form.layerMode.currentIndex()][1] obj.LayerMode = val val = self.propEnums["PathOrientation"][self.form.pathOrientation.currentIndex()][1] obj.PathOrientation = val obj.ReverseDirection = self.form.reverseDirection.isChecked() def getSignalsForUpdate(self, obj): """getSignalsForUpdate(obj) ... return list of signals for updating obj""" debugMsg("getSignalsForUpdate()") signals = [] signals.append(self.form.toolController.currentIndexChanged) signals.append(self.form.coolantController.currentIndexChanged) signals.append(self.form.geo1Extension.editingFinished) signals.append(self.form.geo1Reference.currentIndexChanged) signals.append(self.form.geo2Extension.editingFinished) signals.append(self.form.geo2Reference.currentIndexChanged) signals.append(self.form.layerMode.currentIndexChanged) signals.append(self.form.pathOrientation.currentIndexChanged) if hasattr(self.form.reverseDirection, "checkStateChanged"): # Qt version >= 6.7.0 signals.append(self.form.reverseDirection.checkStateChanged) else: # Qt version < 6.7.0 signals.append(self.form.reverseDirection.stateChanged) return signals def updateVisibility(self, sentObj=None): """updateVisibility(sentObj=None)... Updates visibility of Tasks panel objects.""" # debugMsg('updateVisibility()') hideFeatures = True if hasattr(self.obj, "Base"): if self.obj.Base: self.form.customPoints.hide() self.form.featureReferences.show() self.form.pathOrientation_label.show() self.form.pathOrientation.show() hideFeatures = False base, sublist = self.obj.Base[0] subCnt = len(sublist) if subCnt == 1: debugMsg(" -subCnt == 1") # Save value, then reset choices n1 = sublist[0] # s1 = getattr(base.Shape, n1) # Show Reference1 and customize options within self.form.geo1Reference.show() self.form.geo1Reference_label.show() self.form.geo1Reference_label.setText("Reference: {}".format(n1)) self.customizeReference_1(n1, single=True) # Hide Reference2 self.form.geo2Reference.hide() self.form.geo2Reference_label.hide() self.form.geo2Reference_label.setText("End Reference") if self.CATS[1]: self.CATS[1] = None elif subCnt == 2: debugMsg(" -subCnt == 2") n1 = sublist[0] n2 = sublist[1] # s1 = getattr(base.Shape, n1) # s2 = getattr(base.Shape, n2) # Show Reference1 and customize options within self.form.geo1Reference.show() self.form.geo1Reference_label.show() self.form.geo1Reference_label.setText("Start Reference: {}".format(n1)) self.customizeReference_1(n1) # Show Reference2 and customize options within self.form.geo2Reference.show() self.form.geo2Reference_label.show() self.form.geo2Reference_label.setText("End Reference: {}".format(n2)) self.customizeReference_2(n2) else: self.form.pathOrientation_label.hide() self.form.pathOrientation.hide() if hideFeatures: # reset values self.CATS = [None, None] self.selectInComboBox("Start to End", self.form.pathOrientation) # hide inputs and show message self.form.featureReferences.hide() self.form.customPoints.show() def customizeReference_1(self, sub, single=False): debugMsg("customizeReference_1()") # Customize Reference1 combobox options # by removing unavailable choices cat = sub[:4] if cat != self.CATS[0]: self.CATS[0] = cat slot = PathSlot.ObjectSlot enums = slot._makeReference1Enumerations(slot, sub, single) self.ENUMS["Reference1"] = enums debugMsg("Ref1: {}".format(enums)) rawEnums = slot.propertyEnumerations(dataType="raw")["Reference1"] enumTups = [(t, d) for t, d in rawEnums if d in enums] self._updateComboBox(self.form.geo1Reference, enumTups) def customizeReference_2(self, sub): debugMsg("customizeReference_2()") # Customize Reference2 combobox options # by removing unavailable choices cat = sub[:4] if cat != self.CATS[1]: self.CATS[1] = cat slot = PathSlot.ObjectSlot enums = slot._makeReference2Enumerations(slot, sub) self.ENUMS["Reference2"] = enums debugMsg("Ref2: {}".format(enums)) rawEnums = slot.propertyEnumerations(dataType="raw")["Reference2"] enumTups = [(t, d) for t, d in rawEnums if d in enums] self._updateComboBox(self.form.geo2Reference, enumTups) def registerSignalHandlers(self, obj): # debugMsg('registerSignalHandlers()') # self.form.pathOrientation.currentIndexChanged.connect(self.updateVisibility) pass def _updateComboBox(self, cBox, enumTups): cBox.blockSignals(True) cBox.clear() for text, data in enumTups: # load enumerations cBox.addItem(text, data) self.selectInSlotComboBox(data, cBox) cBox.blockSignals(False) def selectInSlotComboBox(self, name, combo): """selectInSlotComboBox(name, combo) ... helper function to select a specific value in a combo box.""" # Search using currentData and return if found newindex = combo.findData(name) if newindex >= 0: combo.setCurrentIndex(newindex) return # if not found, search using current text newindex = combo.findText(name, QtCore.Qt.MatchFixedString) if newindex >= 0: combo.setCurrentIndex(newindex) return # not found, return unchanged combo.setCurrentIndex(0) return Command = PathOpGui.SetupOperation( "Slot", PathSlot.Create, TaskPanelOpPage, "CAM_Slot", QtCore.QT_TRANSLATE_NOOP("CAM_Slot", "Slot"), QtCore.QT_TRANSLATE_NOOP( "CAM_Slot", "Create a single horizontal slot between two points." "\n\nPoints can be specified through selected geometry or custom points." "\nAllowed selection only from one model:" "\n - two vertexes," "\n - one or two edges," "\n - one horizontal or vertical face," "\n - one or two vertical faces.", ), PathSlot.SetupProperties, ) FreeCAD.Console.PrintLog("Loading PathSlotGui... done\n")