1/*
2 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#ifndef KWINDOWSTATESAVER_H
7#define KWINDOWSTATESAVER_H
8
9#include <kconfiggroup.h>
10#include <kconfiggui_export.h>
11
12#include <QObject>
13
14class QWindow;
15class KWindowStateSaverPrivate;
16
17/*!
18 * \class KWindowStateSaver
19 * \inmodule KConfigGui
20 *
21 * \brief Saves and restores a window size and (when possible) position.
22 *
23 * This is useful for retrofitting persisting window geometry on existing windows or dialogs,
24 * without having to modify those classes themselves, or having to inherit from them.
25 * For this, create a new instance of KWindowStateSaver for every window that should have it's
26 * state persisted, and pass it the window or widget as well as the config group the state
27 * should be stored in. The KWindowStateSaver will restore an existing state and then monitor
28 * the window for subsequent changes to persist. It will delete itself once the window is
29 * deleted.
30 *
31 * \code
32 * QPrintPreviewDialog dlg = ...
33 * new KWindowStateSaver(&dlg, "printPreviewDialogState");
34 * ...
35 * dlg.exec();
36 * \endcode
37 *
38 * Note that freshly created top-level QWidgets (such as the dialog in the above example)
39 * do not have an associated QWindow yet (ie. windowHandle() return \c nullptr). KWindowStateSaver
40 * supports this with its QWidget constructors which will monitor the widget for having
41 * its associated QWindow created before continuing with that.
42 *
43 * When implementing your own windows/dialogs, using KWindowConfig directly can be an
44 * alternative.
45 *
46 * \sa KWindowConfig
47 * \since 5.92
48 */
49class KCONFIGGUI_EXPORT KWindowStateSaver : public QObject
50{
51 Q_OBJECT
52public:
53 /*!
54 * Create a new window state saver for \a window.
55 *
56 * \a configGroup A KConfigGroup that holds the window state.
57 */
58 explicit KWindowStateSaver(QWindow *window, const KConfigGroup &configGroup);
59 /*!
60 * Create a new window state saver for \a window.
61 *
62 * \a configGroupName The name of a KConfigGroup in the default state
63 * configuration (see KSharedConfig::openStateConfig) that holds the window state.
64 */
65 explicit KWindowStateSaver(QWindow *window, const QString &configGroupName);
66
67 /*!
68 * Create a new window state saver for \a widget.
69 *
70 * Use this for widgets that aren't shown yet and would still return @c nullptr from windowHandle().
71 *
72 * \a configGroup A KConfigGroup that holds the window state.
73 */
74 template<typename Widget>
75 explicit inline KWindowStateSaver(Widget *widget, const KConfigGroup &configGroup);
76 /*!
77 * Create a new window state saver for \a widget.
78 *
79 * Use this for widgets that aren't shown yet and would still return \c nullptr from windowHandle().
80 *
81 * \a configGroupName The name of a KConfigGroup in the default state
82 * configuration (see KSharedConfig::openStateConfig) that holds the window state.
83 */
84 template<typename Widget>
85 explicit inline KWindowStateSaver(Widget *widget, const QString &configGroupName);
86
87 ~KWindowStateSaver();
88
89private:
90 void timerEvent(QTimerEvent *event) override;
91 bool eventFilter(QObject *watched, QEvent *event) override;
92
93 // API used by template code, so technically part of the ABI
94 void initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const KConfigGroup &configGroup);
95 void initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const QString &configGroupName);
96
97 // cannot use std::unique_ptr due to the template ctors
98 // not seeing the full private class
99 KWindowStateSaverPrivate *d = nullptr;
100};
101
102template<typename Widget>
103KWindowStateSaver::KWindowStateSaver(Widget *widget, const KConfigGroup &configGroup)
104 : QObject(widget)
105{
106 initWidget(
107 widget,
108 [widget]() {
109 return widget->windowHandle();
110 },
111 configGroup);
112}
113
114template<typename Widget>
115KWindowStateSaver::KWindowStateSaver(Widget *widget, const QString &configGroupName)
116 : QObject(widget)
117{
118 initWidget(
119 widget,
120 [widget]() {
121 return widget->windowHandle();
122 },
123 configGroupName);
124}
125
126#endif // KWINDOWSTATESAVER_H
127

source code of kconfig/src/gui/kwindowstatesaver.h