class ShellFrame(wx.Panel): def __init__(self, parent=None, id=-1, locals=None): wx.Panel.__init__(self, parent, id) self.shell = Shell(parent=self, locals=locals) #self.crust= Crust(parent=self,locals=locals) #self.shell = self.crust.shell #self.shell.SetSize(wxSize(800,100)) EVT_SIZE(self, self.OnSize) def OnSize(self, event): self.shell.SetSize(self.GetClientSizeTuple())
class FenetrePrincipale(wx.Frame): def __init__(self, config): wx.Frame.__init__(self, None, id=wx.ID_ANY, title=tourbillon.__nom__, size=(640, 400), style=wx.DEFAULT_FRAME_STYLE) self.SetBackgroundColour(images.couleur('grille')) self.config = config # Création d'un gestionnaire de fenetres pour la gestion des fenêtres flottantes self._mgr = aui.AuiManager( self, aui.AUI_MGR_ALLOW_FLOATING | aui.AUI_MGR_TRANSPARENT_HINT | aui.AUI_MGR_TRANSPARENT_DRAG | aui.AUI_MGR_ALLOW_ACTIVE_PANE) # Fenêtre informations montrée self.fenetre_affichage = dlginfo.DialogueInformations( self, self.config) self.affichage_visible = False self.fenetre_affichage.Bind(wx.EVT_CLOSE, self.masquer_info) # Icon self.SetIcon(images.TourBillon_icon()) # Créer la barre de menu self.barre_menu = barres.BarreMenu(self) self.SetMenuBar(self.barre_menu) # Créer la barre de statut self.barre_etat = barres.BarreEtat(self) self.SetStatusBar(self.barre_etat) # Créer la barre des boutons (pas la guerre) self.barre_bouton = barres.BarreBouton(self) self._mgr.AddPane( self.barre_bouton, aui.AuiPaneInfo().Name("controles").Top().CaptionVisible( False).MinSize(wx.Size(-1, 60)).DockFixed().Floatable(False)) # Créer la grille if self.config.get_typed('INTERFACE', 'image'): chemin_image = glob(configdir('fond_perso*'))[0] else: chemin_image = "" self.grille = grl.GrillePanel(self, images.bitmap(chemin_image)) self.barre_menu.FindItemById(barres.ID_STATISTIQUES).Check( self.config.get_typed('INTERFACE', 'afficher_statistiques')) self.afficher_statistiques(None) self._mgr.AddPane(self.grille, aui.AuiPaneInfo().Name("grille").CenterPane()) # Creation d'un shell Python (utile pour le debug) self.shell = Shell(self, introText='', locals={ 'intf': self, 'trb': tournoi.tournoi(), 'cfg': self.config, 'cst': cst }, InterpClass=None, startupScript=None, execStartupScript=True) self.shell.SetSize((600, 200)) self._mgr.AddPane( self.shell, aui.AuiPaneInfo().Name('shell').Caption("Python Shell").Bottom(). CloseButton(True).MaximizeButton(True).Hide()) self.barre_menu.FindItemById(barres.ID_SHELL).Check( self.config.get_typed('INTERFACE', 'afficher_shell')) self.afficher_shell(None) # Effectuer les connections sur les evenements # ... de la barre de menu self.Bind(wx.EVT_MENU, self.nouveau, id=wx.ID_NEW) self.Bind(wx.EVT_MENU, self.ouvrir_demande, id=wx.ID_OPEN) self.Bind(wx.EVT_MENU, self.enregistrer, id=wx.ID_SAVE) self.Bind(wx.EVT_MENU, self.enregistrer_sous, id=wx.ID_SAVEAS) self.Bind(wx.EVT_MENU, self.apercu_avant_impression, id=wx.ID_PREVIEW_PRINT) self.Bind(wx.EVT_MENU, self.imprimer, id=wx.ID_PRINT) self.Bind(wx.EVT_MENU, self.quitter, id=wx.ID_EXIT) self.Bind(wx.EVT_MENU, self.afficher_statistiques, id=barres.ID_STATISTIQUES) self.Bind(wx.EVT_MENU, self.afficher_info, id=barres.ID_INFO) self.Bind(wx.EVT_MENU, self.afficher_tirage, id=barres.ID_TIRAGE) self.Bind(wx.EVT_MENU, self.afficher_shell, id=barres.ID_SHELL) self.Bind(wx.EVT_MENU, self.nouvelle_equipe, id=barres.ID_NOUVELLE_E) self.Bind(wx.EVT_MENU, self.modifier_equipe, id=barres.ID_MODIFIER_E) self.Bind(wx.EVT_MENU, self.supprimer_equipe, id=barres.ID_SUPPRIMER_E) self.Bind(wx.EVT_MENU, self.nouvelle_partie, id=barres.ID_NOUVELLE_P) self.Bind(wx.EVT_MENU, self.supprimer_partie, id=barres.ID_SUPPRIMER_P) self.Bind(wx.EVT_MENU, self.entrer_resultats, id=barres.ID_RESULTATS) self.Bind(wx.EVT_MENU, self.classement, id=barres.ID_CLASSEMENT) self.Bind(wx.EVT_MENU, self.preferences, id=wx.ID_PREFERENCES) self.Bind(wx.EVT_MENU, self.info_systeme, id=wx.ID_PROPERTIES) self.Bind(wx.EVT_MENU, self.a_propos_de, id=wx.ID_ABOUT) # ... de la barre de contrôle self.Bind(wx.EVT_BUTTON, self.afficher_partie_prec, self.barre_bouton.btn_precedente) self.Bind(wx.EVT_BUTTON, self.afficher_partie_suiv, self.barre_bouton.btn_suivante) self.Bind(wx.EVT_BUTTON, self.enregistrer, id=wx.ID_SAVE) self.Bind(wx.EVT_BUTTON, self.afficher_info, id=barres.ID_INFO) self.Bind(wx.EVT_BUTTON, self.afficher_tirage, id=barres.ID_TIRAGE) self.Bind(wx.EVT_BUTTON, self.nouvelle_equipe, id=barres.ID_NOUVELLE_E) self.Bind(wx.EVT_BUTTON, self.nouvelle_partie, id=barres.ID_NOUVELLE_P) self.Bind(wx.EVT_BUTTON, self.entrer_resultats, id=barres.ID_RESULTATS) self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, self.grille.rechercher_suivant, id=wx.ID_FIND) self.Bind(wx.EVT_TEXT_ENTER, self.grille.rechercher_suivant, id=wx.ID_FIND) self.Bind(wx.EVT_TEXT, self.grille.rechercher, id=wx.ID_FIND) self.Bind(evt.EVT_MENU_RECHERCHE, self.grille.chg_recherche_colonne, self.barre_bouton) # ... des autres événements self.Bind(wx.EVT_CLOSE, self.quitter) self.Bind(aui.EVT_AUI_PANE_CLOSE, self.masquer_shell) self.Bind(evt.EVT_RAFRAICHIR, self.rafraichir) self.grille.Bind(grl.grid.EVT_GRID_CELL_LEFT_DCLICK, self.grille_double_click) self.grille.Bind(grl.grid.EVT_GRID_CELL_RIGHT_CLICK, self.grille_contexte) self.grille.Bind(wx.EVT_KEY_DOWN, self.grille_enter) # Rafraichir self._mgr.Update() self.Layout() wx.PostEvent(self, evt.RafraichirEvent(self.GetId())) def grille_enter(self, event): """ Ouvre le fenêtre correspondant à l'activitée en cours pour l'équipe selectionnée si la touche [ENTER] et pressée (voir la fonction 'grille_double_click' pour plus de details). """ if event.GetKeyCode() == wx.WXK_RETURN: self.grille_double_click(event) else: event.Skip() def grille_double_click(self, event): """ Ouvre le fenêtre correspondant à l'activitée en cours pour l'équipe selectionnée: - "Ajout de Joueur" si le tournoi n'est pas commencé - "Entrer les Résultats" si le tournoi est commencé """ if tournoi.tournoi() is not None: if self.grille.selection() is not None: statut = tournoi.tournoi().statut if statut == cst.T_INSCRIPTION or ( statut == cst.T_ATTEND_TIRAGE and tournoi.tournoi().nb_parties() == 0): self.modifier_equipe(event) else: self.entrer_resultats(event) def grille_contexte(self, event): """ Ouvre le menu contextuel """ if tournoi.tournoi() is not None: if self.grille.selection() is not None: menu = barres.cree_contexte_menu() self.PopupMenu( menu, wx.GetMousePosition() - self.GetPosition() - (self.grille.GetPosition().x / 2, self.grille.GetPosition().y / 2)) menu.Destroy() def rafraichir(self, event): """ Appelle la methode 'rafraichir' de chaque widget qui a besoin de l'être. """ t = tournoi.tournoi() # Titre if tournoi.FICHIER_TOURNOI is not None: self.SetTitle("%s - %s" % (tourbillon.__nom__, tournoi.FICHIER_TOURNOI)) else: self.SetTitle(tourbillon.__nom__) # Barre de menu if event.quoi == 'menu' or event.quoi == 'tout': if t is None: nom = '' else: nom = 'Tournoi du %s' % t.debut.strftime('%d/%m/%Y') self.barre_menu._rafraichir() self.barre_bouton._rafraichir(nom) # Barre d'état if event.quoi == 'etat' or event.quoi == 'tout': if t is None: self.barre_etat._rafraichir('', 0, 0, 0, False) else: # Indication équipe incomplète nb_incompletes = 0 num_partie = self.barre_bouton.numero() if self.barre_bouton.numero() > 0: for equipe in tournoi.tournoi().partie( num_partie).equipes(): if equipe.resultat(num_partie).etat is None: nb_incompletes += 1 self.barre_etat._rafraichir( t.debut.strftime('%Hh%M'), t.nb_parties(), t.nb_equipes(), nb_incompletes / tournoi.tournoi().equipes_par_manche, t.modifie) p = self.barre_bouton.numero() # Limite de raffraichissement limite = None if self.config.get_typed('INTERFACE', 'CUMULE_STATISTIQUES') == 1: limite = p # Equipes if event.quoi == 'tout': if tournoi.tournoi() is None: self.grille._rafraichir() else: for equipe in tournoi.tournoi().equipes(): self.grille._rafraichir(equipe=equipe, partie=p, partie_limite=limite) elif event.quoi.startswith('equipe'): num = int(event.quoi.split('_')[1]) self.grille._rafraichir(equipe=tournoi.tournoi().equipe(num), partie=p, partie_limite=limite) # Classement if event.quoi == 'classement' or event.quoi == 'tout': if tournoi.tournoi() is not None: avec_victoires = self.config.get_typed('TOURNOI', 'CLASSEMENT_VICTOIRES') avec_joker = self.config.get_typed('TOURNOI', 'CLASSEMENT_JOKER') avec_duree = self.config.get_typed('TOURNOI', 'CLASSEMENT_DUREE') self.grille._rafraichir( classement=tournoi.tournoi().classement( avec_victoires, avec_joker, avec_duree, limite)) else: self.grille._rafraichir(classement={}) # Informations if t is not None: try: self.fenetre_affichage._rafraichir(t.statut) except wx._core.PyAssertionError: # HACK wxpython 3.0 sur Windows 8.1: wxTextMeasure::BeginMeasuring() # must not be used with non-native wxDCs # A resoudre, mais comment????? logger.info( "Je ne peux pas rafraichir la fenêtre d'information aux joueurs (wxpython + Windows bug)" ) # fond if event.quoi == 'fond': if self.config.get_typed('INTERFACE', 'image'): chemin_image = glob(configdir('fond_perso*'))[0] else: chemin_image = "" self.grille.chg_fond(images.bitmap(chemin_image)) def nouveau(self, event): ret = self.enregister_demande() if ret != wx.ID_CANCEL: if self.config.get_typed("INTERFACE", 'NOUVEAU_AFFICHE_PREFERENCES'): ret = self.preferences(evt.PreferencesEvent(self.GetId(), 1)) else: ret = wx.ID_OK if ret == wx.ID_OK: self.shell.interp.locals['trb'] = tournoi.nouveau_tournoi( self.config.get_typed("TOURNOI", "EQUIPES_PAR_MANCHE"), self.config.get_typed("TOURNOI", "POINTS_PAR_MANCHE"), self.config.get_typed("TOURNOI", "JOUEURS_PAR_EQUIPE")) # Rafraichir self.grille.effacer() self.barre_bouton.chg_partie() wx.PostEvent(self, evt.RafraichirEvent(self.GetId())) logger.info(u"Il est %s, un nouveau tournoi commence..." % tournoi.tournoi().debut.strftime('%Hh%M')) def ouvrir_demande(self, event): """ Demander à l'utilisateur quel fichier il souhaite ouvrir. """ ret = self.enregister_demande() if ret != wx.ID_CANCEL: if tournoi.FICHIER_TOURNOI is not None: l = os.path.split(tournoi.FICHIER_TOURNOI) d = l[0] f = l[1] else: d = self.config.get('INTERFACE', 'ENREGISTREMENT') f = '' dlg = wx.FileDialog(self, message="Ouvrir", defaultDir=d, defaultFile=f, wildcard=FILTRE_FICHIER, style=wx.OPEN) ret = dlg.ShowModal() if ret == wx.ID_OK: fichier = dlg.GetPath() self.ouvrir(fichier) dlg.Destroy() def ouvrir(self, fichier): self.shell.interp.locals['trb'] = tournoi.charger_tournoi(fichier) # Rafraichir self.barre_bouton.chg_partie(tournoi.tournoi().nb_parties()) self.grille.effacer() self.grille.ajout_equipe(*tournoi.tournoi().equipes()) wx.PostEvent(self, evt.RafraichirEvent(self.GetId())) self.SetTitle("%s - %s" % (tourbillon.__nom__, fichier)) logger.info(u"Chargé, prêt à jouer mon commandant!") def enregister_demande(self): """ Demander à l'utilisateur s'il veux enregristrer le tournoi courrant. """ continuer = wx.ID_OK if tournoi.tournoi() is not None: if tournoi.tournoi().modifie: dlg = wx.MessageDialog( self, u"Le tournoi en cours n'est pas enregistré, si vous cliquez sur NON, les données seront perdues.", caption=u"Voulez-vous enregistrer le tournoi en cours?", style=wx.CANCEL | wx.YES | wx.NO | wx.ICON_QUESTION) ret = dlg.ShowModal() dlg.Destroy() if ret == wx.ID_YES: continuer = self.enregistrer_sous(None) elif ret == wx.ID_CANCEL: continuer = wx.ID_CANCEL return continuer def enregistrer(self, event): if tournoi.FICHIER_TOURNOI is None: self.enregistrer_sous(event) else: tournoi.enregistrer_tournoi() # Rafraichir wx.PostEvent(self, evt.RafraichirEvent(self.GetId(), 'etat')) def enregistrer_auto(self): if self.config.get_typed( 'INTERFACE', 'ENREGISTREMENT_AUTO') and tournoi.FICHIER_TOURNOI is not None: self.enregistrer(None) def enregistrer_sous(self, event): if tournoi.FICHIER_TOURNOI is not None: l = os.path.split(tournoi.FICHIER_TOURNOI) d = l[0] f = l[1] else: d = self.config.get('INTERFACE', 'ENREGISTREMENT') f = u"tournoi_billon_%s.yml" % datetime.now().strftime('%d/%m/%Y') dlg = wx.FileDialog(self, message="Enregistrer", defaultDir=d, defaultFile=f, wildcard=FILTRE_FICHIER, style=wx.SAVE) ret = dlg.ShowModal() if ret == wx.ID_OK: fichier = dlg.GetPath() _p, ext = os.path.splitext(fichier) if ext not in ['.trb', '.yml']: fichier += '.yml' tournoi.enregistrer_tournoi(fichier) # Rafraichir wx.PostEvent(self, evt.RafraichirEvent(self.GetId(), 'etat')) logger.info(u"C'est dans la boîte.") dlg.Destroy() return ret def apercu_avant_impression(self, event): avec_victoires = self.config.get_typed('TOURNOI', 'CLASSEMENT_VICTOIRES') avec_joker = self.config.get_typed('TOURNOI', 'CLASSEMENT_JOKER') avec_duree = self.config.get_typed('TOURNOI', 'CLASSEMENT_DUREE') dlg = dlgim.DialogueImprimer( self, tournoi.tournoi().classement(avec_victoires, avec_joker, avec_duree)) dlg.Preview() def imprimer(self, event): avec_victoires = self.config.get_typed('TOURNOI', 'CLASSEMENT_VICTOIRES') avec_joker = self.config.get_typed('TOURNOI', 'CLASSEMENT_JOKER') avec_duree = self.config.get_typed('TOURNOI', 'CLASSEMENT_DUREE') dlg = dlgim.DialogueImprimer( self, tournoi.tournoi().classement(avec_victoires, avec_joker, avec_duree)) dlg.Print() def quitter(self, event): ret = self.enregister_demande() if ret != wx.ID_CANCEL: # Enregistrer la géométrie de l'interface if self.IsMaximized(): self.config.set('INTERFACE', 'MAXIMISER', 'True') else: self.config.set('INTERFACE', 'MAXIMISER', 'False') self.config.set( 'INTERFACE', 'GEOMETRIE', str(self.GetPositionTuple() + self.GetSizeTuple())) self.config.set( 'INTERFACE', 'afficher_statistiques', str( self.barre_menu.FindItemById( barres.ID_STATISTIQUES).IsChecked())) self.config.set( 'INTERFACE', 'afficher_shell', str(self.barre_menu.FindItemById(barres.ID_SHELL).IsChecked())) self.Destroy() def afficher_statistiques(self, event): """ Affiche la grille des statistiques du tournoi en cours. """ valeur = self.barre_menu.FindItemById( barres.ID_STATISTIQUES).IsChecked() self.grille.afficher_statistiques(valeur) def afficher_shell(self, event): """ Affiche un shell Python qui donne accées à l'ensemble des variables du programme. """ valeur = self.barre_menu.FindItemById(barres.ID_SHELL).IsChecked() self._mgr.GetPane('shell').Show(valeur) self._mgr.Update() def masquer_shell(self, event): """Masquer le shell (appelé lorsque l'utilisateur click sur le croix rouge de la fenêtre) """ self.barre_menu.FindItemById(barres.ID_SHELL).Check(False) event.Skip() def afficher_info(self, event): """Afficher la fenêtre d'information joueurs. """ self.affichage_visible = not self.affichage_visible if self.affichage_visible: self.barre_bouton.FindItemById(barres.ID_INFO).Check( self.affichage_visible) self.barre_menu.FindItemById(barres.ID_INFO).Check( self.affichage_visible) self.fenetre_affichage.Show() self.SetFocus() else: self.fenetre_affichage.Close() def masquer_info(self, event): """Masquer la fenêtre d'information joueurs (appelé lorsque l'utilisateur click sur le croix rouge de la fenêtre) """ self.affichage_visible = False self.barre_bouton.FindItemById(barres.ID_INFO).Check(False) self.barre_menu.FindItemById(barres.ID_INFO).Check(False) event.Skip() def afficher_tirage(self, event): num = self.barre_bouton.numero() dlg = dlgpa.DialogueAfficherTirage(self, num) dlg.Show() def afficher_partie_prec(self, event): if tournoi.tournoi() is None: self.barre_bouton.chg_partie() else: try: tournoi.tournoi().partie(self.barre_bouton.numero() - 1) self.barre_bouton.chg_partie(self.barre_bouton.numero() - 1) except ValueError, e: self.barre_etat.SetStatusText(unicode(e)) # Rafraichir wx.PostEvent(self, evt.RafraichirEvent(self.GetId()))