1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2010 EDF R&D
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.
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
22 This file centralizes the definitions and implementations of ui components used
23 in the GUI part of the module.
26 __author__ = "aribes/gboulant"
29 from PyQt4.QtCore import QObject
30 from PyQt4.QtCore import * # Import from PyQT
31 from PyQt4 import QtGui,QtCore
33 sgPyQt = SalomePyQt.SalomePyQt()
35 from daGuiImpl.enumerate import Enumerate
36 from daGuiImpl.adaoCase import AdaoCase
37 from daEficasWrapper.adaoEficasWrapper import AdaoEficasWrapper
39 from daUtils.adaoEficasEvent import *
41 import adaoStudyEditor
47 # ==============================================================================
48 # Classes to manage the building of UI components
49 # ==============================================================================
51 UI_ELT_IDS = Enumerate([
56 'SAVE_AS_ADAOCASE_ID',
59 'EDIT_ADAOCASE_POP_ID',
64 UI_ELT_IDS.NEW_ADAOCASE_ID:"newAdaoCase",
65 UI_ELT_IDS.OPEN_ADAOCASE_ID:"openAdaoCase",
66 UI_ELT_IDS.SAVE_ADAOCASE_ID:"saveAdaoCase",
67 UI_ELT_IDS.SAVE_AS_ADAOCASE_ID:"saveasAdaoCase",
68 UI_ELT_IDS.CLOSE_ADAOCASE_ID:"closeAdaoCase",
70 UI_ELT_IDS.EDIT_ADAOCASE_POP_ID:"editAdaoCase",
71 UI_ELT_IDS.YACS_EXPORT_POP_ID:"exportCaseToYACS",
75 class AdaoCaseManager(EficasObserver):
77 Cette classe gére les cas ADAO et coordonne les GUI de SALOME (l'étude)
78 et le GUI de l'objet Eficas (héritage du module Eficas)
82 # Création d'un dictionnaire de cas
84 # Value == objet AdaoCase()
87 # Création des deux managers
88 self.salome_manager = AdaoGuiUiComponentBuilder()
89 self.eficas_manager = AdaoEficasWrapper(parent=SalomePyQt.SalomePyQt().getDesktop())
91 # On s'enregistre comme observer pour les évènements venant d'Eficas
92 # Les évènements du salome_manager viennent par le biais de la méthode
94 self.eficas_manager.addObserver(self)
96 # Création du GUI Eficas
97 self.eficas_manager.init_gui()
99 # Création du viewer QT
100 # Scroll Widget (pour les petites résolutions)
101 area = QtGui.QScrollArea(SalomePyQt.SalomePyQt().getDesktop());
102 area.setWidget(self.eficas_manager)
103 area.setWidgetResizable(1)
105 self.eficas_viewId = sgPyQt.createView(wmType, area)
107 # On interdit que la vue soit fermée
108 # Cela simplifier grandement le code
109 sgPyQt.setViewClosable(self.eficas_viewId, False)
111 # On s'abonne au gestionnaire de selection
112 self.selection_manager = sgPyQt.getSelection()
113 QtCore.QObject.connect(self.selection_manager, QtCore.SIGNAL('currentSelectionChanged()'), self.currentSelectionChanged)
116 self.eficas_manager.setEnabled(True)
118 def deactivate(self):
119 self.eficas_manager.setEnabled(False)
121 def currentSelectionChanged(self):
122 adaoLogger.debug("currentSelectionChanged")
123 salomeStudyItem = adaoGuiHelper.getSelectedItem()
124 for case_name, adao_case in self.cases.iteritems():
125 if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
126 self.eficas_manager.selectCase(adao_case.eficas_editor)
129 def _processEficasTabChanged(self, eficasWrapper, eficasEvent):
131 Gestion de la synchonisation entre le tab courant et la selection
134 editor = eficasEvent.callbackId
135 for case_name, adao_case in self.cases.iteritems():
136 if adao_case.eficas_editor is editor:
137 adaoGuiHelper.selectItem(adao_case.salome_study_item.GetID())
140 # Création d'un nouveau cas
141 # 1: la fonction newAdaoCase est appelée par le GUI SALOME
142 # 2: la fonction _processEficasNewEvent est appelée par le manager EFICAS
143 def newAdaoCase(self):
144 adaoLogger.debug("Création d'un nouveau cas adao")
145 self.eficas_manager.adaofileNew(AdaoCase())
147 def _processEficasNewEvent(self, eficasWrapper, eficasEvent):
148 adao_case = eficasEvent.callbackId
150 salomeStudyId = adaoGuiHelper.getActiveStudyId()
151 salomeStudyItem = adaoStudyEditor.addInStudy(salomeStudyId, adao_case)
152 # Affichage correct dans l'étude
153 adaoGuiHelper.refreshObjectBrowser()
154 adaoGuiHelper.selectItem(salomeStudyItem.GetID())
155 # Finalisation des données du cas
156 adao_case.salome_study_id = salomeStudyId
157 adao_case.salome_study_item = salomeStudyItem
159 self.cases[adao_case.name] = adao_case
161 # Sauvegarde d'un cas
162 # 1: la fonction saveAdaoCase est appelée par le GUI SALOME
163 # 2: la fonction _processEficasSaveEvent est appelée par le manager EFICAS
164 def saveAdaoCase(self):
165 adaoLogger.debug("Sauvegarde du cas s'il y a modification")
166 salomeStudyItem = adaoGuiHelper.getSelectedItem()
167 for case_name, adao_case in self.cases.iteritems():
168 if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
169 self.eficas_manager.adaoFileSave(adao_case)
172 def _processEficasSaveEvent(self, eficasWrapper, eficasEvent):
173 adao_case = eficasEvent.callbackId
174 # On met à jour l'étude
175 adaoStudyEditor.updateItem(adao_case.salome_study_id, adao_case.salome_study_item, adao_case)
176 # Affichage correct dans l'étude
177 adaoGuiHelper.refreshObjectBrowser()
178 adaoGuiHelper.selectItem(adao_case.salome_study_item.GetID())
180 self.cases[adao_case.name] = adao_case
182 # Gestion des évènements venant du manager Eficas
184 EficasEvent.EVENT_TYPES.CLOSE : "_processEficasCloseEvent",
185 EficasEvent.EVENT_TYPES.SAVE : "_processEficasSaveEvent",
186 EficasEvent.EVENT_TYPES.NEW : "_processEficasNewEvent",
187 EficasEvent.EVENT_TYPES.DESTROY : "_processEficasDestroyEvent",
188 EficasEvent.EVENT_TYPES.OPEN : "_processEficasOpenEvent",
189 EficasEvent.EVENT_TYPES.REOPEN : "_processEficasReOpenEvent",
190 EficasEvent.EVENT_TYPES.TABCHANGED : "_processEficasTabChanged"
193 def processEficasEvent(self, eficasWrapper, eficasEvent):
195 Implementation of the interface EficasObserver. The implementation is a
196 switch on the possible types of events defined in EficasEvent.EVENT_TYPES.
199 functionName = self.__processOptions.get(eficasEvent.eventType, lambda : "_processEficasUnknownEvent")
200 return getattr(self,functionName)(eficasWrapper, eficasEvent)
202 def _processEficasUnknownEvent(self, eficasWrapper, eficasEvent):
203 adaoLogger.error("Unknown Eficas Event")
205 # Gestion des évènements venant du GUI de SALOME
206 def processGUIEvent(self, actionId):
208 Main switch function for ui actions processing
210 if ACTIONS_MAP.has_key(actionId):
212 functionName = ACTIONS_MAP[actionId]
213 getattr(self,functionName)()
215 traceback.print_exc()
217 adaoLogger.warning("The requested action is not implemented: " + str(actionId))
219 class AdaoGuiUiComponentBuilder:
221 The initialisation of this class creates the graphic components involved
222 in the GUI (menu, menu item, toolbar). A ui component builder should be
223 created for each opened study and associated to its context.
226 self.initUiComponents()
228 def initUiComponents(self):
232 # create top-level menu
233 mid = sgPyQt.createMenu( "ADAO", -1, UI_ELT_IDS.ADAO_MENU_ID, sgPyQt.defaultMenuGroup() )
235 tid = sgPyQt.createTool( "ADAO" )
237 a = sgPyQt.createAction( UI_ELT_IDS.NEW_ADAOCASE_ID, "New case", "New case", "Create a new adao case", "" )
238 sgPyQt.createMenu(a, mid)
239 sgPyQt.createTool(a, tid)
240 a = sgPyQt.createAction( UI_ELT_IDS.OPEN_ADAOCASE_ID, "Open case", "Open case", "Open an adao case", "" )
241 sgPyQt.createMenu(a, mid)
242 sgPyQt.createTool(a, tid)
243 a = sgPyQt.createAction( UI_ELT_IDS.SAVE_ADAOCASE_ID, "Save case", "Save case", "Save an adao case", "" )
244 sgPyQt.createMenu(a, mid)
245 sgPyQt.createTool(a, tid)
246 a = sgPyQt.createAction( UI_ELT_IDS.SAVE_AS_ADAOCASE_ID, "Save as case", "Save as case", "Save an adao case as", "" )
247 sgPyQt.createMenu(a, mid)
248 sgPyQt.createTool(a, tid)
249 a = sgPyQt.createAction( UI_ELT_IDS.CLOSE_ADAOCASE_ID, "Close case", "Close case", "Close an adao case", "" )
250 sgPyQt.createMenu(a, mid)
251 sgPyQt.createTool(a, tid)
253 # the following action are used in context popup
254 a = sgPyQt.createAction( UI_ELT_IDS.CLOSE_ADAOCASE_ID, "Close case", "Close case", "Close the selected case", "" )
256 a = sgPyQt.createAction( UI_ELT_IDS.EDIT_ADAOCASE_POP_ID, "Edit case", "Edit case", "Edit the selected study case", "" )
257 a = sgPyQt.createAction( UI_ELT_IDS.YACS_EXPORT_POP_ID, "Export to YACS", "Export to YACS", "Generate a YACS graph executing this case", "" )
259 def createPopupMenuOnItem(self,popup,salomeSudyId, item):
260 if adaoStudyEditor.isValidAdaoCaseItem(salomeSudyId, item):
261 popup.addAction( sgPyQt.action( UI_ELT_IDS.CLOSE_ADAOCASE_ID ) )
263 popup.addAction( sgPyQt.action( UI_ELT_IDS.EDIT_ADAOCASE_POP_ID ) )
264 popup.addAction( sgPyQt.action( UI_ELT_IDS.YACS_EXPORT_POP_ID ) )
268 class AdaoGuiActionImpl(EficasObserver):
270 This class implements the ui actions concerning the management of oma study
276 # This dialog is created once so that it can be recycled for each call
278 #self.__dlgNewStudyCase = DlgNewStudyCase()
279 self.__parent = SalomePyQt.SalomePyQt().getDesktop()
280 self.__dlgEficasWrapper = AdaoEficasWrapper(parent=SalomePyQt.SalomePyQt().getDesktop())
281 self.__dlgEficasWrapper.addObserver(self)
282 self.__Eficas_viewId = -1
284 # ==========================================================================
285 # Processing of ui actions
287 def processAction(self,actionId):
289 Main switch function for ui actions processing
291 if ACTIONS_MAP.has_key(actionId):
293 functionName = ACTIONS_MAP[actionId]
294 getattr(self,functionName)()
296 traceback.print_exc()
298 msg = "The requested action is not implemented: " + str(actionId)
301 def showEficas(self):
302 if self.__Eficas_viewId == -1:
303 self.__dlgEficasWrapper.init_gui()
307 area = QtGui.QScrollArea(SalomePyQt.SalomePyQt().getDesktop());
308 area.setWidget( self.__dlgEficasWrapper)
309 area.setWidgetResizable(1)
312 self.__Eficas_viewId = sgPyQt.createView(wmType, area)
313 sgPyQt.setViewClosable(self.__Eficas_viewId, False)
315 if SalomePyQt.SalomePyQt().getActiveView() != self.__Eficas_viewId :
316 result_activate = SalomePyQt.SalomePyQt().activateView(self.__Eficas_viewId)
317 if result_activate == False:
318 self.__dlgEficasWrapper.init_gui()
321 area = QtGui.QScrollArea(SalomePyQt.SalomePyQt().getDesktop());
322 area.setWidget( self.__dlgEficasWrapper)
323 area.setWidgetResizable(1)
326 self.__Eficas_viewId = sgPyQt.createView(wmType, area)
327 sgPyQt.setViewClosable(self.__Eficas_viewId, False)
328 self.__dlgEficasWrapper.setEnabled(True)
333 def deactivate(self):
335 if self.__Eficas_viewId != -1:
336 self.__dlgEficasWrapper.setEnabled(False)
338 # Actions from SALOME GUI
340 def newAdaoCase(self):
342 adaoLogger.debug("newAdaoCase")
344 self.__dlgEficasWrapper.fileNew()
346 def openAdaoCase(self):
348 adaoLogger.debug("openAdaoCase")
351 fichier = QtGui.QFileDialog.getOpenFileName(SalomePyQt.SalomePyQt().getDesktop(),
352 self.__dlgEficasWrapper.trUtf8('Ouvrir Fichier'),
353 self.__dlgEficasWrapper.CONFIGURATION.savedir,
354 self.__dlgEficasWrapper.trUtf8('JDC Files (*.comm);;''All Files (*)'))
355 if fichier.isNull(): return
356 new_case = AdaoCase()
357 new_case.set_filename(str(fichier))
358 new_case.set_name(str(fichier.split('/')[-1]))
359 salomeStudyId = adaoGuiHelper.getActiveStudyId()
360 salomeStudyItem = adaoStudyEditor.addInStudy(salomeStudyId, new_case)
361 case_key = (salomeStudyId, salomeStudyItem.GetID())
362 __cases__[case_key] = new_case
364 # Open file in Eficas
365 self.__dlgEficasWrapper.Openfile(new_case.get_filename())
366 callbackId = [salomeStudyId, salomeStudyItem]
367 self.__dlgEficasWrapper.setCallbackId(callbackId)
369 adaoGuiHelper.refreshObjectBrowser()
371 def editAdaoCase(self):
373 adaoLogger.debug("editAdaoCase")
377 salomeStudyId = adaoGuiHelper.getActiveStudyId()
378 salomeStudyItem = adaoGuiHelper.getSelectedItem(salomeStudyId)
379 case_key = (salomeStudyId, salomeStudyItem.GetID())
381 # ShowEficas, If case is an empty case - case is destroyed by reopen
384 case = __cases__[case_key]
385 # Search if case is in Eficas !
386 callbackId = [salomeStudyId, salomeStudyItem]
387 case_open_in_eficas = self.__dlgEficasWrapper.selectCase(callbackId)
389 # If case is not in eficas Open It !
390 if case_open_in_eficas == False:
391 if case.get_filename() != "":
392 self.__dlgEficasWrapper.Openfile(case.get_filename())
393 callbackId = [salomeStudyId, salomeStudyItem]
394 self.__dlgEficasWrapper.setCallbackId(callbackId)
396 # Case has been destroyed - create a new one
397 self.__dlgEficasWrapper.fileNew()
399 def closeAdaoCase(self):
401 adaoLogger.debug("closeAdaoCase")
404 # First step: get selected case
405 salomeStudyId = adaoGuiHelper.getActiveStudyId()
406 salomeStudyItem = adaoGuiHelper.getSelectedItem(salomeStudyId)
408 # Check if there is a selected case
409 if salomeStudyItem is None:
410 print "[Close case] Please select a case"
413 callbackId = [salomeStudyId, salomeStudyItem]
414 case_open_in_eficas = self.__dlgEficasWrapper.selectCase(callbackId)
416 # If case is in eficas close it !
417 if case_open_in_eficas:
418 # fileClose: remove the CallbackId
419 # fileClose: sends a destroy event
420 self.__dlgEficasWrapper.fileClose()
422 # Test if case exists
423 case_key = (salomeStudyId, salomeStudyItem.GetID())
424 if __cases__.has_key(case_key):
425 __cases__.pop(case_key)
426 adaoStudyEditor.removeItem(salomeStudyId, salomeStudyItem)
427 adaoGuiHelper.refreshObjectBrowser()
429 def saveAdaoCase(self):
431 adaoLogger.debug("saveAdaoCase")
434 def saveasAdaoCase(self):
436 adaoLogger.debug("saveasAdaoCase")
439 def exportCaseToYACS(self):
441 adaoLogger.debug("exportCaseToYACS")
444 # Get case from study
445 salomeStudyId = adaoGuiHelper.getActiveStudyId()
446 salomeStudyItem = adaoGuiHelper.getSelectedItem(salomeStudyId)
447 case_key = (salomeStudyId, salomeStudyItem.GetID())
448 case = __cases__[case_key]
450 # Generates YACS schema and export it
451 msg = case.exportCaseToYACS()
453 # If msg is not empty -> error found
455 adaoGuiHelper.gui_warning(self.__parent, msg)
457 # ==========================================================================
458 # Processing notifications from adaoEficasWrapper
461 EficasEvent.EVENT_TYPES.CLOSE : "_processEficasCloseEvent",
462 EficasEvent.EVENT_TYPES.SAVE : "_processEficasSaveEvent",
463 EficasEvent.EVENT_TYPES.NEW : "_processEficasNewEvent",
464 EficasEvent.EVENT_TYPES.DESTROY : "_processEficasDestroyEvent",
465 EficasEvent.EVENT_TYPES.OPEN : "_processEficasOpenEvent",
466 EficasEvent.EVENT_TYPES.REOPEN : "_processEficasReOpenEvent"
468 def processEficasEvent(self, eficasWrapper, eficasEvent):
470 Implementation of the interface EficasObserver. The implementation is a
471 switch on the possible types of events defined in EficasEvent.EVENT_TYPES.
474 functionName = self.__processOptions.get(eficasEvent.eventType, lambda : "_processEficasUnknownEvent")
475 return getattr(self,functionName)(eficasWrapper, eficasEvent)
477 def _processEficasCloseEvent(self, eficasWrapper, eficasEvent):
480 def _processEficasNewEvent(self, eficasWrapper, eficasEvent):
483 new_case = AdaoCase()
484 case_name = eficasWrapper.getCaseName()
485 new_case.set_name(case_name)
486 salomeStudyId = adaoGuiHelper.getActiveStudyId()
487 salomeStudyItem = adaoStudyEditor.addInStudy(salomeStudyId, new_case)
488 case_key = (salomeStudyId, salomeStudyItem.GetID())
489 __cases__[case_key] = new_case
490 adaoGuiHelper.refreshObjectBrowser()
491 callbackId = [salomeStudyId, salomeStudyItem]
492 self.__dlgEficasWrapper.setCallbackId(callbackId)
494 # We need to select the case
495 adaoGuiHelper.selectItem(salomeStudyItem.GetID())
498 def _processEficasOpenEvent(self, eficasWrapper, eficasEvent):
501 # Ouverture du fichier
502 self.__dlgEficasWrapper.Openfile(self.__dlgEficasWrapper.getOpenFileName())
504 # Creation d'un nouveau cas
505 new_case = AdaoCase()
506 salomeStudyId = adaoGuiHelper.getActiveStudyId()
507 salomeStudyItem = adaoStudyEditor.addInStudy(salomeStudyId, new_case)
508 case_key = (salomeStudyId, salomeStudyItem.GetID())
509 __cases__[case_key] = new_case
511 # Connexion du nouveau cas
512 callbackId = [salomeStudyId, salomeStudyItem]
513 self.__dlgEficasWrapper.setCallbackId(callbackId)
515 # On sauvegarde le cas
516 self._processEficasSaveEvent(self.__dlgEficasWrapper, None, callbackId)
518 def _processEficasSaveEvent(self, eficasWrapper, eficasEvent, callbackId=None):
520 if callbackId is None:
521 callbackId = eficasEvent.callbackId
522 if callbackId is None:
523 raise DevelException("the callback data should not be None. Can't guess what are the study and case")
524 [targetSalomeStudyId,targetSalomeStudyItem] = callbackId
525 if ( targetSalomeStudyId is None ) or ( targetSalomeStudyItem is None ):
526 raise DevelException("the parameters targetSalomeStudyId and targetSalomeStudyItem should not be None")
528 [targetSalomeStudyId,targetSalomeStudyItem] = callbackId
530 # Get Editor All infos we need !
531 case_name = eficasWrapper.getCaseName()
532 file_case_name = eficasWrapper.getFileCaseName()
535 old_case_key = (targetSalomeStudyId, targetSalomeStudyItem.GetID())
536 case =__cases__[old_case_key]
538 # Set new informations
539 case.set_name(case_name)
540 if str(case_name).startswith("Untitled"):
543 case.set_filename(file_case_name)
544 adaoStudyEditor.updateItem(targetSalomeStudyId, targetSalomeStudyItem, case)
547 #new_case_key = (targetSalomeStudyId, targetSalomeStudyItem.GetID())
548 # A ne pas inverser !!!
549 #__cases__.pop(old_case_key)
550 #__cases__[new_case_key] = case
552 adaoGuiHelper.refreshObjectBrowser()
554 def _processEficasDestroyEvent(self, eficasWrapper, eficasEvent):
556 callbackId = eficasEvent.callbackId
557 if callbackId is None:
558 raise DevelException("the callback data should not be None. Can't guess what are the study and case")
559 [targetSalomeStudyId,targetSalomeStudyItem] = callbackId
560 if ( targetSalomeStudyId is None ) or ( targetSalomeStudyItem is None ):
561 raise DevelException("the parameters targetSalomeStudyId and targetSalomeStudyItem should not be None")
563 case_key = (targetSalomeStudyId, targetSalomeStudyItem.GetID())
564 __cases__.pop(case_key)
565 adaoStudyEditor.removeItem(targetSalomeStudyId, targetSalomeStudyItem)
566 adaoGuiHelper.refreshObjectBrowser()
569 # Normalement on ne ferme plus le GUI donc on ne passe plus par là
570 def _processEficasReOpenEvent(self, eficasWrapper, eficasEvent):
572 adaoLogger.warning("_processEficasReOpenEvent")
576 callbackId = eficasEvent.callbackId
577 [salomeStudyId, salomeStudyItem] = callbackId
578 case_key = (salomeStudyId, salomeStudyItem.GetID())
579 case = __cases__[case_key]
580 # Search if case is in Eficas !
581 callbackId = [salomeStudyId, salomeStudyItem]
582 case_open_in_eficas = self.__dlgEficasWrapper.selectCase(callbackId)
583 # If case is not in eficas Open It !
584 if case_open_in_eficas == False:
585 if case.get_filename() != "":
586 self.__dlgEficasWrapper.Openfile(case.get_filename())
587 callbackId = [salomeStudyId, salomeStudyItem]
588 self.__dlgEficasWrapper.setCallbackId(callbackId)
590 # Since I am an empty case I destroy myself before reloading
591 adaoStudyEditor.removeItem(salomeStudyId, salomeStudyItem)
592 adaoGuiHelper.refreshObjectBrowser()
593 __cases__.pop(case_key)
594 callbackId = [salomeStudyId, salomeStudyItem]
595 self.__dlgEficasWrapper.removeCallbackId(callbackId)
597 print "Oups - cannot reopen case !"
598 traceback.print_exc()
600 def _processEficasUnknownEvent(self, eficasWrapper, eficasEvent):
601 print "Unknown Eficas Event"