6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
30#include <QtWidgets/qabstractitemview.h>
31#include <QtWidgets/qcheckbox.h>
32#include <QtWidgets/qtreeview.h>
34#include <QtCore/qregularexpression.h>
40using namespace Qt::StringLiterals;
43
44
45
46
47
55
56
57
58
59
60
61
62
63
64
65
69 m_itemView->removeEventFilter(
this);
71 m_itemView = itemView;
74 m_itemView->installEventFilter(
this);
78
79
83 m_itemView->setFocus();
95 while (aa.parent() != QModelIndex()) {
105 while (ba.parent() != QModelIndex()) {
106 if (ba.parent() == a)
112 for (aa = a; aDepth > bDepth; aDepth--)
114 for (ba = b; aDepth < bDepth; bDepth--)
117 if (aa.parent() == ba.parent()) {
118 if (aa.row() < ba.row())
120 if (aa.row() > ba.row())
122 return aa.column() < ba.column();
125 while (aa.parent().parent() != ba.parent().parent()) {
130 if (aa.parent().row() < ba.parent().row())
132 if (aa.parent().row() > ba.parent().row())
137 return aa.parent().column() > ba.parent().column();
141
142
145 if (!m_itemView || !m_itemView->model()->hasChildren())
149 if (skipCurrent && m_itemView->selectionModel()->hasSelection()) {
150 QModelIndexList il = m_itemView->selectionModel()->selectedIndexes();
151 std::sort(il.begin(), il.end(), indexLessThan);
152 idx = backward ? il.first() : il.last();
154 idx = m_itemView->currentIndex();
158 QModelIndex newIdx = idx;
160 if (!ttf.isEmpty()) {
161 if (newIdx.isValid()) {
162 int column = newIdx.column();
164 if (QTreeView *tv = qobject_cast<QTreeView *>(m_itemView))
165 if (tv->allColumnsShowFocus())
166 column = backward ? 0 : m_itemView->model()->columnCount(newIdx.parent()) - 1;
167 newIdx = findHelper(ttf, skipCurrent, backward,
168 newIdx.parent(), newIdx.row(), column);
170 if (!newIdx.isValid()) {
171 int row = backward ? m_itemView->model()->rowCount() : 0;
172 int column = backward ? 0 : -1;
173 newIdx = findHelper(ttf,
true, backward, m_itemView->rootIndex(), row, column);
174 if (!newIdx.isValid()) {
186 m_itemView->setCurrentIndex(newIdx);
192static inline bool skipForward(
const QAbstractItemModel *model, QModelIndex &parent,
int &row,
int &column)
196 if (column < model->columnCount(parent))
199 while (--column >= 0) {
200 QModelIndex nIdx = model->index(row, column, parent);
201 if (nIdx.isValid()) {
202 if (model->hasChildren(nIdx)) {
210 if (++row < model->rowCount(parent))
212 if (!parent.isValid())
215 column = parent.column();
216 parent = parent.parent();
221static inline bool skipBackward(
const QAbstractItemModel *model, QModelIndex &parent,
int &row,
int &column)
226 if (!parent.isValid())
229 column = parent.column();
230 parent = parent.parent();
232 while (++column < model->columnCount(parent)) {
233 QModelIndex nIdx = model->index(row, column, parent);
234 if (nIdx.isValid()) {
235 if (model->hasChildren(nIdx)) {
236 row = model->rowCount(nIdx) - 1;
253QModelIndex
ItemViewFindWidget::findHelper(
const QString &textToFind,
bool skipCurrent,
bool backward,
254 QModelIndex parent,
int row,
int column)
256 const QAbstractItemModel *model = m_itemView->model();
260 if (!skipBackward(model, parent, row, column))
261 return QModelIndex();
263 if (!skipForward(model, parent, row, column))
264 return QModelIndex();
268 QModelIndex idx = model->index(row, column, parent);
270 Qt::CaseSensitivity cs = caseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive;
273 QString rx =
"\\b"_L1 + QRegularExpression::escape(textToFind)
275 QRegularExpression re(rx);
276 if (cs == Qt::CaseInsensitive)
277 re.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
278 if (idx.data().toString().indexOf(re) >= 0)
281 if (idx.data().toString().indexOf(textToFind, 0, cs) >= 0)