X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=Editeur%2Fwidgets.py;h=30cabe747566be78ea628ca33bea2c57554fe2fc;hb=1a558db360a84dcacd7bfaf1212ef75c6e4939fd;hp=0c02a3c880201ac91242a0d2c8f46bdc7c8c083a;hpb=243fbe08b8fbc49d4ae0a5374069e9133b7b4b31;p=tools%2Feficas.git diff --git a/Editeur/widgets.py b/Editeur/widgets.py index 0c02a3c8..30cabe74 100644 --- a/Editeur/widgets.py +++ b/Editeur/widgets.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== # COPYRIGHT (C) 1991 - 2002 EDF R&D WWW.CODE-ASTER.ORG @@ -22,6 +23,7 @@ # EFICAS # ---------------------------------------------------------- +import Tkinter from Tkinter import * import Pmw import os,sys,re,string @@ -35,6 +37,19 @@ from utils import save_in_file from centerwindow import centerwindow from Noyau.N_utils import repr_float +from Accas import AsException + +# Surcharge de la fonction askyesno qui retourne un resultat errone en Python 2.3 avec Tk 8.4 +# et Tkinter.wantobject==1 +import tkMessageBox +def askyesno(title=None, message=None, **options): + "Ask a question; return true if the answer is yes" + s = tkMessageBox._show(title, message, tkMessageBox.QUESTION, tkMessageBox.YESNO, **options) + if s == tkMessageBox.YES:return 1 + if s == tkMessageBox.NO:return 0 + if s:return 1 + return 0 + class Fenetre : """ Cette classe permet de créer une fenêtre Toplevel dans laquelle @@ -85,6 +100,7 @@ class Fenetre : def wait(self): self.fenetre.grab_set() + self.zone_texte.focus_set() self.fenetre.wait_window(self.fenetre) def quit(self): @@ -110,9 +126,10 @@ class Fenetre : """ Permet de sauvegarder le texte dans un fichier dont on a demandé le nom à l'utilisateur """ file = asksaveasfilename(defaultextension = '.comm', - initialdir = self.appli.CONFIGURATION.rep_user, + #initialdir = self.appli.CONFIGURATION.rep_user, + initialdir = self.appli.CONFIGURATION.initialdir, title="Sauvegarde du "+self.titre) - if file != '': + if file : if not save_in_file(file,self.texte) : showerror("Sauvegarde impossible", "Impossible de sauvegarder le texte dans le fichier spécifié\n"+ @@ -120,194 +137,341 @@ class Fenetre : else: showinfo("Sauvegarde effectuée","Sauvegarde effectuée dans le fichier %s" %file) + def destroy(self): + try : + self.fenetre.destroy() + except : + pass + +class FenetreYesNo(Fenetre): + def __init__(self,appli,titre="",texte="",yes="Yes",no="No"): + self.appli=appli + self.fenetre = Toplevel() + self.fenetre.configure(width = 800,height=500) + self.fenetre.protocol("WM_DELETE_WINDOW", self.quit) + self.fenetre.title(titre) + self.texte = string.replace(texte,'\r\n','\n') + self.titre = titre + fonte=fontes.standardcourier10 + # définition des frames + self.frame_texte = Frame(self.fenetre) + self.frame_boutons = Frame(self.fenetre) + self.frame_boutons.place(relx=0,rely=0, relwidth=1.,relheight=0.1) + self.frame_texte.place( relx=0,rely=0.1, relwidth=1, relheight=0.9) + # définition de la zone texte et du scrollbar + self.zone_texte = Text(self.frame_texte,font=fonte) + self.zone_texte.bind("", self.page_up) + self.zone_texte.bind("", self.page_down) + self.zone_texte.bind("", self.unit_up) + self.zone_texte.bind("", self.unit_down) + self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview) + #self.scroll_h = Scrollbar (self.frame_texte,command = self.zone_texte.xview) + self.scroll_v.pack(side='right',fill ='y') + #self.scroll_h.pack(side='bottom',fill ='x') + self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10) + self.zone_texte.configure(yscrollcommand=self.scroll_v.set) + # définition des boutons + self.but_yes = Button(self.frame_boutons,text = yes,command=self.yes) + self.but_no = Button(self.frame_boutons,text = no,command = self.no) + self.but_yes.place(relx=0.4,rely=0.5,anchor='center') + self.but_no.place(relx=0.6,rely=0.5,anchor='center') + # affichage du texte + self.affiche_texte(self.texte) + centerwindow(self.fenetre) + + def yes(self): + self.result=1 + self.quit() + + def no(self): + self.result=0 + self.quit() + class FenetreDeSelection(Fenetre): - """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée. - Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé. - """ - def __init__(self,panel,item,appli,titre="",texte=""): - Fenetre.__init__(self,appli,titre=titre,texte=texte) - self.fenetre.configure(width = 320,height=400) + """ Classe dérivée de Fenêtre permettant la récupération d'une zone de texte sélectionnée. + Cette classe est utilisée pour affecter une liste de valeurs à un mot-clé. + """ + def __init__(self,panel,item,appli,titre="",texte="",cardinal=1): + Fenetre.__init__(self,appli,titre=titre,texte=texte) + self.frame_boutons.place_forget() + self.frame_texte.place_forget() + self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.8) + self.frame_boutons.place(relheight=0.2,relx=0,rely=0.8,relwidth=1.) + + self.cardinal=cardinal + self.fenetre.configure(width = 320,height=400) centerwindow(self.fenetre) self.panel = panel self.item = item self.fenetre.title(titre) - self.but_save.configure(text="Ajouter",command=self.traite_selection) - # séparateur par défaut - self.separateur = ";" - # création de la zone de saisie du séparateur - l_separateurs_autorises = self.get_separateurs_autorises() - self.choix_sep = Pmw.ComboBox(self.frame_boutons, - label_text = "Séparateur :", - labelpos = 'w', - listheight = 100, - selectioncommand = self.choose_separateur, - scrolledlist_items = l_separateurs_autorises) - self.choix_sep.component('entry').configure(width=6) - self.choix_sep.place(relx=0.01,rely=0.5,anchor='w') - self.choix_sep.selectitem(self.separateur) - # Replacement - self.but_quit.place_forget() - self.but_save.place_forget() - self.but_save.place(relx=0.6,rely=0.5,anchor='center') - self.but_quit.place(relx=0.8,rely=0.5,anchor='center') - - def get_separateurs_autorises(self): - """ - Retourne la liste des séparateurs autorisés - """ - return ['espace',';',','] - - def choose_separateur(self,nom_sep): - """ - Affecte à self.separateur le caractère séparateur correspondant à nom_sep - """ - if nom_sep == 'espace' : - self.separateur = ' ' - else: - self.separateur = nom_sep - - def traite_selection(self): - """ Cette méthode effectue tous les traitements nécessaires pour vérifier - et affecter la liste de valeurs à l'objet réprésenté par self.item - """ - # Récupère la liste des chaines de caractères de la zone sélectionnée - message,liste = self.recupere_liste() - if self.test_probleme(message,"Sélectionnez des données") == 0: - return - # Vérifie que le nombre de données est dans les limites attendues - message = self.verif_liste(liste) - if self.test_probleme(message,"Vérifiez le nombre de données") == 0: - return - # Crée une liste de valeurs du type attendu - message,liste_valeurs = self.creation_liste_valeurs(liste) - if self.test_probleme(message,"Vérifiez le type des données") == 0: - return - # Vérifie que chaque valeur est dans le domaine exigé - message = self.verif_valeurs(liste_valeurs) - if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0: - return - # Ajoute les valeurs dans la liste de valeurs du mot-clé - self.ajouter_valeurs(liste_valeurs) - self.appli.affiche_infos("Liste de valeurs acceptée") - - def test_probleme(self, message, message_eficas): - """ Cette méthode affiche un message d'erreur si message != '' - et retourne 0, sinon retourne 1 sans rien afficher. - """ - if message != "": - showinfo("Problème",message) - self.fenetre.tkraise() - self.appli.affiche_infos(message_eficas) - return 0 - else: - return 1 - - def recupere_liste(self): - """ Cette méthode récupère le texte de la zone sélectionnée, construit et - retourne une liste avec les chaines qui se trouvent entre les séparateurs. - S'il n'y a pas de données selectionnées, elle retourne un message d'erreur - et une liste vide. - """ - message = "" - try: - selection=self.fenetre.selection_get() - except: - message = "Pas de donnée sélectionnée" - return message,None - # les retours chariots doivent être interprétés comme des séparateurs - selection = string.replace(selection,'\n',self.separateur) - # on splitte la sélection suivant le caractère séparateur - liste_chaines = string.split(selection,self.separateur) - l_chaines = [] - for chaine in liste_chaines: - chaine = string.strip(chaine) - if chaine != '' : l_chaines.append(chaine) - return message,l_chaines - - def verif_liste(self, liste): - """ Cette méthode effectue des tests sur le nombre d'éléments de la liste - et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur - correspondant. - """ - message = "" - # nombre d'éléments sélectionnés - nombre_elements = len(liste) - # nombre d'éléments déja dans la liste du panel - nombre_in_liste = len(self.panel.Liste_valeurs.get_liste()) - multiplicite = self.item.GetMultiplicite() - if (nombre_elements % multiplicite) != 0: - message = "Vous devez sélectionner "+str(multiplicite)+" * n données" - return message - nombre_valeurs = nombre_elements / multiplicite - cardinalite = self.item.GetMinMax() - if nombre_valeurs < cardinalite[0]: - message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs" - return message - if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste): - message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs" - return message - - return message - - def creation_liste_valeurs(self, liste): - """ Cette méthode crée et retourne une liste de valeurs du type attendu - par le mot-clé. La liste de valeurs est créée à partir de la liste - de chaines de caractères transmise. - """ - type_attendu = self.item.GetType()[0] - if type_attendu == 'R': - return self.convertir(liste, f_conversion= float) - elif type_attendu == 'I': - return self.convertir(liste, f_conversion= int) - elif type_attendu == 'TXM': - return self.convertir(liste) - else: - message = "Seuls les entiers, les réels et les chaines de caractères sont convertis" - return message,None - - def convertir(self, liste, f_conversion=None): - """ Cette méthode essaie de convertir les éléments de la liste avec la - fonction f_conversion si elle existe, et retourne la liste des - éléments dans le type voulu en cas de succès, sinon retourne None. - """ - liste_valeurs = [] - message = "" - for chaine in liste: - if f_conversion: - try: - liste_valeurs.append(f_conversion(chaine)) - except: - message = "Impossible de convertir "+chaine+" dans le type attendu" - return message,None - else: - liste_valeurs.append(chaine) - return message,liste_valeurs - - def verif_valeurs(self, liste_valeurs): - """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque - élément est dans le domaine voulu. - """ - message = "" - for valeur in liste_valeurs: - test = self.item.IsInIntervalle(valeur) - if test == 0: - intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1]) - message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]" - return message - return message - - def ajouter_valeurs(self, liste_valeurs): - """ Cette méthode ajoute les nouvelles valeurs à la liste existante.""" - liste = self.panel.Liste_valeurs.get_liste() - liste.extend(liste_valeurs) + self.but_save.configure(text="Ajouter",command=self.traite_selection) + # séparateur par défaut + self.separateur = ';' + # création de la zone de saisie du séparateur + l_separateurs_autorises = self.get_separateurs_autorises() + self.choix_sep = Pmw.ComboBox(self.frame_boutons, + label_text = "Séparateur :", + labelpos = 'w', + listheight = 100, + selectioncommand = self.choose_separateur, + scrolledlist_items = l_separateurs_autorises) + self.choix_sep.component('entry').configure(width=6) + self.choix_sep.place(relx=0.01,rely=0.5,anchor='w') + self.choix_sep.selectitem(self.separateur) + # Replacement + self.but_quit.place_forget() + self.but_save.place_forget() + self.but_all = Button(self.frame_boutons,text = "Tout Sélectionner", command=self.tout) + self.but_save.place(relx=0.6,rely=0.6,anchor='center') + self.but_quit.place(relx=0.8,rely=0.6,anchor='center') + self.but_all.place(relx=0.7,rely=0.2,anchor='center') + self.choose_separateur('espace') + + + def get_separateurs_autorises(self): + """ + Retourne la liste des séparateurs autorisés + """ + return ['espace',';',','] + + def choose_separateur(self,nom_sep): + """ + Affecte à self.separateur le caractère séparateur correspondant à nom_sep + """ + if nom_sep == 'espace' : + self.separateur = ' ' + else: + self.separateur = nom_sep + + def tout(self): + liste=[] + texte=self.texte.splitlines() + for l in texte : + for mot in string.split(l,self.separateur): + if mot != '' and mot != ' ' and mot != self.separateur : + liste.append(mot) + self.traite_selection(liste) + + def traite_selection(self,liste=None): + """ Cette méthode effectue tous les traitements nécessaires pour vérifier + et affecter la liste de valeurs à l'objet réprésenté par self.item + """ + # Récupère la liste des chaines de caractères de la zone sélectionnée + message="" + if liste == None: + message,liste = self.recupere_liste() + if self.test_probleme(message,"Sélectionnez des données") == 0: + return + # Vérifie que le nombre de données est dans les limites attendues + message = self.verif_liste(liste) + if self.test_probleme(message,"Vérifiez le nombre de données") == 0: + return + # Crée une liste de valeurs du type attendu + message,liste_valeurs = self.creation_liste_valeurs(liste) + if self.test_probleme(message,"Vérifiez le type des données") == 0: + return + # Vérifie que chaque valeur est dans le domaine exigé + message = self.verif_valeurs(liste_valeurs) + if self.test_probleme(message,"Vérifiez le domaine des valeurs") == 0: + return + # Ajoute les valeurs dans la liste de valeurs du mot-clé + if self.cardinal != 1 : + nb=self.cardinal + l_valeurs=[] + # a ameliorer + if (len(liste_valeurs)%nb != 0): + message="La cardinalité n'est pas correcte" + self.test_probleme(message,"On attend des tuples") + return + for i in range(len(liste_valeurs)/nb) : + if (nb==2): + t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1]) + elif (nb ==3): + t=(liste_valeurs[i*nb], liste_valeurs[i*nb+1], liste_valeurs[i*nb+2]) + else : + print "probleme : prevenir la maintenance Eficas" + return + l_valeurs.append(t) + liste_valeurs=l_valeurs + self.ajouter_valeurs(liste_valeurs) + self.appli.affiche_infos("Liste de valeurs acceptée") + + def test_probleme(self, message, message_eficas): + """ Cette méthode affiche un message d'erreur si message != '' + et retourne 0, sinon retourne 1 sans rien afficher. + """ + if message != "": + showinfo("Problème",message) + self.fenetre.tkraise() + self.appli.affiche_infos(message_eficas) + return 0 + else: + return 1 + + def recupere_liste(self): + """ Cette méthode récupère le texte de la zone sélectionnée, construit et + retourne une liste avec les chaines qui se trouvent entre les séparateurs. + S'il n'y a pas de données selectionnées, elle retourne un message d'erreur + et une liste vide. + """ + message = "" + try: + selection=self.fenetre.selection_get() + except: + message = "Pas de donnée sélectionnée" + return message,None + # les retours chariots doivent être interprétés comme des séparateurs + selection = string.replace(selection,'\n',self.separateur) + # on splitte la sélection suivant le caractère séparateur + liste_chaines = string.split(selection,self.separateur) + l_chaines = [] + for chaine in liste_chaines: + chaine = string.strip(chaine) + if chaine != '' : l_chaines.append(chaine) + return message,l_chaines + + def verif_liste(self, liste): + """ Cette méthode effectue des tests sur le nombre d'éléments de la liste + et retourne 1 si la liste est correcte, sinon 0 et le message d'erreur + correspondant. + """ + message = "" + # nombre d'éléments sélectionnés + nombre_elements = len(liste) + # nombre d'éléments déja dans la liste du panel + nombre_in_liste = len(self.panel.Liste_valeurs.get_liste()) + multiplicite = self.item.GetMultiplicite() + if (nombre_elements % multiplicite) != 0: + message = "Vous devez sélectionner "+str(multiplicite)+" * n données" + return message + nombre_valeurs = nombre_elements / multiplicite + cardinalite = self.item.GetMinMax() + if nombre_valeurs < cardinalite[0]: + message = "Vous devez sélectionner au moins "+str(cardinalite[0])+" valeurs" + return message + if cardinalite[1] != "**" and nombre_valeurs > (long(cardinalite[1])-nombre_in_liste): + message = "La liste ne peut avoir plus de "+str(cardinalite[1])+" valeurs" + return message + + return message + + def creation_liste_valeurs(self, liste): + """ Cette méthode crée et retourne une liste de valeurs du type attendu + par le mot-clé. La liste de valeurs est créée à partir de la liste + de chaines de caractères transmise. + """ + type_attendu = self.item.GetType()[0] + if type_attendu == 'R': + return self.convertir(liste, f_conversion= float) + elif type_attendu == 'I': + return self.convertir(liste, f_conversion= int) + elif type_attendu == 'TXM': + return self.convertir(liste) + else: + message = "Seuls les entiers, les réels et les chaines de caractères sont convertis" + return message,None + + def convertir(self, liste, f_conversion=None): + """ Cette méthode essaie de convertir les éléments de la liste avec la + fonction f_conversion si elle existe, et retourne la liste des + éléments dans le type voulu en cas de succès, sinon retourne None. + """ + liste_valeurs = [] + message = "" + for chaine in liste: + if f_conversion: + try: + liste_valeurs.append(f_conversion(chaine)) + except: + message = "Impossible de convertir "+chaine+" dans le type attendu" + return message,None + else: + liste_valeurs.append(chaine) + return message,liste_valeurs + + def verif_valeurs(self, liste_valeurs): + """ Cette méthode teste tous les éléments de la liste, et retourne 1 si chaque + élément est dans le domaine voulu. + """ + message = "" + for valeur in liste_valeurs: + test = self.item.IsInIntervalle(valeur) + if test == 0: + intervalle = str(self.item.GetIntervalle()[0])+","+str(self.item.GetIntervalle()[1]) + message = "La valeur "+str(valeur)+" n'est pas dans l'intervalle ["+intervalle+"]" + return message + return message + + def ajouter_valeurs(self, liste_valeurs): + """ Cette méthode ajoute les nouvelles valeurs à la liste existante.""" + liste = self.panel.Liste_valeurs.get_liste() + liste.extend(liste_valeurs) self.panel.Liste_valeurs.put_liste(liste) +class FenetreDeParametre(Fenetre) : + def __init__(self,parent,item,appli,texte): + self.parent=parent + self.appli=appli + self.fenetre = Toplevel() + self.fenetre.configure(width = 250,height=100) + self.fenetre.protocol("WM_DELETE_WINDOW", self.quit) + self.fenetre.title("Parametres") + self.titre = "Parametres" + self.texte = string.replace(texte,'\r\n','\n') + fonte=fontes.standardcourier10 + + # définition des frames + self.frame_texte = Frame(self.fenetre) + self.frame_texte.place(relx=0,rely=0,relwidth=1,relheight=0.7) + # définition de la zone texte et du scrollbar + self.zone_texte = Text(self.frame_texte,font=fonte) + self.zone_texte.bind("", self.page_up) + self.zone_texte.bind("", self.page_down) + self.zone_texte.bind("", self.unit_up) + self.zone_texte.bind("", self.unit_down) + self.scroll_v = Scrollbar (self.frame_texte,command = self.zone_texte.yview) + self.scroll_v.pack(side='right',fill ='y') + self.zone_texte.pack(side='top',fill='both',expand=1,padx=5,pady=10) + self.zone_texte.configure(yscrollcommand=self.scroll_v.set) + # affichage du texte + self.affiche_texte(self.texte) + self.zone_texte.config(state="disabled") + + # définition des boutons + self.frame_boutons = Frame(self.fenetre) + self.frame_boutons.place(relheight=0.3,relx=0,rely=0.65,relwidth=1.) + self.label1 = Label(self.frame_boutons,text="surligner la") + self.label2 = Label(self.frame_boutons,text="ligne entière") + self.label1.place(relx=0.1,rely=0) + self.label2.place(relx=0.1,rely=0.5) + self.but_quit = Button(self.frame_boutons,text = "Fermer",command=self.quit) + self.but_save = Button(self.frame_boutons,text = "Choisir",command = self.Choisir) + self.but_save.place(relx=0.6,rely=0,relheight=1) + self.but_quit.place(relx=0.8,rely=0,relheight=1) + + + def Choisir(self): + try: + selection=self.zone_texte.selection_get() + except: + showerror("Pas de donnée sélectionnée", + "Selectionner un parametre") + l_param = "" + for param in selection.splitlines(): + nomparam=param[0:param.find("=")-1] + if nomparam != '' : + l_param=l_param+nomparam+',' + self.parent.entry.delete(0,Tkinter.END) + self.parent.entry.insert(0,l_param[0:-1]) + self.parent.valid_valeur() + self.quit() + class Formulaire: - """ + """ Cette classe permet de créer une boîte Dialog dans laquelle - on affiche un formulaire à remplir par l'utilisateur + on affiche un formulaire à remplir par l'utilisateur """ - def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None): + def __init__(self,fen_pere,obj_pere=None,titre="",texte="",items=(),mode='query',commande=None): if items in ((),[]) : return self.items = items self.titre = titre @@ -318,25 +482,25 @@ class Formulaire: self.command = commande self.display() - def display(self): + def display(self): self.init_validateurs() self.init_fenetre() self.init_texte() self.init_items_formulaire() self.fenetre.activate(geometry='centerscreenalways') - - def init_validateurs(self): - """ - Crée le dictionnaire des validateurs des objets reconnus par le formulaire - """ - self.d_validateurs = {} - self.d_validateurs['rep'] = self.repvalidator - self.d_validateurs['file'] = self.filevalidator - self.d_validateurs['cata']= self.catavalidator + + def init_validateurs(self): + """ + Crée le dictionnaire des validateurs des objets reconnus par le formulaire + """ + self.d_validateurs = {} + self.d_validateurs['rep'] = self.repvalidator + self.d_validateurs['file'] = self.filevalidator + self.d_validateurs['cata']= self.catavalidator - def init_fenetre(self): - """ - Crée la fenêtre Dialog + def init_fenetre(self): + """ + Crée la fenêtre Dialog """ if self.mode == 'query': buttons=('Valider','Annuler') @@ -352,118 +516,118 @@ class Formulaire: buttons=buttons, defaultbutton = defaultbutton, title = self.titre, - command = self.execute) + command = self.execute) self.fenetre.withdraw() - def init_texte(self): - """ - Crée le label qui affiche le texte à l'intérieur du panneau + def init_texte(self): + """ + Crée le label qui affiche le texte à l'intérieur du panneau """ - fonte=fontes.standard - fr_texte = Frame(self.fenetre.interior(),height=60) + fonte=fontes.standard + fr_texte = Frame(self.fenetre.interior(),height=60) fr_texte.pack(side='top',fill='x',expand=1) Label(fr_texte,text = self.texte, font=fonte).place(relx=0.5,rely=0.5,anchor='center') - - def init_items_formulaire(self): - """ - Crée et affiche les items dans la boîte de dialogue - """ - self.radiobut = 0 - self.widgets = [] - self.item_widgets = {} - length_maxi = 0 + + def init_items_formulaire(self): + """ + Crée et affiche les items dans la boîte de dialogue + """ + self.radiobut = 0 + self.widgets = [] + self.item_widgets = {} + length_maxi = 0 for item in self.items: - if len(item[0])>length_maxi : length_maxi = len(item[0]) - window = self.fenetre.interior() - for item in self.items : - label,nature,nom_var,defaut = item - # création de la frame - fr_item = Frame(window,height=40,width=700) - fr_item.pack(side='top',fill='x',expand=1) - # création du label - Label(fr_item,text = label).place(relx=0.05,rely=0.4) + if len(item[0])>length_maxi : length_maxi = len(item[0]) + window = self.fenetre.interior() + for item in self.items : + label,nature,nom_var,defaut = item + # création de la frame + fr_item = Frame(window,height=40,width=700) + fr_item.pack(side='top',fill='x',expand=1) + # création du label + Label(fr_item,text = label).place(relx=0.05,rely=0.4) if nature in ('rep','file','cata'): - # création de l'entry - e_item = Entry(fr_item) - e_item.place(relx=0.5,rely=0.4,relwidth=0.45) - self.widgets.append(e_item) - self.item_widgets[item] = e_item - if defaut : e_item.insert(0,str(defaut)) - elif nature == 'YesNo': - # création de la StringVar - var = StringVar() - setattr(self,'item_'+nom_var,var) - var.set(defaut) - # création du radiobouton - rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI') - rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON') - rb1.place(relx=0.65,rely=0.5,anchor='center') - rb2.place(relx=0.80,rely=0.5,anchor='center') - self.widgets.append((rb1,rb2)) - self.item_widgets[item] = var - # détermination de la méthode à appliquer sur les boutons - if self.mode == 'query': - function = self.active - elif self.mode == 'display': - function = self.inactive - else: - return - # on applique la méthode sur les boutons (activation ou désactivation) - for widget in self.widgets : - if type(widget) == types.TupleType: - for widg in widget : - apply(function,(widg,),{}) - else: - apply(function,(widget,),{}) - - def active(self,widget): - """ - Active le widget passé en argument - """ - widget.configure(state='normal',bg='white') - - def inactive(self,widget): - """ - Inactive le widget passé en argument - """ - if not isinstance(widget,Radiobutton) : - widget.configure(state='disabled',bg='gray95') - else : - widget.configure(state='disabled') - -# -------------------------------------------------------------------------------- -# Validateurs des noms de répertoire, de fichiers et de catalogues -# -------------------------------------------------------------------------------- + # création de l'entry + e_item = Entry(fr_item) + e_item.place(relx=0.5,rely=0.4,relwidth=0.45) + self.widgets.append(e_item) + self.item_widgets[item] = e_item + if defaut : e_item.insert(0,str(defaut)) + elif nature == 'YesNo': + # création de la StringVar + var = StringVar() + setattr(self,'item_'+nom_var,var) + var.set(defaut) + # création du radiobouton + rb1 = Radiobutton(fr_item,text='OUI',variable=var,value='OUI') + rb2 = Radiobutton(fr_item,text='NON',variable=var,value='NON') + rb1.place(relx=0.65,rely=0.5,anchor='center') + rb2.place(relx=0.80,rely=0.5,anchor='center') + self.widgets.append((rb1,rb2)) + self.item_widgets[item] = var + # détermination de la méthode à appliquer sur les boutons + if self.mode == 'query': + function = self.active + elif self.mode == 'display': + function = self.inactive + else: + return + # on applique la méthode sur les boutons (activation ou désactivation) + for widget in self.widgets : + if type(widget) == types.TupleType: + for widg in widget : + apply(function,(widg,),{}) + else: + apply(function,(widget,),{}) + + def active(self,widget): + """ + Active le widget passé en argument + """ + widget.configure(state='normal',bg='white') + + def inactive(self,widget): + """ + Inactive le widget passé en argument + """ + if not isinstance(widget,Radiobutton) : + widget.configure(state='disabled',bg='gray95') + else : + widget.configure(state='disabled') + +# -------------------------------------------------------------------------------- +# Validateurs des noms de répertoire, de fichiers et de catalogues +# ------------------------------------------------------------------------------- def repvalidator(self,text): - """ - Teste si text peut faire référence à un répertoire ou non - Retourne 1 si valide, 0 sinon - """ + """ + Teste si text peut faire référence à un répertoire ou non + Retourne 1 si valide, 0 sinon + """ return os.path.isdir(text),'Répertoire introuvable : %s' %text def filevalidator(self,text): - """ - Teste si text peut faire référence à un fichier ou non - Retourne 1 si valide, 0 sinon - """ + """ + Teste si text peut faire référence à un fichier ou non + Retourne 1 si valide, 0 sinon + """ return os.path.isfile(text),'Fichier introuvable : %s' %text - - def catavalidator(self,text): - """ - Teste si text est un chemin d'accès valide à un catalogue - Retourne 1 si valide, 0 sinon - """ - return os.path.isfile(text),"Catalogue introuvable : %s" %text - -# -------------------------------------------------------------------------------- -# Méthodes callbacks des boutons et de fin -# -------------------------------------------------------------------------------- + + def catavalidator(self,text): + """ + Teste si text est un chemin d'accès valide à un catalogue + Retourne 1 si valide, 0 sinon + """ + return os.path.isfile(text),"Catalogue introuvable : %s" %text + +# -------------------------------------------------------------------------------- +# Méthodes callbacks des boutons et de fin +# -------------------------------------------------------------------------------- - def execute(self,txt): - """ - Cette commande est activée à chaque clic sur un bouton. - Redirige l'action sur la bonne méthode en fonction du bouton activé + def execute(self,txt): + """ + Cette commande est activée à chaque clic sur un bouton. + Redirige l'action sur la bonne méthode en fonction du bouton activé """ if txt == 'Valider': self.fini() @@ -476,26 +640,26 @@ class Formulaire: print "Nom de bouton inconnu" self.quit() - def fini(self): - """ - Commande qui termine le panneau et sauvegarde les nouvelles options - dans l'objet resultat (dictionnaire) + def fini(self): + """ + Commande qui termine le panneau et sauvegarde les nouvelles options + dans l'objet resultat (dictionnaire) """ dico={} - for item,widget in self.item_widgets.items(): - nom_var = item[2] + for item,widget in self.item_widgets.items(): + nom_var = item[2] type_var = item[1] - valeur = widget.get() - if self.d_validateurs.has_key(type_var): - test = self.d_validateurs[type_var](valeur) - if not test : - # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode - # sans tuer la fenêtre bien sûr - widget.selection_range(0,END) + valeur = widget.get() + if self.d_validateurs.has_key(type_var): + test = self.d_validateurs[type_var](valeur) + if not test : + # une entrée n'est pas valide --> on la met en surbrillance et on quitte la méthode + # sans tuer la fenêtre bien sûr + widget.selection_range(0,END) return dico[nom_var] = valeur self.fenetre.destroy() - self.resultat=dico + self.resultat=dico def quit(self): self.fenetre.destroy() @@ -504,7 +668,7 @@ class Formulaire: class ListeChoix : """ Cette classe est utilisée pour afficher une liste de choix passée en paramètre en passant les commandes à lancer suivant différents bindings """ - def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre=''): + def __init__(self,parent,page,liste,liste_commandes=[],liste_marques =[],active ='oui',filtre='non',titre='',optionReturn=None): self.parent = parent self.page = page self.liste = liste @@ -516,6 +680,7 @@ class ListeChoix : self.active = active self.titre = titre self.filtre = filtre + self.optionReturn = optionReturn self.init() def init(self): @@ -552,9 +717,10 @@ class ListeChoix : self.MCbox.pack(fill='y',expand=1,padx=2,pady=2) self.MCbox.configure(yscrollcommand=self.MCscroll.set) + def affiche_liste(self): """ Affiche la liste dans la fenêtre""" - i=0 + liste_labels=[] self.MCbox.config(state=NORMAL) self.MCbox.delete(1.0,END) for objet in self.liste : @@ -566,37 +732,104 @@ class ListeChoix : elif type(objet) in (types.StringType,types.IntType): mot = objet elif type(objet) == types.FloatType : - mot = repr_float(objet) + mot = self.parent.get_valeur_texte(objet) + if mot == "" : + mot = str(objet) + elif type(objet) == types.TupleType : + mot="(" + premier=1 + for val in objet: + if (not premier): + mot=mot+"," + else: + premier=0 + valtexte = self.parent.get_valeur_texte(val) + if valtexte != "" : + mot=mot+valtexte + else: + mot=mot+str(val) + mot=mot+")" else: mot=`objet` label = Label(self.MCbox, text = mot, fg = 'black',bg = 'gray95',justify = 'left') self.dico_labels[mot]=label + liste_labels.append(label) self.MCbox.window_create(END, window=label, stretch = 1) self.MCbox.insert(END,'\n') + if self.optionReturn != None : + label.bind("",lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitemsurligne(x,l,c)) + label.bind("",lambda e,s=self,x=objet,l=label : s.selectNextItem(x,l)) if self.active == 'oui': label.bind(self.liste_commandes[0][0],lambda e,s=self,c=self.liste_commandes[0][1],x=objet,l=label : s.selectitem(x,l,c)) label.bind(self.liste_commandes[1][0],lambda e,s=self,c=self.liste_commandes[1][1],x=objet,l=label : s.deselectitem(l,x,c)) label.bind(self.liste_commandes[2][0],lambda e,s=self,c=self.liste_commandes[2][1],x=objet,l=label : s.chooseitem(x,l,c)) - try : - self.liste_marques.index(i) - self.markitem(label) - except: + + for marque in self.liste_marques: + try: + self.markitem(liste_labels[marque]) + except: pass - i=i+1 + self.MCbox.config(state=DISABLED) self.selection = None + def clear_marque(self): + try: + self.dico_labels[self.arg_selected].configure(bg='gray95',fg='black') + self.arg_selected = '' + except : + pass + + def surligne(self,marque): + try : + self.highlightitem(self.dico_labels[marque]) + self.arg_selected = marque + except: + pass + + def chooseitemsurligne(self,mot,label,commande): + """ Active la méthode de choix passée en argument""" + try: + mot=self.arg_selected + commande(mot) + except AsException,e: + raison=str(e) + showerror(raison.split('\n')[0],raison) + def chooseitem(self,mot,label,commande): """ Active la méthode de choix passée en argument""" - commande(mot) + try: + commande(mot) + except AsException,e: + raison=str(e) + showerror(raison.split('\n')[0],raison) + + def selectNextItem(self,mot,label): + try : + index=self.liste.index(mot) + indexsuivant=index+1 + motsuivant=self.liste[indexsuivant] + labelsuivant=self.dico_labels[motsuivant] + self.clear_marque() + if self.selection != None : + self.deselectitem(self.selection[1],self.selection[0],self.selection[2],) + self.selection = (mot,label,self.selection[2]) + self.highlightitem(labelsuivant) + self.arg_selected=motsuivant + labelsuivant.focus_set() + # PN il faut faire quelque chose pour être dans la fenetre + except: + pass + def selectitem(self,mot,label,commande) : """ Met l'item sélectionné (représenté par son label) en surbrillance et lance la commande associée au double-clic""" + self.clear_marque() if self.selection != None : self.deselectitem(self.selection[1],self.selection[0],self.selection[2],) self.highlightitem(label) @@ -618,6 +851,17 @@ class ListeChoix : self.arg_selected = '' if commande != None : commande(mot) + def cherche_selected_item(self): + index=self.MCbox.index(self.selection[1]) + lign,col=map(int,string.split(index,'.')) + return lign + + def remove_selected_item(self): + index=self.MCbox.index(self.selection[1]) + lign,col=map(int,string.split(index,'.')) + del self.liste[lign-1] + self.affiche_liste() + def entry_changed(self,event=None): """ Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu de l'entry et frappe """ @@ -631,24 +875,32 @@ class ListeChoix : self.MCbox.see(index) self.arg_selected = arg break + try : + self.dico_labels[self.arg_selected].focus_set() + except : + pass def get_liste_old(self): return self.liste + # PN attention à la gestion des paramétres + # cela retourne H = 1 , et ni H, ni 1 + # print repr(val) + # print val.__class__.__name__ def get_liste(self): l=[] for val in self.liste: - try: - val = eval(val) - l.append(val) - except: +# try: +# v = eval(val) +# l.append(v) +# except: l.append(val) return l def put_liste(self,liste): self.liste = liste self.affiche_liste() - + class Affichage : """ Cette classe permet d'afficher au lancement d'EFICAS le message d'attente et la barre de progression""" @@ -702,9 +954,9 @@ class Affichage : self.progress.update() class Ask_Format_Fichier : - """ + """ Cette classe permet de créer une fenêtre Toplevel dans laquelle - on propose le choix du format de fichier de commandes à ouvrir + on propose le choix du format de fichier de commandes à ouvrir """ def __init__(self,appli): self.fenetre = Toplevel() @@ -818,3 +1070,106 @@ class BARRE_K2000(Toplevel): def quit(self): self.quit = 1 + +class ListeChoixParGroupes(ListeChoix) : + """ + Cette classe est utilisée pour afficher une liste de commandes classées par + groupes. L'utilisateur peut réaliser des actions de selection + qui déclenchent des actions spécifiées par les bindings contenus dans liste_commandes + """ + def __init__(self,parent,page,liste_groupes,dict_groupes,liste_commandes=[],liste_marques =[], + active ='oui',filtre='non',titre=''): + self.parent = parent + self.page = page + self.liste_groupes = liste_groupes + self.dict_groupes = dict_groupes + self.dico_labels={} + self.selection = None + self.liste_commandes = liste_commandes + self.liste_marques = liste_marques + self.arg_selected='' + self.active = active + self.titre = titre + self.filtre = filtre + self.init() + + def affiche_liste(self): + """ Affiche la liste dans la fenêtre""" + liste_labels=[] + self.MCbox.config(state=NORMAL) + self.MCbox.delete(1.0,END) + for grp in self.liste_groupes: + # On itère sur les groupes + if grp == "CACHE":continue + liste_commandes=self.dict_groupes[grp] + text="GROUPE<<<<<<<< "+grp+" " + text=text+">"*max(0,30-len(text)) + label = Label(self.MCbox, + text = text, + fg = 'black',bg = 'gray95',justify = 'left') + # On stocke la relation entre le nom de la commande et le label + self.dico_labels[grp]=label + liste_labels.append(label) + self.MCbox.window_create(END, + window=label, + stretch = 1) + self.MCbox.insert(END,'\n') + for cmd in liste_commandes: + label = Label(self.MCbox, + text = cmd, + fg = 'black',bg = 'gray95',justify = 'left') + # On stocke la relation entre le nom de la commande et le label + self.dico_labels[cmd]=label + self.MCbox.window_create(END, + window=label, + stretch = 1) + self.MCbox.insert(END,'\n') + if self.active == 'oui': + label.bind(self.liste_commandes[0][0], + lambda e,s=self,c=self.liste_commandes[0][1],x=cmd,l=label : s.selectitem(x,l,c)) + label.bind(self.liste_commandes[1][0], + lambda e,s=self,c=self.liste_commandes[1][1],x=cmd,l=label : s.deselectitem(l,x,c)) + label.bind(self.liste_commandes[2][0], + lambda e,s=self,c=self.liste_commandes[2][1],x=cmd,l=label : s.chooseitem(x,l,c)) + label.bind("", self.selectNextItem(event)) + + for marque in self.liste_marques: + try: + self.markitem(liste_labels[marque]) + except: + pass + + self.MCbox.config(state=DISABLED) + self.selection = None + + def entry_changed(self,event=None): + """ + Cette méthode est invoquée chaque fois que l'utilisateur modifie le contenu + de l'entry et frappe + """ + if self.arg_selected != '' : self.deselectitem(self.dico_labels[self.arg_selected]) + filtre = self.entry.get()+"*" + FILTRE = string.upper(filtre) + # + # On cherche d'abord dans les noms de groupe + # puis dans les noms de commande groupe par groupe + # + for grp in self.liste_groupes: + if fnmatch.fnmatch(grp,filtre) or fnmatch.fnmatch(grp,FILTRE) : + index = self.MCbox.index(self.dico_labels[grp]) + self.MCbox.see(index) + # On ne selectionne pas le groupe + #self.arg_selected = grp + # On a trouve un groupe on arrete la recherche + return + + for grp in self.liste_groupes: + for cmd in self.dict_groupes[grp] : + if fnmatch.fnmatch(cmd,filtre) or fnmatch.fnmatch(cmd,FILTRE) : + self.highlightitem(self.dico_labels[cmd]) + index = self.MCbox.index(self.dico_labels[cmd]) + self.MCbox.see(index) + self.arg_selected = cmd + # On a trouve une commande on arrete la recherche + return +