Salome HOME
commentaire
[tools/eficas.git] / Editeur / Objecttreeitem.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 """
21 """
22 # import generaux
23 from __future__ import absolute_import
24 from __future__ import print_function
25 try :
26    from builtins import str
27    from builtins import range
28    from builtins import object
29 except :
30    pass
31 import types,os,glob,imp,sys
32 from six.moves.reprlib import Repr
33 from copy import copy,deepcopy
34
35 # import du chargeur de composants
36 from .comploader import make_objecttreeitem
37 from Ihm import CONNECTOR
38 from Extensions.i18n import tr
39 from Extensions.eficas_exception import EficasException
40 from six.moves import range
41
42 myrepr = Repr()
43 myrepr.maxstring = 100
44 myrepr.maxother = 100
45
46 class TreeItem(object):
47
48     """Abstract class representing tree items.
49
50     Methods should typically be overridden, otherwise a default action
51     is used.
52
53     """
54     # itemNode est une factory qui doit retourner un objet de la classe Node
55     # ou derive de cette classe.
56     # Le widget arbre utilisera cet objet comme noeud associe au tree item.
57     # Par defaut, utilise la classe Node de base
58     # La signature de la factory est la suivante :
59     # itemNode(treeOrNode,item,command,rmenu)
60     # ou treeOrNode est le noeud parent, item est l'item associe
61     # command est une fonction python appelee sur selection graphique
62     # du noeud et rmenu est une fonction python appelee sur click droit sur le noeud
63     itemNode=None
64
65     def __init__(self):
66         """Constructor.  Do whatever you need to do."""
67
68     def GetText(self):
69         """Return text string to display."""
70
71     def GetLabelText(self):
72         """Return label text string to display in front of text (if any)."""
73
74     expandable = None
75
76     def _IsExpandable(self):
77         """Do not override!  Called by TreeNode."""
78         if self.expandable is None:
79             self.expandable = self.IsExpandable()
80         return self.expandable
81
82     def IsExpandable(self):
83         """Return whether there are subitems."""
84         return 1
85
86     def _GetSubList(self):
87         """Do not override!  Called by TreeNode."""
88         if not self.IsExpandable():
89             return []
90         sublist = self.GetSubList()
91         if not sublist:
92             self.expandable = 0
93         return sublist
94
95     def IsEditable(self):
96         """Return whether the item's text may be edited."""
97
98     def SetText(self, text):
99         """Change the item's text (if it is editable)."""
100
101     def GetIconName(self):
102         """Return name of icon to be displayed normally."""
103
104     def GetSelectedIconName(self):
105         """Return name of icon to be displayed when selected."""
106
107     def GetSubList(self):
108         """Return list of items forming sublist."""
109
110     def OnDoubleClick(self):
111         """Called on a double-click on the item."""
112
113 class Delegate(object):
114     def __init__(self, delegate=None):
115         self.object = delegate
116         self.__cache = {}
117
118     def setdelegate(self, delegate):
119         self.resetcache()
120         self.object = delegate
121
122     def getdelegate(self):
123         return self.object
124
125     def __getattr__(self, name):
126         attr = getattr(self.object, name) # May raise AttributeError
127         setattr(self, name, attr)
128         self.__cache[name] = attr
129         return attr
130
131     def resetcache(self):
132         for key in list(self.__cache.keys()):
133             try:
134                 delattr(self, key)
135             except AttributeError:
136                 pass
137         self.__cache.clear()
138
139     def cachereport(self):
140         keys = list(self.__cache.keys())
141         keys.sort()
142         #print keys
143
144
145 class ObjectTreeItem(TreeItem,Delegate):
146     def __init__(self, appli, labeltext, object, setfunction=None):
147         self.labeltext = labeltext
148         self.appli = appli
149         # L'objet delegue est stocke dans l'attribut object
150         # L'objet associe a l'item est stocke dans l'attribut _object
151         # Il peut etre obtenu par appel a la methode getObject
152         # Attention : le delegue peut etre different de l'objet associe (MCLIST)
153         # Dans le cas d'une MCListe de longueur 1, l'objet associe est la MCListe
154         # et l'objet delegue est le MCFACT (object = _object.data[0])
155         Delegate.__init__(self,object)
156         # On cache l'objet initial (pour destruction eventuelle
157         # ulterieure)
158         self._object = object
159         self.setfunction = setfunction
160         self.expandable = 1
161         self.sublist=[]
162         self.init()
163
164     def init(self):
165         return
166
167     def getObject(self):
168         return self._object
169
170     def connect(self,channel,callable,args):
171         """ Connecte la fonction callable (avec arguments args) a l'item self sur le 
172             canal channel
173         """
174         #print self,channel,callable,args
175         CONNECTOR.Connect(self._object,channel,callable,args)
176         CONNECTOR.Connect(self.object, channel,callable,args)
177
178     def copy(self):
179         """
180         Cree un item copie de self
181         """
182         object = self._object.copy()
183         appli = copy(self.appli)
184         labeltext = copy(self.labeltext)
185         fonction = deepcopy(self.setfunction)
186         item = make_objecttreeitem(appli,labeltext,object,fonction)
187         return item
188     
189     def isactif(self):
190         if hasattr(self.object,'actif'):
191             return self.object.actif
192         else:
193             return 1
194     
195     def update(self,item):
196         """
197           Met a jour l'item courant a partir d'un autre item passe en argument
198           Ne fait rien par defaut
199         """
200         pass
201
202     def GetLabelText(self):
203         """ Retourne 3 valeurs :
204         - le texte a afficher dans le noeud representant l'item
205         - la fonte dans laquelle afficher ce texte
206         - la couleur du texte
207         """
208         # None --> fonte et couleur par defaut
209         return self.labeltext,None,None
210
211     def get_nature(self) :
212         """ 
213             Retourne la nature de l'item et de l'objet
214         """ 
215         return self.object.nature
216
217     def get_regles(self):
218         """ retourne les regles de l'objet pointe par self """
219         return self.object.get_regles()
220     
221     def get_liste_mc_presents(self):
222         """ Retourne la liste des mots-cles fils de l'objet pointe par self """
223         return self.object.liste_mc_presents()
224     
225     def get_val(self):
226         """ Retourne le nom de la valeur de l'objet pointe par self dans le cas
227             ou celle-ci est un objet (ASSD) """
228         return self.object.getval()
229     
230     def get_definition(self):
231         """ 
232            Retourne l'objet definition de l'objet pointe par self 
233         """
234         return self.object.definition
235
236     def get_liste_mc_ordonnee(self,liste,dico):
237         """ retourne la liste ordonnee (suivant le catalogue) brute des mots-cles
238             d'une entite composee dont le chemin complet est donne sous forme
239             d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
240             il faut encore rearranger cette liste (certains mots-cles deja
241             presents ne doivent plus etre proposes, regles ...)"""
242         return self.object.get_liste_mc_ordonnee(liste,dico)
243
244     def get_liste_mc_ordonnee_brute(self,liste,dico):
245         """
246         retourne la liste ordonnee (suivant le catalogue) BRUTE des mots-cles
247         d'une entite composee dont le chemin complet est donne sous forme
248         d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
249         """
250         return self.object.get_liste_mc_ordonnee_brute(liste,dico)
251    
252     def get_genealogie(self):
253         """
254         Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE)
255         de l'objet pointe par self
256         """
257         return self.object.get_genealogie()
258
259     def get_index_child(self,nom_fils):
260         """
261         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
262         Necessaire pour savoir a quelle position dans la liste des fils il faut ajouter
263         le nouveau mot-cle
264         """
265         return self.object.get_index_child(nom_fils)
266
267     def get_index_child_old(self,nom_fils):
268         """
269         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
270         Necessaire pour savoir a quelle position dans la liste des fils il faut ajouter
271         le nouveau mot-cle
272         """
273         liste_noms_mc_ordonnee = self.get_liste_mc_ordonnee_brute(self.get_genealogie(),self.get_jdc().cata_ordonne_dico)
274         liste_noms_mc_presents = self.object.liste_mc_presents()
275         l=[]
276         for nom in liste_noms_mc_ordonnee:
277             if nom in liste_noms_mc_presents or nom == nom_fils:
278                 l.append(nom)
279         # l contient les anciens mots-cles + le nouveau dans l'ordre
280         return l.index(nom_fils)
281         
282     def append_child(self,name,pos=None):
283         """
284           Permet d'ajouter un item fils a self
285         """
286         if pos == 'first':
287             index = 0
288         elif pos == 'last':
289             index = len(self.liste_mc_presents())
290         elif type(pos) == int :
291             # la position est fixee 
292             index = pos
293         elif type(pos) == types.InstanceType:
294             # pos est un item. Il faut inserer name apres pos
295             index = self.get_index(pos) +1
296         elif type(name) == types.InstanceType:
297             index = self.get_index_child(name.nom)
298         else:
299             index = self.get_index_child(name)
300         return self.addobject(name,index)
301
302     def append_brother(self,name,pos='after'):
303         """
304         Permet d'ajouter un frere a self
305         par defaut on l'ajoute apres self
306         """
307         index = self._object.parent.get_index(self.getObject())
308         if pos == 'before':
309             index = index
310         elif pos == 'after':
311             index = index +1
312         else:
313             print((tr("%d n'est pas un index valide pour append_brother", pos)))
314             return
315         return self.parent.addobject(name,index)
316
317     def get_nom_etape(self):
318         """Retourne le nom de self """
319         return self.object.get_nom_etape()
320
321     def get_copie_objet(self):
322         """ Retourne une copie de l'objet pointe par self """
323         return self.object.copy()
324     
325     def get_position(self):
326         """ Retourne la valeur de l'attribut position de l'objet pointe par self """
327         definition = self.get_definition()
328         try:
329             return getattr(definition,'position')
330         except AttributeError:
331             return 'local'
332         
333     def get_nom(self):
334         """ Retourne le nom de l'objet pointe par self """
335         return self.object.nom
336
337     def get_jdc(self):
338         """ Retourne le jdc auquel appartient l'objet pointe par self """
339         return self.object.jdc
340     
341     def get_valeur(self):
342         """ Retourne la valeur de l'objet pointe par self """
343         return self.object.valeur
344
345     def get_cr(self):
346         """ Retourne le compte-rendu CR de self """
347         return self.object.report()
348
349     def get_objet_commentarise(self):
350         """
351         Cette methode retourne un objet commentarise
352         representatif de self.object
353         --> a surcharger par les differents items
354         """
355         raise EficasException("MESSAGE AU DEVELOPPEUR : il faut \
356                                  surcharger la methode get_objet_commentarise() \
357                                  pour la classe %s", self.__class__.__name__)
358         
359     def isvalid(self):
360         """ Retourne 1 si l'objet pointe par self est valide, 0 sinon"""
361         return self.object.isvalid()
362
363     def iscopiable(self):
364         """
365         Retourne 1 si l'objet est copiable, 0 sinon
366         Par defaut retourne 0
367         """
368         return 0
369     
370     def get_mc_presents(self):
371         """ Retourne le dictionnaire des mots-cles presents de l'objet pointe par self """
372         return self.object.dict_mc_presents()
373
374     def verif_condition_regles(self,l_mc_presents):
375         return self.object.verif_condition_regles(l_mc_presents)
376
377     def get_fr(self):
378         """ Retourne le fr de l'objet pointe par self """
379         try:
380             return self.object.get_fr()
381         except:
382             return ""
383
384     def get_docu(self):
385         """ Retourne la cle de doc de l'objet pointe par self """
386         return self.object.get_docu()
387
388     def set_valeur(self,new_valeur):
389         """ Remplace la valeur de l'objet pointe par self par new_valeur """
390         return self.object.set_valeur(new_valeur)
391         
392     def GetText(self):
393         return myrepr.repr(self.object)
394     
395     def GetIconName(self):
396         if not self.IsExpandable():
397             return "python"
398
399     def IsEditable(self):
400         return self.setfunction is not None
401
402     def SetText(self, text):
403         try:
404             value = eval(text)
405             self.setfunction(value)
406         except:
407             pass
408 # Modif de ma part CCar : je ne comprend pas a quoi ca sert
409 # ca parait meme incorrect
410       #  else:
411       #      self.object = value
412
413     def IsExpandable(self):
414         return 1
415         
416     def GetSubList(self):
417         keys = dir(self.object)
418         sublist = []
419         for key in keys:
420             try:
421                 value = getattr(self.object, key)
422             except AttributeError:
423                 continue
424             item = make_objecttreeitem(
425                 self.appli,
426                 str(key) + " =",
427                 value,
428                 lambda value, key=key, object=self.object:
429                     setattr(object, key, value))
430             sublist.append(item)
431         return sublist
432
433     def wait_fichier_init(self):
434         """ Retourne 1 si l'object pointe par self attend un fichier d'initialisation
435         (ex: macros POURSUITE et INCLUDE de Code_Aster), 0 SINON """
436         return self.object.definition.fichier_ini
437
438     def make_objecttreeitem(self,appli,labeltext, object, setfunction=None):
439         """
440            Cette methode, globale pour les objets de type item, permet de construire et de retourner un objet
441            de type item associe a l'object passe en argument.
442         """
443         return make_objecttreeitem(appli,labeltext,object,setfunction)
444
445     #def __del__(self):
446     #    print "__del__",self
447
448 class AtomicObjectTreeItem(ObjectTreeItem):
449     def IsExpandable(self):
450         return 0
451
452 class SequenceTreeItem(ObjectTreeItem):
453     def IsExpandable(self):
454         return len(self._object) > 0
455
456     def __len__(self) :
457         return len(self._object)
458    
459     def keys(self):
460         return list(range(len(self._object)))
461
462     def GetIconName(self):
463         if self._object.isvalid():
464           return "ast-green-los"
465         elif self._object.isoblig():
466           return "ast-red-los"
467         else:
468           return "ast-yel-los"
469
470     def ajout_possible(self):
471         return self._object.ajout_possible()
472
473     def get_index(self,child):
474         """ Retourne le numero de child dans la liste des enfants de self """
475         return self._object.get_index(child.getObject())
476
477     def GetText(self):
478       return  "    "
479
480     def additem(self,obj,pos):
481         self._object.insert(pos,obj)
482         item = self.make_objecttreeitem(self.appli, obj.nom + ":", obj)
483         return item
484
485     def suppitem(self,item):
486         try :
487             self._object.remove(item.getObject())
488             # la liste peut etre retournee vide !
489             message = "Mot-clef " + item.getObject().nom + " supprime"
490             self.appli.affiche_infos(message)
491             return 1
492         except:
493             return 0
494
495     def GetSubList(self):
496         isublist=iter(self.sublist)
497         liste=self._object.data
498         iliste=iter(liste)
499         self.sublist=[]
500
501         while(1):
502            old_obj=obj=None
503            for item in isublist:
504               old_obj=item.getObject()
505               if old_obj in liste:break
506
507            for obj in iliste:
508               if obj is old_obj:break
509               # nouvel objet : on cree un nouvel item
510               def setfunction(value, object=obj):
511                   object=value
512               it = self.make_objecttreeitem(self.appli, obj.nom + " : ", obj, setfunction)
513               self.sublist.append(it)
514            if old_obj is None and obj is None:break
515            if old_obj is obj: self.sublist.append(item)
516         return self.sublist