File indexing completed on 2024-04-21 15:05:55

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2000 Reginald Stadlbauer <reggie@kde.org>
0004     SPDX-FileCopyrightText: 1997 Stephan Kulow <coolo@kde.org>
0005     SPDX-FileCopyrightText: 1997-2000 Sven Radej <radej@kde.org>
0006     SPDX-FileCopyrightText: 1997-2000 Matthias Ettrich <ettrich@kde.org>
0007     SPDX-FileCopyrightText: 1999 Chris Schlaeger <cs@kde.org>
0008     SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org>
0009     SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
0010 
0011     SPDX-License-Identifier: LGPL-2.0-only
0012 */
0013 
0014 #ifndef KXMLGUIWINDOW_H
0015 #define KXMLGUIWINDOW_H
0016 
0017 #include "kmainwindow.h"
0018 #include "kxmlguibuilder.h"
0019 #include "kxmlguiclient.h"
0020 
0021 class KMenu;
0022 class KXMLGUIFactory;
0023 class KConfig;
0024 class KConfigGroup;
0025 class KToolBar;
0026 class KXmlGuiWindowPrivate;
0027 
0028 /**
0029  * @class KXmlGuiWindow kxmlguiwindow.h KXmlGuiWindow
0030  *
0031  * @brief KMainWindow with convenience functions and integration with XmlGui files.
0032  *
0033  * This class includes several convenience \<action\>Enabled() functions
0034  * to toggle the presence of functionality in your main window,
0035  * including a KCommandBar instance.
0036  *
0037  * The @ref StandardWindowOptions enum can be used to pass additional options
0038  * to describe the main window behavior/appearance.
0039  * Use it in conjunction with setupGUI() to load an appnameui.rc file
0040  * to manage the main window's actions.
0041  *
0042  * setCommandBarEnabled() is set by default.
0043  *
0044  * A minimal example can be created with
0045  * QMainWindow::setCentralWidget() and setupGUI():
0046  *
0047  * @code
0048  * MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent) {
0049  *   textArea = new KTextEdit();
0050  *   setCentralWidget(textArea);
0051  *   setupGUI(Default);
0052  * }
0053  * @endcode
0054  *
0055  * With this, a ready-made main window with menubar and statusbar is created,
0056  * as well as two default menus, Settings and Help.
0057  *
0058  * Management of QActions is made trivial in combination with
0059  * KActionCollection and KStandardAction.
0060  *
0061  * @code
0062  * void MainWindow::setupActions() {
0063  *   QAction *clearAction = new QAction(this);
0064  *   clearAction->setText(i18n("&Clear"));
0065  *   clearAction->setIcon(QIcon::fromTheme("document-new"));
0066  *   actionCollection()->setDefaultShortcut(clearAction, Qt::CTRL + Qt::Key_W);
0067  *   actionCollection()->addAction("clear", clearAction);
0068  *   connect(clearAction, &QAction::triggered, textArea, &KTextEdit::clear);
0069  *   KStandardAction::quit(qApp, &QCoreApplication::quit, actionCollection());
0070  *   setupGUI(Default, "texteditorui.rc");
0071  * }
0072  * @endcode
0073  *
0074  * See https://develop.kde.org/docs/use/kxmlgui/ for a tutorial
0075  * on how to create a simple text editor using KXmlGuiWindow.
0076  *
0077  * See https://develop.kde.org/docs/use/session-managment for more information on session management.
0078  *
0079  * @see KMainWindow
0080  * @see KActionCollection
0081  * @see KStandardAction
0082  * @see setupGUI()
0083  * @see createGUI()
0084  * @see setCommandBarEnabled()
0085  */
0086 
0087 class KXMLGUI_EXPORT KXmlGuiWindow : public KMainWindow, public KXMLGUIBuilder, virtual public KXMLGUIClient
0088 {
0089     Q_OBJECT
0090     Q_PROPERTY(bool hasMenuBar READ hasMenuBar)
0091     Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings)
0092     Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup)
0093     Q_PROPERTY(bool standardToolBarMenuEnabled READ isStandardToolBarMenuEnabled WRITE setStandardToolBarMenuEnabled)
0094 
0095 public:
0096     /**
0097      * @brief Construct a main window.
0098      *
0099      * Note that by default a KXmlGuiWindow is created with the
0100      * Qt::WA_DeleteOnClose attribute set, i.e. it is automatically destroyed
0101      * when the window is closed. If you do not want this behavior, call:
0102      *
0103      * @code
0104      * window->setAttribute(Qt::WA_DeleteOnClose, false);
0105      * @endcode
0106      *
0107      * KXmlGuiWindows must be created on the heap with 'new', like:
0108      *
0109      * @code
0110      * KXmlGuiWindow *kmw = new KXmlGuiWindow(...);
0111      * kmw->setObjectName(...);
0112      * @endcode
0113      *
0114      * IMPORTANT: For session management and window management to work
0115      * properly, all main windows in the application should have a
0116      * different name. Otherwise, the base class KMainWindow will create
0117      * a unique name, but it's recommended to explicitly pass a window name that will
0118      * also describe the type of the window. If there can be several windows of the same
0119      * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make
0120      * the names unique. For example, for a mail client which has one main window showing
0121      * the mails and folders, and which can also have one or more windows for composing
0122      * mails, the name for the folders window should be e.g. "mainwindow" and
0123      * for the composer windows "composer#".
0124      *
0125      * @param parent The widget parent. This is usually @c nullptr,
0126      * but it may also be the window group leader.
0127      * In that case, the KXmlGuiWindow becomes a secondary window.
0128      *
0129      * @param flags Specify the window flags. The default is none.
0130      *
0131      * @see KMainWindow::KMainWindow
0132      */
0133     explicit KXmlGuiWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
0134 
0135     /**
0136      * @brief Destructor.
0137      *
0138      * Will also destroy the toolbars and menubar if needed.
0139      */
0140     ~KXmlGuiWindow() override;
0141 
0142     /**
0143      * @brief Creates a standard help menu when calling createGUI()
0144      * or setupGUI().
0145      *
0146      * @param showHelpMenu Whether to create a Help Menu. @c true by default.
0147      *
0148      * @see isHelpMenuEnabled()
0149      */
0150     void setHelpMenuEnabled(bool showHelpMenu = true);
0151 
0152     /**
0153      * @returns @c true if the help menu is enabled, @c false if setHelpMenuEnabled(false) was set.
0154      * @see setHelpMenuEnabled()
0155      */
0156     bool isHelpMenuEnabled() const;
0157 
0158     virtual KXMLGUIFactory *guiFactory();
0159 
0160     /**
0161      * @brief Generates the interface based on a local XML file.
0162      *
0163      * This is the function that generates UI elements such as the main menu,
0164      * toolbar (if any) and statusbar. This is called by setupGUI(Create) as well.
0165      *
0166      * Typically, in a regular application, you would use setupGUI()
0167      * instead, as it sets up the toolbar/shortcut
0168      * edit actions, among other things.
0169      *
0170      * If @p xmlfile is an empty string, this method will try to construct
0171      * a local XML filename like appnameui.rc where 'appname' is your app's
0172      * name. Typically that app name is what KXMLGUIClient::componentName()
0173      * returns. If that file does not exist, then the XML UI code will use only
0174      * the global (standard) XML file for its layout purposes.
0175      *
0176      * @param xmlfile The path (relative or absolute) to the local xmlfile
0177      *
0178      * @see setupGUI()
0179      */
0180     void createGUI(const QString &xmlfile = QString());
0181 
0182     /**
0183      * @brief Creates a toggle under the 'Settings' menu to show/hide the available toolbars.
0184      *
0185      * The standard toolbar menu toggles the visibility of one or multiple toolbars.
0186      *
0187      * If there is only one toolbar configured, a simple 'Show \<toolbar name\>'
0188      * menu item is shown; if more than one toolbar is configured, a "Shown Toolbars"
0189      * menu is created instead, with 'Show \<toolbar1 name\>', 'Show \<toolbar2 name\>'
0190      * ... sub-menu actions.
0191      *
0192      * If your application uses a non-default XmlGui resource file, then you can
0193      * specify the exact position of the menu/menu item by adding a
0194      * &lt;Merge name="StandardToolBarMenuHandler" /&gt;
0195      * line to the settings menu section of your resource file ( usually appname.rc ).
0196      *
0197      * @param showToolBarMenu Whether to show the standard toolbar menu. @c false by default.
0198      *
0199      * @note This function only makes sense before calling createGUI().
0200      * Using setupGUI(ToolBar) overrides this function.
0201      *
0202      * @see createGUI()
0203      * @see setupGUI()
0204      * @see KToggleBarAction
0205      * @see StandardWindowOption
0206      * @see KMainWindow::toolBar()
0207      * @see KMainWindow::toolBars()
0208      * @see QMainWindow::addToolBar()
0209      * @see QMainWindow::removeToolBar()
0210      * @see createStandardStatusBarAction()
0211      */
0212     void setStandardToolBarMenuEnabled(bool showToolBarMenu);
0213 
0214     /**
0215      * @brief Returns whether setStandardToolBarMenuEnabled() was set.
0216      *
0217      * @note This function only makes sense if createGUI() was used.
0218      * This function returns true only if setStandardToolBarMenuEnabled() was set
0219      * and will return false even if @ref StandardWindowOption::ToolBar was used.
0220      *
0221      * @returns @c true if setStandardToolBarMenuEnabled() was set, @c false otherwise.
0222      *
0223      * @see createGUI()
0224      * @see setupGUI()
0225      * @see setStandardToolBarMenuEnabled()
0226      * @see StandardWindowOption
0227      */
0228     bool isStandardToolBarMenuEnabled() const;
0229 
0230     /**
0231      * @brief Creates a toggle under the 'Settings' menu to show/hide the statusbar.
0232      *
0233      * Calling this method will create a statusbar if one doesn't already exist.
0234      *
0235      * If an application maintains the action on its own (i.e. never calls
0236      * this function), a connection needs to be made to let KMainWindow
0237      * know when the hidden/shown status of the statusbar has changed.
0238      * For example:
0239      * @code
0240      * connect(action, &QAction::triggered,
0241      *         kmainwindow, &KMainWindow::setSettingsDirty);
0242      * @endcode
0243      * Otherwise the status might not be saved by KMainWindow.
0244      *
0245      * @note This function only makes sense before calling createGUI()
0246      * or when using setupGUI() without @ref StandardWindowOption::StatusBar.
0247      *
0248      * @see createGUI()
0249      * @see setupGUI()
0250      * @see StandardWindowOption
0251      * @see KStandardAction::showStatusbar()
0252      * @see setStandardToolBarMenuEnabled()
0253      * @see QMainWindow::setStatusBar()
0254      * @see QMainWindow::statusBar()
0255      */
0256     void createStandardStatusBarAction();
0257 
0258     /**
0259      * @brief Use these options for the first argument of setupGUI().
0260      * @see setupGUI()
0261      * @see StandardWindowOption
0262      */
0263     enum StandardWindowOption {
0264         /**
0265          * Adds action(s) to show/hide the toolbar(s) and adds a menu
0266          * action to configure the toolbar(s).
0267          *
0268          * @see setStandardToolBarMenuEnabled()
0269          * @see isStandardToolBarMenuEnabled()
0270          */
0271         ToolBar = 1,
0272 
0273         /**
0274          * @brief Adds an action in the 'Settings' menu
0275          * to open the configure keyboard shortcuts dialog.
0276          */
0277         Keys = 2,
0278 
0279         /**
0280          * @brief Adds an action to show/hide the statusbar in the 'Settings' menu.
0281          * Note that setting this value will create a statusbar
0282          * if one doesn't already exist.
0283          *
0284          * @see createStandardStatusBarAction()
0285          */
0286         StatusBar = 4,
0287 
0288         /**
0289          * @brief Autosaves (and loads) the toolbar/menubar/statusbar settings and
0290          * window size using the default name.
0291          *
0292          * Like KMainWindow::setAutoSaveSettings(), enabling this causes the application
0293          * to save state data upon close in a KConfig-managed configuration file.
0294          *
0295          * Typically you want to let the default window size be determined by
0296          * the widgets' size hints. Make sure that setupGUI() is called after
0297          * all the widgets are created (including QMainWindow::setCentralWidget())
0298          * so that the default size is managed properly.
0299          *
0300          * @see KMainWindow::setAutoSaveSettings()
0301          * @see KConfig
0302          */
0303         Save = 8,
0304 
0305         /**
0306          * @brief Calls createGUI() once ToolBar, Keys and Statusbar have been
0307          * taken care of.
0308          *
0309          * @note When using KParts::MainWindow, remove this flag from
0310          * the setupGUI() call, since you'll be using createGUI(part)
0311          * instead:
0312          *
0313          * @code
0314          *     setupGUI(ToolBar | Keys | StatusBar | Save);
0315          * @endcode
0316          *
0317          * @see createGUI()
0318          */
0319         Create = 16,
0320 
0321         /**
0322          * @brief Sets all of the above options as true.
0323          */
0324         Default = ToolBar | Keys | StatusBar | Save | Create,
0325     };
0326     Q_FLAG(StandardWindowOption)
0327     /**
0328      * @brief Stores a combination of @ref StandardWindowOptions values.
0329      *
0330      * Use these options for the first argument of setupGUI().
0331      * @see setupGUI()
0332      * @see StandardWindowOption
0333      */
0334     Q_DECLARE_FLAGS(StandardWindowOptions, StandardWindowOption)
0335 
0336     /**
0337      * @brief Configures the current window and its actions in the typical KDE
0338      * fashion.
0339      *
0340      * You can specify which window options/features are going to be set up using
0341      * @p options, see the @ref StandardWindowOptions enum for more details.
0342      *
0343      * @code
0344      * MainWindow::MainWindow(QWidget* parent) : KXmlGuiWindow(parent){
0345      *   textArea = new KTextEdit();
0346      *   setCentralWidget(textArea);
0347      *   setupGUI(Default, "appnameui.rc");
0348      * }
0349      * @endcode
0350      *
0351      * Use a bitwise OR (|) to select multiple enum choices for setupGUI()
0352      * (except when using StandardWindowOption::Default).
0353      *
0354      * @code
0355      * setupGUI(Save | Create, "appnameui.rc");
0356      * @endcode
0357      *
0358      * Typically this function replaces createGUI(),
0359      * but it is possible to call setupGUI(Create) together with helper functions
0360      * such as setStandardToolBarMenuEnabled() and createStandardStatusBarAction().
0361      *
0362      * @warning To use createGUI() and setupGUI()
0363      * for the same window, you must avoid using
0364      * @ref StandardWindowOption::Create. Prefer using only setupGUI().
0365      *
0366      * @note When @ref StandardWindowOption::Save is used,
0367      * this method will restore the state of the application
0368      * window (toolbar, dockwindows positions ...etc), so you need to have
0369      * added all your actions to your UI before calling this
0370      * method.
0371      *
0372      * @param options A combination of @ref StandardWindowOptions to specify
0373      * UI elements to be present in your application window.
0374      * @param xmlfile The relative or absolute path to the local xmlfile.
0375      * If this is an empty string, the code will look for a local XML file
0376      * appnameui.rc, where 'appname' is the name of your app. See the note
0377      * about the xmlfile argument in createGUI().
0378      * @see StandardWindowOption
0379      */
0380     void setupGUI(StandardWindowOptions options = Default, const QString &xmlfile = QString());
0381 
0382     /**
0383      * @brief This is an overloaded function.
0384      *
0385      * @param defaultSize A manually specified window size that overrides the saved size.
0386      * @param options A combination of @ref StandardWindowOptions to specify
0387      * UI elements to be present in your application window.
0388      * @param xmlfile The relative or absolute path to the local xmlfile.
0389      * @see setupGUI()
0390      */
0391     void setupGUI(const QSize &defaultSize, StandardWindowOptions options = Default, const QString &xmlfile = QString());
0392 
0393     /**
0394      * @returns A pointer to the main window's action responsible for the toolbar's menu.
0395      */
0396     QAction *toolBarMenuAction();
0397 
0398     /**
0399      * @internal for KToolBar
0400      */
0401     void setupToolbarMenuActions();
0402 
0403     // TODO KF6 change it to "using KXMLGUIBuilder::finalizeGUI;"
0404     void finalizeGUI(KXMLGUIClient *client) override;
0405 
0406     /**
0407      * @internal
0408      */
0409     void finalizeGUI(bool force);
0410 
0411     // reimplemented for internal reasons
0412     void applyMainWindowSettings(const KConfigGroup &config) override;
0413 
0414     /**
0415      * @brief Enable a KCommandBar to list and quickly execute actions.
0416      *
0417      * A KXmlGuiWindow by default automatically creates a KCommandBar,
0418      * but it is inaccessible unless createGUI() or setupGUI(Create) is used.
0419      *
0420      * It provides a HUD-like menu that lists all QActions in your application
0421      * and can be activated via Ctrl+Atl+i or via an action in the 'Help' menu.
0422      *
0423      * If you need more than a global set of QActions listed for your application,
0424      * use KCommandBar directly instead.
0425      *
0426      * @param showCommandBar Whether to show the command bar. @c true by default.
0427      *
0428      * @since 5.83
0429      *
0430      * @see KCommandBar
0431      * @see KCommandBar::setActions()
0432      * @see isCommandBarEnabled()
0433      */
0434     void setCommandBarEnabled(bool showCommandBar);
0435 
0436     /**
0437      * @brief Returns whether a KCommandBar was set.
0438      * @returns @c true by default, @c false if setCommandBarEnabled(false) was set.
0439      * @since 5.83
0440      * @see setCommandBarEnabled()
0441      */
0442     bool isCommandBarEnabled() const;
0443 
0444 public Q_SLOTS:
0445     /**
0446      * @brief Show a standard configure toolbar dialog.
0447      *
0448      * This slot can be connected directly to the action to configure the toolbar.
0449      *
0450      * @code
0451      * KStandardAction::configureToolbars(this, &KXmlGuiWindow::configureToolbars, actionCollection);
0452      * @endcode
0453      */
0454     virtual void configureToolbars();
0455 
0456     /**
0457      * @brief Applies a state change
0458      *
0459      * Reimplement this to enable and disable actions as defined in the XmlGui rc file.
0460      *
0461      * @param newstate The state change to be applied.
0462      */
0463     virtual void slotStateChanged(const QString &newstate);
0464 
0465     /**
0466      * @brief Applies a state change
0467      *
0468      * Reimplement this to enable and disable actions as defined in the XmlGui rc file.
0469      *
0470      * This function can "reverse" the state (disable the actions which should be
0471      * enabled, and vice-versa) if specified.
0472      *
0473      * @param newstate The state change to be applied.
0474      * @param reverse Whether to reverse @p newstate or not.
0475      */
0476     void slotStateChanged(const QString &newstate, bool reverse);
0477 
0478 protected:
0479     /**
0480      * Reimplemented to catch QEvent::Polish in order to adjust the object name
0481      * if needed, once all constructor code for the main window has run.
0482      * Also reimplemented to catch when a QDockWidget is added or removed.
0483      */
0484     bool event(QEvent *event) override;
0485 
0486     /**
0487      * @brief Checks if there are actions using the same shortcut.
0488      *
0489      * This is called automatically from createGUI().
0490      *
0491      * @since 5.30
0492      */
0493     void checkAmbiguousShortcuts();
0494 
0495 protected Q_SLOTS:
0496     /**
0497      * @brief Rebuilds the GUI after KEditToolBar changes the toolbar layout.
0498      * @see configureToolbars()
0499      */
0500     virtual void saveNewToolbarConfig();
0501 
0502 private:
0503     Q_DECLARE_PRIVATE_D(k_ptr, KXmlGuiWindow)
0504 };
0505 
0506 Q_DECLARE_OPERATORS_FOR_FLAGS(KXmlGuiWindow::StandardWindowOptions)
0507 
0508 #endif