From: rnv Date: Tue, 16 Jun 2015 15:21:31 +0000 (+0300) Subject: Implementation of the '23082: [CEA 1403] Filter to rename fields or components' impro... X-Git-Tag: V7_7_0a1~11 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=8be3a3f3535ee58a5514387e0388e76b54b00579;p=modules%2Fparavis.git Implementation of the '23082: [CEA 1403] Filter to rename fields or components' improvement. --- diff --git a/src/Plugins/ArrayRenamer/ArrayRenamer.xml b/src/Plugins/ArrayRenamer/ArrayRenamer.xml new file mode 100644 index 00000000..18f1f1d8 --- /dev/null +++ b/src/Plugins/ArrayRenamer/ArrayRenamer.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + This property specifies the input to Array Renamer filter. + + + + + Set the arrays information (new name and way how to process array: copy origin array with new name or keep existing array and set new name). + + + + + + + Set the compoenents information for the array. + + + + + + + + + + + + + + + + + diff --git a/src/Plugins/ArrayRenamer/CMakeLists.txt b/src/Plugins/ArrayRenamer/CMakeLists.txt new file mode 100644 index 00000000..c70f45ad --- /dev/null +++ b/src/Plugins/ArrayRenamer/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright (C) 2014-2015 CEA/DEN, EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Roman NIKOLAEV + +PROJECT(ArrayRenamer) + +cmake_minimum_required(VERSION 2.8) + +FIND_PACKAGE(ParaView REQUIRED) +INCLUDE(${PARAVIEW_USE_FILE}) + +SET (outifaces) +SET (outsrcs) + +QT4_WRAP_CPP(moc_srcs pqArraysEditorPropertyWidget.h pqEditComponents.h) + + ADD_PARAVIEW_PROPERTY_GROUP_WIDGET(outifaces outsrcs + TYPE "custom_arrays_editor" + CLASS_NAME pqArraysEditorPropertyWidget) + +ADD_PARAVIEW_PLUGIN(ArrayRenamer "1.0" + SERVER_MANAGER_XML ArrayRenamer.xml + SERVER_MANAGER_SOURCES vtkArrayRenamerFilter.cxx + GUI_INTERFACES ${outifaces} + GUI_RESOURCES pqArrayRenamer.qrc + SOURCES ${outsrcs} ${moc_srcs} pqArraysEditorPropertyWidget.cxx + ) + +INSTALL(TARGETS ArrayRenamer + DESTINATION lib/paraview +) diff --git a/src/Plugins/ArrayRenamer/plugin.cmake b/src/Plugins/ArrayRenamer/plugin.cmake new file mode 100644 index 00000000..311942d1 --- /dev/null +++ b/src/Plugins/ArrayRenamer/plugin.cmake @@ -0,0 +1,3 @@ +pv_plugin(ArrayRenamer + DESCRIPTION "Renames data arrays and array's components" + DEFAULT_ENABLED) diff --git a/src/Plugins/ArrayRenamer/pqArrayRenamer.qrc b/src/Plugins/ArrayRenamer/pqArrayRenamer.qrc new file mode 100644 index 00000000..d82c446d --- /dev/null +++ b/src/Plugins/ArrayRenamer/pqArrayRenamer.qrc @@ -0,0 +1,7 @@ + + + resources/rename_ico_24x24.png + resources/copy_ico_16x16.png + resources/edit_ico_16x16.png + + diff --git a/src/Plugins/ArrayRenamer/pqArraysEditorPropertyWidget.cxx b/src/Plugins/ArrayRenamer/pqArraysEditorPropertyWidget.cxx new file mode 100644 index 00000000..2de62af5 --- /dev/null +++ b/src/Plugins/ArrayRenamer/pqArraysEditorPropertyWidget.cxx @@ -0,0 +1,742 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Roman NIKOLAEV + +// Local includes +#include "pqArraysEditorPropertyWidget.h" +#include "pqEditComponents.h" + +//ParaView includes +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// STD includes +#include + + +/// Table model for the components table +class pqComponentsModel : public QAbstractTableModel { + typedef QAbstractTableModel Superclass; +public: + typedef QPair SingleComponentInfoType; + typedef QVector ComponentsInfoType; +private: + ComponentsInfoType myComponentsInfoVector; + bool myRenameSimilar; + +public: + enum ColumnRoles { + COMPONENT_NAME = 0, + NEW_COMPONENT_NAME = 1, + }; + + //------------------------------------------------------------------ + pqComponentsModel( QObject* parentObject=0 ): + Superclass(parentObject), + myRenameSimilar(false) {} + + //------------------------------------------------------------------ + virtual ~pqComponentsModel() {} + + void setRenameSimilar( bool IsRenameSimilar ) { + myRenameSimilar = IsRenameSimilar; + if ( myRenameSimilar ) { + QHash anUnique; + foreach( SingleComponentInfoType item, myComponentsInfoVector ) { + if( !anUnique.contains( item.first ) ) { + anUnique.insert( item.first,item.second ); + } + } + bool modified = false; + int min = std::numeric_limits::max(); + int max = std::numeric_limits::min(); + for( int i = 0; i < myComponentsInfoVector.size(); i++ ) { + if( anUnique.contains( myComponentsInfoVector[i].first) && + anUnique.value( myComponentsInfoVector[i].first ) != myComponentsInfoVector[i].second ) { + myComponentsInfoVector[i].second = anUnique.value( myComponentsInfoVector[i].first ); + min = qMin( min, i ); + max = qMax( max, i ); + modified = true; + } + } + if( modified ) { + emit dataChanged( index( 1, min ) , index( 1, max ) ); + } + } + } + + //------------------------------------------------------------------ + virtual Qt::ItemFlags flags( const QModelIndex &idx ) const { + Qt::ItemFlags value = Superclass::flags( idx ); + if ( idx.isValid() ) { + switch ( idx.column() ) { + case NEW_COMPONENT_NAME: return value | Qt::ItemIsEditable; + default: + break; + } + } + return value; + } + + //------------------------------------------------------------------ + virtual int rowCount( const QModelIndex& idx=QModelIndex() ) const { + return idx.isValid() ? 0 : myComponentsInfoVector.size(); + } + + //------------------------------------------------------------------ + virtual int columnCount( const QModelIndex& idx=QModelIndex() ) const { + Q_UNUSED( idx ); + return 2; + } + + //------------------------------------------------------------------ + virtual QVariant data(const QModelIndex& idx, int role=Qt::DisplayRole) const { + if ( idx.column() == COMPONENT_NAME ) { + switch ( role ) { + case Qt::DisplayRole: + case Qt::ToolTipRole: + case Qt::StatusTipRole: + return myComponentsInfoVector[idx.row()].first; + default: + break; + } + } + else if (idx.column() == NEW_COMPONENT_NAME) { + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::ToolTipRole: + case Qt::StatusTipRole: + return myComponentsInfoVector[idx.row()].second; + case Qt::ForegroundRole: { + if ( myComponentsInfoVector[idx.row()].second == myComponentsInfoVector[idx.row()].first ) + return QApplication::palette().color(QPalette::Disabled, QPalette::Text); + } + case Qt::FontRole: { + if ( myComponentsInfoVector[idx.row()].second == myComponentsInfoVector[idx.row()].first ) { + QFont f = QApplication::font(); + f.setItalic(true); + return f; + } + } + default: + break; + } + } + return QVariant(); + } + + //------------------------------------------------------------------ + virtual bool setData(const QModelIndex &idx, const QVariant &value, int role=Qt::EditRole) { + if (idx.column() == NEW_COMPONENT_NAME && role == Qt::EditRole ) { + QString new_name = value.toString(); + Q_ASSERT(idx.row() < myComponentsInfoVector.size()); + myComponentsInfoVector[idx.row()].second = new_name; + int min = idx.row(); + int max = idx.row(); + if( myRenameSimilar ) { + QString ref_name = myComponentsInfoVector[idx.row()].first; + for( int i = 0; i < myComponentsInfoVector.size(); i++ ) { + if(myComponentsInfoVector[i].first == ref_name) { + min = qMin( min, i ); + max = qMax( max, i ); + myComponentsInfoVector[i].second = new_name; + } + } + } + emit dataChanged( index( 1, min ) , index( 1, max ) ); + return true; + } + } + + //------------------------------------------------------------------ + QVariant headerData( int section, Qt::Orientation orientation, int role ) const { + if ( orientation == Qt::Horizontal ) { + if ( role == Qt::DisplayRole || role == Qt::ToolTipRole ) { + switch (section) { + case COMPONENT_NAME: + return role == Qt::DisplayRole? "Origin Name": "Origin Names of components"; + case NEW_COMPONENT_NAME: + return role == Qt::DisplayRole? "New Name": "New Names of components"; + default: + break; + } + } + } + return this->Superclass::headerData(section, orientation, role); + } + + //------------------------------------------------------------------ + void setComponentsInfo( const ComponentsInfoType& data ) { + emit this->beginResetModel(); + myComponentsInfoVector = data; + emit this->endResetModel(); + } + + //------------------------------------------------------------------ + const ComponentsInfoType& componentsInfo() const { + return myComponentsInfoVector; + } +private: + Q_DISABLE_COPY(pqComponentsModel); +}; + +/// Table model for the array's table +class pqArraysModel : public QAbstractTableModel +{ + typedef QAbstractTableModel Superclass; +public: + struct ArrayInfo { + bool copyArray; // How to porocess arrays: remane origin array or keep origin and make copy with the new name + QString newName; + pqComponentsModel::ComponentsInfoType myComponentsInfo; + + public: + + //------------------------------------------------------------------ + const int nbComps() const { + return myComponentsInfo.size(); + } + + //------------------------------------------------------------------ + const bool isCompomentsModified() const { + foreach(pqComponentsModel::SingleComponentInfoType item , myComponentsInfo) { + if(item.first != item.second) + return true; + } + return false; + } + }; + +public: + typedef QPair ArraysInfoItemType; + typedef QVector ArraysInfoType; + +private: + ArraysInfoType myArraysInfo; + +public: + + //------------------------------------------------------------------ + enum ColumnRoles { + PROCESSING = 0, + NAME = 1, + NEW_NAME = 2, + COMPONENTS = 3, + }; + + //------------------------------------------------------------------ + pqArraysModel( QObject* parentObject=0 ) : + Superclass( parentObject ) { } + + //------------------------------------------------------------------ + virtual ~pqArraysModel() { } + + //------------------------------------------------------------------ + virtual Qt::ItemFlags flags( const QModelIndex &idx ) const { + Qt::ItemFlags value = Superclass::flags( idx ); + if (idx.isValid()) { + switch ( idx.column() ) { + case PROCESSING: + return value | Qt::ItemIsUserCheckable; + case NEW_NAME: + return value | Qt::ItemIsEditable; + default: + break; + } + } + return value; + } + + //------------------------------------------------------------------ + virtual int rowCount( const QModelIndex& idx=QModelIndex() ) const { + return idx.isValid() ? 0 : myArraysInfo.size(); + } + + //------------------------------------------------------------------ + virtual int columnCount( const QModelIndex& idx=QModelIndex() ) const { + Q_UNUSED(idx); + return 4; + } + + //------------------------------------------------------------------ + virtual QVariant data(const QModelIndex& idx, int role=Qt::DisplayRole) const { + Q_ASSERT( idx.row() < myArraysInfo.size() ); + if ( idx.column() == PROCESSING ) { + switch (role) { + case Qt::CheckStateRole: + return myArraysInfo[idx.row()].second.copyArray ? Qt::Checked : Qt::Unchecked; + default: + break; + } + } else if ( idx.column() == NAME ) { + switch ( role ) { + case Qt::DisplayRole: + case Qt::ToolTipRole: + case Qt::StatusTipRole: + return myArraysInfo[idx.row()].first; + default: + break; + } + } else if ( idx.column() == NEW_NAME ) { + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + case Qt::ToolTipRole: + case Qt::StatusTipRole: + return myArraysInfo[idx.row()].second.newName; + case Qt::ForegroundRole: { + if ( myArraysInfo[idx.row()].second.newName == myArraysInfo[idx.row()].first ) + return QApplication::palette().color(QPalette::Disabled, QPalette::Text); + } + case Qt::FontRole: { + if ( myArraysInfo[idx.row()].second.newName == myArraysInfo[idx.row()].first ) { + QFont f = QApplication::font(); + f.setItalic(true); + return f; + } + } + default: + break; + } + } + return QVariant(); + } + + //------------------------------------------------------------------ + virtual bool setData(const QModelIndex &idx, const QVariant &value, int role=Qt::EditRole) { + + if (idx.column() == PROCESSING && role == Qt::CheckStateRole) { + bool checkState = (value.toInt() == Qt::Checked); + Q_ASSERT(idx.row() < myArraysInfo.size()); + myArraysInfo[idx.row()].second.copyArray = (bool)checkState; + emit dataChanged(idx, idx); + return true; + } + + if (idx.column() == NEW_NAME && role == Qt::EditRole) { + QString new_name = value.toString(); + if ( !new_name.isEmpty() ) { + Q_ASSERT(idx.row() < myArraysInfo.size()); + myArraysInfo[idx.row()].second.newName = new_name; + emit dataChanged(idx, idx); + return true; + } + } + } + + //------------------------------------------------------------------ + QVariant headerData(int section, Qt::Orientation orientation, int role) const { + if ( orientation == Qt::Horizontal ) { + if ( role == Qt::DisplayRole || role == Qt::ToolTipRole ) { + switch ( section ) { + case PROCESSING: + return role == Qt::DisplayRole? "": "Toggle to copy arrays"; + case NAME: + return role == Qt::DisplayRole? "Origin Name": "Origin Names of arrays"; + case NEW_NAME: + return role == Qt::DisplayRole? "New Name": "New Names of arrays"; + case COMPONENTS: + return role == Qt::DisplayRole? "Components" : "Click item to edit components"; + default: + break; + } + } else if ( role == Qt::DecorationRole ) { + switch ( section ) { + case PROCESSING: return QIcon( ":/ArrayRenamerIcons/resources/copy_ico_16x16.png" ); + default: + break; + } + } + } + return Superclass::headerData( section, orientation, role ); + } + + //------------------------------------------------------------------ + QString arrayName( const QModelIndex& idx ) const { + if ( idx.isValid() && idx.row() < myArraysInfo.size() ) { + return myArraysInfo[idx.row()].first; + } + return QString(); + } + + //------------------------------------------------------------------ + void setArraysInfo( const QVector >& data ) { + emit beginResetModel(); + myArraysInfo = data; + emit endResetModel(); + } + + //------------------------------------------------------------------ + const ArraysInfoType& arraysInfo() const { + return myArraysInfo; + } + + //------------------------------------------------------------------ + ArraysInfoType& editArraysInfo() { + return myArraysInfo; + } + +private: + Q_DISABLE_COPY(pqArraysModel); +}; + +//----------------------------------------------------------------------------- +pqEditComponents::pqEditComponents( pqComponentsModel* model, QWidget* parent ) { + + myComponentsModel = model; + setWindowTitle( "Edit Components" ); + + //Layout + QVBoxLayout *mainLayout = new QVBoxLayout( this ); + QGroupBox* aComps = new QGroupBox( "Components", this ); + QGroupBox* aParams = new QGroupBox( "Parameters", this ); + QGroupBox* aBtns = new QGroupBox( this ); + mainLayout->addWidget( aComps ); + mainLayout->addWidget( aParams ); + mainLayout->addWidget( aBtns ); + + /// Table + QVBoxLayout *aCompsLayout = new QVBoxLayout( aComps ); + QTableView* componentsTable = new QTableView( this ); + componentsTable->setModel( model ); + aCompsLayout->addWidget( componentsTable ); + componentsTable->horizontalHeader()->setResizeMode( pqComponentsModel::COMPONENT_NAME, QHeaderView::Stretch ); + componentsTable->horizontalHeader()->setResizeMode( pqComponentsModel::NEW_COMPONENT_NAME, QHeaderView::Stretch ); + + /// Parameters + QVBoxLayout *aParamsLayout = new QVBoxLayout( aParams ); + myRenameAllComps = new QCheckBox( "Rename all similar Components", aParams ); + aParamsLayout->addWidget( myRenameAllComps ); + + /// Buttons + QPushButton* anOk = new QPushButton( "OK", this ); + QPushButton* aCancel = new QPushButton( "Cancel", this ); + QSpacerItem* space = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ); + QHBoxLayout* aBtnsLayout = new QHBoxLayout( aBtns ); + aBtnsLayout->addWidget( anOk ); + aBtnsLayout->addItem( space ); + aBtnsLayout->addWidget( aCancel ); + + //Connections + connect( anOk, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( myRenameAllComps, SIGNAL( toggled(bool) ), this, SLOT( onRenameAll(bool) ) ); + connect( aCancel, SIGNAL( clicked() ), this, SLOT( reject() ) ); +} + +//----------------------------------------------------------------------------- +pqEditComponents::~pqEditComponents() { } + +//----------------------------------------------------------------------------- +bool pqEditComponents::renameAllComps() { + return myRenameAllComps->checkState() == Qt::Checked; +} + +//----------------------------------------------------------------------------- +void pqEditComponents::onRenameAll( bool val ) { + myComponentsModel->setRenameSimilar( val ); +} + +//----------------------------------------------------------------------------- +pqArraysEditorPropertyWidget::pqArraysEditorPropertyWidget( vtkSMProxy* smproxy, vtkSMPropertyGroup* smgroup, QWidget* parentObject ) : + Superclass(smproxy, parentObject) { + + myPropertyGroup = smgroup; + myConnection = vtkEventQtSlotConnect::New(); + + // Table + myArraysTable = new QTableView(this); + myArraysModel = new pqArraysModel(this); + myArraysTable->setModel(myArraysModel); + + // Layout + QVBoxLayout* lay = new QVBoxLayout(this); + lay->addWidget(myArraysTable); + myArraysTable->horizontalHeader()->setResizeMode( pqArraysModel::PROCESSING, QHeaderView::ResizeToContents ); + myArraysTable->horizontalHeader()->setResizeMode( pqArraysModel::NAME, QHeaderView::Stretch); + myArraysTable->horizontalHeader()->setResizeMode( pqArraysModel::NEW_NAME, QHeaderView::Stretch ); + myArraysTable->horizontalHeader()->setResizeMode( pqArraysModel::COMPONENTS, QHeaderView::ResizeToContents ); + myArraysTable->resizeColumnsToContents(); + + // Connections + /// Clien < - > Server + addPropertyLink( this, "arrayInfo", SIGNAL( arraysInfoChanged() ), smgroup->GetProperty( "ArrayInfo" ) ); + addPropertyLink( this, "componentsInfo", SIGNAL( componentsInfoChanged() ), smgroup->GetProperty( "ComponentInfo" ) ); + myConnection->Connect( smproxy, vtkCommand::UpdateDataEvent, this, SLOT( onInputDataChanged() ) ); + + /// Qt + QObject::connect( myArraysModel, + SIGNAL( dataChanged( const QModelIndex &, const QModelIndex& ) ), + this, SLOT( onDataChanged( const QModelIndex&, const QModelIndex& ) ) ); + + // Obtains list of the data arrays + updateArraysList(); +} + +pqArraysEditorPropertyWidget::~pqArraysEditorPropertyWidget() { + delete myArraysModel; + myConnection->Delete(); +} + +//----------------------------------------------------------------------------- +void pqArraysEditorPropertyWidget::setArraysInfo( const QList & values ){ + pqArraysModel::ArraysInfoType vdata; + vdata.resize( values.size()/3 ); + for ( int cc=0; ( cc + 1 ) < values.size(); cc+=3 ) { + vdata[cc/3].first = values[cc].toString(); + vdata[cc/3].second.newName = values[cc+1].toString(); + vdata[cc/3].second.copyArray = values[cc+2].toBool(); + } + myArraysModel->setArraysInfo( vdata ); +} + +//----------------------------------------------------------------------------- +QList pqArraysEditorPropertyWidget::arraysInfo() const { + const pqArraysModel::ArraysInfoType &vdata = myArraysModel->arraysInfo(); + QList reply; + for ( int cc=0; cc < vdata.size(); cc++ ) { + if(vdata[cc].first != vdata[cc].second.newName ) { + reply.push_back( vdata[cc].first ); + reply.push_back( vdata[cc].second.newName ); + reply.push_back( vdata[cc].second.copyArray ? 1 : 0 ); + } + } + return reply; +} + +//----------------------------------------------------------------------------- +void pqArraysEditorPropertyWidget::setComponentsInfo( const QList & values ) { + + pqArraysModel::ArraysInfoType &vdata = myArraysModel->editArraysInfo(); + for(int i = 0; i < vdata.size(); i++) { + vdata.resize( values.size()/3 ); + QString anArrayName = "", aNewCompName = ""; + int aCompId = 0; + for ( int cc=0; ( cc + 1 ) < values.size(); cc+=3 ) { + anArrayName = values[cc].toString(); + aCompId = values[cc+1].toInt(); + aNewCompName = values[cc+2].toString(); + } + if( vdata[i].first == anArrayName && aCompId < vdata[i].second.myComponentsInfo.size() ) { + vdata[i].second.myComponentsInfo[i].second = aNewCompName; + } + } +} + +//----------------------------------------------------------------------------- +QList pqArraysEditorPropertyWidget::componentsInfo() const { + + pqArraysModel::ArraysInfoType &vdata = myArraysModel->editArraysInfo(); + QList reply; + for ( int cc=0; cc < vdata.size(); cc++ ) { + for ( int ll = 0; ll < vdata[cc].second.myComponentsInfo.size(); ll++ ) { + if ( vdata[cc].second.myComponentsInfo[ll].second != vdata[cc].second.myComponentsInfo[ll].first) { + QString aArrayName = + (vdata[cc].first != vdata[cc].second.newName && !vdata[cc].second.newName.isEmpty()) ? vdata[cc].second.newName : vdata[cc].first; + reply.push_back( aArrayName ); + reply.push_back( ll ); + reply.push_back( vdata[cc].second.myComponentsInfo[ll].second ); + } + } + } + + return reply; +} + +//----------------------------------------------------------------------------- +void pqArraysEditorPropertyWidget::onDataChanged( const QModelIndex& topleft, const QModelIndex& btmright ) { + if ( topleft.column() == pqArraysModel::PROCESSING || topleft.column() == pqArraysModel::NEW_NAME ) { + if ( topleft.column() == pqArraysModel::PROCESSING ) { + const pqArraysModel::ArraysInfoType &vdata = myArraysModel->arraysInfo(); + Q_ASSERT(topleft.row() < vdata.size()); + if( vdata[topleft.row()].second.isCompomentsModified() ) { + myPropertyGroup->GetProperty( "ComponentInfo" )->Modified(); + } + } + emit arraysInfoChanged(); + } +} + +//----------------------------------------------------------------------------- +void pqArraysEditorPropertyWidget::updateArraysList() { + vtkPVDataSetAttributesInformation *cdi = NULL, *pdi = NULL; + + vtkSMSourceProxy* input = vtkSMSourceProxy::SafeDownCast( vtkSMUncheckedPropertyHelper( proxy(), "Input" ).GetAsProxy( 0 ) ); + + // Null insput + if ( !input ) + return; + + const QVector > &oldModelData = myArraysModel->arraysInfo(); + + QStringList oldNames; + QPair oldArrayInfo; + foreach ( oldArrayInfo, oldModelData ) { + oldNames.append(oldArrayInfo.first); + } + + myDataTime = input->GetDataInformation( 0 )->GetMTime(); + + pdi = input->GetDataInformation( 0 )->GetPointDataInformation(); + cdi = input->GetDataInformation( 0 )->GetCellDataInformation(); + QVector > myModelArraysInfo; + + if ( pdi ) { + for ( int i=0; iGetNumberOfArrays(); i++ ) { + vtkPVArrayInformation* pvArrayInformation = pdi->GetArrayInformation( i ); + QString anArrayName = QString( pvArrayInformation->GetName() ); + int numComponents = pvArrayInformation->GetNumberOfComponents(); + int index = oldNames.indexOf(anArrayName); + if ( index < 0 ) { + + myModelArraysInfo.push_back( qMakePair( anArrayName , pqArraysModel::ArrayInfo() ) ); + myModelArraysInfo.last().second.newName = anArrayName; + for ( int j=0; jGetComponentName( j ); + myModelArraysInfo.last().second.myComponentsInfo.insert(j, qMakePair( compName, compName ) ); + } + } else { + + myModelArraysInfo.push_back( qMakePair(anArrayName, oldModelData[index].second ) ); + if ( oldModelData[index].second.nbComps() != numComponents ) { + for ( int j=0; jGetComponentName( j ); + myModelArraysInfo.last().second.myComponentsInfo.insert( j, qMakePair( compName, compName ) ); + } + } + } + } + } + if ( cdi ) { + for ( int i=0; iGetNumberOfArrays(); i++ ) { + + vtkPVArrayInformation* pvArrayInformation = cdi->GetArrayInformation( i ); + QString anArrayName = QString( pvArrayInformation->GetName() ); + int numComponents = pvArrayInformation->GetNumberOfComponents(); + int index = oldNames.indexOf(anArrayName); + if ( index < 0 ) { + myModelArraysInfo.push_back( qMakePair( anArrayName , pqArraysModel::ArrayInfo() ) ); + myModelArraysInfo.last().second.newName = anArrayName; + for ( int j=0; jGetComponentName( j ); + myModelArraysInfo.last().second.myComponentsInfo.insert( j, qMakePair( compName, compName ) ); + } + } else { + + myModelArraysInfo.push_back( qMakePair(anArrayName, oldModelData[index].second ) ); + if ( oldModelData[index].second.nbComps() != numComponents ) { + for ( int j=0; jGetComponentName( j ); + myModelArraysInfo.last().second.myComponentsInfo.insert( j, qMakePair( compName, compName ) ); + } + } + } + } + } + + myArraysModel->setArraysInfo(myModelArraysInfo); + + for ( int i = 0; i < myModelArraysInfo.size(); i++ ) { + if ( myModelArraysInfo[i].second.nbComps() > 1 ) { + QPushButton* aBtn = new QPushButton(myArraysTable); + aBtn->setProperty("arrayName",myModelArraysInfo[i].first); + aBtn->setIcon( QIcon( ":/ArrayRenamerIcons/resources/edit_ico_16x16.png" ) ); + myArraysTable->setIndexWidget( myArraysModel->index( i, 3 ), aBtn ); + connect(aBtn, SIGNAL( clicked() ) , this, SLOT( onComponentsEdit() ) ); + } + } +} + +//----------------------------------------------------------------------------- +void pqArraysEditorPropertyWidget::onInputDataChanged() { + + vtkSMSourceProxy* input = vtkSMSourceProxy::SafeDownCast( vtkSMUncheckedPropertyHelper( proxy(), "Input" ).GetAsProxy( 0 ) ); + if ( myDataTime < input->GetDataInformation( 0 )->GetMTime() ) { + updateArraysList(); + } +} + +//----------------------------------------------------------------------------- +void pqArraysEditorPropertyWidget::onComponentsEdit() { + QObject* snd = sender(); + QVariant v = snd->property("arrayName"); + int index = -1; + + if( v.isValid() ) { + QString anArrayName = v.toString(); + pqComponentsModel::ComponentsInfoType* aComponents = NULL; + pqArraysModel::ArraysInfoType &aModelData = myArraysModel->editArraysInfo(); + for ( int i = 0 ; i < aModelData.size() ; i++ ) { + pqArraysModel::ArraysInfoItemType& item = aModelData[i]; + if( item.first == anArrayName ) { + aComponents = &item.second.myComponentsInfo; + index = i; + break; + } + } + + if( aComponents ) { + pqComponentsModel* aCompsModel = new pqComponentsModel(); + aCompsModel->setComponentsInfo(*aComponents); + pqEditComponents* dlg = new pqEditComponents(aCompsModel, this); + if ( dlg->exec() == QDialog::Accepted ) { + const pqComponentsModel::ComponentsInfoType& aRenamedComponents = aCompsModel->componentsInfo(); + if( dlg->renameAllComps() ) { + /// Rename all components in all arrays + for ( int i = 0 ; i < aModelData.size() ; i++ ) { + pqArraysModel::ArraysInfoItemType& item = aModelData[i]; + for (int j = 0; j < item.second.myComponentsInfo.size(); j++ ) { + pqComponentsModel::ComponentsInfoType &aComps = item.second.myComponentsInfo; + for (int k = 0; k < aRenamedComponents.size(); k++ ) { + if( aComps[j].first == aRenamedComponents[k].first ) { + aComps[j].second = aRenamedComponents[k].second; + } + } + } + } + } else { + if( index >= 0 ) { + aModelData[index].second.myComponentsInfo = aRenamedComponents; + } + } + emit componentsInfoChanged(); + } + delete dlg; + delete aCompsModel; + } + } +} diff --git a/src/Plugins/ArrayRenamer/pqArraysEditorPropertyWidget.h b/src/Plugins/ArrayRenamer/pqArraysEditorPropertyWidget.h new file mode 100644 index 00000000..75c2d214 --- /dev/null +++ b/src/Plugins/ArrayRenamer/pqArraysEditorPropertyWidget.h @@ -0,0 +1,96 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Roman NIKOLAEV + +/*========================================================================*/ +#ifndef __pqArraysEditorPropertyWidget_h +#define __pqArraysEditorPropertyWidget_h + +#include +#include + +// ParaView classes +class vtkSMPropertyGroup; +class vtkEventQtSlotConnect; + +// Qt Classes +class QTableView; +class QModelIndex; + +class pqArraysModel; + +/// pqArraysEditorPropertyWidget is the pqPropertyWidget used to edit +/// arrays and array's components. +class VTK_EXPORT pqArraysEditorPropertyWidget : public pqPropertyWidget { + + Q_OBJECT + + Q_PROPERTY(QList arrayInfo + READ arraysInfo + WRITE setArraysInfo + NOTIFY arraysInfoChanged) + + Q_PROPERTY(QList componentsInfo + READ componentsInfo + WRITE setComponentsInfo + NOTIFY componentsInfoChanged) + + + typedef pqPropertyWidget Superclass; + public: + pqArraysEditorPropertyWidget(vtkSMProxy* proxy, vtkSMPropertyGroup* smgroup, QWidget* parent=0); + virtual ~pqArraysEditorPropertyWidget(); + + /// Get/Set the arrays Info + QList arraysInfo() const; + void setArraysInfo(const QList&); + + /// Get/Set the arrays Info + QList componentsInfo() const; + void setComponentsInfo(const QList&); + + + signals: + /// Fired when the arrays Info is changes. + void arraysInfoChanged(); + void componentsInfoChanged(); + +private slots: + /// called whenever the internal model's data changes. + void onDataChanged(const QModelIndex& topleft, const QModelIndex& btmright); + void onComponentsEdit(); + + /// called whenever the input changed. + void onInputDataChanged(); + + private: // Methods + void updateArraysList(); + + private: // Fields + + vtkSmartPointer myPropertyGroup; + vtkEventQtSlotConnect* myConnection; + unsigned long myDataTime; + + //Array's table + pqArraysModel* myArraysModel; + QTableView* myArraysTable; +}; + +#endif // __pqArraysEditorPropertyWidget_h diff --git a/src/Plugins/ArrayRenamer/pqEditComponents.h b/src/Plugins/ArrayRenamer/pqEditComponents.h new file mode 100644 index 00000000..0c37df5a --- /dev/null +++ b/src/Plugins/ArrayRenamer/pqEditComponents.h @@ -0,0 +1,41 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Roman NIKOLAEV + + +#include + +class pqComponentsModel; +class QCheckBox; + +class pqEditComponents : public QDialog { + Q_OBJECT +public: + pqEditComponents( pqComponentsModel* model, QWidget* parent ); + ~pqEditComponents(); + + bool renameAllComps(); + +private slots: + void onRenameAll(bool val); + private: + QCheckBox* myRenameAllComps; + pqComponentsModel* myComponentsModel; + +}; diff --git a/src/Plugins/ArrayRenamer/resources/copy_ico_16x16.png b/src/Plugins/ArrayRenamer/resources/copy_ico_16x16.png new file mode 100755 index 00000000..8969c406 Binary files /dev/null and b/src/Plugins/ArrayRenamer/resources/copy_ico_16x16.png differ diff --git a/src/Plugins/ArrayRenamer/resources/edit_ico_16x16.png b/src/Plugins/ArrayRenamer/resources/edit_ico_16x16.png new file mode 100755 index 00000000..b73a4a3e Binary files /dev/null and b/src/Plugins/ArrayRenamer/resources/edit_ico_16x16.png differ diff --git a/src/Plugins/ArrayRenamer/resources/rename_ico_24x24.png b/src/Plugins/ArrayRenamer/resources/rename_ico_24x24.png new file mode 100755 index 00000000..9066ff59 Binary files /dev/null and b/src/Plugins/ArrayRenamer/resources/rename_ico_24x24.png differ diff --git a/src/Plugins/ArrayRenamer/vtkArrayRenamerFilter.cxx b/src/Plugins/ArrayRenamer/vtkArrayRenamerFilter.cxx new file mode 100644 index 00000000..b5a24eb8 --- /dev/null +++ b/src/Plugins/ArrayRenamer/vtkArrayRenamerFilter.cxx @@ -0,0 +1,195 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Roman NIKOLAEV + +#include "vtkArrayRenamerFilter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +//For debug +//#include + +class vtkArrayRenamerFilter::vtkInternals +{ +public: + //Vector which contains information about array's components : origin_component_name <-> new_name + typedef std::vector< std::pair > ComponentsInfo; + + struct ArrayInfo + { + std::string NewName; // New name of the array + bool CopyArray; // Make copy of the array or keep origin array, but change the name + ComponentsInfo ComponentVector; // Components of the array + ArrayInfo(): + NewName( "" ), + CopyArray( false ) + { + } + }; + typedef std::map ArraysType; // Map : origin_aray_name <-> ArrayInfo struct + ArraysType Arrays; +}; + + +//------------------------------------------------------------------------------ +vtkStandardNewMacro(vtkArrayRenamerFilter); +//-------------------------------------------------------------------------------------------------- +vtkArrayRenamerFilter::vtkArrayRenamerFilter() +{ + this->Internals = new vtkInternals(); +} + +//-------------------------------------------------------------------------------------------------- +vtkArrayRenamerFilter::~vtkArrayRenamerFilter() +{ + delete this->Internals; +} + + + +//-------------------------------------------------------------------------------------------------- +int vtkArrayRenamerFilter::RequestData( vtkInformation* theRequest, + vtkInformationVector** theInputVector, + vtkInformationVector* theOutputVector ) +{ + + //std::cout<<"vtkArrayRenamerFilter::RequestData !!! "<GetInformationObject( 0 ); + vtkInformation *anOutputInfo = theOutputVector->GetInformationObject( 0 ); + + vtkDataSet* anInput = vtkDataSet::GetData(theInputVector[0], 0); + vtkDataSet* anOutput = vtkDataSet::GetData(theOutputVector, 0); + anOutput->DeepCopy(anInput); + vtkFieldData* data = 0; + + vtkInternals::ArraysType::iterator it = this->Internals->Arrays.begin(); + for( ; it != this->Internals->Arrays.end(); it ++ ) { + vtkDataArray* array = anOutput->GetPointData()->GetArray( it->first.c_str() ); + data = anOutput->GetPointData(); + if( !array ) { + array = anOutput->GetCellData()->GetArray( it->first.c_str() ); + data = anOutput->GetCellData(); + } + + if( array && !it->second.NewName.empty() ) { + + if ( it->second.CopyArray ) { + vtkDataArray* new_array = array->NewInstance(); + new_array->DeepCopy(array); + data->AddArray(new_array); + array = new_array; + } + array->SetName(it->second.NewName.c_str()); + } + + if ( array ) { + vtkInternals::ComponentsInfo::iterator vect_it = it->second.ComponentVector.begin(); + for( ; vect_it != it->second.ComponentVector.end(); vect_it++ ) { + array->SetComponentName( vect_it->first, vect_it->second.c_str() ); + } + } + } + + return Superclass::RequestData( theRequest, theInputVector, theOutputVector ); +} + + +void vtkArrayRenamerFilter::SetComponentInfo( const char* arrayname, const int compid, const char* newcompname ) { + //std::cout<<"vtkArrayRenamerFilter::SetComponentArrayInfo : "<Internals->Arrays.clear(); + this->Modified(); +} + +void vtkArrayRenamerFilter::ClearComponentsInfo() { + //std::cout<<"vtkArrayRenamerFilter::ClearComponentsInfo"<Internals->Arrays.begin(); + for( ; it != this->Internals->Arrays.end(); it ++ ){ + it->second.ComponentVector.clear(); + } + this->Modified(); +} diff --git a/src/Plugins/ArrayRenamer/vtkArrayRenamerFilter.h b/src/Plugins/ArrayRenamer/vtkArrayRenamerFilter.h new file mode 100644 index 00000000..828132d1 --- /dev/null +++ b/src/Plugins/ArrayRenamer/vtkArrayRenamerFilter.h @@ -0,0 +1,63 @@ +// Copyright (C) 2014-2015 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Roman NIKOLAEV + +#ifndef __ArrayRenamerFilter_h_ +#define __ArrayRenamerFilter_h_ + +#include + +/** + * Description of class: + * Class allows to rename data arrays and array's components. +*/ +class VTK_EXPORT vtkArrayRenamerFilter : public vtkDataSetAlgorithm +{ +public: + /// Returns pointer on a new instance of the class + static vtkArrayRenamerFilter* New(); + + vtkTypeMacro( vtkArrayRenamerFilter, vtkDataSetAlgorithm ); + + void SetArrayInfo( const char* originarrayname, const char* newarrayname, bool copy ); + void ClearArrayInfo(); + + void SetComponentInfo( const char* arrayname, const int compid, const char* newarrayname ); + void ClearComponentsInfo(); +protected: + /// Constructor & destructor + vtkArrayRenamerFilter(); + virtual ~vtkArrayRenamerFilter(); + + virtual int RequestData( vtkInformation *, + vtkInformationVector **, + vtkInformationVector * ); +private: + vtkArrayRenamerFilter( const vtkArrayRenamerFilter & ); // Not implemented yet + void operator=( const vtkArrayRenamerFilter & ); // Not implemented yet + + void FillListOfArrays( vtkDataObject* ); + + class vtkInternals; + friend class vtkInternals; + vtkInternals* Internals; + +}; + +#endif // __ArrayRenamerFilter_h_