Salome HOME
PN : Choix automatique du concept lorsqu'un seul choix est possible.
[tools/eficas.git] / Editeur / catabrowser.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 # Modules Python
21 import os
22 import sys
23 import types
24 import string
25 import Pmw
26 from Tkinter import *
27
28 # Modules Eficas
29 import fontes
30 from treewidget import Tree
31 from Objecttreeitem import TreeItem
32 from Accas import AsException
33 from Noyau.N_CR import justify_text
34 from Accas import OPER,PROC,MACRO,FORM
35 from Accas import FACT,BLOC,SIMP
36
37 #
38 __version__="$Name:  $"
39 __Id__="$Id: catabrowser.py,v 1.2 2002/05/15 15:31:58 eficas Exp $"
40 #
41 class Tableau:
42   incr = 10
43   def __init__(self,parent,colonnes):
44     self.parent = parent
45     self.colonnes = colonnes
46     self.init()
47
48   def init(self):
49     # recherche du nombre maxi de lignes et de colonnes....
50     for col in self.colonnes :
51       nb_l = 0
52       if len(col) > nb_l : nb_l = len(col)
53     self.nb_lignes = nb_l
54     self.nb_colonnes = len(self.colonnes)
55     # initialisation des coordonnées dans le canvas
56     self.x0 = self.incr
57     self.y0 = self.incr
58     self.x = self.x0 + self.incr
59     self.y = self.y0 + self.incr
60
61   def affiche(self):    
62     self.scrolledcanvas=Pmw.ScrolledCanvas(self.parent,
63                                            hull_width=1.,
64                                            hull_height=1.,
65                                            borderframe=1)
66     Pmw.Color.changecolor(self.scrolledcanvas.component('canvas'),background='gray95')
67     self.scrolledcanvas.pack(padx=10,pady=10,expand=1, fill="both")
68     self.canvas = self.scrolledcanvas.component('canvas')
69     self.affiche_colonnes()
70
71   def affiche_colonnes(self):
72     for i in range(self.nb_lignes):
73       self.affiche_ligne(i)
74     self.aligne_colonnes()
75     self.trace_traits()
76     self.scrolledcanvas.resizescrollregion()
77
78   def get_xy_max(self):
79     try:
80       x0,y0,xmax,ymax = self.canvas.bbox(ALL)
81       return xmax,ymax
82     except:
83       return None,None
84     
85   def trace_traits(self):
86     xmax,ymax = self.get_xy_max()
87     if not xmax : return
88     xmax = xmax+self.incr
89     ymax = ymax+self.incr
90     # trace les traits horizontaux
91     for i in range(self.nb_lignes):
92       tag_lig = 'ligne_'+`i`
93       l_id = self.canvas.find_withtag(tag_lig)
94       x0,y0,x1,y1 = self.bbox(l_id)
95       self.canvas.create_line(x0-self.incr,y0-self.incr,xmax,y0-self.incr)
96     self.canvas.create_line(self.x0,ymax,xmax,ymax)  
97     # trace les traits verticaux
98     for j in range(self.nb_colonnes):
99       tag_col = 'colonne_'+`j`
100       l_id = self.canvas.find_withtag(tag_col)
101       x0,y0,x1,y1 = self.bbox(l_id)
102       self.canvas.create_line(x0-self.incr,y0-self.incr,x0-self.incr,ymax)
103     self.canvas.create_line(xmax,self.y0,xmax,ymax)
104     
105   def bbox(self,l_id):
106     x0,y0,x1,y1 = self.canvas.bbox(l_id[0])
107     for id in l_id[1:]:
108       x2,y2,x3,y3 = self.canvas.bbox(id)
109       x0 = min(x2,x0)
110       y0 = min(y2,y0)
111       x1 = max(x3,x1)
112       y1 = max(y3,y1)
113     return x0,y0,x1,y1
114   
115   def affiche_ligne(self,num_lig):
116     tag_lig = 'ligne_'+`num_lig`
117     num_col = 0
118     for col in self.colonnes:
119       tag_col = 'colonne_'+`num_col`
120       x = 100*num_col+self.x
121       id = self.canvas.create_text(x,self.y,
122                                    text = justify_text(col[num_lig],cesure=60),
123                                    tag=(tag_lig,tag_col),
124                                    anchor='nw',
125                                    font = fontes.canvas)
126       x0,y0,x1,y1 = self.canvas.bbox(id)
127       num_col = num_col+1
128     l_id = self.canvas.find_withtag(tag_lig)
129     x0,y0,x1,y1 = self.bbox(l_id)
130     self.y = y1 + 2*self.incr
131
132   def aligne_colonnes(self):
133     num_col = 0
134     for col in self.colonnes:
135       tag_col = 'colonne_'+`num_col`
136       l_id = self.canvas.find_withtag(tag_col)
137       if not l_id : continue
138       x0,y0,x1,y1 = self.bbox(l_id)
139       self.move(x1+self.incr,self.colonnes[num_col+1:],num_col+1)
140       num_col = num_col+1
141
142   def move(self,x,colonnes,num):
143     num_col = num
144     for col in colonnes:
145       tag_col = 'colonne_'+`num_col`
146       l_id = self.canvas.find_withtag(tag_col)
147       if not l_id : continue
148       x0,y0,x1,y1 = self.canvas.bbox(l_id[0])
149       self.canvas.move(tag_col,x+self.incr-x0,0)
150       num_col = num_col+1
151     
152 class CATAPanel(Frame) :
153   """ Classe servant à créer le panneau représentant l'objet sélectionné dans l'arbre"""
154   def __init__(self,parent,panneau,node) :
155     self.parent=parent
156     self.panneau = panneau
157     self.node=node
158     Frame.__init__(self,self.panneau)
159     self.place(x=0,y=0,relheight=1,relwidth=1)
160     self.init()
161
162   def init(self):
163     # création du label initial
164     label = Label(self,
165                   text = 'Attributs de '+self.node.item.labeltext,
166                   font = fontes.standard_gras_souligne)
167     label.pack(side='top',pady=10)
168     # création des listes correspondant aux colonnes du tableau à afficher
169     colonne1,colonne2 = self.get_listes()
170     # affichage du tableau
171     self.tableau = Tableau(self,(colonne1,colonne2))
172     self.tableau.affiche()
173
174   def get_listes(self):    
175     self.node.item.get_dico_attributs()
176     l_cles_attributs = self.node.item.d_attributs.keys()
177     l_cles_attributs.sort()
178     ind=0
179     liste1 = []
180     liste2=[]
181     for nom_attr in l_cles_attributs :
182       valeur = self.node.item.d_attributs[nom_attr]
183       if type(valeur) == types.TupleType:
184         texte =''
185         for elem in valeur:
186           if type(elem) == types.ClassType:
187             texte = texte + elem.__name__
188           else:
189             texte = texte + str(elem)
190       elif type(valeur) == types.ClassType :
191         texte = valeur.__name__
192       else:
193         texte = str(valeur)
194       liste1.append(nom_attr)
195       liste2.append(texte)
196     return liste1,liste2
197
198 class CATAItem(TreeItem):
199   panel = CATAPanel
200   def __init__(self,appli,labeltext,object,setfunction=None,objet_cata_ordonne = None):
201     self.appli = appli
202     self.labeltext = labeltext
203     self.object=object
204     self.setfunction = setfunction
205     self.objet_cata_ordonne = objet_cata_ordonne
206
207   def get_dico_fils(self):
208     d_fils = {}
209     if type(self.object) != types.TupleType:
210       for e in dir(self.object):
211         cmd = getattr(self.object,e)
212         if isCMD(cmd) :
213           d_fils[string.strip(cmd.nom)] = cmd
214     else:
215       for obj in self.object :
216         for e in dir(obj):
217           cmd = getattr(obj,e)
218           if isCMD(cmd) :
219             d_fils[string.strip(cmd.nom)] = cmd
220     self.d_fils = d_fils
221
222   def get_dico_attributs(self):
223     d_attributs ={}
224     if type(self.object) == types.TupleType :
225       self.d_attributs = d_attributs
226       return
227     l_noms_attributs = ['nom','op','sd_prod','reentrant','repetable','fr','docu','into','valide_vide','actif',
228                         'regles','op_init','niveau','definition','code','niveaux','statut',
229                         'defaut','min','max','homo','position','val_min','val_max','condition']
230     for nom_attribut in l_noms_attributs :
231       if hasattr(self.object,nom_attribut):
232         attr = getattr(self.object,nom_attribut)
233         d_attributs[nom_attribut] = attr
234     self.d_attributs = d_attributs
235
236   def get_liste_mc_ordonnee(self):
237     """ Retourne la liste ordonnée (suivant le catalogue) brute des fils
238     de l'entite courante """
239     if hasattr(self.objet_cata_ordonne,'ordre_mc'):
240       return self.objet_cata_ordonne.ordre_mc
241     else :
242       l=self.objet_cata_ordonne.keys()
243       l.sort()
244       return l
245       
246   def GetLabelText(self):
247     return self.labeltext,None,None
248
249   def get_fr(self):
250     return ''
251   
252   def isMCList(self):
253     return 0
254   
255   def GetSubList(self):
256     sublist=[]
257     if not hasattr(self,'d_fils'):
258       self.get_dico_fils()
259     # on classe les fils dans l'odre du catalogue ...
260     l_cles_fils = self.get_liste_mc_ordonnee()
261     for k in l_cles_fils :
262       if type(self.objet_cata_ordonne) == types.InstanceType :
263         objet_cata = self.objet_cata_ordonne.entites[k]
264       else :
265         objet_cata = self.objet_cata_ordonne.get(k,None)
266       item = make_objecttreeitem(self.appli,k + " : ",self.d_fils[k],
267                                  objet_cata_ordonne = objet_cata)
268       sublist.append(item)
269     return sublist
270
271   def GetIconName(self):
272     return 'ast-green-square'
273
274   def isactif(self):
275     return 1
276   
277 class CMDItem(CATAItem):
278
279   def get_dico_fils(self):
280     self.d_fils = self.object.entites
281
282 class SIMPItem(CATAItem):
283   d_fils={}
284   d_attributs={}
285
286   def GetIconName(self):
287     return 'ast-green-ball'
288
289   def IsExpandable(self):
290     return 0
291   
292 class FACTItem(CMDItem):
293   def GetIconName(self):
294     return 'ast-green-los'
295
296 class BLOCItem(FACTItem): pass
297
298 class ATTRIBUTItem(SIMPItem):
299   def get_dico_attributs(self):
300     self.d_attributs = {}
301
302   def GetSubList(self):
303     return []
304
305   def IsExpandable(self):
306     return 0
307
308   def GetText(self):
309     return self.object
310
311   def GetIconName(self):
312     return 'aucune'  
313
314 class CataBrowser:
315   def __init__(self,parent,appli,cata,item = None):
316     self.parent = parent
317     self.cata = cata
318     self.appli = appli
319     self.item = item
320     self.init()
321
322   def close(self):
323     self.top.destroy()
324
325   def init(self):
326     self.nodes={}
327     self.top = Pmw.Dialog(self.parent,
328                           title = "Visualisation d'un catalogue",
329                           buttons=('OK',),
330                           command = self.quit)
331     self.pane = Pmw.PanedWidget(self.top.component('dialogchildsite'),
332                                 hull_width = 800,
333                                 hull_height = 500,
334                                 orient = 'horizontal')
335     self.pane.add('canvas',min = 0.4, max = 0.6, size = 0.5)
336     self.pane.add('panel',min = 0.4, max = 0.6, size = 0.5)
337     self.pane.pack(expand =1, fill = 'both')
338     self.scrolledcanvas = Pmw.ScrolledCanvas(self.pane.pane('canvas'),
339                                              hull_width=1.,
340                                              hull_height=1.,
341                                              borderframe=1)
342     Pmw.Color.changecolor(self.scrolledcanvas.component('canvas'),background='gray95')
343     self.scrolledcanvas.pack(padx=10,pady=10,expand=1, fill="both")
344     if self.item == None :
345       self.item = CATAItem(self.appli,"Catalogue",self.cata)
346     self.tree = Tree(self.appli,self.item,self.scrolledcanvas,command = self.select_node)
347     self.tree.draw()
348     self.node = self.tree.node_selected
349
350   def select_node(self,node):
351     self.nodes[node]=self.create_panel(node)
352
353   def create_panel(self,node):
354     if hasattr(node.item,"panel"):
355       return getattr(node.item,"panel")(self,self.pane.pane('panel'),node)
356       
357   def quit(self,nom_bouton) :
358     self.top.destroy()
359     
360   def settitle(self):
361     self.top.wm_title("Browser de catalogue " )
362     self.top.wm_iconname("CataBrowser")
363
364  
365 dispatch = {
366     OPER  : CMDItem,
367     PROC  : CMDItem,
368     MACRO  : CMDItem,
369     SIMP : SIMPItem,
370     FACT : FACTItem,
371     BLOC : BLOCItem,
372 }
373
374 def TYPE(o):
375   if isinstance(o,OPER):return OPER
376   elif isinstance(o,PROC):return PROC
377   elif isinstance(o,MACRO):return MACRO
378   elif isinstance(o,FORM):return MACRO
379   elif isinstance(o,SIMP):return SIMP
380   elif isinstance(o,FACT):return FACT
381   elif isinstance(o,BLOC):return BLOC
382   else:return type(o)
383
384 def make_objecttreeitem(appli,labeltext, object, setfunction=None,objet_cata_ordonne=None):
385     t = TYPE(object)
386     if dispatch.has_key(t):
387       c = dispatch[t]
388     else:
389       #print 'on a un objet de type :',t,'  ',object
390       c = ATTRIBUTItem
391     return c(appli,labeltext, object, setfunction = setfunction,objet_cata_ordonne=objet_cata_ordonne)
392
393 def isCMD(cmd):
394    return isinstance(cmd,OPER) or isinstance(cmd,PROC) or isinstance(cmd,MACRO) or isinstance(cmd,FORM)
395
396
397