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