1840
by Adam Reichold
Move the search item delegate into a separate module. |
1 |
/*
|
2 |
||
2073
by Adam Reichold
Fix highlighting of matched text when part of it is elided and silence unused argument warning. |
3 |
Copyright 2018 S. Razi Alavizadeh
|
1840
by Adam Reichold
Move the search item delegate into a separate module. |
4 |
Copyright 2015 Adam Reichold
|
5 |
||
6 |
This file is part of qpdfview.
|
|
7 |
||
8 |
qpdfview is free software: you can redistribute it and/or modify
|
|
9 |
it under the terms of the GNU General Public License as published by
|
|
10 |
the Free Software Foundation, either version 2 of the License, or
|
|
11 |
(at your option) any later version.
|
|
12 |
||
13 |
qpdfview is distributed in the hope that it will be useful,
|
|
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 |
GNU General Public License for more details.
|
|
17 |
||
18 |
You should have received a copy of the GNU General Public License
|
|
19 |
along with qpdfview. If not, see <http://www.gnu.org/licenses/>.
|
|
20 |
||
21 |
*/
|
|
22 |
||
23 |
#include "searchitemdelegate.h" |
|
24 |
||
25 |
#include <QApplication> |
|
26 |
#include <qmath.h> |
|
27 |
#include <QPainter> |
|
28 |
#include <QTextLayout> |
|
29 |
||
30 |
#include "searchmodel.h" |
|
31 |
||
32 |
namespace qpdfview |
|
33 |
{
|
|
34 |
||
35 |
SearchItemDelegate::SearchItemDelegate(QObject* parent) : QStyledItemDelegate(parent) |
|
36 |
{
|
|
37 |
}
|
|
38 |
||
39 |
void SearchItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const |
|
40 |
{
|
|
41 |
QStyledItemDelegate::paint(painter, option, index); |
|
42 |
||
2053
by Adam Reichold
Use a second column in the extend search results view to display the result count and the occurence page. |
43 |
if(index.column() != 0) |
44 |
{
|
|
45 |
return; |
|
46 |
}
|
|
47 |
||
1840
by Adam Reichold
Move the search item delegate into a separate module. |
48 |
const int progress = index.data(SearchModel::ProgressRole).toInt(); |
49 |
||
50 |
if(progress != 0) |
|
51 |
{
|
|
52 |
paintProgress(painter, option, progress); |
|
53 |
return; |
|
54 |
}
|
|
55 |
||
56 |
const QString matchedText = index.data(SearchModel::MatchedTextRole).toString(); |
|
57 |
const QString surroundingText = index.data(SearchModel::SurroundingTextRole).toString(); |
|
58 |
||
59 |
if(!matchedText.isEmpty() && !surroundingText.isEmpty()) |
|
60 |
{
|
|
61 |
paintText(painter, option, matchedText, surroundingText); |
|
62 |
return; |
|
63 |
}
|
|
64 |
}
|
|
65 |
||
66 |
void SearchItemDelegate::paintProgress(QPainter* painter, const QStyleOptionViewItem& option, |
|
67 |
int progress) const |
|
68 |
{
|
|
69 |
QRect highlightedRect = option.rect; |
|
70 |
highlightedRect.setWidth(progress * highlightedRect.width() / 100); |
|
71 |
||
72 |
painter->save(); |
|
73 |
||
74 |
painter->setCompositionMode(QPainter::CompositionMode_Multiply); |
|
75 |
painter->fillRect(highlightedRect, option.palette.highlight()); |
|
76 |
||
77 |
painter->restore(); |
|
78 |
}
|
|
79 |
||
80 |
void SearchItemDelegate::paintText(QPainter* painter, const QStyleOptionViewItem& option, |
|
81 |
const QString& matchedText, const QString& surroundingText) const |
|
82 |
{
|
|
83 |
const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; |
|
84 |
const QRect textRect = option.rect.adjusted(textMargin, 0, -textMargin, 0); |
|
85 |
const QString elidedText = option.fontMetrics.elidedText(surroundingText, option.textElideMode, textRect.width()); |
|
86 |
||
87 |
QTextOption textOption; |
|
88 |
textOption.setWrapMode(QTextOption::NoWrap); |
|
89 |
textOption.setTextDirection(elidedText.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight); |
|
90 |
textOption.setAlignment(QStyle::visualAlignment(textOption.textDirection(), option.displayAlignment)); |
|
91 |
||
92 |
QTextLayout textLayout; |
|
93 |
textLayout.setTextOption(textOption); |
|
94 |
textLayout.setText(elidedText); |
|
95 |
textLayout.setFont(option.font); |
|
96 |
||
97 |
QFont font = textLayout.font(); |
|
98 |
font.setWeight(QFont::Light); |
|
99 |
textLayout.setFont(font); |
|
100 |
||
101 |
||
102 |
QList< QTextLayout::FormatRange > additionalFormats; |
|
103 |
||
2073
by Adam Reichold
Fix highlighting of matched text when part of it is elided and silence unused argument warning. |
104 |
for(int index = 0; (index = surroundingText.indexOf(matchedText, index)) != -1; index += matchedText.length()) |
1840
by Adam Reichold
Move the search item delegate into a separate module. |
105 |
{
|
106 |
QTextLayout::FormatRange formatRange; |
|
107 |
formatRange.start = index; |
|
108 |
formatRange.length = matchedText.length(); |
|
109 |
formatRange.format.setFontWeight(QFont::Bold); |
|
110 |
||
111 |
additionalFormats.append(formatRange); |
|
112 |
}
|
|
113 |
||
114 |
textLayout.setAdditionalFormats(additionalFormats); |
|
115 |
||
116 |
||
117 |
textLayout.beginLayout(); |
|
118 |
||
119 |
QTextLine textLine = textLayout.createLine(); |
|
120 |
||
121 |
if(!textLine.isValid()) |
|
122 |
{
|
|
123 |
return; |
|
124 |
}
|
|
125 |
||
126 |
textLine.setLineWidth(textRect.width()); |
|
127 |
||
128 |
textLayout.endLayout(); |
|
129 |
||
130 |
||
131 |
const QSize layoutSize(textRect.width(), qFloor(textLine.height())); |
|
132 |
const QRect layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment, layoutSize, textRect); |
|
133 |
||
134 |
painter->save(); |
|
135 |
||
136 |
painter->setClipping(true); |
|
137 |
painter->setClipRect(layoutRect); |
|
138 |
||
139 |
textLine.draw(painter, layoutRect.topLeft()); |
|
140 |
||
141 |
painter->restore(); |
|
142 |
}
|
|
143 |
||
144 |
} // qpdfview |