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