File indexing completed on 2024-05-19 04:00:03

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