fw4spl
SPreferencesConfiguration.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2014-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 #include "uiPreferences/action/SPreferencesConfiguration.hpp"
7 
8 #include <fwCom/Signal.hpp>
9 #include <fwCom/Signal.hxx>
10 
11 #include <fwData/Composite.hpp>
12 #include <fwData/Integer.hpp>
13 #include <fwData/location/Folder.hpp>
14 #include <fwData/String.hpp>
15 
16 #include <fwGui/dialog/LocationDialog.hpp>
17 
18 #include <fwPreferences/helper.hpp>
19 
20 #include <fwServices/macros.hpp>
21 #include <fwServices/registry/ObjectService.hpp>
22 
23 #include <boost/lexical_cast.hpp>
24 #include <boost/tokenizer.hpp>
25 
26 #include <QDialog>
27 #include <QDoubleValidator>
28 #include <QGridLayout>
29 #include <QHBoxLayout>
30 #include <QIntValidator>
31 #include <QLabel>
32 #include <QPushButton>
33 
34 namespace uiPreferences
35 {
36 
37 namespace action
38 {
39 
40 const ::fwCom::Signals::SignalKeyType SPreferencesConfiguration::s_PARAMETERS_MODIFIED_SIG = "parametersModified";
41 
43 
44 //-----------------------------------------------------------------------------
45 
47 {
48  m_sigParametersModified = newSignal< ParametersModifiedSignalType >(s_PARAMETERS_MODIFIED_SIG);
49 }
50 
51 //------------------------------------------------------------------------------
52 
54 {
55 }
56 
57 //------------------------------------------------------------------------------
58 
60 {
61  this->actionServiceStarting();
62 
63  // Check preferences
64  ::fwData::Composite::sptr prefs = ::fwPreferences::getPreferences();
65  if(prefs)
66  {
67  for(PreferenceElt& pref : m_preferences)
68  {
69  pref.m_dataPreference = ::fwData::String::New(pref.m_defaultValue);
70  ::fwData::Composite::IteratorType iterPref = prefs->find( pref.m_preferenceKey );
71  if ( iterPref != prefs->end() )
72  {
73  pref.m_dataPreference = ::fwData::String::dynamicCast(iterPref->second);
74  }
75  else
76  {
77  (*prefs)[pref.m_preferenceKey] = pref.m_dataPreference;
78  }
79  }
80  }
81 }
82 
83 //------------------------------------------------------------------------------
84 
86 {
87  this->actionServiceStopping();
88 }
89 
90 //------------------------------------------------------------------------------
91 
93 {
94  this->initialize();
95 
96  ::fwRuntime::ConfigurationElementContainer config = m_configuration->findAllConfigurationElement("preference");
97  for(const auto& elt : config.getElements())
98  {
99  PreferenceElt pref;
100 
101  ConfigurationType typeCfg = elt->findConfigurationElement("type");
102  SLM_ASSERT("element 'type' is missing.", typeCfg);
103  if(typeCfg->getValue() == "checkbox")
104  {
105  pref.m_type = PreferenceType::CHECKBOX;
106  }
107  else if (typeCfg->getValue() == "text" )
108  {
109  pref.m_type = PreferenceType::TEXT;
110  }
111  else if (typeCfg->getValue() == "number")
112  {
113  FW_DEPRECATED_MSG("'number' configuration element will be deprecated in further version please use 'int'",
114  "18.0");
115 
116  pref.m_type = PreferenceType::U_INT;
117  }
118  else if(typeCfg->getValue() == "path")
119  {
120  pref.m_type = PreferenceType::PATH;
121  }
122  else if(typeCfg->getValue() == "combobox")
123  {
124  pref.m_type = PreferenceType::COMBOBOX;
125  }
126  else if(typeCfg->getValue() == "double")
127  {
128  pref.m_type = PreferenceType::DOUBLE;
129  }
130  else if(typeCfg->getValue() == "int")
131  {
132  pref.m_type = PreferenceType::U_INT;
133  }
134  else
135  {
136  OSLM_ERROR("Preference type "<<typeCfg->getValue()<<" is not implemented");
137  }
138 
139  ConfigurationType nameCfg = elt->findConfigurationElement("name");
140  SLM_ASSERT("element 'name' is missing.", nameCfg);
141  pref.m_name = nameCfg->getValue();
142 
143  ConfigurationType keyCfg = elt->findConfigurationElement("key");
144  SLM_ASSERT("element 'key' is missing.", keyCfg);
145  pref.m_preferenceKey = keyCfg->getValue();
146 
147  ConfigurationType defaultValueCfg = elt->findConfigurationElement("default_value");
148  SLM_ASSERT("element 'default_value' is missing.", defaultValueCfg);
149  pref.m_defaultValue = defaultValueCfg->getValue();
150 
151  if(pref.m_type == PreferenceType::TEXT || pref.m_type == PreferenceType::PATH)
152  {
153  pref.m_lineEdit = new QLineEdit(QString::fromStdString(pref.m_defaultValue));
154  }
155  else if(pref.m_type == PreferenceType::CHECKBOX)
156  {
157  pref.m_checkBox = new QCheckBox();
158  pref.m_checkBox->setChecked(pref.m_defaultValue == "true");
159  }
160  else if(pref.m_type == PreferenceType::U_INT)
161  {
162  pref.m_lineEdit = new QLineEdit(QString::fromStdString(pref.m_defaultValue));
163  pref.m_lineEdit->setValidator( new QIntValidator( 0, 999999));
164  }
165  else if(pref.m_type == PreferenceType::DOUBLE)
166  {
167  pref.m_lineEdit = new QLineEdit(QString::fromStdString(pref.m_defaultValue));
168  pref.m_lineEdit->setValidator( new QDoubleValidator( -1000000.0, 1000000.0, 6));
169  }
170  else if(pref.m_type == PreferenceType::COMBOBOX)
171  {
172  ConfigurationType valuesCfg = elt->findConfigurationElement("values");
173  SLM_ASSERT("element 'values' is missing.", valuesCfg);
174 
175  const ::boost::char_separator<char> sep(", ;");
176  const std::string s = valuesCfg->getValue();
177  const ::boost::tokenizer< ::boost::char_separator<char> > tokens {s, sep};
178 
179  pref.m_comboBox = new QComboBox();
180  for(const std::string& value : tokens)
181  {
182  pref.m_comboBox->addItem(QString::fromStdString(value));
183  }
184  }
185  m_preferences.push_back(pref);
186  }
187 }
188 
189 //------------------------------------------------------------------------------
190 
192 {
193  QPointer<QDialog> dialog = new QDialog();
194  QPointer<QGridLayout> layout = new QGridLayout();
195 
196  int index = 0;
197  for(PreferenceElt& pref : m_preferences)
198  {
199  QPointer<QLabel> label = new QLabel(QString::fromStdString(pref.m_name));
200  layout->addWidget(label, index, 0);
201 
202  if(pref.m_type == PreferenceType::TEXT)
203  {
204  pref.m_lineEdit->setText(QString::fromStdString(pref.m_dataPreference->value()));
205  layout->addWidget(pref.m_lineEdit, index, 1);
206  }
207  else if(pref.m_type == PreferenceType::CHECKBOX)
208  {
209  pref.m_checkBox->setChecked(pref.m_dataPreference->value() == "true");
210  layout->addWidget(pref.m_checkBox, index, 1);
211  }
212  else if(pref.m_type == PreferenceType::U_INT || pref.m_type == PreferenceType::DOUBLE)
213  {
214  pref.m_lineEdit->setText(QString::fromStdString(pref.m_dataPreference->value()));
215  layout->addWidget(pref.m_lineEdit, index, 1);
216  }
217  else if(pref.m_type == PreferenceType::PATH)
218  {
219  pref.m_lineEdit->setText(QString::fromStdString(pref.m_dataPreference->value()));
220  layout->addWidget(pref.m_lineEdit, index, 1);
221  QPointer<QPushButton> directorySelector = new QPushButton("...");
222  layout->addWidget(directorySelector, index, 2);
223  QObject::connect(directorySelector.data(), &QPushButton::clicked, [this, pref]()
224  {
225  this->onSelectDir(pref.m_lineEdit);
226  });
227  }
228  else if(pref.m_type == PreferenceType::COMBOBOX)
229  {
230  const int currentIndex = pref.m_comboBox->findText(QString::fromStdString(pref.m_dataPreference->value()));
231  if(currentIndex < 0)
232  {
233  SLM_WARN( "Preference '" + pref.m_dataPreference->value() +
234  "' can't be find in combobox. The first one is selected.");
235  pref.m_comboBox->setCurrentIndex(0);
236  }
237  else
238  {
239  pref.m_comboBox->setCurrentIndex(currentIndex);
240  }
241  layout->addWidget(pref.m_comboBox, index, 1);
242  }
243 
244  ++index;
245  }
246 
247  QPointer<QPushButton> cancelButton = new QPushButton("Cancel");
248  QPointer<QPushButton> okButton = new QPushButton("OK");
249  okButton->setDefault(true);
250 
251  QPointer<QHBoxLayout> buttonLayout = new QHBoxLayout();
252  buttonLayout->addWidget(cancelButton);
253  buttonLayout->addWidget(okButton);
254 
255  layout->addLayout(buttonLayout, index, 1, 4, 2 );
256 
257  QObject::connect(cancelButton.data(), &QPushButton::clicked, dialog.data(), &QDialog::reject);
258  QObject::connect(okButton.data(), &QPushButton::clicked, dialog.data(), &QDialog::accept);
259 
260  dialog->setLayout(layout);
261 
262  if (dialog->exec() == QDialog::Accepted)
263  {
264  for(PreferenceElt& pref : m_preferences)
265  {
266  if((pref.m_type == PreferenceType::TEXT || pref.m_type == PreferenceType::PATH) &&
267  !pref.m_lineEdit->text().isEmpty())
268  {
269  pref.m_dataPreference->value() = pref.m_lineEdit->text().toStdString();
270  }
271  else if(pref.m_type == PreferenceType::CHECKBOX)
272  {
273  pref.m_dataPreference->value() = pref.m_checkBox->isChecked() ? "true" : "false";
274  }
275  else if(pref.m_type == PreferenceType::U_INT || pref.m_type == PreferenceType::DOUBLE)
276  {
277  pref.m_dataPreference->value() = pref.m_lineEdit->text().toStdString();
278  }
279  else if(pref.m_type == PreferenceType::COMBOBOX)
280  {
281  pref.m_dataPreference->value() = pref.m_comboBox->currentText().toStdString();
282  }
283  }
284  m_sigParametersModified->asyncEmit();
285  }
286 }
287 
288 //------------------------------------------------------------------------------
289 
290 void SPreferencesConfiguration::onSelectDir(QPointer<QLineEdit> lineEdit)
291 {
292  static ::boost::filesystem::path _sDefaultPath;
293 
295  dialogFile.setTitle("Select Storage directory");
296  dialogFile.setDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath) );
297  dialogFile.setOption(::fwGui::dialog::ILocationDialog::WRITE);
298  dialogFile.setType(::fwGui::dialog::ILocationDialog::FOLDER);
299 
300  ::fwData::location::Folder::sptr result;
301  result = ::fwData::location::Folder::dynamicCast( dialogFile.show() );
302  if (result)
303  {
304  _sDefaultPath = result->getFolder();
305  lineEdit->setText( QString::fromStdString(result->getFolder().string()) );
306  dialogFile.saveDefaultLocation( ::fwData::location::Folder::New(_sDefaultPath) );
307  }
308 }
309 
310 //------------------------------------------------------------------------------
311 
313 {
314 }
315 
316 //------------------------------------------------------------------------------
317 
318 void SPreferencesConfiguration::info( std::ostream& _sstream )
319 {
320 }
321 
322 //------------------------------------------------------------------------------
323 
324 } // namespace action
325 } // namespace videoQt
virtual void info(std::ostream &_sstream) override
Overrides.
virtual void starting() override
Start the action. Gets the preference composite.
FWGUI_API void actionServiceStarting()
Method called when the action service is starting.
Definition: IActionSrv.cpp:160
This action shows a dialog to configure preferences of an application.
FWGUI_API void actionServiceStopping()
Method called when the action service is stopping.
Definition: IActionSrv.cpp:153
virtual FWGUI_API void setDefaultLocation(::fwData::location::ILocation::sptr loc) override
Set the initial location for the dialog.
FWGUI_API::fwGui::dialog::ILocationDialog & setOption(::fwGui::dialog::ILocationDialog::Options option) override
allow to set option to the file dialog mode=READ/WRITE, check=FILE_MUST_EXIST
FWGUI_API::fwData::location::ILocation::sptr show() override
Display the dialog.
#define FW_DEPRECATED_MSG(message, version)
Use this macro when deprecating a function to warn the developer.
Definition: spyLog.hpp:360
virtual UIPREFERENCES_API ~SPreferencesConfiguration() noexcept
Destructor. Do nothing.
#define SLM_WARN(message)
Definition: spyLog.hpp:261
Defines the service interface managing the menu items.
Definition: IActionSrv.hpp:24
UIPREFERENCES_API SPreferencesConfiguration() noexcept
Constructor. Do nothing.
#define OSLM_ERROR(message)
Definition: spyLog.hpp:274
virtual void configuring() override
Configures the service.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
FWGUI_API void initialize()
Initialize the action.
Definition: IActionSrv.cpp:69
Base class for each data object.
::fwRuntime::ConfigurationElement::sptr m_configuration
Configuration element used to configure service internal state using a generic XML like structure TOD...
Definition: IService.hpp:670
FWGUI_API void setTitle(const std::string &title) override
Set the title for the dialog.
Defines the generic file/folder selector dialog for IHM.
Defines the generic configuration element container class.
FWRUNTIME_API const Container & getElements() const
Returns the configuration element container.
The namespace uiPreferences contains editors to manage the preferences configuration.
FWGUI_API void setType(::fwGui::dialog::ILocationDialog::Types type) override
Set the type of location for the dialog (SINGLE_FILE, FORLDER, MULTI_FILES)
FWGUI_API void saveDefaultLocation(::fwData::location::ILocation::sptr loc) override
Save the specified default location for the dialog in preferences (if available)
virtual void updating() override
Shows a dialog to configure preferences declared in xml.