File indexing completed on 2024-04-14 03:57:10

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     SPDX-FileCopyrightText: 2000-2008 David Faure <faure@kde.org>
0011 
0012     SPDX-License-Identifier: LGPL-2.0-only
0013 */
0014 
0015 #ifndef KMAINWINDOW_H
0016 #define KMAINWINDOW_H
0017 
0018 #include <kxmlgui_export.h>
0019 
0020 #include <QMainWindow>
0021 #include <memory>
0022 
0023 class QMenu;
0024 class KConfig;
0025 class KConfigGroup;
0026 class KMWSessionManager;
0027 class KMainWindowPrivate;
0028 class KToolBar;
0029 
0030 /**
0031  * @class KMainWindow kmainwindow.h KMainWindow
0032  *
0033  * @brief KMainWindow represents a top-level main window.
0034  *
0035  * It extends QMainWindow with session management capabilities. For ready-made window functionality and simpler UI management, use KXmlGuiWindow instead.
0036  *
0037  * Define the minimum/maximum height/width of your central widget and KMainWindow will take this into account.
0038  * For fixed size windows set your main widget to a fixed size. Fixed aspect ratios (QWidget::heightForWidth()) and fixed width widgets are not supported.
0039  *
0040  * Use toolBar() to generate a main toolbar "mainToolBar" or refer to a specific toolbar.
0041  * For a simpler way to manage your toolbars, use KXmlGuiWindow::setupGUI() instead.
0042  *
0043  * Use setAutoSaveSettings() to automatically save and restore the window geometry and toolbar/menubar/statusbar state when the application is restarted.
0044  *
0045  * Use kRestoreMainWindows() in your main function to restore your windows when the session is restored.
0046  *
0047  * The window state is saved when the application is exited.
0048  * Reimplement queryClose() to warn the user of unsaved data upon close or exit.
0049  *
0050  * Reimplement saveProperties() / readProperties() or saveGlobalProperties() / readGlobalProperties()
0051  * to save/restore application-specific state during session management.
0052  *
0053  * Note that session saving is automatically called, session restoring is not,
0054  * and so it needs to be implemented in your main() function.
0055  *
0056  * See https://develop.kde.org/docs/use/session-managment for more information on session management.
0057  */
0058 
0059 class KXMLGUI_EXPORT KMainWindow : public QMainWindow
0060 {
0061     friend class KMWSessionManager;
0062     friend class DockResizeListener;
0063     Q_OBJECT
0064     Q_PROPERTY(bool hasMenuBar READ hasMenuBar)
0065     Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings)
0066     Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup)
0067 
0068 public:
0069     /**
0070      * @brief Constructs a main window.
0071      *
0072      * @param parent The parent widget. This is usually @c nullptr, but it may also be
0073      * the window group leader. In that case,
0074      * the KMainWindow becomes a secondary window.
0075      *
0076      * @param flags Specify the window flags. The default is none.
0077      *
0078      * Note that by default a KMainWindow is created with the
0079      * Qt::WA_DeleteOnClose attribute set, i.e. it is automatically destroyed
0080      * when the window is closed. If you do not want this behavior, call
0081      * \code
0082      * window->setAttribute(Qt::WA_DeleteOnClose, false);
0083      * \endcode
0084      *
0085      * KMainWindows must be created on the heap with 'new', like:
0086      * \code
0087      * KMainWindow *kmw = new KMainWindow(...);
0088      * kmw->setObjectName(...);
0089      * \endcode
0090      *
0091      * Since KDE Frameworks 5.16, KMainWindow will enter information regarding
0092      * the application's translators by default, using KAboutData::setTranslator(). This only occurs
0093      * if no translators are already assigned in KAboutData (see KAboutData::setTranslator() for
0094      * details -- the auto-assignment here uses the same translated strings as specified for that
0095      * function).
0096      *
0097      * IMPORTANT: For session management and window management to work
0098      * properly, all main windows in the application should have a
0099      * different name. Otherwise, KMainWindow will create
0100      * a unique name, but it's recommended to explicitly pass a window name that will
0101      * also describe the type of the window. If there can be several windows of the same
0102      * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make
0103      * the names unique. For example, for a mail client which has one main window showing
0104      * the mails and folders, and which can also have one or more windows for composing
0105      * mails, the name for the folders window should be e.g. "mainwindow" and
0106      * for the composer windows "composer#".
0107      *
0108      * @see KAboutData
0109      */
0110     explicit KMainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
0111 
0112     /**
0113      * @brief Destructor.
0114      *
0115      * Will also destroy the toolbars and menubar if
0116      * needed.
0117      */
0118     ~KMainWindow() override;
0119 
0120     /**
0121      * @param numberOfInstances The number of KMainWindow instances in the application.
0122      * @returns @c true if the number of KMainWindow instances of the previous session did contain the requested @p numberOfInstances, @c false otherwise.
0123      * @see restore()
0124      **/
0125     static bool canBeRestored(int numberOfInstances);
0126 
0127     /**
0128      * @brief Useful if your application uses
0129      * different kinds of top-level windows.
0130      *
0131      * @returns The class name of the top-level window to be restored
0132      * that corresponds to @p instanceNumber.
0133      *
0134      * @param instanceNumber
0135      * @see restore()
0136      */
0137     static const QString classNameOfToplevel(int instanceNumber);
0138 
0139     /**
0140      * @brief Attempt to restore the top-level widget as defined by @p numberOfInstances (1..X).
0141      *
0142      * You should call canBeRestored() first.
0143      *
0144      * If the session did not contain so high a number, the configuration
0145      * is not changed and @c false is returned.
0146      *
0147      * That means clients could simply do the following:
0148      * \code
0149      * if (qApp->isSessionRestored()){
0150      *   int n = 1;
0151      *   while (KMainWindow::canBeRestored(n)){
0152      *     (new childMW)->restore(n);
0153      *     n++;
0154      *   }
0155      * } else {
0156      *   // create default application as usual
0157      * }
0158      * \endcode
0159      * Note that if @p show is @c true (default), QWidget::show() is called
0160      * implicitly in restore.
0161      *
0162      * With this you can easily restore all top-level windows of your
0163      * application.
0164      *
0165      * If your application uses different kinds of top-level
0166      * windows, then you can use KMainWindow::classNameOfToplevel(n)
0167      * to determine the exact type before calling the childMW
0168      * constructor in the example from above.
0169      *
0170      * @note You don't need to deal with this function. Use the
0171      * kRestoreMainWindows() convenience template function instead!
0172      *
0173      * @param numberOfInstances The number of KMainWindow instances from the last session.
0174      * @param show Whether the KMainWindow instances will be visible by default.
0175      *
0176      * @returns @c true if the session contained
0177      * the same number of instances as the requested number,
0178      * @c false if the session contained less instances than the requested number,
0179      * in which case no configuration is changed.
0180      *
0181      * @see kRestoreMainWindows()
0182      * @see readProperties()
0183      * @see canBeRestored()
0184      */
0185     bool restore(int numberOfInstances, bool show = true);
0186 
0187     /**
0188      * @returns @c true if there is a menubar, @c false otherwise.
0189      */
0190     bool hasMenuBar();
0191 
0192     /**
0193      * @returns The list of members of the KMainWindow class.
0194      */
0195     static QList<KMainWindow *> memberList();
0196 
0197     /**
0198      * @brief This is useful to both call specific toolbars that have been created
0199      * or to generate a default one upon call.
0200      *
0201      * This refers to toolbars created dynamically from the XML UI
0202      * framework via KConfig or appnameui.rc.
0203      *
0204      * If the toolbar does not exist, one will be created.
0205      *
0206      * @param name The internal name of the toolbar. If no name is
0207      *             specified, "mainToolBar" is assumed.
0208      *
0209      * @return A pointer to the toolbar with the specified name.
0210      * @see toolBars()
0211      **/
0212     KToolBar *toolBar(const QString &name = QString());
0213 
0214     /**
0215      * @return A list of all toolbars for this window
0216      */
0217     QList<KToolBar *> toolBars() const;
0218 
0219     /**
0220      * @brief This enables autosave of toolbar/menubar/statusbar settings
0221      * (and optionally window size).
0222      * @param groupName A name that identifies the type of window.
0223      * You can have several types of window in the same application.
0224      * If no @p groupName is specified, the value defaults to "MainWindow".
0225      *
0226      * @param saveWindowSize Whether to include the window size
0227      * when saving. @c true by default.
0228      *
0229      * If the *bars were modified when the window is closed,
0230      * saveMainWindowSettings( KConfigGroup(KSharedConfig::openConfig(), groupName) ) will be called.
0231      *
0232      * Typically, you will call setAutoSaveSettings() in your
0233      * KMainWindow-inherited class constructor, and it will take care
0234      * of restoring and saving automatically.
0235      *
0236      * By default, this generates an
0237      * appnamerc ini file as if using default KConfig constructor or KConfig::SimpleConfig.
0238      *
0239      * Make sure you call this @em after all your *bars have been created.
0240      *
0241      * To make sure that KMainWindow properly obtains the default
0242      * size of the window you should do the following:
0243      * - Remove hardcoded resize() calls in the constructor or main
0244      *   to let the automatic resizing determine the default window size.
0245      *   Hardcoded window sizes will be wrong for users that have big fonts,
0246      *   use different styles, long/small translations, large toolbars, and other factors.
0247      * - Put the setAutoSaveSettings() call after all widgets
0248      *   have been created and placed inside the main window
0249      *   (for most apps this means QMainWindow::setCentralWidget())
0250      * - QWidget-based objects should overload "virtual QSize sizeHint() const;"
0251      *   to specify a default size.
0252      * @see KConfig
0253      * @see KSharedConfig
0254      * @see saveMainWindowSettings()
0255      * @see toolBar()
0256      * @see KXmlGuiWindow::setupGUI()
0257      */
0258     void setAutoSaveSettings(const QString &groupName = QStringLiteral("MainWindow"), bool saveWindowSize = true);
0259 
0260     /**
0261      * This is an overloaded function.
0262      * This allows the settings to be saved into a different file
0263      * that does not correspond to that used for KSharedConfig::openConfig().
0264      * @see setAutoSaveSettings(const QString &groupName, bool saveWindowSize)
0265      * @see KConfig
0266      * @see KSharedConfig
0267      * @since 4.1
0268      */
0269     void setAutoSaveSettings(const KConfigGroup &group, bool saveWindowSize = true);
0270 
0271     /**
0272      * @brief Disables the autosave settings feature.
0273      * You don't normally need to call this, ever.
0274      * @see setAutoSaveSettings()
0275      * @see autoSaveSettings()
0276      */
0277     void resetAutoSaveSettings();
0278 
0279     /**
0280      * @return @c true if setAutoSaveSettings() was called,
0281      * @c false by default or if resetAutoSaveSettings() was called.
0282      * @see setAutoSaveSettings()
0283      * @see resetAutoSaveSettings()
0284      */
0285     bool autoSaveSettings() const;
0286 
0287     /**
0288      * @return The group used for autosaving settings.
0289      *
0290      * Do not mistake this with autoSaveConfigGroup.
0291      *
0292      * Only meaningful if setAutoSaveSettings(const QString&, bool) was called.
0293      *
0294      * Do not use this method if setAutoSaveSettings(const KConfigGroup&, bool) was called.
0295      *
0296      * This can be useful for forcing a save or an apply, e.g. before and after
0297      * using KEditToolBar.
0298      *
0299      * @note Prefer saveAutoSaveSettings() for saving or autoSaveConfigGroup() for loading.
0300      *
0301      * @see autoSaveSettings()
0302      * @see setAutoSaveSettings()
0303      * @see saveAutoSaveSettings()
0304      * @see resetAutoSaveSettings()
0305      * @see autoSaveConfigGroup()
0306      */
0307     QString autoSaveGroup() const;
0308 
0309     /**
0310      * @return The group used for autosaving settings.
0311      *
0312      * Only meaningful if setAutoSaveSettings(const QString&, bool) was called.
0313      *
0314      * Do not use this method if setAutoSaveSettings(const KConfigGroup&, bool) was called.
0315      *
0316      * This can be useful for forcing an apply, e.g. after using KEditToolBar.
0317      *
0318      * @see setAutoSaveSettings()
0319      * @see autoSaveGroup()
0320      * @since 4.1
0321      */
0322     KConfigGroup autoSaveConfigGroup() const;
0323 
0324     /**
0325      * @brief Assigns the config group name for the KConfigGroup returned by stateConfigGroup.
0326      * @param configGroup The config group to be assigned.
0327      * Window size and state are stored in the resulting KConfigGroup when this function is called.
0328      * @note If this is used in combination with setAutoSaveSettings, you should call this method first.
0329      *
0330      * @see KConfigGroup()
0331      * @see KSharedConfig::openStateConfig()
0332      * @see stateConfigGroup()
0333      *
0334      * @since 5.88
0335      */
0336     void setStateConfigGroup(const QString &configGroup);
0337 
0338     /**
0339      * @returns The KConfigGroup used to store state data like window sizes or window state.
0340      *
0341      * The resulting group is invalid if setStateConfig is not called explicitly.
0342      *
0343      * @see KConfigGroup
0344      * @since 5.88
0345      */
0346     KConfigGroup stateConfigGroup() const;
0347 
0348     /**
0349      * @brief Read settings for statusbar, menubar and toolbar from their respective
0350      * groups in the config file and apply them.
0351      *
0352      * @param config Config group to read the settings from.
0353      */
0354     virtual void applyMainWindowSettings(const KConfigGroup &config);
0355 
0356     /**
0357      * @brief Manually save the settings for statusbar, menubar and toolbar to their respective
0358      * groups in the KConfigGroup @p config.
0359      *
0360      * Example:
0361      * \code
0362      * KConfigGroup group(KSharedConfig::openConfig(), "MainWindow");
0363      * saveMainWindowSettings(group);
0364      * \endcode
0365      *
0366      * @param config Config group to save the settings to.
0367      * @see setAutoSaveSettings()
0368      * @see KConfig
0369      * @see KSharedConfig
0370      * @see KConfigGroup
0371      */
0372     void saveMainWindowSettings(KConfigGroup &config);
0373 
0374     /**
0375      * @returns The path for the exported window's D-Bus object.
0376      * @since 4.0.1
0377      */
0378     QString dbusName() const;
0379 
0380 public Q_SLOTS:
0381     /**
0382      * @brief Assigns a KDE compliant caption (window title).
0383      *
0384      * @param caption The string that will be
0385      * displayed in the window title, before the application name.
0386      *
0387      * @note This function does the same as setPlainCaption().
0388      *
0389      * @note Do not include the application name
0390      * in this string. It will be added automatically according to the KDE
0391      * standard.
0392      *
0393      * @see setPlainCaption()
0394      */
0395     virtual void setCaption(const QString &caption);
0396     /**
0397      * @brief Makes a KDE compliant caption.
0398      * @param caption Your caption.
0399      * @param modified Whether the document is modified. This displays
0400      * an additional sign in the title bar, usually "**".
0401      *
0402      * This is an overloaded function.
0403      *
0404      * @note Do not include the application name
0405      * in this string. It will be added automatically according to the KDE
0406      * standard.
0407      */
0408     virtual void setCaption(const QString &caption, bool modified);
0409 
0410     /**
0411      * @brief Make a plain caption without any modifications.
0412      *
0413      * @param caption The string that will be
0414      * displayed in the window title, before the application name.
0415      *
0416      * @note This function does the same as setCaption().
0417      *
0418      * @note Do not include the application name
0419      * in this string. It will be added automatically according to the KDE
0420      * standard.
0421      *
0422      * @see setCaption()
0423      */
0424     virtual void setPlainCaption(const QString &caption);
0425 
0426     /**
0427      * @brief Opens the help page for the application.
0428      *
0429      * The application name is
0430      * used as a key to determine what to display and the system will attempt
0431      * to open \<appName\>/index.html.
0432      *
0433      * This method is intended for use by a help button in the toolbar or
0434      * components outside the regular help menu.
0435      *
0436      * Use helpMenu() when you
0437      * want to provide access to the help system from the help menu.
0438      *
0439      * Example (adding a help button to the first toolbar):
0440      *
0441      * \code
0442      * toolBar()->addAction(QIcon::fromTheme("help-contents"), i18n("Help"),
0443      *                       this, &KMainWindow::appHelpActivated);
0444      * \endcode
0445      *
0446      * @see helpMenu()
0447      * @see toolBar()
0448      */
0449     void appHelpActivated();
0450 
0451     /**
0452      * @brief Tell the main window that it should save its settings when being closed.
0453      *
0454      * This is part of the autosave settings feature.
0455      *
0456      * For everything related to toolbars this happens automatically,
0457      * but you have to call setSettingsDirty() in the slot that toggles
0458      * the visibility of the statusbar.
0459      *
0460      * @see saveAutoSaveSettings()
0461      */
0462     void setSettingsDirty();
0463 
0464 protected:
0465     /**
0466      * Reimplemented to catch QEvent::Polish in order to adjust the object name
0467      * if needed, once all constructor code for the main window has run.
0468      * Also reimplemented to catch when a QDockWidget is added or removed.
0469      */
0470     bool event(QEvent *event) override;
0471 
0472     /**
0473      * Reimplemented to open context menus on Shift+F10.
0474      */
0475     void keyPressEvent(QKeyEvent *keyEvent) override;
0476 
0477     /**
0478      * Reimplemented to autosave settings and call queryClose().
0479      *
0480      * We recommend that you reimplement queryClose() rather than closeEvent().
0481      * If you do it anyway, ensure to call the base implementation to keep
0482      * the feature of autosaving window settings working.
0483      */
0484     void closeEvent(QCloseEvent *) override;
0485 
0486     /**
0487      * @brief This function is called before the window is closed,
0488      * either by the user or indirectly by the session manager.
0489      *
0490      * This can be used to prompt the user to save unsaved data before the window is closed.
0491      *
0492      * Example:
0493      * \code
0494      * switch ( KMessageBox::warningTwoActionsCancel( this,
0495      *          i18n("Save changes to document foo?"), QString(),
0496      *          KStandardGuiItem::save(), KStandardGuiItem::discard())) ) {
0497      *   case KMessageBox::PrimaryAction :
0498      *     // save document here. If saving fails, return false;
0499      *     return true;
0500      *   case KMessageBox::SecondaryAction :
0501      *     return true;
0502      *   default: // cancel
0503      *     return false;
0504      * \endcode
0505      *
0506      * @note Do @em not close the document from within this method,
0507      * as it may be called by the session manager before the
0508      * session is saved. If the document is closed before the session save occurs,
0509      * its location might not be properly saved. In addition, the session shutdown
0510      * may be canceled, in which case the document should remain open.
0511      *
0512      * @return @c true by default, @c false according to the reimplementation.
0513      * Returning @c false will cancel the closing operation,
0514      * and if KApplication::sessionSaving() is true, it cancels logout.
0515      *
0516      * @see KApplication::sessionSaving()
0517      */
0518     virtual bool queryClose();
0519 
0520     /**
0521      * @brief Saves your instance-specific properties.
0522      *
0523      * The function is
0524      * invoked when the session manager requests your application
0525      * to save its state.
0526      *
0527      * Reimplement this function in child classes.
0528      *
0529      * \code
0530      * void MainWindow::saveProperties(KConfigGroup &config) {
0531      *   config.writeEntry("myKey", "newValue");
0532      *   ...
0533      * }
0534      * \endcode
0535      *
0536      * @note No user interaction is allowed
0537      * in this function!
0538      *
0539      */
0540     virtual void saveProperties(KConfigGroup &)
0541     {
0542     }
0543 
0544     /**
0545      * @brief Reads your instance-specific properties.
0546      *
0547      * This function is called indirectly by restore().
0548      *
0549      * \code
0550      * void MainWindow::readProperties(KConfigGroup &config) {
0551      *   if (config.hasKey("myKey")) {
0552      *     config.readEntry("myKey", "DefaultValue");
0553      *   }
0554      *   ...
0555      * }
0556      * \endcode
0557      *
0558      * @see readGlobalProperties()
0559      */
0560     virtual void readProperties(const KConfigGroup &)
0561     {
0562     }
0563 
0564     /**
0565      * @brief Saves your application-wide properties.
0566      *
0567      * @param sessionConfig A pointer to the KConfig instance
0568      * used to save the session data.
0569      *
0570      * This function is invoked when the session manager
0571      * requests your application to save its state.
0572      * It is similar to saveProperties(), but it is only called for
0573      * the first main window. This is useful to save global state of your application
0574      * that isn't bound to a particular window.
0575      *
0576      * The default implementation does nothing.
0577      *
0578      * @see readGlobalProperties()
0579      * @see saveProperties()
0580      */
0581     virtual void saveGlobalProperties(KConfig *sessionConfig);
0582 
0583     /**
0584      * @brief Reads your application-wide properties.
0585      *
0586      * @param sessionConfig A pointer to the KConfig instance
0587      * used to load the session data.
0588      *
0589      * @see saveGlobalProperties()
0590      * @see readProperties()
0591      *
0592      */
0593     virtual void readGlobalProperties(KConfig *sessionConfig);
0594     void savePropertiesInternal(KConfig *, int);
0595     bool readPropertiesInternal(KConfig *, int);
0596 
0597     /**
0598      * For inherited classes
0599      */
0600     bool settingsDirty() const;
0601 
0602 protected Q_SLOTS:
0603     /**
0604      * This slot should only be called in case you reimplement closeEvent() and
0605      * if you are using the autosave feature. In all other cases,
0606      * setSettingsDirty() should be called instead to benefit from the delayed
0607      * saving.
0608      *
0609      * Example:
0610      * \code
0611      *
0612      * void MyMainWindow::closeEvent( QCloseEvent *e )
0613      * {
0614      *   // Save settings if autosave is enabled, and settings have changed
0615      *   if ( settingsDirty() && autoSaveSettings() )
0616      *     saveAutoSaveSettings();
0617      *   ..
0618      * }
0619      * \endcode
0620      *
0621      * @see setAutoSaveSettings()
0622      * @see setSettingsDirty()
0623      */
0624     void saveAutoSaveSettings();
0625 
0626 protected:
0627     KXMLGUI_NO_EXPORT KMainWindow(KMainWindowPrivate &dd, QWidget *parent, Qt::WindowFlags f);
0628 
0629     std::unique_ptr<KMainWindowPrivate> const d_ptr;
0630 
0631 private:
0632     Q_DECLARE_PRIVATE(KMainWindow)
0633 
0634     Q_PRIVATE_SLOT(d_func(), void _k_slotSettingsChanged(int))
0635     Q_PRIVATE_SLOT(d_func(), void _k_slotSaveAutoSaveSize())
0636     Q_PRIVATE_SLOT(d_func(), void _k_slotSaveAutoSavePosition())
0637 };
0638 
0639 /**
0640  * @defgroup KXMLGUI_Session KXMLGUI Session Macros and Functions
0641  *
0642  * @{
0643  */
0644 
0645 /**
0646  * @def KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS
0647  * Returns the maximal number of arguments that are actually
0648  * supported by kRestoreMainWindows().
0649  **/
0650 #define KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS 3
0651 
0652 /**
0653  * @brief Restores the last session. (To be used in your main function).
0654  *
0655  * These functions work also if you have more than one kind of top-level
0656  * widget (each derived from KMainWindow, of course).
0657  *
0658  * Imagine you have three kinds of top-level widgets: the classes @c childMW1,
0659  * @c childMW2 and @c childMW3. Then you can just do:
0660  *
0661  * \code
0662  * int main(int argc, char *argv[])
0663  * {
0664  *     // [...]
0665  *     if (qApp->isSessionRestored())
0666  *         kRestoreMainWindows<childMW1, childMW2, childMW3>();
0667  *     else {
0668  *       // create default application as usual
0669  *     }
0670  *     // [...]
0671  * }
0672  * \endcode
0673  *
0674  * kRestoreMainWindows<>() will create (on the heap) as many instances
0675  * of your main windows as have existed in the last session and
0676  * call KMainWindow::restore() with the correct arguments. Note that
0677  * also QWidget::show() is called implicitly.
0678  *
0679  * Currently, these functions are provided for up to three
0680  * template arguments. If you need more, tell us. To help you in
0681  * deciding whether or not you can use kRestoreMainWindows, a
0682  * define #KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS is provided.
0683  *
0684  * @note Prefer this function over directly calling KMainWindow::restore().
0685  *
0686  * @tparam T Top-level widget class
0687  *
0688  * @see KMainWindow::restore()
0689  * @see KMainWindow::classNameOfToplevel()
0690  **/
0691 template<typename T>
0692 inline void kRestoreMainWindows()
0693 {
0694     for (int n = 1; KMainWindow::canBeRestored(n); ++n) {
0695         const QString className = KMainWindow::classNameOfToplevel(n);
0696         if (className == QLatin1String(T::staticMetaObject.className())) {
0697             (new T)->restore(n);
0698         }
0699     }
0700 }
0701 
0702 /**
0703  * @brief Restores the last session.
0704  * This is an overloaded function.
0705  *
0706  * Use this with multiple different top-level widget classes.
0707  *
0708  * @tparam T0 One top-level widget class
0709  * @tparam T1 Explicit other top-level widget class for disambiguation from base template
0710  * @tparam Tn Parameter pack to take 0..n further KMainWindows
0711  * @see kRestoreMainWindows()
0712  */
0713 template<typename T0, typename T1, typename... Tn>
0714 inline void kRestoreMainWindows()
0715 {
0716     kRestoreMainWindows<T0>();
0717     kRestoreMainWindows<T1, Tn...>();
0718 }
0719 /** @}  */
0720 
0721 #endif