Salome HOME
Movement of examples to CVS EXAMPLES SAMPLES_SRC.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_FilterDlg.cxx
1 //  SMESH SMESHGUI : GUI for SMESH component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 //  File   : SMESHGUI_FilterDlg.cxx
25 //  Author : Sergey LITONIN
26 //  Module : SMESH
27
28 #include "SMESHGUI_FilterDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Utils.h"
32 #include "SMESHGUI_VTKUtils.h"
33 #include "SMESHGUI_Filter.h"
34 #include "SMESHGUI_FilterUtils.h"
35 #include "SMESHGUI_FilterLibraryDlg.h"
36
37 #include "SMESH_Actor.h"
38 #include "SMESH_NumberFilter.hxx"
39 #include "SMESH_TypeFilter.hxx"
40
41 #include "GEOMBase.h"
42 #include "GEOM_FaceFilter.h"
43 #include "GEOM_TypeFilter.h"
44
45 #include "SUIT_Desktop.h"
46 #include "SUIT_ResourceMgr.h"
47
48 #include "SalomeApp_Application.h"
49 #include "SalomeApp_Tools.h"
50 #include "SalomeApp_Study.h"
51
52 #include "SALOME_ListIO.hxx"
53 #include "SALOME_ListIteratorOfListIO.hxx"
54 #include "SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger.hxx"
55 #include "SALOMEDSClient_Study.hxx"
56
57 #include "SVTK_ViewWindow.h"
58 #include "SVTK_Selector.h"
59
60 // OCCT Includes
61 #include <StdSelect_TypeOfFace.hxx>
62 #include <BRep_Tool.hxx>
63 #include <TopoDS.hxx>
64 #include <TopoDS_Face.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <Geom_Plane.hxx>
67 #include <Geom_CylindricalSurface.hxx>
68 #include <Precision.hxx>
69 #include <TColStd_MapOfInteger.hxx>
70 #include <TColStd_IndexedMapOfInteger.hxx>
71 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
72
73 // QT Includes
74 #include <qframe.h>
75 #include <qlayout.h>
76 #include <qlineedit.h>
77 #include <qpushbutton.h>
78 #include <qgroupbox.h>
79 #include <qtable.h>
80 #include <qstringlist.h>
81 #include <qlayout.h>
82 #include <qwidgetstack.h>
83 #include <qapplication.h>
84 #include <qcombobox.h>
85 #include <qfontmetrics.h>
86 #include <qmessagebox.h>
87 #include <qlabel.h>
88 #include <qbuttongroup.h>
89 #include <qradiobutton.h>
90 #include <qregexp.h>
91 #include <qlistbox.h>
92 #include <qcheckbox.h>
93 #include <qobjectlist.h>
94 #include <qvalidator.h>
95
96 // IDL Headers
97 #include "SALOMEconfig.h"
98 #include CORBA_SERVER_HEADER(SMESH_Group)
99
100 #define SPACING 5
101 #define MARGIN  10
102
103 using namespace SMESH;
104
105 static int maxLength (const QMap<int, QString> theMap, const QFontMetrics& theMetrics)
106 {
107   int aRes = 0;
108   QMap<int, QString>::const_iterator anIter;
109   for (anIter = theMap.begin(); anIter != theMap.end(); ++anIter)
110     aRes = Max(aRes, theMetrics.width(anIter.data()));
111   return aRes;
112 }
113
114 static int getFilterId (SMESH::ElementType theType)
115 {
116   switch (theType)
117   {
118     case SMESH::NODE   : return SMESHGUI_NodeFilter;
119     case SMESH::EDGE   : return SMESHGUI_EdgeFilter;
120     case SMESH::FACE   : return SMESHGUI_FaceFilter;
121     case SMESH::VOLUME : return SMESHGUI_VolumeFilter;
122     case SMESH::ALL    : return SMESHGUI_AllElementsFilter;
123     default            : return SMESHGUI_UnknownFilter;
124   }
125 }
126
127 /*
128   Class       : SMESHGUI_FilterTable::AdditionalWidget
129   Description : Class for storing additional parameters of criterion
130 */
131
132 class SMESHGUI_FilterTable::AdditionalWidget : public QFrame
133 {
134 public:
135   enum { Tolerance };
136
137 public:
138
139                           AdditionalWidget(QWidget* theParent);
140   virtual                 ~AdditionalWidget();
141
142   virtual void            GetParameters(QValueList<int>&) const;
143   virtual bool            IsValid(const bool theMsg = true) const;
144   virtual double          GetDouble(const int theId) const;
145   virtual int             GetInteger(const int theId) const;
146   virtual QString         GetString(const int theId) const;
147   virtual void            SetDouble(const int theId, const double theVal);
148   virtual void            SetInteger(const int theId, const int theVal);
149   virtual void            SetString(const int theId, const QString& theVal);
150   void                    SetEditable(const int theId, const bool isEditable);
151   void                    SetEditable(const bool isEditable);
152
153 private:
154   QMap< int, QLineEdit* > myLineEdits;
155 };
156
157 SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget (QWidget* theParent)
158      : QFrame(theParent)
159 {
160   QLabel* aLabel = new QLabel(tr("SMESH_TOLERANCE"), this);
161   myLineEdits[ Tolerance ] = new QLineEdit(this);
162   QDoubleValidator* aValidator = new QDoubleValidator(myLineEdits[ Tolerance ]);
163   aValidator->setBottom(0);
164   myLineEdits[ Tolerance ]->setValidator(aValidator);
165
166   QHBoxLayout* aLay = new QHBoxLayout(this, 0, SPACING);
167   aLay->addWidget(aLabel);
168   aLay->addWidget(myLineEdits[ Tolerance ]);
169
170   QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
171   aLay->addItem(aSpacer);
172
173   QString aText = QString("%1").arg(Precision::Confusion());
174   myLineEdits[ Tolerance ]->setText(aText);
175 }
176
177  SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget()
178 {
179 }
180
181 void SMESHGUI_FilterTable::AdditionalWidget::GetParameters (QValueList<int>& theList) const
182 {
183   theList.clear();
184   theList.append(Tolerance);
185 }
186
187 bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const
188 {
189   if (!isEnabled())
190     return true;
191
192   QValueList<int> aParams;
193   GetParameters(aParams);
194   QValueList<int>::const_iterator anIter;
195   for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) {
196     const QLineEdit* aWg = myLineEdits[ *anIter ];
197     int p = 0;
198     QString aText = aWg->text();
199     if (aWg->isEnabled() && aWg->validator()->validate(aText, p) != QValidator::Acceptable) {
200       if (theMsg)
201         QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
202                                  tr("SMESHGUI_INVALID_PARAMETERS"), QMessageBox::Ok);
203       return false;
204     }
205   }
206
207   return true;
208 }
209
210 double SMESHGUI_FilterTable::AdditionalWidget::GetDouble (const int theId) const
211 {
212   return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toDouble() : 0;
213 }
214
215 int SMESHGUI_FilterTable::AdditionalWidget::GetInteger (const int theId) const
216 {
217   return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toInt() : 0;
218 }
219
220 QString SMESHGUI_FilterTable::AdditionalWidget::GetString (const int theId) const
221 {
222   return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text() : QString("");
223 }
224
225 void SMESHGUI_FilterTable::AdditionalWidget::SetDouble (const int theId, const double theVal)
226 {
227   if (myLineEdits.contains(theId))
228     myLineEdits[ theId ]->setText(QString("%1").arg(theVal));
229 }
230
231 void SMESHGUI_FilterTable::AdditionalWidget::SetInteger (const int theId, const int theVal)
232 {
233   if (myLineEdits.contains(theId))
234     myLineEdits[ theId ]->setText(QString("%1").arg(theVal));
235 }
236
237 void SMESHGUI_FilterTable::AdditionalWidget::SetString (const int theId, const QString& theVal)
238 {
239   if (myLineEdits.contains(theId))
240     myLineEdits[ theId ]->setText(theVal);
241 }
242
243 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const int theId, const bool isEditable)
244 {
245   if (myLineEdits.contains(theId))
246     myLineEdits[ theId ]->setEdited(isEditable);
247 }
248
249 void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable)
250 {
251   QValueList<int> aParams;
252   GetParameters(aParams);
253   QValueList<int>::const_iterator anIter;
254   for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter)
255     myLineEdits[ *anIter ]->setEdited(isEditable);
256 }
257
258 /*
259   Class       : SMESHGUI_FilterTable::ComboItem
260   Description : Combo table item. Identificator corresponding to string may be assigned
261 */
262
263 class SMESHGUI_FilterTable::ComboItem : public QComboTableItem
264 {
265 public:
266                           ComboItem(QTable*, const QMap<int, QString>&);
267   virtual                 ~ComboItem();
268
269   virtual void            setStringList (const QStringList & l);
270   void                    setStringList(const QMap<int, QString>& theIds);
271
272   int                     GetValue() const;
273   void                    SetValue(const int);
274
275 private:
276
277   QMap<int, int>          myNumToId;
278   QMap<int, int>          myIdToNum;
279 };
280
281 SMESHGUI_FilterTable::ComboItem::ComboItem (QTable*                   theParent,
282                                             const QMap<int, QString>& theIds)
283 : QComboTableItem(theParent, QStringList())
284 {
285   setStringList(theIds);
286 }
287
288 void SMESHGUI_FilterTable::ComboItem::setStringList (const QStringList & l)
289 {
290   QComboTableItem::setStringList(l);
291 }
292
293 void SMESHGUI_FilterTable::ComboItem::setStringList (const QMap<int, QString>& theIds)
294 {
295   int i = 0;
296   QStringList aList;
297   QMap<int, QString>::const_iterator anIter;
298   for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) {
299     myNumToId[ i ] = anIter.key();
300     myIdToNum[ anIter.key() ] = i;
301     aList.append(anIter.data());
302     i++;
303   }
304
305   setStringList(aList);
306 }
307
308 SMESHGUI_FilterTable::ComboItem::~ComboItem()
309 {
310 }
311
312 int SMESHGUI_FilterTable::ComboItem::GetValue() const
313 {
314   return myNumToId[ currentItem() ];
315 }
316
317 void SMESHGUI_FilterTable::ComboItem::SetValue (const int theVal)
318 {
319   setCurrentItem(myIdToNum[ theVal ]);
320 }
321
322
323 /*
324   Class       : SMESHGUI_FilterTable::Table
325   Description : Table used by this widget
326 */
327
328 class SMESHGUI_FilterTable::Table : public QTable
329 {
330 public:
331                           Table(QWidget* parent);
332                           Table(int numRows, int numCols, QWidget* parent = 0);
333   virtual                 ~Table();
334
335   void                    SetEditable(const bool state, const int row, const int col);
336   bool                    IsEditable(const int row, const int col) const;
337
338   virtual void            insertRows(int row, int count = 1);
339   virtual QString         text(int row, int col) const;
340 };
341
342 //=======================================================================
343 // name    : SMESHGUI_FilterTable::Table::Table
344 // Purpose : Constructor
345 //=======================================================================
346 SMESHGUI_FilterTable::Table::Table (QWidget* parent)
347 : QTable(parent, "SMESHGUI_FilterTable::Table")
348 {
349 }
350
351 SMESHGUI_FilterTable::Table::Table (int numRows, int numCols, QWidget* parent)
352 : QTable(numRows, numCols, parent, "SMESHGUI_FilterTable::Table")
353 {
354 }
355
356 SMESHGUI_FilterTable::Table::~Table()
357 {
358 }
359
360 //=======================================================================
361 // name    : SMESHGUI_FilterTable::Table::SetEditable
362 // Purpose : Set editable of specified cell
363 //=======================================================================
364 void SMESHGUI_FilterTable::Table::SetEditable (const bool isEditable,
365                                                const int row, const int col)
366 {
367   QTableItem* anItem = item(row, col);
368   if(anItem)
369     takeItem(anItem);
370
371   if (!isEditable)
372     setItem(row, col, new QTableItem(this, QTableItem::Never, ""));
373   else
374     setItem(row, col, new QTableItem(this, QTableItem::OnTyping, ""));
375 }
376
377 //=======================================================================
378 // name    : SMESHGUI_FilterTable::Table::IsEditable
379 // Purpose : Verify wheter cell is editable
380 //=======================================================================
381 bool SMESHGUI_FilterTable::Table::IsEditable (const int row, const int col) const
382 {
383   QTableItem* anItem = item(row, col);
384   return anItem == 0 || anItem->editType() != QTableItem::Never;
385 }
386
387 //=======================================================================
388 // name    : SMESHGUI_FilterTable::Table::insertRows
389 // Purpose : Insert rows (virtual redefined)
390 //=======================================================================
391 void SMESHGUI_FilterTable::Table::insertRows (int row, int count)
392 {
393   int anEditRow = currEditRow();
394   int anEditCol = currEditCol();
395
396   if (anEditRow >= 0 && anEditCol >= 0)
397     endEdit(anEditRow, anEditCol, true, false);
398
399   QTable::insertRows( row, count );
400 }
401
402 //=======================================================================
403 // name    : SMESHGUI_FilterTable::Table::text
404 // Purpose : Get text from cell (virtual redefined)
405 //=======================================================================
406 QString SMESHGUI_FilterTable::Table::text (int row, int col) const
407 {
408   int anEditRow = currEditRow();
409   int anEditCol = currEditCol();
410
411   if (anEditRow >= 0 && anEditCol >= 0 && anEditRow == row && anEditCol == col)
412     ((Table*)this)->endEdit(row, col, true, false);
413
414   return QTable::text(row, col);
415 }
416
417
418 /*
419   Class       : SMESHGUI_FilterTable
420   Description : Frame containig
421                   - Button group for switching entity type
422                   - Table for displaying filter criterions
423                   - Buttons for editing table and filter libraries
424 */
425
426 //=======================================================================
427 // name    : SMESHGUI_FilterTable::SMESHGUI_FilterTable
428 // Purpose : Constructor
429 //=======================================================================
430 SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule,
431                                             QWidget* parent,
432                                             const int type)
433 : QFrame(parent),
434   myIsLocked( false ),
435   mySMESHGUI( theModule )
436 {
437   myEntityType = -1;
438   Init(type);
439 }
440
441 //=======================================================================
442 // name    : SMESHGUI_FilterTable::SMESHGUI_FilterTable
443 // Purpose : Constructor
444 //=======================================================================
445 SMESHGUI_FilterTable::SMESHGUI_FilterTable( SMESHGUI* theModule,
446                                             QWidget* parent,
447                                             const QValueList<int>& types)
448 : QFrame(parent),
449   myIsLocked( false ),
450   mySMESHGUI( theModule )
451 {
452   myEntityType = -1;
453   Init(types);
454 }
455
456 SMESHGUI_FilterTable::~SMESHGUI_FilterTable()
457 {
458 }
459
460 //=======================================================================
461 // name    : SMESHGUI_FilterTable::Init
462 // Purpose : Create table corresponding to the specified type
463 //=======================================================================
464 void SMESHGUI_FilterTable::Init (const int type)
465 {
466   QValueList<int> aTypes;
467   aTypes.append(type);
468   Init(aTypes);
469 }
470
471 //=======================================================================
472 // name    : SMESHGUI_FilterTable::Init
473 // Purpose : Create table corresponding to the specified type
474 //=======================================================================
475 void SMESHGUI_FilterTable::Init (const QValueList<int>& theTypes)
476 {
477   if (theTypes.isEmpty())
478     return;
479
480   // Create buttons if necessary
481
482   if (myTables.isEmpty())
483   {
484     int aType = theTypes.first();
485
486     // create main layout
487     QVBoxLayout* aMainLay = new QVBoxLayout(this);
488     QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, this);
489     aMainGrp->setFrameStyle(QFrame::NoFrame);
490     aMainGrp->setInsideMargin(0);
491     aMainLay->addWidget(aMainGrp);
492
493     // create switch of entity types
494     myEntityTypeGrp = new QButtonGroup(1, Qt::Vertical, tr("ENTITY_TYPE"), aMainGrp);
495     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
496     QMap<int, QString>::const_iterator anIter;
497     for (anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter)
498     {
499       QRadioButton* aBtn = new QRadioButton(anIter.data(), myEntityTypeGrp);
500       myEntityTypeGrp->insert(aBtn, anIter.key());
501     }
502
503     myTableGrp = new QGroupBox(1, Qt::Horizontal, tr("FILTER"), aMainGrp );
504     QFrame* aTableFrame = new QFrame(myTableGrp);
505
506     // create table
507     mySwitchTableGrp = new QGroupBox(1, Qt::Horizontal, aTableFrame);
508     mySwitchTableGrp->setFrameStyle(QFrame::NoFrame);
509     mySwitchTableGrp->setInsideMargin(0);
510
511     myTables[ aType ] = createTable(mySwitchTableGrp, aType);
512
513     // create buttons
514     myAddBtn      = new QPushButton(tr("ADD"), aTableFrame);
515     myRemoveBtn   = new QPushButton(tr("REMOVE"), aTableFrame);
516     myClearBtn    = new QPushButton(tr("CLEAR"), aTableFrame);
517     myInsertBtn   = new QPushButton(tr("INSERT"), aTableFrame);
518     myCopyFromBtn = new QPushButton(tr("COPY_FROM"), aTableFrame);
519     myAddToBtn    = new QPushButton(tr("ADD_TO"), aTableFrame);
520
521     myAddBtn->setAutoDefault(false);
522     myRemoveBtn->setAutoDefault(false);
523     myClearBtn->setAutoDefault(false);
524     myInsertBtn->setAutoDefault(false);
525     myCopyFromBtn->setAutoDefault(false);
526     myAddToBtn->setAutoDefault(false);
527
528     myCopyFromBtn->hide();
529     myAddToBtn->hide();
530
531     // layout widgets
532     QGridLayout* aLay = new QGridLayout(aTableFrame, 8, 2, 0, SPACING);
533
534     aLay->addMultiCellWidget(mySwitchTableGrp, 0, 6, 0, 0);
535     aLay->addWidget(myAddBtn, 0, 1);
536     aLay->addWidget(myInsertBtn, 1, 1);
537     aLay->addWidget(myRemoveBtn, 2, 1);
538     aLay->addWidget(myClearBtn, 3, 1);
539     aLay->addWidget(myCopyFromBtn, 5, 1);
540     aLay->addWidget(myAddToBtn, 6, 1);
541     aLay->addMultiCellWidget(createAdditionalFrame(aTableFrame), 7, 7, 0, 1 );
542
543     aLay->setColStretch(0, 1);
544     aLay->setColStretch(1, 0);
545
546     QSpacerItem* aVSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
547     aLay->addItem(aVSpacer, 4, 1);
548
549     // signals and slots
550     connect(myAddBtn,    SIGNAL(clicked()), this, SLOT(onAddBtn()));
551     connect(myInsertBtn, SIGNAL(clicked()), this, SLOT(onInsertBtn()));
552     connect(myRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemoveBtn()));
553     connect(myClearBtn,  SIGNAL(clicked()), this, SLOT(onClearBtn()));
554
555     connect(myCopyFromBtn, SIGNAL(clicked()), this, SLOT(onCopyFromBtn()));
556     connect(myAddToBtn,    SIGNAL(clicked()), this, SLOT(onAddToBtn()));
557
558     connect(myEntityTypeGrp, SIGNAL(clicked(int)), this, SLOT(onEntityType(int)));
559
560     myLibDlg = 0;
561   }
562
563   // Hide buttons of entity types if necessary
564   const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
565   QMap<int, QString>::const_iterator anIt;
566   for (anIt = aSupportedTypes.begin(); anIt != aSupportedTypes.end(); ++anIt)
567   {
568     QButton* aBtn = myEntityTypeGrp->find(anIt.key());
569     theTypes.contains(anIt.key()) ? aBtn->show() : aBtn->hide();
570   }
571
572   // select first button if there is no selected buttons or it is hidden
573   QButton* aBtn = myEntityTypeGrp->selected();
574   if ( aBtn == 0 || theTypes.find(myEntityTypeGrp->id(aBtn)) == theTypes.end())
575     myEntityTypeGrp->setButton(theTypes.first());
576
577   if (theTypes.count() == 1)
578     myEntityTypeGrp->hide();
579   else
580     myEntityTypeGrp->show();
581
582   myTableGrp->updateGeometry();
583   int aType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
584   onEntityType(aType);
585 }
586
587 //=======================================================================
588 // name    : SMESHGUI_FilterTable::GetTableGrp
589 // Purpose : Get group box containing table. May be used for adding new widgets in it
590 //=======================================================================
591 QWidget* SMESHGUI_FilterTable::createAdditionalFrame (QWidget* theParent)
592 {
593   QFrame* aFrame = new QFrame(theParent);
594
595   QFrame* aLine1 = new QFrame(aFrame);
596   QFrame* aLine2 = new QFrame(aFrame);
597   aLine1->setFrameStyle(QFrame::HLine | QFrame::Sunken);
598   aLine2->setFrameStyle(QFrame::HLine | QFrame::Sunken);
599   aLine1->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
600   aLine2->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
601
602   QLabel* aLabel = new QLabel(tr("ADDITIONAL_PARAMETERS"), aFrame);
603
604   myWgStack = new QWidgetStack(aFrame);
605
606   QGridLayout* aLay = new QGridLayout(aFrame, 2, 3, 0, SPACING);
607   aLay->addWidget(aLine1, 0, 0);
608   aLay->addWidget(aLabel, 0, 1);
609   aLay->addWidget(aLine2, 0, 2);
610   aLay->addMultiCellWidget(myWgStack, 1, 1, 0, 2);
611
612   return aFrame;
613 }
614
615 //=======================================================================
616 // name    : SMESHGUI_FilterTable::GetTableGrp
617 // Purpose : Get group box containing table. May be used for adding new widgets in it
618 //=======================================================================
619 QGroupBox* SMESHGUI_FilterTable::GetTableGrp()
620 {
621   return myTableGrp;
622 }
623
624 //=======================================================================
625 // name    : SMESHGUI_FilterTable::onEntityType
626 // Purpose : SLOT. Called when entity type changed.
627 //           Display corresponding table
628 //=======================================================================
629 void SMESHGUI_FilterTable::onEntityType (int theType)
630 {
631   if (myEntityType == theType)
632     return;
633
634   myIsValid = true;
635   emit NeedValidation();
636   if (!myIsValid)
637   {
638     myEntityTypeGrp->setButton(myEntityType);
639     return;
640   }
641
642   myEntityType = theType;
643
644   if (!myTables.contains(theType))
645     myTables[ theType ] = createTable(mySwitchTableGrp, theType);
646
647   TableMap::iterator anIter;
648   for (anIter = myTables.begin(); anIter != myTables.end(); ++anIter)
649     myEntityType == anIter.key() ? anIter.data()->show() : anIter.data()->hide();
650
651   updateBtnState();
652   qApp->processEvents();
653   myTables[ myEntityType ]->updateGeometry();
654   adjustSize();
655
656   emit EntityTypeChanged(theType);
657
658 }
659
660 //=======================================================================
661 // name    : SMESHGUI_FilterTable::IsValid
662 // Purpose : Verify validity of entered data
663 //=======================================================================
664 bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) const
665 {
666   int aType = theEntityType == -1 ? GetType() : theEntityType;
667
668   Table* aTable = myTables[ aType ];
669   for (int i = 0, n = aTable->numRows(); i < n; i++)
670   {
671     int aCriterion = GetCriterionType(i, aType);
672
673     if (aCriterion == FT_RangeOfIds ||
674          aCriterion == FT_BelongToGeom ||
675          aCriterion == FT_BelongToPlane ||
676          aCriterion == FT_BelongToCylinder ||
677          aCriterion == FT_LyingOnGeom) {
678       if (aTable->text(i, 2).isEmpty()) {
679         if (theMess)
680           QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
681                                    tr("ERROR"), QMessageBox::Ok);
682         return false;
683       }
684     } else {
685       bool aRes = false;
686       aTable->blockSignals(true);
687       double  aThreshold = (int)aTable->text(i, 2).toDouble(&aRes);
688       aTable->blockSignals(false);
689
690       if (!aRes && aTable->IsEditable(i, 2)) {
691         if (theMess)
692           QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
693                                    tr("ERROR"), QMessageBox::Ok);
694         return false;
695       }
696       else if (aType == SMESH::EDGE &&
697                 GetCriterionType(i, aType) == SMESH::FT_MultiConnection &&
698                 aThreshold == 1)
699       {
700         if (theMess)
701           QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
702                                    tr("MULTIEDGES_ERROR"), QMessageBox::Ok);
703         return false;
704       }
705     }
706
707     QTableItem* anItem = aTable->item(i, 0);
708     if (myAddWidgets.contains(anItem) && !myAddWidgets[ anItem ]->IsValid())
709       return false;
710   }
711
712   return true;
713 }
714
715 //=======================================================================
716 // name    : SMESHGUI_FilterTable::SetValidity
717 // Purpose : Set validity of the table
718 //=======================================================================
719 void SMESHGUI_FilterTable::SetValidity (const bool isValid)
720 {
721   myIsValid = isValid;
722 }
723
724 //=======================================================================
725 // name    : SMESHGUI_FilterTable::GetType
726 // Purpose : Get current entity type
727 //=======================================================================
728 int SMESHGUI_FilterTable::GetType() const
729 {
730   return myEntityType;
731 }
732
733 //=======================================================================
734 // name    : SMESHGUI_FilterTable::SetType
735 // Purpose : Set current entity type
736 //=======================================================================
737 void SMESHGUI_FilterTable::SetType (const int type)
738 {
739   myEntityTypeGrp->setButton(type);
740   onEntityType(type);
741 }
742
743 //=======================================================================
744 // name    : SMESHGUI_FilterTable::RestorePreviousEntityType
745 // Purpose : Restore previous entity type
746 //=======================================================================
747 void SMESHGUI_FilterTable::RestorePreviousEntityType()
748 {
749   SetType(myEntityType);
750 }
751
752 //=======================================================================
753 // name    : SMESHGUI_FilterTable::GetCriterionType
754 // Purpose : Get type of criterion from specified row (corresponding enums in h-file)
755 //=======================================================================
756 int SMESHGUI_FilterTable::GetCriterionType (const int theRow, const int theType) const
757 {
758   int aType = theType == -1 ? GetType() : theType;
759   Table* aTable = myTables[ aType ];
760   ComboItem* anItem = (ComboItem*)aTable->item(theRow, 0);
761   return anItem != 0 ? anItem->GetValue() : FT_Undefined;
762 }
763
764 //=======================================================================
765 // name    : SMESHGUI_FilterTable::GetCriterion
766 // Purpose : Get parameters of criterion from specified row
767 //=======================================================================
768 void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
769                                          SMESH::Filter::Criterion& theCriterion,
770                                          const int                 theEntityType) const
771 {
772   int aType = theEntityType == -1 ? GetType() : theEntityType;
773   Table* aTable = myTables[ aType ];
774
775   theCriterion.Type = ((ComboItem*)aTable->item(theRow, 0))->GetValue();
776   theCriterion.UnaryOp = ((QCheckTableItem*)aTable->item(theRow, 3))->isChecked() ? FT_LogicalNOT : FT_Undefined;
777   theCriterion.BinaryOp = theRow != aTable->numRows() - 1 ?
778     ((ComboItem*)aTable->item(theRow, 4))->GetValue() : FT_Undefined;
779   theCriterion.TypeOfElement = (ElementType)aType;
780
781   int aCriterionType = GetCriterionType(theRow, aType);
782
783   if (aCriterionType != FT_RangeOfIds &&
784        aCriterionType != FT_BelongToGeom &&
785        aCriterionType != FT_BelongToPlane &&
786        aCriterionType != FT_BelongToCylinder &&
787        aCriterionType != FT_LyingOnGeom)
788   {
789     theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->GetValue();
790     theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble();
791   }
792   else
793     theCriterion.ThresholdStr = aTable->text(theRow, 2).latin1();
794
795   QTableItem* anItem = aTable->item(theRow, 0);
796   if (myAddWidgets.contains(anItem))
797     theCriterion.Tolerance = myAddWidgets[ anItem ]->GetDouble(AdditionalWidget::Tolerance);
798 }
799
800 //=======================================================================
801 // name    : SMESHGUI_FilterTable::SetCriterion
802 // Purpose : Set parameters of criterion of specified row
803 //=======================================================================
804 void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
805                                          const SMESH::Filter::Criterion& theCriterion,
806                                          const int                       theEntityType)
807 {
808   int aType = theEntityType == -1 ? GetType() : theEntityType;
809
810   Table* aTable = myTables[ aType ];
811
812   if (theRow > aTable->numRows() - 1)
813     return;
814
815   ((ComboItem*)aTable->item(theRow, 0))->SetValue(theCriterion.Type);
816   onCriterionChanged(theRow, 0, aType);
817   ((ComboItem*)aTable->item(theRow, 1))->SetValue(theCriterion.Compare);
818   ((QCheckTableItem*)aTable->item(theRow, 3))->setChecked(theCriterion.UnaryOp == FT_LogicalNOT);
819
820   if (theCriterion.BinaryOp != FT_Undefined)
821   {
822     if (!aTable->IsEditable(theRow, 4))
823       aTable->setItem(theRow, 4, getBinaryItem(aTable));
824     ((ComboItem*)aTable->item(theRow, 4))->SetValue(theCriterion.BinaryOp);
825   }
826   else
827     aTable->SetEditable(false, theRow, 4);
828
829   if (theCriterion.Type != FT_RangeOfIds &&
830        theCriterion.Type != FT_BelongToGeom &&
831        theCriterion.Type != FT_BelongToPlane &&
832        theCriterion.Type != FT_BelongToCylinder &&
833        theCriterion.Type != FT_LyingOnGeom)
834     aTable->setText(theRow, 2, QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
835   else
836     aTable->setText(theRow, 2, QString(theCriterion.ThresholdStr));
837
838   if (theCriterion.Compare == FT_EqualTo ||
839        theCriterion.Type    == FT_BelongToPlane ||
840        theCriterion.Type    == FT_BelongToCylinder)
841   {
842     QTableItem* anItem = aTable->item(theRow, 0);
843     if (!myAddWidgets.contains(anItem))
844     {
845       myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
846       myWgStack->addWidget(myAddWidgets[ anItem ]);
847     }
848     myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance);
849   }
850
851   emit CriterionChanged(theRow, aType);
852
853 }
854
855 //=======================================================================
856 // name    : SMESHGUI_FilterTable::Update
857 // Purpose : Update table
858 //=======================================================================
859 void SMESHGUI_FilterTable::Update()
860 {
861   Table* aTable = myTables[ GetType() ];
862   int aCurrRow = aTable->currentRow();
863   int numRows = aTable->numRows();
864   if ((aCurrRow < 0 || aCurrRow >= numRows) && numRows > 0)
865     aTable->setCurrentCell(0, 0);
866   updateAdditionalWidget();
867 }
868
869 //=======================================================================
870 // name    : SMESHGUI_FilterTable::AddCriterion
871 // Purpose : Add criterion with parameters
872 //=======================================================================
873 void SMESHGUI_FilterTable::AddCriterion (const SMESH::Filter::Criterion& theCriterion,
874                                          const int                       theEntityType)
875 {
876   int aType = theEntityType == -1 ? GetType() : theEntityType;
877   Table* aTable = myTables[ aType ];
878   addRow(aTable, aType);
879   SetCriterion(aTable->numRows() - 1, theCriterion);
880 }
881
882 //=======================================================================
883 // name    : SMESHGUI_FilterTable::NumRows
884 // Purpose : Get number of criterions of current type
885 //=======================================================================
886 int SMESHGUI_FilterTable::NumRows (const int theEntityType) const
887 {
888   return myTables[ theEntityType == -1 ? GetType() : theEntityType ]->numRows();
889 }
890
891 //=======================================================================
892 // name    : SMESHGUI_FilterTable::Clear
893 // Purpose : Clear current table
894 //=======================================================================
895 void SMESHGUI_FilterTable::Clear (const int theType)
896 {
897   int aType = theType == -1 ? GetType() : theType;
898   QTable* aTable = myTables[ aType ];
899
900   if (aTable->numRows() == 0)
901     return;
902
903   while (aTable->numRows() > 0)
904   {
905     removeAdditionalWidget(aTable, 0);
906     aTable->removeRow(0);
907   }
908
909   updateBtnState();
910 }
911
912 //=======================================================================
913 // name    : SMESHGUI_FilterTable::onAddBtn
914 // Purpose : SLOT. Called then "Add" button pressed.
915 //           Adds new string to table
916 //=======================================================================
917 void SMESHGUI_FilterTable::onAddBtn()
918 {
919   int aType = GetType();
920   addRow(myTables[ aType ], aType);
921
922   Update();
923 }
924
925 //=======================================================================
926 // name    : SMESHGUI_FilterTable::onInsertBtn
927 // Purpose : SLOT. Called then "Insert" button pressed.
928 //           Inserts new string before current one
929 //=======================================================================
930 void SMESHGUI_FilterTable::onInsertBtn()
931 {
932   addRow(myTables[ GetType() ], GetType(), false);
933 }
934
935 //=======================================================================
936 // name    : SMESHGUI_FilterTable::onRemoveBtn
937 // Purpose : SLOT. Called then "Remove" button pressed.
938 //           Removes current string from table
939 //=======================================================================
940 void SMESHGUI_FilterTable::onRemoveBtn()
941 {
942   Table* aTable = myTables[ GetType() ];
943
944   if (aTable->numRows() == 0)
945     return;
946
947   QMemArray<int> aRows;
948   for (int i = 0, n = aTable->numRows(); i < n; i++)
949   {
950     if (aTable->isRowSelected(i))
951     {
952       aRows.resize(aRows.size() + 1);
953       aRows[ aRows.size() - 1 ] = i;
954       removeAdditionalWidget(aTable, i);
955     }
956   }
957
958   aTable->removeRows(aRows);
959
960   // remove control of binary logical operation from last row
961   if (aTable->numRows() > 0)
962     aTable->SetEditable(false, aTable->numRows() - 1, 4);
963
964   updateBtnState();
965 }
966
967 //=======================================================================
968 // name    : SMESHGUI_FilterTable::updateAdditionalWidget
969 // Purpose : Enable/Disable widget with additonal parameters
970 //=======================================================================
971 void SMESHGUI_FilterTable::updateAdditionalWidget()
972 {
973   Table* aTable = myTables[ GetType() ];
974   int aRow = aTable->currentRow();
975   if (aRow < 0 || aRow >= aTable->numRows())
976   {
977     myWgStack->setEnabled(false);
978     return;
979   }
980
981   ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
982   bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->GetValue() == FT_EqualTo &&
983                   GetCriterionType(aRow) != FT_BelongToGeom &&
984                   GetCriterionType(aRow) != FT_LyingOnGeom &&
985                   GetCriterionType(aRow) != FT_RangeOfIds &&
986                   GetCriterionType(aRow) != FT_FreeEdges &&
987                   GetCriterionType(aRow) != FT_BadOrientedVolume;
988   if (!myAddWidgets.contains(anItem))
989   {
990     myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
991     myWgStack->addWidget(myAddWidgets[ anItem ]);
992   }
993
994   myWgStack->raiseWidget(myWgStack->id(myAddWidgets[ anItem ]));
995   myWgStack->setEnabled(toEnable);
996 }
997
998 //=======================================================================
999 // name    : SMESHGUI_FilterTable::removeAdditionalWidget
1000 // Purpose : Remove widgets containing additional parameters from widget
1001 //           stack and internal map
1002 //=======================================================================
1003 void SMESHGUI_FilterTable::removeAdditionalWidget (QTable* theTable, const int theRow)
1004 {
1005   QTableItem* anItem = theTable->item(theRow, 0);
1006   if (myAddWidgets.contains(anItem))
1007   {
1008     myWgStack->removeWidget(myAddWidgets[ anItem ]);
1009     myAddWidgets[ anItem ]->reparent(0, QPoint());
1010     delete myAddWidgets[ anItem ];
1011     myAddWidgets.remove(anItem);
1012   }
1013 }
1014
1015 //=======================================================================
1016 // name    : SMESHGUI_FilterTable::onClearBtn
1017 // Purpose : SLOT. Called then "Clear" button pressed.
1018 //           Removes all strings from table
1019 //=======================================================================
1020 void SMESHGUI_FilterTable::onClearBtn()
1021 {
1022   QTable* aTable = myTables[ GetType() ];
1023
1024   if (aTable->numRows() == 0)
1025     return;
1026
1027   while (aTable->numRows() > 0)
1028   {
1029     removeAdditionalWidget(aTable, 0);
1030     aTable->removeRow(0);
1031   }
1032
1033   updateBtnState();
1034 }
1035
1036 //=======================================================================
1037 // name    : SMESHGUI_FilterTable::onCurrentChanged()
1038 // Purpose : SLOT. Called when current cell changed
1039 //=======================================================================
1040 void SMESHGUI_FilterTable::onCurrentChanged (int theRow, int theCol)
1041 {
1042   if( !myIsLocked )
1043     updateAdditionalWidget();
1044   emit CurrentChanged(theRow, theCol);
1045 }
1046
1047 //=======================================================================
1048 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1049 // Purpose : Provides reaction on change of criterion
1050 //=======================================================================
1051 void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, const int entityType)
1052 {
1053   int aType = entityType == -1 ? GetType() : entityType;
1054   Table* aTable = myTables[ aType ];
1055   ComboItem* aCompareItem = (ComboItem*)aTable->item(row, 1);
1056
1057   int aCriterionType = GetCriterionType(row);
1058
1059   if (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ||
1060        aType == SMESH::FACE && aCriterionType == SMESH::FT_FreeEdges ||
1061        aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume)
1062   {
1063     if (aCompareItem->count() > 0)
1064       aCompareItem->setStringList(QStringList());
1065     aTable->SetEditable(false, row, 2);
1066   }
1067   else if (aCriterionType == SMESH::FT_RangeOfIds ||
1068            aCriterionType == SMESH::FT_BelongToGeom ||
1069            aCriterionType == SMESH::FT_BelongToPlane ||
1070            aCriterionType == SMESH::FT_BelongToCylinder ||
1071            aCriterionType == SMESH::FT_LyingOnGeom)
1072   {
1073     QMap<int, QString> aMap;
1074     aMap[ FT_EqualTo ] = tr("EQUAL_TO");
1075     aCompareItem->setStringList(aMap);
1076     if (!aTable->IsEditable(row, 2))
1077       aTable->SetEditable(true, row, 2);
1078   }
1079   else
1080   {
1081     if (aCompareItem->count() != 3)
1082     {
1083       aCompareItem->setStringList(QStringList());
1084       aCompareItem->setStringList(getCompare());
1085     }
1086
1087     QString aText = aTable->text(row, 2);
1088     bool isOk = false;
1089     aText.toDouble(&isOk);
1090     aTable->setText(row, 2, isOk ? aText : QString(""));
1091     if (!aTable->IsEditable(row, 2))
1092       aTable->SetEditable(true, row, 2);
1093   }
1094
1095   updateAdditionalWidget();
1096
1097   emit CriterionChanged(row, entityType);
1098 }
1099
1100 //=======================================================================
1101 // name    : SMESHGUI_FilterTable::onCriterionChanged()
1102 // Purpose : SLOT. Called then contents of table changed
1103 //           Provides reaction on change of criterion
1104 //=======================================================================
1105 void SMESHGUI_FilterTable::onCriterionChanged (int row, int col)
1106 {
1107   onCriterionChanged(row, col, -1);
1108 }
1109
1110 //=======================================================================
1111 // name    : SMESHGUI_FilterTable::getFirstSelectedRow
1112 // Purpose : Get first selected row
1113 //=======================================================================
1114 int SMESHGUI_FilterTable::getFirstSelectedRow() const
1115 {
1116   QTable* aTable = myTables[ GetType() ];
1117   for (int i = 0, n = aTable->numRows(); i < n; i++)
1118     if (aTable->isRowSelected(i))
1119       return i;
1120
1121   int aRow = aTable->currentRow();
1122   return aRow >= 0 && aRow < aTable->numRows() ? aRow : -1;
1123 }
1124
1125 //=======================================================================
1126 // name    : SMESHGUI_FilterTable::addRow
1127 // Purpose : Add row at the end of table
1128 //=======================================================================
1129 void SMESHGUI_FilterTable::addRow (Table* theTable, const int theType, const bool toTheEnd)
1130 {
1131   int aCurrRow = 0;
1132   int aSelectedRow = getFirstSelectedRow();
1133   int aCurrCol = theTable->currentColumn();
1134
1135   myIsLocked = true;
1136   if (toTheEnd || aSelectedRow == -1)
1137   {
1138     theTable->insertRows(theTable->numRows());
1139     aCurrRow = theTable->numRows() - 1;
1140   }
1141   else
1142   {
1143     theTable->insertRows(aSelectedRow);
1144     aCurrRow = aSelectedRow;
1145   }
1146   myIsLocked = false;
1147
1148   // Criteria
1149   theTable->setItem(aCurrRow, 0, getCriterionItem(theTable, theType));
1150
1151   // Compare
1152   theTable->setItem(aCurrRow, 1, getCompareItem(theTable));
1153
1154   // Threshold
1155   //theTable->setItem(aCurrRow, 2, new QTableItem(theTable));
1156
1157   //Logical operation NOT
1158   theTable->setItem(aCurrRow, 3, getUnaryItem(theTable));
1159
1160   // Logical binary operation for previous value
1161   int anAddBinOpStr = -1;
1162   if (aCurrRow == theTable->numRows() - 1)
1163     anAddBinOpStr = aCurrRow - 1;
1164   else if (aCurrRow >= 0 )
1165     anAddBinOpStr = aCurrRow;
1166
1167   if (theTable->item(aCurrRow, 4) == 0 ||
1168        theTable->item(aCurrRow, 4)->rtti() != 1)
1169   {
1170
1171
1172     if (anAddBinOpStr >= 0 &&
1173          (theTable->item(anAddBinOpStr, 4) == 0 ||
1174            theTable->item(anAddBinOpStr, 4)->rtti() != 1))
1175       theTable->setItem(anAddBinOpStr, 4, getBinaryItem(theTable));
1176   }
1177
1178   theTable->SetEditable(false, theTable->numRows() - 1, 4);
1179
1180   if (aCurrRow >=0 && aCurrRow < theTable->numRows() &&
1181        aCurrCol >=0 && aCurrCol < theTable->numRows())
1182   theTable->setCurrentCell(aCurrRow, aCurrCol);
1183
1184   onCriterionChanged(aCurrRow, 0);
1185
1186   updateBtnState();
1187 }
1188
1189 //=======================================================================
1190 // name    : SMESHGUI_FilterTable::getCriterionItem
1191 // Purpose : Get combo table item for criteria of specified type
1192 //=======================================================================
1193 QTableItem* SMESHGUI_FilterTable::getCriterionItem (QTable* theParent , const int theType)
1194 {
1195   return new ComboItem(theParent, getCriteria(theType));
1196 }
1197
1198 //=======================================================================
1199 // name    : SMESHGUI_FilterTable::getCompareItem
1200 // Purpose : Get combo table item for operation of comparision
1201 //=======================================================================
1202 QTableItem* SMESHGUI_FilterTable::getCompareItem (QTable* theParent)
1203 {
1204   return new ComboItem(theParent, getCompare());
1205 }
1206
1207 //=======================================================================
1208 // name    : SMESHGUI_FilterTable::getBinaryItem
1209 // Purpose :
1210 //=======================================================================
1211 QTableItem* SMESHGUI_FilterTable::getBinaryItem (QTable* theParent)
1212 {
1213   static QMap<int, QString> aMap;
1214   if (aMap.isEmpty())
1215   {
1216     aMap[ SMESH::FT_LogicalAND ] = tr("AND");
1217     aMap[ SMESH::FT_LogicalOR  ] = tr("OR");
1218   }
1219
1220   return new ComboItem(theParent, aMap);
1221 }
1222
1223 //=======================================================================
1224 // name    : SMESHGUI_FilterTable::getUnaryItem
1225 // Purpose : Get check table item
1226 //=======================================================================
1227 QTableItem* SMESHGUI_FilterTable::getUnaryItem (QTable* theParent)
1228 {
1229   return new QCheckTableItem(theParent, tr("NOT"));
1230 }
1231
1232 //=======================================================================
1233 // name    : SMESHGUI_FilterTable::getSupportedTypes
1234 // Purpose : Get all supported type
1235 //=======================================================================
1236 const QMap<int, QString>& SMESHGUI_FilterTable::getSupportedTypes() const
1237 {
1238   static QMap<int, QString> aTypes;
1239   if (aTypes.isEmpty())
1240   {
1241     aTypes[ SMESH::NODE   ] = tr("NODES");
1242     aTypes[ SMESH::EDGE   ] = tr("EDGES");
1243     aTypes[ SMESH::FACE   ] = tr("FACES");
1244     aTypes[ SMESH::VOLUME ] = tr("VOLUMES");
1245   }
1246
1247   return aTypes;
1248 }
1249
1250 //=======================================================================
1251 // name    : SMESHGUI_FilterTable::getCriteria
1252 // Purpose : Get criteria for specified type
1253 //=======================================================================
1254 const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType) const
1255 {
1256   if (theType == SMESH::NODE)
1257   {
1258     static QMap<int, QString> aCriteria;
1259     if (aCriteria.isEmpty())
1260     {
1261       aCriteria[ SMESH::FT_RangeOfIds       ] = tr("RANGE_OF_IDS");
1262       aCriteria[ SMESH::FT_BelongToGeom     ] = tr("BELONG_TO_GEOM");
1263       aCriteria[ SMESH::FT_BelongToPlane    ] = tr("BELONG_TO_PLANE");
1264       aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
1265       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr("LYING_ON_GEOM");
1266     }
1267     return aCriteria;
1268   }
1269   else if (theType == SMESH::EDGE)
1270   {
1271     static QMap<int, QString> aCriteria;
1272     if (aCriteria.isEmpty())
1273     {
1274       aCriteria[ SMESH::FT_FreeBorders      ] = tr("FREE_BORDERS");
1275       aCriteria[ SMESH::FT_MultiConnection  ] = tr("MULTI_BORDERS");
1276       aCriteria[ SMESH::FT_Length           ] = tr("LENGTH");
1277       aCriteria[ SMESH::FT_RangeOfIds       ] = tr("RANGE_OF_IDS");
1278       aCriteria[ SMESH::FT_BelongToGeom     ] = tr("BELONG_TO_GEOM");
1279       aCriteria[ SMESH::FT_BelongToPlane    ] = tr("BELONG_TO_PLANE");
1280       aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
1281       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr("LYING_ON_GEOM");
1282     }
1283     return aCriteria;
1284   }
1285   else if (theType == SMESH::FACE)
1286   {
1287     static QMap<int, QString> aCriteria;
1288     if (aCriteria.isEmpty())
1289     {
1290       aCriteria[ SMESH::FT_AspectRatio      ] = tr("ASPECT_RATIO");
1291       aCriteria[ SMESH::FT_Warping          ] = tr("WARPING");
1292       aCriteria[ SMESH::FT_MinimumAngle     ] = tr("MINIMUM_ANGLE");
1293       aCriteria[ SMESH::FT_Taper            ] = tr("TAPER");
1294       aCriteria[ SMESH::FT_Skew             ] = tr("SKEW");
1295       aCriteria[ SMESH::FT_Area             ] = tr("AREA");
1296       aCriteria[ SMESH::FT_FreeEdges        ] = tr("FREE_EDGES");
1297       aCriteria[ SMESH::FT_RangeOfIds       ] = tr("RANGE_OF_IDS");
1298       aCriteria[ SMESH::FT_BelongToGeom     ] = tr("BELONG_TO_GEOM");
1299       aCriteria[ SMESH::FT_BelongToPlane    ] = tr("BELONG_TO_PLANE");
1300       aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
1301       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr("LYING_ON_GEOM");
1302       aCriteria[ SMESH::FT_Length2D         ] = tr("LENGTH2D");
1303       aCriteria[ SMESH::FT_MultiConnection2D] = tr("MULTI2D_BORDERS");
1304     }
1305     return aCriteria;
1306   }
1307   else if (theType == SMESH::VOLUME)
1308   {
1309     static QMap<int, QString> aCriteria;
1310     if (aCriteria.isEmpty())
1311     {
1312       aCriteria[ SMESH::FT_AspectRatio3D] = tr("ASPECT_RATIO_3D");
1313       aCriteria[ SMESH::FT_RangeOfIds   ] = tr("RANGE_OF_IDS");
1314       aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
1315       aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
1316       aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
1317       aCriteria[ SMESH::FT_Volume3D ] = tr("VOLUME_3D");
1318     }
1319     return aCriteria;
1320   }
1321   else
1322   {
1323     static QMap<int, QString> aCriteria;
1324     return aCriteria;
1325   }
1326 }
1327
1328
1329 //=======================================================================
1330 // name    : SMESHGUI_FilterTable::getCompare
1331 // Purpose : Get operation of comparison
1332 //=======================================================================
1333 const QMap<int, QString>& SMESHGUI_FilterTable::getCompare() const
1334 {
1335   static QMap<int, QString> aMap;
1336
1337   if (aMap.isEmpty())
1338   {
1339     aMap[ SMESH::FT_LessThan ] = tr("LESS_THAN");
1340     aMap[ SMESH::FT_MoreThan ] = tr("MORE_THAN");
1341     aMap[ SMESH::FT_EqualTo  ] = tr("EQUAL_TO" );
1342   }
1343
1344   return aMap;
1345 }
1346
1347 //=======================================================================
1348 // name    : SMESHGUI_FilterTable::createTable
1349 // Purpose : Create table
1350 //=======================================================================
1351 SMESHGUI_FilterTable::Table* SMESHGUI_FilterTable::createTable (QWidget*  theParent,
1352                                                                 const int theType)
1353 {
1354   // create table
1355   Table* aTable= new Table(0, 5, theParent);
1356
1357   QHeader* aHeaders = aTable->horizontalHeader();
1358
1359   QFontMetrics aMetrics(aHeaders->font());
1360
1361   // append spaces to the header of criteria in order to
1362   // provide visibility of criterion inside comboboxes
1363   static int aMaxLenCr = 0;
1364
1365   if (aMaxLenCr == 0)
1366   {
1367     const QMap<int, QString>& aSupportedTypes = getSupportedTypes();
1368     QMap<int, QString>::const_iterator anIter;
1369     for (anIter = aSupportedTypes.begin(); anIter != aSupportedTypes.end(); ++anIter)
1370       aMaxLenCr = Max(maxLength(getCriteria(anIter.key()), aMetrics), aMaxLenCr);
1371   }
1372
1373   static int aLenCr = abs( aMaxLenCr -
1374                             aMetrics.width(tr("CRITERION"))) / aMetrics.width(' ') + 5;
1375
1376   QString aCrStr;
1377   aCrStr.fill(' ', aLenCr);
1378   QString aCoStr;
1379   aCoStr.fill(' ', 10);
1380
1381   aHeaders->setLabel(0, tr("CRITERION") + aCrStr);
1382   aHeaders->setLabel(1, tr("COMPARE") + aCoStr);
1383   aHeaders->setLabel(2, tr("THRESHOLD_VALUE"));
1384   aHeaders->setLabel(3, tr("UNARY"));
1385   aHeaders->setLabel(4, tr("BINARY") + "  ");
1386
1387   // set geometry of the table
1388   for (int i = 0; i <= 4; i++)
1389     aTable->adjustColumn(i);
1390
1391   aTable->updateGeometry();
1392   QSize aSize = aTable->sizeHint();
1393   int aWidth = aSize.width();
1394   aTable->setMinimumSize(QSize(aWidth, aWidth / 2));
1395   aTable->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
1396
1397   connect(aTable, SIGNAL(valueChanged(int, int)),
1398            this,   SLOT(onCriterionChanged(int, int)));
1399
1400   connect(aTable, SIGNAL(currentChanged(int, int)),
1401            this,   SLOT(onCurrentChanged(int, int)));
1402
1403   return aTable;
1404 }
1405
1406 //=======================================================================
1407 // name    : SMESHGUI_FilterTable::updateBtnState
1408 // Purpose : Update button state
1409 //=======================================================================
1410 void SMESHGUI_FilterTable::updateBtnState()
1411 {
1412   myRemoveBtn->setEnabled(myTables[ GetType() ]->numRows() > 0);
1413   myClearBtn->setEnabled(myTables[ GetType() ]->numRows() > 0);
1414 }
1415
1416 //=======================================================================
1417 // name    : SMESHGUI_FilterTable::SetEditable
1418 // Purpose : Set read only flag for tables. Show/hide buttons for work with rows
1419 //=======================================================================
1420 void SMESHGUI_FilterTable::SetEditable (const bool isEditable)
1421 {
1422   TableMap::iterator anIter;
1423   for (anIter = myTables.begin(); anIter != myTables.end(); ++anIter)
1424   {
1425     anIter.data()->setReadOnly(!isEditable);
1426
1427     if (isEditable)
1428     {
1429       myAddBtn->show();
1430       myInsertBtn->show();
1431       myRemoveBtn->show();
1432       myClearBtn->show();
1433     }
1434     else
1435     {
1436       myAddBtn->hide();
1437       myInsertBtn->hide();
1438       myRemoveBtn->hide();
1439       myClearBtn->hide();
1440     }
1441   }
1442
1443   QMap<QTableItem*, AdditionalWidget*>::iterator anIter2;
1444   for (anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2)
1445     anIter2.data()->SetEditable(isEditable);
1446 }
1447
1448 //=======================================================================
1449 // name    : SMESHGUI_FilterTable::SetEnabled
1450 // Purpose : Enable/Disable table. Switching type of elements already enabled
1451 //=======================================================================
1452 void SMESHGUI_FilterTable::SetEnabled (const bool isEnabled)
1453 {
1454   myAddBtn->setEnabled(isEnabled);
1455   myInsertBtn->setEnabled(isEnabled);
1456   myRemoveBtn->setEnabled(isEnabled);
1457   myClearBtn->setEnabled(isEnabled);
1458
1459   if (isEnabled)
1460     updateBtnState();
1461
1462   QMap<QTableItem*, AdditionalWidget*>::iterator anIter2;
1463   for (anIter2 = myAddWidgets.begin(); anIter2 != myAddWidgets.end(); ++anIter2)
1464     anIter2.data()->setEnabled(isEnabled);
1465 }
1466
1467 //=======================================================================
1468 // name    : SMESHGUI_FilterTable::IsEditable
1469 // Purpose : Verify whether table is editable
1470 //=======================================================================
1471 bool SMESHGUI_FilterTable::IsEditable() const
1472 {
1473   return !myTables[ GetType() ]->isReadOnly();
1474 }
1475
1476 //=======================================================================
1477 // name    : SMESHGUI_FilterTable::SetLibsEnabled
1478 // Purpose : Show/hide buttons for work with libraries
1479 //=======================================================================
1480 void SMESHGUI_FilterTable::SetLibsEnabled (const bool isEnabled)
1481 {
1482   if (isEnabled)
1483   {
1484     myCopyFromBtn->show();
1485     myAddToBtn->show();
1486   }
1487   else
1488   {
1489     myCopyFromBtn->hide();
1490     myAddToBtn->hide();
1491   }
1492 }
1493
1494 //=======================================================================
1495 // name    : SMESHGUI_FilterTable::onCopyFromBtn
1496 // Purpose : SLOT. Called the "Copy from ..." button clicked
1497 //           Display filter library dialog
1498 //=======================================================================
1499 void SMESHGUI_FilterTable::onCopyFromBtn()
1500 {
1501   if (myLibDlg == 0)
1502     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1503       mySMESHGUI, this, GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM);
1504   else
1505     myLibDlg->Init(GetType(), SMESHGUI_FilterLibraryDlg::COPY_FROM);
1506
1507   if (myLibDlg->exec() == QDialog::Accepted)
1508   {
1509     Copy(myLibDlg->GetTable());
1510     Update();
1511   }
1512 }
1513
1514 //=======================================================================
1515 // name    : SMESHGUI_FilterTable::onAddToBtn
1516 // Purpose : SLOT. Called the "Add to ..." button clicked
1517 //           Display filter library dialog
1518 //=======================================================================
1519 void SMESHGUI_FilterTable::onAddToBtn()
1520 {
1521   if (!IsValid(true))
1522     return;
1523   if (myLibDlg == 0)
1524     myLibDlg = new SMESHGUI_FilterLibraryDlg(
1525       mySMESHGUI, this, GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO);
1526   else
1527     myLibDlg->Init(GetType(), SMESHGUI_FilterLibraryDlg::ADD_TO);
1528
1529   myLibDlg->SetTable(this);
1530
1531   myLibDlg->exec();
1532 }
1533
1534 //=======================================================================
1535 // name    : SMESHGUI_FilterTable::Copy
1536 // Purpose : Initialise table with values of other table
1537 //=======================================================================
1538 void SMESHGUI_FilterTable::Copy (const SMESHGUI_FilterTable* theTable)
1539 {
1540   Clear();
1541
1542   for (int i = 0, n = theTable->NumRows(); i < n; i++)
1543   {
1544     SMESH::Filter::Criterion aCriterion = SMESHGUI_FilterDlg::createCriterion();
1545     theTable->GetCriterion(i, aCriterion);
1546     AddCriterion(aCriterion);
1547   }
1548 }
1549
1550 //=======================================================================
1551 // name    : SMESHGUI_FilterTable::CurrentCell
1552 // Purpose : Returns current cell
1553 //=======================================================================
1554 bool SMESHGUI_FilterTable::CurrentCell (int& theRow, int& theCol) const
1555 {
1556   theRow = myTables[ GetType() ]->currentRow();
1557   theCol = myTables[ GetType() ]->currentColumn();
1558   return theRow >= 0 && theCol >= 0;
1559 }
1560
1561 //=======================================================================
1562 // name    : SMESHGUI_FilterTable::SetText
1563 // Purpose : Set text and internal value in cell of threshold value
1564 //=======================================================================
1565 void SMESHGUI_FilterTable::SetThreshold (const int      theRow,
1566                                          const QString& theText,
1567                                          const int      theEntityType)
1568 {
1569   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1570   aTable->setText(theRow, 2, theText);
1571 }
1572
1573 //=======================================================================
1574 // name    : SMESHGUI_FilterTable::SetText
1575 // Purpose : Get text and internal value from cell of threshold value
1576 //=======================================================================
1577 bool SMESHGUI_FilterTable::GetThreshold (const int      theRow,
1578                                          QString&       theText,
1579                                          const int      theEntityType)
1580 {
1581   Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ];
1582   QTableItem* anItem = aTable->item(theRow, 2);
1583   if (anItem != 0)
1584   {
1585     theText = anItem->text();
1586     return true;
1587   }
1588   else
1589    return false;
1590 }
1591
1592 /*
1593   Class       : SMESHGUI_FilterDlg
1594   Description : Dialog to specify filters for VTK viewer
1595 */
1596
1597
1598 //=======================================================================
1599 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
1600 // Purpose : Constructor
1601 //=======================================================================
1602 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*              theModule,
1603                                         const QValueList<int>& theTypes,
1604                                         const char*            theName)
1605 : QDialog( SMESH::GetDesktop( theModule ), theName, false,
1606            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
1607      mySMESHGUI( theModule ),
1608      mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
1609 {
1610   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1611     mySelector = aViewWindow->GetSelector();
1612
1613   construct(theTypes);
1614 }
1615
1616 //=======================================================================
1617 // name    : SMESHGUI_FilterDlg::SMESHGUI_FilterDlg
1618 // Purpose : Constructor
1619 //=======================================================================
1620 SMESHGUI_FilterDlg::SMESHGUI_FilterDlg( SMESHGUI*   theModule,
1621                                         const int   theType,
1622                                         const char* theName)
1623 : QDialog( SMESH::GetDesktop( theModule ), theName, false,
1624            WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu),
1625      mySMESHGUI( theModule ),
1626      mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
1627 {
1628   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1629     mySelector = aViewWindow->GetSelector();
1630   QValueList<int> aTypes;
1631   aTypes.append(theType);
1632   construct(aTypes);
1633 }
1634
1635 //=======================================================================
1636 // name    : SMESHGUI_FilterDlg::construct
1637 // Purpose : Construct dialog (called by constructor)
1638 //=======================================================================
1639 void SMESHGUI_FilterDlg::construct (const QValueList<int>& theTypes)
1640 {
1641   myTypes = theTypes;
1642
1643   setCaption(tr("CAPTION"));
1644
1645   QVBoxLayout* aDlgLay = new QVBoxLayout (this, MARGIN, SPACING);
1646
1647   myMainFrame        = createMainFrame  (this);
1648   QFrame* aBtnFrame  = createButtonFrame(this);
1649
1650   aDlgLay->addWidget(myMainFrame);
1651   aDlgLay->addWidget(aBtnFrame);
1652
1653   aDlgLay->setStretchFactor(myMainFrame, 1);
1654
1655   Init(myTypes);
1656 }
1657
1658 //=======================================================================
1659 // name    : SMESHGUI_FilterDlg::createMainFrame
1660 // Purpose : Create frame containing dialog's input fields
1661 //=======================================================================
1662 QFrame* SMESHGUI_FilterDlg::createMainFrame (QWidget* theParent)
1663 {
1664   QGroupBox* aMainFrame = new QGroupBox(1, Qt::Horizontal, theParent);
1665   aMainFrame->setFrameStyle(QFrame::NoFrame);
1666   aMainFrame->setInsideMargin(0);
1667
1668   // filter frame
1669
1670   myTable = new SMESHGUI_FilterTable( mySMESHGUI, aMainFrame, myTypes );
1671   myTable->SetLibsEnabled(true);
1672
1673   QFrame* aLine = new QFrame(myTable->GetTableGrp());
1674   aLine->setFrameStyle(QFrame::HLine | QFrame::Sunken);
1675
1676   mySetInViewer = new QCheckBox(tr("SET_IN_VIEWER"), myTable->GetTableGrp());
1677   mySetInViewer->setChecked(true);
1678
1679   // other controls
1680   mySourceGrp = createSourceGroup(aMainFrame);
1681
1682   connect(myTable, SIGNAL(CriterionChanged(const int, const int)),
1683                     SLOT(onCriterionChanged(const int, const int)));
1684
1685   connect(myTable, SIGNAL(CurrentChanged(int, int)),
1686                     SLOT(onCurrentChanged(int, int)));
1687
1688   return aMainFrame;
1689 }
1690
1691 //=======================================================================
1692 // name    : SMESHGUI_FilterDlg::createSourceFrame
1693 // Purpose : Create frame containing source radio button
1694 //=======================================================================
1695 QButtonGroup* SMESHGUI_FilterDlg::createSourceGroup (QWidget* theParent)
1696 {
1697   QButtonGroup* aGrp = new QButtonGroup(1, Qt::Vertical, tr("SOURCE"), theParent);
1698
1699   QRadioButton* aMeshBtn = new QRadioButton(tr("MESH"), aGrp);
1700   QRadioButton* aSelBtn  = new QRadioButton(tr("SELECTION"), aGrp);
1701   QRadioButton* aGrpBtn  = new QRadioButton(tr("CURRENT_GROUP"), aGrp);
1702
1703   aGrp->insert(aMeshBtn, Mesh);
1704   aGrp->insert(aSelBtn, Selection);
1705   aGrp->insert(aGrpBtn, Dialog);
1706
1707   aGrp->setButton(Selection);
1708
1709   return aGrp;
1710 }
1711
1712 //=======================================================================
1713 // name    : SMESHGUI_FilterDlg::updateMainButtons
1714 // Purpose : Update visibility of main buttons (OK, Cancel, Close ...)
1715 //=======================================================================
1716 void SMESHGUI_FilterDlg::updateMainButtons()
1717 {
1718   if (myTypes.count() == 1)
1719   {
1720     myButtons[ BTN_Cancel ]->show();
1721     myButtons[ BTN_Apply  ]->hide();
1722     myButtons[ BTN_Close  ]->hide();
1723   }
1724   else
1725   {
1726     myButtons[ BTN_Cancel ]->hide();
1727     myButtons[ BTN_Apply  ]->show();
1728     myButtons[ BTN_Close  ]->show();
1729   }
1730
1731 //  updateGeometry();
1732 }
1733
1734 //=======================================================================
1735 // name    : SMESHGUI_FilterDlg::createButtonFrame
1736 // Purpose : Create frame containing buttons
1737 //=======================================================================
1738 QFrame* SMESHGUI_FilterDlg::createButtonFrame (QWidget* theParent)
1739 {
1740   QGroupBox* aGrp = new QGroupBox(1, Qt::Vertical, theParent);
1741
1742   myButtons[ BTN_OK    ] = new QPushButton(tr("SMESH_BUT_OK"   ), aGrp);
1743   myButtons[ BTN_Apply ] = new QPushButton(tr("SMESH_BUT_APPLY"), aGrp);
1744
1745   QLabel* aLbl = new QLabel(aGrp);
1746   aLbl->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
1747
1748   myButtons[ BTN_Cancel ] = new QPushButton(tr("SMESH_BUT_CANCEL"), aGrp);
1749   myButtons[ BTN_Close  ] = new QPushButton(tr("SMESH_BUT_CLOSE"), aGrp);
1750
1751   connect(myButtons[ BTN_OK     ], SIGNAL(clicked()), SLOT(onOk()));
1752   connect(myButtons[ BTN_Cancel ], SIGNAL(clicked()), SLOT(onClose()));
1753   connect(myButtons[ BTN_Close  ], SIGNAL(clicked()), SLOT(onClose()));
1754   connect(myButtons[ BTN_Apply  ], SIGNAL(clicked()), SLOT(onApply()));
1755
1756   updateMainButtons();
1757
1758   return aGrp;
1759 }
1760
1761 //=======================================================================
1762 // name    : SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg
1763 // Purpose : Destructor
1764 //=======================================================================
1765 SMESHGUI_FilterDlg::~SMESHGUI_FilterDlg()
1766 {
1767 }
1768
1769 //=======================================================================
1770 // name    : SMESHGUI_FilterDlg::Init
1771 // Purpose : Init dialog fields, connect signals and slots, show dialog
1772 //=======================================================================
1773 void SMESHGUI_FilterDlg::Init (const int type)
1774 {
1775   QValueList<int> aTypes;
1776   aTypes.append(type);
1777   Init(aTypes);
1778 }
1779
1780 //=======================================================================
1781 // name    : SMESHGUI_FilterDlg::Init
1782 // Purpose : Init dialog fields, connect signals and slots, show dialog
1783 //=======================================================================
1784 void SMESHGUI_FilterDlg::Init (const QValueList<int>& theTypes)
1785 {
1786   mySourceWg  = 0;
1787   myTypes     = theTypes;
1788   myMesh      = SMESH::SMESH_Mesh::_nil();
1789   myIObjects.Clear();
1790   myIsSelectionChanged = false;
1791
1792   myTable->Init(theTypes);
1793
1794   // set caption
1795   if (theTypes.count() == 1)
1796   {
1797     int aType = theTypes.first();
1798     if      (aType == SMESH::NODE  ) setCaption(tr("NODES_TLT"));
1799     else if (aType == SMESH::EDGE  ) setCaption(tr("EDGES_TLT"));
1800     else if (aType == SMESH::FACE  ) setCaption(tr("FACES_TLT"));
1801     else if (aType == SMESH::VOLUME) setCaption(tr("VOLUMES_TLT"));
1802   }
1803   else
1804     setCaption(tr("TLT"));
1805
1806   qApp->processEvents();
1807   updateGeometry();
1808   adjustSize();
1809   setEnabled(true);
1810
1811   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
1812
1813   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
1814   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
1815
1816   int x, y;
1817   mySMESHGUI->DefineDlgPosition(this, x, y);
1818   this->move(x, y);
1819
1820   updateMainButtons();
1821   updateSelection();
1822
1823   // Initialise filter table with values of previous filter
1824   QValueList<int>::const_iterator anIter;
1825   for (anIter = theTypes.begin(); anIter != theTypes.end(); ++anIter)
1826   {
1827     myTable->Clear(*anIter);
1828     if (!myFilter[ *anIter ]->_is_nil())
1829     {
1830       SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
1831       if (myFilter[ *anIter ]->GetCriteria(aCriteria))
1832       {
1833         for (int i = 0, n = aCriteria->length(); i < n; i++)
1834           myTable->AddCriterion(aCriteria[ i ], *anIter);
1835       }
1836     }
1837   }
1838
1839   if (myInsertState.contains(theTypes.first()))
1840     mySetInViewer->setChecked(myInsertState[ theTypes.first() ]);
1841   else
1842     mySetInViewer->setChecked(true);
1843   if (myApplyToState.contains(theTypes.first()))
1844     mySourceGrp->setButton(myApplyToState[ theTypes.first() ]);
1845   else
1846     mySourceGrp->setButton(Selection);
1847 }
1848
1849 //=======================================================================
1850 // name    : SMESHGUI_FilterDlg::onOk
1851 // Purpose : SLOT called when "Ok" button pressed.
1852 //           Assign filters VTK viewer and close dialog
1853 //=======================================================================
1854 void SMESHGUI_FilterDlg::onOk()
1855 {
1856   if (onApply())
1857   {
1858     mySelectionMgr->clearFilters();
1859     disconnect(mySMESHGUI, 0, this, 0);
1860     disconnect(mySelectionMgr, 0, this, 0);
1861     mySMESHGUI->ResetState();
1862     accept();
1863     emit Accepted();
1864   }
1865 }
1866
1867 //=======================================================================
1868 // name    : SMESHGUI_FilterDlg::onClose
1869 // Purpose : SLOT called when "Close" button pressed. Close dialog
1870 //=======================================================================
1871 void SMESHGUI_FilterDlg::onClose()
1872 {
1873   // Restore previously selected object
1874   if (mySelectionMgr)
1875   {
1876     SALOME_ListIO aList;
1877     mySelectionMgr->clearFilters();
1878     mySelectionMgr->clearSelected();
1879     SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter (myIObjects);
1880     for (; anIter.More(); anIter.Next())
1881     {
1882       aList.Append(anIter.Key());
1883
1884       TColStd_MapOfInteger aResMap;
1885       const TColStd_IndexedMapOfInteger& anIndMap = anIter.Value();
1886       for (int i = 1, n = anIndMap.Extent(); i <= n; i++)
1887         aResMap.Add(anIndMap(i));
1888
1889       mySelector->AddOrRemoveIndex( anIter.Key(), aResMap, false);
1890       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1891         aViewWindow->highlight( anIter.Key(), true, true );
1892     }
1893     mySelectionMgr->setSelectedObjects(aList, false);
1894   }
1895
1896   disconnect(mySMESHGUI, 0, this, 0);
1897   disconnect(mySelectionMgr, 0, this, 0);
1898   mySMESHGUI->ResetState();
1899   reject();
1900   return;
1901 }
1902
1903 //=======================================================================
1904 // name    : SMESHGUI_FilterDlg::onDeactivate
1905 // Purpose : SLOT called when dialog must be deativated
1906 //=======================================================================
1907 void SMESHGUI_FilterDlg::onDeactivate()
1908 {
1909   setEnabled(false);
1910 }
1911
1912 //=======================================================================
1913 // name    : SMESHGUI_FilterDlg::enterEvent
1914 // Purpose : Event filter
1915 //=======================================================================
1916 void SMESHGUI_FilterDlg::enterEvent (QEvent*)
1917 {
1918 //  mySMESHGUI->EmitSignalDeactivateDialog();
1919   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
1920   mySMESHGUI->ResetState();
1921   setEnabled(true);
1922 }
1923
1924 //=======================================================================
1925 // name    : closeEvent()
1926 // Purpose :
1927 //=======================================================================
1928 void SMESHGUI_FilterDlg::closeEvent (QCloseEvent*)
1929 {
1930   onClose();
1931 }
1932
1933 //=======================================================================
1934 // name    : SMESHGUI_FilterDlg::getIdsFromWg
1935 // Purpose : Retrieve list of ids from given widget
1936 //=======================================================================
1937 void SMESHGUI_FilterDlg::getIdsFromWg (const QWidget* theWg, QValueList<int>& theRes) const
1938 {
1939   theRes.clear();
1940   if (theWg == 0)
1941     return;
1942
1943   if (theWg->inherits("QListBox"))
1944   {
1945     QListBox* aListBox = (QListBox*)theWg;
1946     bool b;
1947     for (int i = 0, n = aListBox->count(); i < n; i++)
1948     {
1949       int anId = aListBox->text(i).toInt(&b);
1950       if (b)
1951         theRes.append(anId);
1952     }
1953   }
1954   else if (theWg->inherits("QLineEdit"))
1955   {
1956     QLineEdit* aLineEdit = (QLineEdit*)theWg;
1957     QString aStr = aLineEdit->text();
1958     QRegExp aRegExp("(\\d+)");
1959     bool b;
1960     int aPos = 0;
1961     while (aPos >= 0)
1962     {
1963       aPos = aRegExp.search(aStr, aPos);
1964       if (aPos > -1)
1965       {
1966         int anId = aRegExp.cap(1).toInt(&b);
1967         if (b)
1968           theRes.append(anId);
1969         aPos += aRegExp.matchedLength();
1970       }
1971     }
1972   }
1973 }
1974
1975 //=======================================================================
1976 // name    : SMESHGUI_FilterDlg::getSelMode
1977 // Purpose : Get selection mode of specified type
1978 //=======================================================================
1979 Selection_Mode SMESHGUI_FilterDlg::getSelMode (const int theType) const
1980 {
1981   switch (theType)
1982   {
1983     case SMESH::NODE   : return NodeSelection;
1984     case SMESH::EDGE   : return EdgeSelection;
1985     case SMESH::FACE   : return FaceSelection;
1986     case SMESH::VOLUME : return VolumeSelection;
1987     default            : return ActorSelection;
1988   }
1989
1990 }
1991
1992 //=======================================================================
1993 // name    : SMESHGUI_FilterDlg::setIdsToWg
1994 // Purpose : Insert identifiers in specified widgets
1995 //=======================================================================
1996 void SMESHGUI_FilterDlg::setIdsToWg (QWidget* theWg, const QValueList<int>& theIds)
1997 {
1998   if (theWg == 0)
1999     return;
2000
2001   if (theWg->inherits("QListBox"))
2002   {
2003     QListBox* aListBox = (QListBox*)theWg;
2004     aListBox->clear();
2005
2006     QStringList aStrList;
2007     QValueList<int>::const_iterator anIter;
2008     for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter)
2009       aStrList.append(QString("%1").arg(*anIter));
2010
2011     aListBox->insertStringList(aStrList);
2012   }
2013   else if (theWg->inherits("QLineEdit"))
2014   {
2015     QLineEdit* aLineEdit = (QLineEdit*)theWg;
2016     QString aStr;
2017     QValueList<int>::const_iterator anIter;
2018
2019     for (anIter = theIds.begin(); anIter != theIds.end(); ++ anIter)
2020       aStr += QString("%1 ").arg(*anIter);
2021
2022     if (!aStr.isEmpty())
2023       aStr.remove(aStr.length() - 1, 1);
2024
2025     aLineEdit->setText(aStr);
2026   }
2027 }
2028
2029 //=======================================================================
2030 // name    : SMESHGUI_FilterDlg::isValid
2031 // Purpose : Verify validity of input data
2032 //=======================================================================
2033 bool SMESHGUI_FilterDlg::isValid() const
2034 {
2035   if (!myTable->IsValid())
2036     return false;
2037
2038   for (int i = 0, n = myTable->NumRows(); i < n; i++)
2039   {
2040     int aType = myTable->GetCriterionType(i);
2041     if (aType == FT_BelongToGeom ||
2042         aType == FT_BelongToPlane ||
2043         aType == FT_BelongToCylinder ||
2044         aType == FT_LyingOnGeom) {
2045       QString aName;
2046       myTable->GetThreshold(i, aName);
2047
2048       std::vector<_PTR(SObject)> aList =
2049         SMESH::GetActiveStudyDocument()->FindObjectByName(aName.latin1(), "GEOM");
2050       if (aList.size() == 0) {
2051         QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2052                                  tr("BAD_SHAPE_NAME").arg(aName), QMessageBox::Ok);
2053         return false;
2054       }
2055
2056       if (aType == FT_BelongToCylinder || aType == FT_BelongToPlane) {
2057         CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
2058         //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
2059         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
2060         if (!aGeomObj->_is_nil()) {
2061           TopoDS_Shape aFace;
2062           if (!GEOMBase::GetShape(aGeomObj, aFace) ||
2063                aFace.IsNull() ||
2064                aFace.ShapeType() != TopAbs_FACE) {
2065             QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2066                                      tr("SHAPE_IS_NOT_A_FACE").arg(aName), QMessageBox::Ok);
2067             return false;
2068           }
2069
2070           Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace));
2071           if (aSurf.IsNull()) {
2072             QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2073                                      tr("SHAPE_IS_NOT_A_FACE").arg(aName), QMessageBox::Ok);
2074             return false;
2075           }
2076
2077           if (aType == FT_BelongToPlane && !aSurf->IsKind(STANDARD_TYPE(Geom_Plane))) {
2078             QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2079                                      tr("SHAPE_IS_NOT_A_PLANE").arg(aName), QMessageBox::Ok);
2080             return false;
2081           }
2082
2083           if (aType == FT_BelongToCylinder && !aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
2084             QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"),
2085                                      tr("SHAPE_IS_NOT_A_CYLINDER").arg(aName), QMessageBox::Ok);
2086             return false;
2087           }
2088         }
2089       }
2090     }
2091   }
2092
2093   return true;
2094 }
2095
2096 //=======================================================================
2097 // name    : SMESHGUI_FilterDlg::SetSourceWg
2098 // Purpose : Set widget of parent dialog containing idsto be filtered if
2099 //           user select corresponding source radio button
2100 //=======================================================================
2101 void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg)
2102 {
2103   mySourceWg = theWg;
2104 }
2105
2106 //=======================================================================
2107 // name    : SMESHGUI_FilterDlg::SetGroupIds
2108 // Purpose : Set mesh
2109 //=======================================================================
2110 void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_ptr theMesh)
2111 {
2112   myMesh = theMesh;
2113 }
2114
2115 //=======================================================================
2116 // name    : SMESHGUI_FilterDlg::SetSelection
2117 // Purpose : Get filtered ids
2118 //=======================================================================
2119 void SMESHGUI_FilterDlg::SetSelection()
2120 {
2121   if (mySelectionMgr)
2122     disconnect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionDone()));
2123
2124   if (mySelectionMgr) {
2125     myIObjects.Clear();
2126     const SALOME_ListIO& anObjs = mySelector->StoredIObjects();
2127     SALOME_ListIteratorOfListIO anIter (anObjs);
2128     for (; anIter.More(); anIter.Next()) {
2129       TColStd_IndexedMapOfInteger aMap;
2130       mySelector->GetIndex(anIter.Value(), aMap);
2131       myIObjects.Bind(anIter.Value(), aMap);
2132     }
2133
2134     connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
2135
2136     updateSelection();
2137   }
2138   else
2139     myIObjects.Clear();
2140 }
2141
2142 //=======================================================================
2143 // name    : SMESHGUI_FilterDlg::onApply
2144 // Purpose : SLOT called when "Apply" button pressed.
2145 //           Assign filters to VTK viewer
2146 //=======================================================================
2147 bool SMESHGUI_FilterDlg::onApply()
2148 {
2149   if (!isValid())
2150     return false;
2151
2152   try {
2153     int aCurrType = myTable->GetType();
2154
2155     if (!createFilter(aCurrType))
2156       return false;
2157
2158     insertFilterInViewer();
2159
2160     if (!myFilter[ aCurrType ]->GetPredicate()->_is_nil()) {
2161       QValueList<int> aResultIds;
2162       filterSource(aCurrType, aResultIds);
2163       selectInViewer(aCurrType, aResultIds);
2164     }
2165
2166     myInsertState[ aCurrType ] = mySetInViewer->isChecked();
2167     myApplyToState[ aCurrType ] = mySourceGrp->id(mySourceGrp->selected());
2168   }
2169   catch(const SALOME::SALOME_Exception& S_ex)
2170   {
2171     SalomeApp_Tools::QtCatchCorbaException(S_ex);
2172   }
2173   catch(...)
2174   {
2175   }
2176
2177   return true;
2178 }
2179
2180 //=======================================================================
2181 // name    : SMESHGUI_FilterDlg::createFilter
2182 // Purpose : Create predicate for given type
2183 //=======================================================================
2184 bool SMESHGUI_FilterDlg::createFilter (const int theType)
2185 {
2186   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
2187   if (aFilterMgr->_is_nil())
2188     return false;
2189
2190   int n = myTable->NumRows();
2191
2192   SMESH::Filter::Criteria_var aCriteria = new SMESH::Filter::Criteria;
2193   aCriteria->length(n);
2194
2195   long aPrecision = -1;
2196   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
2197
2198   if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) )
2199     aPrecision = mgr->integerValue( "SMESH", "controls_precision", aPrecision );
2200
2201   for (CORBA::ULong i = 0; i < n; i++) {
2202     SMESH::Filter::Criterion aCriterion = createCriterion();
2203     myTable->GetCriterion(i, aCriterion);
2204     aCriterion.Precision = aPrecision;
2205     aCriteria[ i ] = aCriterion;
2206   }
2207
2208   myFilter[ theType ] = aFilterMgr->CreateFilter();
2209   myFilter[ theType ]->SetCriteria(aCriteria.inout());
2210
2211   return true;
2212 }
2213
2214 //=======================================================================
2215 // name    : SMESHGUI_FilterDlg::insertFilterInViewer
2216 // Purpose : Insert filter in viewer
2217 //=======================================================================
2218 void SMESHGUI_FilterDlg::insertFilterInViewer()
2219 {
2220   if (SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle()) {
2221     SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType();
2222
2223     if (myFilter[ myTable->GetType() ]->_is_nil() ||
2224          myFilter[ myTable->GetType() ]->GetPredicate()->_is_nil() ||
2225          !mySetInViewer->isChecked()) {
2226       SMESH::RemoveFilter(getFilterId(anEntType), aStyle);
2227     } else {
2228       Handle(SMESHGUI_PredicateFilter) aFilter = new SMESHGUI_PredicateFilter();
2229       aFilter->SetPredicate(myFilter[ myTable->GetType() ]->GetPredicate());
2230       SMESH::SetFilter(aFilter, aStyle);
2231     }
2232   }
2233 }
2234
2235 //=======================================================================
2236 // name    : SMESHGUI_FilterDlg::filterSource
2237 // Purpose : Filter source ids
2238 //=======================================================================
2239 void SMESHGUI_FilterDlg::filterSource (const int theType,
2240                                        QValueList<int>& theResIds)
2241 {
2242   theResIds.clear();
2243   if (myFilter[ theType ]->_is_nil())
2244     return;
2245
2246   int aSourceId = mySourceGrp->id(mySourceGrp->selected());
2247
2248   if (aSourceId == Mesh)
2249   {
2250     if (myMesh->_is_nil())
2251       return;
2252     SMESH::long_array_var anIds = myFilter[ theType ]->GetElementsId(myMesh);
2253     for (int i = 0, n = anIds->length(); i < n; i++)
2254       theResIds.append(anIds[ i ]);
2255   }
2256   else if (aSourceId == Selection)
2257   {
2258     filterSelectionSource(theType, theResIds);
2259   }
2260   else if (aSourceId == Dialog)
2261   {
2262     // retrieve ids from dialog
2263     QValueList<int> aDialogIds;
2264     getIdsFromWg(mySourceWg, aDialogIds);
2265
2266     if (myMesh->_is_nil())
2267     {
2268       theResIds = aDialogIds;
2269       return;
2270     }
2271
2272     // filter ids
2273     SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2274     aPred->SetMesh(myMesh);
2275     QValueList<int>::const_iterator anIter;
2276     for (anIter = aDialogIds.begin(); anIter != aDialogIds.end(); ++ anIter)
2277       if (aPred->IsSatisfy(*anIter))
2278         theResIds.append(*anIter);
2279
2280     // set ids to the dialog
2281     setIdsToWg(mySourceWg, theResIds);
2282   }
2283 }
2284
2285 //=======================================================================
2286 // name    : SMESHGUI_FilterDlg::filterSelectionSource
2287 // Purpose : Filter source selection
2288 //=======================================================================
2289 void SMESHGUI_FilterDlg::filterSelectionSource (const int theType,
2290                                                 QValueList<int>& theResIds)
2291 {
2292   theResIds.clear();
2293   if (myMesh->_is_nil() || mySelectionMgr == 0)
2294     return;
2295
2296   // Create map of entities to be filtered
2297   TColStd_MapOfInteger aToBeFiltered;
2298   SALOME_DataMapIteratorOfDataMapOfIOMapOfInteger anIter(myIObjects);
2299
2300   for (; anIter.More(); anIter.Next())
2301   {
2302     // process sub mesh
2303     SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Key());
2304     if (!aSubMesh->_is_nil())
2305     {
2306       if (aSubMesh->GetFather()->GetId() == myMesh->GetId())
2307       {
2308         SMESH::long_array_var anIds =
2309           theType == SMESH::NODE ? aSubMesh->GetNodesId() : aSubMesh->GetElementsId();
2310         for (int i = 0, n = anIds->length(); i < n; i++)
2311           aToBeFiltered.Add(anIds[ i ]);
2312       }
2313     }
2314
2315     // process group
2316     SMESH::SMESH_GroupBase_var aGroup =
2317       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Key());
2318     if (!aGroup->_is_nil())
2319     {
2320       if (aGroup->GetType() == theType && aGroup->GetMesh()->GetId() == myMesh->GetId())
2321       {
2322         SMESH::long_array_var anIds = aGroup->GetListOfID();
2323         for (int i = 0, n = anIds->length(); i < n; i++)
2324           aToBeFiltered.Add(anIds[ i ]);
2325       }
2326     }
2327
2328     // process mesh
2329     SMESH::SMESH_Mesh_var aMeshPtr = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIter.Key());
2330     if (!aMeshPtr->_is_nil() && aMeshPtr->GetId() == myMesh->GetId())
2331     {
2332       const TColStd_IndexedMapOfInteger& aSelMap = anIter.Value();
2333
2334       if (aSelMap.Extent() > 0)
2335       {
2336         if(SMESH::FindActorByEntry(anIter.Key()->getEntry()))
2337         {
2338           for (int i = 1; i <= aSelMap.Extent(); i++)
2339             aToBeFiltered.Add(aSelMap(i));
2340         }
2341       }
2342     }
2343   }
2344
2345   // Filter entities
2346   SMESH::Predicate_ptr aPred = myFilter[ theType ]->GetPredicate();
2347   aPred->SetMesh(myMesh);
2348   TColStd_MapIteratorOfMapOfInteger aResIter(aToBeFiltered);
2349   for (; aResIter.More(); aResIter.Next())
2350     if (aPred->IsSatisfy(aResIter.Key()))
2351       theResIds.append(aResIter.Key());
2352 }
2353
2354 //=======================================================================
2355 // name    : SMESHGUI_FilterDlg::selectInViewer
2356 // Purpose : Select given entities in viewer
2357 //=======================================================================
2358 void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QValueList<int>& theIds)
2359 {
2360   if (mySelectionMgr == 0 || myMesh->_is_nil())
2361     return;
2362
2363   mySelectionMgr->clearFilters();
2364
2365   // Set new selection mode if necessary
2366   Selection_Mode aSelMode = getSelMode(theType);
2367   SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
2368   if ( aViewWindow && aViewWindow->SelectionMode()!=aSelMode) {
2369     mySelectionMgr->clearSelected();
2370     mySelectionMgr->clearFilters();
2371     if (aSelMode == NodeSelection)
2372       SMESH::SetPointRepresentation(true);
2373     aViewWindow->SetSelectionMode(aSelMode);
2374   }
2375
2376   // Clear selection
2377   SMESH_Actor* anActor = SMESH::FindActorByObject(myMesh);
2378   if (!anActor || !anActor->hasIO())
2379     return;
2380
2381   Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
2382   //mySelectionMgr->clearSelected();
2383   //mySelectionMgr->AddIObject(anIO, false);
2384   SALOME_ListIO aList;
2385   aList.Append(anIO);
2386   mySelectionMgr->setSelectedObjects(aList, false);
2387
2388   // Remove filter corresponding to the current type from viewer
2389   int aType = myTable->GetType();
2390   int aFilterId = SMESHGUI_UnknownFilter;
2391   if      (aType == SMESH::EDGE  ) aFilterId = SMESHGUI_EdgeFilter;
2392   else if (aType == SMESH::FACE  ) aFilterId = SMESHGUI_FaceFilter;
2393   else if (aType == SMESH::VOLUME) aFilterId = SMESHGUI_VolumeFilter;
2394   Handle(VTKViewer_Filter) aFilter = SMESH::GetFilter(aFilterId);
2395   SMESH::RemoveFilter(aFilterId);
2396
2397   // get vtk ids
2398   TColStd_MapOfInteger aMap;
2399   QValueList<int>::const_iterator anIter;
2400   for (anIter = theIds.begin(); anIter != theIds.end(); ++anIter) {
2401     aMap.Add(*anIter);
2402   }
2403
2404   // Set new selection
2405   mySelector->AddOrRemoveIndex(anIO, aMap, false);
2406   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
2407     aViewWindow->highlight( anIO, true, true );
2408
2409   // insert previously stored filter in viewer if necessary
2410   if (!aFilter.IsNull())
2411     SMESH::SetFilter(aFilter);
2412 }
2413
2414 //=======================================================================
2415 // name    : SMESHGUI_FilterDlg::createCriterion
2416 // Purpose : Create criterion structure with default values
2417 //=======================================================================
2418 SMESH::Filter::Criterion SMESHGUI_FilterDlg::createCriterion()
2419 {
2420    SMESH::Filter::Criterion aCriterion;
2421
2422   aCriterion.Type          = FT_Undefined;
2423   aCriterion.Compare       = FT_Undefined;
2424   aCriterion.Threshold     = 0;
2425   aCriterion.UnaryOp       = FT_Undefined;
2426   aCriterion.BinaryOp      = FT_Undefined;
2427   aCriterion.ThresholdStr  = "";
2428   aCriterion.TypeOfElement = SMESH::ALL;
2429
2430   return aCriterion;
2431 }
2432
2433 //=======================================================================
2434 // name    : SMESHGUI_FilterDlg::onSelectionDone
2435 // Purpose : SLOT called when selection changed.
2436 //           If current cell corresponds to the threshold value of
2437 //           BelongToGeom criterion name of selected object is set in this cell
2438 //=======================================================================
2439 void SMESHGUI_FilterDlg::onSelectionDone()
2440 {
2441   int aRow, aCol;
2442   const SALOME_ListIO& aList = mySelector->StoredIObjects();
2443
2444   if (aList.Extent() != 1 ||
2445       !myTable->CurrentCell(aRow, aCol) ||
2446       myTable->GetCriterionType(aRow) != FT_BelongToGeom &&
2447       myTable->GetCriterionType(aRow) != FT_BelongToPlane &&
2448       myTable->GetCriterionType(aRow) != FT_BelongToCylinder &&
2449       myTable->GetCriterionType(aRow) != FT_LyingOnGeom)
2450     return;
2451
2452   Handle(SALOME_InteractiveObject) anIO = aList.First();
2453   GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
2454   if (!anObj->_is_nil())
2455     myTable->SetThreshold(aRow, GEOMBase::GetName(anObj));
2456 }
2457
2458 //=======================================================================
2459 // name    : SMESHGUI_FilterDlg::onCriterionChanged
2460 // Purpose : SLOT called when cretarion of current row changed. Update selection
2461 //=======================================================================
2462 void SMESHGUI_FilterDlg::onCriterionChanged (const int , const int)
2463 {
2464   updateSelection();
2465 }
2466
2467 //=======================================================================
2468 // name    : SMESHGUI_FilterDlg::onCurrentChanged
2469 // Purpose : SLOT called when current row changed. Update selection
2470 //=======================================================================
2471 void SMESHGUI_FilterDlg::onCurrentChanged (int, int)
2472 {
2473   updateSelection();
2474 }
2475
2476 //=======================================================================
2477 // name    : SMESHGUI_FilterDlg::updateSelection
2478 // Purpose : UpdateSelection in accordance with current row
2479 //=======================================================================
2480 void SMESHGUI_FilterDlg::updateSelection()
2481 {
2482   if (mySelectionMgr == 0)
2483     return;
2484
2485   TColStd_MapOfInteger allTypes;
2486   for( int i=0; i<10; i++ )
2487     allTypes.Add( i );
2488   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( mySMESHGUI->application()->activeStudy() );
2489   if( !aStudy )
2490     return;
2491
2492
2493   mySelectionMgr->clearFilters();
2494
2495   int aRow, aCol;
2496
2497   if (myTable->CurrentCell(aRow, aCol) &&
2498       (myTable->GetCriterionType(aRow) == FT_BelongToGeom ||
2499        myTable->GetCriterionType(aRow) == FT_BelongToPlane ||
2500        myTable->GetCriterionType(aRow) == FT_BelongToCylinder ||
2501        myTable->GetCriterionType(aRow) == FT_LyingOnGeom)) {
2502
2503     if (myTable->GetCriterionType(aRow) == FT_BelongToGeom ||
2504         myTable->GetCriterionType(aRow) == FT_LyingOnGeom) {
2505
2506       mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true ));
2507
2508     } else if (myTable->GetCriterionType(aRow) == FT_BelongToPlane) {
2509       mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Plane ) );
2510
2511     } else if (myTable->GetCriterionType(aRow) == FT_BelongToCylinder) {
2512       mySelectionMgr->installFilter(new GEOM_FaceFilter( aStudy, StdSelect_Cylinder ) );
2513     }
2514     myIsSelectionChanged = true;
2515
2516   } else {
2517     if (myIsSelectionChanged) {
2518       mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection
2519     }
2520   }
2521 }