From: eficas <> Date: Wed, 3 Apr 2002 11:35:13 +0000 (+0000) Subject: CCAR: Modified Files: X-Git-Tag: CC_param_poursuite~428 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=757737ec737f71d6c88050a6ce0a12d6aaaac30c;p=modules%2Feficas.git CCAR: Modified Files: CCAR: Accas/A_JDC.py Accas/__init__.py Aster/prefs.py Aster/sdist.py CCAR: Editeur/Objecttreeitem.py Editeur/bureau.py CCAR: Editeur/compomacro.py Editeur/compooper.py CCAR: Editeur/compoproc.py Editeur/composimp.py Editeur/eficas.py CCAR: Editeur/jdcdisplay.py Editeur/menubar.py Editeur/treewidget.py CCAR: Extensions/commande_comm.py Extensions/commentaire.py CCAR: Extensions/interpreteur_formule.py Extensions/mcnuplet.py CCAR: Extensions/parametre.py Extensions/parametre_eval.py CCAR: Ihm/I_ETAPE.py Ihm/I_FORM_ETAPE.py Ihm/I_JDC.py CCAR: Ihm/I_MACRO_ETAPE.py Ihm/I_MCCOMPO.py Ihm/I_MCLIST.py CCAR: Ihm/I_MCSIMP.py Ihm/I_OBJECT.py Minicode/cata_saturne.py CCAR: Noyau/N_JDC.py Noyau/N_MACRO_ETAPE.py CCAR: generator/generator_aplat.py generator/generator_python.py CCAR: Added Files: CCAR: Accas/A_ASSD.py Ihm/I_ASSD.py Ihm/I_FONCTION.py CCAR: ---------------------------------------------------------------------- CCAR: Corrections du copier coller, de la création des concepts CO dans MACRO CCAR: et de points divers liés aux formules, et autres CCAR: ajoute possibilité de paramétrer l'appli dans prefs : choix des extensions CCAR: et des menus dans une certaine mesure. --- diff --git a/Accas/A_ASSD.py b/Accas/A_ASSD.py new file mode 100644 index 00000000..1fd9f3a2 --- /dev/null +++ b/Accas/A_ASSD.py @@ -0,0 +1,30 @@ + +from Ihm import I_ASSD +from Ihm import I_FONCTION +from Noyau import N_ASSD +from Noyau import N_GEOM +from Noyau import N_FONCTION +from Noyau import N_CO + +# On ajoute la classe ASSD dans l'héritage multiple pour recréer +# une hiérarchie d'héritage identique à celle de Noyau +# pour faire en sorte que isinstance(o,ASSD) marche encore après +# dérivation + +class ASSD(N_ASSD.ASSD,I_ASSD.ASSD):pass + +class assd(N_ASSD.assd,I_ASSD.ASSD,ASSD):pass + +class FONCTION(N_FONCTION.FONCTION,I_FONCTION.FONCTION,ASSD): + def __init__(self,etape=None,sd=None,reg='oui'): + N_FONCTION.FONCTION.__init__(self,etape=etape,sd=sd,reg=reg) + I_FONCTION.FONCTION.__init__(self,etape=etape,sd=sd,reg=reg) + +class fonction(N_FONCTION.fonction,I_FONCTION.fonction,ASSD): + def __init__(self,etape=None,sd=None,reg='oui'): + N_FONCTION.fonction.__init__(self,etape=etape,sd=sd,reg=reg) + I_FONCTION.fonction.__init__(self,etape=etape,sd=sd,reg=reg) + +class GEOM(N_GEOM.GEOM,I_ASSD.ASSD,ASSD):pass +class geom(N_GEOM.geom,I_ASSD.ASSD,ASSD):pass +class CO(N_CO.CO,I_ASSD.ASSD,ASSD):pass diff --git a/Accas/A_JDC.py b/Accas/A_JDC.py index b709e01f..34af1460 100644 --- a/Accas/A_JDC.py +++ b/Accas/A_JDC.py @@ -4,6 +4,8 @@ from Extensions import jdc from Ihm import I_JDC class JDC(jdc.JDC,I_JDC.JDC,V_JDC.JDC,N_JDC.JDC): + from A_ASSD import CO,assd + def __init__(self,*pos,**args): N_JDC.JDC.__init__(self,*pos,**args) V_JDC.JDC.__init__(self) diff --git a/Accas/__init__.py b/Accas/__init__.py index b61776b3..c0711f72 100644 --- a/Accas/__init__.py +++ b/Accas/__init__.py @@ -39,11 +39,11 @@ from A_EXCLUS import EXCLUS from A_ENSEMBLE import ENSEMBLE from A_A_CLASSER import A_CLASSER -from Noyau.N_ASSD import ASSD,assd -from Noyau.N_GEOM import GEOM,geom -from Noyau.N_FONCTION import FONCTION -from Noyau.N_FONCTION import fonction -from Noyau.N_CO import CO +from A_ASSD import ASSD,assd +from A_ASSD import GEOM,geom +from A_ASSD import FONCTION, fonction +from A_ASSD import CO + from Noyau.N__F import _F from Noyau.N_Exception import AsException diff --git a/Aster/prefs.py b/Aster/prefs.py index f3d82ae8..f125381e 100644 --- a/Aster/prefs.py +++ b/Aster/prefs.py @@ -19,3 +19,40 @@ CODE_PATH = None # Par défaut on utilise le répertoire icons dans Editeur ICONDIR=os.path.join(INSTALLDIR,'Editeur','icons') +labels= ('Fichier','Edition','Jeu de commandes', + # 'Catalogue','Browsers','Options' + ) + +extensions=['readercata','bureau', + # 'browser','options' + ] + +menu_defs={ 'bureau': [ + ('Fichier',[ + ('Nouveau','newJDC'), + ('Ouvrir','openJDC'), + ('Enregistrer','saveJDC'), + ('Enregistrer sous','saveasJDC'), + None, + ('Fermer','closeJDC'), + ('Quitter','exitEFICAS'), + ] + ), + ('Edition',[ + ('Copier','copy'), + ('Couper','cut'), + ('Coller','paste'), + ] + ), + ('Jeu de commandes',[ + ('Rapport de validation','visuCRJDC'), + # ('Fichier à plat','visu_a_plat'), + ('Fichier .py','visuJDC_py'), + ('Fichier source','visu_txt_brut_JDC'), + ('Paramètres Eficas','affichage_fichier_ini'), + ('Mots-clés inconnus','mc_inconnus'), + ] + ), + ] + } + diff --git a/Aster/sdist.py b/Aster/sdist.py index c992f405..e0a96057 100644 --- a/Aster/sdist.py +++ b/Aster/sdist.py @@ -21,7 +21,7 @@ import os,shutil,glob,sys import types -version="$Name: $"[7:-2] or 'Test' +version="$Name: $"[7:-2] or 'Test1_2' path_Noyau="../../../Tutorial/Superv" nom_distrib="Eficas"+version+"AsterSTA6" diff --git a/Editeur/Objecttreeitem.py b/Editeur/Objecttreeitem.py index 7e9ff7db..4a912c12 100644 --- a/Editeur/Objecttreeitem.py +++ b/Editeur/Objecttreeitem.py @@ -393,6 +393,12 @@ class SequenceTreeItem(ObjectTreeItem): def GetText(self): return " " + def additem(self,obj,pos): + # XXX Passer par addentite de MCList ??? + self.object.insert(pos,obj) + item = self.make_objecttreeitem(self.appli, obj.nom + ":", obj) + return item + def suppitem(self,item): if not self.object.isMCList():return 1 try : diff --git a/Editeur/bureau.py b/Editeur/bureau.py index 41840842..ca57be47 100644 --- a/Editeur/bureau.py +++ b/Editeur/bureau.py @@ -10,6 +10,7 @@ from tkMessageBox import showinfo,askyesno,showerror # Modules Eficas import splash +import prefs import convert import generator from jdcdisplay import JDCDISPLAY @@ -58,6 +59,14 @@ class BUREAU: ('Delete24',"delete","Supprime l'objet courant",'jdc'), ('Help24',"view_doc","Documentation de l'objet courant",'jdc') ) + try: + menu_defs=prefs.menu_defs['bureau'] + except: + pass + try: + button_defs=prefs.button_defs['bureau'] + except: + pass def __init__(self,appli,parent): self.parent=parent @@ -108,6 +117,7 @@ class BUREAU: cata_ord_dico=self.cata_ordonne_dico, appli=self.appli) self.JDCName=J.nom + self.fileName=None self.ShowJDC(J,self.JDCName) self.appli.toolbar.active_boutons() @@ -504,12 +514,16 @@ class BUREAU: """ if not hasattr(self,'JDC') : return titre = "fichier de commandes utilisateur" - texte = self.JDC.procedure - if texte == None: + #texte = self.JDC.procedure + #if texte == None: + if self.JDCDisplay_courant.fichier == None: self.appli.affiche_infos("Pas de fichier initial") - showerror("Impossible de visualiser le fichier initial","EFICAS ne peut visualiser le fichier \ - initial.\nIl s'agit d'un nouveau JDC") + showerror("Impossible de visualiser le fichier initial", + "EFICAS ne peut visualiser le fichier initial.\nIl s'agit d'un nouveau JDC") return + f=open(self.JDCDisplay_courant.fichier,'r') + texte=f.read() + f.close() self.visu_texte_JDC = Fenetre(self.appli,titre=titre,texte=texte) def affichage_fichier_ini(self): diff --git a/Editeur/compomacro.py b/Editeur/compomacro.py index ce439f5d..d4e79e67 100644 --- a/Editeur/compomacro.py +++ b/Editeur/compomacro.py @@ -23,8 +23,8 @@ import convert from widgets import Fenetre # -__version__="$Name: V1_1p1 $" -__Id__="$Id: compomacro.py,v 1.1.1.1 2001/12/04 15:38:22 eficas Exp $" +__version__="$Name: $" +__Id__="$Id: compomacro.py,v 1.1.1.1 2002/03/26 09:08:45 eficas Exp $" # class MACROPanel(panels.OngletPanel): @@ -187,6 +187,11 @@ class MACROTreeItem(compooper.EtapeTreeItem): Ce nom dépend de la validité de l'objet """ if self.object.isactif(): + if self.object.state != 'unchanged': + # Si des modifications ont eu lieu on force le calcul des concepts de sortie + # et celui du contexte glissant + self.object.get_type_produit(force=1) + self.object.parent.reset_context() if self.object.isvalid(): return "ast-green-square" else: @@ -274,10 +279,6 @@ class MACROTreeItem(compooper.EtapeTreeItem): def verif_condition_bloc(self): return self.object.verif_condition_bloc() - def nomme_sd(self,nom): - """ Lance la méthode de nommage de la SD """ - return self.object.nomme_sd(nom) - def get_noms_sd_oper_reentrant(self): return self.object.get_noms_sd_oper_reentrant() diff --git a/Editeur/compooper.py b/Editeur/compooper.py index eceb5cf8..0cf43cb7 100644 --- a/Editeur/compooper.py +++ b/Editeur/compooper.py @@ -189,7 +189,9 @@ class EtapeTreeItem(Objecttreeitem.ObjectTreeItem): def nomme_sd(self,nom): """ Lance la méthode de nommage de la SD """ - return self.object.nomme_sd(nom) + test,mess= self.object.nomme_sd(nom) + if test:self.object.parent.reset_context() + return test,mess def is_reentrant(self): return self.object.is_reentrant() diff --git a/Editeur/compoproc.py b/Editeur/compoproc.py index 7cbc5edf..f802546f 100644 --- a/Editeur/compoproc.py +++ b/Editeur/compoproc.py @@ -130,10 +130,6 @@ class ProcEtapeTreeItem(compooper.EtapeTreeItem): def verif_condition_bloc(self): return self.object.verif_condition_bloc() - def nomme_sd(self,nom): - """ Lance la méthode de nommage de la SD """ - return self.object.nomme_sd(nom) - def get_noms_sd_oper_reentrant(self): return self.object.get_noms_sd_oper_reentrant() diff --git a/Editeur/composimp.py b/Editeur/composimp.py index d7ec659b..bd6f6d20 100644 --- a/Editeur/composimp.py +++ b/Editeur/composimp.py @@ -5,13 +5,16 @@ # SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND # REDISTRIBUTION OF THIS FILE. # ====================================================================== +# Modules Python import string,types,os from Tkinter import * import Pmw from tkFileDialog import * from tkMessageBox import showinfo from copy import copy,deepcopy +import traceback +# Modules Eficas import Objecttreeitem import prefs import panels @@ -51,7 +54,8 @@ class newSIMPPanel(panels.OngletPanel): def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'): """ - Enregistre val comme valeur de self.node.item.object SANS faire de test de validité + Enregistre val comme valeur de self.node.item.object SANS + faire de test de validité """ if self.parent.modified == 'n' : self.parent.init_modif() if name != None: @@ -878,7 +882,7 @@ class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel): self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center') # affichage du bouton 'Nouveau concept' self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ", - items = ('OUI','NON'),menubutton_width=10) + items = ('NON','OUI'),menubutton_width=10) self.b_co.configure(command = lambda e,s=self : s.ask_new_concept()) self.b_co.place(relx=0.05,rely=0.6,anchor='w') self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :') @@ -890,7 +894,6 @@ class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel): self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie) self.aide = Label(self.frame_valeur, text = aide) self.aide.place(relx=0.5,rely=0.85,anchor='n') - self.b_co.invoke('NON') # affichage de la valeur courante self.display_valeur() @@ -902,13 +905,68 @@ class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel): pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour entrer le nom d'un concept non encore existant""" + def valid_valeur(self): + """ + Teste si la valeur fournie par l'utilisateur est une valeur permise : + - si oui, l'enregistre + - si non, restaure l'ancienne valeur + """ + if self.parent.modified == 'n' : self.parent.init_modif() + valeur = self.get_valeur() + print "valid_valeur ",valeur + self.erase_valeur() + anc_val = self.node.item.get_valeur() + print "anc_val ",anc_val + test_CO=self.node.item.is_CO(anc_val) + test = self.node.item.set_valeur(valeur) + if not test : + mess = "impossible d'évaluer : %s " %`valeur` + self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée :"+mess) + return + elif self.node.item.isvalid() : + self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée') + if test_CO: + # il faut egalement propager la destruction de l'ancien concept + self.node.item.delete_valeur_co(valeur=anc_val) + # et on force le recalcul des concepts de sortie de l'etape + self.node.item.object.etape.get_type_produit(force=1) + # et le recalcul du contexte + self.node.item.object.etape.parent.reset_context() + self.node.parent.select() + else : + cr = self.node.item.get_cr() + mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal() + self.record_valeur(anc_val,mess=mess) + return + if self.node.item.get_position()=='global': + self.node.etape.verif_all() + elif self.node.item.get_position()=='global_jdc': + self.node.racine.verif_all() + else : + self.node.parent.verif() + self.node.update() + def valid_nom_concept_co(self,event=None): """ Lit le nom donné par l'utilisateur au concept de type CO qui doit être la valeur du MCS courant et stocke cette valeur """ + if self.parent.modified == 'n' : self.parent.init_modif() + anc_val = self.node.item.get_valeur() nom_concept = self.entry_co.get() - self.node.item.set_valeur_co(nom_concept) + test,mess=self.node.item.set_valeur_co(nom_concept) + if not test: + # On n'a pas pu créer le concept + self.parent.appli.affiche_infos(mess) + return + elif self.node.item.isvalid() : + self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée') + self.node.parent.select() + else : + cr = self.node.item.get_cr() + mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal() + self.record_valeur(anc_val,mess=mess) + return if self.node.item.get_position()=='global': self.node.etape.verif_all() elif self.node.item.get_position()=='global_jdc': @@ -932,6 +990,9 @@ class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel): self.label_valeur.place_forget() self.entry_co.focus() elif new_concept == 'NON': + # On est passe de OUI à NON, on supprime la valeur + self.node.item.delete_valeur_co() + self.record_valeur(name=None,mess="Suppression CO enregistrée") self.label_co.place_forget() self.entry_co.place_forget() self.l_resu.place(relx=0.05,rely=0.7) @@ -942,14 +1003,40 @@ class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel): Affiche la valeur de l'objet pointé par self """ valeur = self.node.item.get_valeur() - if valeur == None : return # pas de valeur à afficher ... + if valeur == None or valeur == '': + self.valeur_choisie.set('') + return # pas de valeur à afficher ... # il faut configurer le bouton si la valeur est un objet CO # sinon afficher le nom du concept dans self.valeur_choisie - if valeur.__class__.__name__ != 'CO': - self.valeur_choisie.set(valeur.nom) - else: + if self.node.item.is_CO(): self.b_co.invoke('OUI') self.entry_co.insert(0,valeur.nom) + else: + self.valeur_choisie.set(valeur.nom) + + def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'): + """ + Enregistre val comme valeur de self.node.item.object SANS faire de test de validité + """ + if self.parent.modified == 'n' : self.parent.init_modif() + if name != None: + valeur =name + else : + self.entry_co.delete(0,END) + valeur= self.entry_co.get() + self.node.item.set_valeur_co(valeur) + self.parent.appli.affiche_infos(mess) + # On met a jour le display dans le panneau + self.display_valeur() + if self.node.item.get_position()=='global': + self.node.etape.verif_all() + elif self.node.item.get_position()=='global_jdc': + self.node.racine.verif_all() + else : + self.node.parent.verif() + if self.node.item.isvalid(): + self.node.parent.select() + self.node.update() class UNIQUE_BASE_Panel(UNIQUE_Panel): @@ -1135,7 +1222,6 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem): else: # on attend un entier, un réel ou une string self.panel = UNIQUE_BASE_Panel - def SetText(self, text): try: @@ -1218,42 +1304,47 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem): def GetMinMax(self): """ Retourne les valeurs min et max de la définition de object """ return self.object.get_min_max() - - def GetMultiplicite(self): - """ A préciser. - Retourne la multiplicité des valeurs affectées à l'objet - représenté par l'item. Pour le moment retourne invariablement 1. - """ - return 1 - - def GetType(self): - """ Retourne le type de valeur attendu par l'objet représenté par l'item. - """ - return self.object.get_type() - - def GetIntervalle(self): - """ Retourne le domaine de valeur attendu par l'objet représenté par l'item. - """ - return self.object.getintervalle() - - def IsInIntervalle(self,valeur): - """ Retourne 1 si la valeur est dans l'intervalle permis par - l'objet représenté par l'item. - """ - return self.object.isinintervalle(valeur) + + def GetMultiplicite(self): + """ A préciser. + Retourne la multiplicité des valeurs affectées à l'objet + représenté par l'item. Pour le moment retourne invariablement 1. + """ + return 1 + + def GetType(self): + """ + Retourne le type de valeur attendu par l'objet représenté par l'item. + """ + return self.object.get_type() + + def GetIntervalle(self): + """ + Retourne le domaine de valeur attendu par l'objet représenté + par l'item. + """ + return self.object.getintervalle() + + def IsInIntervalle(self,valeur): + """ + Retourne 1 si la valeur est dans l'intervalle permis par + l'objet représenté par l'item. + """ + return self.object.isinintervalle(valeur) def set_valeur_co(self,nom_co): """ Affecte au MCS pointé par self l'objet de type CO et de nom nom_co """ - self.object.set_valeur_co(nom_co) + return self.object.set_valeur_co(nom_co) def get_sd_avant_du_bon_type(self): """ Retourne la liste des noms des SD présentes avant l'étape qui contient le MCS pointé par self et du type requis par ce MCS """ - return self.object.jdc.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type) + return self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape, + self.object.definition.type) def GetListeValeurs(self) : """ Retourne la liste des valeurs de object """ @@ -1272,6 +1363,34 @@ class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem): - retourne 'valeur' (chaîne de caractères) sinon """ return self.object.eval_valeur(valeur) + def is_CO(self,valeur=None): + """ + Indique si valeur est un concept produit de la macro + Cette méthode n'a de sens que pour un MCSIMP d'une MACRO + Si valeur vaut None on teste la valeur du mot cle + """ + # Pour savoir si un concept est un nouveau concept de macro + # on regarde s'il est présent dans l'attribut sdprods de l'étape + # ou si son nom de classe est CO. + # Il faut faire les 2 tests car une macro non valide peut etre + # dans un etat pas tres catholique avec des CO pas encore types + # et donc pas dans sdprods (resultat d'une exception dans type_sdprod) + if not valeur:valeur=self.object.valeur + if valeur in self.object.etape.sdprods:return 1 + if type(valeur) is not types.ClassType:return 0 + if valeur.__class__.__name__ == 'CO':return 1 + return 0 + + def delete_valeur_co(self,valeur=None): + """ + Supprime la valeur du mot cle (de type CO) + il faut propager la destruction aux autres etapes + """ + if not valeur : valeur=self.object.valeur + # XXX faut il vraiment appeler del_sdprod ??? + #self.object.etape.parent.del_sdprod(valeur) + self.object.etape.parent.delete_concept(valeur) + import Accas treeitem = SIMPTreeItem objet = Accas.MCSIMP diff --git a/Editeur/eficas.py b/Editeur/eficas.py index c1d683c1..e8d46db4 100644 --- a/Editeur/eficas.py +++ b/Editeur/eficas.py @@ -17,7 +17,10 @@ from widgets import Fenetre class EFICAS(appli.APPLI): - extensions=['readercata','bureau','browser','options'] + try: + from prefs import extensions + except: + extensions=['readercata','bureau','browser','options'] def get_texte_infos(self): texte=appli.APPLI.get_texte_infos(self) diff --git a/Editeur/jdcdisplay.py b/Editeur/jdcdisplay.py index d85ab06a..5d068aa1 100644 --- a/Editeur/jdcdisplay.py +++ b/Editeur/jdcdisplay.py @@ -148,7 +148,7 @@ class JDCDISPLAY: Ne permet que la copie d'objets de type Commande ou MCF """ objet_a_copier = self.appli.noeud_a_editer.item.get_copie_objet() - if objet_a_copier.__class__.__name__ in ('ETAPE','PROC_ETAPE','MACRO_ETAPE'): + if objet_a_copier.__class__.__name__ in ('ETAPE','PROC_ETAPE','MACRO_ETAPE','FORM_ETAPE'): self.doPaste_Commande(objet_a_copier) elif objet_a_copier.__class__.__name__ == "MCFACT": self.doPaste_MCF(objet_a_copier) @@ -159,14 +159,16 @@ class JDCDISPLAY: def doPaste_Commande(self,objet_a_copier): """ - Réalise la copie de l'objet passé en argument qui est nécessairement une commande + Réalise la copie de l'objet passé en argument qui est nécessairement + une commande """ # il faut vérifier que le noeud sélectionné (noeud courant) est bien # une commande ou un JDC sinon la copie est impossible ... if self.node_selected.item.isCommande() : child = self.node_selected.append_brother(objet_a_copier,retour='oui') elif self.node_selected.item.isJdc() : - child = self.node_selected.append_child(objet_a_copier,retour='oui') + child = self.node_selected.append_child(objet_a_copier,pos='first', + retour='oui') else: showinfo("Copie impossible", "Vous ne pouvez coller la commande copiée à ce niveau de l'arborescence !") @@ -195,10 +197,17 @@ class JDCDISPLAY: child = self.node_selected.append_child(objet_a_copier,retour='oui') elif self.node_selected.item.isMCList() : # le noeud courant est une MCList - child = self.node_selected.parent.append_child(objet_a_copier,retour='oui') + child = self.node_selected.parent.append_child(objet_a_copier,pos='first',retour='oui') elif self.node_selected.item.isMCFact(): # le noeud courant est un MCFACT - child = self.node_selected.parent.append_child(objet_a_copier,retour='oui') + if self.node_selected.parent.item.isMCList(): + # le noeud selectionne est un MCFACT dans une MCList + child = self.node_selected.parent.append_child(objet_a_copier, + pos=self.node_selected.item, + retour='oui') + else: + # le noeud MCFACT selectionne n'est pas dans une MCList + child = self.node_selected.parent.append_child(objet_a_copier,retour='oui') else: showinfo("Copie impossible", "Vous ne pouvez coller le mot-clé facteur copié à ce niveau de l'arborescence !") diff --git a/Editeur/menubar.py b/Editeur/menubar.py index ad2366e8..dd1f8d1d 100644 --- a/Editeur/menubar.py +++ b/Editeur/menubar.py @@ -12,7 +12,10 @@ class MENUBAR: self.parent.configure(menu=self.menubar) self.init() - labels= ('Fichier','Edition','Jeu de commandes','Catalogue','Browsers','Options') + try: + from prefs import labels + except: + labels= ('Fichier','Edition','Jeu de commandes','Catalogue','Browsers','Options') def init(self): self.menudict={} @@ -21,11 +24,3 @@ class MENUBAR: self.menudict[label]=menu self.menubar.add_cascade(label=label,menu=menu) - #self.optionmenu.add_command(label='Catalogue développeur',command=self.choix_cata_developpeur) - - #self.browsermenu.add_command(label='Browser catalogue',command = self.browser_catalogue) - #self.browsermenu.add_command(label='Shell',command = self.shell) - #self.browsermenu.add_command(label='Editeur catalogue',command = self.edite_catalogue) - - - diff --git a/Editeur/treewidget.py b/Editeur/treewidget.py index c80538f9..8b505029 100644 --- a/Editeur/treewidget.py +++ b/Editeur/treewidget.py @@ -14,7 +14,7 @@ import images # __version__="$Name: $" -__Id__="$Id: treewidget.py,v 1.1.1.1 2002/03/26 09:08:45 eficas Exp $" +__Id__="$Id: treewidget.py,v 1.2 2002/03/27 16:20:02 eficas Exp $" # Fonte_Standard = fontes.standard @@ -523,21 +523,23 @@ class Node : def full_creation(self,name,pos=None): """ - Interface avec ACCAS : création de l'objet de nom name et - du noeud associé. Retourne le noeud fils ainsi créé + Interface avec ACCAS : création de l'objet de nom name et + du noeud associé. Retourne le noeud fils ainsi créé """ item = self.item.additem(name,pos) if item == None or item == 0: # impossible d'ajouter le noeud de nom : name return 0 nature = item.get_nature() - #if nature =="COMMANDE" or nature == "OPERATEUR" or nature == "PROCEDURE": if nature in ("COMMANDE","OPERATEUR","PROCEDURE","COMMENTAIRE", "PARAMETRE","COMMANDE_COMMENTARISEE","PARAMETRE_EVAL"): # on veut ajouter une commande ou un commentaire ou un paramètre # il ne faut pas rechercher un même objet déjà existant # à modifier : il faut tester l'attribut 'repetable' enfant = None + elif self.item.object.isMCList(): + # Dans ce cas on ne fait pas de remplacement. On ne cherche pas un objet de meme nom + enfant=None else : enfant = self.get_node_fils(item.get_nom()) if enfant : @@ -613,6 +615,9 @@ class Node : # on donne la position depuis l'extérieur # (appel de append_child par append_brother par exemple) index = pos + elif type(pos) == types.InstanceType: + # pos est un item. Il faut inserer name apres pos + index = self.item.get_index(pos) +1 else : if type(name) == types.InstanceType: index = self.item.get_index_child(name.nom) diff --git a/Extensions/commande_comm.py b/Extensions/commande_comm.py index 68bd102d..adbf3bab 100644 --- a/Extensions/commande_comm.py +++ b/Extensions/commande_comm.py @@ -30,6 +30,7 @@ class COMMANDE_COMM: self.definition=self self.nom = '' self.niveau = self.parent.niveau + self.actif=1 #self.appel = N_utils.callee_where(niveau=2) if reg=='oui' : self.register() diff --git a/Extensions/commentaire.py b/Extensions/commentaire.py index 733a2016..64c3c750 100644 --- a/Extensions/commentaire.py +++ b/Extensions/commentaire.py @@ -145,5 +145,11 @@ class COMMENTAIRE : """ return [] + def get_sdprods(self,nom_sd): + """ + Retourne les concepts produits par la commande + """ + return None + diff --git a/Extensions/interpreteur_formule.py b/Extensions/interpreteur_formule.py index 7e2dbdf9..ad4db800 100644 --- a/Extensions/interpreteur_formule.py +++ b/Extensions/interpreteur_formule.py @@ -145,6 +145,8 @@ class Interpreteur_Formule: texte = [texte,] for text_arg in texte: text_arg = string.replace(text_arg,'\n','') + # Enleve les espaces + text_arg = string.replace(text_arg,' ','') try: self.l_operateurs.append(self.split_operateurs(text_arg)) except InterpreteurException,e: diff --git a/Extensions/mcnuplet.py b/Extensions/mcnuplet.py index da997b6d..b3753a84 100644 --- a/Extensions/mcnuplet.py +++ b/Extensions/mcnuplet.py @@ -32,6 +32,7 @@ class MCNUPLET(V_MCCOMPO.MCCOMPO,N_MCCOMPO.MCCOMPO): self.niveau = None self.etape = None self.state = 'undetermined' + self.actif=1 self.mc_liste=self.build_mc() def build_mc(self): diff --git a/Extensions/parametre.py b/Extensions/parametre.py index 94f028f0..7e18bc16 100644 --- a/Extensions/parametre.py +++ b/Extensions/parametre.py @@ -33,6 +33,7 @@ class PARAMETRE : self.definition=self self.jdc = self.parent = CONTEXT.get_current_step() self.niveau=self.parent.niveau + self.actif=1 self.register() def interprete_valeur(self,val): diff --git a/Extensions/parametre_eval.py b/Extensions/parametre_eval.py index a9685498..8518aa46 100644 --- a/Extensions/parametre_eval.py +++ b/Extensions/parametre_eval.py @@ -36,6 +36,7 @@ class PARAMETRE_EVAL(parametre.PARAMETRE) : self.jdc = self.parent = CONTEXT.get_current_step() self.definition=self self.niveau = self.parent.niveau + self.actif=1 # Ceci est-il indispensable ??? #self.appel = N_utils.callee_where(niveau=2) self.register() diff --git a/Ihm/I_ASSD.py b/Ihm/I_ASSD.py new file mode 100644 index 00000000..cd08c8c9 --- /dev/null +++ b/Ihm/I_ASSD.py @@ -0,0 +1,4 @@ + +class ASSD: + def __repr__(self): + return "concept %s de type %s" % (self.get_name(),self.__class__.__name__) diff --git a/Ihm/I_ETAPE.py b/Ihm/I_ETAPE.py index d6f6f58c..35351a44 100644 --- a/Ihm/I_ETAPE.py +++ b/Ihm/I_ETAPE.py @@ -63,7 +63,8 @@ class ETAPE(I_MCCOMPO.MCCOMPO): """ if self.isvalid() : if type(self.definition.op_init) == types.FunctionType : - apply(self.definition.op_init,(self,self.master.g_context)) + # XXX Normalement en mode editeur g_context ne peut pas etre utilisé + apply(self.definition.op_init,(self,self.parent.g_context)) self.state = 'modified' def nomme_sd(self,nom) : @@ -234,13 +235,11 @@ class ETAPE(I_MCCOMPO.MCCOMPO): etape.state = 'modified' etape.reuse = None etape.sdnom = None + etape.etape=etape etape.mc_liste=[] for objet in self.mc_liste: new_obj = objet.copy() - new_obj.parent = etape - if hasattr(new_obj,'isMcList') : - if new_obj.isMCList() : - new_obj.init(new_obj.nom,etape) + new_obj.reparent(etape) etape.mc_liste.append(new_obj) return etape @@ -274,3 +273,20 @@ class ETAPE(I_MCCOMPO.MCCOMPO): l.extend(child.get_sd_utilisees()) return l + def get_genealogie(self): + """ + Retourne la liste des noms des ascendants de l'objet self + en s'arretant à la première ETAPE rencontrée + """ + return [self.nom] + + def reparent(self,parent): + """ + Cette methode sert a reinitialiser la parente de l'objet + """ + self.parent=parent + self.jdc=parent.get_jdc_root() + self.etape=self + for mocle in self.mc_liste: + mocle.reparent(self) + diff --git a/Ihm/I_FONCTION.py b/Ihm/I_FONCTION.py new file mode 100644 index 00000000..44f6a170 --- /dev/null +++ b/Ihm/I_FONCTION.py @@ -0,0 +1,22 @@ +from I_ASSD import ASSD + +class FONCTION(ASSD): + def __init__(self,etape=None,sd=None,reg='oui'): + #ASSD.__init__(self,etape=etape,sd=sd,reg=reg) + if reg=='oui': + self.jdc.register_fonction(self) + + def get_formule(self): + """ + Retourne une formule décrivant self sous la forme d'un tuple : + (nom,type_retourne,arguments,corps) + """ + if hasattr(self.etape,'get_formule'): + # on est dans le cas d'une formule Aster + return self.etape.get_formule() + else: + # on est dans le cas d'une fonction + return (self.nom,'REEL','(REEL:x)','''bidon''') + +class fonction(FONCTION) : pass + diff --git a/Ihm/I_FORM_ETAPE.py b/Ihm/I_FORM_ETAPE.py index 51100165..c45aa676 100644 --- a/Ihm/I_FORM_ETAPE.py +++ b/Ihm/I_FORM_ETAPE.py @@ -56,6 +56,15 @@ class FORM_ETAPE(MACRO_ETAPE): else: return '' + def get_formule(self): + """ + Retourne un tuple décrivant la formule : + (nom,type_retourne,arguments,corps) + """ + t,a,c = self.analyse_formule() + n = self.get_nom() + return (n,t,a,c) + def verif_arguments(self,arguments = None): """ Vérifie si les arguments passés en argument (si aucun prend les arguments courants) diff --git a/Ihm/I_JDC.py b/Ihm/I_JDC.py index 2c26ab8e..1765b2c5 100644 --- a/Ihm/I_JDC.py +++ b/Ihm/I_JDC.py @@ -6,9 +6,8 @@ import string,linecache # Modules Eficas import I_OBJECT -from Noyau.N_ASSD import assd +from Noyau.N_ASSD import ASSD from Noyau.N_ETAPE import ETAPE -from Noyau.N_CO import CO from Noyau.N_Exception import AsException from Extensions import commentaire,parametre,parametre_eval @@ -21,6 +20,7 @@ class JDC(I_OBJECT.OBJECT): self.niveau=self self.params=[] self.fonctions=[] + self._etape_context=None def get_cmd(self,nomcmd): """ @@ -38,20 +38,32 @@ class JDC(I_OBJECT.OBJECT): l=[] for k,v in d.items(): if type(v) != types.InstanceType : continue - if assd in types_permis or CO in types_permis : - l.append(k) - continue - for type_ok in types_permis: - if type_ok in ('R','I','C','TXM') and v in self.params : l.append(k) - elif type_ok == 'R' and v.__class__.__name__ == 'reel' : l.append(k) - elif type_ok == 'I' and v.__class__.__name__ == 'entier' : l.append(k) - elif type_ok == 'C' and v.__class__.__name__ == 'complexe' : l.append(k) - elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' : l.append(k) - elif type(type_ok) != types.ClassType : continue - elif v.__class__ == type_ok or issubclass(v.__class__,type_ok): l.append(k) + # On considère que seul assd indique un type quelconque pas CO + elif self.assd in types_permis : + l.append(k) + elif self.est_permis(v,types_permis): + l.append(k) l.sort() return l + def est_permis(self,v,types_permis): + for type_ok in types_permis: + if type_ok in ('R','I','C','TXM') and v in self.params : + return 1 + elif type_ok == 'R' and v.__class__.__name__ == 'reel' : + return 1 + elif type_ok == 'I' and v.__class__.__name__ == 'entier' : + return 1 + elif type_ok == 'C' and v.__class__.__name__ == 'complexe' : + return 1 + elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' : + return 1 + elif type(type_ok) != types.ClassType : + continue + elif v.__class__ == type_ok or issubclass(v.__class__,type_ok): + return 1 + return 0 + def addentite(self,name,pos): """ Ajoute une entite : @@ -83,6 +95,7 @@ class JDC(I_OBJECT.OBJECT): if pos == None : pos = 0 self.etapes.insert(pos,objet) self.editmode=0 + self.reset_context() self.active_etapes() return objet elif name == "PARAMETRE_EVAL": @@ -93,6 +106,7 @@ class JDC(I_OBJECT.OBJECT): if pos == None : pos = 0 self.etapes.insert(pos,objet) self.editmode=0 + self.reset_context() self.active_etapes() return objet elif type(name)==types.InstanceType: @@ -100,10 +114,8 @@ class JDC(I_OBJECT.OBJECT): # existante (par copie donc) # on est donc nécessairement en mode editeur ... objet = name - objet.jdc = objet.parent = self - #XXX current_step n'existe plus. A priori le parent devrait etre self - # ainsi que le step courant. - #objet.parent = self.current_step + # Il ne faut pas oublier de reaffecter le parent d'obj (si copie) + objet.reparent(self) self.set_current_step() if isinstance(objet,ETAPE): if objet.nom_niveau_definition == 'JDC': @@ -117,6 +129,7 @@ class JDC(I_OBJECT.OBJECT): self.etapes.insert(pos,objet) self.active_etapes() self.editmode=0 + self.reset_context() return objet else : # On veut ajouter une nouvelle commande @@ -125,11 +138,13 @@ class JDC(I_OBJECT.OBJECT): cmd=self.get_cmd(name) # L'appel a make_objet n'a pas pour effet d'enregistrer l'étape # auprès du step courant car editmode vaut 1 + # Par contre elle a le bon parent grace a set_current_step e=cmd.make_objet() if pos == None : pos = 0 self.etapes.insert(pos,e) self.reset_current_step() self.editmode=0 + self.reset_context() self.active_etapes() return e except: @@ -151,13 +166,15 @@ class JDC(I_OBJECT.OBJECT): def get_sd_avant_etape(self,nom_sd,etape): return self.get_contexte_avant(etape).get(nom_sd,None) - def get_sd_apres_etape(self,nom_sd,etape): + def get_sd_apres_etape(self,nom_sd,etape,avec='non'): """ Cette méthode retourne la SD de nom nom_sd qui est éventuellement - définie apres etape + définie apres etape + Si avec vaut 'non' exclut etape de la recherche """ ietap=self.etapes.index(etape) - for e in self.etapes[ietap+1:]: + if avec == 'non':ietap=ietap+1 + for e in self.etapes[ietap:]: sd=e.get_sdprods(nom_sd) if sd: if hasattr(e,'reuse'): @@ -165,16 +182,17 @@ class JDC(I_OBJECT.OBJECT): return sd return None - def get_sd_autour_etape(self,nom_sd,etape): + def get_sd_autour_etape(self,nom_sd,etape,avec='non'): """ Fonction: retourne la SD de nom nom_sd qui est éventuellement définie avant ou apres etape Permet de vérifier si un concept de meme nom existe dans le périmètre d'une étape + Si avec vaut 'non' exclut etape de la recherche """ sd=self.get_sd_avant_etape(nom_sd,etape) if sd:return sd - return self.get_sd_apres_etape(nom_sd,etape) + return self.get_sd_apres_etape(nom_sd,etape,avec) def active_etapes(self): """ @@ -267,6 +285,12 @@ class JDC(I_OBJECT.OBJECT): """ self.params.append(param) + def register_fonction(self,fonction): + """ + Cette méthode sert à ajouter une fonction dans la liste des fonctions + """ + self.fonctions.append(fonction) + def delete_param(self,param): """ Supprime le paramètre param de la liste des paramètres @@ -297,6 +321,14 @@ class JDC(I_OBJECT.OBJECT): nom = form.nom if not nom : continue if d.has_key(nom): l_fonctions.append(form.get_formule()) + + # on ajoute les concepts produits par DEFI_VALEUR + # XXX On pourrait peut etre faire plutot le test sur le type + # de concept : entier, reel, complexe, etc. + for k,v in d.items(): + if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',): + l_constantes.append(k) + # on retourne les deux listes return l_constantes,l_fonctions @@ -373,3 +405,69 @@ class JDC(I_OBJECT.OBJECT): linecache.cache[file]=0,0,string.split(text,'\n'),file return file,text + + def get_genealogie(self): + """ + Retourne la liste des noms des ascendants de l'objet self + jusqu'à la première ETAPE parent. + """ + return [] + + def NommerSdprod(self,sd,sdnom): + """ + Nomme la SD apres avoir verifie que le nommage est possible : nom + non utilise + Si le nom est deja utilise, leve une exception + Met le concept créé dans le concept global g_context + """ + # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment + # Le dictionnaire g_context ne représente pas le contexte + # effectif avant une étape. + # Il faut utiliser get_contexte_avant avec une indication de l'étape + # traitée. Pour le moment, il n'y a pas de moyen de le faire : ajouter + # un attribut dans le JDC ??? + if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom + if self._etape_context: + o=self.get_contexte_avant(self._etape_context).get(sdnom,None) + else: + o=self.g_context.get(sdnom,None) + if isinstance(o,ASSD): + raise AsException("Nom de concept deja defini : %s" % sdnom) + + # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja. + # Ajoute a la creation (appel de reg_sd). + self.g_context[sdnom]=sd + sd.nom=sdnom + + def set_etape_context(self,etape): + """ + Positionne l'etape qui sera utilisee dans NommerSdProd pour + decider si le concept passé pourra etre nommé + """ + self._etape_context=etape + + def reset_context(self): + """ + Cette methode reinitialise le contexte glissant pour pouvoir + tenir compte des modifications de l'utilisateur : création + de commandes, nommage de concepts, etc. + """ + self.current_context={} + self.index_etape_courante=0 + + def del_param(self,param): + """ + Supprime le paramètre param de la liste des paramètres + et du contexte gobal + """ + if param in self.params : self.params.remove(param) + if self.g_context.has_key(param.nom) : del self.g_context[param.nom] + + def del_fonction(self,fonction): + """ + Supprime la fonction fonction de la liste des fonctions + et du contexte gobal + """ + if fonction in self.fonctions : self.fonctions.remove(fonction) + if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom] + diff --git a/Ihm/I_MACRO_ETAPE.py b/Ihm/I_MACRO_ETAPE.py index be318d25..67ccbddf 100644 --- a/Ihm/I_MACRO_ETAPE.py +++ b/Ihm/I_MACRO_ETAPE.py @@ -11,6 +11,9 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): def __init__(self): I_ETAPE.ETAPE.__init__(self) + # XXX CCAR : ne suis pas certain que typret doive etre + # initialise à None (a verifier) + self.typret=None def get_sdprods(self,nom_sd): """ @@ -61,6 +64,10 @@ class MACRO_ETAPE(I_ETAPE.ETAPE): context_ini = context_ini, appli=self.jdc.appli) j.analyse() + # XXX en passant par un jdc auxiliaire, on risque de rendre les etapes inactives + # on les force dans l'etat actif + for etape in j.etapes: + etape.active() except: traceback.print_exc() return None diff --git a/Ihm/I_MCCOMPO.py b/Ihm/I_MCCOMPO.py index 31efd18f..0473b104 100644 --- a/Ihm/I_MCCOMPO.py +++ b/Ihm/I_MCCOMPO.py @@ -25,24 +25,6 @@ class MCCOMPO(I_OBJECT.OBJECT): else: return self.nom - def get_genealogie(self): - """ - Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC - ou ETAPE) de self jusqu'au premier objet etape rencontré - """ - l=[] - objet = self - while objet.nature != 'JDC' : - if not objet.isMCList() : - l.append(string.strip(objet.nom)) - else : - pass - # Si objet.etape == etape c'est que objet est l'étape origine de la généalogie - if objet.etape == objet: break - objet = objet.parent - l.reverse() - return l - def get_liste_mc_ordonnee(self,liste,dico): """ Retourne la liste ordonnée (suivant le catalogue) des mots-clés @@ -219,6 +201,8 @@ class MCCOMPO(I_OBJECT.OBJECT): new_obj.init(objet.nom,self) new_obj.append(old_obj) new_obj.append(objet) + # Il ne faut pas oublier de reaffecter le parent d'obj + objet.reparent(self) self.mc_liste.remove(old_obj) self.mc_liste.insert(index,new_obj) self.fin_modif() @@ -227,12 +211,16 @@ class MCCOMPO(I_OBJECT.OBJECT): # une liste d'objets de même type existe déjà #print "une liste d'objets de même type existe déjà" old_obj.append(objet) + # Il ne faut pas oublier de reaffecter le parent d'obj + objet.reparent(self) self.fin_modif() return old_obj if pos == None : self.mc_liste.append(objet) else : self.mc_liste.insert(pos,objet) + # Il ne faut pas oublier de reaffecter le parent d'obj (si copie) + objet.reparent(self) self.fin_modif() return objet @@ -308,13 +296,14 @@ class MCCOMPO(I_OBJECT.OBJECT): # ce qui n'est pas du tout bon dans le cas d'une copie !!!!!!! # FR : peut-on passer par là autrement que dans le cas d'une copie ??? # FR --> je suppose que non - objet.parent = None + # XXX CCAR : le pb c'est qu'on vérifie ensuite quel parent avait l'objet + # Il me semble preferable de changer le parent a la fin quand la copie est acceptee objet.valeur = copy(self.valeur) objet.val = copy(self.val) objet.mc_liste=[] for obj in self.mc_liste: new_obj = obj.copy() - new_obj.parent = objet + new_obj.reparent(objet) objet.mc_liste.append(new_obj) return objet @@ -371,3 +360,12 @@ class MCCOMPO(I_OBJECT.OBJECT): liste_retraits.append(k) return liste_ajouts,liste_retraits + def reparent(self,parent): + """ + Cette methode sert a reinitialiser la parente de l'objet + """ + self.parent=parent + self.jdc=parent.get_jdc_root() + self.etape=parent.etape + for mocle in self.mc_liste: + mocle.reparent(self) diff --git a/Ihm/I_MCLIST.py b/Ihm/I_MCLIST.py index c58c6d40..243992ce 100644 --- a/Ihm/I_MCLIST.py +++ b/Ihm/I_MCLIST.py @@ -53,12 +53,13 @@ class MCList: Réalise la copie d'une MCList """ liste = self.data[0].definition.list_instance() - # XXX Pas de parent ?? - # FR -->Il faut en spécifier un pour la méthode init qui attend 2 arguments ... + # FR -->Il faut spécifier un parent pour la méthode init qui attend 2 arguments ... liste.init(self.nom,self.parent) for objet in self: new_obj = objet.copy() - new_obj.parent = liste + # Pour etre coherent avec le constructeur de mots cles facteurs N_FACT.__call__ + # dans lequel le parent de l'element d'une MCList est le parent de la MCList + new_obj.reparent(self.parent) liste.append(new_obj) return liste @@ -116,3 +117,36 @@ class MCList: """ if self.parent == None: return None return self.parent.get_etape() + + def get_genealogie(self): + """ + Retourne la liste des noms des ascendants. + Un objet MCList n'est pas enregistré dans la genealogie. + XXX Meme si le MCFACT fils ne l'est pas lui non plus ???? + """ + if self.parent: + return self.parent.get_genealogie() + else: + return [] + + def get_liste_mc_ordonnee_brute(self,liste,dico): + """ + Retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés + d'une entité composée dont le chemin complet est donné sous forme + d'une liste du type :ETAPE + MCFACT ou MCBLOC + ... + """ + for arg in liste: + objet_cata = dico[arg] + dico=objet_cata.dico + return objet_cata.liste + + def reparent(self,parent): + """ + Cette methode sert a reinitialiser la parente de l'objet + """ + self.parent=parent + self.jdc=parent.jdc + self.etape=etape + for mcfact in self.data: + mcfact.reparent(parent) + diff --git a/Ihm/I_MCSIMP.py b/Ihm/I_MCSIMP.py index c7f3fb73..1875b989 100644 --- a/Ihm/I_MCSIMP.py +++ b/Ihm/I_MCSIMP.py @@ -7,10 +7,21 @@ myrepr.maxstring = 100 myrepr.maxother = 100 from Noyau.N_utils import repr_float + +# Attention : les classes ASSD,.... peuvent etre surchargées +# dans le package Accas. Il faut donc prendre des précautions si +# on utilise les classes du Noyau pour faire des tests (isxxxx, ...) +# Si on veut créer des objets comme des CO avec les classes du noyau +# ils n'auront pas les conportements des autres packages (pb!!!) +# Il vaut mieux les importer d'Accas mais problème d'import circulaire, +# on ne peut pas les importer au début. +# On fait donc un import local quand c'est nécessaire (peut occasionner +# des pbs de prformance). from Noyau.N_ASSD import ASSD,assd from Noyau.N_GEOM import GEOM,geom from Noyau.N_CO import CO -from Noyau.N_EVAL import EVAL +# fin attention + from Extensions import parametre import I_OBJECT @@ -82,7 +93,8 @@ class MCSIMP(I_OBJECT.OBJECT): """ for typ in self.definition.type: if type(typ) == types.ClassType : - if typ is CO : return 1 + if issubclass(typ,CO) : + return 1 return 0 def wait_assd(self): @@ -104,7 +116,7 @@ class MCSIMP(I_OBJECT.OBJECT): """ for typ in self.definition.type: if type(typ) == types.ClassType : - if typ in (GEOM,ASSD,geom,assd) or issubclass(typ,GEOM) : + if typ.__name__ in ("GEOM","ASSD","geom","assd") or issubclass(typ,GEOM) : return 1 return 0 @@ -165,6 +177,8 @@ class MCSIMP(I_OBJECT.OBJECT): # type de nom new_valeur if self.wait_co(): try: + # Pour avoir la classe CO avec tous ses comportements + from Accas import CO self.valeur=CO(new_valeur) except: traceback.print_exc() @@ -204,6 +218,8 @@ class MCSIMP(I_OBJECT.OBJECT): return sd,1 else: d={} + # On veut EVAL avec tous ses comportements. On utilise Accas. Perfs ?? + from Accas import EVAL d['EVAL']=EVAL try : objet = eval(new_valeur,d) @@ -260,10 +276,48 @@ class MCSIMP(I_OBJECT.OBJECT): def set_valeur_co(self,nom_co): """ - Affecte à self l'objet de type CO et de nom nom_co + Affecte à self l'objet de type CO et de nom nom_co """ - new_objet = CO(nom_co) + step=self.etape.parent + if nom_co == None or nom_co == '': + new_objet=None + else: + # Pour le moment on importe en local le CO de Accas. + # Si problème de perfs, il faudra faire autrement + from Accas import CO + # Avant de créer un concept il faut s'assurer du contexte : step + # courant + sd= step.get_sd_autour_etape(nom_co,self.etape,avec='oui') + if sd: + # Si un concept du meme nom existe deja dans la portée de l'étape + # on ne crée pas le concept + return 0,"un concept de meme nom existe deja" + # Il n'existe pas de concept de meme nom. On peut donc le créer + # Il faut néanmoins que la méthode NommerSdProd de step gère les + # contextes en mode editeur + # Normalement la méthode du Noyau doit etre surchargée + # On déclare l'étape du mot clé comme etape courante pour NommerSdprod + cs= CONTEXT.get_current_step() + CONTEXT.unset_current_step() + CONTEXT.set_current_step(step) + step.set_etape_context(self.etape) + new_objet = CO(nom_co) + CONTEXT.unset_current_step() + CONTEXT.set_current_step(cs) self.valeur = new_objet self.val = new_objet self.init_modif() + step.reset_context() + # On force l'enregistrement de new_objet en tant que concept produit + # de la macro en appelant get_type_produit avec force=1 + self.etape.get_type_produit(force=1) + return 1,"Concept créé" + def reparent(self,parent): + """ + Cette methode sert a reinitialiser la parente de l'objet + """ + self.parent=parent + self.jdc=parent.jdc + self.etape=parent.etape + diff --git a/Ihm/I_OBJECT.py b/Ihm/I_OBJECT.py index 04ef8cca..dea18249 100644 --- a/Ihm/I_OBJECT.py +++ b/Ihm/I_OBJECT.py @@ -2,7 +2,12 @@ """ import string +import Noyau + class OBJECT: + from Noyau.N_CO import CO + from Noyau.N_ASSD import assd + def isMCList(self): """ Retourne 1 si self est une MCList (liste de mots-clés), @@ -86,4 +91,18 @@ class OBJECT: Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE) de self jusqu'au premier objet etape rencontré """ - return [] + if self.parent: + l=self.parent.get_genealogie() + l.append(string.strip(self.nom)) + return l + else: + return [string.strip(self.nom)] + + def reparent(self,parent): + """ + Cette methode sert a reinitialiser la parente de l'objet + """ + self.parent=parent + self.jdc=parent.jdc + + diff --git a/Minicode/cata_saturne.py b/Minicode/cata_saturne.py index 40975a2d..d45445c8 100755 --- a/Minicode/cata_saturne.py +++ b/Minicode/cata_saturne.py @@ -11,13 +11,21 @@ JdC = JDC_CATA(code='SATURNE', AU_MOINS_UN('FIN'), A_CLASSER(('DEBUT','POURSUITE'),'FIN') ) - ); + ) # P. RASCLE MMN # remarques diverses sur le catalogue Saturne # - dans les blocs, il faut au moins un mot clé de statut obligatoire # probleme de rafraichissement des blocs dépendants quand la valeur d'un mot cle global (ITURB) passe de 1 à 0 +# Type le plus general +class entier (ASSD):pass +class reel (ASSD):pass +class complexe(ASSD):pass +class liste (ASSD):pass +class chaine (ASSD):pass + + class sonde(ASSD):pass class varsca(ASSD):pass class flusca(ASSD):pass @@ -36,7 +44,35 @@ class tsr23(ASSD):pass class resti(ASSD):pass class maillage(ASSD):pass -class listr8 (ASSD):pass +class modele(ASSD):pass +class matr_asse(ASSD):pass +class cham_elem_sief_r(ASSD):pass +class theta_geom(ASSD):pass +class cham_mater(ASSD):pass +class cara_elem(ASSD):pass +class char_ther(ASSD):pass +class char_meca(ASSD):pass +class nume_ddl(ASSD):pass +class char_acou(ASSD):pass +class listr8 (ASSD):pass +class matr_elem(ASSD):pass +class matr_elem_depl_c(matr_elem):pass +class matr_elem_depl_r(matr_elem):pass +class matr_elem_pres_c(matr_elem):pass +class matr_elem_temp_r(matr_elem):pass + +# matr_asse : +#-------------------------------- +class matr_asse(ASSD):pass +class matr_asse_depl_c(matr_asse):pass +class matr_asse_depl_r(matr_asse):pass +class matr_asse_gene_r(matr_asse):pass +class matr_asse_gene_c(matr_asse):pass +class matr_asse_pres_c(matr_asse):pass +class matr_asse_pres_r(matr_asse):pass +class matr_asse_temp_c(matr_asse):pass +class matr_asse_temp_r(matr_asse):pass + # fin entete @@ -101,6 +137,33 @@ FORMULE = FORM( nom='FORMULE',op=-5,sd_prod=fonction, COMPLEXE = SIMP(typ = 'shell',max=1), ) ; +AFFE_MODELE=OPER(nom="AFFE_MODELE",op=18,sd_prod=modele,docu="U4.41.01-f1", + fr="Affectation des éléments finis sur le maillage",reentrant='n', + MAILLAGE =SIMP(statut='o',typ=(maillage) ), + INFO =SIMP(statut='f',typ='I',defaut=1,into=(1,2) ), + VERIF =SIMP(statut='f',typ='TXM',max=2,into=("MAILLE","NOEUD") ), + ); +NUME_DDL=OPER(nom="NUME_DDL",op=11,sd_prod=nume_ddl,docu="U4.61.11-f",reentrant='n', + fr="Etablissement de la numérotation des ddl avec ou sans renumérotation et du stockage de la matrice", + MATR_RIGI =SIMP(statut='f',typ=(matr_elem_depl_r ,matr_elem_depl_c, + matr_elem_temp_r,matr_elem_pres_c),max=100 ), + MODELE =SIMP(statut='f',typ=modele ), + b_modele =BLOC(condition = "MODELE != None", + CHARGE =SIMP(statut='f',max='**',typ=(char_meca,char_ther,char_acou, ),), + ), + METHODE =SIMP(statut='f',typ='TXM',defaut="MULT_FRONT",into=("MULT_FRONT","LDLT","GCPC") ), + b_mult_front =BLOC(condition="METHODE=='MULT_FRONT'",fr="paramètres associés à la méthode multifrontale", + RENUM =SIMP(statut='f',typ='TXM',into=("MD","MDA","METIS"),defaut="METIS" ), + ), + b_ldlt =BLOC(condition="METHODE=='LDLT'",fr="paramètres associés à la méthode LDLT", + RENUM =SIMP(statut='f',typ='TXM',into=("RCMK","SANS"),defaut="RCMK" ), + ), + b_gcpc =BLOC(condition="METHODE=='GCPC'",fr="paramètres associés à la méthode gradient conjugué", + RENUM =SIMP(statut='f',typ='TXM',into=("RCMK","SANS"),defaut="RCMK" ), + ), + INFO =SIMP(statut='f',typ='I',into=(1,2)), +) ; + DEFI_SONDE = OPER(nom="DEFI_SONDE",op= 1,sd_prod=sonde, docu="U2D1", fr="définition d'une sonde historique avec ses coordonnées", @@ -1229,3 +1292,210 @@ FIN=PROC(nom="FIN",op=9999,repetable='n',fr="Fin d'une ) ; +def macro_matr_asse_ops(self,MODELE,CHAM_MATER,CARA_ELEM,MATR_ASSE, + SOLVEUR,NUME_DDL,CHARGE,INST,**args): + """ + Ecriture de la macro MACRO_MATR_ASSE + """ + ier=0 + # On met le mot cle NUME_DDL dans une variable locale pour le proteger + numeddl=NUME_DDL + # On importe les definitions des commandes a utiliser dans la macro + # Le nom de la variable doit etre obligatoirement le nom de la commande + CALC_MATR_ELEM=self.get_cmd('CALC_MATR_ELEM') + NUME_DDL =self.get_cmd('NUME_DDL') + ASSE_MATRICE =self.get_cmd('ASSE_MATRICE') + # La macro compte pour 1 dans la numerotation des commandes + self.icmd=1 + + if SOLVEUR: + methode=SOLVEUR['METHODE'] + if methode=='LDLT': + if SOLVEUR['RENUM']: + renum=SOLVEUR['RENUM'] + else: + renum='RCMK' + if renum not in ('SANS','RCMK'): + ier=ier+1 + self.cr.fatal("Avec methode LDLT, RENUM doit etre SANS ou RCMK.") + return ier + elif methode=='MULT_FRONT': + if SOLVEUR['RENUM']: + renum=SOLVEUR['RENUM'] + else: + renum='MDA' + if renum not in ('MDA','MD','METIS'): + ier=ier+1 + self.cr.fatal("Avec methode MULT_FRONT, RENUM doit etre MDA, MD ou RCMK.") + return ier + elif methode=='GCPC': + if SOLVEUR['RENUM']: + renum=SOLVEUR['RENUM'] + else: + renum='SANS' + if renum not in ('SANS','RCMK'): + ier=ier+1 + self.cr.fatal("Avec methode GCPC, RENUM doit etre SANS ou RCMK.") + return ier + else: + methode='MULT_FRONT' + renum ='MDA' + + if numeddl in self.sdprods: + # Si le concept numeddl est dans self.sdprods + # il doit etre produit par la macro + # il faudra donc appeler la commande NUME_DDL + lnume = 1 + else: + lnume = 0 + lrigel = 0 + lmasel = 0 + + iocc=0 + for m in MATR_ASSE: + iocc=iocc+1 + option=m['OPTION'] + if iocc == 1 and lnume == 1 and option not in ('RIGI_MECA','RIGI_MECA_LAGR', + 'RIGI_THER','RIGI_ACOU') : + ier=ier+1 + self.cr.fatal("LA PREMIERE OPTION DOIT ETRE RIGI_MECA OU RIGI_THER OU RIGI_ACOU OU RIGI_MECA_LAGR") + return ier + + if m['SIEF_ELGA']!=None and option!='RIGI_GEOM': + ier=ier+1 + self.cr.fatal("SIEF_ELGA N EST ADMIS QU AVEC L OPTION RIGI_GEOM") + return ier + + if m['MODE_FOURIER']!=None and option not in ('RIGI_MECA','RIGI_FLUI_STRU','RIGI_THER'): + ier=ier+1 + self.cr.fatal("MODE_FOURIER N EST ADMIS QU AVEC UNE DES OPTIONS RIGI_MECA RIGI_FLUI_STRU RIGI_THER") + return ier + + if (m['THETA']!=None or m['PROPAGATION']!=None) and option!='RIGI_MECA_LAGR': + ier=ier+1 + self.cr.fatal("PROPAGATION ET,OU THETA NE SONT ADMIS QU AVEC L OPTION RIGI_MECA_LAGR") + return ier + motscles={'OPTION':option} + if option == 'AMOR_MECA': + if (not lrigel or not lmasel): + ier=ier+1 + self.cr.fatal("""POUR CALCULER AMOR_MECA, IL FAUT AVOIR CALCULE + RIGI_MECA ET MASS_MECA AUPARAVANT (DANS LE MEME APPEL)""") + return ier + if CHAM_MATER != None: + motscles['RIGI_MECA'] =rigel + motscles['MASS_MECA'] =masel + if CHARGE != None: + if option[0:9] not in ('MASS_THER','RIGI_GEOM','MASS_ID_M'): + motscles['CHARGE'] =CHARGE + if CHAM_MATER != None: motscles['CHAM_MATER'] =CHAM_MATER + if CARA_ELEM != None: motscles['CARA_ELEM'] =CARA_ELEM + if INST != None: motscles['INST'] =INST + if m['SIEF_ELGA'] : motscles['SIEF_ELGA'] =m['SIEF_ELGA'] + if m['MODE_FOURIER']: motscles['MODE_FOURIER']=m['MODE_FOURIER'] + if m['THETA'] : motscles['THETA'] =m['THETA'] + if m['PROPAGATION'] : motscles['PROPAGATION'] =m['PROPAGATION'] + __a=CALC_MATR_ELEM(MODELE=MODELE,**motscles) + + if option == 'RIGI_MECA': + rigel = __a + lrigel = 1 + if option == 'MASS_MECA': + masel = __a + lmasel = 1 + + if lnume and option in ('RIGI_MECA','RIGI_THER','RIGI_ACOU','RIGI_MECA_LAGR'): + self.DeclareOut('num',numeddl) + # On peut passer des mots cles egaux a None. Ils sont ignores + num=NUME_DDL(MATR_RIGI=__a,METHODE=methode,RENUM=renum) + else: + num=numeddl + + self.DeclareOut('mm',m['MATRICE']) + mm=ASSE_MATRICE(MATR_ELEM=__a,NUME_DDL=num) + return ier + +def macro_matr_asse_prod(self,NUME_DDL,MATR_ASSE,**args): + if not MATR_ASSE: raise AsException("Impossible de typer les concepts resultats") + if not NUME_DDL: raise AsException("Impossible de typer les concepts resultats") + self.type_sdprod(NUME_DDL,nume_ddl) + for m in MATR_ASSE: + opti=m['OPTION'] + + if opti in ( "RIGI_MECA","RIGI_FLUI_STRU","RIGI_MECA_LAGR" , + "MASS_MECA" , "MASS_FLUI_STRU" ,"RIGI_GEOM" ,"RIGI_ROTA", + "AMOR_MECA","IMPE_MECA","MASS_ID_MDEP_R","MASS_ID_MDNS_R", + "ONDE_FLUI","MASS_MECA_DIAG" ) : t=matr_asse_depl_r + + if opti in ( "RIGI_ACOU","MASS_ACOU","AMOR_ACOU",) : t=matr_asse_pres_c + + if opti in ( "RIGI_THER","MASS_THER","RIGI_THER_CONV" , + "RIGI_THER_CONV_D","MASS_ID_MTEM_R","MASS_ID_MTNS_R",) : t=matr_asse_temp_r + + if opti == "RIGI_MECA_HYST" : t= matr_asse_depl_c + + self.type_sdprod(m['MATRICE'],t) + return None + +MACRO_MATR_ASSE=MACRO(nom="MACRO_MATR_ASSE",op=macro_matr_asse_ops,docu="U4.61.21-c", + sd_prod=macro_matr_asse_prod, + fr="Calcul des matrices assemblées (matr_asse_gd) par exemple de rigidité, de masse ", + MODELE =SIMP(statut='o',typ=modele), + CHAM_MATER =SIMP(statut='f',typ=cham_mater), + CARA_ELEM =SIMP(statut='f',typ=cara_elem), + CHARGE =SIMP(statut='f',typ=(char_meca,char_ther,char_acou)), + INST =SIMP(statut='f',typ='R'), + NUME_DDL =SIMP(statut='o',typ=(nume_ddl,CO)), + SOLVEUR =FACT(statut='d',min=01,max=01, + METHODE =SIMP(statut='f',typ='TXM',defaut="MULT_FRONT", + into=("LDLT","MULT_FRONT","GCPC")), + RENUM =SIMP(statut='f',typ='TXM',into=("SANS","RCMK","MD","MDA","METIS")), + ), + MATR_ASSE =FACT(statut='o',min=01,max='**', + MATRICE =SIMP(statut='o',typ=(matr_asse,CO)), + OPTION =SIMP(statut='o',typ='TXM', + into=("RIGI_MECA","MASS_MECA","MASS_MECA_DIAG", + "AMOR_MECA","RIGI_MECA_HYST","IMPE_MECA", + "ONDE_FLUI","RIGI_FLUI_STRU","MASS_FLUI_STRU", + "RIGI_ROTA","RIGI_GEOM","RIGI_MECA_LAGR", + "RIGI_THER","MASS_THER", + "RIGI_ACOU","MASS_ACOU","AMOR_ACOU", + "MASS_ID_MTEM_R","MASS_ID_MTNS_R","MASS_ID_MDEP_R","MASS_ID_MDNS_R",) + ), + SIEF_ELGA =SIMP(statut='f',typ=cham_elem_sief_r), + MODE_FOURIER =SIMP(statut='f',typ='I'), + THETA =SIMP(statut='f',typ=theta_geom), + PROPAGATION =SIMP(statut='f',typ='R'), + ), + TITRE =SIMP(statut='f',typ='TXM',max='**'), + INFO =SIMP(statut='f',typ='I',defaut=1,into=(1,2)), +) ; + + +def defi_valeur_prod(self,IS=None,R8=None,TX=None,C8=None,LS=None): + if IS != None : return entier + if R8 != None : return reel + if TX != None : return chaine + if C8 != None : return complexe + if LS != None : return liste + raise AsException("type de concept resultat non prevu") + +DEFI_VALEUR=MACRO(nom="DEFI_VALEUR",op=-4,sd_prod=defi_valeur_prod, + fr="Affectation d une valeur à une variable Superviseur", + docu="U4.31.04-e1",reentrant='f', + regles=(UN_PARMI('IS','R8','TX','C8','LS'),), + IS =SIMP(statut='f',typ='I',max='**'), + R8 =SIMP(statut='f',typ='R',max='**'), + TX =SIMP(statut='f',typ='TXM',max='**'), + C8 =SIMP(statut='f',typ='C',max='**'), + LS =SIMP(statut='f',typ='L',max='**'), +) ; + +def macro2_prod(self,MODELE,**args): + return maillage + +MACRO2 =MACRO(nom="MACRO2",op= -5 ,docu="U4.61.21-c", + sd_prod=macro2_prod, + fr="Calcul des matrices assemblées (matr_asse_gd) par exemple de rigidité, de masse ", + MODELE =SIMP(statut='o',typ=modele), +); diff --git a/generator/generator_aplat.py b/generator/generator_aplat.py index c12b6dac..11a9953f 100644 --- a/generator/generator_aplat.py +++ b/generator/generator_aplat.py @@ -268,7 +268,7 @@ class AplatGenerator: text = '' init = self.init + self.sep + obj.nom old_init=self.init - for data in self.data : + for data in obj.data : i=i+1 self.init = init + self.sep + "occurrence n°"+`i` text = text + self.generator(data) @@ -283,7 +283,7 @@ class AplatGenerator: if type(obj.valeur) in (types.TupleType,types.ListType) : # On est en présence d'une liste de valeur rep = '(' - for val in self.valeur: + for val in obj.valeur: if type(val) == types.InstanceType : rep = rep + self.generator(val) +',' else: diff --git a/generator/generator_python.py b/generator/generator_python.py index 6220c818..212efca3 100644 --- a/generator/generator_python.py +++ b/generator/generator_python.py @@ -453,6 +453,8 @@ class PythonGenerator: if hasattr(obj.etape,'sdprods'): if val in obj.etape.sdprods : s = s + "CO('"+ self.generator(val) +"')" + elif val.__class__.__name__ == 'CO': + s = s + "CO('"+ self.generator(val) +"')" else: s = s + self.generator(val) elif isinstance(val,PARAMETRE): @@ -472,6 +474,8 @@ class PythonGenerator: if hasattr(obj.etape,'sdprods'): if val in obj.etape.sdprods : s = "CO('"+ self.generator(val) +"')" + elif val.__class__.__name__ == 'CO': + s = "CO('"+ self.generator(val) +"')" else: s = self.generator(val) elif isinstance(val,PARAMETRE):