File indexing completed on 2024-04-28 04:38:22

0001 /*
0002     SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KDEVPLATFORM_PLUGIN_CONTEXTBROWSERPLUGIN_H
0008 #define KDEVPLATFORM_PLUGIN_CONTEXTBROWSERPLUGIN_H
0009 
0010 #include <QVariant>
0011 #include <QSet>
0012 #include <QMap>
0013 #include <QList>
0014 #include <QUrl>
0015 #include <QPointer>
0016 
0017 #include <KTextEditor/TextHintInterface>
0018 #include <interfaces/iplugin.h>
0019 #include <language/duchain/duchainpointer.h>
0020 #include <language/duchain/declaration.h>
0021 #include <language/duchain/indexedducontext.h>
0022 #include <language/duchain/problem.h>
0023 #include <language/editor/persistentmovingrange.h>
0024 #include <language/interfaces/iquickopen.h>
0025 #include <language/editor/documentcursor.h>
0026 
0027 #include <language/interfaces/icontextbrowser.h>
0028 
0029 class QHBoxLayout;
0030 class QMenu;
0031 class QToolButton;
0032 
0033 namespace Sublime {
0034 class MainWindow;
0035 }
0036 
0037 namespace KDevelop {
0038 class IDocument;
0039 class DUContext;
0040 class TopDUContext;
0041 class ReferencedTopDUContext;
0042 class DUChainBase;
0043 class AbstractNavigationWidget;
0044 }
0045 
0046 namespace KTextEditor {
0047 class Document;
0048 class View;
0049 }
0050 
0051 class ContextBrowserViewFactory;
0052 class ContextBrowserView;
0053 class ContextBrowserPlugin;
0054 class BrowseManager;
0055 
0056 class ContextBrowserHintProvider
0057     : public KTextEditor::TextHintProvider
0058 {
0059 public:
0060     explicit ContextBrowserHintProvider(ContextBrowserPlugin* plugin);
0061     QString textHint(KTextEditor::View* view, const KTextEditor::Cursor& position) override;
0062 
0063 private:
0064     ContextBrowserPlugin* m_plugin;
0065 };
0066 
0067 QWidget* masterWidget(QWidget* w);
0068 
0069 struct ViewHighlights
0070 {
0071     ViewHighlights() : keep(false)
0072     {
0073     }
0074     // Whether the same highlighting should be kept highlighted (usually during typing)
0075     bool keep;
0076     // The declaration that is highlighted for this view
0077     KDevelop::IndexedDeclaration declaration;
0078     // Highlighted ranges. Those may also be contained by different views.
0079     QList<KDevelop::PersistentMovingRange::Ptr> highlights;
0080 };
0081 
0082 class ContextBrowserPlugin
0083     : public KDevelop::IPlugin
0084     , public KDevelop::IContextBrowser
0085 {
0086     Q_OBJECT
0087     Q_INTERFACES(KDevelop::IContextBrowser)
0088 
0089 public:
0090     explicit ContextBrowserPlugin(QObject* parent, const QVariantList& = QVariantList());
0091     ~ContextBrowserPlugin() override;
0092 
0093     void unload() override;
0094 
0095     void registerToolView(ContextBrowserView* view);
0096     void unRegisterToolView(ContextBrowserView* view);
0097 
0098     KDevelop::ContextMenuExtension contextMenuExtension(KDevelop::Context* context, QWidget* parent) override;
0099 
0100     KXMLGUIClient* createGUIForMainWindow(Sublime::MainWindow* window) override;
0101 
0102     ///duchain must be locked
0103     ///@param force When this is true, the history-entry is added, no matter whether the context is "interesting" or not
0104     void updateHistory(KDevelop::DUContext* context, const KTextEditor::Cursor& cursorPosition,
0105                        bool force = false);
0106 
0107     void updateDeclarationListBox(KDevelop::DUContext* context);
0108 
0109     void showUses(const KDevelop::DeclarationPointer& declaration) override;
0110 
0111     KTextEditor::Attribute::Ptr highlightedUseAttribute() const;
0112     KTextEditor::Attribute::Ptr highlightedSpecialObjectAttribute() const;
0113 
0114 public Q_SLOTS:
0115     void showUsesDelayed(const KDevelop::DeclarationPointer& declaration);
0116     void previousContextShortcut();
0117     void nextContextShortcut();
0118 
0119     void startDelayedBrowsing(KTextEditor::View* view);
0120     void stopDelayedBrowsing();
0121     void invokeAction(int index);
0122 
0123     void previousUseShortcut();
0124     void nextUseShortcut();
0125 
0126     void declarationSelectedInUI(const KDevelop::DeclarationPointer& decl);
0127 
0128     void updateReady(const KDevelop::IndexedString& url, const KDevelop::ReferencedTopDUContext& topContext);
0129     void textDocumentCreated(KDevelop::IDocument* document);
0130     void documentActivated(KDevelop::IDocument*);
0131     void viewDestroyed(QObject* obj);
0132     void cursorPositionChanged(KTextEditor::View* view, const KTextEditor::Cursor& newPosition);
0133     void viewCreated(KTextEditor::Document*, KTextEditor::View*);
0134     void updateViews();
0135 
0136     void hideToolTip();
0137     void findUses();
0138 
0139     void textInserted(KTextEditor::Document* doc, const KTextEditor::Cursor& cursor, const QString& text);
0140     void selectionChanged(KTextEditor::View*);
0141 
0142     void historyNext();
0143     void historyPrevious();
0144 
0145     void colorSetupChanged();
0146 
0147 private Q_SLOTS:
0148     // history browsing
0149     void documentJumpPerformed(KDevelop::IDocument* newDocument,
0150                                const KTextEditor::Cursor& newCursor,
0151                                KDevelop::IDocument* previousDocument,
0152                                const KTextEditor::Cursor& previousCursor);
0153 
0154     void nextMenuAboutToShow();
0155     void previousMenuAboutToShow();
0156     void actionTriggered();
0157 
0158     void navigateLeft();
0159     void navigateRight();
0160     void navigateUp();
0161     void navigateDown();
0162     void navigateAccept();
0163     void navigateBack();
0164 
0165 private:
0166     QWidget* toolbarWidgetForMainWindow(Sublime::MainWindow* window);
0167     void createActionsForMainWindow(Sublime::MainWindow* window, QString& xmlFile,
0168                                     KActionCollection& actions) override;
0169     QWidget* navigationWidgetForPosition(KTextEditor::View* view, KTextEditor::Cursor position,
0170                                          KTextEditor::Range& itemRange);
0171     void switchUse(bool forward);
0172     void clearMouseHover();
0173 
0174     void addHighlight(KTextEditor::View* view, KDevelop::Declaration* decl);
0175 
0176     /** helper for updateBrowserView().
0177      *  Tries to find a 'specialLanguageObject' (eg macro) in @p view under cursor @c.
0178      *  If found returns true and sets @p pickedLanguage to the language this object belongs to */
0179     KDevelop::Declaration* findDeclaration(KTextEditor::View* view, const KTextEditor::Cursor&, bool mouseHighlight);
0180     void updateForView(KTextEditor::View* view);
0181 
0182     // history browsing
0183     bool isPreviousEntry(KDevelop::DUContext*, const KTextEditor::Cursor& cursor) const;
0184     QString actionTextFor(int historyIndex) const;
0185     void updateButtonState();
0186     void openDocument(int historyIndex);
0187     void fillHistoryPopup(QMenu* menu, const QList<int>& historyIndices);
0188 
0189     enum NavigationActionType {
0190         Accept,
0191         Back,
0192         Down,
0193         Up,
0194         Left,
0195         Right
0196     };
0197     void doNavigate(NavigationActionType action);
0198 
0199 private:
0200 
0201     // Returns the currently active and visible context browser view that belongs
0202     // to the same context (mainwindow and area) as the given widget
0203     ContextBrowserView* browserViewForWidget(QWidget* widget) const;
0204 
0205     void showToolTip(KTextEditor::View* view, KTextEditor::Cursor position);
0206     QTimer* m_updateTimer;
0207 
0208     //Contains the range, the old attribute, and the attribute it was replaced with
0209     QSet<KTextEditor::View*> m_updateViews;
0210     QMap<KTextEditor::View*, ViewHighlights> m_highlightedRanges;
0211 
0212     //Holds a list of all active context browser tool views
0213     QList<ContextBrowserView*> m_views;
0214 
0215     QVector<KTextEditor::View*> m_textHintProvidedViews;
0216 
0217     //Used to override the next declaration that will be highlighted
0218     KDevelop::IndexedDeclaration m_useDeclaration;
0219     KDevelop::IndexedDeclaration m_lastHighlightedDeclaration;
0220 
0221     QUrl m_mouseHoverDocument;
0222     KTextEditor::Cursor m_mouseHoverCursor;
0223     ContextBrowserViewFactory* m_viewFactory;
0224     QPointer<QWidget> m_currentToolTip;
0225     QPointer<QWidget> m_currentNavigationWidget;
0226     KDevelop::IndexedDeclaration m_currentToolTipDeclaration;
0227     QVector<KDevelop::IProblem::Ptr> m_currentToolTipProblems;
0228     QAction* m_findUses;
0229 
0230     QPointer<KTextEditor::Document> m_lastInsertionDocument;
0231     KTextEditor::Cursor m_lastInsertionPos;
0232 
0233     // outline toolbar
0234     QPointer<QLineEdit> m_outlineLine;
0235     QPointer<QHBoxLayout> m_toolbarWidgetLayout;
0236     QPointer<QWidget> m_toolbarWidget;
0237 
0238     // history browsing
0239     struct HistoryEntry
0240     {
0241         //Duchain must be locked
0242         explicit HistoryEntry(
0243             KDevelop::IndexedDUContext ctx = KDevelop::IndexedDUContext(),
0244             const KTextEditor::Cursor& cursorPosition = KTextEditor::Cursor());
0245         explicit HistoryEntry(const KDevelop::DocumentCursor& pos);
0246         //Duchain must be locked
0247         void setCursorPosition(const KTextEditor::Cursor& cursorPosition);
0248 
0249         //Duchain does not need to be locked
0250         KDevelop::DocumentCursor computePosition() const;
0251 
0252         KDevelop::IndexedDUContext context;
0253         KDevelop::DocumentCursor absoluteCursorPosition;
0254         KTextEditor::Cursor relativeCursorPosition; //Cursor position relative to the start line of the context
0255         QString alternativeString;
0256     };
0257 
0258     QVector<HistoryEntry> m_history;
0259     QPointer<QToolButton> m_previousButton;
0260     QPointer<QToolButton> m_nextButton;
0261     QPointer<QMenu> m_previousMenu, m_nextMenu;
0262     QList<KDevelop::IndexedDeclaration> m_listDeclarations;
0263     KDevelop::IndexedString m_listUrl;
0264     BrowseManager* m_browseManager;
0265     //Used to not record jumps triggered by the context-browser as history entries
0266     QPointer<QWidget> m_focusBackWidget;
0267     int m_nextHistoryIndex;
0268 
0269     mutable KTextEditor::Attribute::Ptr m_highlightAttribute;
0270 
0271     friend class ContextBrowserHintProvider;
0272     ContextBrowserHintProvider m_textHintProvider;
0273 };
0274 
0275 #endif // KDEVPLATFORM_PLUGIN_CONTEXTBROWSERPLUGIN_H