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 { ScopeType = 0x1, Scope = 0x2, AccessType = 0x4, ItemType = 0x8 };
93
94 enum { // An own property that will be used to mark the best-matches group internally
95 BestMatchesProperty = 2 * KTextEditor::CodeCompletionModel::LastProperty
96 };
97
98 Q_DECLARE_FLAGS(GroupingMethods, gm)
99
100 static const int ScopeTypeMask = 0x380000;
101 static const int AccessTypeMask = 0x7;
102 static const int ItemTypeMask = 0xfe0;
103
104 void debugStats();
105
106 /// Returns whether one of the filtered items exactly matches its completion string
108
109 KTEXTEDITOR_EXPORT uint filteredItemCount() const;
110
111protected:
112 int contextMatchQuality(const QModelIndex &index) const override;
113
115 void expandIndex(const QModelIndex &index);
116 // Emitted whenever something has changed about the group of argument-hints
117 void argumentHintsChanged();
118
119private Q_SLOTS:
120 void slotRowsInserted(const QModelIndex &parent, int start, int end);
121 void slotRowsRemoved(const QModelIndex &parent, int start, int end);
122 void slotModelReset();
123
124 // Updates the best-matches group
125 void updateBestMatches();
126 // Makes sure that the ungrouped group contains each item only once
127 // Must only be called right after the group was created
128 void makeGroupItemsUnique(bool onlyFiltered = false);
129
130private:
131 typedef QPair<KTextEditor::CodeCompletionModel *, QModelIndex> ModelRow;
132 virtual int contextMatchQuality(const ModelRow &sourceRow) const;
133
134 QTreeView *treeView() const override;
135
136 friend class KateArgumentHintModel;
137 static ModelRow modelRowPair(const QModelIndex &index);
138
139 // Represents a source row; provides sorting method
140 class Item
141 {
142 public:
143 Item(bool doInitialMatch, KateCompletionModel *model, const HierarchicalModelHandler &handler, ModelRow sourceRow);
144
145 // Returns true if the item is not filtered and matches the current completion string
146 bool isVisible() const;
147
148 enum MatchType { NoMatch = 0, PerfectMatch, StartsWithMatch, AbbreviationMatch, ContainsMatch };
149 MatchType match(KateCompletionModel *model);
150
151 const ModelRow &sourceRow() const;
152
153 // Sorting operator
154 bool lessThan(KateCompletionModel *model, const Item &rhs) const;
155
156 bool haveExactMatch() const
157 {
158 return m_haveExactMatch;
159 }
160
161 QString name() const
162 {
163 return m_nameColumn;
164 }
165
166 private:
167 ModelRow m_sourceRow;
168
169 QString m_nameColumn;
170
171 int inheritanceDepth;
172
173 // True when currently matching completion string
174 MatchType matchCompletion;
175 bool m_haveExactMatch;
176 bool m_unimportant;
177 };
178
179public:
180 // Grouping and sorting of rows
181 class Group
182 {
183 public:
184 explicit Group(const QString &title, int attribute, KateCompletionModel *model);
185
186 void addItem(const Item &i, bool notifyModel = false);
187 /// Removes the item specified by \a row. Returns true if a change was made to rows.
188 bool removeItem(const ModelRow &row);
189 void resort();
190 void clear();
191 // Returns whether this group should be ordered before other
192 bool orderBefore(Group *other) const;
193 // Returns a number that can be used for ordering
194 int orderNumber() const;
195
196 /// Returns the row in the this group's filtered list of the given model-row in a source-model
197 ///-1 if the item is not in the filtered list
198 ///@todo Implement an efficient way of doing this map, that does _not_ iterate over all items!
199 int rowOf(const ModelRow &item)
200 {
201 for (int a = 0; a < (int)filtered.size(); ++a) {
202 if (filtered[a].sourceRow() == item) {
203 return a;
204 }
205 }
206 return -1;
207 }
208
209 KateCompletionModel *model;
210 int attribute;
211 QString title, scope;
212 std::vector<Item> filtered;
213 std::vector<Item> prefilter;
214 bool isEmpty;
215 //-1 if none was set
216 int customSortingKey;
217 };
218
219 typedef std::set<Group *> GroupSet;
220
221 bool hasGroups() const
222 {
223 // qCDebug(LOG_KTE) << "m_groupHash.size()"<<m_groupHash.size();
224 // qCDebug(LOG_KTE) << "m_rowTable.count()"<<m_rowTable.count();
225 return m_hasGroups;
226 }
227
228private:
229 QString commonPrefixInternal(const QString &forcePrefix) const;
230 /// @note performs model reset
231 void createGroups();
232 /// Creates all sub-items of index i, or the item corresponding to index i. Returns the affected groups.
233 /// i must be an index in the source model
234 GroupSet createItems(const HierarchicalModelHandler &, const QModelIndex &i, bool notifyModel = false);
235 /// Deletes all sub-items of index i, or the item corresponding to index i. Returns the affected groups.
236 /// i must be an index in the source model
237 GroupSet deleteItems(const QModelIndex &i);
238 Group *createItem(const HierarchicalModelHandler &, const QModelIndex &i, bool notifyModel = false);
239 /// @note Make sure you're in a {begin,end}ResetModel block when calling this!
240 void clearGroups();
241 void hideOrShowGroup(Group *g, bool notifyModel = false);
242 /// When forceGrouping is enabled, all given attributes will be used for grouping, regardless of the completion settings.
243 Group *fetchGroup(int attribute, bool forceGrouping = false);
244 // If this returns nonzero on an index, the index is the header of the returned group
245 Group *groupForIndex(const QModelIndex &index) const;
246 inline Group *groupOfParent(const QModelIndex &child) const
247 {
248 return static_cast<Group *>(child.internalPointer());
249 }
250 QModelIndex indexForRow(Group *g, int row) const;
251 QModelIndex indexForGroup(Group *g) const;
252
253 enum changeTypes { Broaden, Narrow, Change };
254
255 // Returns whether the model needs to be reset
256 void changeCompletions(Group *g);
257
258 bool hasCompletionModel() const;
259
260 /// Removes attributes not used in grouping from the input \a attribute
261 int groupingAttributes(int attribute) const;
262 static int countBits(int value);
263
264 void resort();
265
266 KTEXTEDITOR_EXPORT static bool matchesAbbreviation(const QString &word, const QString &typed, int &score);
267 // exported for completion_test
268
269 bool m_hasGroups = false;
270
271 // ### Runtime state
272 // General
275
276 // Column merging
277 const std::array<std::vector<int>, 3> m_columnMerges = {{
278 {0},
279 {1, 2, 3, 4},
280 {5},
281 }};
282
283 QTimer *m_updateBestMatchesTimer;
284
285 Group *m_ungrouped;
286 Group *m_argumentHints; // The argument-hints will be passed on to another model, to be shown in another widget
287 Group *m_bestMatches; // A temporary group used for holding the best matches of all visible items
288
289 // Storing the sorted order
290 std::vector<Group *> m_rowTable;
291 std::vector<Group *> m_emptyGroups;
292 // Quick access to each specific group (if it exists)
293 QMultiHash<int, Group *> m_groupHash;
294 // Maps custom group-names to their specific groups
295 QHash<QString, Group *> m_customGroupHash;
296
297 friend class CompletionTest;
298};
299
300Q_DECLARE_OPERATORS_FOR_FLAGS(KateCompletionModel::GroupingMethods)
301
302#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 Tue Mar 26 2024 11:15:43 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.