diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 71aea43f0..d2cd46991 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -77,6 +77,8 @@ SOURCE_GROUP("shipareascurve" FILES ${ShipAreasCurve_SRCS}) SET(ShipHydrostatics_SRCS shipHydrostatics/__init__.py + shipHydrostatics/TaskPanel.py + shipHydrostatics/TaskPanel.ui shipHydrostatics/Tools.py ) SOURCE_GROUP("shiphydrostatics" FILES ${ShipHydrostatics_SRCS}) diff --git a/src/Mod/Ship/InitGui.py b/src/Mod/Ship/InitGui.py index 5d0a87efe..b20c552af 100644 --- a/src/Mod/Ship/InitGui.py +++ b/src/Mod/Ship/InitGui.py @@ -32,11 +32,11 @@ class ShipWorkbench ( Workbench ): def Initialize(self): # ToolBar - list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] + list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"] self.appendToolbar("Ship design",list) # Menu - list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] + list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"] self.appendMenu("Ship design",list) Gui.addWorkbench(ShipWorkbench()) diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index 87f2a4759..d572d41d6 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -54,6 +54,8 @@ nobase_data_DATA = \ shipAreasCurve/TaskPanel.py \ shipAreasCurve/TaskPanel.ui \ shipHydrostatics/__init__.py \ + shipHydrostatics/TaskPanel.py \ + shipHydrostatics/TaskPanel.ui \ shipHydrostatics/Tools.py \ shipUtils/__init__.py \ shipUtils/Math.py \ diff --git a/src/Mod/Ship/ShipGui.py b/src/Mod/Ship/ShipGui.py index c59a43c71..8f50b4be0 100644 --- a/src/Mod/Ship/ShipGui.py +++ b/src/Mod/Ship/ShipGui.py @@ -71,8 +71,21 @@ class AreasCurve: MenuText = str(Translator.translate('Areas curve')) ToolTip = str(Translator.translate('Plot transversal areas curve')) return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} + +class Hydrostatics: + def Activated(self): + import shipHydrostatics + shipHydrostatics.load() + + def GetResources(self): + from shipUtils import Paths, Translator + IconPath = Paths.iconsPath() + "/HydrostaticsIco.png" + MenuText = str(Translator.translate('Hydrostatics')) + ToolTip = str(Translator.translate('Plot ship hydrostatics')) + return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} FreeCADGui.addCommand('Ship_LoadExample', LoadExample()) FreeCADGui.addCommand('Ship_CreateShip', CreateShip()) FreeCADGui.addCommand('Ship_OutlineDraw', OutlineDraw()) FreeCADGui.addCommand('Ship_AreasCurve', AreasCurve()) +FreeCADGui.addCommand('Ship_Hydrostatics', Hydrostatics()) diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.py b/src/Mod/Ship/shipHydrostatics/TaskPanel.py new file mode 100644 index 000000000..d0feb40dc --- /dev/null +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.py @@ -0,0 +1,223 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2011, 2012 * +#* Jose Luis Cercos Pita * +#* * +#* 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 math +# FreeCAD modules +import FreeCAD as App +import FreeCADGui as Gui +# Qt library +from PyQt4 import QtGui,QtCore +# Module +# import Plot +import Instance +from shipUtils import Paths, Translator +from surfUtils import Geometry +import Tools + +class TaskPanel: + def __init__(self): + self.ui = Paths.modulePath() + "/shipHydrostatics/TaskPanel.ui" + self.ship = None + + def accept(self): + if not self.ship: + return False + self.save() + return True + + def reject(self): + return True + + def clicked(self, index): + pass + + def open(self): + pass + + def needsFullSpace(self): + return True + + def isAllowedAlterSelection(self): + return False + + def isAllowedAlterView(self): + return True + + def isAllowedAlterDocument(self): + return False + + def helpRequested(self): + pass + + def setupUi(self): + mw = self.getMainWindow() + form = mw.findChild(QtGui.QWidget, "TaskPanel") + form.trim = form.findChild(QtGui.QDoubleSpinBox, "Trim") + form.minDraft = form.findChild(QtGui.QDoubleSpinBox, "MinDraft") + form.maxDraft = form.findChild(QtGui.QDoubleSpinBox, "MaxDraft") + form.nDraft = form.findChild(QtGui.QSpinBox, "NDraft") + self.form = form + # Initial values + if self.initValues(): + return True + self.retranslateUi() + # Connect Signals and Slots + QtCore.QObject.connect(form.trim, QtCore.SIGNAL("valueChanged(double)"), self.onData) + QtCore.QObject.connect(form.minDraft, QtCore.SIGNAL("valueChanged(double)"), self.onData) + QtCore.QObject.connect(form.maxDraft, QtCore.SIGNAL("valueChanged(double)"), self.onData) + + def getMainWindow(self): + "returns the main window" + # using QtGui.qApp.activeWindow() isn't very reliable because if another + # widget than the mainwindow is active (e.g. a dialog) the wrong widget is + # returned + toplevel = QtGui.qApp.topLevelWidgets() + for i in toplevel: + if i.metaObject().className() == "Gui::MainWindow": + return i + raise Exception("No main window found") + + def initValues(self): + """ Set initial values for fields + """ + # Get objects + selObjs = Geometry.getSelectedObjs() + if not selObjs: + msg = Translator.translate("Ship instance must be selected (no object selected)\n") + App.Console.PrintError(msg) + return True + for i in range(0,len(selObjs)): + obj = selObjs[i] + # Test if is a ship instance + props = obj.PropertiesList + try: + props.index("IsShip") + except ValueError: + continue + if obj.IsShip: + # Test if another ship already selected + if self.ship: + msg = Translator.translate("More than one ship selected (extra ship will be neglected)\n") + App.Console.PrintWarning(msg) + break + self.ship = obj + # Test if any valid ship was selected + if not self.ship: + msg = Translator.translate("Ship instance must be selected (no valid ship found at selected objects)\n") + App.Console.PrintError(msg) + return True + # Get bounds + bbox = self.ship.Shape.BoundBox + # Set trim + flag = True + try: + props.index("HydrostaticsTrim") + except ValueError: + flag = False + if flag: + self.form.trim.setValue(self.ship.HydrostaticsTrim) + # Set drafts + self.form.maxDraft.setValue(1.1*self.ship.Draft) + self.form.minDraft.setValue(0.9*self.ship.Draft) + # Try to use saved values + props = self.ship.PropertiesList + flag = True + try: + props.index("HydrostaticsMinDraft") + except ValueError: + flag = False + if flag: + self.form.minDraft.setValue(self.ship.HydrostaticsMinDraft) + flag = True + try: + props.index("HydrostaticsMaxDraft") + except ValueError: + flag = False + if flag: + self.form.maxDraft.setValue(self.ship.HydrostaticsMaxDraft) + self.form.maxDraft.setMaximum(bbox.ZMax) + self.form.minDraft.setMinimum(bbox.ZMin) + self.form.maxDraft.setMinimum(self.form.minDraft.value()) + self.form.minDraft.setMaximum(self.form.maxDraft.value()) + flag = True + try: + props.index("HydrostaticsNDraft") + except ValueError: + flag = False + if flag: + self.form.nDraft.setValue(self.ship.HydrostaticsNDraft) + # Update GUI + msg = Translator.translate("Ready to work\n") + App.Console.PrintMessage(msg) + return False + + def retranslateUi(self): + """ Set user interface locale strings. + """ + self.form.setWindowTitle(Translator.translate("Plot hydrostatics")) + self.form.findChild(QtGui.QLabel, "TrimLabel").setText(Translator.translate("Trim")) + self.form.findChild(QtGui.QLabel, "MinDraftLabel").setText(Translator.translate("Minimum draft")) + self.form.findChild(QtGui.QLabel, "MaxDraftLabel").setText(Translator.translate("Maximum draft")) + self.form.findChild(QtGui.QLabel, "NDraftLabel").setText(Translator.translate("Number of points")) + + def onData(self, value): + """ Method called when input data is changed. + @param value Changed value. + """ + if not self.ship: + return + self.form.maxDraft.setMinimum(self.form.minDraft.value()) + self.form.minDraft.setMaximum(self.form.maxDraft.value()) + + def save(self): + """ Saves data into ship instance. + """ + props = self.ship.PropertiesList + try: + props.index("HydrostaticsTrim") + except ValueError: + self.ship.addProperty("App::PropertyFloat","HydrostaticsTrim","Ship", str(Translator.translate("Hydrostatics trim selected [m]"))) + self.ship.HydrostaticsTrim = self.form.trim.value() + try: + props.index("HydrostaticsMinDraft") + except ValueError: + self.ship.addProperty("App::PropertyFloat","HydrostaticsMinDraft","Ship", str(Translator.translate("Hydrostatics minimum draft selected [m]"))) + self.ship.HydrostaticsMinDraft = self.form.minDraft.value() + try: + props.index("HydrostaticsMaxDraft") + except ValueError: + self.ship.addProperty("App::PropertyFloat","HydrostaticsMaxDraft","Ship", str(Translator.translate("Hydrostatics maximum draft selected [m]"))) + self.ship.HydrostaticsMaxDraft = self.form.maxDraft.value() + try: + props.index("HydrostaticsNDraft") + except ValueError: + self.ship.addProperty("App::PropertyInteger","HydrostaticsNDraft","Ship", str(Translator.translate("Hydrostatics number of points selected [m]"))) + self.ship.HydrostaticsNDraft = self.form.nDraft.value() + +def createTask(): + panel = TaskPanel() + Gui.Control.showDialog(panel) + if panel.setupUi(): + Gui.Control.closeDialog(panel) + return None + return panel diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.ui b/src/Mod/Ship/shipHydrostatics/TaskPanel.ui new file mode 100644 index 000000000..d4b4f0639 --- /dev/null +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.ui @@ -0,0 +1,205 @@ + + + TaskPanel + + + + 0 + 0 + 260 + 256 + + + + Create new ship + + + + + + + + + 0 + 0 + + + + Trim + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + -45.000000000000000 + + + 45.000000000000000 + + + + + + + + 24 + 16777215 + + + + Deg + + + + + + + + + + 0 + 0 + + + + Drafts + + + + + 9 + 19 + 231 + 181 + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + Minimum draft + + + + + + + 3 + + + 0.010000000000000 + + + + + + + + 0 + 0 + + + + Maximum draft + + + + + + + + 0 + 0 + + + + 3 + + + 0.010000000000000 + + + + + + + + 0 + 0 + + + + Number of points + + + + + + + + 0 + 0 + + + + m + + + + + + + + 0 + 0 + + + + m + + + + + + + + 0 + 0 + + + + 1 + + + 9999 + + + 11 + + + + + + + + + + + + diff --git a/src/Mod/Ship/shipHydrostatics/__init__.py b/src/Mod/Ship/shipHydrostatics/__init__.py index 55ed9aee5..5b9a3c477 100644 --- a/src/Mod/Ship/shipHydrostatics/__init__.py +++ b/src/Mod/Ship/shipHydrostatics/__init__.py @@ -21,3 +21,17 @@ #* * #*************************************************************************** + +# FreeCAD modules +import FreeCAD +import FreeCADGui + +# Qt libraries +from PyQt4 import QtGui,QtCore + +# Main object +import TaskPanel + +def load(): + """ Loads the tool """ + TaskPanel.createTask()