Salome HOME
export preselected_id to client
[modules/paravis.git] / 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 // This class is revisited to hack on the SALOME's Preferences "Default" button
61 // to ParaView's "Default" behavior.
62 class PVGUI_ParaViewSettingsPane::pqInternals
63 {
64 public:
65   pqInternals()
66   {
67     // Get the containing preference tab to identify when it has focus
68
69   }
70   ~pqInternals();
71
72   Ui::CustomSettingsWidget Ui;
73
74   // Map from tab indices to stack widget indices. This is needed because there
75   // are more widgets in the stacked widgets than just what we add.
76   QMap<int, int> TabToStackedWidgets;
77 };
78
79 bool PVGUI_ParaViewSettingsPane::ShowRestartRequired = false;
80
81 //----------------------------------------------------------------------------
82 PVGUI_ParaViewSettingsPane::PVGUI_ParaViewSettingsPane(QWidget *widgetParent)
83   : QtxUserDefinedContent(widgetParent),
84     Internals (new PVGUI_ParaViewSettingsPane::pqInternals())
85 {
86   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
87   ui.setupUi(this);
88   ui.tabBar->setDocumentMode(false);
89   ui.tabBar->setDrawBase(false);
90   ui.tabBar->setExpanding(false);
91   ui.tabBar->setUsesScrollButtons(true);
92
93   // Hide restart message
94   ui.restartRequiredLabel->setVisible(PVGUI_ParaViewSettingsPane::ShowRestartRequired);
95
96   QList<vtkSMProxy*> proxies_to_show;
97
98   pqServer* server = pqActiveObjects::instance().activeServer();
99   vtkNew<vtkSMProxyIterator> iter;
100   iter->SetSession(server->session());
101   iter->SetModeToOneGroup();
102   for (iter->Begin("settings"); !iter->IsAtEnd(); iter->Next())
103     {
104     vtkSMProxy* proxy = iter->GetProxy();
105     if (proxy)
106       {
107       proxies_to_show.push_back(proxy);
108       }
109     }
110
111   // Add color palette.
112   if (vtkSMProxy* proxy = server->proxyManager()->GetProxy("global_properties", "ColorPalette"))
113     {
114     proxies_to_show.push_back(proxy);
115     }
116
117   foreach (vtkSMProxy* proxy, proxies_to_show)
118     {
119     QString proxyName = proxy->GetXMLName();
120
121     QScrollArea *scrollArea = new QScrollArea(this);
122     scrollArea->setObjectName(QString("ScrollArea%1").arg(proxyName));
123     scrollArea->setWidgetResizable(true);
124     scrollArea->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
125     scrollArea->setFrameShape(QFrame::NoFrame);
126
127     QWidget* container = new QWidget(scrollArea);
128     container->setObjectName("Container");
129     container->setContentsMargins(6, 0, 6, 0);
130
131     QVBoxLayout* vbox = new QVBoxLayout(container);
132     vbox->setMargin(0);
133     vbox->setSpacing(0);
134
135     pqProxyWidget* widget = new pqProxyWidget(proxy, container);
136     widget->setObjectName("ProxyWidget");
137     widget->setApplyChangesImmediately(false);
138     widget->setView(NULL);
139
140     widget->connect(this, SIGNAL(accepted()), SLOT(apply()));
141     widget->connect(this, SIGNAL(rejected()), SLOT(reset()));
142     this->connect(widget, SIGNAL(restartRequired()), SLOT(showRestartRequiredMessage()));
143     vbox->addWidget(widget);
144
145     QSpacerItem* spacer = new QSpacerItem(0, 0,QSizePolicy::Fixed,
146       QSizePolicy::MinimumExpanding);
147     vbox->addItem(spacer);
148
149     scrollArea->setWidget(container);
150     // show panel widgets
151     widget->updatePanel();
152
153     int tabIndex = ui.tabBar->addTab(proxy->GetXMLLabel());
154     int stackIndex = ui.stackedWidget->addWidget(scrollArea);
155     this->Internals->TabToStackedWidgets[tabIndex] = stackIndex;
156
157     this->connect(widget, SIGNAL(changeAvailable()), SLOT(onChangeAvailable()));
158     widget->connect(this, SIGNAL(filterWidgets(bool, QString)), SLOT(filterWidgets(bool, QString)));
159     }
160
161   // Disable some buttons to start
162 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
163 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
164
165 //  this->connect(ui.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()),
166 //                SLOT(onRestoreDefaults()));
167 //  this->connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), SLOT(clicked(QAbstractButton*)));
168   this->connect(this, SIGNAL(accepted()), SLOT(onAccepted()));
169   this->connect(this, SIGNAL(rejected()), SLOT(onRejected()));
170   this->connect(ui.tabBar, SIGNAL(currentChanged(int)), this, SLOT(onTabIndexChanged(int)));
171
172   this->connect(ui.SearchBox, SIGNAL(advancedSearchActivated(bool)), SLOT(filterPanelWidgets()));
173   this->connect(ui.SearchBox, SIGNAL(textChanged(QString)), SLOT(filterPanelWidgets()));
174
175   // After all the tabs are set up, select the first
176   this->onTabIndexChanged(0);
177
178   this->filterPanelWidgets();
179 }
180
181 //-----------------------------------------------------------------------------
182 PVGUI_ParaViewSettingsPane::~PVGUI_ParaViewSettingsPane()
183 {
184   delete this->Internals;
185   this->Internals = NULL;
186 }
187
188 void PVGUI_ParaViewSettingsPane::store(QtxResourceMgr* , QtxPreferenceMgr* )
189 {
190   emit this->accepted();
191 }
192
193 void PVGUI_ParaViewSettingsPane::retrieve(QtxResourceMgr* , QtxPreferenceMgr* )
194 {
195 //  onRestoreDefaults();
196 }
197
198 void PVGUI_ParaViewSettingsPane::showEvent(QShowEvent * ev)
199 {
200 //  // Connect SALOME's default button to ParaView's default restore.
201 //  LightApp_PreferencesDlg * prefDg;
202 //  QWidget *w = this->parentWidget();
203 //  // UGLY!!!
204 //  while (w)
205 //    {
206 //      LightApp_PreferencesDlg * prefDg = dynamic_cast<LightApp_PreferencesDlg *>( w );
207 //      if (prefDg)
208 //        break;
209 //      w = w->parentWidget();
210 //    }
211 //  if (prefDg)
212 //    prefDg->connect(btn, SIGNAL(clicked()), this, SLOT(onRestoreDefaults()));
213   ev->accept();
214 }
215
216 void PVGUI_ParaViewSettingsPane::hideEvent(QHideEvent * ev)
217 {
218   // Connect SALOME's default button to ParaView's default restore.
219   ev->accept();
220 }
221
222 //-----------------------------------------------------------------------------
223 void PVGUI_ParaViewSettingsPane::clicked(QAbstractButton *button)
224 {
225 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
226 //  QDialogButtonBox::ButtonRole role = ui.buttonBox->buttonRole(button);
227 //  switch (role)
228 //    {
229 //  case QDialogButtonBox::AcceptRole:
230 //  case QDialogButtonBox::ApplyRole:
231 //    emit this->accepted();
232 //    break;
233 //
234 //  case QDialogButtonBox::ResetRole:
235 //  case QDialogButtonBox::RejectRole:
236 //    emit this->rejected();
237 //    break;
238 //  default:
239 //    break;
240 //    }
241 }
242
243 //-----------------------------------------------------------------------------
244 void PVGUI_ParaViewSettingsPane::onAccepted()
245 {
246   // If there are any properties that needed to save their values in QSettings,
247   // do that. Otherwise, save to the vtkSMSettings singleton.
248   vtkSMSettings * settings = vtkSMSettings::GetInstance();
249   pqServer* server = pqActiveObjects::instance().activeServer();
250   vtkNew<vtkSMProxyIterator> iter;
251   iter->SetSession(server->session());
252   iter->SetModeToOneGroup();
253   for (iter->Begin("settings"); !iter->IsAtEnd(); iter->Next())
254     {
255     vtkSMProxy* proxy = iter->GetProxy();
256     settings->SetProxySettings(proxy);
257     vtkSmartPointer<vtkSMPropertyIterator> iter2;
258     iter2.TakeReference(proxy->NewPropertyIterator());
259     for (iter2->Begin(); !iter2->IsAtEnd(); iter2->Next())
260       {
261       vtkSMProperty* smproperty = iter2->GetProperty();
262       if (smproperty && smproperty->GetHints() &&
263         smproperty->GetHints()->FindNestedElementByName("SaveInQSettings"))
264         {
265         QString key = QString("%1.%2").arg(iter->GetKey()).arg(iter2->GetKey());
266         this->saveInQSettings(key.toLatin1().data(), smproperty);
267         }
268       }
269     }
270
271   // Save color palette settings
272   vtkSMProxy* paletteProxy = server->proxyManager()->GetProxy("global_properties", "ColorPalette");
273   if (paletteProxy)
274     {
275     settings->SetProxySettings(paletteProxy);
276     }
277
278   // Disable buttons
279 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
280 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
281 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
282
283   // In theory, the above changes are undo-redo able, the only things that's not
284   // undo-able is the "serialized" values. Hence we just clear the undo stack.
285   CLEAR_UNDO_STACK();
286 }
287
288 //-----------------------------------------------------------------------------
289 void PVGUI_ParaViewSettingsPane::onRejected()
290 {
291   // Disable buttons
292 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
293 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
294 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
295 }
296
297 //-----------------------------------------------------------------------------
298 void PVGUI_ParaViewSettingsPane::onRestoreDefaults()
299 {
300   pqServer* server = pqActiveObjects::instance().activeServer();
301   vtkSMSession * session = server->session();
302
303   vtkNew<vtkSMProxyIterator> iter;
304   iter->SetSession(session);
305   iter->SetModeToOneGroup();
306   for (iter->Begin("settings"); !iter->IsAtEnd(); iter->Next())
307     {
308     vtkSMProxy* proxy = iter->GetProxy();
309     if (proxy)
310       {
311       proxy->ResetPropertiesToXMLDefaults();
312       }
313     }
314
315   vtkSMProxy* paletteProxy = server->proxyManager()->GetProxy("global_properties", "ColorPalette");
316   if (paletteProxy)
317     {
318     paletteProxy->ResetPropertiesToXMLDefaults();
319     }
320 }
321
322 //-----------------------------------------------------------------------------
323 void PVGUI_ParaViewSettingsPane::onTabIndexChanged(int index)
324 {
325   int stackWidgetIndex = this->Internals->TabToStackedWidgets[index];
326   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
327   ui.stackedWidget->setCurrentIndex(stackWidgetIndex);
328 }
329
330 //-----------------------------------------------------------------------------
331 void PVGUI_ParaViewSettingsPane::filterPanelWidgets()
332 {
333   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
334   emit this->filterWidgets(
335     ui.SearchBox->isAdvancedSearchActive(), ui.SearchBox->text());
336 }
337
338 //-----------------------------------------------------------------------------
339 void PVGUI_ParaViewSettingsPane::onChangeAvailable()
340 {
341 //  Ui::CustomSettingsWidget &ui = this->Internals->Ui;
342 //  ui.buttonBox->button(QDialogButtonBox::Reset)->setEnabled(true);
343 //  ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
344 }
345
346 //-----------------------------------------------------------------------------
347 void PVGUI_ParaViewSettingsPane::showRestartRequiredMessage()
348 {
349   Ui::CustomSettingsWidget &ui = this->Internals->Ui;
350   ui.restartRequiredLabel->setVisible(true);
351   PVGUI_ParaViewSettingsPane::ShowRestartRequired = true;
352 }
353
354 //-----------------------------------------------------------------------------
355 void PVGUI_ParaViewSettingsPane::saveInQSettings(
356   const char* key, vtkSMProperty* smproperty)
357 {
358   pqSettings* settings = pqApplicationCore::instance()->settings();
359
360   // FIXME: handle all property types. This will only work for single value
361   // properties.
362   if (smproperty->IsA("vtkSMIntVectorProperty") ||
363     smproperty->IsA("vtkSMIdTypeVectorProperty"))
364     {
365     settings->setValue(key, vtkSMPropertyHelper(smproperty).GetAsInt());
366     }
367   else if (smproperty->IsA("vtkSMDoubleVectorProperty"))
368     {
369     settings->setValue(key, vtkSMPropertyHelper(smproperty).GetAsDouble());
370     }
371   else if (smproperty->IsA("vtkSMStringVectorProperty"))
372     {
373     settings->setValue(key, vtkSMPropertyHelper(smproperty).GetAsString());
374     }
375 }
376