From 5a87e92eb60bdc4fbc79d719a475e0f1d4764036 Mon Sep 17 00:00:00 2001 From: pbruno <> Date: Mon, 19 Feb 2007 19:16:35 +0000 Subject: [PATCH] =?utf8?q?1ere=20mise=20en=20r=C3=A9f=C3=A9rence?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- Interface/Objecttreeitem.py | 507 ++++ Interface/analyse_catalogue.py | 317 +++ Interface/autre_analyse_cata.py | 117 + Interface/basestyle.py | 27 + Interface/browser.py | 521 ++++ Interface/comploader.py | 92 + Interface/compobase.py | 3 + Interface/compobloc.py | 37 + Interface/compocomm.py | 230 ++ Interface/compocommandecomm.py | 92 + Interface/compoerror.py | 31 + Interface/compofact.py | 145 ++ Interface/compoformule.py | 177 ++ Interface/compojdc.py | 118 + Interface/compomacro.py | 159 ++ Interface/compomclist.py | 195 ++ Interface/componiveau.py | 98 + Interface/componuplet.py | 92 + Interface/compooper.py | 429 ++++ Interface/compoparam.py | 120 + Interface/compoparameval.py | 153 ++ Interface/compoproc.py | 23 + Interface/composimp.py | 894 +++++++ Interface/configuration.py | 302 +++ Interface/editor.py | 599 +++++ Interface/eficas.py | 111 + Interface/fontes.py | 36 + Interface/icons.py | 54 + Interface/import_code.py | 36 + Interface/macrodisplay.py | 165 ++ Interface/myMain.ui | 526 ++++ Interface/myMain_ui.py | 490 ++++ Interface/newsimppanel.py | 196 ++ Interface/panels.py | 56 + Interface/panelsSalome.py | 286 +++ Interface/plusieursassdpanel.py | 183 ++ Interface/plusieursbasepanel.py | 543 +++++ Interface/plusieursintopanel.py | 163 ++ Interface/plusieurspanel.py | 175 ++ Interface/qtEficas.py | 169 ++ Interface/readercata.py | 502 ++++ Interface/session.py | 285 +++ Interface/styles.py | 19 + Interface/treeitemincanvas.py | 122 + Interface/uiinfo.py | 114 + Interface/uniqueassdpanel.py | 219 ++ Interface/uniquebasepanel.py | 148 ++ Interface/uniquecomppanel.py | 171 ++ Interface/uniqueintopanel.py | 94 + Interface/uniquepanel.py | 95 + Interface/uniquesdcopanel.py | 242 ++ Interface/utils.py | 153 ++ Interface/viewManager.py | 3997 +++++++++++++++++++++++++++++++ 53 files changed, 14828 insertions(+) create mode 100644 Interface/Objecttreeitem.py create mode 100644 Interface/analyse_catalogue.py create mode 100644 Interface/autre_analyse_cata.py create mode 100644 Interface/basestyle.py create mode 100644 Interface/browser.py create mode 100644 Interface/comploader.py create mode 100644 Interface/compobase.py create mode 100644 Interface/compobloc.py create mode 100644 Interface/compocomm.py create mode 100644 Interface/compocommandecomm.py create mode 100644 Interface/compoerror.py create mode 100644 Interface/compofact.py create mode 100644 Interface/compoformule.py create mode 100644 Interface/compojdc.py create mode 100644 Interface/compomacro.py create mode 100644 Interface/compomclist.py create mode 100644 Interface/componiveau.py create mode 100644 Interface/componuplet.py create mode 100644 Interface/compooper.py create mode 100644 Interface/compoparam.py create mode 100644 Interface/compoparameval.py create mode 100644 Interface/compoproc.py create mode 100644 Interface/composimp.py create mode 100644 Interface/configuration.py create mode 100644 Interface/editor.py create mode 100644 Interface/eficas.py create mode 100644 Interface/fontes.py create mode 100644 Interface/icons.py create mode 100644 Interface/import_code.py create mode 100644 Interface/macrodisplay.py create mode 100644 Interface/myMain.ui create mode 100644 Interface/myMain_ui.py create mode 100644 Interface/newsimppanel.py create mode 100644 Interface/panels.py create mode 100644 Interface/panelsSalome.py create mode 100644 Interface/plusieursassdpanel.py create mode 100644 Interface/plusieursbasepanel.py create mode 100644 Interface/plusieursintopanel.py create mode 100644 Interface/plusieurspanel.py create mode 100644 Interface/qtEficas.py create mode 100644 Interface/readercata.py create mode 100644 Interface/session.py create mode 100644 Interface/styles.py create mode 100644 Interface/treeitemincanvas.py create mode 100644 Interface/uiinfo.py create mode 100644 Interface/uniqueassdpanel.py create mode 100644 Interface/uniquebasepanel.py create mode 100644 Interface/uniquecomppanel.py create mode 100644 Interface/uniqueintopanel.py create mode 100644 Interface/uniquepanel.py create mode 100644 Interface/uniquesdcopanel.py create mode 100644 Interface/utils.py create mode 100644 Interface/viewManager.py diff --git a/Interface/Objecttreeitem.py b/Interface/Objecttreeitem.py new file mode 100644 index 00000000..5bb84ce8 --- /dev/null +++ b/Interface/Objecttreeitem.py @@ -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 index 00000000..e4330be5 --- /dev/null +++ b/Interface/analyse_catalogue.py @@ -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 index 00000000..a9650f06 --- /dev/null +++ b/Interface/autre_analyse_cata.py @@ -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 index 00000000..e4287b75 --- /dev/null +++ b/Interface/basestyle.py @@ -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 index 00000000..0a0d3b6c --- /dev/null +++ b/Interface/browser.py @@ -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 index 00000000..7a86c915 --- /dev/null +++ b/Interface/comploader.py @@ -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 index 00000000..df539df0 --- /dev/null +++ b/Interface/compobase.py @@ -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 index 00000000..90328e29 --- /dev/null +++ b/Interface/compobloc.py @@ -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 index 00000000..0d08ad32 --- /dev/null +++ b/Interface/compocomm.py @@ -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 index 00000000..dff2430b --- /dev/null +++ b/Interface/compocommandecomm.py @@ -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 index 00000000..9aac8152 --- /dev/null +++ b/Interface/compoerror.py @@ -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 index 00000000..21fc97aa --- /dev/null +++ b/Interface/compofact.py @@ -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 index 00000000..f7a93c5a --- /dev/null +++ b/Interface/compoformule.py @@ -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 index 00000000..3710b57b --- /dev/null +++ b/Interface/compojdc.py @@ -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 index 00000000..cc2353ec --- /dev/null +++ b/Interface/compomacro.py @@ -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 index 00000000..439342b4 --- /dev/null +++ b/Interface/compomclist.py @@ -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 index 00000000..74239ec4 --- /dev/null +++ b/Interface/componiveau.py @@ -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 index 00000000..4ef3b22d --- /dev/null +++ b/Interface/componuplet.py @@ -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 index 00000000..14077e7d --- /dev/null +++ b/Interface/compooper.py @@ -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 index 00000000..8fea924d --- /dev/null +++ b/Interface/compoparam.py @@ -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 index 00000000..12db64cd --- /dev/null +++ b/Interface/compoparameval.py @@ -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 index 00000000..43687019 --- /dev/null +++ b/Interface/compoproc.py @@ -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 index 00000000..4f4211b8 --- /dev/null +++ b/Interface/composimp.py @@ -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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) +## self.frame_valeur.bind("",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("",lambda e,c=self.valid_valeur:c()) +## self.entry.bind("",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 """ + + 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 index 00000000..8d9e7a6d --- /dev/null +++ b/Interface/configuration.py @@ -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 index 00000000..2e9c7e69 --- /dev/null +++ b/Interface/editor.py @@ -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 %1 could not be saved.
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 %1 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 index 00000000..e6607f86 --- /dev/null +++ b/Interface/eficas.py @@ -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 index 00000000..8e158927 --- /dev/null +++ b/Interface/fontes.py @@ -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 index 00000000..7e2bd30d --- /dev/null +++ b/Interface/icons.py @@ -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 index 00000000..942c6b4a --- /dev/null +++ b/Interface/import_code.py @@ -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 index 00000000..9e3e671a --- /dev/null +++ b/Interface/macrodisplay.py @@ -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 index 00000000..4ca8b226 --- /dev/null +++ b/Interface/myMain.ui @@ -0,0 +1,526 @@ + +Eficas + + + Eficas + + + true + + + + 0 + 0 + 727 + 575 + + + + WidgetOrigin + + + + + + + Eficas V1.10 pour Aster avec Catalogue V8.3 + + + + + MenuBar + + + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + toolBar + + + MenuBarPanel + + + false + + + Tools + + + + + + + + + + + + + + + fileNewAction + + + image0 + + + New + + + &New + + + Ctrl+N + + + + + fileOpenAction + + + image1 + + + Open + + + &Open... + + + Ctrl+O + + + + + fileSaveAction + + + image2 + + + Save + + + &Save + + + Ctrl+S + + + + + fileSaveAsAction + + + Save As + + + Save &As... + + + + + + + + fileExitAction + + + Exit + + + E&xit + + + + + + + + editUndoAction + + + image3 + + + Undo + + + &Undo + + + Ctrl+Z + + + + + editRedoAction + + + image4 + + + Redo + + + &Redo + + + Ctrl+Y + + + + + editCutAction + + + image5 + + + Cut + + + Cu&t + + + Ctrl+X + + + + + editCopyAction + + + image6 + + + Copy + + + &Copy + + + Ctrl+C + + + + + editPasteAction + + + image7 + + + Paste + + + &Paste + + + Ctrl+V + + + + + editFindAction + + + image8 + + + Find + + + &Find... + + + Ctrl+F + + + + + helpContentsAction + + + Contents + + + &Contents... + + + + + + + + helpIndexAction + + + Index + + + &Index... + + + + + + + + helpAboutAction + + + About + + + &About + + + + + + + + traductionnew_itemAction + + + new item + + + new item + + + + + fileSaveCloseAction + + + Close + + + Close + + + + + fileCloseAction + + + Close + + + Close + + + Ctrl+W + + + + + fileNewViewAction + + + New view + + + + + fileCloseAllAction + + + Close All + + + Close All + + + + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007449444154388dedd5c109c0200c05d06fe936812c10b2ffdd85d25385b6a991480f053f081af0291210f828c5a9d9c4de96cd2b9ad9eb0000660e2fe0c2519839c4f70c4c446d5e6b3538cf928245e4b2f6f014acaa8fda1d4fc1a5741b22079f9d111d96ea8a912c78c10bee64e60719f57e9203ad452a04cc4e50200000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000009949444154388ded94410e85200c445f89c7367f61bc775d2848a42860ffced9548bbe8e13043e1d928177f481a123dc2b34f6f47a3de2b865a8843f4001982a0b3d5f62c58300aa1ad70550449ab9d507a773a8a4ba4f92a2df333c64c63bebbd82e5b8addecbcc7820eb4266c639745dfa80f36faf66c66fa19c3f882fb470ec05cdc0bed07893f68e171492635f686c3eeff6ba3c8fdd366dc4c0452c8781f8080000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000a049444154388dd5954d0a802010859fd14668e18de662d222bc98376a21b4ac451992c66469e0b7f187f1f11c47052a218e762daddbfb9e99f6568f80b5364b8588ce35440400e80a398ce8f99034d2292cc37c8ebd530feb583a05e954341f8a027b2a7d3a1f09bf854dc5d5d953aa396e4f38cab199e2d2e108abe156f82e30977fcb4d8ff942d75dbebed2e143953a93f6caad3d6111f44b7d4f820ff9c0069bb51ecded318c5c0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007349444154388ded92c10e80200840b1ef661d1cff4d876aa888a17669f9360f283ed80060f159425f3a71f53602e08e992b098801d02854176ae47f21ce1fb5b05d38eddc9060d0f11379635b3bc92bd518e239a943ec1d5ab7785cee107be4b215af4091f894de47181ecea59ede9ec59f380062ac28b1e3d701d90000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000007449444154388ded92c10ac02008406ddf2d3b84ffed0ea3586a26d165e0830ea53e8504487e4b910f5489f19ea5a3ca0f8a896365b306c42dd613c649bdc2598316136219f0f936c0a2ef00d75a62614d3ab22996f2a362ffa337c5ebede962aad1a2e84aaaa2f750dd12748c0fd0ab9324677800596e28b1743f46860000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000008249444154388dcdd341128020080550e8e02ebc38ad3273503e48537fe3e48c4f2425fa28e29c6f39920bf9276cb60185358877611388c2576418cda015f520b4e6b55be109dc0622b8e22acf31056e18dfdff80606aa551cc63564c4dcf80cd0201d577a5c85a8845fdc025ea5307afccd07e23a1df283ec2b37d9ad5fb4dfefd49cfbf72fac98c8cc890000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000bf49444154388dd593410a83301045df488ee51dbc8c3ba98bf46a9eabd385350d266362444a3f0c4266fcf3f824f06f12402b66da8c55f3de2212cf9d92cb98c0ba2d7c4544cf9a07638bbad53c4491235ecf7cc1623697a92540c11ff4fda75275015d24a9389e7d6f53df4fe4ccab323eea0f03c0c4b2a0712ce6add89b59b7661c3be095985f261679ee4ebcc22c9788551fe6a2cbc4969a894bcb6f23ee361aab62e252c57294dfbfb610bbf2c897b8a46cc6677eaa519571fa087ea83762da9abacb20235f0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000000d549444154388dc5955d0a84300c8427e2a90a9e6c8b0f4b3dd982d7ca3e58d7fe4cd0ba5d7640024df265da0a057e2439c9eb8d9eaa8841a0c9aad8c82ab32f9c425be1e30e0dcf00c00308f0b3a7a07410a9d7142e00b42c5a5fab696b979b1c837fc0c316b6e4165b64f78d716359919bdc4570de47c04732dd5e5bcc35f0c97762ae787936dccf7513577e79f48c4b27aa0f1327b240f5117fcbe348aa33b6e0224b054d0746b8025e2e3b3e73cde0dd1c97f02e8ed9d0af1db381224bdf33eee698a934a0f617b45540d00bcf4ca08fc0dff406e325c1981bc418760000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000025d49444154388dd593a172db4010863f670a56ecc42278d0653693a0c21c68d6c2e60df21a818111349499c254a8329b55f0e089ddb15ba602b79d6692d699b6d399fee86e67e7db7f77efe07fd3e2c74bd775b3730eef3d5115002382b5166b2d5757578b1729bf02b76d3b0f8703b92d58aed7600400ef1ce3c70306a8aa8aebebeb57c117dfa06ddb525dd754efb600a82a49138a123532ec3ac42b9bcde655ce2ffabe9f87c340fde13dcb4d8daaa24e48ee12c6823808c107969b1a8a9ce3f1f8aa515c38e7c8ada5aa6b00c45f129c67d223938c88e6c860d118b1d592d139baae9bcf83a78965b5465134801b1d2e1f4945c0e350096408ea154490c2e0bd3fef5853c2e486a0019f4d84f58418418362b0408e8b23c924501093314dd359f01b809814112025144015f1964c0bbc1b484b07e4688880c029ebd78e4141f5b434fd76864c053f1e084b0f8580265440634044ce838bbcc03987a61350a3a2285e1d5a4414d0708aa598082162ad3d0fb6d6e287cfa498508d274050447370428c91af8d10fd4481608c390b5e00dcddddcd8e80a9de420248e804840856f03e02907d729465c9ba5ae3468731e6a79fe50260b55a6102c4ee40a6894c33f2cb0cb106512814f8f899b22cb9b9b959b8d1f1f8f848d334b46dfbe29bfe5eadeffbf9783c323a871881ecb4200d1151a8eb9aed76bb00188661eeba8efd7e8f3186ed76cb6ab57ae2fe591b5dd7cdde7b628c8808799e63ada5aaaa67b9bbdd6e6e9a06ef3d755d3f29fec7eafb7ebebdbd9dadb5735996f3fdfdfdfca2e3dfd5c3c3c3dc340dd334b1d96cfe1e184e63dceff7a494fe26f61fe90bbc4c5e59d614caf40000000049454e44ae426082 + + + + + fileNewAction + activated() + Eficas + fileNew() + + + fileOpenAction + activated() + Eficas + fileOpen() + + + fileSaveAction + activated() + Eficas + fileSave() + + + fileSaveAsAction + activated() + Eficas + fileSaveAs() + + + fileExitAction + activated() + Eficas + fileExit() + + + editUndoAction + activated() + Eficas + editUndo() + + + editRedoAction + activated() + Eficas + editRedo() + + + editCutAction + activated() + Eficas + editCut() + + + editPasteAction + activated() + Eficas + editPaste() + + + editFindAction + activated() + Eficas + editFind() + + + helpIndexAction + activated() + Eficas + helpIndex() + + + helpContentsAction + activated() + Eficas + helpContents() + + + helpAboutAction + activated() + Eficas + helpAbout() + + + fileCloseAction + activated() + Eficas + fileClose() + + + fileNewViewAction + activated() + Eficas + fileNewView() + + + fileCloseAllAction + activated() + Eficas + fileCloseAll() + + + editCopyAction + activated() + Eficas + editCopy() + + + + fileNew() + fileOpen() + fileSave() + fileSaveAs() + filePrint() + fileExit() + editUndo() + editRedo() + editCut() + fileNewView() + editPaste() + editFind() + helpIndex() + helpContents() + helpAbout() + fileClose() + fileCloseAll() + editCopy() + + + diff --git a/Interface/myMain_ui.py b/Interface/myMain_ui.py new file mode 100644 index 00000000..2822db7c --- /dev/null +++ b/Interface/myMain_ui.py @@ -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 index 00000000..ea414a03 --- /dev/null +++ b/Interface/newsimppanel.py @@ -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 index 00000000..70b872fd --- /dev/null +++ b/Interface/panels.py @@ -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 index 00000000..6381ba7e --- /dev/null +++ b/Interface/panelsSalome.py @@ -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 index 00000000..88eea05d --- /dev/null +++ b/Interface/plusieursassdpanel.py @@ -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 = (("",self.selectValeur), + ("",self.deselectValeur), + ("",self.sup_valeur_sans_into)) + liste_commandes_choix = (("",self.selectChoix), + ("",self.deselectChoix), + ("",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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + fram.bind("",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 index 00000000..f1d65a9e --- /dev/null +++ b/Interface/plusieursbasepanel.py @@ -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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + fram.bind("",self.parent.appli.efface_aide) + + # création des objets dans les frames + liste_commandes_valeurs = (("",self.selectValeur), + ("",self.deselectValeur), + ("",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 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("",lambda e,c=command:c()) + self.entry.bind("",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 = (("",self.selectValeur), + ("",self.deselectValeur), + ("",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("",lambda e,s=self,a=bulle_aide: s.parent.appli.affiche_aide(e,a)) + fram.bind("",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 index 00000000..1854e865 --- /dev/null +++ b/Interface/plusieursintopanel.py @@ -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 = (("",self.selectValeur), + ("",self.deselectValeur), + ("",self.sup_valeur)) + liste_commandes_choix = (("",self.selectChoix), + ("",self.deselectChoix), + ("",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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + fram.bind("",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 index 00000000..2b59b339 --- /dev/null +++ b/Interface/plusieurspanel.py @@ -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 index 00000000..058bec83 --- /dev/null +++ b/Interface/qtEficas.py @@ -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 index 00000000..c4b604f9 --- /dev/null +++ b/Interface/readercata.py @@ -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 index 00000000..b863e884 --- /dev/null +++ b/Interface/session.py @@ -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 index 00000000..dd90ee60 --- /dev/null +++ b/Interface/styles.py @@ -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 index 00000000..c719789a --- /dev/null +++ b/Interface/treeitemincanvas.py @@ -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 index 00000000..799728d8 --- /dev/null +++ b/Interface/uiinfo.py @@ -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 index 00000000..bc777b76 --- /dev/null +++ b/Interface/uniqueassdpanel.py @@ -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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + self.frame_valeur.bind("",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("",lambda e,c=self.valid_valeur_reel:c()) + self.entry.bind("",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 index 00000000..74e3d87b --- /dev/null +++ b/Interface/uniquebasepanel.py @@ -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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + self.frame_valeur.bind("",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("",lambda e,c=self.valid_valeur:c()) + self.entry.bind("",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 """ + + 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 index 00000000..3aa09074 --- /dev/null +++ b/Interface/uniquecomppanel.py @@ -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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + self.frame_valeur.bind("",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("",lambda e,s=self:s.entry2.component('entry').focus()) + self.entry1.component('entry').bind("",lambda e,s=self:s.entry2.component('entry').focus()) + self.entry2.component('entry').bind("",lambda e,c=self.valid_valeur:c()) + self.entry2.component('entry').bind("",lambda e,c=self.valid_valeur:c()) + self.entry3.component('entry').bind("",lambda e,c=self.valid_complexe:c()) + self.entry3.component('entry').bind("",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 index 00000000..6532e3fa --- /dev/null +++ b/Interface/uniqueintopanel.py @@ -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("",lambda e,s=self,a=bulle_aide : + s.parent.appli.affiche_aide(e,a)) + self.frame_valeur.bind("",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 = (("",self.selectChoix), + ("",self.deselectChoix), + ("",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 index 00000000..99800307 --- /dev/null +++ b/Interface/uniquepanel.py @@ -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 index 00000000..49ecc2a6 --- /dev/null +++ b/Interface/uniquesdcopanel.py @@ -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("",lambda e,s=self,a=bulle_aide : s.parent.appli.affiche_aide(e,a)) + self.frame_valeur.bind("",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("",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('',self.valid_nom_concept_co) + self.entry_co.bind('',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 index 00000000..ecb01bb3 --- /dev/null +++ b/Interface/utils.py @@ -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 index 00000000..84a46f56 --- /dev/null +++ b/Interface/viewManager.py @@ -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( + """New""" + """

An empty editor window will be created.

""" + )) + 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( + """Open a Python file""" + """

You will be asked for the name of a Python file to be opened""" + """ in an editor window.

""" + )) + 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( + """Close Window""" + """

Close the current window.

""" + )) + 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( + """Close All Windows""" + """

Close all editor windows.

""" + )) + 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( + """Save File""" + """

Save the contents of current editor window.

""" + )) + 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( + """Save File as""" + """

Save the contents of current editor window to a new file.""" + """ The file can be entered in a file selection dialog.

""" + )) + 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( + """Save All Files""" + """

Save the contents of all editor windows.

""" + )) + 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( + """Save to Project""" + """

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.

""" + )) + 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( + """Print File""" + """

Print the contents of current editor window.

""" + )) + 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( + """Print Selection""" + """

Print the selection of the current editor window.

""" + )) + 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( + """Search File""" + """

Search for a file.

""" + )) + 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( +## """Undo""" +## """

Undo the last change done in the current editor.

""" +## )) +## 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( +## """Redo""" +## """

Redo the last change done in the current editor.

""" +## )) +## 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( +## """Revert to last saved state""" +## """

Undo all changes up to the last saved state of the current editor.

""" +## )) +## 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( +## """Cut""" +## """

Cut the selected text of the current editor to the clipboard.

""" +## )) +## 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( +## """Copy""" +## """

Copy the selected text of the current editor to the clipboard.

""" +## )) +## 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( +## """Paste""" +## """

Paste the last cut/copied text from the clipboard to""" +## """ the current editor.

""" +## )) +## 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( +## """Clear""" +## """

Delete all text of the current editor.

""" +## )) +## 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( +## """Indent""" +## """

Indents the current line or the lines of the""" +## """ selection by one level.

""" +## )) +## 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( +## """Unindent""" +## """

Unindents the current line or the lines of the""" +## """ selection by one level.

""" +## )) +## 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( +## """Comment""" +## """

Comments the current line or the lines of the""" +## """ current selection.

""" +## )) +## 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( +## """Uncomment""" +## """

Uncomments the current line or the lines of the""" +## """ current selection.

""" +## )) +## 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( +## """Stream Comment""" +## """

Stream comments the current line or the current selection.

""" +## )) +## 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( +## """Box Comment""" +## """

Box comments the current line or the lines of the""" +## """ current selection.

""" +## )) +## 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( +## """Selct to brace""" +## """

Select text of the current editor to the matching brace.

""" +## )) +## 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( +## """Selct All""" +## """

Select all text of the current editor.

""" +## )) +## 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( +## """Deselct All""" +## """

Deselect all text of the current editor.

""" +## )) +## 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( +## """Convert Line End Characters""" +## """

Convert the line end characters to the currently set type.

""" +## )) +## 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( +## """Shorten empty lines""" +## """

Shorten lines consisting solely of whitespace characters.

""" +## )) +## 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( +## """Autocomplete""" +## """

Performs an autocompletion of the word containing the cursor.

""" +## )) +## 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( +## """Autocomplete from Document""" +## """

Performs an autocompletion from document of the word containing the cursor.

""" +## )) +## 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( +## """Autocomplete from APIs""" +## """

Performs an autocompletion from APIs of the word containing the cursor.

""" +## )) +## 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( + """Search""" + """

Search for some text in the current editor. A""" + """ dialog is shown to enter the searchtext and options""" + """ for the search.

""" + )) + 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( + """Search again""" + """

Search again for some text in the current editor.""" + """ The previously entered searchtext and options are reused.

""" + )) + 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( + """Replace""" + """

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.

""" + )) + 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( + """Goto Line""" + """

Go to a specific line of text in the current editor.""" + """ A dialog is shown to enter the linenumber.

""" + )) + 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( + """Goto Brace""" + """

Go to the matching brace in the current editor.

""" + )) + 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( + """Search in Files""" + """

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.

""" + )) + 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( + """Zoom in""" + """

Zoom in on the text. This makes the text bigger.

""" + )) + 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( + """Zoom out""" + """

Zoom out on the text. This makes the text smaller.

""" + )) + 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( + """Zoom""" + """

Zoom the text. This opens a dialog where the""" + """ desired size can be entered.

""" + )) + 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( + """Toggle all folds""" + """

Toggle all folds of the current editor.

""" + )) + self.connect(self.toggleAllAct,SIGNAL('activated()'),self.handleToggleAll) + self.viewActions.append(self.toggleAllAct) + + self.toggleCurrentAct = QAction(self.trUtf8('Toggle current fold'), + self.trUtf8('Toggle ¤t fold'), + 0, self.viewFoldActGrp) + self.toggleCurrentAct.setStatusTip(self.trUtf8('Toggle current fold')) + self.toggleCurrentAct.setWhatsThis(self.trUtf8( + """Toggle current fold""" + """

Toggle the folds of the current line of the current editor.

""" + )) + 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( + """Remove all highlights""" + """

Remove the highlights of all editors.

""" + )) + 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( + """Split view""" + """

Add a split to the view.

""" + )) + 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( + """Arrange horizontally""" + """

Arrange the splitted views horizontally.

""" + )) + 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( + """Remove split""" + """

Remove the current split.

""" + )) + 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( + """Start Macro Recording""" + """

Start recording editor commands into a new macro.

""" + )) + 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( + """Stop Macro Recording""" + """

Stop recording editor commands into a new macro.

""" + )) + 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( + """Run Macro""" + """

Run a previously recorded editor macro.

""" + )) + 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( + """Delete Macro""" + """

Delete a previously recorded editor macro.

""" + )) + 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( + """Load Macro""" + """

Load an editor macro from a file.

""" + )) + 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( + """Save Macro""" + """

Save a previously recorded editor macro to a file.

""" + )) + 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( + """Toggle Bookmark""" + """

Toggle a bookmark at the current line of the current editor.

""" + )) + 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( + """Next Bookmark""" + """

Go to next bookmark of the current editor.

""" + )) + 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( + """Previous Bookmark""" + """

Go to previous bookmark of the current editor.

""" + )) + 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( + """Clear Bookmarks""" + """

Clear bookmarks of all editors.

""" + )) + 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( + """Goto Syntax Error""" + """

Go to next syntax error of the current editor.

""" + )) + 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( + """Clear Syntax Errors""" + """

Clear syntax errors of all editors.

""" + )) + 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 %1 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 +
    +
  • reread the colours for the syntax highlighting
  • +
  • reloads the already created API objetcs
  • +
  • starts or stops the autosave timer
  • +
  • Note: changes in viewmanager type are activated + on an application restart.
  • +
+ """ + # 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:
+ 1: Directory of currently active editor
+ 2: Directory of currently active Project
+ 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:
+ 1: Directory of currently active editor
+ 2: Directory of currently active Project
+ 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) -- 2.39.2