Salome HOME
CCAR: modifications pour INCLUDE; ajout du viewer d'INCLUDE
[tools/eficas.git] / Editeur / jdcdisplay.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 """
21    Ce module contient la classe JDCDISPLAY qui réalise l'affichage
22    du jeu de commandes sous la forme d'un arbre et de panneaux qui portent
23    les informations attachées au noeud de l'arbre sélectionné
24 """
25 # Modules Python
26 import types
27 import Tkinter
28 import Pmw
29
30 # Modules Eficas
31 import panels
32 from treeitemincanvas import TREEITEMINCANVAS
33 from tkMessageBox import showinfo,showerror
34
35 class CONFIG:
36    isdeveloppeur='NON'
37
38 class JDCDISPLAY:
39    """
40        Cette classe ajoute à la class TREEITEMINCANVAS l'affichage des infos
41        attachées au noeud sélectionné dans un notebook
42        L'objet item associé au jdc est créé par la classe TREEITEMINCANVAS
43    """
44    def __init__(self,jdc,nom_jdc,appli=None,parent=None):
45       self.jdc=jdc
46       self.nom_jdc=nom_jdc
47       self.fichier=None
48       self.panel_courant=None
49
50       if not appli:
51          class Appli:
52             def __init__(self):
53                self.CONFIGURATION=CONFIG()
54             def affiche_infos(self,message):
55                print message
56                return
57
58             def efface_aide(self,event):
59                return
60
61             def affiche_aide(self,event,aide):
62                print aide
63                return
64
65          appli=Appli()
66       self.appli=appli
67
68       if not parent:
69          parent=Tkinter.Tk()
70          Pmw.initialise(parent)
71       self.parent=parent
72       self.node_selected = None
73       self.modified='n'
74
75       self.pane=Pmw.PanedWidget(self.parent,orient='horizontal')
76       self.pane.add('treebrowser',min=0.4,size=0.5)
77       self.pane.add('selected',min=0.4)
78       self.pane.pack(expand=1,fill='both')
79       self.tree=TREEITEMINCANVAS(jdc,nom_jdc,self.pane.pane('treebrowser'),
80                  self.appli,self.select_node,self.make_rmenu)
81
82    def make_rmenu(self,node,event):
83       if hasattr(node.item,'rmenu_specs'):
84          rmenu = Tkinter.Menu(self.pane.pane('treebrowser'), tearoff=0)
85          #node.select()
86          self.cree_menu(rmenu,node.item.rmenu_specs,node)
87          rmenu.tk_popup(event.x_root,event.y_root)
88
89    def cree_menu(self,menu,itemlist,node):
90       """
91             Ajoute les items du tuple itemlist
92             dans le menu menu
93       """
94       number_item=0
95       radio=None
96       for item in itemlist:
97          number_item=number_item + 1
98          if not item :
99             menu.add_separator()
100          else:
101             label,method=item
102             if type(method) == types.TupleType:
103                  # On a un tuple => on cree une cascade
104                  menu_cascade=Tkinter.Menu(menu)
105                  menu.add_cascade(label=label,menu=menu_cascade)
106                  self.cree_menu(menu_cascade,method,node)
107             elif method[0] == '&':
108                  # On a une chaine avec & en tete => on cree un radiobouton
109                  try:
110                     command=getattr(node.item,method[1:])
111                     menu.add_radiobutton(label=label,command=lambda a=self.appli,c=command:c(a))
112                     if radio == None:radio=number_item
113                  except:pass
114             else:
115                  try:
116                     command=getattr(node.item,method)
117                     menu.add_command(label=label,command=lambda a=self.appli,c=command:c(a))
118                  except:pass
119       # Si au moins un radiobouton existe on invoke le premier
120       if radio:menu.invoke(radio)
121
122    def select_node(self,node):
123       """
124           Cette méthode est appelée à chaque fois qu'un noeud est sélectionné
125           dans l'arbre.
126           Elle permet l'affichage du panneau correspondant au noeud sélectionné
127       """
128       if node is not self.node_selected :
129          self.create_panel(node)
130       # on conserve la trace du noeud sélectionné et de celui d'avant
131       if self.node_selected :
132           self.ancien_node = self.node_selected
133           self.node_selected = node
134       else:
135           self.ancien_node = self.node_selected = node
136
137    def create_panel(self,node):
138       """
139          Lance la génération du panneau contextuel de l'objet sélectionné 
140          dans l'arbre
141       """
142       if self.panel_courant:
143           # On detruit le panneau
144           self.panel_courant.destroy()
145           o=self.panel_courant
146           self.panel_courant=None
147           # Mettre à 1 pour verifier les cycles entre objets
148           # pour les panneaux
149           withCyclops=0
150           if withCyclops:
151              from Misc import Cyclops
152              z = Cyclops.CycleFinder()
153              z.register(o)
154              del o
155              z.find_cycles()
156              z.show_stats()
157              z.show_cycles()
158
159
160       if node.item.isactif():
161           if hasattr(node.item,"panel"):
162               self.panel_courant=node.item.panel(self,self.pane.pane('selected'),node)
163           else:
164               raise Exception("Le noeud sélectionné n'a pas de panel associé")
165       else:
166           self.panel_courant = panels.Panel_Inactif(self,self.pane.pane('selected'),node)
167       return self.panel_courant
168
169    def init_modif(self):
170       """
171           Met l'attribut modified à 'o' : utilisé par Eficas pour savoir 
172           si un JDC doit être sauvegardé avant destruction ou non
173       """
174       self.modified = 'o'
175
176    def stop_modif(self):
177       """
178           Met l'attribut modified à 'n' : utilisé par Eficas pour savoir 
179           si un JDC doit être sauvegardé avant destruction ou non
180       """
181       self.modified = 'n'
182
183    def mainloop(self):
184       self.parent.mainloop()
185
186    def ReplaceObjectNode(self,node,new_object,nom_sd=None):
187       """
188       Cette méthode sert à remplacer l'objet pointé par node par
189       new_object.
190       Si nom_sd : on remplace un OPER et on essaie de renommer la
191       nouvelle sd par nom_sd
192       """
193       child = node.append_brother(new_object,retour='oui')
194       if child == 0:
195           self.appli.affiche_infos("Impossible de remplacer l'objet du noeud courant")
196       else:
197           self.init_modif()
198           node.delete()
199           if nom_sd:
200               child.item.nomme_sd(nom_sd)
201           child.update()
202
203    def doCut(self):
204       """
205       Stocke dans Eficas.noeud_a_editer le noeud à couper
206       """
207       if not self.node_selected.item.iscopiable():
208           showinfo("Copie impossible",
209                    "Cette version d'EFICAS ne permet que la copie d'objets de type 'Commande' ou mot-clé facteur")
210           return
211       self.edit="couper"
212       self.appli.noeud_a_editer = self.node_selected
213
214    def doCopy(self):
215       """
216       Stocke dans Eficas.noeud_a_editer le noeud à copier
217       """
218       if not self.node_selected.item.iscopiable():
219           showinfo("Copie impossible",
220                    "La copie d'un tel objet n'est pas permise")
221           return
222       self.edit="copier"
223       self.appli.noeud_a_editer = self.node_selected
224
225    def doPaste(self):
226       """
227       Lance la copie de l'objet placé dans self.appli.noeud_a_editer
228       Ne permet que la copie d'objets de type Commande ou MCF
229       """
230       objet_a_copier = self.appli.noeud_a_editer.item.get_copie_objet()
231       if objet_a_copier.__class__.__name__ in ('ETAPE','PROC_ETAPE','MACRO_ETAPE','FORM_ETAPE'):
232           self.doPaste_Commande(objet_a_copier)
233       elif objet_a_copier.__class__.__name__ == "MCFACT":
234           self.doPaste_MCF(objet_a_copier)
235       else:
236           showinfo("Copie impossible",
237                    "Vous ne pouvez copier que des commandes ou des mots-clés facteurs !")
238           return
239
240    def doPaste_Commande(self,objet_a_copier):
241       """
242           Réalise la copie de l'objet passé en argument qui est nécessairement 
243           une commande
244       """
245       # il faut vérifier que le noeud sélectionné (noeud courant) est bien
246       # une commande ou un JDC sinon la copie est impossible ...
247       if self.node_selected.item.isCommande() :
248           child = self.node_selected.append_brother(objet_a_copier,retour='oui')
249       elif self.node_selected.item.isJdc() :
250           child = self.node_selected.append_child(objet_a_copier,pos='first',
251                                                      retour='oui')
252       else:
253           showinfo("Copie impossible",
254                    "Vous ne pouvez coller la commande copiée à ce niveau de l'arborescence !")
255           self.appli.affiche_infos("Copie refusée")
256           return
257       # il faut déclarer le JDCDisplay_courant modifié
258       self.init_modif()
259       # suppression éventuelle du noeud sélectionné
260       if self.edit == "couper":
261           self.appli.noeud_a_editer.delete()
262       if child == 0:
263           # la copie est impossible
264           if self.appli.message != '':
265               showerror("Copie refusée",self.appli.message)
266               self.appli.message = ''
267           self.appli.affiche_infos("Copie refusée")
268       # on rend la copie à nouveau possible en libérant le flag edit
269       self.edit="copier"
270
271    def doPaste_MCF(self,objet_a_copier):
272       """
273       Réalise la copie de l'objet passé en argument qui est nécessairement un MCF
274       """
275       if self.node_selected.item.isCommande() :
276           # le noeud courant est une ETAPE
277           child = self.node_selected.append_child(objet_a_copier,retour='oui')
278       elif self.node_selected.item.isMCList() :
279           # le noeud courant est une MCList
280           child = self.node_selected.parent.append_child(objet_a_copier,pos='first',retour='oui')
281       elif self.node_selected.item.isMCFact():
282           # le noeud courant est un MCFACT
283           if self.node_selected.parent.item.isMCList():
284              # le noeud selectionne est un MCFACT dans une MCList
285              child = self.node_selected.parent.append_child(objet_a_copier,
286                                                             pos=self.node_selected.item,
287                                                             retour='oui')
288           else:
289              # le noeud MCFACT selectionne n'est pas dans une MCList
290              child = self.node_selected.parent.append_child(objet_a_copier,retour='oui')
291       else:
292           showinfo("Copie impossible",
293                    "Vous ne pouvez coller le mot-clé facteur copié à ce niveau de l'arborescence !")
294           self.appli.affiche_infos("Copie refusée")
295           return
296       # il faut déclarer le JDCDisplay_courant modifié
297       self.init_modif()
298       # suppression éventuelle du noeud sélectionné
299       if self.edit == "couper":
300           self.appli.noeud_a_editer.delete()
301       if child == 0:
302           if self.appli.message != '':
303               showerror("Copie refusée",self.appli.message)
304               self.appli.message = ''
305           self.appli.affiche_infos("Copie refusée")
306       # on rend la copie à nouveau possible en libérant le flag edit
307       self.edit="copier"
308
309    def update(self):
310       """Cette methode est utilisee par le JDC associe pour 
311          signaler des modifications globales du JDC
312       """
313       self.tree.update()
314