Salome HOME
1235ce71e9133638fc9448e25ba2dfab24aedb58
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_FilterDlg.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // SMESH SMESHGUI : GUI for SMESH component
23 // File   : SMESHGUI_FilterDlg.cxx
24 // Author : Sergey LITONIN, Open CASCADE S.A.S.
25 // SMESH includes
26 //
27 #include "SMESHGUI_FilterDlg.h"
28
29 #include "SMESHGUI.h"
30 #include "SMESHGUI_Utils.h"
31 #include "SMESHGUI_VTKUtils.h"
32 #include "SMESHGUI_Filter.h"
33 #include "SMESHGUI_FilterUtils.h"
34 #include "SMESHGUI_FilterLibraryDlg.h"
35
36 #include <SMESH_Actor.h>
37 #include <SMESH_NumberFilter.hxx>
38 #include <SMESH_TypeFilter.hxx>
39
40 // SALOME GEOM includes
41 #include <GEOMBase.h>
42 #include <GEOM_FaceFilter.h>
43 #include <GEOM_TypeFilter.h>
44
45 // SALOME GUI includes
46 #include <SUIT_Desktop.h>
47 #include <SUIT_ResourceMgr.h>
48 #include <SUIT_Session.h>
49 #include <SUIT_MessageBox.h>
50 #include <QtxComboBox.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_ElemGeomType ) {
914       QtxComboBox* typeBox = qobject_cast<QtxComboBox*>(aTable->cellWidget(i, 2));
915       if (typeBox && typeBox->currentId() == -1)
916         errMsg = tr( "ERROR" );
917     } else if (aCriterion == SMESH::FT_RangeOfIds ||
918          aCriterion == SMESH::FT_BelongToGeom ||
919          aCriterion == SMESH::FT_BelongToPlane ||
920          aCriterion == SMESH::FT_BelongToCylinder ||
921          aCriterion == SMESH::FT_BelongToGenSurface ||
922          aCriterion == SMESH::FT_LyingOnGeom) {
923       if (aTable->text(i, 2).isEmpty());
924         errMsg = tr( "ERROR" );
925     }
926     else {
927       bool aRes = false;
928       bool isSignalsBlocked = aTable->signalsBlocked();
929       aTable->blockSignals(true);
930       double  aThreshold = (int)aTable->text(i, 2).toDouble(&aRes);
931       aTable->blockSignals(isSignalsBlocked);
932
933       if (!aRes && aTable->isEditable(i, 2))
934         errMsg = tr( "ERROR" );
935       else if (aType == SMESH::EDGE &&
936                 GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
937                 aThreshold == 1)
938         errMsg = tr( "MULTIEDGES_ERROR" );
939     }
940
941     if (!errMsg.isEmpty()) {
942       if (theMess)
943         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), errMsg );
944       return false;
945     }
946
947     QTableWidgetItem* anItem = aTable->item(i, 0);
948     if (myAddWidgets.contains(anItem) && !myAddWidgets[ anItem ]->IsValid())
949       return false;
950   }
951
952   return true;
953 }
954
955 //=======================================================================
956 // name    : SMESHGUI_FilterTable::SetValidity
957 // Purpose : Set validity of the table
958 //=======================================================================
959 void SMESHGUI_FilterTable::SetValidity (const bool isValid)
960 {
961   myIsValid = isValid;
962 }
963
964 //=======================================================================
965 // name    : SMESHGUI_FilterTable::GetType
966 // Purpose : Get current entity type
967 //=======================================================================
968 int SMESHGUI_FilterTable::GetType() const
969 {
970   return myEntityType;
971 }
972
973 //=======================================================================
974 // name    : SMESHGUI_FilterTable::SetType
975 // Purpose : Set current entity type
976 //=======================================================================
977 void SMESHGUI_FilterTable::SetType (const int type)
978 {
979   myEntityTypeGrp->button(type)->setChecked(true);
980   onEntityType(type);
981 }
982
983 //=======================================================================
984 // name    : SMESHGUI_FilterTable::RestorePreviousEntityType
985 // Purpose : Restore previous entity type
986 //=======================================================================
987 void SMESHGUI_FilterTable::RestorePreviousEntityType()
988 {
989   SetType(myEntityType);
990 }
991
992 //=======================================================================
993 // name    : SMESHGUI_FilterTable::GetCriterionType
994 // Purpose : Get type of criterion from specified row (corresponding enums in h-file)
995 //=======================================================================
996 int SMESHGUI_FilterTable::GetCriterionType (const int theRow, const int theType) const
997 {
998   int aType = theType == -1 ? GetType() : theType;
999   Table* aTable = myTables[ aType ];
1000   ComboItem* anItem = (ComboItem*)aTable->item(theRow, 0);
1001   return anItem != 0 ? anItem->value() : SMESH::FT_Undefined;
1002 }
1003
1004 //=======================================================================
1005 // name    : SMESHGUI_FilterTable::GetCriterion
1006 // Purpose : Get parameters of criterion from specified row
1007 //=======================================================================
1008 void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
1009                                          SMESH::Filter::Criterion& theCriterion,
1010                                          const int                 theEntityType) const
1011 {
1012   int aType = theEntityType == -1 ? GetType() : theEntityType;
1013   Table* aTable = myTables[ aType ];
1014
1015   theCriterion.Type = ((ComboItem*)aTable->item(theRow, 0))->value();
1016   theCriterion.UnaryOp = ((CheckItem*)aTable->item(theRow, 3))->checked() ? SMESH::FT_LogicalNOT : SMESH::FT_Undefined;
1017   theCriterion.BinaryOp = theRow != aTable->rowCount() - 1 ?
1018     ((ComboItem*)aTable->item(theRow, 4))->value() : SMESH::FT_Undefined;
1019   theCriterion.TypeOfElement = (SMESH::ElementType)aType;
1020
1021   int aCriterionType = GetCriterionType(theRow, aType);
1022
1023   if ( aCriterionType == SMESH::FT_GroupColor )
1024   {
1025     QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(theRow, 2));
1026     if ( clrBtn )
1027     {
1028       const QColor qClr = clrBtn->color();
1029       QString clrStr = QString( "%1;%2;%3" ).
1030         arg( qClr.red()/256. ).arg( qClr.green()/256. ).arg( qClr.blue()/256. );
1031       theCriterion.ThresholdStr = clrStr.toLatin1().constData();
1032     }
1033   }
1034   else if ( aCriterionType == SMESH::FT_ElemGeomType ) {
1035     QtxComboBox* typeBox = qobject_cast<QtxComboBox*>(aTable->cellWidget(theRow, 2));
1036     if ( typeBox )
1037       theCriterion.Threshold = (double)typeBox->currentId();
1038   }
1039   else if ( aCriterionType != SMESH::FT_RangeOfIds &&
1040             aCriterionType != SMESH::FT_BelongToGeom &&
1041             aCriterionType != SMESH::FT_BelongToPlane &&
1042             aCriterionType != SMESH::FT_BelongToCylinder &&
1043             aCriterionType != SMESH::FT_BelongToGenSurface &&
1044             aCriterionType != SMESH::FT_LyingOnGeom)
1045   {
1046     theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value();
1047     theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
1048   }
1049   else
1050   {
1051     theCriterion.ThresholdStr = aTable->text(theRow, 2).toLatin1().constData();
1052     if ( aCriterionType != SMESH::FT_RangeOfIds )
1053       theCriterion.ThresholdID = aTable->text( theRow, 5 ).toLatin1().constData();
1054   }
1055
1056   QTableWidgetItem* anItem = aTable->item(theRow, 0);
1057   if (myAddWidgets.contains(anItem))
1058     theCriterion.Tolerance = myAddWidgets[ anItem ]->GetDouble(AdditionalWidget::Tolerance);
1059 }
1060
1061 //=======================================================================
1062 // name    : SMESHGUI_FilterTable::SetCriterion
1063 // Purpose : Set parameters of criterion of specified row
1064 //=======================================================================
1065 void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
1066                                          const SMESH::Filter::Criterion& theCriterion,
1067                                          const int                       theEntityType)
1068 {
1069   int aType = theEntityType == -1 ? GetType() : theEntityType;
1070
1071   Table* aTable = myTables[ aType ];
1072
1073   if (theRow > aTable->rowCount() - 1)
1074     return;
1075
1076   ((ComboItem*)aTable->item(theRow, 0))->setValue(theCriterion.Type);
1077   onCriterionChanged(theRow, 0, aType);
1078   ((ComboItem*)aTable->item(theRow, 1))->setValue(theCriterion.Compare);
1079   ((CheckItem*)aTable->item(theRow, 3))->setChecked(theCriterion.UnaryOp == SMESH::FT_LogicalNOT);
1080
1081   if (theCriterion.BinaryOp != SMESH::FT_Undefined)
1082   {
1083     if (!aTable->isEditable(theRow, 4))
1084       aTable->setItem(theRow, 4, getBinaryItem());
1085     ((ComboItem*)aTable->item(theRow, 4))->setValue(theCriterion.BinaryOp);
1086   }
1087   else
1088     aTable->setEditable(false, theRow, 4);
1089
1090   if (theCriterion.Type == SMESH::FT_GroupColor )
1091   {
1092     QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(theRow, 2));
1093     if ( clrBtn )
1094     {
1095       QColor qClr;
1096       QString clrStr( theCriterion.ThresholdStr );
1097       QStringList clrVals = clrStr.split( ";" );
1098       if ( clrVals.count() > 2 )
1099         qClr.setRgb( (int)256*clrVals[0].toDouble(),
1100                      (int)256*clrVals[1].toDouble(),
1101                      (int)256*clrVals[2].toDouble() );
1102       clrBtn->setColor( qClr );
1103     }
1104   }
1105   else if (theCriterion.Type == SMESH::FT_ElemGeomType )
1106   {
1107     QtxComboBox* typeBox = qobject_cast<QtxComboBox*>(aTable->cellWidget(theRow, 2));
1108     if ( typeBox )
1109       typeBox->setCurrentId( (int)(theCriterion.Threshold + 0.5) );
1110   }
1111   else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
1112       theCriterion.Type != SMESH::FT_BelongToGeom &&
1113       theCriterion.Type != SMESH::FT_BelongToPlane &&
1114       theCriterion.Type != SMESH::FT_BelongToCylinder &&
1115       theCriterion.Type != SMESH::FT_BelongToGenSurface &&
1116       theCriterion.Type != SMESH::FT_LyingOnGeom &&
1117       theCriterion.Type != SMESH::FT_FreeBorders &&
1118       theCriterion.Type != SMESH::FT_FreeEdges &&
1119       theCriterion.Type != SMESH::FT_FreeNodes &&
1120       theCriterion.Type != SMESH::FT_FreeFaces &&
1121       theCriterion.Type != SMESH::FT_BadOrientedVolume &&
1122       theCriterion.Type != SMESH::FT_LinearOrQuadratic)
1123     aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
1124   else
1125   {
1126     aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr));
1127     if ( theCriterion.Type != SMESH::FT_RangeOfIds )
1128       aTable->item( theRow, 5 )->setText( QString( theCriterion.ThresholdID ) );
1129   }
1130
1131   if (theCriterion.Compare == SMESH::FT_EqualTo ||
1132        theCriterion.Type    == SMESH::FT_BelongToPlane ||
1133        theCriterion.Type    == SMESH::FT_BelongToCylinder ||
1134        theCriterion.Type    == SMESH::FT_BelongToGenSurface)
1135   {
1136     QTableWidgetItem* anItem = aTable->item(theRow, 0);
1137     if (!myAddWidgets.contains(anItem))
1138     {
1139       myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
1140       myWgStack->addWidget(myAddWidgets[ anItem ]);
1141     }
1142     myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance);
1143   }
1144
1145   emit CriterionChanged(theRow, aType);
1146
1147 }
1148
1149 //=======================================================================
1150 // name    : SMESHGUI_FilterTable::Update
1151 // Purpose : Update table
1152 //=======================================================================
1153 void SMESHGUI_FilterTable::Update()
1154 {
1155   Table* aTable = myTables[ GetType() ];
1156   int aCurrRow = aTable->currentRow();
1157   int numRows = aTable->rowCount();
1158   if ((aCurrRow < 0 || aCurrRow >= numRows) && numRows > 0)
1159     aTable->setCurrentCell(0, 0);
1160   updateAdditionalWidget();
1161 }
1162
1163 //=======================================================================
1164 // name    : SMESHGUI_FilterTable::AddCriterion
1165 // Purpose : Add criterion with parameters
1166 //=======================================================================
1167 void SMESHGUI_FilterTable::AddCriterion (const SMESH::Filter::Criterion& theCriterion,
1168                                          const int                       theEntityType)
1169 {
1170   int aType = theEntityType == -1 ? GetType() : theEntityType;
1171   Table* aTable = myTables[ aType ];
1172   addRow(aTable, aType);
1173   SetCriterion(aTable->rowCount() - 1, theCriterion);
1174 }
1175
1176 //=======================================================================
1177 // name    : SMESHGUI_FilterTable::NumRows
1178 // Purpose : Get number of criterions of current type
1179 //=======================================================================
1180 int SMESHGUI_FilterTable::NumRows (const int theEntityType) const
1181 {
1182   return myTables[ theEntityType == -1 ? GetType() : theEntityType ]->rowCount();
1183 }
1184
1185 //=======================================================================
1186 // name    : SMESHGUI_FilterTable::Clear
1187 // Purpose : Clear current table
1188 //=======================================================================
1189 void SMESHGUI_FilterTable::Clear (const int theType)
1190 {
1191   int aType = theType == -1 ? GetType() : theType;
1192   Table* aTable = myTables[ aType ];
1193
1194   if (aTable->rowCount() == 0)
1195     return;
1196
1197   while (aTable->rowCount() > 0)
1198   {
1199     removeAdditionalWidget(aTable, 0);
1200     aTable->removeRow(0);
1201   }
1202
1203   updateBtnState();
1204 }
1205
1206 //=======================================================================
1207 // name    : SMESHGUI_FilterTable::onAddBtn
1208 // Purpose : SLOT. Called then "Add" button pressed.
1209 //           Adds new string to table
1210 //=======================================================================
1211 void SMESHGUI_FilterTable::onAddBtn()
1212 {
1213   int aType = GetType();
1214   addRow(myTables[ aType ], aType);
1215
1216   Update();
1217 }
1218
1219 //=======================================================================
1220 // name    : SMESHGUI_FilterTable::onInsertBtn
1221 // Purpose : SLOT. Called then "Insert" button pressed.
1222 //           Inserts new string before current one
1223 //=======================================================================
1224 void SMESHGUI_FilterTable::onInsertBtn()
1225 {
1226   addRow(myTables[ GetType() ], GetType(), false);
1227 }
1228
1229 //=======================================================================
1230 // name    : SMESHGUI_FilterTable::onRemoveBtn
1231 // Purpose : SLOT. Called then "Remove" button pressed.
1232 //           Removes current string from table
1233 //=======================================================================
1234 void SMESHGUI_FilterTable::onRemoveBtn()
1235 {
1236   Table* aTable = myTables[ GetType() ];
1237
1238   if (aTable->rowCount() == 0)
1239     return;
1240
1241   QList<QTableWidgetItem*> items = aTable->selectedItems();
1242   
1243   QList<int> aRows = aTable->selectedRows(); // already sorted
1244   int i;
1245   foreach( i, aRows )
1246   {
1247     removeAdditionalWidget(aTable, i);
1248     aTable->removeRow(i);
1249   }
1250
1251   // remove control of binary logical operation from last row
1252   if (aTable->rowCount() > 0)
1253     aTable->setEditable(false, aTable->rowCount() - 1, 4);
1254
1255   updateBtnState();
1256 }
1257
1258 //=======================================================================
1259 // name    : SMESHGUI_FilterTable::updateAdditionalWidget
1260 // Purpose : Enable/Disable widget with additonal parameters
1261 //=======================================================================
1262 void SMESHGUI_FilterTable::updateAdditionalWidget()
1263 {
1264   Table* aTable = myTables[ GetType() ];
1265   int aRow = aTable->currentRow();
1266   if (aRow < 0 || aRow >= aTable->rowCount())
1267   {
1268     myWgStack->setEnabled(false);
1269     return;
1270   }
1271
1272   ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
1273   int aCriterion = GetCriterionType(aRow);
1274   bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo &&
1275                   aCriterion != SMESH::FT_BelongToGeom &&
1276                   aCriterion != SMESH::FT_LyingOnGeom &&
1277                   aCriterion != SMESH::FT_RangeOfIds &&
1278                   aCriterion != SMESH::FT_FreeEdges &&
1279                   aCriterion != SMESH::FT_FreeFaces &&
1280                   aCriterion != SMESH::FT_BadOrientedVolume;
1281
1282   if (!myAddWidgets.contains(anItem))
1283   {
1284     myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
1285     myWgStack->addWidget(myAddWidgets[ anItem ]);
1286   }
1287
1288   myWgStack->setCurrentWidget(myAddWidgets[ anItem ]);
1289   myWgStack->setEnabled(toEnable);
1290 }
1291
1292 //=======================================================================
1293 // name    : SMESHGUI_FilterTable::removeAdditionalWidget
1294 // Purpose : Remove widgets containing additional parameters from widget
1295 //           stack and internal map
1296 //=======================================================================
1297 void SMESHGUI_FilterTable::removeAdditionalWidget (QTableWidget* theTable, const int theRow)
1298 {
1299   QTableWidgetItem* anItem = theTable->item(theRow, 0);
1300   if (myAddWidgets.contains(anItem))
1301   {
1302     myWgStack->removeWidget(myAddWidgets[ anItem ]);
1303     myAddWidgets[ anItem ]->setParent(0);
1304     delete myAddWidgets[ anItem ];
1305     myAddWidgets.remove(anItem);
1306   }
1307 }
1308
1309 //=======================================================================
1310 // name    : SMESHGUI_FilterTable::onClearBtn
1311 // Purpose : SLOT. Called then "Clear" button pressed.
1312 //           Removes all strings from table
1313 //=======================================================================
1314 void SMESHGUI_FilterTable::onClearBtn()
1315 {
1316   Table* aTable = myTables[ GetType() ];
1317
1318   if (aTable->rowCount() == 0)
1319     return;
1320
1321   while (aTable->rowCount() > 0)
1322   {
1323     removeAdditionalWidget(aTable, 0);
1324     aTable->removeRow(0);
1325   }
1326
1327   updateBtnState();
1328 }
1329
1330 //=======================================================================
1331 // name    : SMESHGUI_FilterTable::onCurrentChanged()
1332 // Purpose : SLOT. Called when current cell changed
1333 //=======================================================================
1334 void SMESHGUI_FilterTable::onCurrentChanged (int theRow, int theCol)
1335 {
1336   if( !myIsLocked )
1337     updateAdditionalWidget();
1338   emit CurrentChanged(theRow, theCol);
1339 }
1340
1341 //=======================================================================
1342 // name    : geomTypes
1343 // Purpose : returns available geometry types of elements
1344 //=======================================================================
1345 static QList<int> geomTypes( const int theType )
1346 {
1347   QList<int> typeIds;
1348   if ( theType == SMESH::NODE )
1349     typeIds.append( SMESH::Geom_POINT );
1350   if ( theType == SMESH::ALL || theType == SMESH::EDGE )
1351     typeIds.append( SMESH::Geom_EDGE );
1352   if ( theType == SMESH::ALL || theType == SMESH::FACE )
1353   {
1354     typeIds.append( SMESH::Geom_TRIANGLE );
1355     typeIds.append( SMESH::Geom_QUADRANGLE );
1356     typeIds.append( SMESH::Geom_POLYGON );
1357   }
1358   if ( theType == SMESH::ALL || theType == SMESH::VOLUME )
1359   {
1360     typeIds.append( SMESH::Geom_TETRA );
1361     typeIds.append( SMESH::Geom_PYRAMID );
1362     typeIds.append( SMESH::Geom_HEXA );
1363     typeIds.append( SMESH::Geom_PENTA );
1364     typeIds.append( SMESH::Geom_POLYHEDRA );
1365   }
1366   return typeIds;
1367 }
1368
1369 //=======================================================================
1370 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1371 // Purpose : Provides reaction on change of criterion
1372 //=======================================================================
1373 void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, const int entityType)
1374 {
1375   int aType = entityType == -1 ? GetType() : entityType;
1376   Table* aTable = myTables[ aType ];
1377   ComboItem* aCompareItem = (ComboItem*)aTable->item(row, 1);
1378
1379   int aCriterionType = GetCriterionType(row);
1380   QtxColorButton* clrBtn = qobject_cast<QtxColorButton*>(aTable->cellWidget(row, 2));
1381   QtxComboBox* typeBox = qobject_cast<QtxComboBox*>(aTable->cellWidget(row, 2));
1382   
1383   if ( (aCriterionType == SMESH::FT_GroupColor && !clrBtn) ||
1384        (aCriterionType == SMESH::FT_ElemGeomType && !typeBox) )
1385   {
1386     bool isSignalsBlocked = aTable->signalsBlocked();
1387     aTable->blockSignals( true );
1388     if ( aCriterionType == SMESH::FT_GroupColor )
1389       aTable->setCellWidget( row, 2, new QtxColorButton( aTable ) );
1390     else {
1391       QtxComboBox* typeBox = new QtxComboBox( aTable );
1392       aTable->setCellWidget( row, 2, typeBox );
1393       QList<int> typeIds = geomTypes( aType );
1394       QList<int>::const_iterator anIter = typeIds.begin();
1395       for ( int i = 0; anIter != typeIds.end(); ++anIter, ++i) {
1396         QString typeKey = QString( "GEOM_TYPE_%1" ).arg( *anIter );
1397         typeBox->addItem( tr( typeKey.toLatin1().data() ) );
1398         typeBox->setId( i, *anIter );
1399       }
1400     }
1401     aTable->blockSignals( isSignalsBlocked );
1402   }
1403   else if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) ||
1404             (aCriterionType != SMESH::FT_ElemGeomType && typeBox) )
1405   {
1406     bool isSignalsBlocked = aTable->signalsBlocked();
1407     aTable->blockSignals( true );
1408     aTable->setCellWidget( row, 2, 0 );
1409     aTable->setItem( row, 2, new QTableWidgetItem() );
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->count() != 3)
1456     {
1457       aCompareItem->setItems(getCompare());
1458     }
1459
1460     QString aText = aTable->text(row, 2);
1461     bool isOk = false;
1462     aText.toDouble(&isOk);
1463     aTable->item( row, 2 )->setText(isOk ? aText : QString(""));
1464     if (!aTable->isEditable(row, 1))
1465       aTable->setEditable(true, row, 1);
1466     if (!aTable->isEditable(row, 2))
1467       aTable->setEditable(true, row, 2);
1468   }
1469
1470   updateAdditionalWidget();
1471
1472   emit CriterionChanged(row, entityType);
1473 }
1474
1475 //=======================================================================
1476 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1477 // Purpose : SLOT. Called then contents of table changed
1478 //           Provides reaction on change of criterion
1479 //=======================================================================
1480 void SMESHGUI_FilterTable::onCriterionChanged (int row, int col)
1481 {
1482   onCriterionChanged(row, col, -1);
1483 }
1484
1485 //=======================================================================
1486 // name    : SMESHGUI_FilterTable::getFirstSelectedRow
1487 // Purpose : Get first selected row
1488 //=======================================================================
1489 int SMESHGUI_FilterTable::getFirstSelectedRow() const
1490 {
1491   Table* aTable = myTables[ GetType() ];
1492
1493   QList<int> selRows = aTable->selectedRows(); // already sorted
1494   int aRow = selRows.count() > 0 ? selRows[0] : aTable->currentRow();
1495
1496   return aRow >= 0 && aRow < aTable->rowCount() ? aRow : -1;
1497 }
1498
1499 //=======================================================================
1500 // name    : SMESHGUI_FilterTable::addRow
1501 // Purpose : Add row at the end of table
1502 //=======================================================================
1503 void SMESHGUI_FilterTable::addRow (Table* theTable, const int theType, const bool toTheEnd)
1504 {
1505   int aCurrRow = 0;
1506   int aSelectedRow = getFirstSelectedRow();
1507   int aCurrCol = theTable->currentColumn();
1508
1509   myIsLocked = true;
1510   if (toTheEnd || aSelectedRow == -1)
1511   {
1512     theTable->insertRows(theTable->rowCount());
1513     aCurrRow = theTable->rowCount() - 1;
1514   }
1515   else
1516   {
1517     theTable->insertRows(aSelectedRow);
1518     aCurrRow = aSelectedRow;
1519   }
1520   myIsLocked = false;
1521
1522   // IPAL19372 - to prevent calling onCriterionChaged() slot before completion of setItem()
1523   bool isSignalsBlocked = theTable->signalsBlocked();
1524   theTable->blockSignals( true );
1525
1526   // Criteria
1527   theTable->setItem(aCurrRow, 0, getCriterionItem(theType));
1528
1529   // Compare
1530   theTable->setItem(aCurrRow, 1, getCompareItem());
1531
1532   // Threshold
1533   theTable->setItem(aCurrRow, 2, new QTableWidgetItem());
1534
1535   // Logical operation NOT
1536   theTable->setItem(aCurrRow, 3, getUnaryItem());
1537
1538   // Logical operation AND / OR
1539   theTable->setItem(aCurrRow, 4, new QTableWidgetItem());
1540
1541   theTable->setItem(aCurrRow, 5, new QTableWidgetItem());
1542     
1543   theTable->blockSignals( isSignalsBlocked );
1544
1545   // Logical binary operation for previous value
1546   int anAddBinOpStr = -1;
1547   if (aCurrRow == theTable->rowCount() - 1)
1548     anAddBinOpStr = aCurrRow - 1;
1549   else if (aCurrRow >= 0 )
1550     anAddBinOpStr = aCurrRow;
1551
1552   if (theTable->item(aCurrRow, 4) == 0 ||
1553        theTable->item(aCurrRow, 4)->type() != ComboItem::Type())
1554   {
1555
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 {
2071   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2072     mySelector = aViewWindow->GetSelector();
2073
2074   construct(theTypes);
2075 }
2076
2077 //=======================================================================
2078 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
2079 // Purpose : Constructor
2080 //=======================================================================
2081 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*   theModule,
2082                                         const int   theType )
2083 : QDialog( SMESH::GetDesktop( theModule ) ),
2084   mySMESHGUI( theModule ),
2085   mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
2086 {
2087   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2088     mySelector = aViewWindow->GetSelector();
2089   QList<int> aTypes;
2090   aTypes.append(theType);
2091   construct(aTypes);
2092 }
2093
2094 //=======================================================================
2095 // name    : SMESHGUI_FilterDlg::construct
2096 // Purpose : Construct dialog (called by constructor)
2097 //=======================================================================
2098 void SMESHGUI_FilterDlg::construct (const QList<int>& theTypes)
2099 {
2100   myTypes = theTypes;
2101
2102   setModal(false);
2103   //setAttribute(Qt::WA_DeleteOnClose, true); // VSR ??? is it required?
2104   setWindowTitle(tr("CAPTION"));
2105
2106   QVBoxLayout* aDlgLay = new QVBoxLayout (this);
2107   aDlgLay->setMargin(MARGIN);
2108   aDlgLay->setSpacing(SPACING);
2109
2110   myMainFrame         = createMainFrame  (this);
2111   QWidget* aBtnFrame  = createButtonFrame(this);
2112
2113   aDlgLay->addWidget(myMainFrame);
2114   aDlgLay->addWidget(aBtnFrame);
2115
2116   aDlgLay->setStretchFactor(myMainFrame, 1);
2117
2118   myHelpFileName = "selection_filter_library_page.html";
2119
2120   Init(myTypes);
2121 }
2122
2123 //=======================================================================
2124 // name    : SMESHGUI_FilterDlg::createMainFrame
2125 // Purpose : Create frame containing dialog's input fields
2126 //=======================================================================
2127 QWidget* SMESHGUI_FilterDlg::createMainFrame (QWidget* theParent)
2128 {
2129   QWidget* aMainFrame = new QWidget(theParent);
2130   QVBoxLayout* aMainLay = new QVBoxLayout(aMainFrame);
2131   aMainLay->setMargin(0);
2132   aMainLay->setSpacing(SPACING);
2133
2134   // filter frame
2135
2136   myTable = new SMESHGUI_FilterTable( mySMESHGUI, aMainFrame, myTypes );
2137   myTable->SetLibsEnabled(true);
2138
2139   QGroupBox* aGrp = myTable->GetTableGrp();
2140   QGridLayout* aLay = qobject_cast<QGridLayout*>( aGrp->layout() );
2141   int rows = aLay->rowCount();
2142   int cols = aLay->columnCount();
2143
2144   QFrame* aLine = new QFrame(aGrp);
2145   aLine->setFrameStyle(QFrame::HLine | QFrame::Sunken);
2146   aLay->addWidget(aLine, rows++, 0, 1, cols);
2147
2148   mySetInViewer = new QCheckBox(tr("SET_IN_VIEWER"), aGrp);
2149   mySetInViewer->setChecked(true);
2150   aLay->addWidget(mySetInViewer, rows++, 0, 1, cols);
2151
2152   // other controls
2153   QWidget* aSourceGrp = createSourceGroup(aMainFrame);
2154
2155   connect(myTable, SIGNAL(CriterionChanged(const int, const int)),
2156                     SLOT(onCriterionChanged(const int, const int)));
2157
2158   connect(myTable, SIGNAL(CurrentChanged(int, int)),
2159                     SLOT(onCurrentChanged(int, int)));
2160
2161   aMainLay->addWidget(myTable);
2162   aMainLay->addWidget(aSourceGrp);
2163   
2164   return aMainFrame;
2165 }
2166
2167 //=======================================================================
2168 // name    : SMESHGUI_FilterDlg::createSourceFrame
2169 // Purpose : Create frame containing source radio button
2170 //=======================================================================
2171 QWidget* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent)
2172 {
2173   QGroupBox* aBox = new QGroupBox(tr("SOURCE"), theParent);
2174   QHBoxLayout* aLay = new QHBoxLayout(aBox);
2175   aLay->setMargin(MARGIN);
2176   aLay->setSpacing(SPACING);
2177
2178   mySourceGrp = new QButtonGroup(theParent);
2179
2180   QRadioButton* aMeshBtn = new QRadioButton(tr("MESH"),          aBox);
2181   QRadioButton* aSelBtn  = new QRadioButton(tr("SELECTION"),     aBox);
2182   QRadioButton* aDlgBtn  = new QRadioButton(tr("CURRENT_DIALOG"),aBox);
2183
2184   aLay->addWidget(aMeshBtn);
2185   aLay->addWidget(aSelBtn);
2186   aLay->addWidget(aDlgBtn);
2187
2188   mySourceGrp->addButton(aMeshBtn, Mesh);
2189   mySourceGrp->addButton(aSelBtn,  Selection);
2190   mySourceGrp->addButton(aDlgBtn,  Dialog);
2191
2192   aSelBtn->setChecked(true);
2193
2194   return aBox;
2195 }
2196
2197 //=======================================================================
2198 // name    : SMESHGUI_FilterDlg::updateMainButtons
2199 // Purpose : Update visibility of main buttons (OK, Cancel, Close ...)
2200 //=======================================================================
2201 void SMESHGUI_FilterDlg::updateMainButtons()
2202 {
2203   if (myTypes.count() == 1)
2204   {
2205     myButtons[ BTN_Cancel ]->show();
2206     myButtons[ BTN_Apply  ]->hide();
2207     myButtons[ BTN_Close  ]->hide();
2208   }
2209   else
2210   {
2211     myButtons[ BTN_Cancel ]->hide();
2212     myButtons[ BTN_Apply  ]->show();
2213     myButtons[ BTN_Close  ]->show();
2214   }
2215
2216 //  updateGeometry();
2217 }
2218
2219 //=======================================================================
2220 // name    : SMESHGUI_FilterDlg::createButtonFrame
2221 // Purpose : Create frame containing buttons
2222 //=======================================================================
2223 QWidget* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent)
2224 {
2225   QGroupBox* aGrp = new QGroupBox(theParent);
2226   QHBoxLayout* aLay = new QHBoxLayout(aGrp);
2227   aLay->setMargin(MARGIN);
2228   aLay->setSpacing(SPACING);
2229
2230   myButtons[ BTN_OK     ] = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGrp);
2231   myButtons[ BTN_Apply  ] = new QPushButton(tr("SMESH_BUT_APPLY"),           aGrp);
2232   myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"),          aGrp);
2233   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"),           aGrp);
2234   myButtons[ BTN_Help   ] = new QPushButton(tr("SMESH_BUT_HELP"),            aGrp);
2235
2236   aLay->addWidget(myButtons[ BTN_OK     ]);
2237   aLay->addSpacing(10);
2238   aLay->addWidget(myButtons[ BTN_Apply  ]);
2239   aLay->addSpacing(10);
2240   aLay->addStretch();
2241   aLay->addWidget(myButtons[ BTN_Cancel ]);
2242   aLay->addWidget(myButtons[ BTN_Close  ]);
2243   aLay->addWidget(myButtons[ BTN_Help   ]);
2244
2245   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
2246   connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
2247   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
2248   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
2249   connect(myButtons[ BTN_Help   ], SIGNAL(clicked()), SLOT(onHelp()));
2250
2251   updateMainButtons();
2252
2253   return aGrp;
2254 }
2255
2256 //=======================================================================
2257 // name    : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
2258 // Purpose : Destructor
2259 //=======================================================================
2260 SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
2261 {
2262 }
2263
2264 //=======================================================================
2265 // name    : SMESHGUI_FilterDlg::Init
2266 // Purpose : Init dialog fields, connect signals and slots, show dialog
2267 //=======================================================================
2268 void SMESHGUI_FilterDlg::Init (const int type)
2269 {
2270   QList<int> aTypes;
2271   aTypes.append(type);
2272   Init(aTypes);
2273 }
2274
2275 //=======================================================================
2276 // name    : SMESHGUI_FilterDlg::Init
2277 // Purpose : Init dialog fields, connect signals and slots, show dialog
2278 //=======================================================================
2279 void SMESHGUI_FilterDlg::Init (const QList<int>& theTypes)
2280 {
2281   mySourceWg  = 0;
2282   myTypes     = theTypes;
2283   myMesh      = SMESH::SMESH_Mesh::_nil();
2284   myIObjects.Clear();
2285   myIsSelectionChanged = false;
2286
2287   myTable->Init(theTypes);
2288
2289   // set caption
2290   if (theTypes.count() == 1)
2291   {
2292     int aType = theTypes.first();
2293     if      (aType == SMESH::NODE  ) setWindowTitle(tr("NODES_TLT"));
2294     else if (aType == SMESH::EDGE  ) setWindowTitle(tr("EDGES_TLT"));
2295     else if (aType == SMESH::FACE  ) setWindowTitle(tr("FACES_TLT"));
2296     else if (aType == SMESH::VOLUME) setWindowTitle(tr("VOLUMES_TLT"));
2297   }
2298   else
2299     setWindowTitle(tr("TLT"));
2300
2301   qApp->processEvents();
2302   updateGeometry();
2303   adjustSize();
2304   setEnabled(true);
2305
2306   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
2307
2308   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
2309   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
2310   
2311   updateMainButtons();
2312   updateSelection();
2313
2314   // Initialise filter table with values of previous filter
2315   QList<int>::const_iterator anIter;
2316   for (anIter = theTypes.begin(); anIter != theTypes.end(); ++anIter)
2317   {
2318     myTable->Clear(*anIter);
2319     if (!myFilter[ *anIter ]->_is_nil())
2320     {
2321       SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2322       if (myFilter[ *anIter ]->GetCriteria(aCriteria))
2323       {
2324         for (int i = 0, n = aCriteria->length(); i < n; i++)
2325           myTable->AddCriterion(aCriteria[ i ], *anIter);
2326       }
2327     }
2328   }
2329
2330   if (myInsertState.contains(theTypes.first()))
2331     mySetInViewer->setChecked(myInsertState[ theTypes.first() ]);
2332   else
2333     mySetInViewer->setChecked(true);
2334
2335   mySourceGrp->button(myApplyToState.contains(theTypes.first()) ? 
2336                       myApplyToState[ theTypes.first() ] :
2337                       Selection)->setChecked(true);
2338 }
2339
2340 //=======================================================================
2341 // name    : SMESHGUI_FilterDlg::onOk
2342 // Purpose : SLOT called when "Ok" button pressed.
2343 //           Assign filters VTK viewer and close dialog
2344 //=======================================================================
2345 void SMESHGUI_FilterDlg::onOk()
2346 {
2347   if (onApply())
2348   {
2349     mySelectionMgr->clearFilters();
2350     disconnect(mySMESHGUI, 0, this, 0);
2351     disconnect(mySelectionMgr, 0, this, 0);
2352     mySMESHGUI->ResetState();
2353     accept();
2354     emit Accepted();
2355   }
2356 }
2357
2358 //=======================================================================
2359 // name    : SMESHGUI_FilterDlg::onClose
2360 // Purpose : SLOT called when "Close" button pressed. Close dialog
2361 //=======================================================================
2362 void SMESHGUI_FilterDlg::onClose()
2363 {
2364   // Restore previously selected object
2365   if (mySelectionMgr)
2366   {
2367     SALOME_ListIO aList;
2368     mySelectionMgr->clearFilters();
2369     mySelectionMgr->clearSelected();
2370     SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter (myIObjects);
2371     for ( ; anIter.More(); anIter.Next())
2372     {
2373       aList.Append(anIter.Key());
2374
2375       TColStd_MapOfInteger aResMap;
2376       const TColStd_IndexedMapOfInteger& anIndMap = anIter.Value();
2377       for (int i = 1, n = anIndMap.Extent(); i <= n; i++)
2378         aResMap.Add(anIndMap(i));
2379
2380       mySelector->AddOrRemoveIndex( anIter.Key(), aResMap, false);
2381       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2382         aViewWindow->highlight( anIter.Key(), true, true );
2383     }
2384     mySelectionMgr->setSelectedObjects(aList, false);
2385   }
2386
2387   disconnect(mySMESHGUI, 0, this, 0);
2388   disconnect(mySelectionMgr, 0, this, 0);
2389   mySMESHGUI->ResetState();
2390   reject();
2391   return;
2392 }
2393
2394 //=================================================================================
2395 // function : onHelp()
2396 // purpose  :
2397 //=================================================================================
2398 void SMESHGUI_FilterDlg::onHelp()
2399 {
2400   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
2401   if (app) 
2402     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
2403   else {
2404     QString platform;
2405 #ifdef WIN32
2406     platform = "winapplication";
2407 #else
2408     platform = "application";
2409 #endif
2410     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
2411                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
2412                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
2413                                                                  platform)).
2414                              arg(myHelpFileName));
2415   }
2416 }
2417
2418 //=======================================================================
2419 // name    : SMESHGUI_FilterDlg::onDeactivate
2420 // Purpose : SLOT called when dialog must be deativated
2421 //=======================================================================
2422 void SMESHGUI_FilterDlg::onDeactivate()
2423 {
2424   setEnabled(false);
2425 }
2426
2427 //=======================================================================
2428 // name    : SMESHGUI_FilterDlg::enterEvent
2429 // Purpose : Event filter
2430 //=======================================================================
2431 void SMESHGUI_FilterDlg::enterEvent (QEvent*)
2432 {
2433 //  mySMESHGUI->EmitSignalDeactivateDialog();
2434   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
2435   mySMESHGUI->ResetState();
2436   setEnabled(true);
2437 }
2438
2439 //=======================================================================
2440 // name    : closeEvent()
2441 // Purpose :
2442 //=======================================================================
2443 void SMESHGUI_FilterDlg::closeEvent (QCloseEvent*)
2444 {
2445   onClose();
2446 }
2447
2448 //=======================================================================
2449 // name    : SMESHGUI_FilterDlg::getIdsFromWg
2450 // Purpose : Retrieve list of ids from given widget
2451 //=======================================================================
2452 void SMESHGUI_FilterDlg::getIdsFromWg (const QWidget* theWg, QList<int>& theRes) const
2453 {
2454   theRes.clear();
2455   if (theWg == 0)
2456     return;
2457
2458   if (theWg->inherits("QListWidget"))
2459   {
2460     const QListWidget* aListBox = qobject_cast<const QListWidget*>( theWg );
2461     bool b;
2462     for (int i = 0, n = aListBox->count(); i < n; i++)
2463     {
2464       int anId = aListBox->item(i)->text().toInt(&b);
2465       if (b)
2466         theRes.append(anId);
2467     }
2468   }
2469   else if (theWg->inherits("QLineEdit"))
2470   {
2471     const QLineEdit* aLineEdit = qobject_cast<const QLineEdit*>( theWg );
2472     QString aStr = aLineEdit->text();
2473     QRegExp aRegExp("(\\d+)");
2474     bool b;
2475     int aPos = 0;
2476     while (aPos >= 0)
2477     {
2478       aPos = aRegExp.indexIn(aStr, aPos);
2479       if (aPos > -1)
2480       {
2481         int anId = aRegExp.cap(1).toInt(&b);
2482         if (b)
2483           theRes.append(anId);
2484         aPos += aRegExp.matchedLength();
2485       }
2486     }
2487   }
2488 }
2489
2490 //=======================================================================
2491 // name    : SMESHGUI_FilterDlg::getSelMode
2492 // Purpose : Get selection mode of specified type
2493 //=======================================================================
2494 Selection_Mode SMESHGUI_FilterDlg::getSelMode (const int theType) const
2495 {
2496   switch (theType)
2497   {
2498     case SMESH::NODE   : return NodeSelection;
2499     case SMESH::EDGE   : return EdgeSelection;
2500     case SMESH::FACE   : return FaceSelection;
2501     case SMESH::VOLUME : return VolumeSelection;
2502     case SMESH::ALL    : return CellSelection;
2503     default            : return ActorSelection;
2504   }
2505
2506 }
2507
2508 //=======================================================================
2509 // name    : SMESHGUI_FilterDlg::setIdsToWg
2510 // Purpose : Insert identifiers in specified widgets
2511 //=======================================================================
2512 void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QList<int>& theIds)
2513 {
2514   if (theWg == 0)
2515     return;
2516
2517   if (theWg->inherits("QListWidget"))
2518   {
2519     QListWidget* aListBox = qobject_cast<QListWidget*>( theWg );
2520     aListBox->clear();
2521
2522     QStringList aStrList;
2523     QList<int>::const_iterator anIter;
2524     for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter)
2525       aStrList.append(QString("%1").arg(*anIter));
2526
2527     aListBox->addItems(aStrList);
2528   }
2529   else if (theWg->inherits("QLineEdit"))
2530   {
2531     QLineEdit* aLineEdit = qobject_cast<QLineEdit*>( theWg );
2532     QString aStr;
2533     QList<int>::const_iterator anIter;
2534
2535     for (anIter = theIds.begin(); anIter != theIds.end(); ++ anIter)
2536       aStr += QString("%1 ").arg(*anIter);
2537
2538     if (!aStr.isEmpty())
2539       aStr.remove(aStr.length() - 1, 1);
2540
2541     aLineEdit->setText(aStr);
2542   }
2543 }
2544
2545 //=======================================================================
2546 // name    : SMESHGUI_FilterDlg::isValid
2547 // Purpose : Verify validity of input data
2548 //=======================================================================
2549 bool SMESHGUI_FilterDlg::isValid() const
2550 {
2551   if (!myTable->IsValid())
2552     return false;
2553
2554   for (int i = 0, n = myTable->NumRows(); i < n; i++)
2555   {
2556     int aType = myTable->GetCriterionType(i);
2557     if (aType == SMESH::FT_BelongToGeom ||
2558         aType == SMESH::FT_BelongToPlane ||
2559         aType == SMESH::FT_BelongToCylinder ||
2560         aType == SMESH::FT_BelongToGenSurface ||
2561         aType == SMESH::FT_LyingOnGeom) {
2562       QString aName;
2563       myTable->GetThreshold(i, aName);
2564
2565       std::vector<_PTR(SObject)> aList =
2566         SMESH::GetActiveStudyDocument()->FindObjectByName(aName.toLatin1().constData(), "GEOM");
2567       if (aList.size() == 0) {
2568         SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2569                                      tr("BAD_SHAPE_NAME").arg(aName));
2570         return false;
2571       }
2572
2573       if (aType == SMESH::FT_BelongToCylinder ||
2574           aType == SMESH::FT_BelongToPlane    ||
2575           aType == SMESH::FT_BelongToGenSurface ) {
2576         CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
2577         //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
2578         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
2579         if (!aGeomObj->_is_nil()) {
2580           TopoDS_Shape aFace;
2581           if (!GEOMBase::GetShape(aGeomObj, aFace) ||
2582                aFace.IsNull() ||
2583                aFace.ShapeType() != TopAbs_FACE) {
2584             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2585                                          tr("SHAPE_IS_NOT_A_FACE").arg(aName));
2586             return false;
2587           }
2588
2589           Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace));
2590           if (aSurf.IsNull()) {
2591             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2592                                          tr("SHAPE_IS_NOT_A_FACE").arg(aName));
2593             return false;
2594           }
2595
2596           if (aType == SMESH::FT_BelongToPlane && !aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
2597             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2598                                          tr("SHAPE_IS_NOT_A_PLANE").arg(aName));
2599             return false;
2600           }
2601
2602           if (aType == SMESH::FT_BelongToCylinder && !aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
2603             SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2604                                          tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName));
2605             return false;
2606           }
2607         }
2608       }
2609     }
2610   }
2611
2612   return true;
2613 }
2614
2615 //=======================================================================
2616 // name    : SMESHGUI_FilterDlg::SetSourceWg
2617 // Purpose : Set widget of parent dialog containing idsto be filtered if
2618 //           user select corresponding source radio button
2619 //=======================================================================
2620 void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg)
2621 {
2622   mySourceWg = theWg;
2623 }
2624
2625 //=======================================================================
2626 // name    : SMESHGUI_FilterDlg::SetGroupIds
2627 // Purpose : Set mesh
2628 //=======================================================================
2629 void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
2630 {
2631   myMesh = theMesh;
2632   const bool isEnable = !(myMesh->_is_nil());
2633   myButtons[BTN_OK]->setEnabled(isEnable);
2634   myButtons[BTN_Apply]->setEnabled(isEnable);
2635 }
2636
2637 //=======================================================================
2638 // name    : SMESHGUI_FilterDlg::SetSelection
2639 // Purpose : Get filtered ids
2640 //=======================================================================
2641 void SMESHGUI_FilterDlg::SetSelection()
2642 {
2643   if (mySelectionMgr)
2644     disconnect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionDone()));
2645
2646   if (mySelectionMgr) {
2647     myIObjects.Clear();
2648     const SALOME_ListIO& anObjs = mySelector->StoredIObjects();
2649     SALOME_ListIteratorOfListIO anIter (anObjs);
2650     for ( ; anIter.More(); anIter.Next()) {
2651       TColStd_IndexedMapOfInteger aMap;
2652       mySelector->GetIndex(anIter.Value(), aMap);
2653       myIObjects.Bind(anIter.Value(), aMap);
2654     }
2655
2656     connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
2657
2658     updateSelection();
2659   }
2660   else
2661     myIObjects.Clear();
2662 }
2663
2664 //=======================================================================
2665 // name    : SMESHGUI_FilterDlg::onApply
2666 // Purpose : SLOT called when "Apply" button pressed.
2667 //           Assign filters to VTK viewer
2668 //=======================================================================
2669 bool SMESHGUI_FilterDlg::onApply()
2670 {
2671   if (!isValid())
2672     return false;
2673
2674   try {
2675     int aCurrType = myTable->GetType();
2676
2677     if (!createFilter(aCurrType))
2678       return false;
2679
2680     insertFilterInViewer();
2681
2682     if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) {
2683       QList<int> aResultIds;
2684       filterSource(aCurrType, aResultIds);
2685       selectInViewer(aCurrType, aResultIds);
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     setIdsToWg(mySourceWg, theResIds);
2806   }
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   int aCriterionType = myTable->GetCriterionType(aRow);
2978   if (aList.Extent() != 1 ||
2979       !myTable->CurrentCell(aRow, aCol) ||
2980       aCriterionType != SMESH::FT_BelongToGeom &&
2981       aCriterionType != SMESH::FT_BelongToPlane &&
2982       aCriterionType != SMESH::FT_BelongToCylinder &&
2983       aCriterionType != SMESH::FT_BelongToGenSurface &&
2984       aCriterionType != SMESH::FT_LyingOnGeom)
2985     return;
2986
2987   Handle(SALOME_InteractiveObject) anIO = aList.First();
2988   GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
2989   if (!anObj->_is_nil())
2990     {
2991       myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
2992       //myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj));
2993       myTable->SetID(aRow, anIO->getEntry());
2994     }
2995 }
2996
2997
2998 //=======================================================================
2999 // name    : SMESHGUI_FilterDlg::onCriterionChanged
3000 // Purpose : SLOT called when cretarion of current row changed. Update selection
3001 //=======================================================================
3002 void SMESHGUI_FilterDlg::onCriterionChanged (const int, const int)
3003 {
3004   updateSelection();
3005 }
3006
3007 //=======================================================================
3008 // name    : SMESHGUI_FilterDlg::onCurrentChanged
3009 // Purpose : SLOT called when current row changed. Update selection
3010 //=======================================================================
3011 void SMESHGUI_FilterDlg::onCurrentChanged (int, int)
3012 {
3013   updateSelection();
3014 }
3015
3016 //=======================================================================
3017 // name    : SMESHGUI_FilterDlg::updateSelection
3018 // Purpose : UpdateSelection in accordance with current row
3019 //=======================================================================
3020 void SMESHGUI_FilterDlg::updateSelection()
3021 {
3022   if (mySelectionMgr == 0)
3023     return;
3024
3025   TColStd_MapOfInteger allTypes;
3026   for( int i=0; i<10; i++ )
3027     allTypes.Add( i );
3028   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
3029   if( !aStudy )
3030     return;
3031
3032
3033   mySelectionMgr->clearFilters();
3034
3035   int aRow, aCol;
3036
3037   int aCriterionType = myTable->GetCriterionType(aRow);
3038   if (myTable->CurrentCell(aRow, aCol) &&
3039       (aCriterionType == SMESH::FT_BelongToGeom ||
3040        aCriterionType == SMESH::FT_BelongToPlane ||
3041        aCriterionType == SMESH::FT_BelongToCylinder ||
3042        aCriterionType == SMESH::FT_BelongToGenSurface ||
3043        aCriterionType == SMESH::FT_LyingOnGeom)) {
3044
3045     if (aCriterionType == SMESH::FT_BelongToGeom ||
3046         aCriterionType == SMESH::FT_BelongToGenSurface ||
3047         aCriterionType == SMESH::FT_LyingOnGeom) {
3048
3049       mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true ));
3050
3051     } else if (aCriterionType == SMESH::FT_BelongToPlane) {
3052       mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Plane ) );
3053
3054     } else if (aCriterionType == SMESH::FT_BelongToCylinder) {
3055       mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Cylinder ) );
3056     }
3057     myIsSelectionChanged = true;
3058
3059   } else {
3060     if (myIsSelectionChanged) {
3061       mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
3062     }
3063   }
3064 }
3065
3066 //=================================================================================
3067 // function : keyPressEvent()
3068 // purpose  :
3069 //=================================================================================
3070 void SMESHGUI_FilterDlg::keyPressEvent( QKeyEvent* e )
3071 {
3072   QDialog::keyPressEvent( e );
3073   if ( e->isAccepted() )
3074     return;
3075
3076   if ( e->key() == Qt::Key_F1 ) {
3077     e->accept();
3078     onHelp();
3079   }
3080 }