1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2000 Reginald Stadlbauer <reggie@kde.org>
4 SPDX-FileCopyrightText: 1997 Stephan Kulow <coolo@kde.org>
5 SPDX-FileCopyrightText: 1997-2000 Sven Radej <radej@kde.org>
6 SPDX-FileCopyrightText: 1997-2000 Matthias Ettrich <ettrich@kde.org>
7 SPDX-FileCopyrightText: 1999 Chris Schlaeger <cs@kde.org>
8 SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org>
9 SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org>
10 SPDX-FileCopyrightText: 2000-2008 David Faure <faure@kde.org>
11
12 SPDX-License-Identifier: LGPL-2.0-only
13*/
14
15#ifndef KMAINWINDOW_H
16#define KMAINWINDOW_H
17
18#include <kxmlgui_export.h>
19
20#include <QMainWindow>
21#include <memory>
22
23class QMenu;
24class KConfig;
25class KConfigGroup;
26class KMWSessionManager;
27class KMainWindowPrivate;
28class KToolBar;
29
30/*!
31 * \class KMainWindow
32 * \inmodule KXmlGui
33 *
34 * \brief KMainWindow represents a top-level main window.
35 *
36 * It extends QMainWindow with session management capabilities. For ready-made window functionality and simpler UI management, use KXmlGuiWindow instead.
37 *
38 * Define the minimum/maximum height/width of your central widget and KMainWindow will take this into account.
39 * For fixed size windows set your main widget to a fixed size. Fixed aspect ratios (QWidget::heightForWidth()) and fixed width widgets are not supported.
40 *
41 * Use toolBar() to generate a main toolbar "mainToolBar" or refer to a specific toolbar.
42 * For a simpler way to manage your toolbars, use KXmlGuiWindow::setupGUI() instead.
43 *
44 * Use setAutoSaveSettings() to automatically save and restore the window geometry and toolbar/menubar/statusbar state when the application is restarted.
45 *
46 * Use kRestoreMainWindows() in your main function to restore your windows when the session is restored.
47 *
48 * The window state is saved when the application is exited.
49 * Reimplement queryClose() to warn the user of unsaved data upon close or exit.
50 *
51 * Reimplement saveProperties() / readProperties() or saveGlobalProperties() / readGlobalProperties()
52 * to save/restore application-specific state during session management.
53 *
54 * Note that session saving is automatically called, session restoring is not,
55 * and so it needs to be implemented in your main() function.
56 *
57 * See \l https://develop.kde.org/docs/features/session-managment for more information on session management.
58 */
59
60class KXMLGUI_EXPORT KMainWindow : public QMainWindow
61{
62 friend class KMWSessionManager;
63 friend class DockResizeListener;
64 Q_OBJECT
65
66 /*!
67 * \property KMainWindow::hasMenuBar
68 */
69 Q_PROPERTY(bool hasMenuBar READ hasMenuBar)
70
71 /*!
72 * \property KMainWindow::autoSaveSettings
73 */
74 Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings)
75
76 /*!
77 * \property KMainWindow::autoSaveGroup
78 */
79 Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup)
80
81public:
82 /*!
83 * \brief Constructs a main window.
84 *
85 * \a parent The parent widget. This is usually \c nullptr, but it may also be
86 * the window group leader. In that case,
87 * the KMainWindow becomes a secondary window.
88 *
89 * \a flags Specify the window flags. The default is none.
90 *
91 * Note that by default a KMainWindow is created with the
92 * Qt::WA_DeleteOnClose attribute set, i.e. it is automatically destroyed
93 * when the window is closed. If you do not want this behavior, call
94 * \code
95 * window->setAttribute(Qt::WA_DeleteOnClose, false);
96 * \endcode
97 *
98 * KMainWindows must be created on the heap with 'new', like:
99 * \code
100 * KMainWindow *kmw = new KMainWindow(...);
101 * kmw->setObjectName(...);
102 * \endcode
103 *
104 * Since KDE Frameworks 5.16, KMainWindow will enter information regarding
105 * the application's translators by default, using KAboutData::setTranslator(). This only occurs
106 * if no translators are already assigned in KAboutData (see KAboutData::setTranslator() for
107 * details -- the auto-assignment here uses the same translated strings as specified for that
108 * function).
109 *
110 * \warning For session management and window management to work
111 * properly, all main windows in the application should have a
112 * different name. Otherwise, KMainWindow will create
113 * a unique name, but it's recommended to explicitly pass a window name that will
114 * also describe the type of the window. If there can be several windows of the same
115 * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make
116 * the names unique. For example, for a mail client which has one main window showing
117 * the mails and folders, and which can also have one or more windows for composing
118 * mails, the name for the folders window should be e.g. "mainwindow" and
119 * for the composer windows "composer#".
120 *
121 * \sa KAboutData
122 */
123 explicit KMainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
124
125 /*!
126 * \brief Destructor.
127 *
128 * Will also destroy the toolbars and menubar if
129 * needed.
130 */
131 ~KMainWindow() override;
132
133 /*!
134 * Returns \c true if the number of KMainWindow instances of the previous session did contain the requested \a numberOfInstances, \c false otherwise.
135 *
136 * \a numberOfInstances The number of KMainWindow instances in the application.
137 *
138 * \sa restore()
139 **/
140 static bool canBeRestored(int numberOfInstances);
141
142 /*!
143 * \brief Useful if your application uses
144 * different kinds of top-level windows.
145 *
146 * Returns The class name of the top-level window to be restored
147 * that corresponds to \a instanceNumber.
148 *
149 * \sa restore()
150 */
151 static const QString classNameOfToplevel(int instanceNumber);
152
153 /*!
154 * \brief Attempt to restore the top-level widget as defined by \a numberOfInstances (1..X).
155 *
156 * You should call canBeRestored() first.
157 *
158 * If the session did not contain so high a number, the configuration
159 * is not changed and \c false is returned.
160 *
161 * That means clients could simply do the following:
162 * \code
163 * if (qApp->isSessionRestored()){
164 * int n = 1;
165 * while (KMainWindow::canBeRestored(n)){
166 * (new childMW)->restore(n);
167 * n++;
168 * }
169 * } else {
170 * // create default application as usual
171 * }
172 * \endcode
173 * Note that if \a show is \c true (default), QWidget::show() is called
174 * implicitly in restore.
175 *
176 * With this you can easily restore all top-level windows of your
177 * application.
178 *
179 * If your application uses different kinds of top-level
180 * windows, then you can use KMainWindow::classNameOfToplevel(n)
181 * to determine the exact type before calling the childMW
182 * constructor in the example from above.
183 *
184 * \note You don't need to deal with this function. Use the
185 * kRestoreMainWindows() convenience template function instead!
186 *
187 * \a numberOfInstances The number of KMainWindow instances from the last session.
188 *
189 * \a show Whether the KMainWindow instances will be visible by default.
190 *
191 * Returns \c true if the session contained
192 * the same number of instances as the requested number,
193 * \c false if the session contained less instances than the requested number,
194 * in which case no configuration is changed.
195 *
196 * \sa kRestoreMainWindows()
197 * \sa readProperties()
198 * \sa canBeRestored()
199 */
200 bool restore(int numberOfInstances, bool show = true);
201
202 /*!
203 * Returns \c true if there is a menubar, \c false otherwise.
204 */
205 bool hasMenuBar();
206
207 /*!
208 * Returns The list of members of the KMainWindow class.
209 */
210 static QList<KMainWindow *> memberList();
211
212 /*!
213 * \brief This is useful to both call specific toolbars that have been created
214 * or to generate a default one upon call.
215 *
216 * This refers to toolbars created dynamically from the XML UI
217 * framework via KConfig or appnameui.rc.
218 *
219 * If the toolbar does not exist, one will be created.
220 *
221 * \a name The internal name of the toolbar. If no name is specified,
222 * "mainToolBar" is assumed.
223 *
224 * Returns A pointer to the toolbar with the specified name.
225 * \sa toolBars()
226 **/
227 KToolBar *toolBar(const QString &name = QString());
228
229 /*!
230 * Returns a list of all toolbars for this window
231 */
232 QList<KToolBar *> toolBars() const;
233
234 /*!
235 * \brief This enables autosave of toolbar/menubar/statusbar settings
236 * (and optionally window size).
237 *
238 * \a groupName A name that identifies the type of window.
239 * You can have several types of window in the same application.
240 * If no \a groupName is specified, the value defaults to "MainWindow".
241 *
242 * \a saveWindowSize Whether to include the window size
243 * when saving. \c true by default.
244 *
245 * If the *bars were modified when the window is closed,
246 * \c {saveMainWindowSettings( KConfigGroup(KSharedConfig::openConfig(), groupName) )} will be called.
247 *
248 * Typically, you will call setAutoSaveSettings() in your
249 * KMainWindow-inherited class constructor, and it will take care
250 * of restoring and saving automatically.
251 *
252 * By default, this generates an
253 * appnamerc ini file as if using default KConfig constructor or KConfig::SimpleConfig.
254 *
255 * Make sure you call this \b after all your *bars have been created.
256 *
257 * To make sure that KMainWindow properly obtains the default
258 * size of the window you should do the following:
259 * - Remove hardcoded resize() calls in the constructor or main
260 * to let the automatic resizing determine the default window size.
261 * Hardcoded window sizes will be wrong for users that have big fonts,
262 * use different styles, long/small translations, large toolbars, and other factors.
263 * - Put the setAutoSaveSettings() call after all widgets
264 * have been created and placed inside the main window
265 * (for most apps this means QMainWindow::setCentralWidget())
266 * - QWidget-based objects should overload "virtual QSize sizeHint() const;"
267 * to specify a default size.
268 * \sa KConfig
269 * \sa KSharedConfig
270 * \sa saveMainWindowSettings()
271 * \sa toolBar()
272 * \sa KXmlGuiWindow::setupGUI()
273 */
274 void setAutoSaveSettings(const QString &groupName = QStringLiteral("MainWindow"), bool saveWindowSize = true);
275
276 /*!
277 * \overload KMainWindow::setAutoSaveSettings(const QString &groupName = QStringLiteral("MainWindow"), bool saveWindowSize = true)
278 *
279 * This allows the settings to be saved into a different file
280 * that does not correspond to that used for KSharedConfig::openConfig().
281 *
282 * \a group A name that identifies the type of window.
283 * You can have several types of window in the same application.
284 *
285 * \a saveWindowSize Whether to include the window size
286 * when saving. \c true by default.
287 *
288 * \sa setAutoSaveSettings(const QString &groupName, bool saveWindowSize)
289 * \sa KConfig
290 * \sa KSharedConfig
291 * \since 4.1
292 */
293 void setAutoSaveSettings(const KConfigGroup &group, bool saveWindowSize = true);
294
295 /*!
296 * \brief Disables the autosave settings feature.
297 * You don't normally need to call this, ever.
298 * \sa setAutoSaveSettings()
299 * \sa autoSaveSettings()
300 */
301 void resetAutoSaveSettings();
302
303 /*!
304 * Returns \c true if setAutoSaveSettings() was called,
305 * \c false by default or if resetAutoSaveSettings() was called.
306 * \sa setAutoSaveSettings()
307 * \sa resetAutoSaveSettings()
308 */
309 bool autoSaveSettings() const;
310
311 /*!
312 * Returns The group used for autosaving settings.
313 *
314 * Do not mistake this with autoSaveConfigGroup.
315 *
316 * Only meaningful if setAutoSaveSettings(const QString&, bool) was called.
317 *
318 * Do not use this method if setAutoSaveSettings(const KConfigGroup&, bool) was called.
319 *
320 * This can be useful for forcing a save or an apply, e.g. before and after
321 * using KEditToolBar.
322 *
323 * \note Prefer saveAutoSaveSettings() for saving or autoSaveConfigGroup() for loading.
324 *
325 * \sa autoSaveSettings()
326 * \sa setAutoSaveSettings()
327 * \sa saveAutoSaveSettings()
328 * \sa resetAutoSaveSettings()
329 * \sa autoSaveConfigGroup()
330 */
331 QString autoSaveGroup() const;
332
333 /*!
334 * Returns The group used for autosaving settings.
335 *
336 * Only meaningful if setAutoSaveSettings(const QString&, bool) was called.
337 *
338 * Do not use this method if setAutoSaveSettings(const KConfigGroup&, bool) was called.
339 *
340 * This can be useful for forcing an apply, e.g. after using KEditToolBar.
341 *
342 * \sa setAutoSaveSettings()
343 * \sa autoSaveGroup()
344 * \since 4.1
345 */
346 KConfigGroup autoSaveConfigGroup() const;
347
348 /*!
349 * \brief Assigns the config group name for the KConfigGroup returned by stateConfigGroup.
350 *
351 * \a configGroup The config group to be assigned.
352 *
353 * Window size and state are stored in the resulting KConfigGroup when this function is called.
354 * \note If this is used in combination with setAutoSaveSettings, you should call this method first.
355 *
356 * \sa KConfigGroup
357 * \sa KSharedConfig::openStateConfig()
358 * \sa stateConfigGroup()
359 *
360 * \since 5.88
361 */
362 void setStateConfigGroup(const QString &configGroup);
363
364 /*!
365 * Returns The KConfigGroup used to store state data like window sizes or window state.
366 *
367 * The resulting group is invalid if setStateConfig is not called explicitly.
368 *
369 * \sa KConfigGroup
370 * \since 5.88
371 */
372 KConfigGroup stateConfigGroup() const;
373
374 /*!
375 * \brief Read settings for statusbar, menubar and toolbar from their respective
376 * groups in the config file and apply them.
377 *
378 * \a config Config group to read the settings from.
379 */
380 virtual void applyMainWindowSettings(const KConfigGroup &config);
381
382 /*!
383 * \brief Manually save the settings for statusbar, menubar and toolbar to their respective
384 * groups in the KConfigGroup \a config.
385 *
386 * Usage example:
387 * \code
388 * KConfigGroup group(KSharedConfig::openConfig(), "MainWindow");
389 * saveMainWindowSettings(group);
390 * \endcode
391 *
392 * \a config Config group to save the settings to.
393 * \sa setAutoSaveSettings()
394 * \sa KConfig
395 * \sa KSharedConfig
396 * \sa KConfigGroup
397 */
398 void saveMainWindowSettings(KConfigGroup &config);
399
400 /*!
401 * Returns The path for the exported window's D-Bus object.
402 * \since 4.0.1
403 */
404 QString dbusName() const;
405
406public Q_SLOTS:
407 /*!
408 * \brief Assigns a KDE compliant caption (window title).
409 *
410 * \a caption The string that will be
411 * displayed in the window title, before the application name.
412 *
413 * \note This function does the same as setPlainCaption().
414 *
415 * \note Do not include the application name
416 * in this string. It will be added automatically according to the KDE
417 * standard.
418 *
419 * \sa setPlainCaption()
420 */
421 virtual void setCaption(const QString &caption);
422 /*!
423 * \brief Makes a KDE compliant caption.
424 *
425 * \a caption Your caption.
426 *
427 * \a modified Whether the document is modified. This displays
428 * an additional sign in the title bar, usually "**".
429 *
430 * \overload
431 *
432 * \note Do not include the application name
433 * in this string. It will be added automatically according to the KDE
434 * standard.
435 */
436 virtual void setCaption(const QString &caption, bool modified);
437
438 /*!
439 * \brief Make a plain caption without any modifications.
440 *
441 * \a caption The string that will be
442 * displayed in the window title, before the application name.
443 *
444 * \note This function does the same as setCaption().
445 *
446 * \note Do not include the application name
447 * in this string. It will be added automatically according to the KDE
448 * standard.
449 *
450 * \sa setCaption()
451 */
452 virtual void setPlainCaption(const QString &caption);
453
454 /*!
455 * \brief Opens the help page for the application.
456 *
457 * The application name is
458 * used as a key to determine what to display and the system will attempt
459 * to open \<appName\>/index.html.
460 *
461 * This method is intended for use by a help button in the toolbar or
462 * components outside the regular help menu.
463 *
464 * Use helpMenu() when you
465 * want to provide access to the help system from the help menu.
466 *
467 * Example (adding a help button to the first toolbar):
468 *
469 * \code
470 * toolBar()->addAction(QIcon::fromTheme("help-contents"), i18n("Help"),
471 * this, &KMainWindow::appHelpActivated);
472 * \endcode
473 *
474 * \sa helpMenu()
475 * \sa toolBar()
476 */
477 void appHelpActivated();
478
479 /*!
480 * \brief Tell the main window that it should save its settings when being closed.
481 *
482 * This is part of the autosave settings feature.
483 *
484 * For everything related to toolbars this happens automatically,
485 * but you have to call setSettingsDirty() in the slot that toggles
486 * the visibility of the statusbar.
487 *
488 * \sa saveAutoSaveSettings()
489 */
490 void setSettingsDirty();
491
492protected:
493 /*!
494 * Reimplemented to return the \a event QEvent::Polish in order to adjust the object name
495 * if needed, once all constructor code for the main window has run.
496 * Also reimplemented to catch when a QDockWidget is added or removed.
497 *
498 * \reimp
499 */
500 bool event(QEvent *event) override;
501
502 /*!
503 * \brief Reimplemented to open context menus on Shift+F10.
504 *
505 * \a keyEvent The event assigned to a key press.
506 *
507 * \reimp
508 */
509 void keyPressEvent(QKeyEvent *keyEvent) override;
510
511 /*!
512 * Reimplemented to autosave settings and call queryClose().
513 *
514 * We recommend that you reimplement queryClose() rather than closeEvent().
515 * If you do it anyway, ensure to call the base implementation to keep
516 * the feature of autosaving window settings working.
517 *
518 * \reimp
519 */
520 void closeEvent(QCloseEvent *) override;
521
522 /*!
523 * \brief This function is called before the window is closed,
524 * either by the user or indirectly by the session manager.
525 *
526 * This can be used to prompt the user to save unsaved data before the window is closed.
527 *
528 * Usage example:
529 * \code
530 * switch ( KMessageBox::warningTwoActionsCancel( this,
531 * i18n("Save changes to document foo?"), QString(),
532 * KStandardGuiItem::save(), KStandardGuiItem::discard())) ) {
533 * case KMessageBox::PrimaryAction :
534 * // save document here. If saving fails, return false;
535 * return true;
536 * case KMessageBox::SecondaryAction :
537 * return true;
538 * default: // cancel
539 * return false;
540 * \endcode
541 *
542 * \note Do \b not close the document from within this method,
543 * as it may be called by the session manager before the
544 * session is saved. If the document is closed before the session save occurs,
545 * its location might not be properly saved. In addition, the session shutdown
546 * may be canceled, in which case the document should remain open.
547 *
548 * Returns \c true by default, \c false according to the reimplementation.
549 * Returning \c false will cancel the closing operation,
550 * and if KApplication::sessionSaving() is true, it cancels logout.
551 */
552 virtual bool queryClose();
553
554 /*!
555 * \brief Saves your instance-specific properties.
556 *
557 * The function is
558 * invoked when the session manager requests your application
559 * to save its state.
560 *
561 * Reimplement this function in child classes.
562 *
563 * Usage example:
564 * \code
565 * void MainWindow::saveProperties(KConfigGroup &config) {
566 * config.writeEntry("myKey", "newValue");
567 * ...
568 * }
569 * \endcode
570 *
571 * \note No user interaction is allowed in this function!
572 *
573 */
574 virtual void saveProperties(KConfigGroup &)
575 {
576 }
577
578 /*!
579 * \brief Reads your instance-specific properties.
580 *
581 * This function is called indirectly by restore().
582 *
583 * \code
584 * void MainWindow::readProperties(KConfigGroup &config) {
585 * if (config.hasKey("myKey")) {
586 * config.readEntry("myKey", "DefaultValue");
587 * }
588 * ...
589 * }
590 * \endcode
591 *
592 * \sa readGlobalProperties()
593 */
594 virtual void readProperties(const KConfigGroup &)
595 {
596 }
597
598 /*!
599 * \brief Saves your application-wide properties.
600 *
601 * \a sessionConfig A pointer to the KConfig instance
602 * used to save the session data.
603 *
604 * This function is invoked when the session manager
605 * requests your application to save its state.
606 * It is similar to saveProperties(), but it is only called for
607 * the first main window. This is useful to save global state of your application
608 * that isn't bound to a particular window.
609 *
610 * The default implementation does nothing.
611 *
612 * \sa readGlobalProperties()
613 * \sa saveProperties()
614 */
615 virtual void saveGlobalProperties(KConfig *sessionConfig);
616
617 /*!
618 * \brief Reads your application-wide properties.
619 *
620 * \a sessionConfig A pointer to the KConfig instance
621 * used to load the session data.
622 *
623 * \sa saveGlobalProperties()
624 * \sa readProperties()
625 *
626 */
627 virtual void readGlobalProperties(KConfig *sessionConfig);
628 void savePropertiesInternal(KConfig *, int);
629 bool readPropertiesInternal(KConfig *, int);
630
631 /*!
632 * \brief Returns whether there are unsaved changes.
633 *
634 * For inherited classes.
635 */
636 bool settingsDirty() const;
637
638protected Q_SLOTS:
639 /*!
640 * This slot should only be called in case you reimplement closeEvent() and
641 * if you are using the autosave feature. In all other cases,
642 * setSettingsDirty() should be called instead to benefit from the delayed
643 * saving.
644 *
645 * Usage example:
646 * \code
647 *
648 * void MyMainWindow::closeEvent( QCloseEvent *e )
649 * {
650 * // Save settings if autosave is enabled, and settings have changed
651 * if ( settingsDirty() && autoSaveSettings() )
652 * saveAutoSaveSettings();
653 * ..
654 * }
655 * \endcode
656 *
657 * \sa setAutoSaveSettings()
658 * \sa setSettingsDirty()
659 */
660 void saveAutoSaveSettings();
661
662protected:
663 KXMLGUI_NO_EXPORT KMainWindow(KMainWindowPrivate &dd, QWidget *parent, Qt::WindowFlags f);
664
665 std::unique_ptr<KMainWindowPrivate> const d_ptr;
666
667private:
668 Q_DECLARE_PRIVATE(KMainWindow)
669
670 Q_PRIVATE_SLOT(d_func(), void _k_slotSettingsChanged(int))
671 Q_PRIVATE_SLOT(d_func(), void _k_slotSaveAutoSaveSize())
672 Q_PRIVATE_SLOT(d_func(), void _k_slotSaveAutoSavePosition())
673};
674
675/*!
676 * \macro KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS
677 *
678 * \relates KMainWindow
679 *
680 * Returns the maximal number of arguments that are actually
681 * supported by kRestoreMainWindows().
682 **/
683#define KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS 3
684
685/*!
686 * \fn template<typename T> void kRestoreMainWindows()
687 * \brief Restores the last session. (To be used in your main function).
688 *
689 * \relates KMainWindow
690 *
691 * These functions work also if you have more than one kind of top-level
692 * widget (each derived from KMainWindow, of course).
693 *
694 * Imagine you have three kinds of top-level widgets: the classes \c ChildMW1,
695 * \c ChildMW2 and \c ChildMW3. Then you can just do:
696 *
697 * \code
698 * int main(int argc, char *argv[])
699 * {
700 * // [...]
701 * if (qApp->isSessionRestored())
702 * kRestoreMainWindows<ChildMW1, ChildMW2, ChildMW3>();
703 * else {
704 * // create default application as usual
705 * }
706 * // [...]
707 * }
708 * \endcode
709 *
710 * kRestoreMainWindows will create (on the heap) as many instances
711 * of your main windows as have existed in the last session and
712 * call KMainWindow::restore() with the correct arguments. Note that
713 * also QWidget::show() is called implicitly.
714 *
715 * Currently, these functions are provided for up to three
716 * template arguments. If you need more, tell us. To help you in
717 * deciding whether or not you can use kRestoreMainWindows, a
718 * define KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS is provided.
719 *
720 * \note Prefer this function over directly calling KMainWindow::restore().
721 *
722 * \sa KMainWindow::restore()
723 * \sa KMainWindow::classNameOfToplevel()
724 */
725template<typename T>
726inline void kRestoreMainWindows()
727{
728 for (int n = 1; KMainWindow::canBeRestored(numberOfInstances: n); ++n) {
729 const QString className = KMainWindow::classNameOfToplevel(instanceNumber: n);
730 if (className == QLatin1String(T::staticMetaObject.className())) {
731 (new T)->restore(n);
732 }
733 }
734}
735
736template<typename T0, typename T1, typename... Tn>
737inline void kRestoreMainWindows()
738{
739 kRestoreMainWindows<T0>();
740 kRestoreMainWindows<T1, Tn...>();
741}
742
743#endif
744

source code of kxmlgui/src/kmainwindow.h