manuskript/manuskript/ui/views/outlineDelegates.py
TheJackiMonster dc86e3b14e
Adjusted fixes for python 3.10 to not crash immediately
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
2021-12-13 14:27:59 +01:00

367 lines
13 KiB
Python

#!/usr/bin/env python
# --!-- 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
from manuskript.functions import outlineItemColors, mixColors, colorifyPixmap, toInt, toFloat, drawProgress
from manuskript.ui import style as S
class outlineTitleDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent)
self._view = None
def setView(self, view):
self._view = view
def paint(self, painter, option, index):
item = index.internalPointer()
colors = outlineItemColors(item)
style = qApp.style()
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, index)
iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt)
textRect = style.subElementRect(style.SE_ItemViewItemText, opt)
# Background
style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter)
if settings.viewSettings["Outline"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected:
col = colors[settings.viewSettings["Outline"]["Background"]]
if col != QColor(Qt.transparent):
col2 = QColor(S.base)
if opt.state & QStyle.State_Selected:
col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color()
col = mixColors(col, col2, .2)
painter.save()
painter.setBrush(col)
painter.setPen(Qt.NoPen)
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())
painter.drawRoundedRect(rect, 5, 5)
painter.restore()
# 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)
# Text
if opt.text:
painter.save()
textColor = QColor(S.text)
if option.state & QStyle.State_Selected:
col = QColor(S.highlightedText)
textColor = col
painter.setPen(col)
if settings.viewSettings["Outline"]["Text"] != "Nothing":
col = colors[settings.viewSettings["Outline"]["Text"]]
if col == Qt.transparent:
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))
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)
painter.restore()
# QStyledItemDelegate.paint(self, painter, option, index)
class outlineCharacterDelegate(QStyledItemDelegate):
def __init__(self, mdlCharacter, parent=None):
QStyledItemDelegate.__init__(self, parent)
self.mdlCharacter = mdlCharacter
def sizeHint(self, option, index):
# s = QStyledItemDelegate.sizeHint(self, option, index)
item = QModelIndex()
character = self.mdlCharacter.getCharacterByID(index.data())
if character:
item = character.index(Character.name)
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, item)
s = QStyledItemDelegate.sizeHint(self, opt, item)
if s.width() > 200:
s.setWidth(200)
elif s.width() < 100:
s.setWidth(100)
return s + QSize(18, 0)
def createEditor(self, parent, option, index):
item = index.internalPointer()
# if item.isFolder(): # No POV for folders
# return
editor = QComboBox(parent)
editor.setAutoFillBackground(True)
editor.setFrame(False)
return editor
def setEditorData(self, editor, index):
# editor.addItem("")
editor.addItem(QIcon.fromTheme("dialog-no"), self.tr("None"))
l = [self.tr("Main"), self.tr("Secondary"), self.tr("Minor")]
for importance in range(3):
editor.addItem(l[importance])
editor.setItemData(editor.count() - 1, QBrush(QColor(S.highlightedTextDark)), Qt.ForegroundRole)
editor.setItemData(editor.count() - 1, QBrush(QColor(S.highlightLight)), Qt.BackgroundRole)
item = editor.model().item(editor.count() - 1)
item.setFlags(Qt.ItemIsEnabled)
for i in range(self.mdlCharacter.rowCount()):
imp = toInt(self.mdlCharacter.importance(i))
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)
# except:
# pass
editor.setCurrentIndex(editor.findData(index.data()))
editor.showPopup()
def setModelData(self, editor, model, index):
val = editor.currentData()
model.setData(index, val)
def paint(self, painter, option, index):
##option.rect.setWidth(option.rect.width() - 18)
# QStyledItemDelegate.paint(self, painter, option, index)
##option.rect.setWidth(option.rect.width() + 18)
itemIndex = QModelIndex()
character = self.mdlCharacter.getCharacterByID(index.data())
if character:
itemIndex = character.index(Character.name)
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, itemIndex)
qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
# if index.isValid() and index.internalPointer().data(Outline.POV) not in ["", None]:
if itemIndex.isValid() and self.mdlCharacter.data(itemIndex) not in ["", None]:
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)
class outlineCompileDelegate(QStyledItemDelegate):
def __init__(self, parent=None):
QStyledItemDelegate.__init__(self, parent)
def displayText(self, value, locale):
return ""
#def createEditor(self, parent, option, index):
#return None
class outlineGoalPercentageDelegate(QStyledItemDelegate):
def __init__(self, rootIndex=None, parent=None):
QStyledItemDelegate.__init__(self, parent)
self.rootIndex = rootIndex
def sizeHint(self, option, index):
sh = QStyledItemDelegate.sizeHint(self, option, index)
# if sh.width() > 50:
sh.setWidth(100)
return sh
def paint(self, painter, option, index):
if not index.isValid():
return QStyledItemDelegate.paint(self, painter, option, index)
QStyledItemDelegate.paint(self, painter, option, index)
item = index.internalPointer()
if not item.data(Outline.goal):
return
p = toFloat(item.data(Outline.goalPercentage))
typ = item.data(Outline.type)
level = item.level()
if self.rootIndex and self.rootIndex.isValid():
level -= self.rootIndex.internalPointer().level() + 1
margin = 5
height = max(min(option.rect.height() - 2 * margin, 12) - 2 * level, 6)
painter.save()
rect = option.rect.adjusted(margin, margin, -margin, -margin)
# Move
rect.translate(int(level * rect.width() / 10), 0)
rect.setWidth(int(rect.width() - level * rect.width() / 10))
rect.setHeight(int(height))
rect.setTop(int(option.rect.top() + (option.rect.height() - height) / 2))
drawProgress(painter, rect, p) # from functions
painter.restore()
def displayText(self, value, locale):
return ""
class outlineStatusDelegate(QStyledItemDelegate):
def __init__(self, mdlStatus, parent=None):
QStyledItemDelegate.__init__(self, parent)
self.mdlStatus = mdlStatus
def sizeHint(self, option, index):
s = QStyledItemDelegate.sizeHint(self, option, index)
if s.width() > 150:
s.setWidth(150)
elif s.width() < 50:
s.setWidth(50)
return s + QSize(18, 0)
def createEditor(self, parent, option, index):
editor = QComboBox(parent)
editor.setAutoFillBackground(True)
editor.setFrame(False)
return editor
def setEditorData(self, editor, index):
for i in range(self.mdlStatus.rowCount()):
editor.addItem(self.mdlStatus.item(i, 0).text())
val = index.internalPointer().data(Outline.status)
if not val: val = 0
editor.setCurrentIndex(int(val))
editor.showPopup()
def setModelData(self, editor, model, index):
val = editor.currentIndex()
model.setData(index, val)
def displayText(self, value, locale):
try:
return self.mdlStatus.item(int(value), 0).text()
except:
return ""
def paint(self, painter, option, index):
QStyledItemDelegate.paint(self, painter, option, index)
if index.isValid() and index.internalPointer().data(Outline.status) not in ["", None, "0", 0]:
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)
class outlineLabelDelegate(QStyledItemDelegate):
def __init__(self, mdlLabels, parent=None):
QStyledItemDelegate.__init__(self, parent)
self.mdlLabels = mdlLabels
def sizeHint(self, option, index):
d = index.internalPointer().data(index.column(), Qt.DisplayRole)
if not d:
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)
if s.width() > 150:
s.setWidth(150)
elif s.width() < 50:
s.setWidth(50)
return s + QSize(18, 0)
def createEditor(self, parent, option, index):
item = index.internalPointer()
editor = QComboBox(parent)
# editor.setAutoFillBackground(True)
editor.setFrame(False)
return editor
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())
val = index.internalPointer().data(Outline.label)
if not val: val = 0
editor.setCurrentIndex(int(val))
editor.showPopup()
def setModelData(self, editor, model, index):
val = editor.currentIndex()
model.setData(index, val)
def paint(self, painter, option, index):
if not index.isValid():
return QStyledItemDelegate.paint(self, painter, option, index)
else:
item = index.internalPointer()
d = item.data(index.column(), Qt.DisplayRole)
if not d:
d = 0
lbl = self.mdlLabels.item(int(d), 0)
opt = QStyleOptionViewItem(option)
self.initStyleOption(opt, self.mdlLabels.indexFromItem(lbl))
qApp.style().drawControl(QStyle.CE_ItemViewItem, opt, painter)
# Drop down indicator
if index.isValid() and index.internalPointer().data(Outline.label) not in ["", None, "0", 0]:
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)