Ejemplo n.º 1
1
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, index)
     text, positions = index.data(Qt.UserRole)
     self.initStyleOption(option, index)
     painter.save()
     painter.setFont(option.font)
     p = option.palette
     c = p.HighlightedText if option.state & QStyle.State_Selected else p.Text
     group = (p.Active if option.state & QStyle.State_Active else p.Inactive)
     c = p.color(group, c)
     painter.setClipRect(option.rect)
     if positions is None or -1 in positions:
         painter.setPen(c)
         painter.drawText(option.rect, Qt.AlignLeft | Qt.AlignVCenter | Qt.TextSingleLine, text)
     else:
         to = QTextOption()
         to.setWrapMode(to.NoWrap)
         to.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
         positions = sorted(set(positions) - {-1}, reverse=True)
         text = '<body>%s</body>' % make_highlighted_text(Results.EMPH, text, positions)
         doc = QTextDocument()
         c = 'rgb(%d, %d, %d)'%c.getRgb()[:3]
         doc.setDefaultStyleSheet(' body { color: %s }'%c)
         doc.setHtml(text)
         doc.setDefaultFont(option.font)
         doc.setDocumentMargin(0.0)
         doc.setDefaultTextOption(to)
         height = doc.size().height()
         painter.translate(option.rect.left(), option.rect.top() + (max(0, option.rect.height() - height) // 2))
         doc.drawContents(painter)
     painter.restore()
Ejemplo n.º 2
0
 def __init__(self, *args):
     QPlainTextEdit.__init__(self, *args)
     # Default options to RightToleft
     options = QTextOption()
     options = self.document().defaultTextOption()
     options.setAlignment(Qt.AlignRight)
     options.setTextDirection(Qt.RightToLeft)
     self.document().setDefaultTextOption(options)
     # Default dictionary based on the current locale.
     self.dict = myspeller()
     # self.highlighter = Highlighter(self.document())
     # self.highlighter.setDict(self.dict)
     self.pretxt = ''
    def viewItemDrawText(self, painter, option, rect, text, color, searchText=''):  # noqa C901
        '''
        @note: most of codes taken from QCommonStylePrivate::viewItemDrawText
            added highlighting and simplified for single-line textlayouts
        @param painter QPainter
        @param option QStyleOptionViewItem
        @param rect QRect
        @param text QString
        @param color QColor
        @param searchText QString
        @return: int
        '''
        if not text:
            return 0

        fontMetrics = QFontMetrics(painter.font())
        elidedText = fontMetrics.elidedText(text, option.textElideMode, rect.width())
        textOption = QTextOption()
        textOption.setWrapMode(QTextOption.NoWrap)
        textOption.setAlignment(QStyle.visualAlignment(textOption.textDirection(),
            option.displayAlignment))
        textLayout = QTextLayout()
        textLayout.setFont(painter.font())
        textLayout.setText(elidedText)
        textLayout.setTextOption(textOption)

        if searchText:
            # QList<int>
            delimiters = []
            searchStrings = [ item.strip() for item in searchText.split(' ') ]
            searchStrings = [ item for item in searchStrings if item ]
            # Look for longer parts first
            searchStrings.sort(key=lambda x: len(x), reverse=True)

            text0 = text.lower()
            for string in searchStrings:
                string0 = string.lower()
                delimiter = text0.find(string0)

                while delimiter != -1:
                    start = delimiter
                    end = delimiter + len(string)
                    alreadyContains = False
                    for idx in range(0, len(delimiters), 2):
                        dStart = delimiters[idx]
                        dEnd = delimiters[idx+1]

                        if dStart <= start and dEnd >= end:
                            alreadyContains = True
                            break

                    if not alreadyContains:
                        delimiters.append(start)
                        delimiters.append(end)

                    delimiter = text0.find(string0, end)

            # We need to sort delimiters to properly paint all parts that user typed
            delimiters.sort()

            # If we don't find any match, just paint it withoutany highlight
            if delimiters and len(delimiters) % 2 == 0:
                highlightParts = []  # QList<QTextLayout::FormatRange>

                while delimiters:
                    highlightedPart = QTextLayout.FormatRange()
                    start = delimiters.pop(0)
                    end = delimiters.pop(0)
                    highlightedPart.start = start
                    highlightedPart.length = end - start
                    highlightedPart.format.setFontWeight(QFont.Bold)
                    highlightedPart.format.setUnderlineStyle(QTextCharFormat.SingleUnderline)
                    highlightParts.append(highlightedPart)

                textLayout.setAdditionalFormats(highlightParts)

        # do layout
        self._s_viewItemDrawText(textLayout, rect.width())

        if textLayout.lineCount() <= 0:
            return 0

        textLine = textLayout.lineAt(0)

        # if elidedText after highlighting is longer than available width then
        # re-elide it and redo layout
        diff = textLine.naturalTextWidth() - rect.width()
        if diff > 0:
            # TODO: ?
            elidedText = fontMetrics.elidedText(elidedText, option.textElideMode,
                    rect.width() - diff)
            textLayout.setText(elidedText)
            # redo layout
            self._s_viewItemDrawText(textLayout, rect.width())

            if textLayout.lineCount() <= 0:
                return 0
            textLine = textLayout.lineAt(0)

        # draw line
        painter.setPen(color)
        # qreal
        width = max(rect.width(), textLayout.lineAt(0).width())
        # QRect
        layoutRect = QStyle.alignedRect(option.direction, option.displayAlignment,
                QSize(int(width), int(textLine.height())), rect)
        # QPointF
        position = layoutRect.topLeft()

        textLine.draw(painter, position)

        return int(min(rect.width(), textLayout.lineAt(0).naturalTextWidth()))