KTextEditor

katecompletionmodel.h
1/*
2 SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
3 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#ifndef KATECOMPLETIONMODEL_H
9#define KATECOMPLETIONMODEL_H
10
11#include <QAbstractProxyModel>
12#include <QList>
13#include <QPair>
14
15#include <ktexteditor/codecompletionmodel.h>
16
17#include "expandingtree/expandingwidgetmodel.h"
18#include <ktexteditor_export.h>
19
20#include <set>
21
23class KateArgumentHintModel;
24namespace KTextEditor
25{
26class ViewPrivate;
27}
28class QWidget;
29class QTextEdit;
30class QTimer;
31class HierarchicalModelHandler;
32
33/**
34 * This class has the responsibility for filtering, sorting, and manipulating
35 * code completion data provided by a CodeCompletionModel.
36 *
37 * @author Hamish Rodda <rodda@kde.org>
38 */
40{
42
43public:
44 enum InternalRole {
45 IsNonEmptyGroup = KTextEditor::CodeCompletionModel::LastExtraItemDataRole + 1,
46 };
47
49 ~KateCompletionModel() override;
50
51 QList<KTextEditor::CodeCompletionModel *> completionModels() const;
52 void clearCompletionModels();
53 KTEXTEDITOR_EXPORT void addCompletionModel(KTextEditor::CodeCompletionModel *model);
54 KTEXTEDITOR_EXPORT void setCompletionModel(KTextEditor::CodeCompletionModel *model);
55 void setCompletionModels(const QList<KTextEditor::CodeCompletionModel *> &models);
56 KTEXTEDITOR_EXPORT void removeCompletionModel(KTextEditor::CodeCompletionModel *model);
57
58 KTextEditor::ViewPrivate *view() const;
59 KateCompletionWidget *widget() const;
60
61 KTEXTEDITOR_EXPORT QString currentCompletion(KTextEditor::CodeCompletionModel *model) const;
62 void setCurrentCompletion(QMap<KTextEditor::CodeCompletionModel *, QString> currentMatch);
63
64 int translateColumn(int sourceColumn) const;
65
66 /// Returns a common prefix for all current visible completion entries
67 /// If there is no common prefix, extracts the next useful prefix for the selected index
68 QString commonPrefix(QModelIndex selectedIndex) const;
69
70 void rowSelected(const QModelIndex &row) const;
71
72 bool indexIsItem(const QModelIndex &index) const override;
73
74 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
75 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
76 Qt::ItemFlags flags(const QModelIndex &index) const override;
77 bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
78 virtual bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const;
79 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
80
81 // Disabled in case of bugs, reenable once fully debugged.
82 // virtual QMap<int, QVariant> itemData ( const QModelIndex & index ) const;
83 QModelIndex parent(const QModelIndex &index) const override;
84 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
85
86 /// Maps from this display-model into the appropriate source code-completion model
87 virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
88
89 /// Maps from an index in a source-model to the index of the item in this display-model
90 virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
91
92 enum gm {
93 ScopeType = 0x1,
94 Scope = 0x2,
95 AccessType = 0x4,
96 ItemType = 0x8
97 };
98
99 enum { // An own property that will be used to mark the best-matches group internally
100 BestMatchesProperty = 2 * KTextEditor::CodeCompletionModel::LastProperty
101 };
102
103 Q_DECLARE_FLAGS(GroupingMethods, gm)
104
105 static const int ScopeTypeMask = 0x380000;
106 static const int AccessTypeMask = 0x7;
107 static const int ItemTypeMask = 0xfe0;
108
109 void debugStats();
110
111 /// Returns whether one of the filtered items exactly matches its completion string
113
114 KTEXTEDITOR_EXPORT uint filteredItemCount() const;
115
116protected:
117 int contextMatchQuality(const QModelIndex &index) const override;
118
120 void expandIndex(const QModelIndex &index);
121 // Emitted whenever something has changed about the group of argument-hints
122 void argumentHintsChanged();
123
124private Q_SLOTS:
125 void slotRowsInserted(const QModelIndex &parent, int start, int end);
126 void slotRowsRemoved(const QModelIndex &parent, int start, int end);
127 void slotModelReset();
128
129 // Updates the best-matches group
130 void updateBestMatches();
131 // Makes sure that the ungrouped group contains each item only once
132 // Must only be called right after the group was created
133 void makeGroupItemsUnique(bool onlyFiltered = false);
134
135private:
136 typedef QPair<KTextEditor::CodeCompletionModel *, QModelIndex> ModelRow;
137 virtual int contextMatchQuality(const ModelRow &sourceRow) const;
138
139 QTreeView *treeView() const override;
140
141 friend class KateArgumentHintModel;
142 static ModelRow modelRowPair(const QModelIndex &index);
143
144 // Represents a source row; provides sorting method
145 class Item
146 {
147 public:
148 Item(bool doInitialMatch, KateCompletionModel *model, const HierarchicalModelHandler &handler, ModelRow sourceRow);
149
150 // Returns true if the item is not filtered and matches the current completion string
151 bool isVisible() const;
152
153 enum MatchType {
154 NoMatch = 0,
155 PerfectMatch,
156 StartsWithMatch,
157 AbbreviationMatch,
158 ContainsMatch
159 };
160 MatchType match(KateCompletionModel *model);
161
162 const ModelRow &sourceRow() const;
163
164 // Sorting operator
165 bool lessThan(KateCompletionModel *model, const Item &rhs) const;
166
167 bool haveExactMatch() const
168 {
169 return m_haveExactMatch;
170 }
171
172 QString name() const
173 {
174 return m_nameColumn;
175 }
176
177 private:
178 ModelRow m_sourceRow;
179
180 QString m_nameColumn;
181
182 int inheritanceDepth;
183
184 // True when currently matching completion string
185 MatchType matchCompletion;
186 bool m_haveExactMatch;
187 bool m_unimportant;
188 };
189
190public:
191 // Grouping and sorting of rows
192 class Group
193 {
194 public:
195 explicit Group(const QString &title, int attribute, KateCompletionModel *model);
196
197 void addItem(const Item &i, bool notifyModel = false);
198 /// Removes the item specified by \a row. Returns true if a change was made to rows.
199 bool removeItem(const ModelRow &row);
200 void resort();
201 void clear();
202 // Returns whether this group should be ordered before other
203 bool orderBefore(Group *other) const;
204 // Returns a number that can be used for ordering
205 int orderNumber() const;
206
207 /// Returns the row in the this group's filtered list of the given model-row in a source-model
208 ///-1 if the item is not in the filtered list
209 ///@todo Implement an efficient way of doing this map, that does _not_ iterate over all items!
210 int rowOf(const ModelRow &item)
211 {
212 for (int a = 0; a < (int)filtered.size(); ++a) {
213 if (filtered[a].sourceRow() == item) {
214 return a;
215 }
216 }
217 return -1;
218 }
219
220 KateCompletionModel *model;
221 int attribute;
222 QString title, scope;
223 std::vector<Item> filtered;
224 std::vector<Item> prefilter;
225 bool isEmpty;
226 //-1 if none was set
227 int customSortingKey;
228 };
229
230 typedef std::set<Group *> GroupSet;
231
232 bool hasGroups() const
233 {
234 // qCDebug(LOG_KTE) << "m_groupHash.size()"<<m_groupHash.size();
235 // qCDebug(LOG_KTE) << "m_rowTable.count()"<<m_rowTable.count();
236 return m_hasGroups;
237 }
238
239private:
240 QString commonPrefixInternal(const QString &forcePrefix) const;
241 /// @note performs model reset
242 void createGroups();
243 /// Creates all sub-items of index i, or the item corresponding to index i. Returns the affected groups.
244 /// i must be an index in the source model
245 GroupSet createItems(const HierarchicalModelHandler &, const QModelIndex &i, bool notifyModel = false);
246 /// Deletes all sub-items of index i, or the item corresponding to index i. Returns the affected groups.
247 /// i must be an index in the source model
248 GroupSet deleteItems(const QModelIndex &i);
249 Group *createItem(const HierarchicalModelHandler &, const QModelIndex &i, bool notifyModel = false);
250 /// @note Make sure you're in a {begin,end}ResetModel block when calling this!
251 void clearGroups();
252 void hideOrShowGroup(Group *g, bool notifyModel = false);
253 /// When forceGrouping is enabled, all given attributes will be used for grouping, regardless of the completion settings.
254 Group *fetchGroup(int attribute, bool forceGrouping = false);
255 // If this returns nonzero on an index, the index is the header of the returned group
256 Group *groupForIndex(const QModelIndex &index) const;
257 inline Group *groupOfParent(const QModelIndex &child) const
258 {
259 return static_cast<Group *>(child.internalPointer());
260 }
261 QModelIndex indexForRow(Group *g, int row) const;
262 QModelIndex indexForGroup(Group *g) const;
263
264 enum changeTypes {
265 Broaden,
266 Narrow,
267 Change
268 };
269
270 // Returns whether the model needs to be reset
271 void changeCompletions(Group *g);
272
273 bool hasCompletionModel() const;
274
275 /// Removes attributes not used in grouping from the input \a attribute
276 int groupingAttributes(int attribute) const;
277 static int countBits(int value);
278
279 void resort();
280
281 KTEXTEDITOR_EXPORT static bool matchesAbbreviation(const QString &word, const QString &typed, int &score);
282 // exported for completion_test
283
284 bool m_hasGroups = false;
285
286 // ### Runtime state
287 // General
290
291 // Column merging
292 const std::array<std::vector<int>, 3> m_columnMerges = {{
293 {0},
294 {1, 2, 3, 4},
295 {5},
296 }};
297
298 QTimer *m_updateBestMatchesTimer;
299
300 Group *m_ungrouped;
301 Group *m_argumentHints; // The argument-hints will be passed on to another model, to be shown in another widget
302 Group *m_bestMatches; // A temporary group used for holding the best matches of all visible items
303
304 // Storing the sorted order
305 std::vector<Group *> m_rowTable;
306 std::vector<Group *> m_emptyGroups;
307 // Quick access to each specific group (if it exists)
308 QMultiHash<int, Group *> m_groupHash;
309 // Maps custom group-names to their specific groups
310 QHash<QString, Group *> m_customGroupHash;
311
312 friend class CompletionTest;
313};
314
315Q_DECLARE_OPERATORS_FOR_FLAGS(KateCompletionModel::GroupingMethods)
316
317#endif
Cares about expanding/un-expanding items in a tree-view together with ExpandingDelegate.
An item model for providing code completion, and meta information for enhanced presentation.
This class has the responsibility for filtering, sorting, and manipulating code completion data provi...
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Does not request data from index, this only returns local data like highlighting for expanded rows an...
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
Maps from this display-model into the appropriate source code-completion model.
bool indexIsItem(const QModelIndex &index) const override
Should return true if the given row should be painted like a contained item(as opposed to label-rows ...
bool shouldMatchHideCompletionList() const
Returns whether one of the filtered items exactly matches its completion string.
QString commonPrefix(QModelIndex selectedIndex) const
Returns a common prefix for all current visible completion entries If there is no common prefix,...
int contextMatchQuality(const QModelIndex &index) const override
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
Maps from an index in a source-model to the index of the item in this display-model.
void rowSelected(const QModelIndex &row) const
This is the code completion's main widget, and also contains the core interface logic.
Q_SCRIPTABLE Q_NOREPLY void start()
The KTextEditor namespace contains all the public API that is required to use the KTextEditor compone...
void * internalPointer() const const
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
QObject * parent() const const
DisplayRole
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:11:26 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.