Salome HOME
0020168: EDF SMESH 953: uncomplete selection with filter 'belong on geom'
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_FilterDlg.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // SMESH SMESHGUI : GUI for SMESH component
23 // File   : SMESHGUI_FilterDlg.cxx
24 // Author : Sergey LITONIN, Open CASCADE S.A.S.
25 // SMESH includes
26 //
27 #include "SMESHGUI_FilterDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32 #include "SMESHGUI_Filter.h"
33 #include "SMESHGUI_FilterUtils.h"
34 #include "SMESHGUI_FilterLibraryDlg.h"
35
36 #include <SMESH_Actor.h>
37 #include <SMESH_NumberFilter.hxx>
38 #include <SMESH_TypeFilter.hxx>
39
40 // SALOME GEOM includes
41 #include <GEOMBase.h>
42 #include <GEOM_FaceFilter.h>
43 #include <GEOM_TypeFilter.h>
44
45 // SALOME GUI includes
46 #include <SUIT_Desktop.h>
47 #include <SUIT_ResourceMgr.h>
48 #include <SUIT_Session.h>
49 #include <SUIT_MessageBox.h>
50 #include <QtxColorButton.h>
51
52 #include <LightApp_Application.h>
53 #include <LightApp_SelectionMgr.h>
54 #include <SalomeApp_Tools.h>
55 #include <SalomeApp_Study.h>
56
57 #include <SALOME_ListIO.hxx>
58 #include <SALOME_ListIteratorOfListIO.hxx>
59 #include <SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger.hxx>
60
61 #include <SVTK_ViewWindow.h>
62
63 // SALOME KERNEL includes
64 #include <SALOMEDSClient_Study.hxx>
65
66 // OCCT includes
67 #include <StdSelect_TypeOfFace.hxx>
68 #include <BRep_Tool.hxx>
69 #include <TopoDS.hxx>
70 #include <TopoDS_Shape.hxx>
71 #include <Geom_Plane.hxx>
72 #include <Geom_CylindricalSurface.hxx>
73 #include <Precision.hxx>
74 #include <TColStd_MapOfInteger.hxx>
75 #include <TColStd_IndexedMapOfInteger.hxx>
76 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
77
78 // Qt includes
79 #include <QFrame>
80 #include <QLineEdit>
81 #include <QPushButton>
82 #include <QGroupBox>
83 #include <QTableWidget>
84 #include <QStringList>
85 #include <QHBoxLayout>
86 #include <QVBoxLayout>
87 #include <QGridLayout>
88 #include <QStackedWidget>
89 #include <QApplication>
90 #include <QComboBox>
91 #include <QFontMetrics>
92 #include <QLabel>
93 #include <QButtonGroup>
94 #include <QRadioButton>
95 #include <QRegExp>
96 #include <QListWidget>
97 #include <QCheckBox>
98 #include <QItemDelegate>
99 #include <QDoubleValidator>
100 #include <QKeyEvent>
101 #include <QHeaderView>
102
103 // IDL includes
104 #include <SALOMEconfig.h>
105 #include CORBA_SERVER_HEADER(SMESH_Group)
106
107 #define SPACING 6
108 #define MARGIN  11
109
110 //---------------------------------------
111 // maxLength
112 //---------------------------------------
113 static int maxLength (const QMap<int, QString> theMap, const QFontMetrics& theMetrics)
114 {
115   int aRes = 0;
116   QMap<int, QString>::const_iterator anIter;
117   for (anIter = theMap.begin(); anIter != theMap.end(); ++anIter)
118     aRes = qMax(aRes, theMetrics.width(anIter.value()));
119   return aRes;
120 }
121
122 //---------------------------------------
123 // getFilterId
124 //---------------------------------------
125 static int getFilterId (SMESH::ElementType theType)
126 {
127   switch (theType)
128   {
129     case SMESH::NODE   : return SMESH::NodeFilter;
130     case SMESH::EDGE   : return SMESH::EdgeFilter;
131     case SMESH::FACE   : return SMESH::FaceFilter;
132     case SMESH::VOLUME : return SMESH::VolumeFilter;
133     case SMESH::ALL    : return SMESH::AllElementsFilter;
134     default            : return SMESH::UnknownFilter;
135   }
136 }
137
138 /*
139   Class       : SMESHGUI_FilterTable::AdditionalWidget
140   Description : Class for storing additional parameters of criterion
141 */
142
143 class SMESHGUI_FilterTable::AdditionalWidget : public QWidget
144 {
145 public:
146   enum { Tolerance };
147
148 public:
149   AdditionalWidget(QWidget* theParent);
150   virtual ~AdditionalWidget();
151
152   virtual QList<int>      GetParameters() const;
153   virtual bool            IsValid(const bool = true) const;
154   virtual double          GetDouble(const int) const;
155   virtual int             GetInteger(const int) const;
156   virtual QString         GetString(const int) const;
157   virtual void            SetDouble(const int, const double);
158   virtual void            SetInteger(const int, const int);
159   virtual void            SetString(const int, const QString&);
160   void                    SetEditable(const int, const bool);
161   void                    SetEditable(const bool);
162
163 private:
164   QMap< int, QLineEdit* > myLineEdits;
165 };
166
167 SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget (QWidget* theParent)
168   : QWidget(theParent)
169 {
170   QLabel* aLabel = new QLabel(tr("SMESH_TOLERANCE"), this);
171   myLineEdits[ Tolerance ] = new QLineEdit(this);
172   QDoubleValidator* aValidator = new QDoubleValidator(myLineEdits[ Tolerance ]);
173   aValidator->setBottom(0);
174   myLineEdits[ Tolerance ]->setValidator(aValidator);
175
176   QHBoxLayout* aLay = new QHBoxLayout(this);
177   aLay->setSpacing(SPACING);
178   aLay->setMargin(0);
179
180   aLay->addWidget(aLabel);
181   aLay->addWidget(myLineEdits[ Tolerance ]);
182   aLay->addStretch();
183
184   QString aText = QString("%1").arg(Precision::Confusion());
185   myLineEdits[ Tolerance ]->setText(aText);
186 }
187
188 SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget()
189 {
190 }
191
192 QList<int> SMESHGUI_FilterTable::AdditionalWidget::GetParameters() const
193 {
194   QList<int> theList;
195   theList.append(Tolerance);
196   return theList;
197 }
198
199 bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const
200 {
201   if (!isEnabled())
202     return true;
203
204   QList<int> aParams = GetParameters();
205   QList<int>::const_iterator anIter;
206   for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) {
207     const QLineEdit* aWg = myLineEdits[ *anIter ];
208     int p = 0;
209     QString aText = aWg->text();
210     if (aWg->isEnabled() && aWg->validator()->validate(aText, p) != QValidator::Acceptable) {
211       if (theMsg)
212         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
213                                      tr("SMESHGUI_INVALID_PARAMETERS"));
214       return false;
215     }
216   }
217
218   return true;
219 }
220
221 double SMESHGUI_FilterTable::AdditionalWidget::GetDouble (const int theId) const
222 {
223   return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toDouble() : 0;
224 }
225
226 int SMESHGUI_FilterTable::AdditionalWidget::GetInteger (const int theId) const
227 {
228   return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toInt() : 0;
229 }
230
231 QString SMESHGUI_FilterTable::AdditionalWidget::GetString (const int theId) const
232 {
233   return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text() : QString("");
234 }
235
236 void SMESHGUI_FilterTable::AdditionalWidget::SetDouble (const int theId, const double theVal)
237 {
238   if (myLineEdits.contains(theId))
239     myLineEdits[ theId ]->setText(QString("%1").arg(theVal));
240 }
241
242 void SMESHGUI_FilterTable::AdditionalWidget::SetInteger (const int theId, const int theVal)
243 {
244   if (myLineEdits.contains(theId))
245     myLineEdits[ theId ]->setText(QString("%1").arg(theVal));
246 }
247
248 void SMESHGUI_FilterTable::AdditionalWidget::SetString (const int theId, const QString& theVal)
249 {
250   if (myLineEdits.contains(theId))
251     myLineEdits[ theId ]->setText(theVal);
252 }
253
254 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const int theId, const bool isEditable)
255 {
256   if (myLineEdits.contains(theId))
257     myLineEdits[ theId ]->setReadOnly(!isEditable);
258 }
259
260 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable)
261 {
262   QList<int> aParams = GetParameters();
263   QList<int>::const_iterator anIter;
264   for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter)
265     SetEditable( *anIter,  isEditable );
266 }
267
268 /*
269   Class       : SMESHGUI_FilterTable::ComboItem
270   Description : Combo table item. Identificator corresponding to string may be assigned
271 */
272
273 class SMESHGUI_FilterTable::ComboItem : public QTableWidgetItem
274 {
275 public:
276   static int     Type();
277
278   ComboItem( const QMap<int, QString>& );
279
280   void           setItems( const QMap<int, QString>& );
281   void           clear();
282   int            count() const;
283
284   int            value() const;
285   void           setValue( const int );
286
287 private:
288   int            id( int ) const;
289   int            index( int ) const;
290
291 private:
292   QMap<int, int> myIdToIdx;
293 };
294
295 int SMESHGUI_FilterTable::ComboItem::Type()
296 {
297   return QTableWidgetItem::UserType + 1;
298 }
299
300 SMESHGUI_FilterTable::ComboItem::ComboItem( const QMap<int, QString>& theIds )
301  : QTableWidgetItem( Type() )
302 {
303   setItems( theIds );
304 }
305
306 void SMESHGUI_FilterTable::ComboItem::setItems( const QMap<int, QString>& theIds )
307 {
308   myIdToIdx.clear();
309   QMap<int, QString>::const_iterator it;
310   QStringList items;
311   for ( it = theIds.begin(); it != theIds.end(); ++it ) {
312     myIdToIdx[it.key()] = items.count();
313     items.append( it.value() );
314   }
315   setData( Qt::UserRole, items );
316   setValue( id( 0 ) ); 
317 }
318
319 void SMESHGUI_FilterTable::ComboItem::clear()
320 {
321   QMap<int, QString> empty;
322   setItems( empty );
323 }
324
325 int SMESHGUI_FilterTable::ComboItem::count() const
326 {
327   return myIdToIdx.count();
328 }
329
330 int SMESHGUI_FilterTable::ComboItem::value() const
331 {
332   return( id( data( Qt::UserRole ).toStringList().indexOf( text() ) ) ); 
333 }
334
335 void SMESHGUI_FilterTable::ComboItem::setValue( const int theId )
336 {
337   int idx = index( theId );
338   QStringList items = data( Qt::UserRole ).toStringList();
339   setText( idx >= 0 && idx < items.count() ? items[idx] : "" );
340 }
341
342 int SMESHGUI_FilterTable::ComboItem::id( int idx ) const
343 {
344   QMap<int,int>::const_iterator it;
345   for ( it = myIdToIdx.begin(); it != myIdToIdx.end(); ++it )
346     if ( it.value() == idx ) return it.key();
347   return -1;
348 }
349
350 int SMESHGUI_FilterTable::ComboItem::index( int i ) const
351 {
352   return myIdToIdx.contains( i ) ? myIdToIdx[i] : -1;
353 }
354 /*
355   Class       : SMESHGUI_FilterTable::CheckItem
356   Description : Check table item.
357 */
358
359 class SMESHGUI_FilterTable::CheckItem : public QTableWidgetItem
360 {
361 public:
362   static int     Type();
363
364   CheckItem( bool = false );
365   CheckItem( const QString&, bool = false );
366   ~CheckItem();
367
368   void  setChecked( bool );
369   bool  checked() const;
370 };
371
372 int SMESHGUI_FilterTable::CheckItem::Type()
373 {
374   return QTableWidgetItem::UserType + 2;
375 }
376
377 SMESHGUI_FilterTable::CheckItem::CheckItem( bool value )
378  : QTableWidgetItem( Type() )
379 {
380   Qt::ItemFlags f = flags();
381   f = f | Qt::ItemIsUserCheckable;
382   f = f & ~Qt::ItemIsTristate;
383   f = f & ~Qt::ItemIsEditable;
384   setFlags( f );
385   setChecked(value);
386 }
387
388 SMESHGUI_FilterTable::CheckItem::CheckItem( const QString& text, bool value )
389  : QTableWidgetItem( Type() )
390 {
391   Qt::ItemFlags f = flags();
392   f = f | Qt::ItemIsUserCheckable;
393   f = f & ~Qt::ItemIsTristate;
394   f = f & ~Qt::ItemIsEditable;
395   setFlags( f );
396   setChecked( value );
397   setText( text );
398 }
399
400 SMESHGUI_FilterTable::CheckItem::~CheckItem()
401 {
402 }
403
404 void SMESHGUI_FilterTable::CheckItem::setChecked( bool value )
405 {
406   setCheckState( value ? Qt::Checked : Qt::Unchecked );
407 }
408
409 bool SMESHGUI_FilterTable::CheckItem::checked() const
410 {
411   return checkState() == Qt::Checked;
412 }
413
414 /*
415   Class       : SMESHGUI_FilterTable::ComboDelegate
416   Description : Table used by this widget
417 */
418
419 class SMESHGUI_FilterTable::ComboDelegate : public QItemDelegate
420 {
421 public:
422   ComboDelegate( QObject* = 0 );
423   ~ComboDelegate();
424   
425   QWidget*      createEditor( QWidget*, const QStyleOptionViewItem&,
426                               const QModelIndex& ) const;
427   
428   void          setEditorData( QWidget*, const QModelIndex& ) const;
429   void          setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const;
430   
431   void          updateEditorGeometry( QWidget*, const QStyleOptionViewItem&, 
432                                       const QModelIndex& ) const;
433 private:
434   QTableWidget* myTable;
435 };
436
437 SMESHGUI_FilterTable::ComboDelegate::ComboDelegate( QObject* parent )
438   : QItemDelegate( parent ), 
439     myTable( qobject_cast<QTableWidget*>( parent ) )
440 {
441 }
442   
443 SMESHGUI_FilterTable::ComboDelegate::~ComboDelegate()
444 {
445 }
446
447 QWidget* SMESHGUI_FilterTable::ComboDelegate::createEditor( QWidget* parent,
448                                                             const QStyleOptionViewItem& option,
449                                                             const QModelIndex& index ) const
450 {
451   QStringList l = index.data( Qt::UserRole ).toStringList();
452   if ( !l.isEmpty() ) {
453     QComboBox* cb = new QComboBox( parent );
454     cb->setFrame( false );
455     cb->addItems( l );
456     return cb;
457   }
458   return QItemDelegate::createEditor( parent, option, index );
459 }
460
461 void SMESHGUI_FilterTable::ComboDelegate::setEditorData( QWidget* editor, 
462                                                          const QModelIndex& index ) const
463 {
464   QString value = index.model()->data( index, Qt::DisplayRole ).toString();
465   QComboBox* cb = dynamic_cast<QComboBox*>( editor );
466   bool bOk = false;
467   if ( cb ) {
468     int i = cb->findText( value );
469     if ( i >= 0 ) {
470       cb->setCurrentIndex( i );
471       bOk = true;
472     }
473   }
474   if ( !bOk ) QItemDelegate::setEditorData( editor, index );
475 }
476
477 void SMESHGUI_FilterTable::ComboDelegate::setModelData( QWidget* editor,
478                                                         QAbstractItemModel* model,
479                                                         const QModelIndex& index) const
480 {
481   QComboBox* cb = dynamic_cast<QComboBox*>( editor );
482   if ( cb ) model->setData( index, cb->currentText(), Qt::DisplayRole );
483   else QItemDelegate::setModelData( editor, model, index );
484 }
485
486 void SMESHGUI_FilterTable::ComboDelegate::updateEditorGeometry( QWidget* editor,
487                                                                 const QStyleOptionViewItem& option, 
488                                                                 const QModelIndex& index ) const
489 {
490   editor->setGeometry( option.rect );
491 }
492
493 /*
494   Class       : SMESHGUI_FilterTable::Table
495   Description : Table used by this widget
496 */
497
498 class SMESHGUI_FilterTable::Table : public QTableWidget
499 {
500 public:
501   Table( QWidget* = 0 );
502   Table( int, int, QWidget* = 0 );
503   virtual ~Table();
504
505   QSize                   minimumSizeHint() const;
506
507   void                    setEditable( bool, int, int );
508   bool                    isEditable( int, int ) const;
509
510   void                    setReadOnly( bool );
511   bool                    isReadOnly() const;
512
513   void                    insertRows( int, int = 1 );
514   QString                 text( int, int );
515
516   QList<int>              selectedRows();
517 };
518
519 //=======================================================================
520 // name    : SMESHGUI_FilterTable::Table::Table
521 // Purpose : Constructor
522 //=======================================================================
523 SMESHGUI_FilterTable::Table::Table (QWidget* parent)
524 : QTableWidget(parent)
525 {
526   // set custom item delegate
527   setItemDelegate( new ComboDelegate(this) );
528   // set edit triggers by default
529   setReadOnly( false );
530 }
531
532 //=======================================================================
533 // name    : SMESHGUI_FilterTable::Table::Table
534 // Purpose : Constructor
535 //=======================================================================
536 SMESHGUI_FilterTable::Table::Table (int numRows, int numCols, QWidget* parent)
537 : QTableWidget(numRows, numCols, parent)
538 {
539   // set custom item delegate
540   setItemDelegate( new ComboDelegate(this) );
541   // set edit triggers by default
542   setReadOnly( false );
543 }
544
545 //=======================================================================
546 // name    : SMESHGUI_FilterTable::Table::~Table
547 // Purpose : Destructor
548 //=======================================================================
549 SMESHGUI_FilterTable::Table::~Table()
550 {
551 }
552
553 //=======================================================================
554 // name    : SMESHGUI_FilterTable::Table::minimumSizeHint
555 // Purpose : Get minimum size for the table
556 //=======================================================================
557 QSize SMESHGUI_FilterTable::Table::minimumSizeHint() const
558 {
559   QSize s = QTableWidget::minimumSizeHint();
560   QHeaderView* hv = horizontalHeader();
561   if ( hv )
562     s.setWidth( qMax( s.width(), hv->length() ) );
563   return s;
564 }
565
566 //=======================================================================
567 // name    : SMESHGUI_FilterTable::Table::setEditable
568 // Purpose : Set editable of specified cell
569 //=======================================================================
570 void SMESHGUI_FilterTable::Table::setEditable (bool isEditable,
571                                                int row, int col)
572 {
573   QTableWidgetItem* anItem = item( row, col );
574   if ( anItem ) {
575     bool isSignalsBlocked = signalsBlocked();
576     blockSignals( true );
577
578     Qt::ItemFlags f = anItem->flags();
579     if ( !isEditable ) f = f & ~Qt::ItemIsEditable;
580     else f = f | Qt::ItemIsEditable;
581     anItem->setFlags( f );
582     
583     blockSignals( isSignalsBlocked );
584   }
585 }
586
587 //=======================================================================
588 // name    : SMESHGUI_FilterTable::Table::isEditable
589 // Purpose : Verify wheter cell is editable
590 //=======================================================================
591 bool SMESHGUI_FilterTable::Table::isEditable (int row, int col) const
592 {
593   QTableWidgetItem* anItem = item( row, col );
594   return anItem == 0 || anItem->flags() & Qt::ItemIsEditable;
595 }
596
597 void SMESHGUI_FilterTable::Table::setReadOnly( bool on )
598 {
599   setEditTriggers( on ? 
600                    QAbstractItemView::NoEditTriggers  :
601                    QAbstractItemView::AllEditTriggers );
602 }
603
604 bool SMESHGUI_FilterTable::Table::isReadOnly() const
605 {
606   return editTriggers() == QAbstractItemView::NoEditTriggers;
607 }
608
609 //=======================================================================
610 // name    : SMESHGUI_FilterTable::Table::insertRows
611 // Purpose : Insert rows (virtual redefined)
612 //=======================================================================
613 void SMESHGUI_FilterTable::Table::insertRows (int row, int count)
614 {
615   closePersistentEditor( currentItem() );
616   while ( count-- ) insertRow( row );
617 }
618
619 //=======================================================================
620 // name    : SMESHGUI_FilterTable::Table::text
621 // Purpose : Get text from cell (virtual redefined)
622 //=======================================================================
623 QString SMESHGUI_FilterTable::Table::text (int row, int col)
624 {
625   closePersistentEditor( currentItem() );
626   QTableWidgetItem* anItem = item( row, col );
627   return anItem ? anItem->text() : QString();
628 }
629
630 QList<int> SMESHGUI_FilterTable::Table::selectedRows()
631 {
632   QList<QTableWidgetItem*> selItems = selectedItems();
633   QTableWidgetItem* anItem;
634   QList<int> rows;
635
636   foreach( anItem, selItems ) {
637     int r = row( anItem );
638     if ( !rows.contains( r ) ) rows.append( r );
639   }
640
641   qSort( rows );
642   return rows;
643 }
644
645 /*
646   Class       : SMESHGUI_FilterTable
647   Description : Frame containig
648                   - Button group for switching entity type
649                   - Table for displaying filter criterions
650                   - Buttons for editing table and filter libraries
651 */
652
653 //=======================================================================
654 // name    : SMESHGUI_FilterTable::SMESHGUI_FilterTable
655 // Purpose : Constructor
656 //=======================================================================
657 SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule,
658                                             QWidget* parent,
659                                             const int type )
660 : QWidget( parent ),
661   myIsLocked( false ),
662   mySMESHGUI( theModule )
663 {
664   myEntityType = -1;
665
666   QList<int> aTypes;
667   aTypes.append(type);
668   Init(aTypes);
669 }
670
671 //=======================================================================
672 // name    : SMESHGUI_FilterTable::SMESHGUI_FilterTable
673 // Purpose : Constructor
674 //=======================================================================
675 SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule,
676                                             QWidget* parent,
677                                             const QList<int>& types )
678 : QWidget( parent ),
679   myIsLocked( false ),
680   mySMESHGUI( theModule )
681 {
682   myEntityType = -1;
683   Init(types);
684 }
685
686 SMESHGUI_FilterTable::~SMESHGUI_FilterTable()
687 {
688 }
689
690 //=======================================================================
691 // name    : SMESHGUI_FilterTable::Init
692 // Purpose : Create table corresponding to the specified type
693 //=======================================================================
694 void SMESHGUI_FilterTable::Init (const QList<int>& theTypes)
695 {
696   if (theTypes.isEmpty())
697     return;
698
699   // Create buttons if necessary
700
701   if (myTables.isEmpty())
702   {
703     // create main layout
704     QVBoxLayout* aMainLay = new QVBoxLayout(this);
705     aMainLay->setMargin( 0 );
706     aMainLay->setSpacing( SPACING );
707
708     // create switch of entity types
709     myEntityTypeBox = new QGroupBox(tr("ENTITY_TYPE"), this);
710     QHBoxLayout* myEntityTypeBoxLayout = new QHBoxLayout(myEntityTypeBox);
711     myEntityTypeBoxLayout->setMargin( MARGIN );
712     myEntityTypeBoxLayout->setSpacing( SPACING );
713     myEntityTypeGrp = new QButtonGroup(this);
714
715     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
716     QMap<int, QString>::const_iterator anIter;
717     for (anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter)
718     {
719       QRadioButton* aBtn = new QRadioButton(anIter.value(), myEntityTypeBox);
720       myEntityTypeGrp->addButton(aBtn, anIter.key());
721       myEntityTypeBoxLayout->addWidget(aBtn);
722     }
723
724     myTableGrp = new QGroupBox(tr("FILTER"), this );
725
726     // create table
727     mySwitchTableGrp = new QWidget(myTableGrp);
728     QVBoxLayout* mySwitchTableGrpLayout = new QVBoxLayout(mySwitchTableGrp);
729     mySwitchTableGrpLayout->setMargin(0);
730     mySwitchTableGrpLayout->setSpacing(0);
731
732     QList<int>::const_iterator typeIt = theTypes.begin();
733     for ( ; typeIt != theTypes.end(); ++typeIt ) {
734       Table* aTable = createTable(mySwitchTableGrp, *typeIt);
735       myTables[ *typeIt ] = aTable;
736       mySwitchTableGrpLayout->addWidget(aTable);
737       if ( typeIt != theTypes.begin() )
738         aTable->hide();
739     }
740
741     // create buttons
742     myAddBtn      = new QPushButton(tr("ADD"),       myTableGrp);
743     myRemoveBtn   = new QPushButton(tr("REMOVE"),    myTableGrp);
744     myClearBtn    = new QPushButton(tr("CLEAR"),     myTableGrp);
745     myInsertBtn   = new QPushButton(tr("INSERT"),    myTableGrp);
746     myCopyFromBtn = new QPushButton(tr("COPY_FROM"), myTableGrp);
747     myAddToBtn    = new QPushButton(tr("ADD_TO"),    myTableGrp);
748
749     myAddBtn->setAutoDefault(false);
750     myRemoveBtn->setAutoDefault(false);
751     myClearBtn->setAutoDefault(false);
752     myInsertBtn->setAutoDefault(false);
753     myCopyFromBtn->setAutoDefault(false);
754     myAddToBtn->setAutoDefault(false);
755
756     myCopyFromBtn->hide();
757     myAddToBtn->hide();
758
759     // layout widgets
760     QGridLayout* aLay = new QGridLayout(myTableGrp);
761     aLay->setMargin(MARGIN);
762     aLay->setSpacing(SPACING);
763
764     aLay->addWidget(mySwitchTableGrp, 0, 0, 7, 1);
765     aLay->addWidget(myAddBtn,         0, 1);
766     aLay->addWidget(myInsertBtn,      1, 1);
767     aLay->addWidget(myRemoveBtn,      2, 1);
768     aLay->addWidget(myClearBtn,       3, 1);
769     aLay->addWidget(myCopyFromBtn,    5, 1);
770     aLay->addWidget(myAddToBtn,       6, 1);
771     aLay->addWidget(createAdditionalFrame(myTableGrp), 7, 0, 1, 2 );
772
773     aLay->setRowMinimumHeight(4, 10);
774     aLay->setRowStretch(4, 1);
775     aLay->setColumnStretch(0, 1);
776     aLay->setColumnStretch(1, 0);
777
778     // layout 
779     aMainLay->addWidget(myEntityTypeBox);
780     aMainLay->addWidget(myTableGrp);
781     
782     // signals and slots
783     connect(myAddBtn,    SIGNAL(clicked()), this, SLOT(onAddBtn()));
784     connect(myInsertBtn, SIGNAL(clicked()), this, SLOT(onInsertBtn()));
785     connect(myRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveBtn()));
786     connect(myClearBtn,  SIGNAL(clicked()), this, SLOT(onClearBtn()));
787
788     connect(myCopyFromBtn, SIGNAL(clicked()), this, SLOT(onCopyFromBtn()));
789     connect(myAddToBtn,    SIGNAL(clicked()), this, SLOT(onAddToBtn()));
790
791     connect(myEntityTypeGrp, SIGNAL(buttonClicked(int)), this, SLOT(onEntityType(int)));
792
793     myLibDlg = 0;
794   }
795
796   // Hide buttons of entity types if necessary
797   const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
798   QMap<int, QString>::const_iterator anIt;
799   for (anIt = aSupportedTypes.begin(); anIt != aSupportedTypes.end(); ++anIt)
800   {
801     QAbstractButton* aBtn = myEntityTypeGrp->button(anIt.key());
802     if ( aBtn ) aBtn->setVisible( theTypes.contains(anIt.key()) );
803   }
804
805   // select first button if there is no selected buttons or it is hidden
806   int aBtnId = myEntityTypeGrp->checkedId();
807   if ( aBtnId == -1 || !theTypes.contains(aBtnId) ) {
808     QAbstractButton* aBtn = myEntityTypeGrp->button(theTypes.first());
809     if ( aBtn ) aBtn->setChecked(true);
810   }
811
812   myEntityTypeBox->setVisible(theTypes.count() > 1);
813
814   myTableGrp->updateGeometry();
815   int cType = myEntityTypeGrp->checkedId();
816   onEntityType(cType);
817 }
818
819 //=======================================================================
820 // name    : SMESHGUI_FilterTable::createAdditionalFrame
821 // Purpose : Get group box containing table. May be used for adding new widgets in it
822 //=======================================================================
823 QWidget* SMESHGUI_FilterTable::createAdditionalFrame (QWidget* theParent)
824 {
825   QWidget* aFrame = new QWidget(theParent);
826
827   QFrame* aLine1 = new QFrame(aFrame);
828   QFrame* aLine2 = new QFrame(aFrame);
829   aLine1->setFrameStyle(QFrame::HLine | QFrame::Sunken);
830   aLine2->setFrameStyle(QFrame::HLine | QFrame::Sunken);
831   aLine1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
832   aLine2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
833
834   QLabel* aLabel = new QLabel(tr("ADDITIONAL_PARAMETERS"), aFrame);
835
836   myWgStack = new QStackedWidget(aFrame);
837
838   QGridLayout* aLay = new QGridLayout(aFrame);
839   aLay->setMargin(0);
840   aLay->setSpacing(SPACING);
841   aLay->addWidget(aLine1,    0, 0);
842   aLay->addWidget(aLabel,    0, 1);
843   aLay->addWidget(aLine2,    0, 2);
844   aLay->addWidget(myWgStack, 1, 0, 1, 3);
845
846   return aFrame;
847 }
848
849 //=======================================================================
850 // name    : SMESHGUI_FilterTable::GetTableGrp
851 // Purpose : Get group box containing table. May be used for adding new widgets in it
852 //=======================================================================
853 QGroupBox* SMESHGUI_FilterTable::GetTableGrp()
854 {
855   return myTableGrp;
856 }
857
858 //=======================================================================
859 // name    : SMESHGUI_FilterTable::onEntityType
860 // Purpose : SLOT. Called when entity type changed.
861 //           Display corresponding table
862 //=======================================================================
863 void SMESHGUI_FilterTable::onEntityType (int theType)
864 {
865   if (myEntityType == theType)
866     return;
867
868   myIsValid = true;
869   emit NeedValidation();
870   if (!myIsValid)
871   {
872     myEntityTypeGrp->button(myEntityType)->setChecked(true);
873     return;
874   }
875
876   myEntityType = theType;
877
878   if (!myTables.contains(theType)) {
879     myTables[ theType ] = createTable(mySwitchTableGrp, theType);
880     ((QVBoxLayout*)mySwitchTableGrp->layout())->addWidget(myTables[ theType ]);
881   }
882
883   TableMap::iterator anIter;
884   for (anIter = myTables.begin(); anIter != myTables.end(); ++anIter)
885      anIter.value()->setVisible( myEntityType == anIter.key() );
886
887   updateBtnState();
888   qApp->processEvents();
889   myTables[ myEntityType ]->updateGeometry();
890   adjustSize();
891
892   emit EntityTypeChanged(theType);
893 }
894
895 //=======================================================================
896 // name    : SMESHGUI_FilterTable::IsValid
897 // Purpose : Verify validity of entered data
898 //=======================================================================
899 bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) const
900 {
901   int aType = theEntityType == -1 ? GetType() : theEntityType;
902
903   Table* aTable = myTables[ aType ];
904   for (int i = 0, n = aTable->rowCount(); i < n; i++)
905   {
906     int aCriterion = GetCriterionType(i, aType);
907     QString errMsg;
908     if (aCriterion == SMESH::FT_GroupColor ) {
909       QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(i, 2));
910       if (clrBtn && !clrBtn->color().isValid())
911         errMsg = tr( "GROUPCOLOR_ERROR" );
912     } else if (aCriterion == SMESH::FT_RangeOfIds ||
913          aCriterion == SMESH::FT_BelongToGeom ||
914          aCriterion == SMESH::FT_BelongToPlane ||
915          aCriterion == SMESH::FT_BelongToCylinder ||
916          aCriterion == SMESH::FT_BelongToGenSurface ||
917          aCriterion == SMESH::FT_ElemGeomType ||
918          aCriterion == SMESH::FT_LyingOnGeom) {
919       if (aTable->text(i, 2).isEmpty())
920         errMsg = tr( "ERROR" );
921     }
922     else {
923       bool aRes = false;
924       bool isSignalsBlocked = aTable->signalsBlocked();
925       aTable->blockSignals(true);
926       double  aThreshold = (int)aTable->text(i, 2).toDouble(&aRes);
927       aTable->blockSignals(isSignalsBlocked);
928
929       if (!aRes && aTable->isEditable(i, 2))
930         errMsg = tr( "ERROR" );
931       else if (aType == SMESH::EDGE &&
932                 GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
933                 aThreshold == 1)
934         errMsg = tr( "MULTIEDGES_ERROR" );
935     }
936
937     if (!errMsg.isEmpty()) {
938       if (theMess)
939         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), errMsg );
940       return false;
941     }
942
943     QTableWidgetItem* anItem = aTable->item(i, 0);
944     if (myAddWidgets.contains(anItem) && !myAddWidgets[ anItem ]->IsValid())
945       return false;
946   }
947
948   return true;
949 }
950
951 //=======================================================================
952 // name    : SMESHGUI_FilterTable::SetValidity
953 // Purpose : Set validity of the table
954 //=======================================================================
955 void SMESHGUI_FilterTable::SetValidity (const bool isValid)
956 {
957   myIsValid = isValid;
958 }
959
960 //=======================================================================
961 // name    : SMESHGUI_FilterTable::GetType
962 // Purpose : Get current entity type
963 //=======================================================================
964 int SMESHGUI_FilterTable::GetType() const
965 {
966   return myEntityType;
967 }
968
969 //=======================================================================
970 // name    : SMESHGUI_FilterTable::SetType
971 // Purpose : Set current entity type
972 //=======================================================================
973 void SMESHGUI_FilterTable::SetType (const int type)
974 {
975   myEntityTypeGrp->button(type)->setChecked(true);
976   onEntityType(type);
977 }
978
979 //=======================================================================
980 // name    : SMESHGUI_FilterTable::RestorePreviousEntityType
981 // Purpose : Restore previous entity type
982 //=======================================================================
983 void SMESHGUI_FilterTable::RestorePreviousEntityType()
984 {
985   SetType(myEntityType);
986 }
987
988 //=======================================================================
989 // name    : SMESHGUI_FilterTable::GetCriterionType
990 // Purpose : Get type of criterion from specified row (corresponding enums in h-file)
991 //=======================================================================
992 int SMESHGUI_FilterTable::GetCriterionType (const int theRow, const int theType) const
993 {
994   int aType = theType == -1 ? GetType() : theType;
995   Table* aTable = myTables[ aType ];
996   ComboItem* anItem = (ComboItem*)aTable->item(theRow, 0);
997   return anItem != 0 ? anItem->value() : SMESH::FT_Undefined;
998 }
999
1000 //=======================================================================
1001 // name    : SMESHGUI_FilterTable::GetCriterion
1002 // Purpose : Get parameters of criterion from specified row
1003 //=======================================================================
1004 void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
1005                                          SMESH::Filter::Criterion& theCriterion,
1006                                          const int                 theEntityType) const
1007 {
1008   int aType = theEntityType == -1 ? GetType() : theEntityType;
1009   Table* aTable = myTables[ aType ];
1010
1011   theCriterion.Type = ((ComboItem*)aTable->item(theRow, 0))->value();
1012   theCriterion.UnaryOp = ((CheckItem*)aTable->item(theRow, 3))->checked() ? SMESH::FT_LogicalNOT : SMESH::FT_Undefined;
1013   theCriterion.BinaryOp = theRow != aTable->rowCount() - 1 ?
1014     ((ComboItem*)aTable->item(theRow, 4))->value() : SMESH::FT_Undefined;
1015   theCriterion.TypeOfElement = (SMESH::ElementType)aType;
1016
1017   int aCriterionType = GetCriterionType(theRow, aType);
1018
1019   if ( aCriterionType == SMESH::FT_GroupColor )
1020   {
1021     QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(theRow, 2));
1022     if ( clrBtn )
1023     {
1024       const QColor qClr = clrBtn->color();
1025       QString clrStr = QString( "%1;%2;%3" ).
1026         arg( qClr.red()/256. ).arg( qClr.green()/256. ).arg( qClr.blue()/256. );
1027       theCriterion.ThresholdStr = clrStr.toLatin1().constData();
1028     }
1029   }
1030   else if ( aCriterionType == SMESH::FT_ElemGeomType )
1031     theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value();
1032   else if ( aCriterionType != SMESH::FT_RangeOfIds &&
1033             aCriterionType != SMESH::FT_BelongToGeom &&
1034             aCriterionType != SMESH::FT_BelongToPlane &&
1035             aCriterionType != SMESH::FT_BelongToCylinder &&
1036             aCriterionType != SMESH::FT_BelongToGenSurface &&
1037             aCriterionType != SMESH::FT_LyingOnGeom)
1038   {
1039     theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value();
1040     theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
1041   }
1042   else
1043   {
1044     theCriterion.ThresholdStr = aTable->text(theRow, 2).toLatin1().constData();
1045     if ( aCriterionType != SMESH::FT_RangeOfIds )
1046       theCriterion.ThresholdID = aTable->text( theRow, 5 ).toLatin1().constData();
1047   }
1048
1049   QTableWidgetItem* anItem = aTable->item(theRow, 0);
1050   if (myAddWidgets.contains(anItem))
1051     theCriterion.Tolerance = myAddWidgets[ anItem ]->GetDouble(AdditionalWidget::Tolerance);
1052 }
1053
1054 //=======================================================================
1055 // name    : SMESHGUI_FilterTable::SetCriterion
1056 // Purpose : Set parameters of criterion of specified row
1057 //=======================================================================
1058 void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
1059                                          const SMESH::Filter::Criterion& theCriterion,
1060                                          const int                       theEntityType)
1061 {
1062   int aType = theEntityType == -1 ? GetType() : theEntityType;
1063
1064   Table* aTable = myTables[ aType ];
1065
1066   if (theRow > aTable->rowCount() - 1)
1067     return;
1068
1069   ((ComboItem*)aTable->item(theRow, 0))->setValue(theCriterion.Type);
1070   onCriterionChanged(theRow, 0, aType);
1071   ((ComboItem*)aTable->item(theRow, 1))->setValue(theCriterion.Compare);
1072   ((CheckItem*)aTable->item(theRow, 3))->setChecked(theCriterion.UnaryOp == SMESH::FT_LogicalNOT);
1073
1074   if (theCriterion.BinaryOp != SMESH::FT_Undefined)
1075   {
1076     if (!aTable->isEditable(theRow, 4))
1077       aTable->setItem(theRow, 4, getBinaryItem());
1078     ((ComboItem*)aTable->item(theRow, 4))->setValue(theCriterion.BinaryOp);
1079   }
1080   else
1081     aTable->setEditable(false, theRow, 4);
1082
1083   if (theCriterion.Type == SMESH::FT_GroupColor )
1084   {
1085     QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(theRow, 2));
1086     if ( clrBtn )
1087     {
1088       QColor qClr;
1089       QString clrStr( theCriterion.ThresholdStr );
1090       QStringList clrVals = clrStr.split( ";" );
1091       if ( clrVals.count() > 2 )
1092         qClr.setRgb( (int)256*clrVals[0].toDouble(),
1093                      (int)256*clrVals[1].toDouble(),
1094                      (int)256*clrVals[2].toDouble() );
1095       clrBtn->setColor( qClr );
1096     }
1097   }
1098   else if (theCriterion.Type == SMESH::FT_ElemGeomType )
1099   {
1100     ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2);
1101     typeBox->setValue( (int)(theCriterion.Threshold + 0.5) );
1102   }
1103   else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
1104       theCriterion.Type != SMESH::FT_BelongToGeom &&
1105       theCriterion.Type != SMESH::FT_BelongToPlane &&
1106       theCriterion.Type != SMESH::FT_BelongToCylinder &&
1107       theCriterion.Type != SMESH::FT_BelongToGenSurface &&
1108       theCriterion.Type != SMESH::FT_LyingOnGeom &&
1109       theCriterion.Type != SMESH::FT_FreeBorders &&
1110       theCriterion.Type != SMESH::FT_FreeEdges &&
1111       theCriterion.Type != SMESH::FT_FreeNodes &&
1112       theCriterion.Type != SMESH::FT_FreeFaces &&
1113       theCriterion.Type != SMESH::FT_BadOrientedVolume &&
1114       theCriterion.Type != SMESH::FT_LinearOrQuadratic)
1115     aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
1116   else
1117   {
1118     aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr));
1119     if ( theCriterion.Type != SMESH::FT_RangeOfIds )
1120       aTable->item( theRow, 5 )->setText( QString( theCriterion.ThresholdID ) );
1121   }
1122
1123   if (theCriterion.Compare  == SMESH::FT_EqualTo ||
1124        theCriterion.Type    == SMESH::FT_BelongToPlane ||
1125        theCriterion.Type    == SMESH::FT_BelongToCylinder ||
1126        theCriterion.Type    == SMESH::FT_BelongToGenSurface ||
1127        theCriterion.Type    == SMESH::FT_BelongToGeom ||
1128        theCriterion.Type    == SMESH::FT_LyingOnGeom)
1129   {
1130     QTableWidgetItem* anItem = aTable->item(theRow, 0);
1131     if (!myAddWidgets.contains(anItem))
1132     {
1133       myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
1134       myWgStack->addWidget(myAddWidgets[ anItem ]);
1135     }
1136     myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance);
1137   }
1138
1139   emit CriterionChanged(theRow, aType);
1140
1141 }
1142
1143 //=======================================================================
1144 // name    : SMESHGUI_FilterTable::Update
1145 // Purpose : Update table
1146 //=======================================================================
1147 void SMESHGUI_FilterTable::Update()
1148 {
1149   Table* aTable = myTables[ GetType() ];
1150   int aCurrRow = aTable->currentRow();
1151   int numRows = aTable->rowCount();
1152   if ((aCurrRow < 0 || aCurrRow >= numRows) && numRows > 0)
1153     aTable->setCurrentCell(0, 0);
1154   updateAdditionalWidget();
1155 }
1156
1157 //=======================================================================
1158 // name    : SMESHGUI_FilterTable::AddCriterion
1159 // Purpose : Add criterion with parameters
1160 //=======================================================================
1161 void SMESHGUI_FilterTable::AddCriterion (const SMESH::Filter::Criterion& theCriterion,
1162                                          const int                       theEntityType)
1163 {
1164   int aType = theEntityType == -1 ? GetType() : theEntityType;
1165   Table* aTable = myTables[ aType ];
1166   addRow(aTable, aType);
1167   SetCriterion(aTable->rowCount() - 1, theCriterion);
1168 }
1169
1170 //=======================================================================
1171 // name    : SMESHGUI_FilterTable::NumRows
1172 // Purpose : Get number of criterions of current type
1173 //=======================================================================
1174 int SMESHGUI_FilterTable::NumRows (const int theEntityType) const
1175 {
1176   return myTables[ theEntityType == -1 ? GetType() : theEntityType ]->rowCount();
1177 }
1178
1179 //=======================================================================
1180 // name    : SMESHGUI_FilterTable::Clear
1181 // Purpose : Clear current table
1182 //=======================================================================
1183 void SMESHGUI_FilterTable::Clear (const int theType)
1184 {
1185   int aType = theType == -1 ? GetType() : theType;
1186   Table* aTable = myTables[ aType ];
1187
1188   if (aTable->rowCount() == 0)
1189     return;
1190
1191   while (aTable->rowCount() > 0)
1192   {
1193     removeAdditionalWidget(aTable, 0);
1194     aTable->removeRow(0);
1195   }
1196
1197   updateBtnState();
1198 }
1199
1200 //=======================================================================
1201 // name    : SMESHGUI_FilterTable::onAddBtn
1202 // Purpose : SLOT. Called then "Add" button pressed.
1203 //           Adds new string to table
1204 //=======================================================================
1205 void SMESHGUI_FilterTable::onAddBtn()
1206 {
1207   int aType = GetType();
1208   addRow(myTables[ aType ], aType);
1209
1210   Update();
1211 }
1212
1213 //=======================================================================
1214 // name    : SMESHGUI_FilterTable::onInsertBtn
1215 // Purpose : SLOT. Called then "Insert" button pressed.
1216 //           Inserts new string before current one
1217 //=======================================================================
1218 void SMESHGUI_FilterTable::onInsertBtn()
1219 {
1220   addRow(myTables[ GetType() ], GetType(), false);
1221 }
1222
1223 //=======================================================================
1224 // name    : SMESHGUI_FilterTable::onRemoveBtn
1225 // Purpose : SLOT. Called then "Remove" button pressed.
1226 //           Removes current string from table
1227 //=======================================================================
1228 void SMESHGUI_FilterTable::onRemoveBtn()
1229 {
1230   Table* aTable = myTables[ GetType() ];
1231
1232   if (aTable->rowCount() == 0)
1233     return;
1234
1235   QList<QTableWidgetItem*> items = aTable->selectedItems();
1236   
1237   QList<int> aRows = aTable->selectedRows(); // already sorted
1238   int i;
1239   foreach( i, aRows )
1240   {
1241     removeAdditionalWidget(aTable, i);
1242     aTable->removeRow(i);
1243   }
1244
1245   // remove control of binary logical operation from last row
1246   if (aTable->rowCount() > 0)
1247     aTable->setEditable(false, aTable->rowCount() - 1, 4);
1248
1249   updateBtnState();
1250 }
1251
1252 //=======================================================================
1253 // name    : SMESHGUI_FilterTable::updateAdditionalWidget
1254 // Purpose : Enable/Disable widget with additonal parameters
1255 //=======================================================================
1256 void SMESHGUI_FilterTable::updateAdditionalWidget()
1257 {
1258   Table* aTable = myTables[ GetType() ];
1259   int aRow = aTable->currentRow();
1260   if (aRow < 0 || aRow >= aTable->rowCount())
1261   {
1262     myWgStack->setEnabled(false);
1263     return;
1264   }
1265
1266   ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
1267   int aCriterion = GetCriterionType(aRow);
1268   bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
1269                   aCriterion != SMESH::FT_RangeOfIds &&
1270                   aCriterion != SMESH::FT_FreeEdges &&
1271                   aCriterion != SMESH::FT_FreeFaces &&
1272                   aCriterion != SMESH::FT_BadOrientedVolume;
1273
1274   if (!myAddWidgets.contains(anItem))
1275   {
1276     myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
1277     myWgStack->addWidget(myAddWidgets[ anItem ]);
1278   }
1279
1280   myWgStack->setCurrentWidget(myAddWidgets[ anItem ]);
1281   myWgStack->setEnabled(toEnable);
1282 }
1283
1284 //=======================================================================
1285 // name    : SMESHGUI_FilterTable::removeAdditionalWidget
1286 // Purpose : Remove widgets containing additional parameters from widget
1287 //           stack and internal map
1288 //=======================================================================
1289 void SMESHGUI_FilterTable::removeAdditionalWidget (QTableWidget* theTable, const int theRow)
1290 {
1291   QTableWidgetItem* anItem = theTable->item(theRow, 0);
1292   if (myAddWidgets.contains(anItem))
1293   {
1294     myWgStack->removeWidget(myAddWidgets[ anItem ]);
1295     myAddWidgets[ anItem ]->setParent(0);
1296     delete myAddWidgets[ anItem ];
1297     myAddWidgets.remove(anItem);
1298   }
1299 }
1300
1301 //=======================================================================
1302 // name    : SMESHGUI_FilterTable::onClearBtn
1303 // Purpose : SLOT. Called then "Clear" button pressed.
1304 //           Removes all strings from table
1305 //=======================================================================
1306 void SMESHGUI_FilterTable::onClearBtn()
1307 {
1308   Table* aTable = myTables[ GetType() ];
1309
1310   if (aTable->rowCount() == 0)
1311     return;
1312
1313   while (aTable->rowCount() > 0)
1314   {
1315     removeAdditionalWidget(aTable, 0);
1316     aTable->removeRow(0);
1317   }
1318
1319   updateBtnState();
1320 }
1321
1322 //=======================================================================
1323 // name    : SMESHGUI_FilterTable::onCurrentChanged()
1324 // Purpose : SLOT. Called when current cell changed
1325 //=======================================================================
1326 void SMESHGUI_FilterTable::onCurrentChanged (int theRow, int theCol)
1327 {
1328   if( !myIsLocked )
1329     updateAdditionalWidget();
1330   emit CurrentChanged(theRow, theCol);
1331 }
1332
1333 //=======================================================================
1334 // name    : geomTypes
1335 // Purpose : returns available geometry types of elements
1336 //=======================================================================
1337 static QList<int> geomTypes( const int theType )
1338 {
1339   QList<int> typeIds;
1340   if ( theType == SMESH::NODE )
1341     typeIds.append( SMESH::Geom_POINT );
1342   if ( theType == SMESH::ALL || theType == SMESH::EDGE )
1343     typeIds.append( SMESH::Geom_EDGE );
1344   if ( theType == SMESH::ALL || theType == SMESH::FACE )
1345   {
1346     typeIds.append( SMESH::Geom_TRIANGLE );
1347     typeIds.append( SMESH::Geom_QUADRANGLE );
1348     typeIds.append( SMESH::Geom_POLYGON );
1349   }
1350   if ( theType == SMESH::ALL || theType == SMESH::VOLUME )
1351   {
1352     typeIds.append( SMESH::Geom_TETRA );
1353     typeIds.append( SMESH::Geom_PYRAMID );
1354     typeIds.append( SMESH::Geom_HEXA );
1355     typeIds.append( SMESH::Geom_PENTA );
1356     typeIds.append( SMESH::Geom_POLYHEDRA );
1357   }
1358   return typeIds;
1359 }
1360
1361 //=======================================================================
1362 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1363 // Purpose : Provides reaction on change of criterion
1364 //=======================================================================
1365 void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, const int entityType)
1366 {
1367   int aType = entityType == -1 ? GetType() : entityType;
1368   Table* aTable = myTables[ aType ];
1369   ComboItem* aCompareItem = (ComboItem*)aTable->item(row, 1);
1370
1371   int aCriterionType = GetCriterionType(row);
1372   QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(row, 2));
1373   bool isComboItem = aTable->item(row, 2)->type() == ComboItem::Type();
1374   
1375   if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
1376        (aCriterionType != SMESH::FT_ElemGeomType && isComboItem) )
1377   {
1378     bool isSignalsBlocked = aTable->signalsBlocked();
1379     aTable->blockSignals( true );
1380     aTable->removeCellWidget( row, 2 );
1381     aTable->setItem( row, 2, new QTableWidgetItem() );
1382     aTable->blockSignals( isSignalsBlocked );
1383   }
1384   if ( (aCriterionType == SMESH::FT_GroupColor && !clrBtn) ||
1385        (aCriterionType == SMESH::FT_ElemGeomType && !isComboItem) )
1386   {
1387     bool isSignalsBlocked = aTable->signalsBlocked();
1388     aTable->blockSignals( true );
1389     if ( aCriterionType == SMESH::FT_GroupColor )
1390       aTable->setCellWidget( row, 2, new QtxColorButton( aTable ) );
1391     else {
1392       QList<int> typeIds = geomTypes( aType );
1393       QMap<int, QString> typeNames;
1394       QList<int>::const_iterator anIter = typeIds.begin();
1395       for ( int i = 0; anIter != typeIds.end(); ++anIter, ++i)
1396       {
1397         QString typeKey = QString( "GEOM_TYPE_%1" ).arg( *anIter );
1398         typeNames[ *anIter ] = tr( typeKey.toLatin1().data() );
1399       }
1400       ComboItem* typeBox = new ComboItem( typeNames );
1401       aTable->setItem( row, 2, typeBox );
1402     }
1403     aTable->blockSignals( isSignalsBlocked );
1404   }
1405
1406   if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ||
1407       aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
1408       aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
1409                                aCriterionType == SMESH::FT_FreeFaces) ||
1410       aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume ||
1411       aCriterionType == SMESH::FT_LinearOrQuadratic ||
1412       aCriterionType == SMESH::FT_GroupColor ||
1413       aCriterionType == SMESH::FT_ElemGeomType)
1414   {
1415     bool isSignalsBlocked = aTable->signalsBlocked();
1416     aTable->blockSignals( true );
1417
1418     if (aCompareItem->count() > 0)
1419       aCompareItem->clear();
1420     aTable->setEditable(false, row, 1);
1421     aTable->setEditable(aCriterionType == SMESH::FT_GroupColor ||
1422                         aCriterionType == SMESH::FT_ElemGeomType, row, 2);
1423     aTable->blockSignals( isSignalsBlocked );
1424   }
1425   else if (aCriterionType == SMESH::FT_RangeOfIds ||
1426            aCriterionType == SMESH::FT_BelongToGeom ||
1427            aCriterionType == SMESH::FT_BelongToPlane ||
1428            aCriterionType == SMESH::FT_BelongToCylinder ||
1429            aCriterionType == SMESH::FT_BelongToGenSurface ||
1430            aCriterionType == SMESH::FT_LyingOnGeom)
1431   {
1432     QMap<int, QString> aMap;
1433     aMap[ SMESH::FT_EqualTo ] = tr("EQUAL_TO");
1434     aCompareItem->setItems(aMap);
1435     if (!aTable->isEditable(row, 2))
1436       aTable->setEditable(true, row, 1);
1437     if (!aTable->isEditable(row, 2))
1438       aTable->setEditable(true, row, 2);
1439   }
1440   else if (aCriterionType == SMESH::FT_GroupColor ||
1441            aCriterionType == SMESH::FT_ElemGeomType)
1442   {
1443     if (!aTable->isEditable(row, 2))
1444       aTable->setEditable(true, row, 2);
1445   }
1446   else
1447   {
1448     if (aCompareItem->count() != 3)
1449     {
1450       aCompareItem->setItems(getCompare());
1451     }
1452
1453     QString aText = aTable->text(row, 2);
1454     bool isOk = false;
1455     aText.toDouble(&isOk);
1456     aTable->item( row, 2 )->setText(isOk ? aText : QString(""));
1457     if (!aTable->isEditable(row, 1))
1458       aTable->setEditable(true, row, 1);
1459     if (!aTable->isEditable(row, 2))
1460       aTable->setEditable(true, row, 2);
1461   }
1462
1463   updateAdditionalWidget();
1464
1465   emit CriterionChanged(row, entityType);
1466 }
1467
1468 //=======================================================================
1469 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1470 // Purpose : SLOT. Called then contents of table changed
1471 //           Provides reaction on change of criterion
1472 //=======================================================================
1473 void SMESHGUI_FilterTable::onCriterionChanged (int row, int col)
1474 {
1475   onCriterionChanged(row, col, -1);
1476 }
1477
1478 //=======================================================================
1479 // name    : SMESHGUI_FilterTable::getFirstSelectedRow
1480 // Purpose : Get first selected row
1481 //=======================================================================
1482 int SMESHGUI_FilterTable::getFirstSelectedRow() const
1483 {
1484   Table* aTable = myTables[ GetType() ];
1485
1486   QList<int> selRows = aTable->selectedRows(); // already sorted
1487   int aRow = selRows.count() > 0 ? selRows[0] : aTable->currentRow();
1488
1489   return aRow >= 0 && aRow < aTable->rowCount() ? aRow : -1;
1490 }
1491
1492 //=======================================================================
1493 // name    : SMESHGUI_FilterTable::addRow
1494 // Purpose : Add row at the end of table
1495 //=======================================================================
1496 void SMESHGUI_FilterTable::addRow (Table* theTable, const int theType, const bool toTheEnd)
1497 {
1498   int aCurrRow = 0;
1499   int aSelectedRow = getFirstSelectedRow();
1500   int aCurrCol = theTable->currentColumn();
1501
1502   myIsLocked = true;
1503   if (toTheEnd || aSelectedRow == -1)
1504   {
1505     theTable->insertRows(theTable->rowCount());
1506     aCurrRow = theTable->rowCount() - 1;
1507   }
1508   else
1509   {
1510     theTable->insertRows(aSelectedRow);
1511     aCurrRow = aSelectedRow;
1512   }
1513   myIsLocked = false;
1514
1515   // IPAL19372 - to prevent calling onCriterionChaged() slot before completion of setItem()
1516   bool isSignalsBlocked = theTable->signalsBlocked();
1517   theTable->blockSignals( true );
1518
1519   // Criteria
1520   theTable->setItem(aCurrRow, 0, getCriterionItem(theType));
1521
1522   // Compare
1523   theTable->setItem(aCurrRow, 1, getCompareItem());
1524
1525   // Threshold
1526   theTable->setItem(aCurrRow, 2, new QTableWidgetItem());
1527
1528   // Logical operation NOT
1529   theTable->setItem(aCurrRow, 3, getUnaryItem());
1530
1531   // Logical operation AND / OR
1532   theTable->setItem(aCurrRow, 4, new QTableWidgetItem());
1533
1534   theTable->setItem(aCurrRow, 5, new QTableWidgetItem());
1535     
1536   theTable->blockSignals( isSignalsBlocked );
1537
1538   // Logical binary operation for previous value
1539   int anAddBinOpStr = -1;
1540   if (aCurrRow == theTable->rowCount() - 1)
1541     anAddBinOpStr = aCurrRow - 1;
1542   else if (aCurrRow >= 0 )
1543     anAddBinOpStr = aCurrRow;
1544
1545   if (theTable->item(aCurrRow, 4) == 0 ||
1546        theTable->item(aCurrRow, 4)->type() != ComboItem::Type())
1547   {
1548     if (anAddBinOpStr >= 0 &&
1549          (theTable->item(anAddBinOpStr, 4) == 0 ||
1550            theTable->item(anAddBinOpStr, 4)->type() != ComboItem::Type()))
1551       theTable->setItem(anAddBinOpStr, 4, getBinaryItem());
1552   }
1553
1554   theTable->setEditable(false, theTable->rowCount() - 1, 4);
1555   
1556   if (aCurrRow >=0 && aCurrRow < theTable->rowCount() &&
1557        aCurrCol >=0 && aCurrCol < theTable->rowCount())
1558   theTable->setCurrentCell(aCurrRow, aCurrCol);
1559
1560   onCriterionChanged(aCurrRow, 0);
1561
1562   updateBtnState();
1563 }
1564
1565 //=======================================================================
1566 // name    : SMESHGUI_FilterTable::getCriterionItem
1567 // Purpose : Get combo table item for criteria of specified type
1568 //=======================================================================
1569 QTableWidgetItem* SMESHGUI_FilterTable::getCriterionItem (const int theType) const
1570 {
1571   return new ComboItem(getCriteria(theType));
1572 }
1573
1574 //=======================================================================
1575 // name    : SMESHGUI_FilterTable::getCompareItem
1576 // Purpose : Get combo table item for operation of comparision
1577 //=======================================================================
1578 QTableWidgetItem* SMESHGUI_FilterTable::getCompareItem () const
1579 {
1580   return new ComboItem(getCompare());
1581 }
1582
1583 //=======================================================================
1584 // name    : SMESHGUI_FilterTable::getBinaryItem
1585 // Purpose :
1586 //=======================================================================
1587 QTableWidgetItem* SMESHGUI_FilterTable::getBinaryItem () const
1588 {
1589   static QMap<int, QString> aMap;
1590   if (aMap.isEmpty())
1591   {
1592     aMap[ SMESH::FT_LogicalAND ] = tr("AND");
1593     aMap[ SMESH::FT_LogicalOR  ] = tr("OR");
1594   }
1595
1596   return new ComboItem(aMap);
1597 }
1598
1599 //=======================================================================
1600 // name    : SMESHGUI_FilterTable::getUnaryItem
1601 // Purpose : Get check table item
1602 //=======================================================================
1603 QTableWidgetItem* SMESHGUI_FilterTable::getUnaryItem () const
1604 {
1605   return new CheckItem(tr("NOT"));
1606 }
1607
1608 //=======================================================================
1609 // name    : SMESHGUI_FilterTable::getSupportedTypes
1610 // Purpose : Get all supported type
1611 //=======================================================================
1612 const QMap<int, QString>& SMESHGUI_FilterTable::getSupportedTypes() const
1613 {
1614   static QMap<int, QString> aTypes;
1615   if (aTypes.isEmpty())
1616   {
1617     aTypes[ SMESH::NODE   ] = tr("NODES");
1618     aTypes[ SMESH::EDGE   ] = tr("EDGES");
1619     aTypes[ SMESH::FACE   ] = tr("FACES");
1620     aTypes[ SMESH::VOLUME ] = tr("VOLUMES");
1621     aTypes[ SMESH::ALL ]    = tr("ELEMENTS");
1622   }
1623
1624   return aTypes;
1625 }
1626
1627 //=======================================================================
1628 // name    : SMESHGUI_FilterTable::getCriteria
1629 // Purpose : Get criteria for specified type
1630 //=======================================================================
1631 const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType) const
1632 {
1633   if (theType == SMESH::NODE)
1634   {
1635     static QMap<int, QString> aCriteria;
1636     if (aCriteria.isEmpty())
1637     {
1638       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
1639       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
1640       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
1641       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
1642       aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
1643       aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
1644       aCriteria[ SMESH::FT_FreeNodes          ] = tr("FREE_NODES");
1645       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
1646     }
1647     return aCriteria;
1648   }
1649   else if (theType == SMESH::EDGE)
1650   {
1651     static QMap<int, QString> aCriteria;
1652     if (aCriteria.isEmpty())
1653     {
1654       aCriteria[ SMESH::FT_FreeBorders        ] = tr("FREE_BORDERS");
1655       aCriteria[ SMESH::FT_MultiConnection    ] = tr("MULTI_BORDERS");
1656       aCriteria[ SMESH::FT_Length             ] = tr("LENGTH");
1657       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
1658       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
1659       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
1660       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
1661       aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
1662       aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
1663       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
1664       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
1665       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
1666     }
1667     return aCriteria;
1668   }
1669   else if (theType == SMESH::FACE)
1670   {
1671     static QMap<int, QString> aCriteria;
1672     if (aCriteria.isEmpty())
1673     {
1674       aCriteria[ SMESH::FT_AspectRatio        ] = tr("ASPECT_RATIO");
1675       aCriteria[ SMESH::FT_Warping            ] = tr("WARPING");
1676       aCriteria[ SMESH::FT_MinimumAngle       ] = tr("MINIMUM_ANGLE");
1677       aCriteria[ SMESH::FT_Taper              ] = tr("TAPER");
1678       aCriteria[ SMESH::FT_Skew               ] = tr("SKEW");
1679       aCriteria[ SMESH::FT_Area               ] = tr("AREA");
1680       aCriteria[ SMESH::FT_FreeEdges          ] = tr("FREE_EDGES");
1681       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
1682       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
1683       aCriteria[ SMESH::FT_BelongToPlane      ] = tr("BELONG_TO_PLANE");
1684       aCriteria[ SMESH::FT_BelongToCylinder   ] = tr("BELONG_TO_CYLINDER");
1685       aCriteria[ SMESH::FT_BelongToGenSurface ] = tr("BELONG_TO_GENSURFACE");
1686       aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
1687       aCriteria[ SMESH::FT_Length2D           ] = tr("LENGTH2D");
1688       aCriteria[ SMESH::FT_MultiConnection2D  ] = tr("MULTI2D_BORDERS");
1689       aCriteria[ SMESH::FT_FreeFaces          ] = tr("FREE_FACES");
1690       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
1691       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
1692       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
1693     }
1694     return aCriteria;
1695   }
1696   else if (theType == SMESH::VOLUME)
1697   {
1698     static QMap<int, QString> aCriteria;
1699     if (aCriteria.isEmpty())
1700     {
1701       aCriteria[ SMESH::FT_AspectRatio3D     ] = tr("ASPECT_RATIO_3D");
1702       aCriteria[ SMESH::FT_RangeOfIds        ] = tr("RANGE_OF_IDS");
1703       aCriteria[ SMESH::FT_BelongToGeom      ] = tr("BELONG_TO_GEOM");
1704       aCriteria[ SMESH::FT_LyingOnGeom       ] = tr("LYING_ON_GEOM");
1705       aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
1706       aCriteria[ SMESH::FT_Volume3D          ] = tr("VOLUME_3D");
1707       aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
1708       aCriteria[ SMESH::FT_GroupColor        ] = tr("GROUP_COLOR");
1709       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
1710     }
1711     return aCriteria;
1712   }
1713   else // SMESH::ALL
1714   {
1715     static QMap<int, QString> aCriteria;
1716     if (aCriteria.isEmpty())
1717     {
1718       aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
1719       aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
1720       aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
1721       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
1722       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
1723       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
1724     }
1725
1726     return aCriteria;
1727   }
1728 }
1729
1730
1731 //=======================================================================
1732 // name    : SMESHGUI_FilterTable::getCompare
1733 // Purpose : Get operation of comparison
1734 //=======================================================================
1735 const QMap<int, QString>& SMESHGUI_FilterTable::getCompare() const
1736 {
1737   static QMap<int, QString> aMap;
1738
1739   if (aMap.isEmpty())
1740   {
1741     aMap[ SMESH::FT_LessThan ] = tr("LESS_THAN");
1742     aMap[ SMESH::FT_MoreThan ] = tr("MORE_THAN");
1743     aMap[ SMESH::FT_EqualTo  ] = tr("EQUAL_TO" );
1744   }
1745
1746   return aMap;
1747 }
1748
1749 //=======================================================================
1750 // name    : SMESHGUI_FilterTable::createTable
1751 // Purpose : Create table
1752 //=======================================================================
1753 SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget*  theParent,
1754                                                                 const int theType)
1755 {
1756   // create table
1757   Table* aTable= new Table(0, 6, theParent);
1758
1759   QHeaderView* aHeaders = aTable->horizontalHeader();
1760
1761   QFontMetrics aMetrics(aHeaders->font());
1762
1763   // append spaces to the header of criteria in order to
1764   // provide visibility of criterion inside comboboxes
1765   static int aMaxLenCr = 0;
1766
1767   if (aMaxLenCr == 0)
1768   {
1769     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
1770     QMap<int, QString>::const_iterator anIter;
1771     for (anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter)
1772       aMaxLenCr = qMax(maxLength(getCriteria(anIter.key()), aMetrics), aMaxLenCr);
1773   }
1774
1775   static int aLenCr = qAbs( aMaxLenCr -
1776                             aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5;
1777
1778   QString aCrStr;
1779   aCrStr.fill(' ', aLenCr);
1780   QString aCoStr;
1781   aCoStr.fill(' ', 10);
1782
1783   QStringList aHeaderLabels;
1784   aHeaderLabels.append( tr("CRITERION") + aCrStr );
1785   aHeaderLabels.append( tr("COMPARE")   + aCoStr );
1786   aHeaderLabels.append( tr("THRESHOLD_VALUE") );
1787   aHeaderLabels.append( tr("UNARY") );
1788   aHeaderLabels.append( tr("BINARY") + "  " );
1789   aHeaderLabels.append( tr("ID") );
1790   aTable->setHorizontalHeaderLabels( aHeaderLabels );
1791   
1792   // set geometry of the table
1793   for (int i = 0; i <= 4; i++)
1794     aTable->resizeColumnToContents(i);
1795
1796   // set the ID column invisible
1797   aTable->hideColumn( 5 );
1798
1799   aTable->updateGeometry();
1800   QSize aSize = aTable->sizeHint();
1801   int aWidth = aSize.width();
1802   aTable->setMinimumSize(QSize(aWidth, aWidth / 2));
1803   aTable->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
1804
1805   connect(aTable, SIGNAL(cellChanged(int, int)),
1806           this,   SLOT(onCriterionChanged(int, int)));
1807
1808   connect(aTable, SIGNAL(currentCellChanged(int, int, int, int)),
1809           this,   SLOT(onCurrentChanged(int, int)));
1810   
1811   return aTable;
1812 }
1813
1814 //=======================================================================
1815 // name    : SMESHGUI_FilterTable::updateBtnState
1816 // Purpose : Update button state
1817 //=======================================================================
1818 void SMESHGUI_FilterTable::updateBtnState()
1819 {
1820   myRemoveBtn->setEnabled(myTables[ GetType() ]->rowCount() > 0);
1821   myClearBtn->setEnabled(myTables[ GetType() ]->rowCount() > 0);
1822 }
1823
1824 //=======================================================================
1825 // name    : SMESHGUI_FilterTable::SetEditable
1826 // Purpose : Set read only flag for tables. Show/hide buttons for work with rows
1827 //=======================================================================
1828 void SMESHGUI_FilterTable::SetEditable (const bool isEditable)
1829 {
1830   TableMap::iterator anIter;
1831   for (anIter = myTables.begin(); anIter != myTables.end(); ++anIter)
1832   {
1833     anIter.value()->setReadOnly(!isEditable);
1834
1835     // Set Flags for CheckItems directly IPAL 19974
1836     Table* aTable = anIter.value();
1837     for (int i = 0, n = aTable->rowCount(); i < n; i++)
1838       for (int j = 0, m = aTable->columnCount(); j < m; j++)
1839         {
1840           QTableWidgetItem* anItem = aTable->item(i, j);
1841           if ( dynamic_cast<SMESHGUI_FilterTable::CheckItem*>( anItem ) ) {
1842             Qt::ItemFlags f = anItem->flags();
1843             if (!isEditable) f = f & ~Qt::ItemIsUserCheckable;
1844             else f = f | Qt::ItemIsUserCheckable;
1845             anItem->setFlags( f );
1846           }
1847         }
1848     //end of IPAL19974
1849
1850     if (isEditable)
1851     {
1852       myAddBtn->show();
1853       myInsertBtn->show();
1854       myRemoveBtn->show();
1855       myClearBtn->show();
1856     }
1857     else
1858     {
1859       myAddBtn->hide();
1860       myInsertBtn->hide();
1861       myRemoveBtn->hide();
1862       myClearBtn->hide();
1863     }
1864   }
1865
1866   QMap<QTableWidgetItem*, AdditionalWidget*>::iterator anIter2;
1867   for (anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2)
1868     anIter2.value()->SetEditable(isEditable);
1869 }
1870
1871 //=======================================================================
1872 // name    : SMESHGUI_FilterTable::SetEnabled
1873 // Purpose : Enable/Disable table. Switching type of elements already enabled
1874 //=======================================================================
1875 void SMESHGUI_FilterTable::SetEnabled (const bool isEnabled)
1876 {
1877   myAddBtn->setEnabled(isEnabled);
1878   myInsertBtn->setEnabled(isEnabled);
1879   myRemoveBtn->setEnabled(isEnabled);
1880   myClearBtn->setEnabled(isEnabled);
1881
1882   if (isEnabled)
1883     updateBtnState();
1884
1885   QMap<QTableWidgetItem*, AdditionalWidget*>::iterator anIter2;
1886   for (anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2)
1887     anIter2.value()->setEnabled(isEnabled);
1888 }
1889
1890 //=======================================================================
1891 // name    : SMESHGUI_FilterTable::IsEditable
1892 // Purpose : Verify whether table is editable
1893 //=======================================================================
1894 bool SMESHGUI_FilterTable::IsEditable() const
1895 {
1896   return !myTables[ GetType() ]->isReadOnly();
1897 }
1898
1899 //=======================================================================
1900 // name    : SMESHGUI_FilterTable::SetLibsEnabled
1901 // Purpose : Show/hide buttons for work with libraries
1902 //=======================================================================
1903 void SMESHGUI_FilterTable::SetLibsEnabled (const bool isEnabled)
1904 {
1905   if (isEnabled)
1906   {
1907     myCopyFromBtn->show();
1908     myAddToBtn->show();
1909   }
1910   else
1911   {
1912     myCopyFromBtn->hide();
1913     myAddToBtn->hide();
1914   }
1915 }
1916
1917 //=======================================================================
1918 // name    : SMESHGUI_FilterTable::onCopyFromBtn
1919 // Purpose : SLOT. Called the "Copy from ..." button clicked
1920 //           Display filter library dialog
1921 //=======================================================================
1922 void SMESHGUI_FilterTable::onCopyFromBtn()
1923 {
1924   if (myLibDlg == 0)
1925     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1926       mySMESHGUI, this, GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM);
1927   else
1928     myLibDlg->Init(GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM);
1929
1930   if (myLibDlg->exec() == QDialog::Accepted)
1931   {
1932     Copy(myLibDlg->GetTable());
1933     Update();
1934   }
1935 }
1936
1937 //=======================================================================
1938 // name    : SMESHGUI_FilterTable::onAddToBtn
1939 // Purpose : SLOT. Called the "Add to ..." button clicked
1940 //           Display filter library dialog
1941 //=======================================================================
1942 void SMESHGUI_FilterTable::onAddToBtn()
1943 {
1944   if (!IsValid(true))
1945     return;
1946   if (myLibDlg == 0)
1947     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1948       mySMESHGUI, this, GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO);
1949   else
1950     myLibDlg->Init(GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO);
1951
1952   myLibDlg->SetTable(this);
1953
1954   myLibDlg->exec();
1955 }
1956
1957 //=======================================================================
1958 // name    : SMESHGUI_FilterTable::Copy
1959 // Purpose : Initialise table with values of other table
1960 //=======================================================================
1961 void SMESHGUI_FilterTable::Copy (const SMESHGUI_FilterTable* theTable)
1962 {
1963   Clear();
1964
1965   for (int i = 0, n = theTable->NumRows(); i < n; i++)
1966   {
1967     SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion();
1968     theTable->GetCriterion(i, aCriterion);
1969     AddCriterion(aCriterion);
1970   }
1971 }
1972
1973 //=======================================================================
1974 // name    : SMESHGUI_FilterTable::CurrentCell
1975 // Purpose : Returns current cell
1976 //=======================================================================
1977 bool SMESHGUI_FilterTable::CurrentCell (int& theRow, int& theCol) const
1978 {
1979   theRow = myTables[ GetType() ]->currentRow();
1980   theCol = myTables[ GetType() ]->currentColumn();
1981   return theRow >= 0 && theCol >= 0;
1982 }
1983
1984 //=======================================================================
1985 // name    : SMESHGUI_FilterTable::SetText
1986 // Purpose : Set text and internal value in cell of threshold value
1987 //=======================================================================
1988 void SMESHGUI_FilterTable::SetThreshold (const int      theRow,
1989                                          const QString& theText,
1990                                          const int      theEntityType)
1991 {
1992   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1993   aTable->item( theRow, 2 )->setText(theText);
1994 }
1995
1996 //=======================================================================
1997 // name    : SMESHGUI_FilterTable::SetText
1998 // Purpose : Get text and internal value from cell of threshold value
1999 //=======================================================================
2000 bool SMESHGUI_FilterTable::GetThreshold (const int      theRow,
2001                                          QString&       theText,
2002                                          const int      theEntityType)
2003 {
2004   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
2005   QTableWidgetItem* anItem = aTable->item(theRow, 2);
2006   if (anItem != 0)
2007   {
2008     theText = anItem->text();
2009     return true;
2010   }
2011   else
2012    return false;
2013 }
2014
2015 //=======================================================================
2016 // name    : SMESHGUI_FilterTable::SetID
2017 // Purpose : Set text and internal value in cell of ID value 
2018 //=======================================================================
2019 void SMESHGUI_FilterTable::SetID( const int      theRow,
2020                                          const QString& theText,
2021                                          const int      theEntityType )
2022 {
2023   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
2024   aTable->item( theRow, 5 )->setText( theText );
2025 }
2026
2027 //=======================================================================
2028 // name    : SMESHGUI_FilterTable::GetID
2029 // Purpose : Get text and internal value from cell of ID value
2030 //=======================================================================
2031 bool SMESHGUI_FilterTable::GetID( const int      theRow,
2032                                   QString&       theText,
2033                                   const int      theEntityType )
2034 {
2035   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
2036   QTableWidgetItem* anItem = aTable->item( theRow, 5 );
2037   if ( anItem != 0 )
2038     {
2039       theText = anItem->text();
2040       return true;    
2041     }
2042   else
2043     return false;
2044
2045
2046 /*
2047   Class       : SMESHGUI_FilterDlg
2048   Description : Dialog to specify filters for VTK viewer
2049 */
2050
2051
2052 //=======================================================================
2053 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
2054 // Purpose : Constructor
2055 //=======================================================================
2056 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*         theModule,
2057                                         const QList<int>& theTypes )
2058 : QDialog( SMESH::GetDesktop( theModule ) ),
2059   mySMESHGUI( theModule ),
2060   mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
2061 {
2062   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2063     mySelector = aViewWindow->GetSelector();
2064
2065   construct(theTypes);
2066 }
2067
2068 //=======================================================================
2069 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
2070 // Purpose : Constructor
2071 //=======================================================================
2072 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*   theModule,
2073                                         const int   theType )
2074 : QDialog( SMESH::GetDesktop( theModule ) ),
2075   mySMESHGUI( theModule ),
2076   mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
2077 {
2078   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2079     mySelector = aViewWindow->GetSelector();
2080   QList<int> aTypes;
2081   aTypes.append(theType);
2082   construct(aTypes);
2083 }
2084
2085 //=======================================================================
2086 // name    : SMESHGUI_FilterDlg::construct
2087 // Purpose : Construct dialog (called by constructor)
2088 //=======================================================================
2089 void SMESHGUI_FilterDlg::construct (const QList<int>& theTypes)
2090 {
2091   myTypes = theTypes;
2092
2093   setModal(false);
2094   //setAttribute(Qt::WA_DeleteOnClose, true); // VSR ??? is it required?
2095   setWindowTitle(tr("CAPTION"));
2096
2097   QVBoxLayout* aDlgLay = new QVBoxLayout (this);
2098   aDlgLay->setMargin(MARGIN);
2099   aDlgLay->setSpacing(SPACING);
2100
2101   myMainFrame         = createMainFrame  (this);
2102   QWidget* aBtnFrame  = createButtonFrame(this);
2103
2104   aDlgLay->addWidget(myMainFrame);
2105   aDlgLay->addWidget(aBtnFrame);
2106
2107   aDlgLay->setStretchFactor(myMainFrame, 1);
2108
2109   myHelpFileName = "selection_filter_library_page.html";
2110
2111   Init(myTypes);
2112 }
2113
2114 //=======================================================================
2115 // name    : SMESHGUI_FilterDlg::createMainFrame
2116 // Purpose : Create frame containing dialog's input fields
2117 //=======================================================================
2118 QWidget* SMESHGUI_FilterDlg::createMainFrame (QWidget* theParent)
2119 {
2120   QWidget* aMainFrame = new QWidget(theParent);
2121   QVBoxLayout* aMainLay = new QVBoxLayout(aMainFrame);
2122   aMainLay->setMargin(0);
2123   aMainLay->setSpacing(SPACING);
2124
2125   // filter frame
2126
2127   myTable = new SMESHGUI_FilterTable( mySMESHGUI, aMainFrame, myTypes );
2128   myTable->SetLibsEnabled(true);
2129
2130   QGroupBox* aGrp = myTable->GetTableGrp();
2131   QGridLayout* aLay = qobject_cast<QGridLayout*>( aGrp->layout() );
2132   int rows = aLay->rowCount();
2133   int cols = aLay->columnCount();
2134
2135   QFrame* aLine = new QFrame(aGrp);
2136   aLine->setFrameStyle(QFrame::HLine | QFrame::Sunken);
2137   aLay->addWidget(aLine, rows++, 0, 1, cols);
2138
2139   mySetInViewer = new QCheckBox(tr("SET_IN_VIEWER"), aGrp);
2140   mySetInViewer->setChecked(true);
2141   aLay->addWidget(mySetInViewer, rows++, 0, 1, cols);
2142
2143   // other controls
2144   QWidget* aSourceGrp = createSourceGroup(aMainFrame);
2145
2146   connect(myTable, SIGNAL(CriterionChanged(const int, const int)),
2147                     SLOT(onCriterionChanged(const int, const int)));
2148
2149   connect(myTable, SIGNAL(CurrentChanged(int, int)),
2150                     SLOT(onCurrentChanged(int, int)));
2151
2152   aMainLay->addWidget(myTable);
2153   aMainLay->addWidget(aSourceGrp);
2154   
2155   return aMainFrame;
2156 }
2157
2158 //=======================================================================
2159 // name    : SMESHGUI_FilterDlg::createSourceFrame
2160 // Purpose : Create frame containing source radio button
2161 //=======================================================================
2162 QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent)
2163 {
2164   QGroupBox* aBox = new QGroupBox(tr("SOURCE"), theParent);
2165   QHBoxLayout* aLay = new QHBoxLayout(aBox);
2166   aLay->setMargin(MARGIN);
2167   aLay->setSpacing(SPACING);
2168
2169   mySourceGrp = new QButtonGroup(theParent);
2170
2171   QRadioButton* aMeshBtn = new QRadioButton(tr("MESH"),          aBox);
2172   QRadioButton* aSelBtn  = new QRadioButton(tr("SELECTION"),     aBox);
2173   QRadioButton* aDlgBtn  = new QRadioButton(tr("CURRENT_DIALOG"),aBox);
2174
2175   aLay->addWidget(aMeshBtn);
2176   aLay->addWidget(aSelBtn);
2177   aLay->addWidget(aDlgBtn);
2178
2179   mySourceGrp->addButton(aMeshBtn, Mesh);
2180   mySourceGrp->addButton(aSelBtn,  Selection);
2181   mySourceGrp->addButton(aDlgBtn,  Dialog);
2182
2183   aSelBtn->setChecked(true);
2184
2185   return aBox;
2186 }
2187
2188 //=======================================================================
2189 // name    : SMESHGUI_FilterDlg::updateMainButtons
2190 // Purpose : Update visibility of main buttons (OK, Cancel, Close ...)
2191 //=======================================================================
2192 void SMESHGUI_FilterDlg::updateMainButtons()
2193 {
2194   if (myTypes.count() == 1)
2195   {
2196     myButtons[ BTN_Cancel ]->show();
2197     myButtons[ BTN_Apply  ]->hide();
2198     myButtons[ BTN_Close  ]->hide();
2199   }
2200   else
2201   {
2202     myButtons[ BTN_Cancel ]->hide();
2203     myButtons[ BTN_Apply  ]->show();
2204     myButtons[ BTN_Close  ]->show();
2205   }
2206
2207 //  updateGeometry();
2208 }
2209
2210 //=======================================================================
2211 // name    : SMESHGUI_FilterDlg::createButtonFrame
2212 // Purpose : Create frame containing buttons
2213 //=======================================================================
2214 QWidget* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent)
2215 {
2216   QGroupBox* aGrp = new QGroupBox(theParent);
2217   QHBoxLayout* aLay = new QHBoxLayout(aGrp);
2218   aLay->setMargin(MARGIN);
2219   aLay->setSpacing(SPACING);
2220
2221   myButtons[ BTN_OK     ] = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGrp);
2222   myButtons[ BTN_Apply  ] = new QPushButton(tr("SMESH_BUT_APPLY"),           aGrp);
2223   myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"),          aGrp);
2224   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"),           aGrp);
2225   myButtons[ BTN_Help   ] = new QPushButton(tr("SMESH_BUT_HELP"),            aGrp);
2226
2227   aLay->addWidget(myButtons[ BTN_OK     ]);
2228   aLay->addSpacing(10);
2229   aLay->addWidget(myButtons[ BTN_Apply  ]);
2230   aLay->addSpacing(10);
2231   aLay->addStretch();
2232   aLay->addWidget(myButtons[ BTN_Cancel ]);
2233   aLay->addWidget(myButtons[ BTN_Close  ]);
2234   aLay->addWidget(myButtons[ BTN_Help   ]);
2235
2236   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
2237   connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
2238   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
2239   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
2240   connect(myButtons[ BTN_Help   ], SIGNAL(clicked()), SLOT(onHelp()));
2241
2242   updateMainButtons();
2243
2244   return aGrp;
2245 }
2246
2247 //=======================================================================
2248 // name    : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
2249 // Purpose : Destructor
2250 //=======================================================================
2251 SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
2252 {
2253 }
2254
2255 //=======================================================================
2256 // name    : SMESHGUI_FilterDlg::Init
2257 // Purpose : Init dialog fields, connect signals and slots, show dialog
2258 //=======================================================================
2259 void SMESHGUI_FilterDlg::Init (const int type)
2260 {
2261   QList<int> aTypes;
2262   aTypes.append(type);
2263   Init(aTypes);
2264 }
2265
2266 //=======================================================================
2267 // name    : SMESHGUI_FilterDlg::Init
2268 // Purpose : Init dialog fields, connect signals and slots, show dialog
2269 //=======================================================================
2270 void SMESHGUI_FilterDlg::Init (const QList<int>& theTypes)
2271 {
2272   mySourceWg  = 0;
2273   myTypes     = theTypes;
2274   myMesh      = SMESH::SMESH_Mesh::_nil();
2275   myIObjects.Clear();
2276   myIsSelectionChanged = false;
2277
2278   myTable->Init(theTypes);
2279
2280   // set caption
2281   if (theTypes.count() == 1)
2282   {
2283     int aType = theTypes.first();
2284     if      (aType == SMESH::NODE  ) setWindowTitle(tr("NODES_TLT"));
2285     else if (aType == SMESH::EDGE  ) setWindowTitle(tr("EDGES_TLT"));
2286     else if (aType == SMESH::FACE  ) setWindowTitle(tr("FACES_TLT"));
2287     else if (aType == SMESH::VOLUME) setWindowTitle(tr("VOLUMES_TLT"));
2288     else if (aType == SMESH::ALL)    setWindowTitle(tr("TLT"));
2289   }
2290   else
2291     setWindowTitle(tr("TLT"));
2292
2293   qApp->processEvents();
2294   updateGeometry();
2295   adjustSize();
2296   setEnabled(true);
2297
2298   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
2299
2300   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
2301   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
2302   
2303   updateMainButtons();
2304   updateSelection();
2305
2306   // Initialise filter table with values of previous filter
2307   QList<int>::const_iterator anIter;
2308   for (anIter = theTypes.begin(); anIter != theTypes.end(); ++anIter)
2309   {
2310     myTable->Clear(*anIter);
2311     if (!myFilter[ *anIter ]->_is_nil())
2312     {
2313       SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2314       if (myFilter[ *anIter ]->GetCriteria(aCriteria))
2315       {
2316         for (int i = 0, n = aCriteria->length(); i < n; i++)
2317           myTable->AddCriterion(aCriteria[ i ], *anIter);
2318       }
2319     }
2320   }
2321
2322   if (myInsertState.contains(theTypes.first()))
2323     mySetInViewer->setChecked(myInsertState[ theTypes.first() ]);
2324   else
2325     mySetInViewer->setChecked(true);
2326
2327   mySourceGrp->button(myApplyToState.contains(theTypes.first()) ? 
2328                       myApplyToState[ theTypes.first() ] :
2329                       Selection)->setChecked(true);
2330 }
2331
2332 //=======================================================================
2333 // name    : SMESHGUI_FilterDlg::onOk
2334 // Purpose : SLOT called when "Ok" button pressed.
2335 //           Assign filters VTK viewer and close dialog
2336 //=======================================================================
2337 void SMESHGUI_FilterDlg::onOk()
2338 {
2339   if (onApply())
2340   {
2341     mySelectionMgr->clearFilters();
2342     disconnect(mySMESHGUI, 0, this, 0);
2343     disconnect(mySelectionMgr, 0, this, 0);
2344     mySMESHGUI->ResetState();
2345     accept();
2346     emit Accepted();
2347   }
2348 }
2349
2350 //=======================================================================
2351 // name    : SMESHGUI_FilterDlg::onClose
2352 // Purpose : SLOT called when "Close" button pressed. Close dialog
2353 //=======================================================================
2354 void SMESHGUI_FilterDlg::onClose()
2355 {
2356   // Restore previously selected object
2357   if (mySelectionMgr)
2358   {
2359     SALOME_ListIO aList;
2360     mySelectionMgr->clearFilters();
2361     mySelectionMgr->clearSelected();
2362     SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter (myIObjects);
2363     for ( ; anIter.More(); anIter.Next())
2364     {
2365       aList.Append(anIter.Key());
2366
2367       TColStd_MapOfInteger aResMap;
2368       const TColStd_IndexedMapOfInteger& anIndMap = anIter.Value();
2369       for (int i = 1, n = anIndMap.Extent(); i <= n; i++)
2370         aResMap.Add(anIndMap(i));
2371
2372       mySelector->AddOrRemoveIndex( anIter.Key(), aResMap, false);
2373       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2374         aViewWindow->highlight( anIter.Key(), true, true );
2375     }
2376     mySelectionMgr->setSelectedObjects(aList, false);
2377   }
2378
2379   disconnect(mySMESHGUI, 0, this, 0);
2380   disconnect(mySelectionMgr, 0, this, 0);
2381   mySMESHGUI->ResetState();
2382   reject();
2383   return;
2384 }
2385
2386 //=================================================================================
2387 // function : onHelp()
2388 // purpose  :
2389 //=================================================================================
2390 void SMESHGUI_FilterDlg::onHelp()
2391 {
2392   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
2393   if (app) 
2394     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
2395   else {
2396     QString platform;
2397 #ifdef WIN32
2398     platform = "winapplication";
2399 #else
2400     platform = "application";
2401 #endif
2402     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
2403                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
2404                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
2405                                                                  platform)).
2406                              arg(myHelpFileName));
2407   }
2408 }
2409
2410 //=======================================================================
2411 // name    : SMESHGUI_FilterDlg::onDeactivate
2412 // Purpose : SLOT called when dialog must be deativated
2413 //=======================================================================
2414 void SMESHGUI_FilterDlg::onDeactivate()
2415 {
2416   setEnabled(false);
2417 }
2418
2419 //=======================================================================
2420 // name    : SMESHGUI_FilterDlg::enterEvent
2421 // Purpose : Event filter
2422 //=======================================================================
2423 void SMESHGUI_FilterDlg::enterEvent (QEvent*)
2424 {
2425 //  mySMESHGUI->EmitSignalDeactivateDialog();
2426   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
2427   mySMESHGUI->ResetState();
2428   setEnabled(true);
2429 }
2430
2431 //=======================================================================
2432 // name    : closeEvent()
2433 // Purpose :
2434 //=======================================================================
2435 void SMESHGUI_FilterDlg::closeEvent (QCloseEvent*)
2436 {
2437   onClose();
2438 }
2439
2440 //=======================================================================
2441 // name    : SMESHGUI_FilterDlg::getIdsFromWg
2442 // Purpose : Retrieve list of ids from given widget
2443 //=======================================================================
2444 void SMESHGUI_FilterDlg::getIdsFromWg (const QWidget* theWg, QList<int>& theRes) const
2445 {
2446   theRes.clear();
2447   if (theWg == 0)
2448     return;
2449
2450   if (theWg->inherits("QListWidget"))
2451   {
2452     const QListWidget* aListBox = qobject_cast<const QListWidget*>( theWg );
2453     bool b;
2454     for (int i = 0, n = aListBox->count(); i < n; i++)
2455     {
2456       int anId = aListBox->item(i)->text().toInt(&b);
2457       if (b)
2458         theRes.append(anId);
2459     }
2460   }
2461   else if (theWg->inherits("QLineEdit"))
2462   {
2463     const QLineEdit* aLineEdit = qobject_cast<const QLineEdit*>( theWg );
2464     QString aStr = aLineEdit->text();
2465     QRegExp aRegExp("(\\d+)");
2466     bool b;
2467     int aPos = 0;
2468     while (aPos >= 0)
2469     {
2470       aPos = aRegExp.indexIn(aStr, aPos);
2471       if (aPos > -1)
2472       {
2473         int anId = aRegExp.cap(1).toInt(&b);
2474         if (b)
2475           theRes.append(anId);
2476         aPos += aRegExp.matchedLength();
2477       }
2478     }
2479   }
2480 }
2481
2482 //=======================================================================
2483 // name    : SMESHGUI_FilterDlg::getSelMode
2484 // Purpose : Get selection mode of specified type
2485 //=======================================================================
2486 Selection_Mode SMESHGUI_FilterDlg::getSelMode (const int theType) const
2487 {
2488   switch (theType)
2489   {
2490     case SMESH::NODE   : return NodeSelection;
2491     case SMESH::EDGE   : return EdgeSelection;
2492     case SMESH::FACE   : return FaceSelection;
2493     case SMESH::VOLUME : return VolumeSelection;
2494     case SMESH::ALL    : return CellSelection;
2495     default            : return ActorSelection;
2496   }
2497
2498 }
2499
2500 //=======================================================================
2501 // name    : SMESHGUI_FilterDlg::setIdsToWg
2502 // Purpose : Insert identifiers in specified widgets
2503 //=======================================================================
2504 void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QList<int>& theIds)
2505 {
2506   if (theWg == 0)
2507     return;
2508
2509   if (theWg->inherits("QListWidget"))
2510   {
2511     QListWidget* aListBox = qobject_cast<QListWidget*>( theWg );
2512     aListBox->clear();
2513
2514     QStringList aStrList;
2515     QList<int>::const_iterator anIter;
2516     for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter)
2517       aStrList.append(QString("%1").arg(*anIter));
2518
2519     aListBox->addItems(aStrList);
2520   }
2521   else if (theWg->inherits("QLineEdit"))
2522   {
2523     QLineEdit* aLineEdit = qobject_cast<QLineEdit*>( theWg );
2524     QString aStr;
2525     QList<int>::const_iterator anIter;
2526
2527     for (anIter = theIds.begin(); anIter != theIds.end(); ++ anIter)
2528       aStr += QString("%1 ").arg(*anIter);
2529
2530     if (!aStr.isEmpty())
2531       aStr.remove(aStr.length() - 1, 1);
2532
2533     aLineEdit->setText(aStr);
2534   }
2535 }
2536
2537 //=======================================================================
2538 // name    : SMESHGUI_FilterDlg::isValid
2539 // Purpose : Verify validity of input data
2540 //=======================================================================
2541 bool SMESHGUI_FilterDlg::isValid() const
2542 {
2543   if (!myTable->IsValid())
2544     return false;
2545
2546   for (int i = 0, n = myTable->NumRows(); i < n; i++)
2547   {
2548     int aType = myTable->GetCriterionType(i);
2549     if (aType == SMESH::FT_BelongToGeom ||
2550         aType == SMESH::FT_BelongToPlane ||
2551         aType == SMESH::FT_BelongToCylinder ||
2552         aType == SMESH::FT_BelongToGenSurface ||
2553         aType == SMESH::FT_LyingOnGeom) {
2554       QString aName;
2555       myTable->GetThreshold(i, aName);
2556
2557       std::vector<_PTR(SObject)> aList =
2558         SMESH::GetActiveStudyDocument()->FindObjectByName(aName.toLatin1().constData(), "GEOM");
2559       if (aList.size() == 0) {
2560         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2561                                      tr("BAD_SHAPE_NAME").arg(aName));
2562         return false;
2563       }
2564
2565       if (aType == SMESH::FT_BelongToCylinder ||
2566           aType == SMESH::FT_BelongToPlane    ||
2567           aType == SMESH::FT_BelongToGenSurface ) {
2568         CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
2569         //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
2570         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
2571         if (!aGeomObj->_is_nil()) {
2572           TopoDS_Shape aFace;
2573           if (!GEOMBase::GetShape(aGeomObj, aFace) ||
2574                aFace.IsNull() ||
2575                aFace.ShapeType() != TopAbs_FACE) {
2576             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2577                                          tr("SHAPE_IS_NOT_A_FACE").arg(aName));
2578             return false;
2579           }
2580
2581           Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace));
2582           if (aSurf.IsNull()) {
2583             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2584                                          tr("SHAPE_IS_NOT_A_FACE").arg(aName));
2585             return false;
2586           }
2587
2588           if (aType == SMESH::FT_BelongToPlane && !aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
2589             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2590                                          tr("SHAPE_IS_NOT_A_PLANE").arg(aName));
2591             return false;
2592           }
2593
2594           if (aType == SMESH::FT_BelongToCylinder && !aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
2595             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2596                                          tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName));
2597             return false;
2598           }
2599         }
2600       }
2601     }
2602   }
2603
2604   return true;
2605 }
2606
2607 //=======================================================================
2608 // name    : SMESHGUI_FilterDlg::SetSourceWg
2609 // Purpose : Set widget of parent dialog containing idsto be filtered if
2610 //           user select corresponding source radio button
2611 //=======================================================================
2612 void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg)
2613 {
2614   mySourceWg = theWg;
2615 }
2616
2617 //=======================================================================
2618 // name    : SMESHGUI_FilterDlg::SetGroupIds
2619 // Purpose : Set mesh
2620 //=======================================================================
2621 void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
2622 {
2623   myMesh = theMesh;
2624   const bool isEnable = !(myMesh->_is_nil());
2625   myButtons[BTN_OK]->setEnabled(isEnable);
2626   myButtons[BTN_Apply]->setEnabled(isEnable);
2627 }
2628
2629 //=======================================================================
2630 // name    : SMESHGUI_FilterDlg::SetSelection
2631 // Purpose : Get filtered ids
2632 //=======================================================================
2633 void SMESHGUI_FilterDlg::SetSelection()
2634 {
2635   if (mySelectionMgr)
2636     disconnect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionDone()));
2637
2638   if (mySelectionMgr) {
2639     myIObjects.Clear();
2640     const SALOME_ListIO& anObjs = mySelector->StoredIObjects();
2641     SALOME_ListIteratorOfListIO anIter (anObjs);
2642     for ( ; anIter.More(); anIter.Next()) {
2643       TColStd_IndexedMapOfInteger aMap;
2644       mySelector->GetIndex(anIter.Value(), aMap);
2645       myIObjects.Bind(anIter.Value(), aMap);
2646     }
2647
2648     connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
2649
2650     updateSelection();
2651   }
2652   else
2653     myIObjects.Clear();
2654 }
2655
2656 //=======================================================================
2657 // name    : SMESHGUI_FilterDlg::onApply
2658 // Purpose : SLOT called when "Apply" button pressed.
2659 //           Assign filters to VTK viewer
2660 //=======================================================================
2661 bool SMESHGUI_FilterDlg::onApply()
2662 {
2663   if (!isValid())
2664     return false;
2665
2666   try {
2667     int aCurrType = myTable->GetType();
2668
2669     if (!createFilter(aCurrType))
2670       return false;
2671
2672     insertFilterInViewer();
2673
2674     if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) {
2675       QList<int> aResultIds;
2676       filterSource(aCurrType, aResultIds);
2677       selectInViewer(aCurrType, aResultIds);
2678     }
2679
2680     myInsertState[ aCurrType ] = mySetInViewer->isChecked();
2681     myApplyToState[ aCurrType ] = mySourceGrp->checkedId();
2682   }
2683   catch(const SALOME::SALOME_Exception& S_ex)
2684   {
2685     SalomeApp_Tools::QtCatchCorbaException(S_ex);
2686   }
2687   catch(...)
2688   {
2689   }
2690
2691   return true;
2692 }
2693
2694 //=======================================================================
2695 // name    : SMESHGUI_FilterDlg::createFilter
2696 // Purpose : Create predicate for given type
2697 //=======================================================================
2698 bool SMESHGUI_FilterDlg::createFilter (const int theType)
2699 {
2700   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
2701   if (aFilterMgr->_is_nil())
2702     return false;
2703
2704   int n = myTable->NumRows();
2705
2706   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2707   aCriteria->length(n);
2708
2709   long aPrecision = -1;
2710   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
2711
2712   if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) )
2713     aPrecision = mgr->integerValue( "SMESH", "controls_precision", aPrecision );
2714
2715   for (CORBA::ULong i = 0; i < n; i++) {
2716     SMESH::Filter::Criterion aCriterion = createCriterion();
2717     myTable->GetCriterion(i, aCriterion);
2718     aCriterion.Precision = aPrecision;
2719     aCriteria[ i ] = aCriterion;
2720   }
2721
2722   myFilter[ theType ] = aFilterMgr->CreateFilter();
2723   myFilter[ theType ]->SetCriteria(aCriteria.inout());
2724
2725   return true;
2726 }
2727
2728 //=======================================================================
2729 // name    : SMESHGUI_FilterDlg::insertFilterInViewer
2730 // Purpose : Insert filter in viewer
2731 //=======================================================================
2732 void SMESHGUI_FilterDlg::insertFilterInViewer()
2733 {
2734   if (SVTK_Selector* aSelector = SMESH::GetSelector()) {
2735     SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType();
2736
2737     if (myFilter[ myTable->GetType() ]->_is_nil() ||
2738          myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() ||
2739          !mySetInViewer->isChecked()) {
2740       SMESH::RemoveFilter(getFilterId(anEntType), aSelector);
2741     }
2742     else {
2743       Handle(SMESHGUI_PredicateFilter) aFilter = new SMESHGUI_PredicateFilter();
2744       aFilter->SetPredicate(myFilter[ myTable->GetType() ]->GetPredicate());
2745       SMESH::RemoveFilter(getFilterId(anEntType), aSelector); //skl for IPAL12631
2746       SMESH::SetFilter(aFilter, aSelector);
2747     }
2748   }
2749 }
2750
2751 //=======================================================================
2752 // name    : SMESHGUI_FilterDlg::filterSource
2753 // Purpose : Filter source ids
2754 //=======================================================================
2755 void SMESHGUI_FilterDlg::filterSource (const int theType,
2756                                        QList<int>& theResIds)
2757 {
2758   theResIds.clear();
2759   if (myFilter[ theType ]->_is_nil())
2760     return;
2761
2762   int aSourceId = mySourceGrp->checkedId();
2763
2764   if (aSourceId == Mesh)
2765   {
2766     if (myMesh->_is_nil())
2767       return;
2768     SMESH::long_array_var anIds = myFilter[ theType ]->GetElementsId(myMesh);
2769     for (int i = 0, n = anIds->length(); i < n; i++)
2770       theResIds.append(anIds[ i ]);
2771   }
2772   else if (aSourceId == Selection)
2773   {
2774     filterSelectionSource(theType, theResIds);
2775   }
2776   else if (aSourceId == Dialog)
2777   {
2778     // retrieve ids from dialog
2779     QList<int> aDialogIds;
2780     getIdsFromWg(mySourceWg, aDialogIds);
2781
2782     if (myMesh->_is_nil())
2783     {
2784       theResIds = aDialogIds;
2785       return;
2786     }
2787
2788     // filter ids
2789     SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2790     aPred->SetMesh(myMesh);
2791     QList<int>::const_iterator anIter;
2792     for (anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter)
2793       if (aPred->IsSatisfy(*anIter))
2794         theResIds.append(*anIter);
2795
2796     // set ids to the dialog
2797     setIdsToWg(mySourceWg, theResIds);
2798   }
2799 }
2800
2801 //=======================================================================
2802 // name    : SMESHGUI_FilterDlg::filterSelectionSource
2803 // Purpose : Filter source selection
2804 //=======================================================================
2805 void SMESHGUI_FilterDlg::filterSelectionSource (const int theType,
2806                                                 QList<int>& theResIds)
2807 {
2808   theResIds.clear();
2809   if (myMesh->_is_nil() || mySelectionMgr == 0)
2810     return;
2811
2812   // Create map of entities to be filtered
2813   TColStd_MapOfInteger aToBeFiltered;
2814   SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter(myIObjects);
2815
2816   for ( ; anIter.More(); anIter.Next())
2817   {
2818     // process sub mesh
2819     SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Key());
2820     if (!aSubMesh->_is_nil())
2821     {
2822       if (aSubMesh->GetFather()->GetId() == myMesh->GetId())
2823       {
2824         SMESH::long_array_var anIds =
2825           theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId();
2826         for (int i = 0, n = anIds->length(); i < n; i++)
2827           aToBeFiltered.Add(anIds[ i ]);
2828       }
2829     }
2830
2831     // process group
2832     SMESH::SMESH_GroupBase_var aGroup =
2833       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Key());
2834     if (!aGroup->_is_nil())
2835     {
2836       if (aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId())
2837       {
2838         SMESH::long_array_var anIds = aGroup->GetListOfID();
2839         for (int i = 0, n = anIds->length(); i < n; i++)
2840           aToBeFiltered.Add(anIds[ i ]);
2841       }
2842     }
2843
2844     // process mesh
2845     SMESH::SMESH_Mesh_var aMeshPtr = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIter.Key());
2846     if (!aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId())
2847     {
2848       const TColStd_IndexedMapOfInteger& aSelMap = anIter.Value();
2849
2850       if (aSelMap.Extent() > 0)
2851       {
2852         if(SMESH::FindActorByEntry(anIter.Key()->getEntry()))
2853         {
2854           for (int i = 1; i <= aSelMap.Extent(); i++)
2855             aToBeFiltered.Add(aSelMap(i));
2856         }
2857       }
2858     }
2859   }
2860
2861   // Filter entities
2862   SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2863   aPred->SetMesh(myMesh);
2864   TColStd_MapIteratorOfMapOfInteger aResIter(aToBeFiltered);
2865   for ( ; aResIter.More(); aResIter.Next())
2866     if (aPred->IsSatisfy(aResIter.Key()))
2867       theResIds.append(aResIter.Key());
2868 }
2869
2870 //=======================================================================
2871 // name    : SMESHGUI_FilterDlg::selectInViewer
2872 // Purpose : Select given entities in viewer
2873 //=======================================================================
2874 void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QList<int>& theIds)
2875 {
2876   if (mySelectionMgr == 0 || myMesh->_is_nil())
2877     return;
2878
2879   mySelectionMgr->clearFilters();
2880
2881   // Set new selection mode if necessary
2882   Selection_Mode aSelMode = getSelMode(theType);
2883   SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
2884   if ( aViewWindow && aViewWindow->SelectionMode()!=aSelMode) {
2885     mySelectionMgr->clearSelected();
2886     mySelectionMgr->clearFilters();
2887     if (aSelMode == NodeSelection)
2888       SMESH::SetPointRepresentation(true);
2889     aViewWindow->SetSelectionMode(aSelMode);
2890   }
2891
2892   // Clear selection
2893   SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
2894   if (!anActor || !anActor->hasIO())
2895     return;
2896
2897   Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
2898   //mySelectionMgr->clearSelected();
2899   //mySelectionMgr->AddIObject(anIO, false);
2900   SALOME_ListIO aList;
2901   aList.Append(anIO);
2902   mySelectionMgr->setSelectedObjects(aList, false);
2903
2904   // Remove filter corresponding to the current type from viewer
2905   int aType = myTable->GetType();
2906   int aFilterId = SMESH::UnknownFilter;
2907   if      (aType == SMESH::EDGE  ) aFilterId = SMESH::EdgeFilter;
2908   else if (aType == SMESH::FACE  ) aFilterId = SMESH::FaceFilter;
2909   else if (aType == SMESH::VOLUME) aFilterId = SMESH::VolumeFilter;
2910   Handle(VTKViewer_Filter) aFilter = SMESH::GetFilter(aFilterId);
2911   SMESH::RemoveFilter(aFilterId);
2912
2913   // get vtk ids
2914   TColStd_MapOfInteger aMap;
2915   QList<int>::const_iterator anIter;
2916   for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) {
2917     aMap.Add(*anIter);
2918   }
2919
2920   // Set new selection
2921   mySelector->AddOrRemoveIndex(anIO, aMap, false);
2922   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2923     aViewWindow->highlight( anIO, true, true );
2924
2925   // insert previously stored filter in viewer if necessary
2926   if (!aFilter.IsNull())
2927     SMESH::SetFilter(aFilter);
2928 }
2929
2930 //=======================================================================
2931 // name    : SMESHGUI_FilterDlg::createCriterion
2932 // Purpose : Create criterion structure with default values
2933 //=======================================================================
2934 SMESH::Filter::Criterion SMESHGUI_FilterDlg::createCriterion()
2935 {
2936    SMESH::Filter::Criterion aCriterion;
2937
2938   aCriterion.Type          = SMESH::FT_Undefined;
2939   aCriterion.Compare       = SMESH::FT_Undefined;
2940   aCriterion.Threshold     = 0;
2941   aCriterion.UnaryOp       = SMESH::FT_Undefined;
2942   aCriterion.BinaryOp      = SMESH::FT_Undefined;
2943   aCriterion.ThresholdStr  = "";
2944   aCriterion.ThresholdID   = "";
2945   aCriterion.TypeOfElement = SMESH::ALL;
2946
2947   return aCriterion;
2948 }
2949
2950 //=======================================================================
2951 // name    : SMESHGUI_FilterDlg::onSelectionDone
2952 // Purpose : SLOT called when selection changed.
2953 //           If current cell corresponds to the threshold value of
2954 //           BelongToGeom criterion name of selected object is set in this cell
2955 //=======================================================================
2956 void SMESHGUI_FilterDlg::onSelectionDone()
2957 {
2958   int aRow, aCol;
2959   const SALOME_ListIO& aList = mySelector->StoredIObjects();
2960
2961   if ( myMesh->_is_nil() && aList.Extent()>0 ) {
2962     myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First());
2963     if ( !(myMesh->_is_nil()) ) {
2964       myButtons[BTN_OK]->setEnabled(true);
2965       myButtons[BTN_Apply]->setEnabled(true);
2966     }
2967   }
2968
2969   int aCriterionType = myTable->GetCriterionType(aRow);
2970   if (aList.Extent() != 1 ||
2971       !myTable->CurrentCell(aRow, aCol) ||
2972       aCriterionType != SMESH::FT_BelongToGeom &&
2973       aCriterionType != SMESH::FT_BelongToPlane &&
2974       aCriterionType != SMESH::FT_BelongToCylinder &&
2975       aCriterionType != SMESH::FT_BelongToGenSurface &&
2976       aCriterionType != SMESH::FT_LyingOnGeom)
2977     return;
2978
2979   Handle(SALOME_InteractiveObject) anIO = aList.First();
2980   GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
2981   if (!anObj->_is_nil())
2982     {
2983       myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
2984       //myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj));
2985       myTable->SetID(aRow, anIO->getEntry());
2986     }
2987 }
2988
2989
2990 //=======================================================================
2991 // name    : SMESHGUI_FilterDlg::onCriterionChanged
2992 // Purpose : SLOT called when cretarion of current row changed. Update selection
2993 //=======================================================================
2994 void SMESHGUI_FilterDlg::onCriterionChanged (const int, const int)
2995 {
2996   updateSelection();
2997 }
2998
2999 //=======================================================================
3000 // name    : SMESHGUI_FilterDlg::onCurrentChanged
3001 // Purpose : SLOT called when current row changed. Update selection
3002 //=======================================================================
3003 void SMESHGUI_FilterDlg::onCurrentChanged (int, int)
3004 {
3005   updateSelection();
3006 }
3007
3008 //=======================================================================
3009 // name    : SMESHGUI_FilterDlg::updateSelection
3010 // Purpose : UpdateSelection in accordance with current row
3011 //=======================================================================
3012 void SMESHGUI_FilterDlg::updateSelection()
3013 {
3014   if (mySelectionMgr == 0)
3015     return;
3016
3017   TColStd_MapOfInteger allTypes;
3018   for( int i=0; i<10; i++ )
3019     allTypes.Add( i );
3020   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
3021   if( !aStudy )
3022     return;
3023
3024
3025   mySelectionMgr->clearFilters();
3026
3027   int aRow, aCol;
3028
3029   int aCriterionType = myTable->GetCriterionType(aRow);
3030   if (myTable->CurrentCell(aRow, aCol) &&
3031       (aCriterionType == SMESH::FT_BelongToGeom ||
3032        aCriterionType == SMESH::FT_BelongToPlane ||
3033        aCriterionType == SMESH::FT_BelongToCylinder ||
3034        aCriterionType == SMESH::FT_BelongToGenSurface ||
3035        aCriterionType == SMESH::FT_LyingOnGeom)) {
3036
3037     if (aCriterionType == SMESH::FT_BelongToGeom ||
3038         aCriterionType == SMESH::FT_BelongToGenSurface ||
3039         aCriterionType == SMESH::FT_LyingOnGeom) {
3040
3041       mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true ));
3042
3043     } else if (aCriterionType == SMESH::FT_BelongToPlane) {
3044       mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Plane ) );
3045
3046     } else if (aCriterionType == SMESH::FT_BelongToCylinder) {
3047       mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Cylinder ) );
3048     }
3049     myIsSelectionChanged = true;
3050
3051   } else {
3052     if (myIsSelectionChanged) {
3053       mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
3054     }
3055   }
3056 }
3057
3058 //=================================================================================
3059 // function : keyPressEvent()
3060 // purpose  :
3061 //=================================================================================
3062 void SMESHGUI_FilterDlg::keyPressEvent( QKeyEvent* e )
3063 {
3064   QDialog::keyPressEvent( e );
3065   if ( e->isAccepted() )
3066     return;
3067
3068   if ( e->key() == Qt::Key_F1 ) {
3069     e->accept();
3070     onHelp();
3071   }
3072 }