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.
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.
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.
20 # ======================================================================
21 import os,sys,string,re,types,traceback
27 from Ihm import CONNECTOR
30 __version__="$Name: V1_14 $"
31 __Id__="$Id: treewidget.py,v 1.1.4.4.4.1 2008-10-10 13:47:11 pnoyret Exp $"
34 Fonte_Standard = fontes.standard
37 def __init__(self,appli,jdc_item,scrolledcanvas,command = None,rmenu=None):
39 self.scrolledcanvas = scrolledcanvas
40 self.canvas = self.scrolledcanvas.component('canvas')
42 resolution= self.canvas.winfo_screenwidth()/(self.canvas.winfo_screenmmwidth()/25.4*72)
43 self.DDY=max(20,resolution*(Fonte_Standard[1]+4))
44 self.id_up=self.canvas.bind("<F11>", self.page_up)
45 self.id_down=self.canvas.bind("<F12>", self.page_down)
46 self.id_um=self.canvas.bind("<Key-Left>", self.mot_up)
47 self.id_dm=self.canvas.bind("<Key-Right>", self.mot_down)
48 self.id_s=self.canvas.bind("<1>", self.canvas_select)
50 self.command = command
55 self.node_selected = None
58 def canvas_select(self,event):
59 self.canvas.focus_set()
61 def page_up(self,event):
62 event.widget.yview_scroll(-1, "page")
64 def page_down(self,event):
65 event.widget.yview_scroll(1, "page")
67 def unit_up(self,event):
68 event.widget.yview_scroll(-1, "unit")
70 def unit_down(self,event):
71 event.widget.yview_scroll(1, "unit")
73 def mot_down(self,event):
74 self.select_next(None)
75 self.canvas.focus_set()
77 def mot_down_force(self):
78 self.select_next(None)
79 self.canvas.focus_set()
81 def mot_up(self,event):
82 self.node_selected.select_mot_previous()
83 self.canvas.focus_set()
85 def mot_up_force(self):
86 self.node_selected.select_mot_prev()
87 self.canvas.focus_set()
89 def deplieReplieNode(self):
90 self.node_selected.deplieReplieNode()
92 def build_children(self):
93 """ Construit la liste des enfants de self """
95 child = self.item.itemNode(self,self.item,self.command,self.rmenu)
96 self.children.append(child)
97 child.state='expanded'
100 """ Dessine l'arbre """
103 for child in self.children:
105 lasty = child.lasty + 15
106 self.children[0].select()
107 self.resizescrollregion()
109 def deselectall(self):
110 """ déselectionne tous les éléments de l'arbre """
111 if self.node_selected :
112 self.node_selected.deselect()
115 """ Update tous les éléments de l'arbre """
116 for child in self.children:
120 """ supprime tous les éléments de l'arbre """
121 #print "supprime",self
122 self.canvas.unbind("<F11>",self.id_up)
123 self.canvas.unbind("<F12>",self.id_down)
124 self.canvas.unbind("<Key-Left>",self.id_um)
125 self.canvas.unbind("<Key-Right>",self.id_dm)
126 self.canvas.unbind("<1>",self.id_s)
129 self.node_selected = None
131 self.scrolledcanvas = None
135 for child in self.children:
139 def update_valid(self) :
140 """Cette methode a pour but de mettre a jour la validite du noeud
141 et de propager la demande de mise à jour à son parent
145 def resizescrollregion(self):
146 x0,y0,x1,y1=self.canvas.bbox(ALL)
147 # On ajoute une marge approximativement de la moitié du canvas
148 y1=y1+self.canvas.winfo_height()/2
149 self.canvas.configure(scrollregion = (x0,y0,x1,y1))
151 def select_next(self,event):
152 self.node_selected.select_next()
153 self.canvas.focus_set()
155 def select_previous(self,event):
156 self.node_selected.select_previous()
159 x1, y1, x2, y2=apply(self.canvas.bbox, items)
160 while x2 > self.canvas.canvasx(0)+self.canvas.winfo_width():
161 old=self.canvas.canvasx(0)
162 self.canvas.xview_scroll( 1, 'units')
163 # avoid endless loop if we can't scroll
164 if old == self.canvas.canvasx(0):
166 while y2 > self.canvas.canvasy(0)+self.canvas.winfo_height():
167 old=self.canvas.canvasy(0)
168 self.canvas.yview_scroll( 1, 'units')
169 if old == self.canvas.canvasy(0):
171 # done in this order to ensure upper-left of object is visible
172 while x1 < self.canvas.canvasx(0):
173 old=self.canvas.canvasx(0)
174 self.canvas.xview_scroll( -1, 'units')
175 if old == self.canvas.canvasx(0):
177 while y1 < self.canvas.canvasy(0):
178 old=self.canvas.canvasy(0)
179 self.canvas.yview_scroll( -1, 'units')
180 if old == self.canvas.canvasy(0):
184 # print "__del__",self
188 def __init__(self,parent,item,command=None,rmenu=None):
192 self.command = command
194 self.tree = self.parent.tree
195 self.appli = self.parent.appli
196 self.canvas = self.parent.canvas
200 self.state='collapsed'
203 self.x = self.y =None
207 if self.parent is self.tree:
210 self.racine = self.parent.racine
213 self.item.connect("add",self.onAdd,())
214 self.item.connect("supp",self.onSupp,())
215 self.item.connect("valid",self.onValid,())
218 # print "__del__",self
220 def force_select(self):
222 # le noeud est selectionné. On force la reconstruction du panel associé
223 if self.command:apply(self.command,(None,))
227 #print "onValid : l'item a changé de validité ",self.item,self.item.object,self.item.object.isvalid()
228 self.update_node_valid()
229 self.update_node_label()
230 self.update_node_texte()
231 if self.selected and self.command:
234 def onAdd(self,objet):
235 #print "onAdd : un objet a été ajouté aux fils de l'item ",self.item.object,objet
237 old_nodes=self.children
239 self.redraw_children(old_nodes)
242 def onSupp(self,objet):
243 #print "onSupp : un objet a été supprimé des fils de l'item ",self.item.object,objet
245 old_nodes=self.children
247 self.redraw_children(old_nodes)
250 def update_nodes(self):
251 #print "update_nodes",self
253 inodes=iter(self.children)
254 sublist=self.item._GetSubList()
261 if old_item in sublist:break
262 #print "item supprime",old_item
264 if item is old_item:break
265 #print "item ajoute",item
266 child = item.itemNode(self,item,self.command,self.rmenu)
267 newnodes.append(child)
269 if old_item is None and item is None:break
271 #print "item conserve",item
272 newnodes.append(node)
274 self.children=newnodes
278 #print "supprime",self
283 if not self.children : return
284 for child in self.children:
288 def redraw_children(self,old_nodes):
289 #print "redraw_children",old_nodes
291 y = self.y + self.tree.DDY
295 inodes=iter(old_nodes)
296 iliste=iter(self.children)
297 # on parcourt la liste des anciens noeuds (node)
298 # et la liste des nouveaux noeuds (new_node) en parallele (iterateurs)
303 #print "ancien noeud",node
304 if node in self.children:break # ancien noeud toujours present
305 #print "noeud supprime",node,node.item.GetLabelText()[0]
306 dy=node.y-node.lasty -self.tree.DDY
307 #print "deplacer noeuds",y,dy
308 node.move_nodes(y,dy)
310 #supp_nodes.append(node)
312 for new_node in iliste:
313 #print "nouveau noeud",new_node
314 if new_node in old_nodes: break # nouveau noeud deja present
315 #print "noeud ajoute",new_node,new_node.item.GetLabelText()[0]
316 y=self.draw_node(new_node,x,y)
318 if node is None and new_node is None : break
320 if node is new_node: # ancien noeud
321 #print "noeud conserve",node
322 node.update_node_label()
323 y=y+node.lasty-node.y +self.tree.DDY
325 self.racine.update_coords()
326 self.canvas.delete('line')
327 self.racine.trace_ligne()
328 self.tree.resizescrollregion()
329 # Mettre à 1 pour verifier les cycles entre objets node
332 #from Misc import Cyclops
333 #z = Cyclops.CycleFinder()
335 #for o in supp_nodes:
343 def tag_move_nodes(self,y):
344 """ Marque pour deplacement tous les noeuds au dela de l'ordonnée y """
345 #print "tag_move_nodes",y
346 self.canvas.dtag(ALL,'move')
347 # on marque tous les ids au dela de y
348 x0, y0, x1, y1 = self.canvas.bbox(ALL)
349 if y > y1: # pas d'objet a deplacer
351 self.canvas.addtag_overlapping('move',x0,y,x1,y1)
353 def move_nodes(self,y,dy):
354 """ Déplace de l'incrément dy les noeuds au dela de l'ordonnée y """
355 #print "move_nodes",y,dy
356 self.tag_move_nodes(y)
357 # on déplace tous les items de dy
358 self.canvas.move('move',0,dy)
360 def draw_node(self,new_node,x,y):
361 """ Dessine le noeud new_node en x,y en deplacant les noeuds existants
363 Retourne la position du premier des noeuds deplaces
365 #print "draw_node",new_node,x,y
366 self.tag_move_nodes(y)
367 #if new_node.item.isactif():
368 #new_node.state = 'expanded'
369 new_node.state = 'expanded'
371 dy=(new_node.get_nb_children()+1)*self.tree.DDY
372 #print "deplacer noeuds",y,dy
373 self.canvas.move('move',0,dy)
374 return new_node.lasty+self.tree.DDY
376 def build_children(self):
377 """ Construit la liste des enfants de self """
379 sublist = self.item._GetSubList()
380 if not sublist : return
381 for item in sublist :
382 child = item.itemNode(self,item,self.command,self.rmenu)
383 self.children.append(child)
385 #-----------------------------------------------
386 # Méthodes de sélection/déselection d'un noeud
387 #-----------------------------------------------
389 def select(self, event=None):
391 Rend le noeud courant (self) sélectionné et déselectionne
395 if not self.children : self.build_children()
396 self.tree.deselectall()
398 self.tree.node_selected = self
399 if self.command:apply(self.command,(self,))
403 def deselect(self, event=None):
404 """ Déselectionne self """
406 if self.displayed == 1 : self.dehighlight()
408 def make_visible(self):
409 """ Rend l'objet self visible cad déplace le scroll pour que self
410 soit dans la fenêtre de visu
412 lchild=self.last_child()
413 self.tree.see((self.image_id,lchild.image_id))
415 def select_next(self,ind=0):
416 """ on doit chercher à sélectionner dans l'ordre:
417 - son premier fils s'il est affiché
418 - son frère cadet s'il existe
419 - son oncle (benjamin de son père)
420 - ... appel récursif ...
422 if self.state=='expanded' and len(self.children) > ind:
423 self.children[ind].select()
425 index = self.parent.children.index(self) + 1
427 if isinstance(self.parent,TREE) :
429 self.children[ind].select()
431 self.children[0].select()
433 if self.parent is self.tree:
436 self.parent.select_next(index)
438 def select_mot_prev(self):
439 index = self.parent.children.index(self) - 1
442 self.parent.children[index].select()
443 if self.parent.children[index].state=="expanded":
444 print len(self.parent.children[index].children)
445 if len(self.parent.children[index].children)!=0 :
446 max=len(self.parent.children[index].children) - 1
447 self.parent.children[index].children[max].select()
449 self.parent.children[index].select()
451 self.parent.children[index].select()
452 elif self.parent is self.tree:
457 if self.parent is self.tree:
460 self.parent.select_previous()
463 def select_mot_previous(self):
464 index = self.parent.children.index(self) - 1
467 self.parent.children[index].select()
468 elif self.parent is self.tree:
473 if self.parent is self.tree:
476 self.parent.select_previous()
478 def select_previous(self):
479 """ on doit d'abord sélectionner(dans l'ordre) :
483 index = self.parent.children.index(self) - 1
485 self.parent.children[index].select()
487 #self.parent.select()
488 if self.parent is self.tree:
491 self.parent.select_previous()
493 def popup(self,event=None):
495 Declenche le traitement associé au clic droit de la souris
498 if not self.rmenu:return
499 apply(self.rmenu,(self,event))
501 #-----------------------------------------------
502 # Méthodes de recherche d'informations
503 #-----------------------------------------------
504 def geticonimage(self,name=None):
506 Retourne l'image qui doit être associée à self
509 name = self.item.GetIconName()
510 if not name or name == 'aucune' :
512 return images.get_image(name)
514 def get_nb_children(self):
515 """ Retourne le nombre d'enfants affichés de self """
517 if self.state =='collapsed' : return nb
518 for child in self.children :
519 nb = nb + 1 + child.get_nb_children()
522 def get_liste_id(self):
523 """ Retourne la liste de tous les id (filiation comprise) de self """
525 for child in self.children:
526 liste.extend(child.get_liste_id())
529 def get_node_fils(self,name) :
530 """ Retourne le fils de self de nom name s'il existe"""
531 for child in self.children:
532 if child.item.get_nom() == name: return child
535 #-----------------------------------------------
536 # Méthodes d'affichage d'un noeud
537 #-----------------------------------------------
539 """ Permet de tracer le noeud self """
540 # le début du noeud est en x,y
546 # choix de l'icone à afficher : + ou -
547 if self.item.IsExpandable():
548 if self.state == 'expanded':
549 iconname = "minusnode"
550 callback = self.collapse
552 iconname = "plusnode"
553 callback = self.expand
554 image = self.geticonimage(name=iconname)
555 self.icone_id = self.canvas.create_image(self.x, self.y, image=image)
556 self.callback_id=self.canvas.tag_bind(self.icone_id, "<1>", callback)
557 self.id.append(self.icone_id)
558 # création de la ligne horizontale
559 self.ligne_id = self.canvas.create_line(self.x,self.y,self.x+10,self.y)
560 self.id.append(self.ligne_id)
561 self.canvas.tag_lower(self.ligne_id)
562 # affichage de l'icone (carre ,rond, ovale ...) de couleur
563 image = self.geticonimage()
565 self.image_id = self.canvas.create_image(self.x+15,self.y,image = image)
566 self.select_id2=self.canvas.tag_bind(self.image_id,"<1>",self.select)
567 self.popup_id2=self.canvas.tag_bind(self.image_id,"<3>",self.popup)
568 self.id.append(self.image_id)
571 # affichage du texte : nom de l'objet (ETAPE ou MOT-CLE) et sa valeur
573 if self.state == 'expanded' :
574 if not self.children : self.build_children()
575 if len(self.children) > 0:
577 self.lasty = self.children[-1].lasty
579 def drawchildren(self):
580 """ Dessine les enfants de self """
581 y = self.y + self.tree.DDY
583 for child in self.children:
585 nb = child.get_nb_children()
586 y = y + self.tree.DDY*(nb+1)
590 """ Affiche les deux zones de texte après l'icône de couleur de l'objet """
591 if self.image_id != None :
596 # nom,fonte et couleur de l'objet du noeud à afficher
597 labeltext,fonte,couleur = self.item.GetLabelText()
598 if labeltext == '' : labeltext = ' '
599 if fonte == None : fonte = Fonte_Standard
600 if couleur == None : couleur = 'black'
601 # création du widget label
602 self.label = Label(self.canvas,
607 self.label_id = self.canvas.create_window(textx,texty,window=self.label,anchor='w')
608 self.id.append(self.label_id)
609 # bindings sur le widget label
610 self.select_id=self.label.bind("<1>", self.select)
611 self.popup_id=self.label.bind("<3>", self.popup)
612 self.enter_id=self.label.bind("<Enter>",self.enter)
613 self.leave_id=self.label.bind("<Leave>",self.leave)
614 # valeur de cet objet à afficher
615 x0, y0, x1, y1 = self.canvas.bbox(self.label_id)
616 textx = max(x1, 200) + 10
617 text = self.item.GetText() or " "
618 self.text = Label(self.canvas, text=text,
619 bd=0, padx=2, pady=2,background='gray95',
625 self.text_id = self.canvas.create_window(textx, texty,anchor="w", window=self.text)
626 self.id.append(self.text_id)
628 def highlight(self,event=None):
629 """ Met en surbrillance self"""
630 if hasattr(self,'label'):
631 self.label.configure(fg='white',bg='#00008b')
632 if hasattr(self.item,'get_nom') and self.appli.salome :
633 if self.item.get_nom() == "AFFE_CARA_ELEM":
634 self.item.rmenu_specs=[("View3D", "visu_3D")]
638 def dehighlight(self,event=None):
639 """ Rétablit l'affichage normal de self"""
640 if hasattr(self,'label'):
641 self.label.configure(fg='black',bg='gray95')
643 def enter(self,event=None):
644 """ Met en surbrillance self et affiche le fr de l'objet """
646 fr = self.item.get_fr()
647 self.appli.affiche_infos(fr)
649 def leave(self,event=None):
650 """ Rétablit l'affichage normal de self et efface le fr de l'objet """
651 if not self.selected :
653 self.appli.affiche_infos('')
655 def collapse_children(self):
656 """ Collapse récursivement tous les descendants de self """
657 if not self.children : return
658 for child in self.children:
659 child.state='collapsed'
660 child.collapse_children()
662 def deplieReplieNode(self):
663 if self.state == 'expanded':
668 def collapse(self,event = None):
669 """ Collapse self et descendants et retrace self """
670 nb = self.get_nb_children()
671 self.state = 'collapsed'
672 self.collapse_children()
676 def expand_node(self,event = None):
677 """ Expanse self et le retrace """
678 if self.state == 'expanded':return
679 #if not self.item.isactif() : return
680 if not self.children : self.build_children()
681 self.state = 'expanded'
682 nb = self.get_nb_children()
685 def expand(self,event = None):
686 """ Expanse self et le retrace """
691 """ Redessine self : nb est le décalage à introduire
692 en dessous de self pour le redessiner """
693 # nb = nombre d'items de décalage
694 self.move(self.tree.DDY*nb)
695 # on efface self et on le redessine
697 self.draw(self.x,self.y)
698 # Il n'est pas nécessaire d'appeler update
699 # il suffit d'updater les coordonnees et de retracer les lignes
700 self.racine.update_coords()
701 self.racine.trace_ligne()
703 self.tree.resizescrollregion()
705 def update_coords(self):
706 """ Permet d'updater les coordonnes de self et de tous ses enfants"""
707 if self.displayed == 0 : return
708 if self.image_id != None :
709 coords = self.canvas.coords(self.image_id)
710 self.x = coords[0]-15
712 coords = self.canvas.coords(self.label_id)
713 self.x = coords[0]-15
716 if self.state == 'expanded' :
717 for child in self.children:
718 if child.displayed != 0:
719 child.update_coords()
720 self.lasty = child.lasty
722 def update_icone(self):
723 """ Met à jour les icônes de tous les noeuds : teste la validité de l'objet
724 Cette méthode est très lente, trop !!"""
725 if self.image_id != None :
726 image = self.geticonimage()
727 self.canvas.itemconfig(self.image_id,image=image)
728 if self.state == 'expanded':
729 for child in self.children:
730 if child.displayed != 0:
733 def update_label_texte(self):
734 """ Met a jour le label du noeud et celui de tous ses fils ouverts """
735 self.update_node_label()
736 if self.state == 'expanded' :
737 for child in self.children:
738 if child.displayed != 0 : child.update_label_texte()
740 def update_texte(self):
741 """ Met à jour les noms des SD et valeurs des mots-clés """
742 self.update_node_texte()
743 if self.state == 'expanded' :
744 for child in self.children:
745 if child.displayed != 0 : child.update_texte()
747 def update_node_label(self):
748 """ Met a jour le label du noeud """
749 if self.displayed == 0 : return
750 # nom,fonte et couleur de l'objet du noeud à afficher
751 labeltext,fonte,couleur = self.item.GetLabelText()
752 if labeltext == '' : labeltext = ' '
753 if fonte == None : fonte = Fonte_Standard
754 if couleur == None : couleur = 'black'
755 if hasattr(self,'label') and self.label:
756 self.label.configure(text=labeltext,font=fonte)
758 def update_node_texte(self):
759 """ Met à jour les noms des SD et valeurs des mots-clés """
760 if self.displayed == 0 : return
761 text = self.item.GetText()
762 if text == None : text = ''
763 if hasattr(self,'text') and self.text:
764 self.text.configure(text=text)
766 def update_node_valid(self) :
767 """Cette methode remet a jour la validite du noeud (icone)
770 if self.displayed == 0 : return
771 if hasattr(self,'image_id'):
772 if self.image_id != None :
773 image = self.geticonimage()
774 self.canvas.itemconfig(self.image_id,image=image)
776 def update_valid(self) :
777 """Cette methode a pour but de mettre a jour la validite du noeud
778 et de propager la demande de mise à jour à son parent
780 self.update_node_valid()
781 self.parent.update_valid()
783 def update(self,event=None) :
785 Cette méthode est appelée pour demander l update d un noeud
786 d'un jeu de commandes
787 Cette demande est transmise au noeud racine (le JDC) qui update
788 tout l arbre représentant le jeu de commandes
789 Pendant cette mise à jour, on appelle la méthode isvalid qui
790 fera l update de tous les objets déclarés modifiés lors des
792 La métode isvalid est en général appelée par l intermédiaire de
793 update_icone -> geticonimage -> GetIconName
796 #traceback.print_stack()
797 self.racine.update_coords()
798 self.racine.trace_ligne()
799 self.racine.update_icone()
800 self.racine.update_texte()
801 self.racine.update_label_texte()
802 self.tree.resizescrollregion()
804 def efface_node(self):
805 if self.displayed != 0:
806 self.label.unbind("<1>", self.select_id)
807 self.label.unbind("<3>", self.popup_id)
808 self.label.unbind("<Enter>",self.enter_id)
809 self.label.unbind("<Leave>",self.leave_id)
810 self.canvas.tag_unbind(self.image_id,"<1>",self.select_id2)
811 self.canvas.tag_unbind(self.image_id,"<3>",self.popup_id2)
812 if self.item.IsExpandable():
813 self.canvas.tag_unbind(self.icone_id, "<1>", self.callback_id)
818 self.canvas.delete(id)
829 """ Efface du canvas les id associés à self : cad les siens et ceux
832 if not self.children : return
833 for child in self.children:
837 """ Déplace de l'incrément dy tous les id en dessous de self """
838 # il faut marquer tous les suivants de self
839 bbox1 = self.canvas.bbox(ALL)
840 self.canvas.dtag(ALL,'move')
841 self.canvas.delete('line')
843 self.canvas.addtag_overlapping('move',bbox1[0],self.y +10,bbox1[2],bbox1[3])
845 print "Erreur dans move :"
848 print self.item.getObject()
849 print self.item.getObject().definition.label
852 # on déplace tous les items de dy
853 self.canvas.move('move',0,dy)
855 def trace_ligne(self):
856 """ Dessine les lignes verticales entre frères et entre père et premier fils"""
857 if self.state=='collapsed' : return
858 if len(self.children)==0 : return
859 # on est bien dans le cas d'un noeud expansé avec enfants ...
860 # il faut rechercher l'ordonnée du dernier fils de self
861 y_end = self.children[-1].y
862 ligne = self.canvas.create_line(self.x+15,self.y,self.x+15,y_end,tags='line')
863 self.canvas.tag_lower(ligne)
864 for child in self.children :
868 print "Erreur dans trace_ligne :"
870 print child.item.getObject()
872 def last_child(self):
874 if self.state == 'expanded' and self.children:
875 lchild= self.children[-1].last_child()
878 #------------------------------------------------------------------
879 # Méthodes de création et destruction de noeuds
880 # Certaines de ces méthodes peuvent être appelées depuis l'externe
881 #------------------------------------------------------------------
882 def append_brother(self,name,pos='after',retour='non'):
884 Permet d'ajouter un objet frère à l'objet associé au noeud self
885 par défaut on l'ajoute immédiatement après
888 # on veut ajouter le frère de nom name directement avant ou après self
889 index = self.parent.children.index(self)
895 print str(pos)," n'est pas un index valide pour append_brother"
897 return self.parent.append_child(name,pos=index)
899 def append_child(self,name,pos=None,verif='oui',retour='non'):
901 Methode pour ajouter un objet fils à l'objet associé au noeud self.
902 On peut l'ajouter en début de liste (pos='first'), en fin (pos='last')
903 ou en position intermédiaire.
904 Si pos vaut None, on le place à la position du catalogue.
906 #print "append_child",self,self.children
910 index = len(self.children)
911 elif type(pos) == types.IntType :
914 elif type(pos) == types.InstanceType:
915 # pos est un item. Il faut inserer name apres pos
916 index = self.item.get_index(pos) +1
917 elif type(name) == types.InstanceType:
918 index = self.item.get_index_child(name.nom)
920 index = self.item.get_index_child(name)
921 obj=self.item.additem(name,index)
925 #print "append_child",index,self.children
926 child=self.children[index]
932 Méthode externe pour la destruction de l'objet associé au noeud
933 La mise à jour des noeuds est faite par onSupp sur notification
935 index = self.parent.children.index(self) - 1
936 if index < 0 : index =0
939 ret=parent.item.suppitem(self.item)
942 brothers=parent.children
944 toselect=brothers[index]