manuskript/manuskript/ui/views/outlineDelegates.py

367 lines
13 KiB
Python
Raw Normal View History

2015-06-04 12:04:47 +12:00
#!/usr/bin/env python
2016-02-07 00:34:22 +13:00
# --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QSize, QModelIndex
from PyQt5.QtGui import QColor, QPalette, QIcon, QFont, QFontMetrics, QBrush
from PyQt5.QtWidgets import QStyledItemDelegate, QStyleOptionViewItem, QStyle, QComboBox, QStyleOptionComboBox
from PyQt5.QtWidgets import qApp
from manuskript import settings
from manuskript.enums import Character, Outline
2016-02-07 00:34:22 +13:00
from manuskript.functions import outlineItemColors, mixColors, colorifyPixmap, toInt, toFloat, drawProgress
2017-11-14 22:00:35 +13:00
from manuskript.ui import style as S
2015-06-04 12:04:47 +12:00
2017-11-15 02:48:28 +13:00
2015-06-18 03:15:13 +12:00
class outlineTitleDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
2015-06-16 09:15:10 +12:00
QStyledItemDelegate.__init__(self, parent)
2015-06-18 03:15:13 +12:00
self._view = None
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
def setView(self, view):
self._view = view
2016-02-07 00:34:22 +13:00
2015-06-16 09:15:10 +12:00
def paint(self, painter, option, index):
2016-02-07 00:34:22 +13:00
2015-06-16 09:15:10 +12:00
item = index.internalPointer()
colors = outlineItemColors(item)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
style = qApp.style()
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, index)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt)
textRect = style.subElementRect(style.SE_ItemViewItemText, opt)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
# Background
style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
if settings.viewSettings["Outline"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected:
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
col = colors[settings.viewSettings["Outline"]["Background"]]
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
if col != QColor(Qt.transparent):
2017-11-14 22:00:35 +13:00
col2 = QColor(S.base)
2015-06-18 03:15:13 +12:00
if opt.state & QStyle.State_Selected:
col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color()
col = mixColors(col, col2, .2)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
painter.save()
painter.setBrush(col)
painter.setPen(Qt.NoPen)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
rect = opt.rect
if self._view:
r2 = self._view.visualRect(index)
rect = self._view.viewport().rect()
rect.setLeft(r2.left())
rect.setTop(r2.top())
rect.setBottom(r2.bottom())
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
painter.drawRoundedRect(rect, 5, 5)
painter.restore()
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
# Icon
mode = QIcon.Normal
if not opt.state & QStyle.State_Enabled:
mode = QIcon.Disabled
elif opt.state & QStyle.State_Selected:
mode = QIcon.Selected
state = QIcon.On if opt.state & QStyle.State_Open else QIcon.Off
icon = opt.icon.pixmap(iconRect.size(), mode=mode, state=state)
if opt.icon and settings.viewSettings["Outline"]["Icon"] != "Nothing":
color = colors[settings.viewSettings["Outline"]["Icon"]]
colorifyPixmap(icon, color)
opt.icon = QIcon(icon)
opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
# Text
if opt.text:
painter.save()
2017-11-14 22:00:35 +13:00
textColor = QColor(S.text)
if option.state & QStyle.State_Selected:
col = QColor(S.highlightedText)
textColor = col
painter.setPen(col)
2015-06-18 03:15:13 +12:00
if settings.viewSettings["Outline"]["Text"] != "Nothing":
col = colors[settings.viewSettings["Outline"]["Text"]]
if col == Qt.transparent:
2017-11-14 22:00:35 +13:00
col = textColor
# If text color is Compile and item is selected, we have
# to change the color
if settings.viewSettings["Outline"]["Text"] == "Compile" and \
item.compile() in [0, "0"]:
col = mixColors(textColor, QColor(S.window))
2015-06-18 03:15:13 +12:00
painter.setPen(col)
f = QFont(opt.font)
painter.setFont(f)
fm = QFontMetrics(f)
elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width())
painter.drawText(textRect, Qt.AlignLeft, elidedText)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
painter.restore()
2016-02-07 00:34:22 +13:00
# QStyledItemDelegate.paint(self, painter, option, index)
2015-06-10 00:03:22 +12:00
class outlineCharacterDelegate(QStyledItemDelegate):
def __init__(self, mdlCharacter, parent=None):
2015-06-04 12:04:47 +12:00
QStyledItemDelegate.__init__(self, parent)
self.mdlCharacter = mdlCharacter
2016-02-07 00:34:22 +13:00
2015-06-04 12:51:37 +12:00
def sizeHint(self, option, index):
2016-02-07 00:34:22 +13:00
# s = QStyledItemDelegate.sizeHint(self, option, index)
2015-06-21 21:54:52 +12:00
item = QModelIndex()
2016-03-06 21:21:10 +13:00
character = self.mdlCharacter.getCharacterByID(index.data())
if character:
2017-11-16 09:05:48 +13:00
item = character.index(Character.name)
2016-02-07 00:34:22 +13:00
2015-06-21 21:54:52 +12:00
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, item)
s = QStyledItemDelegate.sizeHint(self, opt, item)
2016-02-07 00:34:22 +13:00
2015-06-06 11:13:27 +12:00
if s.width() > 200:
s.setWidth(200)
elif s.width() < 100:
s.setWidth(100)
2015-06-04 12:51:37 +12:00
return s + QSize(18, 0)
2016-02-07 00:34:22 +13:00
2015-06-04 12:04:47 +12:00
def createEditor(self, parent, option, index):
item = index.internalPointer()
2016-02-07 00:34:22 +13:00
# if item.isFolder(): # No POV for folders
# return
2015-06-04 12:04:47 +12:00
editor = QComboBox(parent)
editor.setAutoFillBackground(True)
2015-06-04 12:51:37 +12:00
editor.setFrame(False)
2015-06-04 12:04:47 +12:00
return editor
2016-02-07 00:34:22 +13:00
2015-06-04 12:04:47 +12:00
def setEditorData(self, editor, index):
2016-02-07 00:34:22 +13:00
# editor.addItem("")
2015-09-29 22:17:03 +13:00
editor.addItem(QIcon.fromTheme("dialog-no"), self.tr("None"))
2016-02-07 00:34:22 +13:00
l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]
for importance in range(3):
editor.addItem(l[importance])
2017-11-15 02:48:28 +13:00
editor.setItemData(editor.count() - 1, QBrush(QColor(S.highlightedTextDark)), Qt.ForegroundRole)
editor.setItemData(editor.count() - 1, QBrush(QColor(S.highlightLight)), Qt.BackgroundRole)
2015-06-29 20:22:18 +12:00
item = editor.model().item(editor.count() - 1)
item.setFlags(Qt.ItemIsEnabled)
for i in range(self.mdlCharacter.rowCount()):
imp = toInt(self.mdlCharacter.importance(i))
2016-02-07 00:34:22 +13:00
if not 2 - imp == importance: continue
# try:
editor.addItem(self.mdlCharacter.icon(i), self.mdlCharacter.name(i), self.mdlCharacter.ID(i))
editor.setItemData(editor.count() - 1, self.mdlCharacter.name(i), Qt.ToolTipRole)
2016-02-07 00:34:22 +13:00
# except:
# pass
2015-06-04 12:04:47 +12:00
editor.setCurrentIndex(editor.findData(index.data()))
2015-06-10 00:03:22 +12:00
editor.showPopup()
2016-02-07 00:34:22 +13:00
2015-06-04 12:04:47 +12:00
def setModelData(self, editor, model, index):
val = editor.currentData()
model.setData(index, val)
2016-02-07 00:34:22 +13:00
2015-06-11 05:45:42 +12:00
def paint(self, painter, option, index):
2015-06-21 21:54:52 +12:00
##option.rect.setWidth(option.rect.width() - 18)
2016-02-07 00:34:22 +13:00
# QStyledItemDelegate.paint(self, painter, option, index)
2015-06-21 21:54:52 +12:00
##option.rect.setWidth(option.rect.width() + 18)
2016-02-07 00:34:22 +13:00
2016-03-06 21:21:10 +13:00
itemIndex = QModelIndex()
character = self.mdlCharacter.getCharacterByID(index.data())
if character:
2017-11-16 09:05:48 +13:00
itemIndex = character.index(Character.name)
2016-02-07 00:34:22 +13:00
2015-06-21 21:54:52 +12:00
opt = QStyleOptionViewItem(option)
2016-03-06 21:21:10 +13:00
self.initStyleOption(opt, itemIndex)
2016-02-07 00:34:22 +13:00
2015-06-21 21:54:52 +12:00
qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
2016-02-07 00:34:22 +13:00
2017-11-16 08:58:12 +13:00
# if index.isValid() and index.internalPointer().data(Outline.POV) not in ["", None]:
2016-03-06 21:21:10 +13:00
if itemIndex.isValid() and self.mdlCharacter.data(itemIndex) not in ["", None]:
2015-06-11 05:45:42 +12:00
opt = QStyleOptionComboBox()
opt.rect = option.rect
r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow)
option.rect = r
qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
class outlineCompileDelegate(QStyledItemDelegate):
2015-06-04 12:04:47 +12:00
def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent)
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
def displayText(self, value, locale):
return ""
2016-02-07 00:34:22 +13:00
2017-11-18 05:38:06 +13:00
#def createEditor(self, parent, option, index):
#return None
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
class outlineGoalPercentageDelegate(QStyledItemDelegate):
2015-06-09 22:32:43 +12:00
def __init__(self, rootIndex=None, parent=None):
2015-06-05 21:37:01 +12:00
QStyledItemDelegate.__init__(self, parent)
2015-06-09 22:32:43 +12:00
self.rootIndex = rootIndex
2016-02-07 00:34:22 +13:00
2015-06-09 22:32:43 +12:00
def sizeHint(self, option, index):
sh = QStyledItemDelegate.sizeHint(self, option, index)
2016-02-07 00:34:22 +13:00
# if sh.width() > 50:
2015-06-09 22:32:43 +12:00
sh.setWidth(100)
return sh
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
def paint(self, painter, option, index):
if not index.isValid():
return QStyledItemDelegate.paint(self, painter, option, index)
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
QStyledItemDelegate.paint(self, painter, option, index)
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
item = index.internalPointer()
2016-02-07 00:34:22 +13:00
2017-11-16 08:58:12 +13:00
if not item.data(Outline.goal):
2015-06-05 21:37:01 +12:00
return
2016-02-07 00:34:22 +13:00
2017-11-16 08:58:12 +13:00
p = toFloat(item.data(Outline.goalPercentage))
2015-06-05 21:37:01 +12:00
2017-11-16 08:58:12 +13:00
typ = item.data(Outline.type)
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
level = item.level()
2015-06-11 05:45:42 +12:00
if self.rootIndex and self.rootIndex.isValid():
2015-06-09 22:32:43 +12:00
level -= self.rootIndex.internalPointer().level() + 1
2016-02-07 00:34:22 +13:00
2015-06-07 01:44:04 +12:00
margin = 5
2016-02-07 00:34:22 +13:00
height = max(min(option.rect.height() - 2 * margin, 12) - 2 * level, 6)
2015-06-05 21:37:01 +12:00
painter.save()
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
rect = option.rect.adjusted(margin, margin, -margin, -margin)
2016-02-07 00:34:22 +13:00
2015-06-06 11:13:27 +12:00
# Move
rect.translate(int(level * rect.width() / 10), 0)
rect.setWidth(int(rect.width() - level * rect.width() / 10))
2016-02-07 00:34:22 +13:00
rect.setHeight(int(height))
rect.setTop(int(option.rect.top() + (option.rect.height() - height) / 2))
2016-02-07 00:34:22 +13:00
drawProgress(painter, rect, p) # from functions
2015-06-05 21:37:01 +12:00
painter.restore()
2016-02-07 00:34:22 +13:00
2015-06-05 21:37:01 +12:00
def displayText(self, value, locale):
return ""
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
class outlineStatusDelegate(QStyledItemDelegate):
2015-06-11 01:57:44 +12:00
def __init__(self, mdlStatus, parent=None):
2015-06-04 12:51:37 +12:00
QStyledItemDelegate.__init__(self, parent)
2015-06-11 01:57:44 +12:00
self.mdlStatus = mdlStatus
2016-02-07 00:34:22 +13:00
2015-06-04 12:51:37 +12:00
def sizeHint(self, option, index):
s = QStyledItemDelegate.sizeHint(self, option, index)
2015-06-11 01:57:44 +12:00
if s.width() > 150:
s.setWidth(150)
elif s.width() < 50:
s.setWidth(50)
2015-06-04 12:51:37 +12:00
return s + QSize(18, 0)
2016-02-07 00:34:22 +13:00
2015-06-04 12:51:37 +12:00
def createEditor(self, parent, option, index):
editor = QComboBox(parent)
editor.setAutoFillBackground(True)
editor.setFrame(False)
return editor
2016-02-07 00:34:22 +13:00
2015-06-04 12:51:37 +12:00
def setEditorData(self, editor, index):
2015-06-11 01:57:44 +12:00
for i in range(self.mdlStatus.rowCount()):
editor.addItem(self.mdlStatus.item(i, 0).text())
2016-02-07 00:34:22 +13:00
2017-11-16 08:58:12 +13:00
val = index.internalPointer().data(Outline.status)
2015-06-11 01:57:44 +12:00
if not val: val = 0
editor.setCurrentIndex(int(val))
2015-06-10 00:03:22 +12:00
editor.showPopup()
2016-02-07 00:34:22 +13:00
2015-06-04 12:51:37 +12:00
def setModelData(self, editor, model, index):
2015-06-11 01:57:44 +12:00
val = editor.currentIndex()
2015-06-10 00:03:22 +12:00
model.setData(index, val)
2016-02-07 00:34:22 +13:00
2015-06-11 01:57:44 +12:00
def displayText(self, value, locale):
try:
return self.mdlStatus.item(int(value), 0).text()
except:
return ""
2016-02-07 00:34:22 +13:00
2015-06-11 05:45:42 +12:00
def paint(self, painter, option, index):
QStyledItemDelegate.paint(self, painter, option, index)
2016-02-07 00:34:22 +13:00
2017-11-16 08:58:12 +13:00
if index.isValid() and index.internalPointer().data(Outline.status) not in ["", None, "0", 0]:
2015-06-11 05:45:42 +12:00
opt = QStyleOptionComboBox()
opt.rect = option.rect
r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow)
option.rect = r
qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)
2016-02-07 00:34:22 +13:00
2015-06-18 03:15:13 +12:00
class outlineLabelDelegate(QStyledItemDelegate):
2015-06-10 00:03:22 +12:00
def __init__(self, mdlLabels, parent=None):
QStyledItemDelegate.__init__(self, parent)
self.mdlLabels = mdlLabels
2016-02-07 00:34:22 +13:00
2015-06-11 05:45:42 +12:00
def sizeHint(self, option, index):
d = index.internalPointer().data(index.column(), Qt.DisplayRole)
2016-02-07 00:34:22 +13:00
if not d:
2015-06-11 05:45:42 +12:00
d = 0
item = self.mdlLabels.item(int(d), 0)
idx = self.mdlLabels.indexFromItem(item)
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, idx)
s = qApp.style().sizeFromContents(QStyle.CT_ItemViewItem, opt, QSize(), None)
2015-06-11 05:45:42 +12:00
if s.width() > 150:
s.setWidth(150)
elif s.width() < 50:
s.setWidth(50)
return s + QSize(18, 0)
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
def createEditor(self, parent, option, index):
item = index.internalPointer()
editor = QComboBox(parent)
2016-02-07 00:34:22 +13:00
# editor.setAutoFillBackground(True)
2015-06-10 00:03:22 +12:00
editor.setFrame(False)
return editor
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
def setEditorData(self, editor, index):
for i in range(self.mdlLabels.rowCount()):
editor.addItem(self.mdlLabels.item(i, 0).icon(),
self.mdlLabels.item(i, 0).text())
2016-02-07 00:34:22 +13:00
2017-11-16 08:58:12 +13:00
val = index.internalPointer().data(Outline.label)
2015-06-10 00:03:22 +12:00
if not val: val = 0
editor.setCurrentIndex(int(val))
editor.showPopup()
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
def setModelData(self, editor, model, index):
val = editor.currentIndex()
model.setData(index, val)
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
def paint(self, painter, option, index):
if not index.isValid():
return QStyledItemDelegate.paint(self, painter, option, index)
else:
item = index.internalPointer()
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
d = item.data(index.column(), Qt.DisplayRole)
2016-02-07 00:34:22 +13:00
if not d:
2015-06-10 00:03:22 +12:00
d = 0
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
lbl = self.mdlLabels.item(int(d), 0)
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, self.mdlLabels.indexFromItem(lbl))
2016-02-07 00:34:22 +13:00
2015-06-10 00:03:22 +12:00
qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
2016-02-07 00:34:22 +13:00
2015-06-11 05:45:42 +12:00
# Drop down indicator
2017-11-16 08:58:12 +13:00
if index.isValid() and index.internalPointer().data(Outline.label) not in ["", None, "0", 0]:
2015-06-11 05:45:42 +12:00
opt = QStyleOptionComboBox()
opt.rect = option.rect
r = qApp.style().subControlRect(QStyle.CC_ComboBox, opt, QStyle.SC_ComboBoxArrow)
option.rect = r
qApp.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, option, painter)