Back to index

salome-paravis  6.5.0
pqCustomXYChartDisplayPanel.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2010-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "pqCustomXYChartDisplayPanel.h"
00021 #include "ui_CustomXYChartDisplayPanel.h"
00022 
00023 #include "vtkEventQtSlotConnect.h"
00024 #include "vtkSMChartRepresentationProxy.h"
00025 #include "vtkSMPropertyHelper.h"
00026 #include "vtkDataArray.h"
00027 #include "vtkDataObject.h"
00028 #include "vtkSMArraySelectionDomain.h"
00029 #include "vtkSMIntVectorProperty.h"
00030 #include "vtkSMProxy.h"
00031 #include "vtkSmartPointer.h"
00032 #include "vtkTable.h"
00033 #include "vtkChart.h"
00034 #include "vtkWeakPointer.h"
00035 
00036 #include <QColorDialog>
00037 #include <QHeaderView>
00038 #include <QList>
00039 #include <QPointer>
00040 #include <QPixmap>
00041 #include <QSortFilterProxyModel>
00042 #include <QDebug>
00043 
00044 #include "pqDataInformationModel.h"
00045 #include "pqComboBoxDomain.h"
00046 #include "pqPropertyLinks.h"
00047 #include "pqSignalAdaptorCompositeTreeWidget.h"
00048 #include "pqSignalAdaptors.h"
00049 #include "pqSMAdaptor.h"
00050 #include "pqXYChartView.h"
00051 #include "pqDataRepresentation.h"
00052 #include "pqCustomPlotSettingsModel.h"
00053 
00054 #include <assert.h>
00055 
00056 //-----------------------------------------------------------------------------
00057 class pqCustomXYChartDisplayPanel::pqInternal : public Ui::CustomXYChartDisplayPanel
00058 {
00059 public:
00060   pqInternal()
00061     {
00062     this->SettingsModel = 0;
00063     this->XAxisArrayDomain = 0;
00064     this->XAxisArrayAdaptor = 0;
00065 
00066     this->VTKConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
00067     }
00068 
00069   ~pqInternal()
00070     {
00071     delete this->SettingsModel;
00072     delete this->XAxisArrayDomain;
00073     delete this->XAxisArrayAdaptor;
00074     }
00075 
00076   vtkWeakPointer<vtkSMChartRepresentationProxy> ChartRepresentation;
00077   pqCustomPlotSettingsModel* SettingsModel;
00078   pqComboBoxDomain* XAxisArrayDomain;
00079   pqSignalAdaptorComboBox* XAxisArrayAdaptor;
00080   pqPropertyLinks Links;
00081 
00082   vtkSmartPointer<vtkEventQtSlotConnect> VTKConnect;
00083 
00084   bool InChange;
00085 };
00086 
00087 //-----------------------------------------------------------------------------
00088 pqCustomXYChartDisplayPanel::pqCustomXYChartDisplayPanel(
00089   pqRepresentation* display,QWidget* p)
00090 : pqDisplayPanel(display, p)
00091 {
00092   this->Internal = new pqCustomXYChartDisplayPanel::pqInternal();
00093   this->Internal->setupUi(this);
00094 
00095   this->Internal->SettingsModel = new pqCustomPlotSettingsModel(this);
00096   this->Internal->SeriesList->setModel(this->Internal->SettingsModel);
00097 
00098   this->Internal->XAxisArrayAdaptor = new pqSignalAdaptorComboBox(
00099     this->Internal->XAxisArray);
00100 
00101   QObject::connect(
00102     this->Internal->SeriesList, SIGNAL(activated(const QModelIndex &)),
00103     this, SLOT(activateItem(const QModelIndex &)));
00104   QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
00105   QObject::connect(model,
00106     SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
00107     this, SLOT(updateOptionsWidgets()));
00108   QObject::connect(model,
00109     SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
00110     this, SLOT(updateOptionsWidgets()));
00111   QObject::connect(this->Internal->SettingsModel, SIGNAL(modelReset()),
00112     this, SLOT(updateOptionsWidgets()));
00113   QObject::connect(this->Internal->SettingsModel, SIGNAL(redrawChart()),
00114     this, SLOT(updateAllViews()));
00115   QObject::connect(this->Internal->XAxisArray, SIGNAL(currentIndexChanged(int)),
00116     this, SLOT(updateAllViews()));
00117 
00118   QObject::connect(this->Internal->UseArrayIndex, SIGNAL(toggled(bool)),
00119     this, SLOT(useArrayIndexToggled(bool)));
00120   QObject::connect(this->Internal->UseDataArray, SIGNAL(toggled(bool)),
00121     this, SLOT(useDataArrayToggled(bool)));
00122 
00123   QObject::connect(
00124     this->Internal->ColorButton, SIGNAL(chosenColorChanged(const QColor &)),
00125     this, SLOT(setCurrentSeriesColor(const QColor &)));
00126   QObject::connect(this->Internal->Thickness, SIGNAL(valueChanged(int)),
00127     this, SLOT(setCurrentSeriesThickness(int)));
00128   QObject::connect(this->Internal->StyleList, SIGNAL(currentIndexChanged(int)),
00129     this, SLOT(setCurrentSeriesStyle(int)));
00130   QObject::connect(this->Internal->AxisList, SIGNAL(currentIndexChanged(int)),
00131     this, SLOT(setCurrentSeriesAxes(int)));
00132   QObject::connect(this->Internal->MarkerStyleList, SIGNAL(currentIndexChanged(int)),
00133     this, SLOT(setCurrentSeriesMarkerStyle(int)));
00134 
00135   QObject::connect(
00136     this->Internal->AutoSelect, SIGNAL(toggled(bool)),
00137     this, SLOT(autoSelectToggled(bool)));
00138 
00139   QObject::connect(
00140     this->Internal->IgnoreUnits, SIGNAL(toggled(bool)),
00141     this, SLOT(ignoreUnitsToggled(bool)));
00142 
00143   QObject::connect(
00144     this->Internal->GenerateAxesTitles, SIGNAL(toggled(bool)),
00145     this, SLOT(updateViewOptions()));
00146   QObject::connect(this->Internal->SettingsModel, SIGNAL(redrawChart()),
00147     this, SLOT(updateViewOptions()));
00148 
00149   resetUnitsControls();
00150 
00151   this->setDisplay(display);
00152 
00153   QObject::connect(&this->Internal->Links, SIGNAL(qtWidgetChanged()),
00154                    this, SLOT(reloadSeries()), Qt::QueuedConnection);
00155   QObject::connect(&this->Internal->Links, SIGNAL(qtWidgetChanged()),
00156                    this->Internal->SettingsModel, SLOT(reload()));
00157 }
00158 
00159 //-----------------------------------------------------------------------------
00160 pqCustomXYChartDisplayPanel::~pqCustomXYChartDisplayPanel()
00161 {
00162   delete this->Internal;
00163 }
00164 
00165 //-----------------------------------------------------------------------------
00166 void pqCustomXYChartDisplayPanel::reloadSeries()
00167 {
00168   updateViewOptions();
00169   
00170   this->updateAllViews();
00171   this->updateOptionsWidgets();
00172 }
00173 
00174 //-----------------------------------------------------------------------------
00175 void pqCustomXYChartDisplayPanel::setDisplay(pqRepresentation* disp)
00176 {
00177   this->setEnabled(false);
00178 
00179   vtkSMChartRepresentationProxy* proxy =
00180     vtkSMChartRepresentationProxy::SafeDownCast(disp->getProxy());
00181   this->Internal->ChartRepresentation = proxy;
00182   if (!this->Internal->ChartRepresentation)
00183     {
00184     qWarning() << "pqCustomXYChartDisplayPanel given a representation proxy "
00185                   "that is not an XYChartRepresentation. Cannot edit.";
00186     return;
00187     }
00188 
00189   // this is essential to ensure that when you undo-redo, the representation is
00190   // indeed update-to-date, thus ensuring correct domains etc.
00191   proxy->UpdatePipeline();
00192 
00193   // The model for the plot settings
00194   this->Internal->SettingsModel->setRepresentation(
00195       qobject_cast<pqDataRepresentation*>(disp));
00196 
00197   // Connect to the new properties.pqComboBoxDomain will ensure that
00198   // when ever the domain changes the widget is updated as well.
00199   this->Internal->XAxisArrayDomain = new pqComboBoxDomain(
00200       this->Internal->XAxisArray, proxy->GetProperty("XArrayName"));
00201   this->Internal->Links.addPropertyLink(this->Internal->XAxisArrayAdaptor,
00202       "currentText", SIGNAL(currentTextChanged(const QString&)),
00203       proxy, proxy->GetProperty("XArrayName"));
00204 
00205   // Link to set whether the index is used for the x axis
00206   this->Internal->Links.addPropertyLink(
00207     this->Internal->UseArrayIndex, "checked",
00208     SIGNAL(toggled(bool)),
00209     proxy, proxy->GetProperty("UseIndexForXAxis"));
00210 
00211   // Proxy changed
00212   this->Internal->VTKConnect->Connect(proxy->GetProperty("SeriesNamesInfo"),
00213        vtkCommand::PropertyModifiedEvent, this, SLOT(resetUnitsControls()));
00214 
00215   this->changeDialog(disp);
00216 
00217   this->setEnabled(true);
00218 
00219   this->reloadSeries();
00220 }
00221 
00222 //-----------------------------------------------------------------------------
00223 void pqCustomXYChartDisplayPanel::changeDialog(pqRepresentation* disp)
00224 {
00225   vtkSMChartRepresentationProxy* proxy =
00226     vtkSMChartRepresentationProxy::SafeDownCast(disp->getProxy());
00227   bool visible = true;
00228   if (QString("Bar") == vtkSMPropertyHelper(proxy,"ChartType").GetAsString())
00229     {
00230       visible = false;
00231     }
00232   
00233   this->Internal->Thickness->setVisible(visible);
00234   this->Internal->ThicknessLabel->setVisible(visible);
00235   this->Internal->StyleList->setVisible(visible);
00236   this->Internal->StyleListLabel->setVisible(visible);
00237   this->Internal->MarkerStyleList->setVisible(visible);
00238   this->Internal->MarkerStyleListLabel->setVisible(visible);
00239   this->Internal->AxisList->setVisible(false);
00240   this->Internal->AxisListLabel->setVisible(false);
00241 }
00242 
00243 //-----------------------------------------------------------------------------
00244 void pqCustomXYChartDisplayPanel::activateItem(const QModelIndex &index)
00245 {
00246   if(!this->Internal->ChartRepresentation
00247       || !index.isValid() || index.column() != 1)
00248     {
00249     // We are interested in clicks on the color swab alone.
00250     return;
00251     }
00252 
00253   // Get current color
00254   QColor color = this->Internal->SettingsModel->getSeriesColor(index.row());
00255 
00256   // Show color selector dialog to get a new color
00257   color = QColorDialog::getColor(color, this);
00258   if (color.isValid())
00259     {
00260     // Set the new color
00261     this->Internal->SettingsModel->setSeriesColor(index.row(), color);
00262     this->Internal->ColorButton->blockSignals(true);
00263     this->Internal->ColorButton->setChosenColor(color);
00264     this->Internal->ColorButton->blockSignals(false);
00265     this->updateAllViews();
00266     }
00267 }
00268 
00269 //-----------------------------------------------------------------------------
00270 void pqCustomXYChartDisplayPanel::updateOptionsWidgets()
00271 {
00272   QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
00273   if(model)
00274     {
00275     // Show the options for the current item.
00276     QModelIndex current = model->currentIndex();
00277     QModelIndexList indexes = model->selectedIndexes();
00278     if((!current.isValid() || !model->isSelected(current)) &&
00279         indexes.size() > 0)
00280       {
00281       current = indexes.last();
00282       }
00283 
00284     this->Internal->ColorButton->blockSignals(true);
00285     this->Internal->Thickness->blockSignals(true);
00286     this->Internal->StyleList->blockSignals(true);
00287     this->Internal->MarkerStyleList->blockSignals(true);
00288     this->Internal->AxisList->blockSignals(true);
00289     if (current.isValid())
00290       {
00291       int seriesIndex = current.row();
00292       QColor color = this->Internal->SettingsModel->getSeriesColor(seriesIndex);
00293       this->Internal->ColorButton->setChosenColor(color);
00294       this->Internal->Thickness->setValue(
00295         this->Internal->SettingsModel->getSeriesThickness(seriesIndex));
00296       this->Internal->StyleList->setCurrentIndex(
00297         this->Internal->SettingsModel->getSeriesStyle(seriesIndex));
00298       this->Internal->MarkerStyleList->setCurrentIndex(
00299         this->Internal->SettingsModel->getSeriesMarkerStyle(seriesIndex));
00300       this->Internal->AxisList->setCurrentIndex(
00301         this->Internal->SettingsModel->getSeriesAxisCorner(seriesIndex));
00302       }
00303     else
00304       {
00305       this->Internal->ColorButton->setChosenColor(Qt::white);
00306       this->Internal->Thickness->setValue(1);
00307       this->Internal->StyleList->setCurrentIndex(0);
00308       this->Internal->MarkerStyleList->setCurrentIndex(0);
00309       this->Internal->AxisList->setCurrentIndex(0);
00310       }
00311 
00312     this->Internal->ColorButton->blockSignals(false);
00313     this->Internal->Thickness->blockSignals(false);
00314     this->Internal->StyleList->blockSignals(false);
00315     this->Internal->MarkerStyleList->blockSignals(false);
00316     this->Internal->AxisList->blockSignals(false);
00317 
00318     // Disable the widgets if nothing is selected or current.
00319     bool hasItems = indexes.size() > 0;
00320     this->Internal->ColorButton->setEnabled(hasItems);
00321     this->Internal->Thickness->setEnabled(hasItems);
00322     this->Internal->StyleList->setEnabled(hasItems);
00323     this->Internal->MarkerStyleList->setEnabled(hasItems);
00324     this->Internal->AxisList->setEnabled(hasItems);
00325     }
00326 }
00327 
00328 //-----------------------------------------------------------------------------
00329 void pqCustomXYChartDisplayPanel::setCurrentSeriesColor(const QColor &color)
00330 {
00331   QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
00332   if(model)
00333     {
00334     this->Internal->InChange = true;
00335     QModelIndexList indexes = model->selectedIndexes();
00336     QModelIndexList::Iterator iter = indexes.begin();
00337     for( ; iter != indexes.end(); ++iter)
00338       {
00339       this->Internal->SettingsModel->setSeriesColor(iter->row(), color);
00340       }
00341     this->Internal->InChange = false;
00342     }
00343 }
00344 
00345 //-----------------------------------------------------------------------------
00346 void pqCustomXYChartDisplayPanel::setCurrentSeriesThickness(int thickness)
00347 {
00348   QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
00349   if (model)
00350     {
00351     this->Internal->InChange = true;
00352     QModelIndexList indexes = model->selectedIndexes();
00353     QModelIndexList::Iterator iter = indexes.begin();
00354     for( ; iter != indexes.end(); ++iter)
00355       {
00356       this->Internal->SettingsModel->setSeriesThickness(iter->row(), thickness);
00357       }
00358     this->Internal->InChange = false;
00359     }
00360 }
00361 
00362 //-----------------------------------------------------------------------------
00363 void pqCustomXYChartDisplayPanel::setCurrentSeriesStyle(int style)
00364 {
00365   QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
00366   if (model)
00367     {
00368     this->Internal->InChange = true;
00369     QModelIndexList indexes = model->selectedIndexes();
00370     QModelIndexList::Iterator iter = indexes.begin();
00371     for( ; iter != indexes.end(); ++iter)
00372       {
00373       this->Internal->SettingsModel->setSeriesStyle(iter->row(), style);
00374       }
00375     this->Internal->InChange = false;
00376     }
00377 }
00378 
00379 //-----------------------------------------------------------------------------
00380 void pqCustomXYChartDisplayPanel::setCurrentSeriesMarkerStyle(int style)
00381 {
00382   QItemSelectionModel *model = this->Internal->SeriesList->selectionModel();
00383   if (model)
00384     {
00385     this->Internal->InChange = true;
00386     QModelIndexList indexes = model->selectedIndexes();
00387     QModelIndexList::Iterator iter = indexes.begin();
00388     for( ; iter != indexes.end(); ++iter)
00389       {
00390       this->Internal->SettingsModel->setSeriesMarkerStyle(iter->row(), style);
00391       }
00392     this->Internal->InChange = false;
00393     }
00394 }
00395 
00396 //-----------------------------------------------------------------------------
00397 void pqCustomXYChartDisplayPanel::setCurrentSeriesAxes(int)
00398 {
00399 
00400 }
00401 
00402 //-----------------------------------------------------------------------------
00403 Qt::CheckState pqCustomXYChartDisplayPanel::getEnabledState() const
00404 {
00405   Qt::CheckState enabledState = Qt::Unchecked;
00406 
00407   return enabledState;
00408 }
00409 
00410 //-----------------------------------------------------------------------------
00411 void pqCustomXYChartDisplayPanel::useArrayIndexToggled(bool toggle)
00412 {
00413   this->Internal->UseDataArray->setChecked(!toggle);
00414 }
00415 
00416 //-----------------------------------------------------------------------------
00417 void pqCustomXYChartDisplayPanel::useDataArrayToggled(bool toggle)
00418 {
00419   this->Internal->UseArrayIndex->setChecked(!toggle);
00420   this->updateAllViews();
00421 }
00422 
00423 //-----------------------------------------------------------------------------
00424 void pqCustomXYChartDisplayPanel::autoSelectToggled(bool checked)
00425 {
00426   this->Internal->SettingsModel->SetAutoSelectModeOn(checked);
00427 }
00428 
00429 //-----------------------------------------------------------------------------
00430 void pqCustomXYChartDisplayPanel::ignoreUnitsToggled(bool checked)
00431 {
00432   this->Internal->AutoSelect->setEnabled(!checked);
00433   this->Internal->SettingsModel->SetIgnoreUnitsModeOn(checked);
00434   this->Internal->SettingsModel->SetAutoSelectModeOn(!checked && 
00435                                                this->Internal->AutoSelect->isChecked());
00436 }
00437 
00438 //-----------------------------------------------------------------------------
00439 void pqCustomXYChartDisplayPanel::resetUnitsControls()
00440 {
00441   this->Internal->IgnoreUnits->setCheckState(Qt::Checked);
00442   this->Internal->AutoSelect->setCheckState(Qt::Unchecked);
00443 }
00444 
00445 //-----------------------------------------------------------------------------
00446 void pqCustomXYChartDisplayPanel::updateViewOptions()
00447 {
00448   pqRepresentation* disp = this->getRepresentation();
00449   if (!disp || !this->Internal->ChartRepresentation)
00450     {
00451       return;
00452     }
00453 
00454   pqXYChartView* view = qobject_cast<pqXYChartView*>(disp->getView());
00455   if (view && view->getProxy())
00456     {
00457       vtkSMProxy* proxy = view->getProxy();
00458       
00459       QList<QVariant> values = 
00460        pqSMAdaptor::getMultipleElementProperty(proxy->GetProperty("AxisTitle"));
00461       if (values.size() < 2)
00462        {
00463          return;
00464        }
00465       
00466       if (!this->Internal->GenerateAxesTitles->isChecked())
00467        {
00468          values.insert(0, QVariant(""));
00469          values.insert(1, QVariant(""));
00470        }
00471       else
00472        {
00473          // Set X axis title
00474          int useIndexForXAxis = vtkSMPropertyHelper(
00475               this->Internal->ChartRepresentation, "UseIndexForXAxis").GetAsInt();
00476          
00477          QString xTitle("");
00478          if (!useIndexForXAxis) 
00479            {
00480              xTitle = vtkSMPropertyHelper(this->Internal->ChartRepresentation, "XArrayName")
00481               .GetAsString();
00482            }
00483       
00484          // Set Y axis title
00485          int nbRows = this->Internal->SettingsModel->rowCount(QModelIndex());
00486          int nbEnabled = 0;
00487          int row = 0;
00488          for (int i = 0; i < nbRows && nbEnabled < 2; i++)
00489            {
00490              if (this->Internal->SettingsModel->getSeriesEnabled(i))
00491               {
00492                 nbEnabled++;
00493                 row = i;
00494               }
00495            }
00496          
00497          QString yTitle("");
00498          if (nbEnabled == 1)
00499            {
00500              yTitle = this->Internal->SettingsModel->getSeriesName(row);
00501            }
00502          values.insert(0, QVariant(yTitle));
00503          values.insert(1, QVariant(xTitle));
00504        }
00505 
00506       pqSMAdaptor::setMultipleElementProperty(proxy->GetProperty("AxisTitle"), values);
00507 
00508       view->getProxy()->UpdateVTKObjects();
00509       view->render();
00510     }
00511 }