searchresulttreeitemdelegate.cpp 6.77 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2 3 4
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11 12 13 14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18 19 20 21 22 23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30 31 32 33 34 35 36 37
#include "searchresulttreeitemdelegate.h"
#include "searchresulttreeitemroles.h"

#include <QModelIndex>
#include <QTextDocument>
#include <QPainter>
#include <QAbstractTextDocumentLayout>
#include <QApplication>
Roberto Raggi's avatar
Roberto Raggi committed
38
#include <QDebug>
con's avatar
con committed
39

hjk's avatar
hjk committed
40 41
#include <math.h>

con's avatar
con committed
42 43 44
using namespace Find::Internal;

SearchResultTreeItemDelegate::SearchResultTreeItemDelegate(QObject *parent)
hjk's avatar
hjk committed
45
  : QItemDelegate(parent)
con's avatar
con committed
46 47 48 49 50
{
}

void SearchResultTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
51
    painter->save();
con's avatar
con committed
52

53 54
    QStyleOptionViewItemV3 opt = setOptions(index, option);
    painter->setFont(opt.font);
con's avatar
con committed
55

56
    QItemDelegate::drawBackground(painter, opt, index);
con's avatar
con committed
57

58 59
    int iconAreaWidth = drawIcon(painter, opt, opt.rect, index);
    QRect resultRowRect(opt.rect.adjusted(iconAreaWidth, 0, 0, 0));
con's avatar
con committed
60

61 62
    int lineNumberAreaWidth = drawLineNumber(painter, opt, resultRowRect, index);
    resultRowRect.adjust(lineNumberAreaWidth, 0, 0, 0);
con's avatar
con committed
63

64 65
    QString displayString = index.model()->data(index, Qt::DisplayRole).toString();
    drawMarker(painter, index, displayString, resultRowRect);
con's avatar
con committed
66

67 68 69 70 71 72 73 74 75 76
    // Show number of subresults in displayString
    if (index.model()->hasChildren(index)) {
        displayString += QString::fromLatin1(" (")
                         + QString::number(index.model()->rowCount(index))
                         + QLatin1Char(')');
    }

    // Draw the text and focus/selection
    QItemDelegate::drawDisplay(painter, opt, resultRowRect, displayString);
    QItemDelegate::drawFocus(painter, opt, opt.rect);
Roberto Raggi's avatar
Roberto Raggi committed
77

78 79 80 81 82
    QVariant value = index.data(Qt::CheckStateRole);
    if (value.isValid()) {
        Qt::CheckState checkState = Qt::Unchecked;
        checkState = static_cast<Qt::CheckState>(value.toInt());
        QRect checkRect = check(opt, opt.rect, value);
Roberto Raggi's avatar
Roberto Raggi committed
83

84 85
        QRect emptyRect;
        doLayout(opt, &checkRect, &emptyRect, &emptyRect, false);
Roberto Raggi's avatar
Roberto Raggi committed
86

87
        QItemDelegate::drawCheck(painter, opt, checkRect, checkState);
con's avatar
con committed
88
    }
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

    painter->restore();
}

int SearchResultTreeItemDelegate::drawIcon(QPainter *painter, const QStyleOptionViewItemV3 &option,
                                                 const QRect &rect,
                                                 const QModelIndex &index) const
{
    static const int iconWidth = 16;
    static const int iconPadding = 4;
    QIcon icon = index.model()->data(index, ItemDataRoles::ResultIconRole).value<QIcon>();
    if (icon.isNull())
        return 0;
    QRect iconRect = rect.adjusted(iconPadding, 0, /*is set below anyhow*/0, 0);
    iconRect.setWidth(iconWidth);
    QItemDelegate::drawDecoration(painter, option, iconRect, icon.pixmap(iconWidth));
    return iconWidth + iconPadding;
con's avatar
con committed
106 107 108
}

int SearchResultTreeItemDelegate::drawLineNumber(QPainter *painter, const QStyleOptionViewItemV3 &option,
109
                                                 const QRect &rect,
110
                                                 const QModelIndex &index) const
con's avatar
con committed
111 112 113
{
    static const int lineNumberAreaHorizontalPadding = 4;
    int lineNumber = index.model()->data(index, ItemDataRoles::ResultLineNumberRole).toInt();
114 115 116
    if (lineNumber < 1)
        return 0;
    const bool isSelected = option.state & QStyle::State_Selected;
con's avatar
con committed
117 118
    int lineNumberDigits = (int)floor(log10((double)lineNumber)) + 1;
    int minimumLineNumberDigits = qMax((int)m_minimumLineNumberDigits, lineNumberDigits);
119
    int fontWidth = painter->fontMetrics().width(QString(minimumLineNumberDigits, QLatin1Char('0')));
con's avatar
con committed
120
    int lineNumberAreaWidth = lineNumberAreaHorizontalPadding + fontWidth + lineNumberAreaHorizontalPadding;
121
    QRect lineNumberAreaRect(rect);
con's avatar
con committed
122 123 124 125 126 127 128 129
    lineNumberAreaRect.setWidth(lineNumberAreaWidth);

    QPalette::ColorGroup cg = QPalette::Normal;
    if (!(option.state & QStyle::State_Active))
        cg = QPalette::Inactive;
    else if (!(option.state & QStyle::State_Enabled))
        cg = QPalette::Disabled;

130
    painter->fillRect(lineNumberAreaRect, QBrush(isSelected ?
131 132
        option.palette.brush(cg, QPalette::Highlight) :
        option.palette.color(cg, QPalette::Base).darker(111)));
133 134 135 136 137 138 139 140 141 142

    QStyleOptionViewItemV3 opt = option;
    opt.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
    opt.palette.setColor(cg, QPalette::Text, Qt::darkGray);

    const QStyle *style = QApplication::style();
    const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, 0) + 1;

    const QRect rowRect = lineNumberAreaRect.adjusted(-textMargin, 0, textMargin-lineNumberAreaHorizontalPadding, 0);
    QItemDelegate::drawDisplay(painter, opt, rowRect, QString::number(lineNumber));
con's avatar
con committed
143 144 145 146 147

    return lineNumberAreaWidth;
}

void SearchResultTreeItemDelegate::drawMarker(QPainter *painter, const QModelIndex &index, const QString text,
148
                                              const QRect &rect) const
con's avatar
con committed
149 150 151
{
    int searchTermStart = index.model()->data(index, ItemDataRoles::SearchTermStartRole).toInt();
    int searchTermLength = index.model()->data(index, ItemDataRoles::SearchTermLengthRole).toInt();
152 153 154 155
    if (searchTermStart < 0 || searchTermLength < 1)
        return;
    const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
    int searchTermStartPixels = painter->fontMetrics().width(text.left(searchTermStart));
con's avatar
con committed
156 157 158 159 160 161
    int searchTermLengthPixels = painter->fontMetrics().width(text.mid(searchTermStart, searchTermLength));
    QRect resultHighlightRect(rect);
    resultHighlightRect.setLeft(resultHighlightRect.left() + searchTermStartPixels + textMargin - 1); // -1: Cosmetics
    resultHighlightRect.setRight(resultHighlightRect.left() + searchTermLengthPixels + 1); // +1: Cosmetics
    painter->fillRect(resultHighlightRect, QBrush(qRgb(255, 240, 120)));
}