Salome HOME
PN Pour les formules
[tools/eficas.git] / Editeur / Objecttreeitem.py
1 # -*- coding: utf-8 -*-
2 #            CONFIGURATION MANAGEMENT OF EDF VERSION
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
9 #
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
14 #
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
18 #
19 #
20 # ======================================================================
21 """
22 """
23 # import généraux
24 import types,string,os,glob,imp,sys
25 from repr import Repr
26 from copy import copy,deepcopy
27
28 import treewidget
29
30 myrepr = Repr()
31 myrepr.maxstring = 100
32 myrepr.maxother = 100
33
34 class TreeItem:
35
36     """Abstract class representing tree items.
37
38     Methods should typically be overridden, otherwise a default action
39     is used.
40
41     """
42     # itemNode est une factory qui doit retourner un objet de la classe Node
43     # ou dérivé de cette classe.
44     # Le widget arbre utilisera cet objet comme noeud associé au tree item.
45     # Par defaut, utilise la classe Node de base
46     # La signature de la factory est la suivante :
47     # itemNode(treeOrNode,item,command,rmenu)
48     # ou treeOrNode est le noeud parent, item est l'item associé
49     # command est une fonction python appelée sur sélection graphique
50     # du noeud et rmenu est une fonction python appelée sur click droit sur le noeud
51     itemNode=treewidget.Node
52
53     def __init__(self):
54         """Constructor.  Do whatever you need to do."""
55
56     def GetText(self):
57         """Return text string to display."""
58
59     def GetLabelText(self):
60         """Return label text string to display in front of text (if any)."""
61
62     expandable = None
63
64     def _IsExpandable(self):
65         """Do not override!  Called by TreeNode."""
66         if self.expandable is None:
67             self.expandable = self.IsExpandable()
68         return self.expandable
69
70     def IsExpandable(self):
71         """Return whether there are subitems."""
72         return 1
73
74     def _GetSubList(self):
75         """Do not override!  Called by TreeNode."""
76         if not self.IsExpandable():
77             return []
78         sublist = self.GetSubList()
79         if not sublist:
80             self.expandable = 0
81         return sublist
82
83     def IsEditable(self):
84         """Return whether the item's text may be edited."""
85
86     def SetText(self, text):
87         """Change the item's text (if it is editable)."""
88
89     def GetIconName(self):
90         """Return name of icon to be displayed normally."""
91
92     def GetSelectedIconName(self):
93         """Return name of icon to be displayed when selected."""
94
95     def GetSubList(self):
96         """Return list of items forming sublist."""
97
98     def OnDoubleClick(self):
99         """Called on a double-click on the item."""
100
101 class Delegate:
102     def __init__(self, delegate=None):
103         self.object = delegate
104         self.__cache = {}
105
106     def setdelegate(self, delegate):
107         self.resetcache()
108         self.object = delegate
109
110     def getdelegate(self):
111         return self.object
112
113     def __getattr__(self, name):
114         attr = getattr(self.object, name) # May raise AttributeError
115         setattr(self, name, attr)
116         self.__cache[name] = attr
117         return attr
118
119     def resetcache(self):
120         for key in self.__cache.keys():
121             try:
122                 delattr(self, key)
123             except AttributeError:
124                 pass
125         self.__cache.clear()
126
127     def cachereport(self):
128         keys = self.__cache.keys()
129         keys.sort()
130         print keys
131
132
133 class ObjectTreeItem(TreeItem,Delegate):
134     def __init__(self, appli, labeltext, object, setfunction=None):
135         self.labeltext = labeltext
136         self.appli = appli
137         Delegate.__init__(self,object)
138         # On cache l'objet initial (pour destruction eventuelle
139         # ultérieure)
140         self._object = object
141         self.setfunction = setfunction
142         self.expandable = 1
143         self.init()
144
145     def init(self):
146         return
147
148     def getObject(self):
149         return self._object
150
151     def copy(self):
152         """
153         Crée un item copie de self
154         """
155         object = self._object.copy()
156         appli = copy(self.appli)
157         labeltext = copy(self.labeltext)
158         fonction = deepcopy(self.setfunction)
159         item = make_objecttreeitem(appli,labeltext,object,fonction)
160         return item
161     
162     def isactif(self):
163         if hasattr(self.object,'actif'):
164             return self.object.actif
165         else:
166             return 1
167     
168     def GetLabelText(self):
169         """ Retourne 3 valeurs :
170         - le texte à afficher dans le noeud représentant l'item
171         - la fonte dans laquelle afficher ce texte
172         - la couleur du texte
173         """
174         # None --> fonte et couleur par défaut
175         return self.labeltext,None,None
176
177     def get_nature(self) :
178         """ 
179             Retourne la nature de l'item et de l'objet
180         """ 
181         return self.object.nature
182
183     def get_regles(self):
184         """ retourne les règles de l'objet pointé par self """
185         return self.object.get_regles()
186     
187     def get_liste_mc_presents(self):
188         """ Retourne la liste des mots-clés fils de l'objet pointé par self """
189         return self.object.liste_mc_presents()
190     
191     def get_val(self):
192         """ Retourne le nom de la valeur de l'objet pointé par self dans le cas
193             où celle-ci est un objet (ASSD) """
194         return self.object.getval()
195     
196     def get_definition(self):
197         """ 
198            Retourne l'objet definition de l'objet pointé par self 
199         """
200         return self.object.definition
201
202     def get_liste_mc_ordonnee(self,liste,dico):
203         """ retourne la liste ordonnée (suivant le catalogue) brute des mots-clés
204             d'une entité composée dont le chemin complet est donné sous forme
205             d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
206             il faut encore réarranger cette liste (certains mots-clés déjà
207             présents ne doivent plus être proposés, règles ...)"""
208         return self.object.get_liste_mc_ordonnee(liste,dico)
209
210     def get_liste_mc_ordonnee_brute(self,liste,dico):
211         """
212         retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés
213         d'une entité composée dont le chemin complet est donné sous forme
214         d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
215         """
216         return self.object.get_liste_mc_ordonnee_brute(liste,dico)
217    
218     def get_genealogie(self):
219         """
220         Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE)
221         de l'objet pointé par self
222         """
223         return self.object.get_genealogie()
224
225     def get_index_child(self,nom_fils):
226         """
227         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
228         Nécessaire pour savoir à quelle position dans la liste des fils il faut ajouter
229         le nouveau mot-clé
230         """
231         liste_noms_mc_ordonnee = self.get_liste_mc_ordonnee_brute(self.get_genealogie(),self.get_jdc().cata_ordonne_dico)
232         liste_noms_mc_presents = self.object.liste_mc_presents()
233         l=[]
234         for nom in liste_noms_mc_ordonnee:
235             if nom in liste_noms_mc_presents or nom == nom_fils:
236                 l.append(nom)
237         # l contient les anciens mots-clés + le nouveau dans l'ordre
238         return l.index(nom_fils)
239         
240     def get_nom_etape(self):
241         """Retourne le nom de self """
242         return self.object.get_nom_etape()
243
244     def get_copie_objet(self):
245         """ Retourne une copie de l'objet pointé par self """
246         return self.object.copy()
247     
248     def get_position(self):
249         """ Retourne la valeur de l'attribut position de l'objet pointé par self """
250         definition = self.get_definition()
251         try:
252             return getattr(definition,'position')
253         except AttributeError:
254             return 'local'
255         
256     def get_nom(self):
257         """ Retourne le nom de l'objet pointé par self """
258         return self.object.nom
259
260     def get_jdc(self):
261         """ Retourne le jdc auquel appartient l'objet pointé par self """
262         return self.object.jdc
263     
264     def get_valeur(self):
265         """ Retourne la valeur de l'objet pointé par self """
266         return self.object.valeur
267
268     def get_cr(self):
269         """ Retourne le compte-rendu CR de self """
270         return self.object.report()
271
272     def get_objet_commentarise(self):
273         """
274         Cette méthode retourne un objet commentarisé
275         représentatif de self.object
276         --> à surcharger par les différents items
277         """
278         raise Exception("MESSAGE AU DEVELOPPEUR : il faut surcharger la methode get_objet_commentarise() pour la classe "+self.__class__.__name__)
279         pass
280         
281     def isvalid(self):
282         """ Retourne 1 si l'objet pointé par self est valide, 0 sinon"""
283         return self.object.isvalid()
284
285     def iscopiable(self):
286         """
287         Retourne 1 si l'objet est copiable, 0 sinon
288         Par défaut retourne 0
289         """
290         return 0
291     
292     def get_mc_presents(self):
293         """ Retourne le dictionnaire des mots-clés présents de l'objet pointé par self """
294         return self.object.dict_mc_presents()
295
296     def verif_condition_regles(self,l_mc_presents):
297         return self.object.verif_condition_regles(l_mc_presents)
298
299     def get_fr(self):
300         """ Retourne le fr de l'objet pointé par self """
301         return self.object.get_fr()
302
303     def get_docu(self):
304         """ Retourne la clé de doc de l'objet pointé par self """
305         return self.object.get_docu()
306
307     def set_valeur(self,new_valeur):
308         """ Remplace la valeur de l'objet pointé par self par new_valeur """
309         return self.object.set_valeur(new_valeur)
310         
311     def GetText(self):
312         return myrepr.repr(self.object)
313     
314     def GetIconName(self):
315         if not self.IsExpandable():
316             return "python"
317
318     def IsEditable(self):
319         return self.setfunction is not None
320
321     def SetText(self, text):
322         try:
323             value = eval(text)
324             self.setfunction(value)
325         except:
326             pass
327 # Modif de ma part CCar : je ne comprend pas a quoi ca sert
328 # ca parait meme incorrect
329       #  else:
330       #      self.object = value
331
332     def IsExpandable(self):
333         return 1
334         
335     def GetSubList(self):
336         keys = dir(self.object)
337         sublist = []
338         for key in keys:
339             try:
340                 value = getattr(self.object, key)
341             except AttributeError:
342                 continue
343             item = make_objecttreeitem(
344                 self.appli,
345                 str(key) + " =",
346                 value,
347                 lambda value, key=key, object=self.object:
348                     setattr(object, key, value))
349             sublist.append(item)
350         return sublist
351
352     def wait_fichier_init(self):
353         """ Retourne 1 si l'object pointé par self attend un fichier d'initialisation
354         (ex: macros POURSUITE et INCLUDE de Code_Aster), 0 SINON """
355         return self.object.definition.fichier_ini
356
357     def make_objecttreeitem(self,appli,labeltext, object, setfunction=None):
358         """
359            Cette methode, globale pour les objets de type item, permet de construire et de retourner un objet
360            de type item associé à l'object passé en argument.
361         """
362         c = gettreeitem(object)
363         return c(appli,labeltext, object, setfunction)
364
365 class AtomicObjectTreeItem(ObjectTreeItem):
366     def IsExpandable(self):
367         return 0
368
369 class SequenceTreeItem(ObjectTreeItem):
370     def IsExpandable(self):
371         return len(self._object) > 0
372
373     def __len__(self) :
374         return len(self._object)
375    
376     def keys(self):
377         return range(len(self._object))
378
379     def GetIconName(self):
380         if self._object.isvalid():
381           return "ast-green-los"
382         elif self._object.isoblig():
383           return "ast-red-los"
384         else:
385           return "ast-yel-los"
386
387     def ajout_possible(self):
388         return self._object.ajout_possible()
389
390     def get_index(self,child):
391         """ Retourne le numéro de child dans la liste des enfants de self """
392         return self._object.get_index(child.getObject())
393
394     def GetText(self):
395       return  "    "
396
397     def additem(self,obj,pos):
398         self._object.insert(pos,obj)
399         item = self.make_objecttreeitem(self.appli, obj.nom + ":", obj)
400         return item
401
402     def suppitem(self,item):
403         try :
404             self._object.remove(item.getObject())
405             # la liste peut être retournée vide !
406             message = "Mot-clé " + item.getObject().nom + " supprimé"
407             self.appli.affiche_infos(message)
408             return 1
409         except:
410             return 0
411
412     def GetSubList(self):
413         sublist = []
414         for obj in self._object.data:
415             def setfunction(value, object=obj):
416                 object = value
417             item = make_objecttreeitem(self.appli, obj.nom + ":", obj, setfunction)
418             sublist.append(item)
419         return sublist
420
421 def gettreeitem(object):
422     """
423        Cette fonction retourne la classe item associée à l'objet object.
424        Cette classe item dépend bien sûr de la nature de object, d'où
425        l'interrogation du dictionnaire composants
426     """
427     if type(object) == types.InstanceType:
428       # On cherche d abord dans les composants (plugins)
429       try:
430         return composants[object.__class__]
431       except:
432         # On cherche une eventuelle classe heritee (aleatoire car sans ordre)
433         for e in composants.keys():
434           if isinstance(object,e):return composants[e]
435     # On n'a rien trouve dans les composants
436     return ObjectTreeItem
437
438 def charger_composants():
439     """
440         Cette fonction a pour but de charger tous les modules composants graphiques
441         (fichiers compo*.py dans le même répertoire que ce module )
442         et de remplir le dictionnaire composants utilisé par make_objecttreeitem
443     """
444     composants={}
445     repertoire=os.path.dirname(__file__)
446     listfich=glob.glob(os.path.join(repertoire, "compo*.py"))
447     for fichier in listfich:
448         m= os.path.basename(fichier)[:-3]
449         module=__import__(m,globals(),locals())
450         composants[module.objet]=module.treeitem
451     return composants
452
453 def make_objecttreeitem(appli,labeltext, object, setfunction=None):
454     """
455        Cette fonction permet de construire et de retourner un objet
456        de type item associé à l'object passé en argument.
457     """
458     c = gettreeitem(object)
459     return c(appli,labeltext, object, setfunction)
460
461 # Dictionnaire {object : item} permettant d'associer un item à un object
462 # Ce dictionnaire est renseigné par la méthode charger_composants 
463 composants = charger_composants()
464