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