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.h>
30#include <QtWidgets/qcheckbox.h>
31#include <QtWidgets/qtreeview.h>
33#include <QtCore/qregularexpression.h>
39using namespace Qt::StringLiterals;
42
43
44
45
46
54
55
56
57
58
59
60
61
62
63
64
68 m_itemView->removeEventFilter(
this);
70 m_itemView = itemView;
73 m_itemView->installEventFilter(
this);
77
78
82 m_itemView->setFocus();
94 while (aa.parent() != QModelIndex()) {
104 while (ba.parent() != QModelIndex()) {
105 if (ba.parent() == a)
111 for (aa = a; aDepth > bDepth; aDepth--)
113 for (ba = b; aDepth < bDepth; bDepth--)
116 if (aa.parent() == ba.parent()) {
117 if (aa.row() < ba.row())
119 if (aa.row() > ba.row())
121 return aa.column() < ba.column();
124 while (aa.parent().parent() != ba.parent().parent()) {
129 if (aa.parent().row() < ba.parent().row())
131 if (aa.parent().row() > ba.parent().row())
136 return aa.parent().column() > ba.parent().column();
140
141
144 if (!m_itemView || !m_itemView->model()->hasChildren())
148 if (skipCurrent && m_itemView->selectionModel()->hasSelection()) {
149 QModelIndexList il = m_itemView->selectionModel()->selectedIndexes();
150 std::sort(il.begin(), il.end(), indexLessThan);
151 idx = backward ? il.first() : il.last();
153 idx = m_itemView->currentIndex();
157 QModelIndex newIdx = idx;
159 if (!ttf.isEmpty()) {
160 if (newIdx.isValid()) {
161 int column = newIdx.column();
163 if (QTreeView *tv = qobject_cast<QTreeView *>(m_itemView))
164 if (tv->allColumnsShowFocus())
165 column = backward ? 0 : m_itemView->model()->columnCount(newIdx.parent()) - 1;
166 newIdx = findHelper(ttf, skipCurrent, backward,
167 newIdx.parent(), newIdx.row(), column);
169 if (!newIdx.isValid()) {
170 int row = backward ? m_itemView->model()->rowCount() : 0;
171 int column = backward ? 0 : -1;
172 newIdx = findHelper(ttf,
true, backward, m_itemView->rootIndex(), row, column);
173 if (!newIdx.isValid()) {
185 m_itemView->setCurrentIndex(newIdx);
191static inline bool skipForward(
const QAbstractItemModel *model, QModelIndex &parent,
int &row,
int &column)
195 if (column < model->columnCount(parent))
198 while (--column >= 0) {
199 QModelIndex nIdx = model->index(row, column, parent);
200 if (nIdx.isValid()) {
201 if (model->hasChildren(nIdx)) {
209 if (++row < model->rowCount(parent))
211 if (!parent.isValid())
214 column = parent.column();
215 parent = parent.parent();
220static inline bool skipBackward(
const QAbstractItemModel *model, QModelIndex &parent,
int &row,
int &column)
225 if (!parent.isValid())
228 column = parent.column();
229 parent = parent.parent();
231 while (++column < model->columnCount(parent)) {
232 QModelIndex nIdx = model->index(row, column, parent);
233 if (nIdx.isValid()) {
234 if (model->hasChildren(nIdx)) {
235 row = model->rowCount(nIdx) - 1;
252QModelIndex
ItemViewFindWidget::findHelper(
const QString &textToFind,
bool skipCurrent,
bool backward,
253 QModelIndex parent,
int row,
int column)
255 const QAbstractItemModel *model = m_itemView->model();
259 if (!skipBackward(model, parent, row, column))
260 return QModelIndex();
262 if (!skipForward(model, parent, row, column))
263 return QModelIndex();
267 QModelIndex idx = model->index(row, column, parent);
269 Qt::CaseSensitivity cs = caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
272 QString rx =
"\\b"_L1 + QRegularExpression::escape(textToFind)
274 QRegularExpression re(rx);
275 if (cs == Qt::CaseInsensitive)
276 re.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
277 if (idx.data().toString().indexOf(re) >= 0)
280 if (idx.data().toString().indexOf(textToFind, 0, cs) >= 0)