1 # -*- coding: utf-8 -*-
2 # CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
24 import types,traceback,sys,os
25 import string,linecache
30 from Noyau.N_ASSD import ASSD
31 #from Noyau.N_LASSD import LASSD
32 from Noyau.N_ETAPE import ETAPE
33 from Noyau.N_Exception import AsException
34 from Extensions import commentaire,parametre,parametre_eval
41 class JDC(I_OBJECT.OBJECT):
46 self.etapes_niveaux=[]
50 self._etape_context=None
51 self.recorded_units={}
52 self.old_recorded_units={}
54 def get_index(self,objet):
56 Retourne la position d'objet dans la liste self
58 return self.etapes.index(objet)
60 def get_sd_avant_du_bon_type(self,etape,types_permis):
62 Retourne la liste des concepts avant etape d'un type acceptable
64 d=self.get_contexte_avant(etape)
67 if type(v) != types.InstanceType and not isinstance(v,object): continue
68 # On considère que seul assd indique un type quelconque pas CO
69 elif self.assd in types_permis :
71 elif self.est_permis(v,types_permis):
76 def get_sd_avant_du_bon_type_pour_type_de_base(self,etape,type):
78 Retourne la liste des concepts avant etape d'1 type de base acceptable
79 Attention different de la routine précédente : 1 seul type passé en parametre
80 Teste sur issubclass et par sur le type permis
82 d=self.get_contexte_avant(etape)
85 typeverif=self.cata[0].__dict__[type]
89 if issubclass(v.__class__,typeverif):
94 def cherche_list_avant(self,etape,valeur):
95 d=self.get_contexte_avant(etape)
97 if issubclass(v.__class__,LASSD):
100 # Attention pour enlever les . a la fin des pretendus reels
101 if k == valeur[0:-1] :
105 def est_permis(self,v,types_permis):
106 for type_ok in types_permis:
107 if type_ok in ('R','I','C','TXM') and v in self.params :
109 elif type_ok == 'R' and v.__class__.__name__ == 'reel' :
111 elif type_ok == 'I' and v.__class__.__name__ == 'entier' :
113 elif type_ok == 'C' and v.__class__.__name__ == 'complexe' :
115 elif type_ok == 'TXM' and v.__class__.__name__ == 'chaine' :
117 elif type(type_ok) != types.ClassType and not isinstance(type_ok,type):
119 elif v.__class__ == type_ok or issubclass(v.__class__,type_ok):
123 def addentite(self,name,pos):
126 Si name est le nom d une commande ou un commentaire ajoute
128 Sinon remonte une erreur
132 if name == "COMMENTAIRE" :
133 # ajout d'un commentaire
134 self.set_current_step()
136 for child in self.etapes :
137 if isinstance(child,commentaire.COMMENTAIRE):
139 objet = commentaire.COMMENTAIRE('',parent=self)
140 objet.nom = "_comm_"+`ind`
141 if pos == None : pos = 0
142 self.etapes.insert(pos,objet)
146 CONNECTOR.Emit(self,"add",objet)
149 elif name == "PARAMETRE":
150 # ajout d'un parametre
151 self.set_current_step()
152 nom_param = '_param_'+str(len(self.params)+1)
153 objet = parametre.PARAMETRE(nom=nom_param)
154 if pos == None : pos = 0
155 self.etapes.insert(pos,objet)
159 CONNECTOR.Emit(self,"add",objet)
162 elif name == "PARAMETRE_EVAL":
163 # ajout d'un parametre EVAL
164 self.set_current_step()
165 nom_param = '_param_'+str(len(self.params)+1)
166 objet = parametre_eval.PARAMETRE_EVAL(nom=nom_param)
167 if pos == None : pos = 0
168 self.etapes.insert(pos,objet)
172 CONNECTOR.Emit(self,"add",objet)
175 elif type(name)==types.InstanceType:
176 # on est dans le cas où on veut ajouter une commande déjà
177 # existante (par copie donc)
178 # on est donc nécessairement en mode editeur ...
180 # Il ne faut pas oublier de reaffecter le parent d'obj (si copie)
182 self.set_current_step()
183 if isinstance(objet,ETAPE):
184 if objet.nom_niveau_definition == 'JDC':
185 # l'objet dépend directement du JDC
188 # l'étape dépend d'un niveau et non directement du JDC :
189 # il faut l'enregistrer dans le niveau de parent
190 objet.parent.dict_niveaux[objet.nom_niveau_definition].register(objet)
191 objet.niveau = objet.parent.dict_niveaux[objet.nom_niveau_definition]
192 self.etapes.insert(pos,objet)
194 # il faut vérifier que les concepts utilisés par objet existent bien
195 # à ce niveau d'arborescence
196 objet.verif_existence_sd()
197 objet.update_mc_global()
200 CONNECTOR.Emit(self,"add",objet)
204 # On veut ajouter une nouvelle commande
206 self.set_current_step()
207 cmd=self.get_cmd(name)
208 # L'appel a make_objet n'a pas pour effet d'enregistrer l'étape
209 # auprès du step courant car editmode vaut 1
210 # Par contre elle a le bon parent grace a set_current_step
212 if pos == None : pos = 0
213 self.etapes.insert(pos,e)
214 self.reset_current_step()
218 CONNECTOR.Emit(self,"add",e)
221 except AsException,e:
222 self.reset_current_step()
224 raise AsException("Impossible d ajouter la commande "+name + '\n' +str(e))
226 traceback.print_exc()
227 self.reset_current_step()
229 raise AsException("Impossible d ajouter la commande "+name)
232 #print "JDC.close",self
233 for etape in self.etapes:
234 if hasattr(etape,"close"):etape.close()
235 CONNECTOR.Emit(self,"close")
237 def set_current_step(self):
238 CONTEXT.unset_current_step()
239 CONTEXT.set_current_step(self)
241 def reset_current_step(self):
242 CONTEXT.unset_current_step()
244 def liste_mc_presents(self):
247 def get_sd_avant_etape(self,nom_sd,etape):
248 return self.get_contexte_avant(etape).get(nom_sd,None)
250 def get_sd_apres_etape_avec_detruire(self,nom_sd,sd,etape,avec='non'):
252 Cette méthode retourne la SD sd de nom nom_sd qui est éventuellement
253 définie apres etape en tenant compte des concepts detruits
254 Si avec vaut 'non' exclut etape de la recherche
256 #print "JDC.get_sd_apres_etape_avec_detruire",nom_sd,sd
257 ietap=self.etapes.index(etape)
258 if avec == 'non':ietap=ietap+1
260 for e in self.etapes[ietap:]:
263 autre_sd=d.get(nom_sd,None)
265 # Le concept a ete detruit. On interrompt la recherche car il n'y a
266 # pas eu de redefinition du concept (il n'y a pas de conflit potentiel).
268 if autre_sd is not sd :
269 # L'etape produit un concept different de meme nom. La situation n'est
270 # pas saine (sauf peut etre si reuse ???)
271 if hasattr(e,'reuse') and e.reuse == autre_sd:
272 # Le concept etant reutilise, on interrompt la recherche.
273 # On considere qu'il n'y a pas de nouveau concept defini
274 # meme si dans les etapes suivantes le concept est detruit
275 # et un concept de meme nom créé.
276 # AVERIFIER : avec reuse le concept devrait etre le meme
277 # le passage par ici est tres improbable
280 # Le concept est produit par l'etape (Il y a conflit potentiel).
281 # Le concept est redefini par une etape posterieure.
283 # Pas de destruction du concept ni de redefinition. On retourne le
287 def get_sd_apres_etape(self,nom_sd,etape,avec='non'):
289 Cette méthode retourne la SD de nom nom_sd qui est éventuellement
291 Si avec vaut 'non' exclut etape de la recherche
293 ietap=self.etapes.index(etape)
294 if avec == 'non':ietap=ietap+1
295 for e in self.etapes[ietap:]:
296 sd=e.get_sdprods(nom_sd)
298 if hasattr(e,'reuse'):
303 def get_sd_autour_etape(self,nom_sd,etape,avec='non'):
305 Fonction: retourne la SD de nom nom_sd qui est éventuellement
306 définie avant ou apres etape
307 Permet de vérifier si un concept de meme nom existe dans le périmètre
309 Si avec vaut 'non' exclut etape de la recherche
311 sd=self.get_sd_avant_etape(nom_sd,etape)
313 return self.get_sd_apres_etape(nom_sd,etape,avec)
315 def get_contexte_apres(self,etape):
317 Retourne le dictionnaire des concepts connus apres etape
318 On tient compte des commandes qui modifient le contexte
319 comme DETRUIRE ou les macros
320 Si etape == None, on retourne le contexte en fin de JDC
322 if not etape: return self.get_contexte_avant(etape)
324 d=self.get_contexte_avant(etape)
325 if etape.isactif():etape.update_context(d)
326 self.index_etape_courante=self.index_etape_courante+1
329 def active_etapes(self):
331 Cette méthode a pour fonction de désactiver les étapes qui doivent
332 l'être cad, dans le cas d'ASTER, les étapes qui ne sont pas
333 comprises entre le premier DEBUT/POURSUITE et le premier FIN
334 et rendre actives les autres
336 if self.definition.code == 'ASTER' :
337 # Seulement pour ASTER :
338 # Avant DEBUT actif vaut 0
339 # Apres DEBUT et avant le 1er FIN actif vaut 1
340 # Apres le 1er FIN actif vaut -1
344 for etape in self.etapes:
345 if actif == 0 and etape.nom in ['DEBUT','POURSUITE']:actif=1
350 if etape.nom == 'FIN':actif=-1
352 def suppentite(self,etape) :
354 Cette methode a pour fonction de supprimer une étape dans
356 Retourne 1 si la suppression a pu être effectuée,
357 Retourne 0 dans le cas contraire
359 #print "suppentite",self
360 #PN correction de bugs
361 if etape not in self.etapes:
365 index_etape=self.etapes.index(etape)
366 self.etapes.remove(etape)
368 if etape.niveau is not self:
369 # Dans ce cas l'étape est enregistrée dans un niveau
370 # Il faut la désenregistrer
371 etape.niveau.unregister(etape)
373 etape.supprime_sdprods()
378 # Apres suppression de l'etape il faut controler que les etapes
379 # suivantes ne produisent pas des concepts DETRUITS dans op_init de etape
381 index_etape=index_etape-1
382 etape=self.etapes[index_etape]
385 self.control_context_apres(etape)
388 CONNECTOR.Emit(self,"supp",etape)
392 def control_context_apres(self,etape):
394 Cette méthode verifie que les etapes apres l'etape etape
395 ont bien des concepts produits acceptables (pas de conflit de
397 Si des concepts produits ne sont pas acceptables ils sont supprimés.
398 Effectue les verifications sur les etapes du jdc mais aussi sur les
399 jdc parents s'ils existent.
401 #print "control_context_apres",self,etape
402 #Regularise les etapes du jdc apres l'etape etape
403 self.control_jdc_context_apres(etape)
405 def control_jdc_context_apres(self,etape):
407 Methode semblable a control_context_apres mais ne travaille
408 que sur les etapes et sous etapes du jdc
410 #print "control_jdc_context_apres",self,etape
412 # on demarre de la premiere etape
415 index_etape=self.etapes.index(etape)+1
418 etape=self.etapes[index_etape]
420 #derniere etape du jdc : rien a faire
423 context=self.get_contexte_avant(etape)
425 for e in self.etapes[index_etape:]:
426 e.control_sdprods(context)
427 e.update_context(context)
431 if not self.cr.estvide():return
435 def register_parametre(self,param):
437 Cette méthode sert à ajouter un paramètre dans la liste des paramètres
439 self.params.append(param)
441 def register_fonction(self,fonction):
443 Cette méthode sert à ajouter une fonction dans la liste des fonctions
445 self.fonctions.append(fonction)
447 def delete_param(self,param):
449 Supprime le paramètre param de la liste des paramètres
452 if param in self.params : self.params.remove(param)
453 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
455 def get_parametres_fonctions_avant_etape(self,etape):
457 Retourne deux éléments :
458 - une liste contenant les noms des paramètres (constantes ou EVAL)
460 - une liste contenant les formules définies avant etape
464 # on récupère le contexte avant etape
465 # on ne peut mettre dans les deux listes que des éléments de ce contexte
466 d=self.get_contexte_avant(etape)
467 # construction de l_constantes
468 for param in self.params:
470 if not nom : continue
471 if d.has_key(nom): l_constantes.append(nom)
472 # construction de l_fonctions
473 for form in self.fonctions:
475 if not nom : continue
476 if d.has_key(nom): l_fonctions.append(form.get_formule())
478 # on ajoute les concepts produits par DEFI_VALEUR
479 # XXX On pourrait peut etre faire plutot le test sur le type
480 # de concept : entier, reel, complexe, etc.
481 for k,v in d.items():
482 if hasattr(v,'etape') and v.etape.nom in ('DEFI_VALEUR',):
483 l_constantes.append(k)
485 # on retourne les deux listes
486 return l_constantes,l_fonctions
488 def get_nb_etapes_avant(self,niveau):
490 Retourne le nombre d etapes avant le debut de niveau
493 for niv in self.etapes_niveaux:
494 if niv == niveau:break
495 nb=nb+len(niv.etapes)
498 def send_message(self,message):
500 self.appli.send_message(message)
502 def init_modif(self):
504 Méthode appelée au moment où une modification va être faite afin de
505 déclencher d'éventuels traitements pré-modification
507 #print "init_modif",self
508 self.state = 'modified'
511 #print "fin_modif",self
512 CONNECTOR.Emit(self,"valid")
516 def deep_update_condition_bloc(self):
517 # pour le moment, on ne fait rien
518 raise "Not implemented"
520 def update_condition_bloc(self):
521 # pour le moment, on ne fait rien
522 raise "Not implemented"
524 def get_liste_mc_inconnus(self):
526 Retourne une liste contenant les mots-clés inconnus à la relecture du JDC
528 # cette liste a le format suivant : [etape,(bloc,mcfact,...),nom_mc,valeur_mc]
530 for etape in self.etapes :
532 if not etape.isvalid() :
533 l = etape.get_liste_mc_inconnus()
534 if l : l_mc.extend(l)
537 def get_genealogie(self):
539 Retourne la liste des noms des ascendants de l'objet self
540 jusqu'à la première ETAPE parent.
544 def get_liste_cmd(self):
546 Retourne la liste des commandes du catalogue
548 return self.niveau.definition.get_liste_cmd()
550 def get_groups(self):
552 Retourne la liste des groupes
554 return self.niveau.definition.liste_groupes,self.niveau.definition.dict_groupes
556 def set_etape_context(self,etape):
558 Positionne l'etape qui sera utilisee dans NommerSdProd pour
559 decider si le concept passé pourra etre nommé
561 self._etape_context=etape
563 def reset_context(self):
565 Cette methode reinitialise le contexte glissant pour pouvoir
566 tenir compte des modifications de l'utilisateur : création
567 de commandes, nommage de concepts, etc.
569 #print "reset_context",self,self.nom
570 self.current_context={}
571 self.index_etape_courante=0
573 for i,etape in enumerate(self.etapes):
575 self.index_etapes=ind
577 # for etape in self.etapes:
578 # etape.reset_context()
580 def del_sdprod(self,sd):
582 Supprime la SD sd de la liste des sd et des dictionnaires de contexte
584 #print "del_sdprod",self,sd
585 #print "del_sdprod",self.sds
586 #print "del_sdprod",self.g_context
587 #print "del_sdprod",self.sds_dict
588 if sd in self.sds : self.sds.remove(sd)
589 if self.g_context.has_key(sd.nom) : del self.g_context[sd.nom]
590 if self.sds_dict.has_key(sd.nom) : del self.sds_dict[sd.nom]
592 def del_param(self,param):
594 Supprime le paramètre param de la liste des paramètres
597 if param in self.params : self.params.remove(param)
598 if self.g_context.has_key(param.nom) : del self.g_context[param.nom]
600 def del_fonction(self,fonction):
602 Supprime la fonction fonction de la liste des fonctions
605 if fonction in self.fonctions : self.fonctions.remove(fonction)
606 if self.g_context.has_key(fonction.nom) : del self.g_context[fonction.nom]
608 def append_sdprod(self,sd):
610 Ajoute la SD sd à la liste des sd en vérifiant au préalable qu'une SD de
611 même nom n'existe pas déjà
613 if sd == None or sd.nom == None:return
615 o=self.sds_dict.get(sd.nom,None)
616 if isinstance(o,ASSD):
617 raise AsException("Nom de concept deja defini : %s" % sd.nom)
618 self.sds_dict[sd.nom]=sd
619 self.g_context[sd.nom] = sd
620 if sd not in self.sds : self.sds.append(sd)
622 def append_param(self,param):
624 Ajoute le paramètre param à la liste des params
625 et au contexte global
627 # il faudrait vérifier qu'un paramètre de même nom n'existe pas déjà !!!
628 if param not in self.params : self.params.append(param)
629 self.g_context[param.nom]=param
631 def append_fonction(self,fonction):
633 Ajoute la fonction fonction à la liste des fonctions
634 et au contexte global
636 # il faudrait vérifier qu'une fonction de même nom n'existe pas déjà !!!
637 if fonction not in self.fonctions : self.fonctions.append(fonction)
638 self.g_context[fonction.nom]=fonction
640 def delete_concept(self,sd):
645 Mettre a jour les etapes du JDC suite à la disparition du
647 Seuls les mots cles simples MCSIMP font un traitement autre
648 que de transmettre aux fils
650 #print "delete_concept",self,sd
651 for etape in self.etapes :
652 etape.delete_concept(sd)
654 def replace_concept_after_etape(self,etape,old_sd,sd):
656 Met à jour les étapes du JDC qui sont après etape en fonction
657 du remplacement du concept sd
659 index = self.etapes.index(etape)+1
660 if index == len(self.etapes) :
661 return # etape est la dernière étape du jdc ...on ne fait rien !
662 for child in self.etapes[index:]:
663 child.replace_concept(old_sd,sd)
665 def update_concept_after_etape(self,etape,sd):
667 Met à jour les étapes du JDC qui sont après etape en fonction
668 de la modification (principalement nommage) du concept sd
671 #On traite toutes les etapes
674 index = self.etapes.index(etape)+1
675 if index == len(self.etapes) :
676 return # etape est la dernière étape du jdc ...on ne fait rien !
677 for child in self.etapes[index:]:
678 child.update_concept(sd)
680 def dump_state(self):
681 print "JDC.state: ",self.state
682 for etape in self.etapes :
683 print etape.nom+".state: ",etape.state
685 def change_unit(self,unit,etape,old_unit):
686 #print "change_unit",unit,etape,old_unit
687 #print id(self.recorded_units),self.recorded_units
688 #if self.recorded_units.has_key(old_unit):del self.recorded_units[old_unit]
689 self.record_unit(unit,etape)
691 def record_unit(self,unit,etape):
692 """Enregistre les unites logiques incluses et les infos relatives a l'etape"""
693 #print "record_unit",unit,etape
696 self.recorded_units[None]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
698 self.recorded_units[unit]=(etape.fichier_ini ,etape.fichier_text,etape.recorded_units)
699 #print id(self.recorded_units),self.recorded_units
700 #print self.recorded_units.get(None,(None,"",{}))[2]
701 #print self.recorded_units.get(None,(None,"",{}))[2].get(None,(None,"",{}))
703 def changefichier(self,fichier):
706 def eval_in_context(self,valeur,etape):
707 """ Tente d'evaluer valeur dans le contexte courant de etape
708 Retourne le parametre valeur inchange si l'evaluation est impossible
710 #contexte initial du jdc
711 context=self.condition_context.copy()
712 #contexte courant des concepts. Il contient les parametres
713 context.update(self.get_contexte_avant(etape))
715 objet = eval(valeur,context)
718 #traceback.print_exc()
722 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
724 #print "supprime",self
725 Noyau.N_JDC.JDC.supprime(self)
728 self.const_context={}
732 self.current_context={}
733 self.condition_context={}
734 self.etapes_niveaux=[]
738 self._etape_context=None
741 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
742 def register(self,etape):
744 Cette méthode ajoute etape dans la liste
745 des etapes self.etapes et retourne l identificateur d'étape
746 fourni par l appel a g_register
748 A quoi sert editmode ?
749 - Si editmode vaut 1, on est en mode edition de JDC. On cherche
750 à enregistrer une étape que l'on a créée avec eficas (en passant
751 par addentite) auquel cas on ne veut récupérer que son numéro
752 d'enregistrement et c'est addentité qui l'enregistre dans
753 self.etapes à la bonne place...
754 - Si editmode vaut 0, on est en mode relecture d'un fichier de
755 commandes et on doit enregistrer l'étape à la fin de self.etapes
756 (dans ce cas l'ordre des étapes est bien l'ordre chronologique
759 if not self.editmode:
760 self.etapes.append(etape)
761 self.index_etapes[etape] = len(self.etapes) - 1
764 return self.g_register(etape)
766 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
767 def NommerSdprod(self,sd,sdnom,restrict='non'):
769 Nomme la SD apres avoir verifie que le nommage est possible :
771 Si le nom est deja utilise, leve une exception
772 Met le concept créé dans le concept global g_context
774 # XXX En mode editeur dans EFICAS, le nommage doit etre géré différemment
775 # Le dictionnaire g_context ne représente pas le contexte
776 # effectif avant une étape.
777 # Il faut utiliser get_contexte_avant avec indication de l'étape
779 # Cette etape est indiquee par l'attribut _etape_context qui a ete
780 # positionné préalablement par un appel à set_etape_context
782 if CONTEXT.debug : print "JDC.NommerSdprod ",sd,sdnom
784 if self._etape_context:
785 o=self.get_contexte_avant(self._etape_context).get(sdnom,None)
787 o=self.sds_dict.get(sdnom,None)
789 if isinstance(o,ASSD):
790 raise AsException("Nom de concept deja defini : %s" % sdnom)
792 # ATTENTION : Il ne faut pas ajouter sd dans sds car il s y trouve deja.
793 # Ajoute a la creation (appel de reg_sd).
794 self.sds_dict[sdnom]=sd
797 # En plus si restrict vaut 'non', on insere le concept dans le contexte du JDC
798 if restrict == 'non':
799 self.g_context[sdnom]=sd
801 #ATTENTION SURCHARGE : cette methode doit etre gardée en synchronisation avec celle de Noyau
802 def delete_concept_after_etape(self,etape,sd):
804 Met à jour les étapes du JDC qui sont après etape en fonction
805 de la disparition du concept sd
807 index = self.etapes.index(etape)+1
808 if index == len(self.etapes) :
809 return # etape est la dernière étape du jdc ...on ne fait rien !
810 for child in self.etapes[index:]:
811 child.delete_concept(sd)
813 #ATTENTION SURCHARGE : les methodes ci-dessous surchargent des methodes de Noyau et Validation : a reintegrer
815 def get_file(self,unite=None,fic_origine=''):
817 Retourne le nom du fichier correspondant à un numero d'unité
818 logique (entier) ainsi que le source contenu dans le fichier
821 # Si le JDC est relié à une application maitre, on délègue la recherche
822 file,text= self.appli.get_file(unite,fic_origine)
826 if os.path.exists("fort."+str(unite)):
827 file= "fort."+str(unite)
829 raise AsException("Impossible de trouver le fichier correspondant"
830 " a l unite %s" % unite)
831 if not os.path.exists(file):
832 raise AsException("%s n'est pas un fichier existant" % unite)
836 #if file == None : return None,None
837 text=string.replace(text,'\r\n','\n')
839 linecache.cache[file]=0,0,string.split(text,'\n'),file
842 def isvalid(self,cr='non'):
843 if hasattr(self,'valid'): old_valid=self.valid
845 valid=Validation.V_JDC.JDC.isvalid(self,cr)
846 if valid != old_valid:
847 CONNECTOR.Emit(self,"valid")