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 @@ -1,133 +1,134 @@ add_subdirectory(tests) configure_file(xmlgui/config-xmlgui.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-xmlgui.h ) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/config) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/xmlgui) set(kritawidgetutils_LIB_SRCS WidgetUtilsDebug.cpp kis_icon_utils.cpp kis_action_registry.cpp KisActionsSnapshot.cpp KoGroupButton.cpp KoProgressProxy.cpp KoFakeProgressProxy.cpp KoProgressBar.cpp KoProgressUpdater.cpp KoUpdater.cpp KoUpdaterPrivate_p.cpp KoProperties.cpp KoFileDialog.cpp KoResourcePaths.cpp KisKineticScroller.cpp KisSqueezedComboBox.cpp + KisDialogStateSaver.cpp kis_num_parser.cpp kis_spin_box_unit_manager.cpp config/kcolorscheme.cpp config/kcolorschememanager.cpp config/khelpclient.cpp config/klanguagebutton.cpp config/krecentfilesaction.cpp config/kstandardaction.cpp xmlgui/KisShortcutsEditorItem.cpp xmlgui/KisShortcutEditWidget.cpp xmlgui/KisShortcutsEditorDelegate.cpp xmlgui/KisShortcutsDialog.cpp xmlgui/KisShortcutsDialog_p.cpp xmlgui/KisShortcutsEditor.cpp xmlgui/KisShortcutsEditor_p.cpp xmlgui/kshortcutschemeseditor.cpp xmlgui/kshortcutschemeshelper.cpp xmlgui/kaboutkdedialog_p.cpp xmlgui/kactioncategory.cpp xmlgui/kactioncollection.cpp xmlgui/kbugreport.cpp xmlgui/kcheckaccelerators.cpp xmlgui/kedittoolbar.cpp xmlgui/kgesture.cpp xmlgui/kgesturemap.cpp xmlgui/khelpmenu.cpp xmlgui/kkeysequencewidget.cpp xmlgui/kmainwindow.cpp xmlgui/kmenumenuhandler_p.cpp xmlgui/kshortcutwidget.cpp xmlgui/kswitchlanguagedialog_p.cpp xmlgui/ktoggletoolbaraction.cpp xmlgui/ktoolbar.cpp xmlgui/ktoolbarhandler.cpp xmlgui/kundoactions.cpp xmlgui/kxmlguibuilder.cpp xmlgui/kxmlguiclient.cpp xmlgui/kxmlguifactory.cpp xmlgui/kxmlguifactory_p.cpp xmlgui/kxmlguiversionhandler.cpp xmlgui/kxmlguiwindow.cpp ) if (HAVE_DBUS) set(kritawidgetutils_LIB_SRCS ${kritawidgetutils_LIB_SRCS} xmlgui/kmainwindowiface.cpp ) endif() ki18n_wrap_ui(kritawidgetutils_LIB_SRCS xmlgui/KisShortcutsDialog.ui xmlgui/kshortcutwidget.ui ) qt5_add_resources(kritawidgetutils_LIB_SRCS xmlgui/kxmlgui.qrc) add_library(kritawidgetutils SHARED ${kritawidgetutils_LIB_SRCS}) target_include_directories(kritawidgetutils PUBLIC $ $ ) generate_export_header(kritawidgetutils BASE_NAME kritawidgetutils) if (HAVE_DBUS) set (KRITA_WIDGET_UTILS_EXTRA_LIBS ${KRITA_WIDGET_UTILS_EXTRA_LIBS} Qt5::DBus) endif () if (APPLE) find_library(FOUNDATION_LIBRARY Foundation) set(KRITA_WIDGET_UTILS_EXTRA_LIBS ${KRITA_WIDGET_UTILS_EXTRA_LIBS} ${FOUNDATION_LIBRARY}) endif () target_link_libraries(kritawidgetutils PUBLIC Qt5::Widgets Qt5::Gui Qt5::Xml Qt5::Core KF5::ItemViews kritaglobal PRIVATE Qt5::PrintSupport KF5::I18n KF5::ConfigCore KF5::CoreAddons KF5::ConfigGui KF5::GuiAddons KF5::WidgetsAddons KF5::WindowSystem kritaplugin kritaodf ${KRITA_WIDGET_UTILS_EXTRA_LIBS} ) set_target_properties(kritawidgetutils PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION} ) install(TARGETS kritawidgetutils ${INSTALL_TARGETS_DEFAULT_ARGS}) 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 + * + * 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +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(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 &dialogName, 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 = widget->objectName(); + + QVariant defaultValue; + if (defaults.contains(widgetName)) { + defaultValue = defaults[widgetName]; + } + + if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setChecked(defaultValue.toBool()); + } + else { + qobject_cast(widget)->setChecked(group.readEntry(widgetName, qobject_cast(widget)->isChecked())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setCurrentIndex(defaultValue.toInt()); + } + else { + qobject_cast(widget)->setCurrentIndex(group.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.readEntry(widgetName, qobject_cast(widget)->text())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setValue(defaultValue.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.readEntry(widgetName, qobject_cast(widget)->value())); + } + } + else if (qobject_cast(widget)) { + if (defaultValue.isValid()) { + qobject_cast(widget)->setValue(defaultValue.toDouble()); + } + else { + qobject_cast(widget)->setValue(group.readEntry(widgetName, qobject_cast(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 + * + * 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 +#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 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 &defaults = 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 @@ -1,17 +1,29 @@ set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) include_directories ( ${CMAKE_SOURCE_DIR}/libs/widgetutils ${CMAKE_SOURCE_DIR}/sdk/tests ) include(ECMAddTests) ecm_add_tests( KisActionsSnapshotTest.cpp KoPropertiesTest.cpp kis_simple_math_parser_test.cpp # FIXME this test should be in the ui directory TestKoProgressUpdater.cpp TestSqueezedComboBox.cpp 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 +#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"] = 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/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 +#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 @@ + + + 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 + + + + + +