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