--- /dev/null
+
+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
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)
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
--- /dev/null
+
+
+1- Installation standard
+
+Pour installer EFICAS a partir de la distribution : Eficas.tgz
+faire :
+ tar xzvf Eficas.tgz
+
+ce qui a pour effet de créer un répertoire Eficas
+Tel que Eficas est prêt à etre executé.
+
+ATTENTION :
+Si Eficas est installé dans un répertoire particulier d'administration
+dans lequel les utilisateurs n'ont pas le droit d'écriture, il faut que
+l'administrateur lance Eficas avec les deux versions 5 et 6 pour générer
+les fichiers et catalogues compilés .pyc et _pickled.py
+
+2- Utilisation d'Eficas
+
+Pour utiliser Eficas, aller dans le répertoire Aster et faire :
+ python eficas_aster.py
+
+3- Installation avec un noyau pré-installé
+
+Aller dans le répertoire Aster du répertoire Eficas
+et modifier le fichier prefs.py comme suit :
+Mettre dans la variable CODE_PATH le chemin absolu vers
+le répertoire contenant les deux répertoires Noyau et Validation que vous voulez
+utiliser à la place de ceux fournis dans la livraison d'Eficas
+
+Pour changer les catalogues, modifier le fichier editeur.ini dans le répertoire Aster
+
+
--- /dev/null
+ ======================================================================
+ THIS PROGRAM IS FREE SOFTWARE. YOU CAN REDISTRIBUTE IT AND/OR MODIFY
+ IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
+ THE FREE SOFTWARE FOUNDATION, EITHER VERSION 2 OF THE LICENSE, AND
+ ANY LATER VERSION.
+ THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
+ WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF
+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ SEE THE GNU GENERAL PUBLIC LICENSE FOR MORE DETAILS.
+ ======================================================================
+ TRADUCTION EDF ( POUR INFORMATION )
+ ======================================================================
+ CE PROGRAMME EST UN LOGICIEL LIBRE. VOUS POUVEZ LE DIFFUSER ET/OU LE
+ MODIFIER SELON LES DISPOSITIONS DE LA LICENCE GRAND PUBLIC GNU (GPL)
+ TELLE QU'ELLE EST PUBLIEE PAR LA FREE SOFTWARE FOUNDATION, VERSION 2
+ DE LA LICENCE ET TOUTE VERSION ULTERIEURE.
+ CE PROGRAMME EST DIFFUSE AVEC L'ESPOIR QU'IL SERA UTILE, MAIS SANS
+ GARANTIE, SANS MEME LA GARANTIE IMPLICITE DE QUALIFICATION DE MISE SUR
+ LE MARCHE OU D'ADAPTATION A UNE UTILISATION PARTICULIERE.
+ VOIR POUR DE PLUS AMPLES DETAILS LA LICENCE GRAND PUBLIC GNU (GPL)
+ ======================================================================
--- /dev/null
+
+Pour installer EFICAS voir dans le fichier INSTALL
# 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 format v6','visuJDC_py'),
+ ('Fichier source','visu_txt_brut_JDC'),
+ ('Paramètres Eficas','affichage_fichier_ini'),
+ ('Mots-clés inconnus','mc_inconnus'),
+ ]
+ ),
+ ]
+ }
+
--- /dev/null
+"""
+ Ce module sert à construire les distributions d'EFICAS en fonction
+ du tag CVS courant
+ Les distributions sont :
+ - un tar.gz pour UNIX ne contenant pas mxTextTools
+ - un zip pour Windows contenant mx TextTools préinstallé
+ L'utilisation de ce module est la suivante :
+ 1- Se mettre dans un répertoire de travail
+ 2- Configurer son environnement pour utiliser le référentiel CVS EFICAS
+ 3- Exporter les sources d'EficasV1 par la commande :
+ cvs export -r TAG -d Eficas_export EficasV1
+ ou TAG est le tag CVS de la version que l'on veut distribuer (par exemple V1_1p1)
+ 4- Copier le répertoire fourni par Aster (ACCAS6.2.0) au meme niveau que Eficas_export
+ 5- Aller dans le répertoire Eficas_export
+ 6- Executer le script sdist.py
+ python sdist.py
+ Ce qui a pour effet de creer un repertoire dist contenant les 2 distributions
+ et de les copier dans le répertoire indiqué par dir_download s'il est accessible
+
+"""
+import os,shutil,glob,sys
+import types
+
+version="$Name: $"[7:-2] or 'Test1_2'
+# ==========Path du noyau fourni par Aster====================
+path_Noyau="../../../Tutorial/Superv"
+# ============================================================
+nom_distrib="Eficas"+version+"AsterSTA6"
+path_distrib=os.path.join("dist",nom_distrib)
+path_TextTools="/home/eficas/pkg/mxTools/egenix2.0.2pourWindows/mx/TextTools"
+dir_download= "/home/eficas/WWW/telechargement/eficas"
+
+def main():
+ if os.path.isdir('dist'):shutil.rmtree('dist')
+
+ copyfiles('.',path_distrib,['README','LICENSE.TERMS','INSTALL'])
+
+ copyfiles('../Editeur',os.path.join(path_distrib,'Editeur'),['*.py','faqs.txt'])
+ copyfiles('../Ihm',os.path.join(path_distrib,'Ihm'),['*.py'])
+ copyfiles('../Extensions',os.path.join(path_distrib,'Extensions'),['*.py'])
+ copyfiles('../Accas',os.path.join(path_distrib,'Accas'),['*.py'])
+ copyfiles('../Aster',os.path.join(path_distrib,'Aster'),['prefs.py',
+ 'editeur.ini',
+ 'eficas_aster.py',
+ ])
+ copyfiles('../convert',os.path.join(path_distrib,'convert'),['*.py'])
+ copyfiles('../convert/Parserv5',os.path.join(path_distrib,'convert','Parserv5'),['*.py'])
+
+ copyfiles('../generator',os.path.join(path_distrib,'generator'),['*.py'])
+
+ copyfiles('../Editeur/icons',os.path.join(path_distrib,'Editeur','icons'),['*.gif'])
+
+ copyfiles(os.path.join(path_Noyau,'Noyau'),os.path.join(path_distrib,'Noyau'),['*.py'])
+ copyfiles(os.path.join(path_Noyau,'Validation'),os.path.join(path_distrib,'Validation'),['*.py'])
+ copyfiles(os.path.join(path_Noyau,'Cata'),os.path.join(path_distrib,'Aster','Cata'),['*.py',
+ ])
+
+ copyfiles('../Tools',os.path.join(path_distrib,'Tools'),['*.py'])
+ copyfiles('../Tools/foztools',os.path.join(path_distrib,'Tools','foztools'),['*.py'])
+
+ tarball= maketarball('dist',nom_distrib,nom_distrib)
+ try:
+ shutil.copy(tarball,dir_download)
+ except:
+ print "Repertoire de download inconnu : ",dir_download
+
+ try:
+ shutil.copytree(path_TextTools,os.path.join(path_distrib,'Tools','TextTools'))
+ except:
+ print "Impossible de recuperer mxTextTools : ",dir_download
+ sys.exit(1)
+
+ zipfile= makezipfile('dist',nom_distrib,nom_distrib)
+ try:
+ shutil.copy(zipfile,dir_download)
+ except:
+ print "Repertoire de download inconnu : ",dir_download
+
+def make_dir(dir_cible):
+ if type(dir_cible) is not types.StringType:
+ raise "make_dir : dir_cible doit etre une string (%s)" % `dir_cible`
+ head,tail=os.path.split(dir_cible)
+ tails=[tail]
+ while head and tail and not os.path.isdir(head):
+ head,tail=os.path.split(head)
+ tails.insert(0, tail)
+
+ for d in tails:
+ head = os.path.join(head, d)
+ if not os.path.isdir(head):os.mkdir(head)
+
+
+def copyfiles(dir_origin,dir_cible,listfiles):
+ if not os.path.isdir(dir_cible):make_dir(dir_cible)
+ for glob_files in listfiles:
+ for file in glob.glob(os.path.join(dir_origin,glob_files)):
+ shutil.copy(file,dir_cible)
+
+def maketarball(dir_trav,dir_cible,nom_tar):
+ prev=os.getcwd()
+ print prev
+ os.chdir(dir_trav)
+ os.system("tar -cf "+nom_tar+".tar "+dir_cible)
+ os.system("gzip -f9 "+nom_tar+".tar ")
+ os.chdir(prev)
+ return os.path.join(dir_trav,nom_tar+".tar.gz")
+
+def makezipfile(dir_trav,dir_cible,nom_tar):
+ prev=os.getcwd()
+ os.chdir(dir_trav)
+ os.system("zip -rq "+nom_tar+".zip "+dir_cible)
+ os.chdir(prev)
+ return os.path.join(dir_trav,nom_tar+".zip")
+
+main()
+
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 :
root.option_add('*background', 'grey')
root.option_add('*foreground', 'black')
root.option_add('*EntryField.Entry.background', 'white')
+ root.option_add('*Entry*background', 'white')
root.option_add('*Listbox*background', 'white')
root.option_add('*Listbox*selectBackground', '#00008b')
root.option_add('*Listbox*selectForeground', 'white')
# Modules Eficas
import splash
+import prefs
import convert
import generator
from jdcdisplay import JDCDISPLAY
('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
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()
Demande à l'utilisateur quel JDC existant il veut ouvrir
"""
if self.code == 'ASTER':
- filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),)
+ filetypes = ( ("format "+self.appli.format_fichier.get(), ".comm"),("Tous",'*'))
else:
filetypes = ( ("format "+self.appli.format_fichier.get(), ".py"),)
if not hasattr(self,'initialdir'):
"""
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):
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.2 2002/04/03 11:35:12 eficas Exp $"
#
class MACROPanel(panels.OngletPanel):
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:
# item.object = MCSIMP, MCFACT, MCBLOC ou MCList
if item.object.isoblig() :
self.appli.affiche_infos('Impossible de supprimer un mot-clé obligatoire ')
+ print "Impossible de supprimer un mot-clé obligatoire"
return 0
else :
self.object.suppentite(item.object)
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()
Retourne 1 si l'objet pointé par self est un MCFact, 0 sinon
"""
return 0
-
+
+ def isMCList(self):
+ """
+ Retourne 1 si l'objet pointé par self est une MCList, 0 sinon
+ """
+ return 1
+
+ def additem(self,obj,pos):
+ """
+ Ajoute un objet MCFACT à la MCList (self.object) à la position pos
+ """
+ self.object.init_modif()
+ obj.verif_existence_sd()
+ obj.reparent(self.object.parent)
+ self.object.insert(pos,obj)
+ item = self.make_objecttreeitem(self.appli, obj.nom + ":", obj)
+ return item
+
+ def suppitem(self,item):
+ """
+ Retire un objet MCFACT de la MCList (self.object)
+ """
+ self.object.init_modif()
+ self.object.remove(item.object)
+ # la liste peut être retournée vide !
+ message = "Mot-clé " + item.object.nom + " supprimé"
+ self.appli.affiche_infos(message)
+ return 1
+
import Accas
treeitem = MCListTreeItem
objet = Accas.MCList
# ======================================================================
from Tkinter import *
import Pmw
+import traceback
import Objecttreeitem
import panels
import fontes
choix = self.listbox.getcurselection()[0]
self.valeur_choisie.set(choix)
except:
- pass
+ traceback.print_exc()
+
def choose_valeur_from_list(self,command):
try:
self.valeur_choisie.set(choix)
apply(command,(),{})
except:
- pass
+ traceback.print_exc()
class EtapeTreeItem(Objecttreeitem.ObjectTreeItem):
panel = OPERPanel
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()
commande_comment.jdc = commande_comment.parent = self.object.jdc
return commande_comment
+ def replace_child(self,old_item,new_item):
+ """
+ Remplace old_item.object par new_item.object dans les fils de self.object
+ """
+ index = self.object.mc_liste.index(old_item.object)
+ self.object.init_modif()
+ self.object.mc_liste.remove(old_item.object)
+ self.object.mc_liste.insert(index,new_item.object)
+ self.object.fin_modif()
+
import Accas
treeitem = EtapeTreeItem
objet = Accas.ETAPE
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()
# 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
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:
self.node.racine.verif_all()
else :
self.node.parent.verif()
+ self.node.update()
if self.node.item.isvalid():
self.node.parent.select()
- self.node.update()
# ----------------------------------------------------------------------------------------
# Méthodes utlisées pour la manipulation des items dans les listes de choix
# ----------------------------------------------------------------------------------------
self.record_valeur(valeur)
if self.node.item.isvalid():
self.node.parent.select()
- # fermeture de la fenêtre de sélection\r
- if self.ajout_valeurs:\r
- self.ajout_valeurs.quit()\r
+ # fermeture de la fenêtre de sélection
+ if self.ajout_valeurs:
+ self.ajout_valeurs.quit()
def annule_modifs_valeur(self):
"""
RAZ de la liste des valeurs (annule toutes les valeurs saisies par l'utilisateur)
"""
self.node.select()
- # fermeture de la fenêtre de sélection\r
- if self.ajout_valeurs:\r
- self.ajout_valeurs.quit()\r
+ # fermeture de la fenêtre de sélection
+ if self.ajout_valeurs:
+ self.ajout_valeurs.quit()
def traite_reel(self,valeur):
"""
"""
Génère la page de saisie de plusieurs valeurs parmi un ensemble discret
de possibles
- """\r
+ """
self.ajout_valeurs = None
# On récupère la bulle d'aide du panneau, l'objet, min et max (cardinalité de la liste),
# la liste des choix et la liste des valeurs
# Création de l'entry ou de la liste des SD
self.label = Label(self.frame_choix,text="Valeur :")
self.make_entry(frame = self.frame_choix,command = self.add_valeur_sans_into)
- self.label.place(relx=0.05,rely=0.5)\r
- # Création d'un bouton "Importer ..." sur le panel.\r
- bouton_valeurs_fichier = Button(self.frame_choix,\r
- text="Importer ...",\r
- command=self.select_in_file)\r
- bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)\r
+ self.label.place(relx=0.05,rely=0.5)
+ # Création d'un bouton "Importer ..." sur le panel.
+ bouton_valeurs_fichier = Button(self.frame_choix,
+ text="Importer ...",
+ command=self.select_in_file)
+ bouton_valeurs_fichier.place(relx=0.28,rely=0.7,relwidth=0.6)
self.ajout_valeurs = None
# boutons Ajouter et Supprimer
bouton_add = Button(self.frame_boutons_fleches,
bouton_add.place(relx=0.3,rely=0.35)
bouton_sup.place(relx=0.3,rely=0.65)
# affichage de l'aide
+ self.frame_aide.update()
self.aide = Label(self.frame_aide,
text = aide,
justify='center',
- anchor='center')
+ anchor='center',
+ wraplength=int(self.frame_aide.winfo_width()*0.8))
self.aide.place(relx=0.5,rely=0.5,anchor='center',relwidth=1)
self.Liste_valeurs.affiche_liste()
# boutons Accepter et Annuler
command = self.annule_modifs_valeur)
for but in (bouton_accepter,bouton_annuler):
but.pack(side='left',padx=5)
-\r
- def select_in_file(self):\r
- """ Permet d'ouvrir un fichier choisi par l'utilisateur. """\r
- nom_fichier = askopenfilename(title="Choix fichier :")\r
- if nom_fichier == "":\r
- return\r
- try:\r
- f = open(nom_fichier, "rb")\r
- selection_texte = f.read()\r
- f.close()\r
- self.ajout_valeurs = FenetreDeSelection(self, self.node.item,\r
- titre="Sélection de valeurs",\r
- texte=selection_texte)\r
- except:\r
- showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)\r
+
+ def select_in_file(self):
+ """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
+ nom_fichier = askopenfilename(title="Choix fichier :")
+ if nom_fichier == "":
+ return
+ try:
+ f = open(nom_fichier, "rb")
+ selection_texte = f.read()
+ f.close()
+ self.ajout_valeurs = FenetreDeSelection(self,
+ self.node.item,
+ self.parent.appli,
+ titre="Sélection de valeurs",
+ texte=selection_texte)
+ except:
+ traceback.print_exc()
+ showinfo("Erreur de fichier","impossible d'ouvir le fichier "+nom_fichier)
def get_bulle_aide(self):
"""
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 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()
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()
class UNIQUE_INTO_Panel(UNIQUE_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 :')
self.l_resu = Label(self.frame_valeur,text='Structure de donnée choisie :')
self.valeur_choisie = StringVar()
self.label_valeur = Label(self.frame_valeur,textvariable=self.valeur_choisie)
- self.aide = Label(self.frame_valeur, text = aide)
+ self.frame_valeur.update()
+ self.aide = Label(self.frame_valeur,
+ text = aide,
+ wraplength=int(self.frame_valeur.winfo_width()*0.8),
+ justify='center')
self.aide.place(relx=0.5,rely=0.85,anchor='n')
- self.b_co.invoke('NON')
# affichage de la valeur courante
self.display_valeur()
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()
+ self.erase_valeur()
+ anc_val = self.node.item.get_valeur()
+ 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':
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)
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):
self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
self.entry.focus()
# aide associée au panneau
- self.aide = Label(self.frame_valeur, text = aide)
+ self.frame_valeur.update()
+ self.aide = Label(self.frame_valeur,
+ text = aide,
+ wraplength=int(self.frame_valeur.winfo_width()*0.8),
+ justify='center')
self.aide.place(relx=0.5,rely=0.7,anchor='n')
# affichage de la valeur du MCS
self.display_valeur()
self.entry1.place(relx=0.27,rely = 0.5,relwidth=0.35)
self.entry2.place(relx=0.65,rely = 0.5,relwidth=0.35)
self.entry1.focus()
- self.aide = Label(self.frame_valeur, text = aide)
+ self.frame_valeur.update()
+ self.aide = Label(self.frame_valeur,
+ text = aide,
+ wraplength=int(self.frame_valeur.winfo_width()*0.8),
+ justify='center')
self.aide.place(relx=0.5,rely=0.7,anchor='n')
def get_bulle_aide(self):
else:
# on attend un entier, un réel ou une string
self.panel = UNIQUE_BASE_Panel
-
def SetText(self, text):
try:
def GetMinMax(self):
""" Retourne les valeurs min et max de la définition de object """
return self.object.get_min_max()
-\r
- def GetMultiplicite(self):\r
- """ A préciser.\r
- Retourne la multiplicité des valeurs affectées à l'objet\r
- représenté par l'item. Pour le moment retourne invariablement 1.\r
- """\r
- return 1\r
-\r
- def GetType(self):\r
- """ Retourne le type de valeur attendu par l'objet représenté par l'item.\r
- """\r
- return self.object.get_type()\r
-\r
- def GetIntervalle(self):\r
- """ Retourne le domaine de valeur attendu par l'objet représenté par l'item.\r
- """\r
- return self.object.getintervalle()\r
-\r
- def IsInIntervalle(self,valeur):\r
- """ Retourne 1 si la valeur est dans l'intervalle permis par\r
- l'objet représenté par l'item.\r
- """\r
- return self.object.isinintervalle(valeur)\r
+
+ 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 """
- 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
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)
self.jdc=jdc
self.nom_jdc=nom_jdc
self.fichier=None
+ self.panel_courant=None
if not appli:
class Appli:
Lance la génération du panneau contextuel de l'objet sélectionné
dans l'arbre
"""
+ if self.panel_courant:
+ # On detruit le panneau
+ self.panel_courant.destroy()
+ o=self.panel_courant
+ self.panel_courant=None
+ # Mettre à 1 pour verifier les cycles entre objets
+ # pour les panneaux
+ withCyclops=0
+ if withCyclops:
+ from Misc import Cyclops
+ z = Cyclops.CycleFinder()
+ z.register(o)
+ del o
+ z.find_cycles()
+ z.show_stats()
+ z.show_cycles()
+
+
if node.item.isactif():
if hasattr(node.item,"panel"):
- return node.item.panel(self,self.pane.pane('selected'),node)
+ self.panel_courant=node.item.panel(self,self.pane.pane('selected'),node)
else:
raise Exception("Le noeud sélectionné n'a pas de panel associé")
else:
- return panels.Panel_Inactif(self,self.pane.pane('selected'),node)
+ self.panel_courant = panels.Panel_Inactif(self,self.pane.pane('selected'),node)
+ return self.panel_courant
def init_modif(self):
"""
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)
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 !")
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 !")
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={}
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)
-
-
-
self.creer_boutons()
self.init()
+ def destroy(self):
+ Frame.destroy(self)
+ self.panneau=None
+ self.parent=None
+ # Because on herite de Frame
+ self.master=None
+ # On supprime explicitement les references aux objets Tk
+ self.nb=None
+ self.fr_but=None
+ self.bouton_cata=None
+ self.bouton_doc=None
+ self.bouton_com=None
+ self.bouton_sup=None
+ self.frame_eval=None
+ self.label=None
+ self.frame_boutons=None
+ self.frame_comment=None
+ self.frame_param=None
+ # On termine la suppression de facon brutale (objets Tk et non Tk)
+ for k in self.__dict__.keys():
+ # il est plus prudent de ne pas détruire le lien sur le Node
+ # si on voulait mettre l'attribut node à None, il faudrait
+ # que tous les appels à node.parent.select() apparaissent après
+ # toutes les autres actions liées au panel (node.item.isglobal(), ...)
+ if k != 'node' : setattr(self,k,None)
+
def creer_boutons(self):
"""
Méthode créant les boutons se trouvant dans la partie contextuelle d'EFICAS
if self.parent.modified == 'n' : self.parent.init_modif()
pere = self.node.parent
self.node.delete()
- pere.select()
def affiche(self):
""" Force l'affichage des fenêtres en cours """
self.parent=parent
self.item=Objecttreeitem.make_objecttreeitem(self.appli,self.nom,self.object)
- self.canvas=Pmw.ScrolledCanvas(self.parent,borderframe=1)
+ self.canvas=Pmw.ScrolledCanvas(self.parent,borderframe=1,canvas_background='gray95')
self.canvas.pack(padx=10,pady=10,fill = 'both', expand = 1)
if not sel:
def sel(event=None):
# SEE THE FILE "LICENSE.TERMS" FOR INFORMATION ON USAGE AND
# REDISTRIBUTION OF THIS FILE.
# ======================================================================
-import os,sys,string,re,types
+import os,sys,string,re,types,traceback
from Tkinter import *
import images
#
-__version__="$Name: V1_1p1 $"
-__Id__="$Id: treewidget.py,v 1.1.1.1 2001/12/04 15:38:23 eficas Exp $"
+__version__="$Name: $"
+__Id__="$Id: treewidget.py,v 1.3 2002/04/03 11:35:12 eficas Exp $"
#
Fonte_Standard = fontes.standard
try:
self.canvas.addtag_overlapping('move',bbox1[0],self.y +10,bbox1[2],bbox1[3])
except:
+ print "Erreur dans move :"
print self
print self.item
print self.item.object
try:
child.trace_ligne()
except:
+ print "Erreur dans trace_ligne :"
print child
print child.item.object
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 :
# 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)
print 'Erreur dans la destruction de ',self.item.get_nom(),' dans delete'
nbnew = pere.get_nb_children()
pere.redraw(nbnew-nbold)
+ pere.select()
def copynode(self,node,pos) :
""" node est le noeud à copier à la position pos de self ( = parent de node) """
try :
child.item.object.mc_liste = objet_copie.mc_liste
except:
- pass
+ traceback.print_exc()
#--------------------------------------------------------------
# Méthodes de vérification du contexte et de validité du noeud
#--------------------------------------------------------------
- def traite_mclist(self):
+ def traite_mclist_OLD(self):
""" Dans le cas d'une MCList il faut vérifier qu'elle n'est pas vide
ou réduite à un seul élément suite à une destruction
"""
# self représente une MCList
+ print "on passe par traite_mclist ",len(self.item)
if len(self.item) == 0 :
# la liste est vide : il faut la supprimer
self.delete()
noeud = self.children[0]
if self.parent.delete_child(self):
self.parent.append_node_child(noeud.item,pos=index,verif='non')
+ else:
+ print "destruction de self impossible !"
#if self.parent.delete_child(self):
# self.parent.copynode(self.children[0],index)
#else :
else :
return
+ def traite_mclist(self):
+ """ Dans le cas d'une MCList il faut vérifier qu'elle n'est pas vide
+ ou réduite à un seul élément suite à une destruction
+ """
+ # self représente une MCList
+ if len(self.item) == 0 :
+ # la liste est vide : il faut la supprimer
+ self.delete()
+ elif len(self.item) == 1:
+ # il ne reste plus qu'un élément dans la liste
+ # il faut supprimer la liste et créer directement l'objet
+ index = self.parent.children.index(self)
+ noeud = self.children[0]
+ noeud.parent = self.parent
+ self.parent.delete_node_child(self)
+ self.parent.item.replace_child(self.item,noeud.item)
+ self.parent.children.insert(index,noeud)
+ else :
+ return
+
def verif_all(self):
self.verif_all_children()
""" Retourne 1 si sd est du bon type par rapport à la classe """
return 0
+class cata:
+ def __init__(self):
+ CONTEXT.unset_current_cata()
+ CONTEXT.set_current_cata(self)
+
+ def enregistre(self,commande):
+ return
+
+c=cata()
+
OP1 = OPER(nom='OP1',op=1,sd_prod=concept,reentrant='f',
a=SIMP(typ='I'),
c=SIMP(typ='I',position='global'),
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()
"""
return []
+ 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
+
+ def verif_existence_sd(self):
+ """
+ Vérifie que les structures de données utilisées dans self existent bien dans le contexte
+ avant étape, sinon enlève la référence à ces concepts
+ --> sans objet pour les commandes commentarisées
+ """
+ pass
+
"""
return []
-
+ def get_sdprods(self,nom_sd):
+ """
+ Retourne les concepts produits par la commande
+ """
+ return None
+
+ def verif_existence_sd(self):
+ pass
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:
self.niveau = None
self.etape = None
self.state = 'undetermined'
+ self.actif=1
self.mc_liste=self.build_mc()
def build_mc(self):
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):
"""
return []
-
+ def verif_existence_sd(self):
+ pass
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()
"""
if not val : return None
d={}
+ val = string.strip(val)
+ if val[-1] == ';' : val = val[0:-1]
d['EVAL'] = Accas.EVAL
try:
valeur = eval(val,{},d)
--- /dev/null
+
+class ASSD:
+ def __repr__(self):
+ return "concept %s de type %s" % (self.get_name(),self.__class__.__name__)
"""
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) :
# Cas particulier des opérateurs réentrants
if not self.isvalid(sd='non') : return 0,"Nommage du concept refusé : l'opérateur n'est pas valide"
if self.definition.reentrant == 'o':
- self.sd = self.reuse = self.jdc.get_sdprod(nom)
+ # FR : appel à get_sdprod incorrect : il faut appeler get_sd_avant_etape
+ #self.sd = self.reuse = self.jdc.get_sdprod(nom)
+ self.sd = self.reuse = self.jdc.get_sd_avant_etape(nom,self)
if self.sd != None :
return 1,"Concept existant"
else:
if self.definition.reentrant == 'f' :
sd = self.jdc.get_sd_avant_etape(nom,self)
if sd != None :
- self.sd = self.reuse = sd
- return 1,"Opérateur facultativement réentrant et concept existant trouvé"
+ # FR : il faut tester que la sd trouvée est du bon type !!!!!!!!!!!!!!!!!
+ if isinstance(sd,self.get_type_produit()) :
+ self.sd = self.reuse = sd
+ return 1,"Opérateur facultativement réentrant et concept existant trouvé"
+ else:
+ return 0,"Concept déjà existant et de mauvais type"
else :
# il faut éventuellement enlever le lien vers une SD existante car si on passe ici
# cela signifie que l'opérateur n'est pas utilisé en mode réentrant.
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.reparent(etape)
etape.mc_liste.append(new_obj)
return etape
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)
+
+ def verif_existence_sd(self):
+ """
+ Vérifie que les structures de données utilisées dans self existent bien dans le contexte
+ avant étape, sinon enlève la référence à ces concepts
+ """
+ for motcle in self.mc_liste :
+ motcle.verif_existence_sd()
+
+ def Build_sd(self,nom):
+ """
+ Construit le concept produit de l'opérateur. Deux cas
+ peuvent se présenter :
+
+ - le parent n'est pas défini. Dans ce cas, l'étape prend en charge la création
+ et le nommage du concept.
+
+ - le parent est défini. Dans ce cas, l'étape demande au parent la création et
+ le nommage du concept.
+
+ """
+ if not self.isactif():return
+ # FR : attention cette méthode ne devrait pas se trouver là car elle surcharge celle qui
+ # se trouve dans N_ETAPE.py et elle est partie intégrante du noyau, mais, suite à l'absence de
+ # test de validité de l'opérateur avant d'essayer de déterminer la sd produite, on n'arrivait
+ # pas à relire avec EFICAS un fichier contenant une étape encore incomplète du style :
+ # sansnom = AFFE_CHAR_CINE(MODELE=None)
+ # Suite à la stabilisation du noyau d'Aster, je n'ai pas eu d'autre solution que de surcharger
+ # cette méthode ici en rajoutant le test manquant ...
+ if not self.isvalid(sd='non') : return
+ try:
+ if self.parent:
+ sd= self.parent.create_sdprod(self,nom)
+ if type(self.definition.op_init) == types.FunctionType:
+ apply(self.definition.op_init,(self,self.parent.g_context))
+ else:
+ sd=self.get_sd_prod()
+ # On n'utilise pas self.definition.op_init car self.parent
+ # n'existe pas
+ if sd != None and self.reuse == None:
+ # On ne nomme le concept que dans le cas de non reutilisation
+ # d un concept
+ sd.nom=nom
+ if self.jdc and self.jdc.par_lot == "NON" :
+ self.Execute()
+ return sd
+ except AsException,e:
+ raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
+ 'fichier : ',self.appel[1],e)
+ except EOFError:
+ # XXX Normalement le contexte courant doit etre le parent.
+ # Il n'y a pas de raison de remettre le contexte au parent
+ #self.reset_current_step()
+ raise
+ except :
+ l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
+ raise AsException("Etape ",self.nom,'ligne : ',self.appel[0],
+ 'fichier : ',self.appel[1]+'\n',
+ string.join(l))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+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
+
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)
# 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
self.niveau=self
self.params=[]
self.fonctions=[]
+ self._etape_context=None
def get_cmd(self,nomcmd):
"""
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 :
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":
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:
# 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':
objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
self.etapes.insert(pos,objet)
+ # il faut vérifier que les concepts utilisés par objet existent bien
+ # à ce niveau d'arborescence
+ objet.verif_existence_sd()
self.active_etapes()
self.editmode=0
+ self.reset_context()
return objet
else :
# On veut ajouter une nouvelle commande
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:
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'):
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):
"""
"""
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
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
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]
+
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):
"""
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
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.definition.label != '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
"""
self.init_modif()
if type(name)==types.StringType :
+ # on est en mode création d'un motcle
if self.ispermis(name) == 0 : return 0
objet=self.definition.entites[name](val=None,nom=name,parent=self)
if hasattr(objet.definition,'position'):
elif objet.definition.position == 'global_jdc' :
self.append_mc_global_jdc(objet)
else :
+ # dans ce cas on est en mode copie d'un motcle
objet = name
+ objet.verif_existence_sd()
# si un objet de même nom est déjà présent dans la liste
# et si l'objet est répétable
# il faut créer une MCList et remplacer l'objet de la liste
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()
# 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
def copy(self):
""" Retourne une copie de self """
objet = self.makeobjet()
+ # FR : attention !!! avec makeobjet, objet a le même parent que self
+ # 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
+ # 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.reparent(objet)
objet.mc_liste.append(new_obj)
return objet
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)
+
+ def verif_existence_sd(self):
+ """
+ Vérifie que les structures de données utilisées dans self existent bien dans le contexte
+ avant étape, sinon enlève la référence à ces concepts
+ """
+ for motcle in self.mc_liste :
+ motcle.verif_existence_sd()
return 0
def isoblig(self):
- for i in self.data:
- if i.isoblig():return 1
- return 0
+ """
+ Une MCList n'est jamais obligatoire (même si le MCFACT qu'elle représente l'est
+ """
+ return 0
+ #for i in self.data:
+ # if i.isoblig():return 1
+ #return 0
def liste_mc_presents(self):
return []
child.delete_concept(sd)
def copy(self):
+ """
+ Réalise la copie d'une MCList
+ """
liste = self.data[0].definition.list_instance()
- # XXX Pas de parent ??
- liste.init(self.nom)
+ # 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()
+ # 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
# Sans objet pour une liste de mots clés facteurs
return [],[]
+ def init_modif(self):
+ """
+ Met l'état de l'objet à modified et propage au parent
+ qui vaut None s'il n'existe pas
+ """
+ self.state = 'modified'
+ if self.parent:
+ self.parent.init_modif()
+
+ def get_etape(self):
+ """
+ Retourne l'étape à laquelle appartient self
+ Un objet de la catégorie etape doit retourner self pour indiquer que
+ l'étape a été trouvée
+ XXX double emploi avec self.etape ???
+ """
+ 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=parent.etape
+ for mcfact in self.data:
+ mcfact.reparent(parent)
+
+ def verif_existence_sd(self):
+ """
+ Vérifie que les structures de données utilisées dans self existent bien dans le contexte
+ avant étape, sinon enlève la référence à ces concepts
+ """
+ for motcle in self.data :
+ motcle.verif_existence_sd()
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
"""
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):
"""
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
# 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()
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)
def copy(self):
""" Retourne une copie de self """
objet = self.makeobjet()
- #XXX est ce utile ??
- objet.valeur = copy(self.valeur)
- objet.val = copy(self.val)
+ # il faut copier les listes et les tuples mais pas les autres valeurs
+ # possibles (réel,SD,...)
+ if type(self.valeur) in (types.ListType,types.TupleType):
+ objet.valeur = copy(self.valeur)
+ else:
+ objet.valeur = self.valeur
+ objet.val = objet.valeur
return objet
def makeobjet(self):
if issubclass(self.valeur.__class__,ASSD) : l.append(self.valeur)
return l
+
+ def set_valeur_co(self,nom_co):
+ """
+ Affecte à self l'objet de type CO et de nom 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
+
+ def verif_existence_sd(self):
+ """
+ Vérifie que les structures de données utilisées dans self existent bien dans le contexte
+ avant étape, sinon enlève la référence à ces concepts
+ """
+ l_sd_avant_etape = self.jdc.get_contexte_avant(self.etape).values()
+ if type(self.valeur) in (types.TupleType,types.ListType) :
+ l=[]
+ for sd in self.valeur:
+ if isinstance(sd,ASSD) :
+ if sd in l_sd_avant_etape :
+ l.append(sd)
+ else:
+ l.append(sd)
+ self.valeur=l
+ self.init_modif()
+ else:
+ if isinstance(self.valeur,ASSD) :
+ if self.valeur not in l_sd_avant_etape :
+ self.valeur = None
+ self.init_modif()
+
+
+ def get_min_max(self):
+ """
+ Retourne les valeurs min et max admissibles pour la valeur de self
+ """
+ return self.definition.min,self.definition.max
+
+
+ def get_type(self):
+ """
+ Retourne le type attendu par le mot-clé simple
+ """
+ return self.definition.type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
"""
"""
+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),
"""
return [],[]
+ 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é
+ """
+ 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
+
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
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
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",
) ;
+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),
+);
import Editeur
from Editeur import eficas_go
-if len(sys.argv) > 1 :
- # on veut ouvrir un fichier directement au lancement d'Eficas
- eficas_go.lance_eficas(code='SATURNE',fichier = sys.argv[1])
+def main():
+ if len(sys.argv) > 1 :
+ # on veut ouvrir un fichier directement au lancement d'Eficas
+ eficas_go.lance_eficas(code='SATURNE',fichier = sys.argv[1])
+ else:
+ # on veut ouvrir Eficas 'vide'
+ eficas_go.lance_eficas(code='SATURNE')
+
+def hidez():
+ from Misc import Cyclops
+ z = Cyclops.CycleFinder()
+ z.run(main)
+ z.find_cycles()
+ z.show_stats()
+ z.show_cycles()
+ # z.show_cycleobjs()
+ # z.show_sccs()
+ z.show_arcs()
+
+withCyclops=0
+
+if withCyclops:
+ hidez()
else:
- # on veut ouvrir Eficas 'vide'
- eficas_go.lance_eficas(code='SATURNE')
+ main()
+
utilisée par héritage multiple pour composer les traitements.
"""
# Modules Python
-import string,types
+import string,types,sys
import traceback
# Modules EFICAS
# Erreur pendant le calcul du type retourné
if CONTEXT.debug:traceback.print_exc()
self.sd=None
- if cr == 'oui' : self.cr.fatal('Impossible d affecter un type au résultat')
+ if cr == 'oui' :
+ l=traceback.format_exception(sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2])
+ self.cr.fatal('Impossible d affecter un type au résultat\n'+ string.join(l[2:]))
return 0
# on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
if self.reuse:
utilisée par héritage multiple pour composer les traitements.
"""
# Modules Python
-import string,types
+import string,types,sys
import traceback
# Modules EFICAS
# Erreur pendant le calcul du type retourné
if CONTEXT.debug:traceback.print_exc()
self.sd=None
- if cr == 'oui' : self.cr.fatal('Impossible d affecter un type au résultat')
+ if cr == 'oui' :
+ l=traceback.format_exception(sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2])
+ self.cr.fatal('Impossible d affecter un type au résultat\n'+string.join(l[2:]))
return 0
# on teste maintenant si la SD est r\351utilis\351e ou s'il faut la cr\351er
if self.reuse:
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)
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:
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):
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):