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