]> SALOME platform Git repositories - modules/adao.git/blob - src/daSalome/daGUI/daGuiImpl/adaoGuiManager.py
Salome HOME
ceef4a25e09ece42cc4d8a961bd268c04c9434db
[modules/adao.git] / src / daSalome / daGUI / daGuiImpl / adaoGuiManager.py
1 # -*- coding: utf-8 -*-
2 #  Copyright (C) 2010-2014 EDF R&D
3 #
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.
8 #
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.
13 #
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
17 #
18 #  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 """
22 This file centralizes the definitions and implementations of ui components used
23 in the GUI part of the module.
24 """
25
26 __author__ = "aribes/gboulant"
27
28 import traceback
29 from PyQt4.QtCore import QObject
30 from PyQt4.QtCore import *        # Import from PyQT
31 from PyQt4 import QtGui,QtCore
32 import SalomePyQt
33 sgPyQt = SalomePyQt.SalomePyQt()
34
35 from daUtils.enumerate import Enumerate
36 from daGuiImpl.adaoCase import AdaoCase
37 from daEficasWrapper.adaoEficasWrapper import AdaoEficasWrapper
38
39 from daUtils.adaoEficasEvent import *
40 import adaoGuiHelper
41 import adaoStudyEditor
42 from daUtils import adaoLogger
43
44 __cases__ = {}
45
46 #
47 # ==============================================================================
48 # Classes to manage the building of UI components
49 # ==============================================================================
50 #
51 UI_ELT_IDS = Enumerate([
52         'ADAO_MENU_ID',
53         'NEW_ADAOCASE_ID',
54         'OPEN_ADAOCASE_ID',
55         'SAVE_ADAOCASE_ID',
56         'SAVE_AS_ADAOCASE_ID',
57         'CLOSE_ADAOCASE_ID',
58         'YACS_EXPORT_ID',
59         ],offset=6950)
60
61 ACTIONS_MAP={
62     UI_ELT_IDS.NEW_ADAOCASE_ID:"newAdaoCase",
63     UI_ELT_IDS.OPEN_ADAOCASE_ID:"openAdaoCase",
64     UI_ELT_IDS.SAVE_ADAOCASE_ID:"saveAdaoCase",
65     UI_ELT_IDS.SAVE_AS_ADAOCASE_ID:"saveasAdaoCase",
66     UI_ELT_IDS.CLOSE_ADAOCASE_ID:"closeAdaoCase",
67     UI_ELT_IDS.YACS_EXPORT_ID:"exportCaseToYACS",
68 }
69
70
71 class AdaoCaseManager(EficasObserver):
72   """
73   Cette classe gére les cas ADAO et coordonne les GUI de SALOME (l'étude)
74   et le GUI de l'objet Eficas (héritage du module Eficas)
75   """
76
77   def __init__(self):
78
79     # Création d'un dictionnaire de cas
80     # Key   == ref objet editor eficas (on est sur qu'elle est unique, cas duplication)
81     # Value == objet AdaoCase()
82     self.cases = {}
83
84     # Création des deux managers
85     self.salome_manager = AdaoGuiUiComponentBuilder()
86     self.eficas_manager = AdaoEficasWrapper(parent=SalomePyQt.SalomePyQt().getDesktop())
87
88     # On s'enregistre comme observer pour les évènements venant d'Eficas
89     # Les évènements du salome_manager viennent par le biais de la méthode
90     # processGUIEvent
91     self.eficas_manager.addObserver(self)
92
93     # Création du GUI Eficas
94     self.eficas_manager.init_gui()
95
96     # Création du viewer QT
97     # Scroll Widget (pour les petites résolutions)
98     area = QtGui.QScrollArea(SalomePyQt.SalomePyQt().getDesktop());
99     area.setWidget(self.eficas_manager)
100     area.setWidgetResizable(1)
101     wmType = "ADAO View"
102     self.eficas_viewId = sgPyQt.createView(wmType, area)
103
104     # On interdit que la vue soit fermée
105     # Cela simplifier grandement le code
106     sgPyQt.setViewClosable(self.eficas_viewId, False)
107
108     # On s'abonne au gestionnaire de selection
109     self.selection_manager = sgPyQt.getSelection()
110     QtCore.QObject.connect(self.selection_manager, QtCore.SIGNAL('currentSelectionChanged()'), self.currentSelectionChanged)
111
112 ######
113 #
114 # Gestion de l'activation/désactivation du module
115 #
116 ######
117
118   def activate(self):
119     self.eficas_manager.setEnabled(True)
120     sgPyQt.activateView(self.eficas_viewId)
121     self.harmonizeSelectionFromEficas()
122
123   def deactivate(self):
124     self.eficas_manager.setEnabled(False)
125
126 #######
127 #
128 # Gestion de la sélection entre le GUI d'Eficas
129 # et l'arbre d'étude de SALOME
130 #
131 #######
132
133   # Depuis l'étude SALOME
134   def currentSelectionChanged(self):
135     """
136     Cette méthode permet de changer le tab vu dans eficas
137     selon la sélection de l'utilisateur dans l'étude SALOME
138     """
139     adaoLogger.debug("currentSelectionChanged")
140     salomeStudyItem = adaoGuiHelper.getSelectedItem()
141     if salomeStudyItem is not None:
142       for case_editor, adao_case in self.cases.iteritems():
143         if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
144           self.eficas_manager.selectCase(adao_case.eficas_editor)
145           break
146
147   # Depuis Eficas
148   def _processEficasTabChanged(self, eficasWrapper, eficasEvent):
149     """
150     Gestion de la synchonisation entre le tab courant d'Eficas
151     et la selection dans l'étude SALOME
152     """
153     editor = eficasEvent.callbackId
154     for case_editor, adao_case in self.cases.iteritems():
155       if case_editor is editor:
156         adaoGuiHelper.selectItem(adao_case.salome_study_item.GetID())
157         break
158
159   # On remet la sélection dans SALOME grâce au tab dans Eficas
160   def harmonizeSelectionFromEficas(self):
161     """
162     Cette méthode permet d'harmoniser la sélection dans l'étude
163     grâce au tab courant d'Eficas
164     """
165     if self.cases:
166       # 1: Get current tab index in Eficas
167       editor = self.eficas_manager.getCurrentEditor()
168       # 2: sync with SALOME GUI is a tab is opened
169       if editor:
170         for case_editor, adao_case in self.cases.iteritems():
171           if case_editor is editor:
172             adaoGuiHelper.selectItem(adao_case.salome_study_item.GetID())
173             break
174
175 #######
176 #
177 # Gestion de la création d'un nouveau cas
178 # 1: la fonction newAdaoCase est appelée par le GUI SALOME
179 # 2: la fonction _processEficasNewEvent est appelée par le manager EFICAS
180 #
181 #######
182
183   def newAdaoCase(self):
184     adaoLogger.debug("Création d'un nouveau cas adao")
185     self.eficas_manager.adaofileNew(AdaoCase())
186
187   def _processEficasNewEvent(self, eficasWrapper, eficasEvent):
188     adao_case = eficasEvent.callbackId
189     # Ajout dand l'étude
190     salomeStudyId   = adaoGuiHelper.getActiveStudyId()
191     salomeStudyItem = adaoStudyEditor.addInStudy(salomeStudyId, adao_case)
192     # Affichage correct dans l'étude
193     adaoGuiHelper.refreshObjectBrowser()
194     adaoGuiHelper.selectItem(salomeStudyItem.GetID())
195     # Finalisation des données du cas
196     adao_case.salome_study_id   = salomeStudyId
197     adao_case.salome_study_item = salomeStudyItem
198     # Ajout du cas
199     self.cases[adao_case.eficas_editor] = adao_case
200
201 #######
202 #
203 # Gestion de l'ouverture d'un cas
204 # 1: la fonction openAdaoCase est appelée par le GUI SALOME
205 # 2: la fonction _processEficasOpenEvent est appelée par le manager EFICAS
206 #
207 #######
208
209 # Rq: l'ouverture d'un cas adao est un cas particulier de la création d'un cas adao
210
211   def openAdaoCase(self):
212     adaoLogger.debug("Ouverture d'un cas adao")
213     self.eficas_manager.adaoFileOpen(AdaoCase())
214
215   def _processEficasOpenEvent(self, eficasWrapper, eficasEvent):
216     self._processEficasNewEvent(eficasWrapper, eficasEvent)
217
218 #######
219 #
220 # Gestion de la sauvegarde d'un cas
221 # 1: la fonction saveAdaoCase est appelée par le GUI SALOME
222 # 1 bis: la fonction saveasAdaoCase est appelée par le GUI SALOME
223 # 2: la fonction _processEficasSaveEvent est appelée par le manager EFICAS
224 #
225 #######
226
227   def saveAdaoCase(self):
228     adaoLogger.debug("Sauvegarde du cas s'il y a modification")
229     # A priori, l'utilisateur s'attend à sauvegarder le cas qui est ouvert
230     # dans le GUI d'Eficas
231     self.harmonizeSelectionFromEficas()
232     salomeStudyItem = adaoGuiHelper.getSelectedItem()
233     for case_name, adao_case in self.cases.iteritems():
234       if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
235         self.eficas_manager.adaoFileSave(adao_case)
236         break
237
238   def saveasAdaoCase(self):
239     adaoLogger.debug("Sauvegarde du cas s'il y a modification (version save as)")
240     # A priori, l'utilisateur s'attend à sauvegarder le cas qui est ouvert
241     # dans le GUI d'Eficas
242     self.harmonizeSelectionFromEficas()
243     salomeStudyItem = adaoGuiHelper.getSelectedItem()
244     for case_name, adao_case in self.cases.iteritems():
245       if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
246         self.eficas_manager.adaoFileSaveAs(adao_case)
247         break
248
249   def _processEficasSaveEvent(self, eficasWrapper, eficasEvent):
250     adao_case = eficasEvent.callbackId
251     # On met à jour l'étude
252     adaoStudyEditor.updateItem(adao_case.salome_study_id, adao_case.salome_study_item, adao_case)
253     # Affichage correct dans l'étude
254     adaoGuiHelper.refreshObjectBrowser()
255     adaoGuiHelper.selectItem(adao_case.salome_study_item.GetID())
256     # Ajout du cas
257     self.cases[adao_case.name] = adao_case
258
259 #######
260 #
261 # Gestion de la fermeture d'un cas
262 # 1: la fonction closeAdaoCase est appelée par le GUI SALOME
263 # 2: la fonction _processEficasCloseEvent est appelée par le manager EFICAS
264 #
265 #######
266
267   def closeAdaoCase(self):
268     adaoLogger.debug("Fermeture d'un cas")
269     # A priori, l'utilisateur s'attend à sauvegarder le cas qui est ouvert
270     # dans le GUI d'Eficas
271     self.harmonizeSelectionFromEficas()
272     salomeStudyItem = adaoGuiHelper.getSelectedItem()
273     for case_name, adao_case in self.cases.iteritems():
274       if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
275         self.eficas_manager.adaoFileClose(adao_case)
276         break
277
278   def _processEficasCloseEvent(self, eficasWrapper, eficasEvent):
279     adaoLogger.debug("Destruction d'un cas")
280     editor = eficasEvent.callbackId
281     # Recuperation du cas
282     adao_case = self.cases[editor]
283     # Suppression de l'objet dans l'étude
284     adaoStudyEditor.removeItem(adao_case.salome_study_id, adao_case.salome_study_item)
285     # Suppression du cas
286     self.cases.pop(editor)
287     # Refresh GUI -> appelle currentSelectionChanged()
288     adaoGuiHelper.refreshObjectBrowser()
289
290 #######
291 #
292 # Gestion de la connexion avec YACS
293 # 1: la fonction exportCasToYACS exporte l'étude vers YACS
294 #
295 #######
296   def exportCaseToYACS(self):
297     adaoLogger.debug("Export du cas vers YACS")
298
299     # A priori, l'utilisateur s'attend à exporter le cas qui est ouvert
300     # dans le GUI d'Eficas
301     self.harmonizeSelectionFromEficas()
302     salomeStudyItem = adaoGuiHelper.getSelectedItem()
303     for case_name, adao_case in self.cases.iteritems():
304       if adao_case.salome_study_item.GetID() == salomeStudyItem.GetID():
305         if adao_case.isOk():
306           msg = adao_case.exportCaseToYACS()
307           # If msg is not empty -> error found
308           if msg != "":
309             adaoGuiHelper.gui_warning(SalomePyQt.SalomePyQt().getDesktop(), msg)
310         else:
311           adaoGuiHelper.gui_warning(SalomePyQt.SalomePyQt().getDesktop(), "Cannot export case, case is not valid")
312         break
313
314 #######
315 #
316 # Méthodes secondaires permettant de rediriger les évènements
317 # de SALOME et d'Eficas vers les bonnes méthodes de la classe
318 #
319 #######
320
321   # Gestion des évènements venant du manager Eficas
322   __processOptions={
323       EficasEvent.EVENT_TYPES.CLOSE      : "_processEficasCloseEvent",
324       EficasEvent.EVENT_TYPES.SAVE       : "_processEficasSaveEvent",
325       EficasEvent.EVENT_TYPES.NEW        : "_processEficasNewEvent",
326       EficasEvent.EVENT_TYPES.CLOSE      : "_processEficasCloseEvent",
327       EficasEvent.EVENT_TYPES.OPEN       : "_processEficasOpenEvent",
328       EficasEvent.EVENT_TYPES.TABCHANGED : "_processEficasTabChanged",
329       EficasEvent.EVENT_TYPES.REOPEN     : "_processEficasReOpenEvent"
330       }
331
332   def processEficasEvent(self, eficasWrapper, eficasEvent):
333       """
334       Implementation of the interface EficasObserver. The implementation is a
335       switch on the possible types of events defined in EficasEvent.EVENT_TYPES.
336       @overload
337       """
338       functionName = self.__processOptions.get(eficasEvent.eventType, lambda : "_processEficasUnknownEvent")
339       return getattr(self,functionName)(eficasWrapper, eficasEvent)
340
341   def _processEficasUnknownEvent(self, eficasWrapper, eficasEvent):
342     adaoLogger.error("Unknown Eficas Event")
343
344   # Gestion des évènements venant du GUI de SALOME
345   def processGUIEvent(self, actionId):
346     """
347     Main switch function for ui actions processing
348     """
349     if ACTIONS_MAP.has_key(actionId):
350       try:
351           functionName = ACTIONS_MAP[actionId]
352           getattr(self,functionName)()
353       except:
354           traceback.print_exc()
355     else:
356       adaoLogger.warning("The requested action is not implemented: " + str(actionId))
357
358 class AdaoGuiUiComponentBuilder:
359     """
360     The initialisation of this class creates the graphic components involved
361     in the GUI (menu, menu item, toolbar). A ui component builder should be
362     created for each opened study and associated to its context.
363     """
364     def __init__(self):
365         self.initUiComponents()
366
367     def initUiComponents(self):
368
369         objectTR = QObject()
370
371         # create top-level menu
372         mid = sgPyQt.createMenu( "ADAO", -1, UI_ELT_IDS.ADAO_MENU_ID, sgPyQt.defaultMenuGroup() )
373         # create toolbar
374         tid = sgPyQt.createTool( "ADAO" )
375
376         a = sgPyQt.createAction( UI_ELT_IDS.NEW_ADAOCASE_ID, "New case", "New case", "Create a new ADAO case", "eficas_new.png" )
377         sgPyQt.createMenu(a, mid)
378         sgPyQt.createTool(a, tid)
379         a = sgPyQt.createAction( UI_ELT_IDS.OPEN_ADAOCASE_ID, "Open case", "Open case", "Open an ADAO case", "eficas_open.png" )
380         sgPyQt.createMenu(a, mid)
381         sgPyQt.createTool(a, tid)
382         a = sgPyQt.createAction( UI_ELT_IDS.SAVE_ADAOCASE_ID, "Save case", "Save case", "Save an ADAO case", "eficas_save.png" )
383         sgPyQt.createMenu(a, mid)
384         sgPyQt.createTool(a, tid)
385         a = sgPyQt.createAction( UI_ELT_IDS.SAVE_AS_ADAOCASE_ID, "Save as case", "Save as case", "Save an ADAO case as", "eficas_saveas.png" )
386         sgPyQt.createMenu(a, mid)
387         sgPyQt.createTool(a, tid)
388         a = sgPyQt.createAction( UI_ELT_IDS.CLOSE_ADAOCASE_ID, "Close case", "Close case", "Close an ADAO case", "eficas_close.png" )
389         sgPyQt.createMenu(a, mid)
390         sgPyQt.createTool(a, tid)
391         a = sgPyQt.createAction( UI_ELT_IDS.YACS_EXPORT_ID, "Export to YACS", "Export to YACS", "Generate a YACS graph executing this case", "eficas_yacs.png" )
392         sgPyQt.createMenu(a, mid)
393         sgPyQt.createTool(a, tid)
394
395         # the following action are used in context popup
396         a = sgPyQt.createAction( UI_ELT_IDS.CLOSE_ADAOCASE_ID, "Close case", "Close case", "Close the selected case", "" )
397         a = sgPyQt.createAction( UI_ELT_IDS.YACS_EXPORT_ID, "Export to YACS", "Export to YACS", "Generate a YACS graph executing this case", "" )
398
399     def createPopupMenuOnItem(self,popup,salomeSudyId, item):
400         if adaoStudyEditor.isValidAdaoCaseItem(salomeSudyId, item):
401           popup.addAction( sgPyQt.action( UI_ELT_IDS.CLOSE_ADAOCASE_ID ) )
402           popup.addAction( sgPyQt.action( UI_ELT_IDS.YACS_EXPORT_ID ) )
403         return popup