aboutsummaryrefslogtreecommitdiff
path: root/src/gui/kwindowstatesaver.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kwindowstatesaver.h')
-rw-r--r--src/gui/kwindowstatesaver.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/gui/kwindowstatesaver.h b/src/gui/kwindowstatesaver.h
new file mode 100644
index 00000000..47b6ae95
--- /dev/null
+++ b/src/gui/kwindowstatesaver.h
@@ -0,0 +1,144 @@
+/*
+ SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#ifndef KWINDOWSTATESAVER_H
+#define KWINDOWSTATESAVER_H
+
+#include <kconfiggroup.h>
+#include <kconfiggui_export.h>
+
+#include <QObject>
+
+class QWindow;
+class KWindowStateSaverPrivate;
+
+/**
+ * Saves and restores a window size and (when possible) position.
+ *
+ * This is useful for retrofitting persisting window geometry on existing windows or dialogs,
+ * without having to modify those classes themselves, or having to inherit from them.
+ * For this, create a new instance of KWindowStateSaver for every window that should have it's
+ * state persisted, and pass it the window or widget as well as the config group the state
+ * should be stored in. The KWindowStateSaver will restore an existing state and then monitor
+ * the window for subsequent changes to persist. It will delete itself once the window is
+ * deleted.
+ *
+ * @code
+ * QPrintPreviewDialog dlg = ...
+ * new KWindowStateSaver(&dlg, "printPreviewDialogState");
+ * ...
+ * dlg.exec();
+ * @endcode
+ *
+ * Note that freshly created top-level QWidgets (such as the dialog in the above example)
+ * do not have an associated QWindow yet (ie. windowHandle() return @c nullptr). KWindowStateSaver
+ * supports this with its QWidget constructors which will monitor the widget for having
+ * its associated QWindow created before continuing with that.
+ *
+ * When implementing your own windows/dialogs, using KWindowConfig directly can be an
+ * alternative.
+ *
+ * @see KWindowConfig
+ * @since 5.92
+ */
+class KCONFIGGUI_EXPORT KWindowStateSaver : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * Create a new window state saver for @p window.
+ * @param configGroup A KConfigGroup that holds the window state.
+ */
+ explicit KWindowStateSaver(QWindow *window, const KConfigGroup &configGroup);
+ /**
+ * Create a new window state saver for @p window.
+ * @param configGroupName The name of a KConfigGroup in the default state
+ * configuration (see KSharedConfig::openStateConfig) that holds the window state.
+ */
+ explicit KWindowStateSaver(QWindow *window, const QString &configGroupName);
+ /**
+ * Create a new window state saver for @p window.
+ * @param configGroupName The name of a KConfigGroup in the default state
+ * configuration (see KSharedConfig::openStateConfig) that holds the window state.
+ */
+ explicit KWindowStateSaver(QWindow *window, const char *configGroupName);
+
+ /**
+ * Create a new window state saver for @p widget.
+ * Use this for widgets that aren't shown yet and would still return @c nullptr from windowHandle().
+ * @param configGroup A KConfigGroup that holds the window state.
+ */
+ template<typename Widget>
+ explicit inline KWindowStateSaver(Widget *widget, const KConfigGroup &configGroup);
+ /**
+ * Create a new window state saver for @p widget.
+ * Use this for widgets that aren't shown yet and would still return @c nullptr from windowHandle().
+ * @param configGroupName The name of a KConfigGroup in the default state
+ * configuration (see KSharedConfig::openStateConfig) that holds the window state.
+ */
+ template<typename Widget>
+ explicit inline KWindowStateSaver(Widget *widget, const QString &configGroupName);
+ /**
+ * Create a new window state saver for @p widget.
+ * Use this for widgets that aren't shown yet and would still return @c nullptr from windowHandle().
+ * @param configGroupName The name of a KConfigGroup in the default state
+ * configuration (see KSharedConfig::openStateConfig) that holds the window state.
+ */
+ template<typename Widget>
+ explicit inline KWindowStateSaver(Widget *widget, const char *configGroupName);
+
+ ~KWindowStateSaver();
+
+private:
+ void timerEvent(QTimerEvent *event) override;
+ bool eventFilter(QObject *watched, QEvent *event) override;
+
+ // API used by template code, so technically part of the ABI
+ void initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const KConfigGroup &configGroup);
+ void initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const QString &configGroupName);
+ void initWidget(QObject *widget, const std::function<QWindow *()> &windowHandleCallback, const char *configGroupName);
+
+ // cannot use std::unique_ptr due to the template ctors
+ // not seeing the full private class
+ KWindowStateSaverPrivate *d = nullptr;
+};
+
+template<typename Widget>
+KWindowStateSaver::KWindowStateSaver(Widget *widget, const KConfigGroup &configGroup)
+ : QObject(widget)
+{
+ initWidget(
+ widget,
+ [widget]() {
+ return widget->windowHandle();
+ },
+ configGroup);
+}
+
+template<typename Widget>
+KWindowStateSaver::KWindowStateSaver(Widget *widget, const QString &configGroupName)
+ : QObject(widget)
+{
+ initWidget(
+ widget,
+ [widget]() {
+ return widget->windowHandle();
+ },
+ configGroupName);
+}
+
+template<typename Widget>
+KWindowStateSaver::KWindowStateSaver(Widget *widget, const char *configGroupName)
+ : QObject(widget)
+{
+ initWidget(
+ widget,
+ [widget]() {
+ return widget->windowHandle();
+ },
+ configGroupName);
+}
+
+#endif // KWINDOWSTATESAVER_H