From b4b065d8ec004f3012810abc3e80bcad13708d45 Mon Sep 17 00:00:00 2001
From: Eike Ziller <eike.ziller@digia.com>
Date: Fri, 15 Nov 2013 10:06:51 +0100
Subject: [PATCH] Fix painting of search results

Painting the highlighting was wrong, and it was worst for selected rows.
The QItemDelegate::drawDisplay implementation also paints the
highlighted background at the wrong position wrt to the text
(PM_FocusFrameHMargin), so we now do all the highlights ourselves.

Task-number: QTCREATORBUG-9838
Change-Id: Iad68f114a984680e41aeb78d7c61a16651653213
Reviewed-by: David Schulz <david.schulz@digia.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
---
 .../find/searchresulttreeitemdelegate.cpp     | 55 ++++++++++++-------
 .../find/searchresulttreeitemdelegate.h       |  2 +-
 2 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/src/plugins/find/searchresulttreeitemdelegate.cpp b/src/plugins/find/searchresulttreeitemdelegate.cpp
index b4333e9e07b..a1cf8f778a4 100644
--- a/src/plugins/find/searchresulttreeitemdelegate.cpp
+++ b/src/plugins/find/searchresulttreeitemdelegate.cpp
@@ -144,7 +144,7 @@ int SearchResultTreeItemDelegate::drawLineNumber(QPainter *painter, const QStyle
 }
 
 void SearchResultTreeItemDelegate::drawText(QPainter *painter,
-                                            const QStyleOptionViewItem &opt,
+                                            const QStyleOptionViewItem &option,
                                             const QRect &rect,
                                             const QModelIndex &index) const
 {
@@ -159,7 +159,7 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
     const int searchTermStart = index.model()->data(index, ItemDataRoles::SearchTermStartRole).toInt();
     int searchTermLength = index.model()->data(index, ItemDataRoles::SearchTermLengthRole).toInt();
     if (searchTermStart < 0 || searchTermStart >= text.length() || searchTermLength < 1) {
-        QItemDelegate::drawDisplay(painter, opt, rect, text);
+        QItemDelegate::drawDisplay(painter, option, rect, text);
         return;
     }
     // clip searchTermLength to end of line
@@ -168,29 +168,48 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
     int searchTermStartPixels = painter->fontMetrics().width(text.left(searchTermStart));
     int searchTermLengthPixels = painter->fontMetrics().width(text.mid(searchTermStart, searchTermLength));
 
-    // Text before the highlighting
+    // rects
     QRect beforeHighlightRect(rect);
     beforeHighlightRect.setRight(beforeHighlightRect.left() + searchTermStartPixels);
-    QStyleOptionViewItem noHighlightOpt = opt;
+
+    QRect resultHighlightRect(rect);
+    resultHighlightRect.setLeft(beforeHighlightRect.right());
+    resultHighlightRect.setRight(resultHighlightRect.left() + searchTermLengthPixels);
+
+    QRect afterHighlightRect(rect);
+    afterHighlightRect.setLeft(resultHighlightRect.right());
+
+    // paint all highlight backgrounds
+    // qitemdelegate has problems with painting background when highlighted
+    // (highlighted background at wrong position because text is offset with textMargin)
+    // so we duplicate a lot here, see qitemdelegate for reference
+    bool isSelected = option.state & QStyle::State_Selected;
+    QPalette::ColorGroup cg = option.state & QStyle::State_Enabled
+                              ? QPalette::Normal : QPalette::Disabled;
+    if (cg == QPalette::Normal && !(option.state & QStyle::State_Active))
+        cg = QPalette::Inactive;
+    QStyleOptionViewItem baseOption = option;
+    baseOption.state &= ~QStyle::State_Selected;
+    if (isSelected) {
+        painter->fillRect(beforeHighlightRect.adjusted(textMargin, 0, textMargin, 0),
+                          option.palette.brush(cg, QPalette::Highlight));
+        painter->fillRect(afterHighlightRect.adjusted(textMargin, 0, textMargin, 0),
+                          option.palette.brush(cg, QPalette::Highlight));
+    }
+    const QColor highlightBackground =
+            index.model()->data(index, ItemDataRoles::ResultHighlightBackgroundColor).value<QColor>();
+    painter->fillRect(resultHighlightRect.adjusted(textMargin, 0, textMargin - 1, 0), QBrush(highlightBackground));
+
+    // Text before the highlighting
+    QStyleOptionViewItem noHighlightOpt = baseOption;
     noHighlightOpt.rect = beforeHighlightRect;
     noHighlightOpt.textElideMode = Qt::ElideNone;
+    if (isSelected)
+        noHighlightOpt.palette.setColor(QPalette::Text, noHighlightOpt.palette.color(cg, QPalette::HighlightedText));
     QItemDelegate::drawDisplay(painter, noHighlightOpt,
                                beforeHighlightRect, text.mid(0, searchTermStart));
 
-    // Highlight background
-    QRect highlightBackgroundRect(rect);
-    highlightBackgroundRect.setLeft(highlightBackgroundRect.left()
-                                    + searchTermStartPixels + textMargin - 1); // -1: Cosmetics
-    highlightBackgroundRect.setRight(highlightBackgroundRect.left()
-                                     + searchTermLengthPixels + 1); // +1: Cosmetics
-    const QColor highlightBackground =
-            index.model()->data(index, ItemDataRoles::ResultHighlightBackgroundColor).value<QColor>();
-    painter->fillRect(highlightBackgroundRect, QBrush(highlightBackground));
-
     // Highlight text
-    QRect resultHighlightRect(rect);
-    resultHighlightRect.setLeft(beforeHighlightRect.right());
-    resultHighlightRect.setRight(resultHighlightRect.left() + searchTermLengthPixels + textMargin);
     QStyleOptionViewItem highlightOpt = noHighlightOpt;
     const QColor highlightForeground =
             index.model()->data(index, ItemDataRoles::ResultHighlightForegroundColor).value<QColor>();
@@ -199,8 +218,6 @@ void SearchResultTreeItemDelegate::drawText(QPainter *painter,
                                text.mid(searchTermStart, searchTermLength));
 
     // Text after the Highlight
-    QRect afterHighlightRect(rect);
-    afterHighlightRect.setLeft(resultHighlightRect.right());
     noHighlightOpt.rect = afterHighlightRect;
     QItemDelegate::drawDisplay(painter, noHighlightOpt, afterHighlightRect,
                                text.mid(searchTermStart + searchTermLength));
diff --git a/src/plugins/find/searchresulttreeitemdelegate.h b/src/plugins/find/searchresulttreeitemdelegate.h
index d1659df148a..ecef3098355 100644
--- a/src/plugins/find/searchresulttreeitemdelegate.h
+++ b/src/plugins/find/searchresulttreeitemdelegate.h
@@ -43,7 +43,7 @@ public:
 
 private:
     int drawLineNumber(QPainter *painter, const QStyleOptionViewItemV3 &option, const QRect &rect, const QModelIndex &index) const;
-    void drawText(QPainter *painter, const QStyleOptionViewItem &opt,
+    void drawText(QPainter *painter, const QStyleOptionViewItem &option,
                            const QRect &rect, const QModelIndex &index) const;
 
     static const int m_minimumLineNumberDigits = 6;
-- 
GitLab