[krita] libs/widgetutils: Add the DialogStateSaver widget utility

Boudewijn Rempt null at kde.org
Fri May 10 13:27:13 BST 2019


Git commit b2cb529a87345b947f7e53233e3333575d6e6fa4 by Boudewijn Rempt.
Committed on 10/05/2019 at 11:25.
Pushed by rempt into branch 'master'.

Add the DialogStateSaver widget utility

These functions take a widget and save and restore the values
of input widgets. You can override the values that it restores,
which might be necessary since all input widgets are saved.

Currently supports:

QCheckBox
QComboBox
QLineEdit
QAbstractSlider
QSpinBox
QDoubleSpinBox

and classes derived from these classes.

CCMAIL:kimageshop at kde.org

M  +1    -0    libs/widgetutils/CMakeLists.txt
A  +138  -0    libs/widgetutils/KisDialogStateSaver.cpp     [License: GPL (v2+)]
A  +55   -0    libs/widgetutils/KisDialogStateSaver.h     [License: GPL (v2+)]
M  +12   -0    libs/widgetutils/tests/CMakeLists.txt
A  +49   -0    libs/widgetutils/tests/KisDialogStateSaverTest.cpp     [License: UNKNOWN]  *
A  +15   -0    libs/widgetutils/tests/KisDialogStateSaverTest.h     [License: UNKNOWN]  *
A  +103  -0    libs/widgetutils/tests/dialogsavertestwidget.ui

The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.


https://invent.kde.org/kde/krita/commit/b2cb529a87345b947f7e53233e3333575d6e6fa4

diff --git a/libs/widgetutils/CMakeLists.txt b/libs/widgetutils/CMakeLists.txt
index 92ff02afd1..6163a25966 100644
--- a/libs/widgetutils/CMakeLists.txt
+++ b/libs/widgetutils/CMakeLists.txt
@@ -24,6 +24,7 @@ set(kritawidgetutils_LIB_SRCS
     KoResourcePaths.cpp
     KisKineticScroller.cpp
     KisSqueezedComboBox.cpp
+    KisDialogStateSaver.cpp
 
     kis_num_parser.cpp
     kis_spin_box_unit_manager.cpp
diff --git a/libs/widgetutils/KisDialogStateSaver.cpp b/libs/widgetutils/KisDialogStateSaver.cpp
new file mode 100644
index 0000000000..1dbf6c4328
--- /dev/null
+++ b/libs/widgetutils/KisDialogStateSaver.cpp
@@ -0,0 +1,138 @@
+/*
+ *  Copyright (c) 2019 Boudewijn Rempt <boud at kde.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "KisDialogStateSaver.h"
+
+#include <ksharedconfig.h>
+#include <kconfiggroup.h>
+
+#include <QDebug>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QLineEdit>
+#include <QAbstractSlider>
+#include <QSpinBox>
+#include <QDoubleSpinBox>
+
+void KisDialogStateSaver::saveState(QWidget *parent, const QString &dialogName)
+{
+    Q_ASSERT(parent);
+    Q_ASSERT(!dialogName.isEmpty());
+
+    KConfigGroup group(KSharedConfig::openConfig(), dialogName);
+    Q_FOREACH(QWidget *widget, parent->findChildren<QWidget*>(QString())) {
+
+        if (widget && !widget->objectName().isEmpty() ) {
+            if (qobject_cast<QCheckBox*>(widget)) {
+                group.writeEntry(widget->objectName(), qobject_cast<const QCheckBox*>(widget)->isChecked());
+            }
+            else if (qobject_cast<QComboBox*>(widget)) {
+                group.writeEntry(widget->objectName(), qobject_cast<QComboBox*>(widget)->currentIndex());
+            }
+            else if (qobject_cast<QLineEdit*>(widget)) {
+                group.writeEntry(widget->objectName(), qobject_cast<QLineEdit*>(widget)->text());
+            }
+            else if (qobject_cast<QAbstractSlider*>(widget)) {
+                group.writeEntry(widget->objectName(), qobject_cast<QAbstractSlider*>(widget)->value());
+            }
+            else if (qobject_cast<QSpinBox*>(widget)) {
+                group.writeEntry(widget->objectName(), qobject_cast<QSpinBox*>(widget)->value());
+            }
+            else if (qobject_cast<QDoubleSpinBox*>(widget)) {
+                group.writeEntry(widget->objectName(), qobject_cast<QDoubleSpinBox*>(widget)->value());
+            }
+            else {
+                //qWarning() << "Cannot save state for object" << widget;
+            }
+
+        }
+    }
+}
+
+void KisDialogStateSaver::restoreState(QWidget *parent, const QString &dialogName, const QMap<QString, QVariant> &defaults)
+{
+    Q_ASSERT(parent);
+    Q_ASSERT(!dialogName.isEmpty());
+
+    KConfigGroup group( KSharedConfig::openConfig(), dialogName);
+
+    Q_FOREACH(QWidget *widget, parent->findChildren<QWidget*>(QString())) {
+
+        if (widget && !widget->objectName().isEmpty()) {
+
+            QString widgetName = widget->objectName();
+
+            QVariant defaultValue;
+            if (defaults.contains(widgetName)) {
+                defaultValue = defaults[widgetName];
+            }
+
+            if (qobject_cast<QCheckBox*>(widget)) {
+                if (defaultValue.isValid()) {
+                    qobject_cast<QCheckBox*>(widget)->setChecked(defaultValue.toBool());
+                }
+                else {
+                    qobject_cast<QCheckBox*>(widget)->setChecked(group.readEntry<bool>(widgetName, qobject_cast<QCheckBox*>(widget)->isChecked()));
+                }
+            }
+            else if (qobject_cast<QComboBox*>(widget)) {
+                if (defaultValue.isValid()) {
+                    qobject_cast<QComboBox*>(widget)->setCurrentIndex(defaultValue.toInt());
+                }
+                else {
+                    qobject_cast<QComboBox*>(widget)->setCurrentIndex(group.readEntry<int>(widgetName, qobject_cast<QComboBox*>(widget)->currentIndex()));
+                }
+            }
+            else if (qobject_cast<QLineEdit*>(widget)) {
+                if (defaultValue.isValid()) {
+                    qobject_cast<QLineEdit*>(widget)->setText(defaultValue.toString());
+                }
+                else {
+                    qobject_cast<QLineEdit*>(widget)->setText(group.readEntry<QString>(widgetName, qobject_cast<QLineEdit*>(widget)->text()));
+                }
+            }
+            else if (qobject_cast<QAbstractSlider*>(widget)) {
+                if (defaultValue.isValid()) {
+                    qobject_cast<QAbstractSlider*>(widget)->setValue(defaultValue.toInt());
+                }
+                else {
+                    qobject_cast<QAbstractSlider*>(widget)->setValue(group.readEntry<int>(widgetName, qobject_cast<QAbstractSlider*>(widget)->value()));
+                }
+            }
+            else if (qobject_cast<QSpinBox*>(widget)) {
+                if (defaultValue.isValid()) {
+                    qobject_cast<QSpinBox*>(widget)->setValue(defaultValue.toInt());
+                }
+                else {
+                    qobject_cast<QSpinBox*>(widget)->setValue(group.readEntry<int>(widgetName, qobject_cast<QSpinBox*>(widget)->value()));
+                }
+            }
+            else if (qobject_cast<QDoubleSpinBox*>(widget)) {
+                if (defaultValue.isValid()) {
+                    qobject_cast<QDoubleSpinBox*>(widget)->setValue(defaultValue.toDouble());
+                }
+                else {
+                    qobject_cast<QDoubleSpinBox*>(widget)->setValue(group.readEntry<int>(widgetName, qobject_cast<QDoubleSpinBox*>(widget)->value()));
+                }
+
+            }
+            else {
+                //qWarning() << "Cannot restore state for object" << widget;
+            }
+        }
+    }
+}
diff --git a/libs/widgetutils/KisDialogStateSaver.h b/libs/widgetutils/KisDialogStateSaver.h
new file mode 100644
index 0000000000..78ee33260f
--- /dev/null
+++ b/libs/widgetutils/KisDialogStateSaver.h
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2019 Boudewijn Rempt <boud at kde.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef KISDIALOGSTATESAVER_H
+#define KISDIALOGSTATESAVER_H
+
+#include "kritawidgetutils_export.h"
+
+#include <QWidget>
+#include <QString>
+#include <QMap>
+#include <QVariant>
+
+/**
+ * @brief The KisDialogStateSaver class saves state for the specified
+ * widget in the kritarc file and restores it. Simply call saveState
+ * in your dialog's destructor, and use restoreState in the constructor.
+ */
+namespace KisDialogStateSaver
+{
+    /**
+     * @brief saveState saves the state for the specified widgets
+     * @param parent the parent at the top of the QObject hierarchy that contains the child widgets
+     * @param dialogName the name for the section under which we will save the state
+     * @return true if all the widgets could be saved, false if there was a problem
+     */
+    KRITAWIDGETUTILS_EXPORT void saveState(QWidget *parent, const QString &dialogName);
+
+    /**
+     * @brief restoreState restores the state of the dialog
+     * @param parent the parent at the top of the QObject hierarchy that contains the child widgets
+     * @param dialogName the name for the section under which we will restore the state
+     * @param defaults: contains default values for widgets. If there are widgets for which no default
+     *  has been specified, the default value created by QVariant will be used.
+     * in the variant part of the map.
+     * @return true if all the widgets could be restored, false if there was a problem
+     */
+    KRITAWIDGETUTILS_EXPORT void restoreState(QWidget *parent, const QString &dialogName, const QMap<QString, QVariant> &defaults = QMap<QString, QVariant>());
+};
+
+#endif // KISDIALOGSTATESAVER_H
diff --git a/libs/widgetutils/tests/CMakeLists.txt b/libs/widgetutils/tests/CMakeLists.txt
index c90c6a8070..5a05fe2d82 100644
--- a/libs/widgetutils/tests/CMakeLists.txt
+++ b/libs/widgetutils/tests/CMakeLists.txt
@@ -15,3 +15,15 @@ ecm_add_tests(
     NAME_PREFIX "libs-widgetutils-"
     LINK_LIBRARIES kritawidgetutils kritaimage Qt5::Test
 )
+
+ki18n_wrap_ui(DialogStateSaver_SRCS
+    dialogsavertestwidget.ui
+)
+
+ecm_add_test(
+    KisDialogStateSaverTest.cpp
+    ${DialogStateSaver_SRCS}
+    TEST_NAME KisDialogStateSaverTest
+    LINK_LIBRARIES kritawidgetutils Qt5::Test KF5::ConfigCore
+    NAME_PREFIX "libs-widgetutils-")
+
diff --git a/libs/widgetutils/tests/KisDialogStateSaverTest.cpp b/libs/widgetutils/tests/KisDialogStateSaverTest.cpp
new file mode 100644
index 0000000000..5b15f743f0
--- /dev/null
+++ b/libs/widgetutils/tests/KisDialogStateSaverTest.cpp
@@ -0,0 +1,49 @@
+#include "KisDialogStateSaverTest.h"
+#include <QTest>
+#include <KisDialogStateSaver.h>
+#include <QWidget>
+#include <ksharedconfig.h>
+#include <kconfiggroup.h>
+
+
+void KisDialogStateSaverTest::testSave()
+{
+    QWidget w;
+    Ui::DialogSaverTestWidget page;
+    page.setupUi(&w);
+
+    page.lineEdit->setText("test");
+    page.spinBox->setValue(5);
+    page.doubleSpinBox->setValue(3.0);
+    page.verticalSlider->setValue(10);
+    page.checkBox->setChecked(true);
+    KisDialogStateSaver::saveState(&w, "StateSaverTest");
+    KConfigGroup group(KSharedConfig::openConfig(), "StateSaverTest");
+    QCOMPARE(group.readEntry("lineEdit", QString()), "test");
+    QCOMPARE(group.readEntry("spinBox", 0), 5);
+    QCOMPARE(group.readEntry("doubleSpinBox", 0.0), 3.0);
+    QCOMPARE(group.readEntry("verticalSlider", 0), 10);
+    QCOMPARE(group.readEntry("checkBox", false), true);
+}
+
+void KisDialogStateSaverTest::testRestore()
+{
+    QWidget w;
+    Ui::DialogSaverTestWidget page;
+    page.setupUi(&w);
+    QMap<QString, QVariant> overrideMap;
+
+    overrideMap["spinBox"] = QVariant::fromValue<int>(10);
+
+    KisDialogStateSaver::restoreState(&w, "StateSaverTest", overrideMap);
+
+    QCOMPARE(page.lineEdit->text(), "test");
+    QCOMPARE(page.spinBox->value(), 10);
+    QCOMPARE(page.doubleSpinBox->value(), 3.0);
+    QCOMPARE(page.verticalSlider->value(), 10);
+    QCOMPARE(page.checkBox->isChecked(), true);
+
+}
+
+
+QTEST_MAIN(KisDialogStateSaverTest)
diff --git a/libs/widgetutils/tests/KisDialogStateSaverTest.h b/libs/widgetutils/tests/KisDialogStateSaverTest.h
new file mode 100644
index 0000000000..c36a05a31f
--- /dev/null
+++ b/libs/widgetutils/tests/KisDialogStateSaverTest.h
@@ -0,0 +1,15 @@
+#ifndef KISDIALOGSTATESAVERTEST_H
+#define KISDIALOGSTATESAVERTEST_H
+
+#include <QTest>
+#include "ui_dialogsavertestwidget.h"
+
+class KisDialogStateSaverTest : public QObject
+{
+    Q_OBJECT
+private Q_SLOTS:
+    void testSave();
+    void testRestore();
+};
+
+#endif // KISDIALOGSTATESAVERTEST_H
diff --git a/libs/widgetutils/tests/dialogsavertestwidget.ui b/libs/widgetutils/tests/dialogsavertestwidget.ui
new file mode 100644
index 0000000000..66e70b337d
--- /dev/null
+++ b/libs/widgetutils/tests/dialogsavertestwidget.ui
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DialogSaverTestWidget</class>
+ <widget class="QWidget" name="DialogSaverTestWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <widget class="QPushButton" name="pushButton">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>20</y>
+     <width>88</width>
+     <height>34</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>PushButton</string>
+   </property>
+  </widget>
+  <widget class="QLineEdit" name="lineEdit">
+   <property name="geometry">
+    <rect>
+     <x>120</x>
+     <y>20</y>
+     <width>113</width>
+     <height>32</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string/>
+   </property>
+  </widget>
+  <widget class="QSpinBox" name="spinBox">
+   <property name="geometry">
+    <rect>
+     <x>120</x>
+     <y>60</y>
+     <width>52</width>
+     <height>32</height>
+    </rect>
+   </property>
+   <property name="singleStep">
+    <number>0</number>
+   </property>
+   <property name="value">
+    <number>0</number>
+   </property>
+  </widget>
+  <widget class="QDoubleSpinBox" name="doubleSpinBox">
+   <property name="geometry">
+    <rect>
+     <x>120</x>
+     <y>100</y>
+     <width>71</width>
+     <height>32</height>
+    </rect>
+   </property>
+   <property name="value">
+    <double>0.000000000000000</double>
+   </property>
+  </widget>
+  <widget class="QSlider" name="verticalSlider">
+   <property name="geometry">
+    <rect>
+     <x>330</x>
+     <y>30</y>
+     <width>20</width>
+     <height>160</height>
+    </rect>
+   </property>
+   <property name="orientation">
+    <enum>Qt::Vertical</enum>
+   </property>
+  </widget>
+  <widget class="QCheckBox" name="checkBox">
+   <property name="geometry">
+    <rect>
+     <x>130</x>
+     <y>160</y>
+     <width>88</width>
+     <height>22</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>CheckBox</string>
+   </property>
+   <property name="checked">
+    <bool>false</bool>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>



More information about the kimageshop mailing list