Salome HOME
CCAR: modifications pour permettre l'edition des includes et poursuites
authoreficas <>
Thu, 16 Jun 2005 09:27:26 +0000 (09:27 +0000)
committereficas <>
Thu, 16 Jun 2005 09:27:26 +0000 (09:27 +0000)
sans avoir besoin de disposer de fichiers existants. Ceci a conduit
a changer le mode d'edition et donc les verifications internes d'ou de
nombreuses modifications mais principalement liees aux includes.
Quelques problemes ont ete corriges au passage.
Un test associe est defini dans le fichier Aster/Tests/princ.ini
Le module ops.py a du etre modifie (fonction detruire)

24 files changed:
Aster/Cata/ops.py
Aster/Tests/princ.comm [new file with mode: 0644]
Aster/Tests/princ.ini [new file with mode: 0644]
Aster/Tests/princl.11 [new file with mode: 0644]
Aster/Tests/princl.12 [new file with mode: 0644]
Aster/Tests/princl.14 [new file with mode: 0644]
Aster/Tests/princl.35 [new file with mode: 0644]
Editeur/appli.py
Editeur/bureau.py
Editeur/compomacro.py
Editeur/eficas.py
Editeur/jdcdisplay.py
Editeur/macrodisplay.py
Editeur/panels.py
Editeur/treewidget.py
Extensions/jdc_include.py
Ihm/I_ETAPE.py
Ihm/I_FORM_ETAPE.py
Ihm/I_JDC.py
Ihm/I_MACRO_ETAPE.py
Ihm/I_MCCOMPO.py
Ihm/I_MCLIST.py
Ihm/I_MCSIMP.py
Ihm/I_OBJECT.py

index 3b917d00dca468127ec0d0bc4218508c13a0474d..110eb96a0d640b958ce8be7302c0bcfc8a0fe055 100644 (file)
@@ -251,6 +251,7 @@ def detruire(self,d):
      sd=[]
      for mc in self["CONCEPT"]:
        mcs=mc["NOM"]
+       if mcs is None:continue
        if type(mcs) == types.ListType or type(mcs) == types.TupleType:
          for e in mcs:
            if isinstance(e,ASSD):
diff --git a/Aster/Tests/princ.comm b/Aster/Tests/princ.comm
new file mode 100644 (file)
index 0000000..59f33a8
--- /dev/null
@@ -0,0 +1,16 @@
+
+POURSUITE();
+
+# commentaire
+
+xx=LIRE_MAILLAGE();
+
+INCLUDE(UNITE=12,);
+
+INCLUDE(UNITE=35,);
+
+INCLUDE(UNITE=11,);
+
+yy=LIRE_MAILLAGE();
+
+DETRUIRE(CONCEPT=_F(NOM=None,),);
diff --git a/Aster/Tests/princ.ini b/Aster/Tests/princ.ini
new file mode 100644 (file)
index 0000000..a8865fb
--- /dev/null
@@ -0,0 +1,20 @@
+[jdc]
+jdc=a
+[a]
+comm=princ.comm
+poursuite=pours1
+11=princl.11
+12=princl.12
+14=princl.14
+35=princl.35
+[pours1]
+comm=p1.comm
+poursuite=pours2
+11=incl.11
+[pours2]
+comm=p2.comm
+poursuite=pours3
+11=incl.12
+[pours3]
+comm=d0.comm
+11=incl.16
diff --git a/Aster/Tests/princl.11 b/Aster/Tests/princl.11
new file mode 100644 (file)
index 0000000..ef02b73
--- /dev/null
@@ -0,0 +1,3 @@
+MAA=LIRE_MAILLAGE()
+
+
diff --git a/Aster/Tests/princl.12 b/Aster/Tests/princl.12
new file mode 100644 (file)
index 0000000..eb15ffd
--- /dev/null
@@ -0,0 +1,15 @@
+MMAA=LIRE_MAILLAGE()
+
+mo=AFFE_MODELE(MAILLAGE=MMAA,
+               AFFE=_F(TOUT='OUI',
+                       PHENOMENE='MECANIQUE',
+                       MODELISATION='3D',),);
+
+MACRO_MATR_ASSE(MODELE=mo,
+                NUME_DDL=CO('numdl'),
+                MATR_ASSE=_F(MATRICE=CO('mmm'),
+                             OPTION='RIGI_MECA',),);
+
+mmm=FACT_LDLT(reuse =mmm,
+             MATR_ASSE=mmm,);
+
diff --git a/Aster/Tests/princl.14 b/Aster/Tests/princl.14
new file mode 100644 (file)
index 0000000..3ee3c9f
--- /dev/null
@@ -0,0 +1,11 @@
+
+mmo=AFFE_MODELE(MAILLAGE=xx,
+                AFFE=_F(TOUT='OUI',
+                        PHENOMENE='MECANIQUE',
+                        MODELISATION='3D',),);
+
+MACRO_MATR_ASSE(MODELE=mmo,
+                NUME_DDL=CO('nume'),
+                MATR_ASSE=_F(MATRICE=CO('mmb'),
+                             OPTION='RIGI_MECA',),);
+
diff --git a/Aster/Tests/princl.35 b/Aster/Tests/princl.35
new file mode 100644 (file)
index 0000000..4a9f4aa
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+INCLUDE(UNITE=14,);
+
+DETRUIRE(CONCEPT=_F(NOM=None,),);
\ No newline at end of file
index 9478e5bcc630441790abc580816704072a7e2d45..1ca53a34833fc9ab713a1dc126b8ec0a624d5afb 100644 (file)
@@ -92,7 +92,7 @@ class APPLI:
       for study in session.d_env.studies:
           os.chdir(cwd)
           d=session.get_unit(study,self)
-          self.bureau.openJDC(study["comm"],d)
+          self.bureau.openJDC(file=study["comm"],units=d)
 
 
   def send_message(self,message):
index 19aef955b91e3525dd7c2c144bcecfa4c64bcfd1..5ee1dfa2e01c1b1082ac1acaff863bfa77701fad 100644 (file)
@@ -132,10 +132,11 @@ class BUREAU:
       if len(self.liste_JDCDisplay) == 0 : return
       #if self.JDCDisplay_courant : self.JDCDisplay_courant.jdc.unset_context()
       numero_jdc = self.nb.index(self.nb.getcurselection())
+      self.JDCDisplay_courant.unselect()
       self.JDCDisplay_courant = self.liste_JDCDisplay[numero_jdc]
       self.JDC = self.JDCDisplay_courant.jdc
-      #self.JDC.set_context()
       self.JDCName = self.JDC.nom
+      self.JDCDisplay_courant.select()
       #print "selectJDC",numero_jdc,self.JDCDisplay_courant,self.JDCName
 
    def newJDC_include(self,event=None):
@@ -298,7 +299,7 @@ class BUREAU:
       texte_cr = str(cr)
       self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
 
-   def openJDC(self,file=None,units=None):
+   def openJDC(self,event=None,file=None,units=None):
       """
           Demande à l'utilisateur quel JDC existant il veut ouvrir
       """
@@ -311,9 +312,6 @@ class BUREAU:
       if not hasattr(self,'initialdir'):
          self.initialdir = self.appli.CONFIGURATION.initialdir
 
-      if file.__class__.__name__ in  ('Event',):
-         file=None
-
       if not file :
           file = askopenfilename(title="Ouverture d'un fichier de commandes Aster",
                                  defaultextension=".comm",
@@ -379,7 +377,6 @@ class BUREAU:
             self.appli.top.update()
             self.visuCR(mode='JDC')
 
-
    def GetLabelJDC(self,nb_jdc = 'absent'):
       """
       Retourne le label de l'onglet du NoteBook associé au JDC à afficher
@@ -503,8 +500,8 @@ class BUREAU:
                   # l'utilisateur a sauvegardé le JDC sous un autre nom
                   self.JDCDisplay_courant.fichier = sauvegarde
                   self.JDCName = self.JDC.nom = stripPath(sauvegarde)
+                  self.JDC.changefichier(sauvegarde)
                   self.changeNomPage()
-                  CONNECTOR.Emit(self.JDC,"valid")
               return 1
       else :
           return 0
index 2c7d3c08957d68cd6430b9852718471052f7125c..bafed5540d6944578b778010c695bc3b01a1c762 100644 (file)
@@ -38,7 +38,7 @@ from Ihm import CONNECTOR
 
 #
 __version__="$Name:  $"
-__Id__="$Id: compomacro.py,v 1.21 2005/06/01 15:18:15 eficas Exp $"
+__Id__="$Id: compomacro.py,v 1.22 2005/06/10 13:47:49 eficas Exp $"
 #
 
 class MACROPanel(panels.OngletPanel):
@@ -164,7 +164,8 @@ class MACROPanel(panels.OngletPanel):
   def annule_fichier_init(self,event=None):
     """ Restaure dans self.entry le nom de fichier_init"""
     self.entry.delete(0,Tkinter.END)
-    self.entry.insert(0,self.node.item.object.fichier_ini)
+    if self.node.item.object.fichier_ini:
+       self.entry.insert(0,self.node.item.object.fichier_ini)
 
   def browse_fichier_init(self,event=None):
     """ 
@@ -176,6 +177,9 @@ class MACROPanel(panels.OngletPanel):
       self.entry.delete(0,Tkinter.END)
       self.entry.insert(0,file)
     
+  def update_panel(self):
+    if hasattr(self,"entry"):
+       self.annule_fichier_init()
     
 class MACROTreeItem(compooper.EtapeTreeItem):
   """ Cette classe hérite d'une grande partie des comportements
@@ -202,8 +206,8 @@ class INCLUDETreeItemBase(MACROTreeItem):
     #print "makeEdit",self.object.jdc_aux,self.object.jdc_aux.nom
     #print "makeEdit",self.object.jdc_aux.context_ini
     if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
-         showerror("Include vide","L'include doit etre correctement initialisé avant d'etre édité")
-         return
+       #L'include n'est pas initialise
+       self.object.build_include(None,"")
     self.parent_node=node
     # On cree un nouvel onglet dans le bureau
     appli.bureau.ShowJDC(self.object.jdc_aux,self.object.jdc_aux.nom,
@@ -218,7 +222,7 @@ class INCLUDETreeItemBase(MACROTreeItem):
 
   def makeView(self,appli,node):
     if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
-         showerror("Include vide","L'include doit etre correctement initialisé avant d'etre édité")
+         showerror("Include vide","L'include doit etre correctement initialisé pour etre visualisé")
          return
     nom=self.object.nom
     if hasattr(self.object,'fichier_ini'):
@@ -238,9 +242,8 @@ class INCLUDEPanel(MACROPanel):
     """
     Affiche la page d'onglet correspondant au changement du fichier INCLUDE
     """
-    if self.node.item["UNITE"] is None:
-       # Le numero de l'INCLUDE n'est pas defini
-       titre = Tkinter.Label(page,text="Le numero de l'INCLUDE doit etre defini avec le mot cle UNITE" )
+    if not hasattr(self.node.item.object,'fichier_ini'):
+       titre = Tkinter.Label(page,text="L'INCLUDE n'a pas de fichier associé\nIl faut d'abord choisir un numero d'unité " )
        titre.place(relx=0.5,rely=0.5,anchor='center')
     else:
        MACROPanel.makeFichierPage(self,page)
@@ -248,7 +251,33 @@ class INCLUDEPanel(MACROPanel):
 class INCLUDETreeItem(INCLUDETreeItemBase):
    panel=INCLUDEPanel
 
-class POURSUITETreeItem(INCLUDETreeItemBase): pass
+class POURSUITETreeItem(INCLUDETreeItemBase): 
+  def makeEdit(self,appli,node):
+    if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
+       #La poursuite n'est pas initialisee
+       text="""DEBUT()
+FIN()"""
+       self.object.build_poursuite(None,text)
+    self.parent_node=node
+    # On cree un nouvel onglet dans le bureau
+    appli.bureau.ShowJDC(self.object.jdc_aux,self.object.jdc_aux.nom,
+                             label_onglet=None,
+                             JDCDISPLAY=macrodisplay.MACRODISPLAY)
+    self.myjdc=appli.bureau.JDCDisplay_courant
+    self.myjdc.fichier=self.object.fichier_ini
+
+  def makeView(self,appli,node):
+    if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
+         showerror("Poursuite vide","Une POURSUITE doit etre correctement initialisée pour etre visualisée")
+         return
+    nom=self.object.nom
+    if hasattr(self.object,'fichier_ini'):
+       if self.object.fichier_ini is None:
+          nom=nom+' '+"Fichier non défini"
+       else:
+          nom=nom+' '+self.object.fichier_ini
+    macdisp=macrodisplay.makeMacroDisplay(appli,self,nom)
+    CONNECTOR.Connect(self.object.jdc_aux,"close",self.onCloseView,(macdisp,))
 
 class INCLUDE_MATERIAUTreeItem(INCLUDETreeItemBase):
   rmenu_specs=[("View","makeView"),
index 463ac547ca1b53ff133387e9e8bb4b9ed6875c20..c683ed5ac905435daf72ed350ce4975c38fd6d64 100644 (file)
@@ -72,7 +72,7 @@ class EFICAS(appli.APPLI):
         self._ulfile.setentry('')
         self.dialog.deactivate(result)
         self.ulfile = None
-        self.text=None
+        self.text=""
 
   def get_file(self,unite=None,fic_origine = ''):
       """ 
index 863c5b61024944fa1f38712ddb27693b706ecdb2..4400de16e1e40a62877258b507544d44506b8fe5 100644 (file)
@@ -121,6 +121,12 @@ class JDCDISPLAY:
       # Si au moins un radiobouton existe on invoke le premier
       if radio:menu.invoke(radio)
 
+   def select(self):
+      return
+
+   def unselect(self):
+      return
+
    def select_node(self,node):
       """
           Cette méthode est appelée à chaque fois qu'un noeud est sélectionné
@@ -128,14 +134,13 @@ class JDCDISPLAY:
           Elle permet l'affichage du panneau correspondant au noeud sélectionné
       """
       if node is not self.node_selected :
+         #ATTENTION: il faut affecter l'attribut node_selected avant d'appeler 
+         # create_panel pour eviter une recursion infinie entre create_panel, 
+         # Emit, onValid, select_node
+         self.node_selected = node
          self.create_panel(node)
-      self.node_selected = node
-      ## on conserve la trace du noeud sélectionné et de celui d'avant
-      #if self.node_selected :
-          #self.ancien_node = self.node_selected
-          #self.node_selected = node
-      #else:
-          #self.ancien_node = self.node_selected = node
+      elif self.panel_courant:
+         self.panel_courant.update_panel()
 
    def create_panel(self,node):
       """
index af5671e9711956282f27b505b705309561a25cc2..1be2e911cf19eda1ff00c39c9e9d0dcc09d3a1ed 100644 (file)
@@ -108,6 +108,7 @@ class MacroDisplay:
       if radio:menu.invoke(radio)
 
   def quit(self):
+    self.tree.supprime()
     self.fenetre.destroy()
 
 def makeMacroDisplay(appli,macroitem,nom_item):
index a1ebed2923d9d80ff066bec1112b7a54cd295762..74b3b1d5e35a5c56629a64cc8f9f843fa6e3a68b 100644 (file)
@@ -56,6 +56,9 @@ class Panel(Frame) :
       """ appele a la destruction du panel """
       #print "PANEL DETRUIT"
 
+  def update_panel(self):
+      """Methode appele pour demander une mise a jour du panneau"""
+
   def destroy(self):
       Frame.destroy(self)
       self.panneau=None
index e8718716579b92ae25f0db49ad49add30cf0f507..78b3a16c247745cb718a787fb069fc696a8bd61d 100644 (file)
@@ -28,7 +28,7 @@ from Ihm import CONNECTOR
 
 #
 __version__="$Name:  $"
-__Id__="$Id: treewidget.py,v 1.23 2005/06/06 09:33:06 eficas Exp $"
+__Id__="$Id: treewidget.py,v 1.24 2005/06/10 14:59:37 eficas Exp $"
 #
 
 Fonte_Standard = fontes.standard
@@ -101,6 +101,11 @@ class Tree :
         for child in self.children:
             child.update()
 
+    def supprime(self):
+        """ supprime tous les éléments de l'arbre """
+        for child in self.children:
+            child.supprime()
+
     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
@@ -183,18 +188,6 @@ class Node :
         else:
            self.racine = self.parent.racine
            
-        # etape = noeud d'étape auquel appartient self
-        # = self si c'est lui-même
-        #if isinstance(self.parent,Tree) :
-            # on est  sur un noeud de JDC
-            #self.etape=None
-        #elif isinstance(self.parent.parent,Tree) :
-            # on est sur un noeud d'étape
-            #self.etape=self
-        #else :
-            # on est sur un noeud de mot-clé
-            #self.etape=self.parent.etape
-
     def reconnect(self):
         self.disconnect()
         self.connect()
@@ -232,6 +225,8 @@ class Node :
         self.update_node_valid()
         self.update_node_label()
         self.update_node_texte()
+        if self.selected and self.command:
+           self.command(self)
 
     def onAdd(self,objet):
         #print "onAdd : un objet a été ajouté aux fils de l'item ",self.item.object,objet
@@ -333,7 +328,7 @@ class Node :
 
            if node is new_node: # ancien noeud
               #print "noeud conserve",node
-              node.update_label_texte()
+              node.update_node_label()
               y=y+node.lasty-node.y +20
 
         self.racine.update_coords()
@@ -709,6 +704,7 @@ class Node :
         
     def update_node_label(self):
         """ Met a jour le label du noeud """
+        if self.displayed == 0 : return
         # nom,fonte et couleur de l'objet du noeud à afficher
         labeltext,fonte,couleur = self.item.GetLabelText()
         if labeltext    == ''   : labeltext = '   '
@@ -718,6 +714,7 @@ class Node :
 
     def update_node_texte(self):
         """ Met à jour les noms des SD et valeurs des mots-clés """
+        if self.displayed == 0 : return
         text = self.item.GetText()
         if text == None : text = ''
         self.text.configure(text=text)
@@ -726,6 +723,7 @@ class Node :
         """Cette methode remet a jour la validite du noeud (icone)
            Elle appelle isvalid
         """
+        if self.displayed == 0 : return
         if self.image_id != None :
             image = self.geticonimage()
             self.canvas.itemconfig(self.image_id,image=image)
index 94cc0163c94a817eb573e6e2f202f7d8196d1a3f..39196a235f254f78e3956c1d790865047395deda 100644 (file)
@@ -94,11 +94,12 @@ class JDC_POURSUITE(JDC):
    def force_contexte(self,contexte):
       for nom_sd,sd in contexte.items():
         if not isinstance(sd,ASSD):continue
-        if self.jdc_pere.get_sd_apres_etape_avec_detruire(nom_sd,sd,
-                                                       etape=self.etape_include):
+        autre_sd= self.jdc_pere.get_sd_apres_etape_avec_detruire(nom_sd,sd,
+                                                       etape=self.etape_include)
+        if autre_sd is None:continue
+        if sd is not autre_sd:
            # Il existe un autre concept de meme nom produit par une etape apres self 
            # on detruit ce concept pour pouvoir inserer les etapes du jdc_include
-           #print "force_contexte",sd.etape,sd.nom,sd.etape.nom
            if sd.etape:
               sd.etape.supprime_sdprod(sd)
 
@@ -119,7 +120,8 @@ class JDC_POURSUITE(JDC):
         if not isinstance(sd,ASSD):continue
         autre_sd= self.jdc_pere.get_sd_apres_etape_avec_detruire(nom_sd,sd,
                                                        etape=self.etape_include)
-        if sd and sd is not autre_sd:
+        if autre_sd is None:continue
+        if sd is not autre_sd:
            # Il existe un concept produit par une etape apres self 
            # => impossible d'inserer
            raise Exception("Impossible d'inclure le fichier. Un concept de nom " +
@@ -165,27 +167,9 @@ class JDC_POURSUITE(JDC):
           ex : INCLUDE et POURSUITE
       """
       #print "jdc_include.fin_modif",self,self.etape_include
-      if not self.etape_include:
-         CONNECTOR.Emit(self,"valid")
-         return
-      # Mise a jour du contexte en fin d'include
-      # On suppose que toutes les modifications sont valides
-      # On recupere le contexte final dans j_context
-      j_context=self.get_contexte_avant(None) #get_verif_contexte ???
-      # On remplit le dictionnaire des concepts produits de l'etape macro INCLUDE
-      # sans y mettre les concepts présents dans le  contexte initial (context_ini)
-      # On ajoute egalement les concepts produits dans le sds_dict du parent
-      # sans verification car on est sur (verification integrée) que
-      # le nommage est possible
-      self.etape_include.g_context.clear()
-      for k,v in j_context.items():
-         if not self.context_ini.has_key(k) or self.context_ini[k] != v:
-            self.etape_include.g_context[k]=v
-            self.etape_include.parent.sds_dict[k]=v
-
       CONNECTOR.Emit(self,"valid")
-      self.etape_include.fin_modif()
-      #print "jdc_include.fin_modif.context_ini",self.context_ini
+      if self.etape_include:
+         self.etape_include.fin_modif()
 
    def supprime(self):
       """
@@ -202,22 +186,20 @@ class JDC_POURSUITE(JDC):
          comme DETRUIRE ou les macros
          Si etape == None, on retourne le contexte en fin de JDC
       """
+      #print "jdc_include.get_contexte_avant",etape,etape and etape.nom
       if self.etape_include:
-         self.context_ini = self.etape_include.parent.get_contexte_avant(self.etape_include).copy()
-      return JDC.get_contexte_avant(self,etape)
-
-   #def get_sd_avant_etape(self,nom_sd,etape):
-      #sd=self.etape_include.parent.get_sd_avant_etape(nom_sd,self.etape_include)
-      #if sd:return sd
-      #return JDC.get_sd_avant_etape(self,nom_sd,etape)
-
-   #def get_sd_avant_du_bon_type(self,etape,types_permis):
-      #"""
-      #    Retourne la liste des concepts avant etape d'un type acceptable
-      #"""
-      #l1=self.etape_include.parent.get_sd_avant_du_bon_type(self.etape_include,types_permis)
-      #l2=JDC.get_sd_avant_du_bon_type(self,etape,types_permis)
-      #return l1+l2
+         new_context=self.etape_include.parent.get_contexte_avant(self.etape_include).copy()
+         self.context_ini=new_context
+      d= JDC.get_contexte_avant(self,etape)
+      return d
+
+   def reset_context(self):
+      #print "jdc_include.reset_context",self,self.nom
+      if self.etape_include:
+         self.etape_include.parent.reset_context()
+         new_context=self.etape_include.parent.get_contexte_avant(self.etape_include).copy()
+         self.context_ini=new_context
+      JDC.reset_context(self)
 
    def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
       """
@@ -240,7 +222,6 @@ class JDC_POURSUITE(JDC):
       """
       #print "jdc_include.get_sd_apres_etape_avec_detruire",nom_sd,sd,id(sd)
       autre_sd=JDC.get_sd_apres_etape_avec_detruire(self,nom_sd,sd,etape,avec)
-      #print autre_sd,id(autre_sd)
       # si autre_sd vaut None le concept sd a ete detruit. On peut terminer
       # la recherche en retournant None
       # Si autre_sd ne vaut pas sd, le concept a ete redefini. On peut terminer
@@ -273,6 +254,15 @@ class JDC_POURSUITE(JDC):
       if self.etape_include:
          self.etape_include.parent.delete_concept_after_etape(self.etape_include,sd)
 
+   def update_concept_after_etape(self,etape,sd):
+      """
+          Fonction : mettre a jour les etapes du JDC suite a une modification
+          du concept sd (principalement renommage)
+      """
+      JDC.update_concept_after_etape(self,etape,sd)
+      if self.etape_include:
+         self.etape_include.parent.update_concept_after_etape(self.etape_include,sd)
+
    def replace_concept_after_etape(self,etape,old_sd,sd):
       """
           Fonction : Mettre à jour les étapes du JDC qui sont après etape suite au
@@ -284,6 +274,27 @@ class JDC_POURSUITE(JDC):
       if self.etape_include:
          self.etape_include.parent.replace_concept_after_etape(self.etape_include,old_sd,sd)
 
+   def changefichier(self,fichier):
+      if self.etape_include:
+         self.etape_include.fichier_ini=fichier
+      self.fin_modif()
+
+   def control_context_apres(self,etape):
+      """
+         Cette méthode verifie que les etapes apres l'etape etape
+         ont bien des concepts produits acceptables (pas de conflit de
+         nom principalement)
+         Si des concepts produits ne sont pas acceptables ils sont supprimés.
+         Effectue les verifications sur les etapes du jdc mais aussi sur les
+         jdc parents s'ils existent.
+      """
+      #print "jdc_include.control_context_apres",self,etape
+      #Regularise les etapes du jdc apres l'etape etape
+      self.control_jdc_context_apres(etape)
+      if self.etape_include:
+         # il existe un jdc pere. On propage la regularisation
+         self.etape_include.parent.control_context_apres(self.etape_include)
+
 class JDC_INCLUDE(JDC_POURSUITE):
    def get_liste_cmd(self):
       """
index 4664252bc48c38ca47cd0e43067696e00e31a739..f05dd1d339859f4b4bcc511a28eb6e1e435cc699 100644 (file)
@@ -83,12 +83,14 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
           ex : INCLUDE et POURSUITE
       """
       #print "fin_modif",self,self.parent
-      #if hasattr(self,'jdc_aux'):print "fin_modif",self.jdc_aux.context_ini
-      if self.isvalid() :
-         #if hasattr(self,'jdc_aux'):print "fin_modif",self.jdc_aux.context_ini
-         d=self.parent.get_contexte_apres(self)
-         #print d
-      #if hasattr(self,'jdc_aux'):print "fin_modif",self.jdc_aux.context_ini
+      if self.nom == "DETRUIRE":
+         #Il n'est pas conseillé de mettre des traitements dans fin_modif. Ceci est une
+         # exception qu'il faut supprimer à terme.
+         #une commande DETRUIRE a été modifiée. Il faut verifier les commandes
+         #suivantes
+         #ATTENTION: aux eventuelles recursions
+         self.parent.control_context_apres(self)
+
       CONNECTOR.Emit(self,"valid")
       if self.parent:
         self.parent.fin_modif()
@@ -153,6 +155,7 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
       # mais est utilisé en mode non réentrant
       #
       if self.sd == None :
+          #Pas de concept produit preexistant
           if self.parent.get_sd_autour_etape(nom,self):
             # Un concept de ce nom existe dans le voisinage de l'etape courante
             # On retablit l'ancien concept reentrant s'il existait
@@ -166,14 +169,16 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
             # Il est créé sans nom mais enregistré dans la liste des concepts existants
             try:
                self.get_sd_prod()
-               # Il suffit de changer son attribut nom pour le nommer
+               # Renommage du concept : Il suffit de changer son attribut nom pour le nommer
                self.sd.nom = nom
                self.sdnom=nom
+               self.parent.update_concept_after_etape(self,self.sd)
                self.fin_modif()
                return 1,"Nommage du concept effectué"
             except:
                return 0,"Nommage impossible"+str(sys.exc_info()[1])
       else :
+          #Un concept produit preexiste
           old_nom=self.sd.nom
           if string.find(old_nom,'sansnom') :
             # Dans le cas où old_nom == sansnom, isvalid retourne 0 alors que ...
@@ -182,8 +187,10 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
             if self.parent.get_sd_autour_etape(nom,self):
               return 0,"Nommage du concept refuse : un concept de meme nom existe deja"
             else:
+              # Renommage du concept : Il suffit de changer son attribut nom pour le nommer
              self.sd.nom=nom
               self.sdnom=nom
+              self.parent.update_concept_after_etape(self,self.sd)
               self.fin_modif()
               return 1,"Nommage du concept effectué"
           if self.isvalid() :
@@ -193,8 +200,10 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
             if self.parent.get_sd_autour_etape(nom,self):
               return 0,"Nommage du concept refuse : un concept de meme nom existe deja"
             else:
+              # Renommage du concept : Il suffit de changer son attribut nom pour le nommer
               self.sd.nom=nom
               self.sdnom=nom
+              self.parent.update_concept_after_etape(self,self.sd)
               self.fin_modif()
               return 1,"Nommage du concept effectué"
           else:
@@ -240,18 +249,11 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
 
    def control_sdprods(self,d):
       """
-          Cette methode doit updater le contexte fournit par
-          l'appelant en argument (d) en fonction de sa definition
-          tout en verifiant que ses concepts produits ne sont pas 
+          Cette methode doit verifier que ses concepts produits ne sont pas
           deja definis dans le contexte
+          Si c'est le cas, les concepts produits doivent etre supprimes
       """
-      if type(self.definition.op_init) == types.FunctionType:
-        try:
-           apply(self.definition.op_init,(self,d))
-        except:
-           #traceback.print_exc()
-           pass
-
+      #print "control_sdprods",d.keys(),self.sd and self.sd.nom,self.nom
       if self.sd:
         if d.has_key(self.sd.nom):
            # Le concept est deja defini
@@ -262,11 +264,12 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
               # Redefinition du concept, on l'annule
               #XXX on pourrait simplement annuler son nom pour conserver les objets
               # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
-              self.sd=self.reuse=self.sdnom=None
               self.init_modif()
-        else:
-           # Le concept n'est pas defini, on peut updater d
-           d[self.sd.nom]=self.sd
+              sd=self.sd
+              self.sd=self.reuse=self.sdnom=None
+              #supprime les references a sd dans les etapes suivantes
+              self.parent.delete_concept_after_etape(self,sd)
+              self.fin_modif()
 
    def supprime_sdprod(self,sd):
       """
@@ -300,6 +303,10 @@ class ETAPE(I_MCCOMPO.MCCOMPO):
    def close(self):
       return
 
+   def update_concept(self,sd):
+      for child in self.mc_liste :
+          child.update_concept(sd)
+
    def delete_concept(self,sd):
       """ 
           Inputs :
index f5e632adff88c2fbac78615c1a66c28ab665c5c0..75cad81c75c0d3ba79e26b1cd0489b23f02b9bcb 100644 (file)
@@ -329,6 +329,9 @@ class FORM_ETAPE(MACRO_ETAPE):
         if not self.sd : return
         self.jdc.del_fonction(self.sd)
 
+    def update_concept(self,sd):
+        return
+
     def delete_concept(self,sd):
         """ 
          Inputs :
index b043c48d6f86451f3851a5ea33dbff1e396e93aa..97984193f8cb567b604e24b2d24eb374472dd40a 100644 (file)
@@ -142,9 +142,7 @@ class JDC(I_OBJECT.OBJECT):
         # on est donc nécessairement en mode editeur ...
         objet = name
         # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
-        #if hasattr(objet,'sd'):print "addentite",objet.sd
         objet.reparent(self)
-        #if hasattr(objet,'sd'):print "addentite",objet.sd
         self.set_current_step()
         if isinstance(objet,ETAPE):
           if objet.nom_niveau_definition == 'JDC':
@@ -158,12 +156,10 @@ class JDC(I_OBJECT.OBJECT):
         self.etapes.insert(pos,objet)
        # il faut vérifier que les concepts utilisés par objet existent bien
        # à ce niveau d'arborescence
-        #if hasattr(objet,'sd'):print "addentite",objet.sd
        objet.verif_existence_sd()
         self.active_etapes()
         self.editmode=0
         self.reset_context()
-        #print "addentite",self.etapes
         CONNECTOR.Emit(self,"add",objet)
         self.fin_modif()
         return objet
@@ -182,7 +178,6 @@ class JDC(I_OBJECT.OBJECT):
           self.editmode=0
           self.reset_context()
           self.active_etapes()
-          #print "addentite",self.etapes
           CONNECTOR.Emit(self,"add",e)
           self.fin_modif()
           return e
@@ -326,30 +321,69 @@ class JDC(I_OBJECT.OBJECT):
       """
       #print "suppentite",self
       self.init_modif()
-      # On memorise le contexte avant l'etape a supprimer
-      d=self.get_contexte_avant(etape)
       index_etape=self.etapes.index(etape)
-      #print "suppentite",index_etape,d
-
       self.etapes.remove(etape)
+
       if etape.niveau is not self:
         # Dans ce cas l'étape est enregistrée dans un niveau
         # Il faut la désenregistrer
         etape.niveau.unregister(etape)
+
       etape.supprime_sdprods()
       etape.close()
       self.active_etapes()
 
       # Apres suppression de l'etape il faut controler que les etapes
       # suivantes ne produisent pas des concepts DETRUITS dans op_init de etape
-      for e in self.etapes[index_etape:]:
-         e.control_sdprods(d)
+      if index_etape > 0: 
+         index_etape=index_etape-1
+         etape=self.etapes[index_etape]
+      else:
+         etape=None
+      self.control_context_apres(etape)
       
       self.reset_context()
       CONNECTOR.Emit(self,"supp",etape)
       self.fin_modif()
       return 1
 
+   def control_context_apres(self,etape):
+      """
+         Cette méthode verifie que les etapes apres l'etape etape
+         ont bien des concepts produits acceptables (pas de conflit de 
+         nom principalement)
+         Si des concepts produits ne sont pas acceptables ils sont supprimés.
+         Effectue les verifications sur les etapes du jdc mais aussi sur les
+         jdc parents s'ils existent.
+      """
+      #print "control_context_apres",self,etape
+      #Regularise les etapes du jdc apres l'etape etape
+      self.control_jdc_context_apres(etape)
+
+   def control_jdc_context_apres(self,etape):
+      """
+          Methode semblable a control_context_apres mais ne travaille
+          que sur les etapes et sous etapes du jdc
+      """
+      #print "control_jdc_context_apres",self,etape
+      if etape is None:
+         # on demarre de la premiere etape
+         index_etape=0
+      else:
+         index_etape=self.etapes.index(etape)+1
+
+      try:
+         etape=self.etapes[index_etape]
+      except:
+         #derniere etape du jdc : rien a faire
+         return
+
+      context=self.get_contexte_avant(etape)
+
+      for e in self.etapes[index_etape:]:
+          e.control_sdprods(context)
+          e.update_context(context)
+
    def analyse(self):
       self.compile()
       if not self.cr.estvide():return
@@ -490,10 +524,11 @@ class JDC(I_OBJECT.OBJECT):
           tenir compte des modifications de l'utilisateur : création
           de commandes, nommage de concepts, etc.
       """
+      #print "reset_context",self,self.nom
       self.current_context={}
       self.index_etape_courante=0
-      for etape in self.etapes:
-          etape.reset_context()
+   #   for etape in self.etapes:
+   #       etape.reset_context()
 
    def del_sdprod(self,sd):
       """
@@ -580,8 +615,22 @@ class JDC(I_OBJECT.OBJECT):
       for child in self.etapes[index:]:
         child.replace_concept(old_sd,sd)
 
+   def update_concept_after_etape(self,etape,sd):
+      """
+          Met à jour les étapes du JDC qui sont après etape en fonction
+          de la modification (principalement nommage) du concept sd
+      """
+      if etape is None:
+         #On traite toutes les etapes
+         index=0
+      else:
+         index = self.etapes.index(etape)+1
+      if index == len(self.etapes) :
+         return # etape est la dernière étape du jdc ...on ne fait rien !
+      for child in self.etapes[index:]:
+        child.update_concept(sd)
+
    def dump_state(self):
-      print "dump_state"
       print "JDC.state: ",self.state
       for etape in self.etapes :
          print etape.nom+".state: ",etape.state
@@ -604,6 +653,9 @@ class JDC(I_OBJECT.OBJECT):
       #print self.recorded_units.get(None,(None,"",{}))[2]
       #print self.recorded_units.get(None,(None,"",{}))[2].get(None,(None,"",{}))
 
+   def changefichier(self,fichier):
+       self.fin_modif()
+
 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
    def register(self,etape):
       """
@@ -677,3 +729,30 @@ class JDC(I_OBJECT.OBJECT):
 
 #ATTENTION SURCHARGE : les methodes ci-dessous surchargent des methodes de Noyau et Validation : a reintegrer
 
+   def get_file(self,unite=None,fic_origine=''):
+      """
+          Retourne le nom du fichier correspondant à un numero d'unité
+          logique (entier) ainsi que le source contenu dans le fichier
+      """
+      if self.appli :
+         # Si le JDC est relié à une application maitre, on délègue la recherche
+         file,text= self.appli.get_file(unite,fic_origine)
+      else:
+         file = None
+         if unite != None:
+            if os.path.exists("fort."+str(unite)):
+               file= "fort."+str(unite)
+         if file == None :
+            raise AsException("Impossible de trouver le fichier correspondant"
+                               " a l unite %s" % unite)
+         if not os.path.exists(file):
+            raise AsException("%s n'est pas un fichier existant" % unite)
+         fproc=open(file,'r')
+         text=fproc.read()
+         fproc.close()
+      #if file == None : return None,None
+      text=string.replace(text,'\r\n','\n')
+      if file:
+         linecache.cache[file]=0,0,string.split(text,'\n'),file
+      return file,text
+
index 94f1bb3c0900b4e08e4d1853482f3f69cff5dc92..18e7ece7ed6cbb80b5b7dcf7ca14aa2b1db73d59 100644 (file)
@@ -64,13 +64,14 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          ou leve une exception
          --> utilisée par ops.POURSUITE et INCLUDE
     """
-    #print "get_contexte_jdc"
+    #print "get_contexte_jdc",self,self.nom
     try:
        # on essaie de créer un objet JDC auxiliaire avec un contexte initial
        # Attention get_contexte_avant retourne un dictionnaire qui contient
        # le contexte courant. Ce dictionnaire est reactualise regulierement.
        # Si on veut garder l'etat du contexte fige, il faut en faire une copie.
        context_ini = self.parent.get_contexte_avant(self).copy()
+       #print "get_contexte_jdc",context_ini.keys()
 
        # Indispensable avant de creer un nouveau JDC
        CONTEXT.unset_current_step()
@@ -85,9 +86,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        # En principe si la memorisation est faite au bon moment il n'est pas necessaire
        # de prendre cette precaution mais ce n'est pas vrai partout.
        old_recorded_units=self.recorded_units.copy()
-       #print "get_contexte_jdc",id(self.recorded_units)
-       #self.recorded_units.clear()
 
+       if fichier is None:fichier="SansNom"
        j=self.JdC_aux( procedure=text, nom=fichier,
                                 appli=self.jdc.appli,
                                 cata=self.jdc.cata,
@@ -102,9 +102,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        # On récupère les étapes internes (pour validation)
        self.etapes=j.etapes
        self.jdc_aux=j
-       #print "get_contexte_jdc",id(self.etapes)
     except:
-       traceback.print_exc()
        # On force le contexte (etape courante) à self
        CONTEXT.unset_current_step()
        CONTEXT.set_current_step(self)
@@ -129,8 +127,6 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
 
     # Si aucune erreur rencontrée
     # On recupere le contexte de l'include verifie
-    #print "context_ini",j.context_ini
-    #print "g_context",j.g_context
     try:
        j_context=j.get_verif_contexte()
     except:
@@ -138,8 +134,6 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        CONTEXT.set_current_step(self)
        raise
 
-    #print "context_ini",j.context_ini
-
     # On remplit le dictionnaire des concepts produits inclus
     # en retirant les concepts présents dans le  contexte initial
     # On ajoute egalement le concept produit dans le sds_dict du parent
@@ -157,11 +151,9 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.index_etape_courante=j.index_etape_courante
     self.jdc_aux=j
 
-    # XXX j.supprime() ???
     # On rétablit le contexte (etape courante) à self
     CONTEXT.unset_current_step()
     CONTEXT.set_current_step(self)
-    #print "context_ini",self.jdc_aux.context_ini
 
     return j_context
 
@@ -204,17 +196,13 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       
   def control_sdprods(self,d):
       """
-          Cette methode doit updater le contexte fournit par
-          l'appelant en argument (d) en fonction de sa definition
-          tout en verifiant que ses concepts produits ne sont pas
-          deja definis dans le contexte
+          Cette methode doit verifier que les concepts produits par la 
+          commande ne sont pas incompatibles avec le contexte fourni (d).
+          Si c'est le cas, le concept produit doit etre supprime
+          Si la macro a elle meme des etapes, elle doit propager
+          le traitement (voir methode control_jdc_context_apres de I_JDC)
       """
-      if hasattr(self,"fichier_unite"):
-         self.update_fichier_init(self.fichier_unite)
-         self.init_modif()
-
-      if type(self.definition.op_init) == types.FunctionType:
-        apply(self.definition.op_init,(self,d))
+      #print "I_MACRO_ETAPE.control_sdprods",d.keys(),self.nom,self.sd and self.sd.nom
       if self.sd:
         if d.has_key(self.sd.nom):
            # Le concept est deja defini
@@ -225,18 +213,30 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
               # Redefinition du concept, on l'annule
               #XXX on pourrait simplement annuler son nom pour conserver les objets
               # l'utilisateur n'aurait alors qu'a renommer le concept (faisable??)
-              self.sd=self.reuse=self.sdnom=None
               self.init_modif()
-        else:
-           # Le concept n'est pas defini, on peut updater d
-           d[self.sd.nom]=self.sd
+              sd=self.sd
+              self.sd=self.reuse=self.sdnom=None
+              self.parent.delete_concept_after_etape(self,sd)
+              self.fin_modif()
+
       # On verifie les concepts a droite du signe =
-      for co in self.sdprods:
+      self.init_modif()
+      sdprods=self.sdprods[:]
+      self.sdprods=[]
+      for co in sdprods:
         if d.has_key(co.nom) and co is not d[co.nom] :
+           #nettoie les mots cles de l'étape qui ont comme valeur co
            self.delete_concept(co)
+           #supprime les references a co dans les etapes suivantes
+           self.parent.delete_concept_after_etape(self,co)
         else:
-           d[co.nom]=co
+           self.sdprods.append(co)
+      self.fin_modif()
        
+      for e in self.etapes:
+          e.control_sdprods(d)
+          e.update_context(d)
+
   def supprime_sdprod(self,sd):
       """
          Supprime le concept produit sd s'il est produit par l'etape
@@ -294,6 +294,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          # La macro a un jdc auxiliaire inclus. On demande la reinitialisation du contexte
          self.jdc_aux.reset_context()
 
+  def update_concept(self,sd):
+      I_ETAPE.ETAPE.update_concept(self,sd)
+      for etape in self.etapes:
+          etape.update_concept(sd)
+
   def delete_concept(self,sd):
       """
           Fonction : Mettre a jour les mots cles de l etape et eventuellement
@@ -321,6 +326,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
        Tente de changer le fichier include. Le precedent include est conservé
        dans old_xxx
     """
+    #print "change_fichier_init",new_fic
     if not hasattr(self,'fichier_ini'):
        self.fichier_ini=None
        self.fichier_text=None
@@ -365,6 +371,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.reevalue_sd_jdc()
 
     self.fin_modif()
+    if self.old_jdc_aux:
+       self.old_jdc_aux.close()
 
   def restore_fichier_init(self):
     """
@@ -400,6 +408,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.current_context=self.jdc_aux.current_context
     self.index_etape_courante=self.jdc_aux.index_etape_courante
     self.contexte_fichier_init = j_context
+    self.fichier_err = None
 
     # On enregistre la modification de fichier
     self.init_modif()
@@ -416,9 +425,61 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.old_contexte_fichier_init=self.old_context
     self.reevalue_sd_jdc()
     self.fin_modif()
+    if self.old_jdc_aux:
+       self.old_jdc_aux.close()
 
     self.jdc_aux.force_contexte(self.g_context)
 
+  def build_include(self,fichier,text):
+    import Extensions.jdc_include
+    self.JdC_aux=Extensions.jdc_include.JdC_include
+    # un include partage la table des unites avec son parent (jdc)
+    self.recorded_units=self.parent.recorded_units
+    self.build_jdcaux(fichier,text)
+
+  def build_poursuite(self,fichier,text):
+    import Extensions.jdc_include
+    self.JdC_aux=Extensions.jdc_include.JdC_poursuite
+    # une poursuite a sa propre table d'unites
+    self.recorded_units={}
+    self.build_jdcaux(fichier,text)
+
+  def build_jdcaux(self,fichier,text):
+    """
+         Cree un jdc auxiliaire initialise avec text. 
+         Initialise le nom du fichier associé avec fichier
+         N'enregistre pas d'association unite <-> fichier
+    """
+    self.fichier_ini = fichier
+    self.fichier_text= text
+    self.fichier_unite=None
+    self.fichier_err = None
+    try:
+       contexte = self.get_contexte_jdc(fichier,text)
+       if contexte is None :
+          # Impossible de construire le jdc auxiliaire (sortie par None)
+          # On simule une sortie par exception
+          raise Exception("Impossible de construire le jeu de commandes correspondant au fichier")
+       else:
+          # La construction du jdc auxiliaire est allée au bout
+          self.contexte_fichier_init = contexte
+       self.init_modif()
+       self.fin_modif()
+    except:
+       # Impossible de construire le jdc auxiliaire (sortie par exception)
+       l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
+       if self.jdc.appli:
+          self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
+                                        message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
+                                       )
+       self.g_context={}
+       self.etapes=[]
+       self.jdc_aux=None
+       self.fichier_err = string.join(l)
+       self.contexte_fichier_init={}
+       self.init_modif()
+       self.fin_modif()
+       raise
 
   def make_contexte_include(self,fichier,text):
     """
@@ -461,58 +522,60 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
       self.fichier_err = None
       self.old_contexte_fichier_init=old_context
       self.reevalue_sd_jdc()
-      #print "reevalue_fichier_init",self.jdc_aux.context_ini
 
   def update_fichier_init(self,unite):
       """Reevalue le fichier init sans demander (dans la mesure du possible) a l'utilisateur 
          les noms des fichiers
          Ceci suppose que les relations entre unites et noms ont été memorisees préalablement
+         L'include a été initialisé précédemment. Le jdc auxiliaire existe.
       """
-      #print "update_fichier_init",unite
-      self.fichier_err=None
+      #print "update_fichier_init",unite,self.fichier_unite 
       self.old_contexte_fichier_init=self.contexte_fichier_init
       old_fichier_ini=self.fichier_ini
+      if not hasattr(self,"jdc_aux"):self.jdc_aux=None
+      old_jdc_aux=self.jdc_aux
 
       #print "update_fichier_init",self,self.parent,self.parent.recorded_units
 
-      #if unite != self.fichier_unite or not self.parent.recorded_units.has_key(unite):
-      if not self.parent.recorded_units.has_key(unite):
-         # Le numero d'unite a ete change. Le nouveau numero ne fait pas partie des numeros
-         # enregistres.
+      if self.fichier_unite is None:
+         # L'unité n'était pas définie précédemment. On ne change que l'unite
+         #print "update_fichier_init","pas de changement dans include"
+         self.fichier_unite=unite
+         return
+      elif unite == self.fichier_unite :
+         # L'unité n'a pas changé
+         #print "update_fichier_init","pas de changement dans include 3"
+         return
+      elif unite != self.fichier_unite :
+         # L'unité était définie précédemment. On remplace l'include 
+         #
          f,text=self.get_file_memo(unite=unite,fic_origine=self.parent.nom)
-         if f is not None:
+         if f is None:
+            # Le fichier associé n'a pas pu etre defini
+            # on change l'unite associée mais pas l'include
+            #print "update_fichier_init","pas de changement dans include 2"
+            self.fichier_unite=unite
+            return
+         else:
             self.fichier_ini = f
             self.fichier_text=text
+            self.fichier_unite=unite
          #print "update_fichier_init",self.recorded_units
-      else:
-         # Unite existante
-         f,text,units=self.parent.recorded_units[unite]
-         self.fichier_ini = f
-         self.fichier_text=text
-         self.recorded_units=units
 
-      if self.fichier_ini is None:
-         # Le fichier n'est pas défini
-         self.fichier_err="Le fichier associé n'est pas défini"
-         self.parent.change_unit(unite,self,self.fichier_unite)
-         self.g_context={}
-         self.etapes=[]
-         self.jdc_aux=None
-         self.contexte_fichier_init={}
-         self.parent.reset_context()
-         self.reevalue_sd_jdc()
-         return
+      #print "update_fichier_init",self.fichier_ini,self.fichier_text,self.fichier_unite
 
       if old_fichier_ini == self.fichier_ini:
          # Le fichier inclus n'a pas changé. On ne recrée pas le contexte
+         # mais on enregistre le changement d'association unite <-> fichier
          #print "update_fichier_init.fichier inchange",self.jdc_aux.context_ini
+         self.parent.record_unit(unite,self)
          return
 
       try:
+        self.fichier_err=None
         self.make_contexte_include(self.fichier_ini,self.fichier_text)
         # Les 3 attributs fichier_ini fichier_text recorded_units doivent etre corrects
         # avant d'appeler change_unit
-        self.parent.change_unit(unite,self,self.fichier_unite)
       except:
         # Erreurs lors de l'evaluation de text dans un JDC auxiliaire
         l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
@@ -520,21 +583,24 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
         # mais on n'utilise pas les concepts crees par ce fichier
         # on met l'etape en erreur : fichier_err=string.join(l)
         self.fichier_err=string.join(l)
-        self.parent.change_unit(unite,self,self.fichier_unite)
         self.g_context={}
         self.etapes=[]
         self.jdc_aux=None
         self.contexte_fichier_init={}
 
+      if old_jdc_aux:
+         old_jdc_aux.close()
+      self.parent.record_unit(unite,self)
       # Le contexte du parent doit etre reinitialise car les concepts 
       # produits ont changé
       self.parent.reset_context()
       # Si des concepts ont disparu lors du changement de fichier, on 
       # demande leur suppression
       self.reevalue_sd_jdc()
-      #print "update_fichier_init",self.jdc_aux.context_ini
+      #print "update_fichier_init",self.jdc_aux.context_ini.keys()
 
   def record_unite(self):
+      #print "record_unite",self.nom
       if self.nom == "POURSUITE":
          self.parent.record_unit(None,self)
       else:
@@ -546,7 +612,6 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          Initialise en plus recorded_units
       """
       #print "get_file_memo",unite,fic_origine,self,self.parent
-      #print self.parent.old_recorded_units
       #print self.parent.recorded_units
       if unite is None:
          # On est dans le cas d'une poursuite. On ne reutilise aucune unite de parent
@@ -555,14 +620,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
          # On est dans le cas d'un include. On reutilise toutes les unites de parent
          units=self.parent.recorded_units
 
-      #if self.parent.old_recorded_units.has_key(unite):
       if self.parent.recorded_units.has_key(unite):
          f,text,units=self.parent.recorded_units[unite]
-         #f,text,units=self.parent.old_recorded_units[unite]
-         #print id(self.recorded_units)
-         self.recorded_units=units
-         #print id(self.recorded_units)
-         return f,text
       elif self.jdc :
          f,text=self.jdc.get_file(unite=unite,fic_origine=fic_origine)
       else:
@@ -574,6 +633,37 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
                           message="Ce fichier ne sera pas pris en compte\n"+"Le fichier associé n'est pas défini")
       return f,text
 
+  def update_context(self,d):
+      """
+         Met à jour le contexte contenu dans le dictionnaire d
+         Une MACRO_ETAPE peut ajouter plusieurs concepts dans le contexte
+         Une fonction enregistree dans op_init peut egalement modifier le contexte
+      """
+      #print "update_context",self,self.nom,d.keys()
+      if hasattr(self,"jdc_aux") and self.jdc_aux:
+            #ATTENTION: update_context NE DOIT PAS appeler reset_context
+            # car il appelle directement ou indirectement update_context
+            # equivalent a reset_context. Evite les recursions
+            self.jdc_aux.context_ini=d.copy()
+            self.jdc_aux.current_context={}
+            self.jdc_aux.index_etape_courante=0
+            #ATTENTION: il ne faut pas utiliser self.jdc_aux.get_contexte_avant
+            #car cet appel conduit a des remontées multiples incohérentes dans le
+            # ou les parents. 
+            #get_context_avant appelle update_context qui NE DOIT PAS appeler get_contexte_avant
+            #On n'a besoin que d'un update local connaissant
+            # le contexte amont : d qui sert a reinitialiser self.context_ini
+            for e in self.etapes:
+                e.update_context(d)
+            return
+
+      if type(self.definition.op_init) == types.FunctionType:
+        apply(self.definition.op_init,(self,d))
+      if self.sd != None:d[self.sd.nom]=self.sd
+      for co in self.sdprods:
+        d[co.nom]=co
+      #print "update_context.fin",d.keys()
+
 #ATTENTION SURCHARGE : cette methode surcharge celle de Noyau (a garder en synchro)
   def get_file(self,unite=None,fic_origine=''):
       """Retourne le nom du fichier et le source correspondant a l'unite unite
@@ -616,7 +706,8 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
            raise
          self.JdC_aux=Extensions.jdc_include.JdC_include
 
-         if f is None:
+         #print "make_include",self.fichier_ini,self.fichier_text 
+         if f is None and not text:
              self.fichier_err="Le fichier INCLUDE n est pas defini"
              self.parent.record_unit(unite,self)
              raise Exception(self.fichier_err)
@@ -629,7 +720,7 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
            l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
            if self.jdc.appli:
               self.jdc.appli.affiche_alerte("Erreur lors de l'evaluation du fichier inclus",
-                                            message="Ce fichier ne sera pas pris en compte\n"+string.join(l)
+                                            message="Le contenu de ce fichier ne sera pas pris en compte\n"+string.join(l)
                                            )
            self.parent.record_unit(unite,self)
            self.g_context={}
@@ -671,11 +762,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
     self.JdC_aux=Extensions.jdc_include.JdC_include
     try:
        self.make_contexte_include(self.fichier_ini ,self.fichier_text)
-       self.parent.record_unit(self.fichier_unite,self)
+       #self.parent.record_unit(self.fichier_unite,self)
     except:
        l=traceback.format_exception_only("Fichier invalide",sys.exc_info()[1])
        self.fichier_err = string.join(l)
-       self.parent.record_unit(self.fichier_unite,self)
+       #self.parent.record_unit(self.fichier_unite,self)
        self.g_context={}
        self.etapes=[]
        self.jdc_aux=None
@@ -737,9 +828,11 @@ class MACRO_ETAPE(I_ETAPE.ETAPE):
            raise
          self.JdC_aux=Extensions.jdc_include.JdC_poursuite
          self.contexte_fichier_init={}
+         #print "make_poursuite",self.fichier_ini,self.fichier_text
 
          if f is None:
              self.fichier_err="Le fichier POURSUITE n'est pas defini"
+             self.jdc_aux=None
              self.parent.record_unit(None,self)
              raise Exception(self.fichier_err)
 
index af50e342387f9362be84c0f58b3f2f31b497dfe1..28bb21f1b8ef16260866641ae442c663eed744e4 100644 (file)
@@ -311,6 +311,10 @@ class MCCOMPO(I_OBJECT.OBJECT):
         if fils.parent.nom != self.nom : return 0
       return 1
 
+  def update_concept(self,sd):
+    for child in self.mc_liste :
+        child.update_concept(sd)
+
   def delete_concept(self,sd):
     """ 
         Inputs :
index f15824cb6d2f74d8c0c00a673679e9e62236d5b0..41aa9c0583b0776b9f59dd816820ab76d25a761b 100644 (file)
@@ -112,6 +112,10 @@ class MCList:
   def liste_mc_presents(self):
     return []
 
+  def update_concept(self,sd):
+    for child in self.data :
+        child.update_concept(sd)
+
   def delete_concept(self,sd):
     """ 
         Inputs :
index 83e9bb29cbaf40e93f3e93ea372b6d5bc961165b..4e6ff313552ccdf3cb0b74141710e799bd1ed258 100644 (file)
@@ -313,6 +313,11 @@ class MCSIMP(I_OBJECT.OBJECT):
        except:
          return None
 
+  def update_concept(self,sd):
+    if type(self.valeur) in (types.ListType,types.TupleType) :
+       if sd in self.valeur:self.fin_modif()
+    else:
+       if sd == self.valeur:self.fin_modif()
 
   def delete_concept(self,sd):
     """ 
index 0f4d28ea3233ad7c87e76a39148fbe8108892e0a..d794797bc37e1c4bfd6e0e79110ea34e62fbb14e 100644 (file)
@@ -137,3 +137,5 @@ class OBJECT:
      except:
         return ''
 
+  def update_concept(self,sd):
+     pass