Back to index

salome-smesh  6.5.0
inputdialog.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 # Copyright (C) 2011-2012  EDF R&D
00003 #
00004 # This library is free software; you can redistribute it and/or
00005 # modify it under the terms of the GNU Lesser General Public
00006 # License as published by the Free Software Foundation; either
00007 # version 2.1 of the License.
00008 #
00009 # This library is distributed in the hope that it will be useful,
00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 # Lesser General Public License for more details.
00013 #
00014 # You should have received a copy of the GNU Lesser General Public
00015 # License along with this library; if not, write to the Free Software
00016 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00017 #
00018 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00019 #
00020 # Author : Guillaume Boulant (EDF)
00021 #
00022 
00023 import os
00024 
00025 import salome
00026 from salome.kernel import studyedit
00027 from salome.gui.genericdialog import GenericDialog
00028 from salome.gui import helper as guihelper
00029 from salome.smesh.smeshstudytools import SMeshStudyTools
00030 
00031 from omniORB import CORBA
00032 
00033 from PyQt4.QtCore import QObject, SIGNAL, SLOT
00034 from PyQt4.QtGui import QIcon, QStandardItemModel, QStandardItem, QMessageBox
00035 
00036 from inputframe_ui import Ui_InputFrame
00037 from inputdata import InputData
00038 
00039 DEBUG_MODE=True
00040 GROUPNAME_MAXLENGTH=8
00041 
00042 class InputDialog(GenericDialog):
00043 
00044     TBL_HEADER_LABEL=["Input Mesh", "Output group name"]
00045 
00046     def __init__(self, parent=None, name="InputDialog", modal=0):
00047         """
00048         This initializes a dialog windows to define the input data of
00049         the plugin function. The input data consist in a list of
00050         meshes characterizes each by a name, a pointer to the smesh
00051         servant object, a type and a group name (see data model in the
00052         inputdata.py).
00053         """
00054         GenericDialog.__init__(self, parent, name, modal)
00055         # Set up the user interface from Designer.
00056         self.__ui = Ui_InputFrame()
00057         # BE CAREFULL HERE, the ui form is NOT drawn in the global
00058         # dialog (already containing some generic widgets) but in the
00059         # center panel created in the GenericDialog as a void
00060         # container for the form. The InputFrame form is supposed
00061         # here to create only the widgets to be placed in the center
00062         # panel. Then, the setupUi function of this form draws itself
00063         # in the specified panel, i.e. the panel returned by
00064         # self.getPanel().
00065         self.__ui.setupUi(self.getPanel())
00066 
00067         self.setWindowTitle("Specification of input files")
00068 
00069         # The icon are supposed to be located in the plugin folder,
00070         # i.e. in the same folder than this python module file
00071         iconfolder=os.path.dirname(os.path.abspath(__file__))
00072         icon = QIcon()
00073         icon.addFile(os.path.join(iconfolder,"select.png"))
00074         self.__ui.btnSmeshObject.setIcon(icon)
00075         icon = QIcon()
00076         icon.addFile(os.path.join(iconfolder,"addinput.png"))
00077         self.__ui.btnAddInput.setIcon(icon)
00078         icon = QIcon()
00079         icon.addFile(os.path.join(iconfolder,"deleteinput.png"))
00080         self.__ui.btnDeleteInput.setIcon(icon)
00081 
00082         # We specify here the items in the combo box (even if already
00083         # defined in the designer) so that we can be sure of the item
00084         # indexation.
00085         self.MESHTYPE_ICONS = {}
00086         meshTypeIndex = InputData.MESHTYPES.CONCRETE
00087         self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Béton")
00088         icon = QIcon()
00089         icon.addFile(os.path.join(iconfolder,"concrete.png"))
00090         self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
00091         self.MESHTYPE_ICONS[meshTypeIndex] = icon
00092 
00093         meshTypeIndex = InputData.MESHTYPES.STEELBAR
00094         self.__ui.cmbMeshType.setItemText(meshTypeIndex, "Acier")
00095         icon = QIcon()
00096         icon.addFile(os.path.join(iconfolder,"steelbar.png"))
00097         self.__ui.cmbMeshType.setItemIcon(meshTypeIndex, icon)
00098         self.MESHTYPE_ICONS[meshTypeIndex] = icon
00099         
00100         # The click on btnSmeshObject (signal clicked() emitted by the
00101         # button btnSmeshObject) is connected to the slot
00102         # onSelectSmeshObject, etc ...
00103         self.connect(self.__ui.btnSmeshObject, SIGNAL('clicked()'), self.onSelectSmeshObject )
00104         self.connect(self.__ui.btnAddInput,    SIGNAL('clicked()'), self.onAddInput )
00105         self.connect(self.__ui.btnDeleteInput, SIGNAL('clicked()'), self.onDeleteInput )
00106 
00107         # Set up the model of the Qt table list
00108         self.__inputModel = QStandardItemModel(0,2)
00109         self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
00110         self.__ui.tblListInput.setModel(self.__inputModel)
00111         self.__ui.tblListInput.verticalHeader().hide()
00112         self.__ui.tblListInput.horizontalHeader().setStretchLastSection(True)
00113         # Note that the type is not display explicitly in the Qt table
00114         # because it is specified using an icon on the text of the
00115         # name item. 
00116 
00117         # Note that PADDER does not support group name longer than 8
00118         # characters. We apply then this limit in the gui field.
00119         self.__ui.txtGroupName.setMaxLength(GROUPNAME_MAXLENGTH)
00120 
00121         self.clear()
00122 
00123         self.smeshStudyTool = SMeshStudyTools()
00124 
00125     def clear(self):
00126         """
00127         This function clears the data gui area and associated values.
00128         """
00129         self.__ui.txtSmeshObject.setText("")
00130         self.__ui.txtGroupName.setText("")
00131         self.__inputModel.clear()
00132         self.__inputModel.setHorizontalHeaderLabels(InputDialog.TBL_HEADER_LABEL)
00133         if not DEBUG_MODE:
00134             self.__ui.txtSmeshObject.setEnabled(False)
00135             self.__ui.btnAddInput.setEnabled(False)
00136         self.__selectedMesh = None
00137         self.__dictInputData = {}
00138         self.__nbConcreteMesh = 0
00139         self.__nbSteelbarMesh = 0
00140 
00141     def accept(self):
00142         """
00143         This function is the slot connected to the button OK
00144         """
00145         # The dialog is raised in a non modal mode to get
00146         # interactivity with the parents windows. Then we have to emit
00147         # a signal to warn the parent observer that the dialog has
00148         # been validated so that it can process the event
00149         GenericDialog.accept(self)
00150         if self.wasOk():
00151             self.emit(SIGNAL('inputValidated()'))
00152 
00153     def onSelectSmeshObject(self):
00154         '''
00155         This function is the slot connected on the mesh selection
00156         button. It memorizes the selected mesh and put its name in the
00157         text field of the dialog box.
00158         '''
00159         mySObject, myEntry = guihelper.getSObjectSelected()
00160         if CORBA.is_nil(mySObject):
00161             self.__ui.txtSmeshObject.setText("You must choose a mesh")
00162             self.__ui.txtGroupName.setText("")
00163             self.__ui.txtSmeshObject.setEnabled(False)
00164             self.__ui.btnAddInput.setEnabled(False)
00165             self.__selectedMesh = None
00166             return
00167 
00168         self.smeshStudyTool.updateStudy(studyedit.getActiveStudyId())
00169         self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject)
00170         if CORBA.is_nil(self.__selectedMesh):
00171             self.__ui.txtSmeshObject.setText("The selected object is not a mesh")
00172             self.__ui.txtGroupName.setText("")
00173             self.__ui.txtSmeshObject.setEnabled(False)
00174             self.__ui.btnAddInput.setEnabled(False)
00175             self.__selectedMesh = None
00176             return
00177         myName = mySObject.GetName()
00178         self.__ui.txtSmeshObject.setText(myName)
00179         self.__ui.txtSmeshObject.setEnabled(True)
00180         self.__ui.btnAddInput.setEnabled(True)
00181 
00182         # We can suggest a default group name from the mesh name
00183         self.__ui.txtGroupName.setText(myName)
00184 
00185     def onAddInput(self):
00186         """
00187         This function is the slot connected to the Add button. It
00188         creates a new entry in the list of input data, or updates this
00189         entry if it already exists.
00190         """
00191         meshName   = str(self.__ui.txtSmeshObject.text().trimmed())
00192         meshObject = self.__selectedMesh
00193         meshType   = self.__ui.cmbMeshType.currentIndex()
00194         groupName  = str(self.__ui.txtGroupName.text().trimmed())
00195 
00196         self.__addInputInGui(meshName, meshObject, meshType, groupName)
00197         self.__addInputInMap(meshName, meshObject, meshType, groupName)
00198 
00199     def __addInputInGui(self, meshName, meshObject, meshType, groupName):
00200         """
00201         This function adds an entry with the specified data int the
00202         GUI table (for data visualization purpose).
00203         """
00204         # The mesh name is used as the key index in the model. We have
00205         # to check first if this item already exists in the list.
00206         tblItems = self.__inputModel.findItems(meshName)
00207         row = self.__inputModel.rowCount()
00208         if not tblItems:
00209             tblItems = []
00210             tblItems.append(QStandardItem()) # input mesh name
00211             tblItems.append(QStandardItem()) # output group name
00212         else:
00213             row = tblItems[0].index().row()
00214             tblItems.append(self.__inputModel.item(row,1))
00215 
00216         tblItems[0].setText(meshName)
00217         tblItems[0].setIcon(self.MESHTYPE_ICONS[meshType])
00218         tblItems[1].setText(groupName)
00219         self.__inputModel.setItem(row,0,tblItems[0])
00220         self.__inputModel.setItem(row,1,tblItems[1])
00221         self.__ui.tblListInput.setCurrentIndex(tblItems[0].index())
00222 
00223     def __addInputInMap(self, meshName, meshObject, meshType, groupName):
00224         """
00225         This function adds an entry with the specified data in the
00226         internal map (for data management purpose).
00227         """
00228         # if the entry already exists, we remove it to replace by a
00229         # new one
00230         if self.__dictInputData.has_key(meshName):
00231             self.__delInputFromMap(meshName)
00232         
00233         inputData = InputData()
00234         inputData.meshName   = meshName
00235         inputData.meshObject = meshObject
00236         inputData.meshType   = meshType
00237         inputData.groupName  = groupName
00238         # The key of the map is the mesh name
00239         self.__dictInputData[meshName] = inputData
00240         if inputData.meshType == InputData.MESHTYPES.CONCRETE:
00241             self.__nbConcreteMesh += 1
00242         else:
00243             self.__nbSteelbarMesh += 1
00244 
00245         print inputData
00246         print "meshType = ",inputData.meshType
00247         print "nb concrete mesh ",self.__nbConcreteMesh
00248         print "nb steelbar mesh ",self.__nbSteelbarMesh
00249             
00250 
00251     def onDeleteInput(self):
00252         """
00253         This function is the slot connected to the Delete button. It
00254         remove from the data list the entry selected in the Qt table.
00255         """
00256         selectedIdx = self.__ui.tblListInput.selectedIndexes()
00257         if selectedIdx:
00258             row  = selectedIdx[0].row()
00259             tblItem  = self.__inputModel.item(row,0)
00260             meshName = str(tblItem.text())
00261             self.__inputModel.takeRow(row)
00262             # Don't forget to remove this entry from the mesh object
00263             # internal dictionnary
00264             self.__delInputFromMap(meshName)
00265 
00266     def __delInputFromMap(self, meshName):
00267         """
00268         This function removes the specified entry from the internal
00269         map (for data management purpose) 
00270         """
00271         inputData = self.__dictInputData.pop(meshName)
00272         if inputData.meshType == InputData.MESHTYPES.CONCRETE:
00273             self.__nbConcreteMesh -= 1
00274         else:
00275             self.__nbSteelbarMesh -= 1
00276 
00277         print inputData
00278         print "nb concrete mesh ",self.__nbConcreteMesh
00279         print "nb steelbar mesh ",self.__nbSteelbarMesh
00280 
00281 
00282     def setData(self, listInputData=[]):
00283         """
00284         This function fills the dialog widgets with values provided by
00285         the specified data list.
00286         """
00287         self.clear()
00288         for inputData in listInputData:
00289 
00290             meshName   = inputData.meshName
00291             meshObject = inputData.meshObject
00292             meshType   = inputData.meshType
00293             groupName  = inputData.groupName
00294             
00295             self.__addInputInGui(meshName, meshObject, meshType, groupName)
00296             self.__addInputInMap(meshName, meshObject, meshType, groupName)
00297 
00298             if not DEBUG_MODE:
00299                 self.onSelectSmeshObject()
00300 
00301     def getData(self):
00302         """
00303         This function returns a list of InputData that corresponds to
00304         the data in the dialog widgets of the current dialog.
00305         """
00306         # Note that the values() function returns a copy of the list
00307         # of values.
00308         return self.__dictInputData.values()
00309         
00310     def checkData(self):
00311         """
00312         This function checks if the data are valid, from the dialog
00313         window point of view.
00314         """
00315         if self.__nbConcreteMesh < 1:
00316             self.checkDataMessage = "You must define at least one CONCRETE mesh"
00317             return False        
00318         if self.__nbConcreteMesh > 1:
00319             self.checkDataMessage  = "You define multiple CONCRETE meshes."
00320             self.checkDataMessage += "You should verify first that your version of PADDER support this configuration."
00321             # just warn the user, but don't block
00322             QMessageBox.information(self, "Info", self.checkDataMessage)
00323             return True
00324         if self.__nbSteelbarMesh < 1:
00325             self.checkDataMessage = "You must define at least one STEELBAR mesh"
00326             return False
00327         return True
00328 
00329 
00330 # ==============================================================================
00331 # Basic use case
00332 # ==============================================================================
00333 #
00334 def TEST_InputDialog():
00335     import sys
00336     from PyQt4.QtCore import QObject, SIGNAL, SLOT
00337     from PyQt4.QtGui import QApplication
00338     app = QApplication(sys.argv)
00339     QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
00340 
00341     dlg=InputDialog()
00342     dlg.displayAndWait()
00343     if dlg.wasOk():
00344         print "OK has been pressed"
00345 
00346 def TEST_InputDialog_setData():
00347     import sys
00348     from PyQt4.QtCore import QObject, SIGNAL, SLOT
00349     from PyQt4.QtGui import QApplication
00350     app = QApplication(sys.argv)
00351     QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
00352 
00353     dlg=InputDialog()
00354 
00355     from inputdata import InputData
00356     inputData = InputData()
00357     inputData.meshName   = "myMesh"
00358     inputData.meshObject = None
00359     inputData.meshType   = InputData.MESHTYPES.CONCRETE
00360     inputData.groupName  = "myGroup"
00361     listInputData = []
00362     listInputData.append(inputData)
00363     
00364     dlg.setData2(listInputData)
00365     
00366     dlg.displayAndWait()
00367     if dlg.wasOk():
00368         print "OK has been pressed"
00369         outputListInputData = dlg.getData2()
00370         print outputListInputData
00371 
00372 
00373 if __name__ == "__main__":
00374     #TEST_InputDialog()
00375     TEST_InputDialog_setData()
00376