File indexing completed on 2024-04-21 03:57:22

0001 /*
0002     SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
0003     SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
0004     SPDX-FileCopyrightText: 2022-2024 Waqar Ahmed <waqar.17a@gmail.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef KATECOMPLETIONWIDGET_H
0010 #define KATECOMPLETIONWIDGET_H
0011 
0012 #include <QFrame>
0013 #include <QObject>
0014 #include <QPointer>
0015 
0016 #include <ktexteditor_export.h>
0017 
0018 #include <ktexteditor/codecompletionmodel.h>
0019 #include <ktexteditor/movingrange.h>
0020 
0021 class QToolButton;
0022 class QPushButton;
0023 class QLabel;
0024 class QTimer;
0025 
0026 namespace KTextEditor
0027 {
0028 class ViewPrivate;
0029 }
0030 class DocTip;
0031 class KateCompletionModel;
0032 class KateCompletionTree;
0033 class KateArgumentHintTree;
0034 class KateArgumentHintModel;
0035 class ArgumentHintWidget;
0036 
0037 /**
0038  * This is the code completion's main widget, and also contains the
0039  * core interface logic.
0040  *
0041  * @author Hamish Rodda <rodda@kde.org>
0042  */
0043 class KTEXTEDITOR_EXPORT KateCompletionWidget : public QFrame
0044 {
0045     Q_OBJECT
0046 
0047 public:
0048     explicit KateCompletionWidget(KTextEditor::ViewPrivate *parent);
0049     ~KateCompletionWidget() override;
0050 
0051     KTextEditor::ViewPrivate *view() const;
0052     KateCompletionTree *treeView() const;
0053 
0054     bool isCompletionActive() const;
0055     void startCompletion(KTextEditor::CodeCompletionModel::InvocationType invocationType,
0056                          const QList<KTextEditor::CodeCompletionModel *> &models = QList<KTextEditor::CodeCompletionModel *>());
0057     void startCompletion(KTextEditor::Range word,
0058                          KTextEditor::CodeCompletionModel *model,
0059                          KTextEditor::CodeCompletionModel::InvocationType invocationType = KTextEditor::CodeCompletionModel::ManualInvocation);
0060     void startCompletion(KTextEditor::Range word,
0061                          const QList<KTextEditor::CodeCompletionModel *> &models = QList<KTextEditor::CodeCompletionModel *>(),
0062                          KTextEditor::CodeCompletionModel::InvocationType invocationType = KTextEditor::CodeCompletionModel::ManualInvocation);
0063     void userInvokedCompletion();
0064 
0065 public Q_SLOTS:
0066     // Executed when return is pressed while completion is active.
0067     bool execute();
0068     void cursorDown();
0069     void cursorUp();
0070 
0071 public:
0072     enum Direction {
0073         Down,
0074         Up,
0075     };
0076 
0077     void tabCompletion(Direction direction = Down);
0078 
0079     void toggleDocumentation();
0080 
0081     const KateCompletionModel *model() const;
0082     KateCompletionModel *model();
0083 
0084     void registerCompletionModel(KTextEditor::CodeCompletionModel *model);
0085     void unregisterCompletionModel(KTextEditor::CodeCompletionModel *model);
0086     bool isCompletionModelRegistered(KTextEditor::CodeCompletionModel *model) const;
0087     QList<KTextEditor::CodeCompletionModel *> codeCompletionModels() const;
0088 
0089     int automaticInvocationDelay() const;
0090     void setAutomaticInvocationDelay(int delay);
0091 
0092     void setIgnoreBufferSignals(bool ignore) const;
0093 
0094     bool m_ignoreBufferSignals = false;
0095 
0096     struct CompletionRange {
0097         CompletionRange()
0098         {
0099         }
0100         explicit CompletionRange(KTextEditor::MovingRange *r)
0101             : range(r)
0102         {
0103         }
0104 
0105         bool operator==(const CompletionRange &rhs) const
0106         {
0107             return range->toRange() == rhs.range->toRange();
0108         }
0109 
0110         KTextEditor::MovingRange *range = nullptr;
0111         // Whenever the cursor goes before this position, the completion is stopped, unless it is invalid.
0112         KTextEditor::Cursor leftBoundary;
0113     };
0114 
0115     KTextEditor::MovingRange *completionRange(KTextEditor::CodeCompletionModel *model = nullptr) const;
0116     QMap<KTextEditor::CodeCompletionModel *, CompletionRange> completionRanges() const;
0117 
0118     // Navigation
0119     void pageDown();
0120     void pageUp();
0121     void top();
0122     void bottom();
0123 
0124     QWidget *currentEmbeddedWidget();
0125 
0126     void updatePosition(bool force = false);
0127     bool eventFilter(QObject *watched, QEvent *event) override;
0128 
0129     KateArgumentHintModel *argumentHintModel() const;
0130 
0131     /// Called by KateViewInternal, because we need the specific information from the event.
0132 
0133     void updateHeight();
0134 
0135     void showDocTip(const QModelIndex &idx);
0136     DocTip *docTip() const
0137     {
0138         return m_docTip;
0139     }
0140 
0141 public Q_SLOTS:
0142     void waitForModelReset();
0143 
0144     void abortCompletion();
0145     void automaticInvocation();
0146 
0147     /*    void updateFocus();*/
0148     void argumentHintsChanged(bool hasContent);
0149 
0150     bool navigateUp();
0151     bool navigateDown();
0152     bool navigateLeft();
0153     bool navigateRight();
0154     bool navigateAccept();
0155     bool navigateBack();
0156 
0157 protected:
0158     void showEvent(QShowEvent *event) override;
0159     void resizeEvent(QResizeEvent *event) override;
0160     void moveEvent(QMoveEvent *event) override;
0161     void focusOutEvent(QFocusEvent *event) override;
0162 
0163 private Q_SLOTS:
0164     void completionModelReset();
0165     void modelDestroyed(QObject *model);
0166     void modelContentChanged();
0167     void cursorPositionChanged();
0168     void modelReset();
0169     void rowsInserted(const QModelIndex &parent, int row, int rowEnd);
0170     void viewFocusOut();
0171 
0172     void wrapLine(KTextEditor::Document *document, KTextEditor::Cursor position);
0173     void unwrapLine(KTextEditor::Document *, int line);
0174     void insertText(KTextEditor::Document *, KTextEditor::Cursor position, const QString &text);
0175     void removeText(KTextEditor::Document *, KTextEditor::Range range, const QString &);
0176 
0177 private:
0178     KTEXTEDITOR_NO_EXPORT
0179     void updateAndShow();
0180     KTEXTEDITOR_NO_EXPORT
0181     void updateArgumentHintGeometry();
0182     KTEXTEDITOR_NO_EXPORT
0183     QModelIndex selectedIndex() const;
0184 
0185     KTEXTEDITOR_NO_EXPORT
0186     void clear();
0187 
0188     KTEXTEDITOR_NO_EXPORT
0189     void completionRangeChanged(KTextEditor::CodeCompletionModel *, const KTextEditor::Range &word);
0190 
0191     KTEXTEDITOR_NO_EXPORT
0192     QString tailString() const;
0193 
0194     KTEXTEDITOR_NO_EXPORT
0195     void deleteCompletionRanges();
0196 
0197 private:
0198     QList<KTextEditor::CodeCompletionModel *> m_sourceModels;
0199     KateCompletionModel *m_presentationModel;
0200 
0201     QMap<KTextEditor::CodeCompletionModel *, CompletionRange> m_completionRanges;
0202     QSet<KTextEditor::CodeCompletionModel *> m_waitingForReset;
0203 
0204     KTextEditor::Cursor m_lastCursorPosition;
0205 
0206     KTextEditor::ViewPrivate *m_view;
0207     KateCompletionTree *m_entryList;
0208     KateArgumentHintModel *m_argumentHintModel;
0209     // KateArgumentHintTree *m_argumentHintTree;
0210     ArgumentHintWidget *m_argumentHintWidget;
0211     DocTip *m_docTip;
0212 
0213     QTimer *m_automaticInvocationTimer;
0214 
0215     KTextEditor::Cursor m_automaticInvocationAt;
0216     QString m_automaticInvocationLine;
0217     int m_automaticInvocationDelay;
0218 
0219     bool m_lastInsertionByUser;
0220     bool m_isSuspended;
0221     bool m_dontShowArgumentHints; // Used temporarily to prevent flashing
0222     bool m_needShow;
0223 
0224     bool m_hadCompletionNavigation;
0225 
0226     bool m_haveExactMatch;
0227 
0228     bool m_noAutoHide;
0229 
0230     /**
0231      * is a completion edit ongoing?
0232      */
0233     bool m_completionEditRunning;
0234 
0235     int m_expandedAddedHeightBase;
0236 
0237     KTextEditor::CodeCompletionModel::InvocationType m_lastInvocationType;
0238 };
0239 
0240 #endif