manuskript/manuskript/ui/views/plotTreeView.py

213 lines
7.1 KiB
Python
Raw Normal View History

2015-06-23 06:30:43 +12:00
#!/usr/bin/env python
2016-02-07 00:34:22 +13:00
# --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QModelIndex, QMimeData
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem
2015-07-03 03:45:27 +12:00
from lxml import etree as ET
2016-02-07 00:34:22 +13:00
from manuskript import settings
from manuskript.enums import Plot, Outline, PlotStep
2016-02-07 00:34:22 +13:00
from manuskript.models import references as Ref
2017-11-15 02:48:28 +13:00
from manuskript.ui import style as S
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
class plotTreeView(QTreeWidget):
def __init__(self, parent=None):
QTreeWidget.__init__(self, parent)
self._model = None
self._catRow = [-1, -1, -1]
self._filter = ""
self._lastID = -1
self._updating = False
self._showSubPlot = False
self.setRootIsDecorated(False)
self.setIndentation(10)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
self.setColumnCount(1)
self._rootItem = QTreeWidgetItem()
self.insertTopLevelItem(0, self._rootItem)
2016-02-07 00:34:22 +13:00
# self.currentItemChanged.connect(self._currentItemChanged)
2015-07-03 03:45:27 +12:00
2016-02-07 00:34:22 +13:00
###############################################################################
# SETTERS
###############################################################################
2015-07-03 03:45:27 +12:00
2015-06-23 06:30:43 +12:00
def setShowSubPlot(self, v):
self._showSubPlot = v
self.updateItems()
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
def setPlotModel(self, model):
self._model = model
self._model.dataChanged.connect(self.updateMaybe)
self._model.rowsInserted.connect(self.updateMaybe2)
self._model.rowsRemoved.connect(self.updateMaybe2)
self.updateItems()
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
def setFilter(self, text):
self._filter = text
self.updateItems()
2015-07-03 03:45:27 +12:00
2016-02-07 00:34:22 +13:00
###############################################################################
# GETTERS
###############################################################################
2015-07-03 03:45:27 +12:00
def getItemByID(self, ID):
2015-07-06 19:45:28 +12:00
"Recursively search items to find one whose data is ``ID``."
2016-02-07 00:34:22 +13:00
2015-07-06 19:45:28 +12:00
def find(item, ID):
if item.data(0, Qt.UserRole) == ID:
return item
for i in range(item.childCount()):
r = find(item.child(i), ID)
if r:
return r
2016-02-07 00:34:22 +13:00
2015-07-06 19:45:28 +12:00
return find(self.invisibleRootItem(), ID)
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
def currentPlotIndex(self):
"Returns index of the current item in plot model."
return self._model.getIndexFromID(self.currentPlotID())
def currentPlotID(self):
"Returns ID of the current item in plot model."
2015-07-03 03:45:27 +12:00
ID = None
if self.currentItem():
ID = self.currentItem().data(0, Qt.UserRole)
2016-02-07 00:34:22 +13:00
return ID
2016-02-07 00:34:22 +13:00
###############################################################################
# UPDATES
###############################################################################
2015-07-03 03:45:27 +12:00
2015-06-23 06:30:43 +12:00
def updateMaybe(self, topLeft, bottomRight):
if topLeft.parent() != QModelIndex() and \
2017-11-16 09:05:48 +13:00
topLeft.column() <= PlotStep.name <= bottomRight.column() and \
self._showSubPlot:
# Name's of Step has been updated, we update Items if showing
# subplots.
self.updateItems()
elif topLeft.parent() != QModelIndex():
2015-06-23 06:30:43 +12:00
return
2016-02-07 00:34:22 +13:00
2017-11-16 09:05:48 +13:00
if topLeft.column() <= Plot.name <= bottomRight.column():
2015-06-23 06:30:43 +12:00
# Update name
self.updateNames()
2016-02-07 00:34:22 +13:00
2017-11-16 09:05:48 +13:00
elif topLeft.column() <= Plot.importance <= bottomRight.column():
2015-06-23 06:30:43 +12:00
# Importance changed
self.updateItems()
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
def updateMaybe2(self, parent, first, last):
"Rows inserted or removed"
if parent == QModelIndex():
self.updateItems()
2016-02-07 00:34:22 +13:00
2015-07-01 23:14:03 +12:00
elif self._showSubPlot:
self.updateItems()
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
def updateNames(self):
for i in range(self.topLevelItemCount()):
item = self.topLevelItem(i)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
for c in range(item.childCount()):
sub = item.child(c)
ID = sub.data(0, Qt.UserRole)
if ID:
name = self._model.getPlotNameByID(ID)
sub.setText(0, name)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
def updateItems(self):
if not self._model:
return
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
if self.currentItem():
self._lastID = self.currentItem().data(0, Qt.UserRole)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
self._updating = True
self.clear()
plots = self._model.getPlotsByImportance()
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
h = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]
for i in range(3):
cat = QTreeWidgetItem(self, [h[i]])
2017-11-15 02:48:28 +13:00
cat.setBackground(0, QBrush(QColor(S.highlightLight)))
cat.setForeground(0, QBrush(QColor(S.highlightedTextDark)))
2015-06-23 06:30:43 +12:00
cat.setTextAlignment(0, Qt.AlignCenter)
f = cat.font(0)
f.setBold(True)
cat.setFont(0, f)
2015-07-03 03:45:27 +12:00
cat.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
2015-06-23 06:30:43 +12:00
self.addTopLevelItem(cat)
2016-02-07 00:34:22 +13:00
# cat.setChildIndicatorPolicy(cat.DontShowIndicator)
2015-06-23 06:30:43 +12:00
for ID in plots[i]:
name = self._model.getPlotNameByID(ID)
2016-02-07 00:34:22 +13:00
if not self._filter.lower() in name.lower():
2015-06-23 06:30:43 +12:00
continue
item = QTreeWidgetItem(cat, [name])
item.setData(0, Qt.UserRole, ID)
2015-07-03 03:45:27 +12:00
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
if self._showSubPlot:
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
f = item.font(0)
f.setBold(True)
item.setFont(0, f)
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
for subID, name, summary in self._model.getSubPlotsByID(ID):
2015-06-23 06:30:43 +12:00
sub = QTreeWidgetItem(item, [name])
2016-02-07 00:34:22 +13:00
# sub.setData(0, Qt.UserRole, "{}:{}".format(ID, subID))
2015-07-03 03:45:27 +12:00
sub.setData(0, Qt.UserRole, ID)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
if ID == self._lastID:
self.setCurrentItem(item)
2016-02-07 00:34:22 +13:00
2015-06-23 06:30:43 +12:00
self.expandAll()
self._updating = False
2015-07-03 03:45:27 +12:00
2016-02-07 00:34:22 +13:00
###############################################################################
# DRAG N DROP
###############################################################################
2015-07-03 03:45:27 +12:00
def mimeTypes(self):
return ["application/xml"]
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
def mimeData(self, items):
mimeData = QMimeData()
encodedData = ""
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
root = ET.Element("outlineItems")
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
for item in items:
plotID = item.data(0, Qt.UserRole)
subplotRaw = item.parent().indexOfChild(item)
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
_id, name, summary = self._model.getSubPlotsByID(plotID)[subplotRaw]
2016-02-07 00:34:22 +13:00
sub = ET.Element("outlineItem")
2015-07-03 03:45:27 +12:00
sub.set(Outline.title.name, name)
sub.set(Outline.type.name, settings.defaultTextType)
2016-02-05 05:53:27 +13:00
sub.set(Outline.summaryFull.name, summary)
2015-07-03 03:45:27 +12:00
sub.set(Outline.notes.name, self.tr("**Plot:** {}").format(
2016-02-07 00:34:22 +13:00
Ref.plotReference(plotID)))
2015-07-03 03:45:27 +12:00
root.append(sub)
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
encodedData = ET.tostring(root)
2016-02-07 00:34:22 +13:00
2015-07-03 03:45:27 +12:00
mimeData.setData("application/xml", encodedData)
2016-02-07 00:34:22 +13:00
return mimeData
2015-07-03 03:45:27 +12:00
2016-02-07 00:34:22 +13:00
###############################################################################
# EVENTS
###############################################################################
2015-07-03 03:45:27 +12:00
2015-06-23 06:30:43 +12:00
def mouseDoubleClickEvent(self, event):
item = self.currentItem()
if not item:
return
2015-06-23 06:30:43 +12:00
# Catching double clicks to forbid collapsing of toplevel items
if item.parent():
QTreeWidget.mouseDoubleClickEvent(self, event)