1 // SMESH SMESHGUI : GUI for SMESH component
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESHGUI_FilterDlg.cxx
25 // Author : Sergey LITONIN
29 #include "SMESHGUI_FilterDlg.h"
30 #include "SMESHGUI_Filter.h"
31 #include "SMESH_Actor.h"
32 #include "VTKViewer_InteractorStyleSALOME.h"
33 #include "VTKViewer_ViewFrame.h"
34 #include "QAD_RightFrame.h"
35 #include "SALOME_ListIteratorOfListIO.hxx"
36 #include "SALOMEGUI_QtCatchCorbaException.hxx"
39 #include <TColStd_MapOfInteger.hxx>
43 #include <qlineedit.h>
44 #include <qpushbutton.h>
45 #include <qgroupbox.h>
47 #include <qstringlist.h>
49 #include <qwidgetstack.h>
50 #include <qapplication.h>
51 #include <qcombobox.h>
52 #include <qfontmetrics.h>
53 #include <qmessagebox.h>
55 #include <qbuttongroup.h>
56 #include <qradiobutton.h>
59 #include <qcheckbox.h>
64 static int maxLength( const QStringList& theList, const QFontMetrics& theMetrics )
67 QStringList::const_iterator anIter;
68 for ( anIter = theList.begin(); anIter != theList.end(); ++anIter )
69 aRes = Max( aRes, theMetrics.width( *anIter ) );
74 Class : SMESHGUI_FilterDlg::Table
75 Description : Table used by this dialog
78 class SMESHGUI_FilterDlg::Table : public QTable
81 Table( QWidget* parent = 0 );
82 Table( int numRows, int numCols, QWidget* parent = 0 );
85 void SetEditable( const bool state, const int row, const int col );
86 bool IsEditable( const int row, const int col ) const;
88 virtual bool eventFilter( QObject *o, QEvent *e );
89 virtual void insertRows( int row, int count = 1 );
90 virtual QString text( int row, int col ) const;
93 SMESHGUI_FilterDlg::Table::Table( QWidget* parent )
94 : QTable( parent, "SMESHGUI_FilterDlg::Table" )
98 SMESHGUI_FilterDlg::Table::Table( int numRows, int numCols, QWidget* parent )
99 : QTable( numRows, numCols, parent, "SMESHGUI_FilterDlg::Table" )
103 SMESHGUI_FilterDlg::Table::~Table()
107 void SMESHGUI_FilterDlg::Table::SetEditable( const bool isEditable, const int row, const int col )
109 QTableItem* anItem = item( row, col );
115 setItem( row, col, new QTableItem( this, QTableItem::Never, "" ) );
119 setItem( row, col, new QTableItem( this, QTableItem::OnTyping, "" ) );
123 bool SMESHGUI_FilterDlg::Table::IsEditable( const int row, const int col ) const
125 QTableItem* anItem = item( row, col );
126 return anItem == 0 || anItem->editType() != QTableItem::Never;
129 void SMESHGUI_FilterDlg::Table::insertRows( int row, int count )
131 int anEditRow = currEditRow();
132 int anEditCol = currEditCol();
134 // printf( "sln: anEditRow = %d, anEditCol = %d\n", anEditRow, anEditCol );
136 if ( anEditRow >= 0 && anEditCol >= 0 )
137 endEdit( anEditRow, anEditCol, true, false );
139 QTable::insertRows( row, count );
142 QString SMESHGUI_FilterDlg::Table::text( int row, int col ) const
144 int anEditRow = currEditRow();
145 int anEditCol = currEditCol();
147 if ( anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col )
148 ((Table*)this)->endEdit( row, col, true, false );
150 return QTable::text( row, col );
153 bool SMESHGUI_FilterDlg::Table::eventFilter( QObject *o, QEvent *e )
155 return QTable::eventFilter( o, e );
159 Class : SMESHGUI_FilterDlg
160 Description : Dialog to specify filters for VTK viewer
164 //=======================================================================
165 // name : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
166 // Purpose : Constructor
167 //=======================================================================
168 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget* theParent,
171 const char* theName )
172 : QDialog( theParent, theName, theModal,
173 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
177 setCaption( tr( "CAPTION" ) );
179 QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
181 myMainFrame = createMainFrame ( this );
182 QFrame* aBtnFrame = createButtonFrame( this, theModal );
184 aDlgLay->addWidget( myMainFrame );
185 aDlgLay->addWidget( aBtnFrame );
187 aDlgLay->setStretchFactor( myMainFrame, 1 );
193 //=======================================================================
194 // name : SMESHGUI_FilterDlg::createMainFrame
195 // Purpose : Create frame containing dialog's input fields
196 //=======================================================================
197 QFrame* SMESHGUI_FilterDlg::createMainFrame( QWidget* theParent )
199 QGroupBox* aMainFrame = new QGroupBox( 1, Qt::Horizontal, theParent );
200 aMainFrame->setFrameStyle( QFrame::NoFrame );
201 aMainFrame->setInsideMargin( 0 );
205 QGroupBox* aFilterGrp = new QGroupBox( 1, Qt::Horizontal, tr ( "Filter" ), aMainFrame );
206 QFrame* aFilterFrame = new QFrame( aFilterGrp );
208 myTableGrp = new QGroupBox( 1, Qt::Horizontal, aFilterFrame );
209 myTableGrp->setFrameStyle( QFrame::NoFrame );
210 myTableGrp->setInsideMargin( 0 );
212 myTables[ myType ] = createTable( myTableGrp, myType );
213 myAddBtn = new QPushButton( tr( "ADD" ), aFilterFrame );
214 myRemoveBtn = new QPushButton( tr( "REMOVE" ), aFilterFrame );
215 myClearBtn = new QPushButton( tr( "CLEAR" ), aFilterFrame );
217 QGridLayout* aLay = new QGridLayout( aFilterFrame, 4, 2, 0, SPACING );
219 aLay->addMultiCellWidget( myTableGrp, 0, 3, 0, 0 );
220 aLay->addWidget( myAddBtn, 0, 1 );
221 aLay->addWidget( myRemoveBtn, 1, 1 );
222 aLay->addWidget( myClearBtn, 2, 1 );
223 aLay->setColStretch( 0, 1 );
224 aLay->setColStretch( 1, 0 );
226 mySetInViewer = new QCheckBox( tr( "SET_IN_VIEWER" ), aFilterGrp );
227 mySetInViewer->setChecked( true );
229 QSpacerItem* aVSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
230 aLay->addItem( aVSpacer, 3, 1 );
233 mySourceGrp = createSourceGroup( aMainFrame );
236 connect( myAddBtn, SIGNAL( clicked() ), this, SLOT( onAddBtn() ) );
237 connect( myRemoveBtn, SIGNAL( clicked() ), this, SLOT( onRemoveBtn() ) );
238 connect( myClearBtn, SIGNAL( clicked() ), this, SLOT( onClearBtn() ) );
243 //=======================================================================
244 // name : SMESHGUI_FilterDlg::createSourceFrame
245 // Purpose : Create frame containing source radio button
246 //=======================================================================
247 QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup( QWidget* theParent )
249 QButtonGroup* aGrp = new QButtonGroup( 1, Qt::Vertical, tr( "SOURCE" ), theParent );
251 QRadioButton* aMeshBtn = new QRadioButton( tr( "MESH" ), aGrp );
252 QRadioButton* aSelBtn = new QRadioButton( tr( "SELECTION" ), aGrp );
253 QRadioButton* aGrpBtn = new QRadioButton( tr( "CURRENT_GROUP" ), aGrp );
254 // QRadioButton* aNoneBtn = new QRadioButton( tr( "NONE" ), aGrp );
256 aGrp->insert( aMeshBtn, Mesh );
257 aGrp->insert( aSelBtn, Selection );
258 aGrp->insert( aGrpBtn, Dialog );
259 // aGrp->insert( aNoneBtn, None );
261 aGrp->setButton( Selection );
266 //=======================================================================
267 // name : SMESHGUI_FilterDlg::createTable
268 // Purpose : Create table
269 //=======================================================================
270 SMESHGUI_FilterDlg::Table* SMESHGUI_FilterDlg::createTable( QWidget* theParent,
274 Table* aTable= new Table( 0, 5, theParent );
276 QHeader* aHeaders = aTable->horizontalHeader();
278 QFontMetrics aMetrics( aHeaders->font() );
280 int aLenCr = abs( maxLength( getCriteria( theType ), aMetrics ) -
281 aMetrics.width( tr( "CRITERION" ) ) ) / aMetrics.width( ' ' ) + 5;
283 int aLenCo = abs( maxLength( getCriteria( theType ), aMetrics ) -
284 aMetrics.width( tr( "COMPARE" ) ) ) / aMetrics.width( ' ' ) + 5;
287 aCrStr.fill( ' ', aLenCr );
289 aCoStr.fill( ' ', 10 );
291 aHeaders->setLabel( 0, tr( "CRITERION" ) + aCrStr );
292 aHeaders->setLabel( 1, tr( "COMPARE" ) + aCoStr );
293 aHeaders->setLabel( 2, tr( "THRESHOLD_VALUE" ) );
294 aHeaders->setLabel( 3, tr( "UNARY" ) );
295 aHeaders->setLabel( 4, tr( "BINARY" ) + " " );
297 // set geometry of the table
299 for ( int i = 0; i <= 4; i++ )
300 aTable->adjustColumn( i );
302 aTable->updateGeometry();
303 QSize aSize = aTable->sizeHint();
304 int aWidth = aSize.width();
305 aTable->setMinimumSize( QSize( aWidth, aWidth / 2 ) );
306 aTable->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
308 if ( theType == SMESH::EDGE )
309 connect( aTable, SIGNAL( valueChanged( int, int ) ),
310 this, SLOT( onCriterionChanged( int, int ) ) );
315 //=======================================================================
316 // name : SMESHGUI_FilterDlg::createButtonFrame
317 // Purpose : Create frame containing buttons
318 //=======================================================================
319 QFrame* SMESHGUI_FilterDlg::createButtonFrame( QWidget* theParent, const bool theModal )
321 QGroupBox* aGrp = new QGroupBox( 1, Qt::Vertical, theParent );
323 myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), aGrp );
324 myApplyBtn = new QPushButton( tr( "SMESH_BUT_APPLY" ), aGrp );
325 QLabel* aLbl = new QLabel( aGrp );
326 myCloseBtn = new QPushButton( tr( "SMESH_BUT_CANCEL" ), aGrp );
328 aLbl->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
330 connect( myOkBtn, SIGNAL( clicked() ), SLOT( onOk() ) );
331 connect( myCloseBtn, SIGNAL( clicked() ), SLOT( onClose() ) ) ;
332 connect( myApplyBtn, SIGNAL( clicked() ), SLOT( onApply() ) );
340 //=======================================================================
341 // name : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
342 // Purpose : Destructor
343 //=======================================================================
344 SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
348 //=======================================================================
349 // name : SMESHGUI_FilterDlg::Init
350 // Purpose : Init dialog fields, connect signals and slots, show dialog
351 //=======================================================================
352 void SMESHGUI_FilterDlg::Init( const int theType )
357 myMesh = SMESH::SMESH_Mesh::_nil();
359 // activate corresponding tab
360 if ( !myTables.contains( myType ) )
361 myTables[ myType ] = createTable( myTableGrp, myType );
363 TableMap::iterator anIter;
364 for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter )
365 if ( anIter.key() == theType )
366 anIter.data()->show();
368 anIter.data()->hide();
371 setCaption( myType == SMESH::EDGE ? tr( "EDGES_TLT" ) : tr( "FACES_TLT" ) );
373 qApp->processEvents();
378 mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
379 mySMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
381 connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
382 connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
385 mySMESHGUI->DefineDlgPosition( this, x, y );
393 //=======================================================================
394 // name : SMESHGUI_FilterDlg::onOk
395 // Purpose : SLOT called when "Ok" button pressed.
396 // Assign filters VTK viewer and close dialog
397 //=======================================================================
398 void SMESHGUI_FilterDlg::onOk()
402 disconnect( mySMESHGUI, 0, this, 0 );
403 mySMESHGUI->ResetState() ;
409 //=======================================================================
410 // name : SMESHGUI_FilterDlg::onClose
411 // Purpose : SLOT called when "Close" button pressed. Close dialog
412 //=======================================================================
413 void SMESHGUI_FilterDlg::onClose()
415 disconnect( mySMESHGUI, 0, this, 0 );
416 mySMESHGUI->ResetState() ;
421 //=======================================================================
422 // name : SMESHGUI_FilterDlg::onDeactivate
423 // Purpose : SLOT called when dialog must be deativated
424 //=======================================================================
425 void SMESHGUI_FilterDlg::onDeactivate()
430 //=======================================================================
431 // name : SMESHGUI_FilterDlg::enterEvent
432 // Purpose : Event filter
433 //=======================================================================
434 void SMESHGUI_FilterDlg::enterEvent( QEvent* )
436 // mySMESHGUI->EmitSignalDeactivateDialog();
441 //=================================================================================
442 // function : closeEvent()
444 //=================================================================================
445 void SMESHGUI_FilterDlg::closeEvent( QCloseEvent* e )
450 //=======================================================================
451 // name : SMESHGUI_FilterDlg::getCriteria
452 // Purpose : Retrieve list of ids from given widget
453 //=======================================================================
454 void SMESHGUI_FilterDlg::getIdsFromWg( const QWidget* theWg, QValueList<int>& theRes ) const
460 if ( theWg->inherits( "QListBox" ) )
462 QListBox* aListBox = ( QListBox* )theWg;
464 for ( int i = 0, n = aListBox->count(); i < n; i++ )
466 int anId = aListBox->text( i ).toInt( &b );
468 theRes.append( anId );
471 else if ( theWg->inherits( "QLineEdit" ) )
473 QLineEdit* aLineEdit = ( QLineEdit* )theWg;
474 QString aStr = aLineEdit->text();
475 QRegExp aRegExp( "(\\d+)" );
480 aPos = aRegExp.search( aStr, aPos );
483 int anId = aRegExp.cap( 1 ).toInt( &b );
485 theRes.append( anId );
486 aPos += aRegExp.matchedLength();
492 //=======================================================================
493 // name : SMESHGUI_FilterDlg::getSelMode
494 // Purpose : Get criteria for specified type
495 //=======================================================================
496 Selection_Mode SMESHGUI_FilterDlg::getSelMode( const int theType ) const
500 case SMESH::NODE : return NodeSelection;
501 case SMESH::EDGE : return EdgeSelection;
502 case SMESH::FACE : return FaceSelection;
503 case SMESH::VOLUME : return VolumeSelection;
504 default : return ActorSelection;
509 //=======================================================================
510 // name : SMESHGUI_FilterDlg::getCriteria
511 // Purpose : Get criteria for specified type
512 //=======================================================================
513 void SMESHGUI_FilterDlg::setIdsToWg( QWidget* theWg, const QValueList<int>& theIds )
518 if ( theWg->inherits( "QListBox" ) )
520 QListBox* aListBox = ( QListBox* )theWg;
523 QStringList aStrList;
524 QValueList<int>::const_iterator anIter;
525 for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
526 aStrList.append( QString( "%1" ).arg( *anIter ) );
528 aListBox->insertStringList( aStrList );
530 else if ( theWg->inherits( "QLineEdit" ) )
532 QLineEdit* aLineEdit = ( QLineEdit* )theWg;
534 QValueList<int>::const_iterator anIter;
536 for ( anIter = theIds.begin(); anIter != theIds.end(); ++ anIter )
537 aStr += QString( "%1 " ).arg( *anIter );
539 if ( !aStr.isEmpty() )
540 aStr.remove( aStr.length() - 1, 1 );
542 aLineEdit->setText( aStr );
546 //=======================================================================
547 // name : SMESHGUI_FilterDlg::getCriteria
548 // Purpose : Get criteria for specified type
549 //=======================================================================
550 const QStringList& SMESHGUI_FilterDlg::getCriteria( const int theType ) const
552 if ( theType == SMESH::EDGE )
554 static QStringList aCriteria;
555 if ( aCriteria.isEmpty() )
557 aCriteria.append( tr( "FREE_BORDERS" ) );
558 aCriteria.append( tr( "MULTI_BORDERS" ) );
559 aCriteria.append( tr( "LENGTH" ) );
563 else if ( theType == SMESH::FACE )
565 static QStringList aCriteria;
566 if ( aCriteria.isEmpty() )
568 aCriteria.append( tr( "ASPECT_RATIO" ) );
569 aCriteria.append( tr( "WARPING" ) );
570 aCriteria.append( tr( "MINIMUM_ANGLE" ) );
571 aCriteria.append( tr( "TAPER" ) );
572 aCriteria.append( tr( "SKEW" ) );
573 aCriteria.append( tr( "AREA" ) );
579 static QStringList aCriteria;
584 //=======================================================================
585 // name : SMESHGUI_FilterDlg::getCompare
586 // Purpose : Get operation of comparison
587 //=======================================================================
588 const QStringList& SMESHGUI_FilterDlg::getCompare () const
590 static QStringList aList;
592 if ( aList.isEmpty() )
594 aList.append( tr( "LESS_THAN" ) );
595 aList.append( tr( "MORE_THAN" ) );
596 aList.append( tr( "EQUAL_TO" ) );
602 //=======================================================================
603 // name : SMESHGUI_FilterDlg::getCriterionItem
604 // Purpose : Get combo table item for criteria of specified type
605 //=======================================================================
606 QTableItem* SMESHGUI_FilterDlg::getCriterionItem( QTable* theParent , const int theType )
608 return new QComboTableItem( theParent, getCriteria( theType ) );
611 //=======================================================================
612 // name : SMESHGUI_FilterDlg::getCompareItem
613 // Purpose : Get combo table item for operation of comparision
614 //=======================================================================
615 QTableItem* SMESHGUI_FilterDlg::getCompareItem( QTable* theParent )
617 return new QComboTableItem( theParent, getCompare() );
620 //=======================================================================
621 // name : SMESHGUI_FilterDlg::getLogOpItem
623 //=======================================================================
624 QTableItem* SMESHGUI_FilterDlg::getLogOpItem( QTable* theParent )
626 static QStringList aList;
627 if ( aList.isEmpty() )
629 aList.append( tr( "AND" ) );
630 aList.append( tr( "OR" ) );
633 return new QComboTableItem( theParent, aList );
636 //=======================================================================
637 // name : SMESHGUI_FilterDlg::getNotItem
638 // Purpose : Get check table item
639 //=======================================================================
640 QTableItem* SMESHGUI_FilterDlg::getNotItem( QTable* theParent )
642 return new QCheckTableItem( theParent, tr( "NOT" ) );
645 //=======================================================================
646 // name : SMESHGUI_FilterDlg::getCurrType
647 // Purpose : Get current entity type
648 //=======================================================================
649 int SMESHGUI_FilterDlg::getCurrType() const
654 //=======================================================================
655 // name : SMESHGUI_FilterDlg::getCriterion
657 //=======================================================================
658 int SMESHGUI_FilterDlg::getCriterion( const int theType, const int theRow ) const
660 QComboTableItem* anItem = ( QComboTableItem* )myTables[ getCurrType() ]->item( theRow, 0 );
661 return anItem->currentItem();
664 //=======================================================================
665 // name : SMESHGUI_FilterDlg::addRow
667 //=======================================================================
668 void SMESHGUI_FilterDlg::addRow( Table* theTable, const int theType )
670 theTable->insertRows( theTable->numRows() );
671 int aCurrRow = theTable->numRows() - 1;
674 theTable->setItem( aCurrRow, 0, getCriterionItem( theTable, theType ) );
677 theTable->setItem( aCurrRow, 1, getCompareItem( theTable ) );
679 //Logical operation NOT
680 theTable->setItem( aCurrRow, 3, getNotItem( theTable ) );
682 // Logical binary operation for previous value
684 theTable->setItem( aCurrRow - 1, 4, getLogOpItem( theTable ) );
685 theTable->SetEditable( false, aCurrRow, 4 );
687 onCriterionChanged( aCurrRow, 0 );
690 //=======================================================================
691 // name : SMESHGUI_FilterDlg::onAddBtn
692 // Purpose : SLOT. Called then "Add" button pressed.
693 // Adds new string to table
694 //=======================================================================
695 void SMESHGUI_FilterDlg::onAddBtn()
698 int aType = getCurrType();
699 Table* aTable = myTables[ aType ];
701 addRow( aTable, aType );
707 //=======================================================================
708 // name : SMESHGUI_FilterDlg::onCriterionChanged()
709 // Purpose : SLOT. Called then contents of table changed
710 // Provides reaction on change of criterion
711 //=======================================================================
712 void SMESHGUI_FilterDlg::onCriterionChanged( int row, int col )
714 int aType = getCurrType();
715 if ( aType != SMESH::EDGE || col != 0 )
718 Table* aTable = myTables[ aType ];
719 QComboTableItem* aCompareItem = (QComboTableItem*)aTable->item( row, 1 );
721 if ( getCriterion( aType, row ) != FreeBorders )
723 if ( aCompareItem->count() == 0 )
724 aCompareItem->setStringList( getCompare() );
726 QString aText = aTable->text( row, 2 );
727 aTable->SetEditable( true, row, 2 );
728 aTable->setText( row, 2, aText );
732 if ( aCompareItem->count() > 0 )
733 aCompareItem->setStringList( QStringList() );
734 aTable->SetEditable( false, row, 2 );
738 //=======================================================================
739 // name : SMESHGUI_FilterDlg::onRemoveBtn
740 // Purpose : SLOT. Called then "Remove" button pressed.
741 // Removes current string from table
742 //=======================================================================
743 void SMESHGUI_FilterDlg::onRemoveBtn()
745 Table* aTable = myTables[ getCurrType() ];
747 if ( aTable->numRows() == 0 )
750 QMemArray<int> aRows;
751 for ( int i = 0, n = aTable->numRows(); i < n; i++ )
753 if ( aTable->isRowSelected( i ) )
755 aRows.resize( aRows.size() + 1 );
756 aRows[ aRows.size() - 1 ] = i;
760 aTable->removeRows( aRows );
762 // remove control of binary logical operation from last row
763 if ( aTable->numRows() > 0 )
764 aTable->SetEditable( false, aTable->numRows() - 1, 4 );
769 //=======================================================================
770 // name : SMESHGUI_FilterDlg::onClearBtn
771 // Purpose : SLOT. Called then "Clear" button pressed.
772 // Removes all strings from table
773 //=======================================================================
774 void SMESHGUI_FilterDlg::onClearBtn()
776 QTable* aTable = myTables[ getCurrType() ];
778 if ( aTable->numRows() == 0 )
781 while ( aTable->numRows() > 0 )
782 aTable->removeRow( 0 );
787 //=======================================================================
788 // name : SMESHGUI_FilterDlg::updateBtnState
789 // Purpose : Update button state
790 //=======================================================================
791 void SMESHGUI_FilterDlg::updateBtnState()
793 myRemoveBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 );
794 myClearBtn->setEnabled( myTables[ getCurrType() ]->numRows() > 0 );
797 //=======================================================================
798 // name : SMESHGUI_FilterDlg::isValid
799 // Purpose : Verify validity of input data
800 //=======================================================================
801 bool SMESHGUI_FilterDlg::isValid() const
803 Table* aTable = myTables[ getCurrType() ];
804 for ( int i = 0, n = aTable->numRows(); i < n; i++ )
806 bool isEditable = aTable->IsEditable( i ,2 );
808 int aThreshold = ( int )aTable->text( i, 2 ).toDouble( &aRes );
809 if ( isEditable && !aRes )
811 QMessageBox::information( mySMESHGUI->GetDesktop(),
812 tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ),
816 else if ( getCurrType() == SMESH::EDGE &&
817 getCriterion( SMESH::EDGE, i ) == MultiBorders &&
820 QMessageBox::information( mySMESHGUI->GetDesktop(),
821 tr( "SMESH_INSUFFICIENT_DATA" ), tr( "MULTIEDGES_ERROR" ),
830 //=======================================================================
831 // name : SMESHGUI_FilterDlg::GetResultIds
832 // Purpose : Get filtered ids
833 //=======================================================================
834 /*void SMESHGUI_FilterDlg::GetResultIds( SMESH::SMESH_Mesh_ptr theMesh,
835 QValueList<int>& theIds ) const
837 if ( !myPredicate->_is_nil() )
840 myPredicate->SetMesh( theMesh );
843 QValueList<int>::const_iterator anIter;
844 for ( anIter = myInputIds.begin(); anIter != myInputIds.end(); ++anIter )
845 if ( myPredicate->IsSatisfy( *anIter ) )
846 theIds.append( *anIter );
850 //=======================================================================
851 // name : SMESHGUI_FilterDlg::SetSourceWg
852 // Purpose : Set widget of parent dialog containing idsto be filtered if
853 // user select corresponding source radio button
854 //=======================================================================
855 void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg )
860 //=======================================================================
861 // name : SMESHGUI_FilterDlg::SetGroupIds
862 // Purpose : Set mesh
863 //=======================================================================
864 void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh )
869 //=======================================================================
870 // name : SMESHGUI_FilterDlg::SetSelection
871 // Purpose : Get filtered ids
872 //=======================================================================
873 void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel )
875 mySelection = theSel;
878 //=======================================================================
879 // name : SMESHGUI_FilterDlg::onApply
880 // Purpose : SLOT called when "Apply" button pressed.
881 // Assign filters to VTK viewer
882 //=======================================================================
883 bool SMESHGUI_FilterDlg::onApply()
890 int aCurrType = getCurrType();
892 SMESH::Predicate_ptr aPredicate = createPredicate( aCurrType );
894 if ( mySetInViewer->isChecked() )
895 insertFilterInViewer( aPredicate );
897 if ( !aPredicate->_is_nil() )
899 QValueList<int> aResultIds;
900 filterSource( aCurrType, aPredicate, aResultIds );
901 selectInViewer( aCurrType, aResultIds );
904 catch( const SALOME::SALOME_Exception& S_ex )
906 QtCatchCorbaException( S_ex );
915 //=======================================================================
916 // name : SMESHGUI_FilterDlg::createPredicate
917 // Purpose : Create predicate for given type
918 //=======================================================================
919 SMESH::Predicate_ptr SMESHGUI_FilterDlg::createPredicate( const int theType )
921 SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr();
922 if ( aFilterMgr->_is_nil() )
923 return SMESH::Predicate::_nil();
925 QTable* aTable = myTables[ theType ];
927 return SMESH::Predicate::_nil();
929 // CREATE two lists ( PREDICATES and LOG OP )
932 QValueList<SMESH::Predicate_ptr> aPredicates;
933 QValueList<int> aLogOps;
934 for ( int i = 0, n = aTable->numRows(); i < n; i++ )
936 int aCriterion = getCriterion( theType, i );
938 SMESH::Predicate_ptr aPredicate = SMESH::Predicate::_nil();
939 SMESH::NumericalFunctor_ptr aFunctor = SMESH::NumericalFunctor::_nil();
941 if ( theType == SMESH::EDGE )
943 switch ( aCriterion )
946 aPredicate = aFilterMgr->CreateFreeBorders();
949 aFunctor = aFilterMgr->CreateMultiConnection();
952 aFunctor = aFilterMgr->CreateLength();
960 switch ( aCriterion )
963 aFunctor = aFilterMgr->CreateAspectRatio();
966 aFunctor = aFilterMgr->CreateWarping();
969 aFunctor = aFilterMgr->CreateMinimumAngle();
972 aFunctor = aFilterMgr->CreateTaper();
975 aFunctor = aFilterMgr->CreateSkew();
978 aFunctor = aFilterMgr->CreateArea();
986 if ( !aFunctor->_is_nil() && aPredicate->_is_nil() )
988 QComboTableItem* aCombo = (QComboTableItem*)aTable->item( i, 1 );
989 int aCompareOp = aCombo->currentItem();
990 double aThreshold = aTable->text( i, 2 ).toDouble();
992 SMESH::Comparator_ptr aComparator = SMESH::Comparator::_nil();
994 if ( aCompareOp == LessThan )
995 aComparator = aFilterMgr->CreateLessThan();
996 else if ( aCompareOp == MoreThan )
997 aComparator = aFilterMgr->CreateMoreThan();
998 else if ( aCompareOp == EqualTo )
999 aComparator = aFilterMgr->CreateEqualTo();
1003 aComparator->SetNumFunctor( aFunctor );
1004 aComparator->SetMargin( aThreshold );
1006 aPredicate = aComparator;
1010 QCheckTableItem* anItem = (QCheckTableItem*)aTable->item( i, 3 );
1011 if ( anItem->isChecked() )
1013 SMESH::LogicalNOT_ptr aNotPred = aFilterMgr->CreateLogicalNOT();
1014 aNotPred->SetPredicate( aPredicate );
1015 aPredicate = aNotPred;
1019 int aLogOp = ( i == n - 1 ) ? LO_Undefined
1020 : ( (QComboTableItem*)aTable->item( i, 4 ) )->currentItem();
1021 aPredicates.append( aPredicate );
1022 aLogOps.append( aLogOp );
1026 // CREATE ONE PREDICATE FROM PREVIOUSLY CREATED MAP
1028 // combine all "AND" operations
1030 QValueList<SMESH::Predicate_ptr> aResList;
1032 QValueList<SMESH::Predicate_ptr>::iterator aPredIter;
1033 QValueList<int>::iterator aLogOpIter;
1035 SMESH::Predicate_ptr aPrevPredicate = SMESH::Predicate::_nil();
1036 int aPrevLogOp = LO_Undefined;
1038 for ( aPredIter = aPredicates.begin(), aLogOpIter = aLogOps.begin();
1039 aPredIter != aPredicates.end() && aLogOpIter != aLogOps.end();
1040 ++aPredIter, ++aLogOpIter )
1042 int aCurrLogOp = *aLogOpIter;
1044 SMESH::Predicate_ptr aCurrPred = SMESH::Predicate::_nil();
1046 if ( aPrevLogOp == LO_And )
1049 SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalAND();
1050 aBinaryPred->SetPredicate1( aPrevPredicate );
1051 aBinaryPred->SetPredicate2( *aPredIter );
1052 aCurrPred = aBinaryPred;
1055 aCurrPred = *aPredIter;
1057 if ( aCurrLogOp != LO_And )
1058 aResList.append( aCurrPred );
1060 aPrevPredicate = aCurrPred;
1061 aPrevLogOp = aCurrLogOp;
1064 // combine all "OR" operations
1066 SMESH::Predicate_ptr aResPredicate = SMESH::Predicate::_nil();
1068 if ( aResList.count() == 1 )
1069 aResPredicate = aResList.first();
1070 else if ( aResList.count() > 1 )
1072 QValueList<SMESH::Predicate_ptr>::iterator anIter = aResList.begin();
1073 aResPredicate = *anIter;
1075 for ( ; anIter != aResList.end(); ++anIter )
1077 SMESH::LogicalBinary_ptr aBinaryPred = aFilterMgr->CreateLogicalOR();
1078 aBinaryPred->SetPredicate1( aResPredicate );
1079 aBinaryPred->SetPredicate2( *anIter );
1080 aResPredicate = aBinaryPred;
1084 return aResPredicate;
1087 //=======================================================================
1088 // name : SMESHGUI_FilterDlg::insertFilterInViewer
1089 // Purpose : Insert filter in viewer
1090 //=======================================================================
1091 void SMESHGUI_FilterDlg::insertFilterInViewer( SMESH::Predicate_ptr thePred )
1093 VTKViewer_InteractorStyleSALOME* aStyle = ((VTKViewer_ViewFrame*)mySMESHGUI->GetActiveStudy()->
1094 getActiveStudyFrame()->getRightFrame()->getViewFrame())->
1095 getRWInteractor()->GetInteractorStyleSALOME();
1097 if ( thePred->_is_nil() )
1099 if ( myType == SMESH::EDGE )
1100 aStyle->RemoveEdgeFilter();
1101 else if ( myType == SMESH::FACE )
1102 aStyle->RemoveFaceFilter();
1106 Handle(SMESHGUI_Filter) aFilter = new SMESHGUI_Filter();
1107 aFilter->SetPredicate( thePred );
1108 if ( myType == SMESH::EDGE )
1109 aStyle->SetEdgeFilter( aFilter );
1110 else if ( myType == SMESH::FACE )
1111 aStyle->SetFaceFilter( aFilter );
1115 //=======================================================================
1116 // name : SMESHGUI_FilterDlg::filterSource
1117 // Purpose : Filter source ids
1118 //=======================================================================
1119 void SMESHGUI_FilterDlg::filterSource( const int theType,
1120 SMESH::Predicate_ptr thePred,
1121 QValueList<int>& theResIds )
1125 int aSourceId = mySourceGrp->id( mySourceGrp->selected() );
1127 if ( aSourceId == Mesh )
1129 if ( myMesh->_is_nil() )
1131 SMESH::FilterManager_ptr aFilterMgr = mySMESHGUI->GetFilterMgr();
1132 SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
1133 aFilter->SetPredicate( thePred );
1134 SMESH::long_array_var anIds = aFilter->GetElementsId( myMesh );
1135 for ( int i = 0, n = anIds->length(); i < n; i++ )
1136 theResIds.append( anIds[ i ] );
1138 else if ( aSourceId == Selection )
1140 filterSelectionSource( theType, thePred, theResIds );
1142 else if ( aSourceId == Dialog )
1144 // retrieve ids from dialog
1145 QValueList<int> aDialogIds;
1146 getIdsFromWg( mySourceWg, aDialogIds );
1148 if ( myMesh->_is_nil() )
1150 theResIds = aDialogIds;
1155 thePred->SetMesh( myMesh );
1156 QValueList<int>::const_iterator anIter;
1157 for ( anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter )
1158 if ( thePred->IsSatisfy( *anIter ) )
1159 theResIds.append( *anIter );
1161 // set ids to the dialog
1162 setIdsToWg( mySourceWg, theResIds );
1166 //=======================================================================
1167 // name : SMESHGUI_FilterDlg::filterSelectionSource
1168 // Purpose : Filter source selection
1169 //=======================================================================
1170 void SMESHGUI_FilterDlg::filterSelectionSource( const int theType,
1171 SMESH::Predicate_ptr thePred,
1172 QValueList<int>& theResIds )
1175 if ( myMesh->_is_nil() || mySelection == 0 )
1178 // Create map of entities to be filtered
1179 TColStd_MapOfInteger aToBeFiltered;
1180 Standard_Boolean aRes = false;
1181 SALOME_ListIteratorOfListIO anIter( mySelection->StoredIObjects() );
1183 for ( ; anIter.More(); anIter.Next() )
1186 SMESH::SMESH_subMesh_ptr aSubMesh = mySMESHGUI->ConvertIOinSubMesh( anIter.Value(), aRes );
1187 if ( aRes && !aSubMesh->_is_nil() )
1189 if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() )
1191 SMESH::long_array_var anIds =
1192 theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId();
1193 for ( int i = 0, n = anIds->length(); i < n; i++ )
1194 aToBeFiltered.Add( anIds[ i ] );
1199 SMESH::SMESH_Group_ptr aGroup = mySMESHGUI->ConvertIOinSMESHGroup( anIter.Value(), aRes );
1200 if ( aRes && !aGroup->_is_nil() )
1202 if ( aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId() )
1204 SMESH::long_array_var anIds = aGroup->GetListOfID();
1205 for ( int i = 0, n = anIds->length(); i < n; i++ )
1206 aToBeFiltered.Add( anIds[ i ] );
1211 SMESH::SMESH_Mesh_ptr aMeshPtr = mySMESHGUI->ConvertIOinMesh( anIter.Value(), aRes );
1212 if ( aRes && !aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId() )
1214 TColStd_MapOfInteger aVtkMap;
1215 mySelection->GetIndex( anIter.Value(), aVtkMap );
1217 if ( aVtkMap.Extent() > 0 )
1219 SMESH_Actor *anActor = mySMESHGUI->FindActorByEntry(
1220 anIter.Value()->getEntry(), aRes, true );
1221 if ( aRes && anActor != 0 )
1223 TColStd_MapIteratorOfMapOfInteger aVtkMapIter( aVtkMap );
1224 for ( ; aVtkMapIter.More(); aVtkMapIter.Next() )
1225 aToBeFiltered.Add( theType == SMESH::NODE
1226 ? anActor->GetNodeObjId( aVtkMapIter.Key() )
1227 : anActor->GetElemObjId( aVtkMapIter.Key() ) );
1234 thePred->SetMesh( myMesh );
1235 TColStd_MapIteratorOfMapOfInteger aResIter( aToBeFiltered );
1236 for ( ; aResIter.More(); aResIter.Next() )
1237 if ( thePred->IsSatisfy( aResIter.Key() ) )
1238 theResIds.append( aResIter.Key() );
1241 //=======================================================================
1242 // name : SMESHGUI_FilterDlg::selectInViewer
1243 // Purpose : Select given entities in viewer
1244 //=======================================================================
1245 void SMESHGUI_FilterDlg::selectInViewer( const int theType, const QValueList<int>& theIds )
1247 if ( mySelection == 0 || myMesh->_is_nil() )
1250 // Set new selection mode if necessary
1251 Selection_Mode aSelMode = getSelMode( theType );
1252 if ( aSelMode != mySelection->SelectionMode() )
1254 mySelection->ClearIObjects();
1255 mySelection->ClearFilters();
1256 if ( aSelMode == NodeSelection )
1257 mySMESHGUI->ViewNodes();
1258 QAD_Application::getDesktop()->SetSelectionMode( aSelMode );
1261 Standard_Boolean aRes = false;
1262 SMESH_Actor* anActor = mySMESHGUI->FindActor( myMesh, aRes, true );
1263 if ( !aRes || anActor == 0 || !anActor->hasIO() )
1266 Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
1267 mySelection->ClearIObjects();
1268 mySelection->AddIObject( anIO, false );
1270 TColStd_MapOfInteger aMap;
1271 QValueList<int>::const_iterator anIter;
1272 for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
1274 std::vector<int> aVtkList = anActor->GetElemVtkId( *anIter );
1275 std::vector<int>::iterator it;
1276 for ( it = aVtkList.begin(); it != aVtkList.end(); ++it )
1280 mySelection->AddOrRemoveIndex( anIO, aMap, false, true );