Salome HOME
report modif variees + patch CEA
[tools/eficas.git] / Editeur / Objecttreeitem.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2017   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 object
28 except :
29    pass
30 import types,os,glob,imp,sys
31 from copy import copy,deepcopy
32
33 # import du chargeur de composants
34 from .comploader import makeObjecttreeitem
35 from Ihm import CONNECTOR
36 from Extensions.i18n import tr
37 from Extensions.eficas_exception import EficasException
38
39 try :
40    from repr import Repr
41 except :
42    from reprlib import Repr
43 myrepr = Repr()
44 myrepr.maxstring = 100
45 myrepr.maxother = 100
46
47 class TreeItem(object):
48
49     """Abstract class representing tree items.
50
51     Methods should typically be overridden, otherwise a default action
52     is used.
53
54     """
55     # itemNode est une factory qui doit retourner un objet de la classe Node
56     # ou derive de cette classe.
57     # Le widget arbre utilisera cet objet comme noeud associe au tree item.
58     # Par defaut, utilise la classe Node de base
59     # La signature de la factory est la suivante :
60     # itemNode(treeOrNode,item,command,rmenu)
61     # ou treeOrNode est le noeud parent, item est l'item associe
62     # command est une fonction python appelee sur selection graphique
63     # du noeud et rmenu est une fonction python appelee sur click droit sur le noeud
64     itemNode=None
65
66     def __init__(self):
67         """Constructor.  Do whatever you need to do."""
68
69     def getText(self):
70         """Return text string to display."""
71
72     def getLabelText(self):
73         """Return label text string to display in front of text (if any)."""
74
75     expandable = None
76
77     def _isExpandable(self):
78         """Do not override!  Called by TreeNode."""
79         if self.expandable is None:
80             self.expandable = self.isExpandable()
81         return self.expandable
82
83     def isExpandable(self):
84         """Return whether there are subitems."""
85         return 1
86
87     def _getSubList(self):
88         """Do not override!  Called by TreeNode."""
89         if not self.isExpandable():
90             return []
91         sublist = self.getSubList()
92         if not sublist:
93             self.expandable = 0
94         return sublist
95
96     def IsEditable(self):
97         """Return whether the item's text may be edited."""
98
99     def SetText(self, text):
100         """Change the item's text (if it is editable)."""
101
102     def getIconName(self):
103         """Return name of icon to be displayed normally."""
104
105     def getSelectedIconName(self):
106         """Return name of icon to be displayed when selected."""
107
108     def getSubList(self):
109         """Return list of items forming sublist."""
110
111     def onDoubleClick(self):
112         """Called on a double-click on the item."""
113
114 class Delegate(object):
115     def __init__(self, delegate=None):
116         self.object = delegate
117         self.__cache = {}
118
119     def setDelegate(self, delegate):
120         self.resetcache()
121         self.object = delegate
122
123     def getDelegate(self):
124         return self.object
125
126     def __getattr__(self, name):
127         attr = getattr(self.object, name) # May raise AttributeError
128         setattr(self, name, attr)
129         self.__cache[name] = attr
130         return attr
131
132     def resetcache(self):
133         for key in list(self.__cache.keys()):
134             try:
135                 delattr(self, key)
136             except AttributeError:
137                 pass
138         self.__cache.clear()
139
140     def cachereport(self):
141         keys = list(self.__cache.keys())
142         keys.sort()
143         #print keys
144
145
146 class ObjectTreeItem(TreeItem,Delegate):
147     def __init__(self, appliEficas, labeltext, object, setFunction=None):
148         self.labeltext = labeltext
149         self.appliEficas = appliEficas
150         # L'objet delegue est stocke dans l'attribut object
151         # L'objet associe a l'item est stocke dans l'attribut _object
152         # Il peut etre obtenu par appel a la methode getObject
153         # Attention : le delegue peut etre different de l'objet associe (MCLIST)
154         # Dans le cas d'une MCListe de longueur 1, l'objet associe est la MCListe
155         # et l'objet delegue est le MCFACT (object = _object.data[0])
156         Delegate.__init__(self,object)
157         # On cache l'objet initial (pour destruction eventuelle
158         # ulterieure)
159         self._object = object
160         self.setFunction = setFunction
161         self.expandable = 1
162         self.sublist=[]
163         self.init()
164
165     def init(self):
166         return
167
168     def getObject(self):
169         return self._object
170
171     def connect(self,channel,callable,args):
172         """ Connecte la fonction callable (avec arguments args) a l'item self sur le 
173             canal channel
174         """
175         #print self,channel,callable,args
176         CONNECTOR.Connect(self._object,channel,callable,args)
177         CONNECTOR.Connect(self.object, channel,callable,args)
178
179     def copy(self):
180         """
181         Cree un item copie de self
182         """
183         object = self._object.copy()
184         appliEficas = copy(self.appliEficas)
185         labeltext = copy(self.labeltext)
186         fonction = deepcopy(self.setFunction)
187         item = makeObjecttreeitem(appliEficas,labeltext,object,fonction)
188         return item
189     
190     def isActif(self):
191         if hasattr(self.object,'actif'):
192             return self.object.actif
193         else:
194             return 1
195     
196     def update(self,item):
197         """
198           Met a jour l'item courant a partir d'un autre item passe en argument
199           Ne fait rien par defaut
200         """
201         pass
202
203     def getLabelText(self):
204         """ Retourne 3 valeurs :
205         - le texte a afficher dans le noeud representant l'item
206         - la fonte dans laquelle afficher ce texte
207         - la couleur du texte
208         """
209         # None --> fonte et couleur par defaut
210         return tr(self.labeltext),None,None
211
212     def getNature(self) :
213         """ 
214             Retourne la nature de l'item et de l'objet
215         """ 
216         return self.object.nature
217
218     def getRegles(self):
219         """ retourne les regles de l'objet pointe par self """
220         return self.object.getRegles()
221     
222     def getListeMcPresents(self):
223         """ Retourne la liste des mots-cles fils de l'objet pointe par self """
224         return self.object.listeMcPresents()
225     
226     def getVal(self):
227         """ Retourne le nom de la valeur de l'objet pointe par self dans le cas
228             ou celle-ci est un objet (ASSD) """
229         return self.object.getVal()
230     
231     def get_definition(self):
232         """ 
233            Retourne l'objet definition de l'objet pointe par self 
234         """
235         return self.object.definition
236
237     def getListeMcOrdonnee(self,liste,dico):
238         """ retourne la liste ordonnee (suivant le catalogue) brute des mots-cles
239             d'une entite composee dont le chemin complet est donne sous forme
240             d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
241             il faut encore rearranger cette liste (certains mots-cles deja
242             presents ne doivent plus etre proposes, regles ...)"""
243         return self.object.getListeMcOrdonnee(liste,dico)
244
245     def getListeMcOrdonneeBrute(self,liste,dico):
246         """
247         retourne la liste ordonnee (suivant le catalogue) BRUTE des mots-cles
248         d'une entite composee dont le chemin complet est donne sous forme
249         d'une liste du type :ETAPE + MCFACT ou MCBLOC + ...
250         """
251         return self.object.getListeMcOrdonneeBrute(liste,dico)
252    
253     def getGenealogie(self):
254         """
255         Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE)
256         de l'objet pointe par self
257         """
258         return self.object.getGenealogie()
259
260     def getIndexChild(self,nom_fils):
261         """
262         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
263         Necessaire pour savoir a quelle position dans la liste des fils il faut ajouter
264         le nouveau mot-cle
265         """
266         return self.object.getIndexChild(nom_fils)
267
268     def getIndexChild_old(self,nom_fils):
269         """
270         Retourne l'index dans la liste des fils de self du nouveau fils de nom nom_fils
271         Necessaire pour savoir a quelle position dans la liste des fils il faut ajouter
272         le nouveau mot-cle
273         """
274         liste_noms_mc_ordonnee = self.getListeMcOrdonneeBrute(self.getGenealogie(),self.getJdc().cata_ordonne_dico)
275         liste_noms_mc_presents = self.object.listeMcPresents()
276         l=[]
277         for nom in liste_noms_mc_ordonnee:
278             if nom in liste_noms_mc_presents or nom == nom_fils:
279                 l.append(nom)
280         # l contient les anciens mots-cles + le nouveau dans l'ordre
281         return l.index(nom_fils)
282         
283     def appendChild(self,name,pos=None):
284         """
285           Permet d'ajouter un item fils a self
286         """
287         if pos == 'first':
288             index = 0
289         elif pos == 'last':
290             index = len(self.listeMcPresents())
291         elif type(pos) == int :
292             # la position est fixee 
293             index = pos
294         #elif type(pos) == types.InstanceType:
295         elif type(pos) == object :
296             # pos est un item. Il faut inserer name apres pos
297             index = self.getIndex(pos) +1
298         #elif type(name) == types.InstanceType:
299         elif type(name) == object :
300             index = self.getIndexChild(name.nom)
301         else:
302             index = self.getIndexChild(name)
303         return self.addobject(name,index)
304
305     def appendBrother(self,name,pos='after'):
306         """
307         Permet d'ajouter un frere a self
308         par defaut on l'ajoute apres self
309         """
310         index = self._object.parent.getIndex(self.getObject())
311         if pos == 'before':
312             index = index
313         elif pos == 'after':
314             index = index +1
315         else:
316             print((tr("%d n'est pas un index valide pour appendBrother", pos)))
317             return
318         return self.parent.addobject(name,index)
319
320     def getCopieObjet(self):
321         """ Retourne une copie de l'objet pointe par self """
322         return self.object.copy()
323     
324     def getPosition(self):
325         """ Retourne la valeur de l'attribut position de l'objet pointe par self """
326         definition = self.get_definition()
327         try:
328             return getattr(definition,'position')
329         except AttributeError:
330             return 'local'
331         
332     def getNom(self):
333         """ Retourne le nom de l'objet pointe par self """
334         return self.object.nom
335
336     def getJdc(self):
337         """ Retourne le jdc auquel appartient l'objet pointe par self """
338         return self.object.jdc
339     
340     def getValeur(self):
341         """ Retourne la valeur de l'objet pointe par self """
342         return self.object.valeur
343
344     def getCr(self):
345         """ Retourne le compte-rendu CR de self """
346         return self.object.report()
347
348     def getObjetCommentarise(self):
349         """
350         Cette methode retourne un objet commentarise
351         representatif de self.object
352         --> a surcharger par les differents items
353         """
354         raise EficasException("MESSAGE AU DEVELOPPEUR : il faut \
355                                  surcharger la methode getObjetCommentarise() \
356                                  pour la classe %s", self.__class__.__name__)
357         
358     def isValid(self):
359         """ Retourne 1 si l'objet pointe par self est valide, 0 sinon"""
360         return self.object.isValid()
361
362     def isCopiable(self):
363         """
364         Retourne 1 si l'objet est copiable, 0 sinon
365         Par defaut retourne 0
366         """
367         return 0
368     
369     def getMcPresents(self):
370         """ Retourne le dictionnaire des mots-cles presents de l'objet pointe par self """
371         return self.object.dictMcPresents()
372
373     def verifConditionRegles(self,l_mc_presents):
374         return self.object.verifConditionRegles(l_mc_presents)
375
376     def getFr(self):
377         """ Retourne le fr de l'objet pointe par self """
378         try:
379             return self.object.getFr()
380         except:
381             return ""
382
383     def getDocu(self):
384         """ Retourne la cle de doc de l'objet pointe par self """
385         return self.object.getDocu()
386
387     def setValeur(self,new_valeur):
388         """ Remplace la valeur de l'objet pointe par self par new_valeur """
389         return self.object.setValeur(new_valeur)
390         
391     def getText(self):
392         return myrepr.repr(self.object)
393     
394     def getIconName(self):
395         if not self.isExpandable():
396             return "python"
397
398     def IsEditable(self):
399         return self.setFunction is not None
400
401     def SetText(self, text):
402         try:
403             value = eval(text)
404             self.setFunction(value)
405         except:
406             pass
407
408     def isExpandable(self):
409         return 1
410         
411     def getSubList(self):
412         keys = dir(self.object)
413         sublist = []
414         for key in keys:
415             try:
416                 value = getattr(self.object, key)
417             except AttributeError:
418                 continue
419             item = makeObjecttreeitem(
420                 self.appliEficas,
421                 str(key) + " =",
422                 value,
423                 lambda value, key=key, object=self.object:
424                     setattr(object, key, value))
425             sublist.append(item)
426         return sublist
427
428     # a piori inutile PN 06 11 17
429     #def wait_fichier_init(self):
430         """ Retourne 1 si l'object pointe par self attend un fichier d'initialisation
431         (ex: macros POURSUITE et INCLUDE de Code_Aster), 0 SINON """
432     #    return self.object.definition.fichier_ini
433
434     def makeObjecttreeitem(self,appliEficas,labeltext, object, setFunction=None):
435         """
436            Cette methode, globale pour les objets de type item, permet de construire et de retourner un objet
437            de type item associe a l'object passe en argument.
438         """
439         return makeObjecttreeitem(appliEficas,labeltext,object,setFunction)
440
441     #def __del__(self):
442     #    print "__del__",self
443
444 class AtomicObjectTreeItem(ObjectTreeItem):
445     def isExpandable(self):
446         return 0
447
448 class SequenceTreeItem(ObjectTreeItem):
449     def isExpandable(self):
450         return len(self._object) > 0
451
452     def __len__(self) :
453         return len(self._object)
454    
455     def keys(self):
456         return list(range(len(self._object)))
457
458     def getIconName(self):
459         if self._object.isValid():
460           return "ast-green-los"
461         elif self._object.isOblig():
462           return "ast-red-los"
463         else:
464           return "ast-yel-los"
465
466     def ajoutPossible(self):
467         return self._object.ajoutPossible()
468
469     def getIndex(self,child):
470         """ Retourne le numero de child dans la liste des enfants de self """
471         return self._object.getIndex(child.getObject())
472
473     def getText(self):
474       return  "    "
475
476     def addItem(self,obj,pos):
477         self._object.insert(pos,obj)
478         item = self.makeObjecttreeitem(self.appliEficas, obj.nom + ":", obj)
479         return item
480
481     def suppItem(self,item):
482         try :
483             self._object.remove(item.getObject())
484             # la liste peut etre retournee vide !
485             message = "Mot-clef " + item.getObject().nom + " supprime"
486             self.appliEficas.afficheInfos(message)
487             return 1
488         except:
489             return 0
490
491     def getSubList(self):
492         isublist=iter(self.sublist)
493         liste=self._object.data
494         iliste=iter(liste)
495         self.sublist=[]
496
497         while(1):
498            old_obj=obj=None
499            for item in isublist:
500               old_obj=item.getObject()
501               if old_obj in liste:break
502
503            for obj in iliste:
504               if obj is old_obj:break
505               # nouvel objet : on cree un nouvel item
506               def setFunction(value, object=obj):
507                   object=value
508               it = self.makeObjecttreeitem(self.appliEficas, obj.nom + " : ", obj, setFunction)
509               self.sublist.append(it)
510            if old_obj is None and obj is None:break
511            if old_obj is obj: self.sublist.append(item)
512         return self.sublist