#
__version__="$Name: $"
-__Id__="$Id: treewidget.py,v 1.6 2002/09/09 10:39:06 eficas Exp $"
+__Id__="$Id: treewidget.py,v 1.11 2003/03/07 16:17:12 eficas Exp $"
#
Fonte_Standard = fontes.standard
class Tree :
- def __init__(self,appli,jdc_item,scrolledcanvas,command = None):
+ def __init__(self,appli,jdc_item,scrolledcanvas,command = None,rmenu=None):
self.item = jdc_item
self.scrolledcanvas = scrolledcanvas
self.canvas = self.scrolledcanvas.component('canvas')
self.canvas.bind("<Key-Next>", self.page_down)
self.canvas.bind("<Key-Up>", self.unit_up)
self.canvas.bind("<Key-Down>", self.unit_down)
+ self.canvas.bind("<1>", self.canvas_select)
self.tree = self
self.command = command
+ self.rmenu=rmenu
self.appli = appli
self.parent = None
self.racine = self
self.node_selected = None
self.build_children()
+ def canvas_select(self,event):
+ self.canvas.focus_set()
+
def page_up(self,event):
event.widget.yview_scroll(-1, "page")
def page_down(self,event):
def build_children(self):
""" Construit la liste des enfants de self """
self.children = []
- child = Node(self,self.item,self.command)
+ child = Node(self,self.item,self.command,self.rmenu)
self.children.append(child)
child.state='expanded'
for child in self.children:
child.draw(x,lasty)
lasty = child.lasty + 15
- child.trace_ligne()
- #self.update()
self.children[0].select()
self.resizescrollregion()
- def deselectall_old(self):
- """ déselectionne tous les éléments de l'arbre """
- for child in self.children:
- child.deselect()
-
def deselectall(self):
""" déselectionne tous les éléments de l'arbre """
if self.node_selected :
for child in self.children:
child.update()
+ def update_valid(self) :
+ """Cette methode a pour but de mettre a jour la validite du noeud
+ et de propager la demande de mise à jour à son parent
+ """
+ pass
+
def resizescrollregion(self):
- self.scrolledcanvas.resizescrollregion()
+ x0,y0,x1,y1=self.canvas.bbox(ALL)
+ # On ajoute une marge approximativement de la moitié du canvas
+ y1=y1+self.canvas.winfo_height()/2
+ self.canvas.configure(scrollregion = (x0,y0,x1,y1))
def select_next(self,event):
self.node_selected.select_next()
def verif_all(self):
for child in self.children :
self.verif_all_children()
+
+ def see(self,items):
+ x1, y1, x2, y2=apply(self.canvas.bbox, items)
+ while x2 > self.canvas.canvasx(0)+self.canvas.winfo_width():
+ old=self.canvas.canvasx(0)
+ self.canvas.xview_scroll( 1, 'units')
+ # avoid endless loop if we can't scroll
+ if old == self.canvas.canvasx(0):
+ break
+ while y2 > self.canvas.canvasy(0)+self.canvas.winfo_height():
+ old=self.canvas.canvasy(0)
+ self.canvas.yview_scroll( 1, 'units')
+ if old == self.canvas.canvasy(0):
+ break
+ # done in this order to ensure upper-left of object is visible
+ while x1 < self.canvas.canvasx(0):
+ old=self.canvas.canvasx(0)
+ self.canvas.xview_scroll( -1, 'units')
+ if old == self.canvas.canvasx(0):
+ break
+ while y1 < self.canvas.canvasy(0):
+ old=self.canvas.canvasy(0)
+ self.canvas.yview_scroll( -1, 'units')
+ if old == self.canvas.canvasy(0):
+ break
class Node :
- def __init__(self,parent,item,command=None):
+ def __init__(self,parent,item,command=None,rmenu=None):
self.parent = parent
self.item = item
self.command = command
+ self.rmenu=rmenu
self.tree = self.parent.tree
self.appli = self.parent.appli
self.canvas = self.parent.canvas
self.init()
- #self.build_children()
def init(self):
self.state='collapsed'
sublist = self.item._GetSubList()
if not sublist : return
for item in sublist :
- child = Node(self,item,self.command)
+ child = Node(self,item,self.command,self.rmenu)
self.children.append(child)
#-----------------------------------------------
self.tree.node_selected = self
if self.command:apply(self.command,(self,))
self.highlight()
- self.canvas.focus_force()
- #self.make_visible()
-
- def deselect_old(self, event=None):
- """ Déselectionne self """
- self.selected = 0
- if self.displayed == 1:
- self.dehighlight()
- for child in self.children:
- child.deselect()
+ self.make_visible()
def deselect(self, event=None):
""" Déselectionne self """
def make_visible(self):
""" Rend l'objet self visible cad déplace le scroll pour que self soit dans
- la fenêtre de visu"""
- x0,y0,x1,y1 = self.canvas.bbox(ALL)
- self.canvas.yview("moveto",self.y/y1)
+ la fenêtre de visu
+ """
+ lchild=self.last_child()
+ self.tree.see((self.image_id,lchild.image_id))
def select_next(self,ind=0):
""" on doit chercher à sélectionner dans l'ordre:
self.parent.children[index].select()
except:
self.parent.select()
+
+ def popup(self,event=None):
+ """
+ Declenche le traitement associé au clic droit de la souris
+ sur l'icone du Node
+ """
+ if not self.rmenu:return
+ apply(self.rmenu,(self,event))
+
#-----------------------------------------------
# Méthodes de recherche d'informations
#-----------------------------------------------
if image != None :
self.image_id = self.canvas.create_image(self.x+15,self.y,image = image)
self.canvas.tag_bind(self.image_id,"<1>",self.select)
+ self.canvas.tag_bind(self.image_id,"<3>",self.popup)
self.id.append(self.image_id)
else:
self.image_id = None
child.draw(x,y)
nb = child.get_nb_children()
y = y + 20*(nb+1)
+ self.trace_ligne()
def drawtext(self):
""" Affiche les deux zones de texte après l'icône de couleur de l'objet """
self.id.append(self.label_id)
# bindings sur le widget label
self.label.bind("<1>", self.select)
+ self.label.bind("<3>", self.popup)
self.label.bind("<Enter>",self.enter)
self.label.bind("<Leave>",self.leave)
# valeur de cet objet à afficher
nb = self.get_nb_children()
self.state = 'collapsed'
self.collapse_children()
- self.efface()
- try:
- self.move(-20*nb)
- except:
- pass
- self.draw(self.x,self.y)
+ self.redraw(-nb)
self.select()
- self.update()
-
+
def expand(self,event = None):
""" Expanse self et le retrace """
if not self.item.isactif() : return
if not self.children : self.build_children()
self.state = 'expanded'
nb = self.get_nb_children()
- self.move(20*nb)
- self.efface()
- self.draw(self.x,self.y)
+ self.redraw(nb)
self.select()
- self.update()
def redraw(self,nb):
""" Redessine self : nb est le décalage à introduire
# on efface self et on le redessine
self.efface()
self.draw(self.x,self.y)
- self.update()
+ # Il n'est pas nécessaire d'appeler update
+ # il suffit d'updater les coordonnees et de retracer les lignes
+ self.racine.update_coords()
+ self.racine.trace_ligne()
+ self.update_valid()
+ self.tree.resizescrollregion()
def update_coords(self):
""" Permet d'updater les coordonnes de self et de tous ses enfants"""
for child in self.children:
if child.displayed != 0 : child.update_texte()
+ def update_valid(self) :
+ """Cette methode a pour but de mettre a jour la validite du noeud
+ et de propager la demande de mise à jour à son parent
+ """
+ if self.image_id != None :
+ image = self.geticonimage()
+ self.canvas.itemconfig(self.image_id,image=image)
+ self.parent.update_valid()
+
def update(self,event=None) :
""" Classe Node :
Cette méthode est appelée pour demander l update d un noeud
print 'dy=',dy
# on déplace tous les items de dy
self.canvas.move('move',0,dy)
- # il faut réactualiser la zone de scroll
- self.tree.resizescrollregion()
def trace_ligne(self):
""" Dessine les lignes verticales entre frères et entre père et premier fils"""
print child
print child.item.object
- def make_visible_OBSOLETE(self,nb):
- """ Cette méthode a pour but de rendre le noeud self (avec tous ses descendants
- affichés) visible dans le canvas """
- x = self.canvas.canvasx(self.canvas.cget('width'))
- y = self.canvas.canvasy(self.canvas.cget('height'))
- #print 'x,y =',x,y
- x0,y0,x1,y1 = self.canvas.bbox(ALL)
- #print 'x0,y1=',x0,y1
- y_deb = self.y
- nb = self.get_nb_children()
- y_fin = y_deb + 20*nb
- #print 'y_deb,y_fin=',y_deb,y_fin
-
+ def last_child(self):
+ lchild=self
+ if self.state == 'expanded' and self.children:
+ lchild= self.children[-1].last_child()
+ return lchild
+
#------------------------------------------------------------------
# Méthodes de création et destruction de noeuds
# Certaines de ces méthodes peuvent être appelées depuis l'externe
if enfant :
# un fils de même nom existe déjà : on remplace
# un MCFACT (ou une MCList) par une (autre) MCList
- child = Node(self,item,self.command)
+ child = Node(self,item,self.command,self.rmenu)
self.replace_node(enfant,child)
else :
- child = Node(self, item,self.command)
+ child = Node(self, item,self.command,self.rmenu)
if pos is None:
self.children.append(child)
else :
"""
if not self.children : self.build_children()
if pos == None :
- #pos = len(self.children)
if type(fils) == types.InstanceType:
pos = self.item.get_index_child(fils.nom)
else:
if child == 0 :
# on n'a pas pu créer le noeud fils
return 0
- child.displayed = 1
self.state = 'expanded'
+ child.displayed = 1
+ if child.item.isactif():
+ child.state = 'expanded'
+ if not child.children : child.build_children()
if verif == 'oui':
- if not child.children : child.build_children()
test = child.item.isMCList()
if test :
child.children[-1].verif_condition()
nbnew = self.get_nb_children()
self.redraw(nbnew-nbold)
child.select()
- child.expand()
- #child.make_visible()
if retour == 'oui': return child
def delete_node_child(self,child):
child.item.object.mc_liste = objet_copie.mc_liste
except:
traceback.print_exc()
+
#--------------------------------------------------------------
# Méthodes de vérification du contexte et de validité du noeud
#--------------------------------------------------------------