Salome HOME
CCAR: modifications pour :
[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 traceback
29 import Tkinter
30 import Pmw
31
32 # Modules Eficas
33 import panels
34 from treeitemincanvas import TREEITEMINCANVAS
35 from widgets import showinfo,showerror
36
37 class CONFIG:
38    isdeveloppeur='NON'
39
40 class JDCDISPLAY:
41    """
42        Cette classe ajoute à la class TREEITEMINCANVAS l'affichage des infos
43        attachées au noeud sélectionné dans un notebook
44        L'objet item associé au jdc est créé par la classe TREEITEMINCANVAS
45    """
46    def __init__(self,jdc,nom_jdc,appli=None,parent=None):
47       self.jdc=jdc
48       self.nom_jdc=nom_jdc
49       self.fichier=None
50       self.panel_courant=None
51
52       if not appli:
53          class Appli:
54             def __init__(self):
55                self.CONFIGURATION=CONFIG()
56             def affiche_infos(self,message):
57                print message
58                return
59
60             def efface_aide(self,event):
61                return
62
63             def affiche_aide(self,event,aide):
64                print aide
65                return
66
67          appli=Appli()
68       self.appli=appli
69
70       if not parent:
71          parent=Tkinter.Tk()
72          Pmw.initialise(parent)
73       self.parent=parent
74       self.node_selected = None
75       self.modified='n'
76
77       self.pane=Pmw.PanedWidget(self.parent,orient='horizontal')
78       self.pane.add('treebrowser',min=0.4,size=0.5)
79       self.pane.add('selected',min=0.4)
80       self.pane.pack(expand=1,fill='both')
81       self.tree=TREEITEMINCANVAS(jdc,nom_jdc,self.pane.pane('treebrowser'),
82                  self.appli,self.select_node,self.make_rmenu)
83
84    def make_rmenu(self,node,event):
85       if hasattr(node.item,'rmenu_specs'):
86          rmenu = Tkinter.Menu(self.pane.pane('treebrowser'), tearoff=0)
87          #node.select()
88          self.cree_menu(rmenu,node.item.rmenu_specs,node)
89          rmenu.tk_popup(event.x_root,event.y_root)
90
91    def cree_menu(self,menu,itemlist,node):
92       """
93             Ajoute les items du tuple itemlist
94             dans le menu menu
95       """
96       number_item=0
97       radio=None
98       for item in itemlist:
99          number_item=number_item + 1
100          if not item :
101             menu.add_separator()
102          else:
103             label,method=item
104             if type(method) == types.TupleType:
105                  # On a un tuple => on cree une cascade
106                  menu_cascade=Tkinter.Menu(menu)
107                  menu.add_cascade(label=label,menu=menu_cascade)
108                  self.cree_menu(menu_cascade,method,node)
109             elif method[0] == '&':
110                  # On a une chaine avec & en tete => on cree un radiobouton
111                  try:
112                     command=getattr(node.item,method[1:])
113                     menu.add_radiobutton(label=label,command=lambda a=self.appli,c=command,n=node:c(a,n))
114                     if radio == None:radio=number_item
115                  except:pass
116             else:
117                  try:
118                     command=getattr(node.item,method)
119                     menu.add_command(label=label,command=lambda a=self.appli,c=command,n=node:c(a,n))
120                  except:pass
121       # Si au moins un radiobouton existe on invoke le premier
122       if radio:menu.invoke(radio)
123
124    def select_node(self,node):
125       """
126           Cette méthode est appelée à chaque fois qu'un noeud est sélectionné
127           dans l'arbre.
128           Elle permet l'affichage du panneau correspondant au noeud sélectionné
129       """
130       if node is not self.node_selected :
131          self.create_panel(node)
132       self.node_selected = node
133       ## on conserve la trace du noeud sélectionné et de celui d'avant
134       #if self.node_selected :
135           #self.ancien_node = self.node_selected
136           #self.node_selected = node
137       #else:
138           #self.ancien_node = self.node_selected = node
139
140    def create_panel(self,node):
141       """
142          Lance la génération du panneau contextuel de l'objet sélectionné 
143          dans l'arbre
144       """
145       if self.panel_courant:
146           # On detruit le panneau
147           self.panel_courant.destroy()
148           o=self.panel_courant
149           self.panel_courant=None
150           # Mettre à 1 pour verifier les cycles entre objets
151           # pour les panneaux
152           withCyclops=0
153           if withCyclops:
154              from Misc import Cyclops
155              z = Cyclops.CycleFinder()
156              z.register(o)
157              del o
158              z.find_cycles()
159              z.show_stats()
160              z.show_cycles()
161
162       if node is None:
163           self.panel_courant=None
164           return self.panel_courant
165
166       if node.item.isactif():
167           if hasattr(node.item,"panel"):
168               self.panel_courant=node.item.panel(self,self.pane.pane('selected'),node)
169           else:
170               raise Exception("Le noeud sélectionné n'a pas de panel associé")
171       else:
172           self.panel_courant = panels.Panel_Inactif(self,self.pane.pane('selected'),node)
173       return self.panel_courant
174
175    def init_modif(self):
176       """
177           Met l'attribut modified à 'o' : utilisé par Eficas pour savoir 
178           si un JDC doit être sauvegardé avant destruction ou non
179       """
180       self.modified = 'o'
181
182    def stop_modif(self):
183       """
184           Met l'attribut modified à 'n' : utilisé par Eficas pour savoir 
185           si un JDC doit être sauvegardé avant destruction ou non
186       """
187       self.modified = 'n'
188
189    def mainloop(self):
190       self.parent.mainloop()
191
192    def ReplaceObjectNode(self,node,new_object,nom_sd=None):
193       """
194       Cette méthode sert à remplacer l'objet pointé par node par
195       new_object.
196       Si nom_sd : on remplace un OPER et on essaie de renommer la
197       nouvelle sd par nom_sd
198       """
199       child = node.append_brother(new_object,retour='oui')
200       if child == 0:
201           self.appli.affiche_infos("Impossible de remplacer l'objet du noeud courant")
202       else:
203           self.init_modif()
204           node.delete()
205           #if nom_sd:
206               #child.item.nomme_sd(nom_sd)
207           child.select()
208           #child.update()
209
210    def doCut(self):
211       """
212       Stocke dans Eficas.noeud_a_editer le noeud à couper
213       """
214       if not self.node_selected.item.iscopiable():
215           showinfo("Copie impossible",
216                    "Cette version d'EFICAS ne permet que la copie d'objets de type 'Commande' ou mot-clé facteur")
217           return
218       self.edit="couper"
219       self.appli.noeud_a_editer = self.node_selected
220
221    def doCopy(self):
222       """
223       Stocke dans Eficas.noeud_a_editer le noeud à copier
224       """
225       if not self.node_selected.item.iscopiable():
226           showinfo("Copie impossible",
227                    "La copie d'un tel objet n'est pas permise")
228           return
229       self.edit="copier"
230       self.appli.noeud_a_editer = self.node_selected
231
232    def doPaste(self):
233       """
234       Lance la copie de l'objet placé dans self.appli.noeud_a_editer
235       Ne permet que la copie d'objets de type Commande ou MCF
236       """
237       try:
238          child=self.appli.noeud_a_editer.doPaste(self.node_selected)
239       except:
240          traceback.print_exc()
241          showinfo("Action de coller impossible",
242                   "L'action de coller apres un tel objet n'est pas permise")
243          return
244
245       if child == 0:
246           if self.appli.message != '':
247              showerror("Copie refusée",self.appli.message)
248              self.appli.message = ''
249           self.appli.affiche_infos("Copie refusée")
250           return
251
252       # il faut déclarer le JDCDisplay_courant modifié
253       self.init_modif()
254       # suppression éventuelle du noeud sélectionné
255       # si possible on renomme l objet comme le noeud couper
256       if self.edit == "couper":
257          #nom = self.appli.noeud_a_editer.item.object.sd.nom
258          item=self.appli.noeud_a_editer.item
259          self.appli.noeud_a_editer.delete()
260          child.item.update(item)
261          #test,mess = child.item.nomme_sd(nom)
262          child.select()
263       # on rend la copie à nouveau possible en libérant le flag edit
264       self.edit="copier"
265
266    def update(self):
267       """Cette methode est utilisee par le JDC associe pour 
268          signaler des modifications globales du JDC
269       """
270       self.tree.update()
271