manuskript/manuskript/models/worldModel.py

283 lines
9.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python
2016-02-07 00:34:22 +13:00
# --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex
from PyQt5.QtCore import QSize
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItem, QBrush, QFontMetrics
2017-11-15 02:48:28 +13:00
from PyQt5.QtGui import QStandardItemModel, QColor
2016-02-07 00:34:22 +13:00
from PyQt5.QtWidgets import QMenu, QAction, qApp
from manuskript.enums import World
2017-11-15 02:48:28 +13:00
from manuskript.functions import mainWindow
from manuskript.ui import style as S
2016-02-07 00:34:22 +13:00
class worldModel(QStandardItemModel):
def __init__(self, parent):
QStandardItemModel.__init__(self, 0, 3, parent)
self.mw = mainWindow()
2016-02-07 00:34:22 +13:00
###############################################################################
# SELECTION
###############################################################################
def selectedItem(self):
2016-02-07 00:34:22 +13:00
"""Returns the item selected in mw.treeWorld. invisibleRootItem if None."""
index = self.selectedIndex()
item = self.itemFromIndex(index)
if item:
return item
else:
return self.invisibleRootItem()
def selectedIndex(self):
2016-02-07 00:34:22 +13:00
"""Returns the selected index in the treeView."""
if self.mw.treeWorld.selectedIndexes():
return self.mw.treeWorld.currentIndex()
else:
return QModelIndex()
2016-02-07 00:34:22 +13:00
def selectedIndexes(self):
return self.mw.treeWorld.selectedIndexes()
2016-02-07 00:34:22 +13:00
###############################################################################
# GETTERS
###############################################################################
def ID(self, index):
2016-02-07 00:34:22 +13:00
"""Returns the ID of the given index."""
index = index.sibling(index.row(), World.ID.value)
return self.data(index)
2016-02-07 00:34:22 +13:00
def name(self, index):
2016-02-07 00:34:22 +13:00
"""Returns the name of the given index."""
index = index.sibling(index.row(), World.name.value)
return self.data(index)
2016-02-07 00:34:22 +13:00
def description(self, index):
index = index.sibling(index.row(), World.description.value)
return self.data(index)
2016-02-07 00:34:22 +13:00
def conflict(self, index):
index = index.sibling(index.row(), World.conflict.value)
return self.data(index)
2016-02-07 00:34:22 +13:00
def passion(self, index):
index = index.sibling(index.row(), World.passion.value)
return self.data(index)
2016-02-07 00:34:22 +13:00
def itemID(self, item):
2016-02-07 00:34:22 +13:00
"""Returns the ID of the given item."""
index = self.indexFromItem(item)
return self.ID(index)
2016-02-07 00:34:22 +13:00
def children(self, item):
2016-02-07 00:34:22 +13:00
"""Returns a list of all item's children."""
c = []
for i in range(item.rowCount()):
c.append(item.child(i))
return c
2016-02-07 00:34:22 +13:00
def listAll(self):
2016-02-07 00:34:22 +13:00
"""Returns a list of tupple ``(name, ID, path)`` for all items."""
lst = []
2016-02-07 00:34:22 +13:00
def readAll(item):
name = item.text()
ID = self.itemID(item)
path = self.path(item)
if name and ID:
lst.append((name, ID, path))
for c in self.children(item):
readAll(c)
2016-02-07 00:34:22 +13:00
readAll(self.invisibleRootItem())
2016-02-07 00:34:22 +13:00
return lst
2016-02-07 00:34:22 +13:00
def indexByID(self, ID):
2016-02-07 00:34:22 +13:00
"""Returns the index of item whose ID is ID."""
return self.indexFromItem(self.itemByID(ID))
2016-02-07 00:34:22 +13:00
def itemByID(self, ID):
2016-02-07 00:34:22 +13:00
"""Returns the item whose ID is ID."""
def browse(item):
if self.itemID(item) == ID:
return item
for c in self.children(item):
r = browse(c)
if r:
return r
2016-02-07 00:34:22 +13:00
r = browse(self.invisibleRootItem())
2015-07-10 22:29:25 +12:00
return r if r else None
2016-02-07 00:34:22 +13:00
def path(self, item):
2016-02-07 00:34:22 +13:00
"""Returns the path to the item in the form of 'ancestor > ... > grand-parent > parent'."""
path = []
while item.parent():
item = item.parent()
path.append(item.text())
path = " > ".join(path)
return path
2016-02-07 00:34:22 +13:00
###############################################################################
# ADDING AND REMOVE
###############################################################################
def addItem(self, title=None, parent=None):
2016-02-07 00:34:22 +13:00
"""Adds an item, and returns it."""
if not parent:
parent = self.selectedItem()
if not title:
title = self.tr("New item")
name = QStandardItem(title)
_id = QStandardItem(self.getUniqueID())
row = [name, _id] + [QStandardItem() for i in range(2, len(World))]
parent.appendRow(row)
return name
def getUniqueID(self):
2016-02-07 00:34:22 +13:00
"""Returns an unused ID"""
parentItem = self.invisibleRootItem()
vals = []
2016-02-07 00:34:22 +13:00
def collectIDs(item):
vals.append(int(self.itemID(item)))
for c in self.children(item):
collectIDs(c)
2016-02-07 00:34:22 +13:00
for c in self.children(parentItem):
collectIDs(c)
2016-02-07 00:34:22 +13:00
k = 0
2016-02-07 00:34:22 +13:00
while k in vals:
k += 1
return str(k)
def removeItem(self):
while self.selectedIndexes():
index = self.selectedIndexes()[0]
self.removeRows(index.row(), 1, index.parent())
2016-02-07 00:34:22 +13:00
###############################################################################
# TEMPLATES
###############################################################################
def dataSets(self):
2016-02-07 00:34:22 +13:00
"""Returns sets of empty data that can guide the writer for world building."""
dataset = {
self.tr("Fantasy world building"): [
(self.tr("Physical"), [
self.tr("Climate"),
self.tr("Topography"),
self.tr("Astronomy"),
self.tr("Natural ressources"),
self.tr("Wild life"),
self.tr("Flora"),
self.tr("History"),
self.tr("Races"),
self.tr("Diseases"),
2016-02-07 00:34:22 +13:00
]),
(self.tr("Cultural"), [
self.tr("Customs"),
self.tr("Food"),
self.tr("Languages"),
self.tr("Education"),
self.tr("Dresses"),
self.tr("Science"),
self.tr("Calendar"),
self.tr("Bodily language"),
self.tr("Ethics"),
self.tr("Religion"),
self.tr("Government"),
self.tr("Politics"),
self.tr("Gender roles"),
self.tr("Music and arts"),
self.tr("Architecture"),
self.tr("Military"),
self.tr("Technology"),
self.tr("Courtship"),
self.tr("Demography"),
self.tr("Transportation"),
self.tr("Medicine"),
2016-02-07 00:34:22 +13:00
]),
(self.tr("Magic system"), [
self.tr("Rules"),
self.tr("Organization"),
self.tr("Magical objects"),
self.tr("Magical places"),
self.tr("Magical races"),
2016-02-07 00:34:22 +13:00
]),
self.tr("Important places"),
self.tr("Important objects"),
2016-02-07 00:34:22 +13:00
]
}
return dataset
2016-02-07 00:34:22 +13:00
def emptyDataMenu(self):
2016-02-07 00:34:22 +13:00
"""Returns a menu with the empty data sets."""
self.menu = QMenu("menu")
for name in self.dataSets():
a = QAction(name, self.menu)
a.triggered.connect(self.setEmptyData)
self.menu.addAction(a)
return self.menu
2016-02-07 00:34:22 +13:00
def setEmptyData(self):
2016-02-07 00:34:22 +13:00
"""Called from the menu generated with ``emptyDataMenu``."""
act = self.sender()
data = self.dataSets()[act.text()]
2016-02-07 00:34:22 +13:00
def addItems(data, parent):
for d in data:
if len(d) == 1 or type(d) == str:
self.addItem(d, parent)
else:
i = self.addItem(d[0], parent)
addItems(d[1], i)
2016-02-07 00:34:22 +13:00
addItems(data, None)
self.mw.treeWorld.expandAll()
2016-02-07 00:34:22 +13:00
###############################################################################
# APPEARANCE
###############################################################################
def data(self, index, role=Qt.EditRole):
level = 0
i = index
while i.parent() != QModelIndex():
i = i.parent()
level += 1
2016-02-07 00:34:22 +13:00
if role == Qt.BackgroundRole:
if level == 0:
2017-11-15 02:48:28 +13:00
return QBrush(QColor(S.highlightLight))
2016-02-07 00:34:22 +13:00
if role == Qt.TextAlignmentRole:
if level == 0:
return Qt.AlignCenter
2016-02-07 00:34:22 +13:00
if role == Qt.FontRole:
if level in [0, 1]:
f = qApp.font()
f.setBold(True)
return f
2016-02-07 00:34:22 +13:00
if role == Qt.ForegroundRole:
if level == 0:
2017-11-15 02:48:28 +13:00
return QBrush(QColor(S.highlightedTextDark))
2016-02-07 00:34:22 +13:00
if role == Qt.SizeHintRole:
fm = QFontMetrics(qApp.font())
h = fm.height()
if level == 0:
return QSize(0, h + 12)
elif level == 1:
return QSize(0, h + 6)
2016-02-07 00:34:22 +13:00
return QStandardItemModel.data(self, index, role)