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