X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESHGUI%2FSMESHGUI_FilterDlg.cxx;h=95f8ed3039d5e3e72b2157a38ba6a641790c1e4f;hp=5995bd8bad1c58400f21d4af07919fa07b495010;hb=81f4aba6d730b754eeac248a753c33ba673beaa1;hpb=c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8 diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 5995bd8ba..95f8ed303 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -1,22 +1,22 @@ // SMESH SMESHGUI : GUI for SMESH component // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// 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 -// +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org // // @@ -25,19 +25,52 @@ // Author : Sergey LITONIN // Module : SMESH -#include "SMESHGUI.h" #include "SMESHGUI_FilterDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_Filter.h" +#include "SMESHGUI_FilterUtils.h" +#include "SMESHGUI_FilterLibraryDlg.h" + #include "SMESH_Actor.h" -#include "VTKViewer_InteractorStyleSALOME.h" -#include "VTKViewer_ViewFrame.h" -#include "QAD_RightFrame.h" -#include "SALOME_ListIteratorOfListIO.hxx" -#include "SALOMEGUI_QtCatchCorbaException.hxx" +#include "SMESH_NumberFilter.hxx" +#include "SMESH_TypeFilter.hxx" + +#include "GEOMBase.h" +#include "GEOM_FaceFilter.h" +#include "GEOM_TypeFilter.h" +#include "SUIT_Desktop.h" +#include "SUIT_ResourceMgr.h" +#include "SalomeApp_Application.h" +#include "SalomeApp_Tools.h" +#include "SalomeApp_Study.h" + +#include "SALOME_ListIO.hxx" +#include "SALOME_ListIteratorOfListIO.hxx" +#include "SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger.hxx" +#include "SALOMEDSClient_Study.hxx" + +#include "SVTK_ViewWindow.h" +#include "SVTK_Selector.h" + +// OCCT Includes +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +// QT Includes #include #include #include @@ -57,741 +90,1940 @@ #include #include #include +#include +#include -#define SPACING 5 +// IDL Headers +#include "SALOMEconfig.h" +#include CORBA_SERVER_HEADER(SMESH_Group) + +#define SPACING 5 #define MARGIN 10 -static int maxLength( const QStringList& theList, const QFontMetrics& theMetrics ) +using namespace SMESH; + +static int maxLength (const QMap theMap, const QFontMetrics& theMetrics) { int aRes = 0; - QStringList::const_iterator anIter; - for ( anIter = theList.begin(); anIter != theList.end(); ++anIter ) - aRes = Max( aRes, theMetrics.width( *anIter ) ); - return aRes; + QMap::const_iterator anIter; + for (anIter = theMap.begin(); anIter != theMap.end(); ++anIter) + aRes = Max(aRes, theMetrics.width(anIter.data())); + return aRes; +} + +static int getFilterId (SMESH::ElementType theType) +{ + switch (theType) + { + case SMESH::NODE : return SMESHGUI_NodeFilter; + case SMESH::EDGE : return SMESHGUI_EdgeFilter; + case SMESH::FACE : return SMESHGUI_FaceFilter; + case SMESH::VOLUME : return SMESHGUI_VolumeFilter; + case SMESH::ALL : return SMESHGUI_AllElementsFilter; + default : return SMESHGUI_UnknownFilter; + } } /* - Class : SMESHGUI_FilterDlg::Table - Description : Table used by this dialog + Class : SMESHGUI_FilterTable::AdditionalWidget + Description : Class for storing additional parameters of criterion */ -class SMESHGUI_FilterDlg::Table : public QTable +class SMESHGUI_FilterTable::AdditionalWidget : public QFrame { public: - Table( QWidget* parent = 0 ); - Table( int numRows, int numCols, QWidget* parent = 0 ); - virtual ~Table(); + enum { Tolerance }; - void SetEditable( const bool state, const int row, const int col ); - bool IsEditable( const int row, const int col ) const; +public: - virtual bool eventFilter( QObject *o, QEvent *e ); - virtual void insertRows( int row, int count = 1 ); - virtual QString text( int row, int col ) const; + AdditionalWidget(QWidget* theParent); + virtual ~AdditionalWidget(); + + virtual void GetParameters(QValueList&) const; + virtual bool IsValid(const bool theMsg = true) const; + virtual double GetDouble(const int theId) const; + virtual int GetInteger(const int theId) const; + virtual QString GetString(const int theId) const; + virtual void SetDouble(const int theId, const double theVal); + virtual void SetInteger(const int theId, const int theVal); + virtual void SetString(const int theId, const QString& theVal); + void SetEditable(const int theId, const bool isEditable); + void SetEditable(const bool isEditable); + +private: + QMap< int, QLineEdit* > myLineEdits; }; -SMESHGUI_FilterDlg::Table::Table( QWidget* parent ) -: QTable( parent, "SMESHGUI_FilterDlg::Table" ) +SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget (QWidget* theParent) + : QFrame(theParent) { + QLabel* aLabel = new QLabel(tr("SMESH_TOLERANCE"), this); + myLineEdits[ Tolerance ] = new QLineEdit(this); + QDoubleValidator* aValidator = new QDoubleValidator(myLineEdits[ Tolerance ]); + aValidator->setBottom(0); + myLineEdits[ Tolerance ]->setValidator(aValidator); + + QHBoxLayout* aLay = new QHBoxLayout(this, 0, SPACING); + aLay->addWidget(aLabel); + aLay->addWidget(myLineEdits[ Tolerance ]); + + QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + aLay->addItem(aSpacer); + + QString aText = QString("%1").arg(Precision::Confusion()); + myLineEdits[ Tolerance ]->setText(aText); } -SMESHGUI_FilterDlg::Table::Table( int numRows, int numCols, QWidget* parent ) -: QTable( numRows, numCols, parent, "SMESHGUI_FilterDlg::Table" ) + SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget() { } -SMESHGUI_FilterDlg::Table::~Table() +void SMESHGUI_FilterTable::AdditionalWidget::GetParameters (QValueList& theList) const { + theList.clear(); + theList.append(Tolerance); } -void SMESHGUI_FilterDlg::Table::SetEditable( const bool isEditable, const int row, const int col ) +bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const { - QTableItem* anItem = item( row, col ); - if( anItem ) - takeItem( anItem ); + if (!isEnabled()) + return true; - if ( !isEditable ) - { - setItem( row, col, new QTableItem( this, QTableItem::Never, "" ) ); - } - else - { - setItem( row, col, new QTableItem( this, QTableItem::OnTyping, "" ) ); + QValueList aParams; + GetParameters(aParams); + QValueList::const_iterator anIter; + for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) { + const QLineEdit* aWg = myLineEdits[ *anIter ]; + int p = 0; + QString aText = aWg->text(); + if (aWg->isEnabled() && aWg->validator()->validate(aText, p) != QValidator::Acceptable) { + if (theMsg) + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SMESHGUI_INVALID_PARAMETERS"), QMessageBox::Ok); + return false; + } } + + return true; } -bool SMESHGUI_FilterDlg::Table::IsEditable( const int row, const int col ) const +double SMESHGUI_FilterTable::AdditionalWidget::GetDouble (const int theId) const { - QTableItem* anItem = item( row, col ); - return anItem == 0 || anItem->editType() != QTableItem::Never; + return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toDouble() : 0; } -void SMESHGUI_FilterDlg::Table::insertRows( int row, int count ) +int SMESHGUI_FilterTable::AdditionalWidget::GetInteger (const int theId) const { - int anEditRow = currEditRow(); - int anEditCol = currEditCol(); - -// printf( "sln: anEditRow = %d, anEditCol = %d\n", anEditRow, anEditCol ); + return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toInt() : 0; +} - if ( anEditRow >= 0 && anEditCol >= 0 ) - endEdit( anEditRow, anEditCol, true, false ); +QString SMESHGUI_FilterTable::AdditionalWidget::GetString (const int theId) const +{ + return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text() : QString(""); +} - QTable::insertRows( row, count ); +void SMESHGUI_FilterTable::AdditionalWidget::SetDouble (const int theId, const double theVal) +{ + if (myLineEdits.contains(theId)) + myLineEdits[ theId ]->setText(QString("%1").arg(theVal)); } -QString SMESHGUI_FilterDlg::Table::text( int row, int col ) const +void SMESHGUI_FilterTable::AdditionalWidget::SetInteger (const int theId, const int theVal) { - int anEditRow = currEditRow(); - int anEditCol = currEditCol(); + if (myLineEdits.contains(theId)) + myLineEdits[ theId ]->setText(QString("%1").arg(theVal)); +} - if ( anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col ) - ((Table*)this)->endEdit( row, col, true, false ); +void SMESHGUI_FilterTable::AdditionalWidget::SetString (const int theId, const QString& theVal) +{ + if (myLineEdits.contains(theId)) + myLineEdits[ theId ]->setText(theVal); +} - return QTable::text( row, col ); +void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const int theId, const bool isEditable) +{ + if (myLineEdits.contains(theId)) + myLineEdits[ theId ]->setEdited(isEditable); } -bool SMESHGUI_FilterDlg::Table::eventFilter( QObject *o, QEvent *e ) +void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable) { - return QTable::eventFilter( o, e ); + QValueList aParams; + GetParameters(aParams); + QValueList::const_iterator anIter; + for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) + myLineEdits[ *anIter ]->setEdited(isEditable); } /* - Class : SMESHGUI_FilterDlg - Description : Dialog to specify filters for VTK viewer + Class : SMESHGUI_FilterTable::ComboItem + Description : Combo table item. Identificator corresponding to string may be assigned */ +class SMESHGUI_FilterTable::ComboItem : public QComboTableItem +{ +public: + ComboItem(QTable*, const QMap&); + virtual ~ComboItem(); -//======================================================================= -// name : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg -// Purpose : Constructor -//======================================================================= -SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget* theParent, - const int theType, - const bool theModal, - const char* theName ) -: QDialog( theParent, theName, theModal, - WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ) + virtual void setStringList (const QStringList & l); + void setStringList(const QMap& theIds); + + int GetValue() const; + void SetValue(const int); + +private: + + QMap myNumToId; + QMap myIdToNum; +}; + +SMESHGUI_FilterTable::ComboItem::ComboItem (QTable* theParent, + const QMap& theIds) +: QComboTableItem(theParent, QStringList()) { - myType = theType; + setStringList(theIds); +} - setCaption( tr( "CAPTION" ) ); +void SMESHGUI_FilterTable::ComboItem::setStringList (const QStringList & l) +{ + QComboTableItem::setStringList(l); +} - QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING ); +void SMESHGUI_FilterTable::ComboItem::setStringList (const QMap& theIds) +{ + int i = 0; + QStringList aList; + QMap::const_iterator anIter; + for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) { + myNumToId[ i ] = anIter.key(); + myIdToNum[ anIter.key() ] = i; + aList.append(anIter.data()); + i++; + } - myMainFrame = createMainFrame ( this ); - QFrame* aBtnFrame = createButtonFrame( this, theModal ); + setStringList(aList); +} - aDlgLay->addWidget( myMainFrame ); - aDlgLay->addWidget( aBtnFrame ); +SMESHGUI_FilterTable::ComboItem::~ComboItem() +{ +} - aDlgLay->setStretchFactor( myMainFrame, 1 ); +int SMESHGUI_FilterTable::ComboItem::GetValue() const +{ + return myNumToId[ currentItem() ]; +} - Init( myType ); +void SMESHGUI_FilterTable::ComboItem::SetValue (const int theVal) +{ + setCurrentItem(myIdToNum[ theVal ]); } +/* + Class : SMESHGUI_FilterTable::Table + Description : Table used by this widget +*/ + +class SMESHGUI_FilterTable::Table : public QTable +{ +public: + Table(QWidget* parent); + Table(int numRows, int numCols, QWidget* parent = 0); + virtual ~Table(); + + void SetEditable(const bool state, const int row, const int col); + bool IsEditable(const int row, const int col) const; + + virtual void insertRows(int row, int count = 1); + virtual QString text(int row, int col) const; +}; + //======================================================================= -// name : SMESHGUI_FilterDlg::createMainFrame -// Purpose : Create frame containing dialog's input fields +// name : SMESHGUI_FilterTable::Table::Table +// Purpose : Constructor //======================================================================= -QFrame* SMESHGUI_FilterDlg::createMainFrame( QWidget* theParent ) +SMESHGUI_FilterTable::Table::Table (QWidget* parent) +: QTable(parent, "SMESHGUI_FilterTable::Table") { - QGroupBox* aMainFrame = new QGroupBox( 1, Qt::Horizontal, theParent ); - aMainFrame->setFrameStyle( QFrame::NoFrame ); - aMainFrame->setInsideMargin( 0 ); - - // filter frame +} - QGroupBox* aFilterGrp = new QGroupBox( 1, Qt::Horizontal, tr ( "Filter" ), aMainFrame ); - QFrame* aFilterFrame = new QFrame( aFilterGrp ); +SMESHGUI_FilterTable::Table::Table (int numRows, int numCols, QWidget* parent) +: QTable(numRows, numCols, parent, "SMESHGUI_FilterTable::Table") +{ +} - myTableGrp = new QGroupBox( 1, Qt::Horizontal, aFilterFrame ); - myTableGrp->setFrameStyle( QFrame::NoFrame ); - myTableGrp->setInsideMargin( 0 ); - - myTables[ myType ] = createTable( myTableGrp, myType ); - myAddBtn = new QPushButton( tr( "ADD" ), aFilterFrame ); - myRemoveBtn = new QPushButton( tr( "REMOVE" ), aFilterFrame ); - myClearBtn = new QPushButton( tr( "CLEAR" ), aFilterFrame ); +SMESHGUI_FilterTable::Table::~Table() +{ +} - QGridLayout* aLay = new QGridLayout( aFilterFrame, 4, 2, 0, SPACING ); +//======================================================================= +// name : SMESHGUI_FilterTable::Table::SetEditable +// Purpose : Set editable of specified cell +//======================================================================= +void SMESHGUI_FilterTable::Table::SetEditable (const bool isEditable, + const int row, const int col) +{ + QTableItem* anItem = item(row, col); + if(anItem) + takeItem(anItem); - aLay->addMultiCellWidget( myTableGrp, 0, 3, 0, 0 ); - aLay->addWidget( myAddBtn, 0, 1 ); - aLay->addWidget( myRemoveBtn, 1, 1 ); - aLay->addWidget( myClearBtn, 2, 1 ); - aLay->setColStretch( 0, 1 ); - aLay->setColStretch( 1, 0 ); + if (!isEditable) + setItem(row, col, new QTableItem(this, QTableItem::Never, "")); + else + setItem(row, col, new QTableItem(this, QTableItem::OnTyping, "")); +} - mySetInViewer = new QCheckBox( tr( "SET_IN_VIEWER" ), aFilterGrp ); - mySetInViewer->setChecked( true ); +//======================================================================= +// name : SMESHGUI_FilterTable::Table::IsEditable +// Purpose : Verify wheter cell is editable +//======================================================================= +bool SMESHGUI_FilterTable::Table::IsEditable (const int row, const int col) const +{ + QTableItem* anItem = item(row, col); + return anItem == 0 || anItem->editType() != QTableItem::Never; +} - QSpacerItem* aVSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding ); - aLay->addItem( aVSpacer, 3, 1 ); +//======================================================================= +// name : SMESHGUI_FilterTable::Table::insertRows +// Purpose : Insert rows (virtual redefined) +//======================================================================= +void SMESHGUI_FilterTable::Table::insertRows (int row, int count) +{ + int anEditRow = currEditRow(); + int anEditCol = currEditCol(); - // other controls - mySourceGrp = createSourceGroup( aMainFrame ); - - // signals and slots - connect( myAddBtn, SIGNAL( clicked() ), this, SLOT( onAddBtn() ) ); - connect( myRemoveBtn, SIGNAL( clicked() ), this, SLOT( onRemoveBtn() ) ); - connect( myClearBtn, SIGNAL( clicked() ), this, SLOT( onClearBtn() ) ); + if (anEditRow >= 0 && anEditCol >= 0) + endEdit(anEditRow, anEditCol, true, false); - return aMainFrame; + QTable::insertRows( row, count ); } //======================================================================= -// name : SMESHGUI_FilterDlg::createSourceFrame -// Purpose : Create frame containing source radio button +// name : SMESHGUI_FilterTable::Table::text +// Purpose : Get text from cell (virtual redefined) //======================================================================= -QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup( QWidget* theParent ) +QString SMESHGUI_FilterTable::Table::text (int row, int col) const { - QButtonGroup* aGrp = new QButtonGroup( 1, Qt::Vertical, tr( "SOURCE" ), theParent ); + int anEditRow = currEditRow(); + int anEditCol = currEditCol(); + + if (anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col) + ((Table*)this)->endEdit(row, col, true, false); - QRadioButton* aMeshBtn = new QRadioButton( tr( "MESH" ), aGrp ); - QRadioButton* aSelBtn = new QRadioButton( tr( "SELECTION" ), aGrp ); - QRadioButton* aGrpBtn = new QRadioButton( tr( "CURRENT_GROUP" ), aGrp ); -// QRadioButton* aNoneBtn = new QRadioButton( tr( "NONE" ), aGrp ); + return QTable::text(row, col); +} - aGrp->insert( aMeshBtn, Mesh ); - aGrp->insert( aSelBtn, Selection ); - aGrp->insert( aGrpBtn, Dialog ); -// aGrp->insert( aNoneBtn, None ); - aGrp->setButton( Selection ); +/* + Class : SMESHGUI_FilterTable + Description : Frame containig + - Button group for switching entity type + - Table for displaying filter criterions + - Buttons for editing table and filter libraries +*/ - return aGrp; +//======================================================================= +// name : SMESHGUI_FilterTable::SMESHGUI_FilterTable +// Purpose : Constructor +//======================================================================= +SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule, + QWidget* parent, + const int type) +: QFrame(parent), + myIsLocked( false ), + mySMESHGUI( theModule ) +{ + myEntityType = -1; + Init(type); } //======================================================================= -// name : SMESHGUI_FilterDlg::createTable -// Purpose : Create table +// name : SMESHGUI_FilterTable::SMESHGUI_FilterTable +// Purpose : Constructor //======================================================================= -SMESHGUI_FilterDlg::Table* SMESHGUI_FilterDlg::createTable( QWidget* theParent, - const int theType ) +SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule, + QWidget* parent, + const QValueList& types) +: QFrame(parent), + myIsLocked( false ), + mySMESHGUI( theModule ) { - // create table - Table* aTable= new Table( 0, 5, theParent ); + myEntityType = -1; + Init(types); +} - QHeader* aHeaders = aTable->horizontalHeader(); +SMESHGUI_FilterTable::~SMESHGUI_FilterTable() +{ +} - QFontMetrics aMetrics( aHeaders->font() ); +//======================================================================= +// name : SMESHGUI_FilterTable::Init +// Purpose : Create table corresponding to the specified type +//======================================================================= +void SMESHGUI_FilterTable::Init (const int type) +{ + QValueList aTypes; + aTypes.append(type); + Init(aTypes); +} - int aLenCr = abs( maxLength( getCriteria( theType ), aMetrics ) - - aMetrics.width( tr( "CRITERION" ) ) ) / aMetrics.width( ' ' ) + 5; +//======================================================================= +// name : SMESHGUI_FilterTable::Init +// Purpose : Create table corresponding to the specified type +//======================================================================= +void SMESHGUI_FilterTable::Init (const QValueList& theTypes) +{ + if (theTypes.isEmpty()) + return; - int aLenCo = abs( maxLength( getCriteria( theType ), aMetrics ) - - aMetrics.width( tr( "COMPARE" ) ) ) / aMetrics.width( ' ' ) + 5; + // Create buttons if necessary - QString aCrStr; - aCrStr.fill( ' ', aLenCr ); - QString aCoStr; - aCoStr.fill( ' ', 10 ); + if (myTables.isEmpty()) + { + int aType = theTypes.first(); + + // create main layout + QVBoxLayout* aMainLay = new QVBoxLayout(this); + QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, this); + aMainGrp->setFrameStyle(QFrame::NoFrame); + aMainGrp->setInsideMargin(0); + aMainLay->addWidget(aMainGrp); + + // create switch of entity types + myEntityTypeGrp = new QButtonGroup(1, Qt::Vertical, tr("ENTITY_TYPE"), aMainGrp); + const QMap& aSupportedTypes = getSupportedTypes(); + QMap::const_iterator anIter; + for (anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter) + { + QRadioButton* aBtn = new QRadioButton(anIter.data(), myEntityTypeGrp); + myEntityTypeGrp->insert(aBtn, anIter.key()); + } - aHeaders->setLabel( 0, tr( "CRITERION" ) + aCrStr ); - aHeaders->setLabel( 1, tr( "COMPARE" ) + aCoStr ); - aHeaders->setLabel( 2, tr( "THRESHOLD_VALUE" ) ); - aHeaders->setLabel( 3, tr( "UNARY" ) ); - aHeaders->setLabel( 4, tr( "BINARY" ) + " " ); + myTableGrp = new QGroupBox(1, Qt::Horizontal, tr("FILTER"), aMainGrp ); + QFrame* aTableFrame = new QFrame(myTableGrp); - // set geometry of the table + // create table + mySwitchTableGrp = new QGroupBox(1, Qt::Horizontal, aTableFrame); + mySwitchTableGrp->setFrameStyle(QFrame::NoFrame); + mySwitchTableGrp->setInsideMargin(0); - for ( int i = 0; i <= 4; i++ ) - aTable->adjustColumn( i ); + myTables[ aType ] = createTable(mySwitchTableGrp, aType); - aTable->updateGeometry(); - QSize aSize = aTable->sizeHint(); - int aWidth = aSize.width(); - aTable->setMinimumSize( QSize( aWidth, aWidth / 2 ) ); - aTable->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) ); + // create buttons + myAddBtn = new QPushButton(tr("ADD"), aTableFrame); + myRemoveBtn = new QPushButton(tr("REMOVE"), aTableFrame); + myClearBtn = new QPushButton(tr("CLEAR"), aTableFrame); + myInsertBtn = new QPushButton(tr("INSERT"), aTableFrame); + myCopyFromBtn = new QPushButton(tr("COPY_FROM"), aTableFrame); + myAddToBtn = new QPushButton(tr("ADD_TO"), aTableFrame); - if ( theType == SMESH::EDGE ) - connect( aTable, SIGNAL( valueChanged( int, int ) ), - this, SLOT( onCriterionChanged( int, int ) ) ); + myAddBtn->setAutoDefault(false); + myRemoveBtn->setAutoDefault(false); + myClearBtn->setAutoDefault(false); + myInsertBtn->setAutoDefault(false); + myCopyFromBtn->setAutoDefault(false); + myAddToBtn->setAutoDefault(false); - return aTable; + myCopyFromBtn->hide(); + myAddToBtn->hide(); + + // layout widgets + QGridLayout* aLay = new QGridLayout(aTableFrame, 8, 2, 0, SPACING); + + aLay->addMultiCellWidget(mySwitchTableGrp, 0, 6, 0, 0); + aLay->addWidget(myAddBtn, 0, 1); + aLay->addWidget(myInsertBtn, 1, 1); + aLay->addWidget(myRemoveBtn, 2, 1); + aLay->addWidget(myClearBtn, 3, 1); + aLay->addWidget(myCopyFromBtn, 5, 1); + aLay->addWidget(myAddToBtn, 6, 1); + aLay->addMultiCellWidget(createAdditionalFrame(aTableFrame), 7, 7, 0, 1 ); + + aLay->setColStretch(0, 1); + aLay->setColStretch(1, 0); + + QSpacerItem* aVSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); + aLay->addItem(aVSpacer, 4, 1); + + // signals and slots + connect(myAddBtn, SIGNAL(clicked()), this, SLOT(onAddBtn())); + connect(myInsertBtn, SIGNAL(clicked()), this, SLOT(onInsertBtn())); + connect(myRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveBtn())); + connect(myClearBtn, SIGNAL(clicked()), this, SLOT(onClearBtn())); + + connect(myCopyFromBtn, SIGNAL(clicked()), this, SLOT(onCopyFromBtn())); + connect(myAddToBtn, SIGNAL(clicked()), this, SLOT(onAddToBtn())); + + connect(myEntityTypeGrp, SIGNAL(clicked(int)), this, SLOT(onEntityType(int))); + + myLibDlg = 0; + } + + // Hide buttons of entity types if necessary + const QMap& aSupportedTypes = getSupportedTypes(); + QMap::const_iterator anIt; + for (anIt = aSupportedTypes.begin(); anIt != aSupportedTypes.end(); ++anIt) + { + QButton* aBtn = myEntityTypeGrp->find(anIt.key()); + theTypes.contains(anIt.key()) ? aBtn->show() : aBtn->hide(); + } + + // select first button if there is no selected buttons or it is hidden + QButton* aBtn = myEntityTypeGrp->selected(); + if ( aBtn == 0 || theTypes.find(myEntityTypeGrp->id(aBtn)) == theTypes.end()) + myEntityTypeGrp->setButton(theTypes.first()); + + if (theTypes.count() == 1) + myEntityTypeGrp->hide(); + else + myEntityTypeGrp->show(); + + myTableGrp->updateGeometry(); + int aType = myEntityTypeGrp->id(myEntityTypeGrp->selected()); + onEntityType(aType); } //======================================================================= -// name : SMESHGUI_FilterDlg::createButtonFrame -// Purpose : Create frame containing buttons +// name : SMESHGUI_FilterTable::GetTableGrp +// Purpose : Get group box containing table. May be used for adding new widgets in it //======================================================================= -QFrame* SMESHGUI_FilterDlg::createButtonFrame( QWidget* theParent, const bool theModal ) +QWidget* SMESHGUI_FilterTable::createAdditionalFrame (QWidget* theParent) { - QGroupBox* aGrp = new QGroupBox( 1, Qt::Vertical, theParent ); - - myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aGrp ); - myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aGrp ); - QLabel* aLbl = new QLabel( aGrp ); - myCloseBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), aGrp ); + QFrame* aFrame = new QFrame(theParent); - aLbl->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + QFrame* aLine1 = new QFrame(aFrame); + QFrame* aLine2 = new QFrame(aFrame); + aLine1->setFrameStyle(QFrame::HLine | QFrame::Sunken); + aLine2->setFrameStyle(QFrame::HLine | QFrame::Sunken); + aLine1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + aLine2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) ); - connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ; - connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) ); + QLabel* aLabel = new QLabel(tr("ADDITIONAL_PARAMETERS"), aFrame); - if ( theModal ) - myApplyBtn->hide(); + myWgStack = new QWidgetStack(aFrame); - return aGrp; + QGridLayout* aLay = new QGridLayout(aFrame, 2, 3, 0, SPACING); + aLay->addWidget(aLine1, 0, 0); + aLay->addWidget(aLabel, 0, 1); + aLay->addWidget(aLine2, 0, 2); + aLay->addMultiCellWidget(myWgStack, 1, 1, 0, 2); + + return aFrame; } //======================================================================= -// name : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg -// Purpose : Destructor +// name : SMESHGUI_FilterTable::GetTableGrp +// Purpose : Get group box containing table. May be used for adding new widgets in it //======================================================================= -SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg() +QGroupBox* SMESHGUI_FilterTable::GetTableGrp() { + return myTableGrp; } //======================================================================= -// name : SMESHGUI_FilterDlg::Init -// Purpose : Init dialog fields, connect signals and slots, show dialog +// name : SMESHGUI_FilterTable::onEntityType +// Purpose : SLOT. Called when entity type changed. +// Display corresponding table //======================================================================= -void SMESHGUI_FilterDlg::Init( const int theType ) +void SMESHGUI_FilterTable::onEntityType (int theType) { - mySourceWg = 0; - mySelection = 0; - myType = theType; - myMesh = SMESH::SMESH_Mesh::_nil(); + if (myEntityType == theType) + return; - // activate corresponding tab - if ( !myTables.contains( myType ) ) - myTables[ myType ] = createTable( myTableGrp, myType ); + myIsValid = true; + emit NeedValidation(); + if (!myIsValid) + { + myEntityTypeGrp->setButton(myEntityType); + return; + } - TableMap::iterator anIter; - for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter ) - if ( anIter.key() == theType ) - anIter.data()->show(); - else - anIter.data()->hide(); + myEntityType = theType; - // set caption - setCaption( myType == SMESH::EDGE ? tr( "EDGES_TLT" ) : tr( "FACES_TLT" ) ); + if (!myTables.contains(theType)) + myTables[ theType ] = createTable(mySwitchTableGrp, theType); + + TableMap::iterator anIter; + for (anIter = myTables.begin(); anIter != myTables.end(); ++anIter) + myEntityType == anIter.key() ? anIter.data()->show() : anIter.data()->hide(); + updateBtnState(); qApp->processEvents(); - updateGeometry(); + myTables[ myEntityType ]->updateGeometry(); adjustSize(); - setEnabled( true ); - mySMESHGUI = SMESHGUI::GetSMESHGUI() ; - mySMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ; + emit EntityTypeChanged(theType); + +} - connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) ); - connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) ); +//======================================================================= +// name : SMESHGUI_FilterTable::IsValid +// Purpose : Verify validity of entered data +//======================================================================= +bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) const +{ + int aType = theEntityType == -1 ? GetType() : theEntityType; - int x, y ; - mySMESHGUI->DefineDlgPosition( this, x, y ); - this->move( x, y ); + Table* aTable = myTables[ aType ]; + for (int i = 0, n = aTable->numRows(); i < n; i++) + { + int aCriterion = GetCriterionType(i, aType); + + if (aCriterion == FT_RangeOfIds || + aCriterion == FT_BelongToGeom || + aCriterion == FT_BelongToPlane || + aCriterion == FT_BelongToCylinder || + aCriterion == FT_LyingOnGeom) { + if (aTable->text(i, 2).isEmpty()) { + if (theMess) + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("ERROR"), QMessageBox::Ok); + return false; + } + } else { + bool aRes = false; + aTable->blockSignals(true); + double aThreshold = (int)aTable->text(i, 2).toDouble(&aRes); + aTable->blockSignals(false); + + if (!aRes && aTable->IsEditable(i, 2)) { + if (theMess) + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("ERROR"), QMessageBox::Ok); + return false; + } + else if (aType == SMESH::EDGE && + GetCriterionType(i, aType) == SMESH::FT_MultiConnection && + aThreshold == 1) + { + if (theMess) + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("MULTIEDGES_ERROR"), QMessageBox::Ok); + return false; + } + } - this->show(); + QTableItem* anItem = aTable->item(i, 0); + if (myAddWidgets.contains(anItem) && !myAddWidgets[ anItem ]->IsValid()) + return false; + } - return; + return true; } //======================================================================= -// name : SMESHGUI_FilterDlg::onOk -// Purpose : SLOT called when "Ok" button pressed. -// Assign filters VTK viewer and close dialog +// name : SMESHGUI_FilterTable::SetValidity +// Purpose : Set validity of the table //======================================================================= -void SMESHGUI_FilterDlg::onOk() +void SMESHGUI_FilterTable::SetValidity (const bool isValid) { - if ( onApply() ) - { - disconnect( mySMESHGUI, 0, this, 0 ); - mySMESHGUI->ResetState() ; - accept(); - } - + myIsValid = isValid; } //======================================================================= -// name : SMESHGUI_FilterDlg::onClose -// Purpose : SLOT called when "Close" button pressed. Close dialog +// name : SMESHGUI_FilterTable::GetType +// Purpose : Get current entity type //======================================================================= -void SMESHGUI_FilterDlg::onClose() +int SMESHGUI_FilterTable::GetType() const { - disconnect( mySMESHGUI, 0, this, 0 ); - mySMESHGUI->ResetState() ; - reject() ; - return ; + return myEntityType; } //======================================================================= -// name : SMESHGUI_FilterDlg::onDeactivate -// Purpose : SLOT called when dialog must be deativated +// name : SMESHGUI_FilterTable::SetType +// Purpose : Set current entity type //======================================================================= -void SMESHGUI_FilterDlg::onDeactivate() +void SMESHGUI_FilterTable::SetType (const int type) { - setEnabled( false ); + myEntityTypeGrp->setButton(type); + onEntityType(type); } //======================================================================= -// name : SMESHGUI_FilterDlg::enterEvent -// Purpose : Event filter +// name : SMESHGUI_FilterTable::RestorePreviousEntityType +// Purpose : Restore previous entity type //======================================================================= -void SMESHGUI_FilterDlg::enterEvent( QEvent* ) +void SMESHGUI_FilterTable::RestorePreviousEntityType() { -// mySMESHGUI->EmitSignalDeactivateDialog(); - setEnabled( true ); + SetType(myEntityType); } +//======================================================================= +// name : SMESHGUI_FilterTable::GetCriterionType +// Purpose : Get type of criterion from specified row (corresponding enums in h-file) +//======================================================================= +int SMESHGUI_FilterTable::GetCriterionType (const int theRow, const int theType) const +{ + int aType = theType == -1 ? GetType() : theType; + Table* aTable = myTables[ aType ]; + ComboItem* anItem = (ComboItem*)aTable->item(theRow, 0); + return anItem != 0 ? anItem->GetValue() : FT_Undefined; +} -//================================================================================= -// function : closeEvent() -// purpose : -//================================================================================= -void SMESHGUI_FilterDlg::closeEvent( QCloseEvent* e ) +//======================================================================= +// name : SMESHGUI_FilterTable::GetCriterion +// Purpose : Get parameters of criterion from specified row +//======================================================================= +void SMESHGUI_FilterTable::GetCriterion (const int theRow, + SMESH::Filter::Criterion& theCriterion, + const int theEntityType) const { - onClose() ; + int aType = theEntityType == -1 ? GetType() : theEntityType; + Table* aTable = myTables[ aType ]; + + theCriterion.Type = ((ComboItem*)aTable->item(theRow, 0))->GetValue(); + theCriterion.UnaryOp = ((QCheckTableItem*)aTable->item(theRow, 3))->isChecked() ? FT_LogicalNOT : FT_Undefined; + theCriterion.BinaryOp = theRow != aTable->numRows() - 1 ? + ((ComboItem*)aTable->item(theRow, 4))->GetValue() : FT_Undefined; + theCriterion.TypeOfElement = (ElementType)aType; + + int aCriterionType = GetCriterionType(theRow, aType); + + if (aCriterionType != FT_RangeOfIds && + aCriterionType != FT_BelongToGeom && + aCriterionType != FT_BelongToPlane && + aCriterionType != FT_BelongToCylinder && + aCriterionType != FT_LyingOnGeom) + { + theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->GetValue(); + theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble(); + } + else + theCriterion.ThresholdStr = aTable->text(theRow, 2).latin1(); + + QTableItem* anItem = aTable->item(theRow, 0); + if (myAddWidgets.contains(anItem)) + theCriterion.Tolerance = myAddWidgets[ anItem ]->GetDouble(AdditionalWidget::Tolerance); } //======================================================================= -// name : SMESHGUI_FilterDlg::getCriteria -// Purpose : Retrieve list of ids from given widget +// name : SMESHGUI_FilterTable::SetCriterion +// Purpose : Set parameters of criterion of specified row //======================================================================= -void SMESHGUI_FilterDlg::getIdsFromWg( const QWidget* theWg, QValueList& theRes ) const +void SMESHGUI_FilterTable::SetCriterion (const int theRow, + const SMESH::Filter::Criterion& theCriterion, + const int theEntityType) { - theRes.clear(); - if ( theWg == 0 ) + int aType = theEntityType == -1 ? GetType() : theEntityType; + + Table* aTable = myTables[ aType ]; + + if (theRow > aTable->numRows() - 1) return; - if ( theWg->inherits( "QListBox" ) ) + ((ComboItem*)aTable->item(theRow, 0))->SetValue(theCriterion.Type); + onCriterionChanged(theRow, 0, aType); + ((ComboItem*)aTable->item(theRow, 1))->SetValue(theCriterion.Compare); + ((QCheckTableItem*)aTable->item(theRow, 3))->setChecked(theCriterion.UnaryOp == FT_LogicalNOT); + + if (theCriterion.BinaryOp != FT_Undefined) { - QListBox* aListBox = ( QListBox* )theWg; - bool b; - for ( int i = 0, n = aListBox->count(); i < n; i++ ) - { - int anId = aListBox->text( i ).toInt( &b ); - if ( b ) - theRes.append( anId ); - } + if (!aTable->IsEditable(theRow, 4)) + aTable->setItem(theRow, 4, getBinaryItem(aTable)); + ((ComboItem*)aTable->item(theRow, 4))->SetValue(theCriterion.BinaryOp); } - else if ( theWg->inherits( "QLineEdit" ) ) + else + aTable->SetEditable(false, theRow, 4); + + if (theCriterion.Type != FT_RangeOfIds && + theCriterion.Type != FT_BelongToGeom && + theCriterion.Type != FT_BelongToPlane && + theCriterion.Type != FT_BelongToCylinder && + theCriterion.Type != FT_LyingOnGeom) + aTable->setText(theRow, 2, QString("%1").arg(theCriterion.Threshold, 0, 'g', 15)); + else + aTable->setText(theRow, 2, QString(theCriterion.ThresholdStr)); + + if (theCriterion.Compare == FT_EqualTo || + theCriterion.Type == FT_BelongToPlane || + theCriterion.Type == FT_BelongToCylinder) { - QLineEdit* aLineEdit = ( QLineEdit* )theWg; - QString aStr = aLineEdit->text(); - QRegExp aRegExp( "(\\d+)" ); - bool b; - int aPos = 0; - while ( aPos >= 0 ) + QTableItem* anItem = aTable->item(theRow, 0); + if (!myAddWidgets.contains(anItem)) { - aPos = aRegExp.search( aStr, aPos ); - if ( aPos > -1 ) - { - int anId = aRegExp.cap( 1 ).toInt( &b ); - if ( b ) - theRes.append( anId ); - aPos += aRegExp.matchedLength(); - } + myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack); + myWgStack->addWidget(myAddWidgets[ anItem ]); } + myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance); } + + emit CriterionChanged(theRow, aType); + } //======================================================================= -// name : SMESHGUI_FilterDlg::getSelMode -// Purpose : Get criteria for specified type +// name : SMESHGUI_FilterTable::Update +// Purpose : Update table //======================================================================= -Selection_Mode SMESHGUI_FilterDlg::getSelMode( const int theType ) const +void SMESHGUI_FilterTable::Update() { - switch ( theType ) - { - case SMESH::NODE : return NodeSelection; - case SMESH::EDGE : return EdgeSelection; - case SMESH::FACE : return FaceSelection; - case SMESH::VOLUME : return VolumeSelection; - default : return ActorSelection; + Table* aTable = myTables[ GetType() ]; + int aCurrRow = aTable->currentRow(); + int numRows = aTable->numRows(); + if ((aCurrRow < 0 || aCurrRow >= numRows) && numRows > 0) + aTable->setCurrentCell(0, 0); + updateAdditionalWidget(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::AddCriterion +// Purpose : Add criterion with parameters +//======================================================================= +void SMESHGUI_FilterTable::AddCriterion (const SMESH::Filter::Criterion& theCriterion, + const int theEntityType) +{ + int aType = theEntityType == -1 ? GetType() : theEntityType; + Table* aTable = myTables[ aType ]; + addRow(aTable, aType); + SetCriterion(aTable->numRows() - 1, theCriterion); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::NumRows +// Purpose : Get number of criterions of current type +//======================================================================= +int SMESHGUI_FilterTable::NumRows (const int theEntityType) const +{ + return myTables[ theEntityType == -1 ? GetType() : theEntityType ]->numRows(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::Clear +// Purpose : Clear current table +//======================================================================= +void SMESHGUI_FilterTable::Clear (const int theType) +{ + int aType = theType == -1 ? GetType() : theType; + QTable* aTable = myTables[ aType ]; + + if (aTable->numRows() == 0) + return; + + while (aTable->numRows() > 0) + { + removeAdditionalWidget(aTable, 0); + aTable->removeRow(0); } - + + updateBtnState(); } //======================================================================= -// name : SMESHGUI_FilterDlg::getCriteria -// Purpose : Get criteria for specified type +// name : SMESHGUI_FilterTable::onAddBtn +// Purpose : SLOT. Called then "Add" button pressed. +// Adds new string to table //======================================================================= -void SMESHGUI_FilterDlg::setIdsToWg( QWidget* theWg, const QValueList& theIds ) +void SMESHGUI_FilterTable::onAddBtn() { - if ( theWg == 0 ) + int aType = GetType(); + addRow(myTables[ aType ], aType); + + Update(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onInsertBtn +// Purpose : SLOT. Called then "Insert" button pressed. +// Inserts new string before current one +//======================================================================= +void SMESHGUI_FilterTable::onInsertBtn() +{ + addRow(myTables[ GetType() ], GetType(), false); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onRemoveBtn +// Purpose : SLOT. Called then "Remove" button pressed. +// Removes current string from table +//======================================================================= +void SMESHGUI_FilterTable::onRemoveBtn() +{ + Table* aTable = myTables[ GetType() ]; + + if (aTable->numRows() == 0) return; - - if ( theWg->inherits( "QListBox" ) ) + + QMemArray aRows; + for (int i = 0, n = aTable->numRows(); i < n; i++) { - QListBox* aListBox = ( QListBox* )theWg; - aListBox->clear(); - - QStringList aStrList; - QValueList::const_iterator anIter; - for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter ) - aStrList.append( QString( "%1" ).arg( *anIter ) ); + if (aTable->isRowSelected(i)) + { + aRows.resize(aRows.size() + 1); + aRows[ aRows.size() - 1 ] = i; + removeAdditionalWidget(aTable, i); + } + } + + aTable->removeRows(aRows); + + // remove control of binary logical operation from last row + if (aTable->numRows() > 0) + aTable->SetEditable(false, aTable->numRows() - 1, 4); + + updateBtnState(); +} - aListBox->insertStringList( aStrList ); +//======================================================================= +// name : SMESHGUI_FilterTable::updateAdditionalWidget +// Purpose : Enable/Disable widget with additonal parameters +//======================================================================= +void SMESHGUI_FilterTable::updateAdditionalWidget() +{ + Table* aTable = myTables[ GetType() ]; + int aRow = aTable->currentRow(); + if (aRow < 0 || aRow >= aTable->numRows()) + { + myWgStack->setEnabled(false); + return; } - else if ( theWg->inherits( "QLineEdit" ) ) + + ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0)); + bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->GetValue() == FT_EqualTo && + GetCriterionType(aRow) != FT_BelongToGeom && + GetCriterionType(aRow) != FT_LyingOnGeom && + GetCriterionType(aRow) != FT_RangeOfIds && + GetCriterionType(aRow) != FT_FreeEdges && + GetCriterionType(aRow) != FT_BadOrientedVolume; + if (!myAddWidgets.contains(anItem)) { - QLineEdit* aLineEdit = ( QLineEdit* )theWg; - QString aStr; - QValueList::const_iterator anIter; + myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack); + myWgStack->addWidget(myAddWidgets[ anItem ]); + } + + myWgStack->raiseWidget(myWgStack->id(myAddWidgets[ anItem ])); + myWgStack->setEnabled(toEnable); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::removeAdditionalWidget +// Purpose : Remove widgets containing additional parameters from widget +// stack and internal map +//======================================================================= +void SMESHGUI_FilterTable::removeAdditionalWidget (QTable* theTable, const int theRow) +{ + QTableItem* anItem = theTable->item(theRow, 0); + if (myAddWidgets.contains(anItem)) + { + myWgStack->removeWidget(myAddWidgets[ anItem ]); + myAddWidgets[ anItem ]->reparent(0, QPoint()); + delete myAddWidgets[ anItem ]; + myAddWidgets.remove(anItem); + } +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onClearBtn +// Purpose : SLOT. Called then "Clear" button pressed. +// Removes all strings from table +//======================================================================= +void SMESHGUI_FilterTable::onClearBtn() +{ + QTable* aTable = myTables[ GetType() ]; + + if (aTable->numRows() == 0) + return; + + while (aTable->numRows() > 0) + { + removeAdditionalWidget(aTable, 0); + aTable->removeRow(0); + } + + updateBtnState(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onCurrentChanged() +// Purpose : SLOT. Called when current cell changed +//======================================================================= +void SMESHGUI_FilterTable::onCurrentChanged (int theRow, int theCol) +{ + if( !myIsLocked ) + updateAdditionalWidget(); + emit CurrentChanged(theRow, theCol); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onCriterionChanged() +// Purpose : Provides reaction on change of criterion +//======================================================================= +void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, const int entityType) +{ + int aType = entityType == -1 ? GetType() : entityType; + Table* aTable = myTables[ aType ]; + ComboItem* aCompareItem = (ComboItem*)aTable->item(row, 1); + + int aCriterionType = GetCriterionType(row); - for ( anIter = theIds.begin(); anIter != theIds.end(); ++ anIter ) - aStr += QString( "%1 " ).arg( *anIter ); + if (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders || + aType == SMESH::FACE && aCriterionType == SMESH::FT_FreeEdges || + aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume) + { + if (aCompareItem->count() > 0) + aCompareItem->setStringList(QStringList()); + aTable->SetEditable(false, row, 2); + } + else if (aCriterionType == SMESH::FT_RangeOfIds || + aCriterionType == SMESH::FT_BelongToGeom || + aCriterionType == SMESH::FT_BelongToPlane || + aCriterionType == SMESH::FT_BelongToCylinder || + aCriterionType == SMESH::FT_LyingOnGeom) + { + QMap aMap; + aMap[ FT_EqualTo ] = tr("EQUAL_TO"); + aCompareItem->setStringList(aMap); + if (!aTable->IsEditable(row, 2)) + aTable->SetEditable(true, row, 2); + } + else + { + if (aCompareItem->count() != 3) + { + aCompareItem->setStringList(QStringList()); + aCompareItem->setStringList(getCompare()); + } + + QString aText = aTable->text(row, 2); + bool isOk = false; + aText.toDouble(&isOk); + aTable->setText(row, 2, isOk ? aText : QString("")); + if (!aTable->IsEditable(row, 2)) + aTable->SetEditable(true, row, 2); + } + + updateAdditionalWidget(); + + emit CriterionChanged(row, entityType); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onCriterionChanged() +// Purpose : SLOT. Called then contents of table changed +// Provides reaction on change of criterion +//======================================================================= +void SMESHGUI_FilterTable::onCriterionChanged (int row, int col) +{ + onCriterionChanged(row, col, -1); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::getFirstSelectedRow +// Purpose : Get first selected row +//======================================================================= +int SMESHGUI_FilterTable::getFirstSelectedRow() const +{ + QTable* aTable = myTables[ GetType() ]; + for (int i = 0, n = aTable->numRows(); i < n; i++) + if (aTable->isRowSelected(i)) + return i; + + int aRow = aTable->currentRow(); + return aRow >= 0 && aRow < aTable->numRows() ? aRow : -1; +} + +//======================================================================= +// name : SMESHGUI_FilterTable::addRow +// Purpose : Add row at the end of table +//======================================================================= +void SMESHGUI_FilterTable::addRow (Table* theTable, const int theType, const bool toTheEnd) +{ + int aCurrRow = 0; + int aSelectedRow = getFirstSelectedRow(); + int aCurrCol = theTable->currentColumn(); + + myIsLocked = true; + if (toTheEnd || aSelectedRow == -1) + { + theTable->insertRows(theTable->numRows()); + aCurrRow = theTable->numRows() - 1; + } + else + { + theTable->insertRows(aSelectedRow); + aCurrRow = aSelectedRow; + } + myIsLocked = false; + + // Criteria + theTable->setItem(aCurrRow, 0, getCriterionItem(theTable, theType)); + + // Compare + theTable->setItem(aCurrRow, 1, getCompareItem(theTable)); + + // Threshold + //theTable->setItem(aCurrRow, 2, new QTableItem(theTable)); + + //Logical operation NOT + theTable->setItem(aCurrRow, 3, getUnaryItem(theTable)); + + // Logical binary operation for previous value + int anAddBinOpStr = -1; + if (aCurrRow == theTable->numRows() - 1) + anAddBinOpStr = aCurrRow - 1; + else if (aCurrRow >= 0 ) + anAddBinOpStr = aCurrRow; + + if (theTable->item(aCurrRow, 4) == 0 || + theTable->item(aCurrRow, 4)->rtti() != 1) + { + + + if (anAddBinOpStr >= 0 && + (theTable->item(anAddBinOpStr, 4) == 0 || + theTable->item(anAddBinOpStr, 4)->rtti() != 1)) + theTable->setItem(anAddBinOpStr, 4, getBinaryItem(theTable)); + } + + theTable->SetEditable(false, theTable->numRows() - 1, 4); - if ( !aStr.isEmpty() ) - aStr.remove( aStr.length() - 1, 1 ); + if (aCurrRow >=0 && aCurrRow < theTable->numRows() && + aCurrCol >=0 && aCurrCol < theTable->numRows()) + theTable->setCurrentCell(aCurrRow, aCurrCol); - aLineEdit->setText( aStr ); + onCriterionChanged(aCurrRow, 0); + + updateBtnState(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::getCriterionItem +// Purpose : Get combo table item for criteria of specified type +//======================================================================= +QTableItem* SMESHGUI_FilterTable::getCriterionItem (QTable* theParent , const int theType) +{ + return new ComboItem(theParent, getCriteria(theType)); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::getCompareItem +// Purpose : Get combo table item for operation of comparision +//======================================================================= +QTableItem* SMESHGUI_FilterTable::getCompareItem (QTable* theParent) +{ + return new ComboItem(theParent, getCompare()); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::getBinaryItem +// Purpose : +//======================================================================= +QTableItem* SMESHGUI_FilterTable::getBinaryItem (QTable* theParent) +{ + static QMap aMap; + if (aMap.isEmpty()) + { + aMap[ SMESH::FT_LogicalAND ] = tr("AND"); + aMap[ SMESH::FT_LogicalOR ] = tr("OR"); + } + + return new ComboItem(theParent, aMap); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::getUnaryItem +// Purpose : Get check table item +//======================================================================= +QTableItem* SMESHGUI_FilterTable::getUnaryItem (QTable* theParent) +{ + return new QCheckTableItem(theParent, tr("NOT")); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::getSupportedTypes +// Purpose : Get all supported type +//======================================================================= +const QMap& SMESHGUI_FilterTable::getSupportedTypes() const +{ + static QMap aTypes; + if (aTypes.isEmpty()) + { + aTypes[ SMESH::NODE ] = tr("NODES"); + aTypes[ SMESH::EDGE ] = tr("EDGES"); + aTypes[ SMESH::FACE ] = tr("FACES"); + aTypes[ SMESH::VOLUME ] = tr("VOLUMES"); } + + return aTypes; } //======================================================================= -// name : SMESHGUI_FilterDlg::getCriteria +// name : SMESHGUI_FilterTable::getCriteria // Purpose : Get criteria for specified type //======================================================================= -const QStringList& SMESHGUI_FilterDlg::getCriteria( const int theType ) const +const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) const { - if ( theType == SMESH::EDGE ) + if (theType == SMESH::NODE) { - static QStringList aCriteria; - if ( aCriteria.isEmpty() ) + static QMap aCriteria; + if (aCriteria.isEmpty()) { - aCriteria.append( tr( "FREE_BORDERS" ) ); - aCriteria.append( tr( "MULTI_BORDERS" ) ); - aCriteria.append( tr( "LENGTH" ) ); + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); + aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); + aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); + aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); } return aCriteria; } - else if ( theType == SMESH::FACE ) + else if (theType == SMESH::EDGE) { - static QStringList aCriteria; - if ( aCriteria.isEmpty() ) + static QMap aCriteria; + if (aCriteria.isEmpty()) { - aCriteria.append( tr( "ASPECT_RATIO" ) ); - aCriteria.append( tr( "WARPING" ) ); - aCriteria.append( tr( "MINIMUM_ANGLE" ) ); - aCriteria.append( tr( "TAPER" ) ); - aCriteria.append( tr( "SKEW" ) ); - aCriteria.append( tr( "AREA" ) ); + aCriteria[ SMESH::FT_FreeBorders ] = tr("FREE_BORDERS"); + aCriteria[ SMESH::FT_MultiConnection ] = tr("MULTI_BORDERS"); + aCriteria[ SMESH::FT_Length ] = tr("LENGTH"); + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); + aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); + aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); + aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); + } + return aCriteria; + } + else if (theType == SMESH::FACE) + { + static QMap aCriteria; + if (aCriteria.isEmpty()) + { + aCriteria[ SMESH::FT_AspectRatio ] = tr("ASPECT_RATIO"); + aCriteria[ SMESH::FT_Warping ] = tr("WARPING"); + aCriteria[ SMESH::FT_MinimumAngle ] = tr("MINIMUM_ANGLE"); + aCriteria[ SMESH::FT_Taper ] = tr("TAPER"); + aCriteria[ SMESH::FT_Skew ] = tr("SKEW"); + aCriteria[ SMESH::FT_Area ] = tr("AREA"); + aCriteria[ SMESH::FT_FreeEdges ] = tr("FREE_EDGES"); + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); + aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); + aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); + aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); + aCriteria[ SMESH::FT_Length2D ] = tr("LENGTH2D"); + aCriteria[ SMESH::FT_MultiConnection2D] = tr("MULTI2D_BORDERS"); + } + return aCriteria; + } + else if (theType == SMESH::VOLUME) + { + static QMap aCriteria; + if (aCriteria.isEmpty()) + { + aCriteria[ SMESH::FT_AspectRatio3D] = tr("ASPECT_RATIO_3D"); + aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); + aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); + aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); + aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME"); + aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D"); } return aCriteria; } else { - static QStringList aCriteria; + static QMap aCriteria; return aCriteria; } } + //======================================================================= -// name : SMESHGUI_FilterDlg::getCompare +// name : SMESHGUI_FilterTable::getCompare // Purpose : Get operation of comparison //======================================================================= -const QStringList& SMESHGUI_FilterDlg::getCompare () const +const QMap& SMESHGUI_FilterTable::getCompare() const { - static QStringList aList; + static QMap aMap; + + if (aMap.isEmpty()) + { + aMap[ SMESH::FT_LessThan ] = tr("LESS_THAN"); + aMap[ SMESH::FT_MoreThan ] = tr("MORE_THAN"); + aMap[ SMESH::FT_EqualTo ] = tr("EQUAL_TO" ); + } + + return aMap; +} + +//======================================================================= +// name : SMESHGUI_FilterTable::createTable +// Purpose : Create table +//======================================================================= +SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget* theParent, + const int theType) +{ + // create table + Table* aTable= new Table(0, 5, theParent); + + QHeader* aHeaders = aTable->horizontalHeader(); + + QFontMetrics aMetrics(aHeaders->font()); + + // append spaces to the header of criteria in order to + // provide visibility of criterion inside comboboxes + static int aMaxLenCr = 0; + + if (aMaxLenCr == 0) + { + const QMap& aSupportedTypes = getSupportedTypes(); + QMap::const_iterator anIter; + for (anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter) + aMaxLenCr = Max(maxLength(getCriteria(anIter.key()), aMetrics), aMaxLenCr); + } + + static int aLenCr = abs( aMaxLenCr - + aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5; + + QString aCrStr; + aCrStr.fill(' ', aLenCr); + QString aCoStr; + aCoStr.fill(' ', 10); + + aHeaders->setLabel(0, tr("CRITERION") + aCrStr); + aHeaders->setLabel(1, tr("COMPARE") + aCoStr); + aHeaders->setLabel(2, tr("THRESHOLD_VALUE")); + aHeaders->setLabel(3, tr("UNARY")); + aHeaders->setLabel(4, tr("BINARY") + " "); + + // set geometry of the table + for (int i = 0; i <= 4; i++) + aTable->adjustColumn(i); + + aTable->updateGeometry(); + QSize aSize = aTable->sizeHint(); + int aWidth = aSize.width(); + aTable->setMinimumSize(QSize(aWidth, aWidth / 2)); + aTable->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding)); + + connect(aTable, SIGNAL(valueChanged(int, int)), + this, SLOT(onCriterionChanged(int, int))); + + connect(aTable, SIGNAL(currentChanged(int, int)), + this, SLOT(onCurrentChanged(int, int))); + + return aTable; +} + +//======================================================================= +// name : SMESHGUI_FilterTable::updateBtnState +// Purpose : Update button state +//======================================================================= +void SMESHGUI_FilterTable::updateBtnState() +{ + myRemoveBtn->setEnabled(myTables[ GetType() ]->numRows() > 0); + myClearBtn->setEnabled(myTables[ GetType() ]->numRows() > 0); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::SetEditable +// Purpose : Set read only flag for tables. Show/hide buttons for work with rows +//======================================================================= +void SMESHGUI_FilterTable::SetEditable (const bool isEditable) +{ + TableMap::iterator anIter; + for (anIter = myTables.begin(); anIter != myTables.end(); ++anIter) + { + anIter.data()->setReadOnly(!isEditable); + + if (isEditable) + { + myAddBtn->show(); + myInsertBtn->show(); + myRemoveBtn->show(); + myClearBtn->show(); + } + else + { + myAddBtn->hide(); + myInsertBtn->hide(); + myRemoveBtn->hide(); + myClearBtn->hide(); + } + } + + QMap::iterator anIter2; + for (anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2) + anIter2.data()->SetEditable(isEditable); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::SetEnabled +// Purpose : Enable/Disable table. Switching type of elements already enabled +//======================================================================= +void SMESHGUI_FilterTable::SetEnabled (const bool isEnabled) +{ + myAddBtn->setEnabled(isEnabled); + myInsertBtn->setEnabled(isEnabled); + myRemoveBtn->setEnabled(isEnabled); + myClearBtn->setEnabled(isEnabled); + + if (isEnabled) + updateBtnState(); + + QMap::iterator anIter2; + for (anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2) + anIter2.data()->setEnabled(isEnabled); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::IsEditable +// Purpose : Verify whether table is editable +//======================================================================= +bool SMESHGUI_FilterTable::IsEditable() const +{ + return !myTables[ GetType() ]->isReadOnly(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::SetLibsEnabled +// Purpose : Show/hide buttons for work with libraries +//======================================================================= +void SMESHGUI_FilterTable::SetLibsEnabled (const bool isEnabled) +{ + if (isEnabled) + { + myCopyFromBtn->show(); + myAddToBtn->show(); + } + else + { + myCopyFromBtn->hide(); + myAddToBtn->hide(); + } +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onCopyFromBtn +// Purpose : SLOT. Called the "Copy from ..." button clicked +// Display filter library dialog +//======================================================================= +void SMESHGUI_FilterTable::onCopyFromBtn() +{ + if (myLibDlg == 0) + myLibDlg = new SMESHGUI_FilterLibraryDlg( + mySMESHGUI, this, GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM); + else + myLibDlg->Init(GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM); + + if (myLibDlg->exec() == QDialog::Accepted) + { + Copy(myLibDlg->GetTable()); + Update(); + } +} + +//======================================================================= +// name : SMESHGUI_FilterTable::onAddToBtn +// Purpose : SLOT. Called the "Add to ..." button clicked +// Display filter library dialog +//======================================================================= +void SMESHGUI_FilterTable::onAddToBtn() +{ + if (!IsValid(true)) + return; + if (myLibDlg == 0) + myLibDlg = new SMESHGUI_FilterLibraryDlg( + mySMESHGUI, this, GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO); + else + myLibDlg->Init(GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO); + + myLibDlg->SetTable(this); + + myLibDlg->exec(); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::Copy +// Purpose : Initialise table with values of other table +//======================================================================= +void SMESHGUI_FilterTable::Copy (const SMESHGUI_FilterTable* theTable) +{ + Clear(); + + for (int i = 0, n = theTable->NumRows(); i < n; i++) + { + SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion(); + theTable->GetCriterion(i, aCriterion); + AddCriterion(aCriterion); + } +} + +//======================================================================= +// name : SMESHGUI_FilterTable::CurrentCell +// Purpose : Returns current cell +//======================================================================= +bool SMESHGUI_FilterTable::CurrentCell (int& theRow, int& theCol) const +{ + theRow = myTables[ GetType() ]->currentRow(); + theCol = myTables[ GetType() ]->currentColumn(); + return theRow >= 0 && theCol >= 0; +} + +//======================================================================= +// name : SMESHGUI_FilterTable::SetText +// Purpose : Set text and internal value in cell of threshold value +//======================================================================= +void SMESHGUI_FilterTable::SetThreshold (const int theRow, + const QString& theText, + const int theEntityType) +{ + Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ]; + aTable->setText(theRow, 2, theText); +} + +//======================================================================= +// name : SMESHGUI_FilterTable::SetText +// Purpose : Get text and internal value from cell of threshold value +//======================================================================= +bool SMESHGUI_FilterTable::GetThreshold (const int theRow, + QString& theText, + const int theEntityType) +{ + Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ]; + QTableItem* anItem = aTable->item(theRow, 2); + if (anItem != 0) + { + theText = anItem->text(); + return true; + } + else + return false; +} + +/* + Class : SMESHGUI_FilterDlg + Description : Dialog to specify filters for VTK viewer +*/ + + +//======================================================================= +// name : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg +// Purpose : Constructor +//======================================================================= +SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI* theModule, + const QValueList& theTypes, + const char* theName) +: QDialog( SMESH::GetDesktop( theModule ), theName, false, + WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) +{ + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + mySelector = aViewWindow->GetSelector(); + + construct(theTypes); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg +// Purpose : Constructor +//======================================================================= +SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI* theModule, + const int theType, + const char* theName) +: QDialog( SMESH::GetDesktop( theModule ), theName, false, + WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) +{ + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + mySelector = aViewWindow->GetSelector(); + QValueList aTypes; + aTypes.append(theType); + construct(aTypes); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::construct +// Purpose : Construct dialog (called by constructor) +//======================================================================= +void SMESHGUI_FilterDlg::construct (const QValueList& theTypes) +{ + myTypes = theTypes; + + setCaption(tr("CAPTION")); + + QVBoxLayout* aDlgLay = new QVBoxLayout (this, MARGIN, SPACING); + + myMainFrame = createMainFrame (this); + QFrame* aBtnFrame = createButtonFrame(this); + + aDlgLay->addWidget(myMainFrame); + aDlgLay->addWidget(aBtnFrame); + + aDlgLay->setStretchFactor(myMainFrame, 1); + + Init(myTypes); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createMainFrame +// Purpose : Create frame containing dialog's input fields +//======================================================================= +QFrame* SMESHGUI_FilterDlg::createMainFrame (QWidget* theParent) +{ + QGroupBox* aMainFrame = new QGroupBox(1, Qt::Horizontal, theParent); + aMainFrame->setFrameStyle(QFrame::NoFrame); + aMainFrame->setInsideMargin(0); + + // filter frame + + myTable = new SMESHGUI_FilterTable( mySMESHGUI, aMainFrame, myTypes ); + myTable->SetLibsEnabled(true); + + QFrame* aLine = new QFrame(myTable->GetTableGrp()); + aLine->setFrameStyle(QFrame::HLine | QFrame::Sunken); + + mySetInViewer = new QCheckBox(tr("SET_IN_VIEWER"), myTable->GetTableGrp()); + mySetInViewer->setChecked(true); + + // other controls + mySourceGrp = createSourceGroup(aMainFrame); + + connect(myTable, SIGNAL(CriterionChanged(const int, const int)), + SLOT(onCriterionChanged(const int, const int))); + + connect(myTable, SIGNAL(CurrentChanged(int, int)), + SLOT(onCurrentChanged(int, int))); + + return aMainFrame; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createSourceFrame +// Purpose : Create frame containing source radio button +//======================================================================= +QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent) +{ + QButtonGroup* aGrp = new QButtonGroup(1, Qt::Vertical, tr("SOURCE"), theParent); + + QRadioButton* aMeshBtn = new QRadioButton(tr("MESH"), aGrp); + QRadioButton* aSelBtn = new QRadioButton(tr("SELECTION"), aGrp); + QRadioButton* aGrpBtn = new QRadioButton(tr("CURRENT_GROUP"), aGrp); + + aGrp->insert(aMeshBtn, Mesh); + aGrp->insert(aSelBtn, Selection); + aGrp->insert(aGrpBtn, Dialog); + + aGrp->setButton(Selection); + + return aGrp; +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::updateMainButtons +// Purpose : Update visibility of main buttons (OK, Cancel, Close ...) +//======================================================================= +void SMESHGUI_FilterDlg::updateMainButtons() +{ + if (myTypes.count() == 1) + { + myButtons[ BTN_Cancel ]->show(); + myButtons[ BTN_Apply ]->hide(); + myButtons[ BTN_Close ]->hide(); + } + else + { + myButtons[ BTN_Cancel ]->hide(); + myButtons[ BTN_Apply ]->show(); + myButtons[ BTN_Close ]->show(); + } + +// updateGeometry(); +} + +//======================================================================= +// name : SMESHGUI_FilterDlg::createButtonFrame +// Purpose : Create frame containing buttons +//======================================================================= +QFrame* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent) +{ + QGroupBox* aGrp = new QGroupBox(1, Qt::Vertical, theParent); + + myButtons[ BTN_OK ] = new QPushButton(tr("SMESH_BUT_OK" ), aGrp); + myButtons[ BTN_Apply ] = new QPushButton(tr("SMESH_BUT_APPLY"), aGrp); + + QLabel* aLbl = new QLabel(aGrp); + aLbl->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + + myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp); + myButtons[ BTN_Close ] = new QPushButton(tr("SMESH_BUT_CLOSE"), aGrp); - if ( aList.isEmpty() ) - { - aList.append( tr( "LESS_THAN" ) ); - aList.append( tr( "MORE_THAN" ) ); - aList.append( tr( "EQUAL_TO" ) ); - } + connect(myButtons[ BTN_OK ], SIGNAL(clicked()), SLOT(onOk())); + connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose())); + connect(myButtons[ BTN_Close ], SIGNAL(clicked()), SLOT(onClose())); + connect(myButtons[ BTN_Apply ], SIGNAL(clicked()), SLOT(onApply())); - return aList; + updateMainButtons(); + + return aGrp; } //======================================================================= -// name : SMESHGUI_FilterDlg::getCriterionItem -// Purpose : Get combo table item for criteria of specified type +// name : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg +// Purpose : Destructor //======================================================================= -QTableItem* SMESHGUI_FilterDlg::getCriterionItem( QTable* theParent , const int theType ) +SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg() { - return new QComboTableItem( theParent, getCriteria( theType ) ); } //======================================================================= -// name : SMESHGUI_FilterDlg::getCompareItem -// Purpose : Get combo table item for operation of comparision +// name : SMESHGUI_FilterDlg::Init +// Purpose : Init dialog fields, connect signals and slots, show dialog //======================================================================= -QTableItem* SMESHGUI_FilterDlg::getCompareItem( QTable* theParent ) +void SMESHGUI_FilterDlg::Init (const int type) { - return new QComboTableItem( theParent, getCompare() ); + QValueList aTypes; + aTypes.append(type); + Init(aTypes); } //======================================================================= -// name : SMESHGUI_FilterDlg::getLogOpItem -// Purpose : +// name : SMESHGUI_FilterDlg::Init +// Purpose : Init dialog fields, connect signals and slots, show dialog //======================================================================= -QTableItem* SMESHGUI_FilterDlg::getLogOpItem( QTable* theParent ) +void SMESHGUI_FilterDlg::Init (const QValueList& theTypes) { - static QStringList aList; - if ( aList.isEmpty() ) + mySourceWg = 0; + myTypes = theTypes; + myMesh = SMESH::SMESH_Mesh::_nil(); + myIObjects.Clear(); + myIsSelectionChanged = false; + + myTable->Init(theTypes); + + // set caption + if (theTypes.count() == 1) + { + int aType = theTypes.first(); + if (aType == SMESH::NODE ) setCaption(tr("NODES_TLT")); + else if (aType == SMESH::EDGE ) setCaption(tr("EDGES_TLT")); + else if (aType == SMESH::FACE ) setCaption(tr("FACES_TLT")); + else if (aType == SMESH::VOLUME) setCaption(tr("VOLUMES_TLT")); + } + else + setCaption(tr("TLT")); + + qApp->processEvents(); + updateGeometry(); + adjustSize(); + setEnabled(true); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate())); + connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose())); + + int x, y; + mySMESHGUI->DefineDlgPosition(this, x, y); + this->move(x, y); + + updateMainButtons(); + updateSelection(); + + // Initialise filter table with values of previous filter + QValueList::const_iterator anIter; + for (anIter = theTypes.begin(); anIter != theTypes.end(); ++anIter) { - aList.append( tr( "AND" ) ); - aList.append( tr( "OR" ) ); + myTable->Clear(*anIter); + if (!myFilter[ *anIter ]->_is_nil()) + { + SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria; + if (myFilter[ *anIter ]->GetCriteria(aCriteria)) + { + for (int i = 0, n = aCriteria->length(); i < n; i++) + myTable->AddCriterion(aCriteria[ i ], *anIter); + } + } } - return new QComboTableItem( theParent, aList ); + if (myInsertState.contains(theTypes.first())) + mySetInViewer->setChecked(myInsertState[ theTypes.first() ]); + else + mySetInViewer->setChecked(true); + if (myApplyToState.contains(theTypes.first())) + mySourceGrp->setButton(myApplyToState[ theTypes.first() ]); + else + mySourceGrp->setButton(Selection); } //======================================================================= -// name : SMESHGUI_FilterDlg::getNotItem -// Purpose : Get check table item +// name : SMESHGUI_FilterDlg::onOk +// Purpose : SLOT called when "Ok" button pressed. +// Assign filters VTK viewer and close dialog //======================================================================= -QTableItem* SMESHGUI_FilterDlg::getNotItem( QTable* theParent ) +void SMESHGUI_FilterDlg::onOk() { - return new QCheckTableItem( theParent, tr( "NOT" ) ); + if (onApply()) + { + mySelectionMgr->clearFilters(); + disconnect(mySMESHGUI, 0, this, 0); + disconnect(mySelectionMgr, 0, this, 0); + mySMESHGUI->ResetState(); + accept(); + emit Accepted(); + } } //======================================================================= -// name : SMESHGUI_FilterDlg::getCurrType -// Purpose : Get current entity type +// name : SMESHGUI_FilterDlg::onClose +// Purpose : SLOT called when "Close" button pressed. Close dialog //======================================================================= -int SMESHGUI_FilterDlg::getCurrType() const +void SMESHGUI_FilterDlg::onClose() { - return myType; + // Restore previously selected object + if (mySelectionMgr) + { + SALOME_ListIO aList; + mySelectionMgr->clearFilters(); + mySelectionMgr->clearSelected(); + SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter (myIObjects); + for (; anIter.More(); anIter.Next()) + { + aList.Append(anIter.Key()); + + TColStd_MapOfInteger aResMap; + const TColStd_IndexedMapOfInteger& anIndMap = anIter.Value(); + for (int i = 1, n = anIndMap.Extent(); i <= n; i++) + aResMap.Add(anIndMap(i)); + + mySelector->AddOrRemoveIndex( anIter.Key(), aResMap, false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( anIter.Key(), true, true ); + } + mySelectionMgr->setSelectedObjects(aList, false); + } + + disconnect(mySMESHGUI, 0, this, 0); + disconnect(mySelectionMgr, 0, this, 0); + mySMESHGUI->ResetState(); + reject(); + return; } //======================================================================= -// name : SMESHGUI_FilterDlg::getCriterion -// Purpose : +// name : SMESHGUI_FilterDlg::onDeactivate +// Purpose : SLOT called when dialog must be deativated //======================================================================= -int SMESHGUI_FilterDlg::getCriterion( const int theType, const int theRow ) const +void SMESHGUI_FilterDlg::onDeactivate() { - QComboTableItem* anItem = ( QComboTableItem* )myTables[ getCurrType() ]->item( theRow, 0 ); - return anItem->currentItem(); + setEnabled(false); } //======================================================================= -// name : SMESHGUI_FilterDlg::addRow -// Purpose : +// name : SMESHGUI_FilterDlg::enterEvent +// Purpose : Event filter //======================================================================= -void SMESHGUI_FilterDlg::addRow( Table* theTable, const int theType ) +void SMESHGUI_FilterDlg::enterEvent (QEvent*) { - theTable->insertRows( theTable->numRows() ); - int aCurrRow = theTable->numRows() - 1; - - // Criteria - theTable->setItem( aCurrRow, 0, getCriterionItem( theTable, theType ) ); - - // Compare - theTable->setItem( aCurrRow, 1, getCompareItem( theTable ) ); - - //Logical operation NOT - theTable->setItem( aCurrRow, 3, getNotItem( theTable ) ); - - // Logical binary operation for previous value - if ( aCurrRow > 0 ) - theTable->setItem( aCurrRow - 1, 4, getLogOpItem( theTable ) ); - theTable->SetEditable( false, aCurrRow, 4 ); - - onCriterionChanged( aCurrRow, 0 ); +// mySMESHGUI->EmitSignalDeactivateDialog(); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + mySMESHGUI->ResetState(); + setEnabled(true); } //======================================================================= -// name : SMESHGUI_FilterDlg::onAddBtn -// Purpose : SLOT. Called then "Add" button pressed. -// Adds new string to table +// name : closeEvent() +// Purpose : //======================================================================= -void SMESHGUI_FilterDlg::onAddBtn() +void SMESHGUI_FilterDlg::closeEvent (QCloseEvent*) { - // QTable - int aType = getCurrType(); - Table* aTable = myTables[ aType ]; - - addRow( aTable, aType ); - - updateBtnState(); - + onClose(); } //======================================================================= -// name : SMESHGUI_FilterDlg::onCriterionChanged() -// Purpose : SLOT. Called then contents of table changed -// Provides reaction on change of criterion +// name : SMESHGUI_FilterDlg::getIdsFromWg +// Purpose : Retrieve list of ids from given widget //======================================================================= -void SMESHGUI_FilterDlg::onCriterionChanged( int row, int col ) +void SMESHGUI_FilterDlg::getIdsFromWg (const QWidget* theWg, QValueList& theRes) const { - int aType = getCurrType(); - if ( aType != SMESH::EDGE || col != 0 ) + theRes.clear(); + if (theWg == 0) return; - Table* aTable = myTables[ aType ]; - QComboTableItem* aCompareItem = (QComboTableItem*)aTable->item( row, 1 ); - - if ( getCriterion( aType, row ) != FreeBorders ) + if (theWg->inherits("QListBox")) { - if ( aCompareItem->count() == 0 ) - aCompareItem->setStringList( getCompare() ); - - QString aText = aTable->text( row, 2 ); - aTable->SetEditable( true, row, 2 ); - aTable->setText( row, 2, aText ); + QListBox* aListBox = (QListBox*)theWg; + bool b; + for (int i = 0, n = aListBox->count(); i < n; i++) + { + int anId = aListBox->text(i).toInt(&b); + if (b) + theRes.append(anId); + } } - else + else if (theWg->inherits("QLineEdit")) { - if ( aCompareItem->count() > 0 ) - aCompareItem->setStringList( QStringList() ); - aTable->SetEditable( false, row, 2 ); + QLineEdit* aLineEdit = (QLineEdit*)theWg; + QString aStr = aLineEdit->text(); + QRegExp aRegExp("(\\d+)"); + bool b; + int aPos = 0; + while (aPos >= 0) + { + aPos = aRegExp.search(aStr, aPos); + if (aPos > -1) + { + int anId = aRegExp.cap(1).toInt(&b); + if (b) + theRes.append(anId); + aPos += aRegExp.matchedLength(); + } + } } } //======================================================================= -// name : SMESHGUI_FilterDlg::onRemoveBtn -// Purpose : SLOT. Called then "Remove" button pressed. -// Removes current string from table +// name : SMESHGUI_FilterDlg::getSelMode +// Purpose : Get selection mode of specified type //======================================================================= -void SMESHGUI_FilterDlg::onRemoveBtn() +Selection_Mode SMESHGUI_FilterDlg::getSelMode (const int theType) const { - Table* aTable = myTables[ getCurrType() ]; - - if ( aTable->numRows() == 0 ) - return; - - QMemArray aRows; - for ( int i = 0, n = aTable->numRows(); i < n; i++ ) + switch (theType) { - if ( aTable->isRowSelected( i ) ) - { - aRows.resize( aRows.size() + 1 ); - aRows[ aRows.size() - 1 ] = i; - } + case SMESH::NODE : return NodeSelection; + case SMESH::EDGE : return EdgeSelection; + case SMESH::FACE : return FaceSelection; + case SMESH::VOLUME : return VolumeSelection; + default : return ActorSelection; } - aTable->removeRows( aRows ); - - // remove control of binary logical operation from last row - if ( aTable->numRows() > 0 ) - aTable->SetEditable( false, aTable->numRows() - 1, 4 ); - - updateBtnState(); } //======================================================================= -// name : SMESHGUI_FilterDlg::onClearBtn -// Purpose : SLOT. Called then "Clear" button pressed. -// Removes all strings from table +// name : SMESHGUI_FilterDlg::setIdsToWg +// Purpose : Insert identifiers in specified widgets //======================================================================= -void SMESHGUI_FilterDlg::onClearBtn() +void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QValueList& theIds) { - QTable* aTable = myTables[ getCurrType() ]; - - if ( aTable->numRows() == 0 ) + if (theWg == 0) return; - while ( aTable->numRows() > 0 ) - aTable->removeRow( 0 ); + if (theWg->inherits("QListBox")) + { + QListBox* aListBox = (QListBox*)theWg; + aListBox->clear(); - updateBtnState(); -} + QStringList aStrList; + QValueList::const_iterator anIter; + for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) + aStrList.append(QString("%1").arg(*anIter)); -//======================================================================= -// name : SMESHGUI_FilterDlg::updateBtnState -// Purpose : Update button state -//======================================================================= -void SMESHGUI_FilterDlg::updateBtnState() -{ - myRemoveBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 ); - myClearBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 ); + aListBox->insertStringList(aStrList); + } + else if (theWg->inherits("QLineEdit")) + { + QLineEdit* aLineEdit = (QLineEdit*)theWg; + QString aStr; + QValueList::const_iterator anIter; + + for (anIter = theIds.begin(); anIter != theIds.end(); ++ anIter) + aStr += QString("%1 ").arg(*anIter); + + if (!aStr.isEmpty()) + aStr.remove(aStr.length() - 1, 1); + + aLineEdit->setText(aStr); + } } //======================================================================= @@ -800,59 +2032,73 @@ void SMESHGUI_FilterDlg::updateBtnState() //======================================================================= bool SMESHGUI_FilterDlg::isValid() const { - Table* aTable = myTables[ getCurrType() ]; - for ( int i = 0, n = aTable->numRows(); i < n; i++ ) + if (!myTable->IsValid()) + return false; + + for (int i = 0, n = myTable->NumRows(); i < n; i++) { - bool isEditable = aTable->IsEditable( i ,2 ); - bool aRes = false; - int aThreshold = ( int )aTable->text( i, 2 ).toDouble( &aRes ); - if ( isEditable && !aRes ) - { - QMessageBox::information( mySMESHGUI->GetDesktop(), - tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ), - QMessageBox::Ok ); - return false; - } - else if ( getCurrType() == SMESH::EDGE && - getCriterion( SMESH::EDGE, i ) == MultiBorders && - aThreshold == 1 ) - { - QMessageBox::information( mySMESHGUI->GetDesktop(), - tr( "SMESH_INSUFFICIENT_DATA" ), tr( "MULTIEDGES_ERROR" ), - QMessageBox::Ok ); - return false; + int aType = myTable->GetCriterionType(i); + if (aType == FT_BelongToGeom || + aType == FT_BelongToPlane || + aType == FT_BelongToCylinder || + aType == FT_LyingOnGeom) { + QString aName; + myTable->GetThreshold(i, aName); + + std::vector<_PTR(SObject)> aList = + SMESH::GetActiveStudyDocument()->FindObjectByName(aName.latin1(), "GEOM"); + if (aList.size() == 0) { + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("BAD_SHAPE_NAME").arg(aName), QMessageBox::Ok); + return false; + } + + if (aType == FT_BelongToCylinder || aType == FT_BelongToPlane) { + CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]); + //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject()); + GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject); + if (!aGeomObj->_is_nil()) { + TopoDS_Shape aFace; + if (!GEOMBase::GetShape(aGeomObj, aFace) || + aFace.IsNull() || + aFace.ShapeType() != TopAbs_FACE) { + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SHAPE_IS_NOT_A_FACE").arg(aName), QMessageBox::Ok); + return false; + } + + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace)); + if (aSurf.IsNull()) { + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SHAPE_IS_NOT_A_FACE").arg(aName), QMessageBox::Ok); + return false; + } + + if (aType == FT_BelongToPlane && !aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) { + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SHAPE_IS_NOT_A_PLANE").arg(aName), QMessageBox::Ok); + return false; + } + + if (aType == FT_BelongToCylinder && !aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) { + QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName), QMessageBox::Ok); + return false; + } + } + } } } return true; } -//======================================================================= -// name : SMESHGUI_FilterDlg::GetResultIds -// Purpose : Get filtered ids -//======================================================================= -/*void SMESHGUI_FilterDlg::GetResultIds( SMESH::SMESH_Mesh_ptr theMesh, - QValueList& theIds ) const -{ - if ( !myPredicate->_is_nil() ) - theIds = myInputIds; - else - myPredicate->SetMesh( theMesh ); - - theIds.clear(); - QValueList::const_iterator anIter; - for ( anIter = myInputIds.begin(); anIter != myInputIds.end(); ++anIter ) - if ( myPredicate->IsSatisfy( *anIter ) ) - theIds.append( *anIter ); -} -*/ - //======================================================================= // name : SMESHGUI_FilterDlg::SetSourceWg // Purpose : Set widget of parent dialog containing idsto be filtered if // user select corresponding source radio button //======================================================================= -void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg ) +void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg) { mySourceWg = theWg; } @@ -861,7 +2107,7 @@ void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg ) // name : SMESHGUI_FilterDlg::SetGroupIds // Purpose : Set mesh //======================================================================= -void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh ) +void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_ptr theMesh) { myMesh = theMesh; } @@ -870,9 +2116,27 @@ void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh ) // name : SMESHGUI_FilterDlg::SetSelection // Purpose : Get filtered ids //======================================================================= -void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel ) +void SMESHGUI_FilterDlg::SetSelection() { - mySelection = theSel; + if (mySelectionMgr) + disconnect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionDone())); + + if (mySelectionMgr) { + myIObjects.Clear(); + const SALOME_ListIO& anObjs = mySelector->StoredIObjects(); + SALOME_ListIteratorOfListIO anIter (anObjs); + for (; anIter.More(); anIter.Next()) { + TColStd_IndexedMapOfInteger aMap; + mySelector->GetIndex(anIter.Value(), aMap); + myIObjects.Bind(anIter.Value(), aMap); + } + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone())); + + updateSelection(); + } + else + myIObjects.Clear(); } //======================================================================= @@ -882,30 +2146,31 @@ void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel ) //======================================================================= bool SMESHGUI_FilterDlg::onApply() { - if ( !isValid() ) + if (!isValid()) return false; - try - { - int aCurrType = getCurrType(); + try { + int aCurrType = myTable->GetType(); - SMESH::Predicate_ptr aPredicate = createPredicate( aCurrType ); + if (!createFilter(aCurrType)) + return false; - if ( mySetInViewer->isChecked() ) - insertFilterInViewer( aPredicate ); + insertFilterInViewer(); - if ( !aPredicate->_is_nil() ) - { + if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) { QValueList aResultIds; - filterSource( aCurrType, aPredicate, aResultIds ); - selectInViewer( aCurrType, aResultIds ); + filterSource(aCurrType, aResultIds); + selectInViewer(aCurrType, aResultIds); } + + myInsertState[ aCurrType ] = mySetInViewer->isChecked(); + myApplyToState[ aCurrType ] = mySourceGrp->id(mySourceGrp->selected()); } - catch( const SALOME::SALOME_Exception& S_ex ) + catch(const SALOME::SALOME_Exception& S_ex) { - QtCatchCorbaException( S_ex ); + SalomeApp_Tools::QtCatchCorbaException(S_ex); } - catch( ... ) + catch(...) { } @@ -913,202 +2178,57 @@ bool SMESHGUI_FilterDlg::onApply() } //======================================================================= -// name : SMESHGUI_FilterDlg::createPredicate +// name : SMESHGUI_FilterDlg::createFilter // Purpose : Create predicate for given type //======================================================================= -SMESH::Predicate_ptr SMESHGUI_FilterDlg::createPredicate( const int theType ) +bool SMESHGUI_FilterDlg::createFilter (const int theType) { - SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr(); - if ( aFilterMgr->_is_nil() ) - return SMESH::Predicate::_nil(); - - QTable* aTable = myTables[ theType ]; - if ( aTable == 0 ) - return SMESH::Predicate::_nil(); - - // CREATE two lists ( PREDICATES and LOG OP ) - - // Criterion - QValueList aPredicates; - QValueList aLogOps; - for ( int i = 0, n = aTable->numRows(); i < n; i++ ) - { - int aCriterion = getCriterion( theType, i ); - - SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil(); - SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil(); - - if ( theType == SMESH::EDGE ) - { - switch ( aCriterion ) - { - case FreeBorders: - aPredicate = aFilterMgr->CreateFreeBorders(); - break; - case MultiBorders: - aFunctor = aFilterMgr->CreateMultiConnection(); - break; - case Length: - aFunctor = aFilterMgr->CreateLength(); - break; - default: - continue; - } - } - else - { - switch ( aCriterion ) - { - case AspectRatio: - aFunctor = aFilterMgr->CreateAspectRatio(); - break; - case Warping: - aFunctor = aFilterMgr->CreateWarping(); - break; - case MinimumAngle: - aFunctor = aFilterMgr->CreateMinimumAngle(); - break; - case Taper: - aFunctor = aFilterMgr->CreateTaper(); - break; - case Skew: - aFunctor = aFilterMgr->CreateSkew(); - break; - case Area: - aFunctor = aFilterMgr->CreateArea(); - break; - default: - continue; - } - } - - // Comparator - if ( !aFunctor->_is_nil() && aPredicate->_is_nil() ) - { - QComboTableItem* aCombo = (QComboTableItem*)aTable->item( i, 1 ); - int aCompareOp = aCombo->currentItem(); - double aThreshold = aTable->text( i, 2 ).toDouble(); - - SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil(); - - if ( aCompareOp == LessThan ) - aComparator = aFilterMgr->CreateLessThan(); - else if ( aCompareOp == MoreThan ) - aComparator = aFilterMgr->CreateMoreThan(); - else if ( aCompareOp == EqualTo ) - aComparator = aFilterMgr->CreateEqualTo(); - else - continue; - - aComparator->SetNumFunctor( aFunctor ); - aComparator->SetMargin( aThreshold ); - - aPredicate = aComparator; - } - - // Logical not - QCheckTableItem* anItem = (QCheckTableItem*)aTable->item( i, 3 ); - if ( anItem->isChecked() ) - { - SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT(); - aNotPred->SetPredicate( aPredicate ); - aPredicate = aNotPred; - } - - // logical op - int aLogOp = ( i == n - 1 ) ? LO_Undefined - : ( (QComboTableItem*)aTable->item( i, 4 ) )->currentItem(); - aPredicates.append( aPredicate ); - aLogOps.append( aLogOp ); - - } // for - - // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP - - // combine all "AND" operations - - QValueList aResList; - - QValueList::iterator aPredIter; - QValueList::iterator aLogOpIter; - - SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil(); - int aPrevLogOp = LO_Undefined; - - for ( aPredIter = aPredicates.begin(), aLogOpIter = aLogOps.begin(); - aPredIter != aPredicates.end() && aLogOpIter != aLogOps.end(); - ++aPredIter, ++aLogOpIter ) - { - int aCurrLogOp = *aLogOpIter; + SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager(); + if (aFilterMgr->_is_nil()) + return false; - SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil(); + int n = myTable->NumRows(); - if ( aPrevLogOp == LO_And ) - { + SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria; + aCriteria->length(n); - SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND(); - aBinaryPred->SetPredicate1( aPrevPredicate ); - aBinaryPred->SetPredicate2( *aPredIter ); - aCurrPred = aBinaryPred; - } - else - aCurrPred = *aPredIter; + long aPrecision = -1; + SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI ); - if ( aCurrLogOp != LO_And ) - aResList.append( aCurrPred ); + if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) ) + aPrecision = mgr->integerValue( "SMESH", "controls_precision", aPrecision ); - aPrevPredicate = aCurrPred; - aPrevLogOp = aCurrLogOp; + for (CORBA::ULong i = 0; i < n; i++) { + SMESH::Filter::Criterion aCriterion = createCriterion(); + myTable->GetCriterion(i, aCriterion); + aCriterion.Precision = aPrecision; + aCriteria[ i ] = aCriterion; } - // combine all "OR" operations - - SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil(); - - if ( aResList.count() == 1 ) - aResPredicate = aResList.first(); - else if ( aResList.count() > 1 ) - { - QValueList::iterator anIter = aResList.begin(); - aResPredicate = *anIter; - anIter++; - for ( ; anIter != aResList.end(); ++anIter ) - { - SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR(); - aBinaryPred->SetPredicate1( aResPredicate ); - aBinaryPred->SetPredicate2( *anIter ); - aResPredicate = aBinaryPred; - } - } + myFilter[ theType ] = aFilterMgr->CreateFilter(); + myFilter[ theType ]->SetCriteria(aCriteria.inout()); - return aResPredicate; + return true; } //======================================================================= // name : SMESHGUI_FilterDlg::insertFilterInViewer // Purpose : Insert filter in viewer //======================================================================= -void SMESHGUI_FilterDlg::insertFilterInViewer( SMESH::Predicate_ptr thePred ) +void SMESHGUI_FilterDlg::insertFilterInViewer() { - VTKViewer_InteractorStyleSALOME* aStyle = ((VTKViewer_ViewFrame*)mySMESHGUI->GetActiveStudy()-> - getActiveStudyFrame()->getRightFrame()->getViewFrame())-> - getRWInteractor()->GetInteractorStyleSALOME(); - - if ( thePred->_is_nil() ) - { - if ( myType == SMESH::EDGE ) - aStyle->RemoveEdgeFilter(); - else if ( myType == SMESH::FACE ) - aStyle->RemoveFaceFilter(); - } - else - { - Handle(SMESHGUI_Filter) aFilter = new SMESHGUI_Filter(); - aFilter->SetPredicate( thePred ); - if ( myType == SMESH::EDGE ) - aStyle->SetEdgeFilter( aFilter ); - else if ( myType == SMESH::FACE ) - aStyle->SetFaceFilter( aFilter ); + if (SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle()) { + SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType(); + + if (myFilter[ myTable->GetType() ]->_is_nil() || + myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() || + !mySetInViewer->isChecked()) { + SMESH::RemoveFilter(getFilterId(anEntType), aStyle); + } else { + Handle(SMESHGUI_PredicateFilter) aFilter = new SMESHGUI_PredicateFilter(); + aFilter->SetPredicate(myFilter[ myTable->GetType() ]->GetPredicate()); + SMESH::SetFilter(aFilter, aStyle); + } } } @@ -1116,50 +2236,49 @@ void SMESHGUI_FilterDlg::insertFilterInViewer( SMESH::Predicate_ptr thePred ) // name : SMESHGUI_FilterDlg::filterSource // Purpose : Filter source ids //======================================================================= -void SMESHGUI_FilterDlg::filterSource( const int theType, - SMESH::Predicate_ptr thePred, - QValueList& theResIds ) +void SMESHGUI_FilterDlg::filterSource (const int theType, + QValueList& theResIds) { theResIds.clear(); - - int aSourceId = mySourceGrp->id( mySourceGrp->selected() ); + if (myFilter[ theType ]->_is_nil()) + return; - if ( aSourceId == Mesh ) + int aSourceId = mySourceGrp->id(mySourceGrp->selected()); + + if (aSourceId == Mesh) { - if ( myMesh->_is_nil() ) + if (myMesh->_is_nil()) return; - SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr(); - SMESH::Filter_var aFilter = aFilterMgr->CreateFilter(); - aFilter->SetPredicate( thePred ); - SMESH::long_array_var anIds = aFilter->GetElementsId( myMesh ); - for ( int i = 0, n = anIds->length(); i < n; i++ ) - theResIds.append( anIds[ i ] ); + SMESH::long_array_var anIds = myFilter[ theType ]->GetElementsId(myMesh); + for (int i = 0, n = anIds->length(); i < n; i++) + theResIds.append(anIds[ i ]); } - else if ( aSourceId == Selection ) + else if (aSourceId == Selection) { - filterSelectionSource( theType, thePred, theResIds ); + filterSelectionSource(theType, theResIds); } - else if ( aSourceId == Dialog ) + else if (aSourceId == Dialog) { // retrieve ids from dialog QValueList aDialogIds; - getIdsFromWg( mySourceWg, aDialogIds ); - - if ( myMesh->_is_nil() ) + getIdsFromWg(mySourceWg, aDialogIds); + + if (myMesh->_is_nil()) { theResIds = aDialogIds; return; } // filter ids - thePred->SetMesh( myMesh ); + SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate(); + aPred->SetMesh(myMesh); QValueList::const_iterator anIter; - for ( anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter ) - if ( thePred->IsSatisfy( *anIter ) ) - theResIds.append( *anIter ); + for (anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter) + if (aPred->IsSatisfy(*anIter)) + theResIds.append(*anIter); // set ids to the dialog - setIdsToWg( mySourceWg, theResIds ); + setIdsToWg(mySourceWg, theResIds); } } @@ -1167,136 +2286,236 @@ void SMESHGUI_FilterDlg::filterSource( const int theType, // name : SMESHGUI_FilterDlg::filterSelectionSource // Purpose : Filter source selection //======================================================================= -void SMESHGUI_FilterDlg::filterSelectionSource( const int theType, - SMESH::Predicate_ptr thePred, - QValueList& theResIds ) +void SMESHGUI_FilterDlg::filterSelectionSource (const int theType, + QValueList& theResIds) { theResIds.clear(); - if ( myMesh->_is_nil() || mySelection == 0 ) + if (myMesh->_is_nil() || mySelectionMgr == 0) return; // Create map of entities to be filtered TColStd_MapOfInteger aToBeFiltered; - Standard_Boolean aRes = false; - SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() ); - - for ( ; anIter.More(); anIter.Next() ) + SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter(myIObjects); + + for (; anIter.More(); anIter.Next()) { // process sub mesh - SMESH::SMESH_subMesh_ptr aSubMesh = mySMESHGUI->ConvertIOinSubMesh( anIter.Value(), aRes ); - if ( aRes && !aSubMesh->_is_nil() ) + SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(anIter.Key()); + if (!aSubMesh->_is_nil()) { - if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() ) + if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) { SMESH::long_array_var anIds = theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId(); - for ( int i = 0, n = anIds->length(); i < n; i++ ) - aToBeFiltered.Add( anIds[ i ] ); + for (int i = 0, n = anIds->length(); i < n; i++) + aToBeFiltered.Add(anIds[ i ]); } } // process group - SMESH::SMESH_Group_ptr aGroup = mySMESHGUI->ConvertIOinSMESHGroup( anIter.Value(), aRes ); - if ( aRes && !aGroup->_is_nil() ) + SMESH::SMESH_GroupBase_var aGroup = + SMESH::IObjectToInterface(anIter.Key()); + if (!aGroup->_is_nil()) { - if ( aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId() ) + if (aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId()) { SMESH::long_array_var anIds = aGroup->GetListOfID(); - for ( int i = 0, n = anIds->length(); i < n; i++ ) - aToBeFiltered.Add( anIds[ i ] ); + for (int i = 0, n = anIds->length(); i < n; i++) + aToBeFiltered.Add(anIds[ i ]); } } // process mesh - SMESH::SMESH_Mesh_ptr aMeshPtr = mySMESHGUI->ConvertIOinMesh( anIter.Value(), aRes ); - if ( aRes && !aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId() ) + SMESH::SMESH_Mesh_var aMeshPtr = SMESH::IObjectToInterface(anIter.Key()); + if (!aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId()) { - TColStd_MapOfInteger aVtkMap; - mySelection->GetIndex( anIter.Value(), aVtkMap ); + const TColStd_IndexedMapOfInteger& aSelMap = anIter.Value(); - if ( aVtkMap.Extent() > 0 ) + if (aSelMap.Extent() > 0) { - SMESH_Actor *anActor = mySMESHGUI->FindActorByEntry( - anIter.Value()->getEntry(), aRes, true ); - if ( aRes && anActor != 0 ) + if(SMESH::FindActorByEntry(anIter.Key()->getEntry())) { - TColStd_MapIteratorOfMapOfInteger aVtkMapIter( aVtkMap ); - for ( ; aVtkMapIter.More(); aVtkMapIter.Next() ) - aToBeFiltered.Add( theType == SMESH::NODE - ? anActor->GetNodeObjId( aVtkMapIter.Key() ) - : anActor->GetElemObjId( aVtkMapIter.Key() ) ); + for (int i = 1; i <= aSelMap.Extent(); i++) + aToBeFiltered.Add(aSelMap(i)); } } } } // Filter entities - thePred->SetMesh( myMesh ); - TColStd_MapIteratorOfMapOfInteger aResIter( aToBeFiltered ); - for ( ; aResIter.More(); aResIter.Next() ) - if ( thePred->IsSatisfy( aResIter.Key() ) ) - theResIds.append( aResIter.Key() ); + SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate(); + aPred->SetMesh(myMesh); + TColStd_MapIteratorOfMapOfInteger aResIter(aToBeFiltered); + for (; aResIter.More(); aResIter.Next()) + if (aPred->IsSatisfy(aResIter.Key())) + theResIds.append(aResIter.Key()); } //======================================================================= // name : SMESHGUI_FilterDlg::selectInViewer // Purpose : Select given entities in viewer //======================================================================= -void SMESHGUI_FilterDlg::selectInViewer( const int theType, const QValueList& theIds ) +void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QValueList& theIds) { - if ( mySelection == 0 || myMesh->_is_nil() ) + if (mySelectionMgr == 0 || myMesh->_is_nil()) return; + mySelectionMgr->clearFilters(); + // Set new selection mode if necessary - Selection_Mode aSelMode = getSelMode( theType ); - if ( aSelMode != mySelection->SelectionMode() ) - { - mySelection->ClearIObjects(); - mySelection->ClearFilters(); - if ( aSelMode == NodeSelection ) - mySMESHGUI->ViewNodes(); - QAD_Application::getDesktop()->SetSelectionMode( aSelMode ); + Selection_Mode aSelMode = getSelMode(theType); + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ); + if ( aViewWindow && aViewWindow->SelectionMode()!=aSelMode) { + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + if (aSelMode == NodeSelection) + SMESH::SetPointRepresentation(true); + aViewWindow->SetSelectionMode(aSelMode); } - Standard_Boolean aRes = false; - SMESH_Actor* anActor = mySMESHGUI->FindActor( myMesh, aRes, true ); - if ( !aRes || anActor == 0 || !anActor->hasIO() ) + // Clear selection + SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh); + if (!anActor || !anActor->hasIO()) return; Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); - mySelection->ClearIObjects(); - mySelection->AddIObject( anIO, false ); - + //mySelectionMgr->clearSelected(); + //mySelectionMgr->AddIObject(anIO, false); + SALOME_ListIO aList; + aList.Append(anIO); + mySelectionMgr->setSelectedObjects(aList, false); + + // Remove filter corresponding to the current type from viewer + int aType = myTable->GetType(); + int aFilterId = SMESHGUI_UnknownFilter; + if (aType == SMESH::EDGE ) aFilterId = SMESHGUI_EdgeFilter; + else if (aType == SMESH::FACE ) aFilterId = SMESHGUI_FaceFilter; + else if (aType == SMESH::VOLUME) aFilterId = SMESHGUI_VolumeFilter; + Handle(VTKViewer_Filter) aFilter = SMESH::GetFilter(aFilterId); + SMESH::RemoveFilter(aFilterId); + + // get vtk ids TColStd_MapOfInteger aMap; QValueList::const_iterator anIter; - for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter ) - { - std::vector aVtkList = anActor->GetElemVtkId( *anIter ); - std::vector::iterator it; - for ( it = aVtkList.begin(); it != aVtkList.end(); ++it ) - aMap.Add( *it ); + for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) { + aMap.Add(*anIter); } - mySelection->AddOrRemoveIndex( anIO, aMap, false, true ); - -} - + // Set new selection + mySelector->AddOrRemoveIndex(anIO, aMap, false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->highlight( anIO, true, true ); + // insert previously stored filter in viewer if necessary + if (!aFilter.IsNull()) + SMESH::SetFilter(aFilter); +} +//======================================================================= +// name : SMESHGUI_FilterDlg::createCriterion +// Purpose : Create criterion structure with default values +//======================================================================= +SMESH::Filter::Criterion SMESHGUI_FilterDlg::createCriterion() +{ + SMESH::Filter::Criterion aCriterion; + aCriterion.Type = FT_Undefined; + aCriterion.Compare = FT_Undefined; + aCriterion.Threshold = 0; + aCriterion.UnaryOp = FT_Undefined; + aCriterion.BinaryOp = FT_Undefined; + aCriterion.ThresholdStr = ""; + aCriterion.TypeOfElement = SMESH::ALL; + return aCriterion; +} +//======================================================================= +// name : SMESHGUI_FilterDlg::onSelectionDone +// Purpose : SLOT called when selection changed. +// If current cell corresponds to the threshold value of +// BelongToGeom criterion name of selected object is set in this cell +//======================================================================= +void SMESHGUI_FilterDlg::onSelectionDone() +{ + int aRow, aCol; + const SALOME_ListIO& aList = mySelector->StoredIObjects(); + + if (aList.Extent() != 1 || + !myTable->CurrentCell(aRow, aCol) || + myTable->GetCriterionType(aRow) != FT_BelongToGeom && + myTable->GetCriterionType(aRow) != FT_BelongToPlane && + myTable->GetCriterionType(aRow) != FT_BelongToCylinder && + myTable->GetCriterionType(aRow) != FT_LyingOnGeom) + return; + Handle(SALOME_InteractiveObject) anIO = aList.First(); + GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface(anIO); + if (!anObj->_is_nil()) + myTable->SetThreshold(aRow, GEOMBase::GetName(anObj)); +} +//======================================================================= +// name : SMESHGUI_FilterDlg::onCriterionChanged +// Purpose : SLOT called when cretarion of current row changed. Update selection +//======================================================================= +void SMESHGUI_FilterDlg::onCriterionChanged (const int , const int) +{ + updateSelection(); +} +//======================================================================= +// name : SMESHGUI_FilterDlg::onCurrentChanged +// Purpose : SLOT called when current row changed. Update selection +//======================================================================= +void SMESHGUI_FilterDlg::onCurrentChanged (int, int) +{ + updateSelection(); +} +//======================================================================= +// name : SMESHGUI_FilterDlg::updateSelection +// Purpose : UpdateSelection in accordance with current row +//======================================================================= +void SMESHGUI_FilterDlg::updateSelection() +{ + if (mySelectionMgr == 0) + return; + TColStd_MapOfInteger allTypes; + for( int i=0; i<10; i++ ) + allTypes.Add( i ); + SalomeApp_Study* aStudy = dynamic_cast( mySMESHGUI->application()->activeStudy() ); + if( !aStudy ) + return; + mySelectionMgr->clearFilters(); + int aRow, aCol; + if (myTable->CurrentCell(aRow, aCol) && + (myTable->GetCriterionType(aRow) == FT_BelongToGeom || + myTable->GetCriterionType(aRow) == FT_BelongToPlane || + myTable->GetCriterionType(aRow) == FT_BelongToCylinder || + myTable->GetCriterionType(aRow) == FT_LyingOnGeom)) { + if (myTable->GetCriterionType(aRow) == FT_BelongToGeom || + myTable->GetCriterionType(aRow) == FT_LyingOnGeom) { + mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true )); + } else if (myTable->GetCriterionType(aRow) == FT_BelongToPlane) { + mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Plane ) ); + } else if (myTable->GetCriterionType(aRow) == FT_BelongToCylinder) { + mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Cylinder ) ); + } + myIsSelectionChanged = true; + } else { + if (myIsSelectionChanged) { + mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection + } + } +}