]> SALOME platform Git repositories - tools/eficas.git/commitdiff
Salome HOME
1ere mise en référence
authorpbruno <>
Mon, 19 Feb 2007 19:16:35 +0000 (19:16 +0000)
committerpbruno <>
Mon, 19 Feb 2007 19:16:35 +0000 (19:16 +0000)
53 files changed:
Interface/Objecttreeitem.py [new file with mode: 0644]
Interface/analyse_catalogue.py [new file with mode: 0644]
Interface/autre_analyse_cata.py [new file with mode: 0644]
Interface/basestyle.py [new file with mode: 0644]
Interface/browser.py [new file with mode: 0644]
Interface/comploader.py [new file with mode: 0644]
Interface/compobase.py [new file with mode: 0644]
Interface/compobloc.py [new file with mode: 0644]
Interface/compocomm.py [new file with mode: 0644]
Interface/compocommandecomm.py [new file with mode: 0644]
Interface/compoerror.py [new file with mode: 0644]
Interface/compofact.py [new file with mode: 0644]
Interface/compoformule.py [new file with mode: 0644]
Interface/compojdc.py [new file with mode: 0644]
Interface/compomacro.py [new file with mode: 0644]
Interface/compomclist.py [new file with mode: 0644]
Interface/componiveau.py [new file with mode: 0644]
Interface/componuplet.py [new file with mode: 0644]
Interface/compooper.py [new file with mode: 0644]
Interface/compoparam.py [new file with mode: 0644]
Interface/compoparameval.py [new file with mode: 0644]
Interface/compoproc.py [new file with mode: 0644]
Interface/composimp.py [new file with mode: 0644]
Interface/configuration.py [new file with mode: 0644]
Interface/editor.py [new file with mode: 0644]
Interface/eficas.py [new file with mode: 0644]
Interface/fontes.py [new file with mode: 0644]
Interface/icons.py [new file with mode: 0644]
Interface/import_code.py [new file with mode: 0644]
Interface/macrodisplay.py [new file with mode: 0644]
Interface/myMain.ui [new file with mode: 0644]
Interface/myMain_ui.py [new file with mode: 0644]
Interface/newsimppanel.py [new file with mode: 0644]
Interface/panels.py [new file with mode: 0644]
Interface/panelsSalome.py [new file with mode: 0644]
Interface/plusieursassdpanel.py [new file with mode: 0644]
Interface/plusieursbasepanel.py [new file with mode: 0644]
Interface/plusieursintopanel.py [new file with mode: 0644]
Interface/plusieurspanel.py [new file with mode: 0644]
Interface/qtEficas.py [new file with mode: 0644]
Interface/readercata.py [new file with mode: 0644]
Interface/session.py [new file with mode: 0644]
Interface/styles.py [new file with mode: 0644]
Interface/treeitemincanvas.py [new file with mode: 0644]
Interface/uiinfo.py [new file with mode: 0644]
Interface/uniqueassdpanel.py [new file with mode: 0644]
Interface/uniquebasepanel.py [new file with mode: 0644]
Interface/uniquecomppanel.py [new file with mode: 0644]
Interface/uniqueintopanel.py [new file with mode: 0644]
Interface/uniquepanel.py [new file with mode: 0644]
Interface/uniquesdcopanel.py [new file with mode: 0644]
Interface/utils.py [new file with mode: 0644]
Interface/viewManager.py [new file with mode: 0644]

diff --git a/Interface/Objecttreeitem.py b/Interface/Objecttreeitem.py
new file mode 100644 (file)
index 0000000..5bb84ce
--- /dev/null
@@ -0,0 +1,507 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+"""
+# import généraux
+import types,string,os,glob,imp,sys
+from repr import Repr
+from copy import copy,deepcopy
+
+# import du chargeur de composants
+from comploader import make_objecttreeitem
+##import treewidget
+import browser
+from Ihm import CONNECTOR
+
+myrepr = Repr()
+myrepr.maxstring = 100
+myrepr.maxother = 100
+
+class TreeItem:
+
+    """Abstract class representing tree items.
+
+    Methods should typically be overridden, otherwise a default action
+    is used.
+
+    """
+    # itemNode est une factory qui doit retourner un objet de la classe Node
+    # ou dérivé de cette classe.
+    # Le widget arbre utilisera cet objet comme noeud associé au tree item.
+    # Par defaut, utilise la classe Node de base
+    # La signature de la factory est la suivante :
+    # itemNode(treeOrNode,item,command,rmenu)
+    # ou treeOrNode est le noeud parent, item est l'item associé
+    # command est une fonction python appelée sur sélection graphique
+    # du noeud et rmenu est une fonction python appelée sur click droit sur le noeud
+##    itemNode=treewidget.Node
+    itemNode=browser.JDCNode
+
+    def __init__(self):
+        """Constructor.  Do whatever you need to do."""
+
+    def GetText(self):
+        """Return text string to display."""
+
+    def GetLabelText(self):
+        """Return label text string to display in front of text (if any)."""
+
+    expandable = None
+
+    def _IsExpandable(self):
+        """Do not override!  Called by TreeNode."""
+        if self.expandable is None:
+            self.expandable = self.IsExpandable()
+        return self.expandable
+
+    def IsExpandable(self):
+        """Return whether there are subitems."""
+        return 1
+
+    def _GetSubList(self):
+        """Do not override!  Called by TreeNode."""
+        if not self.IsExpandable():
+            return []
+        sublist = self.GetSubList()
+        if not sublist:
+            self.expandable = 0
+        return sublist
+
+    def IsEditable(self):
+        """Return whether the item's text may be edited."""
+
+    def SetText(self, text):
+        """Change the item's text (if it is editable)."""
+
+    def GetIconName(self):
+        """Return name of icon to be displayed normally."""
+
+    def GetSelectedIconName(self):
+        """Return name of icon to be displayed when selected."""
+
+    def GetSubList(self):
+        """Return list of items forming sublist."""
+
+    def OnDoubleClick(self):
+        """Called on a double-click on the item."""
+
+class Delegate:
+    def __init__(self, delegate=None):
+        self.object = delegate
+        self.__cache = {}
+
+    def setdelegate(self, delegate):
+        self.resetcache()
+        self.object = delegate
+
+    def getdelegate(self):
+        return self.object
+
+    def __getattr__(self, name):
+        attr = getattr(self.object, name) # May raise AttributeError
+        setattr(self, name, attr)
+        self.__cache[name] = attr
+        return attr
+
+    def resetcache(self):
+        for key in self.__cache.keys():
+            try:
+                delattr(self, key)
+            except AttributeError:
+                pass
+        self.__cache.clear()
+
+    def cachereport(self):
+        keys = self.__cache.keys()
+        keys.sort()
+        print keys
+
+
+class ObjectTreeItem(TreeItem,Delegate):
+    def __init__(self, appli, labeltext, object, setfunction=None):
+        self.labeltext = labeltext
+        self.appli = appli
+        # L'objet délegué est stocké dans l'attribut object
+        # L'objet associé à l'item est stocké dans l'attribut _object
+        # Il peut etre obtenu par appel à la méthode getObject
+        # Attention : le délégué peut etre différent de l'objet associé (MCLIST)
+        # Dans le cas d'une MCListe de longueur 1, l'objet associé est la MCListe
+        # et l'objet délégué est le MCFACT (object = _object.data[0])
+        Delegate.__init__(self,object)
+        # On cache l'objet initial (pour destruction eventuelle
+        # ultérieure)
+        self._object = object
+        self.setfunction = setfunction
+        self.expandable = 1
+        self.sublist=[]
+        self.init()
+
+    def init(self):
+        return
+
+    def getObject(self):
+        return self._object
+
+    def connect(self,channel,callable,args):
+        """ Connecte la fonction callable (avec arguments args) à l'item self sur le 
+            canal channel
+        """
+        CONNECTOR.Connect(self._object,channel,callable,args)
+        CONNECTOR.Connect(self.object, channel,callable,args)
+
+    def copy(self):
+        """
+        Crée un item copie de self
+        """
+        object = self._object.copy()
+        appli = copy(self.appli)
+        labeltext = copy(self.labeltext)
+        fonction = deepcopy(self.setfunction)
+        item = make_objecttreeitem(appli,labeltext,object,fonction)
+        return item
+    
+    def isactif(self):
+        if hasattr(self.object,'actif'):
+            return self.object.actif
+        else:
+            return 1
+    
+    def update(self,item):
+        """
+          Met a jour l'item courant a partir d'un autre item passe en argument
+          Ne fait rien par defaut
+        """
+        pass
+
+    def GetLabelText(self):
+        """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+        """
+        # None --> fonte et couleur par défaut
+        return self.labeltext,None,None
+
+    def get_nature(self) :
+        """ 
+            Retourne la nature de l'item et de l'objet
+        """ 
+        return self.object.nature
+
+    def get_regles(self):
+        """ retourne les règles de l'objet pointé par self """
+        return self.object.get_regles()
+    
+    def get_liste_mc_presents(self):
+        """ Retourne la liste des mots-clés fils de l'objet pointé par self """
+        return self.object.liste_mc_presents()
+    
+    def get_val(self):
+        """ Retourne le nom de la valeur de l'objet pointé par self dans le cas
+            où celle-ci est un objet (ASSD) """
+        return self.object.getval()
+    
+    def get_definition(self):
+        """ 
+           Retourne l'objet definition de l'objet pointé par self 
+        """
+        return self.object.definition
+
+    def get_liste_mc_ordonnee(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 + ...
+            il faut encore réarranger cette liste (certains mots-clés déjà
+            présents ne doivent plus être proposés, règles ...)"""
+        return self.object.get_liste_mc_ordonnee(liste,dico)
+
+    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 + ...
+        """
+        return self.object.get_liste_mc_ordonnee_brute(liste,dico)
+   
+    def get_genealogie(self):
+        """
+        Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE)
+        de l'objet pointé par self
+        """
+        return self.object.get_genealogie()
+
+    def get_index_child(self,nom_fils):
+        """
+        Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
+        Nécessaire pour savoir à quelle position dans la liste des fils il faut ajouter
+        le nouveau mot-clé
+        """
+        return self.object.get_index_child(nom_fils)
+
+    def get_index_child_old(self,nom_fils):
+        """
+        Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
+        Nécessaire pour savoir à quelle position dans la liste des fils il faut ajouter
+        le nouveau mot-clé
+        """
+        liste_noms_mc_ordonnee = self.get_liste_mc_ordonnee_brute(self.get_genealogie(),self.get_jdc().cata_ordonne_dico)
+        liste_noms_mc_presents = self.object.liste_mc_presents()
+        l=[]
+        for nom in liste_noms_mc_ordonnee:
+            if nom in liste_noms_mc_presents or nom == nom_fils:
+                l.append(nom)
+        # l contient les anciens mots-clés + le nouveau dans l'ordre
+        return l.index(nom_fils)
+        
+    def append_child(self,name,pos=None):
+        """
+          Permet d'ajouter un item fils à self
+        """
+        if pos == 'first':
+            index = 0
+        elif pos == 'last':
+            index = len(self.liste_mc_presents())
+        elif type(pos) == types.IntType :
+            # la position est fixée 
+            index = pos
+        elif type(pos) == types.InstanceType:
+            # pos est un item. Il faut inserer name apres pos
+            index = self.get_index(pos) +1
+        elif type(name) == types.InstanceType:
+            index = self.get_index_child(name.nom)
+        else:
+            index = self.get_index_child(name)
+        return self.addobject(name,index)
+
+    def append_brother(self,name,pos='after'):
+        """
+        Permet d'ajouter un frère à self
+        par défaut on l'ajoute après self
+        """
+        index = self._object.parent.get_index(self.getObject())
+        if pos == 'before':
+            index = index
+        elif pos == 'after':
+            index = index +1
+        else:
+            print str(pos)," n'est pas un index valide pour append_brother"
+            return
+        return self.parent.addobject(name,index)
+
+    def get_nom_etape(self):
+        """Retourne le nom de self """
+        return self.object.get_nom_etape()
+
+    def get_copie_objet(self):
+        """ Retourne une copie de l'objet pointé par self """
+        return self.object.copy()
+    
+    def get_position(self):
+        """ Retourne la valeur de l'attribut position de l'objet pointé par self """
+        definition = self.get_definition()
+        try:
+            return getattr(definition,'position')
+        except AttributeError:
+            return 'local'
+        
+    def get_nom(self):
+        """ Retourne le nom de l'objet pointé par self """
+        return self.object.nom
+
+    def get_jdc(self):
+        """ Retourne le jdc auquel appartient l'objet pointé par self """
+        return self.object.jdc
+    
+    def get_valeur(self):
+        """ Retourne la valeur de l'objet pointé par self """
+        return self.object.valeur
+
+    def get_cr(self):
+        """ Retourne le compte-rendu CR de self """
+        return self.object.report()
+
+    def get_objet_commentarise(self):
+        """
+        Cette méthode retourne un objet commentarisé
+        représentatif de self.object
+        --> à surcharger par les différents items
+        """
+        raise Exception("MESSAGE AU DEVELOPPEUR : il faut surcharger la methode get_objet_commentarise() pour la classe "+self.__class__.__name__)
+        pass
+        
+    def isvalid(self):
+        """ Retourne 1 si l'objet pointé par self est valide, 0 sinon"""
+        return self.object.isvalid()
+
+    def iscopiable(self):
+        """
+        Retourne 1 si l'objet est copiable, 0 sinon
+        Par défaut retourne 0
+        """
+        return 0
+    
+    def get_mc_presents(self):
+        """ Retourne le dictionnaire des mots-clés présents de l'objet pointé par self """
+        return self.object.dict_mc_presents()
+
+    def verif_condition_regles(self,l_mc_presents):
+        return self.object.verif_condition_regles(l_mc_presents)
+
+    def get_fr(self):
+        """ Retourne le fr de l'objet pointé par self """
+        try:
+            return self.object.get_fr()
+        except:
+            return ""
+
+    def get_docu(self):
+        """ Retourne la clé de doc de l'objet pointé par self """
+        return self.object.get_docu()
+
+    def set_valeur(self,new_valeur):
+        """ Remplace la valeur de l'objet pointé par self par new_valeur """
+        return self.object.set_valeur(new_valeur)
+        
+    def GetText(self):
+        return myrepr.repr(self.object)
+    
+    def GetIconName(self):
+        if not self.IsExpandable():
+            return "python"
+
+    def IsEditable(self):
+        return self.setfunction is not None
+
+    def SetText(self, text):
+        try:
+            value = eval(text)
+            self.setfunction(value)
+        except:
+            pass
+# Modif de ma part CCar : je ne comprend pas a quoi ca sert
+# ca parait meme incorrect
+      #  else:
+      #      self.object = value
+
+    def IsExpandable(self):
+        return 1
+        
+    def GetSubList(self):
+        keys = dir(self.object)
+        sublist = []
+        for key in keys:
+            try:
+                value = getattr(self.object, key)
+            except AttributeError:
+                continue
+            item = make_objecttreeitem(
+                self.appli,
+                str(key) + " =",
+                value,
+                lambda value, key=key, object=self.object:
+                    setattr(object, key, value))
+            sublist.append(item)
+        return sublist
+
+    def wait_fichier_init(self):
+        """ Retourne 1 si l'object pointé par self attend un fichier d'initialisation
+        (ex: macros POURSUITE et INCLUDE de Code_Aster), 0 SINON """
+        return self.object.definition.fichier_ini
+
+    def make_objecttreeitem(self,appli,labeltext, object, setfunction=None):
+        """
+           Cette methode, globale pour les objets de type item, permet de construire et de retourner un objet
+           de type item associé à l'object passé en argument.
+        """
+        return make_objecttreeitem(appli,labeltext,object,setfunction)
+
+    #def __del__(self):
+    #    print "__del__",self
+
+class AtomicObjectTreeItem(ObjectTreeItem):
+    def IsExpandable(self):
+        return 0
+
+class SequenceTreeItem(ObjectTreeItem):
+    def IsExpandable(self):
+        return len(self._object) > 0
+
+    def __len__(self) :
+        return len(self._object)
+   
+    def keys(self):
+        return range(len(self._object))
+
+    def GetIconName(self):
+        if self._object.isvalid():
+          return "ast-green-los"
+        elif self._object.isoblig():
+          return "ast-red-los"
+        else:
+          return "ast-yel-los"
+
+    def ajout_possible(self):
+        return self._object.ajout_possible()
+
+    def get_index(self,child):
+        """ Retourne le numéro de child dans la liste des enfants de self """
+        return self._object.get_index(child.getObject())
+
+    def GetText(self):
+      return  "    "
+
+    def additem(self,obj,pos):
+        self._object.insert(pos,obj)
+        item = self.make_objecttreeitem(self.appli, obj.nom + ":", obj)
+        return item
+
+    def suppitem(self,item):
+        try :
+            self._object.remove(item.getObject())
+            # la liste peut être retournée vide !
+            message = "Mot-clé " + item.getObject().nom + " supprimé"
+            self.appli.affiche_infos(message)
+            return 1
+        except:
+            return 0
+
+    def GetSubList(self):
+        isublist=iter(self.sublist)
+        liste=self._object.data
+        iliste=iter(liste)
+        self.sublist=[]
+
+        while(1):
+           old_obj=obj=None
+           for item in isublist:
+              old_obj=item.getObject()
+              if old_obj in liste:break
+
+           for obj in iliste:
+              if obj is old_obj:break
+              # nouvel objet : on cree un nouvel item
+              def setfunction(value, object=obj):
+                  object=value
+              it = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, setfunction)
+              self.sublist.append(it)
+           if old_obj is None and obj is None:break
+           if old_obj is obj: self.sublist.append(item)
+        return self.sublist
diff --git a/Interface/analyse_catalogue.py b/Interface/analyse_catalogue.py
new file mode 100644 (file)
index 0000000..e4330be
--- /dev/null
@@ -0,0 +1,317 @@
+# -*- coding: utf-8 -*-
+#                                                CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002        EDF R&D                                                                        WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#                1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+from string import split,strip,lowercase,uppercase
+import re,string,cPickle,os
+
+from Noyau.N_CR import CR
+
+#
+__Id__="$Id: analyse_catalogue.py,v 1.5 2006-06-20 17:39:20 cchris Exp $"
+__version__="$Name: V1_11_qt $"
+#
+l_noms_commandes = ['OPER','PROC','MACRO','FORM']
+l_noms_composes=['FACT','BLOC','NUPL','FORM']
+l_noms_simples=['SIMP',]
+l_noms=l_noms_composes+l_noms_simples
+
+def elimine_commentaires(text):
+        """ Elimine les lignes de commentaires dans text
+        Attention : supprime sauvagement tous les caractères entre # et le retour chariot ..."""
+        comments = re.compile(r'#[^\n]*')
+        return comments.sub('',text)
+
+def cherche_nom(text):
+        Whitespace = r'[ \f\t]*'
+        Name = r'[a-zA-Z_]\w*'
+        myexpr = '('+Name+')'+Whitespace+'='+Whitespace+'$'
+        a=re.search(myexpr,text)
+        return a.group(1)
+
+def cherche_args(text):
+        text = strip(text)
+        longueur = len(text)
+        if text[0] != '(':
+                return 'erreur !'
+        else :
+                nbpar = 1
+                for i in range(1,longueur) :
+                        if text[i] =='(':
+                                nbpar = nbpar + 1
+                        elif text[i] == ')':
+                                nbpar = nbpar - 1
+                        else :
+                                continue
+                        if nbpar == 0:
+                                break
+                if nbpar != 0 :
+                        return 'erreur !','erreur !'
+                else :
+                        try :
+                                return text[1:i],text[i+1:] # on enlève les première et dernière parenthèses
+                        except :
+                                return text[1:i],''
+
+class ENTITE :
+        def cherche_enfants(self):
+                try :
+                        self.text = strip(self.text)
+                        liste = re.split('=',self.text,1)
+                        if len(liste)>1 :
+                                arg1=liste[0]
+                                reste=liste[1]
+                                reste = strip(reste)
+                                if reste[0:4] in l_noms :
+                                        nom_mc = cherche_nom(arg1+'=')
+                                        arg_mc, self.text = cherche_args(reste[4:])
+                                        self.cree_mc(nom_mc,arg_mc,reste[0:4])
+                                else :
+                                        self.text = reste
+                                self.cherche_enfants()
+                        else :
+                                # pas de = rencontré
+                                return
+                except Exception,e:
+                        self.cr.fatal("Erreur rencontrée dans recherche_enfants :%s" %str(e))
+                
+        def cree_mc(self,nom_mc,arg_mc,test):
+                if test in l_noms_composes :
+                        mc = FACT_CATA(nom_mc,arg_mc,self)
+                        self.children.append(mc)
+                elif test in l_noms_simples :
+                        mc = SIMP_CATA(nom_mc,self)
+                        self.children.append(mc)
+                else :
+                        print 'erreur dans la création du mot-clé :',nom_mc
+
+        def construit_liste_dico(self):
+                l=[]
+                d={}
+                if len(self.children)==0:
+                        self.ordre_mc = l
+                        self.entites = d
+                        return
+                try :
+                        for child in self.children:
+                                l.append(child.nom)
+                                d[child.nom]=child
+                        self.ordre_mc = l
+                        self.entites = d
+                except:
+                        print 'erreur :',self.nom,self.__class__
+                
+class COMMANDE_CATA(ENTITE) :
+        def __init__(self,nom,args,parent):
+                self.nom = nom
+                self.args = args
+                self.children = []
+                self.text = args
+                self.cr = CR()
+                self.cr.debut = "Début commande %s" %self.nom
+                self.cr.fin = "Fin commande %s" %self.nom
+                self.cherche_enfants()
+                self.construit_liste_dico()
+                parent.cr.add(self.cr)
+
+        def affiche(self):
+                texte_cmd = '\n'
+                texte_cmd = texte_cmd + 'Commande :' + self.nom + '\n'
+                for child in self.children :
+                        texte_cmd = texte_cmd + child.affiche(1)
+                return texte_cmd
+
+class SIMP_CATA :
+        def __init__(self,nom,parent):
+                self.nom = nom
+                self.cr = CR()
+                self.cr.debut = "Début mot-clé simple %s" %self.nom
+                self.cr.fin = "Fin mot-clé simple %s" %self.nom
+                parent.cr.add(self.cr)
+
+        def affiche(self,ind):
+                sep = ' '*5
+                return sep*ind+self.nom+'\n'
+
+class FACT_CATA(ENTITE) :
+        def __init__(self,nom,args,parent):
+                self.nom=nom
+                self.args=args
+                self.children = []
+                self.text=args
+                self.cr = CR()
+                self.cr.debut = "Début mot-clé facteur ou bloc %s" %self.nom
+                self.cr.fin = "Fin mot-clé facteur ou bloc %s" %self.nom
+                self.cherche_enfants()
+                self.construit_liste_dico()
+                parent.cr.add(self.cr)
+
+        def affiche(self,ind):
+                sep = ' '*5
+                text = ''
+                text = text + sep*ind+self.nom+'\n'
+                for child in self.children :
+                        text = text + child.affiche(ind+1)
+                return text
+                
+class CATALOGUE_CATA:
+        def __init__(self,parent,fichier):
+                self.parent = parent
+                self.fichier=fichier
+                self.cr = CR()
+                self.cr.debut = "Début compte-rendu catalogue %s" %self.fichier
+                self.cr.fin = "Fin compte-rendu catalogue %s" %self.fichier
+                self.ouvrir_fichier()
+                self.liste_commandes=[]
+                self.liste_textes_commandes=[]
+
+        def ouvrir_fichier(self):
+                try :
+                        f=open(self.fichier,'r')
+                        self.texte_complet=f.read()
+                        f.close()
+                except e:
+                        print "Impossible d'ouvrir le fichier :",self.fichier
+                        print e
+                        self.cr.fatal("Impossible d'ouvrir le fichier :%s" %self.fichier)
+
+        def constr_list_txt_cmd(self,text):
+                text = elimine_commentaires(text)
+                pattern = '\) *;'
+                liste=re.split(pattern,text)
+                for i in range(0,len(liste)-1):
+                        self.liste_textes_commandes.append(liste[i]+')')
+
+        def analyse_commande_old(self,text):
+                #if strip(text) == '' or strip(text) ==')': return
+                liste = re.split('OPER *\(',text,1)
+                if len(liste) < 2 :
+                        liste = re.split('PROC *\(',text,1)
+                if len(liste) < 2 :
+                        liste = re.split('MACRO *\(',text,1)
+                if len(liste) < 2 :
+                        print "le texte à analyser n'est pas celui d'une commande ou d'un opérateur",text
+                        self.cr.fatal("le texte à analyser n'est pas celui d'une commande ou d'un opérateur :%s" %text)
+                        return
+                debut = liste[0]
+                fin = liste[1]
+                nom_cmd = cherche_nom(debut)
+                if nom_cmd == 'erreur !':
+                        print "Erreur dans la recherche du nom de la commande :",debut
+                args_cmd,toto = cherche_args('('+fin)
+                if args_cmd == 'erreur !':
+                        print "Erreur dans la recherche des args de la commande :",debut
+                cmd=COMMANDE_CATA(nom_cmd,args_cmd,self)
+                self.liste_commandes.append(cmd)
+
+        def analyse_commande(self,text):
+                #if strip(text) == '' or strip(text) ==')': return
+                for nom_cmd in l_noms_commandes:
+                        liste = re.split(nom_cmd+' *\(',text,1)
+                        if len(liste) == 2 : break
+                if len(liste) < 2 :
+                        print "le texte à analyser n'est pas celui d'une commande connue :"+str(l_noms_commandes),text
+                        self.cr.fatal("le texte à analyser n'est pas celui d'une commande ou d'un opérateur :%s" %text)
+                        return
+                debut = liste[0]
+                fin = liste[1]
+                nom_cmd = cherche_nom(debut)
+                if nom_cmd == 'erreur !':
+                        print "Erreur dans la recherche du nom de la commande :",debut
+                args_cmd,toto = cherche_args('('+fin)
+                if args_cmd == 'erreur !':
+                        print "Erreur dans la recherche des args de la commande :",debut
+                        print fin
+                cmd=COMMANDE_CATA(nom_cmd,args_cmd,self)
+                self.liste_commandes.append(cmd)
+                
+        def analyse_texte(self,texte):
+                self.constr_list_txt_cmd(texte)
+                try:
+                        self.parent.configure_barre(len(self.liste_textes_commandes))
+                except:
+                        pass
+                for texte_commande in self.liste_textes_commandes :
+                        try:
+                                self.parent.update_barre()
+                        except:
+                                pass
+                        self.analyse_commande(texte_commande)
+                self.construit_liste_dico()
+
+        def ecrit_lcmd(self):
+                f=open('U:\\EFICAS\\Accas\\cata.txt','w')
+                for cmd in self.liste_commandes :
+                        f.write(cmd.affiche())
+                f.close()
+
+        def construit_liste_dico(self):
+                l=[]
+                d={}
+                for cmd in self.liste_commandes:
+                        l.append(cmd.nom)
+                        d[cmd.nom]=cmd
+                self.ordre_mc = l
+                self.entites = d
+
+        def report(self):
+                """ retourne l'objet rapport du catalogue de commande """
+                return self.cr
+
+def analyse_catalogue(parent,nom_cata):
+        cata = CATALOGUE_CATA(parent,nom_cata)
+        cata.analyse_texte(cata.texte_complet)
+        return cata
+
+def analyse_catalogue_commande(parent,nom_cata):
+        cata = CATALOGUE_CATA(parent,nom_cata)
+        cata.analyse_commande(cata.texte_complet)
+        cata.construit_liste_dico()
+        return cata
+
+
+def make_cata_pickle(fic_cata):
+        """
+        Lance l'analyse de l'ordre des mots-clés dans le catalogue dont le nom
+        est passé en argument et sauvegarde ces infos dans le fichier pickle relu
+        par Eficas
+        """
+        fic_cata_p = os.path.splitext(fic_cata)[0]+'_pickled.py'
+        cata_ordonne = analyse_catalogue(None,fic_cata)
+        f = open(fic_cata_p,'w+')
+        p = cPickle.Pickler(f)
+        p.dump(cata_ordonne.entites)
+        f.close()
+        
+if __name__ == "__main__" :
+        import profile
+        profile.run("analyse_catalogue(None,'U:\\EFICAS\\Cata\\cata_saturne.py')")
+
+
+
+
+
+
+
+
+
+
+
+                                
+                                
diff --git a/Interface/autre_analyse_cata.py b/Interface/autre_analyse_cata.py
new file mode 100644 (file)
index 0000000..a9650f0
--- /dev/null
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+   Ce module sert a retrouver l'ordre des mots cles d'un catalogue de
+   commandes
+"""
+if __name__ == "__main__" :
+   import sys
+   sys.path[:0]=[".."]
+   sys.path[:0]=["../Aster"]
+   sys.path[:0]=["../Saturne"]
+
+from Accas import NUPL
+
+def traite_entiteNUPL(entite):
+   """
+       Fonction speciale pour les nuplets (classe NUPL)
+       Cette fonction ajoute a l'objet entite un attribut de nom ordre_mc
+       qui est une liste vide.
+   """
+   entite.ordre_mc=[]
+
+def traite_entite(entite,liste_simp_reel):
+   """
+       Cette fonction ajoute a l'objet entite un attribut de nom ordre_mc
+       qui est une liste contenant le nom des sous entites dans l'ordre 
+       de leur apparition dans le catalogue.
+       L'ordre d'apparition dans le catalogue est donné par l'attribut _no
+       de l'entite
+       La fonction active le meme type de traitement pour les sous entites
+       de entite
+   """
+   l=[]
+   for k,v in entite.entites.items():
+      if isinstance(v,NUPL):
+         traite_entiteNUPL(v)
+      else:
+         traite_reel(v,liste_simp_reel)
+         traite_entite(v,liste_simp_reel)
+      l.append((v._no,k))
+   l.sort()
+   entite.ordre_mc=[ item for index, item in l ]
+
+def traite_reel(objet,liste_simp_reel):
+    if objet.__class__.__name__ == "SIMP":
+       if ( 'R' in objet.type):
+          if objet.nom not in liste_simp_reel :
+             liste_simp_reel.append(objet.nom)
+
+def analyse_niveau(cata_ordonne_dico,niveau,liste_simp_reel):
+   """
+       Analyse un niveau dans un catalogue de commandes
+   """
+   if niveau.l_niveaux == ():
+       # Il n'y a pas de sous niveaux
+       for oper in niveau.entites:
+           traite_entite(oper,liste_simp_reel)
+           cata_ordonne_dico[oper.nom]=oper
+   else:
+       for niv in niveau.l_niveaux:
+           analyse_niveau(cata_ordonne_dico,niv)
+  
+def analyse_catalogue(cata):
+   """
+      Cette fonction analyse le catalogue cata pour construire avec l'aide
+      de traite_entite la structure de données ordre_mc qui donne l'ordre
+      d'apparition des mots clés dans le catalogue
+      Elle retourne un dictionnaire qui contient toutes les commandes
+      du catalogue indexées par leur nom
+   """
+   cata_ordonne_dico={}
+   liste_simp_reel=[]
+   if cata.JdC.l_niveaux == ():
+       # Il n'y a pas de niveaux
+       a=1
+       for oper in cata.JdC.commandes:
+           traite_entite(oper,liste_simp_reel)
+           cata_ordonne_dico[oper.nom]=oper
+   else:
+       for niv in cata.JdC.l_niveaux:
+           analyse_niveau(cata_ordonne_dico,niv,liste_simp_reel)
+   return cata_ordonne_dico,liste_simp_reel
+
+
+if __name__ == "__main__" :
+   from Cata import cata_STA6
+   dico=analyse_catalogue(cata_STA6)
+   #import cata_saturne
+   #dico=analyse_catalogue(cata_saturne)
+
+   def print_entite(entite,dec='  '):
+       print dec,entite.nom,entite.__class__.__name__
+       for mocle in entite.ordre_mc:
+          print_entite(entite.entites[mocle],dec=dec+'  ')
+
+   for k,v in dico.items():
+      print_entite(v,dec='')
+
+   print dico.keys()
diff --git a/Interface/basestyle.py b/Interface/basestyle.py
new file mode 100644 (file)
index 0000000..e4287b7
--- /dev/null
@@ -0,0 +1,27 @@
+class STYLE:
+    background='gray90'
+    foreground='black'
+    entry_background='white'
+    list_background='white'
+    list_select_background='#00008b'
+    list_select_foreground='grey'
+    tooltip_background="yellow"
+
+    standard = ("Helvetica",12)
+    standard_italique = ("Helvetica",12,'italic')
+    standard_gras = ("Helvetica",12,'bold')
+    standard_gras_souligne = ("Helvetica",12,'bold','underline')
+
+    canvas = ('Helvetica',10)
+    canvas_italique = ('Helvetica',10,'italic')
+    canvas_gras = ("Helvetica",10,'bold')
+    canvas_gras_italique = ("Helvetica",12,'bold','italic')
+
+    standard12 = ("Helvetica",14)
+    standard12_gras = ("Helvetica",14,'bold')
+    standard12_gras_italique = ( "Helvetica",14,'bold','italic')
+
+    standardcourier10 = ("Courier",14)
+    statusfont = ("Helvetica",16)
+
+style=STYLE()
diff --git a/Interface/browser.py b/Interface/browser.py
new file mode 100644 (file)
index 0000000..0a0d3b6
--- /dev/null
@@ -0,0 +1,521 @@
+# -*- coding: utf-8 -*-
+import os,sys,string,re,types,traceback
+
+from qt import *
+
+
+import icons
+icons.initializeMimeSourceFactory()
+
+
+class JDCTree( QListView ):
+    def __init__( self, jdc_item, parent = None ):        
+        QListView.__init__( self, parent )
+        
+        self.item     = jdc_item
+        self.tree     = self        
+        self.editor   = parent
+        self.racine   = self
+        self.node_selected = None
+        self.children      = self.build_children()        
+        
+        self.setCaption(self.trUtf8('Browser'))
+        self.setRootIsDecorated(1)
+        self.setSorting(-1)
+        self.addColumn(self.trUtf8('Name'))
+        self.addColumn(self.trUtf8('Value'))
+                
+        self.connect(self,SIGNAL('contextMenuRequested(QListViewItem *, const QPoint &, int)'),
+                     self.handleContextMenu)
+
+##        self.connect(self,SIGNAL('selectionChanged(QListViewItem *)'),self.handleChanged)
+        self.connect(self, SIGNAL("onItem ( QListViewItem * ) "), self.handleOnItem)
+        
+        #rightButtonClicked  CS_pbruno todo ?? selectionChanged
+##        self.connect(self,SIGNAL('returnPressed(QListViewItem *)'),self.handleReturnPressed)        
+##    def handleReturnPressed(self):
+##        """
+##        Private slot to handle the open popup menu entry.
+##        """        
+##            pass
+        
+    def handleContextMenu(self,itm,coord,col):
+        """
+        Private slot to show the context menu of the listview.
+        
+        @param itm the selected listview item (QListViewItem)
+        @param coord the position of the mouse pointer (QPoint)
+        @param col the column of the mouse pointer (int)
+        """
+        try:
+            if itm.menu:
+                itm.menu.popup(coord)            
+        except:
+            pass
+            
+    def handleOnItem(self,  item ):
+##        print "handleChanged ->",item.text(0)        
+        fr = item.item.get_fr()
+        self.editor.affiche_infos(fr)
+        
+    def build_children(self):
+        """ Construit la liste des enfants de self """
+        children = []
+        child = self.item.itemNode(self,self.item)
+        children.append(child)
+        child.state='expanded'
+        return children
+        
+    def supprime(self):
+        """ supprime tous les éléments de l'arbre """
+        raise RuntimeError, 'Not implemented'
+        self.tree = None
+        self.racine = None
+        self.node_selected = None
+        self.item = None
+        self.scrolledcanvas = None
+##        self.canvas = None        
+##        self.rmenu=None
+        for child in self.children:
+            child.supprime()
+        self.children=[]
+                
+    def showEvent(self, event):
+        """ QT : pour afficher le 1er niveau d'arborescence de l''arbre"""        
+        self.children[0].select()
+        
+    def update(self):
+        """ Update tous les éléments de l'arbre """
+        print 'TREE update'
+        for child in self.children:
+            child.update()
+            
+    def update_valid(self) :
+        """Cette methode a pour but de mettre a jour la validite du noeud
+           et de propager la demande de mise à jour à son parent
+        """
+        print 'TREE update_valid'
+        
+# type de noeud
+COMMENT     = "COMMENTAIRE"
+PARAMETERS  = "PARAMETRE"
+
+        
+class JDCNode(QListViewItem):
+    def __init__( self, parent, item, after=None, bold=0):
+        """
+        Constructor
+        
+        @param parent parent Browser or BrowserNode
+        @param text text to be displayed by this node (string or QString)
+        @param after sibling this node is positioned after
+        @param bold flag indicating a highlighted font
+        """        
+        self.item   = item        
+        self.parent = parent
+        self.tree   = self.parent.tree
+        self.editor = self.parent.tree.editor
+        self.bold   = bold
+                
+        name  = item.GetLabelText()[0] 
+        value = item.GetText()
+        
+        if after is None:        
+            QListViewItem.__init__(self,parent)
+            self.setText(0, name)
+            self.setText(1, value)            
+        else:
+            QListViewItem.__init__(self,parent, after)
+            self.setText(0, name)
+            self.setText(1, value)
+            
+        p = icons.getPixmap(item.GetIconName() + ".gif")
+        self.setPixmap(0,p)
+        self.setExpandable(item.IsExpandable())
+            
+                
+        self.connect()    
+        self.init()        
+        self.createPopUpMenu()
+        
+        
+    def paintCell(self, p, cg, column, width, alignment):
+        """
+        Overwritten class to set a different text color, if bold is true.
+        
+        @param p the painter (QPainter)
+        @param cg the color group (QColorGroup)
+        @param column the column (int)
+        @param width width of the cell (int)
+        @param alignment alignment of the cell (int)
+        """
+        _cg = QColorGroup(cg)
+        c = _cg.text()
+        
+        if self.bold and column == 0:
+            _cg.setColor(QColorGroup.Text, Qt.red)
+            
+        QListViewItem.paintCell(self, p, _cg, column, width, alignment)
+        
+        _cg.setColor(QColorGroup.Text, c)
+        
+        
+    def setOpen(self, o):
+        """
+        Public slot to set/reset the open state.
+        
+        @param o flag indicating the open state
+        """        
+        if o:        
+            if not self.children :                
+                self.build_children()
+            self.selected = 1
+            self.tree.node_selected = self            
+##            self.highlight()
+        else:
+            
+            for child in self.children:
+                self.takeItem(child)
+                del child
+            self.children = []
+        QListViewItem.setOpen(self,o)        
+    
+    
+    
+     
+    #----------------------------------------------------
+    #   interface à implémenter par les noeuds dérivés (debut)
+    #----------------------------------------------------
+    def getPanel(self):
+        return None
+        
+    def createPopUpMenu(self):
+        pass 
+        
+    #----------------------------------------------------
+    #   interface à implémenter par les noeuds dérivés (fin)
+    #----------------------------------------------------
+    
+    def init(self): #CS_pbruno toclean
+        self.state='collapsed'
+        self.displayed = 0
+        self.selected = 0
+        self.x = self.y  =None
+        self.lasty = 0
+        self.children = []
+        self.id = []
+        if self.parent is self.tree:
+           self.racine=self
+        else:
+           self.racine = self.parent.racine
+                      
+    def connect(self):
+        self.item.connect("add",self.onAdd,())
+        self.item.connect("supp",self.onSupp,())
+        self.item.connect("valid",self.onValid,())
+           
+           
+           
+    def commentIt(self):
+        """
+        Cette méthode a pour but de commentariser la commande pointée par self
+        """
+        # On traite par une exception le cas où l'utilisateur final cherche à désactiver
+        # (commentariser) un commentaire.
+        try :
+            pos=self.parent.children.index( self )
+            commande_comment = self.item.get_objet_commentarise()
+            # On signale au parent du panel (le JDCDisplay) une modification
+            self.editor.init_modif()
+            self.parent.children[pos].select()
+        except Exception,e:
+            traceback.print_exc()
+            #CS_pbruno todo #widgets.showerror("TOO BAD",str(e))
+        return
+        
+    def unCommentIt(self):
+        """
+        Réalise la décommentarisation de self
+        """
+        try:
+            pos=self.parent.children.index(self.node)
+            commande,nom = self.item.uncomment()
+            self.parent.children[pos].select()
+        except Exception,e:
+            #CS_pbruno todo #showerror("Erreur !",str(e))
+            return        
+        
+    def addComment( self, after=True ):
+        """
+        Ajoute un commentaire à l'intérieur du JDC :
+        """
+        self.editor.init_modif()        
+        if after:
+            pos = 'after'
+        else:
+            pos = 'before'
+        return self.append_brother( COMMENT, pos )
+                
+    def addParameters( self, after=True ):
+        """
+        Ajoute un parametre à l'intérieur du JDC :
+        """
+        self.editor.init_modif()
+        if after:
+            pos = 'after'
+        else:
+            pos = 'before'
+        return self.append_brother( PARAMETERS, pos )
+    
+    
+    
+    def select( self ):
+        """
+        Rend le noeud courant (self) sélectionné et déselectionne
+        tous les autres
+        """        
+        self.setOpen( True )    
+                               
+    #------------------------------------------------------------------
+    # Méthodes de création et destruction de noeuds
+    # Certaines de ces méthodes peuvent être appelées depuis l'externe
+    #------------------------------------------------------------------
+    def append_brother(self,name,pos='after',retour='non'):
+        """
+        Permet d'ajouter un objet frère à l'objet associé au noeud self
+        par défaut on l'ajoute immédiatement après 
+        Méthode externe
+        """
+        # on veut ajouter le frère de nom name directement avant ou après self
+##        print "*********** append_brother ", self.item.GetLabelText()
+        index = self.parent.children.index(self)
+        if pos == 'before':
+            index = index
+        elif pos == 'after':
+            index = index +1
+        else:
+            print str(pos)," n'est pas un index valide pour append_brother"
+            return 0
+        return self.parent.append_child(name,pos=index)
+
+    def append_child(self,name,pos=None,verif='oui',retour='non'):
+        """
+           Methode pour ajouter un objet fils à l'objet associé au noeud self.
+           On peut l'ajouter en début de liste (pos='first'), en fin (pos='last')
+           ou en position intermédiaire.
+           Si pos vaut None, on le place à la position du catalogue.
+        """
+##        print "************** append_child ",self.item.GetLabelText()
+        if pos == 'first':
+            index = 0
+        elif pos == 'last':
+            index = len(self.children)
+        elif type(pos) == types.IntType :
+            # position fixee
+            index = pos
+        elif type(pos) == types.InstanceType:
+            # pos est un item. Il faut inserer name apres pos
+            index = self.item.get_index(pos) +1
+        elif type(name) == types.InstanceType:
+            index = self.item.get_index_child(name.nom)
+        else:
+            index = self.item.get_index_child(name)
+        obj=self.item.additem(name,index) #CS_pbruno emet le signal 'add'
+        #print obj
+        if obj is None:obj=0
+        if obj == 0:return 0
+        #print "append_child",index,self.children
+        child=self.children[index]
+        child.select()
+        return child
+
+    def delete(self):
+        """ 
+            Méthode externe pour la destruction de l'objet associé au noeud
+            La mise à jour des noeuds est faite par onSupp sur notification
+        """
+        self.editor.init_modif()
+        index = self.parent.children.index(self) - 1 
+        if index < 0 : index =0
+
+        parent=self.parent
+        ret=parent.item.suppitem(self.item)
+        if ret == 0:return
+
+        brothers=parent.children
+        if brothers:
+           toselect=brothers[index]
+        else:
+           toselect=parent
+        toselect.select()
+        
+    #------------------------------------------------------------------
+    def onValid(self):        
+        print "NODE onValid : l'item a changé de validité ",self.item.GetLabelText()        
+        self.update_node_valid()
+        self.update_node_label()
+        self.update_node_texte()
+        
+
+    def onAdd(self,objet):        
+        print "NODE onAdd : un objet a été ajouté aux fils de l'item ",self.item.GetLabelText()
+        old_nodes=self.children
+        self.update_nodes()
+        #self.select()
+
+    def onSupp(self,objet):
+        print "NODE onSupp : un objet a été supprimé des fils de l'item ",self.item.object,objet
+        old_nodes=self.children
+        self.update_nodes()
+        #self.select()
+        
+    def update_node_valid(self):
+        """Cette methode remet a jour la validite du noeud (icone)
+           Elle appelle isvalid
+        """
+        print 'NODE update_node_valid', self.item.GetLabelText()
+        p = icons.getPixmap(self.item.GetIconName() + ".gif")
+        self.setPixmap(0,p)
+
+    def update_node_label(self): #CS_pbruno todo
+        """ Met a jour le label du noeud """
+        print "NODE update_node_label", self.item.GetLabelText()
+        labeltext,fonte,couleur = self.item.GetLabelText()
+        self.setText(0, labeltext)        
+##        if self.displayed == 0 : return
+##        # nom,fonte et couleur de l'objet du noeud à afficher
+##        labeltext,fonte,couleur = self.item.GetLabelText()
+##        if labeltext    == ''   : labeltext = '   '
+##        if fonte        == None : fonte = Fonte_Standard
+##        if couleur      == None : couleur = 'black'
+##        self.label.configure(text=labeltext,font=fonte)
+    
+    def update_node_texte(self):
+        """ Met à jour les noms des SD et valeurs des mots-clés """
+        print "NODE update_node_texte", self.item.GetLabelText()
+        value = self.item.GetText()
+        self.setText(1, value)
+
+    def update_nodes(self):
+        print "NODE update_nodes ", self.item.GetLabelText()
+        self.setOpen( False )
+        self.setOpen( True )
+        #self.select()
+            
+    def update_texte(self):
+        """ Met à jour les noms des SD et valeurs des mots-clés """
+        print "NODE update_texte", self.item.GetLabelText()
+        self.update_node_texte()
+        if self.state == 'expanded' :
+            for child in self.children:
+                if child.displayed != 0 : child.update_texte()
+        
+    def update_valid(self) :
+        """Cette methode a pour but de mettre a jour la validite du noeud
+           et de propager la demande de mise à jour à son parent
+        """
+        print "NODE update_valid", self.item.GetLabelText()
+        self.update_node_valid()
+        self.parent.update_valid()            
+
+    def supprime(self):
+        print "NODE supprime",self.item.GetLabelText()
+        self.efface_node()
+        self.racine = None        
+        if not self.children : return
+        for child in self.children:
+            child.supprime()
+        self.children=None    
+
+    def build_children(self):
+        """ Construit la liste des enfants de self """        
+        print "NODE : Construit la liste des enfants de", self.item.GetLabelText()
+        self.children = []
+        sublist = self.item._GetSubList()
+        if sublist :            
+            last = None
+            for item in sublist :                
+                child = item.itemNode(self, item, last)
+                last = child
+                self.children.append(child)
+            
+            
+    
+        
+        
+##    def highlight(self,event=None):
+##        """ Met en surbrillance self"""
+##        if hasattr(self,'label'):
+##            self.label.configure(fg='white',bg='#00008b')
+##        if (hasattr(self.item,'get_nom') and hasattr( self.appli, 'salome')) :
+##            if self.item.get_nom() == "AFFE_CARA_ELEM":
+##               self.item.rmenu_specs=[("View3D", "visu_3D")] #CS_pbruno todo
+##               self.tree.rmenu
+              
+
+
+##    def update(self,event=None) :
+##        """ Classe Node :
+##            Cette méthode est appelée pour demander l update d un noeud 
+##            d'un jeu de commandes
+##            Cette demande est transmise au noeud racine (le JDC) qui update
+##            tout l arbre représentant le jeu de commandes
+##            Pendant cette mise à jour, on appelle la méthode isvalid qui
+##            fera l update de tous les objets déclarés modifiés lors des
+##            actions précédentes
+##            La métode isvalid est en général appelée par l intermédiaire de
+##            update_icone -> geticonimage -> GetIconName
+##        """
+##        print 20*"NODE update",self.item.GetLabelText()
+##        #print "update",self
+##        #traceback.print_stack()
+##        self.racine.update_coords()
+##        self.racine.trace_ligne()
+##        self.racine.update_icone()
+##        self.racine.update_texte()
+##        self.racine.update_label_texte()
+##        self.tree.resizescrollregion()
+
+
+
+        
+        
+    
+if __name__=='__main__':
+    from qt import *
+    
+##    import cataManager
+##    f=open('az.comm','r')
+##    text=f.read()
+##    f.close()
+##    j=cataManager.cata.JdC(procedure=text,cata=cataManager.cata,nom="ahlv100a",
+##                    cata_ord_dico=cataManager.cata_ordonne)
+##    print 'cata.JdC->',j
+##    
+##    j.compile()
+##    if not j.cr.estvide():
+##       print j.cr
+##       sys.exit()
+##    
+##    j.exec_compile()
+##    if not j.cr.estvide():
+##       print j.cr
+##       sys.exit()
+##           
+##    import comploader
+##    comploader.charger_composants()
+##
+##    app = QApplication(sys.argv)    
+##    import Objecttreeitem
+##    jdc_item=Objecttreeitem.make_objecttreeitem( app, "nom", j )
+##    
+##    t=JDCTree( jdc_item ) 
+##    app.setMainWidget(t)    
+##    app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+##    t.show()
+##            
+##    res = app.exec_loop()
+##    sys.exit(res)
+    
+
+
diff --git a/Interface/comploader.py b/Interface/comploader.py
new file mode 100644 (file)
index 0000000..7a86c91
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+   Module de chargement des composants et de mapping des objets du noyau
+   Accas vers les items d'EFICAS
+
+   - composants : dictionnaire de stockage des relations entre types
+     d'objet du noyau et types d'item
+   - charger_composants() : fonction de chargement des composants. Retourne
+     le dictionnaire composants.
+   - gettreeitem(object) -> type d'item : fonction qui retourne un type
+     d'item correspondant au type de l'objet noyau fourni.
+   - make_objecttreeitem(appli,labeltext, object, setfunction=None) -> item : fonction qui retourne un item
+     correspondant à l'objet noyau fourni.
+"""
+# import généraux
+import os,glob,types
+
+# Dictionnaire {object : item} permettant d'associer un item à un object
+# Ce dictionnaire est renseigné par la méthode charger_composants 
+composants = {}
+
+def charger_composants():
+    """
+        Cette fonction a pour but de charger tous les modules composants graphiques
+        (fichiers compo*.py dans le même répertoire que ce module )
+        et de remplir le dictionnaire composants utilisé par make_objecttreeitem
+    """
+    repertoire=os.path.dirname(__file__)
+    listfich=glob.glob(os.path.join(repertoire, "compo*.py"))
+    for fichier in listfich:
+        m= os.path.basename(fichier)[:-3]
+        module=__import__(m,globals(),locals())
+        composants[module.objet]=module.treeitem
+    return composants
+
+def gettreeitem(object):
+    """
+      Cette fonction retourne la classe item associée à l'objet object.
+      Cette classe item dépend bien sûr de la nature de object, d'où
+      l'interrogation du dictionnaire composants
+    """
+    # Si la definition de l'objet a un attribut itemeditor, il indique 
+    # la classe a utiliser pour l'item
+    try:
+       return object.definition.itemeditor
+    except:
+       pass
+
+    # On cherche ensuite dans les composants (plugins)
+    try:
+       itemtype= composants[object.__class__]
+       return itemtype
+    except:
+       pass
+
+    # Puis une eventuelle classe heritee (aleatoire car sans ordre)
+    for e in composants.keys():
+        if e and isinstance(object,e):
+           itemtype= composants[e]
+           return itemtype
+
+    # Si on n'a rien trouve dans les composants on utilise l'objet par defaut
+    itemtype=composants[None]
+    return itemtype
+
+def make_objecttreeitem(appli,labeltext, object, setfunction=None):
+    """
+       Cette fonction permet de construire et de retourner un objet
+       de type item associé à l'object passé en argument.
+    """
+    c = gettreeitem(object)
+    return c(appli,labeltext, object, setfunction)
+
diff --git a/Interface/compobase.py b/Interface/compobase.py
new file mode 100644 (file)
index 0000000..df539df
--- /dev/null
@@ -0,0 +1,3 @@
+import Objecttreeitem
+treeitem = Objecttreeitem.ObjectTreeItem
+objet = None
diff --git a/Interface/compobloc.py b/Interface/compobloc.py
new file mode 100644 (file)
index 0000000..90328e2
--- /dev/null
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+
+##from Tkinter import *
+##import Pmw
+
+import Objecttreeitem
+import compofact
+
+import browser
+from qt import *
+
+
+
+class Node(browser.JDCNode):
+    def getPanel(self):
+        """        
+        """    
+        return compofact.FACTPanel( self, self.editor )
+
+
+
+class BLOCTreeItem(compofact.FACTTreeItem):
+##  panel = compofact.FACTPanel
+  itemNode=Node
+
+  def get_objet(self,name) :
+      for v in self.object.mc_liste:
+          if v.nom == name : return v
+      return None
+    
+  def iscopiable(self):
+    return 0
+
+
+import Accas
+treeitem = BLOCTreeItem
+objet = Accas.MCBLOC   
diff --git a/Interface/compocomm.py b/Interface/compocomm.py
new file mode 100644 (file)
index 0000000..0d08ad3
--- /dev/null
@@ -0,0 +1,230 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+
+import string
+
+import Objecttreeitem
+##import panels
+##import fontes
+##
+##Fonte_Commentaire = fontes.standard_italique
+
+##class COMMPanel(panels.OngletPanel):
+##  
+##  def init(self):
+##    """
+##    Initialise les frame des panneaux contextuels relatifs à un COMMENTAIRE
+##    """
+##    nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
+##    nb.pack(fill = 'both', expand = 1)
+##    self.nb=nb
+##    nb.add('TexteComm', tab_text='Texte Commentaire')
+##    nb.add('Commande', tab_text='Nouvelle Commande')
+##    nb.add('Commentaire',tab_text='Paramètre/Commentaire')
+##    self.makeCOMMPage(nb.page("TexteComm"))
+##    self.makeCommandePage(nb.page("Commande"))
+##    self.makeParamCommentPage_for_etape(nb.page("Commentaire"))
+##    nb.tab('TexteComm').focus_set()
+##    self.enlevebind()
+##    self.creebind()
+##    nb.setnaturalsize()
+##    
+##  def makeCOMMPage(self,page):
+##    """
+##    Crée la page qui permet d'afficher et d'éditer le texte du commentaire
+##    """
+##    self.frame_valeur = Frame(page)
+##    self.frame_valeur.place(relwidth=0.9,relheight=0.9,relx=0.05,rely=0.05,anchor='nw')
+##    self.widget_text = Pmw.ScrolledText(self.frame_valeur,
+##                                        borderframe=1,
+##                                        labelpos='n',
+##                                        label_text = 'Texte du commentaire\n ')
+##    self.widget_text.pack(side='top',expand=1,fill='both')
+##    self.widget_text.configure(hscrollmode='dynamic',
+##                               vscrollmode='dynamic')
+##    self.make_buttons()
+##    self.display_valeur()
+##
+##  def make_buttons(self):
+##    """
+##    Crée les boutons du panneau
+##    """
+##    self.bouton_sup.place_forget()
+##    self.bouton_doc.place_forget()
+##    self.bouton_val = Button(self.fr_but,text='Valider',command=self.change_valeur,width=14)
+##    self.bouton_ann = Button(self.fr_but,text='Annuler',command=self.display_valeur,width=14)
+##
+##    self.bouton_val.place(relx=0.25,rely=0.5,relheight=0.8,anchor='center')
+##    self.bouton_ann.place(relx=0.50,rely=0.5,relheight=0.8,anchor='center')
+##    self.bouton_sup.place(relx=0.75,rely=0.5,relheight=0.8,anchor='center')
+##
+##
+##  def change_valeur(self):
+##    """
+##    Stocke la nouvelle valeur donnée par l'utilisateur comme valeur du commentaire
+##    """
+##    if self.parent.modified == 'n' : self.parent.init_modif()
+##    new_valeur = self.widget_text.get()
+##    self.node.item.set_valeur(new_valeur)
+##    self.node.update()
+##
+##  def display_valeur(self):
+##    """
+##    Affiche dans self.widget_text la valeur de l'objet commentaire
+##    (annule d'éventuelles modifications faite par l'utilisateur)
+##    """
+##    t=self.node.item.get_valeur()
+##    try:
+##        self.widget_text.settext(unicode(t))
+##    except:
+##        # Si probleme avec unicode
+##        self.widget_text.settext(t)
+
+import browser
+from qt import *
+
+class COMMPanel(QTabWidget): #CS_pbruno todo
+    def __init__(self,node, parent = None,name = None,fl = 0):
+        QTabWidget.__init__(self,parent,name,fl)        
+        self.editor    = parent
+        self.node      = node
+        
+        tabKey      = QWidget(self)
+        tabConcept  = QWidget(self)
+        tabCommande = QWidget(self)
+        tabComment  = QWidget(self)
+        
+        label = QLabel( "le label", tabComment)
+        commentLayout = QHBoxLayout(tabComment,11,6,"commentLayout ")
+        commentButtonA = QPushButton('un commentaire après', tabComment )
+        commentLayout.addWidget(commentButtonA )       
+        commentButtonB = QPushButton( 'un commentaire avant', tabComment)
+        commentLayout.addWidget(commentButtonB )
+        suppressButton = QPushButton( 'supprimer', tabComment)
+        commentLayout.addWidget(suppressButton )
+        
+        
+        self.insertTab( tabKey, 'Nouveau mot-cle' )
+        self.insertTab( tabConcept, 'Nommer concept')
+        self.insertTab( tabCommande, 'Nouvelle Commande')
+        self.insertTab( tabComment ,"Parametre/Commentaire")
+                
+        #self.setCurrentPage(0)
+        
+        QObject.connect( commentButtonA, SIGNAL( "clicked()" ), self.addCommentA )
+        QObject.connect( commentButtonB, SIGNAL( "clicked()" ), self.addCommentB )
+        QObject.connect( suppressButton, SIGNAL( "clicked()" ), self.supprimer )
+        
+
+    def addCommentA(self): 
+        """      
+        """        
+        print 'addCommentA', 
+        self.node.append_brother("COMMENTAIRE",'after')
+        self.editor.init_modif()
+        
+        
+    def addCommentB(self): 
+        """      
+        """
+        print 'addCommentB'        
+        self.node.append_brother("COMMENTAIRE",'before')
+        self.editor.init_modif()
+
+    def supprimer(self): 
+        """
+        Suppression du noeud courant
+        """
+        # On signale au parent du panel (le JDCDisplay) une modification         
+        self.node.delete()
+        self.editor.init_modif()
+    
+
+
+
+class Node(browser.JDCNode):
+    pass
+##    def getPanel( self ):
+##        """
+##        """
+##        return COMMPanel( self, self.editor )
+    
+class COMMTreeItem(Objecttreeitem.ObjectTreeItem):
+##    panel = COMMPanel
+    itemNode=Node    
+
+    def init(self):
+      self.setfunction = self.set_valeur
+
+    def GetIconName(self):
+      """
+      Retourne le nom de l'icône associée au noeud qui porte self,
+      dépendant de la validité de l'objet
+      NB : un commentaire est toujours valide ...
+      """
+      return "ast-white-percent"
+
+    def GetLabelText(self):
+        """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+        """
+        return 'commentaire'#CS_pbruno,Fonte_Commentaire,None
+
+    def get_valeur(self):
+      """
+      Retourne la valeur de l'objet Commentaire cad son texte
+      """
+      return self.object.get_valeur() or ''
+    
+    def GetText(self):
+        texte = self.object.valeur
+        texte = string.split(texte,'\n')[0]
+        if len(texte) < 25 :
+            return texte
+        else :
+            return texte[0:24]
+
+    def set_valeur(self,valeur):
+      """
+      Afefcte valeur à l'objet COMMENTAIRE
+      """
+      self.object.set_valeur(valeur)
+      
+    def GetSubList(self):
+      """
+      Retourne la liste des fils de self
+      """
+      return []
+
+
+    def get_objet_commentarise(self):
+       """
+           La méthode get_objet_commentarise() de la classe compocomm.COMMTreeItem
+           surcharge la méthode get_objet_commentarise de la classe Objecttreeitem.ObjectTreeItem
+           elle a pour but d'empecher l'utilisateur final de commentariser un commentaire.
+       """
+       raise Exception( 'Citoyen : tu peux "commentariser" une commande MAIS PAS UN COMMENTAIRE' )
+  
+import Extensions
+treeitem =COMMTreeItem
+objet = Extensions.commentaire.COMMENTAIRE    
diff --git a/Interface/compocommandecomm.py b/Interface/compocommandecomm.py
new file mode 100644 (file)
index 0000000..dff2430
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+
+import traceback
+from Tkinter import *
+import Pmw
+import string
+##    from widgets import showerror
+
+import Objecttreeitem
+import browser
+from qt import *
+
+
+
+class Node(browser.JDCNode):
+    pass
+##    def getPanel(self):
+##        """        
+##        """    
+##        return COMMANDE_COMMPanel( self, self.editor )
+
+
+    
+class COMMANDE_COMMTreeItem(Objecttreeitem.ObjectTreeItem):
+##    panel = COMMANDE_COMMPanel
+    itemNode=Node
+    
+    def init(self):
+      self.setfunction = self.set_valeur
+
+    def GetIconName(self):
+      """
+      Retourne le nom de l'icône associée au noeud qui porte self,
+      dépendant de la validité de l'objet
+      NB : une commande commentarisée est toujours valide ...
+      """
+      if self.isvalid():
+          return "ast-green-percent"
+      else:
+          return "ast-red-percent"
+
+    def GetLabelText(self):
+        """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+        """
+##        return 'commande commentarisée',Fonte_Commentaire,None
+        return 'commande commentarisée',None,None #CS_pbruno todo
+
+    def get_valeur(self):
+      """
+      Retourne la valeur de la commande commentarisée cad son texte
+      """
+      return self.object.get_valeur() or ''
+    
+    def GetText(self):
+        texte = self.object.valeur
+        texte = string.split(texte,'\n')[0]
+        if len(texte) < 25 :
+            return texte
+        else :
+            return texte[0:24]
+
+    def set_valeur(self,valeur):
+      """
+      Afefcte valeur à l'objet commande commentarisée
+      """
+      self.object.set_valeur(valeur)
+      
+    def GetSubList(self):
+      """
+      Retourne la liste des fils de self
+      """
+      return []
+
+    def uncomment(self):
+      """
+      Demande à l'objet commande commentarisée de se décommentariser.
+      Si l'opération s'effectue correctement, retourne l'objet commande
+      et éventuellement le nom de la sd produite, sinon lève une exception
+      """
+      try:
+        commande,nom = self.object.uncomment()
+      except Exception,e:
+        traceback.print_exc()
+        raise e
+      return commande,nom
+  
+import Accas
+treeitem =COMMANDE_COMMTreeItem
+objet = Accas.COMMANDE_COMM    
diff --git a/Interface/compoerror.py b/Interface/compoerror.py
new file mode 100644 (file)
index 0000000..9aac815
--- /dev/null
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+
+
+#Modules Eficas
+from Noyau.N_OBJECT import ErrorObj
+import Objecttreeitem
+
+
+import browser
+from qt import *
+
+class Node(browser.JDCNode):
+    pass    
+##    def getPanel(self):
+##        """        
+##        """    
+##        return ERRORPanel( self, self.editor )
+
+
+class ERRORTreeItem(Objecttreeitem.AtomicObjectTreeItem):
+##    panel = ERRORPanel
+    itemNode=Node
+    
+    def GetIconName(self):
+        return "ast-red-ball"
+
+
+treeitem =ERRORTreeItem
+objet = ErrorObj
+
diff --git a/Interface/compofact.py b/Interface/compofact.py
new file mode 100644 (file)
index 0000000..21fc97a
--- /dev/null
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+
+import Objecttreeitem
+
+import browser
+from qt import *
+
+
+class FACTPanel(QTabWidget): #CS_pbruno todo
+    def __init__(self,node, parent = None,name = None,fl = 0):
+        QTabWidget.__init__(self,parent,name,fl)
+        self.editor    = parent
+        self.node      = node
+
+class Node(browser.JDCNode):
+    def getPanel(self):
+        """
+        """
+        return FACTPanel( self, self.editor )
+        
+    def doPaste(self,node_selected):
+        objet_a_copier = self.item.get_copie_objet()
+        child=node_selected.doPaste_MCF(objet_a_copier)
+        return child
+
+    def doPaste_MCF(self,objet_a_copier):
+        child = self.parent.append_child(objet_a_copier,
+                                              pos=self.item,
+                                              retour='oui')
+        return child
+
+
+class FACTTreeItem(Objecttreeitem.ObjectTreeItem):
+##  panel = FACTPanel
+##  panel = FACTPanel
+  itemNode=Node
+  
+  def IsExpandable(self):
+    return 1
+
+  def GetText(self):
+      return  ''
+
+  def GetLabelText(self):
+      """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+      """
+      # None --> fonte et couleur par défaut
+      return self.object.getlabeltext(),None,None
+
+  def isvalid(self):
+    return self.object.isvalid()
+
+  def iscopiable(self):
+    return 1
+
+  def GetIconName(self):
+    if self.object.isvalid():
+      return "ast-green-los"
+    elif self.object.isoblig():
+      return "ast-red-los"
+    else:
+      return "ast-yel-los"
+
+  def keys(self):
+    keys=self.object.mc_dict.keys()
+    return keys
+
+  def GetSubList(self):
+      """
+         Reactualise la liste des items fils stockes dans self.sublist
+      """
+      liste=self.object.mc_liste
+      sublist=[None]*len(liste)
+      # suppression des items lies aux objets disparus
+      for item in self.sublist:
+         old_obj=item.getObject()
+         if old_obj in liste:
+            pos=liste.index(old_obj)
+            sublist[pos]=item
+         else:
+            pass # objets supprimes ignores
+      # ajout des items lies aux nouveaux objets
+      pos=0
+      for obj in liste:
+         if sublist[pos] is None:
+            # nouvel objet : on cree un nouvel item
+            def setfunction(value, object=obj):
+                object.setval(value)
+            item = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, setfunction)
+            sublist[pos]=item
+         pos=pos+1
+
+      self.sublist=sublist
+      return self.sublist
+
+  def additem(self,name,pos):
+    #print "compofact.additem",name,pos
+    objet = self.object.addentite(name,pos)
+    return objet
+
+  def suppitem(self,item) :
+      """ 
+         Cette methode a pour fonction de supprimer l'item passé en argument
+         des fils de l'item FACT qui est son pere
+           - item = item du MOCLE à supprimer du MOCLE père
+           - item.getObject() = MCSIMP ou MCBLOC 
+      """
+      itemobject=item.getObject()
+      if itemobject.isoblig() :
+         self.appli.affiche_infos('Impossible de supprimer un mot-clé obligatoire ')
+         return 0
+
+      if self.object.suppentite(itemobject):
+         message = "Mot-clé " + itemobject.nom + " supprimé"
+         self.appli.affiche_infos(message)
+         return 1
+      else:
+         self.appli.affiche_infos('Pb interne : impossible de supprimer ce mot-clé')
+         return 0
+
+import Accas
+objet = Accas.MCFACT
+treeitem = FACTTreeItem
diff --git a/Interface/compoformule.py b/Interface/compoformule.py
new file mode 100644 (file)
index 0000000..f7a93c5
--- /dev/null
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*-
+
+"""
+Ce module contient les classes permettant de définir les objets graphiques
+représentant un objet de type FORMULE, cad le panneau et l'item de l'arbre
+d'EFICAS
+"""
+
+
+import string
+import compooper
+
+import browser
+from qt import *
+
+
+class Node(browser.JDCNode):
+    pass
+##    def getPanel(self):
+##        """
+##        """
+##        return FORMULEPanel( self, self.editor )
+        
+            
+class FORMULETreeItem(compooper.EtapeTreeItem):
+    """
+    Classe servant à définir l'item porté par le noeud de l'arbre d'EFICAS
+    qui représente la FORMULE
+    """
+    itemNode=Node
+##    panel = FORMULEPanel
+
+    def init(self):
+      self.setfunction = self.set_valeur
+
+# ---------------------------------------------------------------------------
+#                   API de FORMULE pour l'arbre 
+# ---------------------------------------------------------------------------
+    def GetSubList(self):
+      """
+      Retourne la liste des fils de self
+      On considère que FORMULE n'a pas de fils
+      --> modification par rapport à MACRO classique
+      """
+      # dans EFICAS on ne souhaite pas afficher les mots-clés fils de FORMULE
+      # de façon traditionnelle
+      return []
+
+    def GetIconName(self):
+      """
+      Retourne le nom de l'icône à afficher dans l'arbre
+      Ce nom dépend de la validité de l'objet
+      """
+      if self.object.isactif():
+        self.object.state="modified"
+        if self.object.isvalid():
+          return "ast-green-square"
+        else:
+          return "ast-red-square"
+      else:
+        return "ast-white-text"
+
+    def GetLabelText(self):
+      """ Retourne 3 valeurs :
+      - le texte à afficher dans le noeud représentant l'item
+      - la fonte dans laquelle afficher ce texte
+      - la couleur du texte
+      """
+      if self.object.isactif():
+        # None --> fonte et couleur par défaut
+        return self.labeltext,None,None
+      else:
+        return self.labeltext,fontes.standard_italique,None
+    
+# ---------------------------------------------------------------------------
+#       Méthodes permettant la modification et la lecture des attributs
+#       du paramètre = API graphique de la FORMULE pour Panel et EFICAS
+# ---------------------------------------------------------------------------
+
+    def get_nom(self):
+      """
+      Retourne le nom de la FORMULE
+      """
+      return self.object.get_nom()
+
+    def get_type(self):
+      """
+      Retourne le type de la valeur retournée par la FORMULE
+      """
+      return self.object.type_retourne
+
+    def get_args(self):
+      """
+      Retourne les arguments de la FORMULE
+      """
+      args=""
+      for mot in self.object.mc_liste:
+          if mot.nom == 'NOM_PARA':
+             args=mot.valeur
+             break
+      if args :
+          if args[0] == "(" and args[-1] ==")":
+             args=args[1:-1]
+          # transforme en tuple si ce n est pas déjà le casa
+          try :
+             args=string.split(args,',')
+          except :
+             pass
+      return args
+
+    def get_corps(self):
+      """
+      Retourne le corps de la FORMULE
+      """
+      corps=""
+      for mot in self.object.mc_liste:
+          if mot.nom == 'VALE':
+             corps=mot.valeur
+             break
+      return corps
+
+
+    def get_liste_types_autorises(self):
+      """
+         Retourne la liste des types autorises pour les valeurs de sortie 
+         d'une FORMULE
+      """
+      return self.object.l_types_autorises
+
+    def save_formule(self,new_nom,new_typ,new_arg,new_exp):
+      """
+      Vérifie si (new_nom,new_typ,new_arg,new_exp) définit bien une FORMULE 
+      licite :
+          - si oui, stocke ces paramètres comme nouveaux paramètres de la 
+            FORMULE courante et retourne 1
+          - si non, laisse les paramètres anciens de la FORMULE inchangés et 
+            retourne 0
+      """
+      test,erreur = self.object.verif_formule_python(formule=(new_nom,new_typ,new_arg,
+                                                       new_exp))
+      if test :
+          # la formule est bien correcte : on sauve les nouveaux paramètres
+          test=self.object.update_formule_python(formule=(new_nom,new_typ,new_exp,new_arg))
+      return test,erreur
+
+# ---------------------------------------------------------------------------
+#          Accès aux méthodes de vérification de l'objet FORM_ETAPE
+# ---------------------------------------------------------------------------
+
+    def verif_nom(self,nom):
+        """
+        Lance la vérification du nom passé en argument
+        """
+        return self.object.verif_nom(nom)
+
+    def verif_arguments(self,arguments):
+        """
+        Lance la vérification des arguments passés en argument
+        """
+        return self.object.verif_arguments('('+arguments+')')
+
+    def verif_formule(self,formule):
+        """
+        Lance la vérification de FORMULE passée en argument
+        """
+        return self.object.verif_formule(formule=formule)
+
+
+    def verif_formule_python(self,formule):
+        """
+        Lance la vérification de FORMULE passée en argument
+        """
+        return self.object.verif_formule_python(formule=formule)
+
+import Accas
+treeitem =FORMULETreeItem
+objet = Accas.FORM_ETAPE
diff --git a/Interface/compojdc.py b/Interface/compojdc.py
new file mode 100644 (file)
index 0000000..3710b57
--- /dev/null
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+import Objecttreeitem
+
+import browser
+from qt import *
+
+
+class Node(browser.JDCNode):
+##    def getPanel(self):
+##        """
+##        """
+##        return JDCPanel( self, self.editor )
+
+    def doPaste_Commande(self,objet_a_copier):
+        """
+          Réalise la copie de l'objet passé en argument qui est nécessairement
+          une commande
+        """
+        #child = self.item.append_child(objet_a_copier,pos='first')
+        child = self.append_child(objet_a_copier,pos='first',retour='oui')
+        #if child is None : return 0
+        return child
+
+
+class JDCTreeItem(Objecttreeitem.ObjectTreeItem):
+##  panel = JDCPanel
+  itemNode=Node
+  
+  def IsExpandable(self):
+    return 1
+
+  def GetText(self):
+      return  "    "
+
+  def GetLabelText(self):
+      # None --> fonte et couleur par défaut
+      return self.object.nom,None,None
+
+  def get_jdc(self):
+    """
+    Retourne l'objet pointé par self
+    """
+    return self.object
+  
+  def GetIconName(self):
+    if self.object.isvalid():
+      return "ast-green-square"
+    else:
+      return "ast-red-square"
+
+  def keys(self):
+      if self.object.etapes_niveaux != []:
+          return range(len(self.object.etapes_niveaux))
+      else:
+          return range(len(self.object.etapes))
+
+  def additem(self,name,pos):
+      cmd = self._object.addentite(name,pos)
+      return cmd
+
+  def suppitem(self,item) :
+    # item = item de l'ETAPE à supprimer du JDC
+    # item.getObject() = ETAPE ou COMMENTAIRE
+    # self.object = JDC
+    itemobject=item.getObject()
+    if self.object.suppentite(itemobject):
+       if itemobject.nature == "COMMENTAIRE" :
+          message = "Commentaire supprimé"
+       else :
+          message = "Commande " + itemobject.nom + " supprimée"
+       self.appli.affiche_infos(message)
+       return 1
+    else:
+       self.appli.affiche_infos("Pb interne : impossible de supprimer cet objet")
+       return 0
+
+  def GetSubList(self):
+    """
+       Retourne la liste des items fils de l'item jdc.
+       Cette liste est conservee et mise a jour a chaque appel
+    """
+    if self.object.etapes_niveaux != []:
+        liste = self.object.etapes_niveaux
+    else:
+        liste = self.object.etapes
+    sublist=[None]*len(liste)
+    # suppression des items lies aux objets disparus
+    for item in self.sublist:
+       old_obj=item.getObject()
+       if old_obj in liste:
+          pos=liste.index(old_obj)
+          sublist[pos]=item
+       else:
+          pass # objets supprimes ignores
+    # ajout des items lies aux nouveaux objets
+    pos=0
+    for obj in liste:
+       if sublist[pos] is None:
+          # nouvel objet : on cree un nouvel item
+          item = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj)
+          sublist[pos]=item
+       pos=pos+1
+
+    self.sublist=sublist
+    return self.sublist
+
+  def get_l_noms_etapes(self):
+      """ Retourne la liste des noms des étapes de self.object"""
+      return self.object.get_l_noms_etapes()
+
+  def get_liste_cmd(self):
+      #print "get_liste_cmd",self.object.niveau.definition
+      listeCmd = self.object.niveau.definition.get_liste_cmd()
+      return listeCmd
+
+import Accas
+treeitem =JDCTreeItem
+objet = Accas.JDC    
diff --git a/Interface/compomacro.py b/Interface/compomacro.py
new file mode 100644 (file)
index 0000000..cc2353e
--- /dev/null
@@ -0,0 +1,159 @@
+# -*- coding: utf-8 -*-
+# Modules Python
+import os,sys,string
+import types
+
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import compooper
+import convert
+
+#
+__version__="$Name: V1_11_qt $"
+__Id__="$Id: compomacro.py,v 1.26 2006-12-15 16:00:21 cchris Exp $"
+#
+
+
+    
+import browser
+from qt import *
+
+
+class MACRONode(browser.JDCNode):
+    pass
+##    def getPanel(self):
+##        """
+##        """
+##        return MACROPanel( self, self.editor )    
+    
+class MACROTreeItem(compooper.EtapeTreeItem):
+  """ Cette classe hérite d'une grande partie des comportements
+      de la classe compooper.EtapeTreeItem
+  """
+  itemNode=MACRONode
+##  panel=MACROPanel
+
+class INCLUDETreeItemBase(MACROTreeItem):
+  rmenu_specs=[("View","makeView"),
+               ("Edit","makeEdit"),
+              ]
+
+  def __init__(self,appli, labeltext, object, setfunction):
+    MACROTreeItem.__init__(self,appli, labeltext, object, setfunction)
+
+  def iscopiable(self):
+      """
+      Retourne 1 si l'objet est copiable, 0 sinon
+      """
+      return 0
+
+  def makeEdit(self,appli,node):
+    #print "makeEdit",self.object,self.object.nom
+    #print "makeEdit",self.object.jdc_aux,self.object.jdc_aux.nom
+    #print "makeEdit",self.object.jdc_aux.context_ini
+    if self.object.text_converted == 0:
+        # Le texte du fichier inclus n'a pas pu etre converti par le module convert
+        msg="Le fichier de commande n'a pas pu etre converti pour etre editable par Eficas\n\n"
+        msg=msg+self.object.text_error
+        Fenetre(self,titre="Include non editable",texte=msg,wrap='none')
+        return
+
+    if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
+       #L'include n'est pas initialise
+       self.object.build_include(None,"")
+
+    # On cree un nouvel onglet dans le bureau
+    appli.bureau.ShowJDC(self.object.jdc_aux,self.object.jdc_aux.nom,
+                             label_onglet=None,
+                             JDCDISPLAY=macrodisplay.MACRODISPLAY)
+
+  def makeView(self,appli,node):
+    if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
+         showerror("Include vide",
+                 "L'include doit etre correctement initialisé pour etre visualisé")
+         return
+
+    nom=self.object.nom
+    if hasattr(self.object,'fichier_ini'):
+       if self.object.fichier_ini is None:
+          nom=nom+' '+"Fichier non défini"
+       else:
+          nom=nom+' '+self.object.fichier_ini
+    macdisp=macrodisplay.makeMacroDisplay(appli,self,nom)
+
+
+
+class INCLUDENode(browser.JDCNode):
+    pass
+##    def getPanel(self):
+##        """
+##        """
+##        return INCLUDEPanel( self, self.editor )  
+
+
+class INCLUDETreeItem(INCLUDETreeItemBase):
+##   panel=INCLUDEPanel
+    itemNode=INCLUDENode
+    
+
+class POURSUITETreeItem(INCLUDETreeItemBase): 
+  def makeEdit(self,appli,node):
+    if self.object.text_converted == 0:
+        # Le texte du fichier inclus n'a pas pu etre converti par le module convert
+        msg="Le fichier de commande n'a pas pu etre converti pour etre editable par Eficas\n\n"
+        msg=msg+self.object.text_error
+        Fenetre(self,titre="Poursuite non editable",texte=msg,wrap='none')
+        return
+
+    if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
+       #La poursuite n'est pas initialisee
+       text="""DEBUT()
+FIN()"""
+       self.object.build_poursuite(None,text)
+
+    # On cree un nouvel onglet dans le bureau
+    appli.bureau.ShowJDC(self.object.jdc_aux,self.object.jdc_aux.nom,
+                             label_onglet=None,
+                             JDCDISPLAY=macrodisplay.MACRODISPLAY)
+
+  def makeView(self,appli,node):
+    if not hasattr(self.object,"jdc_aux") or self.object.jdc_aux is None:
+         showerror("Poursuite vide","Une POURSUITE doit etre correctement initialisée pour etre visualisée")
+         return
+    nom=self.object.nom
+    if hasattr(self.object,'fichier_ini'):
+       if self.object.fichier_ini is None:
+          nom=nom+' '+"Fichier non défini"
+       else:
+          nom=nom+' '+self.object.fichier_ini
+    macdisp=macrodisplay.makeMacroDisplay(appli,self,nom)
+
+class INCLUDE_MATERIAUTreeItem(INCLUDETreeItemBase):
+  rmenu_specs=[("View","makeView"),
+              ]
+  def iscopiable(self):
+      """
+      Retourne 1 si l'objet est copiable, 0 sinon
+      """
+      return 1
+
+
+def treeitem(appli, labeltext, object, setfunction=None):
+   """ Factory qui retourne l'item adapté au type de macro : 
+       INCLUDE, POURSUITE, MACRO
+   """
+   if object.nom == "INCLUDE_MATERIAU":
+      return INCLUDE_MATERIAUTreeItem(appli, labeltext, object, setfunction)
+   elif object.nom == "INCLUDE":
+      return INCLUDETreeItem(appli, labeltext, object, setfunction)
+   elif object.nom == "POURSUITE":
+      return POURSUITETreeItem(appli, labeltext, object, setfunction)
+   else:
+      return MACROTreeItem(appli, labeltext, object, setfunction)
+
+import Accas
+objet=Accas.MACRO_ETAPE
+    
+import macrodisplay
diff --git a/Interface/compomclist.py b/Interface/compomclist.py
new file mode 100644 (file)
index 0000000..439342b
--- /dev/null
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+
+import types
+from Noyau.N_OBJECT import ErrorObj
+import Objecttreeitem
+import traceback
+
+
+import compofact
+import compoerror
+
+
+import browser
+from qt import *
+
+
+class Node(browser.JDCNode):
+##    def getPanel(self):
+##        """        
+##        """    
+##        return MCLISTPanel( self, self.editor )
+
+    def doPaste(self,node_selected):
+        objet_a_copier = self.item.get_copie_objet()
+        child=node_selected.doPaste_MCF(objet_a_copier)
+        #print "doPaste",child
+        return child
+
+    def doPaste_MCF(self,objet_a_copier):
+        if self.item.isMCList() :
+          # le noeud courant est une MCList
+          child = self.append_child(objet_a_copier,pos='first',retour='oui')
+          #child = self.parent.append_child(objet_a_copier,pos='first',retour='oui')
+        elif self.item.isMCFact() :
+          # le noeud courant est un MCFACT
+          if self.parent.item.isMCList():
+             # le noeud selectionne est un MCFACT dans une MCList
+             child = self.parent.append_child(objet_a_copier,
+                                              pos=self.item,
+                                              retour='oui')
+          else:
+             # le noeud MCFACT selectionne n'est pas dans une MCList
+             child = self.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.appli.affiche_infos("Copie refusée")
+          child=None
+        #print "doPaste_MCF",child
+        return child
+
+class MCListTreeItem(Objecttreeitem.SequenceTreeItem,compofact.FACTTreeItem):
+    """ La classe MCListTreeItem joue le role d'un adaptateur pour les objets
+        du noyau Accas instances de la classe MCLIST.
+        Elle adapte ces objets pour leur permettre d'etre intégrés en tant que
+        noeuds dans un arbre graphique (voir treewidget.py et ObjectTreeItem.py).
+        Cette classe délègue les appels de méthode et les accès
+        aux attributs à l'objet du noyau soit manuellement soit 
+        automatiquement (voir classe Delegate et attribut object).
+    """
+    itemNode=Node
+
+    def init(self):
+        # Si l'objet Accas (MCList) a moins d'un mot cle facteur
+        # on utilise directement ce mot cle facteur comme delegue
+        self.updateDelegate()
+
+    def updateDelegate(self):
+        if len(self._object) > 1:
+           self.setdelegate(self._object)
+        else:
+           self.setdelegate(self._object.data[0])
+
+    def panel(self,jdcdisplay,pane,node):
+        """ Retourne une instance de l'objet panneau associe a l'item (self)
+            Si la liste ne contient qu'un mot clé facteur, on utilise le panneau
+            FACTPanel.
+            Si la liste est plus longue on utilise le panneau MCLISTPanel.
+        """
+        if len(self._object) > 1:
+           return MCLISTPanel(jdcdisplay,pane,node)
+        elif isinstance(self._object.data[0],ErrorObj):
+           return compoerror.ERRORPanel(jdcdisplay,pane,node)
+        else:
+           return compofact.FACTPanel(jdcdisplay,pane,node)
+
+    def IsExpandable(self):
+        if len(self._object) > 1:
+           return Objecttreeitem.SequenceTreeItem.IsExpandable(self)
+        else:
+           return compofact.FACTTreeItem.IsExpandable(self)
+
+    def GetSubList(self):
+        self.updateDelegate()
+        if len(self._object) <= 1:
+           self._object.data[0].alt_parent=self._object
+           return compofact.FACTTreeItem.GetSubList(self)
+
+        liste=self._object.data
+        sublist=[None]*len(liste)
+        # suppression des items lies aux objets disparus
+        for item in self.sublist:
+           old_obj=item.getObject()
+           if old_obj in liste:
+              pos=liste.index(old_obj)
+              sublist[pos]=item
+           else:
+              pass # objets supprimes ignores
+        # ajout des items lies aux nouveaux objets
+        pos=0
+        for obj in liste:
+           if sublist[pos] is None:
+              # nouvel objet : on cree un nouvel item
+              def setfunction(value, object=obj):
+                  object=value
+              item = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, setfunction)
+              sublist[pos]=item
+              #Attention : on ajoute une information supplementaire pour l'actualisation de 
+              # la validite. L'attribut parent d'un MCFACT pointe sur le parent de la MCLISTE
+              # et pas sur la MCLISTE elle meme ce qui rompt la chaine de remontee des
+              # informations de validite. alt_parent permet de remedier a ce defaut.
+              obj.alt_parent=self._object
+           pos=pos+1
+
+        self.sublist=sublist
+        return self.sublist
+
+    def GetIconName(self):
+        if self._object.isvalid():
+            return "ast-green-los"
+        elif self._object.isoblig():
+            return "ast-red-los"
+        else:
+            return "ast-yel-los"
+
+    def get_docu(self):
+        """ Retourne la clé de doc de l'objet pointé par self """
+        return self.object.get_docu()    
+
+    def iscopiable(self):
+        if len(self._object) > 1:
+           return Objecttreeitem.SequenceTreeItem.iscopiable(self)
+        else:
+           return compofact.FACTTreeItem.iscopiable(self)
+
+    def isMCFact(self):
+        """
+        Retourne 1 si l'objet pointé par self est un MCFact, 0 sinon
+        """
+        return len(self._object) <= 1
+
+    def isMCList(self):
+        """
+        Retourne 1 si l'objet pointé par self est une MCList, 0 sinon
+        """
+        return len(self._object) > 1
+        
+    def get_copie_objet(self):
+        return self._object.data[0].copy()
+
+    def additem(self,obj,pos):
+        #print "compomclist.additem",obj,pos
+        if len(self._object) <= 1:
+           return compofact.FACTTreeItem.additem(self,obj,pos)
+
+        o= self.object.addentite(obj,pos)
+        return o
+
+    def suppitem(self,item):
+        """
+        Retire un objet MCFACT de la MCList (self.object) 
+        """
+        #print "compomclist.suppitem",item
+        obj=item.getObject()
+        if len(self._object) <= 1:
+           return compofact.FACTTreeItem.suppitem(self,item)
+
+        if self.object.suppentite(obj):
+           if len(self._object) == 1: self.updateDelegate()     
+           message = "Mot-clé " + obj.nom + " supprimé"
+           self.appli.affiche_infos(message)
+           return 1
+        else:
+           self.appli.affiche_infos('Impossible de supprimer ce mot-clé')
+           return 0
+
+            
+import Accas
+objet = Accas.MCList    
+
+def treeitem(appli,labeltext,object,setfunction):
+  """ Factory qui produit un objet treeitem adapte a un objet 
+      Accas.MCList (attribut objet de ce module)
+  """
+  return MCListTreeItem(appli,labeltext,object,setfunction)
diff --git a/Interface/componiveau.py b/Interface/componiveau.py
new file mode 100644 (file)
index 0000000..74239ec
--- /dev/null
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+import Objecttreeitem
+from Extensions import commentaire 
+
+import browser
+from qt import *
+
+class Node(browser.JDCNode): pass
+##    def getPanel(self):
+##        """        
+##        """    
+##        return NIVEAUPanel( self, self.editor )
+
+class NIVEAUTreeItem(Objecttreeitem.ObjectTreeItem):
+##  panel = NIVEAUPanel
+  itemNode=Node
+
+  def isactif(self):
+      return self.object.isactif()
+    
+  def IsExpandable(self):
+      return 1
+    
+  def GetLabelText(self):
+      """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+      """
+      if self.isactif():
+          fonte = Fonte_Niveau
+      else :
+          fonte = Fonte_Niveau_inactif
+      return self.labeltext,fonte,'#00008b'
+    
+  def GetIconName(self):
+      if self.isactif():
+          if self.object.isvalid():
+              return "ast-green-text"
+          else:
+              return "ast-red-text"
+      else:
+          return "ast-white-text"
+  
+  def keys(self):
+      if self.object.etapes_niveaux != []:
+          return range(len(self.object.etapes_niveaux))
+      else:
+          return range(len(self.object.etapes))
+
+  def GetSubList(self):
+    sublist=[]
+    for key in self.keys():
+      if self.object.etapes_niveaux != []:
+          liste = self.object.etapes_niveaux
+      else:
+          liste = self.object.etapes
+      try:
+        value = liste[key]
+      except KeyError:
+        continue
+      def setfunction(value, key=key, object=liste):
+        object[key] = value
+      item =self.make_objecttreeitem(self.appli,value.ident() + " : ", value, setfunction)
+      sublist.append(item)
+    return sublist
+
+  def additem(self,name,pos):
+      if isinstance(name,Objecttreeitem.TreeItem) :
+          cmd=self.object.addentite(name.getObject(),pos)
+      else :
+          cmd = self.object.addentite(name,pos)
+      item = self.make_objecttreeitem(self.appli,cmd.nom + " : ", cmd)
+      return item
+
+  def suppitem(self,item) :
+    # item = item de l'ETAPE à supprimer du JDC
+    # item.getObject() = ETAPE ou COMMENTAIRE
+    # self.object = JDC
+    itemobject=item.getObject()
+    if self.object.suppentite(itemobject):
+       if isinstance(item.object,commentaire.COMMENTAIRE):
+          message = "Commentaire supprimé"
+       else :
+          message = "Commande " + itemobject.nom + " supprimée"
+       self.appli.affiche_infos(message)
+       return 1
+    else:
+       self.appli.affiche_infos("Pb interne : impossible de supprimer cet objet")
+       return 0
+
+  def GetText(self):
+      return ''
+
+    
+import Accas
+treeitem = NIVEAUTreeItem
+objet = Accas.ETAPE_NIVEAU    
diff --git a/Interface/componuplet.py b/Interface/componuplet.py
new file mode 100644 (file)
index 0000000..4ef3b22
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import types
+
+from repr import Repr
+from copy import copy,deepcopy
+
+# Modules Eficas
+import Objecttreeitem
+
+
+#
+__version__="$Name: V1_11_qt $"
+__Id__="$Id: componuplet.py,v 1.9 2005-12-07 10:20:34 eficas Exp $"
+#
+
+myrepr = Repr()
+myrepr.maxstring = 100
+myrepr.maxother = 100
+
+# Si Expandable vaut 1 les éléments du nuplet apparaissent dans l'arbre
+# Si Expandable vaut 0 les éléments n'apparaissent pas
+Expandable=1
+
+
+import browser
+from qt import *
+
+class Node(browser.JDCNode): pass
+##    def getPanel(self):
+##        """        
+##        """    
+##        return NUPLETPanel( self, self.editor )
+    
+
+class NUPLETTreeItem(Objecttreeitem.ObjectTreeItem):
+##  panel=NUPLETPanel
+  itemNode=Node
+
+  def IsExpandable(self):
+    return Expandable
+
+  def GetText(self):
+      return  ''
+
+  def isvalid(self):
+    return self.object.isvalid()
+
+  def GetIconName(self):
+    if self.object.isvalid():
+      return "ast-green-los"
+    elif self.object.isoblig():
+      return "ast-red-los"
+    else:
+      return "ast-yel-los"
+
+  def GetSubList(self):
+    if not Expandable:return []
+    sublist=[]
+    for obj in self.object.mc_liste:
+      item = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, None)    
+      sublist.append(item)
+    return sublist
+
+  def additem(self,name,pos):
+    raise "NUPLET"
+
+  def suppitem(self,item) :
+    raise "NUPLET"
+
+import Accas
+treeitem=NUPLETTreeItem
+objet=Accas.MCNUPLET
diff --git a/Interface/compooper.py b/Interface/compooper.py
new file mode 100644 (file)
index 0000000..14077e7
--- /dev/null
@@ -0,0 +1,429 @@
+# -*- coding: utf-8 -*-
+
+import traceback
+import Objecttreeitem
+
+
+import string
+import browser
+from qt import *
+
+SEPARATEUR = '-'*30        
+        
+class OPERPanel(QTabWidget): #CS_pbruno todo
+    def __init__(self,node, parent = None,name = None,fl = 0):
+        QTabWidget.__init__(self,parent,name,fl)        
+        self.editor    = parent
+        self.node      = node
+        
+        tabKey      = self._buildTabKeyWord()
+        tabKeyWord  = self.buildTabConcept()
+        tabCommande = self.buildTabCommand()
+                        
+        self.insertTab( tabKey,     'Nouveau mot-cle' )
+        self.insertTab( tabKeyWord, 'Nommer concept')
+        self.insertTab( tabCommande,'Nouvelle Commande')
+                
+        #self.setCurrentPage(0)
+    
+    def get_liste_cmd(self):
+        #print "get_liste_cmd",self.node.item.object
+        jdc=self.node.item.object.get_jdc_root()
+        listeCmd = jdc.get_liste_cmd()
+        return listeCmd
+
+
+    def buildTabCommand(self):
+        """
+        """
+        tabCommand = QWidget(self)
+        layout = QVBoxLayout(tabCommand)
+        listBox = QListBox(tabCommand)
+        layout.addWidget(listBox)
+        liste_cmd = self.get_liste_cmd()
+        for aCmd in liste_cmd:         
+            listBox.insertItem( aCmd )
+            
+##        QObject.connect( listBox, SIGNAL( "doubleClicked(QListBoxItem* item)" ), self.defCmd )
+        QObject.connect( listBox, SIGNAL( "doubleClicked(QListBoxItem*)" ), self.defCmd )
+        return tabCommand
+        
+          
+    def buildTabConcept(self):
+        """
+        """
+        if self.node.item.is_reentrant():
+            print "# commande obligatoirement reentrante"
+            return self._buildTabConceptReentrant()
+        else:
+            print "# commande non reentrante ou facultativement reentrante"
+            return self._buildTabConcept()
+            
+    def _buildTabConceptReentrant(self):
+        """
+        """
+        raise 'CS_pbruno todo'
+            
+    def _buildTabConcept(self):
+        """
+        """
+        tabKeyWord = QWidget(self)
+        layout = QVBoxLayout(tabKeyWord)
+        
+        self.leConceptValue = QLineEdit(tabKeyWord)
+        
+        label1 = QLabel(tabKeyWord)
+        label1.setText("Nom du concept")
+        
+        layout.addWidget(label1)
+        layout.addWidget(self.leConceptValue)
+        
+        pushButton = QPushButton(tabKeyWord,"pushButton1")
+        
+        self.leConceptValue.setText(self.node.item.GetText())
+        type_sd = self.node.item.get_type_sd_prod()
+        if type_sd :
+          txt = "L'opérateur courant retourne un objet de type %s" %type_sd
+          label2 = QLabel(tabKeyWord)
+          label2.setText(txt)
+          layout.addWidget(label2)
+          
+        QObject.connect( pushButton , SIGNAL( "clicked()" ), self.defConcept )
+        return tabKeyWord
+        
+    def defConcept(self):
+        """
+        Nomme le concept SD retourné par l'étape
+        """
+        nom = str(self.leConceptValue.text())
+        nom = string.strip(nom)
+        if nom == '' : return # si pas de nom, on ressort sans rien faire ...
+        self.editor.init_modif()
+        test,mess = self.node.item.nomme_sd(nom)
+        #self.node.verif()
+        #self.node.racine.update()
+        self.editor.affiche_infos(mess)
+        
+    def defCmd(self, aQListBoxItem ):
+        """
+        On ajoute une commande après la commande selectionnée : after
+        ou bien on ajoute un commentaire
+        """      
+        name = str( aQListBoxItem.text() )
+        if name == SEPARATEUR:return
+        self.editor.init_modif()
+        if name != "COMMENTAIRE":
+            #parent=self.node.parent
+            #new_obj = parent.item.append_child(name,self.node.item.getObject())
+            #parent.children[parent.children.index(self.node)+1].select()
+            new_node = self.node.append_brother(name,'after')
+        else :
+            new_node = self.ajout_commentaire()
+    
+    def _buildTabKeyWord(self):
+        """
+        """
+        genea =self.node.item.get_genealogie()
+        jdc = self.node.item.get_jdc()
+        liste_mc=self.node.item.get_liste_mc_ordonnee(genea,jdc.cata_ordonne_dico)
+        
+        tabKeyWord  = QWidget(self)
+        layout = QVBoxLayout(tabKeyWord)
+        listBox = QListBox(tabKeyWord)
+        layout.addWidget(listBox)
+        for aMc in liste_mc:
+            listBox.insertItem( aMc)
+
+##        QObject.connect( listBox, SIGNAL( "doubleClicked(QListBoxItem* item)" ), self.defCmd )
+        QObject.connect( listBox, SIGNAL( "doubleClicked(QListBoxItem*)" ), self.defMC )
+        # CS_pbruno todo self.selectMC, self.deselectMC
+        return tabKeyWord
+    
+    
+    def defMC(self,aQListBoxItem):
+      """ On ajoute un mot-clé à la commande : subnode """
+      name = str( aQListBoxItem.text() )
+      if name == SEPARATEUR:return
+      self.editor.init_modif()
+      if name != "COMMENTAIRE":
+          self.node.append_child(name)
+      else :
+          self.ajout_commentaire()
+    
+
+class Node(browser.JDCNode):
+    def getPanel(self):
+        """
+        editor: (le parent)
+        """    
+        return OPERPanel( self, self.editor )
+        
+    def createPopUpMenu(self):
+        #menu
+        self.menu = QPopupMenu(self.tree)
+        
+        #ss-menu Comment: 
+        self.commentMenu = QPopupMenu( self.menu )
+        self.commentMenu.insertItem( 'it', self.commentIt )
+        self.commentMenu.insertItem( 'after', self.addCommentAfter )
+        self.commentMenu.insertItem( 'before', self.addCommentBefore )
+        
+        #ss-menu Parameters: 
+        self.parametersMenu = QPopupMenu( self.menu )
+        self.parametersMenu.insertItem( 'after', self.addParametersAfter )
+        self.parametersMenu.insertItem( 'before', self.addParametersBefore )
+        
+        #item du menu
+        self.menu.insertItem( qApp.translate('Browser','Delete'), self.delete )
+        self.menu.insertItem( qApp.translate('Browser','Comment'), self.commentMenu ) # CS_pbruno todo activer/désactiver
+        self.menu.insertItem( qApp.translate('Browser','Uncomment'), self.unCommentIt ) # CS_pbruno todo activer/désactiver
+        self.menu.insertItem( qApp.translate('Browser','Parameters'), self.parametersMenu )
+    
+    def addCommentAfter(self):
+        """
+        """        
+        self.addComment()
+                        
+    def addCommentBefore(self):
+        """      
+        """
+        self.addComment(False)        
+        
+    def addParametersAfter(self):
+        """
+        """        
+        self.addParameters()
+                        
+    def addParametersBefore(self):
+        """      
+        """
+        self.addParameters(False)
+        
+                
+        
+    def doPaste(self,node_selected):
+        """
+            Déclenche la copie de l'objet item avec pour cible
+            l'objet passé en argument : node_selected
+        """
+        objet_a_copier = self.item.get_copie_objet()
+        child=node_selected.doPaste_Commande(objet_a_copier)
+        return child
+
+    def doPaste_Commande(self,objet_a_copier):
+        """
+          Réalise la copie de l'objet passé en argument qui est nécessairement
+          une commande
+        """
+        parent=self.parent
+        #child = parent.item.append_child(objet_a_copier,self.item.getObject())
+        child = self.append_brother(objet_a_copier,retour='oui')
+        #if child is None:return 0
+        return child
+
+    def doPaste_MCF(self,objet_a_copier):
+        """
+           Réalise la copie de l'objet passé en argument (objet_a_copier)
+           Il s'agit forcément d'un mot clé facteur
+        """
+        child = self.append_child(objet_a_copier,pos='first',retour='oui')
+        return child
+
+
+class EtapeTreeItem(Objecttreeitem.ObjectTreeItem):
+  """ La classe EtapeTreeItem est un adaptateur des objets ETAPE du noyau
+      Accas. Elle leur permet d'etre affichés comme des noeuds
+      d'un arbre graphique.
+      Cette classe a entre autres deux attributs importants :
+        - _object qui est un pointeur vers l'objet du noyau
+        - object qui pointe vers l'objet auquel sont délégués les
+          appels de méthode et les accès aux attributs
+      Dans le cas d'une ETAPE, _object et object pointent vers le 
+      meme objet.
+  """
+##  panel = OPERPanel
+  itemNode=Node
+  
+  def IsExpandable(self):
+      return 1
+
+  def GetIconName(self):
+      """
+      Retourne le nom de l'icône à afficher dans l'arbre
+      Ce nom dépend de la validité de l'objet
+      """
+      if not self.object.isactif():
+         return "ast-white-square"
+      elif self.object.isvalid():
+         return "ast-green-square"
+      else:
+         return "ast-red-square"
+
+  def GetLabelText(self):
+      """ Retourne 3 valeurs :
+      - le texte à afficher dans le noeud représentant l'item
+      - la fonte dans laquelle afficher ce texte
+      - la couleur du texte
+      """
+      if self.object.isactif():
+        # None --> fonte et couleur par défaut
+        return self.labeltext,None,None
+      else:
+        return self.labeltext, None, None #CS_pbruno todo
+##        return self.labeltext,fontes.standard_italique,None 
+      
+  def get_objet(self,name) :
+      for v in self.object.mc_liste:
+          if v.nom == name : return v
+      return None
+      
+  def get_type_sd_prod(self):
+      """
+         Retourne le nom du type du concept résultat de l'étape
+      """
+      sd_prod=self.object.get_type_produit()
+      if sd_prod:
+         return sd_prod.__name__
+      else:
+         return ""
+
+  def additem(self,name,pos):      
+      print "CS_PBRUNO compooper.additem",name,pos
+      mcent = self._object.addentite(name,pos)
+      print "CS_PBRUNO mcent ",mcent 
+      return mcent
+      
+
+  def suppitem(self,item) :
+      # item : item du MOCLE de l'ETAPE à supprimer
+      # item.getObject() = MCSIMP, MCFACT, MCBLOC ou MCList 
+      itemobject=item.getObject()
+      if itemobject.isoblig() :
+          self.appli.affiche_infos('Impossible de supprimer un mot-clé obligatoire ')
+          return 0
+      if self.object.suppentite(itemobject):
+          message = "Mot-clé " + itemobject.nom + " supprimé"
+          self.appli.affiche_infos(message)
+          return 1
+      else :
+          self.appli.affiche_infos('Pb interne : impossible de supprimer ce mot-clé')
+          return 0
+
+  def GetText(self):
+      try:
+          return self.object.get_sdname()
+      except:
+          return ''
+
+  def keys(self):
+      keys=self.object.mc_dict.keys()
+      return keys
+
+  def GetSubList(self):
+      """
+         Reactualise la liste des items fils stockes dans self.sublist
+      """
+      if self.isactif():
+         liste=self.object.mc_liste
+      else:
+         liste=[]
+
+      sublist=[None]*len(liste)
+      # suppression des items lies aux objets disparus
+      for item in self.sublist:
+         old_obj=item.getObject()
+         if old_obj in liste:
+            pos=liste.index(old_obj)
+            sublist[pos]=item
+         else:
+            pass # objets supprimes ignores
+
+      # ajout des items lies aux nouveaux objets
+      pos=0
+      for obj in liste:
+         if sublist[pos] is None:
+            # nouvel objet : on cree un nouvel item
+            def setfunction(value, object=obj):
+                object.setval(value)
+            item = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, setfunction)
+            sublist[pos]=item
+         pos=pos+1
+
+      self.sublist=sublist
+      return self.sublist
+
+  def isvalid(self):
+      return self.object.isvalid()
+
+  def iscopiable(self):
+      """
+      Retourne 1 si l'objet est copiable, 0 sinon
+      """
+      return 1
+
+  def update(self,item):
+      if item.sd and item.sd.nom:
+         self.nomme_sd(item.sd.nom)
+
+  def nomme_sd(self,nom):
+      """ Lance la méthode de nommage de la SD """
+      oldnom=""
+      if self.object.sd != None :
+         oldnom=self.object.sd.nom
+      test,mess= self.object.nomme_sd(nom)
+      if test:self.object.parent.reset_context()
+      if (test and self.appli.dict_reels.has_key(oldnom) ):
+              self.appli.dict_reels[nom]=self.appli.dict_reels[oldnom]
+      return test,mess
+
+  def is_reentrant(self):
+      return self.object.is_reentrant()
+    
+  def get_noms_sd_oper_reentrant(self):
+      return self.object.get_noms_sd_oper_reentrant()
+
+  def get_objet_commentarise(self):
+      """
+          Cette méthode retourne un objet commentarisé
+          représentatif de self.object
+      """
+      # Format de fichier utilisé
+      format=self.appli.format_fichier
+      return self.object.get_objet_commentarise(format)
+
+  def get_objet_commentarise_BAK(self):
+      """
+          Cette méthode retourne un objet commentarisé
+          représentatif de self.object
+      """
+      import generator,string,Accas
+      # Format de fichier utilisé
+      format=self.appli.format_fichier.get()
+      g=generator.plugins[format]()
+      texte_commande = g.gener(self.object,format='beautifie')
+      # Il faut enlever la première ligne vide de texte_commande que 
+      # rajoute le generator
+      rebut,texte_commande = string.split(texte_commande,'\n',1)
+      # on construit l'objet COMMANDE_COMM repésentatif de self mais non 
+      # enregistré dans le jdc
+      commande_comment = Accas.COMMANDE_COMM(texte=texte_commande,reg='non',
+                                             parent=self.object.parent)
+      commande_comment.niveau = self.object.niveau
+      commande_comment.jdc = commande_comment.parent = self.object.jdc
+
+      pos=self.object.parent.etapes.index(self.object)
+      parent=self.object.parent
+      self.object.parent.suppentite(self.object)
+      parent.addentite(commande_comment,pos)
+
+      return commande_comment
+
+  def visu_3D(self,appli,node) :
+      import TroisDPal
+      troisD=TroisDPal.TroisDPilote(node.item,appli,node.parent)
+      troisD.envoievisu()
+
+import Accas
+treeitem = EtapeTreeItem
+objet = Accas.ETAPE    
+
diff --git a/Interface/compoparam.py b/Interface/compoparam.py
new file mode 100644 (file)
index 0000000..8fea924
--- /dev/null
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+"""
+   Ce module contient les classes permettant de définir les objets graphiques
+   représentant un objet de type PARAMETRE, cad le panneau et l'item de l'arbre
+   d'EFICAS
+"""
+
+# import modules Python
+import string
+
+# import modules EFICAS
+import Objecttreeitem
+
+
+import browser
+from qt import *
+
+class Node(browser.JDCNode): pass
+##    def getPanel(self):
+##        """        
+##        """    
+##        return PARAMPanel( self, self.editor )
+
+
+class PARAMTreeItem(Objecttreeitem.ObjectTreeItem):
+    """
+    Classe servant à définir l'item porté par le noeud de l'arbre d'EFICAS
+    qui représente le PARAMETRE
+    """
+    itemNode=Node
+##    panel = PARAMPanel
+
+    def init(self):      
+      self.setfunction = self.set_valeur
+
+# ---------------------------------------------------------------------------
+#                   API du PARAMETRE pour l'arbre 
+# ---------------------------------------------------------------------------
+
+    def GetIconName(self):
+      """
+      Retourne le nom de l'icône associée au noeud qui porte self,
+      dépendant de la validité de l'objet
+      NB : un PARAMETRE est toujours valide ...
+      """
+      if self.isactif():
+          if self.isvalid():
+              return "ast-green-square"
+          else:
+              return "ast-red-square"
+      else:
+          return "ast-white-square"
+
+    def GetLabelText(self):
+        """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+        """
+        return 'Paramètre',None,None #CS_pbruno todo
+##        return 'Paramètre',Fonte_PARAMETRE,None 
+
+    def GetText(self):
+      """
+      Retourne le texte à afficher après le nom de la commande (ici après 'paramètre')
+      Ce texte est tronqué à 25 caractères
+      """
+      texte = repr(self.object)
+      texte = string.split(texte,'\n')[0]
+      if len(texte) < 25 :
+          return texte
+      else :
+          return texte[0:24]+'...'
+
+    def GetSubList(self):
+      """
+      Retourne la liste des fils de self
+      """
+      return []
+    
+# ---------------------------------------------------------------------------
+#       Méthodes permettant la modification et la lecture des attributs
+#       du paramètre = API graphique du PARAMETRE pour Panel et EFICAS
+# ---------------------------------------------------------------------------
+
+    def get_valeur(self):
+      """
+      Retourne la valeur de l'objet PARAMETRE cad son texte
+      """
+      if self.object.valeur is None: return ''
+      else: return self.object.valeur 
+
+    def get_nom(self):
+      """
+      Retourne le nom du paramètre
+      """
+      return self.object.nom
+
+    def set_valeur(self,new_valeur):
+      """
+      Affecte valeur à l'objet PARAMETRE
+      """
+      self.object.set_valeur(new_valeur)
+
+    def set_nom(self,new_nom):
+      """
+      Renomme le paramètre
+      """
+      self.object.set_nom(new_nom)
+      #self.object.set_attribut('nom',new_nom)
+
+    def get_fr(self):
+      """
+      Retourne le fr associé au paramètre, cad la bulle d'aide pour EFICAS
+      """
+      return "Définition d'un paramètre"
+    
+import Extensions.parametre
+treeitem =PARAMTreeItem
+objet = Extensions.parametre.PARAMETRE
diff --git a/Interface/compoparameval.py b/Interface/compoparameval.py
new file mode 100644 (file)
index 0000000..12db64c
--- /dev/null
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*-
+
+"""
+Ce module contient les classes permettant de définir les objets graphiques
+représentant un objet de type PARAMETRE_EVAL, cad le panneau et l'item de l'arbre
+d'EFICAS
+"""
+
+# import modules Python
+import string
+
+# import modules EFICAS
+
+import Objecttreeitem
+
+
+import browser
+from qt import *
+
+class Node(browser.JDCNode): pass
+##    def getPanel(self):
+##        """        
+##        """    
+##        return PARAM_EVALPanel( self, self.editor )
+
+
+class PARAM_EVALTreeItem(Objecttreeitem.ObjectTreeItem):
+    """
+    Classe servant à définir l'item porté par le noeud de l'arbre d'EFICAS
+    qui représente le PARAMETRE
+    """
+    itemNode=Node
+##    panel = PARAM_EVALPanel
+
+    def init(self):
+      self.setfunction = self.set_valeur
+
+# ---------------------------------------------------------------------------
+#                   API du PARAMETRE pour l'arbre 
+# ---------------------------------------------------------------------------
+
+    def GetIconName(self):
+      """
+      Retourne le nom de l'icône associée au noeud qui porte self,
+      dépendant de la validité de l'objet
+      NB : un PARAMETRE est toujours valide ...
+      """
+      if self.isactif():
+          if self.isvalid():
+              return "ast-green-square"
+          else:
+              return "ast-red-square"
+      else:
+          return "ast-white-square"
+
+    def GetLabelText(self):
+        """ Retourne 3 valeurs :
+        - le texte à afficher dans le noeud représentant l'item
+        - la fonte dans laquelle afficher ce texte
+        - la couleur du texte
+        """
+        return 'EVAL',Fonte_PARAMETRE,None
+
+    def GetText(self):
+      """
+      Retourne le texte à afficher après le nom de la commande (ici après 'paramètre')
+      Ce texte est tronqué à 25 caractères
+      """
+      texte = repr(self.object)
+      texte = string.split(texte,'\n')[0]
+      if len(texte) < 25 :
+          return texte
+      else :
+          return texte[0:24]+'...'
+
+    def GetSubList(self):
+      """
+      Retourne la liste des fils de self
+      """
+      return []
+    
+# ---------------------------------------------------------------------------
+#       Méthodes permettant la modification et la lecture des attributs
+#       du paramètre = API graphique du PARAMETRE pour Panel et EFICAS
+# ---------------------------------------------------------------------------
+
+    def isvalid(self):
+      """
+      Indique si l'objet pointé par self est valide
+      """
+      return self.object.isvalid()
+    
+    def get_valeur(self):
+      """
+      Retourne une chaîne représentant la valeur de l'objet PARAMETRE
+      cad de l'objet class_eval.EVAL
+      """
+      return self.object.get_valeur() or ''
+
+    def get_nom(self):
+      """
+      Retourne le nom du paramètre
+      """
+      return self.object.get_nom()
+
+    def set_valeur(self,new_valeur):
+      """
+      Affecte new_valeur à l'objet PARAMETRE_EVAL
+      """
+      # on construit le texte de la nouvelle valeur
+      new_valeur = 'EVAL("""'+new_valeur+'""")'
+      # on affecte la nouvelle valeur à self.object
+      self.object.set_valeur(new_valeur)
+
+    def set_nom(self,new_nom):
+      """
+      Renomme le paramètre
+      """
+      self.object.set_nom(new_nom)
+
+    def get_fr(self):
+      """
+      Retourne le fr associé au paramètre, cad la bulle d'aide pour EFICAS
+      """
+      return "Définition d'un paramètre de type EVAL"
+
+    def verif_nom(self,nom):
+      """
+      Lance la vérification de validité du nom passé en argument
+      """
+      return self.object.verif_nom(nom = nom)
+
+    def verif_eval(self,valeur):
+      """
+      Lance la vérification de validité de l'expression EVAL passée en argument
+      """
+      return self.object.verif_eval(exp_eval = valeur)
+
+    def save_parametre_eval(self,new_nom,new_val):
+      """
+      Vérifie si (new_nom,new_val) définit bien un EVAL licite :
+          - si oui, stocke ces paramètres comme nouveaux paramètres de l'EVAL courant et retourne 1
+          - si non, laisse les paramètres anciens de EVAL inchangés et retourne 0
+      """
+      test,erreur = self.object.verif_parametre_eval(param=(new_nom,new_val))
+      if test :
+          # la formule est bien correcte : on sauve les nouveaux paramètres
+          self.object.update(param=(new_nom,new_val))
+      return test,erreur
+      
+import Extensions.parametre_eval
+treeitem =PARAM_EVALTreeItem
+objet = Extensions.parametre_eval.PARAMETRE_EVAL
diff --git a/Interface/compoproc.py b/Interface/compoproc.py
new file mode 100644 (file)
index 0000000..4368701
--- /dev/null
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+import Objecttreeitem
+import compooper
+
+
+import browser
+from qt import *
+
+class Node(browser.JDCNode): pass
+##    def getPanel(self):
+##        """        
+##        """    
+##        return PROCPanel( self, self.editor )
+
+class ProcEtapeTreeItem(compooper.EtapeTreeItem):
+    itemNode=Node
+##  panel = PROCPanel
+    pass
+  
+import Accas
+treeitem = ProcEtapeTreeItem
+objet = Accas.PROC_ETAPE    
+
diff --git a/Interface/composimp.py b/Interface/composimp.py
new file mode 100644 (file)
index 0000000..4f4211b
--- /dev/null
@@ -0,0 +1,894 @@
+# -*- coding: utf-8 -*-
+# Modules Python
+import string,types,os
+
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+
+from Noyau.N_CR import justify_text
+import browser
+from qt import *
+    
+class UNIQUE_BASE_Panel(QTabWidget): #CS_pbruno todo tmp
+    """
+    Classe servant à définir le panneau associé aux mots-clés simples qui attendent
+    une valeur d'un type de base (entier, réel ou string).
+    """    
+    def __init__(self,node, parent = None,name = None,fl = 0):
+        QTabWidget.__init__(self,parent,name,fl)        
+        self.editor    = parent
+        self.node      = node
+                
+        tabSaisie  = self._buildTabSaisie()
+        tabKey     = QWidget(self)
+        
+        self.addTab( tabSaisie, QString('Saisie Valeur') )
+        #self.insertTab( tabSaisie, 'Saisie Valeur' )
+        #self.setCurrentPage(0)
+        
+    def __tr(self,s,c = None):
+        return qApp.translate("Form1",s,c)
+
+    def __trUtf8(self,s,c = None):
+        return qApp.translate("Form1",s,c,QApplication.UnicodeUTF8)
+        
+    def _buildTabSaisie(self):
+        """
+        """
+        tabSaisie = QWidget(self)
+        layout = QVBoxLayout(tabSaisie)
+        
+        self.leValue = QLineEdit(tabSaisie)
+        
+        label1 = QLabel(tabSaisie)
+        label1.setText("Valeur")
+        
+        layout.addWidget(label1)
+        layout.addWidget(self.leValue)
+        
+        pushButton = QPushButton(tabSaisie,"pushButton1")        
+                
+        aide=self.get_aide()
+        aide= justify_text(texte=aide)
+        label2 = QLabel(tabSaisie)
+        label2.setText(aide)
+        layout.addWidget(label2)        
+        
+        self.display_valeur()
+          
+        QObject.connect( pushButton , SIGNAL( "clicked()" ), self.valide ) #CS_pbruno todo bind Return
+        return tabSaisie
+    
+    def valide(self):
+        self.valid_valeur()
+    
+##    def defConcept(self):
+##        """
+##        Nomme le concept SD retourné par l'étape      
+##        """
+##        nom = str(self.leConceptValue.text())
+##        nom = string.strip(nom)
+##        if nom == '' : return # si pas de nom, on ressort sans rien faire ...
+##        self.editor.init_modif()
+##        test,mess = self.node.item.nomme_sd(nom)
+##        #self.node.verif()
+##        #self.node.racine.update()
+##        self.editor.affiche_infos(mess)                
+
+  
+##  def makeValeurPage(self,page):
+##      """
+##      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
+##      de base cad entier, réel, string ou complexe
+##      """
+##      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
+##      # et de la liste des SD du bon type (constituant la liste des choix)
+##      bulle_aide=self.get_bulle_aide()
+##      aide=self.get_aide()
+##      aide= justify_text(texte=aide)
+##      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
+##      # Remplissage du panneau
+##      self.frame_valeur = Frame(page)
+##      self.frame_valeur.pack(fill='both',expand=1)
+##      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+##      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+##      self.label = Label(self.frame_valeur,text='Valeur :')
+##      self.label.place(relx=0.1,rely=0.2)
+##      self.entry = Entry(self.frame_valeur,relief='sunken')
+##      self.entry.place(relx=0.28,rely=0.2,relwidth=0.6)
+##      self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
+##      self.entry.bind("<KP_Enter>",lambda e,c=self.valid_valeur:c())
+##      # aide associée au panneau
+##      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.9,anchor='n')
+##      # bouton parametre
+##      bouton_parametres = Button(self.frame_valeur, text="Parametres", command=self.affiche_parametre)
+##      bouton_parametres.place(relx=0.28,rely=0.5,relwidth=0.4)
+##      bouton_val = Button(self.frame_valeur, text="Valider", command=self.valide)
+##      bouton_val.place(relx=0.28,rely=0.6,relwidth=0.4)
+##      # affichage de la valeur du MCS
+##      self.display_valeur()
+##
+##  def affiche_parametre(self) :
+##     if self.node.item.get_liste_param_possible() != [ ]:
+##        txtparam=""
+##        for param in self.node.item.get_liste_param_possible():
+##           txtparam=txtparam+repr(param)+"\n"
+##        if txtparam=="":
+##           showerror("Aucun parametre ","Pas de parametre de ce type")
+##        else :
+##           try :
+##                   self.fenetreparam.destroy()
+##           except :
+##                pass
+##           self.fenetreparam=FenetreDeParametre( self, self.node.item, self.parent.appli, txtparam)
+##
+##  def destroy(self):
+##      try :
+##              self.fenetreparam.destroy()
+##      except :
+##        pass
+##      Widget.destroy(self)
+
+    
+
+    def get_aide(self):
+        """
+        Retourne la phrase d'aide indiquant de quel type doit être la valeur
+        du mot-clé simple fournie par l'utilisateur
+        """
+        mc = self.node.item.get_definition()        
+        d_aides = { 'TXM' : self.__trUtf8("Une chaîne de caractères est attendue"),
+                    'R'   : self.__trUtf8("Un réel est attendu"),
+                    'I'   : self.__trUtf8("Un entier est attendu") }
+        type = mc.type[0]
+        commentaire=str(d_aides.get(type, self.__trUtf8("Type de base inconnu")))
+        aideval=self.node.item.aide()
+        commentaire=commentaire +"\n"+ aideval
+        return commentaire
+
+##  def get_bulle_aide(self):
+##      """
+##      Retourne la bulle d'aide associée au panneau et affichée par clic droit
+##      """
+##      return """Saisissez la valeur que vous voulez affecter au mot-clé simple
+##      dans la zone de saisie et pressez <Return>"""
+      
+    def display_valeur(self):
+        """
+        Affiche la valeur de l'objet pointé par self
+        """        
+        valeur = self.node.item.get_valeur()        
+        if valeur == None or valeur == '' : # pas de valeur à afficher ...
+            valeur = ''
+        else:
+            valeur_texte=self.get_valeur_texte(valeur)
+            if valeur_texte:
+                valeur = valeur_texte                
+        self.leValue.setText( str(valeur) )
+        
+      
+    # -------------   UNIQUE_Panel  debut
+    def valid_valeur(self,valeurentree=None):
+        """
+        Teste si la valeur fournie par l'utilisateur est une valeur permise :
+          - si oui, l'enregistre
+          - si non, restaure l'ancienne valeur
+        """
+        self.editor.init_modif()      
+        anc_val = self.node.item.get_valeur()
+        if valeurentree== None :
+            ##valeurentree = self.get_valeur()
+            valeurentree = str(self.leValue.text())
+            print 'XXXXX valeurentree ->',valeurentree 
+         
+        valeur,validite=self.node.item.eval_valeur(valeurentree)
+        if not validite :
+            commentaire = "impossible d'évaluer : %s " %`valeurentree`
+            self.display_valeur()
+            self.editor.affiche_infos(commentaire)
+            return
+   
+        test = self.node.item.set_valeur(valeur)
+        if test :
+            self.set_valeur_texte(str(valeurentree))
+       
+        if not test :
+            mess = "impossible d'évaluer : %s " %`valeur`
+            self.editor.affiche_infos("Valeur du mot-clé non autorisée : "+mess)
+        elif self.node.item.isvalid() :
+            self.editor.affiche_infos('Valeur du mot-clé enregistrée')
+        else :
+            cr = self.node.item.get_cr()
+            mess = "Valeur du mot-clé non autorisée "+cr.get_mess_fatal()
+            self.reset_old_valeur(anc_val,mess=mess)
+
+        self.display_valeur()
+      
+      
+    # -------------   UNIQUE_Panel  fin    
+    # -------------   newSIMPPanel  debut
+    def reset_old_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é ni ré-évaluer l'ancienne valeur
+          permet de rester avec des valeurs non entrees et de ne pas 
+          ré-évaluer des entiers par exemple
+      """
+      self.editor.init_modif()
+      self.node.item.set_valeur(name)
+      self.editor.affiche_infos(mess)
+      
+    # ----------------------------------------------------------------------------------------
+    #   Méthodes utilisées pour la manipulation des items en notation scientifique
+    # ----------------------------------------------------------------------------------------
+    def set_valeur_texte(self,texte_valeur) :
+        """ Sert à mettre à jour la notation scientifique"""
+        try :
+            if "R" in self.node.item.object.definition.type:
+                if texte_valeur[0] != "'":
+                   clef=eval(texte_valeur)
+                   if str(clef) != str(texte_valeur) :
+                      self.node.item.object.init_modif()
+                      clefobj=self.node.item.object.GetNomConcept()
+                      if not self.editor.dict_reels.has_key(clefobj):
+                         self.editor.dict_reels[clefobj] = {}
+                      self.editor.dict_reels[clefobj][clef]=texte_valeur
+                      self.editor.dict_reels[clefobj]
+                      self.node.item.object.fin_modif()
+        except:
+            pass
+
+    def get_valeur_texte(self,valeur) :
+        print "get_valeur_texte valeur->", valeur
+        valeur_texte=""
+        print 'A ->' , self.node.item.object.definition.type
+        if "R" in self.node.item.object.definition.type:
+            clefobj=self.node.item.object.GetNomConcept()
+            print 'B clefobj->' , clefobj
+            print 'B self.editor.dict_reels->' , self.editor.dict_reels
+            if self.editor.dict_reels.has_key(clefobj):
+                print 'C self.editor.dict_reels[clefobj]->' , self.editor.dict_reels[clefobj]
+                if self.editor.dict_reels[clefobj].has_key(valeur):
+                    print 'D self.editor.dict_reels[clefobj][valeur]->' , self.editor.dict_reels[clefobj][valeur]
+                    valeur_texte=self.editor.dict_reels[clefobj][valeur]
+        return valeur_texte
+    
+    # -------------   newSIMPPanel  fin
+      
+      
+    
+    
+    
+    
+class Node(browser.JDCNode):
+    def getPanel(self):
+        """        
+        """
+        return UNIQUE_BASE_Panel( self, self.editor )
+    
+    
+      
+class SIMPTreeItem(Objecttreeitem.AtomicObjectTreeItem):
+##  from newsimppanel import newSIMPPanel
+##  panel = newSIMPPanel
+  itemNode=Node
+
+  def init(self) :
+      self.expandable = 0
+      self.affect_panel()
+
+
+  def affect_panel(self):
+      """
+      Cette méthode attribue le panel à l'objet pointé par self en fonction de la
+      nature de la valeur demandée pour cet objet
+      """      
+##      from uniquepanel import UNIQUE_Panel
+##      from plusieurspanel import PLUSIEURS_Panel
+            
+
+      #print "affect_panel : ",self.nom,self.is_list(),self.has_into(), self.get_into(None)
+      # Attention l ordre des if est important
+
+      if self.wait_shell():
+          # l'objet attend un shell
+          from shellpanel import SHELLPanel
+          self.panel = SHELLPanel
+      elif self.has_into():
+          # l'objet prend sa (ses) valeur(s) dans un ensemble discret de valeurs
+          if self.is_list() :
+             from plusieursintopanel import PLUSIEURS_INTO_Panel
+             self.panel = PLUSIEURS_INTO_Panel
+          else:
+             from uniqueintopanel import UNIQUE_INTO_Panel
+             self.panel = UNIQUE_INTO_Panel
+      else:
+          # l'objet prend une ou des valeurs à priori quelconques
+          if self.is_list() :
+              # on attend une liste de valeurs mais de quel type ?
+              if self.wait_assd():
+                  # on attend une liste de SD
+                  from plusieursassdpanel import PLUSIEURS_ASSD_Panel
+                  self.panel = PLUSIEURS_ASSD_Panel
+              else:
+                  # on attend une liste de valeurs de types debase (entiers, réels,...)
+                  #from plusieursbasepanel import PLUSIEURS_BASE_OR_UNELISTE_Panel
+                  #self.panel = PLUSIEURS_BASE_OR_UNELISTE_Panel
+                  from plusieursbasepanel import PLUSIEURS_BASE_Panel
+                  self.panel = PLUSIEURS_BASE_Panel
+          else:
+              # on n'attend qu'une seule valeur mais de quel type ?
+              if self.wait_co():
+                  # on attend une SD ou un objet de la classe CO (qui n'existe pas encore)
+                  from uniquesdcopanel import UNIQUE_SDCO_Panel
+                  self.panel = UNIQUE_SDCO_Panel
+              elif self.wait_assd():
+                  # on attend une SD
+                  from uniqueassdpanel import UNIQUE_ASSD_Panel
+                  from uniqueassdpanel import UNIQUE_ASSD_Panel_Reel
+                  if 'R' in self.GetType():
+                     self.panel = UNIQUE_ASSD_Panel_Reel
+                  else :
+                     self.panel = UNIQUE_ASSD_Panel
+              else:
+                  # on attend une valeur d'un type de base (entier,réel,...)
+                  if self.wait_complex():
+                      # on attend un complexe
+                      from uniquecomppanel import UNIQUE_COMP_Panel
+                      self.panel = UNIQUE_COMP_Panel
+                  else:
+                      # on attend un entier, un réel ou une string
+##                      from uniquebasepanel import UNIQUE_BASE_Panel CS_pbruno todo tmp UNIQUE_BASE_Panel                      
+                      self.panel = UNIQUE_BASE_Panel
+      # cas particulier des fonctions
+      genea = self.get_genealogie()
+      if "VALE" in genea or "VALE_C" in genea:
+         if "DEFI_FONCTION" in genea :
+            from fonctionpanel import FONCTION_Panel
+            self.panel=FONCTION_Panel
+      #---------------------------------------------------------
+      # PN ajout pour lancement de Salome
+      #---------------------------------------------------------
+      if hasattr( self.appli, 'salome' ):
+          import panelsSalome
+
+          self.select_noeud_maille=0
+          self.clef_fonction="SALOME"
+          for i in range(0,len( genea )) :
+             self.clef_fonction=self.clef_fonction+"_"+ genea[i]
+             #if genea[i] == "GROUP_NO" or genea[i] == "GROUP_MA":
+          if "GROUP_NO" in genea[len(genea)-1] or "GROUP_MA" in genea[len(genea)-1]:
+             self.select_noeud_maille=1
+
+          recherche=panelsSalome.dict_classes_salome[self.panel]
+          if hasattr(recherche,self.clef_fonction):
+             self.panel=recherche
+          if self.select_noeud_maille==1 :
+             self.panel=recherche
+
+
+  #-----------------------------------------------
+  #
+  # Methodes liees aux informations sur le Panel
+  # ou au mot-clef simple
+  #
+  #-----------------------------------------------
+  # is_list
+  # get_into                a priori inutile --> commentee
+  # has_into
+  # wait_into                a priori inutile --> commentee
+  # GetMinMax
+  # GetMultiplicite
+  # GetIntervalle
+  # GetListeValeurs
+  # get_liste_possible
+
+  def is_list(self):
+      """
+          Cette méthode indique si le mot cle simple attend une liste (valeur de retour 1)
+          ou s'il n'en attend pas (valeur de retour 0)
+
+          Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
+          Dans le cas sans validateur, l'information est donnée par l'attribut max
+          de la definition du mot cle.
+          Dans le cas avec validateur, il faut combiner l'information précédente avec
+          celle issue de l'appel de la méthode is_list sur le validateur.On utilisera
+          l'operateur ET pour effectuer cette combinaison (AndVal).
+      """
+      is_a_list=0
+      min,max = self.GetMinMax()
+      assert (min <= max)
+      if max > 1 :
+                is_a_list=1
+      # Dans le cas avec validateurs, pour que le mot cle soit considéré
+      # comme acceptant une liste, il faut que max soit supérieur a 1
+      # ET que la méthode is_list du validateur retourne 1. Dans les autres cas
+      # on retournera 0 (n'attend pas de liste)
+      if self.definition.validators :
+         is_a_list= self.definition.validators.is_list() * is_a_list
+      return is_a_list 
+
+  #def get_into(self,liste_courante=None):
+  #    """
+  #        Cette méthode retourne la liste de choix proposée par le mot cle. Si le mot cle ne propose
+  #        pas de liste de choix, la méthode retourne None.
+  #        L'argument d'entrée liste_courante, s'il est différent de None, donne la liste des choix déjà
+  #        effectués par l'utilisateur. Dans ce cas, la méthode get_into doit calculer la liste des choix
+  #        en en tenant compte.
+  #        Cette méthode part du principe que la relation entre into du mot clé et les validateurs est
+  #        une relation de type ET (AndVal).
+  #    """
+  #    if not self.object.definition.validators :
+  #       return self.object.definition.into
+  #    else:
+  #       return self.object.definition.validators.get_into(liste_courante,self.definition.into)
+
+  def has_into(self):
+      """
+          Cette méthode indique si le mot cle simple propose un choix (valeur de retour 1)
+          ou s'il n'en propose pas (valeur de retour 0)
+
+          Deux cas principaux peuvent se presenter : avec validateurs ou bien sans.
+          Dans le cas sans validateur, l'information est donnée par l'attribut into
+          de la definition du mot cle.
+          Dans le cas avec validateurs, pour que le mot cle soit considéré
+          comme proposant un choix, il faut que into soit présent OU
+          que la méthode has_into du validateur retourne 1. Dans les autres cas
+          on retournera 0 (ne propose pas de choix)
+      """
+      has_an_into=0
+      if self.definition.into:
+               has_an_into=1
+      elif self.definition.validators :
+         has_an_into= self.definition.validators.has_into()
+      return has_an_into
+
+#  def wait_into(self):
+#      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
+#      prend ses valeurs dans un ensemble discret (into), 0 sinon """
+#      if self.object.definition.into != None :
+#          return 1
+#      else:
+#          return 0
+
+  def GetMinMax(self):
+      """ Retourne les valeurs min et max de la définition de object """
+      return self.object.get_min_max()
+
+  def GetMultiplicite(self):
+      """ A préciser.
+          Retourne la multiplicité des valeurs affectées à l'objet
+          représenté par l'item. Pour le moment retourne invariablement 1.
+      """
+      return 1
+
+  def GetIntervalle(self):
+      """ 
+           Retourne le domaine de valeur attendu par l'objet représenté 
+           par l'item.
+      """
+      return self.object.getintervalle()
+
+  def GetListeValeurs(self) :
+      """ Retourne la liste des valeurs de object """
+      valeurs=self.object.get_liste_valeurs()
+      try :
+        if "R" in self.object.definition.type:
+           clef=self.object.GetNomConcept()
+           if self.appli.dict_reels.has_key(clef):
+              if type(valeurs) == types.TupleType:
+                 valeurs_reelles=[]
+                 for val in valeurs :
+                    if self.appli.dict_reels[clef].has_key(val) : 
+                       valeurs_reelles.append(self.appli.dict_reels[clef][val])
+                    else :
+                       valeurs_reelles.append(val)
+              else :
+                 if self.appli.dict_reels[clef].has_key(valeurs):
+                    valeurs_reelles=self.appli.dict_reels[clef][valeurs]
+              valeurs=valeurs_reelles
+      except :
+        pass
+      return valeurs
+    
+  def get_liste_possible(self,listeActuelle=[]):
+      if hasattr(self.definition.validators,'into'):
+         valeurspossibles = self.definition.validators.into 
+      else:
+         valeurspossibles = self.get_definition().into
+
+      #On ne garde que les items valides
+      listevalideitem=[]
+      for item in valeurspossibles:
+          encorevalide=self.valide_item(item)
+          if encorevalide :
+             listevalideitem.append(item)
+
+      #on ne garde que les choix possibles qui passent le test de valide_liste_partielle
+      listevalideliste=[]
+      for item in listevalideitem:
+          encorevalide=self.valide_liste_partielle(item,listeActuelle)
+          if encorevalide :
+              listevalideliste.append(item)
+      return listevalideliste
+
+  def get_liste_param_possible(self):
+      liste_param=[]
+      for param in self.object.jdc.params:
+          encorevalide=self.valide_item(param.valeur)
+          if encorevalide:
+             type_param=param.valeur.__class__.__name__
+             for typ in self.definition.type:
+                 if typ=='R':
+                     liste_param.append(param)
+                 if typ=='I' and type_param=='int':
+                     liste_param.append(param)
+                 if typ=='TXM' and type_param=='str':
+                     liste_param.append(repr(param))
+      return liste_param
+
+  #--------------------------------------------------
+  #
+  # Methodes liees a la validite des valeurs saisies
+  #
+  #---------------------------------------------------
+  # valide_item
+  # valide_liste_partielle
+  # valide_liste_complete
+  # info_erreur_item
+  # info_erreur_liste
+  # IsInIntervalle
+  # isvalid
+
+  def valide_item(self,item):
+      """
+        La validation est réalisée directement par l'objet
+      """
+      return self.object.valide_item(item)
+     
+  def valide_liste_partielle(self,item,listecourante):
+      #On protege la liste en entree en la copiant
+      valeur=listecourante[:]
+      valeur.append(item)
+      return self.object.valid_valeur_partielle(valeur)
+
+  def valide_liste_complete (self,valeur):
+      return self.object.valid_valeur(valeur)
+
+  def valide_val (self,valeur):
+      return self.object.valid_val(valeur)
+
+  def info_erreur_item(self) :
+      commentaire=""
+      if self.definition.validators :
+         commentaire=self.definition.validators.info_erreur_item()
+      return commentaire
+      
+  def aide(self) :
+      commentaire=""
+      if self.definition.validators :
+         commentaire=self.definition.validators.aide()
+      return commentaire
+
+  def info_erreur_liste(self) :
+      commentaire=""
+      if self.definition.validators :
+         commentaire=self.definition.validators.info_erreur_liste()
+      return commentaire
+
+  def IsInIntervalle(self,valeur):
+      """ 
+          Retourne 1 si la valeur est dans l'intervalle permis par
+          l'objet représenté par l'item.
+      """
+      return self.valide_item(valeur)
+
+  def isvalid(self):
+    valide=self.object.isvalid()
+    return valide
+
+  #--------------------------------------------------
+  #
+  # Autres ...
+  #
+  #---------------------------------------------------
+  # SetText         a priori inutilisee --> commentee
+  # GetIconName
+  # GetText
+  # getval     a  priori inutilisee --> commentee
+  # set_valeur_co
+  # get_sd_avant_du_bon_type
+  # verif        a  priori inutilisee --> commentee
+  # delete_valeur_co
+
+  #def SetText(self, text):
+  #  try:
+  #    value = eval(text)
+  #    self.object.setval(value)
+  #  except:
+  #    pass
+
+  def GetIconName(self):
+    if self.isvalid():
+      return "ast-green-ball"
+    elif self.object.isoblig():
+      return "ast-red-ball"
+    else:
+      return "ast-yel-ball"
+
+  def GetText(self):
+    """
+    Classe SIMPTreeItem
+    Retourne le texte à afficher dans l'arbre représentant la valeur de l'objet
+    pointé par self 
+    """
+    text= self.object.GetText()
+    return text
+    
+  #def getval(self):
+  #    return self.object.getval()
+
+  def set_valeur_co(self,nom_co):
+      """
+      Affecte au MCS pointé par self l'objet de type CO et de nom nom_co
+      """
+      ret = self.object.set_valeur_co(nom_co)
+      #print "set_valeur_co",ret
+      return ret
+      
+  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
+      """
+      a=self.object.etape.parent.get_sd_avant_du_bon_type(self.object.etape,self.object.definition.type)
+      return a
+
+  def get_sd_avant_du_bon_type_pour_type_de_base(self):
+      a=self.object.jdc.get_sd_avant_du_bon_type_pour_type_de_base(self.object.etape,"LASSD")
+      return a
+
+
+
+  #def verif(self):
+  #    pass
+
+  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)
+
+  #-----------------------------------------------
+  #
+  # Methodes liees au type de l objet attendu
+  #
+  #-----------------------------------------------
+  # wait_co 
+  # wait_geom
+  # wait_complex
+  # wait_reel
+  # wait_shell
+  # wait_assd
+  # GetType
+
+  def wait_co(self):
+      """
+      Méthode booléenne qui retourne 1 si l'objet pointé par self
+      attend un objet de type ASSD qui n'existe pas encore (type CO()),
+      0 sinon
+      """
+      return self.object.wait_co()
+
+  def wait_geom(self):
+      """
+      Méthode booléenne qui retourne 1 si l'objet pointé par self
+      attend un objet GEOM, 0 sinon
+      """
+      return self.object.wait_geom()
+    
+  def wait_complex(self):
+      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
+      attend un complexe, 0 sinon """
+      if 'C' in self.object.definition.type:
+          return 1
+      else:
+          return 0
+
+  def wait_reel(self):
+      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
+      attend un réel, 0 sinon """
+      if 'R' in self.object.definition.type:
+          return 1
+      else:
+          return 0
+        
+  def wait_shell(self):
+      """ Méthode booléenne qui retourne 1 si l'objet pointé par self
+      attend un shell, 0 sinon """
+      if 'shell' in self.object.definition.type:
+          return 1
+      else:
+          return 0
+
+  def wait_assd(self):
+      """Méthode booléenne qui retourne 1 si l'objet pointé par self
+      attend un objet de type ASSD ou dérivé, 0 sinon """
+      return self.object.wait_assd()
+    
+  def wait_assd_or_type_base(self) :
+      boo=0
+      if len(self.object.definition.type) > 1 :
+         if self.wait_reel() :
+            boo = 1
+         if 'I' in self.object.definition.type :
+            boo = 1
+      return boo
+
+   
+  def GetType(self):
+      """ 
+          Retourne le type de valeur attendu par l'objet représenté par l'item.
+      """
+      return self.object.get_type()
+
+  #-----------------------------------------------------
+  #
+  # Methodes liees  a l evaluation de la valeur saisie
+  #
+  #-----------------------------------------------------
+  # eval_valeur
+  # eval_valeur_item
+  # is_CO
+  # traite_reel
+
+  def eval_valeur(self,valeur):
+      """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur de self :
+             - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
+             - retourne 'valeur' (chaîne de caractères) sinon
+      """
+      newvaleur=self.eval_val(valeur)
+      return newvaleur,1
+
+  def eval_valeur_BAK(self,valeur):
+      """ Lance l'interprétation de 'valeur' (chaîne de caractères) comme valeur
+      de l'objet pointé par self :
+        - retourne l'objet associé si on a pu interpréter (entier, réel, ASSD,...)
+        - retourne 'valeur' (chaîne de caractères) sinon
+        - retourne None en cas d invalidite
+        - retourne invalide si 1 des objets du tuple l est
+      """
+      validite=1
+      if type(valeur) in (types.ListType,types.TupleType) :
+         valeurretour=[]
+         for item in valeur :
+             newvaleur,validiteitem=self.eval_valeur_item(item)
+             valeurretour.append(newvaleur)
+             if validiteitem == 0:
+                validite=0
+      else :
+         valeurretour,validite= self.eval_valeur_item(valeur)
+      if validite == 0 :
+         valeurretour = None
+      return valeurretour,validite
+
+  def eval_valeur_item(self,valeur):
+      """ Lance l'interprétation de 'valeur' qui doit ne pas etre un tuple 
+          - va retourner la valeur de retour et la validite
+            selon le type de l objet attendu
+          - traite les reels et les parametres 
+      """ 
+      #print "eval_valeur_item",valeur
+      if valeur==None or valeur == "" :
+         return None,0
+      validite=1
+      if self.wait_reel():
+             valeurinter = self.traite_reel(valeur)
+             if valeurinter != None :
+                valeurretour,validite= self.object.eval_valeur(valeurinter)
+             else:
+                valeurretour,validite= self.object.eval_valeur(valeur)
+      elif self.wait_geom():
+             valeurretour,validite = valeur,1
+      else :
+             valeurretour,validite= self.object.eval_valeur(valeur)
+      #print "eval_valeur_item",valeurretour,validite
+
+      if validite == 0:
+         if type(valeur) == types.StringType and self.object.wait_TXM():
+            essai_valeur="'" + valeur + "'"
+            valeurretour,validite= self.object.eval_valeur(essai_valeur)
+
+      if hasattr(valeurretour,'__class__'):
+         #if valeurretour.__class__.__name__ in ('PARAMETRE','PARAMETRE_EVAL'):
+         if valeurretour.__class__.__name__ in ('PARAMETRE',):
+            validite=1
+
+      #if self.wait_co():
+         # CCAR : il ne faut pas essayer de creer un concept
+         # il faut simplement en chercher un existant ce qui a du etre fait par self.object.eval_valeur(valeur)
+         #try:
+            #valeurretour=Accas.CO(valeur)
+         #except:
+            #valeurretour=None
+            #validite=0
+      # on est dans le cas où on a évalué et où on n'aurait pas du
+      if self.object.wait_TXM() :
+          if type(valeurretour) != types.StringType:
+             valeurretour=str(valeur)
+             validite=1
+      return valeurretour,validite
+      
+  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.InstanceType:return 0
+      if valeur.__class__.__name__ == 'CO':return 1
+      return 0
+
+  def is_param(self,valeur) :
+      for param in self.jdc.params:
+          if (repr(param) == valeur):
+             return 1
+      return 0
+
+  def traite_reel(self,valeur):
+      """
+      Cette fonction a pour but de rajouter le '.' en fin de chaîne pour un réel
+      ou de détecter si on fait référence à un concept produit par DEFI_VALEUR
+      ou un EVAL ...
+      """
+      valeur = string.strip(valeur)
+      liste_reels = self.get_sd_avant_du_bon_type()
+      if valeur in liste_reels:
+          return valeur
+      if len(valeur) >= 3 :
+          if valeur[0:4] == 'EVAL' :
+              # on a trouvé un EVAL --> on retourne directement la valeur
+              return valeur
+      if string.find(valeur,'.') == -1 :
+          # aucun '.' n'a été trouvé dans valeur --> on en rajoute un à la fin
+          if (self.is_param(valeur)):
+              return valeur
+          else:
+              if string.find(valeur,'e') != -1:
+                 # Notation scientifique ?
+                 try :
+                    r=eval(valeur)
+                    return valeur
+                 except :
+                    return None
+              else :
+                 return valeur+'.'
+      else:
+          return valeur
+        
+
+import Accas
+treeitem = SIMPTreeItem
+objet = Accas.MCSIMP
+
diff --git a/Interface/configuration.py b/Interface/configuration.py
new file mode 100644 (file)
index 0000000..8d9e7a6
--- /dev/null
@@ -0,0 +1,302 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+    Ce module sert pour charger les paramètres de configuration d'EFICAS
+"""
+# Modules Python
+import os,sys,string,types
+import traceback
+
+# Modules Eficas
+#from widgets import showinfo,showerror,askretrycancel # CS_pbruno todo
+import utils
+
+class CONFIGbase:
+
+  #-----------------------------------
+  def __init__(self,appli):
+  #-----------------------------------
+
+  # Classe de base permettant de lire, afficher
+  # et sauvegarder les fichiers utilisateurs editeur.ini
+  # et style.py
+  # Classe Mere de : class CONFIG(CONFIGbase)
+  #                  class CONFIGStyle(CONFIGbase):
+
+      self.appli = appli  
+      if self.appli:
+         self.parent=appli.top
+      else:
+         self.parent=None
+      self.rep_user = utils.get_rep_user()
+      self.lecture_fichier_ini_standard()
+      self.lecture_fichier_ini_utilisateur()
+      self.init_liste_param()
+  
+  #--------------------------------------
+  def lecture_fichier_ini_standard(self):
+  #--------------------------------------
+  # Verifie l'existence du fichier "standard"
+  # appelle la lecture de ce fichier
+      if not os.path.isfile(self.fic_ini):
+          print self.fic_ini
+          showerror("Erreur","Pas de fichier de configuration" + self.fic_ini+"\n")
+          print "Erreur à la lecture du fichier de configuration : %s" % self.fic_ini
+          sys.exit(0)
+      self.lecture_fichier(self.fic_ini)
+
+  #-----------------------------
+  def lecture_fichier(self,fic):
+  #------------------------------
+  # lit les paramètres du fichier eficas.ini ou style.py
+  # les transforme en attribut de l 'objet  
+  # utilisation du dictionnaire local pour récuperer style
+      txt = utils.read_file(fic)
+      from styles import style
+      d=locals()
+      try:
+         exec txt in d
+      except:
+         l=traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2])
+         showerror("Erreur","Une erreur s'est produite lors de la lecture du fichier : " + fic + "\n")
+         print "Erreur à la lecture du fichier de configuration : %s" % fic
+         sys.exit()
+
+      for k in d.keys() :
+          if  k in self.labels.keys()  :
+             setattr(self,k,d[k])
+      
+      for k in d['style'].__dict__.keys() :
+          setattr(self,k,d['style'].__dict__[k])
+   
+  #--------------------------------------
+  def lecture_fichier_ini_utilisateur(self):
+  #--------------------------------------
+  # Surcharge les paramètres standards par les paramètres utilisateur s'ils existent
+      self.fic_ini_utilisateur = os.path.join(self.rep_user,self.fichier)
+      if not os.path.isfile(self.fic_ini_utilisateur):
+          return
+      self.lecture_fichier(self.fic_ini_utilisateur)
+
+
+  #--------------------------------------
+  def affichage_fichier_ini(self):
+  #--------------------------------------
+      """
+      Affichage des valeurs des paramètres relus par Eficas
+      """
+      import widgets
+      result = widgets.Formulaire(self.parent,
+                                  obj_pere = self,
+                                  titre = self.titre,
+                                  texte = self.texte_ini,
+                                  items = self.l_param,
+                                  mode='display',
+                                  commande=('Modifier',self.commande))
+      if result.resultat :
+          #print 'on sauvegarde les nouveaux paramètres :',result.resultat
+          self.save_param_ini(result.resultat)
+
+  #--------------------------------------
+  def save_param_ini(self,dico):
+  #--------------------------------------
+  # sauvegarde
+  # les nouveaux paramètres dans le fichier de configuration utilisateur
+  #
+      f=open(self.fic_ini_utilisateur,'w+')
+      for k,v in dico.items():
+         if self.types[k] in ('mot2','mot3','mot4'): 
+            v1=v[1:-1]
+            val=v1.split(",")
+            p = "(" 
+            listeval=""
+            for valeur in val:
+              listeval = listeval+ p + str(valeur) 
+              p=" , "
+            listeval = listeval + ")"
+            f.write(str(self.pref)+str(k) + '=' + str(listeval) + '\n') 
+         elif k == 'catalogues' :
+            f.write(k + '\t=\t' + str(v) + '\n')
+         else:
+            f.write(str(self.pref)+str(k) + '\t=\t"' + str(v) + '"\n')
+      f.close()
+      self.lecture_fichier_ini_utilisateur()
+
+  #-------------------------------------------
+  def creation_fichier_ini_si_possible(self):
+  #-------------------------------------------
+      return self.creation_fichier_ini(mode='ignorer_annuler')
+
+  #--------------------------------------------------------
+  def creation_fichier_ini(self,mode='considerer_annuler'):
+  #---------------------------------------------------------
+  # Récupération des valeurs des paramétres requis pour la création du fichier
+  # eficas.ini
+  #
+      import widgets
+      items = self.l_param
+      result = widgets.Formulaire(self.parent,
+                                  obj_pere = self,
+                                  titre = "Saisie des données indispensables à la configuration d'EFICAS",
+                                  texte = self.texte,
+                                  items = items,
+                                  mode='query')
+      if not result.resultat :
+          if mode == 'considerer_annuler':
+             test = askretrycancel("Erreur","Données incorrectes !")
+             if not test:
+                 # XXX On sort d'EFICAS, je suppose
+                 self.appli.exitEFICAS()
+             else:
+                 self.creation_fichier_ini()
+          else:
+              return None
+      else :
+          self.save_param_ini(result.resultat)
+          return result.resultat
+
+  #--------------------------
+  def init_liste_param (self):
+  #--------------------------
+  # construit self.l_param 
+  # a partir de self.labels et des attributs 
+  # de l objet (mis a jour lors de la lecture du fichier)
+  # l_param est une liste de tuples où chaque tuple est de la forme :
+  #           (label,nature,nom_var,defaut)
+
+      self.l_param=[]
+      for k in self.labels.keys()  :
+          if hasattr(self,k) :
+             if k in self.YesNo.keys():
+                self.l_param.append((self.labels[k],self.types[k],k,self.__dict__[k],
+                                     self.YesNo[k][0],self.YesNo[k][1]))
+             else :
+                self.l_param.append((self.labels[k],self.types[k],k,self.__dict__[k]))
+      self.l_param = tuple(self.l_param)
+
+
+class CONFIG(CONFIGbase):
+  def __init__(self,appli,rep_ini):
+      self.texte = "EFICAS a besoin de certains renseignements pour se configurer\n"+\
+              "Veuillez remplir TOUS les champs ci-dessous et appuyer sur 'Valider'\n"+\
+              "Si vous annulez, EFICAS ne se lancera pas !!"
+      self.fichier="editeur.ini"
+      self.rep_ini = rep_ini
+      self.fic_ini = os.path.join(self.rep_ini,self.fichier)
+      self.titre = "Paramètres nécessaires à la configuration d'EFICAS"
+      self.texte_ini = "Voici les paramètres que requiert Eficas"
+      self.commande = self.creation_fichier_ini_si_possible
+      self.pref=""
+      self.labels={"initialdir"    : "Répertoire initial pour Open/Save des fichiers",
+                   "rep_travail"   : "Répertoire de travail",
+                   "rep_mat"       : "Répertoire materiaux",
+                   "path_doc"      : "Chemin d'accès à la doc Aster",
+                   "exec_acrobat"  : "Ligne de commande Acrobat Reader",
+                   "catalogues"    : "Versions du code ",
+                   "isdeveloppeur" : "Niveau de message ",
+                   "path_cata_dev" : "Chemin d'accès aux catalogues développeurs"}
+                   
+      self.types ={"initialdir":"rep", "rep_travail":"rep","rep_mat":"rep",
+                   "path_doc": "rep","exec_acrobat":"file","exec_acrobat":"file",
+                   "catalogues" :"cata","isdeveloppeur":"YesNo","path_cata_dev":"rep"}
+
+      self.YesNo={}
+      self.YesNo['isdeveloppeur']=('Deboggage','Utilisation')
+
+      # Valeurs par defaut
+      self.rep_user = utils.get_rep_user()
+      self.initialdir=self.rep_user
+      self.rep_travail=os.path.join(self.rep_user,'uaster','tmp_eficas')
+      self.rep_mat='/aster/v7/materiau'
+      self.path_doc=self.rep_user
+      self.exec_acrobat=self.rep_user
+      self.catalogues= os.path.join(self.rep_ini,'..','Cata/cata.py')
+      self.isdeveloppeur='NON'
+      self.path_cata_dev=os.path.join(self.rep_user,'cata')
+
+      CONFIGbase.__init__ (self,appli)
+
+
+class CONFIGStyle(CONFIGbase):
+  def __init__(self,appli,rep_ini):
+      self.texte = "Pour prendre en compte les modifications \n"+\
+                   "     RELANCER EFICAS"
+      self.fichier="style.py"
+      self.rep_ini = rep_ini
+      self.fic_ini = os.path.join(self.rep_ini,self.fichier)
+      self.titre = "Paramètres d affichage"
+      self.texte_ini = "Voici les paramètres configurables :  "
+      self.commande = self.creation_fichier_ini_si_possible
+      self.pref="style."
+      self.labels={"background":"couleur du fonds", 
+                   "foreground":"couleur de la police standard" ,
+                   "standard":" police et taille standard",
+                   "standard_italique":"police utilisée pour l'arbre ",
+                   "standard_gras_souligne":"police utilisée pour le gras souligné",
+                   "canvas_italique":"police italique",
+                   "standard_gras":"gras",
+                   #"canvas":"police",
+                   #"canvas_gras":"police gras",
+                   #"canvas_gras_italique":"police gras italique",
+                   #"standard12":"police 12",
+                   #"standard12_gras":"police 12 gras",
+                   #"standard12_gras_italique":"police 12 gras italique",
+                   #"standardcourier10":"courrier "
+                   "statusfont":"police utilisée dans la status Bar",
+                  }
+      self.types ={"background":"mot", 
+                   "foreground":"mot" ,
+                   "standard":"mot2",
+                   "standard_italique":"mot3",
+                   "standard_gras":"mot3",
+                   "standard_gras_souligne":"mot4",
+                   "canvas":"mot2",
+                   "canvas_italique":"mot3",
+                   "canvas_gras":"mot3",
+                   "canvas_gras_italique":"mot4",
+                   "standard12":"mot2",
+                   "standard12_gras":"mot3",
+                   "standard12_gras_italique":"mot4",
+                   "statusfont":"mot2",
+                   "standardcourier10":"mot2"}
+      self.YesNo={}
+      self.l_param=[]
+      CONFIGbase.__init__ (self,appli)
+
+  def affichage_style_ini(self):
+      self.affichage_fichier_ini()
+
+def make_config(appli,rep):
+    return CONFIG(appli,rep)
+
+def make_config_style(appli,rep):
+    return CONFIGStyle(appli,rep)
+
+
+
+"""
+lecture des paramètres standards et utilisateur
+"""
+import prefs
+appli = None
+CONFIGURATION = make_config( appli, prefs.REPINI )
+CONFIGStyle   = make_config_style( appli, prefs.REPINI )
diff --git a/Interface/editor.py b/Interface/editor.py
new file mode 100644 (file)
index 0000000..2e9c7e6
--- /dev/null
@@ -0,0 +1,599 @@
+# -*- coding: utf-8 -*-
+
+# Modules Python
+import types,sys,os
+import traceback
+
+# Modules Eficas
+from qt import *
+import browser
+
+import readercata
+import session
+import comploader
+import convert,generator
+import Objecttreeitem
+import prefs
+import configuration
+import panels
+
+VERSION_EFICAS  = "EFICAS v1.11"
+VERSION_CODE    = session.d_env.cata
+##if session.d_env.has_attr('cata'):
+##    VERSION_CODE = session.d_env.cata
+##else:
+##    VERSION_CODE = 'v8.2'
+
+
+        
+
+class JDCEditor(QSplitter):
+    """
+       Editeur de jdc
+    """
+    def __init__(self,fn,parent=None, editor = None):          
+        QSplitter.__init__(self, parent,'')
+        
+        # CS_pbruno compatiblity begin
+        self.top  = None
+        self.code = prefs.code
+        self.version_code = VERSION_CODE
+        self.titre=VERSION_EFICAS + ' pour '+ self.code
+        self.dict_reels={}
+        self.liste_simp_reel=[]
+        #format=self.format_fichier.get() CS_pbruno gestion python 
+        self.format_fichier = 'python'
+        self.CONFIGURATION = configuration.CONFIGURATION
+        self.CONFIGStyle   = configuration.CONFIGStyle
+        #self.appli = self
+        self.sb = qApp.mainWidget().statusBar()
+        # CS_pbruno compatiblity end
+      
+        self.parent         = parent
+        self.vm             = parent    #viewManager
+        self.fileName       = fn
+        self.fileInfo       = None
+        self.lastModified   = 0
+        self.jdc            = None
+        
+        self.fichier=None
+        self.panel_courant=None    
+        self.parent.node_selected = None
+        self.modified   = False
+        self.isReadOnly = False
+        ##      self.nom_jdc=fn
+        
+        if not hasattr( readercata, 'reader' ):
+            readercata.reader = readercata.READERCATA( self, self )
+        self.readercata = readercata.reader
+        
+        
+        ###################################################
+        if self.fileName is not None:
+            self.fileInfo = QFileInfo(self.fileName)
+            self.fileInfo.setCaching(0)
+            if editor is None:
+                self.readFile(self.fileName)                
+            else:
+                # clone the given editor
+##                self.setDocument(editor.document())
+##                self.breaks = editor.breaks
+##                self.bookmarks = editor.bookmarks
+##                self.syntaxerrors = editor.syntaxerrors
+                self.top            = editor.top
+                self.code           = editor.code
+                self.version_code   = editor.version_code
+                self.titre          = editor.titre
+                self.dict_reels     = editor.dict_reels
+                self.liste_simp_reel= editor.liste_simp_reel                
+                self.format_fichier = editor.format_fichier
+                self.CONFIGURATION  = editor.CONFIGURATION
+                self.CONFIGStyle    = editor.CONFIGStyle
+                self.jdc            = editor.jdc
+                
+                self.lastModified = self.fileInfo.lastModified()                        
+        elif editor is not None:
+##            self.setDocument(editor.document())
+            self.jdc = editor.jdc
+        else: #nouveau jdc
+            self.jdc = self._newJDC()
+            
+                
+        
+        
+        #------- config widget --------------
+        comploader.charger_composants()
+                
+        if self.jdc:
+            jdc_item=Objecttreeitem.make_objecttreeitem( self, "nom", self.jdc )
+            self.tree = browser.JDCTree( jdc_item, self )
+            self.connect(self.tree,SIGNAL('selectionChanged(QListViewItem *)'),self.updatePanel)
+      
+        sh = self.sizeHint()
+        if sh.height() < 300:
+            sh.setHeight(300)
+        self.resize(sh)
+            
+        # Make sure tabbing through a QWorkspace works.
+        self.setFocusPolicy(QWidget.StrongFocus)
+        self._updateReadOnly(1)
+        
+        # Set the editors size if it is too big for the parent.
+        if parent is not None:
+            req = self.size()
+            bnd = req.boundedTo(parent.size())
+        
+            if bnd.width() < req.width() or bnd.height() < req.height():
+                self.resize(bnd)
+        
+        self.panel = QWidget(self)        
+        self.connect(self, SIGNAL('modificationChanged(bool)'), self.handleModificationChanged)
+                
+        
+    def _updateReadOnly(self, bForce=1):
+        """
+        Private method to update the readOnly information for this editor. 
+        
+        If bForce is True, then updates everything regardless if
+        the attributes have actually changed, such as during
+        initialization time.  A signal is emitted after the
+        caption change.
+
+        @param bForce 1 to force change, 0 to only update and emit
+                signal if there was an attribute change.
+        """
+        if self.fileName is None:
+            return
+        readOnly = not QFileInfo(self.fileName).isWritable() and 1 or 0
+        if not bForce and (readOnly == self.isReadOnly):
+            return
+        cap = self.fileName
+        if readOnly:
+            cap = "%s (ro)" % unicode(cap)
+##        self.setReadOnly(readOnly)
+        self.isReadOnly = readOnly
+        self.setCaption(cap)
+        self.emit(PYSIGNAL('captionChanged'), (cap, self))
+        
+    def _newJDC( self ):        
+        """
+        Initialise un nouveau JDC vierge
+        """
+        CONTEXT.unset_current_step()        
+        jdc=self.readercata.cata[0].JdC( procedure="",
+                                         appli=self,
+                                         cata=self.readercata.cata,
+                                         cata_ord_dico=self.readercata.cata_ordonne_dico,
+                                         rep_mat=configuration.CONFIGURATION.rep_mat#self.CONFIGURATION.rep_mat
+                                        )                         
+        jdc.analyse()        
+        return jdc
+
+    def readFile(self, fn):
+        """
+        Public slot to read the text from a file.
+        
+        @param fn filename to read from (string or QString)
+        """        
+        fn = unicode(fn)        
+            
+        qApp.setOverrideCursor(Qt.waitCursor)
+                        
+        # ------------------------------------------------------------------------------------
+        #                         charge le JDC
+        # ------------------------------------------------------------------------------------      
+        
+        jdcName=os.path.basename(fn)
+        # Il faut convertir le contenu du fichier en fonction du format
+        if convert.plugins.has_key( self.format_fichier ):
+             # Le convertisseur existe on l'utilise
+             appli = self # CS_pbruno compatiblity parseur_python: self.appli.liste_simp_reel, self.appli.dict_reels
+             p=convert.plugins[self.format_fichier]()
+             p.readfile(fn)         
+             text=p.convert('exec',appli)
+             if not p.cr.estvide():
+                 raise ValueError(str(p.cr))
+        
+        CONTEXT.unset_current_step()
+        ##      # On se met dans le repertoire ou se trouve le fichier de commandes
+        ##      # pour trouver les eventuels fichiers include ou autres
+        ##      # localises a cote du fichier de commandes
+        ##      self.initialdir = os.path.dirname(os.path.abspath(file))
+        ##      os.chdir(self.initialdir)
+        jdc=self.readercata.cata[0].JdC(procedure=text,
+                                    appli=self,
+                                    cata=self.readercata.cata,
+                                    cata_ord_dico=self.readercata.cata_ordonne_dico,
+                                    nom=jdcName,
+                                    rep_mat=configuration.CONFIGURATION#self.CONFIGURATION.rep_mat
+                                   )
+        jdc.analyse()
+        txt= jdc.cr.get_mess_exception()
+        if txt:raise ValueError(txt)
+        self.jdc=jdc
+        self.jdc.appli = self
+        # ------------------------------------------------------------------------------------
+        #                         charge le JDC fin
+        # ------------------------------------------------------------------------------------
+##        self.setModified(0)
+        self.modified = False
+                        
+        qApp.restoreOverrideCursor()
+        
+        self.lastModified = self.fileInfo.lastModified()
+        
+        
+    def handleRenamed(self, fn):
+        """
+        Public slot to handle the editorRenamed signal.
+        
+        @param fn filename to be set for the editor (QString or string).
+        """
+        self.fileName = unicode(fn)
+        self.setCaption(self.fileName)
+        
+        if self.fileInfo is None:
+            self.fileInfo = QFileInfo(self.fileName)
+            self.fileInfo.setCaching(0)
+        
+        self.lastModified = self.fileInfo.lastModified()
+        self.vm.setEditorName(self, self.fileName)
+        self._updateReadOnly(1)        
+
+    def handleNewView(self):
+        """
+        Private slot to create a new view to an open document.
+        """
+        self.vm.newEditorView(self.fileName, self)#, self.isPythonFile)
+
+    def handleModificationChanged(self, m):
+        """
+        Private slot to handle the modificationChanged signal. 
+        
+        It emits the signal modificationStatusChanged with parameters
+        m and self.
+        
+        @param m modification status
+        """
+        if not m and self.fileInfo is not None:
+            self.lastModified = self.fileInfo.lastModified()
+        self.emit(PYSIGNAL('modificationStatusChanged'), (m, self))
+        
+    def hasSyntaxErrors(self):        
+        return False #CS_pbruno todo
+        
+    def closeIt(self):
+        """
+        Public method called by the viewmanager to finally get rid of us.
+        """
+##      print 'BUREAU closeSelectedJDC '
+##      if self.JDCDisplay_courant.modified == 'o' :
+##          message = "Voulez-vous sauvegarder le jeu de commandes "+self.JDC.nom+" courant ?"
+##          reponse = askyesno(title="Sauvegarde du jdc courant",
+##                             message=message)
+##          if reponse :
+##              test = self.saveJDC()
+##              if test == 0 :
+##                  self.appli.affiche_infos("Sauvegarde impossible")
+##                  return
+
+##      CONNECTOR.Disconnect(self.JDCDisplay_courant.jdc,"close",self.onClose,(self.JDCDisplay_courant,))
+##      self.JDCDisplay_courant.supprime()
+        self.jdc.supprime()
+##      self.liste_JDCDisplay.remove(self.JDCDisplay_courant)
+##      # Active le mecanisme de selection du notebook (selectJDC)
+##      self.nb.delete(self.nb.getcurselection())
+##
+##      try:
+##          index = self.nb.index(self.nb.getcurselection())
+##          self.JDCDisplay_courant = self.liste_JDCDisplay[index]
+##          self.JDC = self.JDCDisplay_courant.jdc
+##      except:
+##          self.JDC = None
+##          self.JDCDisplay_courant = None
+##          self.appli.toolbar.inactive_boutons()
+        self.close()
+    
+
+    def affiche_infos(self,message):        
+        self.sb.message(message,2000)
+
+    def updatePanel(self, jdcNode):
+        """
+        Appelé à chaque changement de noeud
+        """
+        self.parent.node_selected = jdcNode
+        if self.panel:
+            self.panel.close()
+            del self.panel
+            self.panel = None
+            
+        if jdcNode.item.isactif():
+            self.panel = jdcNode.getPanel()
+        else:
+            self.panel = panels.PanelInactif(self)
+            
+        if not self.panel:
+            self.panel = panels.NoPanel(self)
+        
+        self.panel.show()
+        
+    
+    
+    def init_modif(self):
+      """
+          Met l'attribut modified à 'o' : utilisé par Eficas pour savoir 
+          si un JDC doit être sauvegardé avant destruction ou non
+      """
+      self.modified = True
+      self.emit(PYSIGNAL('modificationStatusChanged'), (True, self))
+    
+    def stop_modif(self):
+      """
+          Met l'attribut modified à 'n' : utilisé par Eficas pour savoir 
+          si un JDC doit être sauvegardé avant destruction ou non
+      """      
+      self.modified = False
+      self.emit(PYSIGNAL('modificationStatusChanged'), (False, self))
+    
+    
+    def cut(self):
+      """
+      Stocke dans Eficas.noeud_a_editer le noeud à couper
+      """
+      if not self.parent.node_selected.item.iscopiable():
+          showinfo("Copie impossible",
+                   "Cette version d'EFICAS ne permet que la copie d'objets de type 'Commande' ou mot-clé facteur")
+          return
+      self.parent.edit="couper"
+      self.parent.noeud_a_editer = self.parent.node_selected      
+    
+    def copy(self):
+      """
+      Stocke dans Eficas.noeud_a_editer le noeud à copier
+      """
+      if not self.parent.node_selected.item.iscopiable():
+          showinfo("Copie impossible",
+                   "La copie d'un tel objet n'est pas permise")
+          return
+      self.parent.edit="copier"
+      self.parent.noeud_a_editer = self.parent.node_selected
+    
+    def paste(self):
+      """
+      Lance la copie de l'objet placé dans self.parent.noeud_a_editer
+      Ne permet que la copie d'objets de type Commande ou MCF
+      """
+      try:
+         child=self.parent.noeud_a_editer.doPaste(self.parent.node_selected)
+      except:
+         traceback.print_exc()
+         showinfo("Action de coller impossible",
+                  "L'action de coller apres un tel objet n'est pas permise")
+         return
+    
+      if child == 0:
+          if self.message != '':
+             showerror("Copie refusée",self.message)
+             self.message = ''
+          self.affiche_infos("Copie refusée")
+          return
+    
+      # il faut déclarer le JDCDisplay_courant modifié
+      self.init_modif()
+      # suppression éventuelle du noeud sélectionné
+      # si possible on renomme l objet comme le noeud couper
+      if self.parent.edit == "couper":
+         #nom = self.parent.noeud_a_editer.item.object.sd.nom
+         item=self.parent.noeud_a_editer.item
+         self.parent.noeud_a_editer.delete()
+         child.item.update(item)
+         #test,mess = child.item.nomme_sd(nom)
+         child.select()
+      # on rend la copie à nouveau possible en libérant le flag edit
+      self.parent.edit="copier"
+          
+    #--------------------------------------------------------------------------------------      
+    def getFileName(self):
+      return self.fileName
+      
+    def writeFile(self, fn):
+        """
+        Public slot to write the text to a file.
+        
+        @param fn filename to write to (string or QString)
+        @return flag indicating success
+        """
+        fn = unicode(fn)
+        txt = self.get_text_JDC('python')
+
+        eol = '\n'        
+        if len(txt) >= len(eol):
+            if txt[-len(eol):] != eol:
+                txt += eol
+        else:
+            txt += eol        
+        try:
+            f = open(fn, 'wb')
+            f.write(txt)
+            f.close()
+            return 1
+        except IOError, why:
+            QMessageBox.critical(self, self.trUtf8('Save File'),
+                self.trUtf8('The file <b>%1</b> could not be saved.<br>Reason: %2')
+                    .arg(unicode(fn)).arg(str(why)))
+            return 0
+
+    def get_text_JDC(self,format):
+      if generator.plugins.has_key(format):
+         # Le generateur existe on l'utilise
+         g=generator.plugins[format]()
+         jdc_formate=g.gener(self.jdc,format='beautifie')
+         if not g.cr.estvide():
+            raise 'CS_pbruno error' #CS_pbruno todo
+##            self.appli.affiche_infos("Erreur à la generation")
+##            showerror("Erreur à la generation","EFICAS ne sait pas convertir ce JDC")
+##            return
+         else:
+            return jdc_formate
+      else:
+         raise 'CS_pbruno error' #CS_pbruno todo
+####         # Il n'existe pas c'est une erreur
+####         self.appli.affiche_infos("Format %s non reconnu" % format)
+####         showerror("Format %s non reconnu" % format,"EFICAS ne sait pas convertir le JDC en format %s "% format)
+####         return
+      
+      
+    def saveFile(self, saveas = 0, path = None):
+        """
+        Public slot to save the text to a file.
+        
+        @param saveas flag indicating a 'save as' action
+        @param path directory to save the file in (string or QString)
+        @return tuple of two values (boolean, string) giving a success indicator and
+            the name of the saved file
+        """        
+        self.modified = True #CS_pbruno test
+                
+        if not saveas and not self.modified:#self.isModified():
+            return (0, None)      # do nothing if text wasn't changed
+            
+        newName = None
+        if saveas or self.fileName is None:
+            if path is None and self.fileName is not None:
+                path = os.path.dirname(unicode(self.fileName))
+            selectedFilter = QString('')
+            fn = QFileDialog.getSaveFileName(path,
+                self.trUtf8("JDC (*.comm);;"
+                    "All Files (*)"), self, None,
+                self.trUtf8("Save File"), selectedFilter, 0)
+                
+            if not fn.isNull():
+                ext = QFileInfo(fn).extension()
+                if ext.isEmpty():
+                    ex = selectedFilter.section('(*',1,1).section(')',0,0)
+                    if not ex.isEmpty():
+                        fn.append(ex)
+                if QFileInfo(fn).exists():
+                    abort = QMessageBox.warning(self,
+                        self.trUtf8("Save File"),
+                        self.trUtf8("The file <b>%1</b> already exists.")
+                            .arg(fn),
+                        self.trUtf8("&Overwrite"),
+                        self.trUtf8("&Abort"), None, 1)
+                    if abort:
+                        return (0, None)
+                fn = unicode(QDir.convertSeparators(fn))
+                newName = fn
+            else:
+                return (0, None)
+        else:
+            fn = self.fileName
+        
+        if self.writeFile(fn):
+            self.fileName = fn
+            self.modified  = False                        
+##            self.setReadOnly(0)
+            self.setCaption(self.fileName)                
+            if self.fileInfo is None or saveas:
+                self.fileInfo = QFileInfo(self.fileName)
+                self.fileInfo.setCaching(0)
+                self.emit(PYSIGNAL('editorRenamed'), (self.fileName,))
+            self.lastModified = self.fileInfo.lastModified()
+            if newName is not None:
+                self.vm.addToRecentList(newName)
+            self.emit(PYSIGNAL('editorSaved'), (self.fileName,))
+            self.stop_modif()            
+            return (1, self.fileName)
+        else:
+            return (0, None)
+
+    def saveFileAs(self, path = None):
+        """
+        Public slot to save a file with a new name.
+        
+        @param path directory to save the file in (string or QString)
+        @return tuple of two values (boolean, string) giving a success indicator and
+            the name of the saved file
+        """
+        return self.saveFile(1, path)
+
+
+
+
+##    def cree_cataitem(self):
+##      """
+##          On récupère dans l'appli_composant readercata les variables
+##          qui servent par la suite pour la création des JDC
+##      """
+##      self.cataitem=self.appli.readercata.cataitem
+##      self.cata=self.appli.readercata.cata
+##      self.cata_ordonne_dico=self.appli.readercata.cata_ordonne_dico
+##      self.code=self.appli.readercata.code
+##      self.version_code=self.appli.readercata.version_code
+##      self.fic_cata=self.appli.readercata.fic_cata
+
+   
+   
+if __name__=='__main__': 
+
+##    from autre_analyse_cata import analyse_catalogue
+##    from Cata import cataSTA8
+##    cata=cataSTA8
+##    fic_cata="../../Aster/Cata/cataSTA8/cata.py"
+##    cata_ordonne ,list_simp_reel = analyse_catalogue(cata)
+    
+    
+
+    from qt import *
+    
+  
+    app = QApplication(sys.argv)
+    
+    d=JDCEditor('az.comm')
+    app.setMainWidget(d)    
+    app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+    d.show()
+            
+    res = app.exec_loop()
+    sys.exit(res)
+
+    
+    
+    
+##    
+###                         charge le JDC
+##      # ------------------------------------------------------------------------------------      
+##      self.readercata=readercata.READERCATA(self,None)
+##      
+##      jdcName=os.path.basename(fn)
+##      # Il faut convertir le contenu du fichier en fonction du format
+##      if convert.plugins.has_key( self.format_fichier ):
+##         # Le convertisseur existe on l'utilise
+##         appli = self # CS_pbruno      parseur_python : self.appli.liste_simp_reel self.appli.dict_reels
+##         p=convert.plugins[self.format_fichier]()
+##         p.readfile(fn)         
+##         text=p.convert('exec',appli)
+##         if not p.cr.estvide():
+##             raise ValueError(str(p.cr))
+##
+##      CONTEXT.unset_current_step()
+####      # On se met dans le repertoire ou se trouve le fichier de commandes
+####      # pour trouver les eventuels fichiers include ou autres
+####      # localises a cote du fichier de commandes
+####      self.initialdir = os.path.dirname(os.path.abspath(file))
+####      os.chdir(self.initialdir)      
+##      
+##      jdc=self.readercata.cata[0].JdC(procedure=text,
+##                                    appli=self,
+##                                    cata=self.readercata.cata,
+##                                    cata_ord_dico=self.readercata.cata_ordonne_dico,
+##                                    nom=jdcName,
+##                                    rep_mat=configuration.CONFIGURATION#self.CONFIGURATION.rep_mat
+##                                   )
+##      jdc.analyse()
+##      txt= jdc.cr.get_mess_exception()
+##      if txt:raise ValueError(txt)
+##      # ------------------------------------------------------------------------------------
+##      #                         charge le JDC fin
+##      # ------------------------------------------------------------------------------------    
diff --git a/Interface/eficas.py b/Interface/eficas.py
new file mode 100644 (file)
index 0000000..e6607f8
--- /dev/null
@@ -0,0 +1,111 @@
+class UserInterface(Eficas):    
+    """
+    Class implementing the main user interface.
+    
+    @signal appendStderr(string) emitted to write data to stderr logger
+    @signal appendStdout(string) emitted to write data to stdout logger
+    @signal preferencesChanged() emitted after the preferences were changed
+    """
+    def __init__(self):
+        """
+        Constructor
+        
+        @param loc locale to be used by the UI (string)
+        @param splash reference to the splashscreen (UI.SplashScreen.SplashScreen)
+        """
+        Eficas.__init__(self)
+
+##        self.loc = loc
+        
+##        self.layout = Preferences.getUILayout()
+##        self.passiveMode = Preferences.getDebugger("PassiveDbgEnabled")
+            
+##        self.setIcon(UI.PixmapCache.getPixmap("eric.png"))
+        
+        
+
+
+        
+
+##        # Generate and set our icon provider for QFileDialog
+##        self.iconProvider = IconProvider()
+##        QFileDialog.setIconProvider(self.iconProvider)
+        
+        # Generate the debug server object
+        dbs = DebugServer()
+        
+        
+        # Create main layout type 4 (floating windows)
+        
+        # Create the view manager depending on the configuration setting
+        #self.viewmanager = ViewManager.factory(self, self, dbs)
+        self.viewmanager = MyTabview(self, self, dbs) #MyTabview, MyWorkspace, Listspace
+        self.setCentralWidget(self.viewmanager)
+        
+        #self.viewmanager.mynewEditorView()
+
+        
+        
+##        # Generate the redirection helpers
+##        self.stdout = Redirector(0)
+##        self.stderr = Redirector(1)
+        
+        # Generate the shortcuts configuration dialog
+##        self.shortcutsDialog = ShortcutsDialog(self, 'Shortcuts')
+
+            
+        # now setup the connections
+##        splash.message(self.trUtf8("Setting up connections..."))
+
+        
+                     
+
+                     
+        self.connect(self,PYSIGNAL('preferencesChanged'),
+                     self.viewmanager.handlePreferencesChanged)
+                     
+        
+        self.connect(self.viewmanager,PYSIGNAL('lastEditorClosed'),
+                     self.handleLastEditorClosed)
+        self.connect(self.viewmanager,PYSIGNAL('editorOpened'),
+                     self.handleEditorOpened)
+                     
+        
+        
+        # Initialize the actions, menues, toolbar and statusbar
+####        splash.message(self.trUtf8("Initializing Actions..."))
+##        self.initActions()
+####        splash.message(self.trUtf8("Initializing Menus..."))
+##        self.initMenus()
+####        splash.message(self.trUtf8("Initializing Toolbars..."))
+##        self.initToolbars()
+####        splash.message(self.trUtf8("Initializing Statusbar..."))
+##        self.initStatusbar()
+
+        # Initialise the instance variables.
+        self.currentProg = None
+        self.isProg = 0
+        self.utEditorOpen = 0
+        self.utProjectOpen = 0
+        
+        self.inDragDrop = 0
+        self.setAcceptDrops(1)
+
+
+        
+    def handleLastEditorClosed(self):
+        """
+        Public slot to handle the lastEditorClosed signal.
+        """
+        pass
+        
+    def handleEditorOpened(self, fn):
+        """
+        Public slot to handle the editorOpened signal.
+        
+        @param fn filename of the opened editor (string)
+        """
+        pass
+        
+    def fileOpen(self, prog=None):
+        self.viewmanager.handleOpen(prog)
diff --git a/Interface/fontes.py b/Interface/fontes.py
new file mode 100644 (file)
index 0000000..8e15892
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+standard = ("Times",10)
+standard_italique = ("Times",10,'italic')
+standard_gras = ("Times",10,'bold')
+standard_gras_souligne = ("Times",10,'bold','underline')
+
+canvas = ('times',8)
+canvas_italique = ('times',8,'italic')
+canvas_gras = ("Times",8,'bold')
+canvas_gras_italique = ("Times",10,'bold','italic')
+
+standard12 = ("Times",12)
+standard12_gras = ("Times",12,'bold')
+standard12_gras_italique = ( "times",12,'bold','italic')
+
+standardcourier10 = ("Courier",10)
+
diff --git a/Interface/icons.py b/Interface/icons.py
new file mode 100644 (file)
index 0000000..7e2bd30
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+
+
+from qt import QPixmap
+
+class PixmapCache:
+    """
+    Class implementing a pixmap cache for icons.
+    """
+    def __init__(self):
+        """
+        Constructor
+        """
+        self.pixmapCache = {}
+
+    def getPixmap(self, key):
+        """
+        Public method to retrieve a pixmap.
+        
+        @param key name of the wanted pixmap (string)
+        @return the requested pixmap (QPixmap)
+        """
+        try:
+            return self.pixmapCache[key]
+        except KeyError:
+            self.pixmapCache[key] = QPixmap.fromMimeSource(key)
+            return self.pixmapCache[key]
+            
+pixCache = PixmapCache()
+
+def getPixmap(key, cache = pixCache):
+    """
+    Module function to retrieve a pixmap.
+    
+    @param key name of the wanted pixmap (string)
+    @return the requested pixmap (QPixmap)
+    """
+    return cache.getPixmap(key)
+    
+    
+
+from qt import QMimeSourceFactory
+
+def initializeMimeSourceFactory():
+    """
+    Function to initialize the default mime source factory.
+    
+    @param ericDir directory name of the eric installation
+    """
+    defaultFactory = QMimeSourceFactory.defaultFactory()
+    #defaultFactory.addFilePath("/local00/dev/src/EficasV1/Editeur/icons") #CS_pbruno todo (config)
+    defaultFactory.addFilePath("../Editeur/icons") #CS_pbruno todo (config)
+    
+##initializeMimeSourceFactory()        
diff --git a/Interface/import_code.py b/Interface/import_code.py
new file mode 100644 (file)
index 0000000..942c6b4
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+    Ce module réalise toutes les mises à jour du chemin pour 
+    les imports de modules Python
+"""
+import sys
+import prefs
+# Ce chemin permet d'importer les modules Noyau et Validation
+# représentant le code utilisé (si fourni)
+if prefs.CODE_PATH:
+   sys.path[:0]=[prefs.CODE_PATH]
+   import Noyau,Validation
+   del sys.path[0]
+
+# Ensuite on utilise les packages de l'intallation
+sys.path[:0]=[prefs.INSTALLDIR]
+import Accas
diff --git a/Interface/macrodisplay.py b/Interface/macrodisplay.py
new file mode 100644 (file)
index 0000000..9e3e671
--- /dev/null
@@ -0,0 +1,165 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+   Ce module contient la classe MacroDisplay qui realise l'affichage 
+   des sous commandes d'une macro sous forme d'arbre
+"""
+# Modules Python
+import types,sys
+##import Tkinter,Pmw
+
+# Modules EFICAS
+##import images
+##import tooltip
+import Objecttreeitem
+import compojdc
+##import treewidget
+##from widgets import Fenetre
+from Ihm import CONNECTOR
+
+##class MACRO2TreeItem(compojdc.JDCTreeItem):
+##      pass
+##
+##class MacroDisplay:
+##  def __init__(self,appli,macroitem,nom_jdc):
+##    self.fenetre = Tkinter.Toplevel()
+##    self.fenetre.configure(width = 800,height=500)
+##    self.fenetre.protocol("WM_DELETE_WINDOW", self.quit)
+##    self.fenetre.title("Visualisation Macro_Etape")
+##    self.macroitem=macroitem
+##    self.jdc=macroitem.object.jdc_aux
+##    self.nom_jdc=nom_jdc
+##    self.appli=appli
+##    self.barre=Tkinter.Frame(self.fenetre,relief="ridge",bd=2)
+##    self.barre.pack(expand=0,fill=Tkinter.X)
+##    if self.macroitem.object.fichier_text is not None:
+##      b=Tkinter.Button(self.barre,image=images.get_image("Zoom24"),command=self.visufile)
+##      b.pack(side='left')
+##      tp=tooltip.TOOLTIP(b,"View file")
+##    self.mainPart=Pmw.ScrolledCanvas(self.fenetre,
+##                                     hull_width=600,
+##                                     hull_height=500,
+##                                     borderframe=1)
+##    self.canvas=self.mainPart.component('canvas')
+##    Pmw.Color.changecolor(self.canvas,background='gray95')
+##    self.mainPart.pack(padx=10,pady=10,fill = 'both', expand = 1)
+##    self.item=MACRO2TreeItem(self.appli,nom_jdc,self.jdc)
+##    self.tree = treewidget.Tree(self.appli,self.item,self.mainPart,command=None,rmenu=self.make_rmenu)
+##    self.tree.draw()
+##    CONNECTOR.Connect(self.jdc,"close",self.onCloseView,())
+##
+##  def onCloseView(self):
+##    self.quit()
+##
+##  def visufile(self):
+##    Fenetre(self.appli,titre="Source du fichier inclus",texte=self.macroitem.object.fichier_text)
+##
+##  def make_rmenu(self,node,event):
+##      if hasattr(node.item,'rmenu_specs'):
+##         rmenu = Tkinter.Menu(self.canvas, tearoff=0)
+##         self.cree_menu(rmenu,node.item.rmenu_specs,node)
+##         rmenu.tk_popup(event.x_root,event.y_root)
+##
+##  def cree_menu(self,menu,itemlist,node):
+##      """
+##            Ajoute les items du tuple itemlist
+##            dans le menu menu
+##      """
+##      number_item=0
+##      radio=None
+##      for item in itemlist:
+##         number_item=number_item + 1
+##         if not item :
+##            menu.add_separator()
+##         else:
+##            label,method=item
+##            if type(method) == types.TupleType:
+##                 # On a un tuple => on cree une cascade
+##                 menu_cascade=Tkinter.Menu(menu)
+##                 menu.add_cascade(label=label,menu=menu_cascade)
+##                 self.cree_menu(menu_cascade,method,node)
+##            elif method[0] == '&':
+##                 # On a une chaine avec & en tete => on cree un radiobouton
+##                 try:
+##                    command=getattr(node.item,method[1:])
+##                    menu.add_radiobutton(label=label,command=lambda a=self.appli,c=command,n=node:c(a,n))
+##                    if radio == None:radio=number_item
+##                 except:pass
+##            else:
+##                 try:
+##                    command=getattr(node.item,method)
+##                    menu.add_command(label=label,command=lambda a=self.appli,c=command,n=node:c(a,n))
+##                 except:pass
+##      # Si au moins un radiobouton existe on invoke le premier
+##      if radio:menu.invoke(radio)
+##
+##  def quit(self):
+##    #print "quit",self
+##    self.tree.supprime()
+##    self.tree=None
+##    self.fenetre.destroy()
+##
+##  #def __del__(self):
+##  #  print "__del__",self
+##
+##def makeMacroDisplay(appli,macroitem,nom_item):
+##  return MacroDisplay(appli,macroitem,nom_item)
+##
+##import treeitemincanvas
+##
+##class TREEITEMINCANVAS(treeitemincanvas.TREEITEMINCANVAS):
+##   def __init__(self,object,nom="",parent=None,appli=None,sel=None,rmenu=None):
+##      #print "TREEITEMINCANVAS",object
+##      self.object=object
+##      self.nom=nom
+##      self.appli=appli
+##      self.parent=parent
+##
+##      self.item=MACRO2TreeItem(self.appli,self.nom,self.object)
+##      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):
+##            return
+##      self.tree=treewidget.Tree(self.appli,self.item,self.canvas,command=sel,rmenu=rmenu)
+##      self.tree.draw()
+##
+##import jdcdisplay
+##
+##class MACRODISPLAY(jdcdisplay.JDCDISPLAY):
+##   def __init__(self,jdc,nom_jdc,appli=None,parent=None):
+##      #print "MACRODISPLAY",jdc
+##      self.jdc=jdc
+##      self.nom_jdc=nom_jdc
+##      self.fichier=None
+##      self.panel_courant=None
+##      self.appli=appli
+##      self.parent=parent
+##      self.node_selected = None
+##      self.modified='n'
+##
+##      self.pane=Pmw.PanedWidget(self.parent,orient='horizontal')
+##      self.pane.add('treebrowser',min=0.4,size=0.5)
+##      self.pane.add('selected',min=0.4)
+##      self.pane.pack(expand=1,fill='both')
+##      self.tree=TREEITEMINCANVAS(jdc,nom_jdc,self.pane.pane('treebrowser'),
+##                 self.appli,self.select_node,self.make_rmenu)
+
diff --git a/Interface/myMain.ui b/Interface/myMain.ui
new file mode 100644 (file)
index 0000000..4ca8b22
--- /dev/null
@@ -0,0 +1,526 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Eficas</class>
+<widget class="QMainWindow">
+    <property name="name">
+        <cstring>Eficas</cstring>
+    </property>
+    <property name="enabled">
+        <bool>true</bool>
+    </property>
+    <property name="geometry">
+        <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>727</width>
+            <height>575</height>
+        </rect>
+    </property>
+    <property name="backgroundOrigin">
+        <enum>WidgetOrigin</enum>
+    </property>
+    <property name="font">
+        <font>
+        </font>
+    </property>
+    <property name="caption">
+        <string>Eficas V1.10 pour Aster avec Catalogue V8.3</string>
+    </property>
+</widget>
+<menubar>
+    <property name="name">
+        <cstring>MenuBar</cstring>
+    </property>
+    <property name="margin">
+        <number>2</number>
+    </property>
+    <item text="&amp;Fichier" name="Fichier">
+        <action name="fileNewAction"/>
+        <action name="fileNewViewAction"/>
+        <action name="fileOpenAction"/>
+        <action name="fileSaveAction"/>
+        <action name="fileSaveAsAction"/>
+        <action name="fileCloseAction"/>
+        <action name="fileCloseAllAction"/>
+        <separator/>
+        <separator/>
+        <action name="fileExitAction"/>
+    </item>
+    <item text="&amp;Edition" name="Edition">
+        <separator/>
+        <action name="editCutAction"/>
+        <action name="editCopyAction"/>
+        <action name="editPasteAction"/>
+        <separator/>
+        <action name="editFindAction"/>
+    </item>
+    <item text="JdC" name="JdC">
+    </item>
+    <item text="Options" name="Options">
+    </item>
+    <item text="&amp;Aide" name="Aide">
+    </item>
+    <item text="Traduction" name="Traduction">
+        <action name="traductionnew_itemAction"/>
+    </item>
+    <item text="Patrons" name="Patrons">
+    </item>
+</menubar>
+<toolbars>
+    <toolbar dock="2">
+        <property name="name">
+            <cstring>toolBar</cstring>
+        </property>
+        <property name="frameShape">
+            <enum>MenuBarPanel</enum>
+        </property>
+        <property name="horizontallyStretchable">
+            <bool>false</bool>
+        </property>
+        <property name="label">
+            <string>Tools</string>
+        </property>
+        <action name="fileNewAction"/>
+        <action name="fileSaveAction"/>
+        <action name="fileOpenAction"/>
+        <action name="fileSaveAsAction"/>
+        <action name="editCutAction"/>
+        <action name="editPasteAction"/>
+        <action name="editFindAction"/>
+        <action name="fileExitAction"/>
+    </toolbar>
+</toolbars>
+<actions>
+    <action>
+        <property name="name">
+            <cstring>fileNewAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image0</iconset>
+        </property>
+        <property name="text">
+            <string>New</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;New</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+N</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileOpenAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image1</iconset>
+        </property>
+        <property name="text">
+            <string>Open</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Open...</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+O</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileSaveAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image2</iconset>
+        </property>
+        <property name="text">
+            <string>Save</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Save</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+S</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileSaveAsAction</cstring>
+        </property>
+        <property name="text">
+            <string>Save As</string>
+        </property>
+        <property name="menuText">
+            <string>Save &amp;As...</string>
+        </property>
+        <property name="accel">
+            <string></string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileExitAction</cstring>
+        </property>
+        <property name="text">
+            <string>Exit</string>
+        </property>
+        <property name="menuText">
+            <string>E&amp;xit</string>
+        </property>
+        <property name="accel">
+            <string></string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>editUndoAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image3</iconset>
+        </property>
+        <property name="text">
+            <string>Undo</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Undo</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Z</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>editRedoAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image4</iconset>
+        </property>
+        <property name="text">
+            <string>Redo</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Redo</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+Y</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>editCutAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image5</iconset>
+        </property>
+        <property name="text">
+            <string>Cut</string>
+        </property>
+        <property name="menuText">
+            <string>Cu&amp;t</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+X</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>editCopyAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image6</iconset>
+        </property>
+        <property name="text">
+            <string>Copy</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Copy</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+C</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>editPasteAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image7</iconset>
+        </property>
+        <property name="text">
+            <string>Paste</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Paste</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+V</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>editFindAction</cstring>
+        </property>
+        <property name="iconSet">
+            <iconset>image8</iconset>
+        </property>
+        <property name="text">
+            <string>Find</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Find...</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+F</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>helpContentsAction</cstring>
+        </property>
+        <property name="text">
+            <string>Contents</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Contents...</string>
+        </property>
+        <property name="accel">
+            <string></string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>helpIndexAction</cstring>
+        </property>
+        <property name="text">
+            <string>Index</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;Index...</string>
+        </property>
+        <property name="accel">
+            <string></string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>helpAboutAction</cstring>
+        </property>
+        <property name="text">
+            <string>About</string>
+        </property>
+        <property name="menuText">
+            <string>&amp;About</string>
+        </property>
+        <property name="accel">
+            <string></string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>traductionnew_itemAction</cstring>
+        </property>
+        <property name="text">
+            <string>new item</string>
+        </property>
+        <property name="menuText">
+            <string>new item</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileSaveCloseAction</cstring>
+        </property>
+        <property name="text">
+            <string>Close</string>
+        </property>
+        <property name="menuText">
+            <string>Close</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileCloseAction</cstring>
+        </property>
+        <property name="text">
+            <string>Close</string>
+        </property>
+        <property name="menuText">
+            <string>Close</string>
+        </property>
+        <property name="accel">
+            <string>Ctrl+W</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileNewViewAction</cstring>
+        </property>
+        <property name="text">
+            <string>New view</string>
+        </property>
+    </action>
+    <action>
+        <property name="name">
+            <cstring>fileCloseAllAction</cstring>
+        </property>
+        <property name="text">
+            <string>Close All</string>
+        </property>
+        <property name="menuText">
+            <string>Close All</string>
+        </property>
+    </action>
+</actions>
+<images>
+    <image name="image0">
+        <data format="PNG" length="173">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007449444154388dedd5c109c0200c05d06fe936812c10b2ffdd85d25385b6a991480f053f081af0291210f828c5a9d9c4de96cd2b9ad9eb0000660e2fe0c2519839c4f70c4c446d5e6b3538cf928245e4b2f6f014acaa8fda1d4fc1a5741b22079f9d111d96ea8a912c78c10bee64e60719f57e9203ad452a04cc4e50200000000049454e44ae426082</data>
+    </image>
+    <image name="image1">
+        <data format="PNG" length="210">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000009949444154388ded94410e85200c445f89c7367f61bc775d2848a42860ffced9548bbe8e13043e1d928177f481a123dc2b34f6f47a3de2b865a8843f4001982a0b3d5f62c58300aa1ad70550449ab9d507a773a8a4ba4f92a2df333c64c63bebbd82e5b8addecbcc7820eb4266c639745dfa80f36faf66c66fa19c3f882fb470ec05cdc0bed07893f68e171492635f686c3eeff6ba3c8fdd366dc4c0452c8781f8080000000049454e44ae426082</data>
+    </image>
+    <image name="image2">
+        <data format="PNG" length="217">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000a049444154388dd5954d0a802010859fd14668e18de662d222bc98376a21b4ac451992c66469e0b7f187f1f11c47052a218e762daddbfb9e99f6568f80b5364b8588ce35440400e80a398ce8f99034d2292cc37c8ebd530feb583a05e954341f8a027b2a7d3a1f09bf854dc5d5d953aa396e4f38cab199e2d2e108abe156f82e30977fcb4d8ff942d75dbebed2e143953a93f6caad3d6111f44b7d4f820ff9c0069bb51ecded318c5c0000000049454e44ae426082</data>
+    </image>
+    <image name="image3">
+        <data format="PNG" length="172">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007349444154388ded92c10e80200840b1ef661d1cff4d876aa888a17669f9360f283ed80060f159425f3a71f53602e08e992b098801d02854176ae47f21ce1fb5b05d38eddc9060d0f11379635b3bc92bd518e239a943ec1d5ab7785cee107be4b215af4091f894de47181ecea59ede9ec59f380062ac28b1e3d701d90000000049454e44ae426082</data>
+    </image>
+    <image name="image4">
+        <data format="PNG" length="173">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007449444154388ded92c10ac02008406ddf2d3b84ffed0ea3586a26d165e0830ea53e8504487e4b910f5489f19ea5a3ca0f8a896365b306c42dd613c649bdc2598316136219f0f936c0a2ef00d75a62614d3ab22996f2a362ffa337c5ebede962aad1a2e84aaaa2f750dd12748c0fd0ab9324677800596e28b1743f46860000000049454e44ae426082</data>
+    </image>
+    <image name="image5">
+        <data format="PNG" length="187">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000008249444154388dcdd341128020080550e8e02ebc38ad3273503e48537fe3e48c4f2425fa28e29c6f39920bf9276cb60185358877611388c2576418cda015f520b4e6b55be109dc0622b8e22acf31056e18dfdff80606aa551cc63564c4dcf80cd0201d577a5c85a8845fdc025ea5307afccd07e23a1df283ec2b37d9ad5fb4dfefd49cfbf72fac98c8cc890000000049454e44ae426082</data>
+    </image>
+    <image name="image6">
+        <data format="PNG" length="248">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000bf49444154388dd593410a83301045df488ee51dbc8c3ba98bf46a9eabd385350d266362444a3f0c4266fcf3f824f06f12402b66da8c55f3de2212cf9d92cb98c0ba2d7c4544cf9a07638bbad53c4491235ecf7cc1623697a92540c11ff4fda75275015d24a9389e7d6f53df4fe4ccab323eea0f03c0c4b2a0712ce6add89b59b7661c3be095985f261679ee4ebcc22c9788551fe6a2cbc4969a894bcb6f23ee361aab62e252c57294dfbfb610bbf2c897b8a46cc6677eaa519571fa087ea83762da9abacb20235f0000000049454e44ae426082</data>
+    </image>
+    <image name="image7">
+        <data format="PNG" length="270">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000d549444154388dc5955d0a84300c8427e2a90a9e6c8b0f4b3dd982d7ca3e58d7fe4cd0ba5d7640024df265da0a057e2439c9eb8d9eaa8841a0c9aad8c82ab32f9c425be1e30e0dcf00c00308f0b3a7a07410a9d7142e00b42c5a5fab696b979b1c837fc0c316b6e4165b64f78d716359919bdc4570de47c04732dd5e5bcc35f0c97762ae787936dccf7513577e79f48c4b27aa0f1327b240f5117fcbe348aa33b6e0224b054d0746b8025e2e3b3e73cde0dd1c97f02e8ed9d0af1db381224bdf33eee698a934a0f617b45540d00bcf4ca08fc0dff406e325c1981bc418760000000049454e44ae426082</data>
+    </image>
+    <image name="image8">
+        <data format="PNG" length="662">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000025d49444154388dd593a172db4010863f670a56ecc42278d0653693a0c21c68d6c2e60df21a818111349499c254a8329b55f0e089ddb15ba602b79d6692d699b6d399fee86e67e7db7f77efe07fd3e2c74bd775b3730eef3d5115002382b5166b2d5757578b1729bf02b76d3b0f8703b92d58aed7600400ef1ce3c70306a8aa8aebebeb57c117dfa06ddb525dd754efb600a82a49138a123532ec3ac42b9bcde655ce2ffabe9f87c340fde13dcb4d8daaa24e48ee12c6823808c107969b1a8a9ce3f1f8aa515c38e7c8ada5aa6b00c45f129c67d223938c88e6c860d118b1d592d139baae9bcf83a78965b5465134801b1d2e1f4945c0e350096408ea154490c2e0bd3fef5853c2e486a0019f4d84f58418418362b0408e8b23c924501093314dd359f01b809814112025144015f1964c0bbc1b484b07e4688880c029ebd78e4141f5b434fd76864c053f1e084b0f8580265440634044ce838bbcc03987a61350a3a2285e1d5a4414d0708aa598082162ad3d0fb6d6e287cfa498508d274050447370428c91af8d10fd4481608c390b5e00dcddddcd8e80a9de420248e804840856f03e02907d729465c9ba5ae3468731e6a79fe50260b55a6102c4ee40a6894c33f2cb0cb106512814f8f899b22cb9b9b959b8d1f1f8f848d334b46dfbe29bfe5eadeffbf9783c323a871881ecb4200d1151a8eb9aed76bb00188661eeba8efd7e8f3186ed76cb6ab57ae2fe591b5dd7cdde7b628c8808799e63ada5aaaa67b9bbdd6e6e9a06ef3d755d3f29fec7eafb7ebebdbd9dadb5735996f3fdfdfdfca2e3dfd5c3c3c3dc340dd334b1d96cfe1e184e63dceff7a494fe26f61fe90bbc4c5e59d614caf40000000049454e44ae426082</data>
+    </image>
+</images>
+<connections>
+    <connection>
+        <sender>fileNewAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileNew()</slot>
+    </connection>
+    <connection>
+        <sender>fileOpenAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileOpen()</slot>
+    </connection>
+    <connection>
+        <sender>fileSaveAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileSave()</slot>
+    </connection>
+    <connection>
+        <sender>fileSaveAsAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileSaveAs()</slot>
+    </connection>
+    <connection>
+        <sender>fileExitAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileExit()</slot>
+    </connection>
+    <connection>
+        <sender>editUndoAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>editUndo()</slot>
+    </connection>
+    <connection>
+        <sender>editRedoAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>editRedo()</slot>
+    </connection>
+    <connection>
+        <sender>editCutAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>editCut()</slot>
+    </connection>
+    <connection>
+        <sender>editPasteAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>editPaste()</slot>
+    </connection>
+    <connection>
+        <sender>editFindAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>editFind()</slot>
+    </connection>
+    <connection>
+        <sender>helpIndexAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>helpIndex()</slot>
+    </connection>
+    <connection>
+        <sender>helpContentsAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>helpContents()</slot>
+    </connection>
+    <connection>
+        <sender>helpAboutAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>helpAbout()</slot>
+    </connection>
+    <connection>
+        <sender>fileCloseAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileClose()</slot>
+    </connection>
+    <connection>
+        <sender>fileNewViewAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileNewView()</slot>
+    </connection>
+    <connection>
+        <sender>fileCloseAllAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>fileCloseAll()</slot>
+    </connection>
+    <connection>
+        <sender>editCopyAction</sender>
+        <signal>activated()</signal>
+        <receiver>Eficas</receiver>
+        <slot>editCopy()</slot>
+    </connection>
+</connections>
+<slots>
+    <slot>fileNew()</slot>
+    <slot>fileOpen()</slot>
+    <slot>fileSave()</slot>
+    <slot>fileSaveAs()</slot>
+    <slot>filePrint()</slot>
+    <slot>fileExit()</slot>
+    <slot>editUndo()</slot>
+    <slot>editRedo()</slot>
+    <slot>editCut()</slot>
+    <slot>fileNewView()</slot>
+    <slot>editPaste()</slot>
+    <slot>editFind()</slot>
+    <slot>helpIndex()</slot>
+    <slot>helpContents()</slot>
+    <slot>helpAbout()</slot>
+    <slot>fileClose()</slot>
+    <slot>fileCloseAll()</slot>
+    <slot>editCopy()</slot>
+</slots>
+<layoutdefaults spacing="2" margin="2"/>
+</UI>
diff --git a/Interface/myMain_ui.py b/Interface/myMain_ui.py
new file mode 100644 (file)
index 0000000..2822db7
--- /dev/null
@@ -0,0 +1,490 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'myMain.ui'
+#
+# Created: Fri Feb 16 10:50:30 2007
+#      by: The PyQt User Interface Compiler (pyuic) 3.13
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from qt import *
+
+image0_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\x74\x49\x44\x41\x54\x38\x8d\xed\xd5\xc1\x09\xc0" \
+    "\x20\x0c\x05\xd0\x6f\xe9\x36\x81\x2c\x10\xb2\xff" \
+    "\xdd\x85\xd2\x53\x85\xb6\xa9\x91\x48\x0f\x05\x3f" \
+    "\x08\x1a\xf0\x29\x12\x10\xf8\x28\xc5\xa9\xd9\xc4" \
+    "\xde\x96\xcd\x2b\x9a\xd9\xeb\x00\x00\x66\x0e\x2f" \
+    "\xe0\xc2\x51\x98\x39\xc4\xf7\x0c\x4c\x44\x6d\x5e" \
+    "\x6b\x35\x38\xcf\x92\x82\x45\xe4\xb2\xf6\xf0\x14" \
+    "\xac\xaa\x8f\xda\x1d\x4f\xc1\xa5\x74\x1b\x22\x07" \
+    "\x9f\x9d\x11\x1d\x96\xea\x8a\x91\x2c\x78\xc1\x0b" \
+    "\xee\x64\xe6\x07\x19\xf5\x7e\x92\x03\xad\x45\x2a" \
+    "\x04\xcc\x4e\x50\x20\x00\x00\x00\x00\x49\x45\x4e" \
+    "\x44\xae\x42\x60\x82"
+image1_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\x99\x49\x44\x41\x54\x38\x8d\xed\x94\x41\x0e\x85" \
+    "\x20\x0c\x44\x5f\x89\xc7\x36\x7f\x61\xbc\x77\x5d" \
+    "\x28\x48\xa4\x28\x60\xff\xce\xd9\x54\x8b\xbe\x8e" \
+    "\x13\x04\x3e\x1d\x92\x81\x77\xf4\x81\xa1\x23\xdc" \
+    "\x2b\x34\xf6\xf4\x7a\x3d\xe2\xb8\x65\xa8\x84\x3f" \
+    "\x40\x01\x98\x2a\x0b\x3d\x5f\x62\xc5\x83\x00\xaa" \
+    "\x1a\xd7\x05\x50\x44\x9a\xb9\xd5\x07\xa7\x73\xa8" \
+    "\xa4\xba\x4f\x92\xa2\xdf\x33\x3c\x64\xc6\x3b\xeb" \
+    "\xbd\x82\xe5\xb8\xad\xde\xcb\xcc\x78\x20\xeb\x42" \
+    "\x66\xc6\x39\x74\x5d\xfa\x80\xf3\x6f\xaf\x66\xc6" \
+    "\x6f\xa1\x9c\x3f\x88\x2f\xb4\x70\xec\x05\xcd\xc0" \
+    "\xbe\xd0\x78\x93\xf6\x8e\x17\x14\x92\x63\x5f\x68" \
+    "\x6c\x3e\xef\xf6\xba\x3c\x8f\xdd\x36\x6d\xc4\xc0" \
+    "\x45\x2c\x87\x81\xf8\x08\x00\x00\x00\x00\x49\x45" \
+    "\x4e\x44\xae\x42\x60\x82"
+image2_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\xa0\x49\x44\x41\x54\x38\x8d\xd5\x95\x4d\x0a\x80" \
+    "\x20\x10\x85\x9f\xd1\x46\x68\xe1\x8d\xe6\x62\xd2" \
+    "\x22\xbc\x98\x37\x6a\x21\xb4\xac\x45\x19\x92\xc6" \
+    "\x64\x69\xe0\xb7\xf1\x87\xf1\xf1\x1c\x47\x05\x2a" \
+    "\x21\x8e\x76\x2d\xad\xdb\xfb\x9e\x99\xf6\x56\x8f" \
+    "\x80\xb5\x36\x4b\x85\x88\xce\x35\x44\x04\x00\xe8" \
+    "\x0a\x39\x8c\xe8\xf9\x90\x34\xd2\x29\x2c\xc3\x7c" \
+    "\x8e\xbd\x53\x0f\xeb\x58\x3a\x05\xe9\x54\x34\x1f" \
+    "\x8a\x02\x7b\x2a\x7d\x3a\x1f\x09\xbf\x85\x4d\xc5" \
+    "\xd5\xd9\x53\xaa\x39\x6e\x4f\x38\xca\xb1\x99\xe2" \
+    "\xd2\xe1\x08\xab\xe1\x56\xf8\x2e\x30\x97\x7f\xcb" \
+    "\x4d\x8f\xf9\x42\xd7\x5d\xbe\xbe\xd2\xe1\x43\x95" \
+    "\x3a\x93\xf6\xca\xad\x3d\x61\x11\xf4\x4b\x7d\x4f" \
+    "\x82\x0f\xf9\xc0\x06\x9b\xb5\x1e\xcd\xed\x31\x8c" \
+    "\x5c\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60" \
+    "\x82"
+image3_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\x73\x49\x44\x41\x54\x38\x8d\xed\x92\xc1\x0e\x80" \
+    "\x20\x08\x40\xb1\xef\x66\x1d\x1c\xff\x4d\x87\x6a" \
+    "\xa8\x88\xa1\x76\x69\xf9\x36\x0f\x28\x3e\xd8\x00" \
+    "\x60\xf1\x59\x42\x5f\x3a\x71\xf5\x36\x02\xe0\x8e" \
+    "\x99\x2b\x09\x88\x01\xd0\x28\x54\x17\x6a\xe4\x7f" \
+    "\x21\xce\x1f\xb5\xb0\x5d\x38\xed\xdc\x90\x60\xd0" \
+    "\xf1\x13\x79\x63\x5b\x3b\xc9\x2b\xd5\x18\xe2\x39" \
+    "\xa9\x43\xec\x1d\x5a\xb7\x78\x5c\xee\x10\x7b\xe4" \
+    "\xb2\x15\xaf\x40\x91\xf8\x94\xde\x47\x18\x1e\xce" \
+    "\xa5\x9e\xde\x9e\xc5\x9f\x38\x00\x62\xac\x28\xb1" \
+    "\xe3\xd7\x01\xd9\x00\x00\x00\x00\x49\x45\x4e\x44" \
+    "\xae\x42\x60\x82"
+image4_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\x74\x49\x44\x41\x54\x38\x8d\xed\x92\xc1\x0a\xc0" \
+    "\x20\x08\x40\x6d\xdf\x2d\x3b\x84\xff\xed\x0e\xa3" \
+    "\x58\x6a\x26\xd1\x65\xe0\x83\x0e\xa5\x3e\x85\x04" \
+    "\x48\x7e\x4b\x91\x0f\x54\x89\xf1\x9e\xa5\xa3\xca" \
+    "\x0f\x8a\x89\x63\x65\xb3\x06\xc4\x2d\xd6\x13\xc6" \
+    "\x49\xbd\xc2\x59\x83\x16\x13\x62\x19\xf0\xf9\x36" \
+    "\xc0\xa2\xef\x00\xd7\x5a\x62\x61\x4d\x3a\xb2\x29" \
+    "\x96\xf2\xa3\x62\xff\xa3\x37\xc5\xeb\xed\xe9\x62" \
+    "\xaa\xd1\xa2\xe8\x4a\xaa\xa2\xf7\x50\xdd\x12\x74" \
+    "\x8c\x0f\xd0\xab\x93\x24\x67\x78\x00\x59\x6e\x28" \
+    "\xb1\x74\x3f\x46\x86\x00\x00\x00\x00\x49\x45\x4e" \
+    "\x44\xae\x42\x60\x82"
+image5_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\x82\x49\x44\x41\x54\x38\x8d\xcd\xd3\x41\x12\x80" \
+    "\x20\x08\x05\x50\xe8\xe0\x2e\xbc\x38\xad\x32\x73" \
+    "\x50\x3e\x48\x53\x7f\xe3\xe4\x8c\x4f\x24\x25\xfa" \
+    "\x28\xe2\x9c\x6f\x39\x92\x0b\xf9\x27\x6c\xb6\x01" \
+    "\x85\x35\x88\x77\x61\x13\x88\xc2\x57\x64\x18\xcd" \
+    "\xa0\x15\xf5\x20\xb4\xe6\xb5\x5b\xe1\x09\xdc\x06" \
+    "\x22\xb8\xe2\x2a\xcf\x31\x05\x6e\x18\xdf\xdf\xf8" \
+    "\x06\x06\xaa\x55\x1c\xc6\x35\x64\xc4\xdc\xf8\x0c" \
+    "\xd0\x20\x1d\x57\x7a\x5c\x85\xa8\x84\x5f\xdc\x02" \
+    "\x5e\xa5\x30\x7a\xfc\xcd\x07\xe2\x3a\x1d\xf2\x83" \
+    "\xec\x2b\x37\xd9\xad\x5f\xb4\xdf\xef\xd4\x9c\xfb" \
+    "\xf7\x2f\xac\x98\xc8\xcc\x89\x00\x00\x00\x00\x49" \
+    "\x45\x4e\x44\xae\x42\x60\x82"
+image6_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\xbf\x49\x44\x41\x54\x38\x8d\xd5\x93\x41\x0a\x83" \
+    "\x30\x10\x45\xdf\x48\x8e\xe5\x1d\xbc\x8c\x3b\xa9" \
+    "\x8b\xf4\x6a\x9e\xab\xd3\x85\x35\x0d\x26\x63\x62" \
+    "\x44\x4a\x3f\x0c\x42\x66\xfc\xf3\xf8\x24\xf0\x6f" \
+    "\x12\x40\x2b\x66\xda\x8c\x55\xf3\xde\x22\x12\xcf" \
+    "\x9d\x92\xcb\x98\xc0\xba\x2d\x7c\x45\x44\xcf\x9a" \
+    "\x07\x63\x8b\xba\xd5\x3c\x44\x91\x23\x5e\xcf\x7c" \
+    "\xc1\x62\x36\x97\xa9\x25\x40\xc1\x1f\xf4\xfd\xa7" \
+    "\x52\x75\x01\x5d\x24\xa9\x38\x9e\x7d\x6f\x53\xdf" \
+    "\x4f\xe4\xcc\xab\x32\x3e\xea\x0f\x03\xc0\xc4\xb2" \
+    "\xa0\x71\x2c\xe6\xad\xd8\x9b\x59\xb7\x66\x1c\x3b" \
+    "\xe0\x95\x98\x5f\x26\x16\x79\xee\x4e\xbc\xc2\x2c" \
+    "\x97\x88\x55\x1f\xe6\xa2\xcb\xc4\x96\x9a\x89\x4b" \
+    "\xcb\x6f\x23\xee\x36\x1a\xab\x62\xe2\x52\xc5\x72" \
+    "\x94\xdf\xbf\xb6\x10\xbb\xf2\xc8\x97\xb8\xa4\x6c" \
+    "\xc6\x67\x7e\xaa\x51\x95\x71\xfa\x08\x7e\xa8\x37" \
+    "\x62\xda\x9a\xba\xcb\x20\x23\x5f\x00\x00\x00\x00" \
+    "\x49\x45\x4e\x44\xae\x42\x60\x82"
+image7_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x00" \
+    "\xd5\x49\x44\x41\x54\x38\x8d\xc5\x95\x5d\x0a\x84" \
+    "\x30\x0c\x84\x27\xe2\xa9\x0a\x9e\x6c\x8b\x0f\x4b" \
+    "\x3d\xd9\x82\xd7\xca\x3e\x58\xd7\xfe\x4c\xd0\xba" \
+    "\x5d\x76\x40\x02\x4d\xf2\x65\xda\x0a\x05\x7e\x24" \
+    "\x39\xc9\xeb\x8d\x9e\xaa\x88\x41\xa0\xc9\xaa\xd8" \
+    "\xc8\x2a\xb3\x2f\x9c\x42\x5b\xe1\xe3\x0e\x0d\xcf" \
+    "\x00\xc0\x03\x08\xf0\xb3\xa7\xa0\x74\x10\xa9\xd7" \
+    "\x14\x2e\x00\xb4\x2c\x5a\x5f\xab\x69\x6b\x97\x9b" \
+    "\x1c\x83\x7f\xc0\xc3\x16\xb6\xe4\x16\x5b\x64\xf7" \
+    "\x8d\x71\x63\x59\x91\x9b\xdc\x45\x70\xde\x47\xc0" \
+    "\x47\x32\xdd\x5e\x5b\xcc\x35\xf0\xc9\x77\x62\xae" \
+    "\x78\x79\x36\xdc\xcf\x75\x13\x57\x7e\x79\xf4\x8c" \
+    "\x4b\x27\xaa\x0f\x13\x27\xb2\x40\xf5\x11\x7f\xcb" \
+    "\xe3\x48\xaa\x33\xb6\xe0\x22\x4b\x05\x4d\x07\x46" \
+    "\xb8\x02\x5e\x2e\x3b\x3e\x73\xcd\xe0\xdd\x1c\x97" \
+    "\xf0\x2e\x8e\xd9\xd0\xaf\x1d\xb3\x81\x22\x4b\xdf" \
+    "\x33\xee\xe6\x98\xa9\x34\xa0\xf6\x17\xb4\x55\x40" \
+    "\xd0\x0b\xcf\x4c\xa0\x8f\xc0\xdf\xf4\x06\xe3\x25" \
+    "\xc1\x98\x1b\xc4\x18\x76\x00\x00\x00\x00\x49\x45" \
+    "\x4e\x44\xae\x42\x60\x82"
+image8_data = \
+    "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d" \
+    "\x49\x48\x44\x52\x00\x00\x00\x16\x00\x00\x00\x16" \
+    "\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\x00\x00\x02" \
+    "\x5d\x49\x44\x41\x54\x38\x8d\xd5\x93\xa1\x72\xdb" \
+    "\x40\x10\x86\x3f\x67\x0a\x56\xec\xc4\x22\x78\xd0" \
+    "\x65\x36\x93\xa0\xc2\x1c\x68\xd6\xc2\xe6\x0d\xf2" \
+    "\x1a\x81\x81\x11\x34\x94\x99\xc2\x54\xa8\x32\x9b" \
+    "\x55\xf0\xe0\x89\xdd\xb1\x5b\xa6\x02\xb7\x9d\x66" \
+    "\x92\xd6\x99\xb6\xd3\x99\xfe\xe8\x6e\x67\xe7\xdb" \
+    "\x7f\x77\xef\xe0\x7f\xd3\xe2\xc7\x4b\xd7\x75\xb3" \
+    "\x73\x0e\xef\x3d\x51\x15\x00\x23\x82\xb5\x16\x6b" \
+    "\x2d\x57\x57\x57\x8b\x17\x29\xbf\x02\xb7\x6d\x3b" \
+    "\x0f\x87\x03\xb9\x2d\x58\xae\xd7\x60\x04\x00\xef" \
+    "\x1c\xe3\xc7\x03\x06\xa8\xaa\x8a\xeb\xeb\xeb\x57" \
+    "\xc1\x17\xdf\xa0\x6d\xdb\x52\x5d\xd7\x54\xef\xb6" \
+    "\x00\xa8\x2a\x49\x13\x8a\x12\x35\x32\xec\x3a\xc4" \
+    "\x2b\x9b\xcd\xe6\x55\xce\x2f\xfa\xbe\x9f\x87\xc3" \
+    "\x40\xfd\xe1\x3d\xcb\x4d\x8d\xaa\xa2\x4e\x48\xee" \
+    "\x12\xc6\x82\x38\x08\xc1\x07\x96\x9b\x1a\x8a\x9c" \
+    "\xe3\xf1\xf8\xaa\x51\x5c\x38\xe7\xc8\xad\xa5\xaa" \
+    "\x6b\x00\xc4\x5f\x12\x9c\x67\xd2\x23\x93\x8c\x88" \
+    "\xe6\xc8\x60\xd1\x18\xb1\xd5\x92\xd1\x39\xba\xae" \
+    "\x9b\xcf\x83\xa7\x89\x65\xb5\x46\x51\x34\x80\x1b" \
+    "\x1d\x2e\x1f\x49\x45\xc0\xe3\x50\x09\x64\x08\xea" \
+    "\x15\x44\x90\xc2\xe0\xbd\x3f\xef\x58\x53\xc2\xe4" \
+    "\x86\xa0\x01\x9f\x4d\x84\xf5\x84\x18\x41\x83\x62" \
+    "\xb0\x40\x8e\x8b\x23\xc9\x24\x50\x10\x93\x31\x4d" \
+    "\xd3\x59\xf0\x1b\x80\x98\x14\x11\x20\x25\x14\x40" \
+    "\x15\xf1\x96\x4c\x0b\xbc\x1b\x48\x4b\x07\xe4\x68" \
+    "\x88\x80\xc0\x29\xeb\xd7\x8e\x41\x41\xf5\xb4\x34" \
+    "\xfd\x76\x86\x4c\x05\x3f\x1e\x08\x4b\x0f\x85\x80" \
+    "\x26\x54\x40\x63\x40\x44\xce\x83\x8b\xbc\xc0\x39" \
+    "\x87\xa6\x13\x50\xa3\xa2\x28\x5e\x1d\x5a\x44\x14" \
+    "\xd0\x70\x8a\xa5\x98\x08\x21\x62\xad\x3d\x0f\xb6" \
+    "\xd6\xe2\x87\xcf\xa4\x98\x50\x8d\x27\x40\x50\x44" \
+    "\x73\x70\x42\x8c\x91\xaf\x8d\x10\xfd\x44\x81\x60" \
+    "\x8c\x39\x0b\x5e\x00\xdc\xdd\xdd\xcd\x8e\x80\xa9" \
+    "\xde\x42\x02\x48\xe8\x04\x84\x08\x56\xf0\x3e\x02" \
+    "\x90\x7d\x72\x94\x65\xc9\xba\x5a\xe3\x46\x87\x31" \
+    "\xe6\xa7\x9f\xe5\x02\x60\xb5\x5a\x61\x02\xc4\xee" \
+    "\x40\xa6\x89\x4c\x33\xf2\xcb\x0c\xb1\x06\x51\x28" \
+    "\x14\xf8\xf8\x99\xb2\x2c\xb9\xb9\xb9\x59\xb8\xd1" \
+    "\xf1\xf8\xf8\x48\xd3\x34\xb4\x6d\xfb\xe2\x9b\xfe" \
+    "\x5e\xad\xef\xfb\xf9\x78\x3c\x32\x3a\x87\x18\x81" \
+    "\xec\xb4\x20\x0d\x11\x51\xa8\xeb\x9a\xed\x76\xbb" \
+    "\x00\x18\x86\x61\xee\xba\x8e\xfd\x7e\x8f\x31\x86" \
+    "\xed\x76\xcb\x6a\xb5\x7a\xe2\xfe\x59\x1b\x5d\xd7" \
+    "\xcd\xde\x7b\x62\x8c\x88\x08\x79\x9e\x63\xad\xa5" \
+    "\xaa\xaa\x67\xb9\xbb\xdd\x6e\x6e\x9a\x06\xef\x3d" \
+    "\x75\x5d\x3f\x29\xfe\xc7\xea\xfb\x7e\xbe\xbd\xbd" \
+    "\x9d\xad\xb5\x73\x59\x96\xf3\xfd\xfd\xfd\xfc\xa2" \
+    "\xe3\xdf\xd5\xc3\xc3\xc3\xdc\x34\x0d\xd3\x34\xb1" \
+    "\xd9\x6c\xfe\x1e\x18\x4e\x63\xdc\xef\xf7\xa4\x94" \
+    "\xfe\x26\xf6\x1f\xe9\x0b\xbc\x4c\x5e\x59\xd6\x14" \
+    "\xca\xf4\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42" \
+    "\x60\x82"
+
+class Eficas(QMainWindow):
+    def __init__(self,parent = None,name = None,fl = 0):
+        QMainWindow.__init__(self,parent,name,fl)
+        self.statusBar()
+
+        self.image0 = QPixmap()
+        self.image0.loadFromData(image0_data,"PNG")
+        self.image1 = QPixmap()
+        self.image1.loadFromData(image1_data,"PNG")
+        self.image2 = QPixmap()
+        self.image2.loadFromData(image2_data,"PNG")
+        self.image3 = QPixmap()
+        self.image3.loadFromData(image3_data,"PNG")
+        self.image4 = QPixmap()
+        self.image4.loadFromData(image4_data,"PNG")
+        self.image5 = QPixmap()
+        self.image5.loadFromData(image5_data,"PNG")
+        self.image6 = QPixmap()
+        self.image6.loadFromData(image6_data,"PNG")
+        self.image7 = QPixmap()
+        self.image7.loadFromData(image7_data,"PNG")
+        self.image8 = QPixmap()
+        self.image8.loadFromData(image8_data,"PNG")
+        if not name:
+            self.setName("Eficas")
+
+        self.setEnabled(1)
+        self.setBackgroundOrigin(QMainWindow.WidgetOrigin)
+        f = QFont(self.font())
+        self.setFont(f)
+
+
+        self.fileNewAction = QAction(self,"fileNewAction")
+        self.fileNewAction.setIconSet(QIconSet(self.image0))
+        self.fileOpenAction = QAction(self,"fileOpenAction")
+        self.fileOpenAction.setIconSet(QIconSet(self.image1))
+        self.fileSaveAction = QAction(self,"fileSaveAction")
+        self.fileSaveAction.setIconSet(QIconSet(self.image2))
+        self.fileSaveAsAction = QAction(self,"fileSaveAsAction")
+        self.fileExitAction = QAction(self,"fileExitAction")
+        self.editUndoAction = QAction(self,"editUndoAction")
+        self.editUndoAction.setIconSet(QIconSet(self.image3))
+        self.editRedoAction = QAction(self,"editRedoAction")
+        self.editRedoAction.setIconSet(QIconSet(self.image4))
+        self.editCutAction = QAction(self,"editCutAction")
+        self.editCutAction.setIconSet(QIconSet(self.image5))
+        self.editCopyAction = QAction(self,"editCopyAction")
+        self.editCopyAction.setIconSet(QIconSet(self.image6))
+        self.editPasteAction = QAction(self,"editPasteAction")
+        self.editPasteAction.setIconSet(QIconSet(self.image7))
+        self.editFindAction = QAction(self,"editFindAction")
+        self.editFindAction.setIconSet(QIconSet(self.image8))
+        self.helpContentsAction = QAction(self,"helpContentsAction")
+        self.helpIndexAction = QAction(self,"helpIndexAction")
+        self.helpAboutAction = QAction(self,"helpAboutAction")
+        self.traductionnew_itemAction = QAction(self,"traductionnew_itemAction")
+        self.fileSaveCloseAction = QAction(self,"fileSaveCloseAction")
+        self.fileCloseAction = QAction(self,"fileCloseAction")
+        self.fileNewViewAction = QAction(self,"fileNewViewAction")
+        self.fileCloseAllAction = QAction(self,"fileCloseAllAction")
+
+
+        self.toolBar = QToolBar(QString(""),self,Qt.DockTop)
+
+        self.toolBar.setFrameShape(QToolBar.MenuBarPanel)
+        self.toolBar.setHorizontallyStretchable(0)
+        self.fileNewAction.addTo(self.toolBar)
+        self.fileSaveAction.addTo(self.toolBar)
+        self.fileOpenAction.addTo(self.toolBar)
+        self.fileSaveAsAction.addTo(self.toolBar)
+        self.editCutAction.addTo(self.toolBar)
+        self.editPasteAction.addTo(self.toolBar)
+        self.editFindAction.addTo(self.toolBar)
+        self.fileExitAction.addTo(self.toolBar)
+
+
+        self.MenuBar = QMenuBar(self,"MenuBar")
+
+        self.MenuBar.setMargin(2)
+
+        self.Fichier = QPopupMenu(self)
+        self.fileNewAction.addTo(self.Fichier)
+        self.fileNewViewAction.addTo(self.Fichier)
+        self.fileOpenAction.addTo(self.Fichier)
+        self.fileSaveAction.addTo(self.Fichier)
+        self.fileSaveAsAction.addTo(self.Fichier)
+        self.fileCloseAction.addTo(self.Fichier)
+        self.fileCloseAllAction.addTo(self.Fichier)
+        self.Fichier.insertSeparator()
+        self.Fichier.insertSeparator()
+        self.fileExitAction.addTo(self.Fichier)
+        self.MenuBar.insertItem(QString(""),self.Fichier,2)
+
+        self.Edition = QPopupMenu(self)
+        self.Edition.insertSeparator()
+        self.editCutAction.addTo(self.Edition)
+        self.editCopyAction.addTo(self.Edition)
+        self.editPasteAction.addTo(self.Edition)
+        self.Edition.insertSeparator()
+        self.editFindAction.addTo(self.Edition)
+        self.MenuBar.insertItem(QString(""),self.Edition,3)
+
+        self.JdC = QPopupMenu(self)
+        self.MenuBar.insertItem(QString(""),self.JdC,4)
+
+        self.Options = QPopupMenu(self)
+        self.MenuBar.insertItem(QString(""),self.Options,5)
+
+        self.Aide = QPopupMenu(self)
+        self.MenuBar.insertItem(QString(""),self.Aide,6)
+
+        self.Traduction = QPopupMenu(self)
+        self.traductionnew_itemAction.addTo(self.Traduction)
+        self.MenuBar.insertItem(QString(""),self.Traduction,7)
+
+        self.Patrons = QPopupMenu(self)
+        self.MenuBar.insertItem(QString(""),self.Patrons,8)
+
+
+        self.languageChange()
+
+        self.resize(QSize(727,575).expandedTo(self.minimumSizeHint()))
+        self.clearWState(Qt.WState_Polished)
+
+        self.connect(self.fileNewAction,SIGNAL("activated()"),self.fileNew)
+        self.connect(self.fileOpenAction,SIGNAL("activated()"),self.fileOpen)
+        self.connect(self.fileSaveAction,SIGNAL("activated()"),self.fileSave)
+        self.connect(self.fileSaveAsAction,SIGNAL("activated()"),self.fileSaveAs)
+        self.connect(self.fileExitAction,SIGNAL("activated()"),self.fileExit)
+        self.connect(self.editUndoAction,SIGNAL("activated()"),self.editUndo)
+        self.connect(self.editRedoAction,SIGNAL("activated()"),self.editRedo)
+        self.connect(self.editCutAction,SIGNAL("activated()"),self.editCut)
+        self.connect(self.editPasteAction,SIGNAL("activated()"),self.editPaste)
+        self.connect(self.editFindAction,SIGNAL("activated()"),self.editFind)
+        self.connect(self.helpIndexAction,SIGNAL("activated()"),self.helpIndex)
+        self.connect(self.helpContentsAction,SIGNAL("activated()"),self.helpContents)
+        self.connect(self.helpAboutAction,SIGNAL("activated()"),self.helpAbout)
+        self.connect(self.fileCloseAction,SIGNAL("activated()"),self.fileClose)
+        self.connect(self.fileNewViewAction,SIGNAL("activated()"),self.fileNewView)
+        self.connect(self.fileCloseAllAction,SIGNAL("activated()"),self.fileCloseAll)
+        self.connect(self.editCopyAction,SIGNAL("activated()"),self.editCopy)
+
+
+    def languageChange(self):
+        self.setCaption(self.__tr("Eficas V1.10 pour Aster avec Catalogue V8.3"))
+        self.fileNewAction.setText(self.__tr("New"))
+        self.fileNewAction.setMenuText(self.__tr("&New"))
+        self.fileNewAction.setAccel(self.__tr("Ctrl+N"))
+        self.fileOpenAction.setText(self.__tr("Open"))
+        self.fileOpenAction.setMenuText(self.__tr("&Open..."))
+        self.fileOpenAction.setAccel(self.__tr("Ctrl+O"))
+        self.fileSaveAction.setText(self.__tr("Save"))
+        self.fileSaveAction.setMenuText(self.__tr("&Save"))
+        self.fileSaveAction.setAccel(self.__tr("Ctrl+S"))
+        self.fileSaveAsAction.setText(self.__tr("Save As"))
+        self.fileSaveAsAction.setMenuText(self.__tr("Save &As..."))
+        self.fileSaveAsAction.setAccel(QString.null)
+        self.fileExitAction.setText(self.__tr("Exit"))
+        self.fileExitAction.setMenuText(self.__tr("E&xit"))
+        self.fileExitAction.setAccel(QString.null)
+        self.editUndoAction.setText(self.__tr("Undo"))
+        self.editUndoAction.setMenuText(self.__tr("&Undo"))
+        self.editUndoAction.setAccel(self.__tr("Ctrl+Z"))
+        self.editRedoAction.setText(self.__tr("Redo"))
+        self.editRedoAction.setMenuText(self.__tr("&Redo"))
+        self.editRedoAction.setAccel(self.__tr("Ctrl+Y"))
+        self.editCutAction.setText(self.__tr("Cut"))
+        self.editCutAction.setMenuText(self.__tr("Cu&t"))
+        self.editCutAction.setAccel(self.__tr("Ctrl+X"))
+        self.editCopyAction.setText(self.__tr("Copy"))
+        self.editCopyAction.setMenuText(self.__tr("&Copy"))
+        self.editCopyAction.setAccel(self.__tr("Ctrl+C"))
+        self.editPasteAction.setText(self.__tr("Paste"))
+        self.editPasteAction.setMenuText(self.__tr("&Paste"))
+        self.editPasteAction.setAccel(self.__tr("Ctrl+V"))
+        self.editFindAction.setText(self.__tr("Find"))
+        self.editFindAction.setMenuText(self.__tr("&Find..."))
+        self.editFindAction.setAccel(self.__tr("Ctrl+F"))
+        self.helpContentsAction.setText(self.__tr("Contents"))
+        self.helpContentsAction.setMenuText(self.__tr("&Contents..."))
+        self.helpContentsAction.setAccel(QString.null)
+        self.helpIndexAction.setText(self.__tr("Index"))
+        self.helpIndexAction.setMenuText(self.__tr("&Index..."))
+        self.helpIndexAction.setAccel(QString.null)
+        self.helpAboutAction.setText(self.__tr("About"))
+        self.helpAboutAction.setMenuText(self.__tr("&About"))
+        self.helpAboutAction.setAccel(QString.null)
+        self.traductionnew_itemAction.setText(self.__tr("new item"))
+        self.traductionnew_itemAction.setMenuText(self.__tr("new item"))
+        self.fileSaveCloseAction.setText(self.__tr("Close"))
+        self.fileSaveCloseAction.setMenuText(self.__tr("Close"))
+        self.fileCloseAction.setText(self.__tr("Close"))
+        self.fileCloseAction.setMenuText(self.__tr("Close"))
+        self.fileCloseAction.setAccel(self.__tr("Ctrl+W"))
+        self.fileNewViewAction.setText(self.__tr("New view"))
+        self.fileCloseAllAction.setText(self.__tr("Close All"))
+        self.fileCloseAllAction.setMenuText(self.__tr("Close All"))
+        self.toolBar.setLabel(self.__tr("Tools"))
+        if self.MenuBar.findItem(2):
+            self.MenuBar.findItem(2).setText(self.__tr("&Fichier"))
+        if self.MenuBar.findItem(3):
+            self.MenuBar.findItem(3).setText(self.__tr("&Edition"))
+        if self.MenuBar.findItem(4):
+            self.MenuBar.findItem(4).setText(self.__tr("JdC"))
+        if self.MenuBar.findItem(5):
+            self.MenuBar.findItem(5).setText(self.__tr("Options"))
+        if self.MenuBar.findItem(6):
+            self.MenuBar.findItem(6).setText(self.__tr("&Aide"))
+        if self.MenuBar.findItem(7):
+            self.MenuBar.findItem(7).setText(self.__tr("Traduction"))
+        if self.MenuBar.findItem(8):
+            self.MenuBar.findItem(8).setText(self.__tr("Patrons"))
+
+
+    def fileNew(self):
+        print "Eficas.fileNew(): Not implemented yet"
+
+    def fileOpen(self):
+        print "Eficas.fileOpen(): Not implemented yet"
+
+    def fileSave(self):
+        print "Eficas.fileSave(): Not implemented yet"
+
+    def fileSaveAs(self):
+        print "Eficas.fileSaveAs(): Not implemented yet"
+
+    def filePrint(self):
+        print "Eficas.filePrint(): Not implemented yet"
+
+    def fileExit(self):
+        print "Eficas.fileExit(): Not implemented yet"
+
+    def editUndo(self):
+        print "Eficas.editUndo(): Not implemented yet"
+
+    def editRedo(self):
+        print "Eficas.editRedo(): Not implemented yet"
+
+    def editCut(self):
+        print "Eficas.editCut(): Not implemented yet"
+
+    def fileNewView(self):
+        print "Eficas.fileNewView(): Not implemented yet"
+
+    def editPaste(self):
+        print "Eficas.editPaste(): Not implemented yet"
+
+    def editFind(self):
+        print "Eficas.editFind(): Not implemented yet"
+
+    def helpIndex(self):
+        print "Eficas.helpIndex(): Not implemented yet"
+
+    def helpContents(self):
+        print "Eficas.helpContents(): Not implemented yet"
+
+    def helpAbout(self):
+        print "Eficas.helpAbout(): Not implemented yet"
+
+    def fileClose(self):
+        print "Eficas.fileClose(): Not implemented yet"
+
+    def fileCloseAll(self):
+        print "Eficas.fileCloseAll(): Not implemented yet"
+
+    def editCopy(self):
+        print "Eficas.editCopy(): Not implemented yet"
+
+    def __tr(self,s,c = None):
+        return qApp.translate("Eficas",s,c)
diff --git a/Interface/newsimppanel.py b/Interface/newsimppanel.py
new file mode 100644 (file)
index 0000000..ea414a0
--- /dev/null
@@ -0,0 +1,196 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+import composimp
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+
+class newSIMPPanel(panels.OngletPanel):
+  """
+  Classe virtuelle servant de classe mère à toutes les classes Panel
+  servant à afficher et récupérer la valeur d'un mot-clé simple.
+  Le panel est différent suivant le type de la valeur attendu
+  """
+  def init(self):
+      """
+      Méthode appelée par le constructeur de OngletPanel :
+      construit le notebook à 2 onglets utilisé par tous les panels de
+      tous les mots-clés simples
+      """
+      nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
+      nb.pack(fill = 'both', expand = 1)
+      self.nb=nb
+      nb.add('Valeur', tab_text='Saisir valeur')
+      self.makeValeurPage(nb.page('Valeur'))
+      self.enlevebind()
+      self.creebind()
+      nb.setnaturalsize()
+      
+# ----------------------------------------------------------------------------------------
+#   Méthodes utilisées pour l'affectation de la valeur donnée par l'utilisateur
+#    au mot-clé courant
+# ----------------------------------------------------------------------------------------
+
+  def reset_old_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é ni ré-évaluer l'ancienne valeur
+          permet de rester avec des valeurs non entrees et de ne pas 
+          ré-évaluer des entiers par exemple
+      """
+      if self.parent.modified == 'n' : self.parent.init_modif()
+      self.node.item.set_valeur(name)
+      self.parent.appli.affiche_infos(mess)
+
+  def record_valeur(self,name=None,mess='Valeur du mot-clé enregistrée'):
+      """
+          Enregistre  val comme valeur de self.node.item.object  
+          en evaluant l item et en le validant 
+          Si name n'est pas renseigné, la valeur 
+      """
+      if self.parent.modified == 'n' : self.parent.init_modif()
+      if name != None:
+          valeur = name
+          validite = 1
+      else :
+          valeurentree= self.entry.get()
+          self.entry.delete(0,END)
+          if valeurentree == '': valeurentree=None
+          valeur,validite=self.node.item.eval_valeur(valeurentree)
+          if not validite :
+                  valeur= self.entry.get()
+                  commentaire = "impossible d'évaluer : %s " %`valeurentree`
+                  self.parent.appli.affiche_infos(commentaire)
+                
+      if validite : 
+          validite,commentaire=self.node.item.valide_val(valeur)
+      if validite :
+          self.node.item.set_valeur(valeur)
+          self.parent.appli.affiche_infos(mess)
+      else :
+          self.parent.appli.affiche_infos(commentaire)
+
+# ----------------------------------------------------------------------------------------
+#   Méthodes utilisées pour la manipulation des items dans les listes de choix
+# ----------------------------------------------------------------------------------------
+  def selectValeur(self,name):
+      self.selected_valeur = name
+
+  def deselectValeur(self,name):
+      self.selectValeur = None
+
+  def sup_valeur(self,name=None):
+      """
+      Supprime la valeur selectionnée de la liste des valeurs et la rajoute
+      à la liste des choix possibles
+      """
+      if hasattr(self,'selected_valeur') :
+         if ( self.selected_valeur != None and self.selected_valeur != ''):
+            liste_valeurs = self.Liste_valeurs.get_liste()
+            liste_valeurs.remove(self.selected_valeur)
+            self.Liste_valeurs.put_liste(liste_valeurs)
+            listeActuelle=self.Liste_valeurs.get_liste()
+            liste_choix=self.node.item.get_liste_possible(listeActuelle)
+            self.Liste_choix.put_liste(liste_choix)
+            self.selected_valeur = None
+
+  def add_choix(self,name=None):
+      """
+      Ajoute le choix selectionné à la liste des valeurs et le retire
+      de la liste des choix possibles
+      """
+      
+      if hasattr(self,'selected_choix') :
+         if (self.selected_choix != None and self.selected_choix != ''):
+            min,max = self.node.item.GetMinMax()
+            liste_valeurs = self.Liste_valeurs.get_liste()
+            if len(liste_valeurs) >= max :
+                self.parent.appli.affiche_infos("La liste ne peut pas avoir plus de %d éléments" %max)
+                return
+            if (self.Liste_valeurs.selection != None):
+                ligne=self.Liste_valeurs.cherche_selected_item()
+                liste_valeurs.insert(ligne,self.selected_choix)
+            else :
+                liste_valeurs.append(self.selected_choix)
+            self.Liste_valeurs.put_liste(liste_valeurs)
+            listeActuelle=self.Liste_valeurs.get_liste()
+            liste_choix=self.node.item.get_liste_possible(listeActuelle)
+            self.Liste_choix.put_liste(liste_choix)
+            self.selected_choix = None
+
+  def selectChoix(self,name):
+      self.selected_choix = name
+
+  def deselectChoix(self,name):
+      self.selectChoix = None
+      
+  def raisecmd(self,page):
+      try:
+         self.entry.focus()
+      except:
+         pass
+
+# ----------------------------------------------------------------------------------------
+#   Méthodes utilisées pour la manipulation des items en notation scientifique
+# ----------------------------------------------------------------------------------------
+  def set_valeur_texte(self,texte_valeur) :
+      """ Sert à mettre à jour la notation scientifique"""
+      try :
+        if "R" in self.node.item.object.definition.type:
+            if texte_valeur[0] != "'":
+               clef=eval(texte_valeur)
+               if str(clef) != str(texte_valeur) :
+                  self.node.item.object.init_modif()
+                  clefobj=self.node.item.object.GetNomConcept()
+                  if not self.parent.appli.dict_reels.has_key(clefobj):
+                     self.parent.appli.dict_reels[clefobj] = {}
+                  self.parent.appli.dict_reels[clefobj][clef]=texte_valeur
+                  self.parent.appli.dict_reels[clefobj]
+                  self.node.item.object.fin_modif()
+      except:
+        pass
+
+
+  def get_valeur_texte(self,valeur) :
+     valeur_texte=""
+     if "R" in self.node.item.object.definition.type:
+        clefobj=self.node.item.object.GetNomConcept()
+        if self.parent.appli.dict_reels.has_key(clefobj):
+           if self.parent.appli.dict_reels[clefobj].has_key(valeur):
+              valeur_texte=self.parent.appli.dict_reels[clefobj][valeur]
+     return valeur_texte
diff --git a/Interface/panels.py b/Interface/panels.py
new file mode 100644 (file)
index 0000000..70b872f
--- /dev/null
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+import string
+import os
+
+import traceback
+import prefs
+
+from qt import *
+
+
+SEPARATEUR = '-'*30
+
+
+##class Panel(Frame) :
+##    """
+##    Classe servant de classe mère à toutes celles représentant les
+##    panneaux à afficher en fonction de la nature de l'objet en cours
+##    Elle est toujours dérivée.
+##    """
+##    def __init__(self,parent,panneau,node) :
+##      # Le parent d'un panel est un objet de la classe JDCDISPLAY ou derivee
+##      # ou un objet qui a les attributs : appli (de classe APPLI ou derivee),
+##      # modified et la methode init_modif
+##      self.parent=parent
+##      self.panneau = panneau
+##      self.node=node
+##      Frame.__init__(self,self.panneau)
+##      self.place(x=0,y=0,relheight=1,relwidth=1)
+##      self.creer_boutons()
+##      self.init()
+##      global panneauCommande
+##      panneauCommande=self
+
+        
+##class OngletPanel(Panel) :
+##  """ Cette classe est virtuelle et doit être dérivée
+##      Elle contient les principales méthodes d'affichage des différents onglets"""
+
+      
+class PanelInactif( QWidget ):    #CS_pbruno todo
+    def __init__(self,parent = None,name = None,fl = 0):
+        QWidget.__init__( self, parent, name, fl )
+        text = "Le noeud sélectionné ne correspond pas à un objet actif\n"
+        text = text + "Seules les commandes placées entre \nDEBUT/POURSUITE et FIN sont actives"
+        label = QLabel( self )
+        label.setText(text)
+                
+        
+class NoPanel( QWidget ):
+    def __init__(self,parent = None,name = None,fl = 0):
+        QWidget.__init__(self,parent,name,fl)
+        self.textLabel = QLabel(self)
+        self.textLabel.setText(QString("PANNEAU A IMPLEMENTER"))
+        self.textLabel.setGeometry(QRect(130,150,219,17))
+        self.resize(QSize(600,480).expandedTo(self.minimumSizeHint()))
+        
diff --git a/Interface/panelsSalome.py b/Interface/panelsSalome.py
new file mode 100644 (file)
index 0000000..6381ba7
--- /dev/null
@@ -0,0 +1,286 @@
+# -*- coding: utf-8 -*-
+print "Import de panelsSalome"
+
+from Tkinter import *
+from widgets import ListeChoix
+from widgets import showerror
+
+from fonctionpanel      import FONCTION_Panel
+from shellpanel         import SHELLPanel
+from plusieursintopanel import PLUSIEURS_INTO_Panel
+from plusieursassdpanel import PLUSIEURS_ASSD_Panel
+from plusieursbasepanel import PLUSIEURS_BASE_Panel
+from plusieursbasepanel import PLUSIEURS_BASE_OR_UNELISTE_Panel
+from uniquesdcopanel    import UNIQUE_SDCO_Panel
+from uniqueassdpanel    import UNIQUE_ASSD_Panel
+from uniqueintopanel    import UNIQUE_INTO_Panel
+from uniquecomppanel    import UNIQUE_COMP_Panel
+from uniquebasepanel    import UNIQUE_BASE_Panel
+from uniqueassdpanel    import UNIQUE_ASSD_Panel_Reel
+
+from Noyau.N_CR import justify_text
+
+import traceback
+import salome           # CS_pbruno à poubelliser
+import images
+
+
+
+# 2 types de commandes vont etre particularisees dans Salome
+#
+# - un cas general : 
+# Toutes les commandes possedant GROUP_NO ou GROUP_MA
+# seront surchargees d office
+# pour cela on va utiliser le dictionnaire dict_classes_salome
+# qui va permettre de changer la classe de la commande
+# ainsi si un panel en dehors de salome a pour classe PLUSIEURS_BASE_Panel
+# la classe de ce panel devient alors SALOME_PLUSIEURS_BASE_Panel
+# (pour cela voir composimp)
+
+# des commandes "autres" ne pouvant pas etre identifiées par leur nom 
+# il suffit de creer dans la classe SALOME de la commande
+# une fonction portant son nom 
+# Exemple de particularisation d un panel :
+# Supposons que l on veuille particulariser la commande
+#        - LIRE_MAILLAGE_UNITE 
+# le panel initial a pour classe UNIQUE_BASE_Panel
+# il suffit d'ajouter dans la classe derivée SALOME_UNIQUE_BASE_Panel
+# une fonction  SALOME_LIRE_MAILLAGE_UNITE
+# la classe de ce panel devient alors SALOME_UNIQUE_BASE_Panel
+# on peut surcharger les methodes nécessaires (affichage par exemple)  
+
+
+class SALOME_SHELLPanel (SHELLPanel):
+        ""
+
+class SALOME_FONCTION_Panel (FONCTION_Panel):
+        ""
+
+class SALOME_PLUSIEURS_INTO_Panel (PLUSIEURS_INTO_Panel):
+        ""
+
+class SALOME_PLUSIEURS_ASSD_Panel (PLUSIEURS_ASSD_Panel):
+        ""
+
+class SALOME_UNIQUE_INTO_Panel (UNIQUE_INTO_Panel):
+        ""
+
+class SALOME_UNIQUE_SDCO_Panel (UNIQUE_SDCO_Panel):
+        ""
+
+class SALOME_UNIQUE_ASSD_Panel (UNIQUE_ASSD_Panel):
+        ""
+
+class SALOME_UNIQUE_COMP_Panel (UNIQUE_COMP_Panel):
+        ""
+
+class SALOME_UNIQUE_ASSD_Panel_Reel (UNIQUE_ASSD_Panel_Reel):
+        ""
+
+# ------------------------------------------------------------------------------#
+# classe SALOME_PLUSIEURS_BASE_Panel
+#
+# Commandes modifiées  :  
+#        - AFFE_CHAR_MECA_DDL_IMPO_GROUP_NO
+# Methodes surchargées :  
+#        - makeValeurPage(self,page)
+#
+# ------------------------------------------------------------------------------#
+
+class SALOME_PLUSIEURS_BASE_OR_UNELISTE_Panel(PLUSIEURS_BASE_OR_UNELISTE_Panel):
+      ""        
+
+class SALOME_PLUSIEURS_BASE_Panel(PLUSIEURS_BASE_Panel):
+
+  def __init__(self,parent,panneau,node):
+      PLUSIEURS_BASE_Panel.__init__( self, parent, panneau, node )
+      #self.selected_valeur = None
+      
+  def add_valeur_plusieurs_base(self,name=None):
+      try: 
+        valeur,validite,commentaire=self.get_valeur()
+        if not valeur: # sélection dans salome        
+            strSelection = ''
+            
+            genea=self.node.item.get_genealogie()
+            kwType = None
+            for e in genea:
+                if "GROUP_NO" in e:
+                    kwType = "GROUP_NO"
+                if "GROUP_MA" in e:
+                    kwType = "GROUP_MA"            
+                
+            selection, msg = self.parent.appli.selectGroupFromSalome(kwType)
+            if selection:
+                for oneSelection in selection:
+                    strSelection +=str( oneSelection )
+                    strSelection +=','
+                            
+                strSelection = strSelection.rstrip(',')
+                self.display_valeur( strSelection )                
+                    
+        PLUSIEURS_BASE_Panel.add_valeur_plusieurs_base( self, name )
+        if msg:
+            self.parent.appli.affiche_infos(msg)
+        self.erase_valeur()
+      except:
+        print ' erreur  add_valeur_plusieurs_base' #CS_pbruno : afficher boite de dialogue ici ?          
+        
+  def makeValeurPage(self,page):
+      """
+      Crée la page de saisie d'une liste de valeurs à priori quelconques,
+      cad qui ne sont  pas à choisir dans une liste prédéfinie
+      """      
+      PLUSIEURS_BASE_Panel.makeValeurPage(self,page)
+      self.c = Button( self.frame_choix, text='Visualiser',command=self.displayInSalomeGeom )      
+      self.c.place( relx=0.3, rely=0.0,relwidth=0.55)
+      
+      
+  def displayInSalomeGeom( self ):
+      if self.selected_valeur:        
+        ok, msgError = self.parent.appli.displayShape( self.selected_valeur )
+        if not ok:
+            self.parent.appli.affiche_infos(msgError)
+      
+      
+
+
+# ------------------------------------------------------------------------------#
+# classe SALOME_UNIQUE_BASE_Panel
+#
+# Commandes modifiées  :  
+#        - LIRE_MAILLAGE_UNITE 
+# Methodes surchargées :  
+#        - makeValeurPage(self,page)
+#
+# ------------------------------------------------------------------------------#
+
+class SALOME_UNIQUE_BASE_Panel(UNIQUE_BASE_Panel):
+
+# ce dictionnaire va servir lors de la sortie d efficas
+# a creer le fichier qui sera integre au config.txt
+# pour relier une unite logique et un nom de fichier
+
+  dict_fichier_unite={}
+
+
+  def SALOME_DONNEES_HOMARD_FICHIER_MED_MAILLAGE_N(self):
+      entrychaine=salome.sg.getAllSelected()
+      if entrychaine != '':
+          self.entry2.delete(0,END)
+          try:
+              SO = salome.myStudy.FindObjectID(entrychaine[0])
+          except:
+              boo = 0
+              SO = None
+
+          FileName=''
+          if SO != None:
+              myBuilder = salome.myStudy.NewBuilder()
+              boo,FileAttr = myBuilder.FindAttribute(SO,"AttributeFileType")
+              if boo:
+                 val=FileAttr.Value()
+                 if (val !="FICHIERMED" and val != "FICHIER_RESU_MED"):
+                     boo=0
+                     showerror("Pas de Fichier MED","Cet Objet n a pas de fichier MED Associ\xe9")
+                 else:
+                     boo,FileAttr = myBuilder.FindAttribute(SO,"AttributeExternalFileDef")
+              if boo :
+                FileName=FileAttr.Value()
+              else:
+                 showerror("Pas de Fichier MED","Cet Objet n a pas de fichier MED Associ\xe9")
+          if FileName != '' :
+              self.entry.delete(0,END)
+              self.entry2.delete(0,END)
+              self.entry.insert(0,FileName)
+              self.entry2.insert(0,FileName)
+              self.valid_valeur()
+
+
+  def SALOME_DONNEES_HOMARD_TRAITEMENT_NOM_MED_MAILLAGE_N(self):
+      EntryName=''
+      entrychaine=salome.sg.getAllSelected()
+      if entrychaine != '':
+          self.entry2.delete(0,END)
+          try:
+              SO = salome.myStudy.FindObjectID(entrychaine[0])
+          except:
+              boo = 0
+              SO = None
+
+          if SO is not None:
+             myBuilder = salome.myStudy.NewBuilder()
+             ok, AtName = myBuilder.FindAttribute(SO,"AttributeName")
+             if ok:
+                EntryName=AtName.Value()
+
+      if EntryName != '':
+          self.entry.delete(0,END)
+          self.entry2.delete(0,END)
+          self.entry.insert(0,EntryName)
+          self.entry2.insert(0,EntryName)
+          self.valid_valeur()
+
+  def SALOME_DONNEES_HOMARD_FICHIER_MED_MAILLAGE_NP1(self):
+      self.SALOME_DONNEES_HOMARD_FICHIER_MED_MAILLAGE_N()
+
+  def SALOME_DEFI_GROUP_CREA_GROUP_MA_GROUP_MA(self):
+      #try: 
+      if ( 1 == 1 ) :
+        selection, msg = self.parent.appli.selectGroupFromSalome()
+        if selection:
+           strSelection =str( selection )
+           UNIQUE_BASE_Panel.valid_valeur(self,strSelection)
+        if msg:
+            self.parent.appli.affiche_infos(msg)
+        self.erase_valeur()
+      #except:
+      else :
+        print ' erreur  '
+        
+
+  def redistribue_selon_simp(self):
+      genea = self.node.item.get_genealogie()
+      commande="SALOME"
+      for i in range(0,len( genea )) :
+        commande=commande+"_"+ genea[i]
+      # --------------------------------------------------------------
+      # on verifie que la methode n est pas particularise
+      # sinon on appelle SALOME_DEFI_GROUP_CREA_GROUP_MA_GROUP_MA qui
+      # sert comme methode par defaut 
+      # --------------------------------------------------------------
+      try :
+        SALOME_UNIQUE_BASE_Panel.__dict__[commande](self)
+      except :
+         SALOME_UNIQUE_BASE_Panel.SALOME_DEFI_GROUP_CREA_GROUP_MA_GROUP_MA(self)
+
+
+
+  def makeValeurPage(self,page):
+      """
+      Crée la page de saisie d'une valeur à priori quelconque,
+      cad qui ne sont  pas à choisir dans une liste prédéfinie
+      Ajout d'un bouton pour selectionner  à partir de Salome  
+      """      
+      UNIQUE_BASE_Panel.makeValeurPage(self,page)
+      self.b = Button(self.frame_valeur,text='Relier selection',command=self.redistribue_selon_simp)
+      self.b.place(relx=0.28,rely=0.4,relwidth=0.4)
+
+#---------------------------------------------------------------------------------------
+# Correspondances entre les classes eficas et les classes salome_eficas 
+#______________________________________________________________________________________
+dict_classes_salome = { SHELLPanel : SALOME_SHELLPanel, 
+                          FONCTION_Panel       : SALOME_FONCTION_Panel,
+                          PLUSIEURS_INTO_Panel : SALOME_PLUSIEURS_INTO_Panel,
+                          PLUSIEURS_ASSD_Panel : SALOME_PLUSIEURS_ASSD_Panel,
+                          PLUSIEURS_BASE_Panel : SALOME_PLUSIEURS_BASE_Panel,
+                          PLUSIEURS_BASE_OR_UNELISTE_Panel : SALOME_PLUSIEURS_BASE_OR_UNELISTE_Panel,
+                          UNIQUE_INTO_Panel :  SALOME_UNIQUE_INTO_Panel,
+                          UNIQUE_SDCO_Panel : SALOME_UNIQUE_SDCO_Panel,
+                          UNIQUE_ASSD_Panel : SALOME_UNIQUE_ASSD_Panel,
+                          UNIQUE_ASSD_Panel_Reel : SALOME_UNIQUE_ASSD_Panel_Reel,
+                          UNIQUE_COMP_Panel : SALOME_UNIQUE_COMP_Panel,
+                          UNIQUE_BASE_Panel : SALOME_UNIQUE_BASE_Panel}
+
+dict_geom_numgroupe = { }
+dict_geom_numface = { }
diff --git a/Interface/plusieursassdpanel.py b/Interface/plusieursassdpanel.py
new file mode 100644 (file)
index 0000000..88eea05
--- /dev/null
@@ -0,0 +1,183 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from plusieurspanel import PLUSIEURS_Panel 
+
+class PLUSIEURS_ASSD_Panel(PLUSIEURS_Panel):
+  """
+  Classe définissant le panel associé aux mots-clés qui demandent
+  à l'utilisateur de donner une liste de valeurs qui ne sont pas
+  à choisir dans une liste discrètes et qui sont de type dérivé d'ASSD
+  """
+  def makeValeurPage(self,page):
+      """
+      Génère la page de saisie de plusieurs noms de SD parmi un ensemble discret
+      de SD possibles, cad d'un type cohérent avec les types attendus par le mot-clé simple
+      """
+      # On récupère la bulle d'aide du panneau, l'objet, l'aide, min et max (cardinalité de la liste),
+      # la liste des valeurs déjà affectées à l'objet courant et la liste des SD du bon type
+      bulle_aide=self.get_bulle_aide()
+      self.ajout_valeurs=None
+      objet_mc = self.node.item.get_definition()
+      aide = self.get_aide()
+      aide = justify_text(texte=aide)
+      min,max = self.node.item.GetMinMax()
+      l_valeurs = self.node.item.GetListeValeurs()
+      l_choix=self.node.item.get_sd_avant_du_bon_type()
+      l_choix.sort()
+      # remplissage du panneau
+      self.frame_valeurs = Frame(page)
+      self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
+      self.frame_boutons_fleches = Frame(page)
+      self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
+      self.frame_choix = Frame(page)
+      self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
+      self.frame_boutons = Frame(page)
+      self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=0.5,relheight=0.1)
+      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
+                                 ("<Button-3>",self.deselectValeur),
+                                 ("<Double-Button-1>",self.sup_valeur_sans_into))
+      liste_commandes_choix = (("<Button-1>",self.selectChoix),
+                               ("<Button-3>",self.deselectChoix),
+                               ("<Double-Button-1>",self.add_eval_valeur_sans_into))
+      self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
+                                      titre="Valeur(s) actuelle(s)")
+      self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,liste_commandes = liste_commandes_choix,
+                                    titre= "Valeurs possibles")
+      self.bouton_add = Button(self.frame_boutons_fleches,
+                          image = images.get_image('arrow_left'),
+                          command = self.add_eval_valeur_sans_into)
+      self.bouton_sup = Button(self.frame_boutons_fleches,
+                          image = images.get_image('arrow_right'),
+                          command = self.sup_valeur_sans_into)
+      self.bouton_accepter = Button(self.frame_boutons,
+                               text='Valider',
+                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
+      self.bouton_annuler = Button(self.frame_boutons,
+                              text = 'Annuler',
+                              command = self.annule_modifs_valeur)
+      self.bouton_add.place(relx=0.3,rely=0.35)
+      self.bouton_sup.place(relx=0.3,rely=0.65)
+      for but in (self.bouton_accepter,self.bouton_annuler):
+          but.pack(side='left',padx=4)
+      self.Liste_valeurs.affiche_liste()
+      if len(l_valeurs) > 0 :
+          liste_marque=l_valeurs[-1]
+          self.Liste_valeurs.surligne(liste_marque)
+      self.Liste_choix.affiche_liste()
+      for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
+          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+  
+  def add_eval_valeur_sans_into(self,valeurentree=None):
+      if valeurentree == None:
+         valeurentree = self.get_valeur()
+      valeur,validite=self.node.item.eval_valeur(valeurentree)
+      if not validite :
+         commentaire = "impossible d'évaluer : %s " %`valeurentree`
+         self.parent.appli.affiche_infos(commentaire)
+         return
+      self.add_valeur_sans_into(valeur)
+
+  def get_bulle_aide(self):
+      """
+      Retourne la bulle d'aide associée au panneau
+      """
+      return """Un clic sur une valeur des deux listes la sélectionne.
+      - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
+      dans la liste des valeurs que vous voulez affecter au mot-clé simple
+      - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
+      sélectionnée (elle apparaît alors à nouveau comme choix possible
+      dans la liste des choix à droite)
+      - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
+      au mot-clé simple courant
+      - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
+      avant toute modification depuis le dernier 'Valider'"""
+
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide indiquant de quel type doivent être les
+      valeurs que doit entrer l'utilisateur
+      """
+      commentaire=""
+      mc = self.node.item.get_definition()
+      type = mc.type[0].__name__  
+      if len(mc.type)>1 :
+          for typ in mc.type[1:] :
+              type = type + ' ou '+typ.__name__
+      if mc.min == mc.max:
+        commentaire="Une liste de "+`mc.min`+" objets de type "+type+" est attendue"
+      else :
+        commentaire="Une liste d'objets de type "+type+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
+      aideval=self.node.item.aide()
+      commentaire=commentaire +"\n"+ aideval
+      return commentaire
+
+    
+  def sup_valeur(self,name=None):
+      """
+      Supprime la valeur selectionnée de la liste des valeurs et la rajoute
+      à la liste des choix possibles
+      """
+      liste_valeurs = self.Liste_valeurs.get_liste()
+      liste_valeurs.remove(self.selected_valeur)
+      liste_choix = self.node.item.get_definition().into
+      liste_choix = substract_list(liste_choix,liste_valeurs)
+      self.Liste_valeurs.put_liste(liste_valeurs)
+      self.Liste_choix.put_liste(liste_choix)
+      self.selected_valeur = None      
+    
+  def erase_valeur(self):
+      pass
+
+  def get_valeur(self):
+      """
+      Retourne la valeur sélectionnée dans la liste des choix
+      """
+      return self.selected_choix
+
+  def display_valeur(self,val=None):
+      """
+         Affiche la valeur passée en argument dans l'entry de saisie.
+         Par défaut affiche la valeur du mot-clé simple
+      """
+      # Il n'y a pas d'entry pour ce type de panneau
+      return
+
+    
diff --git a/Interface/plusieursbasepanel.py b/Interface/plusieursbasepanel.py
new file mode 100644 (file)
index 0000000..f1d65a9
--- /dev/null
@@ -0,0 +1,543 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import showinfo
+from widgets import askopenfilename
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+from widgets import FenetreDeParametre
+
+from Noyau.N_CR import justify_text
+from Ihm.I_LASSD import LASSD
+from Extensions.parametre import PARAMETRE
+
+from utils import substract_list
+from plusieurspanel import PLUSIEURS_Panel
+from uniqueassdpanel import UNIQUE_ASSD_Panel
+
+import fontes
+import math
+
+class PLUSIEURS_BASE_Panel(PLUSIEURS_Panel):
+  """
+  Classe définissant le panel associé aux mots-clés qui demandent
+  à l'utilisateur de donner une liste de valeurs qui ne sont pas
+  à choisir dans une liste discrètes et qui sont de type de base :
+  entier, réel, string,...
+  """
+  def makeValeurPage(self,page):
+      """
+      Crée la page de saisie d'une liste de valeurs à priori quelconques,
+      cad qui ne sont  pas à choisir dans une liste prédéfinie
+      """
+      #print "Methode Utilisée par Salome"
+      # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
+      # et la liste des valeurs déjà affectées à l'objet courant
+      bulle_aide=self.get_bulle_aide()
+      objet_mc = self.node.item.get_definition()
+      aide = self.get_aide()
+      aide = justify_text(texte=aide)
+      min,max = self.node.item.GetMinMax()
+      l_valeurs = self.node.item.GetListeValeurs()
+
+      # création des frames globales
+      self.frame1 = Frame(page,relief='groove',bd=2)
+      self.frame2 = Frame(page)
+      self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.85)
+      self.frame2.place(relx=0.,rely=0.85,relwidth=1,relheight=0.15)
+      self.frame_right = Frame(self.frame1)
+      self.frame_right.place(relx=0.35,rely=0.,relwidth=0.65,relheight=1.)
+
+      # création des frames internes
+      self.frame_valeurs = Frame(self.frame1)
+      self.frame_valeurs.place(relx=0.02,rely=0.05,relwidth=0.35,relheight=0.95)
+      self.frame_boutons_fleches = Frame(self.frame_right)
+      self.frame_boutons_fleches.place(relx=0.,rely=0.2,relwidth=0.2,relheight=0.5)
+      self.frame_choix = Frame(self.frame_right)
+      self.frame_choix.place(relx=0.2,rely=0.2,relwidth=0.7,relheight=0.8)
+      self.frame_aide = Frame(self.frame_right)
+      self.frame_aide.place(relx=0.1,rely=0.8,relwidth=0.8,relheight=0.2)
+      self.frame_boutons = Frame(self.frame2)
+      self.frame_boutons.place(relx=0.2,rely=0.,relwidth=1,relheight=1.)
+      for fram in (self.frame1,self.frame2,self.frame_right,self.frame_valeurs,
+                 self.frame_boutons_fleches,self.frame_choix,self.frame_aide,self.frame_boutons):
+          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+
+      # création des objets dans les frames
+      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
+                                 ("<Button-3>",self.deselectValeur),
+                                 ("<Double-Button-1>",self.sup_valeur_sans_into))
+      self.Liste_valeurs=ListeChoix(self,self.frame_valeurs,l_valeurs,liste_commandes = liste_commandes_valeurs,
+                                      titre="Valeur(s) actuelle(s)")
+
+      # Création de l'entry ou de la liste des SD
+      # PN : pour ajouter les validators
+      self.label = Label(self.frame_choix,text="Valeur :")
+      self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base)
+      self.label.place(relx=0.05,rely=0.2)
+
+      # Création d'un bouton "Importer ..." et d'un bouton "Paramatres" 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.4,relwidth=0.6)
+      bouton_parametres = Button(self.frame_choix, text="Parametres", command=self.affiche_parametre)
+      bouton_parametres.place(relx=0.28,rely=0.6,relwidth=0.6)
+      self.ajout_valeurs = None
+
+      # boutons Ajouter et Supprimer
+      self.bouton_add = Button(self.frame_boutons_fleches,
+                          image = images.get_image('arrow_left'),
+                          command = self.add_valeur_plusieurs_base)
+      self.bouton_sup = Button(self.frame_boutons_fleches,
+                          image = images.get_image('arrow_right'),
+                          command = self.sup_valeur_sans_into)
+      self.bouton_add.place(relx=0.3,rely=0.35)
+      self.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',
+                              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()
+      if len(l_valeurs) > 0 :
+          liste_marque=l_valeurs[-1]
+          self.Liste_valeurs.surligne(liste_marque)
+          self.selectValeur(liste_marque)
+      # boutons Accepter et Annuler
+      self.bouton_accepter = Button(self.frame_boutons,
+                               text='Valider',
+                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
+      self.bouton_annuler = Button(self.frame_boutons,
+                              text = 'Annuler',
+                              command = self.annule_modifs_valeur)
+      self.bouton_accepter.place(relx=0.2, rely=0.2,relwidth=0.25)
+      self.bouton_annuler.place(relx=0.5, rely=0.2,relwidth=0.25)
+
+  def affiche_parametre(self) :
+      if self.node.item.get_liste_param_possible() != [ ]:
+         txtparam=""
+         for param in self.node.item.get_liste_param_possible():
+            txtparam=txtparam+repr(param)+"\n"
+         if txtparam=="":
+            showerror("Aucun parametre ","Pas de parametre de ce type")
+         else :
+            try :
+                    self.self.fenetreparam.destroy()
+            except:
+                pass
+            self.fenetreparam=FenetreDeParametre( self, self.node.item, self.parent.appli, txtparam)
+
+  def valid_valeur(self):
+      self.add_valeur_plusieurs_base()
+
+  def add_valeur_plusieurs_base(self,name=None):
+      if name != None :
+         valeur = name
+      else:
+         valeur,validite,commentaire=self.get_valeur()
+         if not validite :
+            self.parent.appli.affiche_infos(commentaire)
+            return
+
+      atraiter=[]
+      if type(valeur)  in (types.ListType,types.TupleType) :
+         indice = 0
+         while (indice < len(valeur)):
+            v=valeur[indice]
+            if self.node.item.wait_complex :
+               if (v== 'RI' or v == 'MP'):
+                  try :
+                     t=tuple([v,valeur[indice+1],valeur[indice+2]])
+                     atraiter.append(t)
+                     indice=indice+3
+                  except :
+                     validite=0
+                     commentaire = "Veuillez entrer le complexe sous forme aster ou sous forme python"
+                     self.parent.appli.affiche_infos(commentaire)
+                     return
+               else :     # ce n'est pas un tuple à la mode aster
+                  atraiter.append(v)
+                  indice = indice + 1
+            else:  # on n'attend pas un complexe
+              atraiter.append(v)
+              indice=indice+1
+      else:
+         atraiter.append(valeur)
+         
+      for valeur in atraiter :
+         encorevalide=self.node.item.valide_item(valeur)
+         # qdsjfkllllllllllllllllll
+         if encorevalide :
+            listecourante=self.Liste_valeurs.get_liste()
+            encorevalide=self.node.item.valide_liste_partielle(valeur,listecourante)
+            if not encorevalide : encorevalide = -1
+         self.add_valeur_sans_into(valeur,encorevalide)
+    
+  def select_in_file(self):
+      """ Permet d'ouvrir un fichier choisi par l'utilisateur. """
+      nom_fichier = askopenfilename(title="Choix fichier :")
+
+      if not 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):
+      """
+      Retourne l'aide associée au panneau courant
+      """
+      return """Taper dans la boîte de saisie de droite la valeur que
+      vous voulez affecter au mot-clé simple.
+      - Cliquez sur la flèche gauche ou pressez <Return> pour la faire glisser
+      dans la liste des valeurs que vous voulez affecter au mot-clé simple
+      - Un clic sur une valeur de la liste la sélectionne
+      - Un clic sur la flèche droite ou un double-clic retire la valeur
+      sélectionnée de la liste
+      - Cliquez sur 'Valider' pour que la nouvelle valeur désirée soit affectée
+      au mot-clé simple
+      - Cliquez sur 'Annuler' pour annuler toutes les modifications faites
+      depuis le dernier clic sur 'Valider'"""
+
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
+      que saisit l'utilisateur
+      """
+      commentaire=""
+      mc = self.node.item.get_definition()
+      d_aides = { 'TXM' : 'chaînes de caractères',
+                  'R'   : 'réels',
+                  'I'   : 'entiers',
+                  'C'   : 'complexes'}
+      type = mc.type[0]
+      if not d_aides.has_key(type) : return 'Type de base inconnu'
+      if mc.min == mc.max:
+          commentaire="Une liste de "+d_aides[type]+" de longueur " + `mc.min`  + " est attendue"
+      else :
+          commentaire="Une liste de "+d_aides[type]+" est attendue (min="+`mc.min`+",max="+`mc.max`+')'
+
+      aideval=self.node.item.aide()
+      commentaire=commentaire +"\n"+aideval
+      return commentaire
+
+  def make_entry(self,frame,command,x=0.28,y=0.2):
+      self.entry = Entry(frame,relief='sunken')
+      self.entry.place(relx=0.28,rely=y,relwidth=0.6)
+      self.entry.bind("<Return>",lambda e,c=command:c())
+      self.entry.bind("<KP_Enter>",lambda e,c=command:c())
+      self.entry.focus()
+
+  def get_valeur(self):
+      """
+      Retourne la valeur saisie par l'utilisateur dans self.entry
+      """
+      commentaire = ""
+      if hasattr(self,'entry'):
+         # Traitement d'une entree unique
+         valeurentree = self.entry.get()
+         if (valeurentree == None or valeurentree ==""):
+            return None,0,""
+
+         #On tente une evaluation globale (ne fait pas de vérification de validité
+         #seulement une transformation de la chaine en objet équivalent)
+         valeur,validite=self.node.item.eval_valeur(valeurentree)
+         if valeur == valeurentree:
+             #L'evaluation n'a rien donné : on a toujours la string
+             #on découpe la string sur le séparateur , si c'est possible
+             if valeurentree.find(',') != -1:
+                 valeur=[]
+                 for v in valeurentree.split(','):
+                     vsimple,validite=self.node.item.eval_valeur(v)
+                     valeur.append(vsimple)
+
+         return valeur,validite,commentaire
+
+
+        # if (valeurentree[0] != "(") and (valeurentree.find(',') < len(valeurentree)):
+        #    valeurs=[]
+        #    for v in valeurentree.split(','):
+        #      vsimple,validite=self.node.item.eval_valeur(v)
+              # Pn If ajoute  pour le panneau "double"
+              #if isinstance(vsimple,LASSD) : 
+              #         commentaire = "impossible de mélanger reels et liste prédéfinie"
+              #  validite = 0
+              #         break 
+        #      if validite :
+        #         valeurs.append(vsimple)
+        #      else:
+        #         commentaire = "impossible d'évaluer : %s " %`valeurentree`
+        #         break
+        #    valeur=valeurs
+        # else: 
+        #    valeur,validite=self.node.item.eval_valeur(valeurentree)
+        # if not validite and commentaire == "":
+        #    commentaire = "impossible d'évaluer : %s " %`valeurentree`
+        # return valeur,validite,commentaire
+      #else:
+      #   # Traitement d'une entree de type complexe
+      #   try:
+      #      valeur= (self.typ_cplx.get(),
+      #               string.atof(self.entry1.get()),
+      #               string.atof(self.entry2.get()))
+      #      return valeur,1,""
+      #   except:
+      #      #traceback.print_exc()
+      #      return None,0,"impossible d'évaluer la valeur d'entree"
+
+  def erase_valeur(self):
+      """
+      Efface la valeur donnée par l'utilisateur dans l'entry
+      """
+      if hasattr(self,'entry'):
+         self.entry.delete(0,END)
+      else:
+         self.typ_cplx.set('RI')
+         self.entry1.delete(0,END)
+         self.entry2.delete(0,END)
+
+        
+  def display_valeur(self,val=None):
+      """
+      Affiche la valeur passée en argument dans l'entry de saisie.
+      Par défaut affiche la valeur du mot-clé simple
+      """
+      if not val :
+          valeur = self.node.item.object.getval()
+      else:
+          valeur = val
+      if not valeur : return
+
+      if hasattr(self,'entry'):
+         # Traitement d'une entree unique
+         self.entry.delete(0,END)
+         self.entry.insert(0,str(valeur))
+      else:
+         # Traitement d'une entree de type complexe
+         typ_cplx,x1,x2=valeur
+         self.entry1.delete(0,END)
+         self.entry2.delete(0,END)
+         self.typ_cplx.set(typ_cplx)
+         self.entry1.setentry(x1)
+         self.entry2.setentry(x2)
+
+class PLUSIEURS_BASE_OR_UNELISTE_Panel(PLUSIEURS_BASE_Panel,UNIQUE_ASSD_Panel):
+
+  def makeValeurPage(self,page):
+      """
+      Crée la page de saisie d'une liste de valeurs à priori quelconques,
+      cad qui ne sont  pas à choisir dans une liste prédéfinie
+      """
+      # On récupère la bulle d'aide du panneau, l'objet, l'aide,min et max (cardinalité de la liste),
+      # et la liste des valeurs déjà affectées à l'objet courant
+      bulle_aide=self.get_bulle_aide()
+      objet_mc = self.node.item.get_definition()
+      aide = self.get_aide()
+      aide = justify_text(texte=aide)
+      aide2 = self.get_aide2()
+      aide2 = justify_text(texte=aide2)
+      min,max = self.node.item.GetMinMax()
+      l_valeurs = self.node.item.GetListeValeurs()
+      for i in l_valeurs:
+         if isinstance(i,LASSD) :
+            affiche_entry=l_valeurs
+            l_valeurs=()
+
+      # Il faut traiter ici pour avoir le choix entre une liste
+      # deja constituee (listr8aster) ou manuelle
+
+      # création des frames globales
+      self.frame1 = Frame(page,relief='groove',bd=2)
+      self.frame2 = Frame(page)
+      self.frame1.place(relx=0.,rely=0.,relwidth=1.,relheight=0.9)
+      self.frame2.place(relx=0.,rely=0.9,relwidth=1,relheight=0.1)
+
+      # création des frames internes dans frame1
+      self.frame_valeurs = Frame(self.frame1)
+      self.frame_valeurs.place(relx=0.02,rely=0.55,relwidth=0.35,relheight=0.45)
+      self.frame_haut = Frame(self.frame1)
+      self.frame_haut.place(relx=0.02,rely=0.02,relwidth=0.98,relheight=0.45)
+      self.frame_bas = Frame(self.frame1)
+      self.frame_bas.place(relx=0.37,rely=0.55,relwidth=0.63,relheight=0.45)
+
+      # création des frames internes dans frame_right
+      self.frame_fleches = Frame(self.frame_bas)
+      self.frame_fleches.place(relx=0.,rely=0.4,relwidth=0.2,relheight=0.5)
+      self.frame_choix = Frame(self.frame_bas)
+      self.frame_choix.place(relx=0.2,rely=0.1,relwidth=0.75,relheight=1)
+
+      # affichage de l'aide
+      self.aide = Label(self.frame_haut, text = aide, justify='center', anchor='center',)
+      self.aide.place(relx=0.72,rely=0.25,anchor='center',relwidth=1)
+      self.aide2 = Label(self.frame2, text = aide2,)
+      self.aide2.place(relx=0.4,rely=0.01,relwidth=0.6)
+
+      # Création d'un bouton "Importer ..." et d'un bouton "Parametres" 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.0,relwidth=0.6)
+      bouton_parametres = Button(self.frame_choix, text="Parametres", command=self.affiche_parametre)
+      bouton_parametres.place(relx=0.28,rely=0.25,relwidth=0.6)
+      self.ajout_valeurs = None
+
+
+      # Création de la liste des SD
+      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type_pour_type_de_base()
+      liste_noms_sd = self.tri(liste_noms_sd)
+      self.listbox = Pmw.ScrolledListBox(self.frame_haut,
+                        items=liste_noms_sd,
+                labelpos='n',
+                #label_text="Structures de données du type\n requis parl'objet courant :",
+                label_text="Listes du type\n requis parl'objet courant :",
+                listbox_height = 6,
+                dblclickcommand=lambda s=self,c=UNIQUE_ASSD_Panel.valid_valeur : s.choose_valeur_from_list(c))
+      self.listbox.place(relx=0.00,rely=0.00,relwidth=0.4)
+
+      # On eneleve le label pour gagner de la place 
+      #self.label = Label(self.frame_choix,text="Valeur :")
+      #self.label.place(relx=0.05,rely=0.85)
+      self.make_entry(frame = self.frame_choix,command = self.add_valeur_plusieurs_base,x=0.28,y=0.55)
+      
+      # boutons Ajouter et Supprimer
+      bouton_add = Button(self.frame_fleches, image = images.get_image('arrow_left'),
+                          command = self.add_valeur_plusieurs_base)
+      bouton_sup = Button(self.frame_fleches, image = images.get_image('arrow_right'),
+                          command = self.sup_valeur_sans_into)
+      bouton_add.place(relx=0.2,rely=0.25)
+      bouton_sup.place(relx=0.2,rely=0.70)
+
+
+      # boutons Accepter et Annuler dans frame2
+      bouton_accepter = Button(self.frame2, text='Valider',
+                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
+      bouton_annuler = Button(self.frame2, text = 'Annuler',
+                              command = self.annule_modifs_valeur)
+      for but in (bouton_accepter,bouton_annuler):
+          but.pack(side='left',padx=5)
+
+      # création des objets dans les frames
+      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
+                                 ("<Button-3>",self.deselectValeur),
+                                 ("<Double-Button-1>",self.sup_valeur_sans_into))
+      self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,l_valeurs,
+                                      liste_commandes = liste_commandes_valeurs,
+                                      titre="Valeur(s) non-prédéfinies(s)",
+                                      fonte_titre=None
+                                      )
+
+      for fram in (self.frame1,self.frame2,self.frame_bas,self.frame_haut,self.frame_valeurs,
+                 self.frame_fleches,self.frame_choix):
+          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide: s.parent.appli.affiche_aide(e,a))
+          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+
+      self.Liste_valeurs.affiche_liste()
+      if len(l_valeurs) > 0 :
+          liste_marque=l_valeurs[-1]
+          self.Liste_valeurs.surligne(liste_marque)
+      
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
+      saisies par l'utilisateur
+      """
+      commentaire="Ce motclef accepte soit un nom de liste déja définie soit une liste manuelle de valeurs"
+      return commentaire
+
+  def get_aide2(self):
+      min,max = self.node.item.GetMinMax()
+      aideval=self.node.item.aide()
+      commentaire="min : " + str(min) + ", max : " + str(max)
+      aideval=commentaire + aideval
+      return aideval
+
+  def choose_valeur_from_list(self,command):
+      """
+      Affecte à valeur choisie la sélection courante dans la liste des choix proposés
+      Exécute command
+      """
+      self.Liste_valeurs.liste=[]
+      self.Liste_valeurs.affiche_liste()
+      if len(self.listbox.get()) == 0 : return
+      choix = self.listbox.getcurselection()[0]
+      d={}
+      d["valeurentree"]=choix
+      apply(command,(self,),d)
+     
+
+
+  def tri(self,liste_noms_sd):
+      a=(3+8j)
+      d_types = { 'TXM' : type('A'),
+                  'R'   : type(3.),
+                  'I'   : type(0),
+                  'C'   : type(a)}
+
+      # On enleve seulement ceux qu'on peut
+      # Sur certaines listes, il est possible qu'on ne 
+      # sache pas déterminer le type
+      listefinale=[]
+      typespossibles=self.node.item.object.definition.type
+      typecherche = None
+      for t in typespossibles:
+          if t in d_types.keys() :
+             typecherche = d_types[t]
+             break
+      for liste in liste_noms_sd:
+          valeur,validite=self.node.item.eval_valeur(liste)
+          for mc in valeur.etape.mc_liste :
+              try :
+                 if type(mc.valeur)  in (types.ListType,types.TupleType) :
+                    typeliste=type(mc.valeur[0])
+                 else :
+                    typeliste=type(mc.valeur)
+                 if type(mc.valeur[0]) == typecherche:
+                    listefinale.append(liste)
+              except:
+                 listefinale.append(liste)
+      return listefinale
+
diff --git a/Interface/plusieursintopanel.py b/Interface/plusieursintopanel.py
new file mode 100644 (file)
index 0000000..1854e86
--- /dev/null
@@ -0,0 +1,163 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from plusieurspanel import PLUSIEURS_Panel
+
+class PLUSIEURS_INTO_Panel(PLUSIEURS_Panel):
+  """
+  Classe servant à définir le panneau permettant d'afficher et de saisir une
+  liste de valeurs à choisir parmi une liste discrètes de valeurs possibles
+  """
+  def makeValeurPage(self,page):
+      """
+      Génère la page de saisie de plusieurs valeurs parmi un ensemble discret
+      de possibles
+      """
+      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
+      aide = self.get_aide()
+      aide = justify_text(texte=aide)
+      bulle_aide=self.get_bulle_aide()
+      objet_mc = self.node.item.get_definition()
+      min,max = self.node.item.GetMinMax()
+      #l_choix=list(objet_mc.into)
+      l_valeurs = self.node.item.GetListeValeurs()
+      l_choix= self.node.item.get_liste_possible(l_valeurs)
+      # reinitialisation de l_valeurs
+      l_valeurs = self.node.item.GetListeValeurs()
+
+      # remplissage du panneau
+      self.frame_valeurs = Frame(page)
+      self.frame_valeurs.place(relx=0.05,rely=0.05,relwidth=0.35,relheight=0.7)
+      self.frame_boutons_fleches = Frame(page)
+      self.frame_boutons_fleches.place(relx=0.4,rely=0.,relwidth=0.2,relheight=0.7)
+      self.frame_choix = Frame(page)
+      self.frame_choix.place(relx=0.6,rely=0.05,relwidth=0.35,relheight=0.7)
+      self.frame_boutons = Frame(page)
+      self.frame_boutons.place(relx=0.35,rely=0.87,relwidth=1,relheight=0.1)
+      self.frame_aide = Frame(page)
+      self.frame_aide.place(relx=0.1,rely=0.75,relwidth=1,relheight=0.15)
+      liste_commandes_valeurs = (("<Button-1>",self.selectValeur),
+                                 ("<Button-3>",self.deselectValeur),
+                                 ("<Double-Button-1>",self.sup_valeur))
+      liste_commandes_choix = (("<Button-1>",self.selectChoix),
+                               ("<Button-3>",self.deselectChoix),
+                               ("<Double-Button-1>",self.add_choix))
+      self.Liste_valeurs = ListeChoix(self,self.frame_valeurs,
+                                      l_valeurs,liste_commandes = liste_commandes_valeurs,
+                                      titre="Valeur(s) actuelle(s)")
+      self.Liste_choix = ListeChoix(self,self.frame_choix,l_choix,
+                                    liste_commandes = liste_commandes_choix,
+                                    titre= "Valeurs possibles")
+      self.bouton_add = Button(self.frame_boutons_fleches,
+                          #text="<--",
+                          image = images.get_image('arrow_left'),
+                          command = self.add_choix)
+      self.bouton_sup = Button(self.frame_boutons_fleches,
+                          #text="-->",
+                          image = images.get_image('arrow_right'),
+                          command = self.sup_valeur)
+      self.bouton_accepter = Button(self.frame_boutons,
+                               text='Valider',
+                               command = lambda s=self,m=min,M=max : s.accepte_modifs_valeur(m,M))
+      self.bouton_annuler = Button(self.frame_boutons,
+                              text = 'Annuler',
+                              command = self.annule_modifs_valeur)
+      self.bouton_add.place(relx=0.3,rely=0.35)
+      self.bouton_sup.place(relx=0.3,rely=0.65)
+      for but in (self.bouton_accepter,self.bouton_annuler):
+          but.pack(side='left',padx=3)
+      self.Liste_valeurs.affiche_liste()
+      if len(l_valeurs) > 0 :
+          liste_marque=l_valeurs[-1]
+          self.Liste_valeurs.surligne(liste_marque)
+          self.selectValeur(l_valeurs[-1])
+      self.Liste_choix.affiche_liste()
+      for fram in (self.frame_valeurs,self.frame_boutons_fleches,self.frame_choix,self.frame_boutons):
+          fram.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+          fram.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+      self.frame_aide.update()
+      self.aide = Label(self.frame_aide,
+                        text = aide,
+                        justify='center',
+                        anchor='center')
+                        #wraplength=int(self.frame_aide.winfo_width()*0.8))
+      self.aide.place(relx=0.3,rely=0.5,anchor='center',relwidth=1)
+
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide indiquant de quel type de base doivent être les valeurs
+      que saisit l'utilisateur
+      """
+      commentaire=""
+      mc = self.node.item.get_definition()
+      d_aides = { 'TXM' : 'chaînes de caractères',
+                  'R'   : 'réels',
+                  'I'   : 'entiers',
+                  'C'   : 'complexes'}
+      type = mc.type[0]
+      if not d_aides.has_key(type) : 
+         if mc.min == mc.max:
+            return str(mc.min)+" valeur(s) est(sont) attendue(s)"
+         else :
+            return "entrez entre "+str(mc.min)+" et "+str(mc.max)+" valeurs"
+      if mc.min == mc.max:
+            commentaire="Une liste de "+str(mc.min)+" "+d_aides[type]+" est attendue"
+      else :
+            commentaire="Entre "+str(mc.min)+" et "+str(mc.max)+" valeurs de type  "+d_aides[type]+" sont attendues"
+      aideval=self.node.item.aide()
+      commentaire=commentaire + "\n" + aideval
+      return commentaire
+
+  def get_bulle_aide(self):
+      """
+      Retourne la bulle d'aide du panneau (affichée par clic droit)
+      """
+      return """Un clic sur une valeur des deux listes la sélectionne.
+      - Un clic sur la flèche gauche stocke la valeur possible sélectionnée
+      dans la liste des valeurs que vous voulez affecter au mot-clé simple
+      - Un clic sur la flèche droite déstocke la valeur du mot-clé simple
+      sélectionnée (elle apparaît alors à nouveau comme choix possible
+      dans la liste des choix à droite)
+      - Cliquez sur 'Valider' pour affecter la liste des valeurs sélectionnées
+      au mot-clé simple courant
+      - Cliquez sur 'Annuler' pour restaurer la valeur du mot-clé simple
+      avant toute modification depuis le dernier 'Valider'"""
+
diff --git a/Interface/plusieurspanel.py b/Interface/plusieurspanel.py
new file mode 100644 (file)
index 0000000..2b59b33
--- /dev/null
@@ -0,0 +1,175 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from  newsimppanel import newSIMPPanel
+
+
+class PLUSIEURS_Panel(newSIMPPanel):
+  """
+  Classe virtuelle servant de classe mère à toutes celles définissant
+  un panneau pour un mot-clé simple qui attend une liste de valeurs
+  """
+  def accepte_modifs_valeur(self,min,max,liste=None):
+      """
+      Méthode qui récupère la liste des valeurs donnée par l'utilisateur
+      et l'affecte au mot-clé courant.
+      le parametre None n'est pas rempli sauf par l appel a partir de fonctionpanel
+      """
+      if liste==None:
+         l1_valeurs = self.Liste_valeurs.get_liste()
+      else:
+         l1_valeurs = liste
+
+      #nettoyage de la liste
+      l_valeurs=[]
+      for  val in l1_valeurs :
+        if val != '' and val != None :
+           l_valeurs.append(val)
+    
+      longueur = len(l_valeurs)
+      if longueur < min or longueur > max :
+          self.parent.appli.affiche_infos("Valeur refusée : nombre d'éléments incorrect dans la liste")
+          return
+      if longueur > 1:
+         valeur = tuple(l_valeurs)
+      elif longueur == 1:
+         valeur = l_valeurs[0]
+      else:
+         valeur = None
+
+      self.parent.appli.affiche_infos("Valeur acceptée")
+      self.record_valeur(valeur)
+      # 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
+      if self.ajout_valeurs:
+          self.ajout_valeurs.quit()
+          
+  def add_valeur_sans_into(self,name=None,encorevalide=1):
+      """
+      Tente d'ajouter la valeur fournie (name) à la liste courante :
+        - si la valeur est acceptable, elle est ajoutée dans la liste des valeurs
+        - sinon elle est refusée
+
+      encorevalide vaut 1 si le validateur trouve l item et la liste correctes
+                        0 si le validateur trouve la valeur de l item incorrecte
+                       -1 si le validateur trouve la liste incorrecte
+      """
+      valeur = name
+      commentaire="Valeur incorrecte : ajout à la liste refusé"
+      testvalide=1
+
+      # Pas de traitement des valeurs nulles ( a priori clic involontaire
+      if (valeur == None or valeur =="") :
+          commentaire = "Pas de saisie des valeurs nulles"
+          encorevalide = -2 
+          testtype=0
+      else :
+          testtype,comment = self.node.item.object.verif_type(valeur)
+          if not testtype :
+               commentaire =comment
+               encorevalide=-2
+                
+      if (encorevalide ==0) :
+         commentaire=self.node.item.info_erreur_item()
+      if (encorevalide == -1) :
+         commentaire=self.node.item.info_erreur_liste()
+         # On traite le cas ou la liste n est pas valide pour un pb de cardinalite
+         min,max = self.node.item.GetMinMax()
+         if len(self.Liste_valeurs.get_liste()) >= max : 
+            commentaire="La liste a déjà atteint le nombre maximum d'éléments,ajout refusé"
+
+      if testvalide and (encorevalide == 1):
+         min,max = self.node.item.GetMinMax()
+
+         if testtype :
+            liste_valeurs = self.Liste_valeurs.get_liste()
+            if len(liste_valeurs) >= max :
+                commentaire="La liste a déjà atteint le nombre maximum d'éléments,ajout refusé"
+            else :
+               if (self.Liste_valeurs.selection != None):
+                   ligne=self.Liste_valeurs.cherche_selected_item()
+                   liste_valeurs.insert(ligne,valeur)
+               else :
+                   liste_valeurs.append(valeur)
+               try :
+                  self.set_valeur_texte(str(self.entry.get()))
+               except :
+                  pass
+               self.Liste_valeurs.put_liste(liste_valeurs)
+               self.erase_valeur()
+               commentaire="Nouvelle valeur acceptée"
+         else :
+            commentaire ="Type de la valeur incorrecte"
+
+      self.parent.appli.affiche_infos(commentaire)
+
+  def sup_valeur_sans_into(self,name=None):
+      """
+      Méthode qui sert à retirer de la liste des valeurs la valeur sélectionnée
+      """
+      try:
+          self.Liste_valeurs.remove_selected_item()
+          self.display_valeur(self.selected_valeur)
+          self.selected_valeur = None      
+      except:
+          # la valeur sélectionnée n'est pas dans la liste
+          return
+
+  def display_valeur(self,val=None):
+      """
+      Affiche la valeur passée en argument dans l'entry de saisie.
+      Par défaut affiche la valeur du mot-clé simple
+      """
+      if not val :
+          #valeur = self.node.item.getval()
+          valeur = self.node.item.object.getval()
+      else:
+          valeur = val
+      self.entry.delete(0,END)
+      if not valeur : return
+      self.entry.insert(0,str(valeur))
+      
diff --git a/Interface/qtEficas.py b/Interface/qtEficas.py
new file mode 100644 (file)
index 0000000..058bec8
--- /dev/null
@@ -0,0 +1,169 @@
+"""
+
+"""
+
+
+from qt import *
+from myMain_ui import Eficas
+from viewManager import MyTabview
+
+class Appli(Eficas):    
+    """
+    Class implementing the main user interface.
+    """
+    def __init__(self):
+        """
+        Constructor
+        
+        @param loc locale to be used by the UI (string)
+        @param splash reference to the splashscreen (UI.SplashScreen.SplashScreen)
+        """
+        Eficas.__init__(self)
+
+        self.viewmanager = MyTabview(self, self) #MyTabview, MyWorkspace, Listspace
+        self.setCentralWidget(self.viewmanager)
+
+        self.recentMenu = QPopupMenu(self.Fichier)
+        self.Fichier.insertItem(self.trUtf8('Open &Recent Files'), self.recentMenu)
+        self.connect(self.recentMenu,SIGNAL('aboutToShow()'),self.handleShowRecentMenu)
+        
+
+        self.connect(self,PYSIGNAL('preferencesChanged'),
+                     self.viewmanager.handlePreferencesChanged)
+                     
+        
+        self.connect(self.viewmanager,PYSIGNAL('lastEditorClosed'),
+                     self.handleLastEditorClosed)
+        self.connect(self.viewmanager,PYSIGNAL('editorOpened'),
+                     self.handleEditorOpened)
+                             
+        # Initialise the instance variables.
+        self.currentProg = None
+        self.isProg = 0
+        self.utEditorOpen = 0
+        self.utProjectOpen = 0
+        
+        self.inDragDrop = 0
+        self.setAcceptDrops(1)
+        
+        
+    def handleShowRecentMenu(self):
+        """
+        Private method to set up recent files menu.
+        """
+        idx = 0
+        self.recentMenu.clear()
+        
+        for rp in self.viewmanager.recent:
+            id = self.recentMenu.insertItem('&%d. %s' % (idx+1, unicode(rp)),
+                                            self.handleOpenRecent)
+            self.recentMenu.setItemParameter(id,idx)
+            
+            idx = idx + 1
+            
+        self.recentMenu.insertSeparator()
+        self.recentMenu.insertItem(self.trUtf8('&Clear'), self.handleClearRecent)
+        
+    def handleOpenRecent(self, idx):
+        """
+        Private method to open a file from the list of rencently opened files.
+        
+        @param idx index of the selected entry (int)
+        """        
+        self.viewmanager.handleOpen(unicode(self.viewmanager.recent[idx]))
+        
+    def handleClearRecent(self):
+        """
+        Private method to clear the recent files menu.
+        """
+##        self.recent = QStringList()
+        self.viewmanager.recent = QStringList()
+
+        
+    def handleLastEditorClosed(self):
+        """
+        Public slot to handle the lastEditorClosed signal.
+        """
+        print 10*"handleLastEditorClosed: CS_pbruno todo griser les parties k'il faut "
+        pass # CS_pbruno todo griser les parties k'il faut
+        
+    def handleEditorOpened(self, fn):
+        """
+        Public slot to handle the editorOpened signal.
+        
+        @param fn filename of the opened editor (string)
+        """
+        print 10*"handleEditorOpened: CS_pbruno todo griser les parties k'il faut "
+        pass # CS_pbruno todo degriser les parties k'il faut
+        
+        
+    def fileNew(self):        
+        self.viewmanager.newEditor()        
+        
+    def fileOpen(self, prog=None):
+        self.viewmanager.handleOpen(prog)        
+        
+    def fileNewView(self):
+        self.viewmanager.handleNewView()
+        
+    def fileSave(self):
+        self.viewmanager.saveCurrentEditor()
+        
+    def fileSaveAs(self):
+        self.viewmanager.saveAsCurrentEditor()
+        
+    def fileClose(self):
+        self.viewmanager.handleClose()
+        
+    def fileCloseAll(self):
+        self.viewmanager.handleCloseAll()
+        
+    def fileExit(self):
+        self.viewmanager.handleCloseAll()
+        qApp.closeAllWindows()
+        
+    def editCopy(self):
+        self.viewmanager.handleEditCopy()
+      
+    def editCut(self):
+        self.viewmanager.handleEditCut()
+    
+    def editPaste(self):
+        self.viewmanager.handleEditPaste()
+        
+
+  
+        
+    
+if __name__=='__main__':
+    # Modules Python
+    import sys
+    
+    # Modules Eficas
+    import prefs
+    if hasattr(prefs,'encoding'):
+       # Hack pour changer le codage par defaut des strings
+       import sys
+       reload(sys)
+       sys.setdefaultencoding(prefs.encoding)
+       del sys.setdefaultencoding
+       # Fin hack
+
+    #CS_pbruno note: fait implicitement des trucs ces imports (grr)
+    import styles
+    import import_code
+##    import splash
+    import session
+
+    # Analyse des arguments de la ligne de commande
+    options=session.parse(sys.argv)
+    code=options.code
+
+    app = QApplication(sys.argv)    
+    mw = Appli()
+    app.setMainWidget(mw)
+    app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+    mw.show()
+            
+    res = app.exec_loop()
+    sys.exit(res)
diff --git a/Interface/readercata.py b/Interface/readercata.py
new file mode 100644 (file)
index 0000000..c4b604f
--- /dev/null
@@ -0,0 +1,502 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+    Ce module sert à lire un catalogue et à construire
+    un objet CataItem pour Eficas.
+    Il s'appuie sur la classe READERCATA
+"""
+# Modules Python
+import time
+import os,sys,py_compile
+import traceback
+import cPickle
+import Pmw
+
+# Modules Eficas
+import prefs
+##import splash
+import fontes
+import analyse_catalogue
+from Noyau.N_CR import CR
+##from widgets import showinfo,showerror #CS_pbruno todo
+##from widgets import Fenetre            #CS_pbruno todo
+from utils import init_rep_cata_dev
+
+#import catabrowser
+import autre_analyse_cata
+import uiinfo
+
+
+from qt import *
+class SelectVersionDialog(QDialog):        
+    def __init__(self,versions, parent = None,name = None,modal = 0,fl = 0):
+        QDialog.__init__(self,parent,name,modal,fl)
+
+        self.versions   = versions
+        self.strSelectedVersion = None
+        if not name:
+            self.setName("MyDialog")
+
+        self.setSizeGripEnabled(1)
+
+        LayoutWidget = QWidget(self,"Layout1")
+        LayoutWidget.setGeometry(QRect(20,240,476,33))
+        Layout1 = QHBoxLayout(LayoutWidget,0,6,"Layout1")
+
+        self.buttonHelp = QPushButton(LayoutWidget,"buttonHelp")
+        self.buttonHelp.setAutoDefault(1)
+        Layout1.addWidget(self.buttonHelp)
+        Horizontal_Spacing2 = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
+        Layout1.addItem(Horizontal_Spacing2)
+
+        self.buttonOk = QPushButton(LayoutWidget,"buttonOk")
+        self.buttonOk.setAutoDefault(1)
+        self.buttonOk.setDefault(1)
+        Layout1.addWidget(self.buttonOk)
+
+        self.buttonCancel = QPushButton(LayoutWidget,"buttonCancel")
+        self.buttonCancel.setAutoDefault(1)
+        Layout1.addWidget(self.buttonCancel)
+
+        self.textLabel1 = QLabel(self,"textLabel1")
+        self.textLabel1.setGeometry(QRect(140,90,73,20))
+
+        self.comboBox1 = QComboBox(0,self,"comboBox1")
+        self.comboBox1.setGeometry(QRect(310,90,60,20))
+
+        self.languageChange()
+
+        self.resize(QSize(511,282).expandedTo(self.minimumSizeHint()))
+        self.clearWState(Qt.WState_Polished)
+
+        self.connect(self.buttonOk,SIGNAL("clicked()"),self.accept)
+        self.connect(self.buttonCancel,SIGNAL("clicked()"),self.reject)
+        
+        for aVersion in self.versions:
+            self.comboBox1.insertItem( aVersion )
+
+    def languageChange(self):
+        self.setCaption(self.__tr("MyDialog"))
+        self.buttonHelp.setText(self.__tr("&Help"))
+        self.buttonHelp.setAccel(self.__tr("F1"))
+        self.buttonOk.setText(self.__tr("&OK"))
+        self.buttonOk.setAccel(QString.null)
+        self.buttonCancel.setText(self.__tr("&Cancel"))
+        self.buttonCancel.setAccel(QString.null)
+        self.textLabel1.setText(self.__tr("choix version"))
+        
+    def __tr(self,s,c = None):
+        return qApp.translate("MyDialog",s,c)
+
+    def accept(self):
+        self.strSelectedVersion = str(self.comboBox1.currentText())
+        QDialog.accept(self)
+      
+    def reject( self ):
+        ##self.parent.destroy()
+        QDialog.reject(self)
+        
+
+
+
+class READERCATA:
+
+   menu_defs=[
+              ('Catalogue',[
+                           ("Rapport de validation catalogue",'visuCRCATA'),
+                         ]
+              )
+             ]
+
+   button_defs=[]
+
+   def __init__(self,appli,parent):
+      self.appli=appli      
+      self.parent=parent
+      self.code=self.appli.code
+##      self.appli.format_fichier.set('python') #CS_pbruno tosee
+      self.appli.format_fichier = 'python'
+      self.version_code=self.appli.version_code
+      self.fic_cata=None
+      self.OpenCata()
+      self.cataitem=None
+
+   def OpenCata(self):
+      """ 
+          Ouvre le catalogue standard du code courant, cad le catalogue présent
+          dans le répertoire Cata 
+      """
+      message1 = "Compilation des fichiers Eficas \n\n Veuillez patienter ..."
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = message1)
+      self.configure_barre(4)
+
+      liste_cata_possibles=[]
+      for catalogue in self.appli.CONFIGURATION.catalogues:
+          if catalogue[0] == self.code :
+             liste_cata_possibles.append(catalogue)
+
+      if len(liste_cata_possibles)==0:
+          showerror("Import du catalogue","Pas de catalogue defini pour le code %s" % self.code)
+          self.appli.quit()
+          sys.exit(1)
+
+      if self.version_code is not None:
+          # La version a ete fixee
+          for cata in liste_cata_possibles:
+             if self.version_code == cata[1]:
+                self.fic_cata = cata[2]
+##                self.appli.format_fichier.set(cata[3]) #CS_pbruno todo
+                self.appli.format_fichier = cata[3]
+      elif len(liste_cata_possibles)==1:
+          self.fic_cata = liste_cata_possibles[0][2]
+          self.code = self.appli.CONFIGURATION.catalogues[0][0]
+          self.version_code = liste_cata_possibles[0][1]
+##          self.appli.format_fichier.set(liste_cata_possibles[0][3]) #CS_pbruno todo
+          self.appli.format_fichier = liste_cata_possibles[0][3]
+      else:
+          # plusieurs catalogues sont disponibles : il faut demander à l'utilisateur
+          # lequel il veut utiliser ...
+          self.ask_choix_catalogue()
+
+      if self.fic_cata == None :
+          print "Pas de catalogue pour code %s, version %s" %(self.code,self.version_code)
+          sys.exit(0)
+
+      # détermination de fic_cata_c et fic_cata_p
+      self.fic_cata_c = self.fic_cata + 'c'
+      self.fic_cata_p = os.path.splitext(self.fic_cata)[0]+'_pickled.py'
+
+      #if self.appli.test == 0 :
+      #   splash._splash.configure(text = "Debut compil cata: %d s" % time.clock())
+      # compilation éventuelle du catalogue
+      #test = self.compile_cata(self.fic_cata,self.fic_cata_c)
+      #self.update_barre()
+      #if self.appli.test == 0 :
+      #   splash._splash.configure(text = "Fin compil cata: %d s" % time.clock())
+      #if not test : showerror("Compilation catalogue","Impossible de compiler le catalogue %s" %self.fic_cata)
+
+      # import du catalogue
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = "Debut import_cata: %d s" % time.clock())
+      self.cata = self.import_cata(self.fic_cata)
+      self.update_barre()
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = "Fin import_cata: %d s" % time.clock())
+      if not self.cata : 
+          showerror("Import du catalogue","Impossible d'importer le catalogue %s" %self.fic_cata)
+          self.appli.quit()
+          sys.exit(1)
+      #
+      # analyse du catalogue (ordre des mots-clés)
+      #
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = "Debut Retrouve_Ordre: %d s" % time.clock())
+      # Retrouve_Ordre_Cata_Standard fait une analyse textuelle du catalogue
+      # remplacé par Retrouve_Ordre_Cata_Standard_autre qui utilise une numerotation
+      # des mots clés à la création
+      #self.Retrouve_Ordre_Cata_Standard()
+      self.Retrouve_Ordre_Cata_Standard_autre()
+      self.update_barre()
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = "Fin Retrouve_Ordre: %d s" % time.clock())
+      #
+      # analyse des données liées à l'IHM : UIinfo
+      #
+      uiinfo.traite_UIinfo(self.cata)
+      self.update_barre()
+
+      #
+      # traitement des clefs documentaires
+      #
+      self.traite_clefs_documentaires()
+
+      # chargement et analyse des catalogues développeur (le cas échéant)
+      #
+      if self.appli.CONFIGURATION.isdeveloppeur == 'OUI' :
+          init_rep_cata_dev(self.fic_cata,self.appli.CONFIGURATION.path_cata_dev)
+          fic_cata_dev = os.path.join(self.appli.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
+          if os.path.isfile(fic_cata_dev):
+              # il y a bien un catalogue développeur : il faut récupérer le module_object associé ...
+              test = self.compile_cata(fic_cata_dev,fic_cata_dev+'c')
+              if not test :
+                  showinfo("Compilation catalogue développeur",
+                           "Erreur dans la compilation du catalogue développeur")
+                  self.cata = (self.cata,)
+              else:
+                  self.cata_dev =self.import_cata(fic_cata_dev)
+                  #self.Retrouve_Ordre_Cata_Developpeur()
+                  self.Retrouve_Ordre_Cata_Developpeur_autre()
+                  self.cata = (self.cata,self.cata_dev)
+          else:
+              self.cata = (self.cata,)
+      else:
+          self.cata = (self.cata,)
+      titreSuite=" avec le catalogue " + os.path.basename(self.fic_cata)
+      titre=self.appli.titre+titreSuite
+      if self.appli.top:
+        self.appli.top.title(titre)
+      self.appli.titre=titre
+
+   def import_cata(self,cata):
+      """ 
+          Réalise l'import du catalogue dont le chemin d'accès est donné par cata
+      """
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = "Chargement du catalogue")
+      nom_cata = os.path.splitext(os.path.basename(cata))[0]
+      rep_cata = os.path.dirname(cata)
+      sys.path[:0] = [rep_cata]
+      try :
+          o=__import__(nom_cata)
+          return o
+      except Exception,e:
+          traceback.print_exc()
+          return 0
+
+   def Retrouve_Ordre_Cata_Standard_autre(self):
+      """ 
+          Construit une structure de données dans le catalogue qui permet
+          à EFICAS de retrouver l'ordre des mots-clés dans le texte du catalogue.
+          Pour chaque entité du catlogue on crée une liste de nom ordre_mc qui
+          contient le nom des mots clés dans le bon ordre
+      """ 
+      self.cata_ordonne_dico,self.appli.liste_simp_reel=autre_analyse_cata.analyse_catalogue(self.cata)
+
+   def Retrouve_Ordre_Cata_Standard(self):
+      """ 
+          Retrouve l'ordre des mots-clés dans le catalogue, cad :
+           - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
+               l'ordre des mots-clés dans le catalogue
+           - s'il n'a pas été modifié, relie le fichier pickle 
+      """
+      time1 = os.path.getmtime(self.fic_cata)
+      try :
+          time2 = os.path.getmtime(self.fic_cata_p)
+      except:
+          time2 = 0
+      if time2 > time1 :
+          # l'objet catalogue n'a pas été modifié depuis le dernier "pickle"
+          self.Get_Ordre_Cata()
+      else :
+          # le catalogue a été modifié depuis le dernier "pickle" :
+          # il faut retrouver l'ordre du catalogue et refaire pickle
+          self.Get_Ordre_Cata(mode='cata')
+      self.appli.affiche_infos("Catalogue standard chargé")
+
+   def Retrouve_Ordre_Cata_Developpeur(self):
+      """ 
+          Retrouve l'ordre des mots-clés dans le catalogue, cad :
+          - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
+            l'ordre des mots-clés dans le catalogue
+          - s'il n'a pas été modifié, relie le fichier pickle 
+      """
+      if self.code != 'ASTER' : return
+      fic_cata = os.path.join(self.appli.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
+      message="Chargement catalogue développeur présent dans :\n %s..." % self.appli.CONFIGURATION.path_cata_dev
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = message,barre='oui')
+      cata_dev_ordonne = analyse_cata.analyse_catalogue(self,self.fic_cata)
+      self.cata_dev_ordonne_cr = cata_dev_ordonne.cr
+      cata_dev_ordonne_dico = cata_dev_ordonne.entites
+      self.cata_ordonne_dico.update(cata_dev_ordonne_dico)
+      self.appli.affiche_infos(" catalogue(s) développeur(s) chargé(s)" )
+
+   def Retrouve_Ordre_Cata_Developpeur_autre(self):
+      """
+          Retrouve l'ordre des mots-clés dans le catalogue, cad :
+          - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
+            l'ordre des mots-clés dans le catalogue
+          - s'il n'a pas été modifié, relie le fichier pickle
+      """
+      if self.code != 'ASTER' : return
+      message="Chargement catalogue développeur présent dans :\n %s..." % self.appli.CONFIGURATION.path_cata_dev
+##      if self.appli.test == 0 :
+##         splash._splash.configure(text = message,barre='oui')
+      cata_dev_ordonne_dico,self.appli.liste_simp_reel=autre_analyse_cata.analyse_catalogue(self.cata)
+      self.cata_ordonne_dico.update(cata_dev_ordonne_dico)
+      self.appli.affiche_infos(" catalogue(s) développeur(s) chargé(s)" )
+
+   def Get_Ordre_Cata(self,mode='pickle'):
+      """ 
+          Retrouve l'ordre du catalogue :
+            - mode='pickle ': tente de relire le fichier pickle et sinon lance l'analyse du catalogue
+            - mode='cata'   : force l'analyse du catalogue directement sans relire le pickle
+      """
+      if mode == 'pickle' :
+          try:
+              f = open(self.fic_cata_p)
+              u = cPickle.Unpickler(f)
+##              if self.appli.test == 0 :
+##                 splash._splash.configure(text = "Analyse du catalogue")
+              self.cata_ordonne_dico = u.load()
+              f.close()
+          except :
+              # on peut ne pas arriver à relire le fichier pickle s'il a été altéré
+              # ou (le plus probable) s'il a été créé sous un autre OS
+              self.Get_Ordre_Cata(mode='cata')
+      elif mode == 'cata':
+##          if self.appli.test == 0 :
+##              splash._splash.configure(text = "Analyse du catalogue",barre='oui')
+          cata_ordonne = analyse_catalogue.analyse_catalogue(self,self.fic_cata)
+          self.cata_ordonne_cr = cata_ordonne.cr
+          self.cata_ordonne_dico = cata_ordonne.entites
+##          splash._splash.configure(text = "Sauvegarde des informations sur le catalogue")
+          f = open(self.fic_cata_p,'w+')
+          p = cPickle.Pickler(f)
+          p.dump(self.cata_ordonne_dico)
+          f.close()
+      else :
+          raise Exception("Appel à un mode inconnu de Get_Ordre_Cata : %s" % mode)
+          return
+
+   def ask_choix_catalogue(self):
+      """
+      Ouvre une fenêtre de sélection du catalogue dans le cas où plusieurs
+      ont été définis dans Accas/editeur.ini
+      """      
+      # construction du dictionnaire et de la liste des catalogues
+      self.dico_catalogues = {}
+      defaut = None
+      for catalogue in self.appli.CONFIGURATION.catalogues:
+          if catalogue[0] == self.code :
+              self.dico_catalogues[catalogue[1]] = catalogue
+              if len(catalogue) == 5 :
+                  if catalogue[4]=='defaut' : defaut = catalogue[1]
+      liste_choix = self.dico_catalogues.keys()
+      liste_choix.sort()
+      # test si plusieurs catalogues ou non
+      if len(liste_choix) == 0:
+          showerror("Aucun catalogue déclaré pour %s" %self.code)
+          self.appli.quit()
+          sys.exit(1)
+      elif len(liste_choix) == 1:
+          self.fic_cata = self.dico_catalogues[liste_choix[0]][2]
+          self.version_code = liste_choix[0]
+          return          
+          
+      # création d'une boîte de dialogue modale
+##      version_cata = liste_choix[0]
+##      self.fic_cata = self.dico_catalogues[version_cata][2]
+##      self.version_code = version_cata
+##      self.appli.format_fichier = self.dico_catalogues[version_cata][3]
+      diag = SelectVersionDialog( liste_choix, self.parent, "", True )
+      ret = diag.exec_loop()
+      
+      if ret == QDialog.Accepted:
+          version_cata = diag.strSelectedVersion
+          self.fic_cata = self.dico_catalogues[version_cata][2]
+          self.version_code = version_cata
+          self.appli.format_fichier = self.dico_catalogues[version_cata][3]            
+
+
+   def chooseCata(self,txt):
+      """ 
+          Méthode activée lorsque l'utilisateur a fait son choix et cliqué sur 'OK' ou sur 'ANNULER'
+      """
+      if txt == 'OK' :
+          version_cata = self.radiobutton.getcurselection()
+          self.fic_cata = self.dico_catalogues[version_cata][2]
+          self.version_code = version_cata
+##          self.appli.format_fichier.set(self.dico_catalogues[version_cata][3]) #CS_pbruno tosee
+          self.appli.format_fichier = self.dico_catalogues[version_cata][3]
+          self.fenetre_choix_cata.destroy()
+      else:
+          self.parent.destroy()
+
+   def compile_cata(self,cata,catac):
+      """ 
+           Teste si le catalogue a bien besoin d'être recompilé et si oui, le compile et
+           affiche un message dans le splash . Retourne 1 si la compilation s'est bien déroulée,
+           0 sinon.
+      """
+      time1 = os.path.getmtime(cata)
+      try:
+          time2 = os.path.getmtime(catac)
+      except:
+          time2 = 0
+      if time1 > time2:
+          try:
+              # le catalogue doit être recompilé avant d'être importé
+              if self.appli.test == 0 :
+                 splash._splash.configure(text="Compilation du catalogue\nCela peut prendre plusieurs secondes ...")
+              py_compile.compile(cata)
+          except:
+              return 0
+      return 1
+
+
+#--------------------------------------------------------------------------------
+# Méthodes concernant la barre de progression lors de l'analyse du catalogue
+#--------------------------------------------------------------------------------
+
+   def configure_barre(self,nbcommandes):
+      """ Configure la barre de progression en lui passant comme paramètre le
+          nombre de commandes du catalogue qui lui sert à déterminer la longueur de son incrément """
+      try:
+          if self.appli.test == 0 :
+             splash._splash.configure(barre='oui',ratio = nbcommandes)
+      except:
+          pass
+
+   def update_barre(self):
+      """ Update la position de la barre de progression : la fait progresser de son incrément """
+      try:
+          if self.appli.test == 0 :
+             splash._splash.update_barre()
+      except:
+          pass
+
+   def visuCRCATA(self):
+      """
+      Méthode permettant l'affichage du rapport de validation
+      """
+      cr = CR( debut = "Début rapport de validation du catalogue",
+               fin = "Fin rapport de validation du catalogue")
+      titre="rapport de validation du catalogue"
+      if hasattr(self,'cata_ordonne_cr') :
+          cr.add(self.cata_ordonne_cr)
+      if hasattr(self,'cata_dev_ordonne_cr') :
+          cr.add(self.cata_dev_ordonne_cr)
+      for cata in self.cata:
+          if hasattr(cata,'JdC'):
+              cr.add(cata.JdC.report())
+      texte_cr = str(cr)
+      self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
+
+
+   def traite_clefs_documentaires(self):
+      try:
+        self.fic_cata_clef=os.path.splitext(self.fic_cata_c)[0]+'_clefs_docu'
+        f=open(self.fic_cata_clef)
+      except:
+        #print "Pas de fichier associé contenant des clefs documentaires"
+        return
+
+      dict_clef_docu={}
+      for l in f.readlines():
+          clef=l.split(':')[0]
+          docu=l.split(':')[1]
+          docu=docu[0:-1]
+          dict_clef_docu[clef]=docu
+      for oper in self.cata.JdC.commandes:
+           if dict_clef_docu.has_key(oper.nom):
+              oper.docu=dict_clef_docu[oper.nom]
diff --git a/Interface/session.py b/Interface/session.py
new file mode 100644 (file)
index 0000000..b863e88
--- /dev/null
@@ -0,0 +1,285 @@
+# -*- coding: iso-8859-15 -*-
+"""
+Ce module centralise les informations issues de la ligne de commande.
+
+La ligne de commande est parsee avec l'aide du module python optparse.
+Les options possibles sont : -c, -j, -p, -d, -i, -f comme definies ci-dessous.
+
+Un exemple typique d'utilisation est :
+>>> ./appli.py -c V7.3 -d 1 -j aa -i 11 iii -p ppp -i 22 ii -j bb -f ff
+
+qui demande a l'application d'ouvrir trois jeux de commandes.
+
+Le premier (aa) a un include (11,iii) et est la suite du fichier poursuite ppp 
+qui a lui meme un include (22,ii).
+
+Le deuxieme bb est un jeu de commandes simple.
+
+Le troisieme est decrit dans le fichier ff de type .ini
+qui est parse par le module ConfigParser.
+Chaque section du fichier decrit un jeu de commandes.
+Un include est specifie par: numero logique=nom du fichier
+Une poursuite est specifiee par: poursuite=reference a un jeu de commande 
+Cette reference correspond a un nom de section decrivant le jeu de commandes.
+Le jeu de commandes maitre est donne par l'entree globale jdc dans la section jdc.
+
+Exemple:
+[jdc]
+jdc=a
+[a]
+comm=aa
+poursuite=pours
+11=iii
+[pours]
+comm=ppp
+22=ii
+
+La session utilisera le catalogue V7.3 en mode debug.
+"""
+
+try:
+   import optparse
+   from optparse import OptionValueError
+except:
+   from Tools import optparse
+   from Tools.optparse import OptionValueError
+
+import os,traceback
+import ConfigParser
+import prefs
+
+# Les valeurs decodees par optparse sont mises dans un objet dictionnaire-like.
+# On l'utilise comme environnement de session.
+d_env={}
+#
+# L'attribut "studies" de d_env est une liste dans laquelle on range les etudes de niveau global.
+# Une étude est stockée dans un dictionnaire.
+# La clé "comm" du dictionnaire donne le nom du fichier de commandes principal
+# La clé (optionnelle) "pours" du dictionnaire donne les informations pour une poursuite
+# La valeur associée à la clé est un dictionnaire qui contient les informations sur
+# le nom du fichier de commandes de la poursuite (clé "comm"), une éventuelle poursuite
+# (clé "pours") et les includes (clés entières associées à des noms de fichier).
+#
+#
+#
+# Les informations (dictionnaire) associées au fichier de commandes en cours de traitement 
+# sont stockées dans parser.values.current
+# En general, il faut utiliser current et pas parser.values.studies car les informations
+# sont stockées hiérarchiquement
+#
+
+def check_comm(option, opt_str, value, parser):
+    if not hasattr(parser.values,"studies"):
+       parser.values.studies=[]
+       parser.values.comm=[]
+    if not os.path.isfile(value):
+       raise OptionValueError("le fichier de commandes %s n'existe pas" % value)
+    parser.values.comm.append(value)
+    d_study={"comm":value}
+    parser.values.current=d_study
+    parser.values.studies.append(d_study)
+
+def check_poursuite(option, opt_str, value, parser):
+    if parser.values.comm is None:
+       raise OptionValueError("un fichier de commandes doit etre defini avant une poursuite %s" % value)
+    if not os.path.isfile(value):
+       raise OptionValueError("le fichier poursuite %s n'existe pas" % value)
+    #current : fichier de commandes en cours de traitement (dictionnaire des infos)
+    comm=parser.values.current
+    d_study={"comm":value}
+    comm["pours"]=d_study
+    parser.values.current=d_study
+
+def check_include(option, opt_str, value, parser):
+    try:
+       args=[int(parser.rargs[0]),parser.rargs[1]]
+    except:
+       raise OptionValueError("include mal defini %s" % parser.rargs[0:2])
+
+    del parser.rargs[0]
+    del parser.rargs[0]
+
+    if parser.values.comm is None:
+       raise OptionValueError("un fichier de commandes doit etre defini avant un include %s" % args)
+    if not os.path.isfile(args[1]):
+       raise OptionValueError("le fichier include %s n'existe pas" % args[1])
+
+    comm=parser.values.current
+    comm[args[0]]=args[1]
+
+
+def check_jdc(config,jdc,parser,fich):
+    """
+        Fonction : analyse une section de fichier .ini pour en extraire
+                   les informations sur les fichiers poursuite et includes
+                   définis dans cette section
+
+        parser : objet analyseur de la ligne de commande
+        fich : nom du fichier .ini en cours d'analyse
+        config : objet de la classe ConfigParser permettant de parser le fichier fich
+        jdc : nom de la section du fichier fich à analyser
+    """
+    d_study={}
+
+    for o in config.options(jdc):
+       if o == "poursuite":
+          p=config.get(jdc,"poursuite")
+
+          if not config.has_option(p,"comm"):
+             raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,p))
+          comm=config.get(p,"comm")
+          if not os.path.isfile(comm):
+             raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
+
+          pours=check_jdc(config,p,parser,fich)
+          pours["comm"]=comm
+          d_study["pours"]=pours
+          continue
+
+       try:
+          unit=int(o)
+          # si le parametre est un entier, il s'agit d'un include
+          inc=config.get(jdc,o)
+       except:
+          continue
+       if not os.path.isfile(inc):
+          raise OptionValueError("jdc %s fichier include %s, %s n'existe pas" % (fich,unit,inc))
+       d_study[unit]=inc
+
+    return d_study
+
+def check_fich(option, opt_str, fich, parser):
+    """
+        Fonction : parse le fichier fich (format .ini)
+        
+        option : option en cours de traitement
+        opt_str : chaine de caracteres utilisee par l'utilisateur
+        fich : nom du fichier .ini donné par l'utilisateur
+        parser : objet parseur des options de la ligne de commande
+    """
+    if not os.path.isfile(fich):
+       raise OptionValueError("le fichier jdc %s n'existe pas" % fich)
+    if parser.values.fich is None:
+       parser.values.fich=[]
+    parser.values.fich.append(fich)
+    if not hasattr(parser.values,"studies"):
+       parser.values.studies=[]
+       parser.values.comm=[]
+    config = ConfigParser.ConfigParser()
+    config.read([fich])
+    if not config.has_option("jdc","jdc"):
+       raise OptionValueError("jdc %s manque option jdc dans section jdc")
+    jdc=config.get("jdc","jdc")
+
+    if not config.has_option(jdc,"comm"):
+       raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,jdc))
+    comm=config.get(jdc,"comm")
+    if not os.path.isfile(comm):
+       raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
+    parser.values.comm.append(comm)
+
+    d_study=check_jdc(config,jdc,parser,fich)
+    d_study["comm"]=comm
+    parser.values.studies.append(d_study)
+
+def print_pours(d_pours,dec=''):
+    # Les fichiers includes d'abord
+    for k,v in d_pours.items():
+       if k in ("pours","comm"):continue
+       print dec+" include",k," :",v
+
+    if d_pours.has_key("pours"):
+       # Description de la poursuite
+       print dec+" fichier poursuite:",d_pours["pours"]["comm"]
+       print_pours(d_pours["pours"],dec=dec+"++")
+
+def print_d_env():
+    #print d_env
+    if d_env.studies is None:return
+    for study in d_env.studies:
+       print "nom etude:",study["comm"]
+       print_pours(study,dec="++")
+       print
+
+def create_parser():
+    # creation du parser des options de la ligne de commande
+    parser=optparse.OptionParser(usage="usage: %prog [options]",version="%prog 1.9")
+
+    parser.add_option("-j","--jdc",dest="comm",type='string',
+                    action="callback",callback=check_comm,
+                    help="nom du fichier de commandes")
+
+    parser.add_option("-p","--poursuite", type="string",dest="pours",
+                  action="callback", callback=check_poursuite,
+                  help="nom du fichier poursuite")
+
+    parser.add_option("-i","--include", 
+                  action="callback", callback=check_include,
+                  nargs=2, help="numero d'unite suivi du nom du fichier include")
+
+    parser.add_option("-f","--fich", type="string",dest="fich",
+                  action="callback", callback=check_fich,
+                  help="fichier decrivant une etude")
+
+    parser.add_option("-c","--cata", action="store", type="string",dest="cata",
+                  help="version de catalogue a utiliser")
+
+    parser.add_option("-k","--kode", action="store", type="string",dest="code",
+                  help="nom du code a utiliser",default=prefs.code)
+
+    parser.add_option("-d","--debug", action="store", type="int",dest="debug",
+                  help="niveau de debug")
+
+    return parser
+
+def parse(args):
+    parser=create_parser()
+    (options,args)=parser.parse_args(args[1:])
+    if not hasattr(options,"studies"):
+       options.studies=[]
+       options.comm=[]
+    try:
+       del parser.values.current
+    except:
+       pass
+
+    for file in args:
+         if os.path.isfile(file):
+            options.comm.append(file)
+            options.studies.append({"comm":file})
+         else:
+            parser.error("incorrect number of arguments")
+
+    global d_env
+    d_env=options
+    #print_d_env()
+    return options
+
+def get_unit(d_study,appli):
+    """
+       Fonction : construit et retourne un dictionnaire contenant les informations
+                  sur les fichiers poursuite et includes sous la forme adaptée
+                  pour EFICAS
+                  [None : nom_fichier, texte_source, unites_associees,           # poursuite
+                   numero_include : nom_fichier, texte_source, unites_associees, # include
+                    ...] 
+       d_study : dictionnaire de l'etude
+       appli : objet application EFICAS (permet d'acceder aux services comme get_source)
+    """
+    return get_dunit(d_study,appli)
+
+def get_dunit(d_unit,appli):
+    d={}
+    if d_unit.has_key("pours"):
+       # on a une poursuite
+       comm=d_unit["pours"]["comm"]
+       g=get_dunit(d_unit["pours"],appli)
+       text=appli.get_source(comm)
+       d[None]=comm,text,g
+
+    for k,v in d_unit.items():
+       if k in ("pours","comm"): continue
+       text=appli.get_source(v)
+       d[k]=v,text,d
+
+    return d
diff --git a/Interface/styles.py b/Interface/styles.py
new file mode 100644 (file)
index 0000000..dd90ee6
--- /dev/null
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+import os
+import prefs
+import basestyle
+from basestyle import STYLE,style
+
+inistylefile=os.path.join(prefs.REPINI,"style.py")
+if os.path.isfile(inistylefile):
+   execfile(inistylefile)
+
+userstylefile=os.path.expanduser("~/Eficas_install/style.py")
+if os.path.isfile(userstylefile):
+   execfile(userstylefile)
+
+import fontes
+for attr in dir(style):
+   if attr[0]=='_':continue
+   if not hasattr(fontes,attr):continue
+   setattr(fontes,attr,getattr(style,attr))
diff --git a/Interface/treeitemincanvas.py b/Interface/treeitemincanvas.py
new file mode 100644 (file)
index 0000000..c719789
--- /dev/null
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+"""
+# Modules Python
+import sys
+import Tkinter,Pmw
+
+# Modules Eficas
+import Objecttreeitem
+##import treewidget
+import browser
+
+from qt import *
+
+class QTTREEITEMINCANVAS( treewidget.QTTree ):
+    #def __init__(self, jdc, nom="", parent=None, appli=None, sel=None,):
+    def __init__( self, jdc, appli = None, parent=None, nom="" ):
+##        self.object=jdc
+##        self.nom=nom
+        
+        if not appli:
+            class Appli:
+                def affiche_infos(self,message):
+                    pass
+            appli=Appli()
+            
+        item=Objecttreeitem.make_objecttreeitem( appli, nom, jdc )
+
+##        if not sel:
+##             def sel(event=None):
+##                return
+        print 'itemmmmmmmmm', item
+        print 'parenttttttt', parent
+        treewidget.QTTree.__init__( self, item, appli, parent  ) #, command=sel , rmenu=rmenu )
+##        self.appli.setMainWidget( self.tree )
+##        self.tree.show()
+##        self.appli.exec_loop()
+   
+##    def update(self):
+##        """Cette methode est utilisee pour signaler une mise a jour des objets associes"""
+##        self.tree.update()
+##
+##    def supprime(self):
+##        #print "supprime",self
+##        self.tree.supprime()
+##        self.tree=None
+        
+        
+##      self.canvas.destroy()
+##      self.canvas=None
+
+   #def __del__(self):
+   #   print "__del__",self
+   
+
+   
+   
+
+
+
+class TREEITEMINCANVAS:
+   def __init__(self,object,nom="",parent=None,appli=None,sel=None,rmenu=None):
+      self.object=object
+      self.nom=nom
+
+      if not appli:
+         class Appli:
+            def affiche_infos(self,message):
+               pass
+         appli=Appli()
+      self.appli=appli
+
+      if not parent:
+         parent=Tkinter.Tk()
+         Pmw.initialise(parent)
+      self.parent=parent
+
+      self.item=Objecttreeitem.make_objecttreeitem(self.appli,self.nom,self.object)
+      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):
+            return
+      self.tree=treewidget.Tree(self.appli,self.item,self.canvas,command=sel,rmenu=rmenu)
+      self.tree.draw()
+
+   def mainloop(self):
+      self.parent.mainloop()
+
+   def update(self):
+      """Cette methode est utilisee pour signaler une mise a jour des objets associes"""
+      self.tree.update()
+
+   def supprime(self):
+      #print "supprime",self
+      self.tree.supprime()
+      self.tree=None
+      self.canvas.destroy()
+      self.canvas=None
+
+   #def __del__(self):
+   #   print "__del__",self
+
diff --git a/Interface/uiinfo.py b/Interface/uiinfo.py
new file mode 100644 (file)
index 0000000..799728d
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+   Ce module sert à construire les structures de données porteuses 
+   des informations liées aux groupes de commandes
+"""
+import types
+
+class UIINFO:
+   """
+       Pour le moment la classe UIINFO ne sait traiter que des infos
+       portant sur la definition des groupes de commandes
+       Les autres informations sont ignorées
+   """
+   def __init__(self,parent,groupes=None,**args):
+      """
+         Initialiseur de la classe UIINFO.
+         Initialise a partir du dictionnaire UIinfo passé à
+         un objet ENTITE les attributs de la classe
+      """
+      # L'attribut parent stocke le lien vers l'objet ENTITE relié à UIINFO
+      self.parent=parent
+      self.groupes=groupes
+      if groupes == None:
+         # L'entite n'a pas de groupe associé. On lui associe le groupe "DEFAUT"
+         self.groupes=("DEFAUT",)
+      if type(self.groupes) != types.TupleType:
+         self.groupes=(self.groupes,)
+
+def traite_commande(commande,niveau):
+    """
+        Cette fonction cree l'attribut UI de l'objet commande
+        à partir des informations contenues dans UIinfo
+    """
+    uiinfo=commande.UIinfo or {}
+    UI=UIINFO(commande,**uiinfo)
+    commande.UI=UI
+    if "CACHE" in UI.groupes:
+        # La commande est cachee aux utilisateurs
+        #niveau.dict_groupes["CACHE"].append(commande.nom)
+        pass
+    else:
+        # On ajoute la commande dans tous les groupes specifies
+        for grp in UI.groupes:
+            if not niveau.dict_groupes.has_key(grp): niveau.dict_groupes[grp]=[]
+            niveau.dict_groupes[grp].append(commande.nom)
+
+def traite_niveau(niveau):
+   if niveau.l_niveaux == ():
+       # Il n'y a pas de sous niveaux. niveau.entites ne contient que des commandes
+       niveau.dict_groupes={}
+       for oper in niveau.entites:
+           traite_commande(oper,niveau)
+       # A la fin les cles du dictionnaire dict_groupes donnent la liste des groupes
+       # sans doublon
+       niveau.liste_groupes=niveau.dict_groupes.keys()
+       # On ordonne les listes alphabétiquement
+       niveau.liste_groupes.sort()
+       for v in niveau.dict_groupes.values():v.sort()
+       #print niveau.liste_groupes
+       #print niveau.dict_groupes
+   else:
+       for niv in niveau.l_niveaux:
+           traite_niveau(niv)
+
+def traite_UIinfo(cata):
+   """
+      Cette fonction parcourt la liste des commandes d'un catalogue (cata)
+      construit les objets UIINFO à partir de l'attribut UIinfo de la commande
+      et construit la liste complète de tous les groupes présents
+   """
+   #dict_groupes["CACHE"]=[]
+   #XXX Ne doit pas marcher avec les niveaux
+   if cata.JdC.l_niveaux == ():
+       # Il n'y a pas de niveaux
+       # On stocke la liste des groupes et leur contenu dans le JdC
+       # dans les attributs liste_groupes et dict_groupes
+       cata.JdC.dict_groupes={}
+       for commande in cata.JdC.commandes:
+           traite_commande(commande,cata.JdC)
+       # A la fin les cles du dictionnaire dict_groupes donnent la liste des groupes
+       # sans doublon
+       cata.JdC.liste_groupes=cata.JdC.dict_groupes.keys()
+       # On ordonne les listes alphabétiquement
+       cata.JdC.liste_groupes.sort()
+       for v in cata.JdC.dict_groupes.values():v.sort()
+       #print cata.JdC.liste_groupes
+       #print cata.JdC.dict_groupes
+   else:
+       # Le catalogue de commandes contient des définitions de niveau
+       for niv in cata.JdC.l_niveaux:
+          traite_niveau(niv)
+
+
+
+
diff --git a/Interface/uniqueassdpanel.py b/Interface/uniqueassdpanel.py
new file mode 100644 (file)
index 0000000..bc777b7
--- /dev/null
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from uniquepanel import UNIQUE_Panel
+
+
+class UNIQUE_ASSD_Panel(UNIQUE_Panel):
+  """
+  Classe servant à définir le panneau associé aux objets qui attendent une valeur unique
+  d'un type dérivé d'ASSD
+  """
+  def valid_valeur_automatique(self):
+      """
+         Réalise la validation d'un concept sans remonter dans le
+         node parent dans le cas ou il n'y a qu'un concept possible (liste de longueur 1)
+         Identique à valid_valeur moins appel de self.node.parent.select()
+         On pourrait supposer que le seul concept présent est valide et donc ne pas
+         réaliser tous les tests de vérification.
+      """
+      if self.parent.modified == 'n' : self.parent.init_modif()
+      valeur = self.get_valeur()
+      self.erase_valeur()
+      anc_val = self.node.item.get_valeur()
+      valeur,validite=self.node.item.eval_valeur_item(valeur)
+      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)
+      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()
+      else :
+          cr = self.node.item.get_cr()
+          mess = "Valeur du mot-clé non autorisée :"+cr.get_mess_fatal()
+          self.reset_old_valeur(anc_val,mess=mess)
+
+  def makeValeurPage(self,page,reel="non"):
+      """
+          Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une 
+          SD de type dérivé d'ASSD
+      """
+      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
+      # et de la liste des SD du bon type (constituant la liste des choix)
+      bulle_aide=self.get_bulle_aide()
+      aide=self.get_aide()
+      aide= justify_text(texte=aide)
+      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
+
+      # Remplissage du panneau
+      self.valeur_choisie = StringVar()
+      self.valeur_choisie.set('')
+      min,max =  self.node.item.GetMinMax()
+      if (min == 1 and min == max and len(liste_noms_sd)==1 ):
+          if self.valeur_choisie.get() != liste_noms_sd[0]:
+            if ('R' not in self.node.item.get_type()) :
+                self.valeur_choisie.set(liste_noms_sd[0])
+                self.valid_valeur_automatique()
+         
+      self.frame_valeur = Frame(page)
+      self.frame_valeur.pack(fill='both',expand=1)
+      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+      self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
+                                         items=liste_noms_sd,
+                                         labelpos='n',
+                                         label_text="Structures de données du type\n requis par l'objet courant :",
+                                         listbox_height = 6,
+                                         selectioncommand=self.select_valeur_from_list,
+                                         dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
+      self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
+      Label(self.frame_valeur,text='Structure de donnée choisie :').place(relx=0.05,rely=0.6)
+      Label(self.frame_valeur,textvariable=self.valeur_choisie).place(relx=0.5,rely=0.6)
+      self.but_val = Button(self.frame_valeur,text = "Valider",command= self.Choisir)
+      self.but_val.place(relx=0.3,rely=0.8,relwidth=0.35)
+
+      # affichage de la valeur courante
+      self.display_valeur()
+      if self.__class__.__name__ == 'UNIQUE_ASSD_Panel_Reel' :
+        Label(self.frame_valeur,text='Valeur Réelle').place(relx=0.1,rely=0.9)
+        self.entry = Entry(self.frame_valeur,relief='sunken')
+        self.entry.place(relx=0.28,rely=0.9,relwidth=0.6)
+        self.entry.bind("<Return>",lambda e,c=self.valid_valeur_reel:c())
+        self.entry.bind("<KP_Enter>",lambda e,c=self.valid_valeur_reel:c())
+
+
+
+  def get_bulle_aide(self):
+      """
+      Retourne l'aide associée au panneau
+      """
+      return "Double-cliquez sur la structure de donnée désirée pour valoriser le mot-clé simple courant"
+
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide indiquant de quel type doit être la valeur à donner par l'utilisateur
+      """
+      mc = self.node.item.get_definition()
+      try :
+              type = mc.type[0].__name__  
+      except :
+        type = str(mc.type[0])
+      if len(mc.type)>1 :
+          for typ in mc.type[1:] :
+              try :
+                l=typ.__name__
+              except:
+                l=str(typ)
+              type = type + ' ou '+l
+      commentaire="Un objet de type "+type+" est attendu"
+      aideval=self.node.item.aide()
+      commentaire=commentaire +"\n"+ aideval
+      return commentaire
+
+    
+  def select_valeur_from_list(self):
+      """
+      Affecte à valeur choisie la sélection courante dans la liste des choix proposée
+      """
+      if len(self.listbox.get()) == 0 : return
+      if len(self.listbox.getcurselection()) == 0 : return
+      choix = self.listbox.getcurselection()[0]
+      self.valeur_choisie.set(choix)
+      self.listbox.component("listbox").focus_set()
+
+  def choose_valeur_from_list(self,command):
+      """
+      Affecte à valeur choisie la sélection courante dans la liste des choix proposée
+      Exécute command
+      """
+      if len(self.listbox.get()) == 0 : return
+      if len(self.listbox.getcurselection()) == 0 : return
+      choix = self.listbox.getcurselection()[0]
+      self.valeur_choisie.set(choix)
+      apply(command,(),{})
+
+  def Choisir(self) :
+      #Appeler par le bouton Valider
+      self.choose_valeur_from_list(self.valid_valeur)
+      
+  def get_valeur(self):
+      """
+      Retourne la valeur donnée par l'utilisateur au MCS
+      """
+      return self.valeur_choisie.get()
+    
+  def display_valeur(self):
+      """
+      Affiche la valeur de l'objet pointé par self
+      """
+      valeur = self.node.item.get_valeur()
+      if valeur == None or valeur == '' : return # pas de valeur à afficher ...
+      self.valeur_choisie.set(getattr(valeur,"nom","unknown"))
+
+  def erase_valeur(self):
+      pass
+
+  def appel_make(self,page):
+      self.makeValeurPage(page,reel="oui")
+      
+class UNIQUE_ASSD_Panel_Reel(UNIQUE_ASSD_Panel):
+  def valid_valeur_reel(self):
+      if self.parent.modified == 'n' : self.parent.init_modif()
+      anc_val = self.node.item.get_valeur()
+      valeurentree = self.entry.get()
+      self.valeur_choisie.set(valeurentree)
+      self.valid_valeur()
+
+  def display_valeur(self):
+      valeur = self.node.item.get_valeur()
+      if valeur == None or valeur == '' : return # pas de valeur à afficher ...
+      if type(valeur) == types.FloatType :
+         self.valeur_choisie.set(valeur)
+      else :
+         self.valeur_choisie.set(valeur.nom)
+
+       
+
diff --git a/Interface/uniquebasepanel.py b/Interface/uniquebasepanel.py
new file mode 100644 (file)
index 0000000..74e3d87
--- /dev/null
@@ -0,0 +1,148 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+from Tkinter import Widget
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import FenetreDeParametre
+from widgets import showerror
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from uniquepanel import UNIQUE_Panel
+
+
+class UNIQUE_BASE_Panel(UNIQUE_Panel):
+  """
+  Classe servant à définir le panneau associé aux mots-clés simples qui attendent
+  une valeur d'un type de base (entier, réel ou string).
+  """
+  def makeValeurPage(self,page):
+      """
+      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
+      de base cad entier, réel, string ou complexe
+      """
+      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
+      # et de la liste des SD du bon type (constituant la liste des choix)
+      bulle_aide=self.get_bulle_aide()
+      aide=self.get_aide()
+      aide= justify_text(texte=aide)
+      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
+      # Remplissage du panneau
+      self.frame_valeur = Frame(page)
+      self.frame_valeur.pack(fill='both',expand=1)
+      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+      self.label = Label(self.frame_valeur,text='Valeur :')
+      self.label.place(relx=0.1,rely=0.2)
+      self.entry = Entry(self.frame_valeur,relief='sunken')
+      self.entry.place(relx=0.28,rely=0.2,relwidth=0.6)
+      self.entry.bind("<Return>",lambda e,c=self.valid_valeur:c())
+      self.entry.bind("<KP_Enter>",lambda e,c=self.valid_valeur:c())
+      # aide associée au panneau
+      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.9,anchor='n')
+      # bouton parametre
+      bouton_parametres = Button(self.frame_valeur, text="Parametres", command=self.affiche_parametre)
+      bouton_parametres.place(relx=0.28,rely=0.5,relwidth=0.4)
+      bouton_val = Button(self.frame_valeur, text="Valider", command=self.valide)
+      bouton_val.place(relx=0.28,rely=0.6,relwidth=0.4)
+      # affichage de la valeur du MCS
+      self.display_valeur()
+
+  def valide(self):
+      self.valid_valeur()
+
+  def affiche_parametre(self) :
+     if self.node.item.get_liste_param_possible() != [ ]:
+        txtparam=""
+        for param in self.node.item.get_liste_param_possible():
+           txtparam=txtparam+repr(param)+"\n"
+        if txtparam=="":
+           showerror("Aucun parametre ","Pas de parametre de ce type")
+        else :
+           try :
+                   self.fenetreparam.destroy()
+           except :
+                pass
+           self.fenetreparam=FenetreDeParametre( self, self.node.item, self.parent.appli, txtparam)
+
+  def destroy(self):
+      try :
+              self.fenetreparam.destroy()
+      except :
+        pass
+      Widget.destroy(self)
+
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide indiquant de quel type doit être la valeur
+      du mot-clé simple fournie par l'utilisateur
+      """
+      mc = self.node.item.get_definition()
+      d_aides = { 'TXM' : "Une chaîne de caractères est attendue",
+                  'R'   : "Un réel est attendu",
+                  'I'   : "Un entier est attendu"}
+      type = mc.type[0]
+      commentaire=d_aides.get(type,"Type de base inconnu")
+      aideval=self.node.item.aide()
+      commentaire=commentaire +"\n"+ aideval
+      return commentaire
+
+  def get_bulle_aide(self):
+      """
+      Retourne la bulle d'aide associée au panneau et affichée par clic droit
+      """
+      return """Saisissez la valeur que vous voulez affecter au mot-clé simple
+      dans la zone de saisie et pressez <Return>"""
+      
+  def display_valeur(self):
+      """
+      Affiche la valeur de l'objet pointé par self
+      """
+      valeur = self.node.item.get_valeur()
+      if valeur == None or valeur == '' : # pas de valeur à afficher ...
+         self.entry.delete(0,END)
+         self.entry.focus()
+         return
+
+      valeur_texte=self.get_valeur_texte(valeur)
+      if valeur_texte != "":
+         valeur=valeur_texte
+      self.entry.delete(0,END)
+      self.entry.insert(0,valeur)
+      self.entry.focus()
+      
diff --git a/Interface/uniquecomppanel.py b/Interface/uniquecomppanel.py
new file mode 100644 (file)
index 0000000..3aa0907
--- /dev/null
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from uniquepanel import UNIQUE_Panel
+
+      
+class UNIQUE_COMP_Panel(UNIQUE_Panel):
+  """
+  Classe servant à définir le panneau associé aux mots-clés simples
+  qui attendent une valeur de type complexe
+  """
+  def makeValeurPage(self,page):
+      """
+      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être de type
+      de base cad entier, réel, string ou complexe
+      """
+      # Récupération de l'aide associée au panneau et de l'aide destinée à l'utilisateur
+      bulle_aide=self.get_bulle_aide()
+      aide=self.get_aide()
+      aide= justify_text(texte=aide)
+      # Remplissage du panneau
+      self.frame_valeur = Frame(page)
+      self.frame_valeur.pack(fill='both',expand=1)
+      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+      self.label  = Label(self.frame_valeur,text='Complexe de la forme : a+bj')
+      self.label1 = Label(self.frame_valeur,text='Imaginaire')
+      self.label2 = Label(self.frame_valeur,text='Phase')
+      self.label3 = Label(self.frame_valeur,text='OU')
+      self.label.place (relx=0.15,rely=0.1)
+      self.label1.place(relx=0.6,rely=0.50)
+      self.label2.place(relx=0.6,rely=0.57)
+      self.label3.place(relx=0.15,rely=0.4)
+      self.typ_cplx=StringVar()
+      self.typ_cplx.set('RI')
+      rb1 = Radiobutton(self.frame_valeur, text='RI  : Réel',variable=self.typ_cplx,value='RI')
+      rb2 = Radiobutton(self.frame_valeur, text='MP  : Module',variable=self.typ_cplx,value='MP')
+      rb1.place(relx=0.15,rely = 0.50)
+      rb2.place(relx=0.15,rely = 0.57)
+      self.entry1 = Pmw.EntryField(self.frame_valeur,validate='real')
+      self.entry2 = Pmw.EntryField(self.frame_valeur,validate='real')
+      self.entry3 = Pmw.EntryField(self.frame_valeur)
+      self.entry1.component('entry').bind("<Return>",lambda e,s=self:s.entry2.component('entry').focus())
+      self.entry1.component('entry').bind("<KP_Enter>",lambda e,s=self:s.entry2.component('entry').focus())
+      self.entry2.component('entry').bind("<Return>",lambda e,c=self.valid_valeur:c())
+      self.entry2.component('entry').bind("<KP_Enter>",lambda e,c=self.valid_valeur:c())
+      self.entry3.component('entry').bind("<Return>",lambda e,c=self.valid_complexe:c())
+      self.entry3.component('entry').bind("<KP_Enter>",lambda e,c=self.valid_complexe:c())
+      self.entry1.place(relx=0.15,rely = 0.65,relwidth=0.35)
+      self.entry2.place(relx=0.60,rely = 0.65,relwidth=0.35)
+      self.entry3.place(relx=0.15,rely = 0.20,relwidth=0.60)
+      self.entry1.focus()
+      self.bouton_val=Button(self.frame_valeur,text="Valider",command=self.valider,width=14)
+      self.bouton_val.place(relx=0.4,rely=0.8)
+      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.9,anchor='n')
+      # affichage de la valeur du MCS
+      self.display_valeur()
+
+  def valider(self):
+      if ((self.entry3.get() != None) and (self.entry3.get() != "" )):
+         self.erase_valeur()
+         self.valid_complexe()
+      else :
+         self.valid_valeur()
+         
+
+  def display_valeur(self):
+      """
+      Affiche la valeur de l'objet pointé par self
+      """
+      valeur = self.node.item.get_valeur()
+      if valeur == None or valeur == '' : return # pas de valeur à afficher ...
+      self.entry1.delete(0,END)
+      self.entry2.delete(0,END)
+      self.entry3.delete(0,END)
+      if type(valeur) not in (types.ListType,types.TupleType) :
+         self.display_complexe()
+      else:
+         typ_cplx,x1,x2=valeur
+         self.typ_cplx.set(typ_cplx)
+         self.entry1.setentry(x1)
+         self.entry2.setentry(x2)
+
+  def display_complexe(self):
+      valeur = self.node.item.get_valeur()
+      self.entry3.setentry(valeur)
+
+  def get_bulle_aide(self):
+      """
+      Retourne la bulle d'aide du panneau
+      """
+      return """-Choisissez votre format de saisie du complexe :
+      \t 'RI' = parties réelle et imaginaire
+      \t 'MP' = module/phase (en degrés)
+      - Saisissez ensuite dans les deux zones de saisie les deux nombres attendus"""
+
+  def get_aide(self):
+      """
+      Retourne la phrase d'aide décrivant le type de la valeur que peut prendre
+      le mot-clé simple courant
+      """
+      commentaire='Un complexe est attendu'
+      aideval=self.node.item.aide()
+      commentaire=commentaire +"\n"+ aideval
+      return commentaire
+
+  def get_valeur(self):
+      """
+      Retourne le complexe saisi par l'utilisateur
+      """
+      l=[]
+      l.append(self.typ_cplx.get())
+      try :
+         l.append(string.atof(self.entry1.get()))
+         l.append(string.atof(self.entry2.get()))
+      except :
+         return None
+      return `tuple(l)`
+
+  def erase_valeur(self):
+      """
+      Efface les entries de saisie
+      """
+      self.typ_cplx.set('RI')
+      self.entry1.delete(0,END)
+      self.entry2.delete(0,END)
+      
+  def valid_complexe(self):
+      valeurentree=self.entry3.get()
+      self.valid_valeur(valeurentree=valeurentree)
diff --git a/Interface/uniqueintopanel.py b/Interface/uniqueintopanel.py
new file mode 100644 (file)
index 0000000..6532e3f
--- /dev/null
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from uniquepanel import UNIQUE_Panel
+
+class UNIQUE_INTO_Panel(UNIQUE_Panel):
+  """
+  Classe définissant le panel associé aux mots-clés qui demandent
+  à l'utilisateur de choisir une seule valeur parmi une liste de valeurs
+  discrètes
+  """
+  def makeValeurPage(self,page):
+      """
+      Génère la page de saisie d'une seule valeur parmi un ensemble
+      discret de possibles
+      """
+      # récupération de la bulle d'aide et de l'objet mc
+      bulle_aide=self.get_bulle_aide()
+      objet_mc = self.node.item.get_definition()
+      # remplissage du panel
+      self.frame_valeur = Frame(page)
+      self.frame_valeur.pack(fill='both',expand=1)
+      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : 
+                              s.parent.appli.affiche_aide(e,a))
+      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+      #l_choix=list(objet_mc.into)
+      #l_choix.sort()
+      l_choix=self.node.item.get_liste_possible([])
+      self.label = Label(self.frame_valeur,text='Choisir une valeur :')
+      self.label.pack(side='top')
+      self.frame = Frame(page)
+      self.frame.place(relx=0.33,rely=0.2,relwidth=0.33,relheight=0.6)
+
+
+      liste_commandes = (("<Button-1>",self.selectChoix),
+                         ("<Button-3>",self.deselectChoix),
+                         ("<Double-Button-1>",self.record_valeur))
+      self.Liste_choix = ListeChoix(self,self.frame,l_choix,
+                                    liste_commandes = liste_commandes,
+                                    titre="Valeurs possibles",optionReturn="oui")
+      self.Liste_choix.affiche_liste()
+      self.bouton_val = Button(self.frame_valeur,
+                               text = "Valider",
+                               command=self.record_valeur_ligne,
+                               width=14)
+      self.bouton_val.place(relx=0.33,rely=0.85)
+
+  def record_valeur_ligne(self):
+      valeur=self.Liste_choix.arg_selected
+      self.record_valeur(valeur)
+
+  def get_bulle_aide(self):
+      """
+      Retourne la bulle d'aide affectée au panneau courant (affichée par clic droit)
+      """
+      return """Double-cliquez sur la valeur désirée
+      pour valoriser le mot-clé simple courant"""
+
diff --git a/Interface/uniquepanel.py b/Interface/uniquepanel.py
new file mode 100644 (file)
index 0000000..9980030
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+##from Tkinter import *
+##import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+##import panels
+##import images
+##from widgets import ListeChoix
+##from widgets import FenetreDeSelection
+##
+##from Noyau.N_CR import justify_text
+##from utils import substract_list
+##
+### Import des panels
+##from newsimppanel import newSIMPPanel
+
+class UNIQUE_Panel:
+    pass #CS_pbruno todo
+    
+##class UNIQUE_Panel(newSIMPPanel):    
+##  """
+##  Classe virtuelle servant de classe mère à toutes celles définissant un panneau
+##  permettant l'affichage et la saisie d'une valeur unique pour le mot-clé simple
+##  """
+##
+##  def erase_valeur(self):
+##      """
+##      Efface l'entry de saisie
+##      """
+##      self.entry.delete(0,END)
+##
+##  def get_valeur(self):
+##      """
+##      Retourne la valeur donnée par l'utilisateur
+##      """
+##      return self.entry.get()
+##    
+##  
+##  def valid_valeur(self,valeurentree=None):
+##      """
+##      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()
+##      anc_val = self.node.item.get_valeur()
+##      if valeurentree== None :
+##         valeurentree = self.get_valeur()
+##      valeur,validite=self.node.item.eval_valeur(valeurentree)
+##      if not validite :
+##             commentaire = "impossible d'évaluer : %s " %`valeurentree`
+##             self.display_valeur()
+##             self.parent.appli.affiche_infos(commentaire)
+##             return
+##   
+##      test = self.node.item.set_valeur(valeur)
+##      if test :
+##          self.set_valeur_texte(str(valeurentree))
+##       
+##      if not test :
+##          mess = "impossible d'évaluer : %s " %`valeur`
+##          self.parent.appli.affiche_infos("Valeur du mot-clé non autorisée : "+mess)
+##      elif self.node.item.isvalid() :
+##          self.parent.appli.affiche_infos('Valeur du mot-clé enregistrée')
+##      else :
+##          cr = self.node.item.get_cr()
+##          mess = "Valeur du mot-clé non autorisée "+cr.get_mess_fatal()
+##          self.reset_old_valeur(anc_val,mess=mess)
+##
+##      self.display_valeur()
diff --git a/Interface/uniquesdcopanel.py b/Interface/uniquesdcopanel.py
new file mode 100644 (file)
index 0000000..49ecc2a
--- /dev/null
@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+# Modules Python
+import string,types,os
+from Tkinter import *
+import Pmw
+from copy import copy,deepcopy
+import traceback
+
+# Modules Eficas
+import Objecttreeitem
+import prefs
+import panels
+import images
+from widgets import ListeChoix
+from widgets import FenetreDeSelection
+
+from Noyau.N_CR import justify_text
+from utils import substract_list
+
+# Import des panels
+from uniqueassdpanel import UNIQUE_ASSD_Panel
+
+
+class UNIQUE_SDCO_Panel(UNIQUE_ASSD_Panel):
+  """
+  Classe servant à définir le panneau correspondant à un mot-clé simple
+  qui attend une valeur unique de type dérivé d'ASSD ou non encore
+  existante (type CO(...) utilisé dans les macros uniquement)
+  """
+  def makeValeurPage(self,page):
+      """
+      Génère la page de saisie de la valeur du mot-clé simple courant qui doit être une SD de type dérivé
+      d'ASSD
+      """
+      # Récupération de l'aide associée au panneau, de l'aide destinée à l'utilisateur,
+      # et de la liste des SD du bon type (constituant la liste des choix)
+      bulle_aide=self.get_bulle_aide()
+      aide=self.get_aide()
+      aide= justify_text(texte=aide)
+      liste_noms_sd = self.node.item.get_sd_avant_du_bon_type()
+      # Remplissage du panneau
+      self.frame_valeur = Frame(page)
+      self.frame_valeur.pack(fill='both',expand=1)
+      self.frame_valeur.bind("<Button-3>",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a))
+      self.frame_valeur.bind("<ButtonRelease-3>",self.parent.appli.efface_aide)
+      # affichage de la liste des SD existantes et du bon type
+      self.listbox = Pmw.ScrolledListBox(self.frame_valeur,
+                                         items=liste_noms_sd,
+                                         labelpos='n',
+                                         label_text="Structures de données du type\n requis par l'objet courant :",
+                                         listbox_height = 6,
+                                         selectioncommand=self.select_valeur_from_list,
+                                         dblclickcommand=lambda s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
+      self.listbox.component("listbox").bind("<Return>",lambda e,s=self,c=self.valid_valeur : s.choose_valeur_from_list(c))
+      if liste_noms_sd != [] :
+         self.listbox.place(relx=0.5,rely=0.3,relheight=0.4,anchor='center')
+         self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ", items = ('NON','OUI'),
+                                         menubutton_width=10)
+      else :
+         self.b_co = Pmw.OptionMenu(self.frame_valeur,labelpos='w',label_text = "Nouveau concept : ", items = ('OUI',),
+                                         menubutton_width=10)
+      # affichage du bouton 'Nouveau concept'
+      self.b_co.configure(command = self.ask_new_concept)
+      if liste_noms_sd != [] :
+         self.b_co.place(relx=0.05,rely=0.6,anchor='w')
+      else :
+         self.b_co.place(relx=0.05,rely=0.3,anchor='w')
+      self.label_co = Label(self.frame_valeur,text='Nom du nouveau concept :')
+      self.entry_co = Entry(self.frame_valeur)
+      self.entry_co.bind('<Return>',self.valid_nom_concept_co)
+      self.entry_co.bind('<KP_Enter>',self.valid_nom_concept_co)
+      # affichage du label de la structure de donnée choisie
+      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.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')
+      # affichage de la valeur courante
+      self.display_valeur()
+      if liste_noms_sd == [] :
+          self.b_co.invoke('OUI')
+      
+  def get_bulle_aide(self):
+      """
+      Retourne la bulle d'aide du panneau
+      """
+      return """Double-cliquez sur la structure de donnée désirée
+      pour valoriser le mot-clé simple courant ou cliquez sur NOUVEAU CONCEPT pour
+      entrer le nom d'un concept non encore existant"""
+
+  def valid_valeur(self):
+      """
+      Teste si la valeur fournie par l'utilisateur est une valeur permise :
+      - si oui, l'enregistre
+      - si non, restaure l'ancienne valeur
+      """
+      if self.parent.modified == 'n' : self.parent.init_modif()
+      valeur = self.get_valeur()
+      #print "valid_valeur",valeur
+
+      self.erase_valeur()
+      anc_val = self.node.item.get_valeur()
+      test_CO=self.node.item.is_CO(anc_val)
+      #PN essai pour bug dans MACRO_PROJ_BASE 
+      valeur,validite=self.node.item.eval_valeur(valeur)
+      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
+      #PN essai pour bug dans MACRO_PROJ_BASE 
+      #elif self.node.item.isvalid() :
+      elif validite: 
+          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.reset_old_valeur(anc_val,mess=mess)
+          return
+
+  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
+      """
+      #print "valid_nom_concept_co"
+      if self.parent.modified == 'n' : self.parent.init_modif()
+      anc_val = self.node.item.get_valeur()
+      if anc_val != None:
+          # 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()
+      nom_concept = self.entry_co.get()
+      #print "valid_nom_concept_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.reset_old_valeur(anc_val,mess=mess)
+          return
+
+  def ask_new_concept(self,tag):
+      """
+      Crée une entry dans le panneau d'un MCS qui attend un concept OU un CO() afin de
+      permettre à l'utilisateur de donner le nom du nouveau concept
+      """
+      new_concept = self.b_co.getcurselection()
+      if new_concept == 'OUI':
+          self.label_co.place(relx=0.05,rely=0.7)
+          self.entry_co.place(relx=0.45,rely=0.7,relwidth=0.25)
+          self.l_resu.place_forget()
+          self.label_valeur.place_forget()
+          self.entry_co.focus()
+      elif new_concept == 'NON':
+          # On est passe de OUI à NON, on supprime la valeur
+# PN correction de bug (on passe de non a non et cela supprime la valeur)
+# ajout du if de le ligne suivane
+          if self.node.item.is_CO():
+                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)
+                self.label_valeur.place(relx=0.45,rely=0.7)
+          
+  def display_valeur(self):
+      """
+      Affiche la valeur de l'objet pointé par self
+      """
+      valeur = self.node.item.get_valeur()
+      #print "display_valeur",valeur
+      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 self.node.item.is_CO():
+          #print "display_valeur.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.isvalid():
+          self.node.parent.select()
+
+
diff --git a/Interface/utils.py b/Interface/utils.py
new file mode 100644 (file)
index 0000000..ecb01bb
--- /dev/null
@@ -0,0 +1,153 @@
+# -*- coding: utf-8 -*-
+#            CONFIGURATION MANAGEMENT OF EDF VERSION
+# ======================================================================
+# COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
+# 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, OR
+# (AT YOUR OPTION) 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.
+#
+# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
+# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
+#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
+#
+#
+# ======================================================================
+"""
+    Ce module contient des utilitaires divers
+"""
+import os,re
+import glob
+import traceback
+import codecs,types
+
+def substract_list(liste1,liste2):
+  """ 
+      Enlève tous les éléments de liste2 présents dans liste1 et retourne liste1
+  """
+  for item in liste2:
+    try:
+      liste1.remove(item)
+    except:
+      pass
+  return liste1
+
+def get_rep_user():
+  """
+      Détermine sur quelle plate-forme s'exécute Eficas et recherche
+      le répertoire de l'utilisateur /$home/Eficas_install
+  """
+  if os.name not in ('posix','nt'):
+    print "Système non reconnu par Eficas"
+    print "Prévenir la maintenance"
+    sys.exit(0)
+  if os.name == 'nt':
+    try:
+      drive = os.environ['HOMEDRIVE']
+      nom_user = os.environ['USERNAME']
+      rep_user_eficas = drive+'\\'+nom_user+'\\'+'Eficas_install'
+    except:
+      rep_user_eficas = os.path.join('C:','Eficas_install')
+  else :
+    rep_user_eficas = os.path.join(os.environ['HOME'],'Eficas_install')
+  if os.path.exists(rep_user_eficas):
+    if os.path.isfile(rep_user_eficas) :
+      print "Un fichier de nom %s existe déjà : impossible de créer un répertoire de même nom" %rep_user_eficas
+      sys.exit(0)
+  else :
+    try:
+      os.mkdir(rep_user_eficas)
+    except:
+      print "Création du répertoire %s impossible\n Vérifiez vos droits d'accès" %rep_user_eficas
+  return rep_user_eficas
+
+def read_file(file):
+  """
+      ouvre le fichier file et retourne son contenu
+      si pbe retourne None
+  """
+  try :
+    f=open(file)
+    text=f.read()
+    f.close()
+    return text
+  except:
+    return None
+
+def save_in_file(file,text,dir=None):
+  """
+      crée le fichier file (ou l'écrase s'il existe) et écrit text dedans
+      retourne 1 si OK 0 sinon
+  """
+  try :
+      import string
+      #file=string.split(file,"/")[-1]
+      if dir != None:
+         os.chdir(dir)
+      f=open(file,'w')
+      f.write(text)
+      f.close()
+      return 1
+  except:
+      return 0
+
+def extension_fichier(pathAndFile):
+    """ Return ext if path/filename.ext is given """
+    return os.path.splitext(pathAndFile)[1][1:]
+
+def stripPath(pathAndFile):
+    """ Return filename.ext if path/filename.ext is given """
+    return os.path.split(pathAndFile)[1]
+
+def init_rep_cata_dev(fic_cata,rep_goal):
+  """ 
+      Initialise le répertoire des catalogues développeurs (chemin d'accès donné
+      dans le fichier eficas.ini cad :
+        - le crée s'il n'existe pas encore
+        - copie dedans les 3 fichiers nécessaires :
+          * __init__.py (pour que ce répertoire puisse être interprété comme un package)
+          * entete.py (pour réaliser les import nécessaires à l'interprétation des catalogues)
+          * declaration_concepts.py (idem)
+        - crée le fichier cata_developpeur.py qui sera par la suite importé
+  """
+  try :
+    if not os.path.isdir(rep_goal) :
+      os.mkdir(rep_goal)
+    #texte_entete = get_entete_cata(fic_cata)
+    texte_entete=""
+    # rep_goal doit contenir les catalogues du développeur sous la forme *.capy
+    # il faut créer le catalogue développeur par concaténation de entete,declaration_concepts
+    # et de tous ces fichiers
+    cur_dir = os.getcwd()
+    os.chdir(rep_goal)
+    l_cata_dev = glob.glob('*.capy')
+    if os.path.isfile('cata_developpeur.py') : os.remove('cata_developpeur.py')
+    if len(l_cata_dev) :
+      # des catalogues développeurs sont effectivement présents : on crée cata_dev.py dans rep_goal
+      str = ''
+      str = str + texte_entete+'\n'
+      for file in l_cata_dev :
+        str = str + open(file,'r').read() +'\n'
+      open('cata_developpeur.py','w+').write(str)
+    os.chdir(cur_dir)
+  except:
+    traceback.print_exc()
+    print "Impossible de transférer les fichiers requis dans :",rep_goal
+
+def get_entete_cata(fic_cata):
+  """ Retrouve l'entete du catalogue """
+  l_lignes = open(fic_cata,'r').readlines()
+  txt = ''
+  flag = 0
+  for ligne in l_lignes :
+    if re.match("# debut entete",ligne) : flag = 1
+    if re.match("# fin entete",ligne) : break
+    if not flag : continue
+    txt = txt + ligne
+  return txt
+
diff --git a/Interface/viewManager.py b/Interface/viewManager.py
new file mode 100644 (file)
index 0000000..84a46f5
--- /dev/null
@@ -0,0 +1,3997 @@
+"""
+
+
+"""
+import os
+from qt import *
+
+
+##fonctions utilitaires
+def normabspath(path):
+    """
+    Function returning a normalized, absolute path.
+    
+    @param path file path (string)
+    @return absolute, normalized path (string)
+    """
+    return os.path.abspath(path)
+    
+    
+def samepath(f1, f2):
+    """
+    Function to compare two paths.
+    
+    @param f1 first path for the compare (string)
+    @param f2 second path for the compare (string)
+    @return flag indicating whether the two paths represent the
+        same path on disk.
+    """
+    if f1 is None or f2 is None:
+        return 0
+        
+    if normcasepath(f1) == normcasepath(f2):
+        return 1
+        
+    return 0
+
+def normcasepath(path):
+    """
+    Function returning a path, that is normalized with respect to its case and references.
+    
+    @param path file path (string)
+    @return case normalized path (string)
+    """
+    return os.path.normcase(os.path.normpath(path))    
+    
+
+import icons
+
+
+class ViewManager:
+    """
+    Base class inherited by all specific viewmanager classes.
+    
+    It defines the interface to be implemented by specific
+    viewmanager classes and all common methods.
+    
+    @signal lastEditorClosed emitted after the last editor window was closed
+    @signal editorOpened(string) emitted after an editor window was opened
+    @signal editorSaved(string) emitted after an editor window was saved
+    @signal checkActions(editor) emitted when some actions should be checked
+            for their status
+    @signal cursorChanged(editor) emitted after the cursor position of the active
+            window has changed
+    @signal breakpointToggled(editor) emitted when a breakpoint is toggled.
+    @signal bookmarkToggled(editor) emitted when a bookmark is toggled.
+    """
+    def __init__(self, ui ):
+        """
+        Constructor
+        
+        @param ui reference to the main user interface
+        @param dbs reference to the debug server object
+        """
+        # initialize the instance variables
+        self.ui = ui
+        self.editors = []
+        self.currentEditor = None
+        self.untitledCount = 0
+        self.srHistory = {"search" : QStringList(), "replace" : QStringList()}
+        self.editorsCheckFocusIn = 1
+                
+        self.recent =  QStringList()      
+        #CS_pbruno todo        
+        self.recent.append('/local00/dev/src/EficasV1/Aster/Tests/Recette/efica01a.comm')
+        self.recent.append('/local00/dev/src/EficasV1/Aster/Tests/Recette/az.comm')
+        self.recent.append('/local00/dev/src/EficasV1/Exemples/ellipses74.comm')
+        self.recent.append('/local00/dev/src/EficasV1/Interface/azAster.comm')
+        self.recent.append('/local00/dev/src/orig/EficasV1/Aster/az.comm')
+                                                                          
+##        rs, ok = Preferences.Prefs.settings.readListEntry('/eric3/Recent/Sources')
+##        if ok:
+##            self.recent = rs
+            
+##        self.bookmarked = QStringList()
+##        bs, ok = Preferences.Prefs.settings.readListEntry('/eric3/Bookmarked/Sources')
+##        if ok:
+##            self.bookmarked = bs
+            
+
+        
+        # initialize the central store for api information (used by
+        # autocompletion and calltips)
+        self.apis = {}
+##        for apiLang in Preferences.Prefs.editorAPIDefaults.keys():
+##            self.apis[apiLang] = None
+            
+        self.initFileFilters()
+        
+
+        
+    def initFileFilters(self):
+        """
+        Private method to initialize the lists of supported filename filters.
+        """
+        self.fileFiltersString = self.trUtf8(\
+            'Python Files (*.py);;'
+            'Pyrex Files (*.pyx);;'
+            'Quixote Template Files (*.ptl);;'
+            'IDL Files (*.idl);;'
+            'C Files (*.h *.c);;'
+            'C++ Files (*.h *.hpp *.hh *.cxx *.cpp *.cc);;'
+            'C# Files (*.cs);;'
+            'HTML Files (*.html *.htm *.asp *.shtml *.css);;'
+            'PHP Files (*.php *.php3 *.php4 *.php5 *.phtml);;'
+            'XML Files (*.xml *.xsl *.xslt *.dtd);;'
+            'Java Files (*.java);;'
+            'JavaScript Files (*.js);;'
+            'SQL Files (*.sql);;'
+            'Docbook Files (*.docbook);;'
+            'Perl Files (*.pl *.pm *.ph);;'
+            'Shell Files (*.sh);;'
+            'All Files (*)')
+
+        fileFilters = QStringList.split(';;', self.fileFiltersString)
+        
+        self.ext2Filter = {}
+        for fileFilter in fileFilters:
+            extensions = QStringList.split('*', fileFilter)
+            for extension in extensions[1:]:
+                extension = unicode(extension).strip().replace(')', '')
+                if extension:
+                    self.ext2Filter[extension] = unicode(fileFilter)
+        
+    def setSbInfo(self, sbFile, sbLine, sbPos, sbWritable):
+        """
+        Public method to transfer statusbar info from the user interface to viewmanager.
+        
+        @param sbFile reference to the file part of the statusbar
+        @param sbLine reference to the line number part of the statusbar
+        @param sbPos reference to the character position part of the statusbar
+        @param sbWritable reference to the writability indicator part of the statusbar
+        """
+        self.sbFile = sbFile
+        self.sbLine = sbLine
+        self.sbPos = sbPos
+        self.sbWritable = sbWritable
+        self.setSbFile()
+        
+    def canCascade(self):
+        """
+        Public method to signal if cascading of managed windows is available.
+        
+        @return flag indicating cascading of windows is available
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+        
+    def canTile(self):
+        """
+        Public method to signal if tiling of managed windows is available.
+        
+        @return flag indicating tiling of windows is available
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+        
+    def tile(self):
+        """
+        Public method to tile the managed windows.
+        
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def cascade(self):
+        """
+        Public method to cascade the managed windows.
+        
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+
+    def removeAllViews(self):
+        """
+        Private method to remove all views (i.e. windows)
+        
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def removeView(self, win):
+        """
+        Private method to remove a view (i.e. window)
+        
+        @param win editor window to be removed
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def addView(self, win, fn=None):
+        """
+        Private method to add a view (i.e. window)
+        
+        @param win editor window to be added
+        @param fn filename of this editor
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def showView(self, win, fn=None):
+        """
+        Private method to show a view (i.e. window)
+        
+        @param win editor window to be shown
+        @param fn filename of this editor
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def activeWindow(self):
+        """
+        Private method to return the active (i.e. current) window.
+        
+        @return reference to the active editor
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def handleShowWindowMenu(self, windowMenu):
+        """
+        Private method to set up the viewmanager part of the Window menu.
+        
+        @param windowMenu reference to the window menu
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+    
+    def initWindowActions(self):
+        """
+        Define the user interface actions for window handling.
+        
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+
+    def setEditorName(self, editor, newName):
+        """
+        Change the displayed name of the editor.
+        
+        @param editor editor window to be changed
+        @param newName new name to be shown (string or QString)
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+        
+    def handleModificationStatusChanged(self, m, editor):
+        """
+        Private slot to handle the modificationStatusChanged signal.
+        
+        @param m flag indicating the modification status (boolean)
+        @param editor editor window changed
+        @exception RuntimeError Not implemented
+        """
+        raise RuntimeError, 'Not implemented'
+        
+    #####################################################################
+    ## methods above need to be implemented by a subclass
+    #####################################################################
+    
+    def canSplit(self):
+        """
+        public method to signal if splitting of the view is available.
+        
+        @return flag indicating splitting of the view is available.
+        """
+        return 0
+        
+    def addSplit(self):
+        """
+        Public method used to split the current view.
+        """
+        pass
+        
+    def removeSplit(self):
+        """
+        Public method used to remove the current split view.
+        
+        @return Flag indicating successful deletion
+        """
+        return 0
+        
+    def setSplitOrientation(self, orientation):
+        """
+        Public method used to set the orientation of the split view.
+        
+        @param orientation orientation of the split
+                (QSplitter.Horizontal or QSplitter.Vertical)
+        """
+        pass
+        
+    def eventFilter(self, object, event):
+        """
+        Private method called to filter an event.
+        
+        @param object object, that generated the event (QObject)
+        @param event the event, that was generated by object (QEvent)
+        @return flag indicating if event was filtered out
+        """
+        return 0
+        
+    def focusInEvent(self, event):
+        """
+        Public method called when the viewmanager receives focus.
+        
+        @param event the event object (QFocusEvent)
+        """
+        self.editorActGrp.setEnabled(1)
+        
+    def focusOutEvent(self, event):
+        """
+        Public method called when the viewmanager loses focus.
+        
+        @param event the event object (QFocusEvent)
+        """
+        self.editorActGrp.setEnabled(0)
+        
+    #####################################################################
+    ## methods above need to be implemented by a subclass, that supports
+    ## splitting of the viewmanager area.
+    #####################################################################
+    
+    def initActions(self):
+        """
+        Public method defining the user interface actions.
+        """
+        # list containing all edit actions
+        self.editActions = []
+        
+        # list containing all file actions
+        self.fileActions = []
+        
+        # list containing all search actions
+        self.searchActions = []
+        
+        # list containing all view actions
+        self.viewActions = []
+        
+        # list containing all window actions
+        self.windowActions = []
+        
+        # list containing all macro actions
+        self.macroActions = []
+        
+        # list containing all bookmark actions
+        self.bookmarkActions = []
+        
+        self.initWindowActions()
+        self.initFileActions()
+        self.initEditActions()
+        self.initSearchActions()
+        self.initViewActions()
+        self.initMacroActions()
+        self.initBookmarkActions()
+        
+    ##################################################################
+    ## Initialize the file related actions, file menu and toolbar
+    ##################################################################
+    
+    def initFileActions(self):
+        """
+        Private method defining the user interface actions for file handling.
+        """
+        self.newAct = QAction(self.trUtf8('New'),
+                QIconSet(icons.getPixmap("new.png")),
+                self.trUtf8('&New'),
+                QKeySequence(self.trUtf8("CTRL+N","File|New")),self)
+        self.newAct.setStatusTip(self.trUtf8('Open an empty editor window'))
+        self.newAct.setWhatsThis(self.trUtf8(
+            """<b>New</b>"""
+            """<p>An empty editor window will be created.</p>"""
+        ))
+        self.connect(self.newAct,SIGNAL('activated()'),self.newEditor)
+        self.fileActions.append(self.newAct)
+        
+        self.openAct = QAction(self.trUtf8('Open'),
+                QIconSet(icons.getPixmap("open.png")),
+                self.trUtf8('&Open...'),
+                QKeySequence(self.trUtf8("CTRL+O","File|Open")),self)
+        self.openAct.setStatusTip(self.trUtf8('Open a Python file'))
+        self.openAct.setWhatsThis(self.trUtf8(
+            """<b>Open a Python file</b>"""
+            """<p>You will be asked for the name of a Python file to be opened"""
+            """ in an editor window.</p>"""
+        ))
+        self.connect(self.openAct,SIGNAL('activated()'),self.handleOpen)
+        self.fileActions.append(self.openAct)
+        
+        self.closeActGrp = QActionGroup(self)
+        
+        self.closeAct = QAction(self.trUtf8('Close'),
+                QIconSet(icons.getPixmap("close.png")),
+                self.trUtf8('&Close'),
+                QKeySequence(self.trUtf8("CTRL+W","File|Close")),
+                self.closeActGrp)
+        self.closeAct.setStatusTip(self.trUtf8('Close the current window'))
+        self.closeAct.setWhatsThis(self.trUtf8(
+            """<b>Close Window</b>"""
+            """<p>Close the current window.</p>"""
+        ))
+        self.connect(self.closeAct,SIGNAL('activated()'),self.handleClose)
+        self.fileActions.append(self.closeAct)
+
+        self.closeAllAct = QAction(self.trUtf8('Close All'),
+                self.trUtf8('Clos&e All'),
+                0,self.closeActGrp)
+        self.closeAllAct.setStatusTip(self.trUtf8('Close all editor windows'))
+        self.closeAllAct.setWhatsThis(self.trUtf8(
+            """<b>Close All Windows</b>"""
+            """<p>Close all editor windows.</p>"""
+        ))
+        self.connect(self.closeAllAct,SIGNAL('activated()'),self.handleCloseAll)
+        self.fileActions.append(self.closeAllAct)
+        
+        self.closeActGrp.setEnabled(0)
+        
+        self.saveActGrp = QActionGroup(self)
+
+        self.saveAct = QAction(self.trUtf8('Save'),
+                QIconSet(icons.getPixmap("fileSave.png")),
+                self.trUtf8('&Save'),
+                QKeySequence(self.trUtf8("CTRL+S","File|Save")),
+                self.saveActGrp)
+        self.saveAct.setStatusTip(self.trUtf8('Save the current file'))
+        self.saveAct.setWhatsThis(self.trUtf8(
+            """<b>Save File</b>"""
+            """<p>Save the contents of current editor window.</p>"""
+        ))
+        self.connect(self.saveAct,SIGNAL('activated()'),self.saveCurrentEditor)
+        self.fileActions.append(self.saveAct)
+
+        self.saveAsAct = QAction(self.trUtf8('Save as'),
+                QIconSet(icons.getPixmap("fileSaveAs.png")),
+                self.trUtf8('Save &as...'),
+                QKeySequence(self.trUtf8("SHIFT+CTRL+S","File|Save As")),
+                self.saveActGrp)
+        self.saveAsAct.setStatusTip(self.trUtf8('Save the current file to a new one'))
+        self.saveAsAct.setWhatsThis(self.trUtf8(
+            """<b>Save File as</b>"""
+            """<p>Save the contents of current editor window to a new file."""
+            """ The file can be entered in a file selection dialog.</p>"""
+        ))
+        self.connect(self.saveAsAct,SIGNAL('activated()'),self.saveAsCurrentEditor)
+        self.fileActions.append(self.saveAsAct)
+
+        self.saveAllAct = QAction(self.trUtf8('Save all'),
+                QIconSet(icons.getPixmap("fileSaveAll.png")),
+                self.trUtf8('Save a&ll...'),
+                0,self.saveActGrp)
+        self.saveAllAct.setStatusTip(self.trUtf8('Save all files'))
+        self.saveAllAct.setWhatsThis(self.trUtf8(
+            """<b>Save All Files</b>"""
+            """<p>Save the contents of all editor windows.</p>"""
+        ))
+        self.connect(self.saveAllAct,SIGNAL('activated()'),self.saveAllEditors)
+        self.fileActions.append(self.saveAllAct)
+        
+        self.saveActGrp.setEnabled(0)
+
+        self.saveToProjectAct = QAction(self.trUtf8('Save to Project'),
+                QIconSet(icons.getPixmap("fileSaveProject.png")),
+                self.trUtf8('Save to Pro&ject'),
+                0,self)
+        self.saveToProjectAct.setStatusTip(self.trUtf8('Save the current file to the current project'))
+        self.saveToProjectAct.setWhatsThis(self.trUtf8(
+            """<b>Save to Project</b>"""
+            """<p>Save the contents of the current editor window to the"""
+            """ current project. After the file has been saved, it is"""
+            """ automatically added to the current project.</p>"""
+        ))
+        self.connect(self.saveToProjectAct,SIGNAL('activated()'),self.saveCurrentEditorToProject)
+        self.saveToProjectAct.setEnabled(0)
+        self.fileActions.append(self.saveToProjectAct)
+        
+        self.printAct = QAction(self.trUtf8('Print'),
+                QIconSet(icons.getPixmap("print.png")),
+                self.trUtf8('&Print'),
+                QKeySequence(self.trUtf8("CTRL+P","File|Print")),self)
+        self.printAct.setStatusTip(self.trUtf8('Print the current file'))
+        self.printAct.setWhatsThis(self.trUtf8(
+            """<b>Print File</b>"""
+            """<p>Print the contents of current editor window.</p>"""
+        ))
+        self.connect(self.printAct,SIGNAL('activated()'),self.printCurrentEditor)
+        self.printAct.setEnabled(0)
+        self.fileActions.append(self.printAct)
+
+        self.printSelAct = QAction(self.trUtf8('Print Selection'),
+                QIconSet(icons.getPixmap("print.png")),
+                self.trUtf8('Prin&t Selection'),
+                QKeySequence(self.trUtf8("SHIFT+CTRL+P","File|Print")),self)
+        self.printSelAct.setStatusTip(self.trUtf8('Print the selection of the current file'))
+        self.printSelAct.setWhatsThis(self.trUtf8(
+            """<b>Print Selection</b>"""
+            """<p>Print the selection of the current editor window.</p>"""
+        ))
+        self.connect(self.printSelAct,SIGNAL('activated()'),self.printCurrentEditorSel)
+        self.printSelAct.setEnabled(0)
+        self.fileActions.append(self.printSelAct)
+
+        self.findFileNameAct = QAction(self.trUtf8('Search File'),
+                self.trUtf8('Search &File...'),
+                QKeySequence(self.trUtf8("ALT+CTRL+F","File|Search File")),self)
+        self.findFileNameAct.setStatusTip(self.trUtf8('Search for a file'))
+        self.findFileNameAct.setWhatsThis(self.trUtf8(
+            """<b>Search File</b>"""
+            """<p>Search for a file.</p>"""
+        ))
+        self.connect(self.findFileNameAct,SIGNAL('activated()'),self.handleFindFileName)
+        self.fileActions.append(self.findFileNameAct)
+        
+    def initFileMenu(self):
+        """
+        Public method to create the File menu.
+        
+        @return the generated menu
+        """
+        menu = QPopupMenu(self.ui)
+        self.recentMenu = QPopupMenu(menu)
+        self.bookmarkedMenu = QPopupMenu(menu)
+        menu.insertTearOffHandle()
+        self.newAct.addTo(menu)
+        self.openAct.addTo(menu)
+        menu.insertItem(self.trUtf8('Open &Recent Files'), self.recentMenu)
+        self.connect(self.recentMenu,SIGNAL('aboutToShow()'),self.handleShowRecentMenu)
+        menu.insertItem(self.trUtf8('Open &Bookmarked Files'), self.bookmarkedMenu)
+        self.connect(self.bookmarkedMenu,SIGNAL('aboutToShow()'),self.handleShowBookmarkedMenu)
+        menu.insertSeparator()
+        self.closeAct.addTo(menu)
+        self.closeAllAct.addTo(menu)
+        menu.insertSeparator()
+        self.findFileNameAct.addTo(menu)
+        menu.insertSeparator()
+        self.saveAct.addTo(menu)
+        self.saveAsAct.addTo(menu)
+        self.saveAllAct.addTo(menu)
+        self.saveToProjectAct.addTo(menu)
+        menu.insertSeparator()
+        self.printAct.addTo(menu)
+        self.printSelAct.addTo(menu)
+
+        return menu
+        
+    def initFileToolbar(self):
+        """
+        Public method to create the File toolbar.
+        
+        @return the generated toolbar
+        """
+        tb = QToolBar(self.ui)
+        self.newAct.addTo(tb)
+        self.openAct.addTo(tb)
+        self.closeAct.addTo(tb)
+        tb.addSeparator()
+        self.saveAct.addTo(tb)
+        self.saveAsAct.addTo(tb)
+        self.saveAllAct.addTo(tb)
+        self.saveToProjectAct.addTo(tb)
+        tb.addSeparator()
+        self.printAct.addTo(tb)
+        
+        return tb
+        
+    ##################################################################
+    ## Initialize the edit related actions, edit menu and toolbar
+    ##################################################################
+    
+##    def initEditActions(self):
+##        """
+##        Private method defining the user interface actions for the edit commands.
+##        """
+##        self.editActGrp = QActionGroup(self)
+##
+##        self.undoAct = QAction(self.trUtf8('Undo'),
+##                QIconSet(icons.getPixmap("editUndo.png")),
+##                self.trUtf8('&Undo'),
+##                QKeySequence(self.trUtf8("CTRL+Z","Edit|Undo")),
+##                self.editActGrp)
+##        self.undoAct.setStatusTip(self.trUtf8('Undo the last change'))
+##        self.undoAct.setWhatsThis(self.trUtf8(
+##            """<b>Undo</b>"""
+##            """<p>Undo the last change done in the current editor.</p>"""
+##        ))
+##        self.connect(self.undoAct,SIGNAL('activated()'),self.handleEditUndo)
+##        self.editActions.append(self.undoAct)
+##        
+##        self.redoAct = QAction(self.trUtf8('Redo'),
+##                QIconSet(icons.getPixmap("editRedo.png")),
+##                self.trUtf8('&Redo'),
+##                QKeySequence(self.trUtf8("CTRL+Y","Edit|Redo")),
+##                self.editActGrp)
+##        self.redoAct.setStatusTip(self.trUtf8('Redo the last change'))
+##        self.redoAct.setWhatsThis(self.trUtf8(
+##            """<b>Redo</b>"""
+##            """<p>Redo the last change done in the current editor.</p>"""
+##        ))
+##        self.connect(self.redoAct,SIGNAL('activated()'),self.handleEditRedo)
+##        self.editActions.append(self.redoAct)
+##        
+##        self.revertAct = QAction(self.trUtf8('Revert to last saved state'),
+##                self.trUtf8('Re&vert to last saved state'),
+##                QKeySequence(self.trUtf8("SHIFT+CTRL+Z","Edit|Revert")),
+##                self.editActGrp)
+##        self.revertAct.setStatusTip(self.trUtf8('Revert to last saved state'))
+##        self.revertAct.setWhatsThis(self.trUtf8(
+##            """<b>Revert to last saved state</b>"""
+##            """<p>Undo all changes up to the last saved state of the current editor.</p>"""
+##        ))
+##        self.connect(self.revertAct,SIGNAL('activated()'),self.handleEditRevert)
+##        self.editActions.append(self.revertAct)
+##        
+##        self.cutAct = QAction(self.trUtf8('Cut'),
+##                QIconSet(icons.getPixmap("editCut.png")),
+##                self.trUtf8('Cu&t'),
+##                QKeySequence(self.trUtf8("CTRL+X","Edit|Cut")),
+##                self.editActGrp)
+##        self.cutAct.setStatusTip(self.trUtf8('Cut the selection'))
+##        self.cutAct.setWhatsThis(self.trUtf8(
+##            """<b>Cut</b>"""
+##            """<p>Cut the selected text of the current editor to the clipboard.</p>"""
+##        ))
+##        self.connect(self.cutAct,SIGNAL('activated()'),self.handleEditCut)
+##        self.editActions.append(self.cutAct)
+##        
+##        self.copyAct = QAction(self.trUtf8('Copy'),
+##                QIconSet(icons.getPixmap("editCopy.png")),
+##                self.trUtf8('&Copy'),
+##                QKeySequence(self.trUtf8("CTRL+C","Edit|Copy")),
+##                self.editActGrp)
+##        self.copyAct.setStatusTip(self.trUtf8('Copy the selection'))
+##        self.copyAct.setWhatsThis(self.trUtf8(
+##            """<b>Copy</b>"""
+##            """<p>Copy the selected text of the current editor to the clipboard.</p>"""
+##        ))
+##        self.connect(self.copyAct,SIGNAL('activated()'),self.handleEditCopy)
+##        self.editActions.append(self.copyAct)
+##        
+##        self.pasteAct = QAction(self.trUtf8('Paste'),
+##                QIconSet(icons.getPixmap("editPaste.png")),
+##                self.trUtf8('&Paste'),
+##                QKeySequence(self.trUtf8("CTRL+V","Edit|Paste")),
+##                self.editActGrp)
+##        self.pasteAct.setStatusTip(self.trUtf8('Paste the last cut/copied text'))
+##        self.pasteAct.setWhatsThis(self.trUtf8(
+##            """<b>Paste</b>"""
+##            """<p>Paste the last cut/copied text from the clipboard to"""
+##            """ the current editor.</p>"""
+##        ))
+##        self.connect(self.pasteAct,SIGNAL('activated()'),self.handleEditPaste)
+##        self.editActions.append(self.pasteAct)
+##        
+##        self.deleteAct = QAction(self.trUtf8('Clear'),
+##                QIconSet(icons.getPixmap("editDelete.png")),
+##                self.trUtf8('Cl&ear'),
+##                0,self.editActGrp)
+##        self.deleteAct.setStatusTip(self.trUtf8('Clear all text'))
+##        self.deleteAct.setWhatsThis(self.trUtf8(
+##            """<b>Clear</b>"""
+##            """<p>Delete all text of the current editor.</p>"""
+##        ))
+##        self.connect(self.deleteAct,SIGNAL('activated()'),self.handleEditDelete)
+##        self.editActions.append(self.deleteAct)
+##        
+##        self.indentAct = QAction(self.trUtf8('Indent'),
+##                QIconSet(icons.getPixmap("editIndent.png")),
+##                self.trUtf8('&Indent'),
+##                QKeySequence(self.trUtf8("CTRL+I","Edit|Indent")),
+##                self.editActGrp)
+##        self.indentAct.setStatusTip(self.trUtf8('Indent line'))
+##        self.indentAct.setWhatsThis(self.trUtf8(
+##            """<b>Indent</b>"""
+##            """<p>Indents the current line or the lines of the"""
+##            """ selection by one level.</p>"""
+##        ))
+##        self.connect(self.indentAct,SIGNAL('activated()'),self.handleEditIndent)
+##        self.editActions.append(self.indentAct)
+##        
+##        self.unindentAct = QAction(self.trUtf8('Unindent'),
+##                QIconSet(icons.getPixmap("editUnindent.png")),
+##                self.trUtf8('U&nindent'),
+##                QKeySequence(self.trUtf8("CTRL+U","Edit|Unindent")),
+##                self.editActGrp)
+##        self.unindentAct.setStatusTip(self.trUtf8('Unindent line'))
+##        self.unindentAct.setWhatsThis(self.trUtf8(
+##            """<b>Unindent</b>"""
+##            """<p>Unindents the current line or the lines of the"""
+##            """ selection by one level.</p>"""
+##        ))
+##        self.connect(self.unindentAct,SIGNAL('activated()'),self.handleEditUnindent)
+##        self.editActions.append(self.unindentAct)
+##        
+##        self.commentAct = QAction(self.trUtf8('Comment'),
+##                QIconSet(icons.getPixmap("editComment.png")),
+##                self.trUtf8('C&omment'),
+##                QKeySequence(self.trUtf8("CTRL+M","Edit|Comment")),
+##                self.editActGrp)
+##        self.commentAct.setStatusTip(self.trUtf8('Comment Line or Selection'))
+##        self.commentAct.setWhatsThis(self.trUtf8(
+##            """<b>Comment</b>"""
+##            """<p>Comments the current line or the lines of the"""
+##            """ current selection.</p>"""
+##        ))
+##        self.connect(self.commentAct,SIGNAL('activated()'),self.handleEditComment)
+##        self.editActions.append(self.commentAct)
+##        
+##        self.uncommentAct = QAction(self.trUtf8('Uncomment'),
+##                QIconSet(icons.getPixmap("editUncomment.png")),
+##                self.trUtf8('Unco&mment'),
+##                QKeySequence(self.trUtf8("ALT+CTRL+M","Edit|Uncomment")),
+##                self.editActGrp)
+##        self.uncommentAct.setStatusTip(self.trUtf8('Uncomment Line or Selection'))
+##        self.uncommentAct.setWhatsThis(self.trUtf8(
+##            """<b>Uncomment</b>"""
+##            """<p>Uncomments the current line or the lines of the"""
+##            """ current selection.</p>"""
+##        ))
+##        self.connect(self.uncommentAct,SIGNAL('activated()'),self.handleEditUncomment)
+##        self.editActions.append(self.uncommentAct)
+##        
+##        self.streamCommentAct = QAction(self.trUtf8('Stream Comment'),
+##                self.trUtf8('Stream Comment'),
+##                0, self.editActGrp)
+##        self.streamCommentAct.setStatusTip(self.trUtf8('Stream Comment Line or Selection'))
+##        self.streamCommentAct.setWhatsThis(self.trUtf8(
+##            """<b>Stream Comment</b>"""
+##            """<p>Stream comments the current line or the current selection.</p>"""
+##        ))
+##        self.connect(self.streamCommentAct,SIGNAL('activated()'),self.handleEditStreamComment)
+##        self.editActions.append(self.streamCommentAct)
+##        
+##        self.boxCommentAct = QAction(self.trUtf8('Box Comment'),
+##                self.trUtf8('Box Comment'),
+##                0, self.editActGrp)
+##        self.boxCommentAct.setStatusTip(self.trUtf8('Box Comment Line or Selection'))
+##        self.boxCommentAct.setWhatsThis(self.trUtf8(
+##            """<b>Box Comment</b>"""
+##            """<p>Box comments the current line or the lines of the"""
+##            """ current selection.</p>"""
+##        ))
+##        self.connect(self.boxCommentAct,SIGNAL('activated()'),self.handleEditBoxComment)
+##        self.editActions.append(self.boxCommentAct)
+##        
+##        self.selectBraceAct = QAction(self.trUtf8('Select to brace'),
+##                self.trUtf8('Select to &brace'),
+##                QKeySequence(self.trUtf8("CTRL+E","Edit|Select to brace")),
+##                self.editActGrp)
+##        self.selectBraceAct.setStatusTip(self.trUtf8('Select text to the matching brace'))
+##        self.selectBraceAct.setWhatsThis(self.trUtf8(
+##            """<b>Selct to brace</b>"""
+##            """<p>Select text of the current editor to the matching brace.</p>"""
+##        ))
+##        self.connect(self.selectBraceAct,SIGNAL('activated()'),self.handleEditSelectBrace)
+##        self.editActions.append(self.selectBraceAct)
+##        
+##        self.selectAllAct = QAction(self.trUtf8('Select all'),
+##                self.trUtf8('&Select all'),
+##                QKeySequence(self.trUtf8("CTRL+A","Edit|Select all")),
+##                self.editActGrp)
+##        self.selectAllAct.setStatusTip(self.trUtf8('Select all text'))
+##        self.selectAllAct.setWhatsThis(self.trUtf8(
+##            """<b>Selct All</b>"""
+##            """<p>Select all text of the current editor.</p>"""
+##        ))
+##        self.connect(self.selectAllAct,SIGNAL('activated()'),self.handleEditSelectAll)
+##        self.editActions.append(self.selectAllAct)
+##        
+##        self.deselectAllAct = QAction(self.trUtf8('Deselect all'),
+##                self.trUtf8('&Deselect all'),
+##                QKeySequence(self.trUtf8("ALT+CTRL+A","Edit|Deselect all")),
+##                self.editActGrp)
+##        self.deselectAllAct.setStatusTip(self.trUtf8('Deselect all text'))
+##        self.deselectAllAct.setWhatsThis(self.trUtf8(
+##            """<b>Deselct All</b>"""
+##            """<p>Deselect all text of the current editor.</p>"""
+##        ))
+##        self.connect(self.deselectAllAct,SIGNAL('activated()'),self.handleEditDeselectAll)
+##        self.editActions.append(self.deselectAllAct)
+##        
+##        self.convertEOLAct = QAction(self.trUtf8('Convert Line End Characters'),
+##                self.trUtf8('Convert &Line End Characters'),
+##                0, self.editActGrp)
+##        self.convertEOLAct.setStatusTip(self.trUtf8('Convert Line End Characters'))
+##        self.convertEOLAct.setWhatsThis(self.trUtf8(
+##            """<b>Convert Line End Characters</b>"""
+##            """<p>Convert the line end characters to the currently set type.</p>"""
+##        ))
+##        self.connect(self.convertEOLAct,SIGNAL('activated()'),self.handleConvertEOL)
+##        self.editActions.append(self.convertEOLAct)
+##        
+##        self.shortenEmptyAct = QAction(self.trUtf8('Shorten empty lines'),
+##                self.trUtf8('Shorten empty lines'),
+##                0, self.editActGrp)
+##        self.shortenEmptyAct.setStatusTip(self.trUtf8('Shorten empty lines'))
+##        self.shortenEmptyAct.setWhatsThis(self.trUtf8(
+##            """<b>Shorten empty lines</b>"""
+##            """<p>Shorten lines consisting solely of whitespace characters.</p>"""
+##        ))
+##        self.connect(self.shortenEmptyAct,SIGNAL('activated()'),self.handleShortenEmptyLines)
+##        self.editActions.append(self.shortenEmptyAct)
+##        
+##        self.autoCompleteAct = QAction(self.trUtf8('Autocomplete'),
+##                self.trUtf8('&Autocomplete'),
+##                QKeySequence(self.trUtf8("CTRL+Space","Edit|Autocomplete")),
+##                self.editActGrp)
+##        self.autoCompleteAct.setStatusTip(self.trUtf8('Autocomplete current word'))
+##        self.autoCompleteAct.setWhatsThis(self.trUtf8(
+##            """<b>Autocomplete</b>"""
+##            """<p>Performs an autocompletion of the word containing the cursor.</p>"""
+##        ))
+##        self.connect(self.autoCompleteAct,SIGNAL('activated()'),self.handleEditAutoComplete)
+##        self.editActions.append(self.autoCompleteAct)
+##        
+##        self.autoCompleteFromDocAct = QAction(self.trUtf8('Autocomplete from Document'),
+##                self.trUtf8('Autocomplete from Document'),
+##                QKeySequence(self.trUtf8("CTRL+Shift+Space","Edit|Autocomplete from Document")),
+##                self.editActGrp)
+##        self.autoCompleteFromDocAct.setStatusTip(self.trUtf8('Autocomplete current word from Document'))
+##        self.autoCompleteFromDocAct.setWhatsThis(self.trUtf8(
+##            """<b>Autocomplete from Document</b>"""
+##            """<p>Performs an autocompletion from document of the word containing the cursor.</p>"""
+##        ))
+##        self.connect(self.autoCompleteFromDocAct,SIGNAL('activated()'),self.handleEditAutoCompleteFromDoc)
+##        self.editActions.append(self.autoCompleteFromDocAct)
+##        
+##        self.autoCompleteFromAPIsAct = QAction(self.trUtf8('Autocomplete from APIs'),
+##                self.trUtf8('Autocomplete from APIs'),
+##                QKeySequence(self.trUtf8("CTRL+Alt+Space","Edit|Autocomplete from APIs")),
+##                self.editActGrp)
+##        self.autoCompleteFromAPIsAct.setStatusTip(self.trUtf8('Autocomplete current word from APIs'))
+##        self.autoCompleteFromAPIsAct.setWhatsThis(self.trUtf8(
+##            """<b>Autocomplete from APIs</b>"""
+##            """<p>Performs an autocompletion from APIs of the word containing the cursor.</p>"""
+##        ))
+##        self.connect(self.autoCompleteFromAPIsAct,SIGNAL('activated()'),self.handleEditAutoCompleteFromAPIs)
+##        self.editActions.append(self.autoCompleteFromAPIsAct)
+##        
+##        self.editActGrp.setEnabled(0)
+##        
+##        ####################################################################
+##        ## Below follow the actions for qscintilla standard commands.
+##        ####################################################################
+##        
+##        self.esm = QSignalMapper(self)
+##        self.connect(self.esm, SIGNAL('mapped(int)'), self.editorCommand)
+##        
+##        self.editorActGrp = QActionGroup(self.editActGrp)
+##        
+##        act = QAction(self.trUtf8('Move left one character'), 
+##                      self.trUtf8('Move left one character'), 
+##                      QKeySequence(self.trUtf8('Left')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_CHARLEFT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move right one character'), 
+##                      self.trUtf8('Move right one character'), 
+##                      QKeySequence(self.trUtf8('Right')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_CHARRIGHT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move up one line'), 
+##                      self.trUtf8('Move up one line'), 
+##                      QKeySequence(self.trUtf8('Up')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEUP)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move down one line'), 
+##                      self.trUtf8('Move down one line'), 
+##                      QKeySequence(self.trUtf8('Down')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEDOWN)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move left one word part'), 
+##                      self.trUtf8('Move left one word part'), 
+##                      QKeySequence(self.trUtf8('Alt+Left')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDPARTLEFT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move right one word part'), 
+##                      self.trUtf8('Move right one word part'), 
+##                      QKeySequence(self.trUtf8('Alt+Right')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDPARTRIGHT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move left one word'), 
+##                      self.trUtf8('Move left one word'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Left')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDLEFT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move right one word'), 
+##                      self.trUtf8('Move right one word'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Right')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDRIGHT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move to first visible character in line'), 
+##                      self.trUtf8('Move to first visible character in line'), 
+##                      QKeySequence(self.trUtf8('Home')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_VCHOME)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move to start of displayed line'), 
+##                      self.trUtf8('Move to start of displayed line'), 
+##                      QKeySequence(self.trUtf8('Alt+Home')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_HOMEDISPLAY)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move to end of line'), 
+##                      self.trUtf8('Move to end of line'), 
+##                      QKeySequence(self.trUtf8('End')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Scroll view down one line'), 
+##                      self.trUtf8('Scroll view down one line'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Down')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINESCROLLDOWN)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Scroll view up one line'), 
+##                      self.trUtf8('Scroll view up one line'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Up')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINESCROLLUP)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move up one paragraph'), 
+##                      self.trUtf8('Move up one paragraph'), 
+##                      QKeySequence(self.trUtf8('Alt+Up')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PARAUP)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move down one paragraph'), 
+##                      self.trUtf8('Move down one paragraph'), 
+##                      QKeySequence(self.trUtf8('Alt+Down')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PARADOWN)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move up one page'), 
+##                      self.trUtf8('Move up one page'), 
+##                      QKeySequence(self.trUtf8('PgUp')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PAGEUP)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move down one page'), 
+##                      self.trUtf8('Move down one page'), 
+##                      QKeySequence(self.trUtf8('PgDown')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PAGEDOWN)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move to start of text'), 
+##                      self.trUtf8('Move to start of text'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Home')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DOCUMENTSTART)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move to end of text'), 
+##                      self.trUtf8('Move to end of text'), 
+##                      QKeySequence(self.trUtf8('Ctrl+End')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DOCUMENTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Indent one level'), 
+##                      self.trUtf8('Indent one level'), 
+##                      QKeySequence(self.trUtf8('Tab')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_TAB)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Unindent one level'), 
+##                      self.trUtf8('Unindent one level'), 
+##                      QKeySequence(self.trUtf8('Shift+Tab')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_BACKTAB)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection left one character'), 
+##                      self.trUtf8('Extend selection left one character'), 
+##                      QKeySequence(self.trUtf8('Shift+Left')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_CHARLEFTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection right one character'), 
+##                      self.trUtf8('Extend selection right one character'), 
+##                      QKeySequence(self.trUtf8('Shift+Right')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_CHARRIGHTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection up one line'), 
+##                      self.trUtf8('Extend selection up one line'), 
+##                      QKeySequence(self.trUtf8('Shift+Up')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEUPEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection down one line'), 
+##                      self.trUtf8('Extend selection down one line'), 
+##                      QKeySequence(self.trUtf8('Shift+Down')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEDOWNEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection left one word part'), 
+##                      self.trUtf8('Extend selection left one word part'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+Left')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDPARTLEFTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection right one word part'), 
+##                      self.trUtf8('Extend selection right one word part'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+Right')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDPARTRIGHTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection left one word'), 
+##                      self.trUtf8('Extend selection left one word'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+Left')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDLEFTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection right one word'), 
+##                      self.trUtf8('Extend selection right one word'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+Right')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_WORDRIGHTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection to first visible character in line'), 
+##                      self.trUtf8('Extend selection to first visible character in line'), 
+##                      QKeySequence(self.trUtf8('Shift+Home')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_VCHOMEEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection to start of line'), 
+##                      self.trUtf8('Extend selection to start of line'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+Home')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_HOMEDISPLAYEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection to end of line'), 
+##                      self.trUtf8('Extend selection to end of line'), 
+##                      QKeySequence(self.trUtf8('Shift+End')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEENDEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection up one paragraph'), 
+##                      self.trUtf8('Extend selection up one paragraph'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+Up')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PARAUPEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection down one paragraph'), 
+##                      self.trUtf8('Extend selection down one paragraph'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+Down')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PARADOWNEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection up one page'), 
+##                      self.trUtf8('Extend selection up one page'), 
+##                      QKeySequence(self.trUtf8('Shift+PgUp')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PAGEUPEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection down one page'), 
+##                      self.trUtf8('Extend selection down one page'), 
+##                      QKeySequence(self.trUtf8('Shift+PgDown')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_PAGEDOWNEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection to start of text'), 
+##                      self.trUtf8('Extend selection to start of text'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+Home')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DOCUMENTSTARTEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection to end of text'), 
+##                      self.trUtf8('Extend selection to end of text'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+End')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DOCUMENTENDEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete previous character'), 
+##                      self.trUtf8('Delete previous character'), 
+##                      QKeySequence(self.trUtf8('Backspace')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DELETEBACK)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete previous character if not at line start'), 
+##                      self.trUtf8('Delete previous character if not at line start'), 
+##                      0, self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DELETEBACKNOTLINE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete current character'), 
+##                      self.trUtf8('Delete current character'), 
+##                      QKeySequence(self.trUtf8('Del')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_CLEAR)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete word to left'), 
+##                      self.trUtf8('Delete word to left'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Backspace')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DELWORDLEFT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete word to right'), 
+##                      self.trUtf8('Delete word to right'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Del')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DELWORDRIGHT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete line to left'), 
+##                      self.trUtf8('Delete line to left'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+Backspace')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DELLINELEFT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete line to right'), 
+##                      self.trUtf8('Delete line to right'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+Del')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_DELLINERIGHT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Insert new line'), 
+##                      self.trUtf8('Insert new line'), 
+##                      QKeySequence(self.trUtf8('Return')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_NEWLINE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Delete current line'), 
+##                      self.trUtf8('Delete current line'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+L')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEDELETE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Duplicate current line'), 
+##                      self.trUtf8('Duplicate current line'), 
+##                      QKeySequence(self.trUtf8('Ctrl+D')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEDUPLICATE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Swap current and previous lines'), 
+##                      self.trUtf8('Swap current and previous lines'), 
+##                      QKeySequence(self.trUtf8('Ctrl+T')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINETRANSPOSE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Cut current line'), 
+##                      self.trUtf8('Cut current line'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+L')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINECUT)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Copy current line'), 
+##                      self.trUtf8('Copy current line'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+T')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINECOPY)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Toggle insert/overtype'), 
+##                      self.trUtf8('Toggle insert/overtype'), 
+##                      QKeySequence(self.trUtf8('Ins')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_EDITTOGGLEOVERTYPE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Convert selection to lower case'), 
+##                      self.trUtf8('Convert selection to lower case'), 
+##                      QKeySequence(self.trUtf8('Alt+Shift+U')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LOWERCASE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Convert selection to upper case'), 
+##                      self.trUtf8('Convert selection to upper case'), 
+##                      QKeySequence(self.trUtf8('Ctrl+Shift+U')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_UPPERCASE)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Move to end of displayed line'), 
+##                      self.trUtf8('Move to end of displayed line'), 
+##                      QKeySequence(self.trUtf8('Alt+End')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEENDDISPLAY)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Extend selection to end of displayed line'), 
+##                      self.trUtf8('Extend selection to end of displayed line'), 
+##                      0, self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_LINEENDDISPLAYEXTEND)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Formfeed'), 
+##                      self.trUtf8('Formfeed'), 
+##                      0, self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_FORMFEED)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        act = QAction(self.trUtf8('Escape'), 
+##                      self.trUtf8('Escape'), 
+##                      QKeySequence(self.trUtf8('Esc')), self.editorActGrp)
+##        self.esm.setMapping(act, QextScintilla.SCI_CANCEL)
+##        self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##        self.editActions.append(act)
+##        
+##        # The following actions are only supported for QScintilla > 1.2
+##        # (i.e. build > 70)
+##        if QSCINTILLA_VERSION() > 0x010200:
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection down one line'), 
+##                          self.trUtf8('Extend rectangular selection down one line'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+Down')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_LINEDOWNRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection up one line'), 
+##                          self.trUtf8('Extend rectangular selection up one line'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+Up')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_LINEUPRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection left one character'), 
+##                          self.trUtf8('Extend rectangular selection left one character'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+Left')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_CHARLEFTRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection right one character'), 
+##                          self.trUtf8('Extend rectangular selection right one character'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+Right')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_CHARRIGHTRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection to first visible character in line'), 
+##                          self.trUtf8('Extend rectangular selection to first visible character in line'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+Home')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_VCHOMERECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection to end of line'), 
+##                          self.trUtf8('Extend rectangular selection to end of line'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+End')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_LINEENDRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection up one page'), 
+##                          self.trUtf8('Extend rectangular selection up one page'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+PgUp')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_PAGEUPRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            act = QAction(self.trUtf8('Extend rectangular selection down one page'), 
+##                          self.trUtf8('Extend rectangular selection down one page'), 
+##                          QKeySequence(self.trUtf8('Alt+Ctrl+PgDown')), self.editorActGrp)
+##            self.esm.setMapping(act, QextScintilla.SCI_PAGEDOWNRECTEXTEND)
+##            self.connect(act,SIGNAL('activated()'),self.esm,SLOT('map()'))
+##            self.editActions.append(act)
+##            
+##            # weird things are going on here, had to enable and disable
+##            # it to make it work with the new QScintilla shell
+##            self.editorActGrp.setEnabled(1)
+##            self.editorActGrp.setEnabled(0)
+    
+    def initEditMenu(self):
+        """
+        Public method to create the Edit menu
+        
+        @return the generated menu
+        """
+        menu = QPopupMenu(self.ui)
+        menu.insertTearOffHandle()
+        self.undoAct.addTo(menu)
+        self.redoAct.addTo(menu)
+        self.revertAct.addTo(menu)
+        menu.insertSeparator()
+        self.cutAct.addTo(menu)
+        self.copyAct.addTo(menu)
+        self.pasteAct.addTo(menu)
+        self.deleteAct.addTo(menu)
+        menu.insertSeparator()
+        self.indentAct.addTo(menu)
+        self.unindentAct.addTo(menu)
+        menu.insertSeparator()
+        self.commentAct.addTo(menu)
+        self.uncommentAct.addTo(menu)
+        self.streamCommentAct.addTo(menu)
+        self.boxCommentAct.addTo(menu)
+        menu.insertSeparator()
+        self.autoCompleteAct.addTo(menu)
+        self.autoCompleteFromDocAct.addTo(menu)
+        self.autoCompleteFromAPIsAct.addTo(menu)
+        menu.insertSeparator()
+        self.searchAct.addTo(menu)
+        self.searchAgainAct.addTo(menu)
+        self.replaceAct.addTo(menu)
+        menu.insertSeparator()
+        self.searchFilesAct.addTo(menu)
+        menu.insertSeparator()
+        self.gotoAct.addTo(menu)
+        self.gotoBraceAct.addTo(menu)
+        menu.insertSeparator()
+        self.selectBraceAct.addTo(menu)
+        self.selectAllAct.addTo(menu)
+        self.deselectAllAct.addTo(menu)
+        menu.insertSeparator()
+        self.shortenEmptyAct.addTo(menu)
+        self.convertEOLAct.addTo(menu)
+        
+        return menu
+        
+    def initEditToolbar(self):
+        """
+        Public method to create the Edit toolbar
+        
+        @return the generated toolbar
+        """
+        tb = QToolBar(self.ui)
+        self.undoAct.addTo(tb)
+        self.redoAct.addTo(tb)
+        tb.addSeparator()
+        self.cutAct.addTo(tb)
+        self.copyAct.addTo(tb)
+        self.pasteAct.addTo(tb)
+        self.deleteAct.addTo(tb)
+        tb.addSeparator()
+        self.indentAct.addTo(tb)
+        self.unindentAct.addTo(tb)
+        tb.addSeparator()
+        self.commentAct.addTo(tb)
+        self.uncommentAct.addTo(tb)
+        
+        return tb
+        
+    ##################################################################
+    ## Initialize the search related actions, search menu and toolbar
+    ##################################################################
+    
+    def initSearchActions(self):
+        """
+        Private method defining the user interface actions for the search commands.
+        """
+        self.searchActGrp = QActionGroup(self)
+        
+        self.searchAct = QAction(self.trUtf8('Search'),
+                QIconSet(icons.getPixmap("find.png")),
+                self.trUtf8('&Search...'),
+                QKeySequence(self.trUtf8("CTRL+F","Search|Search")),
+                self.searchActGrp)
+        self.searchAct.setStatusTip(self.trUtf8('Search for a text'))
+        self.searchAct.setWhatsThis(self.trUtf8(
+            """<b>Search</b>"""
+            """<p>Search for some text in the current editor. A"""
+            """ dialog is shown to enter the searchtext and options"""
+            """ for the search.</p>"""
+        ))
+        self.connect(self.searchAct,SIGNAL('activated()'),self.handleSearch)
+        self.searchActions.append(self.searchAct)
+        
+        self.searchAgainAct = QAction(self.trUtf8('Search again'),
+                QIconSet(icons.getPixmap("findNext.png")),
+                self.trUtf8('Search &again'),
+                Qt.Key_F3,self.searchActGrp)
+        self.searchAgainAct.setStatusTip(self.trUtf8('Search again for text'))
+        self.searchAgainAct.setWhatsThis(self.trUtf8(
+            """<b>Search again</b>"""
+            """<p>Search again for some text in the current editor."""
+            """ The previously entered searchtext and options are reused.</p>"""
+        ))
+        self.connect(self.searchAgainAct,SIGNAL('activated()'),self.searchDlg.handleFindNext)
+        self.searchActions.append(self.searchAgainAct)
+        
+        self.replaceAct = QAction(self.trUtf8('Replace'),
+                self.trUtf8('&Replace...'),
+                QKeySequence(self.trUtf8("CTRL+R","Search|Replace")),
+                self.searchActGrp)
+        self.replaceAct.setStatusTip(self.trUtf8('Replace some text'))
+        self.replaceAct.setWhatsThis(self.trUtf8(
+            """<b>Replace</b>"""
+            """<p>Search for some text in the current editor and replace it. A"""
+            """ dialog is shown to enter the searchtext, the replacement text"""
+            """ and options for the search and replace.</p>"""
+        ))
+        self.connect(self.replaceAct,SIGNAL('activated()'),self.handleReplace)
+        self.searchActions.append(self.replaceAct)
+        
+        self.gotoAct = QAction(self.trUtf8('Goto Line'),
+                QIconSet(icons.getPixmap("goto.png")),
+                self.trUtf8('&Goto Line...'),
+                QKeySequence(self.trUtf8("CTRL+G","Search|Goto Line")),
+                self.searchActGrp)
+        self.gotoAct.setStatusTip(self.trUtf8('Goto Line'))
+        self.gotoAct.setWhatsThis(self.trUtf8(
+            """<b>Goto Line</b>"""
+            """<p>Go to a specific line of text in the current editor."""
+            """ A dialog is shown to enter the linenumber.</p>"""
+        ))
+        self.connect(self.gotoAct,SIGNAL('activated()'),self.handleGoto)
+        self.searchActions.append(self.gotoAct)
+        
+        self.gotoBraceAct = QAction(self.trUtf8('Goto Brace'),
+                QIconSet(icons.getPixmap("gotoBrace.png")),
+                self.trUtf8('Goto &Brace'),
+                QKeySequence(self.trUtf8("CTRL+L","Search|Goto Brace")),
+                self.searchActGrp)
+        self.gotoBraceAct.setStatusTip(self.trUtf8('Goto Brace'))
+        self.gotoBraceAct.setWhatsThis(self.trUtf8(
+            """<b>Goto Brace</b>"""
+            """<p>Go to the matching brace in the current editor.</p>"""
+        ))
+        self.connect(self.gotoBraceAct,SIGNAL('activated()'),self.handleGotoBrace)
+        self.searchActions.append(self.gotoBraceAct)
+        
+        self.searchActGrp.setEnabled(0)
+        
+        self.searchFilesAct = QAction(self.trUtf8('Search in Files'),
+                QIconSet(icons.getPixmap("projectFind.png")),
+                self.trUtf8('Search in &Files...'),
+                QKeySequence(self.trUtf8("SHIFT+CTRL+F","Search|Search Files")),
+                self)
+        self.searchFilesAct.setStatusTip(self.trUtf8('Search for a text in files'))
+        self.searchFilesAct.setWhatsThis(self.trUtf8(
+            """<b>Search in Files</b>"""
+            """<p>Search for some text in the files of a directory tree"""
+            """ or the project. A dialog is shown to enter the searchtext"""
+            """ and options for the search and to display the result.</p>"""
+        ))
+        self.connect(self.searchFilesAct,SIGNAL('activated()'),self.handleSearchFiles)
+        self.searchActions.append(self.searchFilesAct)
+        
+    def initSearchToolbar(self):
+        """
+        Public method to create the Search toolbar
+        
+        @return the generated toolbar
+        """
+        tb = QToolBar(self.ui)
+        self.searchAct.addTo(tb)
+        self.searchAgainAct.addTo(tb)
+        tb.addSeparator()
+        self.searchFilesAct.addTo(tb)
+        tb.addSeparator()
+        self.gotoAct.addTo(tb)
+        self.gotoBraceAct.addTo(tb)
+        
+        return tb
+        
+    ##################################################################
+    ## Initialize the view related actions, view menu and toolbar
+    ##################################################################
+    
+    def initViewActions(self):
+        """
+        Protected method defining the user interface actions for the view commands.
+        """
+        self.viewActGrp = QActionGroup(self)
+        self.viewFoldActGrp = QActionGroup(self)
+
+        self.zoomInAct = QAction(self.trUtf8('Zoom in'),
+                            QIconSet(icons.getPixmap("zoomIn.png")),
+                            self.trUtf8('Zoom &in'),
+                            Qt.CTRL+Qt.Key_Plus, self.viewActGrp)
+        self.zoomInAct.setStatusTip(self.trUtf8('Zoom in on the text'))
+        self.zoomInAct.setWhatsThis(self.trUtf8(
+                """<b>Zoom in</b>"""
+                """<p>Zoom in on the text. This makes the text bigger.</p>"""
+                ))
+        self.connect(self.zoomInAct,SIGNAL('activated()'),self.handleZoomIn)
+        self.viewActions.append(self.zoomInAct)
+        
+        self.zoomOutAct = QAction(self.trUtf8('Zoom out'),
+                            QIconSet(icons.getPixmap("zoomOut.png")),
+                            self.trUtf8('Zoom &out'),
+                            Qt.CTRL+Qt.Key_Minus, self.viewActGrp)
+        self.zoomOutAct.setStatusTip(self.trUtf8('Zoom out on the text'))
+        self.zoomOutAct.setWhatsThis(self.trUtf8(
+                """<b>Zoom out</b>"""
+                """<p>Zoom out on the text. This makes the text smaller.</p>"""
+                ))
+        self.connect(self.zoomOutAct,SIGNAL('activated()'),self.handleZoomOut)
+        self.viewActions.append(self.zoomOutAct)
+        
+        self.zoomToAct = QAction(self.trUtf8('Zoom'),
+                            QIconSet(icons.getPixmap("zoomTo.png")),
+                            self.trUtf8('&Zoom'),
+                            0, self.viewActGrp)
+        self.zoomToAct.setStatusTip(self.trUtf8('Zoom the text'))
+        self.zoomToAct.setWhatsThis(self.trUtf8(
+                """<b>Zoom</b>"""
+                """<p>Zoom the text. This opens a dialog where the"""
+                """ desired size can be entered.</p>"""
+                ))
+        self.connect(self.zoomToAct,SIGNAL('activated()'),self.handleZoom)
+        self.viewActions.append(self.zoomToAct)
+        
+        self.toggleAllAct = QAction(self.trUtf8('Toggle all folds'),
+                            self.trUtf8('Toggle &all folds'),
+                            0, self.viewFoldActGrp)
+        self.toggleAllAct.setStatusTip(self.trUtf8('Toggle all folds'))
+        self.toggleAllAct.setWhatsThis(self.trUtf8(
+                """<b>Toggle all folds</b>"""
+                """<p>Toggle all folds of the current editor.</p>"""
+                ))
+        self.connect(self.toggleAllAct,SIGNAL('activated()'),self.handleToggleAll)
+        self.viewActions.append(self.toggleAllAct)
+        
+        self.toggleCurrentAct = QAction(self.trUtf8('Toggle current fold'),
+                            self.trUtf8('Toggle &current fold'),
+                            0, self.viewFoldActGrp)
+        self.toggleCurrentAct.setStatusTip(self.trUtf8('Toggle current fold'))
+        self.toggleCurrentAct.setWhatsThis(self.trUtf8(
+                """<b>Toggle current fold</b>"""
+                """<p>Toggle the folds of the current line of the current editor.</p>"""
+                ))
+        self.connect(self.toggleCurrentAct,SIGNAL('activated()'),self.handleToggleCurrent)
+        self.viewActions.append(self.toggleCurrentAct)
+        
+        self.unhighlightAct = QAction(self.trUtf8('Remove all highlights'),
+                            QIconSet(icons.getPixmap("unhighlight.png")),
+                            self.trUtf8('Remove all highlights'),
+                            0, self)
+        self.unhighlightAct.setStatusTip(self.trUtf8('Remove all highlights'))
+        self.unhighlightAct.setWhatsThis(self.trUtf8(
+                """<b>Remove all highlights</b>"""
+                """<p>Remove the highlights of all editors.</p>"""
+                ))
+        self.connect(self.unhighlightAct,SIGNAL('activated()'),self.unhighlight)
+        self.viewActions.append(self.unhighlightAct)
+        
+        self.splitViewAct = QAction(self.trUtf8('Split view'),
+                            QIconSet(icons.getPixmap("splitVertical.png")),
+                            self.trUtf8('&Split view'),
+                            0, self)
+        self.splitViewAct.setStatusTip(self.trUtf8('Add a split to the view'))
+        self.splitViewAct.setWhatsThis(self.trUtf8(
+                """<b>Split view</b>"""
+                """<p>Add a split to the view.</p>"""
+                ))
+        self.connect(self.splitViewAct,SIGNAL('activated()'),self.handleSplitView)
+        self.viewActions.append(self.splitViewAct)
+        
+        self.splitOrientationAct = QAction(self.trUtf8('Arrange horizontally'),
+                            self.trUtf8('Arrange &horizontally'),
+                            0, self, None, 1)
+        self.splitOrientationAct.setStatusTip(self.trUtf8('Arrange the splitted views horizontally'))
+        self.splitOrientationAct.setWhatsThis(self.trUtf8(
+                """<b>Arrange horizontally</b>"""
+                """<p>Arrange the splitted views horizontally.</p>"""
+                ))
+        self.splitOrientationAct.setOn(0)
+        self.connect(self.splitOrientationAct,SIGNAL('activated()'),self.handleSplitOrientation)
+        self.viewActions.append(self.splitOrientationAct)
+        
+        self.splitRemoveAct = QAction(self.trUtf8('Remove split'),
+                            QIconSet(icons.getPixmap("remsplitVertical.png")),
+                            self.trUtf8('&Remove split'),
+                            0, self)
+        self.splitRemoveAct.setStatusTip(self.trUtf8('Remove the current split'))
+        self.splitRemoveAct.setWhatsThis(self.trUtf8(
+                """<b>Remove split</b>"""
+                """<p>Remove the current split.</p>"""
+                ))
+        self.connect(self.splitRemoveAct,SIGNAL('activated()'),self.removeSplit)
+        self.viewActions.append(self.splitRemoveAct)
+        
+        self.viewActGrp.setEnabled(0)
+        self.viewFoldActGrp.setEnabled(0)
+        self.unhighlightAct.setEnabled(0)
+        self.splitViewAct.setEnabled(0)
+        self.splitOrientationAct.setEnabled(0)
+        self.splitRemoveAct.setEnabled(0)
+        
+    def initViewMenu(self):
+        """
+        Public method to create the View menu
+        
+        @return the generated menu
+        """
+        menu = QPopupMenu(self.ui)
+        menu.insertTearOffHandle()
+        self.viewActGrp.addTo(menu)
+        menu.insertSeparator()
+        self.viewFoldActGrp.addTo(menu)
+        menu.insertSeparator()
+        self.unhighlightAct.addTo(menu)
+        if self.canSplit():
+            menu.insertSeparator()
+            self.splitViewAct.addTo(menu)
+            self.splitOrientationAct.addTo(menu)
+            self.splitRemoveAct.addTo(menu)       
+        return menu
+        
+    def initViewToolbar(self):
+        """
+        Public method to create the View toolbar
+        
+        @return the generated toolbar
+        """
+        tb = QToolBar(self.ui)
+        self.viewActGrp.addTo(tb)
+        tb.addSeparator()
+        self.unhighlightAct.addTo(tb)
+        if self.canSplit():
+            tb.addSeparator()
+            self.splitViewAct.addTo(tb)
+            self.splitRemoveAct.addTo(tb)
+        
+        return tb
+        
+    ##################################################################
+    ## Initialize the macro related actions and macro menu
+    ##################################################################
+    
+    def initMacroActions(self):
+        """
+        Private method defining the user interface actions for the macro commands.
+        """
+        self.macroActGrp = QActionGroup(self)
+
+        self.macroStartRecAct = QAction(self.trUtf8('Start Macro Recording'),
+                            self.trUtf8('S&tart Macro Recording'),
+                            0, self.macroActGrp)
+        self.macroStartRecAct.setStatusTip(self.trUtf8('Start Macro Recording'))
+        self.macroStartRecAct.setWhatsThis(self.trUtf8(
+                """<b>Start Macro Recording</b>"""
+                """<p>Start recording editor commands into a new macro.</p>"""
+                ))
+        self.connect(self.macroStartRecAct,SIGNAL('activated()'),self.handleMacroStartRecording)
+        self.macroActions.append(self.macroStartRecAct)
+        
+        self.macroStopRecAct = QAction(self.trUtf8('Stop Macro Recording'),
+                            self.trUtf8('Sto&p Macro Recording'),
+                            0, self.macroActGrp)
+        self.macroStopRecAct.setStatusTip(self.trUtf8('Stop Macro Recording'))
+        self.macroStopRecAct.setWhatsThis(self.trUtf8(
+                """<b>Stop Macro Recording</b>"""
+                """<p>Stop recording editor commands into a new macro.</p>"""
+                ))
+        self.connect(self.macroStopRecAct,SIGNAL('activated()'),self.handleMacroStopRecording)
+        self.macroActions.append(self.macroStopRecAct)
+        
+        self.macroRunAct = QAction(self.trUtf8('Run Macro'),
+                            self.trUtf8('&Run Macro'),
+                            0, self.macroActGrp)
+        self.macroRunAct.setStatusTip(self.trUtf8('Run Macro'))
+        self.macroRunAct.setWhatsThis(self.trUtf8(
+                """<b>Run Macro</b>"""
+                """<p>Run a previously recorded editor macro.</p>"""
+                ))
+        self.connect(self.macroRunAct,SIGNAL('activated()'),self.handleMacroRun)
+        self.macroActions.append(self.macroRunAct)
+        
+        self.macroDeleteAct = QAction(self.trUtf8('Delete Macro'),
+                            self.trUtf8('&Delete Macro'),
+                            0, self.macroActGrp)
+        self.macroDeleteAct.setStatusTip(self.trUtf8('Delete Macro'))
+        self.macroDeleteAct.setWhatsThis(self.trUtf8(
+                """<b>Delete Macro</b>"""
+                """<p>Delete a previously recorded editor macro.</p>"""
+                ))
+        self.connect(self.macroDeleteAct,SIGNAL('activated()'),self.handleMacroDelete)
+        self.macroActions.append(self.macroDeleteAct)
+        
+        self.macroLoadAct = QAction(self.trUtf8('Load Macro'),
+                            self.trUtf8('&Load Macro'),
+                            0, self.macroActGrp)
+        self.macroLoadAct.setStatusTip(self.trUtf8('Load Macro'))
+        self.macroLoadAct.setWhatsThis(self.trUtf8(
+                """<b>Load Macro</b>"""
+                """<p>Load an editor macro from a file.</p>"""
+                ))
+        self.connect(self.macroLoadAct,SIGNAL('activated()'),self.handleMacroLoad)
+        self.macroActions.append(self.macroLoadAct)
+        
+        self.macroSaveAct = QAction(self.trUtf8('Save Macro'),
+                            self.trUtf8('&Save Macro'),
+                            0, self.macroActGrp)
+        self.macroSaveAct.setStatusTip(self.trUtf8('Save Macro'))
+        self.macroSaveAct.setWhatsThis(self.trUtf8(
+                """<b>Save Macro</b>"""
+                """<p>Save a previously recorded editor macro to a file.</p>"""
+                ))
+        self.connect(self.macroSaveAct,SIGNAL('activated()'),self.handleMacroSave)
+        self.macroActions.append(self.macroSaveAct)
+        
+        self.macroActGrp.setEnabled(0)
+        
+    def initMacroMenu(self):
+        """
+        Public method to create the Macro menu
+        
+        @return the generated menu
+        """
+        menu = QPopupMenu(self.ui)
+        menu.insertTearOffHandle()
+        self.macroActGrp.addTo(menu)
+        return menu
+    
+    #####################################################################
+    ## Initialize the bookmark related actions, bookmark menu and toolbar
+    #####################################################################
+    
+    def initBookmarkActions(self):
+        """
+        Private method defining the user interface actions for the bookmarks commands.
+        """
+        self.bookmarkActGrp = QActionGroup(self)
+
+        self.bookmarkToggleAct = QAction(self.trUtf8('Toggle Bookmark'),
+                            QIconSet(icons.getPixmap("bookmarkToggle.png")),
+                            self.trUtf8('&Toggle Bookmark'),
+                            QKeySequence(self.trUtf8("ALT+CTRL+T","Bookmark|Toggle")),
+                            self.bookmarkActGrp)
+        self.bookmarkToggleAct.setStatusTip(self.trUtf8('Toggle Bookmark'))
+        self.bookmarkToggleAct.setWhatsThis(self.trUtf8(
+                """<b>Toggle Bookmark</b>"""
+                """<p>Toggle a bookmark at the current line of the current editor.</p>"""
+                ))
+        self.connect(self.bookmarkToggleAct,SIGNAL('activated()'),self.handleToggleBookmark)
+        self.bookmarkActions.append(self.bookmarkToggleAct)
+        
+        self.bookmarkNextAct = QAction(self.trUtf8('Next Bookmark'),
+                            QIconSet(icons.getPixmap("bookmarkNext.png")),
+                            self.trUtf8('&Next Bookmark'),
+                            QKeySequence(self.trUtf8("CTRL+PgDown","Bookmark|Next")),
+                            self.bookmarkActGrp)
+        self.bookmarkNextAct.setStatusTip(self.trUtf8('Next Bookmark'))
+        self.bookmarkNextAct.setWhatsThis(self.trUtf8(
+                """<b>Next Bookmark</b>"""
+                """<p>Go to next bookmark of the current editor.</p>"""
+                ))
+        self.connect(self.bookmarkNextAct,SIGNAL('activated()'),self.handleNextBookmark)
+        self.bookmarkActions.append(self.bookmarkNextAct)
+        
+        self.bookmarkPreviousAct = QAction(self.trUtf8('Previous Bookmark'),
+                            QIconSet(icons.getPixmap("bookmarkPrevious.png")),
+                            self.trUtf8('&Previous Bookmark'),
+                            QKeySequence(self.trUtf8("CTRL+PgUp","Bookmark|Previous")),
+                            self.bookmarkActGrp)
+        self.bookmarkPreviousAct.setStatusTip(self.trUtf8('Previous Bookmark'))
+        self.bookmarkPreviousAct.setWhatsThis(self.trUtf8(
+                """<b>Previous Bookmark</b>"""
+                """<p>Go to previous bookmark of the current editor.</p>"""
+                ))
+        self.connect(self.bookmarkPreviousAct,SIGNAL('activated()'),self.handlePreviousBookmark)
+        self.bookmarkActions.append(self.bookmarkPreviousAct)
+        
+        self.bookmarkClearAct = QAction(self.trUtf8('Clear Bookmarks'),
+                            self.trUtf8('&Clear Bookmarks'),
+                            QKeySequence(self.trUtf8("ALT+CTRL+C","Bookmark|Clear")),
+                            self.bookmarkActGrp)
+        self.bookmarkClearAct.setStatusTip(self.trUtf8('Clear Bookmarks'))
+        self.bookmarkClearAct.setWhatsThis(self.trUtf8(
+                """<b>Clear Bookmarks</b>"""
+                """<p>Clear bookmarks of all editors.</p>"""
+                ))
+        self.connect(self.bookmarkClearAct,SIGNAL('activated()'),self.handleClearAllBookmarks)
+        self.bookmarkActions.append(self.bookmarkClearAct)
+        
+        self.syntaxErrorGotoAct = QAction(self.trUtf8('Goto Syntax Error'),
+                            QIconSet(icons.getPixmap("syntaxErrorGoto.png")),
+                            self.trUtf8('&Goto Syntax Error'),
+                            0,
+                            self.bookmarkActGrp)
+        self.syntaxErrorGotoAct.setStatusTip(self.trUtf8('Goto Syntax Error'))
+        self.syntaxErrorGotoAct.setWhatsThis(self.trUtf8(
+                """<b>Goto Syntax Error</b>"""
+                """<p>Go to next syntax error of the current editor.</p>"""
+                ))
+        self.connect(self.syntaxErrorGotoAct,SIGNAL('activated()'),self.handleGotoSyntaxError)
+        self.bookmarkActions.append(self.syntaxErrorGotoAct)
+        
+        self.syntaxErrorClearAct = QAction(self.trUtf8('Clear Syntax Errors'),
+                            self.trUtf8('Clear &Syntax Errors'),
+                            0,
+                            self.bookmarkActGrp)
+        self.syntaxErrorClearAct.setStatusTip(self.trUtf8('Clear Syntax Errors'))
+        self.syntaxErrorClearAct.setWhatsThis(self.trUtf8(
+                """<b>Clear Syntax Errors</b>"""
+                """<p>Clear syntax errors of all editors.</p>"""
+                ))
+        self.connect(self.syntaxErrorClearAct,SIGNAL('activated()'),self.handleClearAllSyntaxErrors)
+        self.bookmarkActions.append(self.syntaxErrorClearAct)
+        
+        self.bookmarkActGrp.setEnabled(0)
+        
+    def initBookmarkMenu(self):
+        """
+        Public method to create the Bookmark menu
+        
+        @return the generated menu
+        """
+        menu = QPopupMenu(self.ui)
+        self.bookmarksMenu = QPopupMenu(menu)
+        
+        menu.insertTearOffHandle()
+        self.bookmarkToggleAct.addTo(menu)
+        self.bookmarkNextAct.addTo(menu)
+        self.bookmarkPreviousAct.addTo(menu)
+        self.bookmarkClearAct.addTo(menu)
+        menu.insertSeparator()
+        menu.insertItem(self.trUtf8('&Bookmarks'), self.bookmarksMenu)
+        menu.insertSeparator()
+        self.syntaxErrorGotoAct.addTo(menu)
+        self.syntaxErrorClearAct.addTo(menu)
+        
+        self.connect(self.bookmarksMenu,SIGNAL('aboutToShow()'),self.handleShowBookmarksMenu)
+        self.connect(self.bookmarksMenu,SIGNAL('activated(int)'),self.handleBookmarkSelected)
+        
+        return menu
+        
+    def initBookmarkToolbar(self):
+        """
+        Public method to create the Bookmark toolbar
+        
+        @return the generated toolbar
+        """
+        tb = QToolBar(self.ui)
+        self.bookmarkToggleAct.addTo(tb)
+        self.bookmarkNextAct.addTo(tb)
+        self.bookmarkPreviousAct.addTo(tb)
+        tb.addSeparator()
+        self.syntaxErrorGotoAct.addTo(tb)
+        
+        return tb
+    
+    ##################################################################
+    ## Methods and slots that deal with file and window handling
+    ##################################################################
+    
+    def handleOpen(self,prog=None):
+        """
+        Public slot to open a Python (or other) file.
+        
+        @param prog name of file to be opened (string or QString)
+        """
+        # Get the file name if one wasn't specified.
+        if prog is None:
+            # set the cwd of the dialog based on the following search criteria:
+            #     1: Directory of currently active editor
+            #     2: Directory of currently active Project
+            #     3: CWD
+            filter = self._getOpenFileFilter()
+            prog = QFileDialog.getOpenFileName(self._getOpenStartDir(),
+                        self.fileFiltersString, self.ui, None, None, filter)
+
+            if prog.isNull():
+                return
+
+        prog = normabspath(unicode(prog))
+
+        # Open up the new file.
+        self.handlePythonFile(prog)
+
+    def checkDirty(self, editor):
+        """
+        Private method to check dirty status and open a message window.
+        
+        @param editor editor window to check
+        @return flag indicating successful reset of the dirty flag (boolean)
+        """        
+        if editor.modified:
+            print 'CHECKDIRTY AAAAAA'
+            fn = editor.getFileName()
+            if fn is None:
+                fn = self.trUtf8('Noname')
+            res = QMessageBox.warning(self.parent(), 
+                self.trUtf8("File Modified"),
+                self.trUtf8("The file <b>%1</b> has unsaved changes.")
+                    .arg(fn),
+                self.trUtf8("&Save"), self.trUtf8("&Discard changes"),
+                self.trUtf8("&Abort"), 0, 2)
+            if res == 0:
+                (ok, newName) = editor.saveFile()
+                if ok:
+                    self.setEditorName(editor, newName)
+                return ok
+            elif res == 2:
+                return 0
+        print 'CHECKDIRTY BBBBBB'
+        return 1
+        
+    def checkAllDirty(self):
+        """
+        Public method to check the dirty status of all editors.
+        
+        @return flag indicating successful reset of all dirty flags (boolean)
+        """
+        for editor in self.editors:
+            if not self.checkDirty(editor):
+                return 0
+                
+        return 1
+        
+    def closeEditor(self, editor):
+        """
+        Private method to close an editor window.
+        
+        @param editor editor window to be closed
+        @return flag indicating success (boolean)
+        """
+        print 'CLOSEEDITOR'
+        # save file if necessary
+        if not self.checkDirty(editor):
+            return 0
+            
+        # remove the window
+        self.removeView(editor)
+        self.editors.remove(editor)        
+        if not len(self.editors):
+            self.handleLastEditorClosed()
+            self.emit(PYSIGNAL('lastEditorClosed'), ()) #CS_pbruno connecter signal avec l'appli
+        return 1
+    
+    def handleClose(self):
+        """
+        Public method to close the current window.
+        
+        @return flag indicating success (boolean)
+        """
+        aw = self.activeWindow()
+        if aw is None:
+            return 0
+            
+        res = self.closeEditor(aw)
+        if res and aw == self.currentEditor:
+            self.currentEditor = None
+            
+        return res
+        
+    def handleNewView(self):
+        """
+        Public method to close the current window.
+        
+        @return flag indicating success (boolean)
+        """
+        aw = self.activeWindow()
+        if aw is None:
+            return 0
+            
+        aw.handleNewView()
+        
+            
+    def handleCloseAll(self):
+        """
+        Private method to close all editor windows via file menu.
+        """
+        savedEditors = self.editors[:]
+        for editor in savedEditors:
+            self.closeEditor(editor)
+            
+    def handleCloseWindow(self, fn):
+        """
+        Public method to close an arbitrary source editor.
+        
+        @param fn filename of editor to be closed
+        @return flag indicating success (boolean)
+        """
+        for editor in self.editors:
+            if samepath(fn, editor.getFileName()):
+                break
+        else:
+            return 1
+            
+        res = self.closeEditor(editor)
+        if res and editor == self.currentEditor:
+            self.currentEditor = None
+            
+        return res
+        
+    def handleExit(self):
+        """
+        Public method to handle the debugged program terminating.
+        """
+        if self.currentEditor is not None:
+            self.currentEditor.highlight()
+            self.currentEditor = None
+            
+        self.setSbFile()
+
+    def handlePythonFile(self,pyfn,lineno=None):
+        """
+        Public method to handle the user selecting a file for display.
+        
+        @param pyfn name of file to be opened
+        @param lineno line number to place the cursor at
+        """
+        try:
+            self.displayPythonFile(pyfn,lineno)
+        except IOError:
+            pass
+
+    def displayPythonFile(self,fn,lineno=None):
+        """
+        Public slot to display a file in an editor.
+        
+        @param fn name of file to be opened
+        @param lineno line number to place the cursor at
+        """
+        isPyFile = lineno and lineno < 0
+        newWin, editor = self.getEditor(fn, isPythonFile=isPyFile)
+        
+        if newWin:
+            self.handleModificationStatusChanged(editor.modified, editor)
+        self.checkActions(editor)
+            
+        if lineno is not None and lineno >= 0:
+            editor.ensureVisible(lineno)
+            editor.gotoLine(lineno)
+        
+        # insert filename into list of recently opened files
+        self.addToRecentList(fn)
+        
+    def newEditorView(self, fn, caller):
+        """
+        Public method to create a new editor displaying the given document.
+        
+        @param fn filename of this view
+        @param caller reference to the editor calling this method        
+        """
+        from editor import JDCEditor
+        print 50*'='
+        print 'newEditorView fn->',fn
+        print 'newEditorView caller.jdc->',caller.jdc
+        print 50*'+'
+        editor = JDCEditor(fn,self, editor=caller)
+        self.editors.append(editor)
+        self.connect(editor, PYSIGNAL('modificationStatusChanged'),
+            self.handleModificationStatusChanged)
+        self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
+        self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
+        self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
+        self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
+        self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
+        self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'), 
+            self.handleEditoracAPIsAvailable)
+        self.handleEditorOpened()
+        self.emit(PYSIGNAL('editorOpened'), (fn,))
+        
+        self.connect(caller, PYSIGNAL('editorRenamed'), editor.handleRenamed)
+        self.connect(editor, PYSIGNAL('editorRenamed'), caller.handleRenamed)
+        
+        self.addView(editor, fn)
+        self.handleModificationStatusChanged(editor.modified, editor)
+        self.checkActions(editor)
+        
+    def addToRecentList(self, fn):
+        """
+        Public slot to add a filename to the list of recently opened files.
+        
+        @param fn name of the file to be added
+        """
+        self.recent.remove(fn)
+        self.recent.prepend(fn)
+        if len(self.recent) > 9:
+            self.recent = self.recent[:9]
+
+    def toggleWindow(self,w):
+        """
+        Private method to toggle a workspace window.
+        
+        @param w editor window to be toggled
+        """
+        if w.isHidden():
+            w.show()
+        else:
+            w.hide()
+
+    def setFileLine(self,fn,line,error=0,syntaxError=0):
+        """
+        Public method to update the user interface when the current program or line changes.
+        
+        @param fn filename of editor to update (string)
+        @param line line number to highlight (int)
+        @param error flag indicating an error highlight (boolean)
+        @param syntaxError flag indicating a syntax error
+        """
+        self.setSbFile(fn,line)
+
+        try:
+            newWin, self.currentEditor = self.getEditor(fn)
+        except IOError:
+            return
+
+        # Change the highlighted line.
+        self.currentEditor.highlight(line,error,syntaxError)
+
+        self.currentEditor.highlightVisible()
+        self.checkActions(self.currentEditor, 0)
+            
+    def setSbFile(self,fn=None,line=None,pos=None):
+        """
+        Private method to set the file info in the status bar.
+        
+        @param fn filename to display (string)
+        @param line line number to display (int)
+        @param pos character position to display (int)
+        """
+        if fn is None:
+            fn = ''
+            writ = '   '
+        else:
+            if QFileInfo(fn).isWritable():
+                writ = ' rw'
+            else:
+                writ = ' ro'
+        
+        self.sbWritable.setText(writ)
+        self.sbFile.setText(self.trUtf8('File: %1').arg(fn,-50))
+
+        if line is None:
+            line = ''
+
+        self.sbLine.setText(self.trUtf8('Line: %1').arg(line,5))
+
+        if pos is None:
+            pos = ''
+            
+        self.sbPos.setText(self.trUtf8('Pos: %1').arg(pos, 5))
+        
+    def unhighlight(self, current=0):
+        """
+        Public method to switch off all highlights.
+        
+        @param current flag indicating only the current editor should be unhighlighted
+                (boolean)
+        """
+        if current: 
+            if self.currentEditor is not None:
+                self.currentEditor.highlight()
+        else:
+            for editor in self.editors:
+                editor.highlight()
+
+    def getOpenFilenames(self):
+        """
+        Public method returning a list of the filenames of all editors.
+        
+        @return list of all opened filenames (list of strings)
+        """
+        filenames = []
+        for editor in self.editors:
+            fn = editor.getFileName()
+            if fn is not None:
+                filenames.append(fn)
+                
+        return filenames
+                
+    def getEditor(self, fn):
+        """
+        Private method to return the editor displaying the given file.
+        
+        If there is no editor with the given file, a new editor window is
+        created.
+        
+        @param fn filename to look for
+        @param isPythonFile flag indicating that this is a Python file
+                even if it doesn't have the .py extension (boolean)
+        @return tuple of two values giving a flag indicating a new window creation and
+            a reference to the editor displaying this file
+        """
+        newWin = 0
+        for editor in self.editors:
+            if samepath(fn, editor.getFileName()):
+                break
+        else:
+            from editor import JDCEditor
+            editor = JDCEditor(fn,self)
+            #editor.setOpaqueResize()
+            #editor = JDCEditor(fn,None,self)
+            #editor = Editor(self.dbs,fn,self,isPythonFile=isPythonFile)
+            
+            self.editors.append(editor)
+            self.connect(editor, PYSIGNAL('modificationStatusChanged'),
+                self.handleModificationStatusChanged)
+            self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
+            self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
+            self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
+            self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
+            self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
+            self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'), 
+                self.handleEditoracAPIsAvailable)
+            self.handleEditorOpened()
+            self.emit(PYSIGNAL('editorOpened'), (fn,))
+            newWin = 1
+
+        if newWin:
+            self.addView(editor, fn)
+        else:
+            self.showView(editor, fn)
+            
+        return (newWin, editor)
+        
+        
+    def getOpenEditor(self, fn):
+        """
+        Public method to return the editor displaying the given file.
+        
+        @param fn filename to look for
+        @return a reference to the editor displaying this file or None, if
+            no editor was found
+        """
+        for editor in self.editors:
+            if samepath(fn, editor.getFileName()):
+                return editor
+                
+        return None
+
+    def getActiveName(self):
+        """
+        Public method to retrieve the filename of the active window.
+        
+        @return filename of active window (string)
+        """
+        aw = self.activeWindow()
+        if aw:
+            return aw.getFileName()
+        else:
+            return None
+
+    def saveEditor(self, fn):
+        """
+        Public method to save a named editor file.
+        
+        @param fn filename of editor to be saved (string)
+        @return flag indicating success (boolean)
+        """
+        for editor in self.editors:
+            if samepath(fn, editor.getFileName()):
+                break
+        else:
+            return 1
+            
+        if not editor.modified:
+            return 1
+        else:
+            ok, dummy = editor.saveFile()
+            return ok
+        
+    def saveCurrentEditor(self):
+        """
+        Public slot to save the contents of the current editor.
+        """
+        aw = self.activeWindow()
+        if aw:
+            ok, newName = aw.saveFile()
+            if ok:
+                self.setEditorName(aw, newName)
+        else:
+            return
+
+    def saveAsCurrentEditor(self):
+        """
+        Public slot to save the contents of the current editor to a new file.
+        """
+        aw = self.activeWindow()
+        if aw:
+            ok, newName = aw.saveFileAs()
+            if ok:
+                self.setEditorName(aw, newName)
+        else:
+            return
+
+    def saveAllEditors(self):
+        """
+        Public slot to save the contents of all editors.
+        """
+        for editor in self.editors:
+            ok, newName = editor.saveFile()
+            if ok:
+                self.setEditorName(editor, newName)
+        
+        # restart autosave timer
+        if self.autosaveInterval > 0:
+            self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
+
+    def saveCurrentEditorToProject(self):
+        """
+        Public slot to save the contents of the current editor to the current project.
+        """
+        pro = self.ui.getProject()
+        path = pro.ppath
+        aw = self.activeWindow()
+        if aw:
+            ok, newName = aw.saveFileAs(path)
+            if ok:
+                self.setEditorName(aw, newName)
+                pro.appendFile(newName)
+        else:
+            return
+        
+    def newEditor(self):
+        """
+        Public slot to generate a new empty editor.
+        """
+        from editor import JDCEditor
+        editor = JDCEditor(None,self)
+        
+        self.editors.append(editor)
+        self.connect(editor, PYSIGNAL('modificationStatusChanged'),
+            self.handleModificationStatusChanged)
+        self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
+        self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
+        self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
+        self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
+        self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
+        self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'), 
+            self.handleEditoracAPIsAvailable)
+        self.addView(editor, None)
+        self.handleEditorOpened()
+        self.checkActions(editor)
+        self.emit(PYSIGNAL('editorOpened'), (None,))
+        
+    def printCurrentEditor(self):
+        """
+        Public slot to print the contents of the current editor.
+        """
+        aw = self.activeWindow()
+        if aw:
+            aw.printFile()
+        else:
+            return
+
+    def printCurrentEditorSel(self):
+        """
+        Public slot to print the selection of the current editor.
+        """
+        aw = self.activeWindow()
+        if aw:
+            aw.printSelection()
+        else:
+            return
+
+##    def handleShowRecentMenu(self):
+##        """
+##        Private method to set up recent files menu.
+##        """
+##        idx = 0
+##        self.recentMenu.clear()
+##        
+##        for rp in self.recent:
+##            id = self.recentMenu.insertItem('&%d. %s' % (idx+1, unicode(rp)),
+##                                            self.handleOpenRecent)
+##            self.recentMenu.setItemParameter(id,idx)
+##            
+##            idx = idx + 1
+##            
+##        self.recentMenu.insertSeparator()
+##        self.recentMenu.insertItem(self.trUtf8('&Clear'), self.handleClearRecent)
+##        
+##    def handleOpenRecent(self, idx):
+##        """
+##        Private method to open a file from the list of rencently opened files.
+##        
+##        @param idx index of the selected entry (int)
+##        """
+##        self.handlePythonFile(unicode(self.recent[idx]))
+##        
+##    def handleClearRecent(self):
+##        """
+##        Private method to clear the recent files menu.
+##        """
+##        self.recent = QStringList()
+        
+        
+    
+        
+    def handleNewProject(self):
+        """
+        Public slot to handle the NewProject signal.
+        """
+        self.saveToProjectAct.setEnabled(1)
+        
+    def handleProjectOpened(self):
+        """
+        Public slot to handle the projectOpened signal.
+        """
+        self.saveToProjectAct.setEnabled(1)
+        
+    def handleProjectClosed(self):
+        """
+        Public slot to handle the projectClosed signal.
+        """
+        self.saveToProjectAct.setEnabled(0)
+        
+    def handleProjectFileRenamed(self, oldfn, newfn):
+        """
+        Public slot to handle the projectFileRenamed signal.
+        
+        @param oldfn old filename of the file (string)
+        @param newfn new filename of the file (string)
+        """
+        editor = self.getOpenEditor(oldfn)
+        if editor:
+            editor.fileRenamed(newfn)
+        
+    def enableEditorsCheckFocusIn(self, enabled):
+        """
+        Public method to set a flag enabling the editors to perform focus in checks.
+        
+        @param enabled flag indicating focus in checks should be performed (boolean)
+        """
+        self.editorsCheckFocusIn = enabled
+        
+    def editorsCheckFocusInEnabled(self):
+        """
+        Public method returning the flag indicating editors should perform focus in checks.
+        
+        @return flag indicating focus in checks should be performed (boolean)
+        """
+        return self.editorsCheckFocusIn
+
+    def handleFindFileName(self):
+        """
+        Private method to handle the search for file action.
+        """
+        self.ui.findFileNameDialog.show()
+        self.ui.findFileNameDialog.raiseW()
+        self.ui.findFileNameDialog.setActiveWindow()
+        
+    ##################################################################
+    ## Below are the action methods for the edit menu
+    ##################################################################
+    
+    def handleEditUndo(self):
+        """
+        Private method to handle the undo action.
+        """
+        self.activeWindow().undo()
+        
+    def handleEditRedo(self):
+        """
+        Private method to handle the redo action.
+        """
+        self.activeWindow().redo()
+        
+    def handleEditRevert(self):
+        """
+        Private method to handle the revert action.
+        """
+        self.activeWindow().revertToUnmodified()
+        
+    def handleEditCut(self):
+        """
+        Private method to handle the cut action.
+        """
+        self.activeWindow().cut()
+        
+    def handleEditCopy(self):
+        """
+        Private method to handle the copy action.
+        """
+        self.activeWindow().copy()
+        
+    def handleEditPaste(self):
+        """
+        Private method to handle the paste action.
+        """
+        self.activeWindow().paste()
+        
+    def handleEditDelete(self):
+        """
+        Private method to handle the delete action.
+        """
+        self.activeWindow().clear()
+        
+    def handleEditIndent(self):
+        """
+        Private method to handle the indent action.
+        """
+        self.activeWindow().indentLineOrSelection()
+        
+    def handleEditUnindent(self):
+        """
+        Private method to handle the unindent action.
+        """
+        self.activeWindow().unindentLineOrSelection()
+        
+    def handleEditComment(self):
+        """
+        Private method to handle the comment action.
+        """
+        self.activeWindow().commentLineOrSelection()
+        
+    def handleEditUncomment(self):
+        """
+        Private method to handle the uncomment action.
+        """
+        self.activeWindow().uncommentLineOrSelection()
+        
+    def handleEditStreamComment(self):
+        """
+        Private method to handle the stream comment action.
+        """
+        self.activeWindow().streamCommentLineOrSelection()
+        
+    def handleEditBoxComment(self):
+        """
+        Private method to handle the box comment action.
+        """
+        self.activeWindow().boxCommentLineOrSelection()
+        
+    def handleEditSelectBrace(self):
+        """
+        Private method to handle the select to brace action.
+        """
+        self.activeWindow().selectToMatchingBrace()
+        
+    def handleEditSelectAll(self):
+        """
+        Private method to handle the select all action.
+        """
+        self.activeWindow().selectAll(1)
+        
+    def handleEditDeselectAll(self):
+        """
+        Private method to handle the select all action.
+        """
+        self.activeWindow().selectAll(0)
+        
+    def handleConvertEOL(self):
+        """
+        Private method to handle the convert line end characters action.
+        """
+        aw = self.activeWindow()
+        aw.convertEols(aw.eolMode())
+        
+    def handleShortenEmptyLines(self):
+        """
+        Private method to handle the shorten empty lines action.
+        """
+        self.activeWindow().handleShortenEmptyLines()
+        
+    def handleEditAutoComplete(self):
+        """
+        Private method to handle the autocomplete action.
+        """
+        aw = self.activeWindow()
+        aw.autoComplete()
+        
+    def handleEditAutoCompleteFromDoc(self):
+        """
+        Private method to handle the autocomplete from document action.
+        """
+        aw = self.activeWindow()
+        aw.autoCompleteFromDocument()
+        
+    def handleEditAutoCompleteFromAPIs(self):
+        """
+        Private method to handle the autocomplete from APIs action.
+        """
+        aw = self.activeWindow()
+        aw.autoCompleteFromAPIs()
+        
+    def handleEditoracAPIsAvailable(self, available):
+        """
+        Private method to handle the availability of API autocompletion signal.
+        """
+        self.autoCompleteFromAPIsAct.setEnabled(available)
+        
+    ##################################################################
+    ## Below are the action and utility methods for the search menu
+    ##################################################################
+
+    def getWord(self, text, index):
+        """
+        Private method to get the word at a position.
+        
+        @param text text to look at (string or QString)
+        @param index position to look at (int)
+        @return the word at that position
+        """
+        re = QRegExp('[^\w_]')
+        start = text.findRev(re, index) + 1
+        end = text.find(re, index)
+        if end > start:
+            word = text.mid(start, end-start)
+        else:
+            word = QString('')
+        return word
+        
+    def textForFind(self):
+        """
+        Private method to determine the selection or the current word for the next find operation.
+        
+        @return selection or current word (QString)
+        """
+        aw = self.activeWindow()
+        if aw is None:
+            return ''
+            
+        if aw.hasSelectedText():
+            text = aw.selectedText()
+            if text.contains('\r') or text.contains('\n'):
+                # the selection contains at least a newline, it is
+                # unlikely to be the expression to search for
+                return ''
+                
+            return text
+            
+        # no selected text, determine the word at the current position
+        line, index = aw.getCursorPosition()
+        return self.getWord(aw.text(line), index)
+        
+    def getSRHistory(self, key):
+        """
+        Private method to get the search or replace history list.
+        
+        @param key list to return (must be 'search' or 'replace')
+        @return the requested history list (QStringList)
+        """
+        return self.srHistory[key]
+        
+    def handleSearch(self):
+        """
+        Private method to handle the search action.
+        """
+        self.searchDlg.showFind(self.textForFind())
+        
+    def handleReplace(self):
+        """
+        Private method to handle the replace action.
+        """
+        self.replaceDlg.showReplace(self.textForFind())
+        
+    def handleGoto(self):
+        """
+        Private method to handle the goto action.
+        """
+        aw = self.activeWindow()
+        dlg = GotoDialog(self.ui, None, 1)
+        dlg.selectAll()
+        if dlg.exec_loop() == QDialog.Accepted:
+            aw.gotoLine(min(dlg.getLinenumber(), aw.lines()))
+        
+    def handleGotoBrace(self):
+        """
+        Private method to handle the goto brace action.
+        """
+        self.activeWindow().moveToMatchingBrace()
+        
+    def handleSearchFiles(self):
+        """
+        Private method to handle the search in files action.
+        """
+        self.ui.findFilesDialog.show(self.textForFind())
+        self.ui.findFilesDialog.raiseW()
+        self.ui.findFilesDialog.setActiveWindow()
+        
+    ##################################################################
+    ## Below are the action methods for the view menu
+    ##################################################################
+    
+    def handleZoomIn(self):
+        """
+        Private method to handle the zoom in action.
+        """
+        self.activeWindow().zoomIn()
+        
+    def handleZoomOut(self):
+        """
+        Private method to handle the zoom out action.
+        """
+        self.activeWindow().zoomOut()
+        
+    def handleZoom(self):
+        """
+        Private method to handle the zoom action.
+        """
+        aw = self.activeWindow()
+        dlg = ZoomDialog(aw.getZoom(), self.ui, None, 1)
+        if dlg.exec_loop() == QDialog.Accepted:
+            aw.zoomTo(dlg.getZoomSize())
+            
+    def handleToggleAll(self):
+        """
+        Private method to handle the toggle all folds action.
+        """
+        self.activeWindow().foldAll()
+        
+    def handleToggleCurrent(self):
+        """
+        Private method to handle the toggle current fold action.
+        """
+        aw = self.activeWindow()
+        line, index = aw.getCursorPosition()
+        aw.foldLine(line)
+        
+    def handleSplitView(self):
+        """
+        Private method to handle the split view action.
+        """
+        self.addSplit()
+        
+    def handleSplitOrientation(self):
+        """
+        Private method to handle the split orientation action.
+        """
+        if self.splitOrientationAct.isOn():
+            self.setSplitOrientation(QSplitter.Horizontal)
+            self.splitViewAct.setIconSet(\
+                QIconSet(icons.getPixmap("splitHorizontal.png")))
+            self.splitRemoveAct.setIconSet(\
+                QIconSet(icons.getPixmap("remsplitHorizontal.png")))
+        else:
+            self.setSplitOrientation(QSplitter.Vertical)
+            self.splitViewAct.setIconSet(\
+                QIconSet(icons.getPixmap("splitVertical.png")))
+            self.splitRemoveAct.setIconSet(\
+                QIconSet(icons.getPixmap("remsplitVertical.png")))
+    
+    ##################################################################
+    ## Below are the action methods for the macro menu
+    ##################################################################
+    
+    def handleMacroStartRecording(self):
+        """
+        Private method to handle the start macro recording action.
+        """
+        self.activeWindow().handleStartMacroRecording()
+        
+    def handleMacroStopRecording(self):
+        """
+        Private method to handle the stop macro recording action.
+        """
+        self.activeWindow().handleStopMacroRecording()
+        
+    def handleMacroRun(self):
+        """
+        Private method to handle the run macro action.
+        """
+        self.activeWindow().handleRunMacro()
+        
+    def handleMacroDelete(self):
+        """
+        Private method to handle the delete macro action.
+        """
+        self.activeWindow().handleDeleteMacro()
+        
+    def handleMacroLoad(self):
+        """
+        Private method to handle the load macro action.
+        """
+        self.activeWindow().handleLoadMacro()
+        
+    def handleMacroSave(self):
+        """
+        Private method to handle the save macro action.
+        """
+        self.activeWindow().handleSaveMacro()
+    
+    ##################################################################
+    ## Below are the action methods for the bookmarks menu
+    ##################################################################
+    
+    def handleToggleBookmark(self):
+        """
+        Private method to handle the toggle bookmark action.
+        """
+        self.activeWindow().handleToggleBookmark()
+        
+    def handleNextBookmark(self):
+        """
+        Private method to handle the next bookmark action.
+        """
+        self.activeWindow().handleNextBookmark()
+    
+    def handlePreviousBookmark(self):
+        """
+        Private method to handle the previous bookmark action.
+        """
+        self.activeWindow().handlePreviousBookmark()
+    
+    def handleClearAllBookmarks(self):
+        """
+        Private method to handle the clear all bookmarks action.
+        """
+        for editor in self.editors:
+            editor.handleClearBookmarks()
+            
+        self.bookmarkNextAct.setEnabled(0)
+        self.bookmarkPreviousAct.setEnabled(0)
+        self.bookmarkClearAct.setEnabled(0)
+    
+    def handleShowBookmarksMenu(self):
+        """
+        Private method to handle the show bookmarks menu signal.
+        """
+        self.bookmarks = {}
+        self.bookmarksMenu.clear()
+        
+        filenames = self.getOpenFilenames()
+        filenames.sort()
+        for filename in filenames:
+            editor = self.getOpenEditor(filename)
+            for bookmark in editor.getBookmarks():
+                if len(filename) > 50:
+                    dots = "..."
+                else:
+                    dots = ""
+                id = self.bookmarksMenu.insertItem(\
+                        "%s%s : %d" % (dots, filename[-50:], bookmark))
+                self.bookmarks[id] = (filename, bookmark)
+    
+    def handleBookmarkSelected(self, id):
+        """
+        Private method to handle the bookmark selected signal.
+        
+        @param id index of the selected menu entry
+                This acts as an index into the list of bookmarks
+                that was created, when the bookmarks menu was built.
+        """
+        self.displayPythonFile(self.bookmarks[id][0], self.bookmarks[id][1])
+        
+    def handleBookmarkToggled(self, editor):
+        """
+        Private slot to handle the bookmarkToggled signal.
+        
+        It checks some bookmark actions and reemits the signal.
+        
+        @param editor editor that sent the signal
+        """
+        if editor.hasBookmarks():
+            self.bookmarkNextAct.setEnabled(1)
+            self.bookmarkPreviousAct.setEnabled(1)
+            self.bookmarkClearAct.setEnabled(1)
+        else:
+            self.bookmarkNextAct.setEnabled(0)
+            self.bookmarkPreviousAct.setEnabled(0)
+            self.bookmarkClearAct.setEnabled(0)
+        self.emit(PYSIGNAL('bookmarkToggled'), (editor,))
+    
+    def handleGotoSyntaxError(self):
+        """
+        Private method to handle the goto syntax error action.
+        """
+        self.activeWindow().handleGotoSyntaxError()
+    
+    def handleClearAllSyntaxErrors(self):
+        """
+        Private method to handle the clear all syntax errors action.
+        """
+        for editor in self.editors:
+            editor.handleClearSyntaxError()
+    
+    def handleSyntaxErrorToggled(self, editor):
+        """
+        Private slot to handle the syntaxerrorToggled signal.
+        
+        It checks some syntax error actions and reemits the signal.
+        
+        @param editor editor that sent the signal
+        """
+        if editor.hasSyntaxErrors():
+            self.syntaxErrorGotoAct.setEnabled(1)
+            self.syntaxErrorClearAct.setEnabled(1)
+        else:
+            self.syntaxErrorGotoAct.setEnabled(0)
+            self.syntaxErrorClearAct.setEnabled(0)
+        self.emit(PYSIGNAL('syntaxerrorToggled'), (editor,))
+    
+    ##################################################################
+    ## Below are general utility methods
+    ##################################################################
+    
+    def handleResetUI(self):
+        """
+        Public slot to handle the resetUI signal.
+        """
+        editor = self.activeWindow()
+        if editor is None:
+            self.setSbFile()
+        else:
+            line, pos = editor.getCursorPosition()
+            self.setSbFile(editor.getFileName(), line+1, pos)
+        
+    def closeViewManager(self):
+        """
+        Public method to shutdown the viewmanager. 
+        
+        If it cannot close all editor windows, it aborts the shutdown process.
+        
+        @return flag indicating success (boolean)
+        """
+        self.handleCloseAll()
+            
+        # save the list of recently opened projects
+        ok = Preferences.Prefs.settings.writeEntry('/eric3/Recent/Sources', self.recent)
+        
+        # save the list of recently opened projects
+        ok = Preferences.Prefs.settings.writeEntry('/eric3/Bookmarked/Sources', self.bookmarked)
+        
+        if len(self.editors):
+            return 0
+        else:
+            return 1
+
+    def handleLastEditorClosed(self):
+        """
+        Private slot to handle the lastEditorClosed signal.
+        """
+        print 'handleLastEditorClosed  CS_pbruno todo'
+##        self.closeActGrp.setEnabled(0)
+##        self.saveActGrp.setEnabled(0)
+##        self.printAct.setEnabled(0)
+##        self.printSelAct.setEnabled(0)
+##        self.editActGrp.setEnabled(0)
+##        self.searchActGrp.setEnabled(0)
+##        self.viewActGrp.setEnabled(0)
+##        self.viewFoldActGrp.setEnabled(0)
+##        self.unhighlightAct.setEnabled(0)
+##        self.splitViewAct.setEnabled(0)
+##        self.splitOrientationAct.setEnabled(0)
+##        self.macroActGrp.setEnabled(0)
+##        self.bookmarkActGrp.setEnabled(0)
+##        self.setSbFile()
+##        
+##        # reinitialize the central store for api information (used by
+##        # autocompletion and calltips)
+##        for key in self.apis.keys():
+##            self.apis[key] = None
+##            
+##        # remove all split views, if this is supported
+##        if self.canSplit():
+##            while self.removeSplit(): pass
+##            
+##        # stop the autosave timer
+##        if self.autosaveTimer.isActive():
+##            self.autosaveTimer.stop()
+        
+    def handleEditorOpened(self):
+        """
+        Private slot to handle the editorOpened signal.
+        """
+        self.closeActGrp.setEnabled(1)
+        self.saveActGrp.setEnabled(1)
+        self.printAct.setEnabled(1)
+        self.printSelAct.setEnabled(1)
+        self.editActGrp.setEnabled(1)
+        self.searchActGrp.setEnabled(1)
+        self.viewActGrp.setEnabled(1)
+        self.viewFoldActGrp.setEnabled(1)
+        self.unhighlightAct.setEnabled(1)
+        self.splitViewAct.setEnabled(1)
+        self.splitOrientationAct.setEnabled(1)
+        self.macroActGrp.setEnabled(1)
+        self.bookmarkActGrp.setEnabled(1)
+        
+        # activate the autosave timer
+        if not self.autosaveTimer.isActive() and \
+           self.autosaveInterval > 0:
+            self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
+        
+        
+    def checkActions(self, editor, setSb=1):
+        """
+        Private slot to check some actions for their enable/disable status and set the statusbar info.
+        
+        @param editor editor window
+        @param setSb flag indicating an update of the status bar is wanted (boolean)
+        """
+        if editor is not None:
+            self.saveAct.setEnabled(editor.modified)
+            self.revertAct.setEnabled(editor.modified)
+            
+            lex = editor.getLexer()
+            if lex is not None:
+                self.commentAct.setEnabled(lex.canBlockComment())
+                self.uncommentAct.setEnabled(lex.canBlockComment())
+                self.streamCommentAct.setEnabled(lex.canStreamComment())
+                self.boxCommentAct.setEnabled(lex.canBoxComment())
+            else:
+                self.commentAct.setEnabled(0)
+                self.uncommentAct.setEnabled(0)
+                self.streamCommentAct.setEnabled(0)
+                self.boxCommentAct.setEnabled(0)
+            
+            if editor.hasBookmarks():
+                self.bookmarkNextAct.setEnabled(1)
+                self.bookmarkPreviousAct.setEnabled(1)
+                self.bookmarkClearAct.setEnabled(1)
+            else:
+                self.bookmarkNextAct.setEnabled(0)
+                self.bookmarkPreviousAct.setEnabled(0)
+                self.bookmarkClearAct.setEnabled(0)
+            
+            if editor.hasSyntaxErrors():
+                self.syntaxErrorGotoAct.setEnabled(1)
+                self.syntaxErrorClearAct.setEnabled(1)
+            else:
+                self.syntaxErrorGotoAct.setEnabled(0)
+                self.syntaxErrorClearAct.setEnabled(0)
+            
+            if editor.canAutoCompleteFromAPIs():
+                self.autoCompleteFromAPIsAct.setEnabled(1)
+            else:
+                self.autoCompleteFromAPIsAct.setEnabled(0)
+                
+            if setSb:
+                line, pos = editor.getCursorPosition()
+                self.setSbFile(editor.getFileName(), line+1, pos)
+                
+            self.emit(PYSIGNAL('checkActions'), (editor,))
+        
+    def handlePreferencesChanged(self):
+        """
+        Public slot to handle the preferencesChanged signal.
+        
+        This method performs the following actions
+            <ul>
+            <li>reread the colours for the syntax highlighting</li>
+            <li>reloads the already created API objetcs</li>
+            <li>starts or stops the autosave timer</li>
+            <li><b>Note</b>: changes in viewmanager type are activated
+              on an application restart.</li>
+            </ul>
+        """
+        # reload api information
+        for language, api in self.apis.items():
+            if api is not None:
+                apifiles = Preferences.getEditorAPI(language)
+                if len(apifiles):
+                    api.clear()
+                    for apifile in apifiles:
+                        api.load(apifile)
+                else:
+                    self.apis[language] = None
+                    
+        # reload editor settings
+        for editor in self.editors:
+            editor.readSettings()
+            
+        # reload the autosave timer setting
+        self.autosaveInterval = Preferences.getEditor("AutosaveInterval")
+        if len(self.editors):
+            if self.autosaveTimer.isActive() and \
+               self.autosaveInterval == 0:
+                self.autosaveTimer.stop()
+            elif not self.autosaveTimer.isActive() and \
+               self.autosaveInterval > 0:
+                self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
+        
+    def handleEditorSaved(self, fn):
+        """
+        Public slot to handle the editorSaved signal.
+        
+        It simply reemits the signal.
+        
+        @param fn filename of the saved editor
+        """
+        self.emit(PYSIGNAL('editorSaved'), (fn,))
+        
+    def handleCursorChanged(self, fn, line, pos):
+        """
+        Private slot to handle the cursorChanged signal. 
+        
+        It emits the signal cursorChanged with parameter editor.
+        
+        @param fn filename (string)
+        @param line line number of the cursor (int)
+        @param pos position in line of the cursor (int)
+        """
+        self.setSbFile(fn, line, pos)
+        self.emit(PYSIGNAL('cursorChanged'), (self.getOpenEditor(fn),))
+        
+    def handleBreakpointToggled(self, editor):
+        """
+        Private slot to handle the breakpointToggled signal.
+        
+        It simply reemits the signal.
+        
+        @param editor editor that sent the signal
+        """
+        self.emit(PYSIGNAL('breakpointToggled'), (editor,))
+        
+##    def getAPIs(self, language):
+##        """
+##        Public method to get an apis object for autocompletion/calltips
+##        
+##        This method creates and loads the QextScintillaAPIs object
+##        dynamically upon request. This saves memory for languages,
+##        that might not be needed at the moment.
+##        
+##        @param language the language of the requested api object (string)
+##        @return the apis object (QextScintillaAPIs)
+##        """
+##        try:
+##            if self.apis[language] is None:
+##                # create the api object
+##                apifiles = Preferences.getEditorAPI(language)
+##                if len(apifiles):
+##                    self.apis[language] = QextScintillaAPIs()
+##                    for apifile in apifiles:
+##                        self.apis[language].load(apifile)
+##            return self.apis[language]
+##        except KeyError:
+##            return None
+            
+    def getProject(self):
+        """
+        Public method to get a reference to the Project object.
+        
+        @return Reference to the Project object (Project.Project)
+        """
+        return self.ui.getProject()
+        
+    def getActions(self, type):
+        """
+        Public method to get a list of all actions.
+        
+        @param type string denoting the action set to get.
+                It must be one of "edit", "file", "search",
+                "view" or "window"
+        @return list of all actions (list of QAction)
+        """
+        try:
+            exec 'actionList = self.%sActions[:]' % type
+        except:
+            actionList = []
+                
+        return actionList
+        
+    def editorCommand(self, cmd):
+        """
+        Private method to send an editor command to the active window.
+        
+        @param cmd the scintilla command to be sent
+        """
+        aw = self.activeWindow()
+        if aw:
+            aw.SendScintilla(cmd)
+        
+    ##################################################################
+    ## Below are protected utility methods
+    ##################################################################
+    
+    def _getOpenStartDir(self):
+        """
+        Protected method to return the starting directory for a file open dialog. 
+        
+        The appropriate starting directory is calculated
+        using the following search order, until a match is found:<br />
+            1: Directory of currently active editor<br />
+            2: Directory of currently active Project<br />
+            3: CWD
+
+        @return String name of directory to start or None
+        """
+        # if we have an active source, return its path
+        if self.activeWindow() is not None and \
+           self.activeWindow().getFileName():
+            return os.path.dirname(self.activeWindow().getFileName())
+            
+        # ok, try if there is an active project and return its path
+        elif self.getProject().isOpen():
+            return self.getProject().ppath
+            
+        else:
+            # None will cause open dialog to start with cwd
+            return None
+
+    def _getOpenFileFilter(self):
+        """
+        Protected method to return the active filename filter for a file open dialog.
+        
+        The appropriate filename filter is determined by file extension of
+        the currently active editor.
+        
+        @return name of the filename filter (QString) or None
+        """
+        if self.activeWindow() is not None and \
+           self.activeWindow().getFileName():
+            ext = os.path.splitext(self.activeWindow().getFileName())[1]
+            try:
+                return QString(self.ext2Filter[ext])
+            except KeyError:
+                return None
+                
+        else:
+            return None
+
+            
+
+
+"""
+Module implementing a tabbed viewmanager class.
+"""
+
+
+##import QScintilla.Editor
+
+
+class TabWidget(QTabWidget):
+    """
+    Class implementing a custimized TabWidget.
+    """
+    def __init__(self, parent):
+        """
+        Constructor
+        
+        @param parent parent widget (QWidget)
+        """
+        QTabWidget.__init__(self, parent)
+        
+        self.editors = []
+        self.curIndex = 0
+        
+        self.connect(self, SIGNAL("currentChanged(QWidget *)"), self.handleCurrentChanged)
+        
+    def handleCurrentChanged(self):
+        """
+        Private slot called by the currentChanged signal.
+        """
+        self.curIndex = self.currentPageIndex()
+        
+    def addTab(self, editor, title):
+        """
+        Overwritten method to add a new tab.
+        
+        @param editor the editor object to be added (QScintilla.Editor.Editor)
+        @param title title for the new tab (string, QString or QTab)
+        """
+        QTabWidget.addTab(self, editor, title)
+        
+        if not editor in self.editors:
+            self.editors.append(editor)
+            self.connect(editor, PYSIGNAL('captionChanged'),
+                self.handleCaptionChange)
+                
+    def showPage(self, editor):
+        """
+        Overridden method to show a tab.
+        
+        @param editor the editor object to be shown (QScintilla.Editor.Editor)
+        """
+        QTabWidget.showPage(self, editor)
+        self.curIndex = self.indexOf(editor)
+        
+    def nextTab(self):
+        """
+        Public slot used to show the next tab.
+        """
+        if self.count():
+            self.curIndex += 1
+            if self.curIndex == self.count():
+                self.curIndex = 0
+                
+            QTabWidget.showPage(self, self.page(self.curIndex))
+
+    def prevTab(self):
+        """
+        Public slot used to show the previous tab.
+        """
+        if self.count():
+            self.curIndex -= 1
+            if self.curIndex == -1:
+                self.curIndex = self.count() - 1
+                
+            QTabWidget.showPage(self, self.page(self.curIndex))
+
+    def handleCaptionChange(self, cap, editor):
+        """
+        Private method to handle Caption change signals from the editor. 
+        
+        Updates the listview text to reflect the new caption information.
+        
+        @param cap Caption for the editor
+        @param editor Editor to update the caption for
+        """
+        fn = editor.getFileName()
+        if fn:
+            txt = os.path.basename(fn)
+            if editor.isReadOnly():
+                txt = '%s (ro)' % txt
+            self.changeTab(editor, txt)
+        
+    def removePage(self, object):
+        """
+        Overwritten method to remove a page.
+        
+        @param object object to be removed (QObject)
+        """
+        QTabWidget.removePage(self, object)
+        
+##        if isinstance(object, QScintilla.Editor.Editor):
+##            self.disconnect(object, PYSIGNAL('captionChanged'),
+##                self.handleCaptionChange)
+        self.disconnect( object, PYSIGNAL('captionChanged'),
+                         self.handleCaptionChange )
+        self.editors.remove(object)
+        
+    def hasEditor(self, editor):
+        """
+        Public method to check for an editor.
+        
+        @param editor editor object to check for
+        @return flag indicating, whether the editor to be checked belongs
+            to the list of editors managed by this tab widget.
+        """
+        return editor in self.editors
+        
+    def hasEditors(self):
+        """
+        Public method to test, if any editor is managed.
+        
+        @return flag indicating editors are managed
+        """
+        return len(self.editors) and 1 or 0
+        
+class Tabview(QSplitter, ViewManager):
+    """
+    Class implementing a tabbed viewmanager class embedded in a splitter.
+    
+    @signal lastEditorClosed emitted after the last editor window was closed
+    @signal editorOpened emitted after an editor window was opened
+    @signal editorSaved emitted after an editor window was saved
+    """
+    def __init__(self,parent, ui):
+        """
+        Constructor
+        
+        @param parent parent widget (QWidget)
+        @param ui reference to the main user interface
+        @param dbs reference to the debug server object
+        """
+        self.tabWidgets = []
+        
+        QSplitter.__init__(self,parent)
+        ViewManager.__init__(self, ui)
+        tw = TabWidget(self)
+        self.tabWidgets.append(tw)
+        self.currentTabWidget = tw
+        self.connect(tw, SIGNAL('currentChanged(QWidget*)'),
+            self.handleCurrentChanged)
+        tw.installEventFilter(self)
+        tw.tabBar().installEventFilter(self)
+        self.setOrientation(QSplitter.Vertical)
+        
+    def initViewActions(self):
+        """
+        Protected method defining the user interface actions for the view commands.
+        """
+        ViewManager.initViewActions(self)
+        
+        self.nextTabAct = QAction(self.trUtf8('Show next tab'), 
+                      self.trUtf8('Show next tab'), 
+                      QKeySequence(self.trUtf8('Ctrl+Alt+Tab')), self)
+        self.connect(self.nextTabAct, SIGNAL('activated()'), self.nextTab)
+        self.viewActions.append(self.nextTabAct)
+        
+        self.prevTabAct = QAction(self.trUtf8('Show previous tab'), 
+                      self.trUtf8('Show previous tab'), 
+                      QKeySequence(self.trUtf8('Shift+Ctrl+Alt+Tab')), self)
+        self.connect(self.prevTabAct, SIGNAL('activated()'), self.prevTab)
+        self.viewActions.append(self.prevTabAct)
+        
+    def nextTab(self):
+        """
+        Private slot used to show the next tab of the current tabwidget.
+        """
+        self.currentTabWidget.nextTab()
+        
+    def prevTab(self):
+        """
+        Private slot used to show the previous tab of the current tabwidget.
+        """
+        self.currentTabWidget.prevTab()
+        
+    def canCascade(self):
+        """
+        Public method to signal if cascading of managed windows is available.
+        
+        @return flag indicating cascading of windows is available
+        """
+        return 0
+        
+    def canTile(self):
+        """
+        Public method to signal if tiling of managed windows is available.
+        
+        @return flag indicating tiling of windows is available
+        """
+        return 0
+        
+    def canSplit(self):
+        """
+        public method to signal if splitting of the view is available.
+        
+        @return flag indicating splitting of the view is available.
+        """
+        return 1
+        
+    def tile(self):
+        """
+        Public method to tile the managed windows.
+        """
+        pass
+        
+    def cascade(self):
+        """
+        Public method to cascade the managed windows.
+        """
+        pass
+        
+    def removeAllViews(self):
+        """
+        Private method to remove all views (i.e. windows)
+        """
+        for win in self.editors:
+            self.removeView(win)
+            
+    def removeView(self, win):
+        """
+        Private method to remove a view (i.e. window)
+        
+        @param win editor window to be removed
+        """
+        print 'removeView win', win
+        for tw in self.tabWidgets:
+            if tw.hasEditor(win):
+                tw.removePage(win)
+                break        
+        win.closeIt()        
+        
+        print 'removeView A'
+        # if this was the last editor in this view, switch to the next, that
+        # still has open editors
+        print 'removeView B'
+        for i in range(self.tabWidgets.index(tw), -1, -1) + \
+                 range(self.tabWidgets.index(tw) + 1, len(self.tabWidgets)):
+            print 'removeView C'
+            if self.tabWidgets[i].hasEditors():
+                self.currentTabWidget = self.tabWidgets[i]
+                self.activeWindow().setFocus()
+                print 'removeView D',self.activeWindow()
+                break
+    
+    def addView(self, win, fn=None):
+        """
+        Private method to add a view (i.e. window)
+        
+        @param win editor window to be added
+        @param fn filename of this editor
+        """
+        win.show()
+        if fn is None:
+            self.untitledCount += 1
+            self.currentTabWidget.addTab(win, self.trUtf8("Untitled %1").arg(self.untitledCount))
+        else:
+            txt = os.path.basename(fn)
+            if not QFileInfo(fn).isWritable():
+                txt = '%s (ro)' % txt
+            self.currentTabWidget.addTab(win, txt)
+            self.currentTabWidget.setTabToolTip(win, os.path.dirname(fn))
+        self.currentTabWidget.showPage(win)
+        win.setFocus()
+    
+    def showView(self, win, fn=None):
+        """
+        Private method to show a view (i.e. window)
+        
+        @param win editor window to be shown
+        @param fn filename of this editor
+        """
+        win.show()
+        for tw in self.tabWidgets:
+            if tw.hasEditor(win):
+                tw.showPage(win)
+                self.currentTabWidget = tw
+                break
+        win.setFocus()
+    
+    def activeWindow(self):
+        """
+        Private method to return the active (i.e. current) window.
+        
+        @return reference to the active editor
+        """
+        return self.currentTabWidget.currentPage()
+        
+    def handleShowWindowMenu(self, windowMenu):
+        """
+        Private method to set up the viewmanager part of the Window menu.
+        
+        @param windowMenu reference to the window menu
+        """
+        pass
+        
+    def initWindowActions(self):
+        """
+        Define the user interface actions for window handling.
+        """
+        pass
+        
+    def setEditorName(self, editor, newName):
+        """
+        Change the displayed name of the editor.
+        
+        @param editor editor window to be changed
+        @param newName new name to be shown (string or QString)
+        """
+        self.currentTabWidget.changeTab(editor, 
+            os.path.basename(unicode(newName)))
+        self.currentTabWidget.setTabToolTip(editor, 
+            os.path.dirname(unicode(newName)))
+    
+    def handleModificationStatusChanged(self, m, editor):
+        """
+        Private slot to handle the modificationStatusChanged signal.
+        
+        @param m flag indicating the modification status (boolean)
+        @param editor editor window changed
+        """
+        print 50*'handleModificationStatusChanged'
+        for tw in self.tabWidgets:
+            if tw.hasEditor(editor):
+                break
+        if m:
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("fileModified.png")))
+        elif editor.hasSyntaxErrors():
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("syntaxError.png")))
+        else:
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("empty.png")))
+        self.checkActions(editor)
+        
+    def handleSyntaxErrorToggled(self, editor):
+        """
+        Private slot to handle the syntaxerrorToggled signal.
+        
+        @param editor editor that sent the signal
+        """
+        for tw in self.tabWidgets:
+            if tw.hasEditor(editor):
+                break
+        if editor.hasSyntaxErrors():
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("syntaxError.png")))
+        else:
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("empty.png")))
+                
+        ViewManager.handleSyntaxErrorToggled(self, editor)
+        
+    def addSplit(self):
+        """
+        Public method used to split the current view.
+        """
+        tw = TabWidget(self)
+        tw.show()
+        self.tabWidgets.append(tw)
+        self.currentTabWidget = self.tabWidgets[-1]
+        self.connect(tw, SIGNAL('currentChanged(QWidget*)'),
+            self.handleCurrentChanged)
+        tw.installEventFilter(self)
+        tw.tabBar().installEventFilter(self)
+        self.setSizes([int(100/len(self.tabWidgets))] * len(self.tabWidgets))
+        self.splitRemoveAct.setEnabled(1)
+        
+    def removeSplit(self):
+        """
+        Public method used to remove the current split view.
+        
+        @return flag indicating successfull removal
+        """
+        if len(self.tabWidgets) > 1:
+            tw = self.currentTabWidget
+            res = 1
+            savedEditors = tw.editors[:]
+            for editor in savedEditors:
+                res &= self.closeEditor(editor)
+            if res:
+                i = self.tabWidgets.index(tw)
+                if i == len(self.tabWidgets)-1:
+                    i -= 1
+                self.tabWidgets.remove(tw)
+                tw.close(1)
+                self.currentTabWidget = self.tabWidgets[i]
+                if len(self.tabWidgets) == 1:
+                    self.splitRemoveAct.setEnabled(0)
+                return 1
+                
+        return 0
+        
+    def setSplitOrientation(self, orientation):
+        """
+        Public method used to set the orientation of the split view.
+        
+        @param orientation orientation of the split
+                (QSplitter.Horizontal or QSplitter.Vertical)
+        """
+        self.setOrientation(orientation)
+        
+    def handleCurrentChanged(self, editor):
+        """
+        Private slot to handle the currentChanged signal.
+        
+        @param editor selected editor window
+        """
+        self.checkActions(editor)
+        editor.setFocus()
+        
+    def eventFilter(self, watched, event):
+        """
+        Method called to filter the event queue.
+        
+        @param watched the QObject being watched
+        @param event the event that occurred
+        @return always 0
+        """
+        if event.type() == QEvent.MouseButtonPress and \
+           not event.button() == Qt.RightButton:
+            if isinstance(watched, QTabWidget):
+                self.currentTabWidget = watched
+            elif isinstance(watched, QTabBar):
+                self.currentTabWidget = watched.parent()
+            elif isinstance(watched, QScintilla.Editor.Editor):
+                for tw in self.tabWidgets:
+                    if tw.hasEditor(watched):
+                        self.currentTabWidget = tw
+                        break
+                        
+            aw = self.activeWindow()
+            if aw is not None:
+                self.checkActions(aw)
+                aw.setFocus()
+            
+        return 0
+
+
+class MyTabview(Tabview):
+    """
+    Base class inherited by all specific viewmanager classes.
+    
+    It defines the interface to be implemented by specific
+    viewmanager classes and all common methods.
+    
+    @signal lastEditorClosed emitted after the last editor window was closed
+    @signal editorOpened(string) emitted after an editor window was opened
+    @signal editorSaved(string) emitted after an editor window was saved
+    @signal checkActions(editor) emitted when some actions should be checked
+            for their status
+    @signal cursorChanged(editor) emitted after the cursor position of the active
+            window has changed
+    @signal breakpointToggled(editor) emitted when a breakpoint is toggled.
+    @signal bookmarkToggled(editor) emitted when a bookmark is toggled.
+    """
+    def __init__(self, parent, ui):
+        Tabview.__init__(self, parent, ui)
+        
+    def checkActions(self, editor, setSb=1):
+        """
+        Private slot to check some actions for their enable/disable status and set the statusbar info.
+        
+        @param editor editor window
+        @param setSb flag indicating an update of the status bar is wanted (boolean)
+        """        
+##        if editor is not None:
+##            self.saveAct.setEnabled(editor.isModified())
+##            self.revertAct.setEnabled(editor.isModified())
+##            
+##            lex = editor.getLexer()
+##            if lex is not None:
+##                self.commentAct.setEnabled(lex.canBlockComment())
+##                self.uncommentAct.setEnabled(lex.canBlockComment())
+##                self.streamCommentAct.setEnabled(lex.canStreamComment())
+##                self.boxCommentAct.setEnabled(lex.canBoxComment())
+##            else:
+##                self.commentAct.setEnabled(0)
+##                self.uncommentAct.setEnabled(0)
+##                self.streamCommentAct.setEnabled(0)
+##                self.boxCommentAct.setEnabled(0)
+##            
+##            if editor.hasBookmarks():
+##                self.bookmarkNextAct.setEnabled(1)
+##                self.bookmarkPreviousAct.setEnabled(1)
+##                self.bookmarkClearAct.setEnabled(1)
+##            else:
+##                self.bookmarkNextAct.setEnabled(0)
+##                self.bookmarkPreviousAct.setEnabled(0)
+##                self.bookmarkClearAct.setEnabled(0)
+##            
+##            if editor.hasSyntaxErrors():
+##                self.syntaxErrorGotoAct.setEnabled(1)
+##                self.syntaxErrorClearAct.setEnabled(1)
+##            else:
+##                self.syntaxErrorGotoAct.setEnabled(0)
+##                self.syntaxErrorClearAct.setEnabled(0)
+##            
+##            if editor.canAutoCompleteFromAPIs():
+##                self.autoCompleteFromAPIsAct.setEnabled(1)
+##            else:
+##                self.autoCompleteFromAPIsAct.setEnabled(0)
+##                
+##            if setSb:
+##                line, pos = editor.getCursorPosition()
+##                self.setSbFile(editor.getFileName(), line+1, pos)            
+        self.emit(PYSIGNAL('checkActions'), (editor,)) 
+
+    def addToRecentList(self, fn):
+        """
+        Public slot to add a filename to the list of recently opened files.
+        
+        @param fn name of the file to be added
+        """
+        print 'self.recent',self.recent
+        print 'type(self.recent)',type(self.recent)
+        self.recent.remove(fn)
+        self.recent.prepend(fn)
+        if len(self.recent) > 9:
+            self.recent = self.recent[:9] 
+        
+    def handleOpen(self,fn=None):
+        """
+        Public slot to open a Python JDC file.
+        
+        @param prog name of file to be opened (string or QString)
+        """
+        # Get the file name if one wasn't specified.
+        if fn is None:
+            # set the cwd of the dialog based on the following search criteria:
+            #     1: Directory of currently active editor
+            #     2: Directory of currently active Project
+            #     3: CWD
+##            filter = self._getOpenFileFilter()            
+##            fn = QFileDialog.getOpenFileName(self._getOpenStartDir(),
+##                        self.fileFiltersString, self.ui, None, None, filter)
+                        
+            fn = QFileDialog.getOpenFileName(self._getOpenStartDir(),
+                        QString("*.comm") , self.ui, None, None, None)
+
+            if fn.isNull():
+                return
+
+        fn = normabspath(unicode(fn))
+
+        newWin, editor = self.getEditor(fn)
+        
+        if newWin:
+            self.handleModificationStatusChanged(editor.modified, editor)
+        self.checkActions(editor)
+        
+        
+            
+##        if lineno is not None and lineno >= 0:
+##            editor.ensureVisible(lineno)
+##            editor.gotoLine(lineno)
+        
+##        # insert filename into list of recently opened files
+        self.addToRecentList(fn)
+    
+
+   ##################################################################
+    ## Below are protected utility methods
+    ##################################################################
+    
+    def _getOpenStartDir(self):
+        """
+        Protected method to return the starting directory for a file open dialog. 
+        
+        The appropriate starting directory is calculated
+        using the following search order, until a match is found:<br />
+            1: Directory of currently active editor<br />
+            2: Directory of currently active Project<br />
+            3: CWD
+
+        @return String name of directory to start or None
+        """
+        # if we have an active source, return its path
+        if self.activeWindow() is not None and \
+           self.activeWindow().getFileName():
+            return os.path.dirname(self.activeWindow().getFileName())
+            
+##        # ok, try if there is an active project and return its path
+##        elif self.getProject().isOpen():
+##            return self.getProject().ppath
+            
+        else:
+            # None will cause open dialog to start with cwd
+            return None        
+
+
+        
+##    def getEditor(self, fn):
+##        """
+##        Private method to return the editor displaying the given file.
+##        
+##        If there is no editor with the given file, a new editor window is
+##        created.
+##        
+##        @param fn filename to look for
+##        @param isPythonFile flag indicating that this is a Python file
+##                even if it doesn't have the .py extension (boolean)
+##        @return tuple of two values giving a flag indicating a new window creation and
+##            a reference to the editor displaying this file
+##        """
+##        newWin = 0
+##        for editor in self.editors:
+##            if Utilities.samepath(fn, editor.getFileName()):
+##                break
+##        else:
+##            from editor import JDCEditor
+##            editor = JDCEditor(fn,None,self)
+##            #editor = Editor(self.dbs,fn,self,isPythonFile=isPythonFile)
+##            
+##            self.editors.append(editor)
+##            self.connect(editor, PYSIGNAL('modificationStatusChanged'),
+##                self.handleModificationStatusChanged)
+##            self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
+##            self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
+##            self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
+##            self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
+##            self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
+##            self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'), 
+##                self.handleEditoracAPIsAvailable)
+##            self.handleEditorOpened()
+##            self.emit(PYSIGNAL('editorOpened'), (fn,))
+##            newWin = 1
+##
+##        if newWin:
+##            self.addView(editor, fn)
+##        else:
+##            self.showView(editor, fn)
+##            
+##        return (newWin, editor)
+        
+    def handleEditorOpened(self):
+        """
+        Private slot to handle the editorOpened signal.
+        """
+        pass
+##        self.closeActGrp.setEnabled(1)
+##        self.saveActGrp.setEnabled(1)
+##        self.printAct.setEnabled(1)
+##        self.printSelAct.setEnabled(1)
+##        self.editActGrp.setEnabled(1)
+##        self.searchActGrp.setEnabled(1)
+##        self.viewActGrp.setEnabled(1)
+##        self.viewFoldActGrp.setEnabled(1)
+##        self.unhighlightAct.setEnabled(1)
+##        self.splitViewAct.setEnabled(1)
+##        self.splitOrientationAct.setEnabled(1)
+##        self.macroActGrp.setEnabled(1)
+##        self.bookmarkActGrp.setEnabled(1)
+##        
+##        # activate the autosave timer
+##        if not self.autosaveTimer.isActive() and \
+##           self.autosaveInterval > 0:
+##            self.autosaveTimer.start(self.autosaveInterval * 60000, 1)
+        
+    def handleModificationStatusChanged(self, m, editor):
+        """
+        Private slot to handle the modificationStatusChanged signal.
+        
+        @param m flag indicating the modification status (boolean)
+        @param editor editor window changed
+        """
+        for tw in self.tabWidgets:
+            if tw.hasEditor(editor):
+                break
+        if m:
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("fileModified.png")))
+        elif editor.hasSyntaxErrors():
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("syntaxError.png")))
+        else:
+            tw.setTabIconSet(editor, 
+                QIconSet(icons.getPixmap("empty.png")))
+        self.checkActions(editor)        
+        
+        
+    #def newEditorView(self, fn, caller, isPythonFile=0):
+##    def mynewEditorView(self):
+##        """
+##        Public method to create a new editor displaying the given document.
+##        
+##        @param fn filename of this view
+##        @param caller reference to the editor calling this method
+##        @param isPythonFile flag indicating that this is a Python file
+##                even if it doesn't have the .py extension (boolean)
+##        """
+##        import jdcdisplay
+##        d=jdcdisplay.QTJDCDISPLAY(j,"ahlv100a", None, self)
+##        self.addView(d, "ahlv100a")
+        
+##        editor = Editor(self.dbs,fn,self,isPythonFile=isPythonFile, editor=caller)
+##        self.editors.append(editor)
+##        self.connect(editor, PYSIGNAL('modificationStatusChanged'),
+##            self.handleModificationStatusChanged)
+##        self.connect(editor, PYSIGNAL('cursorChanged'), self.handleCursorChanged)
+##        self.connect(editor, PYSIGNAL('editorSaved'), self.handleEditorSaved)
+##        self.connect(editor, PYSIGNAL('breakpointToggled'), self.handleBreakpointToggled)
+##        self.connect(editor, PYSIGNAL('bookmarkToggled'), self.handleBookmarkToggled)
+##        self.connect(editor, PYSIGNAL('syntaxerrorToggled'), self.handleSyntaxErrorToggled)
+##        self.connect(editor, PYSIGNAL('autoCompletionAPIsAvailable'), 
+##            self.handleEditoracAPIsAvailable)
+##        self.handleEditorOpened()
+##        self.emit(PYSIGNAL('editorOpened'), (fn,))
+##        
+##        self.connect(caller, PYSIGNAL('editorRenamed'), editor.handleRenamed)
+##        self.connect(editor, PYSIGNAL('editorRenamed'), caller.handleRenamed)
+##        
+##        self.addView(editor, fn)
+##        self.handleModificationStatusChanged(editor.isModified(), editor)
+##        self.checkActions(editor)
+
+
+if __name__=='__main__':
+    import sys
+    app = QApplication(sys.argv)
+    
+    ##mw = UserInterface(loc, splash)
+    mw = MyTabview(None,None)
+    app.setMainWidget(mw)
+    app.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
+    mw.show()
+    mw.getEditor('azAster.comm')
+    mw.getEditor('az.comm')
+    res = app.exec_loop()
+    sys.exit(res)