2016-03-04 04:38:38 +13:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# --!-- coding: utf8 --!--
|
|
|
|
|
from PyQt5.QtCore import QModelIndex, Qt, QAbstractItemModel, QVariant
|
|
|
|
|
from PyQt5.QtGui import QIcon, QPixmap, QColor
|
|
|
|
|
|
|
|
|
|
from manuskript.functions import randomColor, iconColor, mainWindow
|
|
|
|
|
from manuskript.enums import Character as C
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class characterModel(QAbstractItemModel):
|
|
|
|
|
|
|
|
|
|
def __init__(self, parent):
|
|
|
|
|
QAbstractItemModel.__init__(self, parent)
|
|
|
|
|
|
2016-03-10 02:10:22 +13:00
|
|
|
|
# CharacterItems are stored in this list
|
2016-03-04 04:38:38 +13:00
|
|
|
|
self.characters = []
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
# QAbstractItemModel subclassed
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
def rowCount(self, parent=QModelIndex()):
|
|
|
|
|
if parent.isValid():
|
|
|
|
|
c = parent.internalPointer()
|
|
|
|
|
return len(c.infos)
|
|
|
|
|
else:
|
|
|
|
|
return len(self.characters)
|
|
|
|
|
|
|
|
|
|
def columnCount(self, parent=QModelIndex()):
|
|
|
|
|
if parent.isValid():
|
|
|
|
|
# Returns characters infos
|
|
|
|
|
return 2
|
|
|
|
|
else:
|
2016-03-06 21:21:10 +13:00
|
|
|
|
return len(C)
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
|
|
|
|
def data(self, index, role=Qt.DisplayRole):
|
|
|
|
|
c = index.internalPointer()
|
|
|
|
|
if type(c) == Character:
|
|
|
|
|
if role == Qt.DisplayRole:
|
|
|
|
|
if index.column() in c._data:
|
|
|
|
|
return c._data[index.column()]
|
|
|
|
|
else:
|
2016-03-04 05:18:30 +13:00
|
|
|
|
return ""
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
2016-03-24 23:37:18 +13:00
|
|
|
|
elif role == Qt.DecorationRole:
|
|
|
|
|
if index.column() == C.name.value:
|
|
|
|
|
return c.icon
|
|
|
|
|
else:
|
|
|
|
|
return QVariant()
|
|
|
|
|
|
2016-03-04 04:38:38 +13:00
|
|
|
|
elif type(c) == CharacterInfo:
|
|
|
|
|
if role == Qt.DisplayRole or role == Qt.EditRole:
|
|
|
|
|
if index.column() == 0:
|
|
|
|
|
return c.description
|
|
|
|
|
elif index.column() == 1:
|
|
|
|
|
return c.value
|
|
|
|
|
|
|
|
|
|
def setData(self, index, value, role=Qt.EditRole):
|
|
|
|
|
c = index.internalPointer()
|
|
|
|
|
if type(c) == Character:
|
|
|
|
|
if role == Qt.EditRole:
|
|
|
|
|
# We update only if data is different
|
|
|
|
|
if index.column() not in c._data or c._data[index.column()] != value:
|
|
|
|
|
c._data[index.column()] = value
|
|
|
|
|
self.dataChanged.emit(index, index)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
elif type(c) == CharacterInfo:
|
|
|
|
|
if role == Qt.EditRole:
|
|
|
|
|
if index.column() == 0:
|
|
|
|
|
c.description = value
|
|
|
|
|
elif index.column() == 1:
|
|
|
|
|
c.value = value
|
|
|
|
|
self.dataChanged.emit(index, index)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def index(self, row, column, parent=QModelIndex()):
|
|
|
|
|
if not parent.isValid():
|
|
|
|
|
return self.createIndex(row, column, self.characters[row])
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
c = parent.internalPointer()
|
|
|
|
|
if row < len(c.infos):
|
|
|
|
|
return self.createIndex(row, column, c.infos[row])
|
|
|
|
|
else:
|
|
|
|
|
return QModelIndex()
|
|
|
|
|
|
|
|
|
|
def indexFromItem(self, item, column=0):
|
|
|
|
|
if not item:
|
|
|
|
|
return QModelIndex()
|
|
|
|
|
|
|
|
|
|
row = self.characters.index(item)
|
|
|
|
|
col = column
|
|
|
|
|
return self.createIndex(row, col, item)
|
|
|
|
|
|
|
|
|
|
def parent(self, index):
|
|
|
|
|
if not index.isValid():
|
|
|
|
|
return QModelIndex()
|
|
|
|
|
|
|
|
|
|
child = index.internalPointer()
|
|
|
|
|
|
|
|
|
|
if type(child) == Character:
|
|
|
|
|
return QModelIndex()
|
|
|
|
|
|
|
|
|
|
elif type(child) == CharacterInfo:
|
|
|
|
|
return child.character.index()
|
|
|
|
|
|
|
|
|
|
def flags(self, index):
|
|
|
|
|
if index.parent().isValid():
|
|
|
|
|
return QAbstractItemModel.flags(self, index) | Qt.ItemIsEditable
|
|
|
|
|
else:
|
|
|
|
|
return QAbstractItemModel.flags(self, index)
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
# CHARACTER QUERRIES
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
def character(self, row):
|
|
|
|
|
return self.characters[row]
|
|
|
|
|
|
|
|
|
|
def name(self, row):
|
|
|
|
|
return self.character(row).name()
|
|
|
|
|
|
|
|
|
|
def icon(self, row):
|
|
|
|
|
return self.character(row).icon
|
|
|
|
|
|
|
|
|
|
def ID(self, row):
|
|
|
|
|
return self.character(row).ID()
|
|
|
|
|
|
|
|
|
|
def importance(self, row):
|
|
|
|
|
return self.character(row).importance()
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
# MODEL QUERRIES
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
def getCharactersByImportance(self):
|
|
|
|
|
"""
|
|
|
|
|
Lists characters by importance.
|
|
|
|
|
|
|
|
|
|
@return: array of array of ´character´, by importance.
|
|
|
|
|
"""
|
|
|
|
|
r = [[], [], []]
|
|
|
|
|
for c in self.characters:
|
|
|
|
|
r[2-int(c.importance())].append(c)
|
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
def getCharacterByID(self, ID):
|
2016-03-04 05:41:19 +13:00
|
|
|
|
if ID is not None:
|
|
|
|
|
ID = str(ID)
|
|
|
|
|
for c in self.characters:
|
|
|
|
|
if c.ID() == ID:
|
|
|
|
|
return c
|
2016-03-04 04:38:38 +13:00
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
# ADDING / REMOVING
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
def addCharacter(self):
|
|
|
|
|
"""
|
|
|
|
|
Creates a new character
|
2016-03-10 23:45:40 +13:00
|
|
|
|
@return: the character
|
2016-03-04 04:38:38 +13:00
|
|
|
|
"""
|
|
|
|
|
c = Character(model=self, name=self.tr("New character"))
|
|
|
|
|
self.beginInsertRows(QModelIndex(), len(self.characters), len(self.characters))
|
|
|
|
|
self.characters.append(c)
|
|
|
|
|
self.endInsertRows()
|
2016-03-10 23:45:40 +13:00
|
|
|
|
return c
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
|
|
|
|
def removeCharacter(self, ID):
|
|
|
|
|
"""
|
|
|
|
|
Removes character whose ID is ID...
|
|
|
|
|
@param ID: the ID of the character to remove
|
|
|
|
|
@return: nothing
|
|
|
|
|
"""
|
|
|
|
|
c = self.getCharacterByID(ID)
|
|
|
|
|
self.beginRemoveRows(QModelIndex(), self.characters.index(c), self.characters.index(c))
|
|
|
|
|
self.characters.remove(c)
|
2016-03-10 02:10:22 +13:00
|
|
|
|
self.endRemoveRows()
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
# CHARACTER INFOS
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
|
|
|
|
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
|
|
|
|
|
if section == 0:
|
|
|
|
|
return self.tr("Name")
|
|
|
|
|
elif section == 1:
|
|
|
|
|
return self.tr("Value")
|
|
|
|
|
else:
|
|
|
|
|
return C(section).name
|
|
|
|
|
|
|
|
|
|
def addCharacterInfo(self, ID):
|
|
|
|
|
c = self.getCharacterByID(ID)
|
|
|
|
|
self.beginInsertRows(c.index(), len(c.infos), len(c.infos))
|
|
|
|
|
c.infos.append(CharacterInfo(c, description="Description", value="Value"))
|
|
|
|
|
self.endInsertRows()
|
|
|
|
|
|
|
|
|
|
mainWindow().updatePersoInfoView()
|
|
|
|
|
|
|
|
|
|
def removeCharacterInfo(self, ID):
|
|
|
|
|
c = self.getCharacterByID(ID)
|
|
|
|
|
|
|
|
|
|
rm = []
|
|
|
|
|
for idx in mainWindow().tblPersoInfos.selectedIndexes():
|
|
|
|
|
if not idx.row() in rm:
|
|
|
|
|
rm.append(idx.row())
|
|
|
|
|
|
|
|
|
|
rm.sort()
|
|
|
|
|
rm.reverse()
|
|
|
|
|
for r in rm:
|
|
|
|
|
self.beginRemoveRows(c.index(), r, r)
|
|
|
|
|
c.infos.pop(r)
|
|
|
|
|
self.endRemoveRows()
|
|
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
|
# CHARACTER
|
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
|
|
class Character():
|
2016-03-06 00:55:56 +13:00
|
|
|
|
def __init__(self, model, name="No name"):
|
2016-03-04 04:38:38 +13:00
|
|
|
|
self._model = model
|
2016-03-06 05:46:02 +13:00
|
|
|
|
self.lastPath = ""
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
|
|
|
|
self._data = {}
|
|
|
|
|
self._data[C.name.value] = name
|
|
|
|
|
self.assignUniqueID()
|
|
|
|
|
self.assignRandomColor()
|
|
|
|
|
self._data[C.importance.value] = "0"
|
|
|
|
|
|
|
|
|
|
self.infos = []
|
|
|
|
|
|
|
|
|
|
def name(self):
|
|
|
|
|
return self._data[C.name.value]
|
|
|
|
|
|
|
|
|
|
def importance(self):
|
|
|
|
|
return self._data[C.importance.value]
|
|
|
|
|
|
|
|
|
|
def ID(self):
|
|
|
|
|
return self._data[C.ID.value]
|
|
|
|
|
|
|
|
|
|
def index(self, column=0):
|
|
|
|
|
return self._model.indexFromItem(self, column)
|
|
|
|
|
|
|
|
|
|
def assignRandomColor(self):
|
|
|
|
|
"""
|
|
|
|
|
Assigns a random color the the character.
|
|
|
|
|
"""
|
|
|
|
|
color = randomColor(QColor(Qt.white))
|
|
|
|
|
self.setColor(color)
|
|
|
|
|
|
|
|
|
|
def setColor(self, color):
|
|
|
|
|
"""
|
|
|
|
|
Sets the character's color
|
|
|
|
|
@param color: QColor.
|
|
|
|
|
"""
|
|
|
|
|
px = QPixmap(32, 32)
|
|
|
|
|
px.fill(color)
|
|
|
|
|
self.icon = QIcon(px)
|
|
|
|
|
try:
|
|
|
|
|
self._model.dataChanged.emit(self.index(), self.index())
|
|
|
|
|
except:
|
|
|
|
|
# If it is the initialisation, won't be able to emit
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def color(self):
|
|
|
|
|
"""
|
|
|
|
|
Returns character's color in QColor
|
|
|
|
|
@return: QColor
|
|
|
|
|
"""
|
|
|
|
|
return iconColor(self.icon)
|
|
|
|
|
|
|
|
|
|
def assignUniqueID(self, parent=QModelIndex()):
|
|
|
|
|
"""Assigns an unused character ID."""
|
|
|
|
|
vals = []
|
|
|
|
|
for c in self._model.characters:
|
2016-03-04 05:41:19 +13:00
|
|
|
|
vals.append(int(c.ID()))
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
|
|
|
|
k = 0
|
|
|
|
|
while k in vals:
|
|
|
|
|
k += 1
|
|
|
|
|
|
2016-03-04 05:41:19 +13:00
|
|
|
|
self._data[C.ID.value] = str(k)
|
2016-03-04 04:38:38 +13:00
|
|
|
|
|
2016-03-04 05:18:30 +13:00
|
|
|
|
def listInfos(self):
|
|
|
|
|
r = []
|
|
|
|
|
for i in self.infos:
|
|
|
|
|
r.append((i.description, i.value))
|
|
|
|
|
return r
|
|
|
|
|
|
2016-03-04 04:38:38 +13:00
|
|
|
|
class CharacterInfo():
|
|
|
|
|
def __init__(self, character, description="", value=""):
|
|
|
|
|
self.description = description
|
|
|
|
|
self.value = value
|
|
|
|
|
self.character = character
|