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