1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2021 EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 from __future__ import absolute_import
24 from __future__ import print_function
26 from builtins import str
27 from builtins import object
30 import types,os,glob,imp,sys
31 from copy import copy,deepcopy
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
42 from reprlib import Repr
44 myrepr.maxstring = 100
47 class TreeItem(object):
49 """Abstract class representing tree items.
51 Methods should typically be overridden, otherwise a default action
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
67 """Constructor. Do whatever you need to do."""
70 """Return text string to display."""
72 def getLabelText(self):
73 """Return label text string to display in front of text (if any)."""
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
83 def isExpandable(self):
84 """Return whether there are subitems."""
87 def _getSubList(self):
88 """Do not override! Called by TreeNode."""
89 if not self.isExpandable():
91 sublist = self.getSubList()
97 """Return whether the item's text may be edited."""
99 def SetText(self, text):
100 """Change the item's text (if it is editable)."""
102 def getIconName(self):
103 """Return name of icon to be displayed normally."""
105 def getSelectedIconName(self):
106 """Return name of icon to be displayed when selected."""
108 def getSubList(self):
109 """Return list of items forming sublist."""
111 def onDoubleClick(self):
112 """Called on a double-click on the item."""
114 class Delegate(object):
115 def __init__(self, delegate=None):
116 self.object = delegate
119 def setDelegate(self, delegate):
121 self.object = delegate
123 def getDelegate(self):
126 def __getattr__(self, name):
127 attr = getattr(self.object, name) # May raise AttributeError
128 setattr(self, name, attr)
129 self.__cache[name] = attr
132 def resetcache(self):
133 for key in list(self.__cache.keys()):
136 except AttributeError:
140 def cachereport(self):
141 keys = list(self.__cache.keys())
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
159 self._object = object
160 self.setFunction = setFunction
171 def connect(self,channel,callable,args):
172 """ Connecte la fonction callable (avec arguments args) a l'item self sur le
175 #print self,channel,callable,args
176 CONNECTOR.Connect(self._object,channel,callable,args)
177 CONNECTOR.Connect(self.object, channel,callable,args)
181 Cree un item copie de self
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)
191 if hasattr(self.object,'actif'):
192 return self.object.actif
196 def update(self,item):
198 Met a jour l'item courant a partir d'un autre item passe en argument
199 Ne fait rien par defaut
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
209 # None --> fonte et couleur par defaut
210 return tr(self.labeltext),None,None
212 def getNature(self) :
214 Retourne la nature de l'item et de l'objet
216 return self.object.nature
219 """ retourne les regles de l'objet pointe par self """
220 return self.object.getRegles()
222 def getListeMcPresents(self):
223 """ Retourne la liste des mots-cles fils de l'objet pointe par self """
224 return self.object.listeMcPresents()
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()
231 def get_definition(self):
233 Retourne l'objet definition de l'objet pointe par self
235 return self.object.definition
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)
245 def getListeMcOrdonneeBrute(self,liste,dico):
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 + ...
251 return self.object.getListeMcOrdonneeBrute(liste,dico)
253 def getGenealogie(self):
255 Retourne la liste des noms des ascendants (noms de MCSIMP,MCFACT,MCBLOC ou ETAPE)
256 de l'objet pointe par self
258 return self.object.getGenealogie()
260 def getIndexChild(self,nom_fils):
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
266 return self.object.getIndexChild(nom_fils)
268 def getIndexChild_old(self,nom_fils):
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
274 liste_noms_mc_ordonnee = self.getListeMcOrdonneeBrute(self.getGenealogie(),self.getJdc().cata_ordonne_dico)
275 liste_noms_mc_presents = self.object.listeMcPresents()
277 for nom in liste_noms_mc_ordonnee:
278 if nom in liste_noms_mc_presents or nom == nom_fils:
280 # l contient les anciens mots-cles + le nouveau dans l'ordre
281 return l.index(nom_fils)
283 def appendChild(self,name,pos=None):
285 Permet d'ajouter un item fils a self
290 index = len(self.listeMcPresents())
291 elif type(pos) == int :
292 # la position est fixee
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)
302 index = self.getIndexChild(name)
303 return self.addobject(name,index)
305 def appendBrother(self,name,pos='after'):
307 Permet d'ajouter un frere a self
308 par defaut on l'ajoute apres self
310 index = self._object.parent.getIndex(self.getObject())
316 print((tr("%d n'est pas un index valide pour appendBrother", pos)))
318 return self.parent.addobject(name,index)
320 def getCopieObjet(self):
321 """ Retourne une copie de l'objet pointe par self """
322 return self.object.copy()
324 def getPosition(self):
325 """ Retourne la valeur de l'attribut position de l'objet pointe par self """
326 definition = self.get_definition()
328 return getattr(definition,'position')
329 except AttributeError:
333 """ Retourne le nom de l'objet pointe par self """
334 return self.object.nom
337 """ Retourne le jdc auquel appartient l'objet pointe par self """
338 return self.object.jdc
341 """ Retourne la valeur de l'objet pointe par self """
342 return self.object.valeur
345 """ Retourne le compte-rendu CR de self """
346 return self.object.report()
348 def getObjetCommentarise(self):
350 Cette methode retourne un objet commentarise
351 representatif de self.object
352 --> a surcharger par les differents items
354 raise EficasException("MESSAGE AU DEVELOPPEUR : il faut \
355 surcharger la methode getObjetCommentarise() \
356 pour la classe %s", self.__class__.__name__)
359 """ Retourne 1 si l'objet pointe par self est valide, 0 sinon"""
360 return self.object.isValid()
362 def isCopiable(self):
364 Retourne 1 si l'objet est copiable, 0 sinon
365 Par defaut retourne 0
369 def getMcPresents(self):
370 """ Retourne le dictionnaire des mots-cles presents de l'objet pointe par self """
371 return self.object.dictMcPresents()
373 def verifConditionRegles(self,l_mc_presents):
374 return self.object.verifConditionRegles(l_mc_presents)
377 """ Retourne le fr de l'objet pointe par self """
379 return self.object.getFr()
384 """ Retourne la cle de doc de l'objet pointe par self """
385 return self.object.getDocu()
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)
392 return myrepr.repr(self.object)
394 def getIconName(self):
395 if not self.isExpandable():
398 def IsEditable(self):
399 return self.setFunction is not None
401 def SetText(self, text):
404 self.setFunction(value)
408 def isExpandable(self):
411 def getSubList(self):
412 keys = dir(self.object)
416 value = getattr(self.object, key)
417 except AttributeError:
419 item = makeObjecttreeitem(
423 lambda value, key=key, object=self.object:
424 setattr(object, key, value))
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
434 def makeObjecttreeitem(self,appliEficas,labeltext, object, setFunction=None):
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.
439 return makeObjecttreeitem(appliEficas,labeltext,object,setFunction)
442 # print "__del__",self
444 class AtomicObjectTreeItem(ObjectTreeItem):
445 def isExpandable(self):
448 class SequenceTreeItem(ObjectTreeItem):
449 def isExpandable(self):
450 return len(self._object) > 0
453 return len(self._object)
456 return list(range(len(self._object)))
458 def getIconName(self):
459 if self._object.isValid():
460 return "ast-green-los"
461 elif self._object.isOblig():
466 def ajoutPossible(self):
467 return self._object.ajoutPossible()
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())
476 def addItem(self,obj,pos):
477 self._object.insert(pos,obj)
478 item = self.makeObjecttreeitem(self.appliEficas, obj.nom + ":", obj)
481 def suppItem(self,item):
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)
491 def getSubList(self):
492 isublist=iter(self.sublist)
493 liste=self._object.data
499 for item in isublist:
500 old_obj=item.getObject()
501 if old_obj in liste:break
504 if obj is old_obj:break
505 # nouvel objet : on cree un nouvel item
506 def setFunction(value, object=obj):
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)