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