Salome HOME
Merge V9 dans Master
[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 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 makeObjecttreeitem
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 = makeObjecttreeitem(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 getNature(self) :
212         """ 
213             Retourne la nature de l'item et de l'objet
214         """ 
215         return self.object.nature
216
217     def getRegles(self):
218         """ retourne les regles de l'objet pointe par self """
219         return self.object.getRegles()
220     
221     def getListeMcPresents(self):
222         """ Retourne la liste des mots-cles fils de l'objet pointe par self """
223         return self.object.listeMcPresents()
224     
225     def getVal(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 getListeMcOrdonnee(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.getListeMcOrdonnee(liste,dico)
243
244     def getListeMcOrdonneeBrute(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.getListeMcOrdonneeBrute(liste,dico)
251    
252     def getGenealogie(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.getGenealogie()
258
259     def getIndexChild(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.getIndexChild(nom_fils)
266
267     def getIndexChild_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.getListeMcOrdonneeBrute(self.getGenealogie(),self.getJdc().cata_ordonne_dico)
274         liste_noms_mc_presents = self.object.listeMcPresents()
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 appendChild(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.listeMcPresents())
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.getIndex(pos) +1
296         elif type(name) == types.InstanceType:
297             index = self.getIndexChild(name.nom)
298         else:
299             index = self.getIndexChild(name)
300         return self.addobject(name,index)
301
302     def appendBrother(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.getIndex(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 appendBrother", pos)))
314             return
315         return self.parent.addobject(name,index)
316
317     def getCopieObjet(self):
318         """ Retourne une copie de l'objet pointe par self """
319         return self.object.copy()
320     
321     def getPosition(self):
322         """ Retourne la valeur de l'attribut position de l'objet pointe par self """
323         definition = self.get_definition()
324         try:
325             return getattr(definition,'position')
326         except AttributeError:
327             return 'local'
328         
329     def getNom(self):
330         """ Retourne le nom de l'objet pointe par self """
331         return self.object.nom
332
333     def getJdc(self):
334         """ Retourne le jdc auquel appartient l'objet pointe par self """
335         return self.object.jdc
336     
337     def getValeur(self):
338         """ Retourne la valeur de l'objet pointe par self """
339         return self.object.valeur
340
341     def getCr(self):
342         """ Retourne le compte-rendu CR de self """
343         return self.object.report()
344
345     def getObjetCommentarise(self):
346         """
347         Cette methode retourne un objet commentarise
348         representatif de self.object
349         --> a surcharger par les differents items
350         """
351         raise EficasException("MESSAGE AU DEVELOPPEUR : il faut \
352                                  surcharger la methode getObjetCommentarise() \
353                                  pour la classe %s", self.__class__.__name__)
354         
355     def isValid(self):
356         """ Retourne 1 si l'objet pointe par self est valide, 0 sinon"""
357         return self.object.isValid()
358
359     def isCopiable(self):
360         """
361         Retourne 1 si l'objet est copiable, 0 sinon
362         Par defaut retourne 0
363         """
364         return 0
365     
366     def getMcPresents(self):
367         """ Retourne le dictionnaire des mots-cles presents de l'objet pointe par self """
368         return self.object.dictMcPresents()
369
370     def verifConditionRegles(self,l_mc_presents):
371         return self.object.verifConditionRegles(l_mc_presents)
372
373     def getFr(self):
374         """ Retourne le fr de l'objet pointe par self """
375         try:
376             return self.object.getFr()
377         except:
378             return ""
379
380     def getDocu(self):
381         """ Retourne la cle de doc de l'objet pointe par self """
382         return self.object.getDocu()
383
384     def setValeur(self,new_valeur):
385         """ Remplace la valeur de l'objet pointe par self par new_valeur """
386         return self.object.setValeur(new_valeur)
387         
388     def getText(self):
389         return myrepr.repr(self.object)
390     
391     def getIconName(self):
392         if not self.isExpandable():
393             return "python"
394
395     def IsEditable(self):
396         return self.setFunction is not None
397
398     def SetText(self, text):
399         try:
400             value = eval(text)
401             self.setFunction(value)
402         except:
403             pass
404 # Modif de ma part CCar : je ne comprend pas a quoi ca sert
405 # ca parait meme incorrect
406       #  else:
407       #      self.object = value
408
409     def isExpandable(self):
410         return 1
411         
412     def getSubList(self):
413         keys = dir(self.object)
414         sublist = []
415         for key in keys:
416             try:
417                 value = getattr(self.object, key)
418             except AttributeError:
419                 continue
420             item = makeObjecttreeitem(
421                 self.appli,
422                 str(key) + " =",
423                 value,
424                 lambda value, key=key, object=self.object:
425                     setattr(object, key, value))
426             sublist.append(item)
427         return sublist
428
429     # a piori inutile PN 06 11 17
430     #def wait_fichier_init(self):
431         """ Retourne 1 si l'object pointe par self attend un fichier d'initialisation
432         (ex: macros POURSUITE et INCLUDE de Code_Aster), 0 SINON """
433     #    return self.object.definition.fichier_ini
434
435     def makeObjecttreeitem(self,appli,labeltext, object, setFunction=None):
436         """
437            Cette methode, globale pour les objets de type item, permet de construire et de retourner un objet
438            de type item associe a l'object passe en argument.
439         """
440         return makeObjecttreeitem(appli,labeltext,object,setFunction)
441
442     #def __del__(self):
443     #    print "__del__",self
444
445 class AtomicObjectTreeItem(ObjectTreeItem):
446     def isExpandable(self):
447         return 0
448
449 class SequenceTreeItem(ObjectTreeItem):
450     def isExpandable(self):
451         return len(self._object) > 0
452
453     def __len__(self) :
454         return len(self._object)
455    
456     def keys(self):
457         return list(range(len(self._object)))
458
459     def getIconName(self):
460         if self._object.isValid():
461           return "ast-green-los"
462         elif self._object.isOblig():
463           return "ast-red-los"
464         else:
465           return "ast-yel-los"
466
467     def ajoutPossible(self):
468         return self._object.ajoutPossible()
469
470     def getIndex(self,child):
471         """ Retourne le numero de child dans la liste des enfants de self """
472         return self._object.getIndex(child.getObject())
473
474     def getText(self):
475       return  "    "
476
477     def addItem(self,obj,pos):
478         self._object.insert(pos,obj)
479         item = self.makeObjecttreeitem(self.appli, obj.nom + ":", obj)
480         return item
481
482     def suppItem(self,item):
483         try :
484             self._object.remove(item.getObject())
485             # la liste peut etre retournee vide !
486             message = "Mot-clef " + item.getObject().nom + " supprime"
487             self.appli.afficheInfos(message)
488             return 1
489         except:
490             return 0
491
492     def getSubList(self):
493         isublist=iter(self.sublist)
494         liste=self._object.data
495         iliste=iter(liste)
496         self.sublist=[]
497
498         while(1):
499            old_obj=obj=None
500            for item in isublist:
501               old_obj=item.getObject()
502               if old_obj in liste:break
503
504            for obj in iliste:
505               if obj is old_obj:break
506               # nouvel objet : on cree un nouvel item
507               def setFunction(value, object=obj):
508                   object=value
509               it = self.makeObjecttreeitem(self.appli, obj.nom + " : ", obj, setFunction)
510               self.sublist.append(it)
511            if old_obj is None and obj is None:break
512            if old_obj is obj: self.sublist.append(item)
513         return self.sublist