Salome HOME
Merge branch 'abn/rearch'
[modules/paravis.git] / src / PVGUI / PVGUI_ParaViewSettingsPane.cxx
1 // PARAVIS : ParaView wrapper SALOME module
2 //
3 // Copyright (C) 2010-2014  CEA/DEN, EDF R&D
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 //
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //
21 // File   : PVGUI_ParaViewSettingsPane.cxx
22 // Author : Vitaly Smetannikov
23 //
24
25 #include "PVGUI_ParaViewSettingsPane.h"
26 #include "ui_pqCustomSettingsWidget.h"
27
28 #include <QtxDialog.h>
29
30 #include <QString>
31
32
33 #include "pqActiveObjects.h"
34 #include "pqApplicationCore.h"
35 #include "pqProxyWidget.h"
36 #include "pqSearchBox.h"
37 #include "pqServer.h"
38 #include "pqSettings.h"
39 #include "pqUndoStack.h"
40 #include "vtkNew.h"
41 #include "vtkPVXMLElement.h"
42 #include "vtkSmartPointer.h"
43 #include "vtkSMProperty.h"
44 #include "vtkSMPropertyHelper.h"
45 #include "vtkSMPropertyIterator.h"
46 #include "vtkSMProxy.h"
47 #include "vtkSMProxyIterator.h"
48 #include "vtkSMSessionProxyManager.h"
49 #include "vtkSMSettings.h"
50
51 #include <QKeyEvent>
52 #include <QMap>
53 #include <QPushButton>
54 #include <QScrollArea>
55 #include <QSpacerItem>
56 #include <QVBoxLayout>
57 #include <QShowEvent>
58 #include <QHideEvent>
59
60 class PVGUI_ParaViewSettingsPane::pqInternals
61 {
62 public:
63   Ui::CustomSettingsWidget Ui;
64
65   // Map from tab indices to stack widget indices. This is needed because there
66   // are more widgets in the stacked widgets than just what we add.
67   QMap<int, int> TabToStackedWidgets;
68 };
69
70 bool PVGUI_ParaViewSettingsPane::ShowRestartRequired = false;
71
72 //----------------------------------------------------------------------------
73 PVGUI_ParaViewSettingsPane::PVGUI_ParaViewSettingsPane(QWidget *widgetParent)
74   : QtxUserDefinedContent(widgetParent),
75     Internals (new PVGUI_ParaViewSettingsPane::pqInternals())
76 {
77   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
78   ui.setupUi(this);
79   ui.tabBar->setDocumentMode(false);
80   ui.tabBar->setDrawBase(false);
81   ui.tabBar->setExpanding(false);
82   ui.tabBar->setUsesScrollButtons(true);
83
84   // Hide restart message
85   ui.restartRequiredLabel->setVisible(PVGUI_ParaViewSettingsPane::ShowRestartRequired);
86
87   QList<vtkSMProxy*> proxies_to_show;
88
89   pqServer* server = pqActiveObjects::instance().activeServer();
90   vtkNew<vtkSMProxyIterator> iter;
91   iter->SetSession(server->session());
92   iter->SetModeToOneGroup();
93   for (iter->Begin("settings"); !iter->IsAtEnd(); iter->Next())
94     {
95     vtkSMProxy* proxy = iter->GetProxy();
96     if (proxy)
97       {
98       proxies_to_show.push_back(proxy);
99       }
100     }
101
102   // Add color palette.
103   if (vtkSMProxy* proxy = server->proxyManager()->GetProxy("global_properties", "ColorPalette"))
104     {
105     proxies_to_show.push_back(proxy);
106     }
107
108   foreach (vtkSMProxy* proxy, proxies_to_show)
109     {
110     QString proxyName = proxy->GetXMLName();
111
112     QScrollArea *scrollArea = new QScrollArea(this);
113     scrollArea->setObjectName(QString("ScrollArea%1").arg(proxyName));
114     scrollArea->setWidgetResizable(true);
115     scrollArea->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
116     scrollArea->setFrameShape(QFrame::NoFrame);
117
118     QWidget* container = new QWidget(scrollArea);
119     container->setObjectName("Container");
120     container->setContentsMargins(6, 0, 6, 0);
121
122     QVBoxLayout* vbox = new QVBoxLayout(container);
123     vbox->setMargin(0);
124     vbox->setSpacing(0);
125
126     pqProxyWidget* widget = new pqProxyWidget(proxy, container);
127     widget->setObjectName("ProxyWidget");
128     widget->setApplyChangesImmediately(false);
129     widget->setView(NULL);
130
131 //    widget->connect(this, SIGNAL(accepted()), SLOT(apply()));
132 //    widget->connect(this, SIGNAL(rejected()), SLOT(reset()));
133     this->connect(widget, SIGNAL(restartRequired()), SLOT(showRestartRequiredMessage()));
134     vbox->addWidget(widget);
135
136     QSpacerItem* spacer = new QSpacerItem(0, 0,QSizePolicy::Fixed,
137       QSizePolicy::MinimumExpanding);
138     vbox->addItem(spacer);
139
140     scrollArea->setWidget(container);
141     // show panel widgets
142     widget->updatePanel();
143
144     int tabIndex = ui.tabBar->addTab(proxy->GetXMLLabel());
145     int stackIndex = ui.stackedWidget->addWidget(scrollArea);
146     this->Internals->TabToStackedWidgets[tabIndex] = stackIndex;
147
148     this->connect(widget, SIGNAL(changeAvailable()), SLOT(onChangeAvailable()));
149     widget->connect(this, SIGNAL(filterWidgets(bool, QString)), SLOT(filterWidgets(bool, QString)));
150     }
151
152   // Disable some buttons to start
153 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
154 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
155
156 //  this->connect(ui.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()),
157 //                SLOT(onRestoreDefaults()));
158 //  this->connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(clicked(QAbstractButton*)));
159 //  this->connect(this, SIGNAL(accepted()), SLOT(onAccepted()));
160 //  this->connect(this, SIGNAL(rejected()), SLOT(onRejected()));
161   this->connect(ui.tabBar, SIGNAL(currentChanged(int)), this, SLOT(onTabIndexChanged(int)));
162
163   this->connect(ui.SearchBox, SIGNAL(advancedSearchActivated(bool)), SLOT(filterPanelWidgets()));
164   this->connect(ui.SearchBox, SIGNAL(textChanged(QString)), SLOT(filterPanelWidgets()));
165
166   // After all the tabs are set up, select the first
167   this->onTabIndexChanged(0);
168
169   this->filterPanelWidgets();
170 }
171
172 //-----------------------------------------------------------------------------
173 PVGUI_ParaViewSettingsPane::~PVGUI_ParaViewSettingsPane()
174 {
175   delete this->Internals;
176   this->Internals = NULL;
177 }
178
179 void PVGUI_ParaViewSettingsPane::store(QtxResourceMgr* , QtxPreferenceMgr* )
180 {
181   emit this->accepted();
182 }
183
184 void PVGUI_ParaViewSettingsPane::retrieve(QtxResourceMgr* , QtxPreferenceMgr* )
185 {
186 //  onRestoreDefaults();
187 }
188
189 void PVGUI_ParaViewSettingsPane::showEvent(QShowEvent * ev)
190 {
191 //  // Connect SALOME's default button to ParaView's default restore.
192 //  LightApp_PreferencesDlg * prefDg;
193 //  QWidget *w = this->parentWidget();
194 //  // UGLY!!!
195 //  while (w)
196 //    {
197 //      LightApp_PreferencesDlg * prefDg = dynamic_cast<LightApp_PreferencesDlg *>( w );
198 //      if (prefDg)
199 //        break;
200 //      w = w->parentWidget();
201 //    }
202 //  if (prefDg)
203 //    prefDg->connect(btn, SIGNAL(clicked()), this, SLOT(onRestoreDefaults()));
204   ev->accept();
205 }
206
207 void PVGUI_ParaViewSettingsPane::hideEvent(QHideEvent * ev)
208 {
209   // Connect SALOME's default button to ParaView's default restore.
210   ev->accept();
211 }
212
213 //-----------------------------------------------------------------------------
214 void PVGUI_ParaViewSettingsPane::clicked(QAbstractButton *button)
215 {
216 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
217 //  QDialogButtonBox::ButtonRole role = ui.buttonBox->buttonRole(button);
218 //  switch (role)
219 //    {
220 //  case QDialogButtonBox::AcceptRole:
221 //  case QDialogButtonBox::ApplyRole:
222 //    emit this->accepted();
223 //    break;
224 //
225 //  case QDialogButtonBox::ResetRole:
226 //  case QDialogButtonBox::RejectRole:
227 //    emit this->rejected();
228 //    break;
229 //  default:
230 //    break;
231 //    }
232 }
233
234 //-----------------------------------------------------------------------------
235 void PVGUI_ParaViewSettingsPane::onAccepted()
236 {
237   // If there are any properties that needed to save their values in QSettings,
238   // do that. Otherwise, save to the vtkSMSettings singleton.
239   vtkSMSettings * settings = vtkSMSettings::GetInstance();
240   pqServer* server = pqActiveObjects::instance().activeServer();
241   vtkNew<vtkSMProxyIterator> iter;
242   iter->SetSession(server->session());
243   iter->SetModeToOneGroup();
244   for (iter->Begin("settings"); !iter->IsAtEnd(); iter->Next())
245     {
246     vtkSMProxy* proxy = iter->GetProxy();
247     settings->SetProxySettings(proxy);
248     vtkSmartPointer<vtkSMPropertyIterator> iter2;
249     iter2.TakeReference(proxy->NewPropertyIterator());
250     for (iter2->Begin(); !iter2->IsAtEnd(); iter2->Next())
251       {
252       vtkSMProperty* smproperty = iter2->GetProperty();
253       if (smproperty && smproperty->GetHints() &&
254         smproperty->GetHints()->FindNestedElementByName("SaveInQSettings"))
255         {
256         QString key = QString("%1.%2").arg(iter->GetKey()).arg(iter2->GetKey());
257         this->saveInQSettings(key.toLatin1().data(), smproperty);
258         }
259       }
260     }
261
262   // Save color palette settings
263   vtkSMProxy* paletteProxy = server->proxyManager()->GetProxy("global_properties", "ColorPalette");
264   if (paletteProxy)
265     {
266     settings->SetProxySettings(paletteProxy);
267     }
268
269   // Disable buttons
270 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
271 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
272 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
273
274   // In theory, the above changes are undo-redo able, the only things that's not
275   // undo-able is the "serialized" values. Hence we just clear the undo stack.
276   CLEAR_UNDO_STACK();
277 }
278
279 //-----------------------------------------------------------------------------
280 void PVGUI_ParaViewSettingsPane::onRejected()
281 {
282   // Disable buttons
283 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
284 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
285 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
286 }
287
288 //-----------------------------------------------------------------------------
289 void PVGUI_ParaViewSettingsPane::onRestoreDefaults()
290 {
291   pqServer* server = pqActiveObjects::instance().activeServer();
292   vtkSMSession * session = server->session();
293
294   vtkNew<vtkSMProxyIterator> iter;
295   iter->SetSession(session);
296   iter->SetModeToOneGroup();
297   for (iter->Begin("settings"); !iter->IsAtEnd(); iter->Next())
298     {
299     vtkSMProxy* proxy = iter->GetProxy();
300     if (proxy)
301       {
302       proxy->ResetPropertiesToXMLDefaults();
303       }
304     }
305
306   vtkSMProxy* paletteProxy = server->proxyManager()->GetProxy("global_properties", "ColorPalette");
307   if (paletteProxy)
308     {
309     paletteProxy->ResetPropertiesToXMLDefaults();
310     }
311 }
312
313 //-----------------------------------------------------------------------------
314 void PVGUI_ParaViewSettingsPane::onTabIndexChanged(int index)
315 {
316   int stackWidgetIndex = this->Internals->TabToStackedWidgets[index];
317   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
318   ui.stackedWidget->setCurrentIndex(stackWidgetIndex);
319 }
320
321 //-----------------------------------------------------------------------------
322 void PVGUI_ParaViewSettingsPane::filterPanelWidgets()
323 {
324   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
325   emit this->filterWidgets(
326     ui.SearchBox->isAdvancedSearchActive(), ui.SearchBox->text());
327 }
328
329 //-----------------------------------------------------------------------------
330 void PVGUI_ParaViewSettingsPane::onChangeAvailable()
331 {
332 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
333 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(true);
334 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
335 }
336
337 //-----------------------------------------------------------------------------
338 void PVGUI_ParaViewSettingsPane::showRestartRequiredMessage()
339 {
340   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
341   ui.restartRequiredLabel->setVisible(true);
342   PVGUI_ParaViewSettingsPane::ShowRestartRequired = true;
343 }
344
345 //-----------------------------------------------------------------------------
346 void PVGUI_ParaViewSettingsPane::saveInQSettings(
347   const char* key, vtkSMProperty* smproperty)
348 {
349   pqSettings* settings = pqApplicationCore::instance()->settings();
350
351   // FIXME: handle all property types. This will only work for single value
352   // properties.
353   if (smproperty->IsA("vtkSMIntVectorProperty") ||
354     smproperty->IsA("vtkSMIdTypeVectorProperty"))
355     {
356     settings->setValue(key, vtkSMPropertyHelper(smproperty).GetAsInt());
357     }
358   else if (smproperty->IsA("vtkSMDoubleVectorProperty"))
359     {
360     settings->setValue(key, vtkSMPropertyHelper(smproperty).GetAsDouble());
361     }
362   else if (smproperty->IsA("vtkSMStringVectorProperty"))
363     {
364     settings->setValue(key, vtkSMPropertyHelper(smproperty).GetAsString());
365     }
366 }
367