1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCOMPLETER_P_H
5#define QCOMPLETER_P_H
6
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtWidgets/private/qtwidgetsglobal_p.h>
20#include "private/qobject_p.h"
21
22#include "QtWidgets/qabstractitemview.h"
23#include "QtCore/qabstractproxymodel.h"
24#include "QtCore/qmap.h"
25#include "qcompleter.h"
26#include "qstyleditemdelegate.h"
27#include "QtGui/qpainter.h"
28
29#include "private/qabstractproxymodel_p.h"
30#include <QtCore/qpointer.h>
31
32QT_REQUIRE_CONFIG(completer);
33
34QT_BEGIN_NAMESPACE
35
36class QCompletionModel;
37
38class QCompleterPrivate : public QObjectPrivate
39{
40 Q_DECLARE_PUBLIC(QCompleter)
41
42public:
43 QCompleterPrivate();
44 ~QCompleterPrivate() { delete popup; }
45 void init(QAbstractItemModel *model = nullptr);
46
47 QPointer<QWidget> widget;
48 QCompletionModel *proxy;
49 QAbstractItemView *popup;
50 QCompleter::CompletionMode mode;
51 Qt::MatchFlags filterMode;
52
53 QString prefix;
54 Qt::CaseSensitivity cs;
55 int role;
56 int column;
57 int maxVisibleItems;
58 QCompleter::ModelSorting sorting;
59 bool wrap;
60
61 bool eatFocusOut;
62 QRect popupRect;
63 bool hiddenBecauseNoMatch;
64
65 void showPopup(const QRect&);
66 void _q_complete(QModelIndex, bool = false);
67 void _q_completionSelected(const QItemSelection&);
68 void _q_autoResizePopup();
69 void _q_fileSystemModelDirectoryLoaded(const QString &path);
70 void setCurrentIndex(QModelIndex, bool = true);
71
72 static QCompleterPrivate *get(QCompleter *o) { return o->d_func(); }
73 static const QCompleterPrivate *get(const QCompleter *o) { return o->d_func(); }
74};
75
76class QIndexMapper
77{
78public:
79 QIndexMapper() : v(false), f(0), t(-1) { }
80 QIndexMapper(int f, int t) : v(false), f(f), t(t) { }
81 QIndexMapper(const QList<int> &vec) : v(true), vector(vec), f(-1), t(-1) { }
82
83 inline int count() const { return v ? vector.size() : t - f + 1; }
84 inline int operator[] (int index) const { return v ? vector[index] : f + index; }
85 inline int indexOf(int x) const { return v ? vector.indexOf(t: x) : ((t < f) ? -1 : x - f); }
86 inline bool isValid() const { return !isEmpty(); }
87 inline bool isEmpty() const { return v ? vector.isEmpty() : (t < f); }
88 inline void append(int x) { Q_ASSERT(v); vector.append(t: x); }
89 inline int first() const { return v ? vector.first() : f; }
90 inline int last() const { return v ? vector.last() : t; }
91 inline int from() const { Q_ASSERT(!v); return f; }
92 inline int to() const { Q_ASSERT(!v); return t; }
93 inline int cost() const { return vector.size()+2; }
94
95private:
96 bool v;
97 QList<int> vector;
98 int f, t;
99};
100
101struct QMatchData {
102 QMatchData() : exactMatchIndex(-1), partial(false) { }
103 QMatchData(const QIndexMapper& indices, int em, bool p) :
104 indices(indices), exactMatchIndex(em), partial(p) { }
105 QIndexMapper indices;
106 inline bool isValid() const { return indices.isValid(); }
107 int exactMatchIndex;
108 bool partial;
109};
110
111class QCompletionEngine
112{
113public:
114 typedef QMap<QString, QMatchData> CacheItem;
115 typedef QMap<QModelIndex, CacheItem> Cache;
116
117 QCompletionEngine(QCompleterPrivate *c) : c(c), curRow(-1), cost(0) { }
118 virtual ~QCompletionEngine() { }
119
120 void filter(const QStringList &parts);
121
122 QMatchData filterHistory();
123 bool matchHint(const QString &part, const QModelIndex &parent, QMatchData *m) const;
124
125 void saveInCache(QString, const QModelIndex&, const QMatchData&);
126 bool lookupCache(const QString &part, const QModelIndex &parent, QMatchData *m) const;
127
128 virtual void filterOnDemand(int) { }
129 virtual QMatchData filter(const QString&, const QModelIndex&, int) = 0;
130
131 int matchCount() const { return curMatch.indices.count() + historyMatch.indices.count(); }
132
133 QMatchData curMatch, historyMatch;
134 QCompleterPrivate *c;
135 QStringList curParts;
136 QModelIndex curParent;
137 int curRow;
138
139 Cache cache;
140 int cost;
141};
142
143class QSortedModelEngine : public QCompletionEngine
144{
145public:
146 QSortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
147 QMatchData filter(const QString&, const QModelIndex&, int) override;
148 QIndexMapper indexHint(QString, const QModelIndex&, Qt::SortOrder);
149 Qt::SortOrder sortOrder(const QModelIndex&) const;
150};
151
152class QUnsortedModelEngine : public QCompletionEngine
153{
154public:
155 QUnsortedModelEngine(QCompleterPrivate *c) : QCompletionEngine(c) { }
156
157 void filterOnDemand(int) override;
158 QMatchData filter(const QString&, const QModelIndex&, int) override;
159private:
160 int buildIndices(const QString& str, const QModelIndex& parent, int n,
161 const QIndexMapper& iv, QMatchData* m);
162};
163
164class QCompleterItemDelegate : public QStyledItemDelegate
165{
166public:
167 QCompleterItemDelegate(QAbstractItemView *view)
168 : QStyledItemDelegate(view), view(view) { }
169 void paint(QPainter *p, const QStyleOptionViewItem& opt, const QModelIndex& idx) const override {
170 QStyleOptionViewItem optCopy = opt;
171 optCopy.showDecorationSelected = true;
172 if (view->currentIndex() == idx)
173 optCopy.state |= QStyle::State_HasFocus;
174 QStyledItemDelegate::paint(painter: p, option: optCopy, index: idx);
175 }
176
177private:
178 QAbstractItemView *view;
179};
180
181class QCompletionModelPrivate;
182
183class QCompletionModel : public QAbstractProxyModel
184{
185 Q_OBJECT
186
187public:
188 QCompletionModel(QCompleterPrivate *c, QObject *parent);
189
190 void createEngine();
191 void setFiltered(bool);
192 void filter(const QStringList& parts);
193 int completionCount() const;
194 int currentRow() const { return engine->curRow; }
195 bool setCurrentRow(int row);
196 QModelIndex currentIndex(bool) const;
197
198 QModelIndex index(int row, int column, const QModelIndex & = QModelIndex()) const override;
199 int rowCount(const QModelIndex &index = QModelIndex()) const override;
200 int columnCount(const QModelIndex &index = QModelIndex()) const override;
201 bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
202 QModelIndex parent(const QModelIndex & = QModelIndex()) const override { return QModelIndex(); }
203 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
204
205 void setSourceModel(QAbstractItemModel *sourceModel) override;
206 QModelIndex mapToSource(const QModelIndex& proxyIndex) const override;
207 QModelIndex mapFromSource(const QModelIndex& sourceIndex) const override;
208
209 QCompleterPrivate *c;
210 QScopedPointer<QCompletionEngine> engine;
211 bool showAll;
212
213 Q_DECLARE_PRIVATE(QCompletionModel)
214
215signals:
216 void rowsAdded();
217
218public Q_SLOTS:
219 void invalidate();
220 void rowsInserted();
221 void modelDestroyed();
222};
223
224class QCompletionModelPrivate : public QAbstractProxyModelPrivate
225{
226 Q_DECLARE_PUBLIC(QCompletionModel)
227};
228
229QT_END_NAMESPACE
230
231#endif // QCOMPLETER_P_H
232

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/widgets/util/qcompleter_p.h