File indexing completed on 2024-04-21 04:01:49

0001 """
0002 Copyright (c) 2007-2008 Qtrac Ltd <mark@qtrac.eu>
0003 Copyright (C) 2008-2016 Wolfgang Rohdewald <wolfgang@rohdewald.de>
0004 
0005 SPDX-License-Identifier: GPL-2.0
0006 
0007 """
0008 
0009 from qt import Qt, QSize, QRect, QEvent
0010 from qt import QStyledItemDelegate, QLabel, QTextDocument, QStyle, QPalette, \
0011     QStyleOptionViewItem, QApplication
0012 
0013 from guiutil import Painter
0014 
0015 
0016 class ZeroEmptyColumnDelegate(QStyledItemDelegate):
0017 
0018     """Display 0 or 0.00 as empty"""
0019 
0020     def displayText(self, value, locale):
0021         """Display 0 or 0.00 as empty"""
0022         if isinstance(value, int) and value == 0:
0023             return ''
0024         if isinstance(value, float) and value == 0.0:
0025             return ''
0026         return super().displayText(value, locale)
0027 
0028 class RichTextColumnDelegate(QStyledItemDelegate):
0029 
0030     """enables rich text in a view"""
0031     label = None
0032     document = None
0033 
0034     def __init__(self, parent=None):
0035         super().__init__(parent)
0036         if self.label is None:
0037             self.label = QLabel()
0038             self.label.setIndent(5)
0039             self.label.setTextFormat(Qt.RichText)
0040             self.document = QTextDocument()
0041 
0042     def paint(self, painter, option, index):
0043         """paint richtext"""
0044         if option.state & QStyle.State_Selected:
0045             role = QPalette.Highlight
0046         else:
0047             role = QPalette.AlternateBase if index.row() % 2 else QPalette.Base
0048         self.label.setBackgroundRole(role)
0049         text = index.model().data(index, Qt.DisplayRole)
0050         self.label.setText(text)
0051         self.label.setFixedSize(option.rect.size())
0052         with Painter(painter):
0053             painter.translate(option.rect.topLeft())
0054             self.label.render(painter)
0055 
0056     def sizeHint(self, option, index):
0057         """compute size for the final formatted richtext"""
0058         text = index.model().data(index)
0059         self.document.setDefaultFont(option.font)
0060         self.document.setHtml(text)
0061         return QSize(int(self.document.idealWidth()) + 5,
0062                      option.fontMetrics.height())
0063 
0064 
0065 class RightAlignedCheckboxDelegate(QStyledItemDelegate):
0066 
0067     """as the name says. From
0068 https://wiki.qt.io/Technical_FAQ#How_can_I_align_the_checkboxes_in_a_view.3F"""
0069 
0070     def __init__(self, parent, cellFilter):
0071         super().__init__(parent)
0072         self.cellFilter = cellFilter
0073 
0074     @staticmethod
0075     def __textMargin():
0076         """text margin"""
0077         return QApplication.style().pixelMetric(
0078             QStyle.PM_FocusFrameHMargin) + 1
0079 
0080     def paint(self, painter, option, index):
0081         """paint right aligned checkbox"""
0082         viewItemOption = QStyleOptionViewItem(option)
0083         if self.cellFilter(index):
0084             textMargin = self.__textMargin()
0085             newRect = QStyle.alignedRect(
0086                 option.direction, Qt.AlignRight,
0087                 QSize(
0088                     option.decorationSize.width() + 5,
0089                     option.decorationSize.height()),
0090                 QRect(
0091                     option.rect.x() + textMargin, option.rect.y(),
0092                     option.rect.width() - (2 * textMargin),
0093                     option.rect.height()))
0094             viewItemOption.rect = newRect
0095         QStyledItemDelegate.paint(self, painter, viewItemOption, index)
0096 
0097     def editorEvent(self, event, model, option, index):
0098         """edit right aligned checkbox"""
0099         flags = model.flags(index)
0100         # make sure that the item is checkable
0101         if not flags & Qt.ItemIsUserCheckable or not flags & Qt.ItemIsEnabled:
0102             return False
0103         # make sure that we have a check state
0104         value = index.data(Qt.CheckStateRole)
0105         if not isinstance(value, int):
0106             return False
0107         # make sure that we have the right event type
0108         if event.type() == QEvent.MouseButtonRelease:
0109             textMargin = self.__textMargin()
0110             checkRect = QStyle.alignedRect(
0111                 option.direction, Qt.AlignRight,
0112                 option.decorationSize,
0113                 QRect(
0114                     option.rect.x() + (2 * textMargin), option.rect.y(),
0115                     option.rect.width() - (2 * textMargin),
0116                     option.rect.height()))
0117             if not checkRect.contains(event.pos()):
0118                 return False
0119         elif event.type() == QEvent.KeyPress:
0120             if event.key() not in (Qt.Key_Space, Qt.Key_Select):
0121                 return False
0122         else:
0123             return False
0124         if value == Qt.Checked:
0125             state = Qt.Unchecked
0126         else:
0127             state = Qt.Checked
0128         return model.setData(index, state, Qt.CheckStateRole)