Salome HOME
Bug PAL7334 DEVELOPMENT : Control Improvement
[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     {
663       if ( aTable->text( i, 2 ).isEmpty() )
664       {
665         if ( theMess )
666           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
667             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ), QMessageBox::Ok );
668         return false;
669       }
670     }
671     else
672     {
673       bool aRes = false;
674       aTable->blockSignals( true );
675       double  aThreshold = ( int )aTable->text( i, 2 ).toDouble( &aRes );
676       aTable->blockSignals( false );
677
678       if ( !aRes && aTable->IsEditable( i, 2 ) )
679       {
680         if ( theMess )
681           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
682             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "ERROR" ), QMessageBox::Ok );
683         return false;
684       }
685       else if ( aType == SMESH::EDGE &&
686                 GetCriterionType( i, aType ) == SMESH::FT_MultiConnection &&
687                 aThreshold == 1 )
688       {
689         if ( theMess )
690           QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
691             tr( "SMESH_INSUFFICIENT_DATA" ), tr( "MULTIEDGES_ERROR" ), QMessageBox::Ok );
692         return false;
693       }
694     }
695
696     QTableItem* anItem = aTable->item( i, 0 );
697     if ( myAddWidgets.contains( anItem ) && !myAddWidgets[ anItem ]->IsValid() )
698       return false;
699   }
700
701   return true;
702 }
703
704 //=======================================================================
705 // name    : SMESHGUI_FilterTable::SetValidity
706 // Purpose : Set validity of the table
707 //=======================================================================
708 void SMESHGUI_FilterTable::SetValidity( const bool isValid )
709 {
710   myIsValid = isValid;
711 }
712
713 //=======================================================================
714 // name    : SMESHGUI_FilterTable::GetType
715 // Purpose : Get current entity type
716 //=======================================================================
717 int SMESHGUI_FilterTable::GetType() const
718 {
719   return myEntityType;
720 }
721
722 //=======================================================================
723 // name    : SMESHGUI_FilterTable::SetType
724 // Purpose : Set current entity type
725 //=======================================================================
726 void SMESHGUI_FilterTable::SetType( const int type )
727 {
728   myEntityTypeGrp->setButton( type );
729   onEntityType( type );
730 }
731
732 //=======================================================================
733 // name    : SMESHGUI_FilterTable::RestorePreviousEntityType
734 // Purpose : Restore previous entity type
735 //=======================================================================
736 void SMESHGUI_FilterTable::RestorePreviousEntityType()
737 {
738   SetType( myEntityType );
739 }
740
741 //=======================================================================
742 // name    : SMESHGUI_FilterTable::GetCriterionType
743 // Purpose : Get type of criterion from specified row ( corresponding enums in h-file )
744 //=======================================================================
745 int SMESHGUI_FilterTable::GetCriterionType( const int theRow, const int theType ) const
746 {
747   int aType = theType == -1 ? GetType() : theType;
748   Table* aTable = myTables[ aType ];
749   ComboItem* anItem = (ComboItem*)aTable->item( theRow, 0 );
750   return anItem != 0 ? anItem->GetValue() : FT_Undefined;
751 }
752
753 //=======================================================================
754 // name    : SMESHGUI_FilterTable::GetCriterion
755 // Purpose : Get parameters of criterion from specified row
756 //=======================================================================
757 void SMESHGUI_FilterTable::GetCriterion( const int                 theRow,
758                                          SMESH::Filter::Criterion& theCriterion,
759                                          const int                 theEntityType ) const
760 {
761   int aType = theEntityType == -1 ? GetType() : theEntityType;
762   Table* aTable = myTables[ aType ];
763   
764   theCriterion.Type = ( (ComboItem*)aTable->item( theRow, 0 ) )->GetValue();
765   theCriterion.UnaryOp = ( (QCheckTableItem*)aTable->item( theRow, 3 ) )->isChecked() ? FT_LogicalNOT : FT_Undefined;
766   theCriterion.BinaryOp = theRow != aTable->numRows() - 1 ?
767     ( (ComboItem*)aTable->item( theRow, 4 ) )->GetValue() : FT_Undefined;
768   theCriterion.TypeOfElement = (ElementType)aType;
769
770   int aCriterionType = GetCriterionType( theRow, aType );
771
772   if ( aCriterionType != FT_RangeOfIds &&
773        aCriterionType != FT_BelongToGeom &&
774        aCriterionType != FT_BelongToPlane &&
775        aCriterionType != FT_BelongToCylinder )
776   {
777     theCriterion.Compare = ( (ComboItem*)aTable->item( theRow, 1 ) )->GetValue();
778     theCriterion.Threshold = aTable->item( theRow, 2 )->text().toDouble();
779   }
780   else
781     theCriterion.ThresholdStr = aTable->text( theRow, 2 ).latin1();
782
783   QTableItem* anItem = aTable->item( theRow, 0 );
784   if ( myAddWidgets.contains( anItem ) )
785     theCriterion.Tolerance = myAddWidgets[ anItem ]->GetDouble( AdditionalWidget::Tolerance );
786 }
787
788 //=======================================================================
789 // name    : SMESHGUI_FilterTable::SetCriterion
790 // Purpose : Set parameters of criterion of specified row
791 //=======================================================================
792 void SMESHGUI_FilterTable::SetCriterion( const int                       theRow,
793                                          const SMESH::Filter::Criterion& theCriterion,
794                                          const int                       theEntityType )
795 {
796   int aType = theEntityType == -1 ? GetType() : theEntityType;
797
798   Table* aTable = myTables[ aType ];
799
800   if ( theRow > aTable->numRows() - 1 )
801     return;
802
803   ( (ComboItem*)aTable->item( theRow, 0 ) )->SetValue( theCriterion.Type );
804   onCriterionChanged( theRow, 0, aType );
805   ( (ComboItem*)aTable->item( theRow, 1 ) )->SetValue( theCriterion.Compare );
806   ( (QCheckTableItem*)aTable->item( theRow, 3 ) )->setChecked( theCriterion.UnaryOp == FT_LogicalNOT );
807
808   if ( theCriterion.BinaryOp != FT_Undefined )
809   {
810     if ( !aTable->IsEditable( theRow, 4 ) )
811       aTable->setItem( theRow, 4, getBinaryItem( aTable ) );
812     ( (ComboItem*)aTable->item( theRow, 4 ) )->SetValue( theCriterion.BinaryOp );
813   }
814   else
815     aTable->SetEditable( false, theRow, 4 );
816
817   if ( theCriterion.Type != FT_RangeOfIds &&
818        theCriterion.Type != FT_BelongToGeom &&
819        theCriterion.Type != FT_BelongToPlane &&
820        theCriterion.Type != FT_BelongToCylinder )
821     aTable->setText( theRow, 2, QString( "%1" ).arg( theCriterion.Threshold, 0, 'g', 15 ) );
822   else
823     aTable->setText( theRow, 2, QString( theCriterion.ThresholdStr ) );
824
825   if ( theCriterion.Compare == FT_EqualTo ||
826        theCriterion.Type    == FT_BelongToPlane ||
827        theCriterion.Type    == FT_BelongToCylinder )
828   {
829     QTableItem* anItem = aTable->item( theRow, 0 );
830     if ( !myAddWidgets.contains( anItem ) )
831     {
832       myAddWidgets[ anItem ] = new AdditionalWidget( myWgStack );
833       myWgStack->addWidget( myAddWidgets[ anItem ] );
834     }
835     myAddWidgets[ anItem ]->SetDouble( AdditionalWidget::Tolerance, theCriterion.Tolerance );
836   }
837
838   emit CretarionChanged( theRow, aType );
839
840 }
841
842 //=======================================================================
843 // name    : SMESHGUI_FilterTable::Update
844 // Purpose : Update table
845 //=======================================================================
846 void SMESHGUI_FilterTable::Update()
847 {
848   Table* aTable = myTables[ GetType() ];
849   int aCurrRow = aTable->currentRow();
850   int numRows = aTable->numRows();
851   if ( ( aCurrRow < 0 || aCurrRow >= numRows ) && numRows > 0 )
852     aTable->setCurrentCell( 0, 0 );
853   updateAdditionalWidget();
854 }
855
856 //=======================================================================
857 // name    : SMESHGUI_FilterTable::AddCriterion
858 // Purpose : Add criterion with parameters
859 //=======================================================================
860 void SMESHGUI_FilterTable::AddCriterion( const SMESH::Filter::Criterion& theCriterion,
861                                          const int                       theEntityType )
862 {
863   int aType = theEntityType == -1 ? GetType() : theEntityType;
864   Table* aTable = myTables[ aType ];
865   addRow( aTable, aType );
866   SetCriterion( aTable->numRows() - 1, theCriterion );
867 }
868
869 //=======================================================================
870 // name    : SMESHGUI_FilterTable::NumRows
871 // Purpose : Get number of criterions of current type
872 //=======================================================================
873 int SMESHGUI_FilterTable::NumRows( const int theEntityType ) const
874 {
875   return myTables[ theEntityType == -1 ? GetType() : theEntityType ]->numRows();
876 }
877
878 //=======================================================================
879 // name    : SMESHGUI_FilterTable::Clear
880 // Purpose : Clear current table
881 //=======================================================================
882 void SMESHGUI_FilterTable::Clear( const int theType )
883 {
884   int aType = theType == -1 ? GetType() : theType;
885   QTable* aTable = myTables[ aType ];
886
887   if ( aTable->numRows() == 0 )
888     return;
889
890   while ( aTable->numRows() > 0 )
891   {
892     removeAdditionalWidget( aTable, 0 );
893     aTable->removeRow( 0 );
894   }
895
896   updateBtnState();
897 }
898
899 //=======================================================================
900 // name    : SMESHGUI_FilterTable::onAddBtn
901 // Purpose : SLOT. Called then "Add" button pressed.
902 //           Adds new string to table
903 //=======================================================================
904 void SMESHGUI_FilterTable::onAddBtn()
905 {
906   int aType = GetType();
907   addRow( myTables[ aType ], aType );
908
909   Table* aTable = myTables[ aType ];
910   Update();
911 }
912
913 //=======================================================================
914 // name    : SMESHGUI_FilterTable::onInsertBtn
915 // Purpose : SLOT. Called then "Insert" button pressed.
916 //           Inserts new string before current one
917 //=======================================================================
918 void SMESHGUI_FilterTable::onInsertBtn()
919 {
920   addRow( myTables[ GetType() ], GetType(), false );
921 }
922
923 //=======================================================================
924 // name    : SMESHGUI_FilterTable::onRemoveBtn
925 // Purpose : SLOT. Called then "Remove" button pressed.
926 //           Removes current string from table
927 //=======================================================================
928 void SMESHGUI_FilterTable::onRemoveBtn()
929 {
930   Table* aTable = myTables[ GetType() ];
931
932   if ( aTable->numRows() == 0 )
933     return;
934
935   QMemArray<int> aRows;
936   for ( int i = 0, n = aTable->numRows(); i < n; i++ )
937   {
938     if ( aTable->isRowSelected( i ) )
939     {
940       aRows.resize( aRows.size() + 1 );
941       aRows[ aRows.size() - 1 ] = i;
942       removeAdditionalWidget( aTable, i );
943     }
944   }
945
946   aTable->removeRows( aRows );
947
948   // remove control of binary logical operation from last row
949   if ( aTable->numRows() > 0 )
950     aTable->SetEditable( false, aTable->numRows() - 1, 4 );
951
952   updateBtnState();
953 }
954
955 //=======================================================================
956 // name    : SMESHGUI_FilterTable::updateAdditionalWidget
957 // Purpose : Enable/Disable widget with additonal parameters
958 //=======================================================================
959 void SMESHGUI_FilterTable::updateAdditionalWidget()
960 {
961   Table* aTable = myTables[ GetType() ];
962   int aRow = aTable->currentRow();
963   if ( aRow < 0 || aRow >= aTable->numRows() )
964   {
965     myWgStack->setEnabled( false );
966     return;
967   }
968
969   ComboItem* anItem = ( (ComboItem*)aTable->item( aRow, 0 ) );
970   bool toEnable = ( (ComboItem*)aTable->item( aRow, 1 ) )->GetValue() == FT_EqualTo &&
971                   GetCriterionType( aRow ) != FT_BelongToGeom &&
972                   GetCriterionType( aRow ) != FT_RangeOfIds &&
973                   GetCriterionType( aRow ) != FT_FreeEdges;
974   if ( !myAddWidgets.contains( anItem ) )
975   {
976     myAddWidgets[ anItem ] = new AdditionalWidget( myWgStack );
977     myWgStack->addWidget( myAddWidgets[ anItem ] );
978   }
979
980   myWgStack->raiseWidget( myWgStack->id( myAddWidgets[ anItem ] ) );
981   myWgStack->setEnabled( toEnable );
982 }
983
984 //=======================================================================
985 // name    : SMESHGUI_FilterTable::removeAdditionalWidget
986 // Purpose : Remove widgets containing additional parameters from widget
987 //           stack and internal map
988 //=======================================================================
989 void SMESHGUI_FilterTable::removeAdditionalWidget( QTable* theTable, const int theRow )
990 {
991   QTableItem* anItem = theTable->item( theRow, 0 );
992   if ( myAddWidgets.contains( anItem ) )
993   {
994     myWgStack->removeWidget( myAddWidgets[ anItem ] );
995     myAddWidgets[ anItem ]->reparent( 0, QPoint() );
996     delete myAddWidgets[ anItem ];
997     myAddWidgets.remove( anItem );
998   }
999 }
1000
1001 //=======================================================================
1002 // name    : SMESHGUI_FilterTable::onClearBtn
1003 // Purpose : SLOT. Called then "Clear" button pressed.
1004 //           Removes all strings from table
1005 //=======================================================================
1006 void SMESHGUI_FilterTable::onClearBtn()
1007 {
1008   QTable* aTable = myTables[ GetType() ];
1009
1010   if ( aTable->numRows() == 0 )
1011     return;
1012
1013   while ( aTable->numRows() > 0 )
1014   {
1015     removeAdditionalWidget( aTable, 0 );
1016     aTable->removeRow( 0 );
1017   }
1018
1019   updateBtnState();
1020 }
1021
1022 //=======================================================================
1023 // name    : SMESHGUI_FilterTable::onCurrentChanged()
1024 // Purpose : SLOT. Called when current cell changed
1025 //=======================================================================
1026 void SMESHGUI_FilterTable::onCurrentChanged( int theRow, int theCol )
1027 {
1028   updateAdditionalWidget();
1029   emit CurrentChanged( theRow, theCol );
1030 }
1031
1032 //=======================================================================
1033 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1034 // Purpose : Provides reaction on change of criterion
1035 //=======================================================================
1036 void SMESHGUI_FilterTable::onCriterionChanged( const int row, const int col, const int entityType )
1037 {
1038   int aType = entityType == -1 ? GetType() : entityType;
1039   Table* aTable = myTables[ aType ];
1040   ComboItem* aCompareItem = (ComboItem*)aTable->item( row, 1 );
1041
1042   int aCriterionType = GetCriterionType( row );
1043
1044   if ( aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
1045        aType == SMESH::FACE && aCriterionType == SMESH::FT_FreeEdges )
1046   {
1047     if ( aCompareItem->count() > 0 )
1048       aCompareItem->setStringList( QStringList() );
1049     aTable->SetEditable( false, row, 2 );
1050   }
1051   else if ( aCriterionType == SMESH::FT_RangeOfIds ||
1052             aCriterionType == SMESH::FT_BelongToGeom ||
1053             aCriterionType == SMESH::FT_BelongToPlane ||
1054             aCriterionType == SMESH::FT_BelongToCylinder )
1055   {
1056     QMap<int, QString> aMap;
1057     aMap[ FT_EqualTo ] = tr( "EQUAL_TO" );
1058     aCompareItem->setStringList( aMap );
1059     if ( !aTable->IsEditable( row, 2 ) )
1060       aTable->SetEditable( true, row, 2 );
1061   }
1062   else
1063   {
1064     if ( aCompareItem->count() != 3 )
1065     {
1066       aCompareItem->setStringList( QStringList() );
1067       aCompareItem->setStringList( getCompare() );
1068     }
1069
1070     QString aText = aTable->text( row, 2 );
1071     bool isOk = false;
1072     aText.toDouble( &isOk );
1073     aTable->setText( row, 2, isOk ? aText : QString("") );
1074     if ( !aTable->IsEditable( row, 2 ) )
1075       aTable->SetEditable( true, row, 2 );
1076   }
1077
1078   updateAdditionalWidget();
1079   
1080   emit CretarionChanged( row, entityType );
1081 }
1082
1083 //=======================================================================
1084 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1085 // Purpose : SLOT. Called then contents of table changed
1086 //           Provides reaction on change of criterion
1087 //=======================================================================
1088 void SMESHGUI_FilterTable::onCriterionChanged( int row, int col )
1089 {
1090   onCriterionChanged( row, col, -1 );
1091 }
1092
1093 //=======================================================================
1094 // name    : SMESHGUI_FilterTable::getFirstSelectedRow
1095 // Purpose : Get first selected row
1096 //=======================================================================
1097 int SMESHGUI_FilterTable::getFirstSelectedRow() const
1098 {
1099   QTable* aTable = myTables[ GetType() ];
1100   for ( int i = 0, n = aTable->numRows(); i < n; i++ )
1101     if ( aTable->isRowSelected( i ) )
1102       return i;
1103
1104   int aRow = aTable->currentRow();
1105   return aRow >= 0 && aRow < aTable->numRows() ? aRow : -1;
1106 }
1107
1108 //=======================================================================
1109 // name    : SMESHGUI_FilterTable::addRow
1110 // Purpose : Add row at the end of table
1111 //=======================================================================
1112 void SMESHGUI_FilterTable::addRow( Table* theTable, const int theType, const bool toTheEnd )
1113 {
1114   int aCurrRow = 0;
1115   int aSelectedRow = getFirstSelectedRow();
1116   int aCurrCol = theTable->currentColumn();
1117
1118   if ( toTheEnd || aSelectedRow == -1 )
1119   {
1120     theTable->insertRows( theTable->numRows() );
1121     aCurrRow = theTable->numRows() - 1;
1122   }
1123   else
1124   {
1125     theTable->insertRows( aSelectedRow );
1126     aCurrRow = aSelectedRow;
1127   }
1128
1129   // Criteria
1130   theTable->setItem( aCurrRow, 0, getCriterionItem( theTable, theType ) );
1131
1132   // Compare
1133   theTable->setItem( aCurrRow, 1, getCompareItem( theTable ) );
1134
1135   // Threshold
1136   //theTable->setItem( aCurrRow, 2, new QTableItem( theTable ) );  
1137
1138   //Logical operation NOT
1139   theTable->setItem( aCurrRow, 3, getUnaryItem( theTable ) );
1140   
1141   // Logical binary operation for previous value
1142   int anAddBinOpStr = -1;
1143   if ( aCurrRow == theTable->numRows() - 1 )
1144     anAddBinOpStr = aCurrRow - 1;
1145   else if ( aCurrRow >= 0  )
1146     anAddBinOpStr = aCurrRow;
1147   
1148   if ( theTable->item( aCurrRow, 4 ) == 0 ||
1149        theTable->item( aCurrRow, 4 )->rtti() != 1 )
1150   {
1151     
1152
1153     if ( anAddBinOpStr >= 0 &&
1154          ( theTable->item( anAddBinOpStr, 4 ) == 0 ||
1155            theTable->item( anAddBinOpStr, 4 )->rtti() != 1 ) )
1156       theTable->setItem( anAddBinOpStr, 4, getBinaryItem( theTable ) );
1157   }
1158   
1159   theTable->SetEditable( false, theTable->numRows() - 1, 4 );
1160
1161   if ( aCurrRow >=0 && aCurrRow < theTable->numRows() &&
1162        aCurrCol >=0 && aCurrCol < theTable->numRows() )
1163   theTable->setCurrentCell( aCurrRow, aCurrCol );
1164
1165   onCriterionChanged( aCurrRow, 0 );
1166
1167   updateBtnState();
1168 }
1169
1170 //=======================================================================
1171 // name    : SMESHGUI_FilterTable::getCriterionItem
1172 // Purpose : Get combo table item for criteria of specified type
1173 //=======================================================================
1174 QTableItem* SMESHGUI_FilterTable::getCriterionItem( QTable* theParent , const int theType )
1175 {
1176   return new ComboItem( theParent, getCriteria( theType ) );
1177 }
1178
1179 //=======================================================================
1180 // name    : SMESHGUI_FilterTable::getCompareItem
1181 // Purpose : Get combo table item for operation of comparision
1182 //=======================================================================
1183 QTableItem* SMESHGUI_FilterTable::getCompareItem( QTable* theParent )
1184 {
1185   return new ComboItem( theParent, getCompare() );
1186 }
1187
1188 //=======================================================================
1189 // name    : SMESHGUI_FilterTable::getBinaryItem
1190 // Purpose :
1191 //=======================================================================
1192 QTableItem* SMESHGUI_FilterTable::getBinaryItem( QTable* theParent )
1193 {
1194   static QMap<int, QString> aMap;
1195   if ( aMap.isEmpty() )
1196   {
1197     aMap[ SMESH::FT_LogicalAND ] = tr( "AND" );
1198     aMap[ SMESH::FT_LogicalOR  ] = tr( "OR" );
1199   }
1200
1201   return new ComboItem( theParent, aMap );
1202 }
1203
1204 //=======================================================================
1205 // name    : SMESHGUI_FilterTable::getUnaryItem
1206 // Purpose : Get check table item
1207 //=======================================================================
1208 QTableItem* SMESHGUI_FilterTable::getUnaryItem( QTable* theParent )
1209 {
1210   return new QCheckTableItem( theParent, tr( "NOT" ) );
1211 }
1212
1213 //=======================================================================
1214 // name    : SMESHGUI_FilterTable::getSupportedTypes
1215 // Purpose : Get all supported type
1216 //=======================================================================
1217 const QMap<int, QString>& SMESHGUI_FilterTable::getSupportedTypes() const
1218 {
1219   static QMap<int, QString> aTypes;
1220   if ( aTypes.isEmpty() )
1221   {
1222     aTypes[ SMESH::NODE   ] = tr( "NODES" );
1223     aTypes[ SMESH::EDGE   ] = tr( "EDGES" );
1224     aTypes[ SMESH::FACE   ] = tr( "FACES" );
1225     aTypes[ SMESH::VOLUME ] = tr( "VOLUMES" );
1226   }
1227
1228   return aTypes;
1229 }
1230
1231 //=======================================================================
1232 // name    : SMESHGUI_FilterTable::getCriteria
1233 // Purpose : Get criteria for specified type
1234 //=======================================================================
1235 const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria( const int theType ) const
1236 {
1237   if ( theType == SMESH::NODE )
1238   {
1239     static QMap<int, QString> aCriteria;
1240     if ( aCriteria.isEmpty() )
1241     {
1242       aCriteria[ SMESH::FT_RangeOfIds       ] = tr( "RANGE_OF_IDS" );
1243       aCriteria[ SMESH::FT_BelongToGeom     ] = tr( "BELONG_TO_GEOM" );
1244       aCriteria[ SMESH::FT_BelongToPlane    ] = tr( "BELONG_TO_PLANE" );
1245       aCriteria[ SMESH::FT_BelongToCylinder ] = tr( "BELONG_TO_CYLINDER" );
1246     }
1247     return aCriteria;
1248   }
1249   else if ( theType == SMESH::EDGE )
1250   {
1251     static QMap<int, QString> aCriteria;
1252     if ( aCriteria.isEmpty() )
1253     {
1254       aCriteria[ SMESH::FT_FreeBorders      ] = tr( "FREE_BORDERS" );
1255       aCriteria[ SMESH::FT_MultiConnection  ] = tr( "MULTI_BORDERS" );
1256       aCriteria[ SMESH::FT_Length           ] = tr( "LENGTH" );
1257       aCriteria[ SMESH::FT_RangeOfIds       ] = tr( "RANGE_OF_IDS" );
1258       aCriteria[ SMESH::FT_BelongToGeom     ] = tr( "BELONG_TO_GEOM" );
1259       aCriteria[ SMESH::FT_BelongToPlane    ] = tr( "BELONG_TO_PLANE" );
1260       aCriteria[ SMESH::FT_BelongToCylinder ] = tr( "BELONG_TO_CYLINDER" );
1261     }
1262     return aCriteria;
1263   }
1264   else if ( theType == SMESH::FACE )
1265   {
1266     static QMap<int, QString> aCriteria;
1267     if ( aCriteria.isEmpty() )
1268     {
1269       aCriteria[ SMESH::FT_AspectRatio      ] = tr( "ASPECT_RATIO" );
1270       aCriteria[ SMESH::FT_Warping          ] = tr( "WARPING" );
1271       aCriteria[ SMESH::FT_MinimumAngle     ] = tr( "MINIMUM_ANGLE" );
1272       aCriteria[ SMESH::FT_Taper            ] = tr( "TAPER" );
1273       aCriteria[ SMESH::FT_Skew             ] = tr( "SKEW" );
1274       aCriteria[ SMESH::FT_Area             ] = tr( "AREA" );
1275       aCriteria[ SMESH::FT_FreeEdges        ] = tr( "FREE_EDGES" );
1276       aCriteria[ SMESH::FT_RangeOfIds       ] = tr( "RANGE_OF_IDS" );
1277       aCriteria[ SMESH::FT_BelongToGeom     ] = tr( "BELONG_TO_GEOM" );
1278       aCriteria[ SMESH::FT_BelongToPlane    ] = tr( "BELONG_TO_PLANE" );
1279       aCriteria[ SMESH::FT_BelongToCylinder ] = tr( "BELONG_TO_CYLINDER" );
1280       aCriteria[ SMESH::FT_Length2D         ] = tr( "LENGTH2D" );
1281     }
1282     return aCriteria;
1283   }
1284   else if ( theType == SMESH::VOLUME )
1285   {
1286     static QMap<int, QString> aCriteria;
1287     if ( aCriteria.isEmpty() )
1288     {
1289       aCriteria[ SMESH::FT_RangeOfIds   ] = tr( "RANGE_OF_IDS" );
1290       aCriteria[ SMESH::FT_BelongToGeom ] = tr( "BELONG_TO_GEOM" );
1291     }
1292     return aCriteria;
1293   }
1294   else
1295   {
1296     static QMap<int, QString> aCriteria;
1297     return aCriteria;
1298   }
1299 }
1300
1301
1302 //=======================================================================
1303 // name    : SMESHGUI_FilterTable::getCompare
1304 // Purpose : Get operation of comparison
1305 //=======================================================================
1306 const QMap<int, QString>& SMESHGUI_FilterTable::getCompare() const
1307 {
1308   static QMap<int, QString> aMap;
1309
1310   if ( aMap.isEmpty() )
1311   {
1312     aMap[ SMESH::FT_LessThan ] = tr( "LESS_THAN" );
1313     aMap[ SMESH::FT_MoreThan ] = tr( "MORE_THAN" );
1314     aMap[ SMESH::FT_EqualTo  ] = tr( "EQUAL_TO"  );
1315   }
1316
1317   return aMap;
1318 }
1319
1320 //=======================================================================
1321 // name    : SMESHGUI_FilterTable::createTable
1322 // Purpose : Create table
1323 //=======================================================================
1324 SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable( QWidget*  theParent,
1325                                                                 const int theType )
1326 {
1327   // create table
1328   Table* aTable= new Table( 0, 5, theParent );
1329
1330   QHeader* aHeaders = aTable->horizontalHeader();
1331
1332   QFontMetrics aMetrics( aHeaders->font() );
1333
1334   // append spaces to the header of criteria in order to
1335   // provide visibility of criterion inside comboboxes
1336   static int aMaxLenCr = 0;
1337
1338   if ( aMaxLenCr == 0 )
1339   {
1340     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
1341     QMap<int, QString>::const_iterator anIter;
1342     for ( anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter )
1343       aMaxLenCr = Max( maxLength( getCriteria( anIter.key() ), aMetrics ), aMaxLenCr );
1344   }
1345
1346   static int aLenCr = abs(  aMaxLenCr -
1347                             aMetrics.width( tr( "CRITERION" ) ) ) / aMetrics.width( ' ' ) + 5;
1348
1349   static int aLenCo = abs(  maxLength( getCompare(), aMetrics ) -
1350                             aMetrics.width( tr( "COMPARE" ) ) ) / aMetrics.width( ' ' ) + 5;
1351
1352   QString aCrStr;
1353   aCrStr.fill( ' ', aLenCr );
1354   QString aCoStr;
1355   aCoStr.fill( ' ', 10 );
1356
1357   aHeaders->setLabel( 0, tr( "CRITERION" ) + aCrStr );
1358   aHeaders->setLabel( 1, tr( "COMPARE" ) + aCoStr );
1359   aHeaders->setLabel( 2, tr( "THRESHOLD_VALUE" ) );
1360   aHeaders->setLabel( 3, tr( "UNARY" ) );
1361   aHeaders->setLabel( 4, tr( "BINARY" ) + "  " );
1362
1363   // set geometry of the table
1364   for ( int i = 0; i <= 4; i++ )
1365     aTable->adjustColumn( i );
1366
1367   aTable->updateGeometry();
1368   QSize aSize = aTable->sizeHint();
1369   int aWidth = aSize.width();
1370   aTable->setMinimumSize( QSize( aWidth, aWidth / 2 ) );
1371   aTable->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding) );
1372
1373   connect( aTable, SIGNAL( valueChanged( int, int ) ),
1374            this,   SLOT( onCriterionChanged( int, int ) ) );
1375
1376   connect( aTable, SIGNAL( currentChanged( int, int ) ),
1377            this,   SLOT( onCurrentChanged( int, int ) ) );
1378
1379   return aTable;
1380 }
1381
1382 //=======================================================================
1383 // name    : SMESHGUI_FilterTable::updateBtnState
1384 // Purpose : Update button state
1385 //=======================================================================
1386 void SMESHGUI_FilterTable::updateBtnState()
1387 {
1388   myRemoveBtn->setEnabled( myTables[ GetType() ]->numRows() > 0 );
1389   myClearBtn->setEnabled( myTables[ GetType() ]->numRows() > 0 );
1390 }
1391
1392 //=======================================================================
1393 // name    : SMESHGUI_FilterTable::SetEditable
1394 // Purpose : Set read only flag for tables. Show/hide buttons for work with rows
1395 //=======================================================================
1396 void SMESHGUI_FilterTable::SetEditable( const bool isEditable )
1397 {
1398   TableMap::iterator anIter;
1399   for ( anIter = myTables.begin(); anIter != myTables.end(); ++anIter )
1400   {
1401     anIter.data()->setReadOnly( !isEditable );
1402
1403     if ( isEditable )
1404     {
1405       myAddBtn->show();
1406       myInsertBtn->show();
1407       myRemoveBtn->show();
1408       myClearBtn->show();
1409     }
1410     else
1411     {
1412       myAddBtn->hide();
1413       myInsertBtn->hide();
1414       myRemoveBtn->hide();
1415       myClearBtn->hide();
1416     }
1417   }
1418
1419   QMap<QTableItem*, AdditionalWidget*>::iterator anIter2;
1420   for ( anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2 )
1421     anIter2.data()->SetEditable( isEditable );
1422 }
1423
1424 //=======================================================================
1425 // name    : SMESHGUI_FilterTable::SetEnabled
1426 // Purpose : Enable/Disable table. Switching type of elements already enabled
1427 //=======================================================================
1428 void SMESHGUI_FilterTable::SetEnabled( const bool isEnabled )
1429 {
1430   myAddBtn->setEnabled( isEnabled );
1431   myInsertBtn->setEnabled( isEnabled );
1432   myRemoveBtn->setEnabled( isEnabled );
1433   myClearBtn->setEnabled( isEnabled );
1434
1435   if ( isEnabled )
1436     updateBtnState();
1437   
1438   QMap<QTableItem*, AdditionalWidget*>::iterator anIter2;
1439   for ( anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2 )
1440     anIter2.data()->setEnabled( isEnabled );
1441 }
1442
1443 //=======================================================================
1444 // name    : SMESHGUI_FilterTable::IsEditable
1445 // Purpose : Verify whether table is editable
1446 //=======================================================================
1447 bool SMESHGUI_FilterTable::IsEditable() const
1448 {
1449   return !myTables[ GetType() ]->isReadOnly();
1450 }
1451
1452 //=======================================================================
1453 // name    : SMESHGUI_FilterTable::SetLibsEnabled
1454 // Purpose : Show/hide buttons for work with libraries
1455 //=======================================================================
1456 void SMESHGUI_FilterTable::SetLibsEnabled( const bool isEnabled )
1457 {
1458   if ( isEnabled )
1459   {
1460     myCopyFromBtn->show();
1461     myAddToBtn->show();
1462   }
1463   else
1464   {
1465     myCopyFromBtn->hide();
1466     myAddToBtn->hide();
1467   }
1468 }
1469
1470 //=======================================================================
1471 // name    : SMESHGUI_FilterTable::onCopyFromBtn
1472 // Purpose : SLOT. Called the "Copy from ..." button clicked
1473 //           Display filter library dialog
1474 //=======================================================================
1475 void SMESHGUI_FilterTable::onCopyFromBtn()
1476 {
1477   if ( myLibDlg == 0 )
1478     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1479       this, GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM );
1480   else
1481     myLibDlg->Init( GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM );
1482
1483   if ( myLibDlg->exec() == QDialog::Accepted )
1484   {
1485     Copy( myLibDlg->GetTable() );
1486     Update();
1487   }
1488 }
1489
1490 //=======================================================================
1491 // name    : SMESHGUI_FilterTable::onAddToBtn
1492 // Purpose : SLOT. Called the "Add to ..." button clicked
1493 //           Display filter library dialog
1494 //=======================================================================
1495 void SMESHGUI_FilterTable::onAddToBtn()
1496 {
1497   if ( !IsValid( true ) )
1498     return;
1499   if ( myLibDlg == 0 )
1500     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1501       this, GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO );
1502   else
1503     myLibDlg->Init( GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO );
1504
1505   myLibDlg->SetTable( this );
1506     
1507   myLibDlg->exec();
1508 }                                          
1509
1510 //=======================================================================
1511 // name    : SMESHGUI_FilterTable::Copy
1512 // Purpose : Initialise table with values of other table
1513 //=======================================================================
1514 void SMESHGUI_FilterTable::Copy( const SMESHGUI_FilterTable* theTable )
1515 {
1516   Clear();
1517
1518   for ( int i = 0, n = theTable->NumRows(); i < n; i++ )
1519   {
1520     SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion();
1521     theTable->GetCriterion( i, aCriterion );
1522     AddCriterion( aCriterion );
1523   }
1524 }
1525
1526 //=======================================================================
1527 // name    : SMESHGUI_FilterTable::CurrentCell
1528 // Purpose : Returns current cell
1529 //=======================================================================
1530 bool SMESHGUI_FilterTable::CurrentCell( int& theRow, int& theCol ) const
1531 {
1532   theRow = myTables[ GetType() ]->currentRow();
1533   theCol = myTables[ GetType() ]->currentColumn();
1534   return theRow >= 0 && theCol >= 0;
1535 }
1536
1537 //=======================================================================
1538 // name    : SMESHGUI_FilterTable::SetText
1539 // Purpose : Set text and internal value in cell of threshold value 
1540 //=======================================================================
1541 void SMESHGUI_FilterTable::SetThreshold( const int      theRow,
1542                                          const QString& theText,
1543                                          const int      theEntityType )
1544 {
1545   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1546   aTable->setText( theRow, 2, theText );
1547 }
1548
1549 //=======================================================================
1550 // name    : SMESHGUI_FilterTable::SetText
1551 // Purpose : Get text and internal value from cell of threshold value
1552 //=======================================================================
1553 bool SMESHGUI_FilterTable::GetThreshold( const int      theRow,
1554                                          QString&       theText,
1555                                          const int      theEntityType )
1556 {
1557   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1558   QTableItem* anItem = aTable->item( theRow, 2 );
1559   if ( anItem != 0 )
1560   {
1561     theText = anItem->text();
1562     return true;    
1563   }
1564   else
1565    return false;
1566 }
1567
1568 /*                                                                                                                                                 
1569   Class       : SMESHGUI_FilterDlg
1570   Description : Dialog to specify filters for VTK viewer
1571 */
1572
1573
1574 //=======================================================================
1575 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
1576 // Purpose : Constructor
1577 //=======================================================================
1578 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget*               theParent,
1579                                         const QValueList<int>& theTypes,
1580                                         const char*            theName )
1581 : QDialog( theParent, theName, false,
1582            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
1583 {
1584   construct( theTypes );
1585 }
1586
1587 //=======================================================================
1588 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
1589 // Purpose : Constructor
1590 //=======================================================================
1591 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( QWidget*    theParent,
1592                                         const int   theType,
1593                                         const char* theName )
1594 : QDialog( theParent, theName, false,
1595            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu )
1596 {
1597   QValueList<int> aTypes;
1598   aTypes.append( theType );
1599   construct( aTypes );
1600 }
1601
1602 //=======================================================================
1603 // name    : SMESHGUI_FilterDlg::construct
1604 // Purpose : Construct dialog ( called by constructor )
1605 //=======================================================================
1606 void SMESHGUI_FilterDlg::construct( const QValueList<int>& theTypes )
1607 {
1608   myTypes = theTypes;
1609
1610   setCaption( tr( "CAPTION" ) );
1611
1612   QVBoxLayout* aDlgLay = new QVBoxLayout( this, MARGIN, SPACING );
1613
1614   myMainFrame        = createMainFrame  ( this );
1615   QFrame* aBtnFrame  = createButtonFrame( this );
1616
1617   aDlgLay->addWidget( myMainFrame );
1618   aDlgLay->addWidget( aBtnFrame );
1619
1620   aDlgLay->setStretchFactor( myMainFrame, 1 );
1621
1622   Init( myTypes );
1623 }
1624
1625 //=======================================================================
1626 // name    : SMESHGUI_FilterDlg::createMainFrame
1627 // Purpose : Create frame containing dialog's input fields
1628 //=======================================================================
1629 QFrame* SMESHGUI_FilterDlg::createMainFrame( QWidget* theParent )
1630 {
1631   QGroupBox* aMainFrame = new QGroupBox( 1, Qt::Horizontal, theParent );
1632   aMainFrame->setFrameStyle( QFrame::NoFrame );
1633   aMainFrame->setInsideMargin( 0 );
1634
1635   // filter frame
1636
1637   myTable = new SMESHGUI_FilterTable( aMainFrame, myTypes );
1638   myTable->SetLibsEnabled( true );
1639
1640   QFrame* aLine = new QFrame( myTable->GetTableGrp() );
1641   aLine->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1642
1643   mySetInViewer = new QCheckBox( tr( "SET_IN_VIEWER" ), myTable->GetTableGrp() );
1644   mySetInViewer->setChecked( true );
1645
1646   // other controls
1647   mySourceGrp = createSourceGroup( aMainFrame );
1648
1649   connect( myTable, SIGNAL( CretarionChanged( const int, const int ) ),
1650                     SLOT( onCriterionChanged( const int, const int ) ) );
1651
1652   connect( myTable, SIGNAL( CurrentChanged( int, int ) ),
1653                     SLOT( onCurrentChanged( int, int ) ) );                    
1654
1655   return aMainFrame;
1656 }
1657
1658 //=======================================================================
1659 // name    : SMESHGUI_FilterDlg::createSourceFrame
1660 // Purpose : Create frame containing source radio button
1661 //=======================================================================
1662 QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup( QWidget* theParent )
1663 {
1664   QButtonGroup* aGrp = new QButtonGroup( 1, Qt::Vertical, tr( "SOURCE" ), theParent );
1665
1666   QRadioButton* aMeshBtn = new QRadioButton( tr( "MESH" ), aGrp );
1667   QRadioButton* aSelBtn  = new QRadioButton( tr( "SELECTION" ), aGrp );
1668   QRadioButton* aGrpBtn  = new QRadioButton( tr( "CURRENT_GROUP" ), aGrp );
1669
1670   aGrp->insert( aMeshBtn, Mesh );
1671   aGrp->insert( aSelBtn, Selection );
1672   aGrp->insert( aGrpBtn, Dialog );
1673
1674   aGrp->setButton( Selection );
1675
1676   return aGrp;
1677 }
1678
1679 //=======================================================================
1680 // name    : SMESHGUI_FilterDlg::updateMainButtons
1681 // Purpose : Update visibility of main buttons ( OK, Cancel, Close ... )
1682 //=======================================================================
1683 void SMESHGUI_FilterDlg::updateMainButtons()
1684 {
1685   if ( myTypes.count() == 1 )
1686   {
1687     myButtons[ BTN_Cancel ]->show();
1688     myButtons[ BTN_Apply  ]->hide();
1689     myButtons[ BTN_Close  ]->hide();
1690   }
1691   else
1692   {
1693     myButtons[ BTN_Cancel ]->hide();
1694     myButtons[ BTN_Apply  ]->show();
1695     myButtons[ BTN_Close  ]->show();
1696   }
1697
1698 //  updateGeometry();
1699 }
1700
1701 //=======================================================================
1702 // name    : SMESHGUI_FilterDlg::createButtonFrame
1703 // Purpose : Create frame containing buttons
1704 //=======================================================================
1705 QFrame* SMESHGUI_FilterDlg::createButtonFrame( QWidget* theParent )
1706 {
1707   QGroupBox* aGrp = new QGroupBox( 1, Qt::Vertical, theParent );
1708
1709   myButtons[ BTN_OK    ] = new QPushButton( tr( "SMESH_BUT_OK"    ), aGrp );
1710   myButtons[ BTN_Apply ] = new QPushButton( tr( "SMESH_BUT_APPLY" ), aGrp );
1711
1712   QLabel* aLbl = new QLabel( aGrp );
1713   aLbl->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
1714
1715   myButtons[ BTN_Cancel ] = new QPushButton( tr( "SMESH_BUT_CANCEL" ), aGrp );
1716   myButtons[ BTN_Close  ] = new QPushButton( tr( "SMESH_BUT_CLOSE" ), aGrp );
1717
1718   connect( myButtons[ BTN_OK     ], SIGNAL( clicked() ), SLOT( onOk() ) );
1719   connect( myButtons[ BTN_Cancel ], SIGNAL( clicked() ), SLOT( onClose() ) ) ;
1720   connect( myButtons[ BTN_Close  ], SIGNAL( clicked() ), SLOT( onClose() ) ) ;
1721   connect( myButtons[ BTN_Apply  ], SIGNAL( clicked() ), SLOT( onApply() ) );
1722
1723   updateMainButtons();
1724
1725   return aGrp;
1726 }
1727
1728 //=======================================================================
1729 // name    : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
1730 // Purpose : Destructor
1731 //=======================================================================
1732 SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
1733 {
1734 }
1735
1736 //=======================================================================
1737 // name    : SMESHGUI_FilterDlg::Init
1738 // Purpose : Init dialog fields, connect signals and slots, show dialog
1739 //=======================================================================
1740 void SMESHGUI_FilterDlg::Init( const int type )
1741 {
1742   QValueList<int> aTypes;
1743   aTypes.append( type );
1744   Init( aTypes );
1745 }
1746
1747 //=======================================================================
1748 // name    : SMESHGUI_FilterDlg::Init
1749 // Purpose : Init dialog fields, connect signals and slots, show dialog
1750 //=======================================================================
1751 void SMESHGUI_FilterDlg::Init( const QValueList<int>& theTypes )
1752 {
1753   mySourceWg  = 0;
1754   mySelection = 0;
1755   myTypes     = theTypes;
1756   myMesh      = SMESH::SMESH_Mesh::_nil();
1757   myIObjects.Clear();
1758   myIsSelectionChanged = false;
1759
1760   myTable->Init( theTypes );
1761
1762   // set caption
1763   if ( theTypes.count() == 1 )
1764   {
1765     int aType = theTypes.first();
1766     if      ( aType == SMESH::NODE   ) setCaption( tr( "NODES_TLT" ) );
1767     else if ( aType == SMESH::EDGE   ) setCaption( tr( "EDGES_TLT" ) );
1768     else if ( aType == SMESH::FACE   ) setCaption( tr( "FACES_TLT" ) );
1769     else if ( aType == SMESH::VOLUME ) setCaption( tr( "VOLUMES_TLT" ) );
1770   }
1771   else
1772     setCaption( tr( "TLT" ) );
1773
1774   qApp->processEvents();
1775   updateGeometry();
1776   adjustSize();
1777   setEnabled( true );
1778
1779   mySMESHGUI = SMESHGUI::GetSMESHGUI() ;
1780   mySMESHGUI->SetActiveDialogBox( ( QDialog* )this ) ;
1781
1782   connect( mySMESHGUI, SIGNAL( SignalDeactivateActiveDialog() ), SLOT( onDeactivate() ) );
1783   connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), SLOT( onClose() ) );
1784
1785   int x, y ;
1786   mySMESHGUI->DefineDlgPosition( this, x, y );
1787   this->move( x, y );
1788
1789   updateMainButtons();
1790   updateSelection();
1791
1792   // Initialise filter table with values of previous filter
1793   QValueList<int>::const_iterator anIter;
1794   for ( anIter = theTypes.begin(); anIter != theTypes.end(); ++anIter )
1795   {
1796     myTable->Clear( *anIter );
1797     if ( !myFilter[ *anIter ]->_is_nil() )
1798     {
1799       SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
1800       if ( myFilter[ *anIter ]->GetCriteria( aCriteria ) )
1801       {
1802         for ( int i = 0, n = aCriteria->length(); i < n; i++ )
1803           myTable->AddCriterion( aCriteria[ i ], *anIter );
1804       }
1805     }
1806   }
1807
1808   if ( myInsertState.contains( theTypes.first() ) )
1809     mySetInViewer->setChecked( myInsertState[ theTypes.first() ] );
1810   else
1811     mySetInViewer->setChecked( true );
1812   if ( myApplyToState.contains( theTypes.first() ) )
1813     mySourceGrp->setButton( myApplyToState[ theTypes.first() ] );
1814   else
1815     mySourceGrp->setButton( Selection ); 
1816 }
1817
1818 //=======================================================================
1819 // name    : SMESHGUI_FilterDlg::onOk
1820 // Purpose : SLOT called when "Ok" button pressed.
1821 //           Assign filters VTK viewer and close dialog
1822 //=======================================================================
1823 void SMESHGUI_FilterDlg::onOk()
1824 {
1825   if ( onApply() )
1826   {
1827     mySelection->ClearFilters();
1828     disconnect( mySMESHGUI, 0, this, 0 );
1829     disconnect( mySelection, 0, this, 0 );
1830     mySMESHGUI->ResetState() ;
1831     accept();
1832     emit Accepted();
1833   }
1834 }
1835
1836 //=======================================================================
1837 // name    : SMESHGUI_FilterDlg::onClose
1838 // Purpose : SLOT called when "Close" button pressed. Close dialog
1839 //=======================================================================
1840 void SMESHGUI_FilterDlg::onClose()
1841 {
1842   // Restore previously selected object
1843   if ( mySelection )
1844   {
1845     mySelection->ClearFilters();
1846     mySelection->Clear();
1847     SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter( myIObjects );
1848     for ( ; anIter.More(); anIter.Next() )
1849     {
1850       mySelection->AddIObject( anIter.Key() );
1851
1852       TColStd_MapOfInteger aResMap;
1853       const TColStd_IndexedMapOfInteger& anIndMap = anIter.Value();
1854       for ( int i = 1, n = anIndMap.Extent(); i <= n; i++ )
1855         aResMap.Add( anIndMap( i ) );
1856       
1857       mySelection->AddOrRemoveIndex( anIter.Key(), aResMap, false );
1858     }
1859   }
1860
1861   disconnect( mySMESHGUI, 0, this, 0 );
1862   disconnect( mySelection, 0, this, 0 );
1863   mySMESHGUI->ResetState() ;
1864   reject() ;
1865   return ;
1866 }
1867
1868 //=======================================================================
1869 // name    : SMESHGUI_FilterDlg::onDeactivate
1870 // Purpose : SLOT called when dialog must be deativated
1871 //=======================================================================
1872 void SMESHGUI_FilterDlg::onDeactivate()
1873 {
1874   setEnabled( false );
1875 }
1876
1877 //=======================================================================
1878 // name    : SMESHGUI_FilterDlg::enterEvent
1879 // Purpose : Event filter
1880 //=======================================================================
1881 void SMESHGUI_FilterDlg::enterEvent( QEvent* )
1882 {
1883 //  mySMESHGUI->EmitSignalDeactivateDialog();
1884   setEnabled( true );
1885 }
1886
1887
1888 //=================================================================================
1889 // function : closeEvent()
1890 // purpose  :
1891 //=================================================================================
1892 void SMESHGUI_FilterDlg::closeEvent( QCloseEvent* e )
1893 {
1894   onClose() ;
1895 }
1896
1897 //=======================================================================
1898 // name    : SMESHGUI_FilterDlg::getIdsFromWg
1899 // Purpose : Retrieve list of ids from given widget
1900 //=======================================================================
1901 void SMESHGUI_FilterDlg::getIdsFromWg( const QWidget* theWg, QValueList<int>& theRes ) const
1902 {
1903   theRes.clear();
1904   if ( theWg == 0 )
1905     return;
1906
1907   if ( theWg->inherits( "QListBox" ) )
1908   {
1909     QListBox* aListBox = ( QListBox* )theWg;
1910     bool b;
1911     for ( int i = 0, n = aListBox->count(); i < n; i++ )
1912     {
1913       int anId = aListBox->text( i ).toInt( &b );
1914       if ( b )
1915         theRes.append( anId );
1916     }
1917   }
1918   else if ( theWg->inherits( "QLineEdit" ) )
1919   {
1920     QLineEdit* aLineEdit = ( QLineEdit* )theWg;
1921     QString aStr = aLineEdit->text();
1922     QRegExp aRegExp( "(\\d+)" );
1923     bool b;
1924     int aPos = 0;
1925     while ( aPos >= 0 )
1926     {
1927       aPos = aRegExp.search( aStr, aPos );
1928       if ( aPos > -1 )
1929       {
1930         int anId = aRegExp.cap( 1 ).toInt( &b );
1931         if ( b )
1932           theRes.append( anId );
1933         aPos += aRegExp.matchedLength();
1934       }
1935     }
1936   }
1937 }
1938
1939 //=======================================================================
1940 // name    : SMESHGUI_FilterDlg::getSelMode
1941 // Purpose : Get selection mode of specified type
1942 //=======================================================================
1943 Selection_Mode SMESHGUI_FilterDlg::getSelMode( const int theType ) const
1944 {
1945   switch ( theType )
1946   {
1947     case SMESH::NODE   : return NodeSelection;
1948     case SMESH::EDGE   : return EdgeSelection;
1949     case SMESH::FACE   : return FaceSelection;
1950     case SMESH::VOLUME : return VolumeSelection;
1951     default            : return ActorSelection;
1952   }
1953
1954 }
1955
1956 //=======================================================================
1957 // name    : SMESHGUI_FilterDlg::setIdsToWg
1958 // Purpose : Insert identifiers in specified widgets
1959 //=======================================================================
1960 void SMESHGUI_FilterDlg::setIdsToWg( QWidget* theWg, const QValueList<int>& theIds )
1961 {
1962   if ( theWg == 0 )
1963     return;
1964
1965   if ( theWg->inherits( "QListBox" ) )
1966   {
1967     QListBox* aListBox = ( QListBox* )theWg;
1968     aListBox->clear();
1969
1970     QStringList aStrList;
1971     QValueList<int>::const_iterator anIter;
1972     for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
1973       aStrList.append( QString( "%1" ).arg( *anIter ) );
1974
1975     aListBox->insertStringList( aStrList );
1976   }
1977   else if ( theWg->inherits( "QLineEdit" ) )
1978   {
1979     QLineEdit* aLineEdit = ( QLineEdit* )theWg;
1980     QString aStr;
1981     QValueList<int>::const_iterator anIter;
1982
1983     for ( anIter = theIds.begin(); anIter != theIds.end(); ++ anIter )
1984       aStr += QString( "%1 " ).arg( *anIter );
1985
1986     if ( !aStr.isEmpty() )
1987       aStr.remove( aStr.length() - 1, 1 );
1988
1989     aLineEdit->setText( aStr );
1990   }
1991 }
1992
1993 //=======================================================================
1994 // name    : SMESHGUI_FilterDlg::isValid
1995 // Purpose : Verify validity of input data
1996 //=======================================================================
1997 bool SMESHGUI_FilterDlg::isValid() const
1998 {
1999   if ( !myTable->IsValid() )
2000     return false;
2001     
2002   for ( int i = 0, n = myTable->NumRows(); i < n; i++ )
2003   {
2004     int aType = myTable->GetCriterionType( i );
2005     if ( aType == FT_BelongToGeom ||
2006          aType == FT_BelongToPlane ||
2007          aType == FT_BelongToCylinder  )
2008     {
2009       QString aName;
2010       myTable->GetThreshold( i, aName );
2011       
2012       SALOMEDS::Study::ListOfSObject_var aList = SMESHGUI::GetSMESHGUI()->GetActiveStudy()->
2013         getStudyDocument()->FindObjectByName( aName.latin1(), "GEOM" );
2014       if ( aList->length() == 0 )
2015       {
2016         QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2017           tr( "SMESH_INSUFFICIENT_DATA" ), tr( "BAD_SHAPE_NAME" ).arg( aName ), QMessageBox::Ok );
2018         return false;
2019       }
2020
2021       if ( aType == FT_BelongToCylinder || aType == FT_BelongToPlane )
2022       {
2023         GEOM::GEOM_Object_var aGeomObj =
2024           GEOM::GEOM_Object::_narrow( aList[ 0 ]->GetObject() );
2025         if ( !aGeomObj->_is_nil() )
2026         {
2027           TopoDS_Shape aFace;
2028           if ( !GEOMBase::GetShape( aGeomObj, aFace ) ||
2029                aFace.IsNull() ||
2030                aFace.ShapeType() != TopAbs_FACE )
2031           {
2032             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2033               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_FACE" ).arg( aName ), QMessageBox::Ok );
2034             return false;
2035           }
2036
2037           Handle(Geom_Surface) aSurf = BRep_Tool::Surface( TopoDS::Face( aFace ) );
2038           if ( aSurf.IsNull() )
2039           {
2040             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2041               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_FACE" ).arg( aName ), QMessageBox::Ok );
2042             return false;
2043           }
2044
2045           if ( aType == FT_BelongToPlane && !aSurf->IsKind( STANDARD_TYPE( Geom_Plane ) ) )
2046           {
2047             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2048               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_PLANE" ).arg( aName ), QMessageBox::Ok );
2049             return false;
2050           }
2051
2052           if ( aType == FT_BelongToCylinder && !aSurf->IsKind( STANDARD_TYPE( Geom_CylindricalSurface ) ) )
2053           {
2054             QMessageBox::information( SMESHGUI::GetSMESHGUI()->GetDesktop(),
2055               tr( "SMESH_INSUFFICIENT_DATA" ), tr( "SHAPE_IS_NOT_A_CYLINDER" ).arg( aName ), QMessageBox::Ok );
2056             return false;
2057           }
2058         }
2059       }
2060     }
2061   }
2062
2063   return true;
2064 }
2065
2066 //=======================================================================
2067 // name    : SMESHGUI_FilterDlg::SetSourceWg
2068 // Purpose : Set widget of parent dialog containing idsto be filtered if
2069 //           user select corresponding source radio button
2070 //=======================================================================
2071 void SMESHGUI_FilterDlg::SetSourceWg( QWidget* theWg )
2072 {
2073   mySourceWg = theWg;
2074 }
2075
2076 //=======================================================================
2077 // name    : SMESHGUI_FilterDlg::SetGroupIds
2078 // Purpose : Set mesh
2079 //=======================================================================
2080 void SMESHGUI_FilterDlg::SetMesh( SMESH::SMESH_Mesh_ptr theMesh )
2081 {
2082   myMesh = theMesh;
2083 }
2084
2085 //=======================================================================
2086 // name    : SMESHGUI_FilterDlg::SetSelection
2087 // Purpose : Get filtered ids
2088 //=======================================================================
2089 void SMESHGUI_FilterDlg::SetSelection( SALOME_Selection* theSel )
2090 {
2091   if ( mySelection )
2092     disconnect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionDone() ) );
2093     
2094   mySelection = theSel;
2095
2096   if ( mySelection )
2097   {
2098     myIObjects.Clear();
2099     const SALOME_ListIO& anObjs = mySelection->StoredIObjects();
2100     SALOME_ListIteratorOfListIO anIter( anObjs );
2101     for ( ;anIter.More(); anIter.Next() )
2102     {
2103       TColStd_IndexedMapOfInteger aMap;
2104       mySelection->GetIndex( anIter.Value(), aMap );
2105       myIObjects.Bind( anIter.Value(), aMap );
2106     }
2107     
2108     connect( mySelection, SIGNAL( currentSelectionChanged() ), SLOT( onSelectionDone() ) );
2109
2110     updateSelection();
2111   }
2112   else
2113     myIObjects.Clear();
2114 }
2115
2116 //=======================================================================
2117 // name    : SMESHGUI_FilterDlg::onApply
2118 // Purpose : SLOT called when "Apply" button pressed.
2119 //           Assign filters to VTK viewer
2120 //=======================================================================
2121 bool SMESHGUI_FilterDlg::onApply()
2122 {
2123   if ( !isValid() )
2124     return false;
2125
2126   try
2127   {
2128     int aCurrType = myTable->GetType();
2129
2130     if ( !createFilter( aCurrType ) )
2131       return false;
2132
2133     insertFilterInViewer();
2134
2135     if ( !myFilter[ aCurrType ]->GetPredicate()->_is_nil() )
2136     {
2137       QValueList<int> aResultIds;
2138       filterSource( aCurrType, aResultIds );
2139       selectInViewer( aCurrType, aResultIds );
2140     }
2141
2142     myInsertState[ aCurrType ] = mySetInViewer->isChecked();
2143     myApplyToState[ aCurrType ] = mySourceGrp->id( mySourceGrp->selected() );
2144     
2145   }
2146   catch( const SALOME::SALOME_Exception& S_ex )
2147   {
2148     QtCatchCorbaException( S_ex );
2149   }
2150   catch( ... )
2151   {
2152   }
2153
2154   return true;
2155 }
2156
2157 //=======================================================================
2158 // name    : SMESHGUI_FilterDlg::createFilter
2159 // Purpose : Create predicate for given type
2160 //=======================================================================
2161 bool SMESHGUI_FilterDlg::createFilter( const int theType )
2162 {
2163   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
2164   if ( aFilterMgr->_is_nil() )
2165     return false;
2166
2167   int n = myTable->NumRows();
2168
2169   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2170   aCriteria->length( n );
2171
2172   long aPrecision = -1;
2173   if ( QAD_CONFIG->hasSetting( "SMESH:ControlsPrecision" ) )
2174   {
2175     QString aStr = QAD_CONFIG->getSetting( "SMESH:ControlsPrecision" );
2176     bool isOk = false;
2177     int aVal = aStr.toInt( &isOk );
2178     if ( isOk )
2179       aPrecision = aVal;
2180   }
2181   
2182   for ( CORBA::ULong i = 0; i < n; i++ )
2183   {
2184     SMESH::Filter::Criterion aCriterion = createCriterion();
2185     myTable->GetCriterion( i, aCriterion );
2186     aCriterion.Precision = aPrecision;
2187     aCriteria[ i ] = aCriterion;
2188   }
2189
2190   myFilter[ theType ] = aFilterMgr->CreateFilter();
2191   myFilter[ theType ]->SetCriteria( aCriteria.inout() );
2192
2193   return true;
2194 }
2195
2196 //=======================================================================
2197 // name    : SMESHGUI_FilterDlg::insertFilterInViewer
2198 // Purpose : Insert filter in viewer
2199 //=======================================================================
2200 void SMESHGUI_FilterDlg::insertFilterInViewer()
2201 {
2202   if ( VTKViewer_InteractorStyleSALOME* aStyle = SMESH::GetInteractorStyle() )
2203   {
2204     SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType();
2205
2206     if ( myFilter[ myTable->GetType() ]->_is_nil() ||
2207          myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() ||
2208          !mySetInViewer->isChecked() )
2209       SMESH::RemoveFilter( getFilterId( anEntType ), aStyle );
2210     else
2211     {
2212       Handle(SMESHGUI_PredicateFilter) aFilter = new SMESHGUI_PredicateFilter();
2213       aFilter->SetPredicate( myFilter[ myTable->GetType() ]->GetPredicate() );
2214       SMESH::SetFilter( aFilter, aStyle );
2215     }
2216   }
2217 }
2218
2219 //=======================================================================
2220 // name    : SMESHGUI_FilterDlg::filterSource
2221 // Purpose : Filter source ids
2222 //=======================================================================
2223 void SMESHGUI_FilterDlg::filterSource( const int theType,
2224                                        QValueList<int>& theResIds )
2225 {
2226   theResIds.clear();
2227   if ( myFilter[ theType ]->_is_nil() )
2228     return;
2229
2230   int aSourceId = mySourceGrp->id( mySourceGrp->selected() );
2231
2232   if ( aSourceId == Mesh )
2233   {
2234     if ( myMesh->_is_nil() )
2235       return;
2236     SMESH::long_array_var anIds = myFilter[ theType ]->GetElementsId( myMesh );
2237     for ( int i = 0, n = anIds->length(); i < n; i++ )
2238       theResIds.append( anIds[ i ] );
2239   }
2240   else if ( aSourceId == Selection )
2241   {
2242     filterSelectionSource( theType, theResIds );
2243   }
2244   else if ( aSourceId == Dialog )
2245   {
2246     // retrieve ids from dialog
2247     QValueList<int> aDialogIds;
2248     getIdsFromWg( mySourceWg, aDialogIds );
2249
2250     if ( myMesh->_is_nil() )
2251     {
2252       theResIds = aDialogIds;
2253       return;
2254     }
2255
2256     // filter ids
2257     SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2258     aPred->SetMesh( myMesh );
2259     QValueList<int>::const_iterator anIter;
2260     for ( anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter )
2261       if ( aPred->IsSatisfy( *anIter ) )
2262         theResIds.append( *anIter );
2263
2264     // set ids to the dialog
2265     setIdsToWg( mySourceWg, theResIds );
2266   }
2267 }
2268
2269 //=======================================================================
2270 // name    : SMESHGUI_FilterDlg::filterSelectionSource
2271 // Purpose : Filter source selection
2272 //=======================================================================
2273 void SMESHGUI_FilterDlg::filterSelectionSource( const int theType,
2274                                                 QValueList<int>& theResIds )
2275 {
2276   theResIds.clear();
2277   if ( myMesh->_is_nil() || mySelection == 0 )
2278     return;
2279
2280   // Create map of entities to be filtered
2281   TColStd_MapOfInteger aToBeFiltered;
2282   SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter( myIObjects );
2283
2284   for ( ; anIter.More(); anIter.Next() )
2285   {
2286     // process sub mesh
2287     SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>( anIter.Key() );
2288     if ( !aSubMesh->_is_nil() )
2289     {
2290       if ( aSubMesh->GetFather()->GetId() == myMesh->GetId() )
2291       {
2292         SMESH::long_array_var anIds =
2293           theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId();
2294         for ( int i = 0, n = anIds->length(); i < n; i++ )
2295           aToBeFiltered.Add( anIds[ i ] );
2296       }
2297     }
2298
2299     // process group
2300     SMESH::SMESH_GroupBase_var aGroup =
2301       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>( anIter.Key() );
2302     if ( !aGroup->_is_nil() )
2303     {
2304       if ( aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId() )
2305       {
2306         SMESH::long_array_var anIds = aGroup->GetListOfID();
2307         for ( int i = 0, n = anIds->length(); i < n; i++ )
2308           aToBeFiltered.Add( anIds[ i ] );
2309       }
2310     }
2311
2312     // process mesh
2313     SMESH::SMESH_Mesh_var aMeshPtr = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>( anIter.Key() );
2314     if ( !aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId() )
2315     {
2316       const TColStd_IndexedMapOfInteger& aSelMap = anIter.Value();
2317
2318       if ( aSelMap.Extent() > 0 )
2319       {
2320         if(SMESH_Actor *anActor = SMESH::FindActorByEntry( anIter.Key()->getEntry() ) )
2321         {
2322           for ( int i = 1; i <= aSelMap.Extent(); i++ )
2323             aToBeFiltered.Add( aSelMap(i) );
2324         }
2325       }
2326     }
2327   }
2328
2329   // Filter entities
2330   SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2331   aPred->SetMesh( myMesh );
2332   TColStd_MapIteratorOfMapOfInteger aResIter( aToBeFiltered );
2333   for ( ; aResIter.More(); aResIter.Next() )
2334     if ( aPred->IsSatisfy( aResIter.Key() ) )
2335       theResIds.append( aResIter.Key() );
2336 }
2337
2338 //=======================================================================
2339 // name    : SMESHGUI_FilterDlg::selectInViewer
2340 // Purpose : Select given entities in viewer
2341 //=======================================================================
2342 void SMESHGUI_FilterDlg::selectInViewer( const int theType, const QValueList<int>& theIds )
2343 {
2344   if ( mySelection == 0 || myMesh->_is_nil() )
2345     return;
2346
2347   mySelection->ClearFilters();
2348
2349   // Set new selection mode if necessary
2350   Selection_Mode aSelMode = getSelMode( theType );
2351   if ( aSelMode != mySelection->SelectionMode() )
2352   {
2353     mySelection->ClearIObjects();
2354     mySelection->ClearFilters();
2355     if ( aSelMode == NodeSelection )
2356       SMESH::SetPointRepresentation(true);
2357     QAD_Application::getDesktop()->SetSelectionMode( aSelMode );
2358   }
2359
2360   // Clear selection
2361   SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
2362   if ( !anActor || !anActor->hasIO() )
2363     return;
2364
2365   Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
2366   mySelection->ClearIObjects();
2367   mySelection->AddIObject( anIO, false );
2368
2369   // Remove filter corresponding to the current type from viewer
2370   int aType = myTable->GetType();
2371   int aFilterId = SMESHGUI_UnknownFilter;
2372   if      ( aType == SMESH::EDGE   ) aFilterId = SMESHGUI_EdgeFilter;
2373   else if ( aType == SMESH::FACE   ) aFilterId = SMESHGUI_FaceFilter;
2374   else if ( aType == SMESH::VOLUME ) aFilterId = SMESHGUI_VolumeFilter;
2375   Handle(VTKViewer_Filter) aFilter = SMESH::GetFilter( aFilterId );
2376   SMESH::RemoveFilter( aFilterId );
2377
2378   // get vtk ids
2379   TColStd_MapOfInteger aMap;
2380   QValueList<int>::const_iterator anIter;
2381   for ( anIter = theIds.begin(); anIter != theIds.end(); ++anIter )
2382   {
2383     aMap.Add( *anIter );
2384   }
2385
2386   // Set new selection
2387   mySelection->AddOrRemoveIndex( anIO, aMap, false, true );
2388
2389   // insert previously stored filter in viewer if necessary
2390   if ( !aFilter.IsNull() )
2391     SMESH::SetFilter( aFilter );
2392 }
2393
2394 //=======================================================================
2395 // name    : SMESHGUI_FilterDlg::createCriterion
2396 // Purpose : Create criterion structure with default values
2397 //=======================================================================
2398 SMESH::Filter::Criterion SMESHGUI_FilterDlg::createCriterion()
2399 {
2400    SMESH::Filter::Criterion aCriterion;
2401
2402   aCriterion.Type          = FT_Undefined;
2403   aCriterion.Compare       = FT_Undefined;
2404   aCriterion.Threshold     = 0;
2405   aCriterion.UnaryOp       = FT_Undefined;
2406   aCriterion.BinaryOp      = FT_Undefined;
2407   aCriterion.ThresholdStr  = "";
2408   aCriterion.TypeOfElement = SMESH::ALL;
2409
2410   return aCriterion;
2411 }
2412
2413 //=======================================================================
2414 // name    : SMESHGUI_FilterDlg::onSelectionDone
2415 // Purpose : SLOT called when selection changed.
2416 //           If current cell corresponds to the threshold value of
2417 //           BelongToGeom criterion name of selected object is set in this cell
2418 //=======================================================================
2419 void SMESHGUI_FilterDlg::onSelectionDone()
2420 {
2421   int aRow, aCol;
2422   if (  mySelection->IObjectCount() != 1 ||
2423         !myTable->CurrentCell( aRow, aCol ) ||
2424         myTable->GetCriterionType( aRow ) != FT_BelongToGeom &&
2425         myTable->GetCriterionType( aRow ) != FT_BelongToPlane &&
2426         myTable->GetCriterionType( aRow ) != FT_BelongToCylinder)
2427     return;
2428
2429   Handle(SALOME_InteractiveObject) anIO = mySelection->firstIObject() ;
2430   GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( anIO ) ;
2431   if ( !anObj->_is_nil() )
2432     myTable->SetThreshold( aRow, anIO->getName() );
2433 }
2434
2435 //=======================================================================
2436 // name    : SMESHGUI_FilterDlg::onCriterionChanged
2437 // Purpose : SLOT called when cretarion of current row changed. Update selection
2438 //=======================================================================
2439 void SMESHGUI_FilterDlg::onCriterionChanged( const int , const int )
2440 {
2441   updateSelection();
2442 }
2443
2444 //=======================================================================
2445 // name    : SMESHGUI_FilterDlg::onCurrentChanged
2446 // Purpose : SLOT called when current row changed. Update selection
2447 //=======================================================================
2448 void SMESHGUI_FilterDlg::onCurrentChanged( int, int )
2449 {
2450   updateSelection();
2451 }
2452
2453 //=======================================================================
2454 // name    : SMESHGUI_FilterDlg::updateSelection
2455 // Purpose : UpdateSelection in accordance with current row
2456 //=======================================================================
2457 void SMESHGUI_FilterDlg::updateSelection()
2458 {
2459   if ( mySelection == 0 )
2460     return;
2461   
2462   mySelection->ClearFilters();
2463
2464   int aRow, aCol;
2465   
2466   if ( myTable->CurrentCell( aRow, aCol ) &&
2467        ( myTable->GetCriterionType( aRow ) == FT_BelongToGeom ||
2468          myTable->GetCriterionType( aRow ) == FT_BelongToPlane ||
2469          myTable->GetCriterionType( aRow ) == FT_BelongToCylinder ) )
2470   {
2471     if ( myTable->GetCriterionType( aRow ) == FT_BelongToGeom )
2472       mySelection->AddFilter( new SALOME_TypeFilter( "GEOM" ) );
2473     else if ( myTable->GetCriterionType( aRow ) == FT_BelongToPlane )
2474       mySelection->AddFilter( new GEOM_FaceFilter( StdSelect_Plane ) );
2475     else if ( myTable->GetCriterionType( aRow ) == FT_BelongToCylinder )
2476       mySelection->AddFilter( new GEOM_FaceFilter( StdSelect_Cylinder ) );
2477
2478     myIsSelectionChanged = true;
2479   }
2480   else
2481   {
2482     if ( myIsSelectionChanged )
2483       mySelection->AddFilter( new SALOME_TypeFilter( "This filter deactivate selection" ) );
2484   }
2485 }
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509