]> SALOME platform Git repositories - modules/eficas.git/commitdiff
Salome HOME
CCAR: modifications pour INCLUDE; ajout du viewer d'INCLUDE
authoreficas <>
Tue, 12 Nov 2002 12:25:02 +0000 (12:25 +0000)
committereficas <>
Tue, 12 Nov 2002 12:25:02 +0000 (12:25 +0000)
Editeur/bureau.py
Editeur/compomacro.py
Editeur/jdcdisplay.py
Editeur/macrodisplay.py [new file with mode: 0644]
Editeur/patches.py
Editeur/tooltip.py
Editeur/treeitemincanvas.py
Editeur/treewidget.py
Editeur/widgets.py

index ecce22bc55e0e2dee50d934c42a5fd226d7656cd..eb3269926ca8fb3b718a0f81b00a1114d0d672f4 100644 (file)
@@ -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')
 
index 6d8e0f45bc6a24693df91c0deb0acbb7f9947b88..5fa7236ca6b41aa79296f91787b0165aa258733e 100644 (file)
@@ -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):
-    """\r
+    """
     Affiche la page d'onglet correspondant au changement du fichier
     dont a besoin la macro\r
     """
@@ -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
index 820d7bacee44bccf29354c09b40adc6b415f718c..53303962b46b0111a8a1fbca4a177ba5f76438f3 100644 (file)
@@ -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 (file)
index 0000000..069a05d
--- /dev/null
@@ -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)
+
index b85f654c515ab49770da4790fe75b74d5e60084f..fd6741180f2f823460ab4f251f25e3246b5ba4c6 100644 (file)
@@ -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
index 752a57b77c86dac80d50095a18d06024648d42af..87bda661c07b40e18176a4d32e1d4d932a54f64e 100644 (file)
@@ -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("<ButtonPress>", aide)
    label.pack()
+   tp=TOOLTIP(label,"texte d'aide")
    root.mainloop()
 
index a9d5c86e821c8e30713c396c6fa7925119c32048..14ab086ea6c497375dd501cb3a7f1bfbadcfe1b7 100644 (file)
@@ -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):
index ebf3cd5122e27f43f3edd88cb1f81f611bb47201..55b71d962af9ffd8d4ea28608ba8445a84d3a07c 100644 (file)
@@ -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("<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):
@@ -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("<Enter>",self.enter)
         self.label.bind("<Leave>",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
     #--------------------------------------------------------------
index 723e6fcf2a35799f244b1dd0754b74c670326b97..a08654a4765aa4088e8570fc3eccd97a50b1b676 100644 (file)
@@ -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