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.
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.
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.
19 # ======================================================================
26 from widgets import showinfo
32 from treewidget import Tree
33 from Objecttreeitem import TreeItem
34 from Accas import AsException
35 from Noyau.N_CR import justify_text
37 from Accas import ASSD,GEOM
38 import definition_cata
41 __version__="$Name: $"
42 __Id__="$Id: cataediteur.py,v 1.3.6.1 2004/03/01 11:14:09 eficas Exp $"
45 Fonte_Niveau = fontes.canvas_gras_italique
48 """ Classe servant de classe mère à toutes celles représentant les
49 panneaux à afficher en fonction de la nature de l'objet en cours
50 Elle est toujours dérivée."""
51 def __init__(self,parent,panneau,node) :
53 self.panneau = panneau
55 Frame.__init__(self,self.panneau)
56 self.place(x=0,y=0,relheight=1,relwidth=1)
60 def creer_boutons(self):
61 """ Méthode créant les boutons se trouvant dans la partie contextuelle d'EFICAS
62 (à droite sous les onglets ) """
63 self.fr_but = Frame(self,height=30)
64 self.fr_but.pack(side='bottom',fill='x')
65 self.bouton_com = Button(self.fr_but,
67 command = self.ajout_commentaire,
69 self.bouton_sup = Button(self.fr_but,
71 command=self.supprimer,
73 self.bouton_doc = Button(self.fr_but,
75 command=self.visu_doc,
77 self.bouton_cata = Button(self.fr_but,
79 command = self.show_catalogue,
81 if self.parent.appli.CONFIGURATION.isdeveloppeur == 'OUI':
82 self.bouton_sup.place(relx=0.25,rely = 0.5,relheight = 0.8,anchor='w')
83 self.bouton_cata.place(relx=0.5,rely = 0.5,relheight = 0.8,anchor='w')
84 self.bouton_doc.place(relx=0.75,rely = 0.5,relheight = 0.8,anchor='w')
86 self.bouton_sup.place(relx=0.3,rely = 0.5,relheight = 0.8,anchor='w')
87 self.bouton_doc.place(relx=0.7,rely = 0.5,relheight = 0.8,anchor='w')
89 def show_catalogue(self):
91 genea = self.node.item.get_genealogie()
92 self.parent.appli.browser_catalogue_objet(genea)
99 def ajout_commentaire(self,ind='after'):
100 """ Ajoute un commentaire à l'intérieur du JDC, par défaut après le noeud en cours"""
101 if self.parent.modified == 'n' : self.parent.init_modif()
102 return self.node.append_brother("COMMENTAIRE",ind)
104 def ajout_commentaire_first(self):
105 """ Ajoute un commentaire en début de JDC"""
106 if self.parent.modified == 'n' : self.parent.init_modif()
107 return self.node.append_child("COMMENTAIRE",'first')
110 """ Permet d'ouvrir le fichier doc U de la commande au format pdf avec Acrobat Reader
111 - Ne fonctionne pas sous UNIX (chemin d'accès Acrobat Reader)
112 - indication du chemin d'accès aux fichiers pdf à revoir : trop statique"""
113 #cle_doc = self.node.item.get_docu()
114 cle_doc = self.parent.appli.get_docu(self.node)
115 if cle_doc == None : return
116 cle_doc = string.replace(cle_doc,'.','')
117 #cle_doc = string.upper(cle_doc)
118 commande = self.parent.appli.CONFIGURATION.exec_acrobat
119 #nom_fichier = cle_doc+".pdf"
120 nom_fichier = cle_doc+".doc"
121 rep_fichier = cle_doc[0:2]
122 fichier = os.path.abspath(os.path.join(self.parent.appli.CONFIGURATION.path_doc,rep_fichier,nom_fichier))
123 print 'commande =',commande
124 print 'fichier =',fichier
125 print 'existe =',os.path.isfile(fichier)
127 os.spawnv(os.P_NOWAIT,commande,(commande,fichier))
128 elif os.name == 'posix':
129 script ="#!/usr/bin/sh \n%s %s" %(commande,nom_fichier)
130 pid = os.system(script)
133 """ Suppression du noeud courant """
134 if self.parent.modified == 'n' : self.parent.init_modif()
135 pere = self.node.parent
140 """ Force l'affichage des fenêtres en cours """
143 def selectMC(self,name):
144 """ On retrouve le mot-clé sous le curseur pour affichage du fr """
145 cmd=self.node.item.get_definition()
147 for e in cmd.entites.keys() :
149 texte_infos=getattr(cmd.entites[e],'fr')
151 if texte_infos == '' : texte_infos="Pas d'infos disponibles"
152 self.parent.appli.affiche_infos(texte_infos)
154 def defMC(self,name):
155 """ On ajoute un mot-clé à la commande : subnode """
156 if name == SEPARATEUR:return
157 if self.parent.modified == 'n' : self.parent.init_modif()
158 if name != "COMMENTAIRE":
159 self.node.append_child(name)
161 self.ajout_commentaire()
163 def selectFilsCmd(self,name):
166 def defFilsCmd(self,name):
169 def defCmdFirst(self,name):
170 """ On ajoute une commande ou un commentaire au début du fichier de commandes """
171 if name == SEPARATEUR:return
172 if self.parent.modified == 'n' : self.parent.init_modif()
173 if name != "COMMENTAIRE":
174 new_node = self.node.append_child(name,'first')
176 new_node = self.ajout_commentaire_first()
178 def add_commande_avant(self,event=None):
181 def add_commande_apres(self,event=None):
184 class OngletPanel(Panel) :
185 """ Cette classe est virtuelle et doit être dérivée
186 Elle contient les principales méthodes d'affichage des différents onglets"""
188 def raisecmd(self,page):
189 self.nb.page(page).focus_set()
190 if page == 'Concept': self._any.focus()
193 page=self.nb.getcurselection()
194 self.nb.page(page).focus_set()
195 if page == 'Concept':self._any.component('entry').focus_set()
198 def makeConceptPage(self,page):
199 """ Crée la page de saisie du nom du concept """
200 self.label = Label(page,text='Nom du concept :')
201 self.label.place(relx=0.1,rely=0.4)
202 self._any = Entry(page,relief='sunken')
203 self._any.place(relx=0.35,rely=0.4,relwidth=0.5)
204 self._any.bind("<Return>",lambda e,s=self:s.execConcept())
205 self._any.insert(0,self.node.item.GetText())
206 type_sd = self.node.item.object.get_type_sd_prod()
208 txt = "L'opérateur courant retourne un objet de type %s" %type_sd
209 self.label = Label(page, text = txt)
210 self.label.place(relx=0.5,rely=0.55,anchor='n')
213 def makeCommandePage(self,page):
214 """ Affiche la page d'ajout d'une commande relativement à l'objet commande sélectionné """
215 titre = "Où voulez-vous insérer une commande par rapport à %s" %self.node.item.object.nom
216 Label(page,text=titre).place(relx=0.5,rely=0.2,anchor='w')
217 b_avant = Button(page,text='AVANT',
218 command = self.node.item.add_commande_avant)
219 b_apres = Button(page,text='APRES',
220 command = self.node.item.add_commande_apres)
221 b_avant.place(relx=0.35,rely=0.5,anchor='w')
222 b_apres.place(relx=0.65,rely=0.5,anchor='w')
224 def deselectMC(self,name):
225 self.parent.appli.affiche_infos('')
227 def get_liste_cmd(self):
228 listeCmd = self.node.item.object.niveau.definition.get_liste_cmd()
231 def get_liste_fils_cmd(self):
232 return ['Mot-clé simple','Mot-clé facteur','Bloc']
234 def makeMoclesPage(self,page):
235 frame1 = Frame(page,height = 20)
236 frame1.pack(side='top',fill='x')
237 label = Label(frame1,text ="Le mot-clé choisi sera ajouté à la fin du catalogue")
238 label.pack(side='top')
240 frame2.pack(side='top',fill='both',expand=1)
241 liste_cmd = self.get_liste_fils_cmd()
242 liste_commandes = (("<Enter>",self.selectFilsCmd),
243 ("<Leave>",self.deselectFilsCmd),
244 ("<Double-Button-1>",self.defFilsCmd))
245 Liste = ListeChoix(self,frame2,liste_cmd,liste_commandes = liste_commandes,titre = "Mots-clés")
246 Liste.affiche_liste()
248 def deselectFilsCmd(self,name):
251 def makeJDCPage(self,page):
252 liste_cmd = self.get_liste_cmd()
253 liste_commandes = (("<Enter>",self.selectCmd),
254 ("<Leave>",self.deselectCmd),
255 ("<Double-Button-1>",self.defCmdFirst))
256 Liste = ListeChoix(self,page,liste_cmd,liste_commandes = liste_commandes,filtre='oui',titre = "Commandes")
257 Liste.affiche_liste()
259 def makeReglesPage(self,page) :
261 regles = self.node.item.get_regles()
262 dictionnaire = self.node.item.get_mc_presents()
264 l_regles_en_defaut=[]
267 for regle in regles :
268 texte_regles.append(regle.gettext())
269 texte,test = regle.verif(dictionnaire)
270 if test == 0 : l_regles_en_defaut.append(i)
272 Liste = ListeChoix(self,page,texte_regles,liste_marques=l_regles_en_defaut,active='non',titre="Règles")
273 Liste.affiche_liste()
274 #self.afficheListe(page,texte_regles,self.selectRegle,self.execRegle)
276 def execConcept(self):
277 """ Nomme le concept SD retourné par l'étape """
278 if self.parent.modified == 'n' : self.parent.init_modif()
279 nom = self._any.get()
280 # Pourquoi node.etape ???
281 #test,mess = self.node.etape.item.nomme_sd(nom)
282 test,mess = self.node.item.nomme_sd(nom)
283 self.parent.appli.affiche_infos(mess)
284 self.node.racine.update()
289 def makeAttributsPage(self,page):
290 l_attributs=self.node.item.object.attributs
291 d_defauts = self.node.item.object.attributs_defauts
292 for attribut in l_attributs :
293 attr = self.node.item.object.entites_attributs.get(attribut,None)
294 if attr.valeur is d_defauts[attribut] :
295 texte = attribut+' = '+repr(attr.valeur)+' (defaut)'
297 texte = attribut+' = '+repr(attr.valeur)
298 Label(page,text=texte).pack(side='top')
300 def makeSimpPage(self,page):
301 texte = "Où voulez-vous ajouter un mot-clé simple ?"
302 Label(page,text=texte).place(relx=0.5,rely=0.3,anchor='center')
303 b1 = Button(page,text='AVANT '+self.node.item.object.nom,command=self.add_simp_avant)
304 b2 = Button(page,text='APRES '+self.node.item.object.nom,command=self.add_simp_apres)
305 b1.place(relx=0.5,rely=0.5,anchor='center')
306 b2.place(relx=0.5,rely=0.6,anchor='center')
308 def add_simp_avant(self,event=None):
310 Ajoute un mot-clé simple avant celui courant
312 self.node.append_brother('new_simp','before')
315 def add_simp_apres(self,event=None):
317 Ajoute un mot-clé simple après celui courant
319 self.node.append_brother('new_simp','after')
322 class TYPEPanel(Frame):
323 def __init__(self,parent,panneau,node) :
325 self.panneau = panneau
327 Frame.__init__(self,self.panneau)
328 self.place(x=0,y=0,relheight=1,relwidth=1)
331 def creer_texte(self):
332 texte = "Le noeud sélectionné correspond à un type\n"
333 self.label = Label(self,text=texte)
334 self.label.place(relx=0.5,rely=0.4,relwidth=0.8,anchor='center')
336 class OPERPanel(OngletPanel):
338 nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
340 nb.pack(fill = 'both', expand = 1)
342 nb.add('Mocles', tab_text='Ajouter mots-clés')
343 nb.add('Commandes',tab_text='Ajouter une commande')
344 self.makeMoclesPage(nb.page("Mocles"))
345 self.makeCommandePage(nb.page("Commandes"))
346 nb.tab('Mocles').focus_set()
350 class SIMPPanel(OngletPanel):
352 nb = Pmw.NoteBook(self,raisecommand=self.raisecmd)
353 nb.pack(fill = 'both', expand = 1)
355 nb.add('generaux', tab_text='Données générales')
356 nb.add('ihm',tab_text='Données IHM')
357 nb.add('mocle',tab_text='Ajouter un mot-cle simple')
358 self.makeAttributsGenerauxPage(nb.page("generaux"))
359 self.makeAttributsIHMPage(nb.page("ihm"))
360 self.makeSimpPage(nb.page('mocle'))
361 nb.tab('generaux').focus_set()
365 def makeAttributsGenerauxPage(self,page):
366 fr1 = Frame(page,bd=1,relief='raised')
367 fr2 = Frame(page,bd=1,relief='raised')
368 fr3 = Frame(page,bd=1,relief='raised')
369 fr4 = Frame(page,bd=1,relief='raised')
370 fr5 = Frame(page,bd=1,relief='raised')
371 fr1.place(relheight=0.14,relwidth=1,rely=0)
372 fr2.place(relheight=0.14,relwidth=1,rely=0.14)
373 fr3.place(relheight=0.29,relwidth=1,rely=0.28)
374 fr4.place(relheight=0.14,relwidth=1,rely=0.57)
375 fr5.place(relheight=0.28,relwidth=1,rely=0.71)
377 Label(fr1,text = 'Nom :').place(relx=0.05,rely=0.3,anchor='w')
378 self.e_nom = Entry(fr1)
379 self.e_nom.place(relx=0.35,rely=0.3,relwidth=0.3,anchor='w')
380 self.e_nom.bind("<Return>",lambda e,s=self : s.set_valeur_attribut('nom',None))
381 self.e_nom.insert(0,self.get_valeur_attribut('nom'))
383 Label(fr1,text='Statut : ').place(relx=0.05,rely=0.7,anchor='w')
384 self.statut=StringVar()
385 valeurs_statut=[('obligatoire','o'),
389 self.statut.set(self.node.item.object.get_valeur_attribut('statut'))
391 for text,mode in valeurs_statut:
392 b=Radiobutton(fr1,text=text,variable=self.statut,value=mode,
393 command = lambda s=self,m=mode : s.set_valeur_attribut('statut',m))
394 b.place(relx=0.25+i*0.25,rely=0.7,anchor='w')
397 Label(fr2,text='Type de la valeur : ').place(relx=0.05,rely=0.5,anchor='w')
398 self.e_type = Entry(fr2)
399 self.e_type.place(relx=0.35,rely=0.5,relwidth=0.5,anchor='w')
400 self.e_type.insert(0,self.node.item.object.get_valeur_attribut('type'))
401 # Domaine de validité
402 Label(fr3,text='Domaine de validité : ').place(relx=0.05,rely=0.2,anchor='w')
403 self.domaine = StringVar()
404 self.domaine.set(self.node.item.object.get_valeur_attribut('domaine_validité'))
405 b1=Radiobutton(fr3,text='continu',variable=self.domaine,value='continu',
406 command=lambda s=self,f=fr3 :s.change_domaine(f))
407 b2=Radiobutton(fr3,text='discret',variable=self.domaine,value='discret',
408 command=lambda s=self,f=fr3 :s.change_domaine(f))
409 b1.place(relx=0.35,rely=0.2,anchor='w')
410 b2.place(relx=0.65,rely=0.2,anchor='w')
411 self.change_domaine(fr3)
413 if self.domaine.get() == 'continu':
414 # le développeur peut donner la valeur qu'il souhaite, moyennant la vérification de type...
415 Label(fr4,text='Valeur par défaut : ').place(relx=0.05,rely=0.5,anchor='w')
416 self.e_defaut = Entry(fr4)
417 self.e_defaut.place(relx=0.35,rely=0.5,relwidth=0.5,anchor='w')
418 if self.node.item.object.get_valeur_attribut('defaut') :
419 self.e_defaut.insert(0,self.node.item.object.get_valeur_attribut('defaut'))
420 self.e_defaut.bind("<Return>",lambda e,s=self : s.set_valeur_attribut('defaut',None))
422 # dans le cas discret, la valeur par défaut doit être dans l'ensemble des valeurs possibles (into)
423 liste = self.node.item.object.get_valeur_attribut('into')
424 if self.node.item.object.get_valeur_attribut('defaut') :
425 self.set_valeur_attribut('defaut',self.node.item.object.get_valeur_attribut('defaut'))
426 if liste == None : liste = []
427 self.e_defaut = Pmw.OptionMenu(fr4,labelpos='w',label_text = "Valeur par défaut : ",
428 items = self.node.item.object.get_valeur_attribut('into'),
430 self.e_defaut.configure(command = lambda e,s=self : s.set_valeur_attribut('defaut',None))
431 self.e_defaut.place(relx=0.05,rely=0.5,anchor='w')
433 Label(fr5,text='Liste de valeurs : ').place(relx=0.05,rely=0.2,anchor='w')
434 self.liste_valeurs = BooleanVar()
435 liste_valeurs = [('OUI',1),('NON',0)]
436 self.liste_valeurs.set(0)
438 for text,mode in liste_valeurs:
439 b=Radiobutton(fr5,text=text,variable=self.liste_valeurs,value=mode,
440 command=lambda s=self,f=fr5 :s.change_liste_valeurs(f))
441 b.place(relx=0.35+i*0.2,rely=0.2,anchor='w')
443 self.change_liste_valeurs(fr5)
445 def makeAttributsIHMPage(self,page):
446 fr1 = Frame(page,height=100,bd=1,relief='raised')
447 fr2 = Frame(page,height=50,bd=1,relief='raised')
448 fr1.pack(side='top',fill='x')
449 fr2.pack(side='top',fill='x')
451 Label(fr1,text='Champ fr : ').place(relx=0.05,rely=0.35,anchor='w')
452 self.e_fr = Entry(fr1)
453 self.e_fr.place(relx=0.35,rely=0.35,relwidth=0.6,anchor='w')
454 self.e_fr.insert(0,self.node.item.object.get_valeur_attribut('fr'))
456 Label(fr1,text='Champ ang : ').place(relx=0.05,rely=0.70,anchor='w')
457 self.e_ang = Entry(fr1)
458 self.e_ang.place(relx=0.35,rely=0.70,relwidth=0.6,anchor='w')
459 self.e_ang.insert(0,self.node.item.object.get_valeur_attribut('ang'))
460 # Clé documentaire ...
461 Label(fr2,text='Clé documentaire : ').place(relx=0.05,rely=0.50,anchor='w')
462 self.e_docu = Entry(fr2)
463 self.e_docu.place(relx=0.35,rely=0.50,relwidth=0.6,anchor='w')
464 self.e_docu.insert(0,self.node.item.object.get_valeur_attribut('docu'))
466 def detruit_widgets(self,l_widgets):
467 for nom_widg in l_widgets :
469 widg = getattr(self,nom_widg)
471 delattr(self,nom_widg)
475 def change_liste_valeurs(self,fr5):
476 valeur = self.liste_valeurs.get()
478 # pas de liste de valeurs
479 l_widgets=['l_homo','b1_homo','b2_homo','l_min','e_min','l_max','e_max']
480 self.detruit_widgets(l_widgets)
482 # pas de widgets à détruire ...
483 if hasattr(self,'l_homo') :
484 # on est déjà en mode 'liste' --> rien à faire
487 self.l_homo = Label(fr5,text='Liste homogène : ')
488 self.l_homo.place(relx=0.05,rely=0.4,anchor='w')
489 self.homo = BooleanVar()
490 self.homo.set(self.node.item.object.get_valeur_attribut('homo'))
491 self.b1_homo=Radiobutton(fr5,text='OUI',variable=self.homo,value=1)
492 self.b2_homo=Radiobutton(fr5,text='NON',variable=self.homo,value=0)
493 self.b1_homo.place(relx=0.35,rely=0.4,anchor='w')
494 self.b2_homo.place(relx=0.65,rely=0.4,anchor='w')
496 self.l_min = Label(fr5,text='Longueur minimale : ')
497 self.l_min.place(relx=0.05,rely=0.6,anchor='w')
498 self.e_min = Entry(fr5)
499 self.e_min.place(relx=0.4,rely=0.6,relwidth=0.3,anchor='w')
500 self.e_min.insert(0,self.node.item.object.get_valeur_attribut('min'))
502 self.l_max = Label(fr5,text='Longueur maximale : ')
503 self.l_max.place(relx=0.05,rely=0.8,anchor='w')
504 self.e_max = Entry(fr5)
505 self.e_max.place(relx=0.4,rely=0.8,relwidth=0.3,anchor='w')
506 self.e_max.insert(0,self.node.item.object.get_valeur_attribut('max'))
508 def change_domaine(self,fr3):
509 valeur = self.domaine.get()
510 if valeur == 'discret' :
511 l_widgets = ['l_val_min','l_val_max','e_val_min','e_val_max']
512 self.detruit_widgets(l_widgets)
514 #self.l_into = Label(fr3,text='Ensemble de valeurs : ')
515 #self.l_into.place(relx=0.2,rely=0.5,anchor='w')
516 self.e_into = Pmw.ScrolledListBox(fr3,
517 items=self.node.item.object.get_valeur_attribut('into'),
519 label_text= 'Ensemble de valeurs : ',
521 dblclickcommand = self.change_into)
522 self.e_into.place(relx=0.05,rely=0.6,relwidth=0.9,anchor='w')
523 #self.e_into.insert(0,self.node.item.object.get_valeur_attribut('into'))
524 elif valeur == 'continu':
525 l_widgets = ['l_into','e_into']
526 self.detruit_widgets(l_widgets)
527 if hasattr(self,'l_val_min'):
528 # on est déjà en mode 'continu' --> rien à faire
531 self.l_val_min = Label(fr3,text='Valeur minimale : ')
532 self.l_val_min.place(relx=0.05,rely=0.5,anchor='w')
533 self.e_val_min = Entry(fr3)
534 self.e_val_min.place(relx=0.35,rely=0.5,relwidth=0.5,anchor='w')
535 self.e_val_min.bind("<Return>",lambda e,s=self : s.set_valeur_attribut('val_min',None))
536 self.set_valeur_attribut('val_min',self.get_valeur_attribut('val_min'))
538 self.l_val_max = Label(fr3,text='Valeur maximale : ')
539 self.l_val_max.place(relx=0.05,rely=0.8,anchor='w')
540 self.e_val_max = Entry(fr3)
541 self.e_val_max.place(relx=0.35,rely=0.8,relwidth=0.5,anchor='w')
542 self.e_val_max.bind("<Return>",lambda e,s=self : s.set_valeur_attribut('val_max',None))
543 self.set_valeur_attribut('val_max',self.get_valeur_attribut('val_max'))
545 # ------------------------------------------------------------------
546 # Méthodes de validation des entrées faites par l'utilisateur
547 # ------------------------------------------------------------------
549 def get_valeur_attribut(self,nom_attr):
551 Demande à l'item de retourner la valeur de l'attribut nom_attr
553 return self.node.item.get_valeur_attribut(nom_attr)
555 def set_valeur_attribut(self,nom_attr,new_valeur):
557 Affecte la valeur new_valeur à l'attribut nom_attr
558 Vérifie si celle-ci est valide, sinon restaure l'ancienne
560 if new_valeur is None :
561 widget = getattr(self,'e_'+nom_attr)
562 if hasattr(widget,'getcurselection'):
563 new_valeur = widget.getcurselection()
565 new_valeur = widget.get()
566 print "on affecte %s a %s" %(str(new_valeur),nom_attr)
567 self.node.item.set_valeur_attribut(nom_attr,new_valeur)
570 def change_into(self):
572 Méthode activée par double clic sur la ListBox d'affichage des valeurs discrètes possibles :
573 permet de changer la liste de ces valeurs
575 showinfo("Fonction non encore disponible",
576 "Vous ne pouvez pas encore modifier la liste into par cette IHM")
578 class OBJECTItem(TreeItem):
579 def __init__(self,appli,labeltext,object,setfunction=None,objet_cata_ordonne = None):
581 self.labeltext = labeltext
583 self.setfunction = setfunction
584 self.objet_cata_ordonne = objet_cata_ordonne
586 def GetLabelText(self):
587 return self.labeltext,None,None
598 def add_commande_avant(self):
601 def add_commande_apres(self):
604 def set_valeur_attribut(self,nom_attr,new_valeur):
606 Affecte la valeur new_valeur à l'attribut nom_attr
607 Vérifie si celle-ci est valide, sinon restaure l'ancienne
609 old_valeur = self.object.get_valeur_attribut(nom_attr)
610 self.object.set_valeur_attribut(nom_attr,new_valeur)
611 verificateur = 'verif_'+nom_attr
612 if hasattr(self.object,verificateur):
613 if not getattr(self.object,verificateur)():
614 # la nouvelle valeur de nom_attr n'est pas valide : on restaure l'ancienne (sans vérification)
615 self.object.set_valeur_attribut(nom_attr,old_valeur)
616 print 'changement de valeur refuse'
618 print 'changement de valeur accepte'
619 self.object.init_modif()
621 def get_valeur_attribut(self,nom_attr):
623 Retourne la valeur de l'attribut nom_attr
625 return self.object.get_valeur_attribut(nom_attr)
627 class CATAItem(OBJECTItem):
628 def GetSubList(self):
630 for fils in self.object.entites_fils:
631 item = make_objecttreeitem(self.appli,fils.objet.label + " : ",fils,objet_cata_ordonne=self.objet_cata_ordonne)
635 def GetIconName(self):
636 if self.object.isvalid():
637 return 'ast-green-square'
639 return 'ast-red-square'
642 return "Catalogue %s" %self.appli.code
644 def add_commande_avant(self):
647 def add_commande_apres(self):
651 def transforme_liste_dico(liste):
657 class OPERItem(OBJECTItem):
659 def GetSubList(self):
661 # on classe les fils dans l'ordre du catalogue ...
662 l_cles_fils = self.get_liste_mc_ordonnee()
663 # on crée les items fils ...
664 dico_fils = transforme_liste_dico(self.object.entites_fils)
665 for k in l_cles_fils :
666 typ = TYPE_COMPLET(dico_fils[k])
667 if type(self.objet_cata_ordonne) == types.InstanceType :
668 objet_cata = self.objet_cata_ordonne.entites[k]
670 objet_cata = self.objet_cata_ordonne.get(k,None)
671 item = make_objecttreeitem(self.appli,typ + " : ",dico_fils[k],objet_cata_ordonne = objet_cata)
676 #return self.object.nom
677 return self.object.get_valeur_attribut('nom')
679 def get_liste_mc_ordonnee(self):
680 return self.objet_cata_ordonne.ordre_mc
682 def GetIconName(self):
683 if self.object.isvalid():
684 return 'ast-green-square'
686 return 'ast-red-square'
688 def additem(self,name,pos):
689 if isinstance(name,TreeItem) :
690 cmd=self.object.addentite(name.object,pos)
692 cmd = self.object.addentite(name,pos)
693 typ = TYPE_COMPLET(cmd)
694 item = make_objecttreeitem(self.appli,typ + " : ", cmd)
697 def get_attribut(self,nom):
698 if nom == 'nature': return 'OPERATEUR'
700 def get_liste_mc_presents(self):
703 def verif_condition_regles(self,liste):
706 class PROCItem(OPERItem):
709 class MACROItem(OPERItem):
712 class SIMPItem(OPERItem):
715 def GetIconName(self):
716 if self.object.isvalid():
717 return 'ast-green-ball'
719 return 'ast-red-ball'
721 def IsExpandable(self):
724 def GetSubList(self):
727 class FACTItem(OPERItem):
728 def GetIconName(self):
729 if self.object.isvalid():
730 return 'ast-green-los'
734 class BLOCItem(FACTItem): pass
736 class TYPEItem(SIMPItem):
738 def get_dico_attributs(self):
739 self.d_attributs = {}
741 def GetSubList(self):
744 def IsExpandable(self):
748 return self.object.nom
750 class NIVEAUItem(OPERItem):
751 def IsExpandable(self):
754 def get_liste_mc_ordonnee(self):
756 for fils in self.object.entites_fils:
760 def GetSubList(self):
762 # on classe les fils dans l'ordre du catalogue ...
763 l_cles_fils = self.get_liste_mc_ordonnee()
764 # on crꥠles items fils ...
765 dico_fils = transforme_liste_dico(self.object.entites_fils)
766 for k in l_cles_fils :
767 typ = TYPE_COMPLET(dico_fils[k])
768 if type(self.objet_cata_ordonne) == types.InstanceType :
769 objet_cata = self.objet_cata_ordonne.entites[k]
771 objet_cata = self.objet_cata_ordonne.get(k,None)
772 item = make_objecttreeitem(self.appli,typ + " : ",dico_fils[k],objet_cata_ordonne = objet_cata)
776 def GetLabelText(self):
777 """ Retourne 3 valeurs :
778 - le texte à afficher dans le noeud représentant l'item
779 - la fonte dans laquelle afficher ce texte
780 - la couleur du texte
782 return self.labeltext,Fonte_Niveau,'#00008b'
784 def GetIconName(self):
785 if self.object.isvalid():
786 return "ast-green-text"
788 return 'ast-red-text'
790 def additem(self,name,pos):
791 if isinstance(name,TreeItem) :
792 cmd=self.object.addentite(name.object,pos)
794 cmd = self.object.addentite(name,pos)
795 typ = TYPE_COMPLET(obj)
796 item = make_objecttreeitem(self.appli,typ+ " : ", cmd)
799 def suppitem(self,item) :
800 # item = item de l'ETAPE à supprimer du JDC
801 # item.object = ETAPE ou _C
803 self.object.suppentite(item.object)
804 if isinstance(item.object,_C):
805 message = "Commentaire supprimé"
806 self.appli.affiche_infos(message)
808 message = "Commande " + item.object.nom + " supprimée"
809 self.appli.affiche_infos(message)
815 class ATTRIBUTItem(SIMPItem):
816 def get_dico_attributs(self):
817 self.d_attributs = {}
819 def GetSubList(self):
822 def IsExpandable(self):
828 def GetIconName(self):
832 def __init__(self,parent,appli,cata):
834 self.cata = definition_cata.CATALOGUE(cata)
836 self.top = Toplevel()
837 self.top.geometry("800x500")
838 self.top.title("Edition d'un catalogue")
846 self.creerbarremenus()
847 self.pane = Pmw.PanedWidget(self.top,
850 orient = 'horizontal')
851 self.pane.add('canvas',min = 0.4, max = 0.6, size = 0.5)
852 self.pane.add('panel',min = 0.4, max = 0.6, size = 0.5)
853 self.pane.pack(expand =1, fill = 'both')
854 self.scrolledcanvas = Pmw.ScrolledCanvas(self.pane.pane('canvas'),
858 Pmw.Color.changecolor(self.scrolledcanvas.component('canvas'),background='gray95')
859 self.scrolledcanvas.pack(padx=10,pady=10,expand=1, fill="both")
860 self.item = CATAItem(self.appli,"Catalogue",
862 objet_cata_ordonne = self.appli.readercata.cata_ordonne_dico)
864 self.tree = Tree(self.appli,self.item,self.scrolledcanvas,command = self.select_node)
866 self.node = self.tree.node_selected
868 def creerbarremenus(self) :
869 self.menubar=Menu(self.top)
870 self.filemenu=Menu(self.menubar,tearoff=0)
871 self.filemenu.add_command(label='Quitter',command=self.quit)
873 self.editmenu=Menu(self.menubar,tearoff=0)
874 #self.editmenu.add_command(label='Copier',command=self.copy)
875 #self.editmenu.add_command(label='Couper',command=self.cut)
876 #self.editmenu.add_command(label='Coller',command=self.paste)
878 self.affichagemenu=Menu(self.menubar,tearoff=0)
879 self.affichagemenu.add_command(label='Rapport de validation',
880 command = self.visuCR)
881 self.affichagemenu.add_command(label='shell',command = self.shell)
882 #self.affichagemenu.add_command(label='Fichier ࡰlat',command=self.visu_a_plat)
883 #self.affichagemenu.add_command(label='Fichier .py',command =self.visuJDC_py)
884 #self.affichagemenu.add_command(label='Fichier source',command = self.visu_txt_brut_JDC)
885 #self.affichagemenu.add_command(label='Param鵲es Eficas',command=self.affichage_fichier_ini)
887 #self.optionmenu=Menu(self.menubar,tearoff=0)
888 #self.optionmenu.add_command(label='Catalogue d귥loppeur',command=self.choix_cata_developpeur)
890 self.menubar.add_cascade(label='Fichier',menu=self.filemenu)
891 self.menubar.add_cascade(label='Edition',menu=self.editmenu)
892 self.menubar.add_cascade(label='Jeu de commandes',menu=self.affichagemenu)
893 #self.menubar.add_cascade(label='Browsers',menu=self.browsermenu)
894 #self.menubar.add_cascade(label='Catalogue',menu=self.cataloguemenu)
895 #self.menubar.add_cascade(label='Options',menu=self.optionmenu)
896 self.top.configure(menu=self.menubar)
897 self.top.protocol("WM_DELETE_WINDOW",self.quit)
898 self.top.minsize(900,500)
899 self.top.geometry("900x500")
901 def shell(self,event=None):
903 d={'j':self.tree.item.object}
904 Interp.InterpWindow(d,parent=self.parent)
906 def visuCR(self,mode='Cata'):
907 txt = str(self.cata.report())
908 titre="Rapport de validation du catalogue"
909 Fenetre(self.appli,titre=titre,texte=txt)
911 def select_node(self,node):
912 self.nodes[node]=self.create_panel(node)
914 def create_panel(self,node):
915 if hasattr(node.item,"panel"):
916 return getattr(node.item,"panel")(self,self.pane.pane('panel'),node)
922 self.top.wm_title("Browser de catalogue " )
923 self.top.wm_iconname("CataBrowser")
934 'NIVEAU' : NIVEAUItem
938 if isinstance(o,definition_cata.OPER_CATA):return 'OPER'
939 elif isinstance(o,definition_cata.PROC_CATA):return 'PROC'
940 elif isinstance(o,definition_cata.MACRO_CATA):return 'MACRO'
941 elif isinstance(o,definition_cata.SIMP_CATA):return 'SIMP'
942 elif isinstance(o,definition_cata.FACT_CATA):return 'FACT'
943 elif isinstance(o,definition_cata.BLOC_CATA):return 'BLOC'
944 elif isinstance(o,definition_cata.TYPE_CATA):return 'TYPE'
945 elif isinstance(o,definition_cata.NIVEAU_CATA) : return 'NIVEAU'
949 if isinstance(o,definition_cata.OPER_CATA):return "OPERATEUR"
950 elif isinstance(o,definition_cata.PROC_CATA):return "PROCEDURE"
951 elif isinstance(o,definition_cata.MACRO_CATA):return "MACRO"
952 elif isinstance(o,definition_cata.SIMP_CATA):return "Mot-clé SIMPLE"
953 elif isinstance(o,definition_cata.FACT_CATA):return "Mot-clé FACTEUR"
954 elif isinstance(o,definition_cata.BLOC_CATA):return "BLOC"
955 elif isinstance(o,definition_cata.TYPE_CATA):return "Type"
956 elif isinstance(o,definition_cata.NIVEAU_CATA):return "Niveau"
957 else: return "Inconnu ("+`type(o)`+")"
959 def make_objecttreeitem(appli,labeltext, object, setfunction=None,objet_cata_ordonne=None):
961 if dispatch.has_key(t):
964 print 'on a un objet de type :',type(object),' ',object
966 return c(appli,labeltext, object, setfunction = setfunction,objet_cata_ordonne=objet_cata_ordonne)