Просмотр исходного кода

Creation, enregistrement, chargement des parties / parametrage des
chapitres de la partie

olinox14 10 лет назад
Родитель
Сommit
1e905919f6

+ 4 - 3
.settings/org.eclipse.core.resources.prefs

@@ -6,15 +6,13 @@ encoding//lib/Case.py=utf-8
 encoding//lib/Combattant.py=utf-8
 encoding//lib/Decor.py=utf-8
 encoding//lib/EcranAffichageTexte.py=utf-8
-encoding//lib/EcranAltitude.py=utf-8
+encoding//lib/EcranChargerPartie.py=utf-8
 encoding//lib/EcranChargerPlateau.py=utf-8
 encoding//lib/EcranCreerPlateau.py=utf-8
 encoding//lib/EcranEditionMateriel.py=utf-8
 encoding//lib/EcranEditionTerrain.py=utf-8
-encoding//lib/EcranFondPlateau.py=utf-8
 encoding//lib/EcranGestionCombat.py=utf-8
 encoding//lib/EcranSelectionPj.py=utf-8
-encoding//lib/EcranVol.py=utf-8
 encoding//lib/EntreeSortie.py=utf-8
 encoding//lib/Forme.py=utf-8
 encoding//lib/Modes.py=utf-8
@@ -29,8 +27,10 @@ encoding//lib/explorateurMat.py=utf-8
 encoding//lib/frameAttaque.py=utf-8
 encoding//lib/framePj.py=utf-8
 encoding//lib/gC.py=utf-8
+encoding//lib/geometrie.py=utf-8
 encoding//lib/mat.py=utf-8
 encoding//lib/outilsSvg.py=latin1
+encoding//lib/regles.py=utf-8
 encoding//lib/rsc.py=utf-8
 encoding//lib/ui/dm.py=utf-8
 encoding//lib/ui/ecran_altitude.py=utf-8
@@ -38,6 +38,7 @@ encoding//lib/ui/ecran_creationPlateau.py=utf-8
 encoding//lib/ui/ecran_creerPlateau.py=utf-8
 encoding//lib/ui/ecran_explorateur.py=utf-8
 encoding//lib/ui/ecran_message.py=utf-8
+encoding//lib/ui/ecran_panneauPj.py=utf-8
 encoding//lib/ui/ecran_principal.py=utf-8
 encoding//lib/ui/ecran_saisie.py=utf-8
 encoding/DMonde.py=utf-8

+ 92 - 207
DMonde.py

@@ -2,26 +2,18 @@
 # -*- coding: utf-8 -*-
 """Interface principale du programme DMonde
 """
+
 import os
-from sys import exit
 
-from PyQt4.QtCore import SIGNAL, Qt, QString
-from PyQt4.QtGui import QMainWindow, QGraphicsView, QTableWidget, QLineEdit, \
-    QTextEdit, QToolButton, QSlider, QDoubleSpinBox, QWidget, QFrame, \
-    QApplication
+from PyQt4.QtCore import SIGNAL
+from PyQt4.QtGui import QMainWindow, QApplication
 
-from lib.Actions import Ligne
-from lib.Combattant import PJ
-from lib.EcranChargerPlateau import EcranChargerPlateau
-from lib.EcranCreerPlateau import EcranCreerPlateau
-from lib.EcranEditionMateriel import EcranEditionMateriel
-from lib.EcranFondPlateau import EcranFondPlateau
-from lib.Plateau import Plateau
-from lib.commun import rep, Session
-from lib.framePj import FramePj
-from lib.mat import chargerMat, supprimerMat
-from lib.outilsSvg import afficheSvg, enregistrer, chargerUnique, supprSvg
-from lib.rsc import RImage
+from lib.EcranChargerPartie import EcranChargerPartie
+from lib.FenetreEditionPartie import FenetreEditionPartie
+from lib.Partie import Partie
+from lib.Profil import Profil
+from lib.commun import Session, sessionEnCours, rep
+from lib.mat import chargerMat
 from lib.ui.ecran_principal import Ui_principal
 
 
@@ -30,219 +22,111 @@ class DMonde(QMainWindow):
     def __init__(self, parent=None):
         """initialisation de la fenetre"""
         super (DMonde, self).__init__()
-        self.plateau = None
-        self.util = "Joueur"
-        self.partie = ""
-        self.regles = ""
-        self.idPlateauEnCours = ""
-        self.plateauConnecte = False
-        self.pjs = []   #liste des idM des personnages du groupe
+#         self.plateau = None
+#         self.util = "Joueur"
+        self.profil = Profil()
+        self.partie = None
+#         self.regles = ""
+#         self.idPlateauEnCours = ""
+#         self.plateauConnecte = False
+#         self.pjs = []   #liste des idM des personnages du groupe
         self.createWidgets()
 
     def createWidgets(self):
         """construction de l'interface"""
         self.ui = Ui_principal()
         self.ui.setupUi(self)
-        self.afficherPanneauxPlateau(False)
-        self.connect(self.ui.cbt_sauver, SIGNAL("clicked()"), self.enregistrerPlateau)   
-        self.connect(self.ui.cbt_fermer, SIGNAL("clicked()"), self.fermerPlateau)
-        self.connect(self.ui.grp_nouveauPj, SIGNAL("clicked()"), self.nouveauPj)
-        self.ui.cbt_vue.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
-        self.ui.cp_ongletsListes.setStyleSheet("QTabBar::tab { width: 38px; }")
-        self.ui.pi_ongletsListes.setStyleSheet("QTabBar::tab { width: 38px; }")
-        self.creerEcranFondPlateau()
-        
-        self.chargerPartie("")
+        self.connect(self.ui.dm_panneauCentre, SIGNAL("currentChanged(int)"), self.rafraichir) 
         
-#         self.showMaximized()
+        self.connect(self.ui.pt_nouvelle, SIGNAL("clicked()"), self.nouvellePartie) 
+        self.connect(self.ui.pt_editer, SIGNAL("clicked()"), self.editerPartie) 
+        self.connect(self.ui.pt_fermer, SIGNAL("clicked()"), self.fermerPartie) 
+        self.connect(self.ui.pt_charger, SIGNAL("clicked()"), self.afficherEcranChargerPartie) 
+        self.ouverture()
+
+    def ouverture(self):
+        """operations menees a l'ouverture de la fenetre principale"""
+#         self.majLargeurOnglets()
+        self.majAffichage()
+#         self.chargerPartie("")        
+
+    def rafraichir(self):
+        """fonction utilisee pour forcer le repaint"""
+        self.majLargeurOnglets()
 
     def estMj(self):
         return True
 
-    def chargerPartie(self, idPartie):
-        """charge la partie"""
-        self.profil = "olivier"
-        self.partie = "partie1"
-        self.regles = "dd35"
-        
-        self.majFichierInfosSvg()
-        self.chargerListePj()
+    def majAffichage(self):
+        actif = (self.partie != None)
+        self.ui.dm_panneauCentre.setTabEnabled(1, actif)
+        self.ui.dm_panneauCentre.setTabEnabled(2, actif)
+        self.ui.dm_panneauCentre.setTabEnabled(3, actif)
+        self.ui.pt_page.setCurrentIndex( (1 if actif else 0) )
 
-    ########## onglet plateau
-    
-    def creerEcranFondPlateau(self):
-        ecranFondPlateau = EcranFondPlateau(self)
-        self.ui.cbt_vue.resetTransform()
-        self.ui.cbt_vue.setScene(ecranFondPlateau)
+    def majLargeurOnglets(self):
+        val = (self.ui.dm_panneauCentre.width() - 20) / 4
+        self.ui.dm_panneauCentre.setStyleSheet("QTabBar::tab { height: 25; width: "+str(val)+"px; }")        
 
-    def nouveauPlateau(self):
-        """ouvre la fenetre de creation de plateau"""
-        if self.plateau != None:
-            if self.plateau.estCree() == True:
-                return 
-        self.creationPlateau = EcranCreerPlateau()
-        plateau = Plateau(self)
-        self.creationPlateau.afficher(plateau)
-        r = self.creationPlateau.exec_()
-        if r == 1:
-            self.plateau = self.creationPlateau.resultat()
-            self.plateau.creer()
-        
-    def afficherEcranChargerPlateau(self):
-        """ouvre la fenetre de chargement de plateau"""
-        if self.plateau != None:
-            if self.plateau.estCree(): return
-        fen = EcranChargerPlateau(self)
+    def nouvellePartie(self):
+        fen = FenetreEditionPartie()
+        fen.nouvelle()
         fen.show()
         r = fen.exec_()
         if r == 1:
-            idM = fen.resultat()
-            del fen
-            self.chargerPlateau(idM)
-        
-    def chargerPlateau(self, idM):
-        if self.plateau: 
-            if self.plateau.estCree(): self.fermerPlateau()
-        self.plateau = chargerMat(idM, "cbt")
-        self.plateau.recreer(self)  
-
-    def chargerDernierPlateau(self):
-        """charge le dernier plateau sauvegarde"""
-        infosSvg = afficheSvg(os.path.join(rep("cbt"), "infos_sauvegarde"))
-        dernier = None
-        for id_svg in infosSvg:
-            if not dernier or infosSvg[id_svg]["dateSvg"] > infosSvg[dernier]["dateSvg"]:
-                dernier = id_svg
-        if dernier:
-            self.chargerPlateau(dernier)
-                                   
-    def enregistrerPlateau(self):
-        self.plateau.enregistrer("cbt")
-        infos = {"nom": self.plateau.nom(), "chapitre": self.plateau.chapitre, "dateCreation":self.plateau.dateCreation, "dateSvg":self.plateau.dateSvg, \
-                 "public": self.plateau.public, "enCours": self.plateau.enCours}
-        enregistrer(self.plateau.idM(), infos, os.path.join(rep("cbt"), "infos_sauvegarde"))
-    
-    def fermerPlateau(self):
-        self.plateau.fermer()
-        self.plateau = None
-        self.creerEcranFondPlateau()
-        self.afficherPanneauxPlateau(False) 
-
-    def majFichierInfosSvg(self):
-        """construit/maj le fichier contenant la liste des
-           plateaux sauvegardes et leurs informations"""
-        #on parcourt les fichiers de sauvegarde
-        f = []
-        lstFichiersSvg = []
-        for (dirpath, dirnames, filenames) in os.walk(rep("cbt")):
-            f.extend(filenames)
-            break
-        for fichier in f:
-            fileName, fileExtension = os.path.splitext(fichier)
-            if fileExtension == ".dm":
-                lstFichiersSvg.append(fileName)
-      
-        #on verifie leur presence dans le fichier 'infos_sauvegarde'
-        infosSvg = afficheSvg(os.path.join(rep("cbt"), "infos_sauvegarde"))
-        index = len(infosSvg)
-
-        #on ajoute les sauvegardes manquantes si besoin
-        for fichier in lstFichiersSvg:
-            if not fichier in infosSvg:
-                plateau = chargerUnique(os.path.join(rep("cbt"), "{}.dm".format(fichier)))
-                enregistrer(fichier, {"nom": plateau.nom(), "chapitre": plateau.chapitre, "dateCreation":plateau.dateCreation, "dateSvg":plateau.dateSvg, \
-                                      "public": plateau.public, "enCours": plateau.enCours}, "svg\\infos_sauvegarde")
-                index += 1     
-                  
-        #on supprime ceux qui ne sont plus trouves
-        for fichier in infosSvg:
-            if not fichier in lstFichiersSvg:
-                supprSvg(os.path.join(rep("cbt"), "infos_sauvegarde"), fichier)
-
-
-    ########## apparence de l'onglet plateau
-    def afficherPanneauxPlateau(self, actif):
-        index = int(actif)   # 0 si faux, 1 si vrai
-        self.ui.cbt_panneauBas.setCurrentIndex(index)
-        self.ui.cbt_panneauHaut.setCurrentIndex(index)
-        self.ui.cbt_panneauDroite.setCurrentIndex(index)
-        self.ui.cbt_panneauGauche.setCurrentIndex(index)
-        self.ui.cbt_etapeSuivante.setVisible(actif)
-
-    def reinitialiserPanneauxPlateau(self):
-        """remet a neuf les commandes liees au plateau"""
-        for panneau in [self.ui.cbt_panneauHaut, \
-                         self.ui.cbt_panneauBas, \
-                         self.ui.cbt_panneauGauche, \
-                         self.ui.cbt_panneauDroite]:
-            #listes
-            for liste in panneau.findChildren(QTableWidget):
-                while liste.rowCount() > 0:
-                    liste.removeRow(0)
-            #textes
-            for texte in panneau.findChildren(QLineEdit):
-                texte.clear()         
-            for texte in panneau.findChildren(QTextEdit):
-                texte.clear()
-            #a cocher
-            for bouton in panneau.findChildren(QToolButton):
-                if bouton.isCheckable():
-                    bouton.setChecked(False)
-            #autre
-            for item in panneau.findChildren(QSlider):
-                item.setValue(1)
-            for item in panneau.findChildren(QDoubleSpinBox):
-                item.setValue(0)                
-
-
-    ########## onglet groupe
-    def chargerListePj(self):
-        for attributsFichier in os.walk(rep("grp")):
-            for f in attributsFichier[2]:
-                pj = chargerMat(os.path.join(attributsFichier[0], f))
-                self.pjAjouterAListe(pj)
-        self.ui.grp_deroulement_layout.setAlignment(Qt.AlignTop)
+            partie = fen.resultat()
+            self.partie = partie
+            self.partie.afficher(self)
+            self.majPartieEnCours()
+            self.majAffichage()
+            
+        del fen
 
-    def pjAjouterAListe(self, pj = None):
-        compteur = len(self.pjs)
-        colonne = (compteur % 3) * 2
-        ligne = int(compteur / 3)
-        self.pjs.append(pj.idM())
-        
-        panneau = FramePj(compteur)
-        if pj:
-            panneau.chargerPj(pj)
-        panneau.setObjectName(QString("pj_panneau_{}".format(compteur)))
-        self.connect(panneau, SIGNAL("pjModifie(int)"), self.pjEnregistrer)
-        self.ui.grp_deroulement_layout.addWidget(panneau, ligne, colonne)
+    def editerPartie(self):
+        if not self.partie: return
+        fen = FenetreEditionPartie()
+        fen.charger(self.partie)
+        fen.show()
+        r = fen.exec_()
+        if r == 1:
+            partie = fen.resultat()
+            self.partie = partie
+            self.partie.majAffichage()
+        del fen
         
-        ## pour l'espacement entre les panneaux
-        w = QWidget()
-        self.ui.grp_deroulement_layout.addWidget(w, ligne, colonne + 1)
-
-    def pjSupprimer(self, index):
-        panneau = self.findChild(QFrame, "pj_panneau_{}".format(index))
-        pj = panneau.pj()
-        supprimerMat(pj.idM(), "grp")
-        self.ui.grp_deroulement_layout.removeWidget(panneau)
+    def fermerPartie(self):
+        if self.partie:
+            self.partie.fermer()
+            self.majAffichage()
 
-    def nouveauPj(self):
-        fen = EcranEditionMateriel(PJ())
-        fen.afficher()
-        fen.exec_()
-        pj = fen.mat()
+    def afficherEcranChargerPartie(self):
+        fen = EcranChargerPartie(self)
+        fen.show()
+        r = fen.exec_()
+        if r == 1:
+            idM = fen.resultat()
+            self.chargerPartie(idM)
         del fen
-        pj.enregistrer("grp")
-        self.pjAjouterAListe(pj)
 
-    def pjEnregistrer(self, idPj):
-        panneau = self.findChild(QFrame, "pj_panneau_{}".format(idPj))
-        pj = panneau.pj()
-        pj.enregistrer("grp")
+    def chargerPartie(self, idPartie):
+        """charge la partie"""
+        repParties = os.path.join( rep("app"), "parties\\" )
+        chemin = os.path.join( os.path.join( repParties, "{}\\".format(idPartie) ), "{}.dm".format(idPartie) )
+        partie = chargerMat( chemin )
+        if partie:
+            self.partie = partie
+            self.partie.afficher(self)
+            self.majPartieEnCours()
+            self.majAffichage()
+
+    def majPartieEnCours(self):
+        s = sessionEnCours()
+        idM = self.partie.idM() if self.partie else "defaut"
+        s.majPartie(idM)
+        s.enregistrer()
 
     def resizeEvent(self, event):
-        val = (self.ui.dm_panneauCentre.width() - 20) / 3
-        self.ui.dm_panneauCentre.setStyleSheet("QTabBar::tab { height: 25; width: "+str(val)+"px; }")
+        self.majLargeurOnglets()
         
         
 if __name__ == "__main__":
@@ -252,6 +136,7 @@ if __name__ == "__main__":
     #settrace(trace_calls)
     dm = DMonde()
     dm.show()
+    dm.rafraichir()
     r = app.exec_()
     s.fin()
     exit(r)

+ 77 - 74
lib/Actions.py

@@ -8,15 +8,15 @@ from PyQt4.QtGui import QPixmap, QCursor, QToolButton, QIcon, QGraphicsLineItem,
     QApplication
 
 import AEtoile
-import br
 from lib.dialogues import dmVol
-from lib.ui.ecran_attaqueZone import Ui_zne_fenetre
+from lib.ui.ecran_attaqueZone import Ui_zone_fenetre
 import regles
 
 
 class Action(object):
     """action effectuee par un combattant sur le plateau de jeu"""
     def __init__(self):
+        self.plateau = None
         self._num = None         #no du pion actif
         self._nom = "Action"
         self._coordCible = None  #coord de la case ciblee par le curseur
@@ -60,7 +60,7 @@ class Action(object):
     def majCoordCible(self, coord):
         """met a jour les coordonnees de la cible,
             cad la case actuellement survolee par la souris"""
-        if self.plateau.coordonneesValides(coord):
+        if self.plateau.geo.coordonneesValides(coord):
             self._coordCible = coord
             self.maj()
 
@@ -276,6 +276,7 @@ class Attaque(Action):
         self._icone = ""
         self._portee = 1   #portee max en cases
         self._rayon = 0
+        self._pionCible = None
         self._attributs = regles.listeAttributsAttaques()
         self._notes = ""
 
@@ -307,6 +308,10 @@ class Attaque(Action):
     def rayon(self):
         return self._rayon
     
+    def modifierRayon(self, val):
+        if self._rayon < 30: rayon = self._rayon + val
+        self.majRayon(rayon)
+    
     def majRayon(self, rayon):
         try:
             ent = int(rayon)
@@ -340,7 +345,7 @@ class Attaque(Action):
 
     def ldmValide(self):
         x0, y0 = self.acteur().position
-        z0 = self.plateau.cases[self.acteur().position].zA(self._num) + self.acteur().h
+        z0 = self.acteur().zA() + self.acteur().h
         origine = (x0,y0,z0)
         
         #on essaie de cibler toutes les cases de la hauteur de la cible si c'est un pion
@@ -362,7 +367,6 @@ class Cac(Attaque):
     def __init__(self):
         super(Cac, self).__init__()
         self._nom = "Attaque au corps-à-corps"
-        self._pionCible = None
         self._sourceCurseur = ""
         self._nomBouton = "act_attaqueCac"
         self._icone = "img\\curseurEpee.png"
@@ -385,7 +389,7 @@ class Cac(Attaque):
       
     def maj(self):
         self.afficherCibles(False)
-        pionCible = self.plateau.cases[self._coordCible].occupant()
+        pionCible = self.plateau.pions[self.plateau.cases[self._coordCible].occupant()]
         if pionCible != None and pionCible != self.plateau.pionSelectionne():
             self._pionCible = pionCible
         else:
@@ -393,7 +397,7 @@ class Cac(Attaque):
         self.afficherCibles(True)
 
     def estValide(self):
-        return (self._coordCible in self.plateau.zone(self.plateau.pionSelectionne().position, self.portee, 0, False, True))
+        return (self._coordCible in self.plateau.geo.zone(self.plateau.pionSelectionne().position, self.portee, 0, False, True))
 
     def afficherCibles(self, actif):
         if self._pionCible:
@@ -408,7 +412,6 @@ class Distance(Attaque):
         super(Distance, self).__init__()
         self._nom = "Attaque à distance"
         self._itemLigne = None
-        self._pionCible = None
         self._sourceCurseur = ""
         self._nomBouton = "act_attaqueDist"
         self._icone = ":/interface/16/ressource/arc_16.png"
@@ -511,12 +514,15 @@ class Zone(Attaque):
 
     def afficherCibles(self, actif):
         for coord in self._casesCibles:
-            self.plateau.cases[(coord[0], coord[1])].majEstCibleCurseur(actif)
-            z = 0 if len(coord) == 2 else coord[2]
-            if self.plateau.cases[(coord[0], coord[1])].estOccupee(z):
-                pion = self.plateau.cases[(coord[0], coord[1])].occupant(z)
+            x = coord[0] ; y = coord[1]
+            zA = 0 if len(coord) == 2 else coord[2]
+            occupant = self.plateau.cases[(x, y)].occupant(zA)
+            if occupant:
+                pion = self.plateau.pions[occupant]
                 pion.estCibleAttaque(actif) 
-
+            else:
+                self.plateau.cases[(x, y)].majEstCibleCurseur(actif)
+                
     def listePionsCibles(self):
         retour = []
         for coord in self._casesCibles:
@@ -577,13 +583,12 @@ class Ligne(Zone):
             self._casesCibles = []
             x1, y1 = self.acteur().position
             z1 = self.acteur().zA() + self.acteur().h
+            
             x2, y2 = self._coordCible
-            if self.plateau.cases[(x2, y2)].estOccupee():
-                z2 = self.plateau.cases[(x2, y2)].occupant().zA()
-            else:
-                z2 = self.plateau.cases[(x2, y2)].z0   
+            occupant = self.plateau.cases[(x2, y2)].occupant()
+            z2 = self.plateau.cases[(x2, y2)].zA(occupant) if occupant else self.plateau.cases[(x2, y2)].z0
              
-            for coord in br.ligne((x1, y1, z1), (x2, y2, z2)):
+            for coord in self.plateau.geo.ligne((x1, y1, z1), (x2, y2, z2)):
                 if coord != (x1, y1, z1):
                     self._casesCibles.append(coord)  
             
@@ -592,7 +597,9 @@ class Ligne(Zone):
     def estValide(self):
         """la ligne est valide si toutes les cases cibles ne sont pas occupees par autre chose que des combattants"""
         for x, y, zA in self._casesCibles:
-            if self.plateau.cases[(x, y)].occupant(zA) <= 0: return False 
+            occupant = self.plateau.cases[(x, y)].occupant(zA)
+            if occupant:
+                if occupant <= 0: return False 
         return True
             
 class Disque(Zone):
@@ -626,11 +633,10 @@ class Disque(Zone):
 
     @autorise
     def majCibles(self):
-        if self.plateau.cases[self._coordCible].estOccupee():
-            zCible = self.plateau.cases[self._coordCible].occupant().zA()
-        else:
-            zCible = self.plateau.cases[self._coordCible].z0   
-        self._casesCibles = self.plateau.zone3d(self._coordCible, self._rayon, zCible)
+        occupant = self.plateau.cases[self._coordCible].occupant()
+        x, y = self._coordCible
+        z = self.plateau.pions[occupant].zA() if occupant else self.plateau.cases[self._coordCible].z0
+        self._casesCibles = self.plateau.geo.zone3d( (x, y, z) , self._rayon)
 
     def afficherCibles(self, actif):
         if self.estValide():
@@ -642,7 +648,7 @@ class Disque(Zone):
     @autorise
     def majRayon(self, val):
         self._rayon = val
-        self.maj()
+        if self.plateau: self.maj()
 
     @autorise
     def majItemsGraphiques(self):
@@ -685,12 +691,14 @@ class Cone(Zone):
         return "Attaque à de zone (cone)"
 
     def majCibles(self):
-        if self.plateau.cases[self._coordCible].estOccupee():
-            zCible = self.plateau.cases[self._coordCible].occupant().zA()
-        else:
-            zCible = self.plateau.cases[self._coordCible].z0   
-        self._casesCibles = self.plateau.cone3d(self.acteur().position, self._coordCible, \
-                                                (self.acteur().zR + self.acteur().h), zCible)
+        x0, y0 = self.acteur().position
+        z0 = self.acteur().zA() + self.acteur().h
+        x1, y1 = self._coordCible
+        occupant = self.plateau.cases[self._coordCible].occupant()
+        z1 = self.plateau.pions[occupant].zA() if occupant else self.plateau.cases[self._coordCible].z0
+        cone = self.plateau.geo.cone3d( (x0, y0, z0), (x1, y1, z1) )
+        if (x0, y0, z0) in cone: cone.remove((x0, y0, z0))
+        self._casesCibles = cone
         
     def creerItemsGraphiques(self):
         self._itemCible = QGraphicsPolygonItem()
@@ -718,6 +726,24 @@ class Cone(Zone):
         polygone.append(ligne2.p2())
         return polygone
 
+def itemLdm():
+    """retourne l'item graphique utilise pour les lignes de mire"""
+    item = QGraphicsLineItem()
+    item.setZValue(100)
+    pinceau = QPen()
+    pinceau.setColor(QColor(249, 249, 249))
+    pinceau.setStyle(Qt.DashDotLine)
+    pinceau.setWidth(6)
+    item.setPen(pinceau)
+    return item
+    
+def choisirAttaqueZone():
+    """affiche la boite de dialogue permettant un choix de la forme de l'attaque de zone"""
+    fen = EcranAttaqueZone()
+    fen.show()
+    r = fen.exec_()
+    return fen.resultat() if r == 1 else None
+    
 
 class EcranAttaqueZone(QDialog):
     """boite de dialogue de parametrage de l'attaque de zone"""
@@ -727,56 +753,33 @@ class EcranAttaqueZone(QDialog):
         
     def createWidgets(self):
         """construction de l'interface"""
-        self.ui = Ui_zne_fenetre()
+        self.ui = Ui_zone_fenetre()
         self.ui.setupUi(self)
-        self.connect(self.ui.zne_forme, SIGNAL("currentIndexChanged(int)"), self.majAffichage, Qt.UniqueConnection)   
-        self.connect(self.ui.zne_valider, SIGNAL("clicked()"), self.ok, Qt.UniqueConnection)   
-        self.connect(self.ui.zne_annuler, SIGNAL("clicked()"), self.ok, Qt.UniqueConnection)   
-        self.ui.zne_valider.setShortcut("Enter") 
-        self.majAffichage(self.ui.zne_forme.currentIndex())
-
-    def majAffichage(self, index):
-        self.ui.zne_rayon.setVisible((index == 1))
-        self.ui.zne_rayon_lbl.setVisible((index == 1))
+        self.connect(self.ui.zone_ligne, SIGNAL("clicked()"), self.ligne, Qt.UniqueConnection)   
+        self.connect(self.ui.zone_disque, SIGNAL("clicked()"), self.disque, Qt.UniqueConnection)   
+        self.connect(self.ui.zone_cone, SIGNAL("clicked()"), self.cone, Qt.UniqueConnection)   
+        self.setStyleSheet("DmLabel:hover {background: rgb(255, 255, 255)};")
 
     def resultat(self):
-        if self.ui.zne_forme.currentIndex() == 0:
-            attaque = Ligne()
-        elif self.ui.zne_forme.currentIndex() == 1:
-            attaque = Disque()
-            attaque.majRayon(int(self.ui.zne_rayon.value()))
-        elif self.ui.zne_forme.currentIndex() == 2:
-            attaque = Cone()
-        attaque.majPortee(int(self.ui.zne_portee.value())) 
-        return attaque
-
-    def ok(self):
-        self.done(1)     
-
-    def annuler(self):
-        self.done(0)     
-
-def itemLdm():
-    """retourne l'item graphique utilise pour les lignes de mire"""
-    item = QGraphicsLineItem()
-    item.setZValue(100)
-    pinceau = QPen()
-    pinceau.setColor(QColor(249, 249, 249))
-    pinceau.setStyle(Qt.DashDotLine)
-    pinceau.setWidth(6)
-    item.setPen(pinceau)
-    return item
-    
+        return self._resultat
 
+    def ligne(self):
+        self._resultat = Ligne
+        self.done(1)
+        
+    def disque(self):
+        self._resultat = Disque
+        self.done(1)
+        
+    def cone(self):
+        self._resultat = Cone
+        self.done(1)
 
 if __name__ == "__main__":
     app = QApplication(sys.argv)
-    ecran = EcranAttaqueZone()
-    ecran.show()
-    r = app.exec_()
-    att = ecran.resultat()
-    print att.typeAtt(), att.portee()
-    exit(r)      
+    res = choisirAttaqueZone()
+    print res
+    exit()      
 
 
 

+ 1 - 1
lib/Case.py

@@ -131,7 +131,7 @@ class Case(QGraphicsPolygonItem):
         self.majEffet(self.effetActif)
 
     def polygone(self):
-        return self.plateau.polygone(self.x, self.y)
+        return self.plateau.geo.polygone(self.x, self.y)
 
 #     def polygone(self, x, y):
 #         """renvoie l'objet graphique hexagone de la case"""

+ 97 - 0
lib/EcranChargerPartie.py

@@ -0,0 +1,97 @@
+#from __future__ import unicode_literals
+# -*- coding: utf-8 -*-
+import os
+from time import strftime, localtime
+
+from PyQt4.QtCore import SIGNAL, QString
+from PyQt4.QtGui import QDialog, QMessageBox, QIcon, QTableWidgetItem
+
+from lib.commun import rep
+from lib.mat import chargerMat
+from lib.outilsSvg import supprSvg, afficheSvg
+from mat import supprimerMat
+from ui.ecran_chargerPartie import Ui_chpt_fenetre
+
+
+class EcranChargerPartie(QDialog):
+    """interface de creation/chargement de plateau"""
+    def __init__(self, fenetre, parent=None):
+        """initialisation de la fenetre"""
+        super (EcranChargerPartie, self).__init__()
+        self.fenetre = fenetre
+        self._resultat = None
+        self.createWidgets()
+        self.majAffichage()
+        
+    def createWidgets(self):
+        """construction de l'interface"""
+        #construction de l'interface
+        self.ui = Ui_chpt_fenetre()
+        self.ui.setupUi(self)
+        self.majListeChargement()
+        self.connect(self.ui.chpt_supprimer, SIGNAL("clicked()"), self.supprimerPlateau)
+        self.connect(self.ui.chpt_ok, SIGNAL("clicked()"), self.ok)
+        self.connect(self.ui.chpt_liste, SIGNAL("cellClicked(int,int)"), self.majAffichage)
+        self.connect(self.ui.chpt_liste, SIGNAL("cellDoubleClicked(int,int)"), self.ok)
+
+    def ok(self):
+        """renvoie l'identifiant de la partie selectionnee"""
+        self._resultat = self.ui.chpt_liste.texte(self.ui.chpt_liste.currentRow(), 0)
+        self.done(1)
+            
+    def resultat(self):
+        return self._resultat
+            
+    def supprimerPlateau(self):
+        """supprime le plateau selectionne"""
+        reponse = QMessageBox.question(self, 'Avertissement',
+                                           QString().fromUtf8("Etes-vous sûr de vouloir supprimer cette partie,\net tous les plateaux et personnages qu'elle contient?"), QMessageBox.Yes | 
+                                           QMessageBox.No, QMessageBox.No)
+        if reponse == QMessageBox.Yes:       
+            idM = self.ui.chpt_liste.texte(self.ui.chpt_liste.currentRow(), 0)
+            rep = os.path.join(rep("app"), "{}\\".format(idM))
+            os.remove(rep)
+            self.majListeChargement()
+
+    def majAffichage(self):
+        self.ui.chpt_ok.setEnabled(self.ui.chpt_liste.currentRow()>=0)
+        self.ui.chpt_supprimer.setEnabled(self.ui.chpt_liste.currentRow()>=0)
+
+    def majListeChargement(self):
+        """remplit ou maj la liste des plateaux sauvegardes"""
+        #on met a jour la largeur des colonnes
+        largeurs = [0, 370, 100, 0]
+        for col in self.ui.chpt_liste.colonnes():
+            self.ui.chpt_liste.setColumnWidth(col, largeurs[col]);
+
+        self.ui.chpt_liste.setSortingEnabled(False)
+        self.ui.chpt_liste.vider()
+        
+        repParties = os.path.join( rep("app"), "parties\\" )
+        for repertoires in os.walk( repParties ):
+            lstRep = repertoires[1]
+            break
+
+        for idPartie in lstRep:
+            chemin = os.path.join( os.path.join( repParties, "{}\\".format(idPartie) ), "{}.dm".format(idPartie) )
+            partie = chargerMat( chemin )
+            if partie:
+                ligne = self.ui.chpt_liste.nouvelleLigneFin()
+                self.ui.chpt_liste.majTexte(ligne, 0, partie.idM())
+                self.ui.chpt_liste.majTexte(ligne, 1, partie.nom() ) 
+                self.ui.chpt_liste.majTexte(ligne, 2, strftime('%d/%m/%y %H:%M',localtime(partie.dateMaj)) )
+                self.ui.chpt_liste.majData(ligne, 3, partie.dateMaj )
+        for col in self.ui.chpt_liste.colonnes():
+            self.ui.chpt_liste.sizeHintForColumn(col)
+            
+        #on trie par date
+        self.ui.chpt_liste.setSortingEnabled(True)
+        self.ui.chpt_liste.sortItems(5, 1)
+        self.majAffichage()
+        
+
+
+
+
+
+        

+ 1 - 5
lib/EcranChargerPlateau.py

@@ -13,7 +13,7 @@ from ui.ecran_chargerPlateau import Ui_chp_fenetre
 
 class EcranChargerPlateau(QDialog):
     """interface de creation/chargement de plateau"""
-    def __init__(self, fenetrePrincipale, terrain=None, parent=None):
+    def __init__(self, fenetrePrincipale, parent=None):
         """initialisation de la fenetre"""
         super (EcranChargerPlateau, self).__init__()
         self.fenetre = fenetrePrincipale
@@ -32,7 +32,6 @@ class EcranChargerPlateau(QDialog):
         self.connect(self.ui.chp_chapitre, SIGNAL("valueChanged(int)"), self.majListeChargement)
         self.connect(self.ui.chp_toutAfficher, SIGNAL("stateChanged(int)"), self.majListeChargement)
         
-        self.connect(self.ui.chp_liste, SIGNAL("cellClicked(int,int)"), self.focusBoutonCharger)
         self.connect(self.ui.chp_liste, SIGNAL("cellClicked(int,int)"), self.majAffichage)
         self.connect(self.ui.chp_liste, SIGNAL("cellDoubleClicked(int,int)"), self.ok)
 
@@ -59,9 +58,6 @@ class EcranChargerPlateau(QDialog):
         self.ui.chp_ok.setEnabled(self.ui.chp_liste.currentRow()>=0)
         self.ui.chp_supprimer.setEnabled(self.ui.chp_liste.currentRow()>=0)
 
-    def focusBoutonCharger(self):
-        self.ui.chp_ok.setFocus()
-
     def majListeChargement(self):
         """remplit ou maj la liste des plateaux sauvegardes"""
         #on met a jour la largeur des colonnes

+ 601 - 603
lib/EcranEditionMateriel.py

@@ -1,603 +1,601 @@
-#from __future__ import unicode_literals
-# -*- coding: utf-8 -*-
-from __future__ import division
-
-import sys
-
-from PyQt4.QtCore import SIGNAL, Qt, QString, QSize, QVariant
-from PyQt4.QtGui import QDialog, QColorDialog, QColor, QHBoxLayout, QFrame, \
-    QApplication, QCheckBox
-
-import Actions
-from Combattant import Combattant
-from EcranEditionObjet import EcranEditionObjet
-from Objet import Objet
-from VueEditionForme import VueEditionForme
-from dialogues import dmMessage
-from frameAttaque import FrameAttaque
-from lib.Decor import Decor
-from lib.commun import lstLibEtats
-import regles
-from rsc import selectionImage, RImage
-import ui.dm as dm
-from ui.ecran_editionMateriel import Ui_edm_fenetre
-
-
-def nouveauCombattant():
-    return Combattant()
-
-def nouveauDecor():
-    return Decor()
-
-class EcranEditionMateriel(QDialog):
-    """interface de creation/edition de terrains"""
-    def __init__(self, mat, parent=None):
-        """initialisation de la fenetre"""
-        super (EcranEditionMateriel, self).__init__()
-        self._mat = mat
-        self._mode = "creation" if mat.position == (-1,-1) else "combat"
-        self._sections = []
-
-    def mat(self):
-        """retourne le materiel de la fenetre"""
-        return self._mat
-
-    def mode(self):
-        return self._mode
-    
-    def createWidgets(self):
-        """construction de l'interface"""
-        #construction de l'interface
-        self.ui = Ui_edm_fenetre()
-        self.ui.setupUi(self)
-        self.connect(self.ui.edm_enregistrer, SIGNAL("clicked()"), self.valider)
-        self.connect(self.ui.edm_annuler, SIGNAL("clicked()"), self.annuler)
-
-    def toutesLesSections(self):
-        return [EdEnTete, EdPageCreation, EdPageCombat, EdPageDeplacement, EdPageProprietes, \
-                EdPageAttributs, EdPageAttaques, EdPageInventaire, EdPageNotes]
-
-    def section(self, nom):
-        for section in self._sections:
-            if section.__class__.__name__ == nom: return section
-        return None
-
-    def afficher(self, pageInitiale = 0, formeCases = "H"):
-        """affiche la fenetre"""
-        self.createWidgets()
-        
-        #on instancie et on construit les sections necessaires
-        for section in self.toutesLesSections():
-            instance = section(self)
-            if self.mat().typ() in instance.filtre() \
-            and self._mode in instance.modes():
-                self._sections.append(instance)
-                instance.construire()
-                if section == EdPageCreation:
-                    if formeCases == "C": self.ui.edm_casesCarrees.setChecked(True)
-                instance.charger()
-            else:
-                self.ui.edm_menu.setRowHidden((self.toutesLesSections().index(section) - 1), True)
-
-        self.allerAPage(pageInitiale)
-        self.majAffichage()
-        self.show()
-
-    def allerAPage(self, index, sens = "+"):
-        while self.ui.edm_menu.isRowHidden(index): 
-            index += 1 if sens == "+" else -1
-            if index > self.ui.edm_menu.rowCount(): return
-        self.ui.edm_menu.setCurrentCell(index, 0)
-        self.ui.edm_menu.setCurrentCell(index, 1)
-        self.ui.edm_pages.setCurrentIndex(index)        
-
-    def pageSuivante(self):
-        index = self.ui.edm_menu.currentRow() + 1
-        if index > (self.ui.edm_menu.rowCount() - 1): index = 0
-        print index
-        self.allerAPage(index)
-
-    def pagePrecedente(self):
-        index = self.ui.edm_menu.currentRow() - 1
-        if index < 0: index = self.ui.edm_menu.rowCount() - 1
-        print index
-        self.allerAPage(index, "-")        
-
-    def nomModifie(self):
-        """le nom du pion a ete modifie"""
-        self.majAffichage()
-        sectionForme = self.section("EdPageCreation")
-        if sectionForme: sectionForme.majEtiquetteVueForme()
-
-    def logoModifie(self):
-        """le logo du pion a ete modifie"""
-        sectionForme = self.section("EdPageCreation")
-        if sectionForme: sectionForme.logoModifie()
-
-    #### barre d'outils
-    def majAffichage(self):
-        """verifie la validite des saisies"""
-        self.ui.edm_enregistrer.setEnabled(len(self.ui.edm_nom.texte()) > 0) 
-        
-    def valider(self):
-        """enregistre le materiel cree/edite"""
-        for section in self._sections:
-            section.enregistrer()
-        self.done(1)
-
-    def annuler(self):
-        """annule la creation/edition"""
-        self._mat = None
-        self.done(0)
-
-    def wheelEvent(self, event):
-        if event.delta() < 0:
-            self.pageSuivante()
-            return
-        elif event.delta() > 0:
-            self.pagePrecedente()
-            return
-        return QDialog.wheelEvent(self, event)
-
-
-class EdSectionBase(object):
-    """classe de base pour les differentes sections de l'ecran d'edition des pions"""
-    def __init__(self, ecran):
-        self.ecran = ecran
-        self._filtre = []
-        self._modes = ["creation", "combat"]
-        
-    def filtre(self):
-        """liste des classes de materiel concernees par cette section"""
-        return self._filtre
-
-    def modes(self):
-        return self._modes
-
-    def ui(self):
-        return self.ecran.ui
-
-    def mat(self):
-        return self.ecran.mat()
-
-    def construire(self):
-        """construit et met en forme"""
-        pass
-    
-    def charger(self):
-        """charge les donnees du materiel dans la section"""
-        pass
-    
-    def enregistrer(self):
-        """met a jour le materiel en fonction des donnees saisies"""
-        pass
-
-class EdEnTete(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdEnTete, self).__init__(ecran)
-        self._filtre = ["cb", "dc"]
-        
-    def construire(self):
-        if self.ecran.mode() == "creation":
-            self.ecran.connect(self.ui().edm_logo, SIGNAL("clicked()"), self.selectionnerLogo)
-            self.ecran.connect(self.ui().edm_nom, SIGNAL("textEdited(QString)"), self.ecran.nomModifie)
-        else:
-            self.ui().edm_nom.setEnabled(False)
-        self.majLibelleMode()
-
-    def majLibelleMode(self):
-        if self.mat().typ() == "cb":
-            txt1 = "Fiche de personnage"
-        else:
-            txt1 = "Fiche du decor"
-        txt2 = " Creation" if self.ecran.mode() == "creation" else "Combat"
-        self.ui().edm_mode.majTexte((txt1 + " : " + txt2).upper())
-        couleur = "rgb(180,60,50)" if self.ecran.mode() == "combat" else "rgb(20,20,150)"
-        self.ui().edm_enTete.setStyleSheet(QString("#edm_mode {color: "+couleur+";}"))
-
-    def selectionnerLogo(self):
-        img = selectionImage()
-        if img:
-            self.ui().edm_logo.chargerImage(img)
-            self.ecran.logoModifie()
-        
-    def charger(self):
-        self.ui().edm_nom.majTexte(self.mat().nom())
-        if self.mat().logo.estValide():
-            self.ui().edm_logo.chargerImage(self.mat().logo)
-        else:
-            self.ui().edm_logo.majTexte("Choisissez \nun fichier\nimage")
-    
-    def enregistrer(self):
-        self.mat().majNom(self.ui().edm_nom.texte())
-        self.mat().logo = self.ui().edm_logo.image() if self.ui().edm_logo.image() else RImage()
-           
-
-
-class EdPageCreation(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageCreation, self).__init__(ecran)
-        self._filtre = ["cb", "dc"]
-        self._modes = ["creation"]
-
-    def construire(self):
-        self.vueForme = VueEditionForme(self.ui().edm_vueForme)
-        self.ecran.connect(self.ui().edm_aideForme, SIGNAL("clicked()"), self.afficherAideForme)
-        self.ecran.connect(self.ui().edm_casesHexa, SIGNAL("clicked()"), self.majFormeCases)
-        self.ecran.connect(self.ui().edm_casesCarrees, SIGNAL("clicked()"), self.majFormeCases)
-        self.ecran.connect(self.ui().edm_couleur, SIGNAL("clicked()"), self.selectionCouleur)
-        self.ecran.connect(self.ui().edm_image, SIGNAL("clicked()"), self.selectionImage)
-
-    def formeCases(self):
-        return "H" if self.ui().edm_casesHexa.isChecked() else "C"
-
-    def majFormeCases(self):
-        if self.vueForme.formeCases() != self.ecran.formeCases():
-            #on enregistre la def de forme, d'image et d'etiquette en cours
-            self.mat().formeDef[self.vueForme.formeCases()] = self.vueForme.formeDef()
-            self.mat().img = self.vueForme.imageDef()
-            self.mat().etiquette = self.vueForme.etiquetteDef()
-
-            #on recree la scene avec la nouvelle forme de cases
-            self.vueForme.vider()
-            self.vueForme.creer(self.ecran.formeCases())
-
-            #on charge les def correspondantes a la nouvelle forme
-            self.vueForme.chargerFormeDef(self.mat().formeDef[self.formeCases()])
-            self.vueForme.chargerImageDef(self.mat().img)
-            self.vueForme.chargerEtiquetteDef(self.mat().etiquette)
-
-    def majEtiquetteVueForme(self):
-        self.mat().etiquette.txt = self.ui().edm_nom.texte()
-        self.vueForme.chargerEtiquetteDef(self.mat().etiquette)
-
-    def logoModifie(self):
-        self.vueForme.nouvelleImageDef(self.ui().edm_logo.image())
-
-    def selectionImage(self):
-        """selectionne le fichier image dans la boite de dialogue dediee"""
-        img = selectionImage()
-        if img:
-            self.vueForme.nouvelleImageDef(img)
-        
-    def selectionCouleur(self):
-        """selectionne la couleur dans la boite de dialogue dediee"""
-        couleur = QColorDialog(self.ecran).getColor(QColor("white"), self.ecran)
-        if couleur.isValid():
-            self.mat().couleur = couleur
-            self.vueForme.majCouleur(couleur)
-        
-    def afficherAideForme(self):
-        msg = "Sur l'écran ci-contre, vous pouvez éditer la forme et l'apparence de votre pion. Vous pouvez: \n\n" \
-                 "Choisir la couleur du pion \n" \
-                 "Choisir une image (qui remplacera alors le logo sur le pion) \n" \
-                 "Deplacer l'etiquette et l'image sur le pion en cliquant dessus \n" \
-                 "Faire pivoter l'image avec [FLECHE HAUT] et [FLECHE BAS] \n" \
-                 "Modifier la taille de l'image avec [FLECHE GAUCHE] et [FLECHE DROITE] \n" \
-                 "Activer desactiver l'etiquette en gras avec [G] \n" \
-                 "Modifier la taille de la police avec [FLECHE HAUT] et [FLECHE BAS]"
-        dmMessage(msg)   
-
-    def charger(self):
-        self.vueForme.creer(self.formeCases())
-        self.vueForme.autoriserModifForme(True)
-        self.vueForme.majCouleur(self.mat().couleur)
-        self.vueForme.chargerFormeDef(self.mat().formeDef[self.formeCases()])
-        self.vueForme.chargerImageDef(self.mat().img)
-        self.vueForme.chargerEtiquetteDef(self.mat().etiquette)
-    
-    def enregistrer(self):
-        self.mat().formeDef[self.vueForme.formeCases()] = self.vueForme.formeDef()
-        self.mat().img = self.vueForme.imageDef()
-        self.mat().etiquette = self.vueForme.etiquetteDef()
-    
-    
-class EdPageCombat(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageCombat, self).__init__(ecran)
-        self._filtre = ["cb", "dc"]
-        self._modes = ["combat"]
- 
-    def construire(self):
-        #etat
-        dico = lstLibEtats(self.mat().typ())
-        for num in dico:
-            self.ui().edm_etat.addItem(QString.fromUtf8(dico[num]), QVariant(num))
-        self.ui().edm_etat.setCurrentIndex(0)
-        
-        #statuts
-        if self.mat().typ() == "dc":
-            self.ui().edm_statut0.setVisible(False)
-            self.ui().edm_statut1.setVisible(False)
-            self.ui().edm_statut2.setVisible(False)
-            self.ui().edm_statut3.setVisible(False)
-            self.ui().edm_effets.setVisible(False);self.ui().edm_effets_lbl.setVisible(False)
-            self.ui().edm_actions_lbl.setVisible(False)
-        else:
-            self.ui().edm_statut5.setVisible(False)
-#         self.ui().edm_layoutStatuts.update()
-        
-    def charger(self):
-        self.ui().edm_etat.setCurrentIndex(self.ui().edm_etat.findData(QVariant(self.mat().etat)))
-    
-        for statut in self.mat().statuts:
-            case = self.ui().page_cbt.findChild(QCheckBox, "edm_statut{}".format(statut))
-            if case: case.setChecked(True)
-        
-    
-    def enregistrer(self):
-        self.mat().etat = self.ui().edm_etat.itemData(self.ui().edm_etat.currentIndex()).toInt()[0]
-        
-        self.mat().statuts = []
-        for i in range(0, 6):
-            case = self.ui().page_cbt.findChild(QCheckBox, "edm_statut{}".format(i))
-            if case:
-                if case.isChecked(): self.mat().statuts.append(i)
-        
-        
-class EdPageDeplacement(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageDeplacement, self).__init__(ecran)
-        self._filtre = ["cb"]
-        
-    def charger(self):
-        self.ui().edm_taille.setValue(self.mat().h)
-        self.ui().edm_depMarche.setValue(self.mat().depMarche)
-        self.ui().edm_depNage.setValue(self.mat().depNage)
-        self.ui().edm_depEscalade.setValue(self.mat().depEscalade)
-        self.ui().edm_depVol.setValue(self.mat().depVol)
-        self.ui().edm_saut.setValue(self.mat().saut)      
-    
-    def enregistrer(self):
-        self.mat().h = self.ui().edm_taille.value()
-        self.mat().depMarche = self.ui().edm_depMarche.value()
-        self.mat().depNage = self.ui().edm_depNage.value()
-        self.mat().depEscalade = self.ui().edm_depEscalade.value()
-        self.mat().depVol = self.ui().edm_depVol.value()
-        self.mat().saut = self.ui().edm_saut.value()
-
-class EdPageProprietes(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageProprietes, self).__init__(ecran)
-        self._filtre = ["dc"]
-        
-    def charger(self):
-        self.ui().edm_hauteur.setValue(self.mat().h)
-        self.ui().edm_hauteurPlafond.setChecked(self.mat().hMax)
-        self.ui().edm_escalade.setChecked(self.mat().escalade)
-        self.ui().edm_inflammable.setChecked(self.mat().inflammable)
-    
-    def enregistrer(self):
-        self.mat().h = self.ui().edm_hauteur.value()
-        self.mat().hMax = self.ui().edm_hauteurPlafond.isChecked()
-        self.mat().escalade = self.ui().edm_escalade.isChecked()
-        self.mat().brule = self.ui().edm_inflammable.isChecked()
-              
-class EdPageAttributs(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageAttributs, self).__init__(ecran)
-        self._filtre = ["cb"]
-        self._modes = ["creation", "combat"]
-
-    def layoutCarac(self):
-        """retourne le layout des attributs"""
-        return self.ecran.ui.edm_deroulementAttributs_layout       
-
-    def construire(self):
-        """construit les champs d'attributs"""
-        """cree les champs dedies a la saisie des attributs dans la grille dediee"""
-        self.layoutCarac().setSpacing(4)
-        self.layoutCarac().setMargin(0)
-        
-        for nomAttribut in regles.ordreAttributsFichePerso():
-            if len(nomAttribut) > 0:
-                lay = QHBoxLayout()
-                lay.setMargin(0)
-                lay.setSpacing(2)
-
-                etiquette = dm.DmLabel()
-                etiquette.majTexte(regles.attribut(nomAttribut).nom)        
-                etiquette.setObjectName("{}_etiquette".format(nomAttribut))
-                etiquette.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
-                etiquette.setMinimumSize(QSize(110, 24))
-                etiquette.setMaximumSize(QSize(110, 24))
-                lay.addWidget(etiquette)
-                
-                champ = dm.DmLineEdit()
-                champ.setMinimumSize(QSize(80, 24))
-                champ.setMaximumSize(QSize(80, 24))
-                champ.setAlignment(Qt.AlignCenter)
-                champ.majTexte(regles.listeAttributs()[nomAttribut])
-                champ.setObjectName("{}_champ".format(nomAttribut))
-                champ.setStyleSheet("background-color: rgb({},{},{});".format(248,248,248))
-    ##            self.connect(champ, SIGNAL("textChanged()"), self.controlerAttribut)
-                lay.addWidget(champ)
-
-                self.layoutCarac().addLayout(lay)
-            else:
-                lay = QHBoxLayout()
-                etiquetteVide = dm.DmLabel()
-                etiquetteVide.setMinimumHeight(9)
-                etiquetteVide.setMaximumHeight(9)
-                lay.addWidget(etiquetteVide)
-                lay.addWidget(etiquetteVide)
-                self.layoutCarac().addLayout(lay)
-
-    def listeAttributs(self):
-        """renvoie la liste des attributs tels qu'ils
-           sont saisis dans la liste des attributs"""
-        attributs = regles.listeAttributs()
-        for i in range(0, self.layoutCarac().count()):
-            layout = self.layoutCarac().itemAt(i).layout()
-            widget = layout.itemAt(1).widget()
-            if widget != 0 and widget != None:
-                if str(widget.objectName()[-6:]) == "_champ":
-                    attr = str(widget.objectName()[:-6])
-                    attributs[attr] = widget.texte()
-        return attributs   
-        
-    def charger(self):
-        """met a jour la liste des attributs du Combattant"""
-        for i in range(0, self.layoutCarac().count()):
-            layout = self.layoutCarac().itemAt(i).layout()
-            widget = layout.itemAt(1).widget()
-            if widget != 0:
-                if str(widget.objectName()[-6:]) == "_champ":
-                    attr = str(widget.objectName()[:-6])
-                    widget.majTexte(self.ecran.mat().listeAttributs[attr])       
-    
-    def enregistrer(self):
-        self.mat().attributs = self.listeAttributs()
-
-            
-class EdPageAttaques(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageAttaques, self).__init__(ecran)
-        self._filtre = ["cb"]
-        self._compteurAttaque = 0
-    
-    def layoutAtt(self):
-        """retourne le layout des attaques"""
-        return self.ecran.ui.edm_deroulementAttaques_layout
-    
-    def construire(self):
-        self.layoutAtt().setAlignment(Qt.AlignLeft)
-
-    def attaqueNouvelle(self, attaque = None):
-        """ajoute une nouvelle ligne a la liste des attaques"""
-        #on ajoute de suite un panneau 'nouvelle attaque en dessous'
-        self._compteurAttaque += 1
-        panneau = FrameAttaque(self._compteurAttaque)
-        if attaque: panneau.chargerAttaque(attaque)
-        panneau.setObjectName(QString("att_frame_{}".format(self._compteurAttaque)))
-        self.ecran.connect(panneau, SIGNAL("attaqueNouvelle()"), self.attaqueNouvelle)
-        self.ecran.connect(panneau, SIGNAL("attaqueSupprimer(int)"), self.attaqueSupprimer)
-        self.layoutAtt().addWidget(panneau)        
-
-    def attaqueSupprimer(self, index):
-        """supprime la ligne selectionnee de la liste des attaques"""
-        panneau = self.findChild(QFrame, "att_frame_{}".format(index))
-        self.layoutAtt().removeWidget(panneau)
-    
-    def charger(self):
-        self.layoutAtt().setAlignment(Qt.AlignTop)
-        for attaque in self.mat().attaques:
-            self.attaqueNouvelle(attaque)
-        self.attaqueNouvelle()
-    
-    def enregistrer(self):
-        listeAttaques = []
-        for i in range(0, self.layoutAtt().count()):
-            panneau = self.layoutAtt().itemAt(i).widget()
-            if panneau != 0:
-                attaque = panneau.attaque()
-                if attaque:
-                    listeAttaques.append(attaque)
-        self.mat().attaques = listeAttaques
-            
-class EdPageInventaire(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageInventaire, self).__init__(ecran)
-        self._filtre = ["cb", "dc"]
-        
-    def construire(self):
-        self.ecran.ui.edm_listeInventaire.construire()
-        self.ecran.connect(self.ecran.ui.edm_filtreTypeObjet, SIGNAL("currentChanged(int)"), self.filtrerInventaire)
-        self.ecran.ui.edm_filtreTypeObjet.stackUnder(self.ecran.ui.edm_listeInventaire)
-        self.ecran.connect(self.ecran.ui.edm_listeInventaire, SIGNAL("objetClique(int)"), self.editerObjet)
-
-    def editerObjet(self, indexObjet):
-        if indexObjet < len(self.ecran.ui.edm_listeInventaire.inventaire()):
-            objet = self.ecran.ui.edm_listeInventaire.inventaire()[indexObjet]
-        else:
-            objet = None
-        typeObjet = self.ecran.ui.edm_filtreTypeObjet.currentIndex() - 1
-        
-        self.fenetreEO = EcranEditionObjet(objet, typeObjet)
-        self.fenetreEO.show()
-        self.fenetreEO.exec_()
-        resultat = self.fenetreEO.resultat()
-
-        if resultat:
-            if objet:
-                self.ecran.ui.edm_listeInventaire.majObjet(objet, resultat)
-            else:
-                self.ecran.ui.edm_listeInventaire.ajouterObjet(resultat)
-        else:
-            if objet:
-                self.ecran.ui.edm_listeInventaire.supprimerObjet(objet)
-        
-        self.fenetreEO = None
-        self.majTotauxInventaire()
-
-    def majTotauxInventaire(self):
-        inv = self.ecran.ui.edm_listeInventaire.inventaire()
-        poidsTotal = 0.00
-        for obj in inv:
-            poidsTotal += obj.poidsTotal()
-        self.ecran.ui.edm_inventaire_poids.majTexte("{} kg".format(poidsTotal))
-
-    def filtrerInventaire(self, index):
-        filtre = index - 1
-        self.ecran.ui.edm_listeInventaire.filtrer(filtre)
-        
-    def charger(self):
-        self.ui().edm_listeInventaire.charger(self.mat().inventaire)
-        self.majTotauxInventaire()
-    
-    def enregistrer(self):
-        self.mat().inventaire = self.ui().edm_listeInventaire.inventaire()
-            
-class EdPageNotes(EdSectionBase):
-    def __init__(self, ecran):
-        super(EdPageNotes, self).__init__(ecran)
-        self._filtre = ["cb", "dc"]
-
-    def construire(self):
-        if self.mat().typ() == "dc":
-            self.ui().edm_detail_espece.setVisible(False);self.ui().edm_lbl_espece.setVisible(False)
-            self.ui().edm_detail_profession.setVisible(False);self.ui().edm_lbl_profession.setVisible(False)
-            self.ui().edm_detail_religion.setVisible(False);self.ui().edm_lbl_religion.setVisible(False)
-            self.ui().edm_detail_lieuNaissance.setVisible(False);self.ui().edm_lbl_lieuNaissance.setVisible(False)
-            self.ui().edm_detail_espece.setVisible(False);self.ui().edm_lbl_espece.setVisible(False)
-            self.ui().edm_detail_sexe.setVisible(False);self.ui().edm_lbl_sexe.setVisible(False)
-            self.ui().edm_detail_yeux.setVisible(False);self.ui().edm_lbl_yeux.setVisible(False)
-            self.ui().edm_detail_peau.setVisible(False);self.ui().edm_lbl_peau.setVisible(False)
-            self.ui().edm_detail_cheveux.setVisible(False);self.ui().edm_lbl_cheveux.setVisible(False)
-            self.ui().edm_detail_langues.setVisible(False);self.ui().edm_lbl_langues.setVisible(False)
-
-        
-    def layout(self):
-        return self.ui().edm_layoutNotes
-        
-    def charger(self):
-        for detail in self.mat().details:
-            widget = self.ui().edm_pages.findChild(dm.DmLineEdit, "edm_detail_{}".format(detail))
-            if widget: widget.majTexte(self.mat().details[detail])
-#         self.ui().edm_notes.setText(QString.fromUtf8(self.mat().notes))
-    
-    def enregistrer(self):
-        listeWidget = self.ui().edm_pages.findChildren(dm.DmLineEdit)
-        for widget in listeWidget:
-            detail = str(widget.objectName()).replace("edm_detail_","")
-            txt = widget.texte()
-            if len(txt) > 0: self.mat().details[detail] = txt
-        
-#         self.mat().notes = str(self.ui().edm_notes.toPlainText().toUtf8())
-            
-
-if __name__ == "__main__":
-    app = QApplication(sys.argv)
-    mat = Combattant()
-#     mat.position = (1,1)
-    ecran = EcranEditionMateriel(mat)
-    ecran.afficher()
-    r = app.exec_()
-    mat = ecran.mat()
-    exit(r)      
-
-
-
-
-
-
+#from __future__ import unicode_literals
+# -*- coding: utf-8 -*-
+from __future__ import division
+
+import sys
+
+from PyQt4.QtCore import SIGNAL, Qt, QString, QSize, QVariant
+from PyQt4.QtGui import QDialog, QColorDialog, QColor, QHBoxLayout, QFrame, \
+    QApplication, QCheckBox
+
+import Actions
+from Combattant import Combattant
+from EcranEditionObjet import EcranEditionObjet
+from Objet import Objet
+from VueEditionForme import VueEditionForme
+from dialogues import dmMessage
+from frameAttaque import FrameAttaque
+from lib.Decor import Decor
+from lib.commun import lstLibEtats
+import regles
+from rsc import selectionImage, RImage
+import ui.dm as dm
+from ui.ecran_editionMateriel import Ui_edm_fenetre
+
+
+def nouveauCombattant():
+    return Combattant()
+
+def nouveauDecor():
+    return Decor()
+
+class EcranEditionMateriel(QDialog):
+    """interface de creation/edition de terrains"""
+    def __init__(self, mat, parent=None):
+        """initialisation de la fenetre"""
+        super (EcranEditionMateriel, self).__init__()
+        self._mat = mat
+        self._mode = "creation" if mat.position == (-1,-1) else "combat"
+        self._sections = []
+
+    def mat(self):
+        """retourne le materiel de la fenetre"""
+        return self._mat
+
+    def mode(self):
+        return self._mode
+    
+    def createWidgets(self):
+        """construction de l'interface"""
+        #construction de l'interface
+        self.ui = Ui_edm_fenetre()
+        self.ui.setupUi(self)
+        self.connect(self.ui.edm_enregistrer, SIGNAL("clicked()"), self.valider)
+        self.connect(self.ui.edm_annuler, SIGNAL("clicked()"), self.annuler)
+
+    def toutesLesSections(self):
+        return [EdEnTete, EdPageCreation, EdPageCombat, EdPageDeplacement, EdPageProprietes, \
+                EdPageAttributs, EdPageAttaques, EdPageInventaire, EdPageNotes]
+
+    def section(self, nom):
+        for section in self._sections:
+            if section.__class__.__name__ == nom: return section
+        return None
+
+    def afficher(self, pageInitiale = 0, formeCases = "H"):
+        """affiche la fenetre"""
+        self.createWidgets()
+        
+        #on instancie et on construit les sections necessaires
+        for section in self.toutesLesSections():
+            instance = section(self)
+            if self.mat().typ() in instance.filtre() \
+            and self._mode in instance.modes():
+                self._sections.append(instance)
+                instance.construire()
+                if section == EdPageCreation:
+                    if formeCases == "C": self.ui.edm_casesCarrees.setChecked(True)
+                instance.charger()
+            else:
+                self.ui.edm_menu.setRowHidden((self.toutesLesSections().index(section) - 1), True)
+
+        self.allerAPage(pageInitiale)
+        self.majAffichage()
+        self.show()
+
+    def allerAPage(self, index, sens = "+"):
+        while self.ui.edm_menu.isRowHidden(index): 
+            index += 1 if sens == "+" else -1
+            if index > self.ui.edm_menu.rowCount(): return
+        self.ui.edm_menu.setCurrentCell(index, 0)
+        self.ui.edm_menu.setCurrentCell(index, 1)
+        self.ui.edm_pages.setCurrentIndex(index)        
+
+    def pageSuivante(self):
+        index = self.ui.edm_menu.currentRow() + 1
+        if index > (self.ui.edm_menu.rowCount() - 1): index = 0
+        self.allerAPage(index)
+
+    def pagePrecedente(self):
+        index = self.ui.edm_menu.currentRow() - 1
+        if index < 0: index = self.ui.edm_menu.rowCount() - 1
+        self.allerAPage(index, "-")        
+
+    def nomModifie(self):
+        """le nom du pion a ete modifie"""
+        self.majAffichage()
+        sectionForme = self.section("EdPageCreation")
+        if sectionForme: sectionForme.majEtiquetteVueForme()
+
+    def logoModifie(self):
+        """le logo du pion a ete modifie"""
+        sectionForme = self.section("EdPageCreation")
+        if sectionForme: sectionForme.logoModifie()
+
+    #### barre d'outils
+    def majAffichage(self):
+        """verifie la validite des saisies"""
+        self.ui.edm_enregistrer.setEnabled(len(self.ui.edm_nom.texte()) > 0) 
+        
+    def valider(self):
+        """enregistre le materiel cree/edite"""
+        for section in self._sections:
+            section.enregistrer()
+        self.done(1)
+
+    def annuler(self):
+        """annule la creation/edition"""
+        self._mat = None
+        self.done(0)
+
+    def wheelEvent(self, event):
+        if event.delta() < 0:
+            self.pageSuivante()
+            return
+        elif event.delta() > 0:
+            self.pagePrecedente()
+            return
+        return QDialog.wheelEvent(self, event)
+
+
+class EdSectionBase(object):
+    """classe de base pour les differentes sections de l'ecran d'edition des pions"""
+    def __init__(self, ecran):
+        self.ecran = ecran
+        self._filtre = []
+        self._modes = ["creation", "combat"]
+        
+    def filtre(self):
+        """liste des classes de materiel concernees par cette section"""
+        return self._filtre
+
+    def modes(self):
+        return self._modes
+
+    def ui(self):
+        return self.ecran.ui
+
+    def mat(self):
+        return self.ecran.mat()
+
+    def construire(self):
+        """construit et met en forme"""
+        pass
+    
+    def charger(self):
+        """charge les donnees du materiel dans la section"""
+        pass
+    
+    def enregistrer(self):
+        """met a jour le materiel en fonction des donnees saisies"""
+        pass
+
+class EdEnTete(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdEnTete, self).__init__(ecran)
+        self._filtre = ["cb", "dc"]
+        
+    def construire(self):
+        if self.ecran.mode() == "creation":
+            self.ecran.connect(self.ui().edm_logo, SIGNAL("clicked()"), self.selectionnerLogo)
+            self.ecran.connect(self.ui().edm_nom, SIGNAL("textEdited(QString)"), self.ecran.nomModifie)
+        else:
+            self.ui().edm_nom.setEnabled(False)
+        self.majLibelleMode()
+
+    def majLibelleMode(self):
+        if self.mat().typ() == "cb":
+            txt1 = "Fiche de personnage"
+        else:
+            txt1 = "Fiche du decor"
+        txt2 = " Creation" if self.ecran.mode() == "creation" else "Combat"
+        self.ui().edm_mode.majTexte((txt1 + " : " + txt2).upper())
+        couleur = "rgb(180,60,50)" if self.ecran.mode() == "combat" else "rgb(20,20,150)"
+        self.ui().edm_enTete.setStyleSheet(QString("#edm_mode {color: "+couleur+";}"))
+
+    def selectionnerLogo(self):
+        img = selectionImage()
+        if img:
+            self.ui().edm_logo.chargerImage(img)
+            self.ecran.logoModifie()
+        
+    def charger(self):
+        self.ui().edm_nom.majTexte(self.mat().nom())
+        if self.mat().logo.estValide():
+            self.ui().edm_logo.chargerImage(self.mat().logo)
+        else:
+            self.ui().edm_logo.majTexte("Choisissez \nun fichier\nimage")
+    
+    def enregistrer(self):
+        self.mat().majNom(self.ui().edm_nom.texte())
+        self.mat().logo = self.ui().edm_logo.image() if self.ui().edm_logo.image() else RImage()
+           
+
+
+class EdPageCreation(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageCreation, self).__init__(ecran)
+        self._filtre = ["cb", "dc"]
+        self._modes = ["creation"]
+
+    def construire(self):
+        self.vueForme = VueEditionForme(self.ui().edm_vueForme)
+        self.ecran.connect(self.ui().edm_aideForme, SIGNAL("clicked()"), self.afficherAideForme)
+        self.ecran.connect(self.ui().edm_casesHexa, SIGNAL("clicked()"), self.majFormeCases)
+        self.ecran.connect(self.ui().edm_casesCarrees, SIGNAL("clicked()"), self.majFormeCases)
+        self.ecran.connect(self.ui().edm_couleur, SIGNAL("clicked()"), self.selectionCouleur)
+        self.ecran.connect(self.ui().edm_image, SIGNAL("clicked()"), self.selectionImage)
+
+    def formeCases(self):
+        return "H" if self.ui().edm_casesHexa.isChecked() else "C"
+
+    def majFormeCases(self):
+        if self.vueForme.formeCases() != self.ecran.formeCases():
+            #on enregistre la def de forme, d'image et d'etiquette en cours
+            self.mat().formeDef[self.vueForme.formeCases()] = self.vueForme.formeDef()
+            self.mat().img = self.vueForme.imageDef()
+            self.mat().etiquette = self.vueForme.etiquetteDef()
+
+            #on recree la scene avec la nouvelle forme de cases
+            self.vueForme.vider()
+            self.vueForme.creer(self.ecran.formeCases())
+
+            #on charge les def correspondantes a la nouvelle forme
+            self.vueForme.chargerFormeDef(self.mat().formeDef[self.formeCases()])
+            self.vueForme.chargerImageDef(self.mat().img)
+            self.vueForme.chargerEtiquetteDef(self.mat().etiquette)
+
+    def majEtiquetteVueForme(self):
+        self.mat().etiquette.txt = self.ui().edm_nom.texte()
+        self.vueForme.chargerEtiquetteDef(self.mat().etiquette)
+
+    def logoModifie(self):
+        self.vueForme.nouvelleImageDef(self.ui().edm_logo.image())
+
+    def selectionImage(self):
+        """selectionne le fichier image dans la boite de dialogue dediee"""
+        img = selectionImage()
+        if img:
+            self.vueForme.nouvelleImageDef(img)
+        
+    def selectionCouleur(self):
+        """selectionne la couleur dans la boite de dialogue dediee"""
+        couleur = QColorDialog(self.ecran).getColor(QColor("white"), self.ecran)
+        if couleur.isValid():
+            self.mat().couleur = couleur
+            self.vueForme.majCouleur(couleur)
+        
+    def afficherAideForme(self):
+        msg = "Sur l'écran ci-contre, vous pouvez éditer la forme et l'apparence de votre pion. Vous pouvez: \n\n" \
+                 "Choisir la couleur du pion \n" \
+                 "Choisir une image (qui remplacera alors le logo sur le pion) \n" \
+                 "Deplacer l'etiquette et l'image sur le pion en cliquant dessus \n" \
+                 "Faire pivoter l'image avec [FLECHE HAUT] et [FLECHE BAS] \n" \
+                 "Modifier la taille de l'image avec [FLECHE GAUCHE] et [FLECHE DROITE] \n" \
+                 "Activer desactiver l'etiquette en gras avec [G] \n" \
+                 "Modifier la taille de la police avec [FLECHE HAUT] et [FLECHE BAS]"
+        dmMessage(msg)   
+
+    def charger(self):
+        self.vueForme.creer(self.formeCases())
+        self.vueForme.autoriserModifForme(True)
+        self.vueForme.majCouleur(self.mat().couleur)
+        self.vueForme.chargerFormeDef(self.mat().formeDef[self.formeCases()])
+        self.vueForme.chargerImageDef(self.mat().img)
+        self.vueForme.chargerEtiquetteDef(self.mat().etiquette)
+    
+    def enregistrer(self):
+        self.mat().formeDef[self.vueForme.formeCases()] = self.vueForme.formeDef()
+        self.mat().img = self.vueForme.imageDef()
+        self.mat().etiquette = self.vueForme.etiquetteDef()
+    
+    
+class EdPageCombat(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageCombat, self).__init__(ecran)
+        self._filtre = ["cb", "dc"]
+        self._modes = ["combat"]
+ 
+    def construire(self):
+        #etat
+        dico = lstLibEtats(self.mat().typ())
+        for num in dico:
+            self.ui().edm_etat.addItem(QString.fromUtf8(dico[num]), QVariant(num))
+        self.ui().edm_etat.setCurrentIndex(0)
+        
+        #statuts
+        if self.mat().typ() == "dc":
+            self.ui().edm_statut0.setVisible(False)
+            self.ui().edm_statut1.setVisible(False)
+            self.ui().edm_statut2.setVisible(False)
+            self.ui().edm_statut3.setVisible(False)
+            self.ui().edm_effets.setVisible(False);self.ui().edm_effets_lbl.setVisible(False)
+            self.ui().edm_actions_lbl.setVisible(False)
+        else:
+            self.ui().edm_statut5.setVisible(False)
+#         self.ui().edm_layoutStatuts.update()
+        
+    def charger(self):
+        self.ui().edm_etat.setCurrentIndex(self.ui().edm_etat.findData(QVariant(self.mat().etat)))
+    
+        for statut in self.mat().statuts:
+            case = self.ui().page_cbt.findChild(QCheckBox, "edm_statut{}".format(statut))
+            if case: case.setChecked(True)
+        
+    
+    def enregistrer(self):
+        self.mat().etat = self.ui().edm_etat.itemData(self.ui().edm_etat.currentIndex()).toInt()[0]
+        
+        self.mat().statuts = []
+        for i in range(0, 6):
+            case = self.ui().page_cbt.findChild(QCheckBox, "edm_statut{}".format(i))
+            if case:
+                if case.isChecked(): self.mat().statuts.append(i)
+        
+        
+class EdPageDeplacement(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageDeplacement, self).__init__(ecran)
+        self._filtre = ["cb"]
+        
+    def charger(self):
+        self.ui().edm_taille.setValue(self.mat().h)
+        self.ui().edm_depMarche.setValue(self.mat().depMarche)
+        self.ui().edm_depNage.setValue(self.mat().depNage)
+        self.ui().edm_depEscalade.setValue(self.mat().depEscalade)
+        self.ui().edm_depVol.setValue(self.mat().depVol)
+        self.ui().edm_saut.setValue(self.mat().saut)      
+    
+    def enregistrer(self):
+        self.mat().h = self.ui().edm_taille.value()
+        self.mat().depMarche = self.ui().edm_depMarche.value()
+        self.mat().depNage = self.ui().edm_depNage.value()
+        self.mat().depEscalade = self.ui().edm_depEscalade.value()
+        self.mat().depVol = self.ui().edm_depVol.value()
+        self.mat().saut = self.ui().edm_saut.value()
+
+class EdPageProprietes(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageProprietes, self).__init__(ecran)
+        self._filtre = ["dc"]
+        
+    def charger(self):
+        self.ui().edm_hauteur.setValue(self.mat().h)
+        self.ui().edm_hauteurPlafond.setChecked(self.mat().hMax)
+        self.ui().edm_escalade.setChecked(self.mat().escalade)
+        self.ui().edm_inflammable.setChecked(self.mat().inflammable)
+    
+    def enregistrer(self):
+        self.mat().h = self.ui().edm_hauteur.value()
+        self.mat().hMax = self.ui().edm_hauteurPlafond.isChecked()
+        self.mat().escalade = self.ui().edm_escalade.isChecked()
+        self.mat().brule = self.ui().edm_inflammable.isChecked()
+              
+class EdPageAttributs(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageAttributs, self).__init__(ecran)
+        self._filtre = ["cb"]
+        self._modes = ["creation", "combat"]
+
+    def layoutCarac(self):
+        """retourne le layout des attributs"""
+        return self.ecran.ui.edm_deroulementAttributs_layout       
+
+    def construire(self):
+        """construit les champs d'attributs"""
+        """cree les champs dedies a la saisie des attributs dans la grille dediee"""
+        self.layoutCarac().setSpacing(4)
+        self.layoutCarac().setMargin(0)
+        
+        for nomAttribut in regles.ordreAttributsFichePerso():
+            if len(nomAttribut) > 0:
+                lay = QHBoxLayout()
+                lay.setMargin(0)
+                lay.setSpacing(2)
+
+                etiquette = dm.DmLabel()
+                etiquette.majTexte(regles.attribut(nomAttribut).nom)        
+                etiquette.setObjectName("{}_etiquette".format(nomAttribut))
+                etiquette.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
+                etiquette.setMinimumSize(QSize(110, 24))
+                etiquette.setMaximumSize(QSize(110, 24))
+                lay.addWidget(etiquette)
+                
+                champ = dm.DmLineEdit()
+                champ.setMinimumSize(QSize(80, 24))
+                champ.setMaximumSize(QSize(80, 24))
+                champ.setAlignment(Qt.AlignCenter)
+                champ.majTexte(regles.listeAttributs()[nomAttribut])
+                champ.setObjectName("{}_champ".format(nomAttribut))
+                champ.setStyleSheet("background-color: rgb({},{},{});".format(248,248,248))
+    ##            self.connect(champ, SIGNAL("textChanged()"), self.controlerAttribut)
+                lay.addWidget(champ)
+
+                self.layoutCarac().addLayout(lay)
+            else:
+                lay = QHBoxLayout()
+                etiquetteVide = dm.DmLabel()
+                etiquetteVide.setMinimumHeight(9)
+                etiquetteVide.setMaximumHeight(9)
+                lay.addWidget(etiquetteVide)
+                lay.addWidget(etiquetteVide)
+                self.layoutCarac().addLayout(lay)
+
+    def listeAttributs(self):
+        """renvoie la liste des attributs tels qu'ils
+           sont saisis dans la liste des attributs"""
+        attributs = regles.listeAttributs()
+        for i in range(0, self.layoutCarac().count()):
+            layout = self.layoutCarac().itemAt(i).layout()
+            widget = layout.itemAt(1).widget()
+            if widget != 0 and widget != None:
+                if str(widget.objectName()[-6:]) == "_champ":
+                    attr = str(widget.objectName()[:-6])
+                    attributs[attr] = widget.texte()
+        return attributs   
+        
+    def charger(self):
+        """met a jour la liste des attributs du Combattant"""
+        for i in range(0, self.layoutCarac().count()):
+            layout = self.layoutCarac().itemAt(i).layout()
+            widget = layout.itemAt(1).widget()
+            if widget != 0:
+                if str(widget.objectName()[-6:]) == "_champ":
+                    attr = str(widget.objectName()[:-6])
+                    widget.majTexte(self.ecran.mat().listeAttributs[attr])       
+    
+    def enregistrer(self):
+        self.mat().attributs = self.listeAttributs()
+
+            
+class EdPageAttaques(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageAttaques, self).__init__(ecran)
+        self._filtre = ["cb"]
+        self._compteurAttaque = 0
+    
+    def layoutAtt(self):
+        """retourne le layout des attaques"""
+        return self.ecran.ui.edm_deroulementAttaques_layout
+    
+    def construire(self):
+        self.layoutAtt().setAlignment(Qt.AlignLeft)
+
+    def attaqueNouvelle(self, attaque = None):
+        """ajoute une nouvelle ligne a la liste des attaques"""
+        #on ajoute de suite un panneau 'nouvelle attaque en dessous'
+        self._compteurAttaque += 1
+        panneau = FrameAttaque(self._compteurAttaque)
+        if attaque: panneau.chargerAttaque(attaque)
+        panneau.setObjectName(QString("att_frame_{}".format(self._compteurAttaque)))
+        self.ecran.connect(panneau, SIGNAL("attaqueNouvelle()"), self.attaqueNouvelle)
+        self.ecran.connect(panneau, SIGNAL("attaqueSupprimer(int)"), self.attaqueSupprimer)
+        self.layoutAtt().addWidget(panneau)        
+
+    def attaqueSupprimer(self, index):
+        """supprime la ligne selectionnee de la liste des attaques"""
+        panneau = self.findChild(QFrame, "att_frame_{}".format(index))
+        self.layoutAtt().removeWidget(panneau)
+    
+    def charger(self):
+        self.layoutAtt().setAlignment(Qt.AlignTop)
+        for attaque in self.mat().attaques:
+            self.attaqueNouvelle(attaque)
+        self.attaqueNouvelle()
+    
+    def enregistrer(self):
+        listeAttaques = []
+        for i in range(0, self.layoutAtt().count()):
+            panneau = self.layoutAtt().itemAt(i).widget()
+            if panneau != 0:
+                attaque = panneau.attaque()
+                if attaque:
+                    listeAttaques.append(attaque)
+        self.mat().attaques = listeAttaques
+            
+class EdPageInventaire(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageInventaire, self).__init__(ecran)
+        self._filtre = ["cb", "dc"]
+        
+    def construire(self):
+        self.ecran.ui.edm_listeInventaire.construire()
+        self.ecran.connect(self.ecran.ui.edm_filtreTypeObjet, SIGNAL("currentChanged(int)"), self.filtrerInventaire)
+        self.ecran.ui.edm_filtreTypeObjet.stackUnder(self.ecran.ui.edm_listeInventaire)
+        self.ecran.connect(self.ecran.ui.edm_listeInventaire, SIGNAL("objetClique(int)"), self.editerObjet)
+
+    def editerObjet(self, indexObjet):
+        if indexObjet < len(self.ecran.ui.edm_listeInventaire.inventaire()):
+            objet = self.ecran.ui.edm_listeInventaire.inventaire()[indexObjet]
+        else:
+            objet = None
+        typeObjet = self.ecran.ui.edm_filtreTypeObjet.currentIndex() - 1
+        
+        self.fenetreEO = EcranEditionObjet(objet, typeObjet)
+        self.fenetreEO.show()
+        self.fenetreEO.exec_()
+        resultat = self.fenetreEO.resultat()
+
+        if resultat:
+            if objet:
+                self.ecran.ui.edm_listeInventaire.majObjet(objet, resultat)
+            else:
+                self.ecran.ui.edm_listeInventaire.ajouterObjet(resultat)
+        else:
+            if objet:
+                self.ecran.ui.edm_listeInventaire.supprimerObjet(objet)
+        
+        self.fenetreEO = None
+        self.majTotauxInventaire()
+
+    def majTotauxInventaire(self):
+        inv = self.ecran.ui.edm_listeInventaire.inventaire()
+        poidsTotal = 0.00
+        for obj in inv:
+            poidsTotal += obj.poidsTotal()
+        self.ecran.ui.edm_inventaire_poids.majTexte("{} kg".format(poidsTotal))
+
+    def filtrerInventaire(self, index):
+        filtre = index - 1
+        self.ecran.ui.edm_listeInventaire.filtrer(filtre)
+        
+    def charger(self):
+        self.ui().edm_listeInventaire.charger(self.mat().inventaire)
+        self.majTotauxInventaire()
+    
+    def enregistrer(self):
+        self.mat().inventaire = self.ui().edm_listeInventaire.inventaire()
+            
+class EdPageNotes(EdSectionBase):
+    def __init__(self, ecran):
+        super(EdPageNotes, self).__init__(ecran)
+        self._filtre = ["cb", "dc"]
+
+    def construire(self):
+        if self.mat().typ() == "dc":
+            self.ui().edm_detail_espece.setVisible(False);self.ui().edm_lbl_espece.setVisible(False)
+            self.ui().edm_detail_profession.setVisible(False);self.ui().edm_lbl_profession.setVisible(False)
+            self.ui().edm_detail_religion.setVisible(False);self.ui().edm_lbl_religion.setVisible(False)
+            self.ui().edm_detail_lieuNaissance.setVisible(False);self.ui().edm_lbl_lieuNaissance.setVisible(False)
+            self.ui().edm_detail_espece.setVisible(False);self.ui().edm_lbl_espece.setVisible(False)
+            self.ui().edm_detail_sexe.setVisible(False);self.ui().edm_lbl_sexe.setVisible(False)
+            self.ui().edm_detail_yeux.setVisible(False);self.ui().edm_lbl_yeux.setVisible(False)
+            self.ui().edm_detail_peau.setVisible(False);self.ui().edm_lbl_peau.setVisible(False)
+            self.ui().edm_detail_cheveux.setVisible(False);self.ui().edm_lbl_cheveux.setVisible(False)
+            self.ui().edm_detail_langues.setVisible(False);self.ui().edm_lbl_langues.setVisible(False)
+
+        
+    def layout(self):
+        return self.ui().edm_layoutNotes
+        
+    def charger(self):
+        for detail in self.mat().details:
+            widget = self.ui().edm_pages.findChild(dm.DmLineEdit, "edm_detail_{}".format(detail))
+            if widget: widget.majTexte(self.mat().details[detail])
+#         self.ui().edm_notes.setText(QString.fromUtf8(self.mat().notes))
+    
+    def enregistrer(self):
+        listeWidget = self.ui().edm_pages.findChildren(dm.DmLineEdit)
+        for widget in listeWidget:
+            detail = str(widget.objectName()).replace("edm_detail_","")
+            txt = widget.texte()
+            if len(txt) > 0: self.mat().details[detail] = txt
+        
+#         self.mat().notes = str(self.ui().edm_notes.toPlainText().toUtf8())
+            
+
+if __name__ == "__main__":
+    app = QApplication(sys.argv)
+    mat = Combattant()
+#     mat.position = (1,1)
+    ecran = EcranEditionMateriel(mat)
+    ecran.afficher()
+    r = app.exec_()
+    mat = ecran.mat()
+    exit(r)      
+
+
+
+
+
+

+ 149 - 0
lib/FenetreEditionPartie.py

@@ -0,0 +1,149 @@
+'''
+Fenetre de creation / edition de partie
+'''
+from PyQt4.QtCore import SIGNAL, QString, QVariant
+from PyQt4.QtGui import QDialog, QFrame
+
+from lib.Partie import Partie, Chapitre
+from ui.ecran_editionPartie import Ui_ept_fenetre
+from ui.ecran_panneauCh import Ui_ch_panneau
+
+
+class FenetreEditionPartie(QDialog):
+    def __init__(self):
+        super(FenetreEditionPartie, self).__init__()
+        self.createWidgets()
+
+    def createWidgets(self):
+        """construction de l'interface"""
+        self.ui = Ui_ept_fenetre()
+        self.ui.setupUi(self)     
+        self.ui.ept_ch_liste.masquerColonneId()
+        self.connect(self.ui.ept_enregistrer, SIGNAL("clicked()"), self.enregistrer)    
+        self.connect(self.ui.ept_annuler, SIGNAL("clicked()"), self.annuler)    
+        self.connect(self.ui.ept_nom, SIGNAL("textEdited(QString)"), self.majAffichage)
+        
+        self.connect(self.ui.ept_ch_nouveau, SIGNAL("clicked()"), self.nouveauChapitre)
+        
+        self.connect(self.ui.ept_ch_liste, SIGNAL("itemClicked()"), self.afficherChapitre)
+
+    def nouvelle(self):
+        self._p = Partie()
+        self._p.creer()
+        self.chargerChapitres()
+
+    def charger(self, partie):
+        self._p = partie
+        self.ui.ept_nom.majTexte(self._p.nom() )
+        
+        self.chargerChapitres()
+        self.ui.ept_ch_choix.allerA( self._p.chapitreEnCours() )
+
+        self.majAffichage()
+
+    def majAffichage(self):
+        self.ui.ept_enregistrer.setEnabled( (len(self.ui.ept_nom.texte()) > 0) )
+     
+    def resultat(self):
+        self._p.majNom( self.ui.ept_nom.texte() )
+        self._p.majChapitres( self.chapitres() )
+        self._p.majChapitreEnCours( self.ui.ept_ch_choix.valeurActuelle().toInt()[0] )
+        return self._p
+    
+    def enregistrer(self):
+        self.done(1)
+        
+    def annuler(self):
+        self.done(0)
+
+
+    ####### chapitres
+    def ajouterChapitre(self, numCh):
+        """ajoute un chapitre a la table et a la pile"""
+#         txt = "Ch. {} - {}".format(numCh, self._p.chapitres()[numCh].nom) if len(self._p.chapitres()[numCh].nom) > 0 else "Chapitre {}".format(numCh)
+        txt = self._p.chapitres()[numCh].nomLong()
+        
+        #table
+        l = self.ui.ept_ch_liste.nouvelleLigneFin()
+        self.ui.ept_ch_liste.majTexte(l, 0, "%02d" % numCh)
+        self.ui.ept_ch_liste.majTexte(l, 1, txt)
+        
+        #panneau
+        panneau = PanneauChapitre()
+        panneau.charger( self._p.chapitres()[numCh] )
+        self.connect(panneau, SIGNAL("chNomModifie(int, QString)"), self.majNomListe)
+        self.ui.ept_ch_panneaux.addWidget(panneau)
+        
+        #liste deroulante
+        self.ui.ept_ch_choix.addItem(txt, QVariant(numCh) )
+    
+    def chargerChapitres(self):
+        """chargement des chapitres a l'ouverture"""
+        for numCh in self._p.chapitres():
+            self.ajouterChapitre(numCh)
+        if len(self._p.chapitres()) >= 9: self.ui.ept_ch_nouveau.setEnabled(False)        
+        self.afficherChapitre( self._p.chapitreEnCours() )
+    
+    def nouveauChapitre(self):
+        numero = max( [key for key in self._p.chapitres().keys()] ) + 1
+        self._p.chapitres()[numero] = Chapitre(numero)
+        self.ajouterChapitre(numero)
+        self.afficherChapitre()
+        
+    def afficherChapitre(self, numCh = None):
+        """affiche le chapitre demande. si pas de numero, affiche le dernier chapite"""
+        if numCh == None:
+            numCh = max( self._p.chapitres().keys() )
+        l = self.ui.ept_ch_liste.chercherLigne(0, "%02d" % numCh)
+        if l != None: 
+            self.ui.ept_ch_liste.setCurrentCell(l, 0)
+            self.ui.ept_ch_liste.setCurrentCell(l, 1)
+            self.ui.ept_ch_panneaux.setCurrentIndex(l)  
+
+    def majNomListe(self, numCh, nom):
+        """met a jour le noms du chapitre dans la liste"""
+        nom = str(nom)
+        l = self.ui.ept_ch_liste.chercherLigne(0, "%02d" % numCh)
+        if l != None: 
+            txt = "Ch. {} - {}".format(numCh, nom) if len(nom) > 0 else "Chapitre {}".format(numCh)
+            self.ui.ept_ch_liste.majTexte(l, 1, txt)
+        index = self.ui.ept_ch_choix.findData(QVariant(numCh))
+        self.ui.ept_ch_choix.setItemText( index, QString().fromUtf8( txt ) )
+
+    def chapitres(self):
+        dico = {}
+        for i in range( 0, len(self.ui.ept_ch_panneaux) ):
+            ch = self.ui.ept_ch_panneaux.widget(i).chapitre()
+            dico[ch.num] = ch
+        return dico
+        
+class PanneauChapitre(QFrame):
+    def __init__(self, parent=None):
+        super (PanneauChapitre, self).__init__(parent)
+        self.createWidgets()
+        self._ch = None
+        
+    def createWidgets(self):
+        """construction de l'interface"""
+        self.ui = Ui_ch_panneau()
+        self.ui.setupUi(self)     
+        self.connect(self.ui.ch_nom, SIGNAL("editingFinished()"), self.nomModifie)  
+        
+    def charger(self, chapitre):
+        self._ch = chapitre
+        self.ui.ch_num.majTexte( "Chapitre {}".format(self._ch.num) )
+        self.ui.ch_nom.majTexte( self._ch.nom )
+        self.ui.ch_presentation.majTexte( self._ch.presentation )
+#         self.ui.ch_public.setChecked( self._ch.public )        
+
+    def chapitre(self):
+        self._ch.nom = self.ui.ch_nom.texte()
+        self._ch.presentation = self.ui.ch_presentation.texte()
+        return self._ch
+
+    def nomModifie(self):
+        nom = QString().fromUtf8( self.ui.ch_nom.texte() )
+        self.emit(SIGNAL("chNomModifie(int, QString)"), self._ch.num, nom)
+
+
+

+ 10 - 9
lib/Modes.py

@@ -11,13 +11,9 @@ from PyQt4.QtGui import QPixmap, QCursor
 
 import Actions
 from Cache import Cache
-from Combattant import Combattant
-from Decor import Decor
 from EntreeSortie import EntreeSortie
-from Pion import Pion
 from dialogues import dmSaisie
 import dmK
-from lib.EcranAltitude import EcranAltitude
 from lib.dialogues import dmAltitude, dmVol
 import regles
 
@@ -726,7 +722,7 @@ class PionSelectionne(ModeBasePi):
     def nouvelleAction(self, action):
         if self._action:
             self._action.desactiver()
-            self._action = None            
+            self._action = None 
         self._action = action()
         self._action.activer(self.plateau, self._num)
         self.plateau.majArborescenceModes()
@@ -760,15 +756,20 @@ class PionSelectionne(ModeBasePi):
         return accepte
 
     def toucheClavier(self, event):
-        accepte = False
         if self._num > 0:
             if event.key() == Qt.Key_Right:
                 self._action.pivoter(1)
-                accepte = True
+                return True
             elif event.key() == Qt.Key_Left:
                 self._action.pivoter(-1)
-                accepte = True
-        return accepte
+                return True
+            elif event.key() == Qt.Key_Up: 
+                self._action.modifierRayon(1)
+                return True                
+            elif event.key() == Qt.Key_Down:
+                self._action.modifierRayon(-1)
+                return True 
+        return False
 
 
         

+ 252 - 7
lib/Partie.py

@@ -3,19 +3,264 @@
 """partie de DMonde, caracterisee par un groupe de joueurs, des personnages, 
 un MJ (interchangeable), une carte du monde, un journal de quêtes
 une liste de plateaux, et un ensemble de règles"""
+import os
+from time import time
 
+from PyQt4.QtCore import SIGNAL, Qt, QString
+from PyQt4.QtGui import QGraphicsView, QWidget, QFrame
 
-class Partie():
+from lib.Combattant import PJ
+from lib.EcranChargerPlateau import EcranChargerPlateau
+from lib.EcranCreerPlateau import EcranCreerPlateau
+from lib.EcranEditionMateriel import EcranEditionMateriel
+from lib.Plateau import Plateau
+from lib.commun import uid, rep, sessionEnCours
+from lib.framePj import FramePj
+from lib.mat import chargerMat, supprimerMat, Materiel
+from lib.outilsSvg import afficheSvg, enregistrer, chargerUnique, supprSvg
+
+
+class Partie(Materiel):
     def __init__(self):
-        self.id = ""
-        self.nom = "Partie"
+        super(Partie, self).__init__()
+        self._type = "pt"
+        self._repCible = "parties"
+        self._nom = "Partie"
+        self.dateMaj = ""  #date de la derniere mise a jour
+        
+        self.prog = None
+#         self.nom = "Partie"
+        self.j = []  #liste des joueurs
+        self.mj = ""  #idPr du profil associe (utile?)
 
-        self.joueurs = []
-        self.mj = ""
+        self.idRg = None    #id des regles utilisees
 
-        self.regles = ""
+        self.pjs = []          #liste de Combattant()
+        self._plEc = None   #plateau en cours
+        
+        self._ch = {1: Chapitre(1)}   #liste des chapitres (num: Chapitre)
+        self._chEC = 1                  #chapitre en cours
 
-        self.personnages = []          #liste de Combattant()
 #         self.carteMonde = CarteMonde()
 #         self.journal = Journal()
 
+    def __getstate__(self):
+        self.dateMaj = time()
+        state = {key:value for key, value in self.__dict__.items() if not key in ["prog"]}
+        return (state)
+
+    def __setstate__(self, state):
+        self.__dict__ = state
+        super(Partie, self).__init__()
+
+    def nom(self):
+        return self._nom
+    
+    def majNom(self, nom):
+        if len(nom) > 0: self._nom = nom
+
+    def afficher(self, prog):
+        """on affiche la partie"""
+        self.prog = prog
+        self.prog.connect(self.prog.ui.pt_enregistrer, SIGNAL("clicked()"), self.enregistrer) 
+
+        self.prog.connect(self.prog.ui.cbt_enCours, SIGNAL("clicked()"), self.chargerDernierPlateau)   
+        self.prog.connect(self.prog.ui.cbt_charger, SIGNAL("clicked()"), self.afficherEcranChargerPlateau)   
+        self.prog.connect(self.prog.ui.cbt_creer, SIGNAL("clicked()"), self.nouveauPlateau)   
+        self.prog.connect(self.prog.ui.cbt_sauver, SIGNAL("clicked()"), self.enregistrerPlateau)   
+        self.prog.connect(self.prog.ui.cbt_fermer, SIGNAL("clicked()"), self.fermerPlateau)
+        if len(afficheSvg(os.path.join(rep("cbt"), "infos_sauvegarde"))) == 0:
+            self.prog.ui.cbt_enCours.setEnabled(False)
+        
+        self.afficherPlateau(False)
+        self.prog.ui.cbt_vue.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
+        self.prog.ui.cp_ongletsListes.setStyleSheet("QTabBar::tab { width: 41px; }")
+        self.prog.ui.pi_ongletsListes.setStyleSheet("QTabBar::tab { width: 38px; }")
+        
+        self.prog.connect(self.prog.ui.grp_nouveauPj, SIGNAL("clicked()"), self.nouveauPj)
+        self.chargerListePj() 
+        
+        self.majAffichage()
+
+    def creer(self):
+        self.idP = uid("pr")
+
+    def fermer(self):
+        pass
+    
+    def enregistrer(self):
+        super(Partie, self).enregistrer()
+
+    def majAffichage(self):
+        """met a jour l'interface avec les informations de la partie"""
+        self.prog.ui.pt_nom.majTexte("Partie: {}".format(self._nom) )
+        self.prog.ui.pt_chap.majTexte("{}".format(self._ch[self._chEC].nomLong()) )
+        self.prog.ui.pt_presentation.majTexte("{}".format(self._ch[self._chEC].presentation) )
+        self.enregistrer()
+
+    ##### chapitres
+
+    def chapitres(self):
+        return self._ch
+
+    def majChapitres(self, dico):
+        self._ch = dico
+
+    def chapitreEnCours(self):
+        return self._chEC 
+    
+    def majChapitreEnCours(self, num):
+        if num in self._ch: self._chEC = num
+
+    ##### groupe ########"
+    
+    def chargerListePj(self):
+        for attributsFichier in os.walk(rep("grp")):
+            for f in attributsFichier[2]:
+                pj = chargerMat(os.path.join(attributsFichier[0], f))
+                self.pjAjouterAListe(pj)
+        self.prog.ui.grp_deroulement_layout.setAlignment(Qt.AlignTop)
+
+    def pjAjouterAListe(self, pj = None):
+        compteur = len(self.pjs)
+        colonne = (compteur % 3) * 2
+        ligne = int(compteur / 3)
+        self.pjs.append(pj.idM())
+        panneau = FramePj(compteur)
+        if pj:
+            panneau.chargerPj(pj)
+        panneau.setObjectName(QString("pj_panneau_{}".format(compteur)))
+        self.prog.connect(panneau, SIGNAL("pjModifie(int)"), self.pjEnregistrer)
+        self.prog.ui.grp_deroulement_layout.addWidget(panneau, ligne, colonne)
+
+        ## pour l'espacement entre les panneaux
+        w = QWidget()
+        self.prog.ui.grp_deroulement_layout.addWidget(w, ligne, colonne + 1)
+
+    def pjSupprimer(self, index):
+        panneau = self.prog.findChild(QFrame, "pj_panneau_{}".format(index))
+        pj = panneau.pj()
+        supprimerMat(pj.idM(), "grp")
+        self.ui.grp_deroulement_layout.removeWidget(panneau)
+
+    def nouveauPj(self):
+        fen = EcranEditionMateriel(PJ())
+        fen.afficher()
+        fen.exec_()
+        pj = fen.mat()
+        del fen
+        pj.enregistrer("grp")
+        self.pjAjouterAListe(pj)
+
+    def pjEnregistrer(self, idPj):
+        panneau = self.prog.findChild(QFrame, "pj_panneau_{}".format(idPj))
+        pj = panneau.pj()
+        pj.enregistrer("grp")
+
+    ####### plateaux ##########
+    def nouveauPlateau(self):
+        """ouvre la fenetre de creation de plateau"""
+        if self._plEc != None: return
+        fenCP = EcranCreerPlateau()
+        fenCP.afficher( Plateau(self.prog) )
+        r = fenCP.exec_()
+        if r == 1:
+            self._plEc = fenCP.resultat()
+            self._plEc.creer()
+            self.afficherPlateau(True)
+        del fenCP
+        
+        
+    def afficherEcranChargerPlateau(self):
+        """ouvre la fenetre de chargement de plateau"""
+        if self._plEc != None: return
+        fen = EcranChargerPlateau(self)
+        fen.show()
+        r = fen.exec_()
+        if r == 1:
+            idM = fen.resultat()
+            self.chargerPlateau(idM)
+        del fen
+     
+    def chargerDernierPlateau(self):
+        """charge le dernier plateau sauvegarde"""
+        infosSvg = afficheSvg(os.path.join(rep("cbt"), "infos_sauvegarde"))
+        dates = {val["dateSvg"]:key for key, val in infosSvg.items()}
+        if len(dates) == 0: return
+        dernier = dates[max( dates.keys() )]
+        if dernier:
+            self.chargerPlateau(dernier)
+        
+    def chargerPlateau(self, idM):
+        if self._plEc: return
+        self._plEc = chargerMat(idM, "cbt")
+        self._plEc.recreer(self.prog)  
+        self.afficherPlateau(True) 
+
+    def enregistrerPlateau(self):
+        self._plEc.enregistrer("cbt")
+        infos = {"nom": self._plEc.nom(), "chapitre": self._plEc.chapitre, "dateCreation":self._plEc.dateCreation, "dateSvg":self._plEc.dateSvg, \
+                 "public": self._plEc.public, "enCours": self._plEc.enCours}
+        enregistrer(self._plEc.idM(), infos, os.path.join(rep("cbt"), "infos_sauvegarde"))
+    
+    def fermerPlateau(self):
+        self._plEc.fermer()
+        self._plEc = None
+        self.afficherPlateau(False) 
+
+    def majFichierInfosSvg(self):
+        """construit/maj le fichier contenant la liste des
+           plateaux sauvegardes et leurs informations"""
+        #on parcourt les fichiers de sauvegarde
+        f = []
+        lstFichiersSvg = []
+        for (dirpath, dirnames, filenames) in os.walk(rep("cbt")):
+            f.extend(filenames)
+            break
+        for fichier in f:
+            fileName, fileExtension = os.path.splitext(fichier)
+            if fileExtension == ".dm":
+                lstFichiersSvg.append(fileName)
+
+        #on verifie leur presence dans le fichier 'infos_sauvegarde'
+        infosSvg = afficheSvg(os.path.join(rep("cbt"), "infos_sauvegarde"))
+        index = len(infosSvg)
+
+        #on ajoute les sauvegardes manquantes si besoin
+        for fichier in lstFichiersSvg:
+            if not fichier in infosSvg:
+                plateau = chargerUnique(os.path.join(rep("cbt"), "{}.dm".format(fichier)))
+                enregistrer(fichier, {"nom": plateau.nom(), "chapitre": plateau.chapitre, "dateCreation":plateau.dateCreation, "dateSvg":plateau.dateSvg, \
+                                      "public": plateau.public, "enCours": plateau.enCours}, "svg\\infos_sauvegarde")
+                index += 1     
+                  
+        #on supprime ceux qui ne sont plus trouves
+        for fichier in infosSvg:
+            if not fichier in lstFichiersSvg:
+                supprSvg(os.path.join(rep("cbt"), "infos_sauvegarde"), fichier)            
+
+
+    def afficherPlateau(self, actif):
+        index = int(actif)   # 0 si faux, 1 si vrai
+        self.prog.ui.combatPanneau.setCurrentIndex(index)
+#         self.prog.ui.cbt_panneauBas.setCurrentIndex(index)
+#         self.prog.ui.cbt_panneauHaut.setCurrentIndex(index)
+#         self.prog.ui.cbt_panneauDroite.setCurrentIndex(index)
+#         self.prog.ui.cbt_panneauGauche.setCurrentIndex(index)
+#         self.prog.ui.cbt_etapeSuivante.setVisible(actif)
+
+
+class Chapitre():
+    def __init__(self, numero, nom = "", presentation = "", public = False):
+        self.num = numero
+        self.nom = nom
+        self.presentation = ""
+        self.public = public
+        
+    def nomLong(self):
+        if len(self.nom) > 0:
+            return "Ch. {} - {}".format(self.num, self.nom) 
+        else:
+            return "Chapitre {}".format(self.num)
+    
+    

+ 11 - 11
lib/Pinceau.py

@@ -1,9 +1,9 @@
 """pinceau utilise pour la selection et la mise a jour des cases du plateau"""
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from Terrain import Terrain
-from dmF import *
-import br
+from PyQt4.QtCore import QLineF, QRectF, QPointF
+from PyQt4.QtGui import QPen, QColor, QGraphicsLineItem, QGraphicsRectItem
+
+from lib.dmF import mini, maxi
+
 
 class Pinceau():
     def __init__(self, plateau):
@@ -38,12 +38,12 @@ class Pinceau():
             self._epaisseur = val
 
     def defOrigine(self, coord):
-        if self.plateau.coordonneesValides(coord):
+        if self.plateau.geo.coordonneesValides(coord):
             self._coordOrigine = coord
             self._origine = self.plateau.cases[coord].centreGraphique
 
     def defPoint2(self, coord):
-        if self.plateau.coordonneesValides(coord):
+        if self.plateau.geo.coordonneesValides(coord):
             self._point2 = self.plateau.cases[coord].centreGraphique
 
     def selection(self):
@@ -52,7 +52,7 @@ class Pinceau():
     def demarrer(self, coord):
         """commence a peindre a partir de la case choisie comme origine"""
         self._formeVerrouillee = False
-        if self.plateau.coordonneesValides(coord):
+        if self.plateau.geo.coordonneesValides(coord):
             self._coordOrigine = coord
             self._origine = self.plateau.cases[coord].centreGraphique
             self._point2 = self.plateau.cases[coord].centreGraphique
@@ -67,7 +67,7 @@ class Pinceau():
             if self._origine == None: self._origine = self.plateau.cases[coord].centreGraphique
             if self._forme == "simple":
                 #pas de forme: on ajoute les cases survolees a la liste des cases
-                zone = self.plateau.zone(coord, self._epaisseur - 1)
+                zone = self.plateau.geo.zone(coord, self._epaisseur - 1)
                 for coord in zone:
                     if not coord in self._selection:
                         enPlus.append(coord)
@@ -143,7 +143,7 @@ class Pinceau():
                 #on prend l'epaisseur en compte
                 selectPlus = []
                 for coord in select:
-                    zone = self.plateau.zone(coord, self._epaisseur - 1)
+                    zone = self.plateau.geo.zone(coord, self._epaisseur - 1)
                     for ajout in zone:
                         if not ajout in select and not ajout in selectPlus:
                             selectPlus.append(ajout)
@@ -179,7 +179,7 @@ class Pinceau():
         self.plateau.cases[coord].majEstCibleCurseur(actif)
 
     def selectionLigne(self, coord0, coord1):
-        retour = br.ligne(coord0, coord1, self.plateau.formeCases)
+        retour = self.plateau.geo.ligne(coord0, coord1)
         return retour
 
     def selectionRectangle(self, coord0, coord1, plein = True):

+ 2 - 2
lib/Pion.py

@@ -137,7 +137,7 @@ class Pion(QGraphicsObject):
 
     def zA(self):
         """retourne la coord z absolue du pion"""
-        return (self.plateau.cases[self.position].z0 + self.zR)
+        return (self.plateau.cases[self.position].zA(self.numero))
 
     ########### fonctions graphiques et geometriques   ##############
     def ajouterAuPlateau(self, plateau):
@@ -157,7 +157,7 @@ class Pion(QGraphicsObject):
 
         ### ajout des items enfants (dans l'ordre d'empilement)
         #creation du polygone
-        polygone = self.plateau.polygoneAgglo(self.forme.listeCases((0,0)))
+        polygone = self.plateau.geo.polygoneAgglo(self.forme.listeCases((0,0)))
         self.pion.creer(self, polygone)
         #image:
         self.img.creer(self)

+ 221 - 195
lib/Plateau.py

@@ -2,19 +2,17 @@
 # -*- coding: utf-8 -*-
 from __future__ import division
 
-from math import sqrt
 from time import time
 
-from PyQt4.QtCore import Qt, SIGNAL, QPointF, QString, QLineF
+from PyQt4.QtCore import Qt, SIGNAL, QPointF, QString
 from PyQt4.QtGui import QGraphicsScene, QColor, QPixmap, QPainter, QIcon, \
     QTableWidgetItem, QToolButton, QColorDialog, QMessageBox, \
-    QApplication, QPolygonF, QGraphicsPolygonItem, QPen, QGraphicsView
+    QApplication, QGraphicsPolygonItem, QPen, QGraphicsView, QTableWidget, \
+    QLineEdit, QTextEdit, QSlider, QDoubleSpinBox
 
 import Actions
 from Cache import Cache
 from Case import Case
-from Combattant import Combattant
-from Decor import Decor
 from EcranAffichageTexte import EcranAffichageTexte
 from EcranCreerPlateau import EcranCreerPlateau
 from EcranGestionCombat import EcranGestionCombat
@@ -22,14 +20,14 @@ import Modes
 from Pinceau import Pinceau
 from ProjectionDep import ProjectionDep
 from Terrain import Terrain
-import br
-from lib.Actions import EcranAttaqueZone
+from lib.Actions import choisirAttaqueZone
 from lib.EcranEditionMateriel import EcranEditionMateriel
 from lib.ListePions import ListePions
 from lib.commun import lstLibEtats
-from lib.dmF import inverser, contractTxt
+from lib.dmF import contractTxt
 from lib.gC import GestionCombat
 from lib.gM import GestionMateriel
+from lib.geometrie import Geometrie
 from lib.mat import Materiel, chargerMat
 import regles as regles
 
@@ -65,6 +63,7 @@ class Plateau(QGraphicsScene, Materiel):
         self.pinceau = Pinceau(self)
         self.gM = GestionMateriel()
         self.gC = GestionCombat()
+        self.geo = Geometrie()
         self.cases = {}   #dict des cases du plateau   (coordonnées: case)
         self.pions = ListePions()
         self.caches = {}
@@ -107,7 +106,7 @@ class Plateau(QGraphicsScene, Materiel):
     def creer(self):
         """cree le plateau"""
         self.dateCreation = time()
-        self.creePar = self.fenetre.util
+        self.creePar = self.fenetre.profil.pseudo()
         self.hCase = 120  #hauteur d'une case
         self.modeActif = Modes.ModeBase(self)
         self.gestionCombat = None
@@ -115,11 +114,10 @@ class Plateau(QGraphicsScene, Materiel):
         self.connexions()
         
         #cree les cases hexagonales
-        for x in range(self.nbCasesX):
-            for y in range(self.nbCasesY):
-                c = Case(self)
-                c.creer(x, y, self.couleurInit)
-                self.cases[(x,y)] = c
+        for x, y in self.geo.listeCases():
+            c = Case(self)
+            c.creer(x, y, self.couleurInit)
+            self.cases[(x, y)] = c
 
         self.plateauModeCreation()
 
@@ -175,7 +173,32 @@ class Plateau(QGraphicsScene, Materiel):
             self.removeItem(item)
         if self.gestionCombat != None:    
             del self.gestionCombat           
-        self.fenetre.reinitialiserPanneauxPlateau()
+        self.reinitialiserPanneaux()
+
+    def reinitialiserPanneaux(self):
+        """remet a neuf les commandes liees au plateau"""
+        for panneau in [self.fenetre.ui.cbt_panneauHaut, \
+                         self.fenetre.ui.cbt_panneauBas, \
+                         self.fenetre.ui.cbt_panneauGauche, \
+                         self.fenetre.ui.cbt_panneauDroite]:
+            #listes
+            for liste in panneau.findChildren(QTableWidget):
+                while liste.rowCount() > 0:
+                    liste.removeRow(0)
+            #textes
+            for texte in panneau.findChildren(QLineEdit):
+                texte.clear()         
+            for texte in panneau.findChildren(QTextEdit):
+                texte.clear()
+            #a cocher
+            for bouton in panneau.findChildren(QToolButton):
+                if bouton.isCheckable():
+                    bouton.setChecked(False)
+            #autre
+            for item in panneau.findChildren(QSlider):
+                item.setValue(1)
+            for item in panneau.findChildren(QDoubleSpinBox):
+                item.setValue(0)   
 
     def miniature(self):
         """renvoie une miniature du plateau (QPixMap compresse) qui sera enregistree avec les infos de la sauvegarde"""
@@ -205,7 +228,6 @@ class Plateau(QGraphicsScene, Materiel):
         self.fenetre.connect(self.fenetre.ui.cp_afficherNotes, SIGNAL("clicked()"), self.agrandirNotesMjPlateau, Qt.UniqueConnection)
         self.fenetre.connect(self.fenetre.ui.pi_fiche, SIGNAL("clicked()"), self.afficherFichePion, Qt.UniqueConnection)
         
-        
         #listes
         self.fenetre.connect(self.fenetre.ui.cp_listeTerrains, SIGNAL("cellClicked(int,int)"), self.modeMajTerrainCase, Qt.UniqueConnection)
         self.fenetre.connect(self.fenetre.ui.cp_listeCreatures, SIGNAL("cellClicked(int,int)"), self.modeCreationCombattant, Qt.UniqueConnection)
@@ -261,11 +283,11 @@ class Plateau(QGraphicsScene, Materiel):
         self.proj = ProjectionDep(self)
   
         #mise a jour de l'interface de creation
-        self.fenetre.afficherPanneauxPlateau(True)
         self.majNomPlateau()
         self.majBoutonsCouleursPerso()
         self.gM.initialiser(self.fenetre)
         self.gC.initialiser(self)
+        self.geo.initialiser(self)
         
         self.initListeAttaques()
         self.majBoutonEtape()
@@ -273,7 +295,7 @@ class Plateau(QGraphicsScene, Materiel):
         self.fenetre.ui.act_deplacement.setCheckable(True)
         self.fenetre.ui.act_attaqueCac.setCheckable(True)
         self.fenetre.ui.act_attaqueDist.setCheckable(True)
-        self.fenetre.ui.act_attaqueZone.setCheckable(True)
+#         self.fenetre.ui.act_attaqueZone.setCheckable(True)
 
         #mise a jour de l'interface d'informations
         self.majInfoCb(None)
@@ -629,13 +651,18 @@ class Plateau(QGraphicsScene, Materiel):
         self.modeActif.nouvelleAction(Actions.Distance)
 
     def majModeCombatZone(self):
-        fen = EcranAttaqueZone()
-        fen.show()
-        fen.exec_()
-        action = fen.resultat()
-        if action:    
-            self.modeActif.nouvelleAction(action)      
+        action = choisirAttaqueZone()   
+        self.modeActif.nouvelleAction(action)      
 
+#     def majModeCombatLigne(self):
+#         self.modeActif.nouvelleAction(Actions.Ligne)
+#         
+#     def majModeCombatDisque(self):
+#         self.modeActif.nouvelleAction(Actions.Disque)
+#         
+#     def majModeCombatCone(self):
+#         self.modeActif.nouvelleAction(Actions.Cone)
+        
     def majModeDefinirEntree(self):
         self.activerMode(Modes.CreationEntreeSortie, "E")
 
@@ -1028,179 +1055,178 @@ class Plateau(QGraphicsScene, Materiel):
         """centre la vue sur le pion"""
         self.vue().centerOn(self.cases[self.pions[num].position].centreGraphique)
 
-    def coordonneesValides(self, coord):
-        """les coordonnees entrees en parametre sont elles celles d'une case du plateau"""
-        return (coord[0] >= 0 and coord[1] >= 0 and coord[0] < self.nbCasesX and coord[1] < self.nbCasesY)
-
-    def lstCoordAdjacentes(self, x, y):
-        """renvoie la liste des coordonnees adjacentes, !!!! sans condition d'existence sur le plateau !!!!
-           attention: l'ordre est important"""
-        if self.formeCases == "H":
-            if 1 == (x % 2):
-                voisins = [(x, y-1), (x+1, y), (x+1, y+1), (x,  y+1), (x-1, y+1), (x-1, y)]
-            else:
-                voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
-        else:
-            voisins = [(x, y-1), (x+1, y), (x,   y+1), (x-1, y)]
-        return voisins      
-
-    def zone(self, origine, rayon, zR = 0):
-        """renvoie un dictionnaire representant la liste des coordonnees des cases comprises dans la zone
-           la zone en question est la liste des cases situees a une distance d des coordonnees d'origine
-           zR -> altitude relative de l'origine de la zone"""
-        if not self.coordonneesValides(origine) or not rayon >= 0: return {}
-        if rayon == 0: return {origine: 0}
-        resultat = {}
-        aVerifier = [] ; aVerifier2 = [] ; k = 0        
-        #on part de la premiere case, puis on itere a partir de chaque nouveau depart sur les voisins
-        aVerifier.append(origine)
-        while k <= rayon:
-            for depart in aVerifier:
-                for coord in self.cases[depart].voisins:
-                    if not coord in aVerifier and not coord in aVerifier2 and not coord in resultat:
-                        aVerifier2.append(coord)      
-            for elt in aVerifier:
-                resultat[elt] = k
-            aVerifier = aVerifier2 ; aVerifier2 = [] ; k += 1
-        return resultat
-
-    def zone3d(self, origine, rayon, zCible=0):
-        """renvoie les cases de la zone au format (x, y, z)"""
-        retour = []
-        zone = self.zone(origine, rayon)
-        for coord in zone:
-            x, y = coord
-            dz = rayon - zone[coord]
-            for z in range(-dz, dz + 1):
-                retour.append( (x, y, (zCible+z) ) )
-        return retour            
-
-    def cone(self, coord1, coord2):
-        """renvoie les coord des cases composant le cone (en 2d)"""
-        retour = []
-        x1, y1 = coord1 ; x2, y2 = coord2
-        if x1 % 2 == 1: y1 += 0.5
-        if x2 % 2 == 1: y2 += 0.5
-        
-        if abs(y2 - y1) - abs(x2 - x1) <= 0 :
-            #secteur horizontal
-            angleRef = (y2 - y1) / (x2 - x1)
-            dist2Ref = ( (x2 - x1)**2 + (y2 - y1)**2 )
-            for coord in self.cases:
-                x, y = coord
-                if x % 2 == 1: y += 0.5
-                if x != x1:
-                    angle = (y - y1) / (x - x1)
-                    if abs( angleRef - angle ) <= 0.5 and ( (x - x1)**2 + (y - y1)**2 ) <= dist2Ref \
-                    and ( (x - x1) * (x2 - x1) ) > 0:
-                        retour.append(coord)                
-        else:
-            #secteur vertical
-            angleRef = (x2 - x1) / (y2 - y1)
-            dist2Ref = ( (x2 - x1)**2 + (y2 - y1)**2 )
-            for coord in self.cases:
-                x, y = coord
-                if x % 2 == 1: y += 0.5
-                if y != y1:
-                    angle = (x - x1) / (y - y1)
-                    if abs( angleRef - angle ) <= 0.5 and ( (x - x1)**2 + (y - y1)**2 ) <= dist2Ref \
-                    and ( (y - y1) * (y2 - y1) ) > 0:
-                        retour.append(coord) 
-        return retour    
-
-    def cone3d(self, coord1, coord2, z1 = 0, z2 = 0):
-        return self.cone(coord1, coord2)
+#     def coordonneesValides(self, coord):
+#         """les coordonnees entrees en parametre sont elles celles d'une case du plateau"""
+#         return (coord[0] >= 0 and coord[1] >= 0 and coord[0] < self.nbCasesX and coord[1] < self.nbCasesY)
+# 
+#     def lstCoordAdjacentes(self, x, y):
+#         """renvoie la liste des coordonnees adjacentes, !!!! sans condition d'existence sur le plateau !!!!
+#            attention: l'ordre est important"""
+#         if self.formeCases == "H":
+#             if 1 == (x % 2):
+#                 voisins = [(x, y-1), (x+1, y), (x+1, y+1), (x,  y+1), (x-1, y+1), (x-1, y)]
+#             else:
+#                 voisins = [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
+#         else:
+#             voisins = [(x, y-1), (x+1, y), (x,   y+1), (x-1, y)]
+#         return voisins      
+
+#     def zone(self, origine, rayon, zR = 0):
+#         """renvoie un dictionnaire representant la liste des coordonnees des cases comprises dans la zone
+#            la zone en question est la liste des cases situees a une distance d des coordonnees d'origine"""
+#         if not self.coordonneesValides(origine) or not rayon >= 0: return {}
+#         if rayon == 0: return {origine: 0}
+#         resultat = {}
+#         aVerifier = [] ; aVerifier2 = [] ; k = 0        
+#         #on part de la premiere case, puis on itere a partir de chaque nouveau depart sur les voisins
+#         aVerifier.append(origine)
+#         while k <= rayon:
+#             for depart in aVerifier:
+#                 for coord in self.cases[depart].voisins:
+#                     if not coord in aVerifier and not coord in aVerifier2 and not coord in resultat:
+#                         aVerifier2.append(coord)      
+#             for elt in aVerifier:
+#                 resultat[elt] = k
+#             aVerifier = aVerifier2 ; aVerifier2 = [] ; k += 1
+#         return resultat
+
+#     def zone3d(self, origine, rayon, zCible=0):
+#         """renvoie les cases de la zone au format (x, y, z)"""
+#         retour = []
+#         zone = self.zone(origine, rayon)
+#         for coord in zone:
+#             x, y = coord
+#             dz = rayon - zone[coord]
+#             for z in range(-dz, dz + 1):
+#                 retour.append( (x, y, (zCible+z) ) )
+#         return retour            
+
+#     def cone(self, coord1, coord2):
+#         """renvoie les coord des cases composant le cone (en 2d)"""
+#         retour = []
+#         x1, y1 = coord1 ; x2, y2 = coord2
+#         if x1 % 2 == 1: y1 += 0.5
+#         if x2 % 2 == 1: y2 += 0.5
+#         
+#         if abs(y2 - y1) - abs(x2 - x1) <= 0 :
+#             #secteur horizontal
+#             angleRef = (y2 - y1) / (x2 - x1)
+#             dist2Ref = ( (x2 - x1)**2 + (y2 - y1)**2 )
+#             for coord in self.cases:
+#                 x, y = coord
+#                 if x % 2 == 1: y += 0.5
+#                 if x != x1:
+#                     angle = (y - y1) / (x - x1)
+#                     if abs( angleRef - angle ) <= 0.5 and ( (x - x1)**2 + (y - y1)**2 ) <= dist2Ref \
+#                     and ( (x - x1) * (x2 - x1) ) > 0:
+#                         retour.append(coord)                
+#         else:
+#             #secteur vertical
+#             angleRef = (x2 - x1) / (y2 - y1)
+#             dist2Ref = ( (x2 - x1)**2 + (y2 - y1)**2 )
+#             for coord in self.cases:
+#                 x, y = coord
+#                 if x % 2 == 1: y += 0.5
+#                 if y != y1:
+#                     angle = (x - x1) / (y - y1)
+#                     if abs( angleRef - angle ) <= 0.5 and ( (x - x1)**2 + (y - y1)**2 ) <= dist2Ref \
+#                     and ( (y - y1) * (y2 - y1) ) > 0:
+#                         retour.append(coord) 
+#         return retour    
+# 
+#     def cone3d(self, coord1, coord2, z1 = 0, z2 = 0):
+#         return self.cone(coord1, coord2)
    
 
-    def blocAdjacent(self, listeCases):
-        """renvoie un bloc de cases adjacentes a partir de la liste en parametre"""
-        retour = []
-        tmp1 = [listeCases[0]]; tmp2 = [listeCases[0]]
-        while len(tmp2) > 0:
-            tmp2 = []
-            #on liste les cases voisines qui sont dans la liste et pas encore verifiees
-            for coord in tmp1:
-                for voisine in self.cases[coord].voisins:
-                    if voisine in listeCases and not voisine in tmp1 and not voisine in tmp2:
-                        tmp2.append(voisine)
-            #chacune de ces cases prend le statut de verifiee
-            for coord in tmp1:
-                listeCases.remove(coord)
-                retour.append(coord)
-            tmp1 = tmp2
-        return retour 
+#     def blocAdjacent(self, listeCases):
+#         """renvoie un bloc de cases adjacentes a partir de la liste en parametre"""
+#         retour = []
+#         tmp1 = [listeCases[0]]; tmp2 = [listeCases[0]]
+#         while len(tmp2) > 0:
+#             tmp2 = []
+#             #on liste les cases voisines qui sont dans la liste et pas encore verifiees
+#             for coord in tmp1:
+#                 for voisine in self.cases[coord].voisins:
+#                     if voisine in listeCases and not voisine in tmp1 and not voisine in tmp2:
+#                         tmp2.append(voisine)
+#             #chacune de ces cases prend le statut de verifiee
+#             for coord in tmp1:
+#                 listeCases.remove(coord)
+#                 retour.append(coord)
+#             tmp1 = tmp2
+#         return retour 
     
 
-    def polygone(self, x, y):
-        """renvoie l'objet graphique hexagone de la case de coordonnees (x, y)"""
-        polygone = QPolygonF()
-        if self.formeCases == "H":
-            #si x est impair sur un plateau a cases hexagonales, le y est augmente de 0.5
-            if 1 == (x % 2):
-                y += 0.5
-            polygone  << QPointF(((x*0.866)+0.2886)*120,  y*120) \
-                      << QPointF(((x*0.866)+0.866)*120,   y*120) \
-                      << QPointF(((x*0.866)+1.1547)*120, (y+0.5)*120) \
-                      << QPointF(((x*0.866)+0.866)*120,  (y+1)*120) \
-                      << QPointF(((x*0.866)+0.2886)*120, (y+1)*120)  \
-                      << QPointF( (x*0.866)*120,         (y+0.5)*120)
-        else:
-            polygone  << QPointF(x*120,      y*120) \
-                      << QPointF((x+1)*120,  y*120) \
-                      << QPointF((x+1)*120,  (y+1)*120) \
-                      << QPointF(x*120,      (y+1)*120)          
-        return polygone
+#     def polygone(self, x, y):
+#         """renvoie l'objet graphique hexagone de la case de coordonnees (x, y)"""
+#         polygone = QPolygonF()
+#         if self.formeCases == "H":
+#             #si x est impair sur un plateau a cases hexagonales, le y est augmente de 0.5
+#             if 1 == (x % 2):
+#                 y += 0.5
+#             polygone  << QPointF(((x*0.866)+0.2886)*120,  y*120) \
+#                       << QPointF(((x*0.866)+0.866)*120,   y*120) \
+#                       << QPointF(((x*0.866)+1.1547)*120, (y+0.5)*120) \
+#                       << QPointF(((x*0.866)+0.866)*120,  (y+1)*120) \
+#                       << QPointF(((x*0.866)+0.2886)*120, (y+1)*120)  \
+#                       << QPointF( (x*0.866)*120,         (y+0.5)*120)
+#         else:
+#             polygone  << QPointF(x*120,      y*120) \
+#                       << QPointF((x+1)*120,  y*120) \
+#                       << QPointF((x+1)*120,  (y+1)*120) \
+#                       << QPointF(x*120,      (y+1)*120)          
+#         return polygone
     
-    def polygoneAgglo(self, listeCases):
-        """renvoie un polygone contruit par agglomeration des polygones des cases de la liste
-           les cases doivent etre adjacentes (cases hexagonales ou carrees)"""
-        segments = []
-        #on parcourt les faces des polygones des cases, et on ne garde que ceux qui n'ont pas de case 'en face'
-        for coord in listeCases:
-            polygone = self.polygone(coord[0], coord[1])
-            voisins = self.lstCoordAdjacentes(coord[0], coord[1])
-            
-            for i in range(0, len(voisins)):
-                if not voisins[i] in listeCases:
-                    j = i+1
-                    if j > len(voisins) - 1:
-                        j = 0
-                    segments.append(QLineF(polygone[i], polygone[j]))
-
-        #on 'accroche' les segments les uns aux autres, dans l'ordre
-        if not len(segments) > 0: return None
-        segments2 = [segments[0]]
-        for segment2 in segments2:
-            for segment in segments:
-                if not QLineF(segment.p1(), segment.p2()) in segments2 and not QLineF(segment.p2(), segment.p1()) in segments2:
-                    if sqrt((segment.p1().x()-segment2.p2().x())**2+(segment.p1().y()-segment2.p2().y())**2) < 1:
-                        segments2.append(QLineF(segment.p1(), segment.p2()))
-                    elif sqrt((segment.p2().x()-segment2.p2().x())**2+(segment.p2().y()-segment2.p2().y())**2) < 1:   
-                        segments2.append(QLineF(segment.p2(), segment.p1()))
-
-        pointsPolygone = []
-        premierPoint = segments2[0].p1()
-        pointsPolygone.append(premierPoint)
-        for segment in segments2:
-            pointSuivant = segment.p2()
-            if pointSuivant != premierPoint:
-                pointsPolygone.append(pointSuivant)
-
-        #creation du polygone
-        polygone = QPolygonF()
-        for point in pointsPolygone:   
-            polygone.append(point)   
-
-        return polygone  
-
-    def coordCentreListeCases(self, listeCases):
-        """renvoie les coordonnees centrales d'une liste de cases"""
-        retour = None
-        if len(listeCases) > 0:
-            listeTriee = sorted(listeCases)
-            posMilieu = int(len(listeCases)/2)
-            retour = listeTriee[posMilieu]
-        return retour    
+#     def polygoneAgglo(self, listeCases):
+#         """renvoie un polygone contruit par agglomeration des polygones des cases de la liste
+#            les cases doivent etre adjacentes (cases hexagonales ou carrees)"""
+#         segments = []
+#         #on parcourt les faces des polygones des cases, et on ne garde que ceux qui n'ont pas de case 'en face'
+#         for coord in listeCases:
+#             polygone = self.polygone(coord[0], coord[1])
+#             voisins = self.lstCoordAdjacentes(coord[0], coord[1])
+#             
+#             for i in range(0, len(voisins)):
+#                 if not voisins[i] in listeCases:
+#                     j = i+1
+#                     if j > len(voisins) - 1:
+#                         j = 0
+#                     segments.append(QLineF(polygone[i], polygone[j]))
+# 
+#         #on 'accroche' les segments les uns aux autres, dans l'ordre
+#         if not len(segments) > 0: return None
+#         segments2 = [segments[0]]
+#         for segment2 in segments2:
+#             for segment in segments:
+#                 if not QLineF(segment.p1(), segment.p2()) in segments2 and not QLineF(segment.p2(), segment.p1()) in segments2:
+#                     if sqrt((segment.p1().x()-segment2.p2().x())**2+(segment.p1().y()-segment2.p2().y())**2) < 1:
+#                         segments2.append(QLineF(segment.p1(), segment.p2()))
+#                     elif sqrt((segment.p2().x()-segment2.p2().x())**2+(segment.p2().y()-segment2.p2().y())**2) < 1:   
+#                         segments2.append(QLineF(segment.p2(), segment.p1()))
+# 
+#         pointsPolygone = []
+#         premierPoint = segments2[0].p1()
+#         pointsPolygone.append(premierPoint)
+#         for segment in segments2:
+#             pointSuivant = segment.p2()
+#             if pointSuivant != premierPoint:
+#                 pointsPolygone.append(pointSuivant)
+# 
+#         #creation du polygone
+#         polygone = QPolygonF()
+#         for point in pointsPolygone:   
+#             polygone.append(point)   
+# 
+#         return polygone  
+
+#     def coordCentreListeCases(self, listeCases):
+#         """renvoie les coordonnees centrales d'une liste de cases"""
+#         retour = None
+#         if len(listeCases) > 0:
+#             listeTriee = sorted(listeCases)
+#             posMilieu = int(len(listeCases)/2)
+#             retour = listeTriee[posMilieu]
+#         return retour    
 
     def coordonneesAuPoint(self, point):
         """renvoie les coordonnees de la case situee au QPointF entre en parametre"""
@@ -1223,7 +1249,7 @@ class Plateau(QGraphicsScene, Materiel):
         """la ligne de mire entre les deux points est elle valide
            origine et cible sont toutes deux de la forme (x,y,z)"""
         if not cible != origine: return False
-        ldm = br.ligne(origine, cible, self.formeCases)
+        ldm = self.geo.ligne(origine, cible)
         if len(ldm) == 0: return False
         ldm.remove(origine) ; ldm.remove(cible)
         x0, y0, z0 = origine ; x1, y1, z1 = cible
@@ -1294,9 +1320,9 @@ class Plateau(QGraphicsScene, Materiel):
             for coord in listeCases:
                 if self.cases[coord].terrain.franchissable:
                     listeCases2.append(coord)
-            listeCases3 = self.blocAdjacent(listeCases2)
+            listeCases3 = self.geo.blocAdjacent(listeCases2)
 
-            polygone = self.polygoneAgglo(listeCases3)
+            polygone = self.geo.polygoneAgglo(listeCases3)
             if not polygone: return
             self.polygoneZonePlacement.setPolygon(polygone)
             self.listeCasesZonePlacement = listeCases

+ 53 - 0
lib/Profil.py

@@ -0,0 +1,53 @@
+'''
+Profil de l'utilisateur connecte
+'''
+from lib.commun import uid
+
+
+class Profil(object):
+    def __init__(self):
+        self._idPr = None   #uid du profil
+        self._ps = "defaut"  #pseudo
+        self._mdp = None     #mot de passe (optionnel)
+        self._ip = ""         #adresse ip (optionnel)
+        self._port = ""        #port (optionnel)
+        self._pEc = None      #partie en cours
+    
+    def idPr(self):
+        return self._idPr
+    
+    def pseudo(self):
+        return self._ps
+    
+    def majPseudo(self, pseudo):
+        self._ps = pseudo
+    
+    def majMdp(self, mdp):
+        self._mdp = mdp
+    
+    def partieEnCours(self):
+        return self._pEc
+    
+    def majPartieEnCours(self, idP):
+        self._pEc = idP
+    
+    def ip(self):
+        return self._ip
+    
+    def majIp(self, ip):
+        self._ip = ip
+    
+    def port(self):
+        return self._port
+    
+    def majPort(self, port):
+        self._port = port
+    
+    def nouveau(self, pseudo, mdp = None):
+        self._idPr = uid("pr")
+        if len(pseudo) > 0:
+            self._ps = pseudo
+        if mdp:
+            self._mdp = mdp
+        
+        

+ 0 - 199
lib/br.py

@@ -1,199 +0,0 @@
-"""Algorithme de Bresenham"""
-from __future__ import division
-from math import sqrt
-
-def ligne(coord1, coord2, formeCases = "H"):
-    if coord1[0] != coord2[0] or coord1[1] != coord2[1]:
-        if len(coord1) == 2 and len(coord2) == 2:
-            retour = _ligne2d(coord1, coord2, formeCases)
-        elif len(coord1) == 3 and len(coord2) == 3:
-            retour = _ligne3d(coord1, coord2, formeCases)
-        elif len(coord1) == 2 and len(coord2) == 3: 
-            x1, y1 = coord1
-            retour = _ligne3d((x1, y1, 0), coord2, formeCases)
-        elif len(coord1) == 2 and len(coord2) == 3: 
-            x2, y2 = coord2
-            retour = _ligne3d(coord1, (x2, y2, 0), formeCases)
-        else:
-            retour = [coord1]   
-    else:            
-        retour = [coord1]
-         
-    return retour    
-                
-def _ligne2d(coord1, coord2, formeCases = "H"):
-    """renvoie la liste des cases traversees par la ligne entre les cases 1 et 2
-        prend en parametre des coord de la forme (x,y)"""
-    x1, y1 = coord1
-    x2, y2 = coord2
-
-    # on inverse les coord si necessaire (si on va de gauche a droite)
-    inversee = False
-    if x1 > x2:
-        x1, x2 = x2, x1
-        y1, y2 = y2, y1
-        inversee = True
-
-    if formeCases == "H":
-        retour = _brH(x1, y1, x2, y2)
-    else:
-        retour = _brC(x1, y1, x2, y2)
-        
-    # retourne la liste si les coordonnees ont ete interverties
-    if inversee:
-        retour.reverse()
-    return retour
-
-
-def _ligne3d(coord1, coord2, formeCases = "H"):
-    """renvoie la liste des cases traversees par la ligne entre les cases 1 et 2
-        prend en parametre des coord de la forme (x,y, z)"""
-    x1, y1, z1 = coord1
-    x2, y2, z2 = coord2
-    ligne = _ligne2d((x1, y1), (x2, y2), formeCases)
-    ligneZ = _brC(0, z1, (len(ligne)-1), z2)
-    
-    retour = []
-    for coordZ in ligneZ:
-        dist, z = coordZ
-        x, y = ligne[dist]
-        retour.append((x, y, z))
-        
-    return retour
-
-def _brC(x1, y1, x2, y2):
-    """Algorithme ligne de Bresenham (pour cases carrees)"""
-
-    # on verifie si la ligne est plus verticale qu'horizontale
-    estVerticale = abs(y2 - y1) > abs(x2 - x1)
-    if estVerticale:
-        x1, y1 = y1, x1
-        x2, y2 = y2, x2  
-
-    # Calcul des ecarts
-    dx = x2 - x1
-    dy = y2 - y1
- 
-    # Calcul de l'erreur  (l'ecart qui doit s'accumuler au fur et a mesure qu'on avance)
-    #2dx est l'unite, de maniere a travailler avec des entiers
-    error = 0.0
-    pasY = 1 if y1 < y2 else -1
- 
-    # on itere sur les coordonnees de la boite qui contient les coordonnees 1 et 2
-    y = y1
-    retour = []
-    for x in range(x1, x2 + 1):
-        coord = (y, x) if estVerticale else (x, y)
-        retour.append(coord)
-        error += (abs(dy) / dx)
-        if error > 0.5:
-            y += pasY
-            error -= 1.0
-
-    return retour
-
-def _brH(x1, y1, x2, y2):
-    """Algorithme ligne de Bresenham (pour cases hexagonales)"""
-    #calcul selon secteur
-    if abs(x2 - x1) < (2*abs((y2-y1)) + abs(x2 % 2) - abs(x1 % 1)):
-        retour = _brH_v(x1, y1, x2, y2)
-    else:
-        retour = _brH_h(x1, y1, x2, y2)   
-    return retour
-        
-def _brH_h(x1, y1, x2, y2):
-    """Algorithme ligne de Bresenham (pour cases hexagonales - secteur horizontal)"""  
-    # Calcul des ecarts
-    dx = x2 - x1
-    dy = y2 - y1 
-    if (x1 + x2) % 2 == 1: 
-        if x1 % 2 == 0:
-            dy += 0.5
-        else:
-            dy -= 0.5
-                
-    # Calcul de l'erreur  (l'ecart qui doit s'accumuler au fur et a mesure qu'on avance)
-    k = dy / dx
-    pas = 1
-    
-    # on itere sur les coordonnees de la boite qui contient les coordonnees 1 et 2
-    retour = []
-    d = 0.0
-    pos = (x1, y1)
-    retour.append(pos)
-    
-    while pos != (x2, y2):
-        d += k*pas
-        if d > 0:
-            #on se deplace vers la case en dessous a droite 
-            x, y = pos
-            if x %2 == 0:
-                pos = x + 1, y 
-            else:
-                pos = x + 1, y + 1 
-            retour.append(pos)
-            d -= 0.5
-        else:
-            #on se deplace vers la case au dessus a droite
-            x, y = pos
-            if x %2 == 0:
-                pos = x + 1, y - 1   
-            else:
-                pos = x + 1, y         
-            retour.append(pos)
-            d += 0.5
-        
-        if pos[0] > x2:
-            retour = []
-            break
-                      
-    return retour
-    
-def _brH_v(x1, y1, x2, y2):
-    """Algorithme ligne de Bresenham (pour cases hexagonales - secteur vertical)"""
-    #on prend comme unite la demi largeur: u = 0.5773
-    #la demi hauteur d'un hexa vaut donc 0.8860u, ou sqrt(3)/2
-    #[a revoir] une fois cela pose, on muliplie tout par 4dy afin d'eviter nombres flottants et divisions
-    sens = 1 if y2 > y1 else -1
-
-    # Calcul des ecarts
-    dx = 1.5 * (x2 - x1)      #en x, on a 1.5u de centre a centre
-    dy = sens * (y2 - y1)     #en y, on compte en demi hauteurs
-    if (x1 + x2) % 2 == 1: 
-        if x1 % 2 == 0:
-            dy += sens*0.5
-        else:
-            dy -= sens*0.5
-
-    k = dx/(dy*sqrt(3)) #k est la tangente de l'angle par rapport a la verticale
-    pas = 0.5*sqrt(3)   #on avance par demi hauteurs
-
-    retour = []
-    d = 0.0     #decalage
-    pos = (x1, y1)
-    retour.append(pos)
-    
-    while pos != (x2, y2):
-        d += (k*pas)
-        if d <= 0.5:
-            #on se deplace vers la case en dessous (ou au dessus)
-            x, y = pos
-            pos = x, y + sens
-            retour.append(pos)
-            d += (k*pas)
-        else:
-            #on se deplace vers la case en dessous (ou au dessus) a droite
-            x, y = pos
-            if (x %2 == 0 and sens == 1) or (x % 2 == 1 and sens == -1):
-                pos = x + 1, y
-            else:
-                pos = x + 1, y + sens            
-            retour.append(pos)
-            d -= 1.5
-        
-        if sens*pos[1] > sens*y2:
-            retour = []
-            break
-
-    return retour 
-

+ 7 - 7
lib/commun.py

@@ -29,7 +29,7 @@ def rep(nature):
     if not os.path.isdir(retour): os.mkdir(retour)
 
     #2e niveau
-    if nature in ["partie", "mde", "grp", "cbt"]:
+    if nature in ["parties", "mde", "grp", "cbt"]:
         s = sessionEnCours()    
         partie = s.partie()
         retour = os.path.join(retour, "{}\\".format(partie))        
@@ -84,12 +84,12 @@ def charger(fichier):
     """charge l'objet depuis le fichier demande"""
     fichier = "{}".format(fichier) 
     #on recupere l'objet
-#     try:
-    with open(fichier, 'rb') as f:
-        objet = pickle.load(f)
-    f.close()
-#     except IOError:
-#         objet = None
+    try:
+        with open(fichier, 'rb') as f:
+            objet = pickle.load(f)
+        f.close()
+    except IOError:
+        objet = None
     return objet
 
 def sessionEnCours():

+ 1 - 1
lib/frameAttaque.py

@@ -8,7 +8,7 @@ from PyQt4.QtCore import QString, QSize
 from PyQt4.QtGui import QFrame, QHBoxLayout, QLayout
 
 from Actions import *
-from lib.br import ligne
+# from lib.br import ligne
 from lib.ui.dm import DmLabel, DmLineEdit
 import regles
 from ui.ecran_panneauAttaques import Ui_att_frame

+ 1 - 1
lib/framePj.py

@@ -82,7 +82,7 @@ class FramePj(QFrame):
         
     def enterEvent(self, event):
         self.setEnabled(True)
-
+ 
     def leaveEvent(self, event):
         self.setEnabled(False)
 

+ 496 - 0
lib/geometrie.py

@@ -0,0 +1,496 @@
+# -*- coding: utf-8 -*-
+'''
+Fonctions geometriques DMonde
+'''
+from __future__ import division
+
+from math import sqrt, atan2, pi, tan
+import time
+
+from PyQt4.QtCore import QPointF, QLineF
+from PyQt4.QtGui import QPolygonF
+
+
+class Geometrie(object):
+    def __init__(self, fC = "H", dimX = 0, dimY = 0):
+        self._fC = fC
+        self._dimX = dimX
+        self._dimY = dimY
+
+    def initialiser(self, plateau):
+        self._fC = plateau.formeCases
+        self._dimX = plateau.nbCasesX 
+        self._dimY = plateau.nbCasesY
+
+    def listeCases(self):
+        """retourne la liste des cases composant le plateau en fonction de ses dimensions"""
+        retour = []
+        for x in range(self._dimX):
+            for y in range(self._dimY):
+                retour.append( (x, y) )
+        return retour
+
+    def listeCasesF(self, xmin, ymin, xmax, ymax):
+        """liste de cases filtree (performances)"""
+        retour = []
+        if xmin < 0: xmin = 0
+        if ymin < 0: ymin = 0
+        if xmax > self._dimX: xmax = self._dimX
+        if ymax > self._dimY: ymax = self._dimY
+        
+        for x in range(xmin, xmax + 1):
+            for y in range(ymin, ymax + 1):
+                retour.append( (x, y) )
+        return retour        
+
+    def polygone(self, x, y):
+        """renvoie l'objet graphique hexagone de la case de coordonnees (x, y)"""
+        polygone = QPolygonF()
+        if self._fC == "H":
+            #si x est impair sur un plateau a cases hexagonales, le y est augmente de 0.5
+            if 1 == (x % 2): y += 0.5
+            polygone  << QPointF(((x*0.866)+0.2886)*120,  y*120) \
+                      << QPointF(((x*0.866)+0.866)*120,   y*120) \
+                      << QPointF(((x*0.866)+1.1547)*120, (y+0.5)*120) \
+                      << QPointF(((x*0.866)+0.866)*120,  (y+1)*120) \
+                      << QPointF(((x*0.866)+0.2886)*120, (y+1)*120)  \
+                      << QPointF( (x*0.866)*120,         (y+0.5)*120)
+        else:
+            polygone  << QPointF(x*120,      y*120) \
+                      << QPointF((x+1)*120,  y*120) \
+                      << QPointF((x+1)*120,  (y+1)*120) \
+                      << QPointF(x*120,      (y+1)*120)          
+        return polygone
+
+    def polygoneAgglo(self, listeCases):
+        """renvoie un polygone contruit par agglomeration des polygones des cases de la liste
+           les cases doivent etre adjacentes (cases hexagonales ou carrees)"""
+        segments = []
+        #on parcourt les faces des polygones des cases, et on ne garde que ceux qui n'ont pas de case 'en face'
+        for coord in listeCases:
+            polygone = self.polygone(coord[0], coord[1])
+            voisins = self.lstCoordAdjacentes(coord[0], coord[1])
+            
+            for i in range(0, len(voisins)):
+                if not voisins[i] in listeCases:
+                    j = i+1
+                    if j > len(voisins) - 1:
+                        j = 0
+                    segments.append(QLineF(polygone[i], polygone[j]))
+
+        #on 'accroche' les segments les uns aux autres, dans l'ordre
+        if not len(segments) > 0: return None
+        segments2 = [segments[0]]
+        for segment2 in segments2:
+            for segment in segments:
+                if not QLineF(segment.p1(), segment.p2()) in segments2 and not QLineF(segment.p2(), segment.p1()) in segments2:
+                    if sqrt((segment.p1().x()-segment2.p2().x())**2+(segment.p1().y()-segment2.p2().y())**2) < 1:
+                        segments2.append(QLineF(segment.p1(), segment.p2()))
+                    elif sqrt((segment.p2().x()-segment2.p2().x())**2+(segment.p2().y()-segment2.p2().y())**2) < 1:   
+                        segments2.append(QLineF(segment.p2(), segment.p1()))
+
+        pointsPolygone = []
+        premierPoint = segments2[0].p1()
+        pointsPolygone.append(premierPoint)
+        for segment in segments2:
+            pointSuivant = segment.p2()
+            if pointSuivant != premierPoint:
+                pointsPolygone.append(pointSuivant)
+
+        #creation du polygone
+        polygone = QPolygonF()
+        for point in pointsPolygone:   
+            polygone.append(point)   
+
+        return polygone  
+
+
+    def coordonneesValides(self, coord):
+        """les coordonnees entrees en parametre sont elles celles d'une case du plateau"""
+        return (coord[0] >= 0 and coord[1] >= 0 and coord[0] < self._dimX and coord[1] < self._dimY)
+
+    def filtrer(self, lst):
+        """prend en parametre une liste de coordonnees 
+        et retourne une liste de coordonnees valides"""
+        retour = []
+        for coord in lst:
+            x, y = coord[0], coord[1]
+            if self.coordonneesValides((x, y)): retour.append(coord)
+        return retour
+    
+    def coordCentreListeCases(self, listeCases):
+        """renvoie les coordonnees centrales d'une liste de cases"""
+        retour = None
+        if len(listeCases) > 0:
+            listeTriee = sorted(listeCases)
+            posMilieu = int(len(listeCases)/2)
+            retour = listeTriee[posMilieu]
+        return retour    
+
+    def lstCoordAdjacentes(self, x, y):
+        """renvoie la liste des coordonnees adjacentes, 
+           !!! -> sans condition d'existence sur le plateau
+           attention: l'ordre est important"""
+        if self._fC == "H":
+            if 1 == (x % 2):
+                return [(x, y-1), (x+1, y), (x+1, y+1), (x,  y+1), (x-1, y+1), (x-1, y)]
+            else:
+                return [(x, y-1), (x+1, y-1), (x+1, y), (x,  y+1), (x-1, y), (x-1, y-1)]
+        else:
+            return [(x, y-1), (x+1, y), (x,   y+1), (x-1, y)]
+
+    def yR(self, x, y):
+        """retourne le y reel lorsque les cases sont hexagonales"""
+        return y if self._fC != "H" or x % 2 != 1 else y + 0.5
+
+    def zone(self, centre, param):
+        """renvoie un dictionnaire representant la liste des coordonnees des cases comprises dans la zone
+           la zone en question est la liste des cases situees a une distance d des coordonnees d'origine"""
+#         if len(param) == 2:
+#             #on vise des coordonnees
+        cible = param if type(param) == tuple else (-1, -1)
+        rayon = param if type(param) == int else 99
+        if not self.coordonneesValides(centre) or not rayon >= 0: return {}
+        resultat = {}
+        aVerifier = [] ; aVerifier2 = [] ; k = 0        
+        #on part de la premiere case, puis on itere a partir de chaque nouveau depart sur les voisins
+        aVerifier.append(centre)
+        while k <= rayon:
+            for x, y in aVerifier:
+                for coord in self.filtrer(self.lstCoordAdjacentes(x, y)):
+                    if not coord in aVerifier and not coord in aVerifier2 and not coord in resultat:
+                        aVerifier2.append(coord)      
+            for elt in aVerifier:
+                resultat[elt] = k
+                if elt == cible: rayon = k
+            aVerifier = aVerifier2 ; aVerifier2 = [] ; k += 1
+        return resultat
+    
+    def zone3d(self, centre, rayon):
+        """ centre au format (x, y, z)
+            renvoie les cases de la zone au format (x, y, z)"""
+        retour = []
+        x0, y0, z0 = centre
+        zone = self.zone((x0, y0), rayon)
+        for coord in zone:
+            x, y = coord
+            dz = rayon - zone[coord]
+            for z in range(-dz, dz + 1):
+                retour.append( (x, y, (z0 + z) ) )
+        return retour            
+   
+    def blocAdjacent(self, listeCases):
+        """renvoie un bloc de cases adjacentes a partir de la liste en parametre"""
+        retour = []
+        tmp1 = [listeCases[0]]; tmp2 = [listeCases[0]]
+        while len(tmp2) > 0:
+            tmp2 = []
+            #on liste les cases voisines qui sont dans la liste et pas encore verifiees
+            for x, y in tmp1:
+                for voisine in self.lstCoordAdjacentes(x, y):
+                    if voisine in listeCases and not voisine in tmp1 and not voisine in tmp2:
+                        tmp2.append(voisine)
+            #chacune de ces cases prend le statut de verifiee
+            for coord in tmp1:
+                listeCases.remove(coord)
+                retour.append(coord)
+            tmp1 = tmp2
+        return retour 
+
+ 
+    def ligne(self, coord1, coord2):
+        """renvoie la ligne demandee en fonction des parametres"""
+        if coord1[0] == coord2[0] and coord1[1] == coord2[1]: return [coord1]
+        if len(coord1) == 2 and len(coord2) == 2:             return self._ligne2d(coord1, coord2)
+        elif len(coord1) == 3 and len(coord2) == 3:           return self._ligne3d(coord1, coord2)
+        elif len(coord1) == 3 and len(coord2) == 2:           return self._ligne3d((coord1[0], coord1[1], 0), coord2)
+        elif len(coord1) == 2 and len(coord2) == 3:           return self._ligne3d(coord1, (coord2[0], coord2[1], 0))
+        else: return [coord1]   
+              
+    def _ligne2d(self, coord1, coord2):
+        """renvoie la liste des cases traversees par la ligne entre les cases 1 et 2
+            prend en parametre des coord de la forme (x,y)"""
+        x1, y1 = coord1 ; x2, y2 = coord2
+        return self._brH(x1, y1, x2, y2) if self._fC == "H" else self._brC(x1, y1, x2, y2)
+    
+    def _ligne3d(self, coord1, coord2):
+        """renvoie la liste des cases traversees par la ligne entre les cases 1 et 2
+            prend en parametre des coord de la forme (x,y, z)"""
+        x1, y1, z1 = coord1 ; x2, y2, z2 = coord2
+        ligne = self._ligne2d((x1, y1), (x2, y2))
+        ligneZ = self._brC(0, z1, (len(ligne)-1), z2)
+        retour = []
+        for dist, z in ligneZ:
+            x, y = ligne[dist]
+            retour.append((x, y, z))
+        return retour
+  
+    def _brC(self, x1, y1, x2, y2):
+        """Algorithme ligne de Bresenham (pour cases carrees)"""
+        retour = []
+        #SYMETRIE DIAGONALE
+        V = ( abs(y2 - y1) > abs(x2 - x1) )
+        if V: y1, x1, y2, x2 = x1, y1, x2, y2
+        
+        #SYMETRIE VERTICALE
+        inversee = (x1 > x2)
+        if inversee:  x2, y2, x1, y1 = x1, y1, x2, y2
+
+        DX = x2 - x1 ; DY = y2 - y1
+        decalage = 0.0
+        saut = 1 if DY > 0 else -1
+        alpha = ( abs( DY ) / DX )
+        
+        y = y1
+        for x in range(x1, x2 + 1):
+            coord = (y, x) if V else (x, y)
+            retour.append(coord)
+            
+            decalage += alpha
+            if decalage > 0.5:
+                y += saut
+                decalage -= 1.0
+        
+        if inversee: retour.reverse()
+        return retour
+   
+    def _brH(self, x1, y1, x2, y2):
+        """Algorithme ligne de Bresenham (pour cases hexagonales)"""
+        inversee = (x1 > x2)
+        if inversee:
+            x1, x2 = x2, x1
+            y1, y2 = y2, y1
+        
+        #calcul selon secteur
+        if abs(x2 - x1) < (2*abs((y2-y1)) + abs(x2 % 2) - abs(x1 % 1)):
+            retour = self._brH_v(x1, y1, x2, y2)
+        else:
+            retour = self._brH_h(x1, y1, x2, y2)   
+
+        # retourne la liste si les coordonnees ont ete interverties
+        if inversee: retour.reverse()
+        return retour
+            
+    def _brH_h(self, x1, y1, x2, y2):
+        """Algorithme ligne de Bresenham (pour cases hexagonales - secteur horizontal)"""  
+        # Calcul des ecarts
+        dx = x2 - x1 ; dy = y2 - y1 
+        if (x1 + x2) % 2 == 1: 
+            dy += 0.5 if x1 % 2 == 0 else -0.5
+                    
+        # Calcul de l'erreur  (l'ecart qui doit s'accumuler au fur et a mesure qu'on avance)
+        k = dy / dx
+        pas = 1
+        
+        # on itere sur les coordonnees de la boite qui contient les coordonnees 1 et 2
+        retour = []
+        d = 0.0
+        pos = (x1, y1)
+        retour.append(pos)
+        
+        while pos != (x2, y2):
+            d += k*pas
+            if d > 0:
+                #on se deplace vers la case en dessous a droite 
+                x, y = pos
+                if x % 2 == 0:
+                    pos = x + 1, y 
+                else:
+                    pos = x + 1, y + 1 
+                retour.append(pos)
+                d -= 0.5
+            else:
+                #on se deplace vers la case au dessus a droite
+                x, y = pos
+                if x % 2 == 0:
+                    pos = x + 1, y - 1   
+                else:
+                    pos = x + 1, y         
+                retour.append(pos)
+                d += 0.5
+            
+            if pos[0] > x2:
+                retour = []
+                break
+                          
+        return retour
+        
+    def _brH_v(self, x1, y1, x2, y2):
+        """Algorithme ligne de Bresenham (pour cases hexagonales - secteur vertical)"""
+        #on prend comme unite la demi largeur: u = 0.5773
+        #la demi hauteur d'un hexa vaut donc 0.8860u, ou sqrt(3)/2
+        #[a revoir] une fois cela pose, on muliplie tout par 4dy afin d'eviter nombres flottants et divisions
+        sens = 1 if y2 > y1 else -1
+    
+        # Calcul des ecarts
+        dx = 1.5 * (x2 - x1)      #en x, on a 1.5u de centre a centre
+        dy = sens * (y2 - y1)     #en y, on compte en demi hauteurs
+        if (x1 + x2) % 2 == 1: 
+            if x1 % 2 == 0:
+                dy += sens*0.5
+            else:
+                dy -= sens*0.5
+    
+        k = dx/(dy*sqrt(3)) #k est la tangente de l'angle par rapport a la verticale
+        pas = 0.5*sqrt(3)   #on avance par demi hauteurs
+    
+        retour = []
+        d = 0.0     #decalage
+        pos = (x1, y1)
+        retour.append(pos)
+        
+        while pos != (x2, y2):
+            d += (k*pas)
+            if d <= 0.5:
+                #on se deplace vers la case en dessous (ou au dessus)
+                x, y = pos
+                pos = x, y + sens
+                retour.append(pos)
+                d += (k*pas)
+            else:
+                #on se deplace vers la case en dessous (ou au dessus) a droite
+                x, y = pos
+                if (x %2 == 0 and sens == 1) or (x % 2 == 1 and sens == -1):
+                    pos = x + 1, y
+                else:
+                    pos = x + 1, y + sens            
+                retour.append(pos)
+                d -= 1.5
+            
+            if sens*pos[1] > sens*y2:
+                retour = []
+                break
+    
+        return retour 
+
+    def disque(self, coord1, coord2):
+        """rendu pas terrible pour l'instant (a cause du decalage des cases?)"""
+        x1, y1 = coord1 ; x2, y2 = coord2 
+        retour = []
+#         k = 1.1547 if self._fC == "H" else 1
+        k = 1
+        rayon2 = (y2 - y1)**2 + (k* x2 - k* x1)**2
+        for x, y in self.listeCases():
+            if (k*x - k*x1)**2 + (self.yR(x, y) - self.yR(x1, y1))**2 <= (rayon2 + 0.25):
+                retour.append((x, y))
+        return retour
+
+    def cone_(self, coord1, coord2, iAngle = 2):
+        """version disque"""
+        """on trace un disque et on compare les angles"""
+        x1, y1 = coord1 ; x2, y2 = coord2
+        retour = []
+        
+        if self._fC == "H" and 1 == (x1 % 2): y1 += 0.5
+        if self._fC == "H" and 1 == (x2 % 2): y2 += 0.5
+        if iAngle < 0: iAngle = 0
+        if iAngle > 4: iAngle = 4
+        angle = pi/[16, 12, 8, 6, 4][iAngle] # c'est le demi angle!
+        
+        disque = self.disque(coord1, coord2)
+        alpha0 = atan2((x2 - x1), (y2 - y1))
+
+        for coord in disque:
+            x, y = coord
+            d = sqrt( (y - y1)**2 + (x - x1)**2 )
+            
+            if self._fC == "H" and 1 == (x % 2): y += 0.5
+            tolerance = 0.5 * atan2(1, d)   #la tolerance est l'angle d'une case a la distance en cours
+            if self.coordonneesValides( (x, y) ):
+                alpha = atan2( (x - x1) , (y - y1) )
+                if abs(alpha - alpha0) <= (angle + tolerance) or \
+                   ( 2*pi - abs(alpha - alpha0) ) <= (angle + tolerance):
+                    if self._fC == "H" and 1 == (x % 2): y -= 0.5
+                    retour.append( (x, y) )
+        return retour    
+
+    def cone__(self, coord1, coord2, iAngle = 2):
+        """version zone"""
+        """on trace un disque et on compare les angles"""
+        x1, y1 = coord1 ; x2, y2 = coord2
+        retour = {}
+        if self._fC == "H" and 1 == (x1 % 2): y1 += 0.5
+        if self._fC == "H" and 1 == (x2 % 2): y2 += 0.5
+        
+        if iAngle < 0: iAngle = 0
+        if iAngle > 4: iAngle = 4
+        angle = pi/[16, 12, 8, 6, 4][iAngle] # c'est le demi angle!
+        
+        disque = self.zone(coord1, coord2)
+        alpha0 = atan2((x2 - x1), (y2 - y1))
+
+        for coord, d in disque.items():
+            x, y = coord
+            if self._fC == "H" and 1 == (x % 2): y += 0.5
+            tolerance = 0.5 * atan2(1, d)   #la tolerance est l'angle d'une case a la distance en cours
+            if self.coordonneesValides( (x, y) ):
+                alpha = atan2( (x - x1) , (y - y1) )
+                if abs(alpha - alpha0) <= (angle + tolerance) or \
+                   ( 2*pi - abs(alpha - alpha0) ) <= (angle + tolerance):
+                    if self._fC == "H" and 1 == (x % 2): y -= 0.5
+                    retour[(x, y)] = d
+        return retour    
+
+    def cone(self, coord1, coord2, iAngle):
+        """renvoie un dictionnaire representant la liste des coordonnees des cases comprises dans le cone
+        et leur distance a l'origine"""
+        resultat = {}
+        aVerifier = [] ; aVerifier2 = [] ; k = 0 ; rayon = 99 ; x1, y1 = coord1 ; x2, y2 = coord2
+        if iAngle < 0: iAngle = 0
+        if iAngle > 4: iAngle = 4
+        angle = pi/[16, 12, 8][iAngle] # c'est le demi angle!
+        alpha0 = atan2( (x2 - x1), (y2 - y1) )
+        
+        #on part de la premiere case, puis on itere a partir de chaque nouveau depart sur les voisins
+        aVerifier.append(coord1)
+        while k <= rayon:
+            for x, y in aVerifier:
+                for coordV in self.filtrer(self.lstCoordAdjacentes(x, y)):
+                    if not coordV in aVerifier and not coordV in aVerifier2 and not coordV in resultat:
+                        xv, yv = coordV
+                        tolerance = 0.5 * atan2(1, k)   #la tolerance est l'angle d'une case a la distance en cours
+                        alpha = atan2( (xv - x1) , (yv - y1) )
+                        if abs(alpha - alpha0) <= (angle + tolerance) or \
+                            ( 2*pi - abs(alpha - alpha0) ) <= (angle + tolerance):
+                            aVerifier2.append(coordV)      
+            for elt in aVerifier:
+                resultat[elt] = k
+                if elt == coord2: rayon = k
+            aVerifier = aVerifier2 ; aVerifier2 = [] ; k += 1
+        return resultat
+
+    def cone3d(self, coord1, coord2, iAngle = 1):
+        x1, y1, z1 = coord1 ; x2, y2, z2 = coord2
+        #on recupere le cone horizonthal
+        coneH = self.cone( (x1, y1), (x2, y2), iAngle ) 
+        
+        #la ligne de mire
+        d = max([d for d in coneH.values()])
+        ligneZ = self._brC(0, z1, d, z2)
+ 
+        if iAngle < 0: iAngle = 0
+        if iAngle > 4: iAngle = 4
+        angle = pi/[16, 12, 8][iAngle] # c'est le demi angle!
+        retour = []
+        for coord, dist in coneH.items():
+            #calcul de l'ecart de hauteur
+            z0 = ligneZ[dist][1]
+            dz = int(round(dist * tan(angle)))
+            for z in range(-dz, dz + 1):
+                x, y = coord
+                retour.append( (x, y, (z0 + z)) )
+
+        return retour
+
+if __name__ == "__main__":
+    geo = Geometrie("C", 200, 200)
+    c =  geo.cone( (0,0), (5,5), 2)
+    print c
+    
+    
+    
+    
+    
+    
+
+    

+ 0 - 0
lib/EcranFondPlateau.py → lib/old/EcranFondPlateau.py


+ 0 - 0
lib/fonctionsCommunes.py → lib/old/fonctionsCommunes.py


+ 3 - 7
lib/regles.py

@@ -1,7 +1,5 @@
 from __future__ import unicode_literals
 # -*- coding: utf-8 -*-
-##from __future__ import division
-##import os
 
 def attributOrdreJeu():
     """renvoie l'attribut utilise pour definir l'ordre de jeu, None s'il n'existe pas"""
@@ -11,8 +9,6 @@ def sensTriOrdreJeu():
     """renvoie le type de tri pour l'ordre de jeu: 0 = croissant / 1 = decroissant"""
     return 1
 
-
-
 def ordreAttributs():
     """renvoie la liste des attributs avec leur position relative (pour l'affichage en combat)"""
     lst = ["init", "PV", "TotalPV", "CA", "BBA", "Ref", "Vig", "Vol", "F", "D", "C", "I", "S", "Ch", "B_init"]
@@ -169,9 +165,9 @@ def nomMonnaie():
 
 
 if __name__ == "__main__":
-     val = "3"
-     dico = listeControleAttaques()
-     print(dico["svg"].controler(val))
+    val = "3"
+    dico = listeControleAttaques()
+    print(dico["svg"].controler(val))
 
 
 

+ 2 - 2
lib/test.py

@@ -1,3 +1,3 @@
 
-lst = []
-print range(0,0)
+
+print "%03d" % 10

+ 286 - 0
lib/ui/chargerPartie.ui

@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>chpt_fenetre</class>
+ <widget class="QDialog" name="chpt_fenetre">
+  <property name="windowModality">
+   <enum>Qt::ApplicationModal</enum>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>509</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>509</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>509</width>
+    <height>300</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <family>Verdana</family>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Charger un plateau</string>
+  </property>
+  <widget class="DmTableWidget" name="chpt_liste">
+   <property name="geometry">
+    <rect>
+     <x>19</x>
+     <y>41</y>
+     <width>471</width>
+     <height>211</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>247</red>
+         <green>247</green>
+         <blue>247</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Highlight">
+       <brush brushstyle="SolidPattern">
+        <color alpha="100">
+         <red>208</red>
+         <green>69</green>
+         <blue>0</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="AlternateBase">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>229</red>
+         <green>229</green>
+         <blue>229</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>247</red>
+         <green>247</green>
+         <blue>247</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Highlight">
+       <brush brushstyle="SolidPattern">
+        <color alpha="100">
+         <red>208</red>
+         <green>69</green>
+         <blue>0</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="AlternateBase">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>229</red>
+         <green>229</green>
+         <blue>229</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>240</red>
+         <green>240</green>
+         <blue>240</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Highlight">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>51</red>
+         <green>153</green>
+         <blue>255</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="AlternateBase">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>229</red>
+         <green>229</green>
+         <blue>229</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>8</pointsize>
+    </font>
+   </property>
+   <property name="frameShape">
+    <enum>QFrame::StyledPanel</enum>
+   </property>
+   <property name="editTriggers">
+    <set>QAbstractItemView::NoEditTriggers</set>
+   </property>
+   <property name="showDropIndicator" stdset="0">
+    <bool>false</bool>
+   </property>
+   <property name="dragDropOverwriteMode">
+    <bool>false</bool>
+   </property>
+   <property name="selectionMode">
+    <enum>QAbstractItemView::SingleSelection</enum>
+   </property>
+   <property name="selectionBehavior">
+    <enum>QAbstractItemView::SelectRows</enum>
+   </property>
+   <property name="showGrid">
+    <bool>true</bool>
+   </property>
+   <property name="gridStyle">
+    <enum>Qt::DotLine</enum>
+   </property>
+   <property name="cornerButtonEnabled">
+    <bool>true</bool>
+   </property>
+   <attribute name="horizontalHeaderVisible">
+    <bool>true</bool>
+   </attribute>
+   <attribute name="horizontalHeaderDefaultSectionSize">
+    <number>80</number>
+   </attribute>
+   <attribute name="horizontalHeaderHighlightSections">
+    <bool>false</bool>
+   </attribute>
+   <attribute name="verticalHeaderVisible">
+    <bool>false</bool>
+   </attribute>
+   <attribute name="verticalHeaderDefaultSectionSize">
+    <number>24</number>
+   </attribute>
+   <attribute name="verticalHeaderHighlightSections">
+    <bool>false</bool>
+   </attribute>
+   <column>
+    <property name="text">
+     <string>idSvg</string>
+    </property>
+   </column>
+   <column>
+    <property name="text">
+     <string>Nom</string>
+    </property>
+   </column>
+   <column>
+    <property name="text">
+     <string>Date</string>
+    </property>
+   </column>
+   <column>
+    <property name="text">
+     <string>date_tri</string>
+    </property>
+   </column>
+  </widget>
+  <widget class="QPushButton" name="chpt_ok">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>389</x>
+     <y>258</y>
+     <width>100</width>
+     <height>30</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>10</pointsize>
+    </font>
+   </property>
+   <property name="text">
+    <string>Ok</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_11">
+   <property name="geometry">
+    <rect>
+     <x>19</x>
+     <y>11</y>
+     <width>311</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>11</pointsize>
+     <weight>75</weight>
+     <bold>true</bold>
+    </font>
+   </property>
+   <property name="text">
+    <string>Charger une partie</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="chpt_supprimer">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>19</x>
+     <y>258</y>
+     <width>31</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>10</pointsize>
+     <italic>true</italic>
+    </font>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+   <property name="icon">
+    <iconset resource="ressource.qrc">
+     <normaloff>:/interface/16/ressource/corbeille_16.png</normaloff>:/interface/16/ressource/corbeille_16.png</iconset>
+   </property>
+  </widget>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>DmTableWidget</class>
+   <extends>QTableWidget</extends>
+   <header>dm.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="ressource.qrc"/>
+ </resources>
+ <connections/>
+</ui>

+ 9 - 0
lib/ui/chargerPlateau.ui

@@ -247,6 +247,12 @@
    <property name="text">
     <string>Ok</string>
    </property>
+   <property name="autoDefault">
+    <bool>false</bool>
+   </property>
+   <property name="default">
+    <bool>true</bool>
+   </property>
   </widget>
   <widget class="QLabel" name="label_11">
    <property name="geometry">
@@ -293,6 +299,9 @@
     <iconset resource="ressource.qrc">
      <normaloff>:/interface/16/ressource/corbeille_16.png</normaloff>:/interface/16/ressource/corbeille_16.png</iconset>
    </property>
+   <property name="autoDefault">
+    <bool>false</bool>
+   </property>
   </widget>
   <widget class="QSpinBox" name="chp_chapitre">
    <property name="geometry">

+ 1 - 0
lib/ui/convertChargerPartie.cmd

@@ -0,0 +1 @@
+pyuic4 -x chargerPartie.ui -o ecran_chargerPartie.py

+ 1 - 0
lib/ui/convertEditionPartie.cmd

@@ -0,0 +1 @@
+pyuic4 -x dial_editerPartie.ui -o ecran_editionPartie.py

+ 1 - 0
lib/ui/convertPanneauChap.cmd

@@ -0,0 +1 @@
+pyuic4 -x panneauChapitre.ui -o ecran_panneauCh.py

+ 349 - 0
lib/ui/dial_editerPartie.ui

@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ept_fenetre</class>
+ <widget class="QDialog" name="ept_fenetre">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>555</width>
+    <height>480</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>555</width>
+    <height>430</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>555</width>
+    <height>480</height>
+   </size>
+  </property>
+  <property name="font">
+   <font>
+    <family>Verdana</family>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Paramètres de la partie</string>
+  </property>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>71</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Nom :</string>
+   </property>
+  </widget>
+  <widget class="DmLineEdit" name="ept_nom">
+   <property name="geometry">
+    <rect>
+     <x>60</x>
+     <y>10</y>
+     <width>471</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>240</red>
+         <green>240</green>
+         <blue>240</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+  </widget>
+  <widget class="QTabWidget" name="ept_onglets">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>90</y>
+     <width>531</width>
+     <height>331</height>
+    </rect>
+   </property>
+   <property name="currentIndex">
+    <number>0</number>
+   </property>
+   <widget class="QWidget" name="tab_2">
+    <attribute name="title">
+     <string>Chapitres</string>
+    </attribute>
+    <widget class="DmTableWidget" name="ept_ch_liste">
+     <property name="geometry">
+      <rect>
+       <x>10</x>
+       <y>10</y>
+       <width>151</width>
+       <height>281</height>
+      </rect>
+     </property>
+     <property name="palette">
+      <palette>
+       <active>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>249</red>
+           <green>249</green>
+           <blue>249</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Highlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="100">
+           <red>200</red>
+           <green>100</green>
+           <blue>100</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </active>
+       <inactive>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>249</red>
+           <green>249</green>
+           <blue>249</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Highlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="100">
+           <red>200</red>
+           <green>100</green>
+           <blue>100</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </inactive>
+       <disabled>
+        <colorrole role="Base">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>240</red>
+           <green>240</green>
+           <blue>240</blue>
+          </color>
+         </brush>
+        </colorrole>
+        <colorrole role="Highlight">
+         <brush brushstyle="SolidPattern">
+          <color alpha="255">
+           <red>51</red>
+           <green>153</green>
+           <blue>255</blue>
+          </color>
+         </brush>
+        </colorrole>
+       </disabled>
+      </palette>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::NoEditTriggers</set>
+     </property>
+     <property name="selectionMode">
+      <enum>QAbstractItemView::SingleSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectRows</enum>
+     </property>
+     <attribute name="horizontalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+     <attribute name="horizontalHeaderStretchLastSection">
+      <bool>true</bool>
+     </attribute>
+     <attribute name="verticalHeaderVisible">
+      <bool>false</bool>
+     </attribute>
+     <column>
+      <property name="text">
+       <string>idCh</string>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>nomCh</string>
+      </property>
+     </column>
+    </widget>
+    <widget class="QPushButton" name="ept_ch_nouveau">
+     <property name="geometry">
+      <rect>
+       <x>360</x>
+       <y>262</y>
+       <width>151</width>
+       <height>31</height>
+      </rect>
+     </property>
+     <property name="text">
+      <string>Nouveau chapitre</string>
+     </property>
+    </widget>
+    <widget class="QStackedWidget" name="ept_ch_panneaux">
+     <property name="geometry">
+      <rect>
+       <x>170</x>
+       <y>10</y>
+       <width>341</width>
+       <height>241</height>
+      </rect>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QWidget" name="tab_3">
+    <attribute name="title">
+     <string>Règles</string>
+    </attribute>
+   </widget>
+   <widget class="QWidget" name="tab_4">
+    <attribute name="title">
+     <string>Joueurs</string>
+    </attribute>
+   </widget>
+   <widget class="QWidget" name="tab_5">
+    <attribute name="title">
+     <string>Paramètres</string>
+    </attribute>
+   </widget>
+  </widget>
+  <widget class="QPushButton" name="ept_enregistrer">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>410</x>
+     <y>430</y>
+     <width>131</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Enregistrer</string>
+   </property>
+   <property name="autoDefault">
+    <bool>false</bool>
+   </property>
+   <property name="default">
+    <bool>true</bool>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="ept_annuler">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>430</y>
+     <width>121</width>
+     <height>31</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Annuler</string>
+   </property>
+   <property name="autoDefault">
+    <bool>false</bool>
+   </property>
+  </widget>
+  <widget class="DmComboBox" name="ept_ch_choix">
+   <property name="geometry">
+    <rect>
+     <x>160</x>
+     <y>47</y>
+     <width>371</width>
+     <height>27</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>50</y>
+     <width>121</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Chapitre en cours : </string>
+   </property>
+  </widget>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>DmTableWidget</class>
+   <extends>QTableWidget</extends>
+   <header>dm.h</header>
+  </customwidget>
+  <customwidget>
+   <class>DmLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header location="global">dm.h</header>
+  </customwidget>
+  <customwidget>
+   <class>DmComboBox</class>
+   <extends>QComboBox</extends>
+   <header>dm.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>ept_ch_liste</sender>
+   <signal>cellClicked(int,int)</signal>
+   <receiver>ept_ch_panneaux</receiver>
+   <slot>setCurrentIndex(int)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>99</x>
+     <y>222</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>354</x>
+     <y>202</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

+ 352 - 254
lib/ui/dial_zone.ui

@@ -1,254 +1,352 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>zne_fenetre</class>
- <widget class="QDialog" name="zne_fenetre">
-  <property name="windowModality">
-   <enum>Qt::ApplicationModal</enum>
-  </property>
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>308</width>
-    <height>150</height>
-   </rect>
-  </property>
-  <property name="font">
-   <font>
-    <family>Verdana</family>
-   </font>
-  </property>
-  <property name="windowTitle">
-   <string>Attaque de zone</string>
-  </property>
-  <widget class="QSpinBox" name="zne_rayon">
-   <property name="geometry">
-    <rect>
-     <x>250</x>
-     <y>60</y>
-     <width>51</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="palette">
-    <palette>
-     <active>
-      <colorrole role="Base">
-       <brush brushstyle="SolidPattern">
-        <color alpha="255">
-         <red>240</red>
-         <green>240</green>
-         <blue>240</blue>
-        </color>
-       </brush>
-      </colorrole>
-     </active>
-     <inactive>
-      <colorrole role="Base">
-       <brush brushstyle="SolidPattern">
-        <color alpha="255">
-         <red>240</red>
-         <green>240</green>
-         <blue>240</blue>
-        </color>
-       </brush>
-      </colorrole>
-     </inactive>
-     <disabled>
-      <colorrole role="Base">
-       <brush brushstyle="SolidPattern">
-        <color alpha="255">
-         <red>240</red>
-         <green>240</green>
-         <blue>240</blue>
-        </color>
-       </brush>
-      </colorrole>
-     </disabled>
-    </palette>
-   </property>
-   <property name="font">
-    <font>
-     <pointsize>9</pointsize>
-     <weight>75</weight>
-     <bold>true</bold>
-    </font>
-   </property>
-   <property name="minimum">
-    <number>1</number>
-   </property>
-  </widget>
-  <widget class="QComboBox" name="zne_forme">
-   <property name="geometry">
-    <rect>
-     <x>180</x>
-     <y>10</y>
-     <width>121</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <item>
-    <property name="text">
-     <string>  Ligne</string>
-    </property>
-    <property name="icon">
-     <iconset resource="../../../../old/DMonde20150908/lib/ui/ressource.qrc">
-      <normaloff>:/interface/16/ressource/ligne_16.png</normaloff>:/interface/16/ressource/ligne_16.png</iconset>
-    </property>
-   </item>
-   <item>
-    <property name="text">
-     <string>  Disque</string>
-    </property>
-    <property name="icon">
-     <iconset resource="../../../../old/DMonde20150908/lib/ui/ressource.qrc">
-      <normaloff>:/interface/16/ressource/ellipsePleine_16.png</normaloff>:/interface/16/ressource/ellipsePleine_16.png</iconset>
-    </property>
-   </item>
-   <item>
-    <property name="text">
-     <string>  Cône</string>
-    </property>
-    <property name="icon">
-     <iconset resource="../../../../old/DMonde20150908/lib/ui/ressource.qrc">
-      <normaloff>:/interface/16/ressource/cone_16.png</normaloff>:/interface/16/ressource/cone_16.png</iconset>
-    </property>
-   </item>
-  </widget>
-  <widget class="QLabel" name="label">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>10</y>
-     <width>131</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Forme de la zone :</string>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="zne_valider">
-   <property name="geometry">
-    <rect>
-     <x>160</x>
-     <y>110</y>
-     <width>141</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Valider</string>
-   </property>
-   <property name="autoDefault">
-    <bool>false</bool>
-   </property>
-   <property name="default">
-    <bool>true</bool>
-   </property>
-  </widget>
-  <widget class="QPushButton" name="zne_annuler">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>110</y>
-     <width>91</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Annuler</string>
-   </property>
-   <property name="autoDefault">
-    <bool>false</bool>
-   </property>
-  </widget>
-  <widget class="QLabel" name="zne_rayon_lbl">
-   <property name="geometry">
-    <rect>
-     <x>180</x>
-     <y>60</y>
-     <width>61</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Rayon  : </string>
-   </property>
-  </widget>
-  <widget class="QSpinBox" name="zne_portee">
-   <property name="geometry">
-    <rect>
-     <x>100</x>
-     <y>60</y>
-     <width>51</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="palette">
-    <palette>
-     <active>
-      <colorrole role="Base">
-       <brush brushstyle="SolidPattern">
-        <color alpha="255">
-         <red>240</red>
-         <green>240</green>
-         <blue>240</blue>
-        </color>
-       </brush>
-      </colorrole>
-     </active>
-     <inactive>
-      <colorrole role="Base">
-       <brush brushstyle="SolidPattern">
-        <color alpha="255">
-         <red>240</red>
-         <green>240</green>
-         <blue>240</blue>
-        </color>
-       </brush>
-      </colorrole>
-     </inactive>
-     <disabled>
-      <colorrole role="Base">
-       <brush brushstyle="SolidPattern">
-        <color alpha="255">
-         <red>240</red>
-         <green>240</green>
-         <blue>240</blue>
-        </color>
-       </brush>
-      </colorrole>
-     </disabled>
-    </palette>
-   </property>
-   <property name="font">
-    <font>
-     <pointsize>9</pointsize>
-     <weight>75</weight>
-     <bold>true</bold>
-    </font>
-   </property>
-   <property name="minimum">
-    <number>1</number>
-   </property>
-  </widget>
-  <widget class="QLabel" name="label_3">
-   <property name="geometry">
-    <rect>
-     <x>10</x>
-     <y>60</y>
-     <width>81</width>
-     <height>31</height>
-    </rect>
-   </property>
-   <property name="text">
-    <string>Portée max : </string>
-   </property>
-  </widget>
- </widget>
- <resources>
-  <include location="../../../../old/DMonde20150908/lib/ui/ressource.qrc"/>
- </resources>
- <connections/>
-</ui>
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>zone_fenetre</class>
+ <widget class="QDialog" name="zone_fenetre">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>252</width>
+    <height>92</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>252</width>
+    <height>92</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>252</width>
+    <height>92</height>
+   </size>
+  </property>
+  <property name="palette">
+   <palette>
+    <active>
+     <colorrole role="Base">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>240</red>
+        <green>240</green>
+        <blue>240</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </active>
+    <inactive>
+     <colorrole role="Base">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>240</red>
+        <green>240</green>
+        <blue>240</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </inactive>
+    <disabled>
+     <colorrole role="Base">
+      <brush brushstyle="SolidPattern">
+       <color alpha="255">
+        <red>240</red>
+        <green>240</green>
+        <blue>240</blue>
+       </color>
+      </brush>
+     </colorrole>
+    </disabled>
+   </palette>
+  </property>
+  <property name="font">
+   <font>
+    <family>Verdana</family>
+   </font>
+  </property>
+  <property name="windowTitle">
+   <string>Forme de l'attaque de zone</string>
+  </property>
+  <widget class="DmLabel" name="zone_ligne">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>71</width>
+     <height>71</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+   <property name="autoFillBackground">
+    <bool>true</bool>
+   </property>
+   <property name="frameShape">
+    <enum>QFrame::StyledPanel</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+   <property name="pixmap">
+    <pixmap resource="ressource.qrc">:/interface/16/ressource/ligne_16.png</pixmap>
+   </property>
+   <property name="scaledContents">
+    <bool>false</bool>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignCenter</set>
+   </property>
+  </widget>
+  <widget class="DmLabel" name="zone_disque">
+   <property name="geometry">
+    <rect>
+     <x>90</x>
+     <y>10</y>
+     <width>71</width>
+     <height>71</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+   <property name="autoFillBackground">
+    <bool>true</bool>
+   </property>
+   <property name="frameShape">
+    <enum>QFrame::StyledPanel</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+   <property name="pixmap">
+    <pixmap resource="ressource.qrc">:/interface/16/ressource/ellipsePleine_16.png</pixmap>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignCenter</set>
+   </property>
+  </widget>
+  <widget class="DmLabel" name="zone_cone">
+   <property name="geometry">
+    <rect>
+     <x>170</x>
+     <y>10</y>
+     <width>71</width>
+     <height>71</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+      <colorrole role="Window">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+   <property name="autoFillBackground">
+    <bool>true</bool>
+   </property>
+   <property name="frameShape">
+    <enum>QFrame::StyledPanel</enum>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+   <property name="pixmap">
+    <pixmap resource="ressource.qrc">:/interface/16/ressource/cone_16.png</pixmap>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignCenter</set>
+   </property>
+  </widget>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>DmLabel</class>
+   <extends>QLabel</extends>
+   <header location="global">dm.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="ressource.qrc"/>
+ </resources>
+ <connections/>
+</ui>

+ 0 - 10
lib/ui/dm.py

@@ -481,16 +481,6 @@ class DmTableMenu(QTableWidget):
         if ligne == 0:
             self.setItemSelected(item, True)
 
-    
-
-class DmFrame(QFrame):
-    """surcharge de QFrame"""
-    def __init__(self, parent = None):
-        super(DmFrame, self).__init__(parent)
-
-        
-
-
 
     
 

+ 149 - 129
lib/ui/ecran_attaqueZone.py

@@ -1,129 +1,149 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'dial_zone.ui'
-#
-# Created: Fri Sep 18 15:49:21 2015
-#      by: PyQt4 UI code generator 4.10.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
-    _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
-    def _fromUtf8(s):
-        return s
-
-try:
-    _encoding = QtGui.QApplication.UnicodeUTF8
-    def _translate(context, text, disambig):
-        return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
-    def _translate(context, text, disambig):
-        return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_zne_fenetre(object):
-    def setupUi(self, zne_fenetre):
-        zne_fenetre.setObjectName(_fromUtf8("zne_fenetre"))
-        zne_fenetre.setWindowModality(QtCore.Qt.ApplicationModal)
-        zne_fenetre.resize(308, 150)
-        font = QtGui.QFont()
-        font.setFamily(_fromUtf8("Verdana"))
-        zne_fenetre.setFont(font)
-        self.zne_rayon = QtGui.QSpinBox(zne_fenetre)
-        self.zne_rayon.setGeometry(QtCore.QRect(250, 60, 51, 31))
-        palette = QtGui.QPalette()
-        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
-        brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
-        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
-        brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
-        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
-        brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
-        self.zne_rayon.setPalette(palette)
-        font = QtGui.QFont()
-        font.setPointSize(9)
-        font.setBold(True)
-        font.setWeight(75)
-        self.zne_rayon.setFont(font)
-        self.zne_rayon.setMinimum(1)
-        self.zne_rayon.setObjectName(_fromUtf8("zne_rayon"))
-        self.zne_forme = QtGui.QComboBox(zne_fenetre)
-        self.zne_forme.setGeometry(QtCore.QRect(180, 10, 121, 31))
-        self.zne_forme.setObjectName(_fromUtf8("zne_forme"))
-        icon = QtGui.QIcon()
-        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/ligne_16.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.zne_forme.addItem(icon, _fromUtf8(""))
-        icon1 = QtGui.QIcon()
-        icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/ellipsePleine_16.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.zne_forme.addItem(icon1, _fromUtf8(""))
-        icon2 = QtGui.QIcon()
-        icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/cone_16.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
-        self.zne_forme.addItem(icon2, _fromUtf8(""))
-        self.label = QtGui.QLabel(zne_fenetre)
-        self.label.setGeometry(QtCore.QRect(10, 10, 131, 31))
-        self.label.setObjectName(_fromUtf8("label"))
-        self.zne_valider = QtGui.QPushButton(zne_fenetre)
-        self.zne_valider.setGeometry(QtCore.QRect(160, 110, 141, 31))
-        self.zne_valider.setAutoDefault(False)
-        self.zne_valider.setDefault(True)
-        self.zne_valider.setObjectName(_fromUtf8("zne_valider"))
-        self.zne_annuler = QtGui.QPushButton(zne_fenetre)
-        self.zne_annuler.setGeometry(QtCore.QRect(10, 110, 91, 31))
-        self.zne_annuler.setAutoDefault(False)
-        self.zne_annuler.setObjectName(_fromUtf8("zne_annuler"))
-        self.zne_rayon_lbl = QtGui.QLabel(zne_fenetre)
-        self.zne_rayon_lbl.setGeometry(QtCore.QRect(180, 60, 61, 31))
-        self.zne_rayon_lbl.setObjectName(_fromUtf8("zne_rayon_lbl"))
-        self.zne_portee = QtGui.QSpinBox(zne_fenetre)
-        self.zne_portee.setGeometry(QtCore.QRect(100, 60, 51, 31))
-        palette = QtGui.QPalette()
-        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
-        brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
-        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
-        brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
-        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
-        brush.setStyle(QtCore.Qt.SolidPattern)
-        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
-        self.zne_portee.setPalette(palette)
-        font = QtGui.QFont()
-        font.setPointSize(9)
-        font.setBold(True)
-        font.setWeight(75)
-        self.zne_portee.setFont(font)
-        self.zne_portee.setMinimum(1)
-        self.zne_portee.setObjectName(_fromUtf8("zne_portee"))
-        self.label_3 = QtGui.QLabel(zne_fenetre)
-        self.label_3.setGeometry(QtCore.QRect(10, 60, 81, 31))
-        self.label_3.setObjectName(_fromUtf8("label_3"))
-
-        self.retranslateUi(zne_fenetre)
-        QtCore.QMetaObject.connectSlotsByName(zne_fenetre)
-
-    def retranslateUi(self, zne_fenetre):
-        zne_fenetre.setWindowTitle(_translate("zne_fenetre", "Attaque de zone", None))
-        self.zne_forme.setItemText(0, _translate("zne_fenetre", "  Ligne", None))
-        self.zne_forme.setItemText(1, _translate("zne_fenetre", "  Disque", None))
-        self.zne_forme.setItemText(2, _translate("zne_fenetre", "  Cône", None))
-        self.label.setText(_translate("zne_fenetre", "Forme de la zone :", None))
-        self.zne_valider.setText(_translate("zne_fenetre", "Valider", None))
-        self.zne_annuler.setText(_translate("zne_fenetre", "Annuler", None))
-        self.zne_rayon_lbl.setText(_translate("zne_fenetre", "Rayon  : ", None))
-        self.label_3.setText(_translate("zne_fenetre", "Portée max : ", None))
-
-import ressource_rc
-
-if __name__ == "__main__":
-    import sys
-    app = QtGui.QApplication(sys.argv)
-    zne_fenetre = QtGui.QDialog()
-    ui = Ui_zne_fenetre()
-    ui.setupUi(zne_fenetre)
-    zne_fenetre.show()
-    sys.exit(app.exec_())
-
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'dial_zone.ui'
+#
+# Created: Thu Sep 24 10:53:17 2015
+#      by: PyQt4 UI code generator 4.10.4
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+    _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+    def _fromUtf8(s):
+        return s
+
+try:
+    _encoding = QtGui.QApplication.UnicodeUTF8
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig)
+
+class Ui_zone_fenetre(object):
+    def setupUi(self, zone_fenetre):
+        zone_fenetre.setObjectName(_fromUtf8("zone_fenetre"))
+        zone_fenetre.resize(252, 92)
+        zone_fenetre.setMinimumSize(QtCore.QSize(252, 92))
+        zone_fenetre.setMaximumSize(QtCore.QSize(252, 92))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        zone_fenetre.setPalette(palette)
+        font = QtGui.QFont()
+        font.setFamily(_fromUtf8("Verdana"))
+        zone_fenetre.setFont(font)
+        self.zone_ligne = DmLabel(zone_fenetre)
+        self.zone_ligne.setGeometry(QtCore.QRect(10, 10, 71, 71))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
+        self.zone_ligne.setPalette(palette)
+        self.zone_ligne.setAutoFillBackground(True)
+        self.zone_ligne.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.zone_ligne.setText(_fromUtf8(""))
+        self.zone_ligne.setPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/ligne_16.png")))
+        self.zone_ligne.setScaledContents(False)
+        self.zone_ligne.setAlignment(QtCore.Qt.AlignCenter)
+        self.zone_ligne.setObjectName(_fromUtf8("zone_ligne"))
+        self.zone_disque = DmLabel(zone_fenetre)
+        self.zone_disque.setGeometry(QtCore.QRect(90, 10, 71, 71))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
+        self.zone_disque.setPalette(palette)
+        self.zone_disque.setAutoFillBackground(True)
+        self.zone_disque.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.zone_disque.setText(_fromUtf8(""))
+        self.zone_disque.setPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/ellipsePleine_16.png")))
+        self.zone_disque.setAlignment(QtCore.Qt.AlignCenter)
+        self.zone_disque.setObjectName(_fromUtf8("zone_disque"))
+        self.zone_cone = DmLabel(zone_fenetre)
+        self.zone_cone.setGeometry(QtCore.QRect(170, 10, 71, 71))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
+        self.zone_cone.setPalette(palette)
+        self.zone_cone.setAutoFillBackground(True)
+        self.zone_cone.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.zone_cone.setText(_fromUtf8(""))
+        self.zone_cone.setPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/cone_16.png")))
+        self.zone_cone.setAlignment(QtCore.Qt.AlignCenter)
+        self.zone_cone.setObjectName(_fromUtf8("zone_cone"))
+
+        self.retranslateUi(zone_fenetre)
+        QtCore.QMetaObject.connectSlotsByName(zone_fenetre)
+
+    def retranslateUi(self, zone_fenetre):
+        zone_fenetre.setWindowTitle(_translate("zone_fenetre", "Forme de l\'attaque de zone", None))
+
+from dm import DmLabel
+import ressource_rc
+
+if __name__ == "__main__":
+    import sys
+    app = QtGui.QApplication(sys.argv)
+    zone_fenetre = QtGui.QDialog()
+    ui = Ui_zone_fenetre()
+    ui.setupUi(zone_fenetre)
+    zone_fenetre.show()
+    sys.exit(app.exec_())
+

+ 151 - 0
lib/ui/ecran_chargerPartie.py

@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'chargerPartie.ui'
+#
+# Created: Thu Oct 08 16:36:53 2015
+#      by: PyQt4 UI code generator 4.10.4
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+    _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+    def _fromUtf8(s):
+        return s
+
+try:
+    _encoding = QtGui.QApplication.UnicodeUTF8
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig)
+
+class Ui_chpt_fenetre(object):
+    def setupUi(self, chpt_fenetre):
+        chpt_fenetre.setObjectName(_fromUtf8("chpt_fenetre"))
+        chpt_fenetre.setWindowModality(QtCore.Qt.ApplicationModal)
+        chpt_fenetre.resize(509, 300)
+        chpt_fenetre.setMinimumSize(QtCore.QSize(509, 300))
+        chpt_fenetre.setMaximumSize(QtCore.QSize(509, 300))
+        font = QtGui.QFont()
+        font.setFamily(_fromUtf8("Verdana"))
+        chpt_fenetre.setFont(font)
+        self.chpt_liste = DmTableWidget(chpt_fenetre)
+        self.chpt_liste.setGeometry(QtCore.QRect(19, 41, 471, 211))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(247, 247, 247))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(208, 69, 0, 100))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Highlight, brush)
+        brush = QtGui.QBrush(QtGui.QColor(229, 229, 229))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.AlternateBase, brush)
+        brush = QtGui.QBrush(QtGui.QColor(247, 247, 247))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(208, 69, 0, 100))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, brush)
+        brush = QtGui.QBrush(QtGui.QColor(229, 229, 229))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.AlternateBase, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(51, 153, 255))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Highlight, brush)
+        brush = QtGui.QBrush(QtGui.QColor(229, 229, 229))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.AlternateBase, brush)
+        self.chpt_liste.setPalette(palette)
+        font = QtGui.QFont()
+        font.setPointSize(8)
+        self.chpt_liste.setFont(font)
+        self.chpt_liste.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.chpt_liste.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
+        self.chpt_liste.setProperty("showDropIndicator", False)
+        self.chpt_liste.setDragDropOverwriteMode(False)
+        self.chpt_liste.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
+        self.chpt_liste.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
+        self.chpt_liste.setShowGrid(True)
+        self.chpt_liste.setGridStyle(QtCore.Qt.DotLine)
+        self.chpt_liste.setCornerButtonEnabled(True)
+        self.chpt_liste.setObjectName(_fromUtf8("chpt_liste"))
+        self.chpt_liste.setColumnCount(4)
+        self.chpt_liste.setRowCount(0)
+        item = QtGui.QTableWidgetItem()
+        self.chpt_liste.setHorizontalHeaderItem(0, item)
+        item = QtGui.QTableWidgetItem()
+        self.chpt_liste.setHorizontalHeaderItem(1, item)
+        item = QtGui.QTableWidgetItem()
+        self.chpt_liste.setHorizontalHeaderItem(2, item)
+        item = QtGui.QTableWidgetItem()
+        self.chpt_liste.setHorizontalHeaderItem(3, item)
+        self.chpt_liste.horizontalHeader().setVisible(True)
+        self.chpt_liste.horizontalHeader().setDefaultSectionSize(80)
+        self.chpt_liste.horizontalHeader().setHighlightSections(False)
+        self.chpt_liste.verticalHeader().setVisible(False)
+        self.chpt_liste.verticalHeader().setDefaultSectionSize(24)
+        self.chpt_liste.verticalHeader().setHighlightSections(False)
+        self.chpt_ok = QtGui.QPushButton(chpt_fenetre)
+        self.chpt_ok.setEnabled(False)
+        self.chpt_ok.setGeometry(QtCore.QRect(389, 258, 100, 30))
+        font = QtGui.QFont()
+        font.setPointSize(10)
+        self.chpt_ok.setFont(font)
+        self.chpt_ok.setObjectName(_fromUtf8("chpt_ok"))
+        self.label_11 = QtGui.QLabel(chpt_fenetre)
+        self.label_11.setGeometry(QtCore.QRect(19, 11, 311, 21))
+        font = QtGui.QFont()
+        font.setPointSize(11)
+        font.setBold(True)
+        font.setWeight(75)
+        self.label_11.setFont(font)
+        self.label_11.setObjectName(_fromUtf8("label_11"))
+        self.chpt_supprimer = QtGui.QPushButton(chpt_fenetre)
+        self.chpt_supprimer.setEnabled(False)
+        self.chpt_supprimer.setGeometry(QtCore.QRect(19, 258, 31, 31))
+        font = QtGui.QFont()
+        font.setPointSize(10)
+        font.setItalic(True)
+        self.chpt_supprimer.setFont(font)
+        self.chpt_supprimer.setText(_fromUtf8(""))
+        icon = QtGui.QIcon()
+        icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/corbeille_16.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.chpt_supprimer.setIcon(icon)
+        self.chpt_supprimer.setObjectName(_fromUtf8("chpt_supprimer"))
+
+        self.retranslateUi(chpt_fenetre)
+        QtCore.QMetaObject.connectSlotsByName(chpt_fenetre)
+
+    def retranslateUi(self, chpt_fenetre):
+        chpt_fenetre.setWindowTitle(_translate("chpt_fenetre", "Charger un plateau", None))
+        item = self.chpt_liste.horizontalHeaderItem(0)
+        item.setText(_translate("chpt_fenetre", "idSvg", None))
+        item = self.chpt_liste.horizontalHeaderItem(1)
+        item.setText(_translate("chpt_fenetre", "Nom", None))
+        item = self.chpt_liste.horizontalHeaderItem(2)
+        item.setText(_translate("chpt_fenetre", "Date", None))
+        item = self.chpt_liste.horizontalHeaderItem(3)
+        item.setText(_translate("chpt_fenetre", "date_tri", None))
+        self.chpt_ok.setText(_translate("chpt_fenetre", "Ok", None))
+        self.label_11.setText(_translate("chpt_fenetre", "Charger une partie", None))
+
+from dm import DmTableWidget
+import ressource_rc
+
+if __name__ == "__main__":
+    import sys
+    app = QtGui.QApplication(sys.argv)
+    chpt_fenetre = QtGui.QDialog()
+    ui = Ui_chpt_fenetre()
+    ui.setupUi(chpt_fenetre)
+    chpt_fenetre.show()
+    sys.exit(app.exec_())
+

+ 5 - 1
lib/ui/ecran_chargerPlateau.py

@@ -2,7 +2,7 @@
 
 # Form implementation generated from reading ui file 'chargerPlateau.ui'
 #
-# Created: Fri Jun 26 17:01:04 2015
+# Created: Thu Oct 08 16:39:20 2015
 #      by: PyQt4 UI code generator 4.10.4
 #
 # WARNING! All changes made in this file will be lost!
@@ -26,6 +26,7 @@ except AttributeError:
 class Ui_chp_fenetre(object):
     def setupUi(self, chp_fenetre):
         chp_fenetre.setObjectName(_fromUtf8("chp_fenetre"))
+        chp_fenetre.setWindowModality(QtCore.Qt.ApplicationModal)
         chp_fenetre.resize(509, 300)
         chp_fenetre.setMinimumSize(QtCore.QSize(509, 300))
         chp_fenetre.setMaximumSize(QtCore.QSize(509, 300))
@@ -106,6 +107,8 @@ class Ui_chp_fenetre(object):
         font = QtGui.QFont()
         font.setPointSize(10)
         self.chp_ok.setFont(font)
+        self.chp_ok.setAutoDefault(False)
+        self.chp_ok.setDefault(True)
         self.chp_ok.setObjectName(_fromUtf8("chp_ok"))
         self.label_11 = QtGui.QLabel(chp_fenetre)
         self.label_11.setGeometry(QtCore.QRect(19, 11, 311, 21))
@@ -126,6 +129,7 @@ class Ui_chp_fenetre(object):
         icon = QtGui.QIcon()
         icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/interface/16/ressource/corbeille_16.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
         self.chp_supprimer.setIcon(icon)
+        self.chp_supprimer.setAutoDefault(False)
         self.chp_supprimer.setObjectName(_fromUtf8("chp_supprimer"))
         self.chp_chapitre = QtGui.QSpinBox(chp_fenetre)
         self.chp_chapitre.setGeometry(QtCore.QRect(309, 5, 61, 31))

+ 156 - 0
lib/ui/ecran_editionPartie.py

@@ -0,0 +1,156 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'dial_editerPartie.ui'
+#
+# Created: Thu Oct 08 15:40:27 2015
+#      by: PyQt4 UI code generator 4.10.4
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+    _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+    def _fromUtf8(s):
+        return s
+
+try:
+    _encoding = QtGui.QApplication.UnicodeUTF8
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig)
+
+class Ui_ept_fenetre(object):
+    def setupUi(self, ept_fenetre):
+        ept_fenetre.setObjectName(_fromUtf8("ept_fenetre"))
+        ept_fenetre.resize(555, 480)
+        ept_fenetre.setMinimumSize(QtCore.QSize(555, 430))
+        ept_fenetre.setMaximumSize(QtCore.QSize(555, 480))
+        font = QtGui.QFont()
+        font.setFamily(_fromUtf8("Verdana"))
+        ept_fenetre.setFont(font)
+        self.label = QtGui.QLabel(ept_fenetre)
+        self.label.setGeometry(QtCore.QRect(10, 10, 71, 31))
+        self.label.setObjectName(_fromUtf8("label"))
+        self.ept_nom = DmLineEdit(ept_fenetre)
+        self.ept_nom.setGeometry(QtCore.QRect(60, 10, 471, 31))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        self.ept_nom.setPalette(palette)
+        self.ept_nom.setObjectName(_fromUtf8("ept_nom"))
+        self.ept_onglets = QtGui.QTabWidget(ept_fenetre)
+        self.ept_onglets.setGeometry(QtCore.QRect(10, 90, 531, 331))
+        self.ept_onglets.setObjectName(_fromUtf8("ept_onglets"))
+        self.tab_2 = QtGui.QWidget()
+        self.tab_2.setObjectName(_fromUtf8("tab_2"))
+        self.ept_ch_liste = DmTableWidget(self.tab_2)
+        self.ept_ch_liste.setGeometry(QtCore.QRect(10, 10, 151, 281))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(200, 100, 100, 100))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Highlight, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(200, 100, 100, 100))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(51, 153, 255))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Highlight, brush)
+        self.ept_ch_liste.setPalette(palette)
+        self.ept_ch_liste.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
+        self.ept_ch_liste.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
+        self.ept_ch_liste.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
+        self.ept_ch_liste.setObjectName(_fromUtf8("ept_ch_liste"))
+        self.ept_ch_liste.setColumnCount(2)
+        self.ept_ch_liste.setRowCount(0)
+        item = QtGui.QTableWidgetItem()
+        self.ept_ch_liste.setHorizontalHeaderItem(0, item)
+        item = QtGui.QTableWidgetItem()
+        self.ept_ch_liste.setHorizontalHeaderItem(1, item)
+        self.ept_ch_liste.horizontalHeader().setVisible(False)
+        self.ept_ch_liste.horizontalHeader().setStretchLastSection(True)
+        self.ept_ch_liste.verticalHeader().setVisible(False)
+        self.ept_ch_nouveau = QtGui.QPushButton(self.tab_2)
+        self.ept_ch_nouveau.setGeometry(QtCore.QRect(360, 262, 151, 31))
+        self.ept_ch_nouveau.setObjectName(_fromUtf8("ept_ch_nouveau"))
+        self.ept_ch_panneaux = QtGui.QStackedWidget(self.tab_2)
+        self.ept_ch_panneaux.setGeometry(QtCore.QRect(170, 10, 341, 241))
+        self.ept_ch_panneaux.setObjectName(_fromUtf8("ept_ch_panneaux"))
+        self.ept_onglets.addTab(self.tab_2, _fromUtf8(""))
+        self.tab_3 = QtGui.QWidget()
+        self.tab_3.setObjectName(_fromUtf8("tab_3"))
+        self.ept_onglets.addTab(self.tab_3, _fromUtf8(""))
+        self.tab_4 = QtGui.QWidget()
+        self.tab_4.setObjectName(_fromUtf8("tab_4"))
+        self.ept_onglets.addTab(self.tab_4, _fromUtf8(""))
+        self.tab_5 = QtGui.QWidget()
+        self.tab_5.setObjectName(_fromUtf8("tab_5"))
+        self.ept_onglets.addTab(self.tab_5, _fromUtf8(""))
+        self.ept_enregistrer = QtGui.QPushButton(ept_fenetre)
+        self.ept_enregistrer.setEnabled(False)
+        self.ept_enregistrer.setGeometry(QtCore.QRect(410, 430, 131, 31))
+        self.ept_enregistrer.setAutoDefault(False)
+        self.ept_enregistrer.setDefault(True)
+        self.ept_enregistrer.setObjectName(_fromUtf8("ept_enregistrer"))
+        self.ept_annuler = QtGui.QPushButton(ept_fenetre)
+        self.ept_annuler.setGeometry(QtCore.QRect(10, 430, 121, 31))
+        self.ept_annuler.setAutoDefault(False)
+        self.ept_annuler.setObjectName(_fromUtf8("ept_annuler"))
+        self.ept_ch_choix = DmComboBox(ept_fenetre)
+        self.ept_ch_choix.setGeometry(QtCore.QRect(160, 47, 371, 27))
+        self.ept_ch_choix.setObjectName(_fromUtf8("ept_ch_choix"))
+        self.label_2 = QtGui.QLabel(ept_fenetre)
+        self.label_2.setGeometry(QtCore.QRect(30, 50, 121, 21))
+        self.label_2.setObjectName(_fromUtf8("label_2"))
+
+        self.retranslateUi(ept_fenetre)
+        self.ept_onglets.setCurrentIndex(0)
+        QtCore.QObject.connect(self.ept_ch_liste, QtCore.SIGNAL(_fromUtf8("cellClicked(int,int)")), self.ept_ch_panneaux.setCurrentIndex)
+        QtCore.QMetaObject.connectSlotsByName(ept_fenetre)
+
+    def retranslateUi(self, ept_fenetre):
+        ept_fenetre.setWindowTitle(_translate("ept_fenetre", "Paramètres de la partie", None))
+        self.label.setText(_translate("ept_fenetre", "Nom :", None))
+        item = self.ept_ch_liste.horizontalHeaderItem(0)
+        item.setText(_translate("ept_fenetre", "idCh", None))
+        item = self.ept_ch_liste.horizontalHeaderItem(1)
+        item.setText(_translate("ept_fenetre", "nomCh", None))
+        self.ept_ch_nouveau.setText(_translate("ept_fenetre", "Nouveau chapitre", None))
+        self.ept_onglets.setTabText(self.ept_onglets.indexOf(self.tab_2), _translate("ept_fenetre", "Chapitres", None))
+        self.ept_onglets.setTabText(self.ept_onglets.indexOf(self.tab_3), _translate("ept_fenetre", "Règles", None))
+        self.ept_onglets.setTabText(self.ept_onglets.indexOf(self.tab_4), _translate("ept_fenetre", "Joueurs", None))
+        self.ept_onglets.setTabText(self.ept_onglets.indexOf(self.tab_5), _translate("ept_fenetre", "Paramètres", None))
+        self.ept_enregistrer.setText(_translate("ept_fenetre", "Enregistrer", None))
+        self.ept_annuler.setText(_translate("ept_fenetre", "Annuler", None))
+        self.label_2.setText(_translate("ept_fenetre", "Chapitre en cours : ", None))
+
+from dm import DmTableWidget, DmLineEdit, DmComboBox
+
+if __name__ == "__main__":
+    import sys
+    app = QtGui.QApplication(sys.argv)
+    ept_fenetre = QtGui.QDialog()
+    ui = Ui_ept_fenetre()
+    ui.setupUi(ept_fenetre)
+    ept_fenetre.show()
+    sys.exit(app.exec_())
+

+ 92 - 0
lib/ui/ecran_panneauCh.py

@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'panneauChapitre.ui'
+#
+# Created: Thu Oct 08 12:14:08 2015
+#      by: PyQt4 UI code generator 4.10.4
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+try:
+    _fromUtf8 = QtCore.QString.fromUtf8
+except AttributeError:
+    def _fromUtf8(s):
+        return s
+
+try:
+    _encoding = QtGui.QApplication.UnicodeUTF8
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig, _encoding)
+except AttributeError:
+    def _translate(context, text, disambig):
+        return QtGui.QApplication.translate(context, text, disambig)
+
+class Ui_ch_panneau(object):
+    def setupUi(self, ch_panneau):
+        ch_panneau.setObjectName(_fromUtf8("ch_panneau"))
+        ch_panneau.resize(386, 199)
+        ch_panneau.setFrameShape(QtGui.QFrame.StyledPanel)
+        ch_panneau.setFrameShadow(QtGui.QFrame.Raised)
+        self.ch_presentation = DmTextEdit(ch_panneau)
+        self.ch_presentation.setGeometry(QtCore.QRect(30, 90, 321, 71))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        self.ch_presentation.setPalette(palette)
+        self.ch_presentation.setObjectName(_fromUtf8("ch_presentation"))
+        self.ch_num = DmLabel(ch_panneau)
+        self.ch_num.setGeometry(QtCore.QRect(20, 10, 141, 21))
+        font = QtGui.QFont()
+        font.setPointSize(9)
+        self.ch_num.setFont(font)
+        self.ch_num.setObjectName(_fromUtf8("ch_num"))
+        self.label_4 = QtGui.QLabel(ch_panneau)
+        self.label_4.setGeometry(QtCore.QRect(30, 70, 91, 21))
+        self.label_4.setObjectName(_fromUtf8("label_4"))
+        self.ch_nom = DmLineEdit(ch_panneau)
+        self.ch_nom.setGeometry(QtCore.QRect(70, 40, 281, 21))
+        palette = QtGui.QPalette()
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(249, 249, 249))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
+        brush = QtGui.QBrush(QtGui.QColor(240, 240, 240))
+        brush.setStyle(QtCore.Qt.SolidPattern)
+        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
+        self.ch_nom.setPalette(palette)
+        self.ch_nom.setObjectName(_fromUtf8("ch_nom"))
+        self.label_2 = QtGui.QLabel(ch_panneau)
+        self.label_2.setGeometry(QtCore.QRect(30, 40, 41, 21))
+        self.label_2.setObjectName(_fromUtf8("label_2"))
+
+        self.retranslateUi(ch_panneau)
+        QtCore.QMetaObject.connectSlotsByName(ch_panneau)
+
+    def retranslateUi(self, ch_panneau):
+        ch_panneau.setWindowTitle(_translate("ch_panneau", "Frame", None))
+        self.ch_num.setText(_translate("ch_panneau", "Chapitre 1", None))
+        self.label_4.setText(_translate("ch_panneau", "Présentation :", None))
+        self.label_2.setText(_translate("ch_panneau", "Titre :", None))
+
+from dm import DmTextEdit, DmLineEdit, DmLabel
+
+if __name__ == "__main__":
+    import sys
+    app = QtGui.QApplication(sys.argv)
+    ch_panneau = QtGui.QFrame()
+    ui = Ui_ch_panneau()
+    ui.setupUi(ch_panneau)
+    ch_panneau.show()
+    sys.exit(app.exec_())
+

Разница между файлами не показана из-за своего большого размера
+ 524 - 170
lib/ui/ecran_principal.py


+ 180 - 0
lib/ui/panneauChapitre.ui

@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ch_panneau</class>
+ <widget class="QFrame" name="ch_panneau">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>386</width>
+    <height>199</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Frame</string>
+  </property>
+  <property name="frameShape">
+   <enum>QFrame::StyledPanel</enum>
+  </property>
+  <property name="frameShadow">
+   <enum>QFrame::Raised</enum>
+  </property>
+  <widget class="DmTextEdit" name="ch_presentation">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>90</y>
+     <width>321</width>
+     <height>71</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>240</red>
+         <green>240</green>
+         <blue>240</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+  </widget>
+  <widget class="DmLabel" name="ch_num">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>10</y>
+     <width>141</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="font">
+    <font>
+     <pointsize>9</pointsize>
+    </font>
+   </property>
+   <property name="text">
+    <string>Chapitre 1</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_4">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>70</y>
+     <width>91</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Présentation :</string>
+   </property>
+  </widget>
+  <widget class="DmLineEdit" name="ch_nom">
+   <property name="geometry">
+    <rect>
+     <x>70</x>
+     <y>40</y>
+     <width>281</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>249</red>
+         <green>249</green>
+         <blue>249</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="Base">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>240</red>
+         <green>240</green>
+         <blue>240</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label_2">
+   <property name="geometry">
+    <rect>
+     <x>30</x>
+     <y>40</y>
+     <width>41</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Titre :</string>
+   </property>
+  </widget>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>DmLabel</class>
+   <extends>QLabel</extends>
+   <header location="global">dm.h</header>
+  </customwidget>
+  <customwidget>
+   <class>DmTextEdit</class>
+   <extends>QTextEdit</extends>
+   <header location="global">dm.h</header>
+  </customwidget>
+  <customwidget>
+   <class>DmLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header location="global">dm.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>

Разница между файлами не показана из-за своего большого размера
+ 996 - 109
lib/ui/principal.ui


+ 4 - 2
parties/defaut/cbt/infos_sauvegarde

@@ -1,2 +1,4 @@
-€}qU
-plpjxm4I9S}q(UnomqUtestqUdateCreationqGAÕ€¨AûC–UdateSvgqGAÕ€°µ�UchapitreqU1UenCoursq‰Upublicq	‰us.
+€}q(U
+plpjylZoNcq}q(UnomqUqefqUdateCreationqGAÕ€øêG�²UdateSvgqGAÕ€øì«çmUchapitreqU1UenCoursq	‰Upublicq
+‰uU
+plpjyh8Zg5}q(UnomUtestUdateCreationGAÕ€ëNië…UdateSvgGAÕ€ëe˜A‰UchapitreU1UenCours‰Upublic‰uu.

BIN
parties/defaut/cbt/plpjxm4I9S.dm


Некоторые файлы не были показаны из-за большого количества измененных файлов