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 SPDX-FileCopyrightText: 2022-2024 Waqar Ahmed <waqar.17a@gmail.com>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#ifndef KATECOMPLETIONWIDGET_H
10#define KATECOMPLETIONWIDGET_H
11
12#include <QElapsedTimer>
13#include <QFrame>
14#include <QObject>
15#include <QPointer>
16
17#include <ktexteditor_export.h>
18
19#include <ktexteditor/codecompletionmodel.h>
20#include <ktexteditor/movingrange.h>
21
22class QToolButton;
23class QPushButton;
24class QLabel;
25class QTimer;
26
27namespace KTextEditor
28{
29class ViewPrivate;
30}
31class DocTip;
32class KateCompletionModel;
33class KateCompletionTree;
34class KateArgumentHintTree;
35class KateArgumentHintModel;
36class ArgumentHintWidget;
37
38/**
39 * This is the code completion's main widget, and also contains the
40 * core interface logic.
41 *
42 * @author Hamish Rodda <rodda@kde.org>
43 */
44class KTEXTEDITOR_EXPORT KateCompletionWidget : public QFrame
45{
46 Q_OBJECT
47
48public:
49 explicit KateCompletionWidget(KTextEditor::ViewPrivate *parent);
50 ~KateCompletionWidget() override;
51
52 KTextEditor::ViewPrivate *view() const;
53 KateCompletionTree *treeView() const;
54
55 bool isCompletionActive() const;
56 void startCompletion(KTextEditor::CodeCompletionModel::InvocationType invocationType,
57 const QList<KTextEditor::CodeCompletionModel *> &models = QList<KTextEditor::CodeCompletionModel *>());
58 void startCompletion(KTextEditor::Range word,
59 KTextEditor::CodeCompletionModel *model,
60 KTextEditor::CodeCompletionModel::InvocationType invocationType = KTextEditor::CodeCompletionModel::ManualInvocation);
61 void startCompletion(KTextEditor::Range word,
62 const QList<KTextEditor::CodeCompletionModel *> &models = QList<KTextEditor::CodeCompletionModel *>(),
63 KTextEditor::CodeCompletionModel::InvocationType invocationType = KTextEditor::CodeCompletionModel::ManualInvocation);
64 void userInvokedCompletion();
65
66public Q_SLOTS:
67 // Executed when return is pressed while completion is active.
68 bool execute();
69 void cursorDown();
70 void cursorUp();
71
72public:
73 enum Direction {
74 Down,
75 Up,
76 };
77
78 void tabCompletion(Direction direction = Down);
79
80 void toggleDocumentation();
81
82 const KateCompletionModel *model() const;
83 KateCompletionModel *model();
84
85 void registerCompletionModel(KTextEditor::CodeCompletionModel *model);
86 void unregisterCompletionModel(KTextEditor::CodeCompletionModel *model);
87 bool isCompletionModelRegistered(KTextEditor::CodeCompletionModel *model) const;
88 QList<KTextEditor::CodeCompletionModel *> codeCompletionModels() const;
89
90 int automaticInvocationDelay() const;
91 void setAutomaticInvocationDelay(int delay);
92
93 void setIgnoreBufferSignals(bool ignore) const;
94
95 bool m_ignoreBufferSignals = false;
96
97 struct CompletionRange {
98 CompletionRange()
99 {
100 }
101 explicit CompletionRange(KTextEditor::MovingRange *r)
102 : range(r)
103 {
104 }
105
106 bool operator==(const CompletionRange &rhs) const
107 {
108 return range->toRange() == rhs.range->toRange();
109 }
110
111 KTextEditor::MovingRange *range = nullptr;
112 // Whenever the cursor goes before this position, the completion is stopped, unless it is invalid.
113 KTextEditor::Cursor leftBoundary;
114 };
115
116 KTextEditor::MovingRange *completionRange(KTextEditor::CodeCompletionModel *model = nullptr) const;
117 QMap<KTextEditor::CodeCompletionModel *, CompletionRange> completionRanges() const;
118
119 // Navigation
120 void pageDown();
121 void pageUp();
122 void top();
123 void bottom();
124
125 QWidget *currentEmbeddedWidget();
126
127 void updatePosition(bool force = false);
128 bool eventFilter(QObject *watched, QEvent *event) override;
129
130 KateArgumentHintModel *argumentHintModel() const;
131
132 /// Called by KateViewInternal, because we need the specific information from the event.
133
134 void updateHeight();
135
136 void showDocTip(const QModelIndex &idx);
137 DocTip *docTip() const
138 {
139 return m_docTip;
140 }
141
142 bool handleShortcutOverride(QKeyEvent *e);
143
144 int elapsedMSSinceShowing()
145 {
146 return m_timeSinceShowing.elapsed();
147 }
148
149 static constexpr int minRequiredMsToAcceptCompletion()
150 {
151 return 200;
152 }
153
154public Q_SLOTS:
155 void waitForModelReset();
156
157 void abortCompletion();
158 void automaticInvocation();
159
160 /* void updateFocus();*/
161 void argumentHintsChanged(bool hasContent);
162
163 bool navigateUp();
164 bool navigateDown();
165 bool navigateLeft();
166 bool navigateRight();
167 bool navigateAccept();
168 bool navigateBack();
169
170protected:
171 void showEvent(QShowEvent *event) override;
172 void resizeEvent(QResizeEvent *event) override;
173 void moveEvent(QMoveEvent *event) override;
174 void focusOutEvent(QFocusEvent *event) override;
175
176private Q_SLOTS:
177 void completionModelReset();
178 void modelDestroyed(QObject *model);
179 void modelContentChanged();
180 void cursorPositionChanged();
181 void modelReset();
182 void rowsInserted(const QModelIndex &parent, int row, int rowEnd);
183 void viewFocusOut();
184
185 void wrapLine(KTextEditor::Document *document, KTextEditor::Cursor position);
186 void unwrapLine(KTextEditor::Document *, int line);
187 void insertText(KTextEditor::Document *, KTextEditor::Cursor position, const QString &text);
188 void removeText(KTextEditor::Document *, KTextEditor::Range range, const QString &);
189
190private:
191 KTEXTEDITOR_NO_EXPORT
192 void updateAndShow();
193 KTEXTEDITOR_NO_EXPORT
194 void updateArgumentHintGeometry();
195 KTEXTEDITOR_NO_EXPORT
196 QModelIndex selectedIndex() const;
197
198 KTEXTEDITOR_NO_EXPORT
199 void clear();
200
201 KTEXTEDITOR_NO_EXPORT
202 void completionRangeChanged(KTextEditor::CodeCompletionModel *, const KTextEditor::Range &word);
203
204 KTEXTEDITOR_NO_EXPORT
205 QString tailString() const;
206
207 KTEXTEDITOR_NO_EXPORT
208 void deleteCompletionRanges();
209
210 KTEXTEDITOR_NO_EXPORT
211 void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList<int> &roles = QList<int>());
212
213private:
214 QList<KTextEditor::CodeCompletionModel *> m_sourceModels;
215 KateCompletionModel *m_presentationModel;
216
217 QMap<KTextEditor::CodeCompletionModel *, CompletionRange> m_completionRanges;
218 QSet<KTextEditor::CodeCompletionModel *> m_waitingForReset;
219
220 KTextEditor::Cursor m_lastCursorPosition;
221
222 KTextEditor::ViewPrivate *m_view;
223 KateCompletionTree *m_entryList;
224 KateArgumentHintModel *m_argumentHintModel;
225 // KateArgumentHintTree *m_argumentHintTree;
226 ArgumentHintWidget *m_argumentHintWidget;
227 DocTip *m_docTip;
228
229 QTimer *m_automaticInvocationTimer;
230
231 KTextEditor::Cursor m_automaticInvocationAt;
232 QString m_automaticInvocationLine;
233 int m_automaticInvocationDelay;
234
235 bool m_lastInsertionByUser;
236 bool m_isSuspended;
237 bool m_dontShowArgumentHints; // Used temporarily to prevent flashing
238 bool m_needShow;
239
240 bool m_hadCompletionNavigation;
241
242 bool m_haveExactMatch;
243
244 bool m_noAutoHide;
245
246 /**
247 * is a completion edit ongoing?
248 */
249 bool m_completionEditRunning;
250
251 int m_expandedAddedHeightBase;
252
253 KTextEditor::CodeCompletionModel::InvocationType m_lastInvocationType;
254
255 QElapsedTimer m_timeSinceShowing;
256};
257
258#endif
259

source code of ktexteditor/src/completion/katecompletionwidget.h