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@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 [Lice= nse: UNKNOWN] * A +15 -0 libs/widgetutils/tests/KisDialogStateSaverTest.h [Licens= e: 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 wh= ich are listed at that page. https://invent.kde.org/kde/krita/commit/b2cb529a87345b947f7e53233e3333575d6= e6fa4 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/Ki= sDialogStateSaver.cpp new file mode 100644 index 0000000000..1dbf6c4328 --- /dev/null +++ b/libs/widgetutils/KisDialogStateSaver.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2019 Boudewijn Rempt + * + * 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-13= 01, USA. + */ +#include "KisDialogStateSaver.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +void KisDialogStateSaver::saveState(QWidget *parent, const QString &dialog= Name) +{ + Q_ASSERT(parent); + Q_ASSERT(!dialogName.isEmpty()); + + KConfigGroup group(KSharedConfig::openConfig(), dialogName); + Q_FOREACH(QWidget *widget, parent->findChildren(QString())) { + + if (widget && !widget->objectName().isEmpty() ) { + if (qobject_cast(widget)) { + group.writeEntry(widget->objectName(), qobject_cast(widget)->isChecked()); + } + else if (qobject_cast(widget)) { + group.writeEntry(widget->objectName(), qobject_cast(widget)->currentIndex()); + } + else if (qobject_cast(widget)) { + group.writeEntry(widget->objectName(), qobject_cast(widget)->text()); + } + else if (qobject_cast(widget)) { + group.writeEntry(widget->objectName(), qobject_cast(widget)->value()); + } + else if (qobject_cast(widget)) { + group.writeEntry(widget->objectName(), qobject_cast(widget)->value()); + } + else if (qobject_cast(widget)) { + group.writeEntry(widget->objectName(), qobject_cast(widget)->value()); + } + else { + //qWarning() << "Cannot save state for object" << widget; + } + + } + } +} + +void KisDialogStateSaver::restoreState(QWidget *parent, const QString &dia= logName, const QMap &defaults) +{ + Q_ASSERT(parent); + Q_ASSERT(!dialogName.isEmpty()); + + KConfigGroup group( KSharedConfig::openConfig(), dialogName); + + Q_FOREACH(QWidget *widget, parent->findChildren(QString())) { + + if (widget && !widget->objectName().isEmpty()) { + + QString widgetName =3D widget->objectName(); + + QVariant defaultValue; + if (defaults.contains(widgetName)) { + defaultValue =3D defaults[widgetName]; + } + + if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setChecked(defaultVa= lue.toBool()); + } + else { + qobject_cast(widget)->setChecked(group.rea= dEntry(widgetName, qobject_cast(widget)->isChecked())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setCurrentIndex(defa= ultValue.toInt()); + } + else { + qobject_cast(widget)->setCurrentIndex(grou= p.readEntry(widgetName, qobject_cast(widget)->currentIndex= ())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setText(defaultValue= .toString()); + } + else { + qobject_cast(widget)->setText(group.readEn= try(widgetName, qobject_cast(widget)->text())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setValue(defau= ltValue.toInt()); + } + else { + qobject_cast(widget)->setValue(group= .readEntry(widgetName, qobject_cast(widget)->value()= )); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setValue(defaultValue= .toInt()); + } + else { + qobject_cast(widget)->setValue(group.readEn= try(widgetName, qobject_cast(widget)->value())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setValue(defaul= tValue.toDouble()); + } + else { + qobject_cast(widget)->setValue(group.= readEntry(widgetName, qobject_cast(widget)->value())); + } + + } + else { + //qWarning() << "Cannot restore state for object" << widge= t; + } + } + } +} diff --git a/libs/widgetutils/KisDialogStateSaver.h b/libs/widgetutils/KisD= ialogStateSaver.h new file mode 100644 index 0000000000..78ee33260f --- /dev/null +++ b/libs/widgetutils/KisDialogStateSaver.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 Boudewijn Rempt + * + * 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-13= 01, USA. + */ +#ifndef KISDIALOGSTATESAVER_H +#define KISDIALOGSTATESAVER_H + +#include "kritawidgetutils_export.h" + +#include +#include +#include +#include + +/** + * @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 c= ontains 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 c= ontains the child widgets + * @param dialogName the name for the section under which we will rest= ore 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 w= as a problem + */ + KRITAWIDGETUTILS_EXPORT void restoreState(QWidget *parent, const QStri= ng &dialogName, const QMap &defaults =3D QMap()); +}; + +#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/widg= etutils/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 +#include +#include +#include +#include + + +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 overrideMap; + + overrideMap["spinBox"] =3D QVariant::fromValue(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/widget= utils/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 +#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/widgetu= tils/tests/dialogsavertestwidget.ui new file mode 100644 index 0000000000..66e70b337d --- /dev/null +++ b/libs/widgetutils/tests/dialogsavertestwidget.ui @@ -0,0 +1,103 @@ + + + DialogSaverTestWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 20 + 20 + 88 + 34 + + + + PushButton + + + + + + 120 + 20 + 113 + 32 + + + + + + + + + + 120 + 60 + 52 + 32 + + + + 0 + + + 0 + + + + + + 120 + 100 + 71 + 32 + + + + 0.000000000000000 + + + + + + 330 + 30 + 20 + 160 + + + + Qt::Vertical + + + + + + 130 + 160 + 88 + 22 + + + + CheckBox + + + false + + + + + +