-
Notifications
You must be signed in to change notification settings - Fork 6
/
searchhighlighter.cpp
142 lines (122 loc) · 3.97 KB
/
searchhighlighter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* \file
* <!--
* Copyright 2015 Develer S.r.l. (http://www.develer.com/)
* -->
*
* \brief cutecom-ng search result highlighter implementation
*
* \author Aurelien Rainone <aurelien@develer.com>
*/
#include "searchhighlighter.h"
SearchHighlighter::SearchHighlighter(QTextDocument *parent, bool has_cursor_) :
QSyntaxHighlighter(parent),
has_cursor(has_cursor_),
_num_occurences(0),
_occurence_cursor(0),
last_cursor_pos(0)
{
}
void SearchHighlighter::setSearchString(const QString &search)
{
// reset all before highlight loop
_search_string = search;
_occurence_cursor = _num_occurences = 0;
search_string_changed = true;
rehighlight();
if (has_cursor)
{
if (search_string_changed && _num_occurences > 0)
{
// last highlight loop, we didn't mark nothing because the cursor
// should be positioned before the previous position
// so now we rest it and redo the loop
last_cursor_pos = 0;
setSearchString(search);
}
if (search.isEmpty())
emit totalOccurencesChanged(-1);
else
emit totalOccurencesChanged(_num_occurences);
}
}
void SearchHighlighter::highlightBlock(const QString &text)
{
const int block_position = currentBlock().position();
// highlighted text background color (search results)
static const Qt::GlobalColor SEARCHRESULT_BACKCOL = Qt::yellow;
// highlighted text background color (search results)
static const Qt::GlobalColor CURSOR_SEARCHRESULT_BACKCOL = Qt::red;
if (_search_string.isEmpty() || text.isEmpty())
return;
QTextCharFormat charFormat;
const int length = _search_string.length();
int index = text.indexOf(_search_string, 0, Qt::CaseInsensitive);
while (index >= 0)
{
charFormat.setBackground(SEARCHRESULT_BACKCOL);
if (has_cursor)
{
if (search_string_changed)
{
if (block_position + index >= last_cursor_pos)
{
// if search_string just changed, _occurence_cursor has been invalidated
// because it is bound to a specific search string
// however last_cursor_pos records the position
// so now we highlight the first search result we find
last_cursor_pos = block_position + index;
_occurence_cursor = _num_occurences;
charFormat.setBackground(CURSOR_SEARCHRESULT_BACKCOL);
search_string_changed = false;
emit cursorPosChanged(block_position + index);
}
}
else if (_num_occurences == _occurence_cursor)
{
// record position of this occurence
last_cursor_pos = block_position + index;
charFormat.setBackground(CURSOR_SEARCHRESULT_BACKCOL);
emit cursorPosChanged(block_position + index);
}
}
setFormat(index, length, charFormat);
index = text.indexOf(_search_string, index + length, Qt::CaseInsensitive);
++_num_occurences;
}
}
void SearchHighlighter::previousOccurence()
{
// nothing to do if the string-search returned nothing
if (!_search_string.isEmpty())
{
// cyclic behaviour
if (_occurence_cursor == 0)
_occurence_cursor = _num_occurences - 1;
else
--_occurence_cursor;
_num_occurences = 0;
rehighlight();
}
}
void SearchHighlighter::nextOccurence()
{
if (!_search_string.isEmpty())
{
// cyclic behaviour
if (_occurence_cursor == _num_occurences - 1)
_occurence_cursor = 0;
else
++_occurence_cursor;
_num_occurences = 0;
rehighlight();
}
}
int SearchHighlighter::cursorOccurence() const
{
return _occurence_cursor;
}
int SearchHighlighter::totalOccurences() const
{
return _num_occurences;
}