diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 1836ad035c..15ecac0106 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -197,6 +197,7 @@ SET(Draft_view_providers draftviewproviders/view_wire.py draftviewproviders/view_wpproxy.py draftviewproviders/view_hatch.py + draftviewproviders/view_shapestring.py draftviewproviders/README.md ) diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index f3b8e45d4c..cddd5a0eba 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -349,6 +349,8 @@ from draftobjects.shapestring import (ShapeString, _ShapeString) from draftmake.make_shapestring import (make_shapestring, makeShapeString) +if App.GuiUp: + from draftviewproviders.view_shapestring import ViewProviderShapeString # shape 2d view from draftobjects.shape2dview import (Shape2DView, diff --git a/src/Mod/Draft/draftguitools/gui_shapestrings.py b/src/Mod/Draft/draftguitools/gui_shapestrings.py index 941bbfd30b..3fec8ee023 100644 --- a/src/Mod/Draft/draftguitools/gui_shapestrings.py +++ b/src/Mod/Draft/draftguitools/gui_shapestrings.py @@ -46,9 +46,9 @@ import DraftVecUtils import draftutils.utils as utils import draftguitools.gui_base_original as gui_base_original import draftguitools.gui_tool_utils as gui_tool_utils -import drafttaskpanels.task_shapestring as task_shapestring import draftutils.todo as todo +from drafttaskpanels.task_shapestring import ShapeStringTaskPanelCmd from draftutils.translate import translate from draftutils.messages import _msg, _err @@ -70,7 +70,6 @@ class ShapeString(gui_base_original.Creator): def Activated(self): """Execute when the command is called.""" super(ShapeString, self).Activated(name="ShapeString") - self.creator = gui_base_original.Creator if self.ui: self.ui.sourceCmd = self self.taskmode = utils.getParam("UiMode", 1) @@ -81,8 +80,9 @@ class ShapeString(gui_base_original.Creator): del self.task except AttributeError: pass - self.task = task_shapestring.ShapeStringTaskPanel() - self.task.sourceCmd = self + self.task = ShapeStringTaskPanelCmd(self) + self.call = self.view.addEventCallback("SoEvent", self.task.action) + _msg(translate("draft", "Pick ShapeString location point")) todo.ToDo.delay(Gui.Control.showDialog, self.task) else: self.dialog = None diff --git a/src/Mod/Draft/draftmake/make_shapestring.py b/src/Mod/Draft/draftmake/make_shapestring.py index 891124da59..1acd3bb029 100644 --- a/src/Mod/Draft/draftmake/make_shapestring.py +++ b/src/Mod/Draft/draftmake/make_shapestring.py @@ -33,7 +33,7 @@ import draftutils.gui_utils as gui_utils from draftobjects.shapestring import ShapeString if App.GuiUp: - from draftviewproviders.view_base import ViewProviderDraft + from draftviewproviders.view_shapestring import ViewProviderShapeString def make_shapestring(String, FontFile, Size=100, Tracking=0): @@ -60,7 +60,7 @@ def make_shapestring(String, FontFile, Size=100, Tracking=0): obj.Tracking = Tracking if App.GuiUp: - ViewProviderDraft(obj.ViewObject) + ViewProviderShapeString(obj.ViewObject) gui_utils.format_object(obj) obrep = obj.ViewObject if "PointSize" in obrep.PropertiesList: obrep.PointSize = 1 # hide the segment end points diff --git a/src/Mod/Draft/drafttaskpanels/task_shapestring.py b/src/Mod/Draft/drafttaskpanels/task_shapestring.py index ac40d6795d..4029e62c58 100644 --- a/src/Mod/Draft/drafttaskpanels/task_shapestring.py +++ b/src/Mod/Draft/drafttaskpanels/task_shapestring.py @@ -33,12 +33,12 @@ import PySide.QtGui as QtGui import FreeCAD as App import FreeCADGui as Gui -import Draft import Draft_rc -import DraftVecUtils + import draftguitools.gui_tool_utils as gui_tool_utils -from FreeCAD import Units as U +from DraftVecUtils import toString +from draftutils.utils import get_param from draftutils.translate import translate from draftutils.messages import _msg, _err @@ -47,44 +47,39 @@ True if Draft_rc.__name__ else False class ShapeStringTaskPanel: - """TaskPanel for Draft_ShapeString.""" + """Base class for Draft_ShapeString task panel.""" - def __init__(self): - self.form = QtGui.QWidget() + def __init__(self, point=App.Vector(0,0,0), size=10, string="", font=""): + + self.form = Gui.PySideUic.loadUi(":/ui/TaskShapeString.ui") self.form.setObjectName("ShapeStringTaskPanel") self.form.setWindowTitle(translate("draft", "ShapeString")) - layout = QtGui.QVBoxLayout(self.form) - uiFile = QtCore.QFile(":/ui/TaskShapeString.ui") - loader = Gui.UiLoader() - self.task = loader.load(uiFile) - layout.addWidget(self.task) + self.form.setWindowIcon(QtGui.QIcon(":/icons/Draft_ShapeString.svg")) - qStart = U.Quantity(0.0, U.Length) - self.task.sbX.setProperty('rawValue', qStart.Value) - self.task.sbX.setProperty('unit', qStart.getUserPreferred()[2]) - self.task.sbY.setProperty('rawValue', qStart.Value) - self.task.sbY.setProperty('unit', qStart.getUserPreferred()[2]) - self.task.sbZ.setProperty('rawValue', qStart.Value) - self.task.sbZ.setProperty('unit', qStart.getUserPreferred()[2]) - self.task.sbHeight.setProperty('rawValue', 10.0) - self.task.sbHeight.setProperty('unit', qStart.getUserPreferred()[2]) + unit_length = App.Units.Quantity(0.0, App.Units.Length).getUserPreferred()[2] + self.form.sbX.setProperty('rawValue', point.x) + self.form.sbX.setProperty('unit', unit_length) + self.form.sbY.setProperty('rawValue', point.y) + self.form.sbY.setProperty('unit', unit_length) + self.form.sbZ.setProperty('rawValue', point.z) + self.form.sbZ.setProperty('unit', unit_length) + self.form.sbHeight.setProperty('rawValue', size) + self.form.sbHeight.setProperty('unit', unit_length) - self.stringText = translate("draft", "Default") - self.task.leString.setText(self.stringText) + self.stringText = string if string else translate("draft", "Default") + self.form.leString.setText(self.stringText) self.platWinDialog("Overwrite") - self.task.fcFontFile.setFileName(Draft.getParam("FontFile", "")) - self.fileSpec = Draft.getParam("FontFile", "") - self.point = App.Vector(0.0, 0.0, 0.0) + self.fileSpec = font if font else get_param("FontFile", "") + self.form.fcFontFile.setFileName(self.fileSpec) + self.point = point self.pointPicked = False # Default for the "DontUseNativeFontDialog" preference: self.font_dialog_pref = False + # Dummy attribute used by gui_tools_utils.getPoint in action method + self.node = None - QtCore.QObject.connect(self.task.fcFontFile, QtCore.SIGNAL("fileNameSelected(const QString&)"), self.fileSelect) - QtCore.QObject.connect(self.task.pbReset, QtCore.SIGNAL("clicked()"), self.resetPoint) - self.point = None - self.view = Draft.get3DView() - self.call = self.view.addEventCallback("SoEvent", self.action) - _msg(translate("draft", "Pick ShapeString location point:")) + QtCore.QObject.connect(self.form.fcFontFile, QtCore.SIGNAL("fileNameSelected(const QString&)"), self.fileSelect) + QtCore.QObject.connect(self.form.pbReset, QtCore.SIGNAL("clicked()"), self.resetPoint) def fileSelect(self, fn): """Assign the selected file.""" @@ -102,7 +97,7 @@ class ShapeStringTaskPanel: if arg["Key"] == "ESCAPE": self.reject() elif arg["Type"] == "SoLocation2Event": # mouse movement detection - self.point,ctrlPoint,info = gui_tool_utils.getPoint(self.sourceCmd, arg, noTracker=True) + self.point,ctrlPoint,info = gui_tool_utils.getPoint(self, arg, noTracker=True) if not self.pointPicked: self.setPoint(self.point) elif arg["Type"] == "SoMouseButtonEvent": @@ -112,36 +107,10 @@ class ShapeStringTaskPanel: def setPoint(self, point): """Assign the selected point.""" - self.task.sbX.setProperty('rawValue', point.x) - self.task.sbY.setProperty('rawValue', point.y) - self.task.sbZ.setProperty('rawValue', point.z) + self.form.sbX.setProperty('rawValue', point.x) + self.form.sbY.setProperty('rawValue', point.y) + self.form.sbZ.setProperty('rawValue', point.z) - def createObject(self): - """Create object in the current document.""" - dquote = '"' - String = dquote + self.task.leString.text() + dquote - FFile = dquote + str(self.fileSpec) + dquote - - Size = str(U.Quantity(self.task.sbHeight.text()).Value) - Tracking = str(0.0) - x = U.Quantity(self.task.sbX.text()).Value - y = U.Quantity(self.task.sbY.text()).Value - z = U.Quantity(self.task.sbZ.text()).Value - ssBase = App.Vector(x, y, z) - # this try block is almost identical to the one in DraftTools - try: - qr, sup, points, fil = self.sourceCmd.getStrings() - Gui.addModule("Draft") - self.sourceCmd.commit(translate("draft", "Create ShapeString"), - ['ss=Draft.make_shapestring(String=' + String + ', FontFile=' + FFile + ', Size=' + Size + ', Tracking=' + Tracking + ')', - 'plm=FreeCAD.Placement()', - 'plm.Base=' + DraftVecUtils.toString(ssBase), - 'plm.Rotation.Q=' + qr, - 'ss.Placement=plm', - 'ss.Support=' + sup, - 'Draft.autogroup(ss)']) - except Exception: - _err("Draft_ShapeString: error delaying commit\n") def platWinDialog(self, flag): """Handle the type of dialog depending on the platform.""" @@ -166,25 +135,104 @@ class ShapeStringTaskPanel: elif flag == "Restore": ParamGroup.SetBool("DontUseNativeDialog", self.font_dialog_pref) + +class ShapeStringTaskPanelCmd(ShapeStringTaskPanel): + """Task panel for Draft_ShapeString.""" + + def __init__(self, sourceCmd): + super().__init__() + self.sourceCmd = sourceCmd + def accept(self): """Execute when clicking the OK button.""" self.createObject() - if self.call: - self.view.removeEventCallback("SoEvent", self.call) - Gui.ActiveDocument.resetEdit() - Gui.Snapper.off() - self.sourceCmd.creator.finish(self.sourceCmd) - self.platWinDialog("Restore") + self.reject() + return True def reject(self): """Run when clicking the Cancel button.""" - if self.call: - self.view.removeEventCallback("SoEvent", self.call) Gui.ActiveDocument.resetEdit() - Gui.Snapper.off() - self.sourceCmd.creator.finish(self.sourceCmd) + self.sourceCmd.finish() self.platWinDialog("Restore") return True + def createObject(self): + """Create object in the current document.""" + dquote = '"' + String = dquote + self.form.leString.text() + dquote + FFile = dquote + str(self.fileSpec) + dquote + + Size = str(App.Units.Quantity(self.form.sbHeight.text()).Value) + Tracking = str(0.0) + x = App.Units.Quantity(self.form.sbX.text()).Value + y = App.Units.Quantity(self.form.sbY.text()).Value + z = App.Units.Quantity(self.form.sbZ.text()).Value + ssBase = App.Vector(x, y, z) + # this try block is almost identical to the one in DraftTools + try: + qr, sup, points, fil = self.sourceCmd.getStrings() + Gui.addModule("Draft") + self.sourceCmd.commit(translate("draft", "Create ShapeString"), + ['ss=Draft.make_shapestring(String=' + String + ', FontFile=' + FFile + ', Size=' + Size + ', Tracking=' + Tracking + ')', + 'plm=FreeCAD.Placement()', + 'plm.Base=' + toString(ssBase), + 'plm.Rotation.Q=' + qr, + 'ss.Placement=plm', + 'ss.Support=' + sup, + 'Draft.autogroup(ss)']) + except Exception: + _err("Draft_ShapeString: error delaying commit\n") + + +class ShapeStringTaskPanelEdit(ShapeStringTaskPanel): + """Task panel for Draft ShapeString object in edit mode.""" + def __init__(self, vobj): + + base = vobj.Object.Placement.Base + size = vobj.Object.Size.Value + string = vobj.Object.String + font = vobj.Object.FontFile + + super().__init__(base, size, string, font) + self.pointPicked = True + self.vobj = vobj + self.call = Gui.activeView().addEventCallback("SoEvent", self.action) + + def accept(self): + + x = App.Units.Quantity(self.form.sbX.text()).Value + y = App.Units.Quantity(self.form.sbY.text()).Value + z = App.Units.Quantity(self.form.sbZ.text()).Value + + base = App.Vector(x, y, z) + size = App.Units.Quantity(self.form.sbHeight.text()).Value + string = self.form.leString.text() + font_file = self.fileSpec + + o = "FreeCAD.ActiveDocument.getObject(\"" + self.vobj.Object.Name + "\")" + Gui.doCommand(o+".Placement.Base=" + toString(base)) + Gui.doCommand(o+".Size=" + str(size)) + Gui.doCommand(o+".String=\"" + string + "\"") + Gui.doCommand(o+".FontFile=\"" + font_file + "\"") + Gui.doCommand("FreeCAD.ActiveDocument.recompute()") + + self.reject() + + return True + + def reject(self): + + self.vobj.Document.resetEdit() + + return True + + def finish(self): + + Gui.activeView().removeEventCallback("SoEvent", self.call) + Gui.Snapper.off() + Gui.Control.closeDialog() + + return None + ## @} diff --git a/src/Mod/Draft/draftviewproviders/view_facebinder.py b/src/Mod/Draft/draftviewproviders/view_facebinder.py index 41899f179a..29261cb9cc 100644 --- a/src/Mod/Draft/draftviewproviders/view_facebinder.py +++ b/src/Mod/Draft/draftviewproviders/view_facebinder.py @@ -27,7 +27,6 @@ ## \addtogroup draftviewproviders # @{ -import FreeCAD as App import FreeCADGui as Gui import DraftGui diff --git a/src/Mod/Draft/draftviewproviders/view_shapestring.py b/src/Mod/Draft/draftviewproviders/view_shapestring.py new file mode 100644 index 0000000000..7c104b27a5 --- /dev/null +++ b/src/Mod/Draft/draftviewproviders/view_shapestring.py @@ -0,0 +1,55 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2022 Mario Passaglia * +#* * +#* 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 * +#* * +#*************************************************************************** + + +"""Provides the viewprovider code for the Shapestring object.""" + +import FreeCADGui as Gui + +from draftviewproviders.view_base import ViewProviderDraft +from drafttaskpanels.task_shapestring import ShapeStringTaskPanelEdit + +class ViewProviderShapeString(ViewProviderDraft): + + def __init__(self,vobj): + + vobj.Proxy = self + + def getIcon(self): + + return ":/icons/Draft_ShapeString.svg" + + def setEdit(self, vobj, mode): + + self.wb_before_edit = Gui.activeWorkbench() + Gui.activateWorkbench("DraftWorkbench") + self.task = ShapeStringTaskPanelEdit(vobj) + Gui.Control.showDialog(self.task) + + return True + + def unsetEdit(self,vobj,mode): + + self.task.finish() + Gui.activateWorkbench(self.wb_before_edit.name()) + + return True