Salome HOME
Fix for Bug PAL7766 ( An exception appears during construction of a group in the...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_FilterDlg.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESHGUI_FilterDlg.cxx
25 //  Author : Sergey LITONIN
26 //  Module : SMESH
27
28 #include "SMESHGUI_FilterDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_FilterUtils.h"
34
35 #include "SMESHGUI_Filter.h"
36 #include "SMESH_Actor.h"
37 #include "VTKViewer_ViewFrame.h"
38 #include "QAD_Desktop.h"
39 #include "QAD_MessageBox.h"
40 #include "QAD_RightFrame.h"
41 #include "QAD_Config.h"
42 #include "SALOME_ListIteratorOfListIO.hxx"
43 #include "SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger.hxx"
44 #include "SALOMEGUI_QtCatchCorbaException.hxx"
45 #include "SMESHGUI_FilterLibraryDlg.h"
46 #include "SALOME_TypeFilter.hxx"
47
48 #include "GEOMBase.h"
49 #include "GEOM_FaceFilter.hxx"
50
51 #include <TColStd_MapOfInteger.hxx>
52 #include <TColStd_IndexedMapOfInteger.hxx>
53 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
54 #include <Precision.hxx>
55 #include <BRep_Tool.hxx>
56 #include <TopoDS_Shape.hxx>
57 #include <TopoDS.hxx>
58 #include <TopoDS_Face.hxx>
59 #include <Geom_Plane.hxx>
60 #include <Geom_CylindricalSurface.hxx>
61
62 #include <qframe.h>
63 #include <qlayout.h>
64 #include <qlineedit.h>
65 #include <qpushbutton.h>
66 #include <qgroupbox.h>
67 #include <qtable.h>
68 #include <qstringlist.h>
69 #include <qlayout.h>
70 #include <qwidgetstack.h>
71 #include <qapplication.h>
72 #include <qcombobox.h>
73 #include <qfontmetrics.h>
74 #include <qmessagebox.h>
75 #include <qlabel.h>
76 #include <qbuttongroup.h>
77 #include <qradiobutton.h>
78 #include <qregexp.h>
79 #include <qlistbox.h>
80 #include <qcheckbox.h>
81 #include <qobjectlist.h>
82 #include <qvalidator.h>
83
84 // IDL Headers
85 #include "SALOMEconfig.h"
86 #include CORBA_SERVER_HEADER(SMESH_Group)
87
88 #define SPACING 5                  
89 #define MARGIN  10
90
91 using namespace SMESH;
92
93 static int maxLength( const QMap<int, QString> theMap, const QFontMetrics& theMetrics )
94 {
95   int aRes = 0;
96   QMap<int, QString>::const_iterator anIter;
97   for ( anIter = theMap.begin(); anIter != theMap.end(); ++anIter )
98     aRes = Max( aRes, theMetrics.width( anIter.data() ) );
99   return aRes; 
100 }
101
102 static int getFilterId( SMESH::ElementType theType )
103 {
104   switch ( theType )
105   {
106     case SMESH::NODE   : return SMESHGUI_NodeFilter;
107     case SMESH::EDGE   : return SMESHGUI_EdgeFilter;
108     case SMESH::FACE   : return SMESHGUI_FaceFilter;
109     case SMESH::VOLUME : return SMESHGUI_VolumeFilter;
110     case SMESH::ALL    : return SMESHGUI_AllElementsFilter;
111     default            : return SMESHGUI_UnknownFilter;
112   }
113 }
114
115 /*
116   Class       : SMESHGUI_FilterTable::AdditionalWidget
117   Description : Class for storing additional parameters of criterion
118 */
119
120 class SMESHGUI_FilterTable::AdditionalWidget : public QFrame
121 {
122 public:
123   enum { Tolerance };
124   
125 public:
126
127                           AdditionalWidget( QWidget* theParent );
128   virtual                 ~AdditionalWidget();
129
130   virtual void            GetParameters( QValueList<int>& ) const;
131   virtual bool            IsValid( const bool theMsg = true ) const;
132   virtual double          GetDouble( const int theId ) const;
133   virtual int             GetInteger( const int theId ) const;
134   virtual QString         GetString( const int theId ) const;
135   virtual void            SetDouble( const int theId, const double theVal );
136   virtual void            SetInteger( const int theId, const int theVal );
137   virtual void            SetString( const int theId, const QString& theVal );
138   void                    SetEditable( const int theId, const bool isEditable );
139   void                    SetEditable( const bool isEditable );
140
141 private:
142   QMap< int, QLineEdit* > myLineEdits;
143 };
144
145 SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget( QWidget* theParent )
146 : QFrame( theParent )
147 {
148   QLabel* aLabel = new QLabel( tr( "SMESH_TOLERANCE" ), this );
149   myLineEdits[ Tolerance ] = new QLineEdit( this );
150   QDoubleValidator* aValidator = new QDoubleValidator( myLineEdits[ Tolerance ] );
151   aValidator->setBottom( 0 );
152   myLineEdits[ Tolerance ]->setValidator( aValidator );
153
154   QHBoxLayout* aLay = new QHBoxLayout( this, 0, SPACING );
155   aLay->addWidget( aLabel );
156   aLay->addWidget( myLineEdits[ Tolerance ] );
157   
158   QSpacerItem* aSpacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
159   aLay->addItem( aSpacer );
160
161   QString aText = QString( "%1" ).arg( Precision::Confusion() );
162   myLineEdits[ Tolerance ]->setText( aText );
163 }
164 SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget()
165 {
166 }
167
168 void SMESHGUI_FilterTable::AdditionalWidget::GetParameters( QValueList<int>& theList ) const
169 {
170   theList.clear();
171   theList.append( Tolerance );
172 }
173
174 bool SMESHGUI_FilterTable::AdditionalWidget::IsValid( const bool theMsg ) const
175 {
176   if ( !isEnabled() )
177     return true;
178
179   QValueList<int> aParams;
180   GetParameters( aParams );
181   QValueList<int>::const_iterator anIter;
182   for ( anIter = aParams.begin(); anIter != aParams.end(); ++anIter )
183   {
184     const QLineEdit* aWg = myLineEdits[ *anIter ];
185     int p = 0;
186     QString aText = aWg->text();
187     if ( aWg->isEnabled() && aWg->validator()->validate( aText, p ) != QValidator::Acceptable )
188     {
189       if ( theMsg )
190           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
191             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SMESHGUI_INVALID_PARAMETERS" ), QMessageBox::Ok );
192         return false;
193     }
194   }
195
196   return true;
197 }
198
199 double SMESHGUI_FilterTable::AdditionalWidget::GetDouble( const int theId ) const
200 {
201   return myLineEdits.contains( theId ) ? myLineEdits[ theId ]->text().toDouble() : 0;
202 }
203
204 int SMESHGUI_FilterTable::AdditionalWidget::GetInteger( const int theId ) const
205 {
206   return myLineEdits.contains( theId ) ? myLineEdits[ theId ]->text().toInt() : 0;
207 }
208
209 QString SMESHGUI_FilterTable::AdditionalWidget::GetString( const int theId ) const
210 {
211   return myLineEdits.contains( theId ) ? myLineEdits[ theId ]->text() : QString("");
212 }
213
214 void SMESHGUI_FilterTable::AdditionalWidget::SetDouble( const int theId, const double theVal )
215 {
216   if ( myLineEdits.contains( theId ) )
217     myLineEdits[ theId ]->setText( QString( "%1" ).arg( theVal ) );
218 }
219
220 void SMESHGUI_FilterTable::AdditionalWidget::SetInteger( const int theId, const int theVal )
221 {
222   if ( myLineEdits.contains( theId ) )
223     myLineEdits[ theId ]->setText( QString( "%1" ).arg( theVal ) );
224 }
225
226 void SMESHGUI_FilterTable::AdditionalWidget::SetString( const int theId, const QString& theVal )
227 {
228   if ( myLineEdits.contains( theId ) )
229     myLineEdits[ theId ]->setText( theVal );
230 }
231
232 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable( const int theId, const bool isEditable )
233 {
234   if ( myLineEdits.contains( theId ) )
235     myLineEdits[ theId ]->setEdited( isEditable );
236 }
237
238 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable( const bool isEditable )
239 {
240   QValueList<int> aParams;
241   GetParameters( aParams );
242   QValueList<int>::const_iterator anIter;
243   for ( anIter = aParams.begin(); anIter != aParams.end(); ++anIter )
244     myLineEdits[ *anIter ]->setEdited( isEditable );
245 }
246
247 /*
248   Class       : SMESHGUI_FilterTable::ComboItem
249   Description : Combo table item. Identificator corresponding to string may be assigned
250 */
251
252 class SMESHGUI_FilterTable::ComboItem : public QComboTableItem
253
254 {
255 public:
256                           ComboItem( QTable*, const QMap<int, QString>& );
257   virtual                 ~ComboItem();
258
259   virtual void            setStringList ( const QStringList & l );
260   void                    setStringList( const QMap<int, QString>& theIds );
261
262   int                     GetValue() const;
263   void                    SetValue( const int );
264   
265 private:
266   
267   QMap<int, int>          myNumToId;
268   QMap<int, int>          myIdToNum;
269 };
270
271 SMESHGUI_FilterTable::ComboItem::ComboItem( QTable*                   theParent, 
272                                             const QMap<int, QString>& theIds )
273 : QComboTableItem( theParent, QStringList() )
274 {
275   setStringList( theIds );
276 }
277
278 void SMESHGUI_FilterTable::ComboItem::setStringList( const QStringList & l )
279 {
280   QComboTableItem::setStringList( l );
281 }
282
283 void SMESHGUI_FilterTable::ComboItem::setStringList( const QMap<int, QString>& theIds )
284 {
285   int i = 0;
286   QStringList aList;
287   QMap<int, QString>::const_iterator anIter;
288   for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
289   {
290     myNumToId[ i ] = anIter.key();
291     myIdToNum[ anIter.key() ] = i;
292     aList.append( anIter.data() );
293     i++;
294   }
295
296   setStringList( aList );
297 }
298
299 SMESHGUI_FilterTable::ComboItem::~ComboItem()
300 {
301 }
302   
303 int SMESHGUI_FilterTable::ComboItem::GetValue() const
304 {
305   return myNumToId[ currentItem() ];
306 }
307
308 void SMESHGUI_FilterTable::ComboItem::SetValue( const int theVal )
309 {
310   setCurrentItem( myIdToNum[ theVal ] );
311 }
312
313
314 /*
315   Class       : SMESHGUI_FilterTable::Table            
316   Description : Table used by this widget
317 */
318
319 class SMESHGUI_FilterTable::Table : public QTable
320 {
321 public:
322                           Table( QWidget* parent );
323                           Table( int numRows, int numCols, QWidget* parent = 0 );
324   virtual                 ~Table();
325
326   void                    SetEditable( const bool state, const int row, const int col );
327   bool                    IsEditable( const int row, const int col ) const;  
328
329   virtual void            insertRows( int row, int count = 1 );
330   virtual QString         text( int row, int col ) const;
331 };
332
333 //=======================================================================
334 // name    : SMESHGUI_FilterTable::Table::Table
335 // Purpose : Constructor
336 //=======================================================================
337 SMESHGUI_FilterTable::Table::Table( QWidget* parent )
338 : QTable( parent, "SMESHGUI_FilterTable::Table" )
339 {
340 }
341
342 SMESHGUI_FilterTable::Table::Table( int numRows, int numCols, QWidget* parent )
343 : QTable( numRows, numCols, parent, "SMESHGUI_FilterTable::Table" )
344 {
345 }
346
347 SMESHGUI_FilterTable::Table::~Table()
348 {
349 }
350
351 //=======================================================================
352 // name    : SMESHGUI_FilterTable::Table::SetEditable
353 // Purpose : Set editable of specified cell
354 //=======================================================================
355 void SMESHGUI_FilterTable::Table::SetEditable( const bool isEditable, const int row, const int col )
356 {
357   QTableItem* anItem = item( row, col );
358   if( anItem )
359     takeItem( anItem );
360
361   if ( !isEditable )
362     setItem( row, col, new QTableItem( this, QTableItem::Never, "" ) );
363   else
364     setItem( row, col, new QTableItem( this, QTableItem::OnTyping, "" ) );
365 }
366
367 //=======================================================================
368 // name    : SMESHGUI_FilterTable::Table::IsEditable
369 // Purpose : Verify wheter cell is editable
370 //=======================================================================
371 bool SMESHGUI_FilterTable::Table::IsEditable( const int row, const int col ) const
372 {
373   QTableItem* anItem = item( row, col );
374   return anItem == 0 || anItem->editType() != QTableItem::Never;
375 }
376
377 //=======================================================================
378 // name    : SMESHGUI_FilterTable::Table::insertRows
379 // Purpose : Insert rows ( virtual redefined )
380 //=======================================================================
381 void SMESHGUI_FilterTable::Table::insertRows( int row, int count )
382 {
383   int anEditRow = currEditRow();
384   int anEditCol = currEditCol();
385
386   if ( anEditRow >= 0 && anEditCol >= 0 )
387     endEdit( anEditRow, anEditCol, true, false );
388
389   QTable::insertRows( row, count );
390 }
391
392 //=======================================================================
393 // name    : SMESHGUI_FilterTable::Table::text
394 // Purpose : Get text from cell ( virtual redefined ) 
395 //=======================================================================
396 QString SMESHGUI_FilterTable::Table::text( int row, int col ) const
397 {
398   int anEditRow = currEditRow();
399   int anEditCol = currEditCol();
400
401   if ( anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col )
402     ((Table*)this)->endEdit( row, col, true, false );
403
404   return QTable::text( row, col );
405 }
406
407
408
409 /*
410   Class       : SMESHGUI_FilterTable
411   Description : Frame containig 
412                   - Button group for switching entity type
413                   - Table for displaying filter criterions
414                   - Buttons for editing table and filter libraries
415 */
416
417 //=======================================================================
418 // name    : SMESHGUI_FilterTable::SMESHGUI_FilterTable
419 // Purpose : Constructor
420 //=======================================================================
421 SMESHGUI_FilterTable::SMESHGUI_FilterTable( QWidget* parent, 
422                                             const int type )
423 : QFrame( parent )                                            
424 {
425   myEntityType = -1;
426   Init( type );
427 }                 
428
429 //=======================================================================
430 // name    : SMESHGUI_FilterTable::SMESHGUI_FilterTable
431 // Purpose : Constructor
432 //=======================================================================
433 SMESHGUI_FilterTable::SMESHGUI_FilterTable( QWidget* parent, 
434                                             const QValueList<int>& types )
435 : QFrame( parent )                                            
436 {
437   myEntityType = -1;
438   Init( types );
439 }                                            
440
441 SMESHGUI_FilterTable::~SMESHGUI_FilterTable()
442 {
443 }
444
445 //=======================================================================
446 // name    : SMESHGUI_FilterTable::Init
447 // Purpose : Create table corresponding to the specified type
448 //=======================================================================
449 void SMESHGUI_FilterTable::Init( const int type )
450 {
451   QValueList<int> aTypes;
452   aTypes.append( type );
453   Init( aTypes );
454 }
455
456 //=======================================================================
457 // name    : SMESHGUI_FilterTable::Init
458 // Purpose : Create table corresponding to the specified type
459 //=======================================================================
460 void SMESHGUI_FilterTable::Init( const QValueList<int>& theTypes )
461 {
462   if ( theTypes.isEmpty() )
463     return;
464   
465   // Create buttons if necessary
466   
467   if ( myTables.isEmpty() ) 
468   {
469     int aType = theTypes.first();
470
471     // create main layout
472     QVBoxLayout* aMainLay = new QVBoxLayout( this );
473     QGroupBox* aMainGrp = new QGroupBox( 1, Qt::Horizontal, this );
474     aMainGrp->setFrameStyle( QFrame::NoFrame );
475     aMainGrp->setInsideMargin( 0 );
476     aMainLay->addWidget( aMainGrp );
477     
478     // create switch of entity types
479     myEntityTypeGrp = new QButtonGroup( 1, Qt::Vertical, tr( "ENTITY_TYPE" ), aMainGrp );
480     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
481     QMap<int, QString>::const_iterator anIter;
482     for ( anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter )
483     {
484       QRadioButton* aBtn = new QRadioButton( anIter.data(), myEntityTypeGrp );
485       myEntityTypeGrp->insert( aBtn, anIter.key() );
486     }
487
488     myTableGrp = new QGroupBox( 1, Qt::Horizontal, tr( "FILTER" ), aMainGrp  );
489     QFrame* aTableFrame = new QFrame( myTableGrp );
490   
491     // create table
492     mySwitchTableGrp = new QGroupBox( 1, Qt::Horizontal, aTableFrame );
493     mySwitchTableGrp->setFrameStyle( QFrame::NoFrame );
494     mySwitchTableGrp->setInsideMargin( 0 );
495     
496     myTables[ aType ] = createTable( mySwitchTableGrp, aType );
497   
498     // create buttons
499     myAddBtn      = new QPushButton( tr( "ADD" ), aTableFrame );
500     myRemoveBtn   = new QPushButton( tr( "REMOVE" ), aTableFrame );
501     myClearBtn    = new QPushButton( tr( "CLEAR" ), aTableFrame );
502     myInsertBtn   = new QPushButton( tr( "INSERT" ), aTableFrame );
503     myCopyFromBtn = new QPushButton( tr( "COPY_FROM" ), aTableFrame );
504     myAddToBtn    = new QPushButton( tr( "ADD_TO" ), aTableFrame );
505
506     myAddBtn->setAutoDefault( false );
507     myRemoveBtn->setAutoDefault( false );
508     myClearBtn->setAutoDefault( false );
509     myInsertBtn->setAutoDefault( false );
510     myCopyFromBtn->setAutoDefault( false );
511     myAddToBtn->setAutoDefault( false );
512
513     myCopyFromBtn->hide();
514     myAddToBtn->hide();
515     
516     // layout widgets
517     QGridLayout* aLay = new QGridLayout( aTableFrame, 8, 2, 0, SPACING );
518
519     aLay->addMultiCellWidget( mySwitchTableGrp, 0, 6, 0, 0 );
520     aLay->addWidget( myAddBtn, 0, 1 );
521     aLay->addWidget( myInsertBtn, 1, 1 );
522     aLay->addWidget( myRemoveBtn, 2, 1 );
523     aLay->addWidget( myClearBtn, 3, 1 );
524     aLay->addWidget( myCopyFromBtn, 5, 1 );
525     aLay->addWidget( myAddToBtn, 6, 1 );
526     aLay->addMultiCellWidget( createAdditionalFrame( aTableFrame ), 7, 7, 0, 1  );
527     
528     aLay->setColStretch( 0, 1 );
529     aLay->setColStretch( 1, 0 );
530     
531     QSpacerItem* aVSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
532     aLay->addItem( aVSpacer, 4, 1 );
533     
534     // signals and slots
535     connect( myAddBtn,    SIGNAL( clicked() ), this, SLOT( onAddBtn() ) );
536     connect( myInsertBtn, SIGNAL( clicked() ), this, SLOT( onInsertBtn() ) );
537     connect( myRemoveBtn, SIGNAL( clicked() ), this, SLOT( onRemoveBtn() ) );
538     connect( myClearBtn,  SIGNAL( clicked() ), this, SLOT( onClearBtn() ) );
539   
540     connect( myCopyFromBtn, SIGNAL( clicked() ), this, SLOT( onCopyFromBtn() ) );
541     connect( myAddToBtn,    SIGNAL( clicked() ), this, SLOT( onAddToBtn() ) );
542     
543     connect( myEntityTypeGrp, SIGNAL( clicked( int ) ), this, SLOT( onEntityType( int ) ) );
544     
545     myLibDlg = 0;
546   }
547   
548   // Hide buttons of entity types if necessary
549   const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
550   QMap<int, QString>::const_iterator anIt;
551   for ( anIt = aSupportedTypes.begin(); anIt != aSupportedTypes.end(); ++anIt )
552   {
553     QButton* aBtn = myEntityTypeGrp->find( anIt.key() );
554     theTypes.contains( anIt.key() ) ? aBtn->show() : aBtn->hide();
555   }
556
557   // select first button if there is no selected buttons or it is hidden
558   QButton* aBtn = myEntityTypeGrp->selected();
559   if (  aBtn == 0 || theTypes.find( myEntityTypeGrp->id( aBtn ) ) == theTypes.end() )
560     myEntityTypeGrp->setButton( theTypes.first() );
561
562   if ( theTypes.count() == 1 )
563     myEntityTypeGrp->hide();
564   else
565     myEntityTypeGrp->show();
566
567   myTableGrp->updateGeometry();
568   int aType = myEntityTypeGrp->id( myEntityTypeGrp->selected() );
569   onEntityType( aType );
570 }
571
572 //=======================================================================
573 // name    : SMESHGUI_FilterTable::GetTableGrp
574 // Purpose : Get group box containing table. May be used for adding new widgets in it
575 ////=======================================================================
576 QWidget* SMESHGUI_FilterTable::createAdditionalFrame( QWidget* theParent )
577 {
578   QFrame* aFrame = new QFrame( theParent );
579   
580   QFrame* aLine1 = new QFrame( aFrame );
581   QFrame* aLine2 = new QFrame( aFrame );
582   aLine1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
583   aLine2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
584   aLine1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed) );
585   aLine2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed) );
586   
587   QLabel* aLabel = new QLabel( tr( "ADDITIONAL_PARAMETERS" ), aFrame );
588
589   myWgStack = new QWidgetStack( aFrame );
590
591   QGridLayout* aLay = new QGridLayout( aFrame, 2, 3, 0, SPACING );
592   aLay->addWidget( aLine1, 0, 0 );
593   aLay->addWidget( aLabel, 0, 1 );
594   aLay->addWidget( aLine2, 0, 2 );
595   aLay->addMultiCellWidget( myWgStack, 1, 1, 0, 2 );
596
597   return aFrame;
598 }
599
600 //=======================================================================
601 // name    : SMESHGUI_FilterTable::GetTableGrp
602 // Purpose : Get group box containing table. May be used for adding new widgets in it
603 ////=======================================================================
604 QGroupBox* SMESHGUI_FilterTable::GetTableGrp()
605 {
606   return myTableGrp;
607 }
608
609 //=======================================================================
610 // name    : SMESHGUI_FilterTable::onEntityType
611 // Purpose : SLOT. Called when entity type changed.
612 //           Display corresponding table 
613 //=======================================================================
614 void SMESHGUI_FilterTable::onEntityType( int theType )
615 {
616   if ( myEntityType == theType )
617     return;
618
619   myIsValid = true;
620   emit NeedValidation();
621   if ( !myIsValid )
622   {
623     myEntityTypeGrp->setButton( myEntityType );
624     return;
625   }
626
627   myEntityType = theType;
628   
629   if ( !myTables.contains( theType ) )
630     myTables[ theType ] = createTable( mySwitchTableGrp, theType );    
631   
632   TableMap::iterator anIter;
633   for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter )
634     myEntityType == anIter.key() ? anIter.data()->show() : anIter.data()->hide();
635
636   updateBtnState();
637   qApp->processEvents();
638   myTables[ myEntityType ]->updateGeometry();
639   adjustSize();
640
641   emit EntityTypeChanged( theType );
642
643 }
644
645 //=======================================================================
646 // name    : SMESHGUI_FilterTable::IsValid
647 // Purpose : Verify validity of entered data
648 //=======================================================================
649 bool SMESHGUI_FilterTable::IsValid( const bool theMess, const int theEntityType ) const
650 {
651   int aType = theEntityType == -1 ? GetType() : theEntityType;
652
653   Table* aTable = myTables[ aType ];
654   for ( int i = 0, n = aTable->numRows(); i < n; i++ )
655   {
656     int aCriterion = GetCriterionType( i, aType );
657
658     if ( aCriterion == FT_RangeOfIds ||
659          aCriterion == FT_BelongToGeom ||
660          aCriterion == FT_BelongToPlane ||
661          aCriterion == FT_BelongToCylinder ||
662          aCriterion == FT_LyingOnGeom)
663     {
664       if ( aTable->text( i, 2 ).isEmpty() )
665       {
666         if ( theMess )
667           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
668             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ), QMessageBox::Ok );
669         return false;
670       }
671     }
672     else
673     {
674       bool aRes = false;
675       aTable->blockSignals( true );
676       double  aThreshold = ( int )aTable->text( i, 2 ).toDouble( &aRes );
677       aTable->blockSignals( false );
678
679       if ( !aRes && aTable->IsEditable( i, 2 ) )
680       {
681         if ( theMess )
682           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
683             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ), QMessageBox::Ok );
684         return false;
685       }
686       else if ( aType == SMESH::EDGE &&
687                 GetCriterionType( i, aType ) == SMESH::FT_MultiConnection &&
688                 aThreshold == 1 )
689       {
690         if ( theMess )
691           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
692             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "MULTIEDGES_ERROR" ), QMessageBox::Ok );
693         return false;
694       }
695     }
696
697     QTableItem* anItem = aTable->item( i, 0 );
698     if ( myAddWidgets.contains( anItem ) && !myAddWidgets[ anItem ]->IsValid() )
699       return false;
700   }
701
702   return true;
703 }
704
705 //=======================================================================
706 // name    : SMESHGUI_FilterTable::SetValidity
707 // Purpose : Set validity of the table
708 //=======================================================================
709 void SMESHGUI_FilterTable::SetValidity( const bool isValid )
710 {
711   myIsValid = isValid;
712 }
713
714 //=======================================================================
715 // name    : SMESHGUI_FilterTable::GetType
716 // Purpose : Get current entity type
717 //=======================================================================
718 int SMESHGUI_FilterTable::GetType() const
719 {
720   return myEntityType;
721 }
722
723 //=======================================================================
724 // name    : SMESHGUI_FilterTable::SetType
725 // Purpose : Set current entity type
726 //=======================================================================
727 void SMESHGUI_FilterTable::SetType( const int type )
728 {
729   myEntityTypeGrp->setButton( type );
730   onEntityType( type );
731 }
732
733 //=======================================================================
734 // name    : SMESHGUI_FilterTable::RestorePreviousEntityType
735 // Purpose : Restore previous entity type
736 //=======================================================================
737 void SMESHGUI_FilterTable::RestorePreviousEntityType()
738 {
739   SetType( myEntityType );
740 }
741
742 //=======================================================================
743 // name    : SMESHGUI_FilterTable::GetCriterionType
744 // Purpose : Get type of criterion from specified row ( corresponding enums in h-file )
745 //=======================================================================
746 int SMESHGUI_FilterTable::GetCriterionType( const int theRow, const int theType ) const
747 {
748   int aType = theType == -1 ? GetType() : theType;
749   Table* aTable = myTables[ aType ];
750   ComboItem* anItem = (ComboItem*)aTable->item( theRow, 0 );
751   return anItem != 0 ? anItem->GetValue() : FT_Undefined;
752 }
753
754 //=======================================================================
755 // name    : SMESHGUI_FilterTable::GetCriterion
756 // Purpose : Get parameters of criterion from specified row
757 //=======================================================================
758 void SMESHGUI_FilterTable::GetCriterion( const int                 theRow,
759                                          SMESH::Filter::Criterion& theCriterion,
760                                          const int                 theEntityType ) const
761 {
762   int aType = theEntityType == -1 ? GetType() : theEntityType;
763   Table* aTable = myTables[ aType ];
764   
765   theCriterion.Type = ( (ComboItem*)aTable->item( theRow, 0 ) )->GetValue();
766   theCriterion.UnaryOp = ( (QCheckTableItem*)aTable->item( theRow, 3 ) )->isChecked() ? FT_LogicalNOT : FT_Undefined;
767   theCriterion.BinaryOp = theRow != aTable->numRows() - 1 ?
768     ( (ComboItem*)aTable->item( theRow, 4 ) )->GetValue() : FT_Undefined;
769   theCriterion.TypeOfElement = (ElementType)aType;
770
771   int aCriterionType = GetCriterionType( theRow, aType );
772
773   if ( aCriterionType != FT_RangeOfIds &&
774        aCriterionType != FT_BelongToGeom &&
775        aCriterionType != FT_BelongToPlane &&
776        aCriterionType != FT_BelongToCylinder &&
777        aCriterionType != FT_LyingOnGeom)
778   {
779     theCriterion.Compare = ( (ComboItem*)aTable->item( theRow, 1 ) )->GetValue();
780     theCriterion.Threshold = aTable->item( theRow, 2 )->text().toDouble();
781   }
782   else
783     theCriterion.ThresholdStr = aTable->text( theRow, 2 ).latin1();
784
785   QTableItem* anItem = aTable->item( theRow, 0 );
786   if ( myAddWidgets.contains( anItem ) )
787     theCriterion.Tolerance = myAddWidgets[ anItem ]->GetDouble( AdditionalWidget::Tolerance );
788 }
789
790 //=======================================================================
791 // name    : SMESHGUI_FilterTable::SetCriterion
792 // Purpose : Set parameters of criterion of specified row
793 //=======================================================================
794 void SMESHGUI_FilterTable::SetCriterion( const int                       theRow,
795                                          const SMESH::Filter::Criterion& theCriterion,
796                                          const int                       theEntityType )
797 {
798   int aType = theEntityType == -1 ? GetType() : theEntityType;
799
800   Table* aTable = myTables[ aType ];
801
802   if ( theRow > aTable->numRows() - 1 )
803     return;
804
805   ( (ComboItem*)aTable->item( theRow, 0 ) )->SetValue( theCriterion.Type );
806   onCriterionChanged( theRow, 0, aType );
807   ( (ComboItem*)aTable->item( theRow, 1 ) )->SetValue( theCriterion.Compare );
808   ( (QCheckTableItem*)aTable->item( theRow, 3 ) )->setChecked( theCriterion.UnaryOp == FT_LogicalNOT );
809
810   if ( theCriterion.BinaryOp != FT_Undefined )
811   {
812     if ( !aTable->IsEditable( theRow, 4 ) )
813       aTable->setItem( theRow, 4, getBinaryItem( aTable ) );
814     ( (ComboItem*)aTable->item( theRow, 4 ) )->SetValue( theCriterion.BinaryOp );
815   }
816   else
817     aTable->SetEditable( false, theRow, 4 );
818
819   if ( theCriterion.Type != FT_RangeOfIds &&
820        theCriterion.Type != FT_BelongToGeom &&
821        theCriterion.Type != FT_BelongToPlane &&
822        theCriterion.Type != FT_BelongToCylinder &&
823        theCriterion.Type != FT_LyingOnGeom)
824     aTable->setText( theRow, 2, QString( "%1" ).arg( theCriterion.Threshold, 0, 'g', 15 ) );
825   else
826     aTable->setText( theRow, 2, QString( theCriterion.ThresholdStr ) );
827
828   if ( theCriterion.Compare == FT_EqualTo ||
829        theCriterion.Type    == FT_BelongToPlane ||
830        theCriterion.Type    == FT_BelongToCylinder )
831   {
832     QTableItem* anItem = aTable->item( theRow, 0 );
833     if ( !myAddWidgets.contains( anItem ) )
834     {
835       myAddWidgets[ anItem ] = new AdditionalWidget( myWgStack );
836       myWgStack->addWidget( myAddWidgets[ anItem ] );
837     }
838     myAddWidgets[ anItem ]->SetDouble( AdditionalWidget::Tolerance, theCriterion.Tolerance );
839   }
840
841   emit CretarionChanged( theRow, aType );
842
843 }
844
845 //=======================================================================
846 // name    : SMESHGUI_FilterTable::Update
847 // Purpose : Update table
848 //=======================================================================
849 void SMESHGUI_FilterTable::Update()
850 {
851   Table* aTable = myTables[ GetType() ];
852   int aCurrRow = aTable->currentRow();
853   int numRows = aTable->numRows();
854   if ( ( aCurrRow < 0 || aCurrRow >= numRows ) && numRows > 0 )
855     aTable->setCurrentCell( 0, 0 );
856   updateAdditionalWidget();
857 }
858
859 //=======================================================================
860 // name    : SMESHGUI_FilterTable::AddCriterion
861 // Purpose : Add criterion with parameters
862 //=======================================================================
863 void SMESHGUI_FilterTable::AddCriterion( const SMESH::Filter::Criterion& theCriterion,
864                                          const int                       theEntityType )
865 {
866   int aType = theEntityType == -1 ? GetType() : theEntityType;
867   Table* aTable = myTables[ aType ];
868   addRow( aTable, aType );
869   SetCriterion( aTable->numRows() - 1, theCriterion );
870 }
871
872 //=======================================================================
873 // name    : SMESHGUI_FilterTable::NumRows
874 // Purpose : Get number of criterions of current type
875 //=======================================================================
876 int SMESHGUI_FilterTable::NumRows( const int theEntityType ) const
877 {
878   return myTables[ theEntityType == -1 ? GetType() : theEntityType ]->numRows();
879 }
880
881 //=======================================================================
882 // name    : SMESHGUI_FilterTable::Clear
883 // Purpose : Clear current table
884 //=======================================================================
885 void SMESHGUI_FilterTable::Clear( const int theType )
886 {
887   int aType = theType == -1 ? GetType() : theType;
888   QTable* aTable = myTables[ aType ];
889
890   if ( aTable->numRows() == 0 )
891     return;
892
893   while ( aTable->numRows() > 0 )
894   {
895     removeAdditionalWidget( aTable, 0 );
896     aTable->removeRow( 0 );
897   }
898
899   updateBtnState();
900 }
901
902 //=======================================================================
903 // name    : SMESHGUI_FilterTable::onAddBtn
904 // Purpose : SLOT. Called then "Add" button pressed.
905 //           Adds new string to table
906 //=======================================================================
907 void SMESHGUI_FilterTable::onAddBtn()
908 {
909   int aType = GetType();
910   addRow( myTables[ aType ], aType );
911
912   Update();
913 }
914
915 //=======================================================================
916 // name    : SMESHGUI_FilterTable::onInsertBtn
917 // Purpose : SLOT. Called then "Insert" button pressed.
918 //           Inserts new string before current one
919 //=======================================================================
920 void SMESHGUI_FilterTable::onInsertBtn()
921 {
922   addRow( myTables[ GetType() ], GetType(), false );
923 }
924
925 //=======================================================================
926 // name    : SMESHGUI_FilterTable::onRemoveBtn
927 // Purpose : SLOT. Called then "Remove" button pressed.
928 //           Removes current string from table
929 //=======================================================================
930 void SMESHGUI_FilterTable::onRemoveBtn()
931 {
932   Table* aTable = myTables[ GetType() ];
933
934   if ( aTable->numRows() == 0 )
935     return;
936
937   QMemArray<int> aRows;
938   for ( int i = 0, n = aTable->numRows(); i < n; i++ )
939   {
940     if ( aTable->isRowSelected( i ) )
941     {
942       aRows.resize( aRows.size() + 1 );
943       aRows[ aRows.size() - 1 ] = i;
944       removeAdditionalWidget( aTable, i );
945     }
946   }
947
948   aTable->removeRows( aRows );
949
950   // remove control of binary logical operation from last row
951   if ( aTable->numRows() > 0 )
952     aTable->SetEditable( false, aTable->numRows() - 1, 4 );
953
954   updateBtnState();
955 }
956
957 //=======================================================================
958 // name    : SMESHGUI_FilterTable::updateAdditionalWidget
959 // Purpose : Enable/Disable widget with additonal parameters
960 //=======================================================================
961 void SMESHGUI_FilterTable::updateAdditionalWidget()
962 {
963   Table* aTable = myTables[ GetType() ];
964   int aRow = aTable->currentRow();
965   if ( aRow < 0 || aRow >= aTable->numRows() )
966   {
967     myWgStack->setEnabled( false );
968     return;
969   }
970
971   ComboItem* anItem = ( (ComboItem*)aTable->item( aRow, 0 ) );
972   bool toEnable = ( (ComboItem*)aTable->item( aRow, 1 ) )->GetValue() == FT_EqualTo &&
973                   GetCriterionType( aRow ) != FT_BelongToGeom &&
974                   GetCriterionType( aRow ) != FT_LyingOnGeom &&
975                   GetCriterionType( aRow ) != FT_RangeOfIds &&
976                   GetCriterionType( aRow ) != FT_FreeEdges;
977   if ( !myAddWidgets.contains( anItem ) )
978   {
979     myAddWidgets[ anItem ] = new AdditionalWidget( myWgStack );
980     myWgStack->addWidget( myAddWidgets[ anItem ] );
981   }
982
983   myWgStack->raiseWidget( myWgStack->id( myAddWidgets[ anItem ] ) );
984   myWgStack->setEnabled( toEnable );
985 }
986
987 //=======================================================================
988 // name    : SMESHGUI_FilterTable::removeAdditionalWidget
989 // Purpose : Remove widgets containing additional parameters from widget
990 //           stack and internal map
991 //=======================================================================
992 void SMESHGUI_FilterTable::removeAdditionalWidget( QTable* theTable, const int theRow )
993 {
994   QTableItem* anItem = theTable->item( theRow, 0 );
995   if ( myAddWidgets.contains( anItem ) )
996   {
997     myWgStack->removeWidget( myAddWidgets[ anItem ] );
998     myAddWidgets[ anItem ]->reparent( 0, QPoint() );
999     delete myAddWidgets[ anItem ];
1000     myAddWidgets.remove( anItem );
1001   }
1002 }
1003
1004 //=======================================================================
1005 // name    : SMESHGUI_FilterTable::onClearBtn
1006 // Purpose : SLOT. Called then "Clear" button pressed.
1007 //           Removes all strings from table
1008 //=======================================================================
1009 void SMESHGUI_FilterTable::onClearBtn()
1010 {
1011   QTable* aTable = myTables[ GetType() ];
1012
1013   if ( aTable->numRows() == 0 )
1014     return;
1015
1016   while ( aTable->numRows() > 0 )
1017   {
1018     removeAdditionalWidget( aTable, 0 );
1019     aTable->removeRow( 0 );
1020   }
1021
1022   updateBtnState();
1023 }
1024
1025 //=======================================================================
1026 // name    : SMESHGUI_FilterTable::onCurrentChanged()
1027 // Purpose : SLOT. Called when current cell changed
1028 //=======================================================================
1029 void SMESHGUI_FilterTable::onCurrentChanged( int theRow, int theCol )
1030 {
1031   updateAdditionalWidget();
1032   emit CurrentChanged( theRow, theCol );
1033 }
1034
1035 //=======================================================================
1036 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1037 // Purpose : Provides reaction on change of criterion
1038 //=======================================================================
1039 void SMESHGUI_FilterTable::onCriterionChanged( const int row, const int col, const int entityType )
1040 {
1041   int aType = entityType == -1 ? GetType() : entityType;
1042   Table* aTable = myTables[ aType ];
1043   ComboItem* aCompareItem = (ComboItem*)aTable->item( row, 1 );
1044
1045   int aCriterionType = GetCriterionType( row );
1046
1047   if ( aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
1048        aType == SMESH::FACE && aCriterionType == SMESH::FT_FreeEdges )
1049   {
1050     if ( aCompareItem->count() > 0 )
1051       aCompareItem->setStringList( QStringList() );
1052     aTable->SetEditable( false, row, 2 );
1053   }
1054   else if ( aCriterionType == SMESH::FT_RangeOfIds ||
1055             aCriterionType == SMESH::FT_BelongToGeom ||
1056             aCriterionType == SMESH::FT_BelongToPlane ||
1057             aCriterionType == SMESH::FT_BelongToCylinder ||
1058             aCriterionType == SMESH::FT_LyingOnGeom)
1059   {
1060     QMap<int, QString> aMap;
1061     aMap[ FT_EqualTo ] = tr( "EQUAL_TO" );
1062     aCompareItem->setStringList( aMap );
1063     if ( !aTable->IsEditable( row, 2 ) )
1064       aTable->SetEditable( true, row, 2 );
1065   }
1066   else
1067   {
1068     if ( aCompareItem->count() != 3 )
1069     {
1070       aCompareItem->setStringList( QStringList() );
1071       aCompareItem->setStringList( getCompare() );
1072     }
1073
1074     QString aText = aTable->text( row, 2 );
1075     bool isOk = false;
1076     aText.toDouble( &isOk );
1077     aTable->setText( row, 2, isOk ? aText : QString("") );
1078     if ( !aTable->IsEditable( row, 2 ) )
1079       aTable->SetEditable( true, row, 2 );
1080   }
1081
1082   updateAdditionalWidget();
1083   
1084   emit CretarionChanged( row, entityType );
1085 }
1086
1087 //=======================================================================
1088 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1089 // Purpose : SLOT. Called then contents of table changed
1090 //           Provides reaction on change of criterion
1091 //=======================================================================
1092 void SMESHGUI_FilterTable::onCriterionChanged( int row, int col )
1093 {
1094   onCriterionChanged( row, col, -1 );
1095 }
1096
1097 //=======================================================================
1098 // name    : SMESHGUI_FilterTable::getFirstSelectedRow
1099 // Purpose : Get first selected row
1100 //=======================================================================
1101 int SMESHGUI_FilterTable::getFirstSelectedRow() const
1102 {
1103   QTable* aTable = myTables[ GetType() ];
1104   for ( int i = 0, n = aTable->numRows(); i < n; i++ )
1105     if ( aTable->isRowSelected( i ) )
1106       return i;
1107
1108   int aRow = aTable->currentRow();
1109   return aRow >= 0 && aRow < aTable->numRows() ? aRow : -1;
1110 }
1111
1112 //=======================================================================
1113 // name    : SMESHGUI_FilterTable::addRow
1114 // Purpose : Add row at the end of table
1115 //=======================================================================
1116 void SMESHGUI_FilterTable::addRow( Table* theTable, const int theType, const bool toTheEnd )
1117 {
1118   int aCurrRow = 0;
1119   int aSelectedRow = getFirstSelectedRow();
1120   int aCurrCol = theTable->currentColumn();
1121
1122   if ( toTheEnd || aSelectedRow == -1 )
1123   {
1124     theTable->insertRows( theTable->numRows() );
1125     aCurrRow = theTable->numRows() - 1;
1126   }
1127   else
1128   {
1129     theTable->insertRows( aSelectedRow );
1130     aCurrRow = aSelectedRow;
1131   }
1132
1133   // Criteria
1134   theTable->setItem( aCurrRow, 0, getCriterionItem( theTable, theType ) );
1135
1136   // Compare
1137   theTable->setItem( aCurrRow, 1, getCompareItem( theTable ) );
1138
1139   // Threshold
1140   //theTable->setItem( aCurrRow, 2, new QTableItem( theTable ) );  
1141
1142   //Logical operation NOT
1143   theTable->setItem( aCurrRow, 3, getUnaryItem( theTable ) );
1144   
1145   // Logical binary operation for previous value
1146   int anAddBinOpStr = -1;
1147   if ( aCurrRow == theTable->numRows() - 1 )
1148     anAddBinOpStr = aCurrRow - 1;
1149   else if ( aCurrRow >= 0  )
1150     anAddBinOpStr = aCurrRow;
1151   
1152   if ( theTable->item( aCurrRow, 4 ) == 0 ||
1153        theTable->item( aCurrRow, 4 )->rtti() != 1 )
1154   {
1155     
1156
1157     if ( anAddBinOpStr >= 0 &&
1158          ( theTable->item( anAddBinOpStr, 4 ) == 0 ||
1159            theTable->item( anAddBinOpStr, 4 )->rtti() != 1 ) )
1160       theTable->setItem( anAddBinOpStr, 4, getBinaryItem( theTable ) );
1161   }
1162   
1163   theTable->SetEditable( false, theTable->numRows() - 1, 4 );
1164
1165   if ( aCurrRow >=0 && aCurrRow < theTable->numRows() &&
1166        aCurrCol >=0 && aCurrCol < theTable->numRows() )
1167   theTable->setCurrentCell( aCurrRow, aCurrCol );
1168
1169   onCriterionChanged( aCurrRow, 0 );
1170
1171   updateBtnState();
1172 }
1173
1174 //=======================================================================
1175 // name    : SMESHGUI_FilterTable::getCriterionItem
1176 // Purpose : Get combo table item for criteria of specified type
1177 //=======================================================================
1178 QTableItem* SMESHGUI_FilterTable::getCriterionItem( QTable* theParent , const int theType )
1179 {
1180   return new ComboItem( theParent, getCriteria( theType ) );
1181 }
1182
1183 //=======================================================================
1184 // name    : SMESHGUI_FilterTable::getCompareItem
1185 // Purpose : Get combo table item for operation of comparision
1186 //=======================================================================
1187 QTableItem* SMESHGUI_FilterTable::getCompareItem( QTable* theParent )
1188 {
1189   return new ComboItem( theParent, getCompare() );
1190 }
1191
1192 //=======================================================================
1193 // name    : SMESHGUI_FilterTable::getBinaryItem
1194 // Purpose :
1195 //=======================================================================
1196 QTableItem* SMESHGUI_FilterTable::getBinaryItem( QTable* theParent )
1197 {
1198   static QMap<int, QString> aMap;
1199   if ( aMap.isEmpty() )
1200   {
1201     aMap[ SMESH::FT_LogicalAND ] = tr( "AND" );
1202     aMap[ SMESH::FT_LogicalOR  ] = tr( "OR" );
1203   }
1204
1205   return new ComboItem( theParent, aMap );
1206 }
1207
1208 //=======================================================================
1209 // name    : SMESHGUI_FilterTable::getUnaryItem
1210 // Purpose : Get check table item
1211 //=======================================================================
1212 QTableItem* SMESHGUI_FilterTable::getUnaryItem( QTable* theParent )
1213 {
1214   return new QCheckTableItem( theParent, tr( "NOT" ) );
1215 }
1216
1217 //=======================================================================
1218 // name    : SMESHGUI_FilterTable::getSupportedTypes
1219 // Purpose : Get all supported type
1220 //=======================================================================
1221 const QMap<int, QString>& SMESHGUI_FilterTable::getSupportedTypes() const
1222 {
1223   static QMap<int, QString> aTypes;
1224   if ( aTypes.isEmpty() )
1225   {
1226     aTypes[ SMESH::NODE   ] = tr( "NODES" );
1227     aTypes[ SMESH::EDGE   ] = tr( "EDGES" );
1228     aTypes[ SMESH::FACE   ] = tr( "FACES" );
1229     aTypes[ SMESH::VOLUME ] = tr( "VOLUMES" );
1230   }
1231
1232   return aTypes;
1233 }
1234
1235 //=======================================================================
1236 // name    : SMESHGUI_FilterTable::getCriteria
1237 // Purpose : Get criteria for specified type
1238 //=======================================================================
1239 const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria( const int theType ) const
1240 {
1241   if ( theType == SMESH::NODE )
1242   {
1243     static QMap<int, QString> aCriteria;
1244     if ( aCriteria.isEmpty() )
1245     {
1246       aCriteria[ SMESH::FT_RangeOfIds       ] = tr( "RANGE_OF_IDS" );
1247       aCriteria[ SMESH::FT_BelongToGeom     ] = tr( "BELONG_TO_GEOM" );
1248       aCriteria[ SMESH::FT_BelongToPlane    ] = tr( "BELONG_TO_PLANE" );
1249       aCriteria[ SMESH::FT_BelongToCylinder ] = tr( "BELONG_TO_CYLINDER" );
1250       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr( "LYING_ON_GEOM" );
1251     }
1252     return aCriteria;
1253   }
1254   else if ( theType == SMESH::EDGE )
1255   {
1256     static QMap<int, QString> aCriteria;
1257     if ( aCriteria.isEmpty() )
1258     {
1259       aCriteria[ SMESH::FT_FreeBorders      ] = tr( "FREE_BORDERS" );
1260       aCriteria[ SMESH::FT_MultiConnection  ] = tr( "MULTI_BORDERS" );
1261       aCriteria[ SMESH::FT_Length           ] = tr( "LENGTH" );
1262       aCriteria[ SMESH::FT_RangeOfIds       ] = tr( "RANGE_OF_IDS" );
1263       aCriteria[ SMESH::FT_BelongToGeom     ] = tr( "BELONG_TO_GEOM" );
1264       aCriteria[ SMESH::FT_BelongToPlane    ] = tr( "BELONG_TO_PLANE" );
1265       aCriteria[ SMESH::FT_BelongToCylinder ] = tr( "BELONG_TO_CYLINDER" );
1266       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr( "LYING_ON_GEOM" );
1267     }
1268     return aCriteria;
1269   }
1270   else if ( theType == SMESH::FACE )
1271   {
1272     static QMap<int, QString> aCriteria;
1273     if ( aCriteria.isEmpty() )
1274     {
1275       aCriteria[ SMESH::FT_AspectRatio      ] = tr( "ASPECT_RATIO" );
1276       aCriteria[ SMESH::FT_Warping          ] = tr( "WARPING" );
1277       aCriteria[ SMESH::FT_MinimumAngle     ] = tr( "MINIMUM_ANGLE" );
1278       aCriteria[ SMESH::FT_Taper            ] = tr( "TAPER" );
1279       aCriteria[ SMESH::FT_Skew             ] = tr( "SKEW" );
1280       aCriteria[ SMESH::FT_Area             ] = tr( "AREA" );
1281       aCriteria[ SMESH::FT_FreeEdges        ] = tr( "FREE_EDGES" );
1282       aCriteria[ SMESH::FT_RangeOfIds       ] = tr( "RANGE_OF_IDS" );
1283       aCriteria[ SMESH::FT_BelongToGeom     ] = tr( "BELONG_TO_GEOM" );
1284       aCriteria[ SMESH::FT_BelongToPlane    ] = tr( "BELONG_TO_PLANE" );
1285       aCriteria[ SMESH::FT_BelongToCylinder ] = tr( "BELONG_TO_CYLINDER" );
1286       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr( "LYING_ON_GEOM" );
1287       aCriteria[ SMESH::FT_Length2D         ] = tr( "LENGTH2D" );
1288       aCriteria[ SMESH::FT_MultiConnection2D] = tr( "MULTI2D_BORDERS" );
1289     }
1290     return aCriteria;
1291   }
1292   else if ( theType == SMESH::VOLUME )
1293   {
1294     static QMap<int, QString> aCriteria;
1295     if ( aCriteria.isEmpty() )
1296     {
1297       aCriteria[ SMESH::FT_AspectRatio3D] = tr( "ASPECT_RATIO_3D" );
1298       aCriteria[ SMESH::FT_RangeOfIds   ] = tr( "RANGE_OF_IDS" );
1299       aCriteria[ SMESH::FT_BelongToGeom ] = tr( "BELONG_TO_GEOM" );
1300       aCriteria[ SMESH::FT_LyingOnGeom ] = tr( "LYING_ON_GEOM" );
1301     }
1302     return aCriteria;
1303   }
1304   else
1305   {
1306     static QMap<int, QString> aCriteria;
1307     return aCriteria;
1308   }
1309 }
1310
1311
1312 //=======================================================================
1313 // name    : SMESHGUI_FilterTable::getCompare
1314 // Purpose : Get operation of comparison
1315 //=======================================================================
1316 const QMap<int, QString>& SMESHGUI_FilterTable::getCompare() const
1317 {
1318   static QMap<int, QString> aMap;
1319
1320   if ( aMap.isEmpty() )
1321   {
1322     aMap[ SMESH::FT_LessThan ] = tr( "LESS_THAN" );
1323     aMap[ SMESH::FT_MoreThan ] = tr( "MORE_THAN" );
1324     aMap[ SMESH::FT_EqualTo  ] = tr( "EQUAL_TO"  );
1325   }
1326
1327   return aMap;
1328 }
1329
1330 //=======================================================================
1331 // name    : SMESHGUI_FilterTable::createTable
1332 // Purpose : Create table
1333 //=======================================================================
1334 SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable( QWidget*  theParent,
1335                                                                 const int theType )
1336 {
1337   // create table
1338   Table* aTable= new Table( 0, 5, theParent );
1339
1340   QHeader* aHeaders = aTable->horizontalHeader();
1341
1342   QFontMetrics aMetrics( aHeaders->font() );
1343
1344   // append spaces to the header of criteria in order to
1345   // provide visibility of criterion inside comboboxes
1346   static int aMaxLenCr = 0;
1347
1348   if ( aMaxLenCr == 0 )
1349   {
1350     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
1351     QMap<int, QString>::const_iterator anIter;
1352     for ( anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter )
1353       aMaxLenCr = Max( maxLength( getCriteria( anIter.key() ), aMetrics ), aMaxLenCr );
1354   }
1355
1356   static int aLenCr = abs(  aMaxLenCr -
1357                             aMetrics.width( tr( "CRITERION" ) ) ) / aMetrics.width( ' ' ) + 5;
1358
1359   QString aCrStr;
1360   aCrStr.fill( ' ', aLenCr );
1361   QString aCoStr;
1362   aCoStr.fill( ' ', 10 );
1363
1364   aHeaders->setLabel( 0, tr( "CRITERION" ) + aCrStr );
1365   aHeaders->setLabel( 1, tr( "COMPARE" ) + aCoStr );
1366   aHeaders->setLabel( 2, tr( "THRESHOLD_VALUE" ) );
1367   aHeaders->setLabel( 3, tr( "UNARY" ) );
1368   aHeaders->setLabel( 4, tr( "BINARY" ) + "  " );
1369
1370   // set geometry of the table
1371   for ( int i = 0; i <= 4; i++ )
1372     aTable->adjustColumn( i );
1373
1374   aTable->updateGeometry();
1375   QSize aSize = aTable->sizeHint();
1376   int aWidth = aSize.width();
1377   aTable->setMinimumSize( QSize( aWidth, aWidth / 2 ) );
1378   aTable->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
1379
1380   connect( aTable, SIGNAL( valueChanged( int, int ) ),
1381            this,   SLOT( onCriterionChanged( int, int ) ) );
1382
1383   connect( aTable, SIGNAL( currentChanged( int, int ) ),
1384            this,   SLOT( onCurrentChanged( int, int ) ) );
1385
1386   return aTable;
1387 }
1388
1389 //=======================================================================
1390 // name    : SMESHGUI_FilterTable::updateBtnState
1391 // Purpose : Update button state
1392 //=======================================================================
1393 void SMESHGUI_FilterTable::updateBtnState()
1394 {
1395   myRemoveBtn->setEnabled( myTables[ GetType() ]->numRows() > 0 );
1396   myClearBtn->setEnabled( myTables[ GetType() ]->numRows() > 0 );
1397 }
1398
1399 //=======================================================================
1400 // name    : SMESHGUI_FilterTable::SetEditable
1401 // Purpose : Set read only flag for tables. Show/hide buttons for work with rows
1402 //=======================================================================
1403 void SMESHGUI_FilterTable::SetEditable( const bool isEditable )
1404 {
1405   TableMap::iterator anIter;
1406   for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter )
1407   {
1408     anIter.data()->setReadOnly( !isEditable );
1409
1410     if ( isEditable )
1411     {
1412       myAddBtn->show();
1413       myInsertBtn->show();
1414       myRemoveBtn->show();
1415       myClearBtn->show();
1416     }
1417     else
1418     {
1419       myAddBtn->hide();
1420       myInsertBtn->hide();
1421       myRemoveBtn->hide();
1422       myClearBtn->hide();
1423     }
1424   }
1425
1426   QMap<QTableItem*, AdditionalWidget*>::iterator anIter2;
1427   for ( anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2 )
1428     anIter2.data()->SetEditable( isEditable );
1429 }
1430
1431 //=======================================================================
1432 // name    : SMESHGUI_FilterTable::SetEnabled
1433 // Purpose : Enable/Disable table. Switching type of elements already enabled
1434 //=======================================================================
1435 void SMESHGUI_FilterTable::SetEnabled( const bool isEnabled )
1436 {
1437   myAddBtn->setEnabled( isEnabled );
1438   myInsertBtn->setEnabled( isEnabled );
1439   myRemoveBtn->setEnabled( isEnabled );
1440   myClearBtn->setEnabled( isEnabled );
1441
1442   if ( isEnabled )
1443     updateBtnState();
1444   
1445   QMap<QTableItem*, AdditionalWidget*>::iterator anIter2;
1446   for ( anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2 )
1447     anIter2.data()->setEnabled( isEnabled );
1448 }
1449
1450 //=======================================================================
1451 // name    : SMESHGUI_FilterTable::IsEditable
1452 // Purpose : Verify whether table is editable
1453 //=======================================================================
1454 bool SMESHGUI_FilterTable::IsEditable() const
1455 {
1456   return !myTables[ GetType() ]->isReadOnly();
1457 }
1458
1459 //=======================================================================
1460 // name    : SMESHGUI_FilterTable::SetLibsEnabled
1461 // Purpose : Show/hide buttons for work with libraries
1462 //=======================================================================
1463 void SMESHGUI_FilterTable::SetLibsEnabled( const bool isEnabled )
1464 {
1465   if ( isEnabled )
1466   {
1467     myCopyFromBtn->show();
1468     myAddToBtn->show();
1469   }
1470   else
1471   {
1472     myCopyFromBtn->hide();
1473     myAddToBtn->hide();
1474   }
1475 }
1476
1477 //=======================================================================
1478 // name    : SMESHGUI_FilterTable::onCopyFromBtn
1479 // Purpose : SLOT. Called the "Copy from ..." button clicked
1480 //           Display filter library dialog
1481 //=======================================================================
1482 void SMESHGUI_FilterTable::onCopyFromBtn()
1483 {
1484   if ( myLibDlg == 0 )
1485     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1486       this, GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM );
1487   else
1488     myLibDlg->Init( GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM );
1489
1490   if ( myLibDlg->exec() == QDialog::Accepted )
1491   {
1492     Copy( myLibDlg->GetTable() );
1493     Update();
1494   }
1495 }
1496
1497 //=======================================================================
1498 // name    : SMESHGUI_FilterTable::onAddToBtn
1499 // Purpose : SLOT. Called the "Add to ..." button clicked
1500 //           Display filter library dialog
1501 //=======================================================================
1502 void SMESHGUI_FilterTable::onAddToBtn()
1503 {
1504   if ( !IsValid( true ) )
1505     return;
1506   if ( myLibDlg == 0 )
1507     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1508       this, GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO );
1509   else
1510     myLibDlg->Init( GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO );
1511
1512   myLibDlg->SetTable( this );
1513     
1514   myLibDlg->exec();
1515 }                                          
1516
1517 //=======================================================================
1518 // name    : SMESHGUI_FilterTable::Copy
1519 // Purpose : Initialise table with values of other table
1520 //=======================================================================
1521 void SMESHGUI_FilterTable::Copy( const SMESHGUI_FilterTable* theTable )
1522 {
1523   Clear();
1524
1525   for ( int i = 0, n = theTable->NumRows(); i < n; i++ )
1526   {
1527     SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion();
1528     theTable->GetCriterion( i, aCriterion );
1529     AddCriterion( aCriterion );
1530   }
1531 }
1532
1533 //=======================================================================
1534 // name    : SMESHGUI_FilterTable::CurrentCell
1535 // Purpose : Returns current cell
1536 //=======================================================================
1537 bool SMESHGUI_FilterTable::CurrentCell( int& theRow, int& theCol ) const
1538 {
1539   theRow = myTables[ GetType() ]->currentRow();
1540   theCol = myTables[ GetType() ]->currentColumn();
1541   return theRow >= 0 && theCol >= 0;
1542 }
1543
1544 //=======================================================================
1545 // name    : SMESHGUI_FilterTable::SetText
1546 // Purpose : Set text and internal value in cell of threshold value 
1547 //=======================================================================
1548 void SMESHGUI_FilterTable::SetThreshold( const int      theRow,
1549                                          const QString& theText,
1550                                          const int      theEntityType )
1551 {
1552   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1553   aTable->setText( theRow, 2, theText );
1554 }
1555
1556 //=======================================================================
1557 // name    : SMESHGUI_FilterTable::SetText
1558 // Purpose : Get text and internal value from cell of threshold value
1559 //=======================================================================
1560 bool SMESHGUI_FilterTable::GetThreshold( const int      theRow,
1561                                          QString&       theText,
1562                                          const int      theEntityType )
1563 {
1564   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1565   QTableItem* anItem = aTable->item( theRow, 2 );
1566   if ( anItem != 0 )
1567   {
1568     theText = anItem->text();
1569     return true;    
1570   }
1571   else
1572    return false;
1573 }
1574
1575 /*                                                                                                                                                 
1576   Class       : SMESHGUI_FilterDlg
1577   Description : Dialog to specify filters for VTK viewer
1578 */
1579
1580
1581 //=======================================================================
1582 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
1583 // Purpose : Constructor
1584 //=======================================================================
1585 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget*               theParent,
1586                                         const QValueList<int>& theTypes,
1587                                         const char*            theName )
1588 : QDialog( theParent, theName, false,
1589            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
1590 {
1591   construct( theTypes );
1592 }
1593
1594 //=======================================================================
1595 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
1596 // Purpose : Constructor
1597 //=======================================================================
1598 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget*    theParent,
1599                                         const int   theType,
1600                                         const char* theName )
1601 : QDialog( theParent, theName, false,
1602            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
1603 {
1604   QValueList<int> aTypes;
1605   aTypes.append( theType );
1606   construct( aTypes );
1607 }
1608
1609 //=======================================================================
1610 // name    : SMESHGUI_FilterDlg::construct
1611 // Purpose : Construct dialog ( called by constructor )
1612 //=======================================================================
1613 void SMESHGUI_FilterDlg::construct( const QValueList<int>& theTypes )
1614 {
1615   myTypes = theTypes;
1616
1617   setCaption( tr( "CAPTION" ) );
1618
1619   QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
1620
1621   myMainFrame        = createMainFrame  ( this );
1622   QFrame* aBtnFrame  = createButtonFrame( this );
1623
1624   aDlgLay->addWidget( myMainFrame );
1625   aDlgLay->addWidget( aBtnFrame );
1626
1627   aDlgLay->setStretchFactor( myMainFrame, 1 );
1628
1629   Init( myTypes );
1630 }
1631
1632 //=======================================================================
1633 // name    : SMESHGUI_FilterDlg::createMainFrame
1634 // Purpose : Create frame containing dialog's input fields
1635 //=======================================================================
1636 QFrame* SMESHGUI_FilterDlg::createMainFrame( QWidget* theParent )
1637 {
1638   QGroupBox* aMainFrame = new QGroupBox( 1, Qt::Horizontal, theParent );
1639   aMainFrame->setFrameStyle( QFrame::NoFrame );
1640   aMainFrame->setInsideMargin( 0 );
1641
1642   // filter frame
1643
1644   myTable = new SMESHGUI_FilterTable( aMainFrame, myTypes );
1645   myTable->SetLibsEnabled( true );
1646
1647   QFrame* aLine = new QFrame( myTable->GetTableGrp() );
1648   aLine->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1649
1650   mySetInViewer = new QCheckBox( tr( "SET_IN_VIEWER" ), myTable->GetTableGrp() );
1651   mySetInViewer->setChecked( true );
1652
1653   // other controls
1654   mySourceGrp = createSourceGroup( aMainFrame );
1655
1656   connect( myTable, SIGNAL( CretarionChanged( const int, const int ) ),
1657                     SLOT( onCriterionChanged( const int, const int ) ) );
1658
1659   connect( myTable, SIGNAL( CurrentChanged( int, int ) ),
1660                     SLOT( onCurrentChanged( int, int ) ) );                    
1661
1662   return aMainFrame;
1663 }
1664
1665 //=======================================================================
1666 // name    : SMESHGUI_FilterDlg::createSourceFrame
1667 // Purpose : Create frame containing source radio button
1668 //=======================================================================
1669 QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup( QWidget* theParent )
1670 {
1671   QButtonGroup* aGrp = new QButtonGroup( 1, Qt::Vertical, tr( "SOURCE" ), theParent );
1672
1673   QRadioButton* aMeshBtn = new QRadioButton( tr( "MESH" ), aGrp );
1674   QRadioButton* aSelBtn  = new QRadioButton( tr( "SELECTION" ), aGrp );
1675   QRadioButton* aGrpBtn  = new QRadioButton( tr( "CURRENT_GROUP" ), aGrp );
1676
1677   aGrp->insert( aMeshBtn, Mesh );
1678   aGrp->insert( aSelBtn, Selection );
1679   aGrp->insert( aGrpBtn, Dialog );
1680
1681   aGrp->setButton( Selection );
1682
1683   return aGrp;
1684 }
1685
1686 //=======================================================================
1687 // name    : SMESHGUI_FilterDlg::updateMainButtons
1688 // Purpose : Update visibility of main buttons ( OK, Cancel, Close ... )
1689 //=======================================================================
1690 void SMESHGUI_FilterDlg::updateMainButtons()
1691 {
1692   if ( myTypes.count() == 1 )
1693   {
1694     myButtons[ BTN_Cancel ]->show();
1695     myButtons[ BTN_Apply  ]->hide();
1696     myButtons[ BTN_Close  ]->hide();
1697   }
1698   else
1699   {
1700     myButtons[ BTN_Cancel ]->hide();
1701     myButtons[ BTN_Apply  ]->show();
1702     myButtons[ BTN_Close  ]->show();
1703   }
1704
1705 //  updateGeometry();
1706 }
1707
1708 //=======================================================================
1709 // name    : SMESHGUI_FilterDlg::createButtonFrame
1710 // Purpose : Create frame containing buttons
1711 //=======================================================================
1712 QFrame* SMESHGUI_FilterDlg::createButtonFrame( QWidget* theParent )
1713 {
1714   QGroupBox* aGrp = new QGroupBox( 1, Qt::Vertical, theParent );
1715
1716   myButtons[ BTN_OK    ] = new QPushButton( tr( "SMESH_BUT_OK"    ), aGrp );
1717   myButtons[ BTN_Apply ] = new QPushButton( tr( "SMESH_BUT_APPLY" ), aGrp );
1718
1719   QLabel* aLbl = new QLabel( aGrp );
1720   aLbl->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1721
1722   myButtons[ BTN_Cancel ] = new QPushButton( tr( "SMESH_BUT_CANCEL" ), aGrp );
1723   myButtons[ BTN_Close  ] = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aGrp );
1724
1725   connect( myButtons[ BTN_OK     ], SIGNAL( clicked() ), SLOT( onOk() ) );
1726   connect( myButtons[ BTN_Cancel ], SIGNAL( clicked() ), SLOT( onClose() ) ) ;
1727   connect( myButtons[ BTN_Close  ], SIGNAL( clicked() ), SLOT( onClose() ) ) ;
1728   connect( myButtons[ BTN_Apply  ], SIGNAL( clicked() ), SLOT( onApply() ) );
1729
1730   updateMainButtons();
1731
1732   return aGrp;
1733 }
1734
1735 //=======================================================================
1736 // name    : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
1737 // Purpose : Destructor
1738 //=======================================================================
1739 SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
1740 {
1741 }
1742
1743 //=======================================================================
1744 // name    : SMESHGUI_FilterDlg::Init
1745 // Purpose : Init dialog fields, connect signals and slots, show dialog
1746 //=======================================================================
1747 void SMESHGUI_FilterDlg::Init( const int type )
1748 {
1749   QValueList<int> aTypes;
1750   aTypes.append( type );
1751   Init( aTypes );
1752 }
1753
1754 //=======================================================================
1755 // name    : SMESHGUI_FilterDlg::Init
1756 // Purpose : Init dialog fields, connect signals and slots, show dialog
1757 //=======================================================================
1758 void SMESHGUI_FilterDlg::Init( const QValueList<int>& theTypes )
1759 {
1760   mySourceWg  = 0;
1761   mySelection = 0;
1762   myTypes     = theTypes;
1763   myMesh      = SMESH::SMESH_Mesh::_nil();
1764   myIObjects.Clear();
1765   myIsSelectionChanged = false;
1766
1767   myTable->Init( theTypes );
1768
1769   // set caption
1770   if ( theTypes.count() == 1 )
1771   {
1772     int aType = theTypes.first();
1773     if      ( aType == SMESH::NODE   ) setCaption( tr( "NODES_TLT" ) );
1774     else if ( aType == SMESH::EDGE   ) setCaption( tr( "EDGES_TLT" ) );
1775     else if ( aType == SMESH::FACE   ) setCaption( tr( "FACES_TLT" ) );
1776     else if ( aType == SMESH::VOLUME ) setCaption( tr( "VOLUMES_TLT" ) );
1777   }
1778   else
1779     setCaption( tr( "TLT" ) );
1780
1781   qApp->processEvents();
1782   updateGeometry();
1783   adjustSize();
1784   setEnabled( true );
1785
1786   mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
1787   mySMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
1788
1789   connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
1790   connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
1791
1792   int x, y ;
1793   mySMESHGUI->DefineDlgPosition( this, x, y );
1794   this->move( x, y );
1795
1796   updateMainButtons();
1797   updateSelection();
1798
1799   // Initialise filter table with values of previous filter
1800   QValueList<int>::const_iterator anIter;
1801   for ( anIter = theTypes.begin(); anIter != theTypes.end(); ++anIter )
1802   {
1803     myTable->Clear( *anIter );
1804     if ( !myFilter[ *anIter ]->_is_nil() )
1805     {
1806       SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
1807       if ( myFilter[ *anIter ]->GetCriteria( aCriteria ) )
1808       {
1809         for ( int i = 0, n = aCriteria->length(); i < n; i++ )
1810           myTable->AddCriterion( aCriteria[ i ], *anIter );
1811       }
1812     }
1813   }
1814
1815   if ( myInsertState.contains( theTypes.first() ) )
1816     mySetInViewer->setChecked( myInsertState[ theTypes.first() ] );
1817   else
1818     mySetInViewer->setChecked( true );
1819   if ( myApplyToState.contains( theTypes.first() ) )
1820     mySourceGrp->setButton( myApplyToState[ theTypes.first() ] );
1821   else
1822     mySourceGrp->setButton( Selection ); 
1823 }
1824
1825 //=======================================================================
1826 // name    : SMESHGUI_FilterDlg::onOk
1827 // Purpose : SLOT called when "Ok" button pressed.
1828 //           Assign filters VTK viewer and close dialog
1829 //=======================================================================
1830 void SMESHGUI_FilterDlg::onOk()
1831 {
1832   if ( onApply() )
1833   {
1834     mySelection->ClearFilters();
1835     disconnect( mySMESHGUI, 0, this, 0 );
1836     disconnect( mySelection, 0, this, 0 );
1837     mySMESHGUI->ResetState() ;
1838     accept();
1839     emit Accepted();
1840   }
1841 }
1842
1843 //=======================================================================
1844 // name    : SMESHGUI_FilterDlg::onClose
1845 // Purpose : SLOT called when "Close" button pressed. Close dialog
1846 //=======================================================================
1847 void SMESHGUI_FilterDlg::onClose()
1848 {
1849   // Restore previously selected object
1850   if ( mySelection )
1851   {
1852     mySelection->ClearFilters();
1853     mySelection->Clear();
1854     SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter( myIObjects );
1855     for ( ; anIter.More(); anIter.Next() )
1856     {
1857       mySelection->AddIObject( anIter.Key() );
1858
1859       TColStd_MapOfInteger aResMap;
1860       const TColStd_IndexedMapOfInteger& anIndMap = anIter.Value();
1861       for ( int i = 1, n = anIndMap.Extent(); i <= n; i++ )
1862         aResMap.Add( anIndMap( i ) );
1863       
1864       mySelection->AddOrRemoveIndex( anIter.Key(), aResMap, false );
1865     }
1866   }
1867
1868   disconnect( mySMESHGUI, 0, this, 0 );
1869   disconnect( mySelection, 0, this, 0 );
1870   mySMESHGUI->ResetState() ;
1871   reject() ;
1872   return ;
1873 }
1874
1875 //=======================================================================
1876 // name    : SMESHGUI_FilterDlg::onDeactivate
1877 // Purpose : SLOT called when dialog must be deativated
1878 //=======================================================================
1879 void SMESHGUI_FilterDlg::onDeactivate()
1880 {
1881   setEnabled( false );
1882 }
1883
1884 //=======================================================================
1885 // name    : SMESHGUI_FilterDlg::enterEvent
1886 // Purpose : Event filter
1887 //=======================================================================
1888 void SMESHGUI_FilterDlg::enterEvent( QEvent* )
1889 {
1890 //  mySMESHGUI->EmitSignalDeactivateDialog();
1891   mySMESHGUI->SetActiveDialogBox( (QDialog*)this );
1892   mySMESHGUI->ResetState();
1893   setEnabled( true );
1894 }
1895
1896
1897 //=================================================================================
1898 // function : closeEvent()
1899 // purpose  :
1900 //=================================================================================
1901 void SMESHGUI_FilterDlg::closeEvent( QCloseEvent* e )
1902 {
1903   onClose() ;
1904 }
1905
1906 //=======================================================================
1907 // name    : SMESHGUI_FilterDlg::getIdsFromWg
1908 // Purpose : Retrieve list of ids from given widget
1909 //=======================================================================
1910 void SMESHGUI_FilterDlg::getIdsFromWg( const QWidget* theWg, QValueList<int>& theRes ) const
1911 {
1912   theRes.clear();
1913   if ( theWg == 0 )
1914     return;
1915
1916   if ( theWg->inherits( "QListBox" ) )
1917   {
1918     QListBox* aListBox = ( QListBox* )theWg;
1919     bool b;
1920     for ( int i = 0, n = aListBox->count(); i < n; i++ )
1921     {
1922       int anId = aListBox->text( i ).toInt( &b );
1923       if ( b )
1924         theRes.append( anId );
1925     }
1926   }
1927   else if ( theWg->inherits( "QLineEdit" ) )
1928   {
1929     QLineEdit* aLineEdit = ( QLineEdit* )theWg;
1930     QString aStr = aLineEdit->text();
1931     QRegExp aRegExp( "(\\d+)" );
1932     bool b;
1933     int aPos = 0;
1934     while ( aPos >= 0 )
1935     {
1936       aPos = aRegExp.search( aStr, aPos );
1937       if ( aPos > -1 )
1938       {
1939         int anId = aRegExp.cap( 1 ).toInt( &b );
1940         if ( b )
1941           theRes.append( anId );
1942         aPos += aRegExp.matchedLength();
1943       }
1944     }
1945   }
1946 }
1947
1948 //=======================================================================
1949 // name    : SMESHGUI_FilterDlg::getSelMode
1950 // Purpose : Get selection mode of specified type
1951 //=======================================================================
1952 Selection_Mode SMESHGUI_FilterDlg::getSelMode( const int theType ) const
1953 {
1954   switch ( theType )
1955   {
1956     case SMESH::NODE   : return NodeSelection;
1957     case SMESH::EDGE   : return EdgeSelection;
1958     case SMESH::FACE   : return FaceSelection;
1959     case SMESH::VOLUME : return VolumeSelection;
1960     default            : return ActorSelection;
1961   }
1962
1963 }
1964
1965 //=======================================================================
1966 // name    : SMESHGUI_FilterDlg::setIdsToWg
1967 // Purpose : Insert identifiers in specified widgets
1968 //=======================================================================
1969 void SMESHGUI_FilterDlg::setIdsToWg( QWidget* theWg, const QValueList<int>& theIds )
1970 {
1971   if ( theWg == 0 )
1972     return;
1973
1974   if ( theWg->inherits( "QListBox" ) )
1975   {
1976     QListBox* aListBox = ( QListBox* )theWg;
1977     aListBox->clear();
1978
1979     QStringList aStrList;
1980     QValueList<int>::const_iterator anIter;
1981     for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
1982       aStrList.append( QString( "%1" ).arg( *anIter ) );
1983
1984     aListBox->insertStringList( aStrList );
1985   }
1986   else if ( theWg->inherits( "QLineEdit" ) )
1987   {
1988     QLineEdit* aLineEdit = ( QLineEdit* )theWg;
1989     QString aStr;
1990     QValueList<int>::const_iterator anIter;
1991
1992     for ( anIter = theIds.begin(); anIter != theIds.end(); ++ anIter )
1993       aStr += QString( "%1 " ).arg( *anIter );
1994
1995     if ( !aStr.isEmpty() )
1996       aStr.remove( aStr.length() - 1, 1 );
1997
1998     aLineEdit->setText( aStr );
1999   }
2000 }
2001
2002 //=======================================================================
2003 // name    : SMESHGUI_FilterDlg::isValid
2004 // Purpose : Verify validity of input data
2005 //=======================================================================
2006 bool SMESHGUI_FilterDlg::isValid() const
2007 {
2008   if ( !myTable->IsValid() )
2009     return false;
2010     
2011   for ( int i = 0, n = myTable->NumRows(); i < n; i++ )
2012   {
2013     int aType = myTable->GetCriterionType( i );
2014     if ( aType == FT_BelongToGeom ||
2015          aType == FT_BelongToPlane ||
2016          aType == FT_BelongToCylinder ||
2017          aType == FT_LyingOnGeom)
2018     {
2019       QString aName;
2020       myTable->GetThreshold( i, aName );
2021       
2022       SALOMEDS::Study::ListOfSObject_var aList = SMESHGUI::GetSMESHGUI()->GetActiveStudy()->
2023         getStudyDocument()->FindObjectByName( aName.latin1(), "GEOM" );
2024       if ( aList->length() == 0 )
2025       {
2026         QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2027           tr( "SMESH_INSUFFICIENT_DATA" ), tr( "BAD_SHAPE_NAME" ).arg( aName ), QMessageBox::Ok );
2028         return false;
2029       }
2030
2031       if ( aType == FT_BelongToCylinder || aType == FT_BelongToPlane )
2032       {
2033         GEOM::GEOM_Object_var aGeomObj =
2034           GEOM::GEOM_Object::_narrow( aList[ 0 ]->GetObject() );
2035         if ( !aGeomObj->_is_nil() )
2036         {
2037           TopoDS_Shape aFace;
2038           if ( !GEOMBase::GetShape( aGeomObj, aFace ) ||
2039                aFace.IsNull() ||
2040                aFace.ShapeType() != TopAbs_FACE )
2041           {
2042             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2043               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_FACE" ).arg( aName ), QMessageBox::Ok );
2044             return false;
2045           }
2046
2047           Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aFace ) );
2048           if ( aSurf.IsNull() )
2049           {
2050             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2051               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_FACE" ).arg( aName ), QMessageBox::Ok );
2052             return false;
2053           }
2054
2055           if ( aType == FT_BelongToPlane && !aSurf->IsKind( STANDARD_TYPE( Geom_Plane ) ) )
2056           {
2057             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2058               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_PLANE" ).arg( aName ), QMessageBox::Ok );
2059             return false;
2060           }
2061
2062           if ( aType == FT_BelongToCylinder && !aSurf->IsKind( STANDARD_TYPE( Geom_CylindricalSurface ) ) )
2063           {
2064             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2065               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_CYLINDER" ).arg( aName ), QMessageBox::Ok );
2066             return false;
2067           }
2068         }
2069       }
2070     }
2071   }
2072
2073   return true;
2074 }
2075
2076 //=======================================================================
2077 // name    : SMESHGUI_FilterDlg::SetSourceWg
2078 // Purpose : Set widget of parent dialog containing idsto be filtered if
2079 //           user select corresponding source radio button
2080 //=======================================================================
2081 void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg )
2082 {
2083   mySourceWg = theWg;
2084 }
2085
2086 //=======================================================================
2087 // name    : SMESHGUI_FilterDlg::SetGroupIds
2088 // Purpose : Set mesh
2089 //=======================================================================
2090 void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh )
2091 {
2092   myMesh = theMesh;
2093 }
2094
2095 //=======================================================================
2096 // name    : SMESHGUI_FilterDlg::SetSelection
2097 // Purpose : Get filtered ids
2098 //=======================================================================
2099 void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel )
2100 {
2101   if ( mySelection )
2102     disconnect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionDone() ) );
2103     
2104   mySelection = theSel;
2105
2106   if ( mySelection )
2107   {
2108     myIObjects.Clear();
2109     const SALOME_ListIO& anObjs = mySelection->StoredIObjects();
2110     SALOME_ListIteratorOfListIO anIter( anObjs );
2111     for ( ;anIter.More(); anIter.Next() )
2112     {
2113       TColStd_IndexedMapOfInteger aMap;
2114       mySelection->GetIndex( anIter.Value(), aMap );
2115       myIObjects.Bind( anIter.Value(), aMap );
2116     }
2117     
2118     connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
2119
2120     updateSelection();
2121   }
2122   else
2123     myIObjects.Clear();
2124 }
2125
2126 //=======================================================================
2127 // name    : SMESHGUI_FilterDlg::onApply
2128 // Purpose : SLOT called when "Apply" button pressed.
2129 //           Assign filters to VTK viewer
2130 //=======================================================================
2131 bool SMESHGUI_FilterDlg::onApply()
2132 {
2133   if ( !isValid() )
2134     return false;
2135
2136   try
2137   {
2138     int aCurrType = myTable->GetType();
2139
2140     if ( !createFilter( aCurrType ) )
2141       return false;
2142
2143     insertFilterInViewer();
2144
2145     if ( !myFilter[ aCurrType ]->GetPredicate()->_is_nil() )
2146     {
2147       QValueList<int> aResultIds;
2148       filterSource( aCurrType, aResultIds );
2149       selectInViewer( aCurrType, aResultIds );
2150     }
2151
2152     myInsertState[ aCurrType ] = mySetInViewer->isChecked();
2153     myApplyToState[ aCurrType ] = mySourceGrp->id( mySourceGrp->selected() );
2154     
2155   }
2156   catch( const SALOME::SALOME_Exception& S_ex )
2157   {
2158     QtCatchCorbaException( S_ex );
2159   }
2160   catch( ... )
2161   {
2162   }
2163
2164   return true;
2165 }
2166
2167 //=======================================================================
2168 // name    : SMESHGUI_FilterDlg::createFilter
2169 // Purpose : Create predicate for given type
2170 //=======================================================================
2171 bool SMESHGUI_FilterDlg::createFilter( const int theType )
2172 {
2173   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
2174   if ( aFilterMgr->_is_nil() )
2175     return false;
2176
2177   int n = myTable->NumRows();
2178
2179   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2180   aCriteria->length( n );
2181
2182   long aPrecision = -1;
2183   if ( QAD_CONFIG->hasSetting( "SMESH:ControlsPrecision" ) )
2184   {
2185     QString aStr = QAD_CONFIG->getSetting( "SMESH:ControlsPrecision" );
2186     bool isOk = false;
2187     int aVal = aStr.toInt( &isOk );
2188     if ( isOk )
2189       aPrecision = aVal;
2190   }
2191   
2192   for ( CORBA::ULong i = 0; i < n; i++ )
2193   {
2194     SMESH::Filter::Criterion aCriterion = createCriterion();
2195     myTable->GetCriterion( i, aCriterion );
2196     aCriterion.Precision = aPrecision;
2197     aCriteria[ i ] = aCriterion;
2198   }
2199
2200   myFilter[ theType ] = aFilterMgr->CreateFilter();
2201   myFilter[ theType ]->SetCriteria( aCriteria.inout() );
2202
2203   return true;
2204 }
2205
2206 //=======================================================================
2207 // name    : SMESHGUI_FilterDlg::insertFilterInViewer
2208 // Purpose : Insert filter in viewer
2209 //=======================================================================
2210 void SMESHGUI_FilterDlg::insertFilterInViewer()
2211 {
2212   if ( VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle() )
2213   {
2214     SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType();
2215
2216     if ( myFilter[ myTable->GetType() ]->_is_nil() ||
2217          myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() ||
2218          !mySetInViewer->isChecked() )
2219       SMESH::RemoveFilter( getFilterId( anEntType ), aStyle );
2220     else
2221     {
2222       Handle(SMESHGUI_PredicateFilter) aFilter = new SMESHGUI_PredicateFilter();
2223       aFilter->SetPredicate( myFilter[ myTable->GetType() ]->GetPredicate() );
2224       SMESH::SetFilter( aFilter, aStyle );
2225     }
2226   }
2227 }
2228
2229 //=======================================================================
2230 // name    : SMESHGUI_FilterDlg::filterSource
2231 // Purpose : Filter source ids
2232 //=======================================================================
2233 void SMESHGUI_FilterDlg::filterSource( const int theType,
2234                                        QValueList<int>& theResIds )
2235 {
2236   theResIds.clear();
2237   if ( myFilter[ theType ]->_is_nil() )
2238     return;
2239
2240   int aSourceId = mySourceGrp->id( mySourceGrp->selected() );
2241
2242   if ( aSourceId == Mesh )
2243   {
2244     if ( myMesh->_is_nil() )
2245       return;
2246     SMESH::long_array_var anIds = myFilter[ theType ]->GetElementsId( myMesh );
2247     for ( int i = 0, n = anIds->length(); i < n; i++ )
2248       theResIds.append( anIds[ i ] );
2249   }
2250   else if ( aSourceId == Selection )
2251   {
2252     filterSelectionSource( theType, theResIds );
2253   }
2254   else if ( aSourceId == Dialog )
2255   {
2256     // retrieve ids from dialog
2257     QValueList<int> aDialogIds;
2258     getIdsFromWg( mySourceWg, aDialogIds );
2259
2260     if ( myMesh->_is_nil() )
2261     {
2262       theResIds = aDialogIds;
2263       return;
2264     }
2265
2266     // filter ids
2267     SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2268     aPred->SetMesh( myMesh );
2269     QValueList<int>::const_iterator anIter;
2270     for ( anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter )
2271       if ( aPred->IsSatisfy( *anIter ) )
2272         theResIds.append( *anIter );
2273
2274     // set ids to the dialog
2275     setIdsToWg( mySourceWg, theResIds );
2276   }
2277 }
2278
2279 //=======================================================================
2280 // name    : SMESHGUI_FilterDlg::filterSelectionSource
2281 // Purpose : Filter source selection
2282 //=======================================================================
2283 void SMESHGUI_FilterDlg::filterSelectionSource( const int theType,
2284                                                 QValueList<int>& theResIds )
2285 {
2286   theResIds.clear();
2287   if ( myMesh->_is_nil() || mySelection == 0 )
2288     return;
2289
2290   // Create map of entities to be filtered
2291   TColStd_MapOfInteger aToBeFiltered;
2292   SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter( myIObjects );
2293
2294   for ( ; anIter.More(); anIter.Next() )
2295   {
2296     // process sub mesh
2297     SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIter.Key() );
2298     if ( !aSubMesh->_is_nil() )
2299     {
2300       if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() )
2301       {
2302         SMESH::long_array_var anIds =
2303           theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId();
2304         for ( int i = 0, n = anIds->length(); i < n; i++ )
2305           aToBeFiltered.Add( anIds[ i ] );
2306       }
2307     }
2308
2309     // process group
2310     SMESH::SMESH_GroupBase_var aGroup =
2311       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Key() );
2312     if ( !aGroup->_is_nil() )
2313     {
2314       if ( aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId() )
2315       {
2316         SMESH::long_array_var anIds = aGroup->GetListOfID();
2317         for ( int i = 0, n = anIds->length(); i < n; i++ )
2318           aToBeFiltered.Add( anIds[ i ] );
2319       }
2320     }
2321
2322     // process mesh
2323     SMESH::SMESH_Mesh_var aMeshPtr = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>( anIter.Key() );
2324     if ( !aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId() )
2325     {
2326       const TColStd_IndexedMapOfInteger& aSelMap = anIter.Value();
2327
2328       if ( aSelMap.Extent() > 0 )
2329       {
2330         if( SMESH::FindActorByEntry( anIter.Key()->getEntry() ) )
2331         {
2332           for ( int i = 1; i <= aSelMap.Extent(); i++ )
2333             aToBeFiltered.Add( aSelMap(i) );
2334         }
2335       }
2336     }
2337   }
2338
2339   // Filter entities
2340   SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2341   aPred->SetMesh( myMesh );
2342   TColStd_MapIteratorOfMapOfInteger aResIter( aToBeFiltered );
2343   for ( ; aResIter.More(); aResIter.Next() )
2344     if ( aPred->IsSatisfy( aResIter.Key() ) )
2345       theResIds.append( aResIter.Key() );
2346 }
2347
2348 //=======================================================================
2349 // name    : SMESHGUI_FilterDlg::selectInViewer
2350 // Purpose : Select given entities in viewer
2351 //=======================================================================
2352 void SMESHGUI_FilterDlg::selectInViewer( const int theType, const QValueList<int>& theIds )
2353 {
2354   if ( mySelection == 0 || myMesh->_is_nil() )
2355     return;
2356
2357   mySelection->ClearFilters();
2358
2359   // Set new selection mode if necessary
2360   Selection_Mode aSelMode = getSelMode( theType );
2361   if ( aSelMode != mySelection->SelectionMode() )
2362   {
2363     mySelection->ClearIObjects();
2364     mySelection->ClearFilters();
2365     if ( aSelMode == NodeSelection )
2366       SMESH::SetPointRepresentation(true);
2367     QAD_Application::getDesktop()->SetSelectionMode( aSelMode );
2368   }
2369
2370   // Clear selection
2371   SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
2372   if ( !anActor || !anActor->hasIO() )
2373     return;
2374
2375   Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
2376   mySelection->ClearIObjects();
2377   mySelection->AddIObject( anIO, false );
2378
2379   // Remove filter corresponding to the current type from viewer
2380   int aType = myTable->GetType();
2381   int aFilterId = SMESHGUI_UnknownFilter;
2382   if      ( aType == SMESH::EDGE   ) aFilterId = SMESHGUI_EdgeFilter;
2383   else if ( aType == SMESH::FACE   ) aFilterId = SMESHGUI_FaceFilter;
2384   else if ( aType == SMESH::VOLUME ) aFilterId = SMESHGUI_VolumeFilter;
2385   Handle(VTKViewer_Filter) aFilter = SMESH::GetFilter( aFilterId );
2386   SMESH::RemoveFilter( aFilterId );
2387
2388   // get vtk ids
2389   TColStd_MapOfInteger aMap;
2390   QValueList<int>::const_iterator anIter;
2391   for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
2392   {
2393     aMap.Add( *anIter );
2394   }
2395
2396   // Set new selection
2397   mySelection->AddOrRemoveIndex( anIO, aMap, false, true );
2398
2399   // insert previously stored filter in viewer if necessary
2400   if ( !aFilter.IsNull() )
2401     SMESH::SetFilter( aFilter );
2402 }
2403
2404 //=======================================================================
2405 // name    : SMESHGUI_FilterDlg::createCriterion
2406 // Purpose : Create criterion structure with default values
2407 //=======================================================================
2408 SMESH::Filter::Criterion SMESHGUI_FilterDlg::createCriterion()
2409 {
2410    SMESH::Filter::Criterion aCriterion;
2411
2412   aCriterion.Type          = FT_Undefined;
2413   aCriterion.Compare       = FT_Undefined;
2414   aCriterion.Threshold     = 0;
2415   aCriterion.UnaryOp       = FT_Undefined;
2416   aCriterion.BinaryOp      = FT_Undefined;
2417   aCriterion.ThresholdStr  = "";
2418   aCriterion.TypeOfElement = SMESH::ALL;
2419
2420   return aCriterion;
2421 }
2422
2423 //=======================================================================
2424 // name    : SMESHGUI_FilterDlg::onSelectionDone
2425 // Purpose : SLOT called when selection changed.
2426 //           If current cell corresponds to the threshold value of
2427 //           BelongToGeom criterion name of selected object is set in this cell
2428 //=======================================================================
2429 void SMESHGUI_FilterDlg::onSelectionDone()
2430 {
2431   int aRow, aCol;
2432   if (  mySelection->IObjectCount() != 1 ||
2433         !myTable->CurrentCell( aRow, aCol ) ||
2434         myTable->GetCriterionType( aRow ) != FT_BelongToGeom &&
2435         myTable->GetCriterionType( aRow ) != FT_BelongToPlane &&
2436         myTable->GetCriterionType( aRow ) != FT_BelongToCylinder &&
2437         myTable->GetCriterionType( aRow ) != FT_LyingOnGeom )
2438     return;
2439
2440   Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject() ;
2441   GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( anIO ) ;
2442   if ( !anObj->_is_nil() )
2443     myTable->SetThreshold( aRow, anIO->getName() );
2444 }
2445
2446 //=======================================================================
2447 // name    : SMESHGUI_FilterDlg::onCriterionChanged
2448 // Purpose : SLOT called when cretarion of current row changed. Update selection
2449 //=======================================================================
2450 void SMESHGUI_FilterDlg::onCriterionChanged( const int , const int )
2451 {
2452   updateSelection();
2453 }
2454
2455 //=======================================================================
2456 // name    : SMESHGUI_FilterDlg::onCurrentChanged
2457 // Purpose : SLOT called when current row changed. Update selection
2458 //=======================================================================
2459 void SMESHGUI_FilterDlg::onCurrentChanged( int, int )
2460 {
2461   updateSelection();
2462 }
2463
2464 //=======================================================================
2465 // name    : SMESHGUI_FilterDlg::updateSelection
2466 // Purpose : UpdateSelection in accordance with current row
2467 //=======================================================================
2468 void SMESHGUI_FilterDlg::updateSelection()
2469 {
2470   if ( mySelection == 0 )
2471     return;
2472   
2473   mySelection->ClearFilters();
2474
2475   int aRow, aCol;
2476   
2477   if ( myTable->CurrentCell( aRow, aCol ) &&
2478        ( myTable->GetCriterionType( aRow ) == FT_BelongToGeom ||
2479          myTable->GetCriterionType( aRow ) == FT_BelongToPlane ||
2480          myTable->GetCriterionType( aRow ) == FT_BelongToCylinder ||
2481          myTable->GetCriterionType( aRow ) == FT_LyingOnGeom) )
2482   {
2483     if ( myTable->GetCriterionType( aRow ) == FT_BelongToGeom ||  myTable->GetCriterionType( aRow ) == FT_LyingOnGeom )
2484       mySelection->AddFilter( new SALOME_TypeFilter( "GEOM" ) );
2485     else if ( myTable->GetCriterionType( aRow ) == FT_BelongToPlane )
2486       mySelection->AddFilter( new GEOM_FaceFilter( StdSelect_Plane ) );
2487     else if ( myTable->GetCriterionType( aRow ) == FT_BelongToCylinder )
2488       mySelection->AddFilter( new GEOM_FaceFilter( StdSelect_Cylinder ) );
2489
2490     myIsSelectionChanged = true;
2491   }
2492   else
2493   {
2494     if ( myIsSelectionChanged )
2495       mySelection->AddFilter( new SALOME_TypeFilter( "This filter deactivate selection" ) );
2496   }
2497 }
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521