Salome HOME
merge de la branche BR_dev_mars_06 (tag V1_10b5) dans la branche principale
[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 du chargeur de composants
29 from comploader import make_objecttreeitem
30 import treewidget
31 from Ihm import CONNECTOR
32
33 myrepr = Repr()
34 myrepr.maxstring = 100
35 myrepr.maxother = 100
36
37 class TreeItem:
38
39     """Abstract class representing tree items.
40
41     Methods should typically be overridden, otherwise a default action
42     is used.
43
44     """
45     # itemNode est une factory qui doit retourner un objet de la classe Node
46     # ou dérivé de cette classe.
47     # Le widget arbre utilisera cet objet comme noeud associé au tree item.
48     # Par defaut, utilise la classe Node de base
49     # La signature de la factory est la suivante :
50     # itemNode(treeOrNode,item,command,rmenu)
51     # ou treeOrNode est le noeud parent, item est l'item associé
52     # command est une fonction python appelée sur sélection graphique
53     # du noeud et rmenu est une fonction python appelée sur click droit sur le noeud
54     itemNode=treewidget.Node
55
56     def __init__(self):
57         """Constructor.  Do whatever you need to do."""
58
59     def GetText(self):
60         """Return text string to display."""
61
62     def GetLabelText(self):
63         """Return label text string to display in front of text (if any)."""
64
65     expandable = None
66
67     def _IsExpandable(self):
68         """Do not override!  Called by TreeNode."""
69         if self.expandable is None:
70             self.expandable = self.IsExpandable()
71         return self.expandable
72
73     def IsExpandable(self):
74         """Return whether there are subitems."""
75         return 1
76
77     def _GetSubList(self):
78         """Do not override!  Called by TreeNode."""
79         if not self.IsExpandable():
80             return []
81         sublist = self.GetSubList()
82         if not sublist:
83             self.expandable = 0
84         return sublist
85
86     def IsEditable(self):
87         """Return whether the item's text may be edited."""
88
89     def SetText(self, text):
90         """Change the item's text (if it is editable)."""
91
92     def GetIconName(self):
93         """Return name of icon to be displayed normally."""
94
95     def GetSelectedIconName(self):
96         """Return name of icon to be displayed when selected."""
97
98     def GetSubList(self):
99         """Return list of items forming sublist."""
100
101     def OnDoubleClick(self):
102         """Called on a double-click on the item."""
103
104 class Delegate:
105     def __init__(self, delegate=None):
106         self.object = delegate
107         self.__cache = {}
108
109     def setdelegate(self, delegate):
110         self.resetcache()
111         self.object = delegate
112
113     def getdelegate(self):
114         return self.object
115
116     def __getattr__(self, name):
117         attr = getattr(self.object, name) # May raise AttributeError
118         setattr(self, name, attr)
119         self.__cache[name] = attr
120         return attr
121
122     def resetcache(self):
123         for key in self.__cache.keys():
124             try:
125                 delattr(self, key)
126             except AttributeError:
127                 pass
128         self.__cache.clear()
129
130     def cachereport(self):
131         keys = self.__cache.keys()
132         keys.sort()
133         print keys
134
135
136 class ObjectTreeItem(TreeItem,Delegate):
137     def __init__(self, appli, labeltext, object, setfunction=None):
138         self.labeltext = labeltext
139         self.appli = appli
140         # L'objet délegué est stocké dans l'attribut object
141         # L'objet associé à l'item est stocké dans l'attribut _object
142         # Il peut etre obtenu par appel à la méthode getObject
143         # Attention : le délégué peut etre différent de l'objet associé (MCLIST)
144         # Dans le cas d'une MCListe de longueur 1, l'objet associé est la MCListe
145         # et l'objet délégué est le MCFACT (object = _object.data[0])
146         Delegate.__init__(self,object)
147         # On cache l'objet initial (pour destruction eventuelle
148         # ultérieure)
149         self._object = object
150         self.setfunction = setfunction
151         self.expandable = 1
152         self.sublist=[]
153         self.init()
154
155     def init(self):
156         return
157
158     def getObject(self):
159         return self._object
160
161     def connect(self,channel,callable,args):
162         """ Connecte la fonction callable (avec arguments args) à l'item self sur le 
163             canal channel
164         """
165         CONNECTOR.Connect(self._object,channel,callable,args)
166         CONNECTOR.Connect(self.object, channel,callable,args)
167
168     def copy(self):
169         """
170         Crée un item copie de self
171         """
172         object = self._object.copy()
173         appli = copy(self.appli)
174         labeltext = copy(self.labeltext)
175         fonction = deepcopy(self.setfunction)
176         item = make_objecttreeitem(appli,labeltext,object,fonction)
177         return item
178     
179     def isactif(self):
180         if hasattr(self.object,'actif'):
181             return self.object.actif
182         else:
183             return 1
184     
185     def update(self,item):
186         """
187           Met a jour l'item courant a partir d'un autre item passe en argument
188           Ne fait rien par defaut
189         """
190         pass
191
192     def GetLabelText(self):
193         """ Retourne 3 valeurs :
194         - le texte à afficher dans le noeud représentant l'item
195         - la fonte dans laquelle afficher ce texte
196         - la couleur du texte
197         """
198         # None --> fonte et couleur par défaut
199         return self.labeltext,None,None
200
201     def get_nature(self) :
202         """ 
203             Retourne la nature de l'item et de l'objet
204         """ 
205         return self.object.nature
206
207     def get_regles(self):
208         """ retourne les règles de l'objet pointé par self """
209         return self.object.get_regles()
210     
211     def get_liste_mc_presents(self):
212         """ Retourne la liste des mots-clés fils de l'objet pointé par self """
213         return self.object.liste_mc_presents()
214     
215     def get_val(self):
216         """ Retourne le nom de la valeur de l'objet pointé par self dans le cas
217             où celle-ci est un objet (ASSD) """
218         return self.object.getval()
219     
220     def get_definition(self):
221         """ 
222            Retourne l'objet definition de l'objet pointé par self 
223         """
224         return self.object.definition
225
226     def get_liste_mc_ordonnee(self,liste,dico):
227         """ retourne la liste ordonnée (suivant le catalogue) brute des mots-clés
228             d'une entité composée dont le chemin complet est donné sous forme
229             d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
230             il faut encore réarranger cette liste (certains mots-clés déjà
231             présents ne doivent plus être proposés, règles ...)"""
232         return self.object.get_liste_mc_ordonnee(liste,dico)
233
234     def get_liste_mc_ordonnee_brute(self,liste,dico):
235         """
236         retourne la liste ordonnée (suivant le catalogue) BRUTE des mots-clés
237         d'une entité composée dont le chemin complet est donné sous forme
238         d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
239         """
240         return self.object.get_liste_mc_ordonnee_brute(liste,dico)
241    
242     def get_genealogie(self):
243         """
244         Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE)
245         de l'objet pointé par self
246         """
247         return self.object.get_genealogie()
248
249     def get_index_child(self,nom_fils):
250         """
251         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
252         Nécessaire pour savoir à quelle position dans la liste des fils il faut ajouter
253         le nouveau mot-clé
254         """
255         return self.object.get_index_child(nom_fils)
256
257     def get_index_child_old(self,nom_fils):
258         """
259         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
260         Nécessaire pour savoir à quelle position dans la liste des fils il faut ajouter
261         le nouveau mot-clé
262         """
263         liste_noms_mc_ordonnee = self.get_liste_mc_ordonnee_brute(self.get_genealogie(),self.get_jdc().cata_ordonne_dico)
264         liste_noms_mc_presents = self.object.liste_mc_presents()
265         l=[]
266         for nom in liste_noms_mc_ordonnee:
267             if nom in liste_noms_mc_presents or nom == nom_fils:
268                 l.append(nom)
269         # l contient les anciens mots-clés + le nouveau dans l'ordre
270         return l.index(nom_fils)
271         
272     def append_child(self,name,pos=None):
273         """
274           Permet d'ajouter un item fils à self
275         """
276         if pos == 'first':
277             index = 0
278         elif pos == 'last':
279             index = len(self.liste_mc_presents())
280         elif type(pos) == types.IntType :
281             # la position est fixée 
282             index = pos
283         elif type(pos) == types.InstanceType:
284             # pos est un item. Il faut inserer name apres pos
285             index = self.get_index(pos) +1
286         elif type(name) == types.InstanceType:
287             index = self.get_index_child(name.nom)
288         else:
289             index = self.get_index_child(name)
290         return self.addobject(name,index)
291
292     def append_brother(self,name,pos='after'):
293         """
294         Permet d'ajouter un frère à self
295         par défaut on l'ajoute après self
296         """
297         index = self._object.parent.get_index(self.getObject())
298         if pos == 'before':
299             index = index
300         elif pos == 'after':
301             index = index +1
302         else:
303             print str(pos)," n'est pas un index valide pour append_brother"
304             return
305         return self.parent.addobject(name,index)
306
307     def get_nom_etape(self):
308         """Retourne le nom de self """
309         return self.object.get_nom_etape()
310
311     def get_copie_objet(self):
312         """ Retourne une copie de l'objet pointé par self """
313         return self.object.copy()
314     
315     def get_position(self):
316         """ Retourne la valeur de l'attribut position de l'objet pointé par self """
317         definition = self.get_definition()
318         try:
319             return getattr(definition,'position')
320         except AttributeError:
321             return 'local'
322         
323     def get_nom(self):
324         """ Retourne le nom de l'objet pointé par self """
325         return self.object.nom
326
327     def get_jdc(self):
328         """ Retourne le jdc auquel appartient l'objet pointé par self """
329         return self.object.jdc
330     
331     def get_valeur(self):
332         """ Retourne la valeur de l'objet pointé par self """
333         return self.object.valeur
334
335     def get_cr(self):
336         """ Retourne le compte-rendu CR de self """
337         return self.object.report()
338
339     def get_objet_commentarise(self):
340         """
341         Cette méthode retourne un objet commentarisé
342         représentatif de self.object
343         --> à surcharger par les différents items
344         """
345         raise Exception("MESSAGE AU DEVELOPPEUR : il faut surcharger la methode get_objet_commentarise() pour la classe "+self.__class__.__name__)
346         pass
347         
348     def isvalid(self):
349         """ Retourne 1 si l'objet pointé par self est valide, 0 sinon"""
350         return self.object.isvalid()
351
352     def iscopiable(self):
353         """
354         Retourne 1 si l'objet est copiable, 0 sinon
355         Par défaut retourne 0
356         """
357         return 0
358     
359     def get_mc_presents(self):
360         """ Retourne le dictionnaire des mots-clés présents de l'objet pointé par self """
361         return self.object.dict_mc_presents()
362
363     def verif_condition_regles(self,l_mc_presents):
364         return self.object.verif_condition_regles(l_mc_presents)
365
366     def get_fr(self):
367         """ Retourne le fr de l'objet pointé par self """
368         try:
369             return self.object.get_fr()
370         except:
371             return ""
372
373     def get_docu(self):
374         """ Retourne la clé de doc de l'objet pointé par self """
375         return self.object.get_docu()
376
377     def set_valeur(self,new_valeur):
378         """ Remplace la valeur de l'objet pointé par self par new_valeur """
379         return self.object.set_valeur(new_valeur)
380         
381     def GetText(self):
382         return myrepr.repr(self.object)
383     
384     def GetIconName(self):
385         if not self.IsExpandable():
386             return "python"
387
388     def IsEditable(self):
389         return self.setfunction is not None
390
391     def SetText(self, text):
392         try:
393             value = eval(text)
394             self.setfunction(value)
395         except:
396             pass
397 # Modif de ma part CCar : je ne comprend pas a quoi ca sert
398 # ca parait meme incorrect
399       #  else:
400       #      self.object = value
401
402     def IsExpandable(self):
403         return 1
404         
405     def GetSubList(self):
406         keys = dir(self.object)
407         sublist = []
408         for key in keys:
409             try:
410                 value = getattr(self.object, key)
411             except AttributeError:
412                 continue
413             item = make_objecttreeitem(
414                 self.appli,
415                 str(key) + " =",
416                 value,
417                 lambda value, key=key, object=self.object:
418                     setattr(object, key, value))
419             sublist.append(item)
420         return sublist
421
422     def wait_fichier_init(self):
423         """ Retourne 1 si l'object pointé par self attend un fichier d'initialisation
424         (ex: macros POURSUITE et INCLUDE de Code_Aster), 0 SINON """
425         return self.object.definition.fichier_ini
426
427     def make_objecttreeitem(self,appli,labeltext, object, setfunction=None):
428         """
429            Cette methode, globale pour les objets de type item, permet de construire et de retourner un objet
430            de type item associé à l'object passé en argument.
431         """
432         return make_objecttreeitem(appli,labeltext,object,setfunction)
433
434     #def __del__(self):
435     #    print "__del__",self
436
437 class AtomicObjectTreeItem(ObjectTreeItem):
438     def IsExpandable(self):
439         return 0
440
441 class SequenceTreeItem(ObjectTreeItem):
442     def IsExpandable(self):
443         return len(self._object) > 0
444
445     def __len__(self) :
446         return len(self._object)
447    
448     def keys(self):
449         return range(len(self._object))
450
451     def GetIconName(self):
452         if self._object.isvalid():
453           return "ast-green-los"
454         elif self._object.isoblig():
455           return "ast-red-los"
456         else:
457           return "ast-yel-los"
458
459     def ajout_possible(self):
460         return self._object.ajout_possible()
461
462     def get_index(self,child):
463         """ Retourne le numéro de child dans la liste des enfants de self """
464         return self._object.get_index(child.getObject())
465
466     def GetText(self):
467       return  "    "
468
469     def additem(self,obj,pos):
470         self._object.insert(pos,obj)
471         item = self.make_objecttreeitem(self.appli, obj.nom + ":", obj)
472         return item
473
474     def suppitem(self,item):
475         try :
476             self._object.remove(item.getObject())
477             # la liste peut être retournée vide !
478             message = "Mot-clé " + item.getObject().nom + " supprimé"
479             self.appli.affiche_infos(message)
480             return 1
481         except:
482             return 0
483
484     def GetSubList(self):
485         isublist=iter(self.sublist)
486         liste=self._object.data
487         iliste=iter(liste)
488         self.sublist=[]
489
490         while(1):
491            old_obj=obj=None
492            for item in isublist:
493               old_obj=item.getObject()
494               if old_obj in liste:break
495
496            for obj in iliste:
497               if obj is old_obj:break
498               # nouvel objet : on cree un nouvel item
499               def setfunction(value, object=obj):
500                   object=value
501               it = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, setfunction)
502               self.sublist.append(it)
503            if old_obj is None and obj is None:break
504            if old_obj is obj: self.sublist.append(item)
505         return self.sublist