1 // Copyright (C) 2010-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "pqCustomXYChartDisplayPanel.h"
21 #include "ui_CustomXYChartDisplayPanel.h"
23 #include "vtkEventQtSlotConnect.h"
24 #include "vtkSMChartRepresentationProxy.h"
25 #include "vtkSMPropertyHelper.h"
26 #include "vtkDataArray.h"
27 #include "vtkDataObject.h"
28 #include "vtkSMArraySelectionDomain.h"
29 #include "vtkSMIntVectorProperty.h"
30 #include "vtkSMProxy.h"
31 #include "vtkSmartPointer.h"
34 #include "vtkWeakPointer.h"
36 #include <QColorDialog>
37 #include <QHeaderView>
41 #include <QSortFilterProxyModel>
44 #include "pqDataInformationModel.h"
45 #include "pqComboBoxDomain.h"
46 #include "pqPropertyLinks.h"
47 #include "pqSignalAdaptorCompositeTreeWidget.h"
48 #include "pqSignalAdaptors.h"
49 #include "pqSMAdaptor.h"
50 #include "pqXYChartView.h"
51 #include "pqDataRepresentation.h"
52 #include "pqCustomPlotSettingsModel.h"
56 //-----------------------------------------------------------------------------
57 class pqCustomXYChartDisplayPanel::pqInternal : public Ui::CustomXYChartDisplayPanel
62 this->SettingsModel = 0;
63 this->XAxisArrayDomain = 0;
64 this->XAxisArrayAdaptor = 0;
66 this->VTKConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
71 delete this->SettingsModel;
72 delete this->XAxisArrayDomain;
73 delete this->XAxisArrayAdaptor;
76 vtkWeakPointer<vtkSMChartRepresentationProxy> ChartRepresentation;
77 pqCustomPlotSettingsModel* SettingsModel;
78 pqComboBoxDomain* XAxisArrayDomain;
79 pqSignalAdaptorComboBox* XAxisArrayAdaptor;
80 pqPropertyLinks Links;
82 vtkSmartPointer<vtkEventQtSlotConnect> VTKConnect;
87 //-----------------------------------------------------------------------------
88 pqCustomXYChartDisplayPanel::pqCustomXYChartDisplayPanel(
89 pqRepresentation* display,QWidget* p)
90 : pqDisplayPanel(display, p)
92 this->Internal = new pqCustomXYChartDisplayPanel::pqInternal();
93 this->Internal->setupUi(this);
95 this->Internal->SettingsModel = new pqCustomPlotSettingsModel(this);
96 this->Internal->SeriesList->setModel(this->Internal->SettingsModel);
98 this->Internal->XAxisArrayAdaptor = new pqSignalAdaptorComboBox(
99 this->Internal->XAxisArray);
102 this->Internal->SeriesList, SIGNAL(activated(const QModelIndex &)),
103 this, SLOT(activateItem(const QModelIndex &)));
104 QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
105 QObject::connect(model,
106 SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
107 this, SLOT(updateOptionsWidgets()));
108 QObject::connect(model,
109 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
110 this, SLOT(updateOptionsWidgets()));
111 QObject::connect(this->Internal->SettingsModel, SIGNAL(modelReset()),
112 this, SLOT(updateOptionsWidgets()));
113 QObject::connect(this->Internal->SettingsModel, SIGNAL(redrawChart()),
114 this, SLOT(updateAllViews()));
115 QObject::connect(this->Internal->XAxisArray, SIGNAL(currentIndexChanged(int)),
116 this, SLOT(updateAllViews()));
118 QObject::connect(this->Internal->UseArrayIndex, SIGNAL(toggled(bool)),
119 this, SLOT(useArrayIndexToggled(bool)));
120 QObject::connect(this->Internal->UseDataArray, SIGNAL(toggled(bool)),
121 this, SLOT(useDataArrayToggled(bool)));
124 this->Internal->ColorButton, SIGNAL(chosenColorChanged(const QColor &)),
125 this, SLOT(setCurrentSeriesColor(const QColor &)));
126 QObject::connect(this->Internal->Thickness, SIGNAL(valueChanged(int)),
127 this, SLOT(setCurrentSeriesThickness(int)));
128 QObject::connect(this->Internal->StyleList, SIGNAL(currentIndexChanged(int)),
129 this, SLOT(setCurrentSeriesStyle(int)));
130 QObject::connect(this->Internal->AxisList, SIGNAL(currentIndexChanged(int)),
131 this, SLOT(setCurrentSeriesAxes(int)));
132 QObject::connect(this->Internal->MarkerStyleList, SIGNAL(currentIndexChanged(int)),
133 this, SLOT(setCurrentSeriesMarkerStyle(int)));
136 this->Internal->AutoSelect, SIGNAL(toggled(bool)),
137 this, SLOT(autoSelectToggled(bool)));
140 this->Internal->IgnoreUnits, SIGNAL(toggled(bool)),
141 this, SLOT(ignoreUnitsToggled(bool)));
144 this->Internal->GenerateAxesTitles, SIGNAL(toggled(bool)),
145 this, SLOT(updateViewOptions()));
146 QObject::connect(this->Internal->SettingsModel, SIGNAL(redrawChart()),
147 this, SLOT(updateViewOptions()));
149 resetUnitsControls();
151 this->setDisplay(display);
153 QObject::connect(&this->Internal->Links, SIGNAL(qtWidgetChanged()),
154 this, SLOT(reloadSeries()), Qt::QueuedConnection);
155 QObject::connect(&this->Internal->Links, SIGNAL(qtWidgetChanged()),
156 this->Internal->SettingsModel, SLOT(reload()));
159 //-----------------------------------------------------------------------------
160 pqCustomXYChartDisplayPanel::~pqCustomXYChartDisplayPanel()
162 delete this->Internal;
165 //-----------------------------------------------------------------------------
166 void pqCustomXYChartDisplayPanel::reloadSeries()
170 this->updateAllViews();
171 this->updateOptionsWidgets();
174 //-----------------------------------------------------------------------------
175 void pqCustomXYChartDisplayPanel::setDisplay(pqRepresentation* disp)
177 this->setEnabled(false);
179 vtkSMChartRepresentationProxy* proxy =
180 vtkSMChartRepresentationProxy::SafeDownCast(disp->getProxy());
181 this->Internal->ChartRepresentation = proxy;
182 if (!this->Internal->ChartRepresentation)
184 qWarning() << "pqCustomXYChartDisplayPanel given a representation proxy "
185 "that is not an XYChartRepresentation. Cannot edit.";
189 // this is essential to ensure that when you undo-redo, the representation is
190 // indeed update-to-date, thus ensuring correct domains etc.
191 proxy->UpdatePipeline();
193 // The model for the plot settings
194 this->Internal->SettingsModel->setRepresentation(
195 qobject_cast<pqDataRepresentation*>(disp));
197 // Connect to the new properties.pqComboBoxDomain will ensure that
198 // when ever the domain changes the widget is updated as well.
199 this->Internal->XAxisArrayDomain = new pqComboBoxDomain(
200 this->Internal->XAxisArray, proxy->GetProperty("XArrayName"));
201 this->Internal->Links.addPropertyLink(this->Internal->XAxisArrayAdaptor,
202 "currentText", SIGNAL(currentTextChanged(const QString&)),
203 proxy, proxy->GetProperty("XArrayName"));
205 // Link to set whether the index is used for the x axis
206 this->Internal->Links.addPropertyLink(
207 this->Internal->UseArrayIndex, "checked",
208 SIGNAL(toggled(bool)),
209 proxy, proxy->GetProperty("UseIndexForXAxis"));
212 this->Internal->VTKConnect->Connect(proxy->GetProperty("SeriesNamesInfo"),
213 vtkCommand::PropertyModifiedEvent, this, SLOT(resetUnitsControls()));
215 this->changeDialog(disp);
217 this->setEnabled(true);
219 this->reloadSeries();
222 //-----------------------------------------------------------------------------
223 void pqCustomXYChartDisplayPanel::changeDialog(pqRepresentation* disp)
225 vtkSMChartRepresentationProxy* proxy =
226 vtkSMChartRepresentationProxy::SafeDownCast(disp->getProxy());
228 if (QString("Bar") == vtkSMPropertyHelper(proxy,"ChartType").GetAsString())
233 this->Internal->Thickness->setVisible(visible);
234 this->Internal->ThicknessLabel->setVisible(visible);
235 this->Internal->StyleList->setVisible(visible);
236 this->Internal->StyleListLabel->setVisible(visible);
237 this->Internal->MarkerStyleList->setVisible(visible);
238 this->Internal->MarkerStyleListLabel->setVisible(visible);
239 this->Internal->AxisList->setVisible(false);
240 this->Internal->AxisListLabel->setVisible(false);
243 //-----------------------------------------------------------------------------
244 void pqCustomXYChartDisplayPanel::activateItem(const QModelIndex &index)
246 if(!this->Internal->ChartRepresentation
247 || !index.isValid() || index.column() != 1)
249 // We are interested in clicks on the color swab alone.
254 QColor color = this->Internal->SettingsModel->getSeriesColor(index.row());
256 // Show color selector dialog to get a new color
257 color = QColorDialog::getColor(color, this);
261 this->Internal->SettingsModel->setSeriesColor(index.row(), color);
262 this->Internal->ColorButton->blockSignals(true);
263 this->Internal->ColorButton->setChosenColor(color);
264 this->Internal->ColorButton->blockSignals(false);
265 this->updateAllViews();
269 //-----------------------------------------------------------------------------
270 void pqCustomXYChartDisplayPanel::updateOptionsWidgets()
272 QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
275 // Show the options for the current item.
276 QModelIndex current = model->currentIndex();
277 QModelIndexList indexes = model->selectedIndexes();
278 if((!current.isValid() || !model->isSelected(current)) &&
281 current = indexes.last();
284 this->Internal->ColorButton->blockSignals(true);
285 this->Internal->Thickness->blockSignals(true);
286 this->Internal->StyleList->blockSignals(true);
287 this->Internal->MarkerStyleList->blockSignals(true);
288 this->Internal->AxisList->blockSignals(true);
289 if (current.isValid())
291 int seriesIndex = current.row();
292 QColor color = this->Internal->SettingsModel->getSeriesColor(seriesIndex);
293 this->Internal->ColorButton->setChosenColor(color);
294 this->Internal->Thickness->setValue(
295 this->Internal->SettingsModel->getSeriesThickness(seriesIndex));
296 this->Internal->StyleList->setCurrentIndex(
297 this->Internal->SettingsModel->getSeriesStyle(seriesIndex));
298 this->Internal->MarkerStyleList->setCurrentIndex(
299 this->Internal->SettingsModel->getSeriesMarkerStyle(seriesIndex));
300 this->Internal->AxisList->setCurrentIndex(
301 this->Internal->SettingsModel->getSeriesAxisCorner(seriesIndex));
305 this->Internal->ColorButton->setChosenColor(Qt::white);
306 this->Internal->Thickness->setValue(1);
307 this->Internal->StyleList->setCurrentIndex(0);
308 this->Internal->MarkerStyleList->setCurrentIndex(0);
309 this->Internal->AxisList->setCurrentIndex(0);
312 this->Internal->ColorButton->blockSignals(false);
313 this->Internal->Thickness->blockSignals(false);
314 this->Internal->StyleList->blockSignals(false);
315 this->Internal->MarkerStyleList->blockSignals(false);
316 this->Internal->AxisList->blockSignals(false);
318 // Disable the widgets if nothing is selected or current.
319 bool hasItems = indexes.size() > 0;
320 this->Internal->ColorButton->setEnabled(hasItems);
321 this->Internal->Thickness->setEnabled(hasItems);
322 this->Internal->StyleList->setEnabled(hasItems);
323 this->Internal->MarkerStyleList->setEnabled(hasItems);
324 this->Internal->AxisList->setEnabled(hasItems);
328 //-----------------------------------------------------------------------------
329 void pqCustomXYChartDisplayPanel::setCurrentSeriesColor(const QColor &color)
331 QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
334 this->Internal->InChange = true;
335 QModelIndexList indexes = model->selectedIndexes();
336 QModelIndexList::Iterator iter = indexes.begin();
337 for( ; iter != indexes.end(); ++iter)
339 this->Internal->SettingsModel->setSeriesColor(iter->row(), color);
341 this->Internal->InChange = false;
345 //-----------------------------------------------------------------------------
346 void pqCustomXYChartDisplayPanel::setCurrentSeriesThickness(int thickness)
348 QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
351 this->Internal->InChange = true;
352 QModelIndexList indexes = model->selectedIndexes();
353 QModelIndexList::Iterator iter = indexes.begin();
354 for( ; iter != indexes.end(); ++iter)
356 this->Internal->SettingsModel->setSeriesThickness(iter->row(), thickness);
358 this->Internal->InChange = false;
362 //-----------------------------------------------------------------------------
363 void pqCustomXYChartDisplayPanel::setCurrentSeriesStyle(int style)
365 QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
368 this->Internal->InChange = true;
369 QModelIndexList indexes = model->selectedIndexes();
370 QModelIndexList::Iterator iter = indexes.begin();
371 for( ; iter != indexes.end(); ++iter)
373 this->Internal->SettingsModel->setSeriesStyle(iter->row(), style);
375 this->Internal->InChange = false;
379 //-----------------------------------------------------------------------------
380 void pqCustomXYChartDisplayPanel::setCurrentSeriesMarkerStyle(int style)
382 QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
385 this->Internal->InChange = true;
386 QModelIndexList indexes = model->selectedIndexes();
387 QModelIndexList::Iterator iter = indexes.begin();
388 for( ; iter != indexes.end(); ++iter)
390 this->Internal->SettingsModel->setSeriesMarkerStyle(iter->row(), style);
392 this->Internal->InChange = false;
396 //-----------------------------------------------------------------------------
397 void pqCustomXYChartDisplayPanel::setCurrentSeriesAxes(int)
402 //-----------------------------------------------------------------------------
403 Qt::CheckState pqCustomXYChartDisplayPanel::getEnabledState() const
405 Qt::CheckState enabledState = Qt::Unchecked;
410 //-----------------------------------------------------------------------------
411 void pqCustomXYChartDisplayPanel::useArrayIndexToggled(bool toggle)
413 this->Internal->UseDataArray->setChecked(!toggle);
416 //-----------------------------------------------------------------------------
417 void pqCustomXYChartDisplayPanel::useDataArrayToggled(bool toggle)
419 this->Internal->UseArrayIndex->setChecked(!toggle);
420 this->updateAllViews();
423 //-----------------------------------------------------------------------------
424 void pqCustomXYChartDisplayPanel::autoSelectToggled(bool checked)
426 this->Internal->SettingsModel->SetAutoSelectModeOn(checked);
429 //-----------------------------------------------------------------------------
430 void pqCustomXYChartDisplayPanel::ignoreUnitsToggled(bool checked)
432 this->Internal->AutoSelect->setEnabled(!checked);
433 this->Internal->SettingsModel->SetIgnoreUnitsModeOn(checked);
434 this->Internal->SettingsModel->SetAutoSelectModeOn(!checked &&
435 this->Internal->AutoSelect->isChecked());
438 //-----------------------------------------------------------------------------
439 void pqCustomXYChartDisplayPanel::resetUnitsControls()
441 this->Internal->IgnoreUnits->setCheckState(Qt::Checked);
442 this->Internal->AutoSelect->setCheckState(Qt::Unchecked);
445 //-----------------------------------------------------------------------------
446 void pqCustomXYChartDisplayPanel::updateViewOptions()
448 pqRepresentation* disp = this->getRepresentation();
449 if (!disp || !this->Internal->ChartRepresentation)
454 pqXYChartView* view = qobject_cast<pqXYChartView*>(disp->getView());
455 if (view && view->getProxy())
457 vtkSMProxy* proxy = view->getProxy();
459 QList<QVariant> values =
460 pqSMAdaptor::getMultipleElementProperty(proxy->GetProperty("AxisTitle"));
461 if (values.size() < 2)
466 if (!this->Internal->GenerateAxesTitles->isChecked())
468 values.insert(0, QVariant(""));
469 values.insert(1, QVariant(""));
474 int useIndexForXAxis = vtkSMPropertyHelper(
475 this->Internal->ChartRepresentation, "UseIndexForXAxis").GetAsInt();
478 if (!useIndexForXAxis)
480 xTitle = vtkSMPropertyHelper(this->Internal->ChartRepresentation, "XArrayName").GetAsString();
484 int nbRows = this->Internal->SettingsModel->rowCount(QModelIndex());
487 for (int i = 0; i < nbRows && nbEnabled < 2; i++)
489 if (this->Internal->SettingsModel->getSeriesEnabled(i))
499 yTitle = this->Internal->SettingsModel->getSeriesName(row);
501 values.insert(0, QVariant(yTitle));
502 values.insert(1, QVariant(xTitle));
505 pqSMAdaptor::setMultipleElementProperty(proxy->GetProperty("AxisTitle"), values);
507 view->getProxy()->UpdateVTKObjects();