]> SALOME platform Git repositories - tools/eficas.git/blob - Editeur/treewidget.py
Salome HOME
CCAR: Modified Files:
[tools/eficas.git] / Editeur / treewidget.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 import os,sys,string,re,types,traceback
21 from Tkinter import *
22
23
24 import fontes
25 import images
26
27 #
28 __version__="$Name:  $"
29 __Id__="$Id: treewidget.py,v 1.8 2002/10/16 13:27:35 eficas Exp $"
30 #
31
32 Fonte_Standard = fontes.standard
33
34 class Tree :
35     def __init__(self,appli,jdc_item,scrolledcanvas,command = None):
36         self.item = jdc_item
37         self.scrolledcanvas = scrolledcanvas
38         self.canvas = self.scrolledcanvas.component('canvas')
39         self.canvas.bind("<Key-Prior>", self.page_up)
40         self.canvas.bind("<Key-Next>", self.page_down)
41         self.canvas.bind("<Key-Up>", self.unit_up)
42         self.canvas.bind("<Key-Down>", self.unit_down)             
43         self.tree = self
44         self.command = command
45         self.appli = appli
46         self.parent = None
47         self.racine = self
48         self.node_selected = None
49         self.build_children()
50
51     def page_up(self,event):
52         event.widget.yview_scroll(-1, "page")
53     def page_down(self,event):
54         event.widget.yview_scroll(1, "page")
55     def unit_up(self,event):
56         event.widget.yview_scroll(-1, "unit")
57     def unit_down(self,event):
58         event.widget.yview_scroll(1, "unit")              
59
60     def build_children(self):
61         """ Construit la liste des enfants de self """
62         self.children = []
63         child = Node(self,self.item,self.command)
64         self.children.append(child)
65         child.state='expanded'
66
67     def draw(self):
68         """ Dessine l'arbre """
69         lasty = 8
70         x = 5
71         for child in self.children:
72             child.draw(x,lasty)
73             lasty = child.lasty + 15
74         self.children[0].select()
75         self.resizescrollregion()
76
77     def deselectall(self):
78         """ déselectionne tous les éléments de l'arbre """
79         if self.node_selected :
80             self.node_selected.deselect()
81             
82     def update(self):
83         """ Update tous les éléments de l'arbre """
84         for child in self.children:
85             child.update()
86
87     def resizescrollregion(self):
88         self.scrolledcanvas.resizescrollregion()
89
90     def select_next(self,event):
91         self.node_selected.select_next()
92
93     def select_previous(self,event):
94         self.node_selected.select_previous()
95
96     def full_creation(self,name,index):
97         # A changer lorsqu'il y aura plusieurs jdc ouverts en même temps
98         self.children[0].full_creation(name,index)
99
100     def verif_all(self):
101         for child in self.children :
102             self.verif_all_children()
103             
104 class Node :
105     def __init__(self,parent,item,command=None):
106         self.parent = parent
107         self.item = item
108         self.command = command
109         self.tree = self.parent.tree
110         self.appli = self.parent.appli
111         self.canvas = self.parent.canvas
112         self.init()
113         #self.build_children()
114
115     def init(self):
116         self.state='collapsed'
117         self.displayed = 0
118         self.selected = 0
119         self.x = self.y  =None
120         self.lasty = 0
121         self.children = None
122         self.id = []
123         # etape = noeud d'étape auquel appartient self
124         # = self si c'est lui-même
125         if isinstance(self.parent,Tree) :
126             # on est  sur un noeud de JDC
127             self.racine=self
128             self.etape=None
129             self.nature='JDC'
130         elif isinstance(self.parent.parent,Tree) :
131             # on est sur un noeud d'étape
132             self.racine = self.parent
133             self.etape=self
134             self.nature = 'ETAPE'
135         else :
136             # on est sur un noeud de mot-clé
137             self.racine = self.parent.racine
138             self.etape=self.parent.etape
139             self.nature = 'MOTCLE'
140
141     def build_children(self):
142         """ Construit la liste des enfants de self """
143         self.children = []
144         sublist = self.item._GetSubList()
145         if not sublist : return
146         for item in sublist :
147             child = Node(self,item,self.command)
148             self.children.append(child)
149             
150     #-----------------------------------------------
151     # Méthodes de sélection/déselection d'un noeud
152     #-----------------------------------------------
153     
154     def select(self, event=None):
155         """
156         Rend le noeud courant (self) sélectionné et déselectionne
157         tous les autres
158         """
159         if not self.children : self.build_children()
160         self.tree.deselectall()
161         self.selected = 1
162         self.tree.node_selected = self
163         if self.command:apply(self.command,(self,))
164         self.highlight()
165
166     def deselect(self, event=None):
167         """ Déselectionne self """
168         self.selected = 0
169         if self.displayed == 1 : self.dehighlight()
170             
171     def make_visible(self):
172         """ Rend l'objet self visible cad déplace le scroll pour que self soit dans
173         la fenêtre de visu"""
174         x0,y0,x1,y1 = self.canvas.bbox(ALL)
175         self.canvas.yview("moveto",self.y/y1)
176         
177     def select_next(self,ind=0):
178         """ on doit chercher à sélectionner dans l'ordre:
179                 - son premier fils s'il est affiché
180                 - son frère cadet s'il existe
181                 - son oncle (benjamin de son père)
182                 - ... appel récursif ...
183         """
184         if self.state=='expanded' and len(self.children) > ind:
185             self.children[ind].select()
186         else :
187             index = self.parent.children.index(self) + 1
188             if isinstance(self.parent,TREE) :
189                 try:
190                     self.children[ind].select()
191                 except:
192                     self.children[0].select()
193             else :                
194                 self.parent.select_next(index)
195
196     def select_previous(self):
197         """ on doit d'abord sélectionner(dans l'ordre) :
198              - son frère aîné
199              - son père
200         """
201         index = self.parent.children.index(self) + 1
202         try :
203             self.parent.children[index].select()
204         except:
205             self.parent.select()
206     #-----------------------------------------------
207     # Méthodes de recherche d'informations
208     #-----------------------------------------------
209     def geticonimage(self,name=None):
210         """
211         Retourne l'image qui doit être associée à self
212         """
213         if not name :
214             name = self.item.GetIconName()
215         if not name or name == 'aucune' :
216             return None
217         return images.get_image(name)
218
219     def get_nb_children(self):
220         """ Retourne le nombre d'enfants affichés de self """
221         nb = 0
222         if self.state =='collapsed' :  return nb
223         for child in self.children :
224             nb = nb + 1 + child.get_nb_children()
225         return nb
226
227     def get_liste_id(self):
228         """ Retourne la liste de tous les id (filiation comprise) de self """
229         liste = self.id
230         for child in self.children:
231             liste.extend(child.get_liste_id())
232         return liste
233
234     def get_node_fils(self,name) :
235         """ Retourne le fils de self de nom name s'il existe"""
236         for child in self.children:
237             if child.item.get_nom() == name: return child
238         return None
239     #-----------------------------------------------
240     # Méthodes d'affichage d'un noeud
241     #-----------------------------------------------
242     def draw(self,x,y):
243         """ Permet de tracer le noeud self """
244         # le début du noeud est en x,y
245         self.x = x
246         self.y = y
247         self.lasty = y
248         self.displayed = 1
249         self.id=[]
250         # choix de l'icone à afficher : + ou -
251         if self.item.IsExpandable():
252             if self.state == 'expanded':
253                 iconname = "minusnode"
254                 callback = self.collapse
255             else:
256                 iconname = "plusnode"
257                 callback = self.expand
258             image = self.geticonimage(name=iconname)
259             self.icone_id = self.canvas.create_image(self.x, self.y, image=image)
260             self.canvas.tag_bind(self.icone_id, "<1>", callback)
261             self.id.append(self.icone_id)
262         # création de la ligne horizontale
263         self.ligne_id = self.canvas.create_line(self.x,self.y,self.x+10,self.y)
264         self.id.append(self.ligne_id)
265         self.canvas.tag_lower(self.ligne_id)
266         # affichage de l'icone (carre ,rond, ovale ...) de couleur
267         image = self.geticonimage()
268         if image != None :
269             self.image_id = self.canvas.create_image(self.x+15,self.y,image = image)
270             self.canvas.tag_bind(self.image_id,"<1>",self.select)
271             self.id.append(self.image_id)
272         else:
273             self.image_id = None
274         # affichage du texte : nom de l'objet (ETAPE ou MOT-CLE) et sa valeur
275         self.drawtext()
276         if self.state == 'expanded' :
277             if not self.children : self.build_children()
278             if len(self.children) > 0:
279                 self.drawchildren()
280                 self.lasty = self.children[-1].lasty
281    
282     def drawchildren(self):
283         """ Dessine les enfants de self """
284         y = self.y + 20
285         x = self.x + 15
286         for child in self.children:
287             child.draw(x,y)
288             nb = child.get_nb_children()
289             y = y + 20*(nb+1)
290         self.trace_ligne()
291
292     def drawtext(self):
293         """ Affiche les deux zones de texte après l'icône de couleur de l'objet """
294         if self.image_id != None :
295             textx = self.x + 30
296         else:
297             textx = self.x + 15
298         texty = self.y
299         # nom,fonte et couleur de l'objet du noeud à afficher
300         labeltext,fonte,couleur = self.item.GetLabelText()
301         if labeltext    == ''   : labeltext = '   '
302         if fonte        == None : fonte = Fonte_Standard
303         if couleur      == None : couleur = 'black'
304         # création du widget label
305         self.label = Label(self.canvas,
306                            text = labeltext,
307                            fg = couleur,
308                            bg = 'gray95',
309                            font=fonte)
310         self.label_id = self.canvas.create_window(textx,texty,window=self.label,anchor='w')
311         self.id.append(self.label_id)
312         # bindings sur le widget label
313         self.label.bind("<1>", self.select)
314         self.label.bind("<Enter>",self.enter)
315         self.label.bind("<Leave>",self.leave)
316         # valeur de cet objet à afficher
317         x0, y0, x1, y1 = self.canvas.bbox(self.label_id)
318         textx = max(x1, 200) + 10
319         text = self.item.GetText() or " "
320         self.text = Label(self.canvas, text=text,
321                             bd=0, padx=2, pady=2,background='gray95',
322                             font=fonte)
323         if self.selected:
324             self.highlight()
325         else:
326             self.dehighlight()
327         self.text_id = self.canvas.create_window(textx, texty,anchor="w", window=self.text)
328         self.id.append(self.text_id)
329         
330     def highlight(self,event=None):
331         """ Met en surbrillance self"""
332         if hasattr(self,'label'):
333             self.label.configure(fg='white',bg='#00008b')
334             
335     def dehighlight(self,event=None):
336         """ Rétablit l'affichage normal de self"""
337         if hasattr(self,'label'):
338             self.label.configure(fg='black',bg='gray95')
339
340     def enter(self,event=None):
341         """ Met en surbrillance self et affiche le fr de l'objet """
342         self.highlight()
343         fr = self.item.get_fr()
344         self.appli.affiche_infos(fr)
345         
346     def leave(self,event=None):
347         """ Rétablit l'affichage normal de self et efface le fr de l'objet """
348         if not self.selected :
349             self.dehighlight()
350         self.appli.affiche_infos('')
351
352     def collapse_children(self):
353         """ Collapse récursivement tous les descendants de self """
354         if not self.children : return
355         for child in self.children:
356             child.state='collapsed'
357             child.displayed = 0
358             child.collapse_children()
359             
360     def collapse(self,event = None):
361         """ Collapse self et descendants et retrace self """
362         nb = self.get_nb_children()
363         self.state = 'collapsed'
364         self.collapse_children()
365         self.redraw(-nb)
366         self.select()
367    
368     def expand(self,event = None):
369         """ Expanse self et le retrace """
370         if not self.item.isactif() : return
371         if not self.children : self.build_children()
372         self.state = 'expanded'
373         nb = self.get_nb_children()
374         self.redraw(nb)
375         self.select()
376
377     def redraw(self,nb):
378         """ Redessine self :  nb est le décalage à introduire
379             en dessous de self pour le redessiner """
380         # nb = nombre d'items de décalage
381         self.move(20*nb)
382         # on efface self et on le redessine
383         self.efface()
384         self.draw(self.x,self.y)
385         # Il n'est pas nécessaire d'appeler update
386         # il suffit d'updater les coordonnees et de retracer les lignes
387         self.racine.update_coords()
388         self.racine.trace_ligne()
389         
390     def update_coords(self):
391         """ Permet d'updater les coordonnes de self et de tous ses enfants"""
392         if self.displayed == 0 : return
393         if self.image_id != None :
394             coords = self.canvas.coords(self.image_id)
395             self.x = coords[0]-15
396         else:
397             coords = self.canvas.coords(self.label_id)
398             self.x = coords[0]-15
399         self.y = coords[1]
400         if self.state == 'expanded' :
401             for child in self.children:
402                 if child.displayed != 0:
403                     child.update_coords()
404
405     def update_icone(self):
406         """ Met à jour les icônes de tous les noeuds : teste la validité de l'objet
407         Cette méthode est très lente, trop !!"""
408         if self.image_id != None :
409             image = self.geticonimage()
410             self.canvas.itemconfig(self.image_id,image=image)
411         if self.state == 'expanded':
412             for child in self.children:
413                 if child.displayed != 0:
414                     child.update_icone()
415
416     def update_texte(self):
417         """ Met à jour les noms des SD et valeurs des mots-clés """
418         text = self.item.GetText()
419         if text == None : text = ''
420         self.text.configure(text=text)
421         if self.state == 'expanded' :
422             for child in self.children:
423                 if child.displayed != 0 : child.update_texte()
424         
425     def update(self,event=None) :
426         """ Classe Node :
427             Cette méthode est appelée pour demander l update d un noeud 
428              d'un jeu de commandes
429              Cette demande est transmise au noeud racine (le JDC) qui update
430              tout l arbre représentant le jeu de commandes
431              Pendant cette mise à jour, on appelle la méthode isvalid qui
432              fera l update de tous les objets déclarés modifiés lors des
433              actions précédentes
434              La métode isvalid est en général appelée par l intermédiaire de
435              update_icone -> geticonimage -> GetIconName
436         """
437         self.racine.update_coords()
438         self.racine.trace_ligne()
439         self.racine.update_icone()
440         self.racine.update_texte()
441         self.tree.resizescrollregion()
442
443     def efface(self):
444         """ Efface du canvas les id associés à self : cad les siens et ceux
445             de ses enfants """
446         for id in self.id :
447             self.canvas.delete(id)
448         if not self.children : return
449         for child in self.children:
450             child.efface()
451
452     def move(self,dy):
453         """ Déplace de l'incrément dy tous les id en dessous de self """
454         # il faut marquer tous les suivants de self
455         bbox1 = self.canvas.bbox(ALL)
456         self.canvas.dtag(ALL,'move')
457         self.canvas.delete('line')
458         try:
459             self.canvas.addtag_overlapping('move',bbox1[0],self.y +10,bbox1[2],bbox1[3])
460         except:
461             print "Erreur dans move :"
462             print self
463             print self.item
464             print self.item.object
465             print self.item.object.definition.label
466             print 'y=',self.y
467             print 'dy=',dy
468         # on déplace tous les items de dy
469         self.canvas.move('move',0,dy)
470         # il faut réactualiser la zone de scroll
471         self.tree.resizescrollregion()
472
473     def trace_ligne(self):
474         """ Dessine les lignes verticales entre frères et entre père et premier fils"""
475         if self.state=='collapsed' : return
476         #if self.displayed == 0 : return
477         if len(self.children)==0 : return
478         # on est bien dans le cas d'un noeud expansé avec enfants ...
479         # il faut rechercher l'ordonnée du dernier fils de self
480         y_end = self.children[-1].y
481         ligne = self.canvas.create_line(self.x+15,self.y,self.x+15,y_end,tags='line')
482         self.canvas.tag_lower(ligne)
483         for child in self.children :
484             try:
485                 child.trace_ligne()
486             except:
487                 print "Erreur dans trace_ligne :"
488                 print child
489                 print child.item.object
490
491     #------------------------------------------------------------------
492     # Méthodes de création et destruction de noeuds
493     # Certaines de ces méthodes peuvent être appelées depuis l'externe
494     #------------------------------------------------------------------
495     def replace_node(self,node1,node2):
496         """ Remplace le noeud 1 par le noeud 2 dans la liste des enfants de self"""
497         index= self.children.index(node1)
498         self.delete_node_child(node1)
499         self.children.insert(index,node2)
500         
501     def full_creation(self,name,pos=None):
502         """
503             Interface avec ACCAS : création de l'objet de nom name et
504             du noeud associé. Retourne le noeud fils ainsi créé
505         """
506         item = self.item.additem(name,pos)
507         if item == None or item == 0:
508             # impossible d'ajouter le noeud de nom : name
509             return 0
510         nature = item.get_nature()
511         if nature in ("COMMANDE","OPERATEUR","PROCEDURE","COMMENTAIRE",
512                       "PARAMETRE","COMMANDE_COMMENTARISEE","PARAMETRE_EVAL"):
513             # on veut ajouter une commande ou un commentaire ou un paramètre
514             # il ne faut pas rechercher un même objet déjà existant
515             # à modifier : il faut tester l'attribut 'repetable' 
516             enfant = None
517         elif self.item.object.isMCList():
518             # Dans ce cas on ne fait pas de remplacement. On ne cherche pas un objet de meme nom
519             enfant=None
520         else :
521             enfant = self.get_node_fils(item.get_nom())
522         if enfant :
523             # un fils de même nom existe déjà : on remplace
524             # un MCFACT (ou une MCList) par une (autre) MCList
525             child = Node(self,item,self.command)
526             self.replace_node(enfant,child)
527         else :            
528             child = Node(self, item,self.command)
529             if pos is None:
530                 self.children.append(child)
531             else :
532                 self.children.insert(pos,child)
533         return child
534
535     def append_brother(self,name,pos='after',retour='non'):
536         """
537         Permet d'ajouter un frère à self
538         par défaut on l'ajoute après self
539         Méthode externe
540         """
541         # on veut ajouter le frère de nom name directement avant ou après self
542         index = self.parent.children.index(self)
543         if pos == 'before':
544             index = index
545         elif pos == 'after':
546             index = index +1
547         else:
548             print str(pos)," n'est pas un index valide pour append_brother"
549             return
550         return self.parent.append_child(name,pos=index,retour=retour)
551     
552     def append_node_child(self,fils,pos=None,verif='oui'):
553         """
554         Fait appel à la création complète de fils et à la vérification
555         des conditions en fonction du contexte
556         Attention : fils peut être un nom ou déjà un object (cas d'une copie)
557         """
558         if not self.children : self.build_children()
559         if pos == None :
560             if type(fils) == types.InstanceType:
561                 pos = self.item.get_index_child(fils.nom)
562             else:
563                 pos = self.item.get_index_child(fils)
564         child = self.full_creation(fils,pos)
565         if child == 0 :
566             # on n'a pas pu créer le noeud fils
567             return 0
568         self.state = 'expanded'
569         child.displayed = 1
570         if child.item.isactif():
571            child.state = 'expanded'
572         if not child.children : child.build_children()
573         if verif == 'oui':
574             test = child.item.isMCList()
575             if test :
576                 child.children[-1].verif_condition()
577             else :
578                 child.verif_condition()
579             self.verif_condition()
580         return child
581             
582     def append_child(self,name,pos=None,verif='oui',retour='non'):
583         """
584         Permet d'ajouter un fils à self
585         on peut l'ajouter en fin de liste (défaut) ou en début
586         Méthode externe
587         """
588         if pos == 'first':
589             index = 0
590         elif pos == 'last':
591             index = len(self.children)
592         elif pos != None and type(pos) == types.IntType :
593             # on donne la position depuis l'extérieur
594             # (appel de append_child par append_brother par exemple)
595             index = pos
596         elif type(pos) == types.InstanceType:
597             # pos est un item. Il faut inserer name apres pos
598             index = self.item.get_index(pos) +1
599         else :
600             if type(name) == types.InstanceType:
601                 index = self.item.get_index_child(name.nom)
602             else:
603                 index = self.item.get_index_child(name)
604         nbold = self.get_nb_children()
605         self.state='expanded'
606         child = self.append_node_child(name,pos=index)
607         if child == 0 :
608             # on n'a pas pu créer le fils
609             return 0
610         nbnew = self.get_nb_children()
611         self.redraw(nbnew-nbold)
612         child.select()
613         if retour == 'oui': return child
614
615     def delete_node_child(self,child):
616         """ Supprime child des enfants de self et les id associés """
617         child.efface()
618         child.displayed = 0
619         self.children.remove(child)
620         self.canvas.update()
621         
622     def delete_child(self,child):
623         """ 
624             Supprime child des enfants de self, tous les id associés
625             ET l'objet associé 
626         """
627         if self.item.suppitem(child.item):
628             self.delete_node_child(child)
629             return 1
630         else :
631             return 0
632                     
633     def delete(self):
634         """ Méthode externe pour la destruction du noeud ET de l'objet
635             Gère l'update du canvas"""
636         if self.parent.item.isMCList():
637             pere = self.parent.parent
638             nbold = pere.get_nb_children()
639             if self.parent.delete_child(self):
640                 self.parent.traite_mclist()
641             if self.item.get_position() == 'global':
642                 self.etape.verif_all()
643             elif self.item.get_position() == 'global_jdc':
644                 self.racine.verif_all()
645             else:
646                 self.parent.verif_condition()
647             nbnew = pere.get_nb_children()
648         else:
649             pere = self.parent
650             nbold = pere.get_nb_children()
651             if self.parent.delete_child(self):
652                 if self.item.get_position() == 'global':
653                     self.etape.verif_all()
654                 elif self.item.get_position() == 'global_jdc':
655                     self.racine.verif_all()
656                 else:
657                     self.parent.verif_condition()
658             else :
659                 print 'Erreur dans la destruction de ',self.item.get_nom(),' dans delete'
660             nbnew = pere.get_nb_children()
661         pere.redraw(nbnew-nbold)
662         pere.select()
663
664     def copynode(self,node,pos) :
665         """ node est le noeud à copier à la position pos de self ( = parent de node) """
666         objet_copie = node.item.get_copie_objet()
667         child = self.full_creation(node.item,pos)
668         child.displayed = node.displayed
669         #child.image_id = node.image_id
670         #child.label_id = node.label_id
671         if child.item.get_nature() == "MCList":
672             child.item.object[-1].mc_liste = objet_copie.mc_liste
673         else :
674             try :
675                 child.item.object.mc_liste = objet_copie.mc_liste
676             except:
677                 traceback.print_exc()
678     #--------------------------------------------------------------
679     # Méthodes de vérification du contexte et de validité du noeud
680     #--------------------------------------------------------------
681     def traite_mclist_OLD(self):
682         """ Dans le cas d'une MCList il faut vérifier qu'elle n'est pas vide
683             ou réduite à un seul élément suite à une destruction
684         """
685         # self représente une MCList
686         print "on passe par traite_mclist ",len(self.item)
687         if len(self.item) == 0 :
688             # la liste est vide : il faut la supprimer
689             self.delete()
690         elif len(self.item) == 1:
691             # il ne reste plus qu'un élément dans la liste
692             # il faut supprimer la liste et créer directement l'objet
693             index = self.parent.children.index(self)
694             noeud = self.children[0]
695             if self.parent.delete_child(self):
696                 self.parent.append_node_child(noeud.item,pos=index,verif='non')
697             else:
698                 print "destruction de self impossible !"
699             #if self.parent.delete_child(self):
700             #    self.parent.copynode(self.children[0],index)
701             #else :
702             #    print 'erreur dans la destruction de :',self.item.get_nom(),' dans traite_mclist'
703         else :
704             return
705
706     def traite_mclist(self):
707         """ Dans le cas d'une MCList il faut vérifier qu'elle n'est pas vide
708             ou réduite à un seul élément suite à une destruction
709         """
710         # self représente une MCList
711         if len(self.item) == 0 :
712             # la liste est vide : il faut la supprimer
713             self.delete()
714         elif len(self.item) == 1:
715             # il ne reste plus qu'un élément dans la liste
716             # il faut supprimer la liste et créer directement l'objet
717             index = self.parent.children.index(self)
718             noeud = self.children[0]
719             noeud.parent = self.parent
720             self.parent.delete_node_child(self)
721             self.parent.item.replace_child(self.item,noeud.item)
722             self.parent.children.insert(index,noeud)
723         else :
724             return
725             
726     def verif_all(self):
727         self.verif_all_children()
728             
729     def verif_all_children(self):
730         if not self.children : self.build_children()
731         if self.nature != 'JDC' :
732             self.verif()
733         for child in self.children :
734             child.verif_all_children()
735
736     def verif(self) :
737         """ 
738             Lance la vérification des conditions des blocs de self et le cas
739             échéant redessine self 
740         """
741         nbold = self.get_nb_children()
742         test = self.verif_condition()
743         nbnew = self.get_nb_children()
744         if test != 0 :
745             self.redraw(nbnew-nbold)
746
747     def verif_condition(self):
748         """
749         on lance la vérification des conditions de chaque bloc de self
750         on crée ou supprime les noeuds concernés
751         (self est d'un niveau inférieur ou égal à l'ETAPE)
752         """
753         if self.item.object.__class__.__name__ == 'ETAPE_NIVEAU': return 0
754         test = 0
755         l_bloc_arajouter,l_bloc_aenlever = self.verif_condition_bloc()
756         if len(l_bloc_arajouter) > 0:
757             test = 1
758             for mc in l_bloc_arajouter:
759                 self.append_node_child(mc,verif='non')
760         if len(l_bloc_aenlever) > 0:
761             test = 1
762             for mc in l_bloc_aenlever:
763                 mocle = self.get_node_fils(mc)
764                 self.delete_child(mocle)
765         l_mc_presents = self.item.get_liste_mc_presents()
766         l_mc_arajouter= self.verif_condition_regles(l_mc_presents)
767         if len(l_mc_arajouter) > 0:
768             test = 1
769             for mc in l_mc_arajouter:
770                 self.append_node_child(mc,verif='non')
771         if len(l_mc_arajouter)+len(l_bloc_arajouter)+len(l_bloc_aenlever) != 0 :
772             self.verif_condition()
773         return test
774         
775     def verif_condition_bloc(self):
776         return self.item.verif_condition_bloc()
777
778     def verif_condition_regles(self,l_mc_presents):
779         return self.item.verif_condition_regles(l_mc_presents)
780     
781