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