5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
29#include <QtWidgets/QAbstractItemView>
30#include <QtWidgets/QCheckBox>
31#include <QtWidgets/QTreeView>
32#include <QtCore/QRegularExpression>
38using namespace Qt::StringLiterals;
41
42
43
44
45
53
54
55
56
57
58
59
60
61
62
63
67 m_itemView->removeEventFilter(
this);
69 m_itemView = itemView;
72 m_itemView->installEventFilter(
this);
76
77
81 m_itemView->setFocus();
93 while (aa.parent() != QModelIndex()) {
103 while (ba.parent() != QModelIndex()) {
104 if (ba.parent() == a)
110 for (aa = a; aDepth > bDepth; aDepth--)
112 for (ba = b; aDepth < bDepth; bDepth--)
115 if (aa.parent() == ba.parent()) {
116 if (aa.row() < ba.row())
118 if (aa.row() > ba.row())
120 return aa.column() < ba.column();
123 while (aa.parent().parent() != ba.parent().parent()) {
128 if (aa.parent().row() < ba.parent().row())
130 if (aa.parent().row() > ba.parent().row())
135 return aa.parent().column() > ba.parent().column();
139
140
143 if (!m_itemView || !m_itemView->model()->hasChildren())
147 if (skipCurrent && m_itemView->selectionModel()->hasSelection()) {
148 QModelIndexList il = m_itemView->selectionModel()->selectedIndexes();
149 std::sort(il.begin(), il.end(), indexLessThan);
150 idx = backward ? il.first() : il.last();
152 idx = m_itemView->currentIndex();
156 QModelIndex newIdx = idx;
158 if (!ttf.isEmpty()) {
159 if (newIdx.isValid()) {
160 int column = newIdx.column();
162 if (QTreeView *tv = qobject_cast<QTreeView *>(m_itemView))
163 if (tv->allColumnsShowFocus())
164 column = backward ? 0 : m_itemView->model()->columnCount(newIdx.parent()) - 1;
165 newIdx = findHelper(ttf, skipCurrent, backward,
166 newIdx.parent(), newIdx.row(), column);
168 if (!newIdx.isValid()) {
169 int row = backward ? m_itemView->model()->rowCount() : 0;
170 int column = backward ? 0 : -1;
171 newIdx = findHelper(ttf,
true, backward, m_itemView->rootIndex(), row, column);
172 if (!newIdx.isValid()) {
184 m_itemView->setCurrentIndex(newIdx);
190static inline bool skipForward(
const QAbstractItemModel *model, QModelIndex &parent,
int &row,
int &column)
194 if (column < model->columnCount(parent))
197 while (--column >= 0) {
198 QModelIndex nIdx = model->index(row, column, parent);
199 if (nIdx.isValid()) {
200 if (model->hasChildren(nIdx)) {
208 if (++row < model->rowCount(parent))
210 if (!parent.isValid())
213 column = parent.column();
214 parent = parent.parent();
219static inline bool skipBackward(
const QAbstractItemModel *model, QModelIndex &parent,
int &row,
int &column)
224 if (!parent.isValid())
227 column = parent.column();
228 parent = parent.parent();
230 while (++column < model->columnCount(parent)) {
231 QModelIndex nIdx = model->index(row, column, parent);
232 if (nIdx.isValid()) {
233 if (model->hasChildren(nIdx)) {
234 row = model->rowCount(nIdx) - 1;
251QModelIndex
ItemViewFindWidget::findHelper(
const QString &textToFind,
bool skipCurrent,
bool backward,
252 QModelIndex parent,
int row,
int column)
254 const QAbstractItemModel *model = m_itemView->model();
258 if (!skipBackward(model, parent, row, column))
259 return QModelIndex();
261 if (!skipForward(model, parent, row, column))
262 return QModelIndex();
266 QModelIndex idx = model->index(row, column, parent);
268 Qt::CaseSensitivity cs = caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
271 QString rx =
"\\b"_L1 + QRegularExpression::escape(textToFind)
273 QRegularExpression re(rx);
274 if (cs == Qt::CaseInsensitive)
275 re.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
276 if (idx.data().toString().indexOf(re) >= 0)
279 if (idx.data().toString().indexOf(textToFind, 0, cs) >= 0)