# SPDX-License-Identifier: LGPL-2.1-or-later # *************************************************************************** # * (c) 2009, 2010 Yorik van Havre * # * (c) 2009, 2010 Ken Cline * # * (c) 2020 Eliud Cabrera Castillo * # * * # * This file is part of the FreeCAD CAx development system. * # * * # * 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. * # * * # * FreeCAD 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 FreeCAD; if not, write to the Free Software * # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # * USA * # * * # *************************************************************************** """Provides GUI tools to change the slope of a line. It currently only works for a line in the XY plane, it changes the height of one of its points in the Z direction to create a sloped line. """ ## @package gui_lineslope # \ingroup draftguitools # \brief Provides GUI tools to change the slope of a line. ## \addtogroup draftguitools # @{ import PySide.QtWidgets as QtWidgets from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD as App import FreeCADGui as Gui from draftguitools import gui_base from draftutils import params from draftutils import utils from draftutils.translate import translate class LineSlope(gui_base.GuiCommandNeedsSelection): """Gui Command for the Line slope tool. For a line in the XY plane, it changes the height of one of its points to create a sloped line. To Do ----- Make it work also with lines lying on the YZ and XZ planes, or in an arbitrary plane, for which the normal is known. """ def __init__(self): super().__init__(name=translate("draft", "Change Slope")) def GetResources(self): """Set icon, menu and tooltip.""" return { "Pixmap": "Draft_Slope", "MenuText": QT_TRANSLATE_NOOP("Draft_Slope", "Set Slope"), "ToolTip": QT_TRANSLATE_NOOP( "Draft_Slope", "Sets the slope of the selected line by changing the value of the Z value of one of its points.\nIf a polyline is selected, it will apply the slope transformation to each of its segments.\n\nThe slope will always change the Z value, therefore this command only works well for\nstraight Draft lines that are drawn on the XY-plane.", ), } def Activated(self): """Execute when the command is called.""" super().Activated() # for obj in Gui.Selection.getSelection(): # if utils.get_type(obj) != "Wire": # _msg(translate("draft", # "This tool only works with " # "Draft Lines and Wires")) # return # TODO: create a .ui file with QtCreator and import it here # instead of creating the interface programmatically, # see the `gui_othoarray` module for an example. w = QtWidgets.QWidget() w.setWindowTitle(translate("Draft", "Slope")) layout = QtWidgets.QHBoxLayout(w) label = QtWidgets.QLabel(w) label.setText(translate("Draft", "Slope")) layout.addWidget(label) self.spinbox = QtWidgets.QDoubleSpinBox(w) self.spinbox.setDecimals(params.get_param("Decimals", path="Units")) self.spinbox.setMinimum(-9999.99) self.spinbox.setMaximum(9999.99) self.spinbox.setSingleStep(0.01) _tip = ( "New slope of the selected lines.\n" "This is the tangent of the horizontal angle:\n" "0 = horizontal\n" "1 = 45 deg up\n" "-1 = 45deg down\n" ) label.setToolTip(translate("Draft", _tip)) self.spinbox.setToolTip(translate("Draft", _tip)) layout.addWidget(self.spinbox) # In order to display our interface inside the task panel # we must contain our interface inside a parent widget. # Then our interface must be installed in this parent widget # inside the attribute called "form". taskwidget = QtWidgets.QWidget() taskwidget.form = w # The "accept" attribute of the parent widget # should also contain a reference to a function that will be called # when we press the "OK" button. # Then we must show the container widget. taskwidget.accept = self.accept Gui.Control.showDialog(taskwidget) def accept(self): """Execute when clicking the OK button or pressing Enter key. It changes the slope of the line that lies on the XY plane. TODO: make it work also with lines lying on the YZ and XZ planes. """ if hasattr(self, "spinbox"): pc = self.spinbox.value() self.doc.openTransaction("Change slope") for obj in Gui.Selection.getSelection(): if utils.get_type(obj) == "Wire": if len(obj.Points) > 1: lp = None np = [] for p in obj.Points: if not lp: lp = p else: v = p.sub(lp) z = pc * App.Vector(v.x, v.y, 0).Length lp = App.Vector(p.x, p.y, lp.z + z) np.append(lp) obj.Points = np self.doc.commitTransaction() Gui.Control.closeDialog() self.doc.recompute() Draft_Slope = LineSlope Gui.addCommand("Draft_Slope", LineSlope()) ## @}