1 # -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2011-2024 CEA, EDF
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 # Author : Guillaume Boulant (EDF)
26 from salome.kernel import studyedit
27 from salome.gui.genericdialog import GenericDialog
28 from salome.gui import helper as guihelper
29 from salome.smesh.smeshstudytools import SMeshStudyTools
31 from omniORB import CORBA
33 from qtsalome import QIcon, QStandardItemModel, QStandardItem, QMessageBox, pyqtSignal
35 from salome.smesh.spadder.gui.inputframe_ui import Ui_InputFrame
36 from salome.smesh.spadder.gui.inputdata import InputData
41 INPUTDATA_KEY_FILES="meshfiles"
42 INPUTDATA_KEY_PARAM="parameters"
44 PARAM_KEY_NBITER = "NbIteration"
45 PARAM_KEY_RMAXRMIN = "RmaxRmin"
46 PARAM_NBITER_DEFAULT_VALUE = 10
47 PARAM_RMAXRMIN_DEFAULT_VALUE = 3
49 class InputDialog(GenericDialog):
51 TBL_HEADER_LABEL=["Input Mesh", "Output group name"]
53 inputValidated = pyqtSignal()
55 def __init__(self, parent=None, name="InputDialog", modal=0):
57 This initializes a dialog windows to define the input data of
58 the plugin function. The input data consist in a list of
59 meshes characterizes each by a name, a pointer to the smesh
60 servant object, a type and a group name (see data model in the
63 GenericDialog.__init__(self, parent, name, modal)
64 # Set up the user interface from Designer.
65 self.__ui = Ui_InputFrame()
66 # BE CAREFUL HERE, the ui form is NOT drawn in the global
67 # dialog (already containing some generic widgets) but in the
68 # center panel created in the GenericDialog as a void
69 # container for the form. The InputFrame form is supposed
70 # here to create only the widgets to be placed in the center
71 # panel. Then, the setupUi function of this form draws itself
72 # in the specified panel, i.e. the panel returned by
74 self.__ui.setupUi(self.getPanel())
76 self.setWindowTitle("Specification of input files")
78 # The icon are supposed to be located in the plugin folder,
79 # i.e. in the same folder than this python module file
80 iconfolder=os.path.dirname(os.path.abspath(__file__))
82 icon.addFile(os.path.join(iconfolder,"select.png"))
83 self.__ui.btnSmeshObject.setIcon(icon)
85 icon.addFile(os.path.join(iconfolder,"addinput.png"))
86 self.__ui.btnAddInput.setIcon(icon)
88 icon.addFile(os.path.join(iconfolder,"deleteinput.png"))
89 self.__ui.btnDeleteInput.setIcon(icon)
91 # We specify here the items in the combo box (even if already
92 # defined in the designer) so that we can be sure of the item
94 self.MESHTYPE_ICONS = {}
95 meshTypeIndex = InputData.MESHTYPES.CONCRETE
96 self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton")
98 icon.addFile(os.path.join(iconfolder,"concrete.png"))
99 self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
100 self.MESHTYPE_ICONS[meshTypeIndex] = icon
102 meshTypeIndex = InputData.MESHTYPES.STEELBAR
103 self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier")
105 icon.addFile(os.path.join(iconfolder,"steelbar.png"))
106 self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
107 self.MESHTYPE_ICONS[meshTypeIndex] = icon
109 # The click on btnSmeshObject (signal clicked() emitted by the
110 # button btnSmeshObject) is connected to the slot
111 # onSelectSmeshObject, etc ...
112 self.__ui.btnSmeshObject.clicked.connect( self.onSelectSmeshObject )
113 self.__ui.btnAddInput.clicked.connect( self.onAddInput )
114 self.__ui.btnDeleteInput.clicked.connect( self.onDeleteInput )
116 # Set up the model of the Qt table list
117 self.__inputModel = QStandardItemModel(0,2)
118 self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
119 self.__ui.tblListInput.setModel(self.__inputModel)
120 self.__ui.tblListInput.verticalHeader().hide()
121 self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True)
122 # Note that the type is not display explicitly in the Qt table
123 # because it is specified using an icon on the text of the
126 # Setup default values for numerical parameters
127 self.__ui.txtParamNbIter.setValue(PARAM_NBITER_DEFAULT_VALUE)
128 self.__ui.txtParamRmaxRmin.setValue(PARAM_RMAXRMIN_DEFAULT_VALUE)
130 # Note that PADDER does not support group name longer than 8
131 # characters. We apply then this limit in the gui field.
132 self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH)
136 self.smeshStudyTool = SMeshStudyTools()
140 This function clears the data gui area and associated values.
142 self.__ui.txtSmeshObject.setText("")
143 self.__ui.txtGroupName.setText("")
144 self.__inputModel.clear()
145 self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
147 self.__ui.txtSmeshObject.setEnabled(False)
148 self.__ui.btnAddInput.setEnabled(False)
149 self.__selectedMesh = None
150 self.__dictInputFiles = {}
151 self.__nbConcreteMesh = 0
152 self.__nbSteelbarMesh = 0
156 This function is the slot connected to the button OK
158 # The dialog is raised in a non modal mode to get
159 # interactivity with the parents windows. Then we have to emit
160 # a signal to warn the parent observer that the dialog has
161 # been validated so that it can process the event
162 GenericDialog.accept(self)
164 self.inputValidated.emit()
166 def onSelectSmeshObject(self):
168 This function is the slot connected on the mesh selection
169 button. It memorizes the selected mesh and put its name in the
170 text field of the dialog box.
172 mySObject, myEntry = guihelper.getSObjectSelected()
173 if CORBA.is_nil(mySObject):
174 self.__ui.txtSmeshObject.setText("You must choose a mesh")
175 self.__ui.txtGroupName.setText("")
176 self.__ui.txtSmeshObject.setEnabled(False)
177 self.__ui.btnAddInput.setEnabled(False)
178 self.__selectedMesh = None
181 self.smeshStudyTool.updateStudy()
182 self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
183 if CORBA.is_nil(self.__selectedMesh):
184 self.__ui.txtSmeshObject.setText("The selected object is not a mesh")
185 self.__ui.txtGroupName.setText("")
186 self.__ui.txtSmeshObject.setEnabled(False)
187 self.__ui.btnAddInput.setEnabled(False)
188 self.__selectedMesh = None
190 myName = mySObject.GetName()
191 self.__ui.txtSmeshObject.setText(myName)
192 self.__ui.txtSmeshObject.setEnabled(True)
193 self.__ui.btnAddInput.setEnabled(True)
195 # We can suggest a default group name from the mesh name
196 self.__ui.txtGroupName.setText(myName)
198 def onAddInput(self):
200 This function is the slot connected to the Add button. It
201 creates a new entry in the list of input data, or updates this
202 entry if it already exists.
204 meshName = str(self.__ui.txtSmeshObject.text()).strip()
205 meshObject = self.__selectedMesh
206 meshType = self.__ui.cmbMeshType.currentIndex()
207 groupName = str(self.__ui.txtGroupName.text()).strip()
209 self.__addInputInGui(meshName, meshObject, meshType, groupName)
210 self.__addInputInMap(meshName, meshObject, meshType, groupName)
212 def __addInputInGui(self, meshName, meshObject, meshType, groupName):
214 This function adds an entry with the specified data int the
215 GUI table (for data visualization purpose).
217 # The mesh name is used as the key index in the model. We have
218 # to check first if this item already exists in the list.
219 tblItems = self.__inputModel.findItems(meshName)
220 row = self.__inputModel.rowCount()
223 tblItems.append(QStandardItem()) # input mesh name
224 tblItems.append(QStandardItem()) # output group name
226 row = tblItems[0].index().row()
227 tblItems.append(self.__inputModel.item(row,1))
229 tblItems[0].setText(meshName)
230 tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType])
231 tblItems[1].setText(groupName)
232 self.__inputModel.setItem(row,0,tblItems[0])
233 self.__inputModel.setItem(row,1,tblItems[1])
234 self.__ui.tblListInput.setCurrentIndex(tblItems[0].index())
236 def __addInputInMap(self, meshName, meshObject, meshType, groupName):
238 This function adds an entry with the specified data in the
239 internal map (for data management purpose).
241 # if the entry already exists, we remove it to replace by a
243 if meshName in self.__dictInputFiles:
244 self.__delInputFromMap(meshName)
246 inputData = InputData()
247 inputData.meshName = meshName
248 inputData.meshObject = meshObject
249 inputData.meshType = meshType
250 inputData.groupName = groupName
251 # The key of the map is the mesh name
252 self.__dictInputFiles[meshName] = inputData
253 if inputData.meshType == InputData.MESHTYPES.CONCRETE:
254 self.__nbConcreteMesh += 1
256 self.__nbSteelbarMesh += 1
259 print("meshType = ",inputData.meshType)
260 print("nb concrete mesh ",self.__nbConcreteMesh)
261 print("nb steelbar mesh ",self.__nbSteelbarMesh)
264 def onDeleteInput(self):
266 This function is the slot connected to the Delete button. It
267 remove from the data list the entry selected in the Qt table.
269 selectedIdx = self.__ui.tblListInput.selectedIndexes()
271 row = selectedIdx[0].row()
272 tblItem = self.__inputModel.item(row,0)
273 meshName = str(tblItem.text())
274 self.__inputModel.takeRow(row)
275 # Don't forget to remove this entry from the mesh object
276 # internal dictionnary
277 self.__delInputFromMap(meshName)
279 def __delInputFromMap(self, meshName):
281 This function removes the specified entry from the internal
282 map (for data management purpose)
284 inputData = self.__dictInputFiles.pop(meshName)
285 if inputData.meshType == InputData.MESHTYPES.CONCRETE:
286 self.__nbConcreteMesh -= 1
288 self.__nbSteelbarMesh -= 1
291 print("nb concrete mesh ",self.__nbConcreteMesh)
292 print("nb steelbar mesh ",self.__nbSteelbarMesh)
295 def setData(self, dictInputData={}):
297 This function fills the dialog widgets with values provided by
298 the specified data list.
301 if INPUTDATA_KEY_FILES in dictInputData:
302 listInputData = dictInputData["meshfiles"]
303 for inputData in listInputData:
305 meshName = inputData.meshName
306 meshObject = inputData.meshObject
307 meshType = inputData.meshType
308 groupName = inputData.groupName
310 self.__addInputInGui(meshName, meshObject, meshType, groupName)
311 self.__addInputInMap(meshName, meshObject, meshType, groupName)
314 self.onSelectSmeshObject()
316 if INPUTDATA_KEY_PARAM in dictInputData:
317 dictInputParameters = dictInputData[INPUTDATA_KEY_PARAM]
318 if PARAM_KEY_NBITER in dictInputParameters:
319 self.__ui.txtParamNbIter.setValue(dictInputParameters[PARAM_KEY_NBITER])
320 if PARAM_KEY_RMAXRMIN in dictInputParameters:
321 self.__ui.txtParamRminRmax.setValue(dictInputParameters[PARAM_KEY_RMAXRMIN])
325 This function returns a list of InputData that corresponds to
326 the data in the dialog widgets of the current dialog.
328 # Get the list of mesh files
329 # Note that the values() function returns a copy of the list
332 dictInputData[INPUTDATA_KEY_FILES] = self.__dictInputFiles.values()
334 # Get the list of additionnal parameters
335 dictInputParameters = {}
336 dictInputParameters[PARAM_KEY_NBITER] = self.__ui.txtParamNbIter.value()
337 dictInputParameters[PARAM_KEY_RMAXRMIN] = self.__ui.txtParamRmaxRmin.value()
338 dictInputData[INPUTDATA_KEY_PARAM] = dictInputParameters
343 This function checks if the data are valid, from the dialog
344 window point of view.
346 if self.__nbConcreteMesh == 0 and self.__nbSteelbarMesh == 0:
347 self.checkDataMessage = "You must define at least one mesh (CONCRETE or STEELBAR)"
349 if self.__nbConcreteMesh > 1:
350 self.checkDataMessage = "You define multiple CONCRETE meshes."
351 self.checkDataMessage += "You should verify first that your version of PADDER support this configuration."
352 # just warn the user, but don't block
353 QMessageBox.information(self, "Info", self.checkDataMessage)
359 # ==============================================================================
361 # ==============================================================================
363 def TEST_InputDialog():
365 from qtsalome import QApplication
366 app = QApplication(sys.argv)
367 app.lastWindowClosed.connect( app.quit )
372 print("OK has been pressed")
374 def TEST_InputDialog_setData():
376 from qtsalome import QApplication
377 app = QApplication(sys.argv)
378 app.lastWindowClosed.connect( app.quit )
382 from .inputdata import InputData
383 inputData = InputData()
384 inputData.meshName = "myMesh"
385 inputData.meshObject = None
386 inputData.meshType = InputData.MESHTYPES.CONCRETE
387 inputData.groupName = "myGroup"
389 listInputData.append(inputData)
391 dlg.setData2(listInputData)
395 print("OK has been pressed")
396 outputListInputData = dlg.getData2()
397 print(outputListInputData)
400 if __name__ == "__main__":
402 TEST_InputDialog_setData()