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

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