Esempio n. 1
0
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())
Esempio n. 2
0
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()))