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