From 5ba65bc73184e2986aae56f888ba8b87ff74b399 Mon Sep 17 00:00:00 2001 From: eficas <> Date: Thu, 16 Jun 2005 09:27:26 +0000 Subject: [PATCH] CCAR: modifications pour permettre l'edition des includes et poursuites 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) --- Aster/Cata/ops.py | 1 + Aster/Tests/princ.comm | 16 +++ Aster/Tests/princ.ini | 20 ++++ Aster/Tests/princl.11 | 3 + Aster/Tests/princl.12 | 15 +++ Aster/Tests/princl.14 | 11 ++ Aster/Tests/princl.35 | 5 + Editeur/appli.py | 2 +- Editeur/bureau.py | 11 +- Editeur/compomacro.py | 47 ++++++-- Editeur/eficas.py | 2 +- Editeur/jdcdisplay.py | 19 ++-- Editeur/macrodisplay.py | 1 + Editeur/panels.py | 3 + Editeur/treewidget.py | 26 ++--- Extensions/jdc_include.py | 91 ++++++++------- Ihm/I_ETAPE.py | 49 +++++---- Ihm/I_FORM_ETAPE.py | 3 + Ihm/I_JDC.py | 107 +++++++++++++++--- Ihm/I_MACRO_ETAPE.py | 225 +++++++++++++++++++++++++++----------- Ihm/I_MCCOMPO.py | 4 + Ihm/I_MCLIST.py | 4 + Ihm/I_MCSIMP.py | 5 + Ihm/I_OBJECT.py | 2 + 24 files changed, 492 insertions(+), 180 deletions(-) create mode 100644 Aster/Tests/princ.comm create mode 100644 Aster/Tests/princ.ini create mode 100644 Aster/Tests/princl.11 create mode 100644 Aster/Tests/princl.12 create mode 100644 Aster/Tests/princl.14 create mode 100644 Aster/Tests/princl.35 diff --git a/Aster/Cata/ops.py b/Aster/Cata/ops.py index 3b917d00..110eb96a 100644 --- a/Aster/Cata/ops.py +++ b/Aster/Cata/ops.py @@ -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 index 00000000..59f33a88 --- /dev/null +++ b/Aster/Tests/princ.comm @@ -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 index 00000000..a8865fbc --- /dev/null +++ b/Aster/Tests/princ.ini @@ -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 index 00000000..ef02b73e --- /dev/null +++ b/Aster/Tests/princl.11 @@ -0,0 +1,3 @@ +MAA=LIRE_MAILLAGE() + + diff --git a/Aster/Tests/princl.12 b/Aster/Tests/princl.12 new file mode 100644 index 00000000..eb15ffd4 --- /dev/null +++ b/Aster/Tests/princl.12 @@ -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 index 00000000..3ee3c9fe --- /dev/null +++ b/Aster/Tests/princl.14 @@ -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 index 00000000..4a9f4aab --- /dev/null +++ b/Aster/Tests/princl.35 @@ -0,0 +1,5 @@ + + +INCLUDE(UNITE=14,); + +DETRUIRE(CONCEPT=_F(NOM=None,),); \ No newline at end of file diff --git a/Editeur/appli.py b/Editeur/appli.py index 9478e5bc..1ca53a34 100644 --- a/Editeur/appli.py +++ b/Editeur/appli.py @@ -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): diff --git a/Editeur/bureau.py b/Editeur/bureau.py index 19aef955..5ee1dfa2 100644 --- a/Editeur/bureau.py +++ b/Editeur/bureau.py @@ -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 diff --git a/Editeur/compomacro.py b/Editeur/compomacro.py index 2c7d3c08..bafed554 100644 --- a/Editeur/compomacro.py +++ b/Editeur/compomacro.py @@ -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"), diff --git a/Editeur/eficas.py b/Editeur/eficas.py index 463ac547..c683ed5a 100644 --- a/Editeur/eficas.py +++ b/Editeur/eficas.py @@ -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 = ''): """ diff --git a/Editeur/jdcdisplay.py b/Editeur/jdcdisplay.py index 863c5b61..4400de16 100644 --- a/Editeur/jdcdisplay.py +++ b/Editeur/jdcdisplay.py @@ -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): """ diff --git a/Editeur/macrodisplay.py b/Editeur/macrodisplay.py index af5671e9..1be2e911 100644 --- a/Editeur/macrodisplay.py +++ b/Editeur/macrodisplay.py @@ -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): diff --git a/Editeur/panels.py b/Editeur/panels.py index a1ebed29..74b3b1d5 100644 --- a/Editeur/panels.py +++ b/Editeur/panels.py @@ -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 diff --git a/Editeur/treewidget.py b/Editeur/treewidget.py index e8718716..78b3a16c 100644 --- a/Editeur/treewidget.py +++ b/Editeur/treewidget.py @@ -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) diff --git a/Extensions/jdc_include.py b/Extensions/jdc_include.py index 94cc0163..39196a23 100644 --- a/Extensions/jdc_include.py +++ b/Extensions/jdc_include.py @@ -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): """ diff --git a/Ihm/I_ETAPE.py b/Ihm/I_ETAPE.py index 4664252b..f05dd1d3 100644 --- a/Ihm/I_ETAPE.py +++ b/Ihm/I_ETAPE.py @@ -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 : diff --git a/Ihm/I_FORM_ETAPE.py b/Ihm/I_FORM_ETAPE.py index f5e632ad..75cad81c 100644 --- a/Ihm/I_FORM_ETAPE.py +++ b/Ihm/I_FORM_ETAPE.py @@ -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 : diff --git a/Ihm/I_JDC.py b/Ihm/I_JDC.py index b043c48d..97984193 100644 --- a/Ihm/I_JDC.py +++ b/Ihm/I_JDC.py @@ -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 + diff --git a/Ihm/I_MACRO_ETAPE.py b/Ihm/I_MACRO_ETAPE.py index 94f1bb3c..18e7ece7 100644 --- a/Ihm/I_MACRO_ETAPE.py +++ b/Ihm/I_MACRO_ETAPE.py @@ -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) diff --git a/Ihm/I_MCCOMPO.py b/Ihm/I_MCCOMPO.py index af50e342..28bb21f1 100644 --- a/Ihm/I_MCCOMPO.py +++ b/Ihm/I_MCCOMPO.py @@ -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 : diff --git a/Ihm/I_MCLIST.py b/Ihm/I_MCLIST.py index f15824cb..41aa9c05 100644 --- a/Ihm/I_MCLIST.py +++ b/Ihm/I_MCLIST.py @@ -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 : diff --git a/Ihm/I_MCSIMP.py b/Ihm/I_MCSIMP.py index 83e9bb29..4e6ff313 100644 --- a/Ihm/I_MCSIMP.py +++ b/Ihm/I_MCSIMP.py @@ -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): """ diff --git a/Ihm/I_OBJECT.py b/Ihm/I_OBJECT.py index 0f4d28ea..d794797b 100644 --- a/Ihm/I_OBJECT.py +++ b/Ihm/I_OBJECT.py @@ -137,3 +137,5 @@ class OBJECT: except: return '' + def update_concept(self,sd): + pass -- 2.39.2