From 877737f813538f5cb7549feea81ba9aebfe0faa9 Mon Sep 17 00:00:00 2001 From: salome <> Date: Mon, 28 Nov 2005 12:55:04 +0000 Subject: [PATCH] nettoyage du code --- src/CONFIG/Makefile.in | 16 ++ src/CONFIG/eficasConfig.py | 18 ++ src/EFICASGUI/EFICASGUI.py | 69 ++--- src/EFICASGUI/Makefile.in | 13 +- src/EFICASGUI/eficasSalome.py | 459 ++++++++++++++++++++++++++++++++-- src/Makefile.in | 4 +- 6 files changed, 515 insertions(+), 64 deletions(-) create mode 100644 src/CONFIG/Makefile.in create mode 100644 src/CONFIG/eficasConfig.py diff --git a/src/CONFIG/Makefile.in b/src/CONFIG/Makefile.in new file mode 100644 index 00000000..a59c5228 --- /dev/null +++ b/src/CONFIG/Makefile.in @@ -0,0 +1,16 @@ +# source path +top_srcdir=@top_srcdir@ +top_builddir=../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome + +@COMMENCE@ + +EXPORT_PYSCRIPTS = \ +eficasConfig.py + + +# Executables targets + +@CONCLUDE@ + diff --git a/src/CONFIG/eficasConfig.py b/src/CONFIG/eficasConfig.py new file mode 100644 index 00000000..b50a3371 --- /dev/null +++ b/src/CONFIG/eficasConfig.py @@ -0,0 +1,18 @@ +import os + + + + +# répertoire du logiciel Eficas +eficasPath = '' +if os.environ.has_key( "EFICAS_ROOT"): + eficasPath = os.environ["EFICAS_ROOT"] + + + + + + + + + diff --git a/src/EFICASGUI/EFICASGUI.py b/src/EFICASGUI/EFICASGUI.py index d4383962..f2429e85 100644 --- a/src/EFICASGUI/EFICASGUI.py +++ b/src/EFICASGUI/EFICASGUI.py @@ -36,10 +36,6 @@ aGuiDS=salomedsgui.guiDS() print "EFicasGUI :: :::::::::::::::::::::::::::::::::::::::::::::::::::::" -# ----------------------------------------------------------------------------- -# gestionnaire arbre d'étude -from EficasStudy import study - # ----------------------------------------------------------------------------- #Cette méthode est obsolète en V3 @@ -84,8 +80,9 @@ def setSettings(): currentStudyId = sgPyQt.getStudyId() print "setSettings: currentStudyId = " + str(currentStudyId) # _CS_gbo_ Voir si on peut utiliser directement sgPyQt.getStudyId() - # dans salomedsgui? - study.setCurrentStudyID( currentStudyId ) + # dans salomedsgui? + + palStudyManager.setCurrentStudyID( currentStudyId ) #CS_pbruno def activate(): """ @@ -108,8 +105,9 @@ def activeStudyChanged(ID): # studyId=sg.getActiveStudyId() currentStudyId=ID print "_CS_GBO_ : EFICASGUI.activeStudyChanged : currentStudyId = ", currentStudyId - print "_CS_GBO_ : EFICASGUI.activeStudyChanged : sgPyQt.getStudyId() = ", sgPyQt.getStudyId() - study.setCurrentStudyID( ID ) + print "_CS_GBO_ : EFICASGUI.activeStudyChanged : sgPyQt.getStudyId() = ", sgPyQt.getStudyId() + + palStudyManager.setCurrentStudyID( currentStudyId ) #CS_pbruno def definePopup(theContext, theObject, theParent): @@ -136,28 +134,28 @@ import eficasSalome def runEficas(): print "-------------------------EFICASGUI::runEficas-------------------------" - print currentStudyId - eficasSalome.runEficas("ASTER",studyId=currentStudyId) - -def runEELIH(code="ASTER"): - # Enregistrement dans l étude - import eficasEtude - import appli - print "++++++++++++++++++++++++++++++++++++++++++++++++++++" - print currentStudyId - - MaRef=eficasEtude.Eficas_In_Study(code,studyId=currentStudyId) - # flag = E pour Eficas (enregistrement manuel du fichier de commandes) - flag = 'E' - moi=appli.Appli(MaRef, flag) + print currentStudyId + #eficasSalome.runEficas("ASTER",studyId=currentStudyId) + #ws = sgPyQt.getMainFrame() + desktop=sgPyQt.getDesktop() + eficasSalome.runEficas( desktop, palStudyManager, "ASTER" ) + def runEficaspourHomard(): print "runEficas" - eficasSalome.runEficas("HOMARD") + #eficasSalome.runEficas("HOMARD") + desktop=sgPyQt.getDesktop() + eficasSalome.runEficas( desktop, palStudyManager, "HOMARD" ) + + def runEficasHomard(): print "runEficas" - eficasSalome.runEficas("HOMARD") + #eficasSalome.runEficas("HOMARD") + desktop=sgPyQt.getDesktop() + eficasSalome.runEficas( desktop, palStudyManager, "HOMARD" ) + + def runEficasFichier(): """ @@ -166,7 +164,7 @@ def runEficasFichier(): """ print "runEficasFichier" attr=None - code="ASTER" + code=None a=salome.sg.getAllSelected() if len(a) == 1: aGuiDS.setCurrentStudy(currentStudyId) @@ -174,20 +172,25 @@ def runEficasFichier(): if boo : code = "ASTER" else : - boo,attr=aGuiDS.getExternalFileAttribute("FICHIER_EFICAS_HOMARD",a[0]) - code = "HOMARD" + boo,attr=aGuiDS.getExternalFileAttribute("FICHIER_EFICAS_HOMARD",a[0]) + if boo: + code = "HOMARD" + if code: + #eficasSalome.runEficas(code,attr,studyId=currentStudyId) + desktop=sgPyQt.getDesktop() + eficasSalome.runEficas( desktop, palStudyManager, code, attr ) - eficasSalome.runEficas(code,attr,studyId=currentStudyId) # Partie applicative dict_command={ - 941:runEficas, - 943:runEELIH, + 941:runEficas, 946:runEficaspourHomard, - 4041:runEficas, - 4043:runEELIH, + 4041:runEficas, 4046:runEficaspourHomard, 9042:runEficasFichier, } - + +#CS_pbruno temporaire +import studyManager #from PAL +palStudyManager = studyManager.SalomeStudy() \ No newline at end of file diff --git a/src/EFICASGUI/Makefile.in b/src/EFICASGUI/Makefile.in index 2a9b05d4..cd89a890 100644 --- a/src/EFICASGUI/Makefile.in +++ b/src/EFICASGUI/Makefile.in @@ -32,24 +32,13 @@ LIB_SERVER_IDL = PO_FILES = EFICAS_msg_en.po EFICAS_icons.po EXPORT_PYSCRIPTS = \ -dataEficas.py \ -eficasEtude.py \ EFICASGUI.py \ -SMESH_utils.py \ -eficasCL.py \ -ChoixMaillage.py \ -MonChoixMaillage.py \ eficasSalome.py \ -meshdialog.py \ -meshdialogImp.py + # _CS_gbo_151104 Ajout pour compatibilité ascendante entre versions de Eficas EXPORT_PYSCRIPTS+=eficas_etude.py -PYUIC = pyuic - -%.py:%.ui - $(PYUIC) $< -o $@ # additionnal information to compil and link file diff --git a/src/EFICASGUI/eficasSalome.py b/src/EFICASGUI/eficasSalome.py index b86f9e50..df20f668 100644 --- a/src/EFICASGUI/eficasSalome.py +++ b/src/EFICASGUI/eficasSalome.py @@ -1,37 +1,462 @@ import qt import notifqt # ----------------------------------------------------------------------------- -import sys +import sys, os + + +""" # Remplacement de la fonction exit standard par une fonction # qui n'interrompt pas l'execution + sys._exit=sys.exit def exit(ier): print "appel de exit: ",ier -#sys.exit=exit + # Fin remplacement +""" + +import eficasConfig + +sys.path[:0]=[os.path.join( eficasConfig.eficasPath,'Aster'), + os.path.join( eficasConfig.eficasPath,'Homard'), + os.path.join( eficasConfig.eficasPath,'Editeur'), + eficasConfig.eficasPath, + ] +print 'sys.path', sys.path -initialised=0 import Tkinter -root=Tkinter.Tk() -root.withdraw() -def runEficas(code="ASTER",fichier=None,studyId=None): - global initialised - if not initialised: - t=Tkinter.Toplevel() - t.withdraw() - import dataEficas; dataEficas.init(t,code,fichier,studyId=studyId) - t.update() - t.deiconify() - t.update() - #initialised=1 +# mode de lancement Eficas +ASTER = "ASTER" +HOMARD = "HOMARD" + + +import Editeur +from Editeur import eficas +from Editeur import splash + +import salome +import meshGui +import studyManager + +from qxembed import QXEmbed + + + +# message utilisateur +msgWarning = "Attention" +msgSubShapeBadMainShape = "La sélection géométrique SALOME ne correspond pas à une sous-géométrie de la géométrie principale : " +msgMeshGroupBadMainShape = "Le groupe de maillage sélectionné dans SALOME ne référence pas la bonne géométrie principale : " +msgIncompleteSelection = "Tous les éléments de la sélection SALOME n'ont pu étre ajoutée" +msgUnAuthorizedSelecion = "Sélection SALOME non authorisé. Autorisé : sous-géométrie, groupe de maille" +msgErrorAddJdcInSalome = "Erreur dans l'export du fichier de commande dans l'arbre d'étude Salome" +msgErrorDisplayShape = "Erreur dans l'affichage de la forme géométrique sélectionnée" + + + + +#class MyEficas( Tkinter.Toplevel, eficas.EFICAS, QXEmbed ): +class MyEficas( Tkinter.Toplevel, eficas.EFICAS ): + """ + Classe de lancement du logiciel EFICAS dans SALOME. + Cette classe spécialise le logiciel Eficas par l'ajout de: + a)la création de groupes de mailles dans le composant SMESH de SALOME + b)la visualisation d'éléments géométrique dans le coposant GEOM de SALOME par sélection dans EFICAS + """ + def __init__(self, parent, palStudyManager, code = None, fichier = None ): + """ + Constructeur. + + @type parent: + @param parent: widget Qt parent + + @type palStudyManager: studyManager.SalomeStudy + @param palStudyManager: gestionnaire d'étude SALOME + + @type code: string + @param code: catalogue à lancer ( ASTER, HOMARD ). optionnel ( défaut = ASTER ). + + @type fichier: string + @param fichier: chemin absolu du fichier eficas à ouvrir à dès le lancement. optionnel + """ + #QXEmbed.__init__( self, parent, "", qt.Qt.WDestructiveClose | qt.Qt.WStyle_Customize | qt.Qt.WStyle_StaysOnTop ) + Tkinter.Toplevel.__init__( self ) + + #---------------------------- initialisation EFICAS ----------------- + splash.init_splash( self, code = code, titre = "Lancement d'EFICAS pour %s" %code ) + splash._splash.configure( text="Chargement d'EFICAS en cours.\n Veuillez patienter ..." ) + # différence eficas 1.7 et 1.8 + if Editeur.__dict__.has_key( 'session' ): + print 'CS_pbruno has_key session' + from Editeur import session + eficasArg = sys.argv + if fichier: + eficasArg += [ fichier ] + session.parse( eficasArg ) + + eficas.EFICAS.__init__( self, self, code = code ) + #---------------------------------------------------------------------- + + + """ + #------ embarcation dans une fenêtre qt pour mise au premier plan --- + #embedded = QXEmbed( parent, "", qt.Qt.WDestructiveClose | qt.Qt.WStyle_Customize | qt.Qt.WStyle_StaysOnTop ) + embedded = QXEmbed( parent, "" ) + embedded.initialize() + embedded.show() + embedded.embedTk( self.winfo_id() ) + size = embedded.sizeHint() + print 'CS_pbruno size (%s, %s )'%( size.width(), size.height () ) + embedded.resize( size.width(), size.height () ) + embedded.setWFlags( qt.Qt.WDestructiveClose | qt.Qt.WStyle_Customize | qt.Qt.WStyle_StaysOnTop ) + #---------------------------------------------------------------------- + """ + + #--------------- spécialisation EFICAS dans SALOME ------------------- + self.parent = parent + self.salome = True #active les parties de code spécifique dans Salome + self.palStudyManager = palStudyManager # gestionnaire étude SALOME + + # donnée pour la création de groupe de maille + self.mainShapeNames = {} #dictionnaire pour gérer les multiples fichiers possibles ouverts par + self.mainShapeEntries = {} #eficas ( clé = identifiant du JDC ), une mainshape par fichier ouvert. + self.subShapes = {} #dictionnaire des sous-géométrie de la géométrie principale ( clé = entry, valeur = name ) + #---------------------------------------------------------------------- + + + def quit(self): + global appli + self.destroy() + appli = None + + + + def __selectShape( self, jdcID, selectedEntry ): + """ + sélection sous-géométrie dans Salome: + -test1) si c'est un élément géométrique. + -test2) si appartient à la géométrie principale. + + met à jours la liste self.subShapes si test ok + """ + print 'CS_pbruno __selectShape' + name, msgError = '','' + + selectedMainShapeEntry = self.palStudyManager.getMainShapeEntry( selectedEntry ) + + if selectedMainShapeEntry: #ok test1) + if not self.mainShapeEntries.has_key( jdcID ): + self.mainShapeEntries[ jdcID ] = selectedMainShapeEntry + if selectedMainShapeEntry == self.mainShapeEntries[ jdcID ]: + name = self.palStudyManager.getNameAttribute( selectedEntry ) + self.subShapes[ selectedEntry ] = name + else: + print 'CS_pbruno pas la même mainshape selectedEntry->',selectedEntry + if not self.mainShapeNames.has_key( jdcID ): + self.mainShapeNames[ jdcID ] = self.palStudyManager.getNameAttribute( self.mainShapeEntries[ jdcID ] ) + msgError = msgSubShapeBadMainShape + self.mainShapeNames[ jdcID ] + + return name, msgError + + + + def __selectMeshGroup( self, jdcID, selectedEntry ): + """ + sélection groupe de maille dans Salome: + -test 1) si c'est un groupe de maille + -test 2) si le maillage fait référence à la géométrie principale + """ + print 'CS_pbruno __selectMeshGroup' + name, msgError = '','' + + selectedMeshEntry = self.palStudyManager.getMesh( selectedEntry ) + + if selectedMeshEntry: # ok test 1) + print 'CS_pbruno __selectMeshGroup selectedMeshEntry',selectedMeshEntry + selectedMainShapeEntry = self.palStudyManager.getShapeFromMesh( selectedMeshEntry ) + + if selectedMainShapeEntry: #test 2) + print 'CS_pbruno __selectMeshGroup selectedMainShapeEntry',selectedMainShapeEntry + if not self.mainShapeEntries.has_key( jdcID ): + self.mainShapeEntries[ jdcID ] = selectedMainShapeEntry + if selectedMainShapeEntry == self.mainShapeEntries[ jdcID ]: + name = self.palStudyManager.getNameAttribute( selectedEntry ) #ok test 2) + else: + print 'CS_pbruno pas la même mainshape selectedEntry ->',selectedEntry + if not self.mainShapeNames.has_key( jdcID ): + self.mainShapeNames[ jdcID ] = self.palStudyManager.getNameAttribute( self.mainShapeEntries[ jdcID ] ) + msgError = msgMeshGroupBadMainShape + self.mainShapeNames[ jdcID ] + + return name, msgError + + + + + def __updateSubShapes( self, jdcID, groupeNames ): + """ + mise à jours de la liste self.subShapes à partir de la liste des noms de groupe fourni en entré + """ + for name in groupeNames: + entries = self.palStudyManager.getEntriesFromName( studyManager.SGeom, name ) + for entry in entries: + ok, msgError = self.__selectShape( jdcID, entry ) # filtre + if ok: + self.subShapes[ entry ] = name + + + def __getAllGroupeMa(self, item ): + """ + Récupère tous les GROUPE_MA dans le JDC courant + """ + groupMa = () + try: + itemName = item.get_nom() + #print 'CS_pbruno itemName',itemName + if itemName == 'GROUP_MA': + itemValue = item.get_valeur() + print 'CS_pbruno trouvé! GROUP_MA->', itemValue + if type( itemValue ) == str: + groupMa += ( itemValue , ) + elif type( itemValue ) == tuple: + groupMa += itemValue + else: + children = item.GetSubList() + for child in children: + groupMa += self.__getAllGroupeMa( child ) + except: # à cause de GetSubList()... + pass + print 'CS_pbruno groupMa',groupMa + return groupMa + + + def __getAllGroupeNo(self, item ): + """ + Récupère tous les GROUPE_NO dans le JDC courant + """ + groupNo = () + try: + itemName = item.get_nom() + print 'CS_pbruno itemName',itemName + if itemName == 'GROUP_NO': + itemValue = item.get_valeur() + print 'CS_pbruno trouvé! GROUP_NO->', itemValue + if type( itemValue ) == str: + groupNo += ( itemValue , ) + elif type( itemValue ) == tuple: + groupNo += itemValue + else: + children = item.GetSubList() + for child in children: + groupNo += self.__getAllGroupeNo( child ) + except: # à cause de GetSubList()... + pass + return groupNo + + #----------------------- LISTE DES NOUVEAUX CAS D'UTILISATIONS ----------- + def selectGroupFromSalome( self ): + """ + Sélection d'élément(s) d'une géométrie ( sub-shape ) ou d'élément(s) de maillage ( groupe de maille) à partir de l'arbre salome + retourne ( la liste des noms des groupes, message d'erreur ) + + Note: Appelé par EFICAS lorsqu'on clique sur le bouton ajouter à la liste du panel AFF_CHAR_MECA + """ + print 'CS_pbruno selectGroupFromSalome' + names, msg = [], '' + try: + # récupère toutes les sélections de l'utilsateur dans l'arbre Salome + entries = salome.sg.getAllSelected() + print 'CS_pbruno entries->',entries + nbEntries = len( entries ) + if nbEntries >= 1: + print 'CS_pbruno len( entries ) >= 1:' + jdcID = self.bureau.nb.getcurselection() + for entry in entries: + if self.palStudyManager.isMeshGroup( entry ): #sélection d'un groupe de maille + name, msg = self.__selectMeshGroup( jdcID, entry ) + elif self.palStudyManager.isShape( entry ): #sélection d'une sous-géométrie + name, msg = self.__selectShape( jdcID, entry ) + else: + name, msg = '', msgUnAuthorizedSelecion + if name: + names.append( name ) + + if names and len( names ) < nbEntries: + msg = msgIncompleteSelection + except: + pass + salome.sg.EraseAll() + print 'CS_pbruno selectGroupFromSalome names = ',names + return names, msg + + + def addJdcInSalome( self, jdcPath ): + """ + Ajoute le Jeu De Commande ASTER ou HOMARD dans l'arbre d'étude Salome dans la rubrique EFICAS + """ + ok, msgError = False, '' + + if self.bureau.code == 'ASTER': + ok = self.palStudyManager.addEficasItem( jdcPath, studyManager.FICHIER_EFICAS_ASTER ) + elif self.bureau.code == 'HOMARD': + ok = self.palStudyManager.addEficasItem( jdcPath, studyManager.FICHIER_EFICAS_HOMARD ) + #ok = self.palStudyManager.addEficasItem( jdcPath, studyManager.FICHIER_EFICAS_HOMARD_CONF ) CS_pbruno ????? + if not ok: + msgError = msgErrorAddJdcInSalome + return ok, msgError + + + def createOrUpdateMesh( self ): + """ + Ouverture d'une boite de dialogue : Creation de groupes de mailles dans un maillage existant ou un nouveau maillage. + Note: Appelé par EFICAS à la sauvegarde du JDC. + """ + + jdcID = self.bureau.nb.getcurselection() + + groupeMaNames = self.__getAllGroupeMa( self.bureau.JDCDisplay_courant.tree.item ) + groupeNoNames = self.__getAllGroupeNo( self.bureau.JDCDisplay_courant.tree.item ) + + print 'CS_pbruno createOrUpdateMesh groupeMaNames', groupeMaNames + print 'CS_pbruno createOrUpdateMesh groupeNoNames', groupeNoNames + + # mise à jours de la liste des sous-géométrie ( self.subShapes ) + self.__updateSubShapes( jdcID, groupeMaNames ) + self.__updateSubShapes( jdcID, groupeNoNames ) + + + # recupération des identifiants( entries ) associés aux noms des groupes + groupeMaEntries = [] + groupeNoEntries = [] + + for entry, name in self.subShapes.items(): + if name in groupeMaNames: + groupeMaEntries.append( entry ) + if name in groupeNoNames: + groupeNoEntries.append( entry ) + + + print 'CS_pbruno groupeMaEntries ->',groupeMaEntries + print 'CS_pbruno groupeNoEntries ->',groupeNoEntries + if groupeMaEntries or groupeNoEntries: + print 'if groupeMaEntries or groupeNoEntries:' + diag = meshGui.MeshUpdateDialogImpl( self.mainShapeEntries[jdcID], groupeMaEntries, groupeNoEntries, self.palStudyManager, + self.parent ) + diag.show() + + + def displayShape( self, shapeName ): + """ + visualisation géométrie de nom shapeName dans salome + """ + ok, msgError = False, '' + salome.sg.EraseAll() + print 'displayShapestrGeomShape shapeName -> ', shapeName + ok = self.palStudyManager.displayShapeByName( shapeName ) + if not ok: + msgError = msgErrorDisplayShape + return ok, msgError + + + def creeConfigTxt(self,fichier,dico): + """ + sauvegarde = asksaveasfilename(title="fichier config.txt", + defaultextension='.txt', + initialdir = fichier) + f=open(sauvegarde,'w+') + for unite in dico.keys(): + print unite + type=dico[unite][0] + fic=dico[unite][1:] + ligne="fort."+str(unite)+" "+type+" "+fic + f.write(ligne) + f.close() + self.rangeInStudy(sauvegarde) + print "===============================" + print "fin crreConfigTxt" + """ + pass #CS_pbruno à implémenter + + + + + + + + +#def runEficas( palStudyManager, code="ASTER", fichier=None, studyId=None): +def runEficas( parent, palStudyManager, code="ASTER", fichier=None ): + global appli + if not appli: #une seul instance possible! + appli = MyEficas( parent, palStudyManager, code = code, fichier = fichier ) + + def runHomard() : - runEficas("HOMARD") + print 'CS_pbruno non implémentée' + """ + parent = + palStudyManager = + runEficas( parent, palStudyManager, code="HOMARD"): + """ def runAster() : - runEficas("ASTER") + print 'CS_pbruno non implémentée' + """ + parent = + palStudyManager = + runEficas( parent, palStudyManager, code="ASTER"): + """ + + +# Init globale du module +root = Tkinter.Tk() +root.withdraw() + +appli = None + + + + + + + + +""" + #embedded.showMaximized() + #embedded.embed( appli.winfo_id() ) + + embedded.setWFlags( qt.Qt.WStyle_Customize | qt.Qt.WStyle_StaysOnTop ) + embedded.setFocus() + + if embedded.hasFocus () : + print 'hasfocus' + else: + print 'pas focus' + + + if embedded.isFocusEnabled(): + print 'isFocusEnabled()' + else: + print 'not isFocusEnabled()' + + focusP = embedded.focusPolicy() + + if focusP == qt.QWidget.TabFocus: + print 'qt.QWidgetTabFocus' + elif focusP == qt.QWidget.ClickFocus: + print 'qt.ClickFocus' + elif focusP == qt.QWidget.StrongFocus: + print 'qt.StrongFocus' + elif focusP == qt.QWidget.WheelFocus: + print 'qt.WheelFocus' + elif focusP == qt.QWidget.NoFocus: + print 'qt.NoFocus' + else: + print 'bizarre' + + embedded.grabKeyboard() + """ \ No newline at end of file diff --git a/src/Makefile.in b/src/Makefile.in index 53da0e04..660fbdf1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -4,7 +4,7 @@ # Author : Paul RASCLE, EDF # Project : SALOME # Copyright : EDF 2001 -# $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/EFICAS_SRC/src/Makefile.in,v 1.4 2005/09/30 17:41:46 salome Exp $ +# $Header: /home/salome/PlateFormePAL/Bases_CVS_EDF/Modules_EDF/EFICAS_SRC/src/Makefile.in,v 1.5 2005/10/19 14:05:41 salome Exp $ #============================================================================== # source path @@ -15,6 +15,6 @@ VPATH=.:@srcdir@ @COMMENCE@ -SUBDIRS = EFICAS EFICASGUI EELIH STUDY +SUBDIRS = EFICAS EFICASGUI CONFIG @MODULE@ -- 2.39.2