Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_MultiEditDlg.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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : SMESHGUI_MultiEditDlg.cxx
25 //  Author : Sergey LITONIN
26 //  Module : SMESH
27
28 #include "SMESHGUI_MultiEditDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_Filter.h"
32 #include "SMESHGUI_FilterDlg.h"
33 #include "SMESHGUI_Utils.h"
34 #include "SMESHGUI_VTKUtils.h"
35 #include "SMESHGUI_MeshUtils.h"
36 #include "SMESHGUI_FilterUtils.h"
37 #include "SMESHGUI_SpinBox.h"
38
39 #include "SMESH_Actor.h"
40 #include "SMESH_TypeFilter.hxx"
41 #include "SMDS_Mesh.hxx"
42 #include "SMDS_MeshElement.hxx"
43
44 #include "SUIT_ResourceMgr.h"
45 #include "SUIT_Desktop.h"
46 #include "SUIT_Session.h"
47 #include "SUIT_MessageBox.h"
48
49 #include "LightApp_SelectionMgr.h"
50 #include "LightApp_Application.h"
51 #include "SALOME_ListIO.hxx"
52 #include "SALOME_ListIteratorOfListIO.hxx"
53
54 #include "SVTK_Selector.h"
55 #include "SVTK_ViewModel.h"
56 #include "SVTK_ViewWindow.h"
57 #include "VTKViewer_CellLocationsArray.h"
58
59 // OCCT Includes
60 #include <Precision.hxx>
61 #include <TColStd_IndexedMapOfInteger.hxx>
62 #include <TColStd_DataMapOfIntegerInteger.hxx>
63 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
64
65 // VTK Includes
66 #include <vtkCell3D.h>
67 #include <vtkQuad.h>
68 #include <vtkTriangle.h>
69 #include <vtkPolygon.h>
70 #include <vtkConvexPointSet.h>
71 #include <vtkIdList.h>
72 #include <vtkCellArray.h>
73 #include <vtkUnsignedCharArray.h>
74 #include <vtkUnstructuredGrid.h>
75 #include <vtkDataSetMapper.h>
76 #include <vtkProperty.h>
77
78 // QT Includes
79 #include <qframe.h>
80 #include <qlabel.h>
81 #include <qlayout.h>
82 #include <qlistbox.h>
83 #include <qcheckbox.h>
84 #include <qcombobox.h>
85 #include <qgroupbox.h>
86 #include <qlineedit.h>
87 #include <qpushbutton.h>
88 #include <qapplication.h>
89 #include <qradiobutton.h>
90 #include <qhbuttongroup.h>
91
92 // IDL Headers
93 #include "SALOMEconfig.h"
94 #include CORBA_SERVER_HEADER(SMESH_Group)
95
96 #define SPACING 5
97 #define MARGIN  10
98
99 /*!
100  *  Class       : SMESHGUI_MultiEditDlg
101  *  Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
102  *                2 neighboring triangles with 1 common edge
103  */
104
105 //=======================================================================
106 // name    : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
107 // Purpose : Constructor
108 //=======================================================================
109 SMESHGUI_MultiEditDlg
110 ::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
111                         const int theMode,
112                         const bool the3d2d,
113                         const char* theName):
114   QDialog(SMESH::GetDesktop(theModule),
115           theName,
116           false,
117           WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
118     mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
119     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
120     mySMESHGUI(theModule)
121 {
122   myFilterDlg = 0;
123   myEntityType = 0;
124
125   myFilterType = theMode;
126   QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
127
128   QFrame* aMainFrame = createMainFrame  (this, the3d2d);
129   QFrame* aBtnFrame  = createButtonFrame(this);
130
131   aDlgLay->addWidget(aMainFrame);
132   aDlgLay->addWidget(aBtnFrame);
133
134   aDlgLay->setStretchFactor(aMainFrame, 1);
135   aDlgLay->setStretchFactor(aBtnFrame, 0);
136   Init();
137 }
138
139 //=======================================================================
140 // name    : SMESHGUI_MultiEditDlg::createMainFrame
141 // Purpose : Create frame containing dialog's input fields
142 //=======================================================================
143 QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
144 {
145   QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
146   aMainGrp->setFrameStyle(QFrame::NoFrame);
147   aMainGrp->setInsideMargin(0);
148
149   QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
150
151   // "Selected cells" group
152   mySelGrp = new QGroupBox(1, Qt::Horizontal,  aMainGrp);
153
154   myEntityTypeGrp = 0;
155   if (the3d2d) {
156     myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
157     (new QRadioButton(tr("SMESH_FACE"),   myEntityTypeGrp))->setChecked(true);
158     (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
159     myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
160   }
161
162   QFrame* aFrame = new QFrame(mySelGrp);
163
164   myListBox = new QListBox(aFrame);
165   myListBox->setSelectionMode(QListBox::Extended);
166   myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
167   myListBox->installEventFilter(this);
168
169   myFilterBtn = new QPushButton(tr("FILTER")   , aFrame);
170   myAddBtn    = new QPushButton(tr("ADD")      , aFrame);
171   myRemoveBtn = new QPushButton(tr("REMOVE")   , aFrame);
172   mySortBtn   = new QPushButton(tr("SORT_LIST"), aFrame);
173
174   QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5);
175   aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0);
176   aLay->addWidget(myFilterBtn, 0, 1);
177   aLay->addWidget(myAddBtn, 1, 1);
178   aLay->addWidget(myRemoveBtn, 2, 1);
179   aLay->addWidget(mySortBtn, 3, 1);
180
181   QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
182   aLay->addItem(aSpacer, 4, 1);
183
184   myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
185
186   // Split/Join criterion group
187   myCriterionGrp = new QGroupBox(3, Qt::Vertical, tr("SPLIT_JOIN_CRITERION"), aMainGrp);
188
189   myGroupChoice = new QButtonGroup(3, Qt::Vertical, myCriterionGrp);
190   myGroupChoice->setInsideMargin(0);
191   myGroupChoice->setFrameStyle(QFrame::NoFrame);
192   (new QRadioButton(tr("USE_DIAGONAL_1_3"), myGroupChoice))->setChecked(true);
193   (new QRadioButton(tr("USE_DIAGONAL_2_4"), myGroupChoice));
194   (new QRadioButton(tr("USE_NUMERIC_FUNC"), myGroupChoice));
195
196   myComboBoxFunctor = new QComboBox(myCriterionGrp);
197   myComboBoxFunctor->insertItem(tr("ASPECTRATIO_ELEMENTS"));
198   myComboBoxFunctor->insertItem(tr("MINIMUMANGLE_ELEMENTS"));
199   myComboBoxFunctor->insertItem(tr("SKEW_ELEMENTS"));
200   myComboBoxFunctor->insertItem(tr("AREA_ELEMENTS"));
201   //myComboBoxFunctor->insertItem(tr("LENGTH2D_EDGES")); // for existing elements only
202   //myComboBoxFunctor->insertItem(tr("MULTI2D_BORDERS")); // for existing elements only
203   myComboBoxFunctor->setCurrentItem(0);
204
205   myCriterionGrp->hide();
206   myGroupChoice->hide();
207   myComboBoxFunctor->setEnabled(false);
208
209   // "Select from" group
210   QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
211
212   mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
213   mySubmeshBtn = new QPushButton(aGrp);
214   mySubmesh = new QLineEdit(aGrp);
215   mySubmesh->setReadOnly(true);
216   mySubmeshBtn->setPixmap(aPix);
217
218   myGroupChk = new QCheckBox(tr("SMESH_GROUP"), aGrp);
219   myGroupBtn = new QPushButton(aGrp);
220   myGroup = new QLineEdit(aGrp);
221   myGroup->setReadOnly(true);
222   myGroupBtn->setPixmap(aPix);
223
224   return aMainGrp;
225 }
226
227 //=======================================================================
228 // name    : SMESHGUI_MultiEditDlg::createButtonFrame
229 // Purpose : Create frame containing buttons
230 //=======================================================================
231 QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
232 {
233   QFrame* aFrame = new QFrame (theParent);
234   aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
235
236   myOkBtn     = new QPushButton (tr("SMESH_BUT_OK"   ), aFrame);
237   myApplyBtn  = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
238   myCloseBtn  = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
239   myHelpBtn   = new QPushButton (tr("SMESH_BUT_HELP"), aFrame);
240
241   QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
242
243   QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
244
245   aLay->addWidget(myOkBtn);
246   aLay->addWidget(myApplyBtn);
247   aLay->addItem(aSpacer);
248   aLay->addWidget(myCloseBtn);
249   aLay->addWidget(myHelpBtn);
250
251   return aFrame;
252 }
253
254 //=======================================================================
255 // name    : SMESHGUI_MultiEditDlg::isValid
256 // Purpose : Verify validity of input data
257 //=======================================================================
258 bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
259 {
260   return (!myMesh->_is_nil() &&
261           (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
262 }
263
264 //=======================================================================
265 // name    : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
266 // Purpose : Destructor
267 //=======================================================================
268 SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
269 {
270   if (myFilterDlg != 0)
271   {
272     myFilterDlg->reparent(0, QPoint());
273     delete myFilterDlg;
274   }
275 }
276
277 //=======================================================================
278 // name    : SMESHGUI_MultiEditDlg::eventFilter
279 // Purpose : event filter
280 //=======================================================================
281 bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
282 {
283   if (object == myListBox && event->type() == QEvent::KeyPress) {
284     QKeyEvent* ke = (QKeyEvent*)event;
285     if (ke->key() == Key_Delete)
286       onRemoveBtn();
287   }
288   return QDialog::eventFilter(object, event);
289 }
290
291 //=======================================================================
292 // name    : SMESHGUI_MultiEditDlg::getNumericalFunctor
293 // Purpose :
294 //=======================================================================
295 SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor()
296 {
297   SMESH::NumericalFunctor_var aNF = SMESH::NumericalFunctor::_nil();
298
299   SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
300   if (aFilterMgr->_is_nil())
301     return aNF._retn();
302
303   if (myComboBoxFunctor->currentText() == tr("ASPECTRATIO_ELEMENTS"))
304     aNF = aFilterMgr->CreateAspectRatio();
305   else if (myComboBoxFunctor->currentText() == tr("WARP_ELEMENTS"))
306     aNF = aFilterMgr->CreateWarping();
307   else if (myComboBoxFunctor->currentText() == tr("MINIMUMANGLE_ELEMENTS"))
308     aNF = aFilterMgr->CreateMinimumAngle();
309   else if (myComboBoxFunctor->currentText() == tr("TAPER_ELEMENTS"))
310     aNF = aFilterMgr->CreateTaper();
311   else if (myComboBoxFunctor->currentText() == tr("SKEW_ELEMENTS"))
312     aNF = aFilterMgr->CreateSkew();
313   else if (myComboBoxFunctor->currentText() == tr("AREA_ELEMENTS"))
314     aNF = aFilterMgr->CreateArea();
315   else if (myComboBoxFunctor->currentText() == tr("LENGTH2D_EDGES"))
316     aNF = aFilterMgr->CreateLength2D();
317   else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS"))
318     aNF = aFilterMgr->CreateMultiConnection2D();
319   else ;
320
321   return aNF._retn();
322 }
323
324 //=======================================================================
325 // name    : SMESHGUI_MultiEditDlg::Init
326 // Purpose : Init dialog fields, connect signals and slots, show dialog
327 //=======================================================================
328 void SMESHGUI_MultiEditDlg::Init()
329 {
330   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
331   myListBox->clear();
332   myIds.Clear();
333   myBusy = false;
334   myActor = 0;
335   emit ListContensChanged();
336
337   // main buttons
338   connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
339   connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
340   connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
341   connect(myHelpBtn,  SIGNAL(clicked()), SLOT(onHelp()));
342
343   // selection and SMESHGUI
344   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
345   connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
346   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
347
348   // dialog controls
349   connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn()  ));
350   connect(myAddBtn   , SIGNAL(clicked()), SLOT(onAddBtn()     ));
351   connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn()  ));
352   connect(mySortBtn  , SIGNAL(clicked()), SLOT(onSortListBtn()));
353
354   connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
355   connect(myGroupChk  , SIGNAL(stateChanged(int)), SLOT(onGroupChk()  ));
356   connect(myToAllChk  , SIGNAL(stateChanged(int)), SLOT(onToAllChk()  ));
357
358   if (myEntityTypeGrp)
359     connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
360
361   connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
362
363   onSelectionDone();
364
365   // set selection mode
366   setSelectionMode();
367   updateButtons();
368 }
369
370 //=======================================================================
371 // name    : SMESHGUI_MultiEditDlg::onOk
372 // Purpose : SLOT called when "Ok" button pressed.
373 //           Assign filters VTK viewer and close dialog
374 //=======================================================================
375 void SMESHGUI_MultiEditDlg::onOk()
376 {
377   if (onApply())
378     onClose();
379 }
380
381 //=======================================================================
382 // name    : SMESHGUI_MultiEditDlg::getIds
383 // Purpose : Retrive identifiers from list box
384 //=======================================================================
385 SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
386 {
387   SMESH::long_array_var anIds = new SMESH::long_array;
388
389   if (myToAllChk->isChecked())
390   {
391     myIds.Clear();
392     SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
393     if (!anActor)
394       anActor = myActor;
395     if (anActor != 0)
396     {
397       // skl 07.02.2006
398       SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
399       if( myFilterType == SMESHGUI_TriaFilter || 
400           myFilterType == SMESHGUI_QuadFilter ||
401           myFilterType == SMESHGUI_FaceFilter ) {
402         SMDS_FaceIteratorPtr it = aMesh->facesIterator();
403         while(it->more()) {
404           const SMDS_MeshFace* f = it->next();
405           if(myFilterType == SMESHGUI_FaceFilter) {
406             myIds.Add(f->GetID());
407           }
408           else if( myFilterType==SMESHGUI_TriaFilter &&
409                    ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
410             myIds.Add(f->GetID());
411           }
412           else if( myFilterType==SMESHGUI_QuadFilter &&
413                    ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
414             myIds.Add(f->GetID());
415           }
416         }
417       }
418       else if(myFilterType == SMESHGUI_VolumeFilter) {
419         SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
420         while(it->more()) {
421           const SMDS_MeshVolume* f = it->next();
422           myIds.Add(f->GetID());
423         }
424       }
425       /* commented by skl 07.02.2006
426       TVisualObjPtr aVisualObj = anActor->GetObject();
427       vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
428       if (aGrid != 0) {
429         for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
430           vtkCell* aCell = aGrid->GetCell(i);
431           if (aCell != 0) {
432             vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
433             vtkQuad*     aQua = vtkQuad::SafeDownCast(aCell);
434             vtkPolygon*  aPG  = vtkPolygon::SafeDownCast(aCell);
435
436             vtkCell3D*   a3d  = vtkCell3D::SafeDownCast(aCell);
437             vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
438
439             if (aTri && myFilterType == SMESHGUI_TriaFilter ||
440                 aQua && myFilterType == SMESHGUI_QuadFilter ||
441                 (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
442                 (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
443               int anObjId = aVisualObj->GetElemObjId(i);
444               myIds.Add(anObjId);
445             }
446           }
447         }
448       }
449       */
450     }
451   }
452
453   anIds->length(myIds.Extent());
454   TColStd_MapIteratorOfMapOfInteger anIter(myIds);
455   for (int i = 0; anIter.More(); anIter.Next() )
456   {
457     anIds[ i++ ] = anIter.Key();
458   }
459   return anIds._retn();
460 }
461
462 //=======================================================================
463 // name    : SMESHGUI_MultiEditDlg::onClose
464 // Purpose : SLOT called when "Close" button pressed. Close dialog
465 //=======================================================================
466 void SMESHGUI_MultiEditDlg::onClose()
467 {
468   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
469     aViewWindow->SetSelectionMode(ActorSelection);
470   disconnect(mySelectionMgr, 0, this, 0);
471   disconnect(mySMESHGUI, 0, this, 0);
472   mySMESHGUI->ResetState();
473
474   SMESH::RemoveFilters();
475   SMESH::SetPickable();
476
477   //mySelectionMgr->clearSelected();
478   mySelectionMgr->clearFilters();
479
480   reject();
481 }
482
483 //=================================================================================
484 // function : onHelp()
485 // purpose  :
486 //=================================================================================
487 void SMESHGUI_MultiEditDlg::onHelp()
488 {
489   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
490   if (app) 
491     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
492   else {
493                 QString platform;
494 #ifdef WIN32
495                 platform = "winapplication";
496 #else
497                 platform = "application";
498 #endif
499     SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
500                            QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
501                            arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)).arg(myHelpFileName),
502                            QObject::tr("BUT_OK"));
503   }
504 }
505
506 //=======================================================================
507 // name    : SMESHGUI_MultiEditDlg::onSelectionDone
508 // Purpose : SLOT called when selection changed
509 //=======================================================================
510 void SMESHGUI_MultiEditDlg::onSelectionDone()
511 {
512   if (myBusy || !isEnabled()) return;
513   myBusy = true;
514
515   const SALOME_ListIO& aList = mySelector->StoredIObjects();
516
517   int nbSel = aList.Extent();
518   myListBox->clearSelection();
519
520   if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
521     QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
522     if (nbSel == 1) {
523       Handle(SALOME_InteractiveObject) anIO = aList.First();
524       QString aName = "";
525       SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
526       anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
527
528       if (mySubmeshChk->isChecked()) {
529         SMESH::SMESH_subMesh_var aSubMesh =
530           SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
531         if (!aSubMesh->_is_nil())
532           myMesh = aSubMesh->GetFather();
533       } else {
534         SMESH::SMESH_GroupBase_var aGroup =
535           SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
536         if (!aGroup->_is_nil())
537           myMesh = aGroup->GetMesh();
538       }
539     } else if (nbSel > 1) {
540       QString aStr = mySubmeshChk->isChecked() ?
541         tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
542       aNameEdit->setText(aStr.arg(nbSel));
543     } else {
544       aNameEdit->clear();
545     }
546   } else if (nbSel == 1) {
547     QString aListStr = "";
548     Handle(SALOME_InteractiveObject) anIO = aList.First();
549     int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
550     if (aNbItems > 0) {
551       QStringList anElements = QStringList::split(" ", aListStr);
552       QListBoxItem* anItem = 0;
553       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
554         anItem = myListBox->findItem(*it, Qt::ExactMatch);
555         if (anItem) myListBox->setSelected(anItem, true);
556       }
557     }
558
559     myMesh = SMESH::GetMeshByIO(anIO);
560   }
561
562   if (nbSel == 1) {
563     myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
564     if (!myActor)
565       myActor = SMESH::FindActorByObject(myMesh);
566     SVTK_Selector* aSelector = SMESH::GetSelector();
567     Handle(VTKViewer_Filter) aFilter = aSelector->GetFilter(myFilterType);
568     if (!aFilter.IsNull())
569       aFilter->SetActor(myActor);
570   }
571   myBusy = false;
572
573   updateButtons();
574 }
575
576 //=======================================================================
577 // name    : SMESHGUI_MultiEditDlg::onDeactivate
578 // Purpose : SLOT called when dialog must be deativated
579 //=======================================================================
580 void SMESHGUI_MultiEditDlg::onDeactivate()
581 {
582   setEnabled(false);
583 }
584
585 //=======================================================================
586 // name    : SMESHGUI_MultiEditDlg::enterEvent
587 // Purpose : Event filter
588 //=======================================================================
589 void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
590 {
591   if (!isEnabled()) {
592     mySMESHGUI->EmitSignalDeactivateDialog();
593     setEnabled(true);
594     setSelectionMode();
595   }
596 }
597
598 //=======================================================================
599 // name    : SMESHGUI_MultiEditDlg::closeEvent
600 // Purpose :
601 //=======================================================================
602 void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
603 {
604   onClose();
605 }
606 //=======================================================================
607 // name    : SMESHGUI_MultiEditDlg::hideEvent
608 // Purpose : caused by ESC key
609 //=======================================================================
610 void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
611 {
612   if (!isMinimized())
613     onClose();
614 }
615
616 //=======================================================================
617 // name    : SMESHGUI_MultiEditDlg::onFilterBtn
618 // Purpose : SLOT. Called when "Filter" button pressed.
619 //           Start "Selection filters" dialog
620 //=======================================================================
621 void SMESHGUI_MultiEditDlg::onFilterBtn()
622 {
623   if (myFilterDlg == 0) {
624     myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
625     connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
626   } else {
627     myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
628   }
629
630   myFilterDlg->SetSelection();
631   myFilterDlg->SetMesh(myMesh);
632   myFilterDlg->SetSourceWg(myListBox);
633
634   myFilterDlg->show();
635 }
636
637 //=======================================================================
638 // name    : onFilterAccepted()
639 // Purpose : SLOT. Called when Filter dlg closed with OK button.
640 //            Uncheck "Select submesh" and "Select group" checkboxes
641 //=======================================================================
642 void SMESHGUI_MultiEditDlg::onFilterAccepted()
643 {
644   myIds.Clear();
645   for (int i = 0, n = myListBox->count(); i < n; i++)
646     myIds.Add(myListBox->text(i).toInt());
647
648   emit ListContensChanged();
649
650   if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
651     mySubmeshChk->blockSignals(true);
652     myGroupChk->blockSignals(true);
653     mySubmeshChk->setChecked(false);
654     myGroupChk->setChecked(false);
655     mySubmeshChk->blockSignals(false);
656     myGroupChk->blockSignals(false);
657   }
658   updateButtons();
659 }
660
661 //=======================================================================
662 // name    : SMESHGUI_MultiEditDlg::isIdValid
663 // Purpose : Verify whether Id of element satisfies to filters from viewer
664 //=======================================================================
665 bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
666 {
667   SVTK_Selector* aSelector = SMESH::GetSelector();
668   Handle(SMESHGUI_Filter) aFilter =
669     Handle(SMESHGUI_Filter)::DownCast(aSelector->GetFilter(myFilterType));
670
671   return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
672 }
673
674 //=======================================================================
675 // name    : SMESHGUI_MultiEditDlg::onAddBtn
676 // Purpose : SLOT. Called when "Add" button pressed.
677 //           Add selected in viewer entities in list box
678 //=======================================================================
679 void SMESHGUI_MultiEditDlg::onAddBtn()
680 {
681   const SALOME_ListIO& aList = mySelector->StoredIObjects();
682
683   int nbSelected = aList.Extent();
684   if (nbSelected == 0)
685     return;
686
687   TColStd_IndexedMapOfInteger toBeAdded;
688
689   if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
690     if (nbSelected == 1)
691       mySelector->GetIndex(aList.First(),toBeAdded);
692   } else if (mySubmeshChk->isChecked()) {
693     SALOME_ListIteratorOfListIO anIter(aList);
694     for (; anIter.More(); anIter.Next()) {
695       SMESH::SMESH_subMesh_var aSubMesh =
696         SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
697       if (!aSubMesh->_is_nil()) {
698         if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
699           SMESH::long_array_var anIds = aSubMesh->GetElementsId();
700           for (int i = 0, n = anIds->length(); i < n; i++) {
701             if (isIdValid(anIds[ i ]))
702               toBeAdded.Add(anIds[ i ]);
703           }
704         }
705       }
706     }
707   } else if (myGroupChk->isChecked()) {
708     SALOME_ListIteratorOfListIO anIter(aList);
709     for (; anIter.More(); anIter.Next()) {
710       SMESH::SMESH_GroupBase_var aGroup =
711         SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
712       if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
713                                  entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
714                                  entityType() == 1)) {
715         if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
716           SMESH::long_array_var anIds = aGroup->GetListOfID();
717           for (int i = 0, n = anIds->length(); i < n; i++) {
718             if (isIdValid(anIds[ i ]))
719               toBeAdded.Add(anIds[ i ]);
720           }
721         }
722       }
723     }
724   } else {
725   }
726
727   myBusy = true;
728   bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
729   mySubmeshChk->setChecked(false);
730   myGroupChk->setChecked(false);
731   for(int i = 1; i <= toBeAdded.Extent(); i++)
732     if (myIds.Add(toBeAdded(i))) {
733       QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
734       myListBox->insertItem(item);
735       myListBox->setSelected(item, true);
736     }
737   myBusy = false;
738
739   emit ListContensChanged();
740
741   if (isGroupOrSubmesh)
742     onListSelectionChanged();
743
744   updateButtons();
745 }
746
747 //=======================================================================
748 // name    : SMESHGUI_MultiEditDlg::updateButtons
749 // Purpose : Enable/disable buttons of dialog in accordance with current state
750 //=======================================================================
751 void SMESHGUI_MultiEditDlg::updateButtons()
752 {
753   bool isOk = isValid(false);
754   myOkBtn->setEnabled(isOk);
755   myApplyBtn->setEnabled(isOk);
756
757   bool isListBoxNonEmpty = myListBox->count() > 0;
758   bool isToAll = myToAllChk->isChecked();
759   myFilterBtn->setEnabled(!isToAll);
760   myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
761   mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
762
763   const SALOME_ListIO& aList = mySelector->StoredIObjects();
764
765   if (isToAll ||
766       myMesh->_is_nil() ||
767       aList.Extent() != 1 ||
768       (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
769        SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
770        SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
771     myAddBtn->setEnabled(false);
772   else
773     myAddBtn->setEnabled(true);
774
775   mySubmeshChk->setEnabled(!isToAll);
776   mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
777   mySubmesh->setEnabled(mySubmeshChk->isChecked());
778
779   myGroupChk->setEnabled(!isToAll);
780   myGroupBtn->setEnabled(myGroupChk->isChecked());
781   myGroup->setEnabled(myGroupChk->isChecked());
782
783   if (!mySubmeshChk->isChecked())
784     mySubmesh->clear();
785   if (!myGroupChk->isChecked())
786     myGroup->clear();
787
788 }
789
790 //=======================================================================
791 // name    : SMESHGUI_MultiEditDlg::onRemoveBtn
792 // Purpose : SLOT. Called when "Remove" button pressed.
793 //           Remove selected in list box entities
794 //=======================================================================
795 void SMESHGUI_MultiEditDlg::onRemoveBtn()
796 {
797   myBusy = true;
798
799   for (int i = 0, n = myListBox->count(); i < n; i++)
800   {
801     for (int i = myListBox->count(); i > 0; i--) {
802       if (myListBox->isSelected(i - 1))
803       {
804         int anId = myListBox->text(i - 1).toInt();
805         myIds.Remove(anId);
806         myIds.Remove(anId);
807               myListBox->removeItem(i-1);
808       }
809     }
810   }
811   myBusy = false;
812
813   emit ListContensChanged();
814   updateButtons();
815 }
816
817 //=======================================================================
818 // name    : SMESHGUI_MultiEditDlg::onSortListBtn
819 // Purpose : SLOT. Called when "Sort list" button pressed.
820 //           Sort entities of list box
821 //=======================================================================
822 void SMESHGUI_MultiEditDlg::onSortListBtn()
823 {
824   myBusy = true;
825
826   int i, k = myListBox->count();
827   if (k > 0)
828   {
829     QStringList aSelected;
830     std::vector<int> anArray(k);
831     QListBoxItem* anItem;
832     for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
833     {
834       anArray[ i ] = anItem->text().toInt();
835       if (anItem->isSelected())
836         aSelected.append(anItem->text());
837     }
838
839     std::sort(anArray.begin(), anArray.end());
840     myListBox->clear();
841     for (i = 0; i < k; i++)
842       myListBox->insertItem(QString::number(anArray[ i ]));
843
844     for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
845     {
846       anItem = myListBox->findItem(*it, Qt::ExactMatch);
847       if (anItem)
848         myListBox->setSelected(anItem, true);
849     }
850   }
851   myBusy = false;
852 }
853
854 //=======================================================================
855 // name    : SMESHGUI_MultiEditDlg::onListSelectionChanged
856 // Purpose : SLOT. Called when selection in list box changed.
857 //           Highlight in selected entities
858 //=======================================================================
859 void SMESHGUI_MultiEditDlg::onListSelectionChanged()
860 {
861   if (myActor == 0 || myBusy)
862     return;
863
864   if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
865     return;
866
867   SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
868   if (!anActor)
869     anActor = myActor;
870   TVisualObjPtr anObj = anActor->GetObject();
871
872   TColStd_MapOfInteger anIndexes;
873   for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
874   {
875     if (anItem->isSelected())
876     {
877       int anId = anItem->text().toInt();
878       if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
879         anIndexes.Add(anId);
880     }
881   }
882
883   mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
884   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
885     aViewWindow->highlight(anActor->getIO(),true,true);
886 }
887
888 //=======================================================================
889 // name    : SMESHGUI_MultiEditDlg::onSubmeshChk
890 // Purpose : SLOT. Called when state of "SubMesh" check box changed.
891 //           Activate/deactivate selection of submeshes
892 //=======================================================================
893 void SMESHGUI_MultiEditDlg::onSubmeshChk()
894 {
895   bool isChecked = mySubmeshChk->isChecked();
896   mySubmeshBtn->setEnabled(isChecked);
897   mySubmesh->setEnabled(isChecked);
898   if (!isChecked)
899     mySubmesh->clear();
900   if (isChecked && myGroupChk->isChecked())
901       myGroupChk->setChecked(false);
902
903   setSelectionMode();
904 }
905
906 //=======================================================================
907 // name    : SMESHGUI_MultiEditDlg::onGroupChk
908 // Purpose : SLOT. Called when state of "Group" check box changed.
909 //           Activate/deactivate selection of groupes
910 //=======================================================================
911 void SMESHGUI_MultiEditDlg::onGroupChk()
912 {
913   bool isChecked = myGroupChk->isChecked();
914   myGroupBtn->setEnabled(isChecked);
915   myGroup->setEnabled(isChecked);
916   if (!isChecked)
917     myGroup->clear();
918   if (isChecked && mySubmeshChk->isChecked())
919       mySubmeshChk->setChecked(false);
920
921   setSelectionMode();
922 }
923
924 //=======================================================================
925 // name    : SMESHGUI_MultiEditDlg::onToAllChk
926 // Purpose : SLOT. Called when state of "Apply to all" check box changed.
927 //           Activate/deactivate selection
928 //=======================================================================
929 void SMESHGUI_MultiEditDlg::onToAllChk()
930 {
931   bool isChecked = myToAllChk->isChecked();
932
933   if (isChecked)
934     myListBox->clear();
935
936   myIds.Clear();
937
938   emit ListContensChanged();
939
940   updateButtons();
941   setSelectionMode();
942 }
943
944 //=======================================================================
945 // name    : SMESHGUI_MultiEditDlg::setSelectionMode
946 // Purpose : Set selection mode
947 //=======================================================================
948 void SMESHGUI_MultiEditDlg::setSelectionMode()
949 {
950   SMESH::RemoveFilters();
951
952   mySelectionMgr->clearSelected();
953   mySelectionMgr->clearFilters();
954
955   if (mySubmeshChk->isChecked()) {
956     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
957       aViewWindow->SetSelectionMode(ActorSelection);
958     mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
959   }
960   else if (myGroupChk->isChecked()) {
961     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
962       aViewWindow->SetSelectionMode(ActorSelection);
963     mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
964   }
965
966   if (entityType()) {
967     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
968       aViewWindow->SetSelectionMode(VolumeSelection);
969     SMESH::SetFilter(new SMESHGUI_VolumesFilter());
970   } else {
971     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
972       aViewWindow->SetSelectionMode(FaceSelection);
973     if (myFilterType == SMESHGUI_TriaFilter)
974       SMESH::SetFilter(new SMESHGUI_TriangleFilter());
975     else if (myFilterType == SMESHGUI_QuadFilter)
976       SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
977     else
978       SMESH::SetFilter(new SMESHGUI_FacesFilter());
979   }
980 }
981
982 //=======================================================================
983 // name    : SMESHGUI_MultiEditDlg::onApply
984 // Purpose : SLOT. Called when "Apply" button clicked.
985 //=======================================================================
986 bool SMESHGUI_MultiEditDlg::onApply()
987 {
988   if (mySMESHGUI->isActiveStudyLocked())
989     return false;
990   if (!isValid(true))
991     return false;
992
993   SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
994   if (aMeshEditor->_is_nil())
995     return false;
996
997   myBusy = true;
998
999   SMESH::long_array_var anIds = getIds();
1000
1001   bool aResult = process(aMeshEditor, anIds.inout());
1002   if (aResult) {
1003     if (myActor) {
1004       SALOME_ListIO sel;
1005       mySelectionMgr->selectedObjects( sel );
1006       mySelector->ClearIndex();
1007       mySelectionMgr->setSelectedObjects( sel );
1008       SMESH::UpdateView();
1009     }
1010
1011     myListBox->clear();
1012     myIds.Clear();
1013     emit ListContensChanged();
1014
1015     updateButtons();
1016   }
1017
1018   myBusy = false;
1019   return aResult;
1020 }
1021
1022 //=======================================================================
1023 // name    : SMESHGUI_MultiEditDlg::on3d2dChanged
1024 // Purpose :
1025 //=======================================================================
1026 void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
1027 {
1028   if (myEntityType != type) {
1029     myEntityType = type;
1030
1031     myListBox->clear();
1032     myIds.Clear();
1033
1034     emit ListContensChanged();
1035
1036     if (type)
1037       myFilterType = SMESHGUI_VolumeFilter;
1038     else
1039       myFilterType = SMESHGUI_FaceFilter;
1040
1041     updateButtons();
1042     setSelectionMode();
1043   }
1044 }
1045
1046 //=======================================================================
1047 // name    : SMESHGUI_MultiEditDlg::entityType
1048 // Purpose :
1049 //=======================================================================
1050 int SMESHGUI_MultiEditDlg::entityType()
1051 {
1052   return myEntityType;
1053 }
1054
1055 //=================================================================================
1056 // function : keyPressEvent()
1057 // purpose  :
1058 //=================================================================================
1059 void SMESHGUI_MultiEditDlg::keyPressEvent( QKeyEvent* e )
1060 {
1061   QDialog::keyPressEvent( e );
1062   if ( e->isAccepted() )
1063     return;
1064
1065   if ( e->key() == Key_F1 )
1066     {
1067       e->accept();
1068       onHelp();
1069     }
1070 }
1071
1072 /*!
1073  *  Class       : SMESHGUI_ChangeOrientationDlg
1074  *  Description : Modification of orientation of faces
1075  */
1076
1077 SMESHGUI_ChangeOrientationDlg
1078 ::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
1079                                 const char* theName):
1080   SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
1081 {
1082   setCaption(tr("CAPTION"));
1083   myHelpFileName = "changing_orientation_of_elements_page.html";
1084 }
1085
1086 SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
1087 {
1088 }
1089
1090 bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1091                                              const SMESH::long_array&    theIds)
1092 {
1093   return theEditor->Reorient(theIds);
1094 }
1095
1096 /*!
1097  *  Class       : SMESHGUI_UnionOfTrianglesDlg
1098  *  Description : Construction of quadrangles by automatic association of triangles
1099  */
1100
1101 SMESHGUI_UnionOfTrianglesDlg
1102 ::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
1103                                const char* theName):
1104   SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
1105 {
1106   setCaption(tr("CAPTION"));
1107
1108   myComboBoxFunctor->setEnabled(true);
1109   myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only
1110   myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only
1111
1112   // Maximum angle
1113   QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp);
1114   aMaxAngleGrp->setInsideMargin(0);
1115   aMaxAngleGrp->setFrameStyle(QFrame::NoFrame);
1116   new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
1117   myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
1118   myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
1119   myMaxAngleSpin->SetValue(30.0);
1120
1121   myCriterionGrp->show();
1122
1123   myHelpFileName = "uniting_set_of_triangles_page.html";
1124 }
1125
1126 SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
1127 {
1128 }
1129
1130 bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1131                                             const SMESH::long_array&    theIds)
1132 {
1133   SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1134   double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
1135   return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
1136 }
1137
1138
1139 /*!
1140  *  Class       : SMESHGUI_CuttingOfQuadsDlg
1141  *  Description : Automatic splitting of quadrangles into triangles
1142  */
1143
1144 SMESHGUI_CuttingOfQuadsDlg
1145 ::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
1146                              const char* theName):
1147   SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
1148 {
1149   setCaption(tr("CAPTION"));
1150   myPreviewActor = 0;
1151
1152   myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
1153
1154   myCriterionGrp->show();
1155   myGroupChoice->show();
1156   myComboBoxFunctor->setEnabled(false);
1157
1158   connect(myPreviewChk     , SIGNAL(stateChanged(int))   , this, SLOT(onPreviewChk()));
1159   connect(myGroupChoice    , SIGNAL(clicked(int))        , this, SLOT(onCriterionRB()));
1160   connect(myComboBoxFunctor, SIGNAL(activated(int))      , this, SLOT(onPreviewChk()));
1161   connect(this             , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
1162
1163   myHelpFileName = "cutting_quadrangles_page.html";
1164 }
1165
1166 SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
1167 {
1168 }
1169
1170 void SMESHGUI_CuttingOfQuadsDlg::onClose()
1171 {
1172   erasePreview();
1173   SMESHGUI_MultiEditDlg::onClose();
1174 }
1175
1176 bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
1177                                           const SMESH::long_array&    theIds)
1178 {
1179   switch (myGroupChoice->id(myGroupChoice->selected())) {
1180   case 0: // use diagonal 1-3
1181     return theEditor->SplitQuad(theIds, true);
1182   case 1: // use diagonal 2-4
1183     return theEditor->SplitQuad(theIds, false);
1184   default: // use numeric functor
1185     break;
1186   }
1187
1188   SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
1189   return theEditor->QuadToTri(theIds, aCriterion);
1190 }
1191
1192 void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
1193 {
1194   if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor
1195     myComboBoxFunctor->setEnabled(true);
1196   else
1197     myComboBoxFunctor->setEnabled(false);
1198
1199   onPreviewChk();
1200 }
1201
1202 void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
1203 {
1204   myPreviewChk->isChecked() ? displayPreview() : erasePreview();
1205 }
1206
1207 void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
1208 {
1209   if (myPreviewActor == 0)
1210     return;
1211
1212   if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
1213     vf->RemoveActor(myPreviewActor);
1214     vf->Repaint();
1215   }
1216   myPreviewActor->Delete();
1217   myPreviewActor = 0;
1218 }
1219   
1220 void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
1221 {
1222   if (myActor == 0)
1223     return;
1224
1225   if (myPreviewActor != 0)
1226     erasePreview();
1227
1228   // get Ids of elements
1229   SMESH::long_array_var anElemIds = getIds();
1230   if (getIds()->length() == 0)
1231     return;
1232
1233   SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
1234   if (aMesh == 0)
1235     return;
1236
1237   // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor
1238   int aChoice = myGroupChoice->id(myGroupChoice->selected());
1239   SMESH::NumericalFunctor_var aCriterion  = SMESH::NumericalFunctor::_nil();
1240   SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil();
1241   if (aChoice == 2) {
1242     aCriterion  = getNumericalFunctor();
1243     aMeshEditor = myMesh->GetMeshEditor();
1244     if (aMeshEditor->_is_nil())
1245       return;
1246   }
1247
1248   //Create grid
1249   vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
1250
1251   vtkIdType aNbCells = anElemIds->length() * 2;
1252   vtkIdType aCellsSize = 4 * aNbCells;
1253   vtkCellArray* aConnectivity = vtkCellArray::New();
1254   aConnectivity->Allocate(aCellsSize, 0);
1255
1256   vtkPoints* aPoints = vtkPoints::New();
1257   aPoints->SetNumberOfPoints(anElemIds->length() * 4);
1258
1259   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
1260   aCellTypesArray->SetNumberOfComponents(1);
1261   aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
1262
1263   vtkIdList *anIdList = vtkIdList::New();
1264   anIdList->SetNumberOfIds(3);
1265
1266   TColStd_DataMapOfIntegerInteger anIdToVtk;
1267
1268   int aNodes[ 4 ];
1269   int nbPoints = -1;
1270   for (int i = 0, n = anElemIds->length(); i < n; i++)
1271   {
1272     const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
1273     if (anElem == 0 || anElem->NbNodes() != 4)
1274       continue;
1275
1276     SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
1277     int k = 0;
1278     while (anIter->more()) {
1279       const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIter->next());
1280       if (aNode)
1281       {
1282         if (!anIdToVtk.IsBound(aNode->GetID()))
1283         {
1284           aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
1285           anIdToVtk.Bind(aNode->GetID(), nbPoints);
1286         }
1287
1288         aNodes[ k++ ] = aNode->GetID();
1289       }
1290     }
1291
1292     if (k != 4)
1293       continue;
1294
1295     bool isDiag13 = true;
1296     if (aChoice == 0) // use diagonal 1-3
1297     {
1298       isDiag13 = true;
1299     }
1300     else if (aChoice == 1) // use diagonal 2-4
1301     {
1302       isDiag13 = false;
1303     }
1304     else // use numerical functor
1305     {
1306       // compare two sets of possible triangles
1307       int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion);
1308       if (diag == 1) // 1-3
1309         isDiag13 = true;
1310       else if (diag == 2) // 2-4
1311         isDiag13 = false;
1312       else // error
1313         continue;
1314     }
1315
1316     if (isDiag13)
1317     {
1318       anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
1319       anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
1320       anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
1321       aConnectivity->InsertNextCell(anIdList);
1322       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1323
1324       anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
1325       anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
1326       anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
1327       aConnectivity->InsertNextCell(anIdList);
1328       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1329     }
1330     else
1331     {
1332       anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
1333       anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
1334       anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
1335       aConnectivity->InsertNextCell(anIdList);
1336       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1337
1338       anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
1339       anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
1340       anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
1341       aConnectivity->InsertNextCell(anIdList);
1342       aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
1343     }
1344   }
1345
1346   VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
1347   aCellLocationsArray->SetNumberOfComponents(1);
1348   aCellLocationsArray->SetNumberOfTuples(aNbCells);
1349
1350   aConnectivity->InitTraversal();
1351   for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
1352     aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
1353
1354   aGrid->SetPoints(aPoints);
1355   aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
1356
1357   // Create and display actor
1358   vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
1359   aMapper->SetInput(aGrid);
1360
1361   myPreviewActor = SALOME_Actor::New();
1362   myPreviewActor->PickableOff();
1363   myPreviewActor->SetMapper(aMapper);
1364
1365   vtkProperty* aProp = vtkProperty::New();
1366   aProp->SetRepresentationToWireframe();
1367   aProp->SetColor(250, 0, 250);
1368   aProp->SetLineWidth(myActor->GetLineWidth() + 1);
1369   myPreviewActor->SetProperty(aProp);
1370
1371   SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
1372   SMESH::GetCurrentVtkView()->Repaint();
1373
1374   aProp->Delete();
1375   aPoints->Delete();
1376   aConnectivity->Delete();
1377   aGrid->Delete();
1378   aMapper->Delete();
1379   anIdList->Delete();
1380   aCellTypesArray->Delete();
1381   aCellLocationsArray->Delete();
1382 }