From 11935dce38a984f6a5d46223e3e56ff7edbcb871 Mon Sep 17 00:00:00 2001 From: eficas <> Date: Tue, 12 Nov 2002 12:25:02 +0000 Subject: [PATCH] CCAR: modifications pour INCLUDE; ajout du viewer d'INCLUDE --- Editeur/bureau.py | 5 +- Editeur/compomacro.py | 72 +++++++----------- Editeur/jdcdisplay.py | 43 ++++++++++- Editeur/macrodisplay.py | 146 ++++++++++++++++++++++++++++++++++++ Editeur/patches.py | 20 +++++ Editeur/tooltip.py | 12 +-- Editeur/treeitemincanvas.py | 4 +- Editeur/treewidget.py | 80 ++++++++++++++++---- Editeur/widgets.py | 6 +- 9 files changed, 313 insertions(+), 75 deletions(-) create mode 100644 Editeur/macrodisplay.py diff --git a/Editeur/bureau.py b/Editeur/bureau.py index ecce22bc..eb326992 100644 --- a/Editeur/bureau.py +++ b/Editeur/bureau.py @@ -296,8 +296,9 @@ class BUREAU: # si le JDC ne contient rien (vide), on retourne ici if len(self.JDC.etapes) == 0 : return # dans le cas où le JDC est invalide, on affiche son CR - cr = self.JDC.report() - if not cr.estvide() : + if not self.JDC.isvalid(): + #cr = self.JDC.report() + #if not cr.estvide() : self.appli.top.update() self.visuCR(mode='JDC') diff --git a/Editeur/compomacro.py b/Editeur/compomacro.py index 6d8e0f45..5fa7236c 100644 --- a/Editeur/compomacro.py +++ b/Editeur/compomacro.py @@ -36,7 +36,7 @@ from widgets import Fenetre,FenetreYesNo # __version__="$Name: $" -__Id__="$Id: compomacro.py,v 1.5 2002/09/09 10:39:06 eficas Exp $" +__Id__="$Id: compomacro.py,v 1.6 2002/11/06 17:25:56 eficas Exp $" # class MACROPanel(panels.OngletPanel): @@ -68,22 +68,10 @@ class MACROPanel(panels.OngletPanel): self.makeParamCommentPage_for_etape(nb.page("Commentaire")) nb.tab('Mocles').focus_set() nb.setnaturalsize() - #self.monmenu=Tkinter.Menu(self.parent.appli.menubar,tearoff=0) - #self.monmenu.add_command(label='Build',command=self.Build) - #self.monmenu.add_command(label='View',command=self.View) - #self.parent.appli.add_menu(label="Macro",menu=self.monmenu) self.affiche() - def Build(self): - print "Build" - self.node.item.object.Build() - - def View(self): - print "View" - MacroDisplay(self.parent.appli,self.node.item.object,self.node.item.object.nom) - def makeFichierPage(self,page): - """ + """ Affiche la page d'onglet correspondant au changement du fichier dont a besoin la macro """ @@ -132,11 +120,13 @@ class MACROPanel(panels.OngletPanel): self.node.item.object.fichier_text=None self.node.item.object.fichier_err="Le fichier n'est pas defini" self.node.item.object.contexte_fichier_init={} + self.node.item.object.recorded_units={} old_fic = self.node.item.object.fichier_ini old_text = self.node.item.object.fichier_text old_err = self.node.item.object.fichier_err old_context=self.node.item.object.contexte_fichier_init + old_units=self.node.item.object.recorded_units new_fic = self.entry.get() if not os.path.isfile(new_fic) : @@ -149,6 +139,7 @@ class MACROPanel(panels.OngletPanel): # Si probleme a la lecture-conversion on arrete le traitement if not text: return + self.node.item.object.recorded_units={} try: self.node.item.object.make_contexte_include(new_fic,text) @@ -157,7 +148,8 @@ class MACROPanel(panels.OngletPanel): self.parent.appli.affiche_infos("Fichier invalide") l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1]) f=FenetreYesNo(self.parent.appli,titre="Fichier invalide : voulez vous retablir l ancien fichier ?", - texte="Erreur dans l'interprétation du nouveau fichier ...\n\n"+string.join(l)) + texte="Erreur dans l'interprétation du nouveau fichier ...\n\n"+string.join(l), + yes="Retablir",no="Changer") f.wait() reponse=f.result if reponse: @@ -167,18 +159,21 @@ class MACROPanel(panels.OngletPanel): self.node.item.object.fichier_text=old_text self.node.item.object.fichier_err=old_err self.node.item.object.contexte_fichier_init=old_context + self.node.item.object.recorded_units=old_units self.parent.appli.affiche_infos("Fichier invalide ... Ancien fichier restauré") if old_fic: self.entry.insert(0,self.node.item.object.fichier_ini) else: # On conserve la memoire du nouveau fichier - # mais on n'utilise pas les etapes et concepts crees par ce fichier + # mais on n'utilise pas les concepts crees par ce fichier # on met l'etape en erreur : fichier_err=string.join(l) self.node.item.object.init_modif() self.node.item.object.fichier_ini=new_fic self.node.item.object.fichier_text=text self.node.item.object.fichier_err=string.join(l) - self.node.item.object.etapes=[] + # On enregistre la modification de fichier + self.node.item.object.record_unite() + #self.node.item.object.etapes=[] self.node.item.object.g_context={} # Le contexte du parent doit etre reinitialise car les concepts produits ont changé self.node.item.object.parent.reset_context() @@ -198,6 +193,8 @@ class MACROPanel(panels.OngletPanel): self.node.item.object.fichier_ini = new_fic self.node.item.object.fichier_text=text self.node.item.object.fichier_err=None + # On enregistre la modification de fichier + self.node.item.object.record_unite() # Le contexte du parent doit etre reinitialise car les concepts produits ont changé self.node.item.object.parent.reset_context() @@ -328,42 +325,29 @@ class MACROTreeItem(compooper.EtapeTreeItem): def get_noms_sd_oper_reentrant(self): return self.object.get_noms_sd_oper_reentrant() -class INCLUDE_MATERIAUTreeItem(MACROTreeItem): - pass +class INCLUDETreeItem(MACROTreeItem): + rmenu_specs=[("View","makeView")] + + def makeView(self,appli): + nom=self.object.nom + if hasattr(self.object,'fichier_ini'):nom=nom+' '+self.object.fichier_ini + macrodisplay.makeMacroDisplay(appli,self.object,nom) + +class INCLUDE_MATERIAUTreeItem(INCLUDETreeItem): pass +class POURSUITETreeItem(INCLUDETreeItem): pass treeitem=MACROTreeItem def treeitem(appli, labeltext, object, setfunction=None): if object.nom == "INCLUDE_MATERIAU": return INCLUDE_MATERIAUTreeItem(appli, labeltext, object, setfunction) elif object.nom == "INCLUDE": - return MACROTreeItem(appli, labeltext, object, setfunction) + return INCLUDETreeItem(appli, labeltext, object, setfunction) + elif object.nom == "POURSUITE": + return POURSUITETreeItem(appli, labeltext, object, setfunction) else: return MACROTreeItem(appli, labeltext, object, setfunction) import Accas objet=Accas.MACRO_ETAPE -class MacroDisplay: - def __init__(self,appli,jdc,nom_jdc): - self.fenetre = Tkinter.Toplevel() - self.fenetre.configure(width = 800,height=500) - self.fenetre.protocol("WM_DELETE_WINDOW", self.quit) - self.fenetre.title("Visualisation Macro_Etape") - self.jdc=jdc - self.nom_jdc=nom_jdc - self.appli=appli - self.mainPart=Pmw.ScrolledCanvas(self.fenetre, - hull_width=600, - hull_height=500, - borderframe=1) - self.canvas=self.mainPart.component('canvas') - Pmw.Color.changecolor(self.canvas,background='gray95') - self.mainPart.pack(padx=10,pady=10,fill = 'both', expand = 1) - self.item=MACRO2TreeItem(self.appli,nom_jdc,jdc) - import treewidget - self.tree = treewidget.Tree(self.appli,self.item,self.mainPart,command=None) - self.tree.draw() - - def quit(self): - self.fenetre.destroy() - +import macrodisplay diff --git a/Editeur/jdcdisplay.py b/Editeur/jdcdisplay.py index 820d7bac..53303962 100644 --- a/Editeur/jdcdisplay.py +++ b/Editeur/jdcdisplay.py @@ -23,6 +23,7 @@ les informations attachées au noeud de l'arbre sélectionné """ # Modules Python +import types import Tkinter import Pmw @@ -76,7 +77,47 @@ class JDCDISPLAY: self.pane.add('selected',min=0.4) self.pane.pack(expand=1,fill='both') self.tree=TREEITEMINCANVAS(jdc,nom_jdc,self.pane.pane('treebrowser'), - self.appli,self.select_node) + self.appli,self.select_node,self.make_rmenu) + + def make_rmenu(self,node,event): + if hasattr(node.item,'rmenu_specs'): + rmenu = Tkinter.Menu(self.pane.pane('treebrowser'), tearoff=0) + #node.select() + self.cree_menu(rmenu,node.item.rmenu_specs,node) + rmenu.tk_popup(event.x_root,event.y_root) + + def cree_menu(self,menu,itemlist,node): + """ + Ajoute les items du tuple itemlist + dans le menu menu + """ + number_item=0 + radio=None + for item in itemlist: + number_item=number_item + 1 + if not item : + menu.add_separator() + else: + label,method=item + if type(method) == types.TupleType: + # On a un tuple => on cree une cascade + menu_cascade=Tkinter.Menu(menu) + menu.add_cascade(label=label,menu=menu_cascade) + self.cree_menu(menu_cascade,method,node) + elif method[0] == '&': + # On a une chaine avec & en tete => on cree un radiobouton + try: + command=getattr(node.item,method[1:]) + menu.add_radiobutton(label=label,command=lambda a=self.appli,c=command:c(a)) + if radio == None:radio=number_item + except:pass + else: + try: + command=getattr(node.item,method) + menu.add_command(label=label,command=lambda a=self.appli,c=command:c(a)) + except:pass + # Si au moins un radiobouton existe on invoke le premier + if radio:menu.invoke(radio) def select_node(self,node): """ diff --git a/Editeur/macrodisplay.py b/Editeur/macrodisplay.py new file mode 100644 index 00000000..069a05d1 --- /dev/null +++ b/Editeur/macrodisplay.py @@ -0,0 +1,146 @@ +# CONFIGURATION MANAGEMENT OF EDF VERSION +# ====================================================================== +# 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. +# +# +# ====================================================================== +""" + Ce module contient la classe MacroDisplay qui realise l'affichage + des sous commandes d'une macro sous forme d'arbre +""" +# Modules Python +import types +import Tkinter,Pmw + +# Modules EFICAS +import images +import tooltip +import Objecttreeitem +from widgets import Fenetre + +class MACRO2TreeItem(Objecttreeitem.ObjectTreeItem): + def IsExpandable(self): + return 1 + + def GetText(self): + return " " + + def GetIconName(self): + if self.object.isvalid(): + return "ast-green-square" + else: + return "ast-red-square" + + def keys(self): + return range(len(self.object.etapes)) + + def GetSubList(self): + sublist=[] + for key in self.keys(): + liste = self.object.etapes + try: + value = liste[key] + except KeyError: + continue + def setfunction(value, key=key, object=liste): + object[key] = value + item = self.make_objecttreeitem(self.appli,value.ident() + " : ", value, setfunction) + sublist.append(item) + return sublist + + def verif_condition_bloc(self): + # retourne la liste des sous-items dont la condition est valide + # sans objet pour le JDC + return [],[] + + def get_l_noms_etapes(self): + """ Retourne la liste des noms des étapes de self.object""" + return self.object.get_l_noms_etapes() + +class MacroDisplay: + def __init__(self,appli,jdc,nom_jdc): + self.fenetre = Tkinter.Toplevel() + self.fenetre.configure(width = 800,height=500) + self.fenetre.protocol("WM_DELETE_WINDOW", self.quit) + self.fenetre.title("Visualisation Macro_Etape") + self.jdc=jdc + self.nom_jdc=nom_jdc + self.appli=appli + self.barre=Tkinter.Frame(self.fenetre,relief="ridge",bd=2) + self.barre.pack(expand=1,fill=Tkinter.X) + b=Tkinter.Button(self.barre,image=images.get_image("Zoom24"),command=self.visufile) + b.pack(side='left') + tp=tooltip.TOOLTIP(b,"View file") + self.mainPart=Pmw.ScrolledCanvas(self.fenetre, + hull_width=600, + hull_height=500, + borderframe=1) + self.canvas=self.mainPart.component('canvas') + Pmw.Color.changecolor(self.canvas,background='gray95') + self.mainPart.pack(padx=10,pady=10,fill = 'both', expand = 1) + self.item=MACRO2TreeItem(self.appli,nom_jdc,jdc) + import treewidget + self.tree = treewidget.Tree(self.appli,self.item,self.mainPart,command=None,rmenu=self.make_rmenu) + self.tree.draw() + + def visufile(self): + Fenetre(self.appli,titre="Source du fichier inclus",texte=self.jdc.fichier_text) + + def make_rmenu(self,node,event): + if hasattr(node.item,'rmenu_specs'): + rmenu = Tkinter.Menu(self.canvas, tearoff=0) + self.cree_menu(rmenu,node.item.rmenu_specs,node) + rmenu.tk_popup(event.x_root,event.y_root) + + def cree_menu(self,menu,itemlist,node): + """ + Ajoute les items du tuple itemlist + dans le menu menu + """ + number_item=0 + radio=None + for item in itemlist: + number_item=number_item + 1 + if not item : + menu.add_separator() + else: + label,method=item + if type(method) == types.TupleType: + # On a un tuple => on cree une cascade + menu_cascade=Tkinter.Menu(menu) + menu.add_cascade(label=label,menu=menu_cascade) + self.cree_menu(menu_cascade,method,node) + elif method[0] == '&': + # On a une chaine avec & en tete => on cree un radiobouton + try: + command=getattr(node.item,method[1:]) + menu.add_radiobutton(label=label,command=lambda a=self.appli,c=command:c(a)) + if radio == None:radio=number_item + except:pass + else: + try: + command=getattr(node.item,method) + menu.add_command(label=label,command=lambda a=self.appli,c=command:c(a)) + except:pass + # Si au moins un radiobouton existe on invoke le premier + if radio:menu.invoke(radio) + + def quit(self): + self.fenetre.destroy() + +def makeMacroDisplay(appli,jdc,nom_jdc): + return MacroDisplay(appli,jdc,nom_jdc) + diff --git a/Editeur/patches.py b/Editeur/patches.py index b85f654c..fd674118 100644 --- a/Editeur/patches.py +++ b/Editeur/patches.py @@ -1,3 +1,23 @@ +# CONFIGURATION MANAGEMENT OF EDF VERSION +# ====================================================================== +# 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. +# +# +# ====================================================================== + """ Ce module contient des modifications mineures du comportement du noyau ou de validation diff --git a/Editeur/tooltip.py b/Editeur/tooltip.py index 752a57b7..87bda661 100644 --- a/Editeur/tooltip.py +++ b/Editeur/tooltip.py @@ -47,9 +47,9 @@ def after_cancel(t): pass class TOOLTIP: - def __init__(self,widget): + def __init__(self,widget,text=None): self.widget=widget - self.text = None + self.text = text self.timer = None self.tooltip = None self.label = None @@ -119,14 +119,8 @@ class TOOLTIP: if __name__ == "__main__": root=Tkinter.Tk() - - def aide(event): - tp=TOOLTIP(root) - tp.setText("texte d'aide") - tp._showTip() - label = Tkinter.Label(root, text="coucou") - label.bind("", aide) label.pack() + tp=TOOLTIP(label,"texte d'aide") root.mainloop() diff --git a/Editeur/treeitemincanvas.py b/Editeur/treeitemincanvas.py index a9d5c86e..14ab086e 100644 --- a/Editeur/treeitemincanvas.py +++ b/Editeur/treeitemincanvas.py @@ -27,7 +27,7 @@ import Objecttreeitem import treewidget class TREEITEMINCANVAS: - def __init__(self,object,nom="",parent=None,appli=None,sel=None): + def __init__(self,object,nom="",parent=None,appli=None,sel=None,rmenu=None): self.object=object self.nom=nom @@ -49,7 +49,7 @@ class TREEITEMINCANVAS: if not sel: def sel(event=None): return - self.tree=treewidget.Tree(self.appli,self.item,self.canvas,command=sel) + self.tree=treewidget.Tree(self.appli,self.item,self.canvas,command=sel,rmenu=rmenu) self.tree.draw() def mainloop(self): diff --git a/Editeur/treewidget.py b/Editeur/treewidget.py index ebf3cd51..55b71d96 100644 --- a/Editeur/treewidget.py +++ b/Editeur/treewidget.py @@ -26,13 +26,13 @@ import images # __version__="$Name: $" -__Id__="$Id: treewidget.py,v 1.8 2002/10/16 13:27:35 eficas Exp $" +__Id__="$Id: treewidget.py,v 1.9 2002/11/06 17:25:57 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') @@ -40,14 +40,19 @@ class Tree : self.canvas.bind("", self.page_down) self.canvas.bind("", self.unit_up) self.canvas.bind("", 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): @@ -60,7 +65,7 @@ class Tree : 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' @@ -85,7 +90,10 @@ class Tree : child.update() def resizescrollregion(self): - self.scrolledcanvas.resizescrollregion() + x0,y0,x1,y1=self.canvas.bbox(ALL) + y1=y1+(self.canvas.winfo_height()/20-1)*20 + self.canvas.configure(scrollregion = (x0,y0,x1,y1)) + #self.scrolledcanvas.resizescrollregion() def select_next(self,event): self.node_selected.select_next() @@ -100,17 +108,42 @@ class Tree : 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' @@ -144,7 +177,7 @@ class Node : 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) #----------------------------------------------- @@ -162,6 +195,7 @@ class Node : self.tree.node_selected = self if self.command:apply(self.command,(self,)) self.highlight() + self.make_visible() def deselect(self, event=None): """ Déselectionne self """ @@ -170,9 +204,10 @@ class Node : 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: @@ -203,6 +238,15 @@ class Node : 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 #----------------------------------------------- @@ -268,6 +312,7 @@ class Node : 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 @@ -311,6 +356,7 @@ class Node : 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("",self.enter) self.label.bind("",self.leave) # valeur de cet objet à afficher @@ -386,6 +432,7 @@ class Node : # il suffit d'updater les coordonnees et de retracer les lignes self.racine.update_coords() self.racine.trace_ligne() + self.tree.resizescrollregion() def update_coords(self): """ Permet d'updater les coordonnes de self et de tous ses enfants""" @@ -467,8 +514,6 @@ class Node : 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""" @@ -488,6 +533,12 @@ class Node : print child print child.item.object + 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 @@ -522,10 +573,10 @@ class Node : 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 : @@ -675,6 +726,7 @@ class Node : 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 #-------------------------------------------------------------- diff --git a/Editeur/widgets.py b/Editeur/widgets.py index 723e6fcf..a08654a4 100644 --- a/Editeur/widgets.py +++ b/Editeur/widgets.py @@ -123,7 +123,7 @@ class Fenetre : showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file) class FenetreYesNo(Fenetre): - def __init__(self,appli,titre="",texte=""): + def __init__(self,appli,titre="",texte="",yes="Yes",no="No"): self.appli=appli self.fenetre = Toplevel() self.fenetre.configure(width = 800,height=500) @@ -150,8 +150,8 @@ class FenetreYesNo(Fenetre): self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10) self.zone_texte.configure(yscrollcommand=self.scroll_v.set) # définition des boutons - self.but_yes = Button(self.frame_boutons,text = "Yes",command=self.yes) - self.but_no = Button(self.frame_boutons,text = "No",command = self.no) + self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes) + self.but_no = Button(self.frame_boutons,text = no,command = self.no) self.but_yes.place(relx=0.4,rely=0.5,anchor='center') self.but_no.place(relx=0.6,rely=0.5,anchor='center') # affichage du texte -- 2.39.2