Explorar o código

Change ctkSettingsWidget to ctkSettingsDialog

Add "reset" and "restoreDefault" buttons
Clean up internal design of ctkSettingsPanel for easier use.
Julien Finet %!s(int64=14) %!d(string=hai) anos
pai
achega
5207a1b8d2

+ 4 - 4
Libs/Widgets/CMakeLists.txt

@@ -77,10 +77,10 @@ SET(KIT_SRCS
   ctkScreenshotDialog_p.h
   ctkSettings.cpp
   ctkSettings.h
+  ctkSettingsDialog.cpp
+  ctkSettingsDialog.h
   ctkSettingsPanel.cpp
   ctkSettingsPanel.h
-  ctkSettingsWidget.cpp
-  ctkSettingsWidget.h
   ctkSliderWidget.cpp
   ctkSliderWidget.h
   ctkTestApplication.cpp
@@ -154,8 +154,8 @@ SET(KIT_MOC_SRCS
   ctkScreenshotDialog.h
   ctkScreenshotDialog_p.h
   ctkSettings.h
+  ctkSettingsDialog.h
   ctkSettingsPanel.h
-  ctkSettingsWidget.h
   ctkSliderWidget.h
   ctkTestApplication.h
   ctkToolTipTrapper.h
@@ -183,7 +183,7 @@ SET(KIT_UI_FORMS
   Resources/UI/ctkDateRangeWidget.ui
   Resources/UI/ctkMaterialPropertyWidget.ui
   Resources/UI/ctkScreenshotDialog.ui
-  Resources/UI/ctkSettingsWidget.ui
+  Resources/UI/ctkSettingsDialog.ui
   Resources/UI/ctkSliderWidget.ui
   Resources/UI/ctkWorkflowGroupBox.ui
   )

+ 3 - 3
Libs/Widgets/Plugins/CMakeLists.txt

@@ -59,8 +59,8 @@ SET(PLUGIN_SRCS
   ctkTreeComboBoxPlugin.h
   ctkSettingsPanelPlugin.cpp
   ctkSettingsPanelPlugin.h
-  ctkSettingsWidgetPlugin.cpp
-  ctkSettingsWidgetPlugin.h
+  ctkSettingsDialogPlugin.cpp
+  ctkSettingsDialogPlugin.h
   ctkSliderWidgetPlugin.cpp
   ctkSliderWidgetPlugin.h
   ctkWorkflowButtonBoxWidgetPlugin.cpp
@@ -96,7 +96,7 @@ SET(PLUGIN_MOC_SRCS
   ctkTransferFunctionViewPlugin.h
   ctkTreeComboBoxPlugin.h
   ctkSettingsPanelPlugin.h
-  ctkSettingsWidgetPlugin.h
+  ctkSettingsDialogPlugin.h
   ctkSliderWidgetPlugin.h
   ctkWorkflowButtonBoxWidgetPlugin.h
   ctkWorkflowWidgetStepPlugin.h

+ 14 - 14
Libs/Widgets/Plugins/ctkSettingsWidgetPlugin.cpp

@@ -19,50 +19,50 @@
 =========================================================================*/
 
 // CTK includes
-#include "ctkSettingsWidgetPlugin.h"
-#include "ctkSettingsWidget.h"
+#include "ctkSettingsDialogPlugin.h"
+#include "ctkSettingsDialog.h"
 
 //-----------------------------------------------------------------------------
-ctkSettingsWidgetPlugin::ctkSettingsWidgetPlugin(QObject *pluginParent)
+ctkSettingsDialogPlugin::ctkSettingsDialogPlugin(QObject *pluginParent)
   : QObject(pluginParent)
 {
 }
 
 //-----------------------------------------------------------------------------
-QWidget *ctkSettingsWidgetPlugin::createWidget(QWidget* widgetParent)
+QWidget *ctkSettingsDialogPlugin::createWidget(QWidget* widgetParent)
 {
-  ctkSettingsWidget* newWidget = new ctkSettingsWidget(widgetParent);
+  ctkSettingsDialog* newWidget = new ctkSettingsDialog(widgetParent);
   return newWidget;
 }
 
 //-----------------------------------------------------------------------------
-QString ctkSettingsWidgetPlugin::domXml() const
+QString ctkSettingsDialogPlugin::domXml() const
 {
-  return "<widget class=\"ctkSettingsWidget\" \
-          name=\"SettingsWidget\">\n"
+  return "<widget class=\"ctkSettingsDialog\" \
+          name=\"SettingsDialog\">\n"
           "</widget>\n";
 }
 
 //-----------------------------------------------------------------------------
-QIcon ctkSettingsWidgetPlugin::icon() const
+QIcon ctkSettingsDialogPlugin::icon() const
 {
   return QIcon(":/Icons/widget.png");
 }
 
 //-----------------------------------------------------------------------------
-QString ctkSettingsWidgetPlugin::includeFile() const
+QString ctkSettingsDialogPlugin::includeFile() const
 {
-  return "ctkSettingsWidget.h";
+  return "ctkSettingsDialog.h";
 }
 
 //-----------------------------------------------------------------------------
-bool ctkSettingsWidgetPlugin::isContainer() const
+bool ctkSettingsDialogPlugin::isContainer() const
 {
   return false;
 }
 
 //-----------------------------------------------------------------------------
-QString ctkSettingsWidgetPlugin::name() const
+QString ctkSettingsDialogPlugin::name() const
 {
-  return "ctkSettingsWidget";
+  return "ctkSettingsDialog";
 }

+ 4 - 4
Libs/Widgets/Plugins/ctkSettingsWidgetPlugin.h

@@ -18,20 +18,20 @@
 
 =========================================================================*/
 
-#ifndef __ctkSettingsWidgetPlugin_h
-#define __ctkSettingsWidgetPlugin_h
+#ifndef __ctkSettingsDialogPlugin_h
+#define __ctkSettingsDialogPlugin_h
 
 // CTK includes
 #include "ctkWidgetsAbstractPlugin.h"
 
-class CTK_WIDGETS_PLUGINS_EXPORT ctkSettingsWidgetPlugin :
+class CTK_WIDGETS_PLUGINS_EXPORT ctkSettingsDialogPlugin :
   public QObject,
   public ctkWidgetsAbstractPlugin
 {
   Q_OBJECT
 
 public:
-  ctkSettingsWidgetPlugin(QObject *_parent = 0);
+  ctkSettingsDialogPlugin(QObject *_parent = 0);
   
   QWidget *createWidget(QWidget *_parent);
   QString  domXml() const;

+ 2 - 2
Libs/Widgets/Plugins/ctkWidgetsPlugins.h

@@ -46,7 +46,7 @@
 #include "ctkRangeSliderPlugin.h"
 #include "ctkRangeWidgetPlugin.h"
 #include "ctkSettingsPanelPlugin.h"
-#include "ctkSettingsWidgetPlugin.h"
+#include "ctkSettingsDialogPlugin.h"
 #include "ctkSliderWidgetPlugin.h"
 #include "ctkTransferFunctionViewPlugin.h"
 #include "ctkTreeComboBoxPlugin.h"
@@ -84,7 +84,7 @@ public:
             << new ctkRangeSliderPlugin
             << new ctkRangeWidgetPlugin
             << new ctkSettingsPanelPlugin
-            << new ctkSettingsWidgetPlugin
+            << new ctkSettingsDialogPlugin
             << new ctkSliderWidgetPlugin
             << new ctkTransferFunctionViewPlugin
             << new ctkTreeComboBoxPlugin

+ 79 - 0
Libs/Widgets/Resources/UI/ctkSettingsDialog.ui

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ctkSettingsDialog</class>
+ <widget class="QDialog" name="ctkSettingsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>690</width>
+    <height>397</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Settings</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
+   <item row="0" column="0">
+    <widget class="QTreeWidget" name="SettingsTreeWidget">
+     <property name="headerHidden">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string notr="true">1</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QStackedWidget" name="SettingsStackedWidget"/>
+   </item>
+   <item row="1" column="0" colspan="2">
+    <widget class="QDialogButtonBox" name="SettingsButtonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Ok|QDialogButtonBox::Reset|QDialogButtonBox::RestoreDefaults</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>SettingsButtonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>ctkSettingsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>SettingsButtonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>ctkSettingsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

+ 0 - 39
Libs/Widgets/Resources/UI/ctkSettingsWidget.ui

@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ctkSettingsWidget</class>
- <widget class="QWidget" name="ctkSettingsWidget">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>693</width>
-    <height>300</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>Settings</string>
-  </property>
-  <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
-   <property name="margin">
-    <number>0</number>
-   </property>
-   <item>
-    <widget class="QTreeWidget" name="SettingsTreeWidget">
-     <property name="headerHidden">
-      <bool>true</bool>
-     </property>
-     <column>
-      <property name="text">
-       <string notr="true">1</string>
-      </property>
-     </column>
-    </widget>
-   </item>
-   <item>
-    <widget class="QStackedWidget" name="SettingsStackedWidget"/>
-   </item>
-  </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>

+ 2 - 2
Libs/Widgets/Testing/Cpp/CMakeLists.txt

@@ -34,7 +34,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cxx
   ctkDateRangeWidgetTest1.cpp
   ctkSettingsPanelTest1.cpp
   ctkSettingsTest1.cpp
-  ctkSettingsWidgetTest1.cpp
+  ctkSettingsDialogTest1.cpp
   ctkSliderWidgetTest1.cpp
   ctkTreeComboBoxTest1.cpp
   ctkWorkflowWidgetTest1.cpp
@@ -110,7 +110,7 @@ SIMPLE_TEST( ctkRangeWidgetTest1 )
 SIMPLE_TEST( ctkDateRangeWidgetTest1 )
 SIMPLE_TEST( ctkSettingsPanelTest1 )
 SIMPLE_TEST( ctkSettingsTest1 )
-SIMPLE_TEST( ctkSettingsWidgetTest1 )
+SIMPLE_TEST( ctkSettingsDialogTest1 )
 SIMPLE_TEST( ctkSliderWidgetTest1 )
 SIMPLE_TEST( ctkTreeComboBoxTest1 )
 SIMPLE_TEST( ctkWorkflowWidgetTest1 )

+ 19 - 11
Libs/Widgets/Testing/Cpp/ctkSettingsWidgetTest1.cpp

@@ -26,33 +26,34 @@
 
 // CTK includes
 #include "ctkSettingsPanel.h"
-#include "ctkSettingsWidget.h"
+#include "ctkSettingsDialog.h"
 
 // STD includes
 #include <stdlib.h>
 #include <iostream>
 
 //-----------------------------------------------------------------------------
-int ctkSettingsWidgetTest1(int argc, char * argv [] )
+int ctkSettingsDialogTest1(int argc, char * argv [] )
 {
   QApplication app(argc, argv);
   
   QSettings settings(QSettings::IniFormat, QSettings::UserScope, "Common ToolKit", "CTK");
+  settings.remove("key 1");
 
-  ctkSettingsWidget settingsWidget;
-  settingsWidget.setSettings(&settings);
+  ctkSettingsDialog settingsDialog;
+  settingsDialog.setSettings(&settings);
 
   ctkSettingsPanel* panel1 = new ctkSettingsPanel;
-  settingsWidget.addPanel("Panel 1", panel1); 
+  settingsDialog.addPanel("Panel 1", panel1); 
   if (panel1->settings() != &settings)
     {
-    std::cerr << "ctkSettingsWidget::addPanel settings failed" << panel1->settings() << std::endl;
+    std::cerr << "ctkSettingsDialog::addPanel settings failed" << panel1->settings() << std::endl;
     return EXIT_FAILURE;
     }
-  settingsWidget.addPanel("Panel 2", new ctkSettingsPanel);
-  settingsWidget.addPanel("Panel 3", new ctkSettingsPanel);
+  settingsDialog.addPanel("Panel 2", new ctkSettingsPanel);
+  settingsDialog.addPanel("Panel 3", new ctkSettingsPanel);
   ctkSettingsPanel* panel4 = new ctkSettingsPanel;
-  settingsWidget.addPanel("Panel 4", panel4, panel1);
+  settingsDialog.addPanel("Panel 4", panel4, panel1);
 
   QCheckBox* box = new QCheckBox(panel4);
   box->setChecked(false); // false by default but we just want to make sure
@@ -72,10 +73,17 @@ int ctkSettingsWidgetTest1(int argc, char * argv [] )
     std::cerr << "Saving to settings failed" << std::endl;
     return EXIT_FAILURE;
     }
+  settingsDialog.resetSettings();
+  boxVal = settings.value("key 1");
+  if (!boxVal.isValid() || boxVal.toBool() != false)
+    {
+    std::cerr << "Reset failed" << std::endl;
+    return EXIT_FAILURE;
+    }
 
-  settingsWidget.setCurrentPanel("Panel 4");
+  settingsDialog.setCurrentPanel("Panel 4");
 
-  settingsWidget.show();
+  settingsDialog.show();
       
   if (argc < 2 || QString(argv[1]) != "-I" )
     {

+ 111 - 36
Libs/Widgets/ctkSettingsWidget.cpp

@@ -21,24 +21,25 @@
 // Qt includes
 #include <QDebug>
 #include <QMap>
+#include <QPushButton>
 #include <QSettings>
 
 // CTK includes
 #include "ctkSettingsPanel.h"
-#include "ctkSettingsWidget.h"
-#include "ui_ctkSettingsWidget.h"
+#include "ctkSettingsDialog.h"
+#include "ui_ctkSettingsDialog.h"
 #include "ctkLogger.h"
 
-static ctkLogger logger("org.commontk.libs.widgets.ctkSettingsWidget");
+static ctkLogger logger("org.commontk.libs.widgets.ctkSettingsDialog");
 
 //-----------------------------------------------------------------------------
-class ctkSettingsWidgetPrivate: public Ui_ctkSettingsWidget
+class ctkSettingsDialogPrivate: public Ui_ctkSettingsDialog
 {
-  Q_DECLARE_PUBLIC(ctkSettingsWidget);
+  Q_DECLARE_PUBLIC(ctkSettingsDialog);
 protected:
-  ctkSettingsWidget* const q_ptr;
+  ctkSettingsDialog* const q_ptr;
 public:
-  ctkSettingsWidgetPrivate(ctkSettingsWidget& object);
+  ctkSettingsDialogPrivate(ctkSettingsDialog& object);
   void init();
 
   ctkSettingsPanel* panel(QTreeWidgetItem* item)const;
@@ -55,37 +56,39 @@ protected:
 };
 
 // --------------------------------------------------------------------------
-ctkSettingsWidgetPrivate::ctkSettingsWidgetPrivate(ctkSettingsWidget& object)
+ctkSettingsDialogPrivate::ctkSettingsDialogPrivate(ctkSettingsDialog& object)
   :q_ptr(&object)
 {
   this->Settings = 0;
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidgetPrivate::init()
+void ctkSettingsDialogPrivate::init()
 {
-  Q_Q(ctkSettingsWidget);
+  Q_Q(ctkSettingsDialog);
   this->setupUi(q);
 
   QObject::connect(this->SettingsTreeWidget,
     SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
     q, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+  QObject::connect(this->SettingsButtonBox, SIGNAL(clicked(QAbstractButton*)),
+                   q, SLOT(onDialogButtonClicked(QAbstractButton*)));
 }
 
 // --------------------------------------------------------------------------
-ctkSettingsPanel* ctkSettingsWidgetPrivate::panel(QTreeWidgetItem* item)const
+ctkSettingsPanel* ctkSettingsDialogPrivate::panel(QTreeWidgetItem* item)const
 {
   return this->Panels.value(item, 0);
 }
 
 // --------------------------------------------------------------------------
-QTreeWidgetItem* ctkSettingsWidgetPrivate::item(ctkSettingsPanel* panel)const
+QTreeWidgetItem* ctkSettingsDialogPrivate::item(ctkSettingsPanel* panel)const
 {
   return this->Panels.key(panel, this->SettingsTreeWidget->invisibleRootItem());
 }
 
 // --------------------------------------------------------------------------
-QTreeWidgetItem* ctkSettingsWidgetPrivate::item(const QString& label)const
+QTreeWidgetItem* ctkSettingsDialogPrivate::item(const QString& label)const
 {
   QMap<QTreeWidgetItem*, ctkSettingsPanel*>::const_iterator it;
   for (it = this->Panels.constBegin(); it != this->Panels.constEnd(); ++it)
@@ -99,30 +102,30 @@ QTreeWidgetItem* ctkSettingsWidgetPrivate::item(const QString& label)const
 }
 
 // --------------------------------------------------------------------------
-ctkSettingsWidget::ctkSettingsWidget(QWidget* _parent)
+ctkSettingsDialog::ctkSettingsDialog(QWidget* _parent)
   : Superclass(_parent)
-  , d_ptr(new ctkSettingsWidgetPrivate(*this))
+  , d_ptr(new ctkSettingsDialogPrivate(*this))
 {
-  Q_D(ctkSettingsWidget);
+  Q_D(ctkSettingsDialog);
   d->init();
 }
 
 // --------------------------------------------------------------------------
-ctkSettingsWidget::~ctkSettingsWidget()
+ctkSettingsDialog::~ctkSettingsDialog()
 {
 }
 
 // --------------------------------------------------------------------------
-QSettings* ctkSettingsWidget::settings()const
+QSettings* ctkSettingsDialog::settings()const
 {
-  Q_D(const ctkSettingsWidget);
+  Q_D(const ctkSettingsDialog);
   return d->Settings;
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget::setSettings(QSettings* settings)
+void ctkSettingsDialog::setSettings(QSettings* settings)
 {
-  Q_D(ctkSettingsWidget);
+  Q_D(ctkSettingsDialog);
 
   d->Settings = settings;
   foreach(ctkSettingsPanel* panel, d->Panels.values())
@@ -132,10 +135,10 @@ void ctkSettingsWidget::setSettings(QSettings* settings)
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget
+void ctkSettingsDialog
 ::addPanel(ctkSettingsPanel* panel, ctkSettingsPanel* parentPanel)
 {
-  Q_D(ctkSettingsWidget);
+  Q_D(ctkSettingsDialog);
   QTreeWidgetItem* newPanelItem = new QTreeWidgetItem;
   newPanelItem->setText(0, panel->windowTitle());
   newPanelItem->setIcon(0, panel->windowIcon());
@@ -146,12 +149,12 @@ void ctkSettingsWidget
   d->SettingsStackedWidget->addWidget(panel);
 
   connect(panel, SIGNAL(settingChanged(const QString&, const QVariant&)),
-          this, SIGNAL(settingChanged(const QString&, const QVariant&)));
+          this, SLOT(onSettingChanged(const QString&, const QVariant&)));
   panel->setSettings(this->settings());
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget
+void ctkSettingsDialog
 ::addPanel(const QString& label, ctkSettingsPanel* panel, 
            ctkSettingsPanel* parentPanel)
 {
@@ -160,7 +163,7 @@ void ctkSettingsWidget
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget
+void ctkSettingsDialog
 ::addPanel(const QString& label, const QIcon& icon,
            ctkSettingsPanel* panel, ctkSettingsPanel* parentPanel)
 {
@@ -170,32 +173,32 @@ void ctkSettingsWidget
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget::setCurrentPanel(ctkSettingsPanel* panel)
+void ctkSettingsDialog::setCurrentPanel(ctkSettingsPanel* panel)
 {
-  Q_D(ctkSettingsWidget);
+  Q_D(ctkSettingsDialog);
   // eventually calls onCurrentItemChanged() where all the work is done
   d->SettingsTreeWidget->setCurrentItem(d->item(panel));
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget::setCurrentPanel(const QString& label)
+void ctkSettingsDialog::setCurrentPanel(const QString& label)
 {
-  Q_D(ctkSettingsWidget);
+  Q_D(ctkSettingsDialog);
   // eventually calls onCurrentItemChanged() where all the work is done
   d->SettingsTreeWidget->setCurrentItem(d->item(label));
 }
 
 // --------------------------------------------------------------------------
-ctkSettingsPanel* ctkSettingsWidget::currentPanel()const
+ctkSettingsPanel* ctkSettingsDialog::currentPanel()const
 {
-  Q_D(const ctkSettingsWidget);
+  Q_D(const ctkSettingsDialog);
   return d->panel(d->SettingsTreeWidget->currentItem());
 }
 
 // --------------------------------------------------------------------------
-ctkSettingsPanel* ctkSettingsWidget::panel(const QString& label)const
+ctkSettingsPanel* ctkSettingsDialog::panel(const QString& label)const
 {
-  Q_D(const ctkSettingsWidget);
+  Q_D(const ctkSettingsDialog);
   foreach(ctkSettingsPanel* settingsPanel, d->Panels.values())
     {
     if (settingsPanel->windowTitle() == label)
@@ -207,11 +210,83 @@ ctkSettingsPanel* ctkSettingsWidget::panel(const QString& label)const
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsWidget
+void ctkSettingsDialog::accept()
+{
+  this->applySettings();
+  this->Superclass::accept();
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog::reject()
+{
+  this->resetSettings();
+  this->Superclass::accept();
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog::applySettings()
+{
+  Q_D(ctkSettingsDialog);
+  foreach(ctkSettingsPanel* panel, d->Panels.values())
+    {
+    panel->applySettings();
+    }
+  d->SettingsButtonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog::resetSettings()
+{
+  Q_D(ctkSettingsDialog);
+  foreach(ctkSettingsPanel* panel, d->Panels.values())
+    {
+    panel->resetSettings();
+    }
+  d->SettingsButtonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog::restoreDefaultSettings()
+{
+  Q_D(ctkSettingsDialog);
+  foreach(ctkSettingsPanel* panel, d->Panels.values())
+    {
+    panel->restoreDefaultSettings();
+    }
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog
+::onSettingChanged(const QString& key, const QVariant& newVal)
+{
+  Q_D(ctkSettingsDialog);
+  d->SettingsButtonBox->button(QDialogButtonBox::Reset)->setEnabled(true);
+  emit settingChanged(key, newVal);
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog
 ::onCurrentItemChanged(QTreeWidgetItem* currentItem, QTreeWidgetItem* previousItem)
 {
-  Q_D(ctkSettingsWidget);
+  Q_D(ctkSettingsDialog);
   Q_UNUSED(previousItem);
   d->SettingsStackedWidget->setCurrentWidget(
     d->panel(currentItem));
 }
+
+// --------------------------------------------------------------------------
+void ctkSettingsDialog::onDialogButtonClicked(QAbstractButton* button)
+{
+  Q_D(ctkSettingsDialog);
+  switch (d->SettingsButtonBox->standardButton(button))
+    {
+    case QDialogButtonBox::Reset:
+      this->resetSettings();
+      break;
+    case QDialogButtonBox::RestoreDefaults:
+      this->restoreDefaultSettings();
+      break;
+    default:
+      break;
+    }
+}

+ 22 - 12
Libs/Widgets/ctkSettingsWidget.h

@@ -18,32 +18,33 @@
 
 =========================================================================*/
 
-#ifndef __ctkSettingsWidget_h
-#define __ctkSettingsWidget_h
+#ifndef __ctkSettingsDialog_h
+#define __ctkSettingsDialog_h
 
 // Qt includes
-#include <QWidget>
+#include <QDialog>
 
 // CTK includes
 #include "ctkWidgetsExport.h"
 
-class ctkSettingsWidgetPrivate;
+class QAbstractButton;
+class QSettings;
 class QTreeWidgetItem;
+class ctkSettingsDialogPrivate;
 class ctkSettingsPanel;
-class QSettings;
 
-class CTK_WIDGETS_EXPORT ctkSettingsWidget : public QWidget
+class CTK_WIDGETS_EXPORT ctkSettingsDialog : public QDialog
 {
   Q_OBJECT
 public:
   /// Superclass typedef
-  typedef QWidget Superclass;
+  typedef QDialog Superclass;
 
   /// Constructor
-  explicit ctkSettingsWidget(QWidget* parent = 0);
+  explicit ctkSettingsDialog(QWidget* parent = 0);
 
   /// Destructor
-  virtual ~ctkSettingsWidget();
+  virtual ~ctkSettingsDialog();
 
   QSettings* settings()const;
   void setSettings(QSettings* settings);
@@ -61,18 +62,27 @@ public slots:
   void setCurrentPanel(ctkSettingsPanel* panel);
   void setCurrentPanel(const QString& label);
 
+  void applySettings();
+  void resetSettings();
+  void restoreDefaultSettings();
+  
+  virtual void accept();
+  virtual void reject();
+
 signals:
   void settingChanged(const QString& key, const QVariant& value);
 
 protected slots:
+  void onSettingChanged(const QString& key, const QVariant& newVal);
   void onCurrentItemChanged(QTreeWidgetItem* currentItem, QTreeWidgetItem* previous);
+  void onDialogButtonClicked(QAbstractButton* button);
 
 protected:
-  QScopedPointer<ctkSettingsWidgetPrivate> d_ptr;
+  QScopedPointer<ctkSettingsDialogPrivate> d_ptr;
 
 private:
-  Q_DECLARE_PRIVATE(ctkSettingsWidget);
-  Q_DISABLE_COPY(ctkSettingsWidget);
+  Q_DECLARE_PRIVATE(ctkSettingsDialog);
+  Q_DISABLE_COPY(ctkSettingsDialog);
 };
 
 #endif

+ 119 - 57
Libs/Widgets/ctkSettingsPanel.cpp

@@ -29,8 +29,47 @@
 
 static ctkLogger logger("org.commontk.libs.widgets.ctkSettingsPanel");
 
-typedef QPair<QObject*, QString> PropertyType;
+struct PropertyType
+{
+  PropertyType();
+  QObject* Object;
+  QString  Property;
+  QVariant PreviousValue;
+  QVariant DefaultValue;
+
+  QVariant value()const;
+  bool setValue(const QVariant& value);
+};
+
+// --------------------------------------------------------------------------
+PropertyType::PropertyType()
+  : Object(0)
+{
+}
 
+// --------------------------------------------------------------------------
+QVariant PropertyType::value()const
+{
+  if (this->Object == 0 ||
+      this->Property.isEmpty())
+    {
+    return QVariant();
+    }
+  return this->Object->property(this->Property.toLatin1());
+}
+
+// --------------------------------------------------------------------------
+bool PropertyType::setValue(const QVariant& val)
+{
+  if (this->Object == 0 || this->Property.isEmpty())
+    {
+    Q_ASSERT(this->Object && !this->Property.isEmpty());
+    return false;
+    }
+  // the following returns true if the property has been added using Q_PROPERTY
+  // false otherwise (and the property is then a dynamic property)
+  return this->Object->setProperty(this->Property.toLatin1(), val);
+}
 //-----------------------------------------------------------------------------
 class ctkSettingsPanelPrivate
 {
@@ -42,14 +81,10 @@ public:
   ctkSettingsPanelPrivate(ctkSettingsPanel& object);
   void init();
 
-  PropertyType property(const QString& key);
-  QVariant propertyValue(const PropertyType& property)const;
-  bool setPropertyValue(const PropertyType& property, const QVariant& val);
-
-  QSettings*                   Settings;
-  QMap<QString, PropertyType > Properties;
-  QSignalMapper*               SignalMapper;
-  bool                         SaveToSettingsWhenRegister;
+  QSettings*                  Settings;
+  QMap<QString, PropertyType> Properties;
+  QSignalMapper*              SignalMapper;
+  bool                        SaveToSettingsWhenRegister;
 };
 
 // --------------------------------------------------------------------------
@@ -72,37 +107,6 @@ void ctkSettingsPanelPrivate::init()
 }
 
 // --------------------------------------------------------------------------
-PropertyType ctkSettingsPanelPrivate::property(const QString& key)
-{
-  PropertyType defaultProp(0, QString());
-  return this->Properties.value(key, defaultProp);
-}
-
-// --------------------------------------------------------------------------
-QVariant ctkSettingsPanelPrivate::propertyValue(const PropertyType& prop)const
-{
-  if (prop.first == 0 ||
-      prop.second.isEmpty())
-    {
-    return QVariant();
-    }
-  return prop.first->property(prop.second.toLatin1());
-}
-
-// --------------------------------------------------------------------------
-bool ctkSettingsPanelPrivate::setPropertyValue(const PropertyType& prop, const QVariant& val)
-{
-  if (prop.first == 0 ||
-      prop.second.isEmpty())
-    {
-    return false;
-    }
-  // the following return true if the property has been added using Q_PROPERTY
-  // false otherwise (and the property is then a dynamic property)
-  return prop.first->setProperty(prop.second.toLatin1(), val);
-}
-
-// --------------------------------------------------------------------------
 ctkSettingsPanel::ctkSettingsPanel(QWidget* _parent)
   : Superclass(_parent)
   , d_ptr(new ctkSettingsPanelPrivate(*this))
@@ -114,6 +118,7 @@ ctkSettingsPanel::ctkSettingsPanel(QWidget* _parent)
 // --------------------------------------------------------------------------
 ctkSettingsPanel::~ctkSettingsPanel()
 {
+  this->applySettings();
 }
 
 // --------------------------------------------------------------------------
@@ -127,6 +132,10 @@ QSettings* ctkSettingsPanel::settings()const
 void ctkSettingsPanel::setSettings(QSettings* settings)
 {
   Q_D(ctkSettingsPanel);
+  if (d->Settings == settings)
+    {
+    return;
+    }
   d->Settings = settings;
   this->updateProperties();
 }
@@ -141,12 +150,14 @@ void ctkSettingsPanel::updateProperties()
     }
   foreach(const QString& key, d->Properties.keys())
     {
-    QVariant value = d->Settings->value(key);
-    if (value.isValid())
+    if (d->Settings->contains(key))
       {
-      bool res = d->setPropertyValue(d->property(key), value);
+      QVariant value = d->Settings->value(key);
+      PropertyType& prop = d->Properties[key];
+      bool res = prop.setValue(value);
       Q_ASSERT(res);
       Q_UNUSED(res);
+      prop.PreviousValue = value;
       }
     else
       {
@@ -156,15 +167,58 @@ void ctkSettingsPanel::updateProperties()
 }
 
 // --------------------------------------------------------------------------
+void ctkSettingsPanel::updateSetting(const QString& key)
+{
+  Q_D(ctkSettingsPanel);
+  if (!d->Settings)
+    {
+    return;
+    }
+  this->setSetting(key, d->Properties[key].value());
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsPanel::setSetting(const QString& key, const QVariant& newVal)
+{
+  Q_D(ctkSettingsPanel);
+  QVariant oldVal = d->Settings->value(key);
+  d->Settings->setValue(key, newVal);
+  d->Properties[key].setValue(newVal);
+  if (d->Settings->status() != QSettings::NoError)
+    {
+    logger.warn( QString("Error %1 while writing setting %1")
+      .arg(d->Settings->status())
+      .arg(key));
+    }
+  if (oldVal != newVal)
+    {
+    emit settingChanged(key, newVal);
+    }
+}
+
+// --------------------------------------------------------------------------
 void ctkSettingsPanel::registerProperty(const QString& key,
                                         QObject* object,
                                         const QString& property,
                                         const char* signal)
 {
   Q_D(ctkSettingsPanel);
-  d->Properties[key] = PropertyType(object, property);
+  PropertyType prop;
+  prop.Object = object;
+  prop.Property = property;
+  prop.DefaultValue = prop.PreviousValue = prop.value();
+
+  if (d->Settings && d->Settings->contains(key))
+    {
+    QVariant val = d->Settings->value(key);
+    prop.setValue(val);
+    prop.PreviousValue = val;
+    }
+  d->Properties[key] = prop;
+
   d->SignalMapper->setMapping(object, key);
-  connect(object, signal, d->SignalMapper, SLOT(map()));
+  this->connect(object, signal, d->SignalMapper, SLOT(map()));
+  
   if (d->SaveToSettingsWhenRegister)
     {
     this->updateSetting(key);
@@ -172,24 +226,32 @@ void ctkSettingsPanel::registerProperty(const QString& key,
 }
 
 // --------------------------------------------------------------------------
-void ctkSettingsPanel::updateSetting(const QString& key)
+void ctkSettingsPanel::applySettings()
 {
   Q_D(ctkSettingsPanel);
-  if (!d->Settings)
+  foreach(const QString& key, d->Properties.keys())
     {
-    return;
+    PropertyType& prop = d->Properties[key];
+    prop.PreviousValue = prop.value();
     }
-  QVariant oldVal = d->Settings->value(key);
-  QVariant newVal = d->propertyValue(d->property(key));
-  d->Settings->setValue(key, newVal);
-  if (d->Settings->status() != QSettings::NoError)
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsPanel::resetSettings()
+{
+  Q_D(ctkSettingsPanel);
+  foreach(const QString& key, d->Properties.keys())
     {
-    logger.warn( QString("Error %1 while writing setting %1")
-      .arg(d->Settings->status())
-      .arg(key));
+    this->setSetting(key, d->Properties[key].PreviousValue);
     }
-  if (oldVal != newVal)
+}
+
+// --------------------------------------------------------------------------
+void ctkSettingsPanel::restoreDefaultSettings()
+{
+  Q_D(ctkSettingsPanel);
+  foreach(const QString& key, d->Properties.keys())
     {
-    emit settingChanged(key, newVal);
+    this->setSetting(key, d->Properties[key].DefaultValue);
     }
 }

+ 7 - 0
Libs/Widgets/ctkSettingsPanel.h

@@ -50,6 +50,13 @@ public:
                         QObject* object,
                         const QString& property,
                         const char* signal);
+  void setSetting(const QString& key, const QVariant& newVal);
+
+public slots:
+  void applySettings();
+  void resetSettings();
+  void restoreDefaultSettings();
+
 signals:
   void settingChanged(const QString& key, const QVariant& value);