File indexing completed on 2024-05-12 15:45:40

0001 /*
0002     SPDX-FileCopyrightText: 2013 Christoph Cullmann <cullmann@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef KTEXTEDITOR_MAINWINDOW_H
0008 #define KTEXTEDITOR_MAINWINDOW_H
0009 
0010 #include <ktexteditor_export.h>
0011 
0012 #include <QObject>
0013 
0014 class QEvent;
0015 class QIcon;
0016 class QUrl;
0017 class QWidget;
0018 
0019 class KXMLGUIFactory;
0020 
0021 namespace KTextEditor
0022 {
0023 class Plugin;
0024 class Document;
0025 class View;
0026 
0027 /**
0028  * \class MainWindow mainwindow.h <KTextEditor/MainWindow>
0029  *
0030  * This class allows the application that embeds the KTextEditor component to
0031  * allow it to access parts of its main window.
0032  *
0033  * For example the component can get a place to show view bar widgets (e.g. search&replace, goto line, ...).
0034  * This is useful to e.g. have one place inside the window to show such stuff even if the application allows
0035  * the user to have multiple split views available per window.
0036  *
0037  * The application must pass a pointer to the MainWindow object to the createView method on view creation
0038  * and ensure that this main window stays valid for the complete lifetime of the view.
0039  *
0040  * It must not reimplement this class but construct an instance and pass a pointer to a QObject that
0041  * has the required slots to receive the requests.
0042  */
0043 class KTEXTEDITOR_EXPORT MainWindow : public QObject
0044 {
0045     Q_OBJECT
0046 
0047 public:
0048     /**
0049      * Construct an MainWindow wrapper object.
0050      * The passed parent is both the parent of this QObject and the receiver of all interface
0051      * calls via invokeMethod.
0052      * @param parent object the calls are relayed to
0053      */
0054     MainWindow(QObject *parent);
0055 
0056     /**
0057      * Virtual Destructor
0058      */
0059     ~MainWindow() override;
0060 
0061     //
0062     // Accessors to some window properties and contents
0063     //
0064 public:
0065     /**
0066      * Get the toplevel widget.
0067      * \return the real main window widget, nullptr if not available
0068      */
0069     QWidget *window();
0070 
0071     /**
0072      * Accessor to the XMLGUIFactory.
0073      * \return the mainwindow's KXMLGUIFactory, nullptr if not available
0074      */
0075     KXMLGUIFactory *guiFactory();
0076 
0077     //
0078     // Signals related to the main window
0079     //
0080 Q_SIGNALS:
0081     /**
0082      * This signal is emitted for every unhandled ShortcutOverride in the window
0083      * @param e responsible event
0084      */
0085     void unhandledShortcutOverride(QEvent *e);
0086 
0087     //
0088     // View access and manipulation interface
0089     //
0090 public:
0091     /**
0092      * Get a list of all views for this main window.
0093      *
0094      * It is beneficial if the list is sorted by most recently used,
0095      * as the library will e.g. try to use the most recent used url() by walking over this
0096      * list for save and other such things.
0097      *
0098      * @return all views, might be empty!
0099      */
0100     QList<KTextEditor::View *> views();
0101 
0102     /**
0103      * Access the active view.
0104      * \return active view, nullptr if not available
0105      */
0106     KTextEditor::View *activeView();
0107 
0108     /**
0109      * Activate the view with the corresponding \p document.
0110      * If none exist for this document, create one
0111      * \param document the document
0112      * \return activated view of this document,
0113      *         return nullptr if not possible
0114      */
0115     KTextEditor::View *activateView(KTextEditor::Document *document);
0116 
0117     /**
0118      * Open the document \p url with the given \p encoding.
0119      * \param url the document's url
0120      * \param encoding the preferred encoding. If encoding is QString() the
0121      *        encoding will be guessed or the default encoding will be used.
0122      * \return a pointer to the created view for the new document, if a document
0123      *         with this url is already existing, its view will be activated,
0124      *         return nullptr if not possible
0125      */
0126     KTextEditor::View *openUrl(const QUrl &url, const QString &encoding = QString());
0127 
0128     /**
0129      * Close selected view
0130      * \param view the view
0131      * \return true if view was closed
0132      */
0133     bool closeView(KTextEditor::View *view);
0134 
0135     /**
0136      * Split current view space according to \p orientation
0137      * \param orientation in which line split the view
0138      */
0139     void splitView(Qt::Orientation orientation);
0140 
0141     /**
0142      * Close the split view that contains the given view.
0143      * \param view the view.
0144      * \return true if the split view was closed.
0145      */
0146     bool closeSplitView(KTextEditor::View *view);
0147 
0148     /**
0149      * \returns \c true if the given views \p view1 and \p view2 share
0150      * the same split view, false otherwise.
0151      */
0152     bool viewsInSameSplitView(KTextEditor::View *view1, KTextEditor::View *view2);
0153 
0154     //
0155     // Signals related to view handling
0156     //
0157 Q_SIGNALS:
0158     /**
0159      * This signal is emitted whenever the active view changes.
0160      * @param view new active view
0161      */
0162     void viewChanged(KTextEditor::View *view);
0163 
0164     /**
0165      * This signal is emitted whenever a new view is created
0166      * @param view view that was created
0167      */
0168     void viewCreated(KTextEditor::View *view);
0169 
0170     //
0171     // Interface to allow view bars to be constructed in a central place per window
0172     //
0173 public:
0174     /**
0175      * Try to create a view bar for the given view.
0176      * @param view view for which we want an view bar
0177      * @return suitable widget that can host view bars widgets or nullptr
0178      */
0179     QWidget *createViewBar(KTextEditor::View *view);
0180 
0181     /**
0182      * Delete the view bar for the given view.
0183      * @param view view for which we want an view bar
0184      */
0185     void deleteViewBar(KTextEditor::View *view);
0186 
0187     /**
0188      * Add a widget to the view bar.
0189      * @param view view for which the view bar is used
0190      * @param bar bar widget, shall have the viewBarParent() as parent widget
0191      */
0192     void addWidgetToViewBar(KTextEditor::View *view, QWidget *bar);
0193 
0194     /**
0195      * Show the view bar for the given view
0196      * @param view view for which the view bar is used
0197      */
0198     void showViewBar(KTextEditor::View *view);
0199 
0200     /**
0201      * Hide the view bar for the given view
0202      * @param view view for which the view bar is used
0203      */
0204     void hideViewBar(KTextEditor::View *view);
0205 
0206     //
0207     // ToolView stuff, here all stuff belong which allows to
0208     // add/remove and manipulate the toolview of this main windows
0209     //
0210 public:
0211     /**
0212      * Toolview position.
0213      * A toolview can only be at one side at a time.
0214      */
0215     enum ToolViewPosition {
0216         Left = 0, /**< Left side. */
0217         Right = 1, /**< Right side. */
0218         Top = 2, /**< Top side. */
0219         Bottom = 3 /**< Bottom side. */
0220     };
0221 
0222     /**
0223      * Create a new toolview with unique \p identifier at side \p pos
0224      * with \p icon and caption \p text. Use the returned widget to embedd
0225      * your widgets.
0226      * \param plugin which owns this tool view
0227      * \param identifier unique identifier for this toolview
0228      * \param pos position for the toolview, if we are in session restore,
0229      *        this is only a preference
0230      * \param icon icon to use in the sidebar for the toolview
0231      * \param text translated text (i18n()) to use in addition to icon
0232      * \return created toolview on success, otherwise NULL
0233      */
0234     QWidget *createToolView(KTextEditor::Plugin *plugin,
0235                             const QString &identifier,
0236                             KTextEditor::MainWindow::ToolViewPosition pos,
0237                             const QIcon &icon,
0238                             const QString &text);
0239 
0240     /**
0241      * Move the toolview \p widget to position \p pos.
0242      * \param widget the toolview to move, where the widget was constructed
0243      *        by createToolView().
0244      * \param pos new position to move widget to
0245      * \return \e true on success, otherwise \e false
0246      */
0247     bool moveToolView(QWidget *widget, KTextEditor::MainWindow::ToolViewPosition pos);
0248 
0249     /**
0250      * Show the toolview \p widget.
0251      * \param widget the toolview to show, where the widget was constructed
0252      *        by createToolView().
0253      * \return \e true on success, otherwise \e false
0254      * \todo add focus parameter: bool showToolView (QWidget *widget, bool giveFocus );
0255      */
0256     bool showToolView(QWidget *widget);
0257 
0258     /**
0259      * Hide the toolview \p widget.
0260      * \param widget the toolview to hide, where the widget was constructed
0261      *        by createToolView().
0262      * \return \e true on success, otherwise \e false
0263      */
0264     bool hideToolView(QWidget *widget);
0265 
0266     //
0267     // Application plugin accessors
0268     //
0269 public:
0270     /**
0271      * Shows the @p plugin's config page. The @p page specifies which
0272      * config page will be shown, see KTextEditor::Plugin::configPages().
0273      *
0274      * \return \e true on success, otherwise \e false
0275      * \since 5.63
0276      */
0277     bool showPluginConfigPage(KTextEditor::Plugin *plugin, int page);
0278 
0279     /**
0280      * Get a plugin view for the plugin with with identifier \p name.
0281      * \param name the plugin's name
0282      * \return pointer to the plugin view if a plugin with \p name is loaded and has a view for this mainwindow,
0283      *         otherwise NULL
0284      */
0285     QObject *pluginView(const QString &name);
0286 
0287     //
0288     // Signals related to application plugins
0289     //
0290 Q_SIGNALS:
0291     /**
0292      * This signal is emitted when the view of some Plugin is created for this main window.
0293      *
0294      * @param name name of plugin
0295      * @param pluginView the new plugin view
0296      */
0297     void pluginViewCreated(const QString &name, QObject *pluginView);
0298 
0299     /**
0300      * This signal is emitted when the view of some Plugin got deleted.
0301      *
0302      * @warning Do not access the data referenced by the pointer, it is already invalid.
0303      * Use the pointer only to remove mappings in hash or maps
0304      *
0305      * @param name name of plugin
0306      * @param pluginView the deleted plugin view
0307      */
0308     void pluginViewDeleted(const QString &name, QObject *pluginView);
0309 
0310     //
0311     // Custom widget handling
0312     //
0313 public:
0314     /**
0315      * Add a widget to the main window.
0316      * This is useful to show non-KTextEditor::View widgets in the main window.
0317      * The host application should try to manage this like some KTextEditor::View (e.g. as a tab) and provide
0318      * the means to close it.
0319      * \param widget widget to add
0320      * \return success, if false, the plugin needs to take care to show the widget itself, otherwise
0321      *         the main window will take ownership of the widget
0322      * \since 5.98
0323      */
0324     bool addWidget(QWidget *widget);
0325 
0326     //
0327     // Message output
0328     //
0329 public:
0330     /**
0331      * Display a message to the user.
0332      * The host application might show this inside a dedicated output view.
0333      *
0334      * \param message incoming message we shall handle
0335      * \return true, if the host application was able to handle the message, else false
0336      * \since 5.98
0337      *
0338      * details of message format:
0339      *
0340      * message text, will be trimmed before output
0341      *
0342      *    message["text"] = i18n("your cool message")
0343      *
0344      * the text will be split in lines, all lines beside the first can be collapsed away
0345      *
0346      * message type, we support at the moment
0347      *
0348      *    message["type"] = "Error"
0349      *    message["type"] = "Warning"
0350      *    message["type"] = "Info"
0351      *    message["type"] = "Log"
0352      *
0353      * this is take from https://microsoft.github.io/language-server-protocol/specification#window_showMessage MessageType of LSP
0354      *
0355      * will lead to appropriate icons/... in the output view
0356      *
0357      * a message should have some category, like Git, LSP, ....
0358      *
0359      *    message["category"] = i18n(...)
0360      *
0361      * will be used to allow the user to filter for
0362      *
0363      * one can additionally provide a categoryIcon
0364      *
0365      *    message["categoryIcon"] = QIcon(...)
0366      *
0367      * the categoryIcon icon QVariant must contain a QIcon, nothing else!
0368      *
0369      * A string token can be passed to allow to replace messages already send out with new ones.
0370      * That is useful for e.g. progress output
0371      *
0372      *     message["token"] = "yourmessagetoken"
0373      *
0374      */
0375     bool showMessage(const QVariantMap &message);
0376 
0377 private:
0378     /**
0379      * Private d-pointer class is our best friend ;)
0380      */
0381     friend class MainWindowPrivate;
0382 
0383     /**
0384      * Private d-pointer
0385      */
0386     class MainWindowPrivate *const d;
0387 };
0388 
0389 } // namespace KTextEditor
0390 
0391 #endif