-#@ MODIF treewidget Editeur DATE 02/07/2001 AUTEUR D6BHHJP J.P.LEFEBVRE
# CONFIGURATION MANAGEMENT OF EDF VERSION
# ======================================================================
-# COPYRIGHT (C) 1991 - 2001 EDF R&D WWW.CODE-ASTER.ORG
-# SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND
-# REDISTRIBUTION OF THIS FILE.
+# COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
+# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
+# (AT YOUR OPTION) ANY LATER VERSION.
+#
+# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
+# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
+# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
# ======================================================================
-import os,sys,string,re,types
+import os,sys,string,re,types,traceback
from Tkinter import *
#
__version__="$Name: $"
-__Id__="$Id: treewidget.py,v 1.1.1.1 2002/03/26 09:08:45 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
def full_creation(self,name,pos=None):
"""
- Interface avec ACCAS : création de l'objet de nom name et
- du noeud associé. Retourne le noeud fils ainsi créé
+ Interface avec ACCAS : création de l'objet de nom name et
+ du noeud associé. Retourne le noeud fils ainsi créé
"""
item = self.item.additem(name,pos)
if item == None or item == 0:
# impossible d'ajouter le noeud de nom : name
return 0
nature = item.get_nature()
- #if nature =="COMMANDE" or nature == "OPERATEUR" or nature == "PROCEDURE":
if nature in ("COMMANDE","OPERATEUR","PROCEDURE","COMMENTAIRE",
"PARAMETRE","COMMANDE_COMMENTARISEE","PARAMETRE_EVAL"):
# on veut ajouter une commande ou un commentaire ou un paramètre
# il ne faut pas rechercher un même objet déjà existant
# à modifier : il faut tester l'attribut 'repetable'
enfant = None
+ elif self.item.object.isMCList():
+ # Dans ce cas on ne fait pas de remplacement. On ne cherche pas un objet de meme nom
+ enfant=None
else :
enfant = self.get_node_fils(item.get_nom())
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()
# on donne la position depuis l'extérieur
# (appel de append_child par append_brother par exemple)
index = pos
+ elif type(pos) == types.InstanceType:
+ # pos est un item. Il faut inserer name apres pos
+ index = self.item.get_index(pos) +1
else :
if type(name) == types.InstanceType:
index = self.item.get_index_child(name.nom)
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):
print 'Erreur dans la destruction de ',self.item.get_nom(),' dans delete'
nbnew = pere.get_nb_children()
pere.redraw(nbnew-nbold)
+ pere.select()
def copynode(self,node,pos) :
""" node est le noeud à copier à la position pos de self ( = parent de node) """
try :
child.item.object.mc_liste = objet_copie.mc_liste
except:
- pass
+ traceback.print_exc()
+
#--------------------------------------------------------------
# Méthodes de vérification du contexte et de validité du noeud
#--------------------------------------------------------------
- def traite_mclist(self):
+ def traite_mclist_OLD(self):
""" Dans le cas d'une MCList il faut vérifier qu'elle n'est pas vide
ou réduite à un seul élément suite à une destruction
"""
# self représente une MCList
+ print "on passe par traite_mclist ",len(self.item)
if len(self.item) == 0 :
# la liste est vide : il faut la supprimer
self.delete()
noeud = self.children[0]
if self.parent.delete_child(self):
self.parent.append_node_child(noeud.item,pos=index,verif='non')
+ else:
+ print "destruction de self impossible !"
#if self.parent.delete_child(self):
# self.parent.copynode(self.children[0],index)
#else :
else :
return
+ def traite_mclist(self):
+ """ Dans le cas d'une MCList il faut vérifier qu'elle n'est pas vide
+ ou réduite à un seul élément suite à une destruction
+ """
+ # self représente une MCList
+ if len(self.item) == 0 :
+ # la liste est vide : il faut la supprimer
+ self.delete()
+ elif len(self.item) == 1:
+ # il ne reste plus qu'un élément dans la liste
+ # il faut supprimer la liste et créer directement l'objet
+ index = self.parent.children.index(self)
+ noeud = self.children[0]
+ noeud.parent = self.parent
+ self.parent.delete_node_child(self)
+ self.parent.item.replace_child(self.item,noeud.item)
+ self.parent.children.insert(index,noeud)
+ else :
+ return
+
def verif_all(self):
self.verif_all_children()