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

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