Przeglądaj źródła

Merge branch 'ctkdatasetmodel'

* ctkdatasetmodel:
  Add ctkVTKDataSetComboBox
  Add ctkVTKDataSetModel for vtkDataSet arrays
Julien Finet 15 lat temu
rodzic
commit
cd899b1cac

+ 6 - 0
Libs/Visualization/VTK/Widgets/CMakeLists.txt

@@ -22,6 +22,10 @@ SET(KIT_SRCS
   ctkVTKAbstractMatrixWidget.cpp
   ctkVTKAbstractMatrixWidget.h
   ctkVTKAbstractMatrixWidget_p.h
+  ctkVTKDataSetModel.cpp
+  ctkVTKDataSetModel.h
+  ctkVTKDataSetArrayComboBox.cpp
+  ctkVTKDataSetArrayComboBox.h
   ctkVTKMatrixWidget.cpp
   ctkVTKMatrixWidget.h
   ctkVTKRenderView.cpp
@@ -43,6 +47,8 @@ SET(KIT_SRCS
 # Headers that should run through moc
 SET(KIT_MOC_SRCS
   ctkVTKAbstractMatrixWidget_p.h
+  ctkVTKDataSetArrayComboBox.h
+  ctkVTKDataSetModel.h
   ctkVTKMatrixWidget.h
   ctkVTKRenderView.h
   ctkVTKRenderView_p.h

+ 4 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt

@@ -4,6 +4,8 @@ SET(KIT ${PROJECT_NAME})
 # Tests
 #
 SET(TEST_SOURCES
+  ctkVTKDataSetArrayComboBoxTest1.cpp
+  ctkVTKDataSetModelTest1.cpp
   ctkVTKMatrixWidgetTest1.cpp
   ctkTransferFunctionBarsItemTest1.cpp
   ctkTransferFunctionViewTest1.cpp
@@ -61,6 +63,8 @@ ENDMACRO( SIMPLE_TEST  )
 # Add Tests
 #
 
+SIMPLE_TEST( ctkVTKDataSetArrayComboBoxTest1 )
+SIMPLE_TEST( ctkVTKDataSetModelTest1 )
 SIMPLE_TEST( ctkVTKMatrixWidgetTest1 )
 SIMPLE_TEST( ctkTransferFunctionBarsItemTest1 )
 SIMPLE_TEST( ctkTransferFunctionViewTest1 )

+ 64 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKDataSetArrayComboBoxTest1.cpp

@@ -0,0 +1,64 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QDebug>
+#include <QTimer>
+
+// CTK includes
+#include "ctkVTKDataSetArrayComboBox.h"
+
+// VTK includes
+#include <vtkCellData.h>
+#include <vtkFloatArray.h>
+#include <vtkIntArray.h>
+#include <vtkPointData.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKDataSetArrayComboBoxTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  vtkSmartPointer<vtkPolyData> dataSet =
+      vtkSmartPointer<vtkPolyData>::New();
+  vtkSmartPointer<vtkIntArray> ints = vtkSmartPointer<vtkIntArray>::New();
+  ints->SetName("Ints");
+  dataSet->GetPointData()->AddArray(ints);
+  vtkSmartPointer<vtkFloatArray> floats= vtkSmartPointer<vtkFloatArray>::New();
+  floats->SetName("Floats");
+  dataSet->GetCellData()->AddArray(floats);
+  
+  ctkVTKDataSetArrayComboBox comboBox;
+  comboBox.setDataSet(dataSet);
+  comboBox.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(1000, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 68 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKDataSetModelTest1.cpp

@@ -0,0 +1,68 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QApplication>
+#include <QComboBox>
+#include <QTimer>
+#include <QDebug>
+
+// CTK includes
+#include "ctkVTKDataSetModel.h"
+
+// VTK includes
+#include <vtkCellData.h>
+#include <vtkFloatArray.h>
+#include <vtkIntArray.h>
+#include <vtkPointData.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+
+// STD includes
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKDataSetModelTest1(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  vtkSmartPointer<vtkPolyData> dataSet =
+      vtkSmartPointer<vtkPolyData>::New();
+  vtkSmartPointer<vtkIntArray> ints = vtkSmartPointer<vtkIntArray>::New();
+  ints->SetName("Ints");
+  dataSet->GetPointData()->AddArray(ints);
+  vtkSmartPointer<vtkFloatArray> floats= vtkSmartPointer<vtkFloatArray>::New();
+  floats->SetName("Floats");
+  dataSet->GetCellData()->AddArray(floats);
+  
+  ctkVTKDataSetModel dataSetModel;
+  dataSetModel.setDataSet(dataSet);
+  
+  QComboBox comboBox;
+  comboBox.setModel(&dataSetModel);
+  comboBox.show();
+
+  if (argc < 2 || QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(1000, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 158 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDataSetArrayComboBox.cpp

@@ -0,0 +1,158 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QDebug>
+
+// CTK includes
+#include "ctkVTKDataSetArrayComboBox.h"
+#include "ctkVTKDataSetModel.h"
+
+// VTK includes
+#include <vtkDataArray.h>
+
+//-----------------------------------------------------------------------------
+class ctkVTKDataSetArrayComboBoxPrivate
+{
+  Q_DECLARE_PUBLIC(ctkVTKDataSetArrayComboBox);
+protected:
+  ctkVTKDataSetArrayComboBox* const q_ptr;
+public:
+  ctkVTKDataSetArrayComboBoxPrivate(ctkVTKDataSetArrayComboBox& object);
+  void init();
+  ctkVTKDataSetModel* dataSetModel()const;
+  
+  int indexFromArrayName(const QString& dataArrayName)const;
+  int indexFromArray(vtkDataArray* dataArray)const;
+  vtkDataArray* arrayFromIndex(int index)const;
+  QString arrayNameFromIndex(int index)const;
+};
+
+// --------------------------------------------------------------------------
+// ctkVTKDataSetArrayComboBoxPrivate methods
+
+// --------------------------------------------------------------------------
+ctkVTKDataSetArrayComboBoxPrivate::ctkVTKDataSetArrayComboBoxPrivate(ctkVTKDataSetArrayComboBox& object)
+  :q_ptr(&object)
+{
+}
+
+// --------------------------------------------------------------------------
+void ctkVTKDataSetArrayComboBoxPrivate::init()
+{
+  Q_Q(ctkVTKDataSetArrayComboBox);
+  q->setModel(new ctkVTKDataSetModel);
+  QObject::connect(q, SIGNAL(currentIndexChanged(int)),
+                   q, SLOT(onCurrentIndexChanged(int)));
+}
+
+// --------------------------------------------------------------------------
+ctkVTKDataSetModel* ctkVTKDataSetArrayComboBoxPrivate::dataSetModel()const
+{
+  Q_Q(const ctkVTKDataSetArrayComboBox);
+  return qobject_cast<ctkVTKDataSetModel*>(q->model());
+}
+
+// --------------------------------------------------------------------------
+int ctkVTKDataSetArrayComboBoxPrivate::indexFromArrayName(const QString& dataArrayName)const
+{
+  Q_Q(const ctkVTKDataSetArrayComboBox);
+  return q->findText(dataArrayName);
+}
+
+// --------------------------------------------------------------------------
+int ctkVTKDataSetArrayComboBoxPrivate::indexFromArray(vtkDataArray* dataArray)const
+{
+  return this->dataSetModel()->indexFromArray(dataArray,0).row();
+}
+
+// --------------------------------------------------------------------------
+vtkDataArray* ctkVTKDataSetArrayComboBoxPrivate::arrayFromIndex(int index)const
+{
+  return this->dataSetModel()->arrayFromIndex(
+    this->dataSetModel()->index(index, 0));
+}
+
+// --------------------------------------------------------------------------
+QString ctkVTKDataSetArrayComboBoxPrivate::arrayNameFromIndex(int index)const
+{
+  vtkDataArray* dataArray = this->arrayFromIndex(index);
+  return dataArray ? dataArray->GetName() : "";
+}
+
+// --------------------------------------------------------------------------
+// ctkVTKDataSetArrayComboBox methods
+
+// --------------------------------------------------------------------------
+ctkVTKDataSetArrayComboBox::ctkVTKDataSetArrayComboBox(QWidget* _parent)
+  : Superclass(_parent)
+  , d_ptr(new ctkVTKDataSetArrayComboBoxPrivate(*this))
+{
+  Q_D(ctkVTKDataSetArrayComboBox);
+  d->init();
+}
+
+// --------------------------------------------------------------------------
+ctkVTKDataSetArrayComboBox::~ctkVTKDataSetArrayComboBox()
+{
+}
+
+// --------------------------------------------------------------------------
+vtkDataArray* ctkVTKDataSetArrayComboBox::currentArray()const
+{
+  Q_D(const ctkVTKDataSetArrayComboBox);
+  return d->arrayFromIndex(this->currentIndex());
+}
+
+// --------------------------------------------------------------------------
+void ctkVTKDataSetArrayComboBox::setDataSet(vtkDataSet* dataSet)
+{
+  Q_D(ctkVTKDataSetArrayComboBox);
+  d->dataSetModel()->setDataSet(dataSet);
+}
+
+// --------------------------------------------------------------------------
+vtkDataSet* ctkVTKDataSetArrayComboBox::dataSet()const
+{
+  Q_D(const ctkVTKDataSetArrayComboBox);
+  return d->dataSetModel()->dataSet();
+}
+
+// --------------------------------------------------------------------------
+void ctkVTKDataSetArrayComboBox::setCurrentArray(vtkDataArray* dataArray)
+{
+  Q_D(ctkVTKDataSetArrayComboBox);
+  this->setCurrentIndex(d->indexFromArray(dataArray));
+}
+
+// --------------------------------------------------------------------------
+void ctkVTKDataSetArrayComboBox::setCurrentArray(const QString& dataArrayName)
+{
+  Q_D(ctkVTKDataSetArrayComboBox);
+  this->setCurrentIndex(d->indexFromArrayName(dataArrayName));
+}
+
+// --------------------------------------------------------------------------
+void ctkVTKDataSetArrayComboBox::onCurrentIndexChanged(int index)
+{
+  Q_D(ctkVTKDataSetArrayComboBox);
+  emit currentArrayChanged(d->arrayNameFromIndex(index));
+  emit currentArrayChanged(d->arrayFromIndex(index));
+}

+ 71 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDataSetArrayComboBox.h

@@ -0,0 +1,71 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKDataSetArrayComboBox_h
+#define __ctkVTKDataSetArrayComboBox_h
+
+// Qt includes
+#include <QComboBox>
+
+// CTK includes
+#include "ctkVisualizationVTKWidgetsExport.h"
+class ctkVTKDataSetArrayComboBoxPrivate;
+
+class vtkDataArray;
+class vtkDataSet;
+
+///
+/// QComboBox linked to vtkDataSet field arrays
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKDataSetArrayComboBox : public QComboBox
+{
+  Q_OBJECT
+  
+public:
+  /// Superclass typedef
+  typedef QComboBox Superclass;
+  
+  /// Constructors
+  explicit ctkVTKDataSetArrayComboBox(QWidget* parent = 0);
+  virtual ~ctkVTKDataSetArrayComboBox();
+  
+  vtkDataArray* currentArray()const;
+  vtkDataSet* dataSet()const;
+
+public slots:
+  void setDataSet(vtkDataSet* dataSet);
+  /// The array must exist in the dataset
+  void setCurrentArray(vtkDataArray* dataArray);
+  /// the array must exist in the dataset
+  void setCurrentArray(const QString& name);
+
+signals:
+  void currentArrayChanged(vtkDataArray*);
+  void currentArrayChanged(const QString& name);
+protected slots:
+  void onCurrentIndexChanged(int);
+protected:
+  QScopedPointer<ctkVTKDataSetArrayComboBoxPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkVTKDataSetArrayComboBox);
+  Q_DISABLE_COPY(ctkVTKDataSetArrayComboBox);
+};
+
+#endif

+ 344 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDataSetModel.cpp

@@ -0,0 +1,344 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QDebug>
+
+// CTK includes
+#include "ctkVTKDataSetModel.h"
+
+// VTK includes
+#include <vtkCellData.h>
+#include <vtkSmartPointer.h>
+#include <vtkDataArray.h>
+#include <vtkDataSet.h>
+#include <vtkPointData.h>
+
+class ctkVTKDataSetModelPrivate
+{
+  Q_DECLARE_PUBLIC(ctkVTKDataSetModel);
+protected:
+  ctkVTKDataSetModel* const q_ptr;
+public:
+  ctkVTKDataSetModelPrivate(ctkVTKDataSetModel& object);
+  virtual ~ctkVTKDataSetModelPrivate();
+  void init();
+  //void listenDataArrayModifiedEvent();
+
+  vtkSmartPointer<vtkDataSet> DataSet;
+  bool ListenDataArrayModifiedEvent;
+};
+
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModelPrivate::ctkVTKDataSetModelPrivate(ctkVTKDataSetModel& object)
+  : q_ptr(&object)
+{
+  this->ListenDataArrayModifiedEvent = false;
+}
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModelPrivate::~ctkVTKDataSetModelPrivate()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModelPrivate::init()
+{
+  Q_Q(ctkVTKDataSetModel);
+  q->setColumnCount(1);
+  
+  QObject::connect(q, SIGNAL(itemChanged(QStandardItem*)),
+                   q, SLOT(onItemChanged(QStandardItem*)));
+}
+/*
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModelPrivate::listenDataArrayModifiedEvent()
+{
+  Q_Q(ctkVTKDataSetModel);
+  q->qvtkDisconnect(0, vtkCommand::ModifiedEvent, q, SLOT(onArrayModified(vtkObject*)));
+  if (!this->ListenDataArrayModifiedEvent)
+    {
+    return;
+    }
+  const int count = q->rowCount();
+  for (int i = 0; i < count; ++i)
+    {
+    q->qvtkConnect(q->arrayFromIndex(q->index(i,0)),vtkCommand::ModifiedEvent,
+                   q, SLOT(onMRMLNodeModified(vtkObject*)));
+    }
+}
+*/
+
+//------------------------------------------------------------------------------
+// ctkVTKDataSetModel
+//------------------------------------------------------------------------------
+ctkVTKDataSetModel::ctkVTKDataSetModel(QObject *_parent)
+  : QStandardItemModel(_parent)
+  , d_ptr(new ctkVTKDataSetModelPrivate(*this))
+{
+  Q_D(ctkVTKDataSetModel);
+  d->init();
+}
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModel::ctkVTKDataSetModel(ctkVTKDataSetModelPrivate* pimpl, QObject *parentObject)
+  : QStandardItemModel(parentObject)
+  , d_ptr(pimpl)
+{
+  Q_D(ctkVTKDataSetModel);
+  d->init();
+}
+
+//------------------------------------------------------------------------------
+ctkVTKDataSetModel::~ctkVTKDataSetModel()
+{
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::setDataSet(vtkDataSet* dataSet)
+{
+  Q_D(ctkVTKDataSetModel);
+  this->qvtkReconnect(d->DataSet, dataSet, vtkCommand::ModifiedEvent,
+                      this, SLOT(onDataSetModified(vtkObject*)) );
+  d->DataSet = dataSet;
+  this->updateDataSet();
+}
+
+//------------------------------------------------------------------------------
+vtkDataSet* ctkVTKDataSetModel::dataSet()const
+{
+  Q_D(const ctkVTKDataSetModel);
+  return d->DataSet;
+}
+
+//------------------------------------------------------------------------------
+vtkDataArray* ctkVTKDataSetModel::arrayFromItem(QStandardItem* dataArrayItem)const
+{
+  Q_D(const ctkVTKDataSetModel);
+  if (dataArrayItem == 0 || dataArrayItem == this->invisibleRootItem())
+    {
+    return 0;
+    }
+  QVariant dataArrayPointer = dataArrayItem->data(ctkVTK::PointerRole);
+  Q_ASSERT(dataArrayPointer.isValid());
+  vtkDataArray* dataArray = static_cast<vtkDataArray*>(
+    reinterpret_cast<void *>(dataArrayPointer.toLongLong()));
+  Q_ASSERT(dataArray);
+  return dataArray;
+}
+
+//------------------------------------------------------------------------------
+QStandardItem* ctkVTKDataSetModel::itemFromArray(vtkDataArray* dataArray, int column)const
+{
+  if (dataArray == 0)
+    {
+    return 0;
+    }
+  QModelIndexList indexes = this->match(this->index(-1,-1), ctkVTK::PointerRole,
+                                      reinterpret_cast<long long>(dataArray), 1,
+                                      Qt::MatchExactly | Qt::MatchRecursive);
+  while (indexes.size())
+    {
+    if (indexes[0].column() == column)
+      {
+      return this->itemFromIndex(indexes[0]);
+      }
+    indexes = this->match(indexes[0], ctkVTK::PointerRole,
+                          reinterpret_cast<long long>(dataArray), 1,
+                          Qt::MatchExactly | Qt::MatchRecursive);
+    }
+  return 0;
+}
+
+//------------------------------------------------------------------------------
+QModelIndexList ctkVTKDataSetModel::indexes(vtkDataArray* dataArray)const
+{
+  return this->match(this->index(-1,-1), ctkVTK::PointerRole,
+                     QVariant::fromValue(reinterpret_cast<long long>(dataArray)),
+                     -1, Qt::MatchExactly | Qt::MatchRecursive);
+}
+
+/*
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::setListenArrayModifiedEvent(bool listen)
+{
+  Q_D(ctkVTKDataSetModel);
+  if (d->ListenArrayModifiedEvent == listen)
+    {
+    return;
+    }
+  d->ListenArrayModifiedEvent = listen;
+  d->listenArrayModifiedEvent();
+}
+
+//------------------------------------------------------------------------------
+bool ctkVTKDataSetModel::listenNodeModifiedEvent()const
+{
+  Q_D(const ctkVTKDataSetModel);
+  return d->ListenNodeModifiedEvent;
+}
+*/
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::updateDataSet()
+{
+  Q_D(ctkVTKDataSetModel);
+  this->setRowCount(0);
+
+  if (d->DataSet.GetPointer() == 0)
+    {
+    return;
+    }
+
+  // Populate scene with nodes
+  this->populateDataSet();
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::populateDataSet()
+{
+  Q_D(ctkVTKDataSetModel);
+  Q_ASSERT(d->DataSet);
+
+  for (int p = 0; p < d->DataSet->GetPointData()->GetNumberOfArrays(); ++p)
+    {
+    this->insertArray(d->DataSet->GetPointData()->GetArray(p));
+    }
+
+  for (int p = 0; p < d->DataSet->GetCellData()->GetNumberOfArrays(); ++p)
+    {
+    this->insertArray(d->DataSet->GetCellData()->GetArray(p));
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::insertArray(vtkDataArray* dataArray)
+{
+  this->insertArray(dataArray, this->rowCount());
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::insertArray(vtkDataArray* dataArray, int row)
+{
+  Q_D(ctkVTKDataSetModel);
+  Q_ASSERT(vtkDataArray::SafeDownCast(dataArray));
+
+  QList<QStandardItem*> items;
+  for (int i= 0; i < this->columnCount(); ++i)
+    {
+    QStandardItem* newArrayItem = new QStandardItem();
+    this->updateItemFromArray(newArrayItem, dataArray, i);
+    items.append(newArrayItem);
+    }
+  this->insertRow(row,items);
+  // TODO: don't listen to nodes that are hidden from editors ?
+  if (d->ListenDataArrayModifiedEvent)
+    {
+    qvtkConnect(dataArray, vtkCommand::ModifiedEvent,
+                this, SLOT(onArrayModified(vtkObject*)));
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::updateItemFromArray(QStandardItem* item, vtkDataArray* dataArray, int column)
+{
+  item->setData(QVariant::fromValue(reinterpret_cast<long long>(dataArray)), ctkVTK::PointerRole);
+  switch (column)
+    {
+    case 0:
+      item->setText(QString(dataArray->GetName()));
+      break;
+    default:
+      Q_ASSERT(column == 0);
+      break;
+    }
+}
+
+//------------------------------------------------------------------------------
+/*
+void ctkVTKDataSetModel::updateItemFromPointsArray(QStandardItem* item, vtkDataArray* dataArray, int column)
+{
+  this->updateItemFromArray(item, dataArray, column);
+  switch (column)
+    {
+    case 0:
+      item->setIcon();
+      break;
+    default:
+      Q_ASSERT(column == 0)
+      break;
+    }
+}
+
+//------------------------------------------------------------------------------
+/*
+void ctkVTKDataSetModel::updateItemFromCellsArray(QStandardItem* item, vtkDataArray* dataArray, int column)
+{
+  this->updateItemFromArray(item, dataArray, column);
+  switch (column)
+    {
+    case 0:
+      item->setIcon();
+      break;
+    default:
+      Q_ASSERT(column == 0)
+      break;
+    }
+}
+
+*/
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::updateArrayFromItem(vtkDataArray* dataArray, QStandardItem* item)
+{
+  if (item->column() == 0)
+    {
+    dataArray->SetName(item->text().toLatin1());
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::onDataSetModified(vtkObject* dataSet)
+{
+  this->updateDataSet();
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::onArrayModified(vtkObject* array)
+{
+  Q_D(ctkVTKDataSetModel);
+  vtkDataArray* dataArray = vtkDataArray::SafeDownCast(array);
+  Q_ASSERT(dataArray);
+  QModelIndexList arrayIndexes = this->indexes(dataArray);
+
+  foreach (QModelIndex index, arrayIndexes)
+    {
+    QStandardItem* item = this->itemFromIndex(index);
+    this->updateItemFromArray(item, dataArray, item->column());
+    }
+}
+
+//------------------------------------------------------------------------------
+void ctkVTKDataSetModel::onItemChanged(QStandardItem * item)
+{
+  vtkDataArray* dataArray = this->arrayFromItem(item);
+  Q_ASSERT(dataArray);
+  this->updateArrayFromItem(dataArray, item);
+}

+ 105 - 0
Libs/Visualization/VTK/Widgets/ctkVTKDataSetModel.h

@@ -0,0 +1,105 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKDataSetModel_h
+#define __ctkVTKDataSetModel_h
+
+// Qt includes
+#include <QStandardItemModel>
+
+// CTK includes
+#include <ctkVTKObject.h>
+
+// CTK includes
+#include "ctkVisualizationVTKWidgetsExport.h"
+
+class vtkDataSet;
+class vtkDataArray;
+
+namespace ctkVTK
+{
+ enum ItemDataRole {
+   PointerRole = Qt::UserRole + 1
+ };
+};
+
+class ctkVTKDataSetModelPrivate;
+
+//------------------------------------------------------------------------------
+class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKDataSetModel
+  : public QStandardItemModel
+{
+  Q_OBJECT
+  QVTK_OBJECT
+
+public:
+  typedef QStandardItemModel Superclass;
+  ctkVTKDataSetModel(QObject *parent=0);
+  virtual ~ctkVTKDataSetModel();
+
+  virtual void setDataSet(vtkDataSet* dataSet);
+  vtkDataSet* dataSet()const;
+
+  /// Return the vtkDataArray associated to the index.
+  /// 0 if the index doesn't contain a vtkDataArray
+  inline vtkDataArray* arrayFromIndex(const QModelIndex& arrayIndex)const;
+  vtkDataArray* arrayFromItem(QStandardItem* nodeItem)const;
+  inline QModelIndex indexFromArray(vtkDataArray* dataArray, int column = 0)const;
+  QStandardItem* itemFromArray(vtkDataArray* dataArray, int column = 0)const;
+  QModelIndexList indexes(vtkDataArray* dataArray)const;
+
+protected slots:
+  void onDataSetModified(vtkObject* dataSet);
+  void onArrayModified(vtkObject* dataArray);
+  void onItemChanged(QStandardItem * item);
+
+protected:
+
+  ctkVTKDataSetModel(ctkVTKDataSetModelPrivate* pimpl, QObject *parent=0);
+
+  virtual void insertArray(vtkDataArray* dataArray);
+  virtual void insertArray(vtkDataArray* dataArray, int row);
+  virtual void updateItemFromArray(QStandardItem* item, vtkDataArray* dataArray, int column);
+  virtual void updateArrayFromItem(vtkDataArray* dataArray, QStandardItem* item);
+  virtual void updateDataSet();
+  virtual void populateDataSet();
+
+protected:
+  QScopedPointer<ctkVTKDataSetModelPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkVTKDataSetModel);
+  Q_DISABLE_COPY(ctkVTKDataSetModel);
+};
+
+// -----------------------------------------------------------------------------
+vtkDataArray* ctkVTKDataSetModel::arrayFromIndex(const QModelIndex &nodeIndex)const
+{
+  return this->arrayFromItem(this->itemFromIndex(nodeIndex));
+}
+
+// -----------------------------------------------------------------------------
+QModelIndex ctkVTKDataSetModel::indexFromArray(vtkDataArray* dataArray, int column)const
+{
+  QStandardItem* item = this->itemFromArray(dataArray, column);
+  return item ? item->index() : QModelIndex();
+}
+
+#endif