dmtableattaques.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #from __future__ import unicode_literals
  2. # -*- coding: utf-8 -*-
  3. from PyQt4.QtCore import *
  4. from PyQt4.QtGui import *
  5. from lib.Actions import *
  6. import lib.regles as regles
  7. from lib.ui.dm import *
  8. #dans une DmTableAttaques, les 10 premieres colonnes sont reservees aux donnees de base
  9. #le reste des colonnes sert aux donnees complementaires issues des regles
  10. colonnesBase= ["Type", "Nom", "Portee", "Forme", "Rayon"]
  11. largeurColonnesBase = {"Type": 70, "Nom": 100, "Portee": 60, "Forme": 80,"Rayon": 60}
  12. class DmTableAttaques(DmTableWidget):
  13. """interface d'edition des attaques du combattant"""
  14. def __init__(self, parent=None):
  15. super (DmTableAttaques, self).__init__(parent)
  16. def construire(self):
  17. """cree les colonnes de la table"""
  18. #colonnes de base: celles qui ne dependent pas des regles utilisees
  19. for i in range(0, 10):
  20. self.insertColumn(i)
  21. #on cache les colonnes qui ne seront pas utilisees
  22. self.setColumnHidden(i, (i >= len(colonnesBase)))
  23. if i < len(colonnesBase):
  24. #la largeur est geree par une variable globale
  25. self.setHorizontalHeaderItem(i, QTableWidgetItem(colonnesBase[i]))
  26. if colonnesBase[i] in largeurColonnesBase:
  27. largeur = largeurColonnesBase[colonnesBase[i]]
  28. else:
  29. largeur = 60
  30. if largeur > 0:
  31. self.setColumnWidth(i, largeur)
  32. else:
  33. self.setColumnHidden(i, True)
  34. #on ajoute maintenant les colonnes issues des regles
  35. ordre = regles.ordreAttributsAttaques()
  36. for elt in ordre:
  37. numCol = 10 + ordre.index(elt)
  38. self.insertColumn(numCol)
  39. self.setHorizontalHeaderItem(numCol, QTableWidgetItem(QString.fromUtf8(elt)))
  40. self.setColumnWidth(numCol, 45)
  41. self.setColumnHidden(numCol, False)
  42. self.connect(self, SIGNAL("cellChanged(int, int)"), self.celluleModifiee)
  43. def posColonne(self, nom):
  44. """renvoie la position de la colonne demandee"""
  45. retour = None
  46. if nom in colonnesBase:
  47. retour = colonnesBase.index(nom)
  48. elif nom in regles.ordreAttributsAttaques():
  49. retour = 10 + regles.ordreAttributsAttaques().index(nom)
  50. return retour
  51. def listeAttaques(self):
  52. """retourne la liste des attaques de la liste"""
  53. liste = []
  54. for ligne in self.lignes():
  55. attaque = None
  56. typeAttaque = str(self.cellWidget(ligne, self.posColonne("Type")).valeurActuelle().toString())
  57. if typeAttaque == "cac":
  58. attaque = Cac()
  59. elif typeAttaque == "dist":
  60. attaque = Distance()
  61. elif typeAttaque == "zone":
  62. formeAttaque = str(self.cellWidget(ligne, self.posColonne("Forme")).valeurActuelle().toString())
  63. if formeAttaque == "ligne":
  64. attaque = Ligne()
  65. elif formeAttaque == "disque":
  66. attaque = Disque()
  67. elif formeAttaque == "cone":
  68. attaque = Cone()
  69. if attaque:
  70. attaque.majNom(self.texte(ligne, self.posColonne("Nom")))
  71. attaque.majPortee(self.data(ligne, self.posColonne("Portee")))
  72. if typeAttaque == "zone" and formeAttaque == "disque":
  73. attaque.majRayon(self.data(ligne, self.posColonne("Rayon")))
  74. for col in range(10, self.columnCount()):
  75. attr = regles.ordreAttributsAttaques()[(col-10)]
  76. val = str(self.data(ligne, col-10))
  77. if regles.attributAttaque(attr).controler(val):
  78. attaque.majAttribut(attr, val)
  79. liste.append(attaque)
  80. return liste
  81. def charger(self, listeAttaques):
  82. """charge et affiche une liste d'attaques"""
  83. self.vider()
  84. self.majEnCours = True
  85. ligne = 0
  86. for attaque in listeAttaques:
  87. #controle du type d'attaque
  88. if isinstance(attaque, Attaque):
  89. if attaque.__class__.__name__ in ["ligne", "disque", "cone"]:
  90. typeAtt = "zone"
  91. formeAtt = attaque.typeAtt()
  92. else:
  93. typeAtt = attaque.typeAtt()
  94. formeAtt = ""
  95. self.nouvelleLigneFin()
  96. #donnees generales
  97. donneesAttaque = {"Nom": attaque.nom(), "Portee": attaque.portee(), "Rayon": attaque.rayon()}
  98. self.majLigne(ligne, donneesAttaque)
  99. #met a jour le type d'attaque
  100. widget = self.listeTypesAttaques(ligne)
  101. widget.allerA(typeAtt)
  102. self.setCellWidget(ligne, self.posColonne("Type"), widget)
  103. self.afficherDonneesAttaqueZone(ligne, (typeAtt == "zone"))
  104. #maj des attributs de regles
  105. self.majLigne(ligne, attaque.attributs())
  106. ligne += 1
  107. self.majEnCours = False
  108. def nouvelle(self):
  109. """ajoute une ligne a la table et maj avec les valeurs par defaut"""
  110. ligne = self.nouvelleLigneFin()
  111. modeleAttaque = Attaque()
  112. #donnees generales
  113. donneesAttaque = {"Nom": modeleAttaque.nom(), "Portee": modeleAttaque.portee(), "Rayon": modeleAttaque.rayon()}
  114. self.majLigne(ligne, donneesAttaque)
  115. #liste types attaque
  116. widget = self.listeTypesAttaques(ligne)
  117. widget.allerA("cac")
  118. self.setCellWidget(ligne, self.posColonne("Type"), widget)
  119. #des regles
  120. attributs = regles.listeAttributsAttaques()
  121. self.majLigne(ligne, attributs)
  122. self.afficherDonneesAttaqueZone(ligne, False)
  123. def supprimer(self):
  124. """supprime l'attaque selectionnee de la liste des attaques du pion"""
  125. select = self.ligneSelectionnee()
  126. if select:
  127. numAttaque = int(self.data(sel,0))
  128. reponse = QMessageBox.question(self, 'Message',
  129. "Etes vous sûr de vouloir supprimer cette attaque?", QMessageBox.Yes |
  130. QMessageBox.No, QMessageBox.No)
  131. if reponse == QMessageBox.Yes:
  132. self.removeRow(select)
  133. def celluleModifiee(self, ligne, colonne):
  134. """une cellule de la table a ete modifiee par l'utilisateur,
  135. on controle sa validite via la classe Attaque et
  136. on retourne la valeur acceptee, ou l'ancienne valeur sinon"""
  137. if not self.majEnCours:
  138. modeleAttaque = Attaque()
  139. if colonne < len(colonnesBase):
  140. if colonne == self.posColonne("Nom"):
  141. #maj du nom de l'attaque
  142. nouveauNom = self.texte(ligne, colonne)
  143. modeleAttaque.majNom(nouveauNom)
  144. if modeleAttaque.nom() != nouveauNom:
  145. self.majTexte(ligne, colonne, modeleAttaque.nom())
  146. elif colonne == self.posColonne("Type"):
  147. #maj du type de l'attaque (ici, on ne controle pas, mais on met a jour tout l'affichage si besoin)
  148. nouveauType = str(self.cellWidget(ligne, colonne).valeurActuelle().toString())
  149. self.afficherDonneesAttaqueZone(ligne, (nouveauType == "zone"))
  150. elif colonne == self.posColonne("Portee"):
  151. #maj de la portee de l'attaque
  152. nouvellePortee = self.data(ligne, colonne) #! QVariant
  153. modeleAttaque.majPortee(nouvellePortee)
  154. if modeleAttaque.portee() != nouvellePortee:
  155. self.majEnt(ligne, colonne, modeleAttaque.portee())
  156. elif colonne == self.posColonne("Rayon"):
  157. #maj du rayon de l'attaque
  158. nouveauRayon = self.data(ligne, colonne) #! QVariant
  159. modeleAttaque.majRayon(nouveauRayon)
  160. if modeleAttaque.rayon() != nouveauRayon:
  161. self.majEnt(ligne, colonne, modeleAttaque.rayon())
  162. elif colonne >= 10:
  163. #colonnes issues des regles
  164. index = colonne - 10
  165. attribut = regles.ordreAttributsAttaques()[index]
  166. valeurAttribut = regles.listeControleAttaques()[attribut].controler(str(self.data(ligne, colonne).toString()))
  167. if valeurAttribut == None:
  168. self.majData(ligne, colonne, regles.listeControleAttaques()[attribut].defaut)
  169. def afficherDonneesAttaqueZone(self, ligne, afficher):
  170. """rend modifiables ou non les donnees de base liees aux attaques de zone et modifie l'affichage en consequence"""
  171. self.majEnCours = True
  172. if afficher:
  173. modeleAttaque = Attaque()
  174. if self.cellWidget(ligne, self.posColonne("Forme")) == None:
  175. self.setCellWidget(ligne, self.posColonne("Forme"), self.listeFormesZone(ligne))
  176. item = QTableWidgetItem()
  177. item.setData(0, modeleAttaque.rayon())
  178. item.setBackgroundColor(QColor("white"))
  179. self.setItem(ligne, self.posColonne("Rayon"), item)
  180. else:
  181. if self.cellWidget(ligne, self.posColonne("Forme")) != None:
  182. self.removeCellWidget(ligne, self.posColonne("Forme"))
  183. item = QTableWidgetItem(QString.fromUtf8(""))
  184. item.setFlags(Qt.NoItemFlags)
  185. item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
  186. item.setBackgroundColor(QColor(200,200,200))
  187. self.setItem(ligne, self.posColonne("Forme"), item)
  188. item = QTableWidgetItem(QString.fromUtf8(""))
  189. item.setFlags(Qt.NoItemFlags)
  190. item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
  191. item.setBackgroundColor(QColor(200,200,200))
  192. self.setItem(ligne, self.posColonne("Rayon"), item)
  193. self.majEnCours = False
  194. def typeAttaqueModifie(self):
  195. emetteur = self.sender().objectName()
  196. ligne = int(emetteur.replace("cbType_",""))
  197. colonne = self.posColonne("Type")
  198. self.celluleModifiee(ligne, colonne)
  199. def formeAttaqueModifiee(self):
  200. emetteur = self.sender().objectName()
  201. ligne = int(emetteur.replace("cbForme_",""))
  202. colonne = self.posColonne("Type")
  203. self.celluleModifiee(ligne, colonne)
  204. def listeTypesAttaques(self, ligne):
  205. """retourne la DmComboBox qui apparait dans la colonne Type d'attaque"""
  206. liste = DmComboBox()
  207. liste.setObjectName(QString("cbType_{}".format(ligne))) #sert a reconnaitre l'emetteur du signal apres une modif
  208. liste.addItem(QIcon("img\\curseurEpee.png"), QString.fromUtf8("C.à.C"), "cac")
  209. liste.addItem(QIcon("img\\arc.png"), QString.fromUtf8("Dist."), "dist")
  210. liste.addItem(QIcon("img\\baguette.png"), QString.fromUtf8("Zone"), "zone")
  211. self.connect(liste, SIGNAL("currentIndexChanged(int)"), self.typeAttaqueModifie)
  212. return liste
  213. def listeFormesZone(self, ligne):
  214. """retourne la DmComboBox qui apparait dans la colonne forme de zone"""
  215. liste = DmComboBox()
  216. liste.setObjectName(QString("cbForme_{}".format(ligne)))
  217. liste.addItem(QIcon("img\\formeLigne.png"), QString.fromUtf8("Ligne"), "ligne")
  218. liste.addItem(QIcon("img\\formeEllipsePlein.png"), QString.fromUtf8("Disque"), "disque")
  219. liste.addItem(QIcon("img\\cone.png"), QString.fromUtf8("Cone"), "cone")
  220. self.connect(liste, SIGNAL("currentIndexChanged(int)"), self.formeAttaqueModifiee)
  221. return liste