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