Salome HOME
Fix compilation error on Linux caused by previous commit
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_SewingDlg.cxx
1 // Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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 // SMESH SMESHGUI : GUI for SMESH component
24 // File   : SMESHGUI_SewingDlg.cxx
25 // Author : Michael ZORIN, Open CASCADE S.A.S.
26 // SMESH includes
27 //
28 #include "SMESHGUI_SewingDlg.h"
29
30 #include "SMESHGUI.h"
31 #include "SMESHGUI_IdPreview.h"
32 #include "SMESHGUI_IdValidator.h"
33 #include "SMESHGUI_MergeDlg.h"
34 #include "SMESHGUI_MeshUtils.h"
35 #include "SMESHGUI_PreVisualObj.h"
36 #include "SMESHGUI_SpinBox.h"
37 #include "SMESHGUI_Utils.h"
38 #include "SMESHGUI_VTKUtils.h"
39
40 #include <SMDS_Mesh.hxx>
41 #include <SMESH_Actor.h>
42 #include <SMESH_TypeDefs.hxx>
43
44 // SALOME GUI includes
45 #include <LightApp_Application.h>
46 #include <LightApp_SelectionMgr.h>
47 #include <SALOMEDSClient_Study.hxx>
48 #include <SALOME_ListIO.hxx>
49 #include <SUIT_Desktop.h>
50 #include <SUIT_MessageBox.h>
51 #include <SUIT_OverrideCursor.h>
52 #include <SUIT_ResourceMgr.h>
53 #include <SUIT_Session.h>
54 #include <SVTK_ViewModel.h>
55 #include <SVTK_ViewWindow.h>
56 #include <SalomeApp_IntSpinBox.h>
57 #include <SalomeApp_Tools.h>
58
59 // OCCT includes
60 #include <TColStd_MapOfInteger.hxx>
61
62 // Qt includes
63 #include <QApplication>
64 #include <QButtonGroup>
65 #include <QCheckBox>
66 #include <QGridLayout>
67 #include <QGroupBox>
68 #include <QHBoxLayout>
69 #include <QKeyEvent>
70 #include <QLabel>
71 #include <QLineEdit>
72 #include <QListWidget>
73 #include <QPushButton>
74 #include <QRadioButton>
75 #include <QToolButton>
76 #include <QVBoxLayout>
77
78 #define SPACING 6
79 #define MARGIN  11
80
81 namespace
82 {
83   enum ActionType { MODE_AUTO=0, MODE_MANUAL,
84                     MOVE_LEFT_1=0, MOVE_RIGHT_1, MOVE_LEFT_2, MOVE_RIGHT_2,
85                     GROUP_COLOR=Qt::UserRole, GROUP_INDEX };
86 }
87
88 //=================================================================================
89 /*!
90  * \brief Dispalayer of free borders
91  */
92 //=================================================================================
93
94 struct SMESHGUI_SewingDlg::BorderGroupDisplayer
95 {
96   const SMESH::ListOfFreeBorders& myBorders;
97   const SMESH::FreeBordersGroup&  myGroup;
98   QColor                          myColor;
99   SMESH::SMESH_Mesh_ptr           myMesh;
100
101   std::vector< SMESH_Actor* >     myPartActors;
102   SVTK_ViewWindow*                myViewWindow;
103   SMESHGUI_IdPreview              myIdPreview;
104
105   BorderGroupDisplayer( const SMESH::CoincidentFreeBorders& borders,
106                         int                                 groupIndex,
107                         QColor                              color,
108                         SMESH::SMESH_Mesh_ptr               mesh);
109   ~BorderGroupDisplayer();
110   void Hide();
111   void ShowGroup( bool wholeBorders );
112   void ShowPart( int partIndex, bool toEdit );
113   void Update();
114
115 private:
116   void getPartEnds( int partIndex, std::vector<int> & ids, std::list<gp_XYZ>& coords);
117 };
118
119 //=================================================================================
120 // class    : SMESHGUI_SewingDlg()
121 // purpose  :
122 //=================================================================================
123 SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( SMESHGUI* theModule )
124   : QDialog( SMESH::GetDesktop( theModule ) ),
125     mySMESHGUI( theModule ),
126     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
127 {
128   SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( mySMESHGUI );
129   QPixmap image0 (mgr->loadPixmap("SMESH", tr("ICON_SMESH_SEWING_FREEBORDERS")));
130   QPixmap image1 (mgr->loadPixmap("SMESH", tr("ICON_SMESH_SEWING_CONFORM_FREEBORDERS")));
131   QPixmap image2 (mgr->loadPixmap("SMESH", tr("ICON_SMESH_SEWING_BORDERTOSIDE")));
132   QPixmap image3 (mgr->loadPixmap("SMESH", tr("ICON_SMESH_SEWING_SIDEELEMENTS")));
133   QPixmap image4 (mgr->loadPixmap("SMESH", tr("ICON_SELECT")));
134   QPixmap IconRemove(mgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
135
136   setModal(false);
137   setAttribute(Qt::WA_DeleteOnClose, true);
138   setWindowTitle(tr("SMESH_SEWING"));
139   setSizeGripEnabled(true);
140
141   QVBoxLayout* SMESHGUI_SewingDlgLayout = new QVBoxLayout(this);
142   SMESHGUI_SewingDlgLayout->setSpacing(SPACING);
143   SMESHGUI_SewingDlgLayout->setMargin(MARGIN);
144
145   /***************************************************************/
146   ConstructorsBox = new QGroupBox(tr("SMESH_SEWING"), this);
147   GroupConstructors = new QButtonGroup(this);
148   QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
149   ConstructorsBoxLayout->setSpacing(SPACING);
150   ConstructorsBoxLayout->setMargin(MARGIN);
151
152   RadioButton1 = new QRadioButton(ConstructorsBox);
153   RadioButton1->setIcon(image0);
154   RadioButton2 = new QRadioButton(ConstructorsBox);
155   RadioButton2->setIcon(image1);
156   RadioButton3 = new QRadioButton(ConstructorsBox);
157   RadioButton3->setIcon(image2);
158   RadioButton4 = new QRadioButton(ConstructorsBox);
159   RadioButton4->setIcon(image3);
160
161   ConstructorsBoxLayout->addWidget(RadioButton1);
162   ConstructorsBoxLayout->addWidget(RadioButton2);
163   ConstructorsBoxLayout->addWidget(RadioButton3);
164   ConstructorsBoxLayout->addWidget(RadioButton4);
165   GroupConstructors->addButton(RadioButton1, 0);
166   GroupConstructors->addButton(RadioButton2, 1);
167   GroupConstructors->addButton(RadioButton3, 2);
168   GroupConstructors->addButton(RadioButton4, 3);
169
170   /***************************************************************/
171   GroupArguments = new QGroupBox(this);
172   QVBoxLayout* GroupArgumentsLayout = new QVBoxLayout(GroupArguments);
173   GroupArgumentsLayout->setSpacing(SPACING);
174   GroupArgumentsLayout->setMargin(MARGIN);
175
176   // First subgroup
177   SubGroup1 = new QGroupBox(GroupArguments);
178   QGridLayout* SubGroup1Layout = new QGridLayout(SubGroup1);
179   SubGroup1Layout->setSpacing(SPACING);
180   SubGroup1Layout->setMargin(MARGIN);
181
182   // Controls of the first subgroup
183   TextLabel1 = new QLabel(SubGroup1);
184   SelectButton1  = new QPushButton(SubGroup1);
185   SelectButton1->setIcon(image4);
186   LineEdit1 = new QLineEdit(SubGroup1);
187
188   TextLabel2 = new QLabel(SubGroup1);
189   SelectButton2  = new QPushButton(SubGroup1);
190   SelectButton2->setIcon(image4);
191   LineEdit2 = new QLineEdit(SubGroup1);
192
193   TextLabel3 = new QLabel(SubGroup1);
194   SelectButton3  = new QPushButton(SubGroup1);
195   SelectButton3->setIcon(image4);
196   LineEdit3 = new QLineEdit(SubGroup1);
197
198   SubGroup1Layout->addWidget(TextLabel1,    0, 0);
199   SubGroup1Layout->addWidget(SelectButton1, 0, 1);
200   SubGroup1Layout->addWidget(LineEdit1,     0, 2);
201   SubGroup1Layout->addWidget(TextLabel2,    1, 0);
202   SubGroup1Layout->addWidget(SelectButton2, 1, 1);
203   SubGroup1Layout->addWidget(LineEdit2,     1, 2);
204   SubGroup1Layout->addWidget(TextLabel3,    2, 0);
205   SubGroup1Layout->addWidget(SelectButton3, 2, 1);
206   SubGroup1Layout->addWidget(LineEdit3,     2, 2);
207
208   // Second subgroup
209   SubGroup2 = new QGroupBox(GroupArguments);
210   QGridLayout* SubGroup2Layout = new QGridLayout(SubGroup2);
211   SubGroup2Layout->setSpacing(SPACING);
212   SubGroup2Layout->setMargin(MARGIN);
213
214   // Controls of the first subgroup
215   TextLabel4 = new QLabel(SubGroup2);
216   SelectButton4  = new QPushButton(SubGroup2);
217   SelectButton4->setIcon(image4);
218   LineEdit4 = new QLineEdit(SubGroup2);
219
220   TextLabel5 = new QLabel(SubGroup2);
221   SelectButton5  = new QPushButton(SubGroup2);
222   SelectButton5->setIcon(image4);
223   LineEdit5 = new QLineEdit(SubGroup2);
224
225   TextLabel6 = new QLabel(SubGroup2);
226   SelectButton6  = new QPushButton(SubGroup2);
227   SelectButton6->setIcon(image4);
228   LineEdit6 = new QLineEdit(SubGroup2);
229
230   SubGroup2Layout->addWidget(TextLabel4,    0, 0);
231   SubGroup2Layout->addWidget(SelectButton4, 0, 1);
232   SubGroup2Layout->addWidget(LineEdit4,     0, 2);
233   SubGroup2Layout->addWidget(TextLabel5,    1, 0);
234   SubGroup2Layout->addWidget(SelectButton5, 1, 1);
235   SubGroup2Layout->addWidget(LineEdit5,     1, 2);
236   SubGroup2Layout->addWidget(TextLabel6,    2, 0);
237   SubGroup2Layout->addWidget(SelectButton6, 2, 1);
238   SubGroup2Layout->addWidget(LineEdit6,     2, 2);
239
240   // Control for the merging equal elements
241   CheckBoxMerge = new QCheckBox(tr("MERGE_EQUAL_ELEMENTS"), GroupArguments);
242
243   // Control for the polygons creation instead of splitting
244   CheckBoxPolygons = new QCheckBox(tr("CREATE_POLYGONS_INSTEAD_SPLITTING"), GroupArguments);
245   
246   // Control for the polyedres creation to obtain conform mesh
247   CheckBoxPolyedrs = new QCheckBox(tr("CREATE_POLYEDRS_NEAR_BOUNDARY"), GroupArguments);
248
249   /***************************************************************/
250   // Controls to switch free borders mode ( auto || manual )
251
252   ModeGroup = new QGroupBox( tr( "SMESH_MODE" ), GroupArguments );
253   ModeButGrp = new QButtonGroup( ModeGroup );
254   QHBoxLayout* aModeGroupLayout = new QHBoxLayout( ModeGroup );
255   aModeGroupLayout->setMargin( MARGIN );
256   aModeGroupLayout->setSpacing( SPACING );
257
258   QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), ModeGroup );
259   QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL"    ), ModeGroup );
260   ModeButGrp->addButton( rb1, MODE_AUTO );
261   ModeButGrp->addButton( rb2, MODE_MANUAL );
262   aModeGroupLayout->addWidget( rb1 );
263   aModeGroupLayout->addWidget( rb2 );
264   rb1->setChecked(true);
265
266   /***************************************************************/
267   // Controls for detecting coincident free borders
268
269   SewFreeBordersWidget = new QWidget( GroupArguments );
270   QVBoxLayout* aSewFreeBordersLayout = new QVBoxLayout( SewFreeBordersWidget );
271   aSewFreeBordersLayout->setMargin( 0 );
272   aSewFreeBordersLayout->setSpacing( SPACING );
273
274   // Tolerance
275   QWidget* TolAndAuto = new QWidget(SewFreeBordersWidget);
276   QLabel* TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), TolAndAuto);
277   SpinBoxTolerance = new SMESHGUI_SpinBox(TolAndAuto);
278   SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
279   SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision");
280   SpinBoxTolerance->SetValue(0.); // auto-tolerance
281
282   // Auto Sewing
283   AutoSewCheck = new QCheckBox(tr("AUTO_SEWING"), TolAndAuto);
284   AutoSewCheck->setChecked( true );
285
286   // mesh
287   QGroupBox* GroupMesh = new QGroupBox(tr("SMESH_MESH"), SewFreeBordersWidget);
288   QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh);
289   GroupMeshLayout->setSpacing(SPACING);
290   GroupMeshLayout->setMargin(MARGIN);
291
292   QLabel* TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh);
293   //SelectMeshButton = new QPushButton(GroupMesh);
294   //SelectMeshButton->setIcon(IconSelect);
295   LineEditMesh = new QLineEdit(GroupMesh);
296   LineEditMesh->setReadOnly(true);
297
298   GroupMeshLayout->addWidget(TextLabelName);
299   //GroupMeshLayout->addWidget(SelectMeshButton);
300   GroupMeshLayout->addWidget(LineEditMesh);
301
302   QGridLayout* TolAndAutoLayout = new QGridLayout( TolAndAuto );
303   TolAndAutoLayout->setSpacing(SPACING);
304   TolAndAutoLayout->setMargin(0);
305   TolAndAutoLayout->addWidget(GroupMesh,          0, 0, 1, 2 );
306   TolAndAutoLayout->addWidget(TextLabelTolerance, 1, 0 );
307   TolAndAutoLayout->addWidget(SpinBoxTolerance,   1, 1 );
308   TolAndAutoLayout->addWidget(AutoSewCheck,       2, 0 );
309
310   aSewFreeBordersLayout->addWidget( TolAndAuto );
311
312   /******************/
313   // Coincident group
314   GroupCoincidentWidget = new QWidget(SewFreeBordersWidget);
315   QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget);
316   GroupCoincidentLayout->setSpacing(SPACING);
317   GroupCoincidentLayout->setMargin(0);
318
319   QGroupBox* GroupCoincident = new QGroupBox(tr("COINCIDENT_FREE_BORDERS"), GroupCoincidentWidget);
320   QGridLayout* aCoincidentLayout = new QGridLayout(GroupCoincident);
321   aCoincidentLayout->setSpacing(SPACING);
322   aCoincidentLayout->setMargin(MARGIN);
323
324   /*******/
325   // borders
326   ListCoincident = new QListWidget(GroupCoincident);
327   ListCoincident->setSelectionMode(QListWidget::ExtendedSelection);
328
329   DetectButton      = new QPushButton(tr("DETECT"),           GroupCoincident);
330   RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincident);
331
332   SelectAllCheck = new QCheckBox(tr("SELECT_ALL"), GroupCoincident);
333
334   aCoincidentLayout->addWidget(ListCoincident,    0, 0, 5, 2);
335   aCoincidentLayout->addWidget(DetectButton,      1, 2);
336   aCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
337   aCoincidentLayout->addWidget(SelectAllCheck,    5, 0);
338   aCoincidentLayout->setRowMinimumHeight(1, 10);
339   aCoincidentLayout->setRowStretch      (4, 5);
340   aCoincidentLayout->setRowStretch      (5, 0);
341
342   /*****************************************/
343   // Controls for editing the selected group
344
345   QGroupBox* GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), GroupCoincidentWidget);
346   QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit);
347   GroupEditLayout->setSpacing(SPACING);
348   GroupEditLayout->setMargin(MARGIN);
349
350   ListEdit = new QListWidget(GroupEdit);
351   ListEdit->setFlow( QListView::LeftToRight );
352   ListEdit->setSelectionMode(QListWidget::ExtendedSelection);
353   SetFirstButton = new QPushButton(GroupEdit);
354   SetFirstButton->setIcon(QPixmap(SMESHGUI_MergeDlg::IconFirst()));
355   RemoveElemButton = new QPushButton(GroupEdit);
356   RemoveElemButton->setIcon(IconRemove);
357
358   MoveBorderEndsButGrp = new QButtonGroup( GroupEdit );
359   QToolButton* moveBut1 = new QToolButton( GroupEdit );
360   QToolButton* moveBut2 = new QToolButton( GroupEdit );
361   QToolButton* moveBut3 = new QToolButton( GroupEdit );
362   QToolButton* moveBut4 = new QToolButton( GroupEdit );
363   moveBut1->setArrowType( Qt::LeftArrow );
364   moveBut2->setArrowType( Qt::RightArrow );
365   moveBut3->setArrowType( Qt::LeftArrow );
366   moveBut4->setArrowType( Qt::RightArrow );
367   MoveBorderEndsButGrp->addButton( moveBut1, MOVE_LEFT_1 );
368   MoveBorderEndsButGrp->addButton( moveBut2, MOVE_RIGHT_1 );
369   MoveBorderEndsButGrp->addButton( moveBut3, MOVE_LEFT_2 );
370   MoveBorderEndsButGrp->addButton( moveBut4, MOVE_RIGHT_2 );
371
372   SwapBut  = new QPushButton( "<->", GroupEdit );
373   BorderEndLine[0] = new QLineEdit( GroupEdit );
374   BorderEndLine[1] = new QLineEdit( GroupEdit );
375   BorderEndLine[0]->setReadOnly(true);
376   BorderEndLine[1]->setReadOnly(true);
377   QLabel* StepLabel = new QLabel(tr("STEP"), GroupEdit );
378   StepSpin = new SalomeApp_IntSpinBox( 1, 100000, 1, GroupEdit,
379                                        /*acceptNames=*/false, /*showTip=*/false );
380   StepSpin->setValue( 1 );
381
382   GroupEditLayout->addWidget(ListEdit,         0, 0, 1, 8);
383   GroupEditLayout->addWidget(SetFirstButton,   0, 8);
384   GroupEditLayout->addWidget(RemoveElemButton, 0, 9);
385   GroupEditLayout->addWidget(moveBut1,         1, 0);
386   GroupEditLayout->addWidget(BorderEndLine[0], 1, 1);
387   GroupEditLayout->addWidget(moveBut2,         1, 2);
388   GroupEditLayout->addWidget(moveBut3,         1, 3);
389   GroupEditLayout->addWidget(BorderEndLine[1], 1, 4);
390   GroupEditLayout->addWidget(moveBut4,         1, 5);
391   GroupEditLayout->setColumnStretch(              6, 5 );
392   GroupEditLayout->addWidget(SwapBut,          1, 7);
393   GroupEditLayout->addWidget(StepLabel,        1, 8);
394   GroupEditLayout->addWidget(StepSpin,         1, 9);
395   GroupEditLayout->setRowStretch( 0, 1 );
396
397   GroupCoincidentLayout->addWidget( GroupCoincident );
398   GroupCoincidentLayout->addWidget( GroupEdit );
399   GroupCoincidentLayout->setRowStretch( 0, 10 );
400   GroupCoincidentLayout->setRowStretch( 1, 1 );
401
402   aSewFreeBordersLayout->addWidget( GroupCoincidentWidget );
403
404   // layout
405   GroupArgumentsLayout->addWidget(ModeGroup);
406   GroupArgumentsLayout->addWidget(SubGroup1);
407   GroupArgumentsLayout->addWidget(SubGroup2);
408   GroupArgumentsLayout->addWidget(SewFreeBordersWidget);
409   GroupArgumentsLayout->addWidget(CheckBoxMerge);
410   GroupArgumentsLayout->addWidget(CheckBoxPolygons);
411   GroupArgumentsLayout->addWidget(CheckBoxPolyedrs);
412
413   /***************************************************************/
414   GroupButtons = new QGroupBox(this);
415   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
416   GroupButtonsLayout->setSpacing(SPACING);
417   GroupButtonsLayout->setMargin(MARGIN);
418
419   buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
420   buttonOk->setAutoDefault(true);
421   buttonOk->setDefault(true);
422   buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
423   buttonApply->setAutoDefault(true);
424   buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
425   buttonCancel->setAutoDefault(true);
426   buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
427   buttonHelp->setAutoDefault(true);
428
429   GroupButtonsLayout->addWidget(buttonOk);
430   GroupButtonsLayout->addSpacing(10);
431   GroupButtonsLayout->addWidget(buttonApply);
432   GroupButtonsLayout->addSpacing(10);
433   GroupButtonsLayout->addStretch();
434   GroupButtonsLayout->addWidget(buttonCancel);
435   GroupButtonsLayout->addWidget(buttonHelp);
436
437   /***************************************************************/
438   SMESHGUI_SewingDlgLayout->addWidget(ConstructorsBox);
439   SMESHGUI_SewingDlgLayout->addWidget(GroupArguments);
440   SMESHGUI_SewingDlgLayout->addWidget(GroupButtons);
441   //SMESHGUI_SewingDlgLayout->setStretch( 2, 10 );
442
443   /* Initialisations */
444   RadioButton1->setChecked(true);
445
446   LineEdit2->setValidator(new SMESHGUI_IdValidator(this, 1));
447   LineEdit3->setValidator(new SMESHGUI_IdValidator(this, 1));
448   LineEdit5->setValidator(new SMESHGUI_IdValidator(this, 1));
449   LineEdit6->setValidator(new SMESHGUI_IdValidator(this, 1));
450
451   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
452
453   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
454
455   myHelpFileName = "sewing_meshes_page.html";
456
457   myActor = 0;
458   myStoredEntityMode = 0;
459
460   setDisplayMode();
461   Init();
462
463   /* signals and slots connections */
464   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
465   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
466   connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
467   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
468   connect(GroupConstructors, SIGNAL(buttonClicked(int)), SLOT(ConstructorsClicked(int)));
469
470   connect(SelectButton1, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
471   connect(SelectButton2, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
472   connect(SelectButton3, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
473   connect(SelectButton4, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
474   connect(SelectButton5, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
475   connect(SelectButton6, SIGNAL (clicked()),   this, SLOT(SetEditCurrentArgument()));
476
477   connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
478   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
479   /* to close dialog if study change */
480   connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()),      this, SLOT(reject()));
481   connect(mySMESHGUI, SIGNAL(SignalActivatedViewManager()), this, SLOT(onOpenView()));
482   connect(mySMESHGUI, SIGNAL(SignalCloseView()),            this, SLOT(onCloseView()));
483
484   connect(LineEdit1, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
485   connect(LineEdit2, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
486   connect(LineEdit3, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
487   connect(LineEdit4, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
488   connect(LineEdit5, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
489   connect(LineEdit6, SIGNAL(textChanged(const QString&)), SLOT(onTextChange(const QString&)));
490
491   connect(ModeButGrp,           SIGNAL(buttonClicked(int)),     SLOT(onModeChange(int)));
492   connect(AutoSewCheck,         SIGNAL(stateChanged(int)),      SLOT(onAutoSew(int)));
493   connect(DetectButton,         SIGNAL(clicked()),              SLOT(onDetectClicked()));
494   connect(RemoveGroupButton,    SIGNAL(clicked()),              SLOT(onRemoveGroupClicked()));
495   connect(ListCoincident,       SIGNAL(itemSelectionChanged()), SLOT(onSelectGroup()));
496   connect(SelectAllCheck,       SIGNAL(stateChanged(int)),      SLOT(onSelectAll(int)));
497   connect(ListEdit,             SIGNAL(itemSelectionChanged()), SLOT(onSelectBorderPartFromGroup()));
498   connect(SetFirstButton,       SIGNAL(clicked()),              SLOT(onSetFirstClicked()));
499   connect(RemoveElemButton,     SIGNAL(clicked()),              SLOT(onRemoveElemClicked()));
500   connect(MoveBorderEndsButGrp, SIGNAL(buttonClicked(int)),     SLOT(onMoveBorderEnd(int)));
501   connect(SwapBut,              SIGNAL(clicked()),              SLOT(onSwapClicked()));
502
503   ConstructorsClicked(0);
504 }
505
506 //=================================================================================
507 // function : ~SMESHGUI_SewingDlg()
508 // purpose  : Destroys the object and frees any allocated resources
509 //=================================================================================
510 SMESHGUI_SewingDlg::~SMESHGUI_SewingDlg()
511 {
512   for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
513   {
514     delete myBorderDisplayers[ i ];
515     myBorderDisplayers[ i ] = 0;
516   }
517   myBorderDisplayers.clear();
518 }
519
520 //=================================================================================
521 // function : Init()
522 // purpose  :
523 //=================================================================================
524 void SMESHGUI_SewingDlg::Init()
525 {
526   myBusy = false;
527
528   if ( LineEdit1->isVisible() )
529     myEditCurrentArgument = LineEdit1;
530   else
531     myEditCurrentArgument = LineEditMesh;
532   myEditCurrentArgument->setFocus();
533   //myActor = 0;
534   myMesh = SMESH::SMESH_Mesh::_nil();
535   // CheckBoxMerge->setChecked(false);
536   // CheckBoxPolygons->setChecked(false);
537   // CheckBoxPolyedrs->setChecked(false);
538   SelectionIntoArgument();
539 }
540
541 //=================================================================================
542 // function : ConstructorsClicked()
543 // purpose  : Radio button management
544 //=================================================================================
545 void SMESHGUI_SewingDlg::ConstructorsClicked (int constructorId)
546 {
547   disconnect(mySelectionMgr, 0, this, 0);
548   SALOME_ListIO io;
549   mySelectionMgr->selectedObjects( io );
550   mySelectionMgr->clearSelected();
551   LineEdit1->setText("");
552   LineEdit2->setText("");
553   LineEdit3->setText("");
554   LineEdit4->setText("");
555   LineEdit5->setText("");
556   LineEdit6->setText("");
557   myOk1 = myOk2 = myOk3 = myOk4 = myOk5 = myOk6 = false;
558   myEditCurrentArgument = LineEdit1;
559   myEditCurrentArgument->setFocus();
560
561   if (!TextLabel5->isEnabled()) {
562     TextLabel5->setEnabled(true);
563     SelectButton5->setEnabled(true);
564     LineEdit5->setEnabled(true);
565   } else if (!TextLabel6->isEnabled()) {
566     TextLabel6->setEnabled(true);
567     SelectButton6->setEnabled(true);
568     LineEdit6->setEnabled(true);
569   }
570
571   if (constructorId == 1 || constructorId == 3) {
572     if (CheckBoxPolygons->isVisible())
573       CheckBoxPolygons->hide();
574     if (CheckBoxPolyedrs->isVisible())
575       CheckBoxPolyedrs->hide();
576   }
577
578   CheckBoxMerge->setVisible ( constructorId == 3 );
579
580   if (( !SubGroup1->isVisible() ) &&
581       ( constructorId != 0 || ModeButGrp->checkedId() == MODE_MANUAL ))
582   {
583     SubGroup1->show();
584     SubGroup2->show();
585   }
586
587   if ( constructorId != 0 )
588   {
589     ModeGroup->hide();
590     SewFreeBordersWidget->hide();
591     restoreDisplayMode();
592   }
593
594   bool isNodeSelection = true;
595
596   switch (constructorId) {
597   case 0:
598   {
599     GroupArguments->setTitle(tr("SEW_FREE_BORDERS"));
600     SubGroup1->setTitle(tr("BORDER_1"));
601     SubGroup2->setTitle(tr("BORDER_2"));
602
603     if (!CheckBoxPolygons->isVisible())
604       CheckBoxPolygons->show();
605     if (!CheckBoxPolyedrs->isVisible())
606       CheckBoxPolyedrs->show();
607
608     if ( !ModeGroup->isVisible() )
609     {
610       ModeGroup->show();
611     }
612     onModeChange( ModeButGrp->checkedId() );
613
614     isNodeSelection = ( ModeButGrp->checkedId() == MODE_MANUAL );
615
616     break;
617   }
618   case 1:
619   {
620     GroupArguments->setTitle(tr("SEW_CONFORM_FREE_BORDERS"));
621     SubGroup1->setTitle(tr("BORDER_1"));
622     SubGroup2->setTitle(tr("BORDER_2"));
623
624     TextLabel6->setEnabled(false);
625     SelectButton6->setEnabled(false);
626     LineEdit6->setEnabled(false);
627
628     myOk6 = true;
629
630     break;
631   }
632   case 2:
633   {
634     GroupArguments->setTitle(tr("SEW_BORDER_TO_SIDE"));
635     SubGroup1->setTitle(tr("BORDER"));
636     SubGroup2->setTitle(tr("SIDE"));
637
638     TextLabel5->setEnabled(false);
639     SelectButton5->setEnabled(false);
640     LineEdit5->setEnabled(false);
641
642     if (!CheckBoxPolygons->isVisible())
643       CheckBoxPolygons->show();
644     if (!CheckBoxPolyedrs->isVisible())
645       CheckBoxPolyedrs->show();
646
647     myOk5 = true;
648
649     break;
650   }
651   case 3:
652   {
653     GroupArguments->setTitle(tr("SEW_SIDE_ELEMENTS"));
654     SubGroup1->setTitle(tr("SIDE_1"));
655     SubGroup2->setTitle(tr("SIDE_2"));
656
657     TextLabel1->setText(tr("SMESH_ID_ELEMENTS"));
658     TextLabel2->setText(tr("NODE1_TO_MERGE"));
659     TextLabel3->setText(tr("NODE2_TO_MERGE"));
660     TextLabel4->setText(tr("SMESH_ID_ELEMENTS"));
661     TextLabel5->setText(tr("NODE1_TO_MERGE"));
662     TextLabel6->setText(tr("NODE2_TO_MERGE"));
663
664     LineEdit1->setValidator(new SMESHGUI_IdValidator(this));
665     LineEdit4->setValidator(new SMESHGUI_IdValidator(this));
666
667     isNodeSelection = false;
668     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
669       aViewWindow->SetSelectionMode(CellSelection);
670     break;
671   }
672   }
673
674   if (constructorId != 3) {
675     TextLabel1->setText(tr("FIRST_NODE_ID"));
676     TextLabel2->setText(tr("SECOND_NODE_ID"));
677     TextLabel3->setText(tr("LAST_NODE_ID"));
678     TextLabel4->setText(tr("FIRST_NODE_ID"));
679     TextLabel5->setText(tr("SECOND_NODE_ID"));
680     TextLabel6->setText(tr("LAST_NODE_ID"));
681
682     LineEdit1->setValidator(new SMESHGUI_IdValidator(this, 1));
683     LineEdit4->setValidator(new SMESHGUI_IdValidator(this, 1));
684   }
685
686   if ( myActor )
687     myActor->SetPointRepresentation( isNodeSelection );
688
689   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
690     aViewWindow->SetSelectionMode( isNodeSelection ? NodeSelection : ActorSelection );
691
692   UpdateButtons();
693
694   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
695   mySelectionMgr->setSelectedObjects( io );
696
697   QApplication::instance()->processEvents();
698   updateGeometry();
699
700   resize(100,100);
701 }
702
703 //=======================================================================
704 //function : storeDisplayMode
705 //purpose  : save representation of a mesh and switch it to wireframe mode
706 //=======================================================================
707
708 void SMESHGUI_SewingDlg::setDisplayMode()
709 {
710   if ( myStoredEntityMode )
711     return;
712   myStoredEntityMode = 0;
713   myStoredRepresentation = -1;
714
715   if ( myActor && AutoSewCheck->isVisible() && !AutoSewCheck->isChecked() )
716   {
717     myStoredEntityMode     = myActor->GetEntityMode();
718     myStoredRepresentation = myActor->GetRepresentation();
719
720     myActor->SetEntityMode( myStoredEntityMode & ~SMESH_Actor::eVolumes );
721     myActor->SetRepresentation( SMESH_Actor::eEdge );
722   }
723 }
724
725 //=======================================================================
726 //function : restoreDisplayMode
727 //purpose  : restore representation of a mesh
728 //=======================================================================
729
730 void SMESHGUI_SewingDlg::restoreDisplayMode()
731 {
732   if ( myActor && myStoredEntityMode )
733   {
734     if ( myActor->GetEntityMode() == ( myStoredEntityMode & ~SMESH_Actor::eVolumes ))
735       myActor->SetEntityMode( myStoredEntityMode );
736
737     if ( myActor->GetRepresentation() == SMESH_Actor::eEdge )
738       myActor->SetRepresentation( myStoredRepresentation );
739
740     myStoredEntityMode = 0;
741     myStoredRepresentation = -1;
742   }
743   for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
744     if ( myBorderDisplayers[ i ])
745       myBorderDisplayers[ i ]->Hide();
746 }
747
748 //=======================================================================
749 //function : onModeChange
750 //purpose  : SLOT called when mode (auto or manual) of Sew free borders change
751 //=======================================================================
752
753 void SMESHGUI_SewingDlg::onModeChange( int mode )
754 {
755   if ( mode == MODE_MANUAL )
756   {
757     myEditCurrentArgument = LineEdit1;
758     if ( !SubGroup1->isVisible() )
759       SubGroup1->show(), SubGroup2->show();
760     SewFreeBordersWidget->hide();
761   }
762   else
763   {
764     myEditCurrentArgument = LineEditMesh;
765     SubGroup1->hide(), SubGroup2->hide();
766     if ( !SewFreeBordersWidget->isVisible() )
767       SewFreeBordersWidget->show();
768   }
769   if ( myActor )
770     myActor->SetPointRepresentation( mode == MODE_MANUAL );
771
772   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetCurrentVtkView() )
773     aViewWindow->SetSelectionMode( mode == MODE_MANUAL ? NodeSelection : ActorSelection );
774
775   onAutoSew( AutoSewCheck->isChecked() );
776
777   QApplication::instance()->processEvents();
778   updateGeometry();
779
780   resize(100,100);
781 }
782
783 //=======================================================================
784 //function : onAutoSew
785 //purpose  : SLOT called when Auto Sewing check box is checked
786 //=======================================================================
787
788 void SMESHGUI_SewingDlg::onAutoSew( int isAuto )
789 {
790   GroupCoincidentWidget->setVisible( !isAuto );
791
792   QApplication::instance()->processEvents();
793
794   SewFreeBordersWidget->hide();
795   if ( ModeButGrp->checkedId() == MODE_AUTO )
796     SewFreeBordersWidget->show();
797
798   if ( isAuto )
799     restoreDisplayMode();
800   else
801     setDisplayMode();
802   SMESH::RepaintCurrentView();
803
804   UpdateButtons();
805
806   updateGeometry();
807   resize(minimumSizeHint());
808 }
809
810 //=======================================================================
811 //function : haveBorders
812 //purpose  : Returns true if myBorders have been initialized
813 //=======================================================================
814
815 bool SMESHGUI_SewingDlg::haveBorders()
816 {
817   return ( & myBorders.in() &&
818            myBorders->borders.length() &&
819            myBorders->coincidentGroups.length() );
820 }
821
822 //=======================================================================
823 //function : getGroupText
824 //purpose  : Returns a text of a given group of coincident free borders
825 //=======================================================================
826
827 QString SMESHGUI_SewingDlg::getPartText(const SMESH::FreeBorderPart& aPART)
828 {
829   QString text;
830   if ( 0 <= aPART.border && aPART.border < myBorders->borders.length() )
831   {
832     const SMESH::FreeBorder& aBRD = myBorders->borders[ aPART.border ];
833     if ( 0 <= aPART.node1    && aPART.node1 < aBRD.nodeIDs.length() &&
834          0 <= aPART.nodeLast && aPART.nodeLast < aBRD.nodeIDs.length() )
835     {
836       text += QString("( %1 %2 %3 ) ")
837         .arg( aBRD.nodeIDs[ aPART.node1 ] )
838         .arg( aBRD.nodeIDs[ aPART.node2 ] )
839         .arg( aBRD.nodeIDs[ aPART.nodeLast ] );
840     }
841   }
842   return text;
843 }
844
845 //=======================================================================
846 //function : getGroupText
847 //purpose  : Returns a text of a given group of coincident free borders
848 //=======================================================================
849
850 QString SMESHGUI_SewingDlg::getGroupText(int groupIndex)
851 {
852   QString text;
853
854   if ( haveBorders()   &&
855        groupIndex >= 0 &&
856        groupIndex < myBorders->coincidentGroups.length() )
857   {
858     const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ groupIndex ];
859
860     for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
861     {
862       QString partText = getPartText( aGRP[ iP ]);
863       if ( partText.isEmpty() )
864         return "";
865       text += partText;
866     }
867   }
868   return text;
869 }
870
871 //=======================================================================
872 //function : onDetectClicked
873 //purpose  : SLOT called when [Detect] is clicked
874 //=======================================================================
875
876 void SMESHGUI_SewingDlg::onDetectClicked()
877 {
878   myBusy = true;
879   ListCoincident->clear();
880
881   if ( myMesh->_is_nil() )
882     return;
883
884   SUIT_OverrideCursor wc;
885
886   SMESH::SMESH_MeshEditor_var editor = myMesh->GetMeshEditor();
887   myBorders = editor->FindCoincidentFreeBorders( SpinBoxTolerance->GetValue() );
888   if ( haveBorders() )
889   {
890     for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
891     {
892       delete myBorderDisplayers[ i ];
893       myBorderDisplayers[ i ] = 0;
894     }
895     myBorderDisplayers.resize( myBorders->coincidentGroups.length(), 0 );
896
897     for ( uint i = 0; i < myBorders->coincidentGroups.length(); ++i )
898     {
899       QString groupText = getGroupText( i );
900       if ( groupText.isEmpty() )
901         continue;
902
903       QColor groupColor;
904       groupColor.setHsvF( float(i) / myBorders->coincidentGroups.length(), 1., 1. );
905       QPixmap icon( QSize( 20, 20 ));
906       icon.fill( groupColor );
907
908       QListWidgetItem * item = new QListWidgetItem( icon, groupText, ListCoincident );
909       item->setData( GROUP_COLOR, groupColor );
910       item->setData( GROUP_INDEX, i );
911     }
912   }
913   myBusy = false;
914
915   onSelectGroup();
916
917   UpdateButtons();
918 }
919
920 //=======================================================================
921 //function : onRemoveGroupClicked
922 //purpose  :
923 //=======================================================================
924
925 void SMESHGUI_SewingDlg::onRemoveGroupClicked()
926 {
927   myBusy = true;
928   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
929   for ( int i = 0; i < selItems.count(); ++i )
930   {
931     QListWidgetItem* item = selItems[ i ];
932     item->setSelected( false );
933     int groupIndex = item->data( GROUP_INDEX ).toInt();
934     delete item;
935     if ( myBorderDisplayers[ groupIndex ])
936       myBorderDisplayers[ groupIndex ]->Hide();
937     SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
938     aGRP.length( 0 );
939   }
940   myBusy = false;
941
942   onSelectGroup();
943   UpdateButtons();
944 }
945
946 //=======================================================================
947 //function : showGroup
948 //purpose  : display a group of coincident free borders in the Viewer
949 //=======================================================================
950
951 void SMESHGUI_SewingDlg::showGroup( QListWidgetItem* item )
952 {
953   if ( !item ||
954        item->listWidget() != ListCoincident ||
955        !haveBorders())
956     return;
957
958   int    groupIndex = item->data( GROUP_INDEX ).toInt();
959   QColor groupColor = item->data( GROUP_COLOR ).value<QColor>();
960   if ( groupIndex >= 0       &&
961        groupIndex < myBorders->coincidentGroups.length() )
962   {
963     if ( !myBorderDisplayers[ groupIndex ] && SMESH::GetCurrentVtkView())
964       myBorderDisplayers[ groupIndex ] = new BorderGroupDisplayer( myBorders, groupIndex, groupColor, myMesh );
965     bool wholeBorders = setCurrentGroup();
966     if ( myBorderDisplayers[ groupIndex ])
967       myBorderDisplayers[ groupIndex ]->ShowGroup( wholeBorders );
968   }
969 }
970
971 //=======================================================================
972 //function : setCurrentGroup
973 //purpose  : set index of a current free border group to myCurGroupIndex
974 //=======================================================================
975
976 bool SMESHGUI_SewingDlg::setCurrentGroup()
977 {
978   if ( !haveBorders() )
979     return false;
980
981   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
982   if ( selItems.count() != 1 )
983     return false;
984   
985   myCurGroupIndex = selItems[0]->data( GROUP_INDEX ).toInt();
986
987   return ( myCurGroupIndex >= 0 && myCurGroupIndex < myBorders->coincidentGroups.length() );
988 }
989
990 //=======================================================================
991 //function : setCurrentPart
992 //purpose  : set index of a current free border of a current group to myCurPartIndex
993 //=======================================================================
994
995 bool SMESHGUI_SewingDlg::setCurrentPart()
996 {
997   if ( !setCurrentGroup() )
998     return false;
999
1000   if ( ListEdit->selectedItems().count() != 1 )
1001     return false;
1002
1003   myCurPartIndex = ListEdit->currentRow();
1004   const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1005
1006   return ( myCurPartIndex >= 0 && myCurPartIndex < aGRP.length() );
1007 }
1008
1009 //=======================================================================
1010 //function : onSelectGroup
1011 //purpose  : SLOT called when selection of coincident free borders change
1012 //=======================================================================
1013
1014 void SMESHGUI_SewingDlg::onSelectGroup()
1015 {
1016   if ( myBusy )
1017     return;
1018   ListEdit->clear();
1019   BorderEndLine[0]->clear();
1020   BorderEndLine[1]->clear();
1021   for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
1022     if ( myBorderDisplayers[ i ])
1023       myBorderDisplayers[ i ]->Hide();
1024
1025   QList<QListWidgetItem*> selItems = ListCoincident->selectedItems();
1026
1027   RemoveGroupButton->setEnabled( selItems.count() > 0 );
1028
1029   onSelectBorderPartFromGroup(); // enable buttons
1030
1031   if ( !haveBorders() )
1032     return;
1033
1034   SelectAllCheck->blockSignals( true );
1035   if ( ListCoincident->count() != selItems.count() )
1036     SelectAllCheck->setChecked( false );
1037   SelectAllCheck->blockSignals( false );
1038
1039   if ( selItems.empty() ) // nothing selected - show all
1040     for ( int i = 0; i < ListCoincident->count(); ++i )
1041       showGroup( ListCoincident->item( i ));
1042   else
1043     for ( int i = 0; i < selItems.count(); ++i )
1044       showGroup( selItems[ i ]);
1045
1046   if ( setCurrentGroup() ) // edit a selected group
1047   {
1048     const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1049     for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
1050       new QListWidgetItem( getPartText( aGRP[ iP ]), ListEdit );
1051   }
1052   SMESH::RepaintCurrentView();
1053 }
1054
1055 //=======================================================================
1056 //function : onSelectAll
1057 //purpose  : SLOT called when Select All is checked
1058 //=======================================================================
1059
1060 void SMESHGUI_SewingDlg::onSelectAll(int isOn)
1061 {
1062   if ( isOn )
1063     ListCoincident->selectAll();
1064   else
1065     ListCoincident->clearSelection();
1066 }
1067
1068 //=======================================================================
1069 //function : onSelectBorderPartFromGroup
1070 //purpose  : SLOT called when selection of borders in an edited group changes
1071 //=======================================================================
1072
1073 void SMESHGUI_SewingDlg::onSelectBorderPartFromGroup()
1074 {
1075   if ( myBusy ) return;
1076   BorderEndLine[0]->setText("");
1077   BorderEndLine[1]->setText("");
1078   MoveBorderEndsButGrp->button( MOVE_LEFT_1  )->setEnabled( false );
1079   MoveBorderEndsButGrp->button( MOVE_RIGHT_1 )->setEnabled( false );
1080   MoveBorderEndsButGrp->button( MOVE_LEFT_2  )->setEnabled( false );
1081   MoveBorderEndsButGrp->button( MOVE_RIGHT_2 )->setEnabled( false );
1082   SwapBut->setEnabled( false );
1083   SetFirstButton->setEnabled( false );
1084   RemoveElemButton->setEnabled ( ListEdit->count() > 2 );
1085
1086   if ( !setCurrentGroup() )
1087     return;
1088
1089   if ( !myBorderDisplayers[ myCurGroupIndex ]) return;
1090   myBorderDisplayers[ myCurGroupIndex ]->Hide();
1091
1092   QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
1093   bool editPart = ( setCurrentPart() );
1094   for ( int i = 0; i < selItems.count(); ++i )
1095     myBorderDisplayers[ myCurGroupIndex ]->ShowPart( ListEdit->row( selItems[i] ), editPart );
1096
1097   if ( selItems.isEmpty() )
1098     myBorderDisplayers[ myCurGroupIndex ]->ShowGroup( /*wholeBorders=*/ true );
1099
1100   if ( editPart )
1101   {
1102     SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1103     SMESH::FreeBorderPart&   aPRT = aGRP[ myCurPartIndex ];
1104     SMESH::FreeBorder&       aBRD = myBorders->borders[ aPRT.border ];
1105
1106     BorderEndLine[0]->setText( QString::number( aBRD.nodeIDs[ aPRT.node1 ]));
1107     BorderEndLine[1]->setText( QString::number( aBRD.nodeIDs[ aPRT.nodeLast ]));
1108     SwapBut->setEnabled( true );
1109     SetFirstButton->setEnabled( myCurPartIndex > 0 );
1110
1111     int      size = (int) aBRD.nodeIDs.length();
1112     bool isClosed = ( aBRD.nodeIDs[0] == aBRD.nodeIDs[ size-1 ]);
1113     if ( !isClosed )
1114     {
1115       bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
1116       int dn     = ( isFwd ? +1 : -1 ) * StepSpin->value();
1117       MoveBorderEndsButGrp->button( MOVE_LEFT_1  )->
1118         setEnabled( 0 <= aPRT.node1-dn && aPRT.node1-dn < size );
1119       MoveBorderEndsButGrp->button( MOVE_RIGHT_1 )->
1120         setEnabled( 0 <= aPRT.node1+dn && aPRT.node1+dn < size );
1121       MoveBorderEndsButGrp->button( MOVE_LEFT_2  )->
1122         setEnabled( 0 <= aPRT.nodeLast-dn && aPRT.nodeLast-dn < size );
1123       MoveBorderEndsButGrp->button( MOVE_RIGHT_2  )->
1124         setEnabled( 0 <= aPRT.nodeLast+dn && aPRT.nodeLast+dn < size );
1125     }
1126     else
1127     {
1128       MoveBorderEndsButGrp->button( MOVE_LEFT_1  )->setEnabled( true );
1129       MoveBorderEndsButGrp->button( MOVE_RIGHT_1 )->setEnabled( true );
1130       MoveBorderEndsButGrp->button( MOVE_LEFT_2  )->setEnabled( true );
1131       MoveBorderEndsButGrp->button( MOVE_RIGHT_2 )->setEnabled( true );
1132     }
1133   }
1134   SMESH::RepaintCurrentView();
1135 }
1136
1137 //=======================================================================
1138 //function : onGroupChange
1139 //purpose  : Update after modification of a current group by the user
1140 //=======================================================================
1141
1142 void SMESHGUI_SewingDlg::onGroupChange( bool partChange )
1143 {
1144   ListCoincident->currentItem()->setText( getGroupText( myCurGroupIndex ));
1145
1146   const SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1147   for ( int i = 0; i < ListEdit->count(); ++i )
1148     ListEdit->item( i )->setText( getPartText( aGRP[ i ]));
1149
1150   if ( myBorderDisplayers[ myCurGroupIndex ])
1151     myBorderDisplayers[ myCurGroupIndex ]->Update();
1152
1153   if ( partChange )
1154     onSelectBorderPartFromGroup();
1155 }
1156
1157 //=======================================================================
1158 //function : onSetFirstClicked
1159 //purpose  : STOL called when |<< is clicked
1160 //=======================================================================
1161
1162 void SMESHGUI_SewingDlg::onSetFirstClicked()
1163 {
1164   if ( !setCurrentPart() || myCurPartIndex == 0 || ListEdit->count() == 0 )
1165     return;
1166
1167   SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1168
1169   SMESH::FreeBorderPart new1st = aGRP[ myCurPartIndex ];
1170   for ( ; myCurPartIndex > 0; --myCurPartIndex )
1171     aGRP[ myCurPartIndex ] = aGRP[ myCurPartIndex - 1 ];
1172
1173   aGRP[ 0 ] = new1st;
1174
1175   onGroupChange();
1176
1177   myBusy = true;
1178   ListEdit->clearSelection();
1179   myBusy = false;
1180   ListEdit->setCurrentItem( ListEdit->item(0) );//ListEdit->item(0)->setSelected(true);
1181 }
1182
1183 //=======================================================================
1184 //function : onRemoveElemClicked
1185 //purpose  : 
1186 //=======================================================================
1187
1188 void SMESHGUI_SewingDlg::onRemoveElemClicked()
1189 {
1190   if ( !setCurrentGroup() )
1191     return;
1192
1193   SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1194
1195   QList<QListWidgetItem*> selItems = ListEdit->selectedItems();
1196   for ( int i = 0; i < selItems.count(); ++i )
1197   {
1198     int part = ListEdit->row( selItems[i] );
1199     for ( ; part + 1 < aGRP.length(); ++part )
1200       aGRP[ part ] = aGRP[ part + 1 ];
1201     aGRP.length( aGRP.length() - 1 );
1202     delete selItems[i];
1203   }
1204
1205   if ( aGRP.length() == 0 )
1206     onRemoveGroupClicked();
1207   else
1208     onGroupChange( /*partChange=*/true );
1209 }
1210
1211 //=======================================================================
1212 //function : onMoveBorderEnd
1213 //purpose  : 
1214 //=======================================================================
1215
1216 void SMESHGUI_SewingDlg::onMoveBorderEnd(int button)
1217 {
1218   if ( !setCurrentPart() )
1219     return;
1220
1221   SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1222   SMESH::FreeBorderPart&   aPRT = aGRP[ myCurPartIndex ];
1223   SMESH::FreeBorder&       aBRD = myBorders->borders[ aPRT.border ];
1224   int size = (int) aBRD.nodeIDs.length();
1225
1226   bool isClosed = ( aBRD.nodeIDs[0] == aBRD.nodeIDs[ size-1 ]);
1227   if ( isClosed ) --size;
1228
1229   bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
1230   int dn     = ( isFwd ? +1 : -1 ) * StepSpin->value();
1231   if ( button == MOVE_LEFT_1 || button == MOVE_LEFT_2 )
1232     dn *= -1;
1233
1234   switch ( button ) {
1235   case MOVE_LEFT_1:
1236   case MOVE_RIGHT_1:
1237     if (( isClosed ) ||
1238         ( 0 <= aPRT.node1+dn && aPRT.node1+dn < size ))
1239     {
1240       aPRT.node1 = ( aPRT.node1 + size + dn ) % size;
1241       aPRT.node2 = ( aPRT.node2 + size + dn ) % size;
1242       break;
1243     }
1244   case MOVE_LEFT_2:
1245   case MOVE_RIGHT_2:
1246     if (( isClosed ) ||
1247         ( 0 <= aPRT.nodeLast+dn && aPRT.nodeLast+dn < size ))
1248     {
1249       aPRT.nodeLast = ( aPRT.nodeLast + size + dn ) % size;
1250       break;
1251     }
1252   default:
1253     return; // impossible to move
1254   }
1255   
1256   onGroupChange( /*partChange=*/true );
1257 }
1258
1259 //=======================================================================
1260 //function : onSwapClicked
1261 //purpose  : SLOT called when <-> is clicked
1262 //=======================================================================
1263
1264 void SMESHGUI_SewingDlg::onSwapClicked()
1265 {
1266   if ( !setCurrentPart() )
1267     return;
1268
1269   SMESH::FreeBordersGroup& aGRP = myBorders->coincidentGroups[ myCurGroupIndex ];
1270   SMESH::FreeBorderPart&   aPRT = aGRP[ myCurPartIndex ];
1271   SMESH::FreeBorder&       aBRD = myBorders->borders[ aPRT.border ];
1272   int size = (int) aBRD.nodeIDs.length();
1273
1274   bool isClosed = ( aBRD.nodeIDs[0] == aBRD.nodeIDs[ size-1 ]);
1275   if ( isClosed ) --size;
1276
1277   bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
1278
1279   std::swap( aPRT.nodeLast, aPRT.node1 );
1280
1281   aPRT.node2 = ( aPRT.node1 + ( isFwd ? -1 : +1 ) + size ) % size;
1282
1283   onGroupChange( /*partChange=*/true );
1284 }
1285
1286 //=================================================================================
1287 // function : ClickOnApply()
1288 // purpose  :
1289 //=================================================================================
1290 bool SMESHGUI_SewingDlg::ClickOnApply()
1291 {
1292   if (mySMESHGUI->isActiveStudyLocked())
1293     return false;
1294
1295   bool aResult = false;
1296
1297   if (IsValid())
1298   {
1299     bool toMerge          = CheckBoxMerge->isChecked();
1300     bool toCreatePolygons = CheckBoxPolygons->isChecked();
1301     bool toCreatePolyedrs = CheckBoxPolyedrs->isChecked();
1302     try {
1303       SUIT_OverrideCursor aWaitCursor;
1304       SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
1305
1306       int aConstructorId = GetConstructorId();
1307       SMESH::SMESH_MeshEditor::Sew_Error anError;
1308
1309       if (aConstructorId == 0)
1310       {
1311         if ( ModeButGrp->checkedId() == MODE_MANUAL )
1312         {
1313           anError = aMeshEditor->SewFreeBorders(LineEdit1->text().toLong(),
1314                                                 LineEdit2->text().toLong(),
1315                                                 LineEdit3->text().toLong(),
1316                                                 LineEdit4->text().toLong(),
1317                                                 LineEdit5->text().toLong(),
1318                                                 LineEdit6->text().toLong(),
1319                                                 toCreatePolygons,
1320                                                 toCreatePolyedrs);
1321         }
1322         else
1323         {
1324           int nbCoincGroups = ListCoincident->count();
1325           if ( AutoSewCheck->isChecked() )
1326           {
1327             myBorders     = aMeshEditor->FindCoincidentFreeBorders( SpinBoxTolerance->GetValue() );
1328             nbCoincGroups = myBorders->coincidentGroups.length();
1329           }
1330           CORBA::Short nbSewed = aMeshEditor->SewCoincidentFreeBorders( myBorders.inout(),
1331                                                                         toCreatePolygons,
1332                                                                         toCreatePolyedrs);
1333           QString msg;
1334           if ( nbCoincGroups == 0 )
1335             msg = tr("NO_BORDERS_TO_SEW");
1336           else if ( nbSewed < nbCoincGroups )
1337             msg = tr("NOT_ALL_BORDERS_SEWED").arg( nbSewed ).arg( nbCoincGroups );
1338           else
1339             msg = tr("ALL_BORDERS_SEWED").arg( nbSewed );
1340           SUIT_MessageBox::information( this, tr("SMESH_INFORMATION"), msg );
1341
1342           anError = SMESH::SMESH_MeshEditor::SEW_OK;
1343         }
1344       }
1345       else if (aConstructorId == 1)
1346       {
1347         anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(),
1348                                                      LineEdit2->text().toLong(),
1349                                                      LineEdit3->text().toLong(),
1350                                                      LineEdit4->text().toLong(),
1351                                                      LineEdit5->text().toLong());
1352       }
1353       else if (aConstructorId == 2)
1354       {
1355         anError = aMeshEditor->SewBorderToSide(LineEdit1->text().toLong(),
1356                                                LineEdit2->text().toLong(),
1357                                                LineEdit3->text().toLong(),
1358                                                LineEdit4->text().toLong(),
1359                                                LineEdit6->text().toLong(),
1360                                                toCreatePolygons,
1361                                                toCreatePolyedrs);
1362       }
1363       else if (aConstructorId == 3) {
1364         QStringList aListElementsId1 = LineEdit1->text().split(" ", QString::SkipEmptyParts);
1365         QStringList aListElementsId2 = LineEdit4->text().split(" ", QString::SkipEmptyParts);
1366
1367         SMESH::long_array_var anElementsId1 = new SMESH::long_array;
1368         SMESH::long_array_var anElementsId2 = new SMESH::long_array;
1369
1370         anElementsId1->length(aListElementsId1.count());
1371         anElementsId2->length(aListElementsId2.count());
1372
1373         for (int i = 0; i < aListElementsId1.count(); i++)
1374           anElementsId1[i] = aListElementsId1[i].toInt();
1375         for (int i = 0; i < aListElementsId2.count(); i++)
1376           anElementsId2[i] = aListElementsId2[i].toInt();
1377
1378         anError = aMeshEditor->SewSideElements(anElementsId1.inout(),
1379                                                anElementsId2.inout(),
1380                                                LineEdit2->text().toLong(),
1381                                                LineEdit5->text().toLong(),
1382                                                LineEdit3->text().toLong(),
1383                                                LineEdit6->text().toLong());
1384       }
1385       aResult = (anError == SMESH::SMESH_MeshEditor::SEW_OK);
1386
1387       if (toMerge && aResult)
1388         aMeshEditor->MergeEqualElements();
1389
1390       if (!aResult) {
1391         QString msg = tr(QString("ERROR_%1").arg(anError).toLatin1().data());
1392         SUIT_MessageBox::warning(this, tr("SMESH_WRN_WARNING"), msg);
1393       }
1394     }
1395     catch ( const SALOME::SALOME_Exception& S_ex )
1396     {
1397       SalomeApp_Tools::QtCatchCorbaException( S_ex );
1398       return false;
1399     }
1400
1401     if (aResult) {
1402
1403       if ( myActor )
1404       {
1405         Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
1406         SALOME_ListIO aList;
1407         aList.Append(anIO);
1408         mySelectionMgr->setSelectedObjects(aList, false);
1409         SMESH::UpdateView();
1410       }
1411       Init();
1412       ConstructorsClicked(GetConstructorId());
1413
1414       SMESHGUI::Modified();
1415     }
1416   }
1417
1418   return aResult;
1419 }
1420
1421 //=================================================================================
1422 // function : ClickOnOk()
1423 // purpose  :
1424 //=================================================================================
1425 void SMESHGUI_SewingDlg::ClickOnOk()
1426 {
1427   if (ClickOnApply())
1428     reject();
1429 }
1430
1431 //=================================================================================
1432 // function : onOpenView()
1433 // purpose  :
1434 //=================================================================================
1435 void SMESHGUI_SewingDlg::onOpenView()
1436 {
1437   if ( mySelector ) {
1438     SMESH::SetPointRepresentation(false);
1439   }
1440   else {
1441     mySelector = SMESH::GetViewWindow( mySMESHGUI )->GetSelector();
1442     ActivateThisDialog();
1443   }
1444 }
1445
1446 //=================================================================================
1447 // function : onCloseView()
1448 // purpose  :
1449 //=================================================================================
1450 void SMESHGUI_SewingDlg::onCloseView()
1451 {
1452   DeactivateActiveDialog();
1453   mySelector = 0;
1454   myActor = 0;
1455
1456   for ( size_t i = 0; i < myBorderDisplayers.size(); ++i )
1457   {
1458     delete myBorderDisplayers[ i ];
1459     myBorderDisplayers[ i ] = 0;
1460   }
1461   myBorderDisplayers.clear();
1462 }
1463
1464 //=================================================================================
1465 // function : reject()
1466 // purpose  :
1467 //=================================================================================
1468 void SMESHGUI_SewingDlg::reject()
1469 {
1470   restoreDisplayMode();
1471   //mySelectionMgr->clearSelected();
1472   SMESH::SetPointRepresentation(false);
1473   if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1474     aViewWindow->SetSelectionMode(ActorSelection);
1475   disconnect(mySelectionMgr, 0, this, 0);
1476   mySMESHGUI->ResetState();
1477   QDialog::reject();
1478 }
1479
1480 //=================================================================================
1481 // function : ClickOnHelp()
1482 // purpose  :
1483 //=================================================================================
1484 void SMESHGUI_SewingDlg::ClickOnHelp()
1485 {
1486   LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
1487   if (app) 
1488     app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
1489   else {
1490     QString platform;
1491 #ifdef WIN32
1492     platform = "winapplication";
1493 #else
1494     platform = "application";
1495 #endif
1496     SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
1497                              tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
1498                              arg(app->resourceMgr()->stringValue("ExternalBrowser", 
1499                                                                  platform)).
1500                              arg(myHelpFileName));
1501   }
1502 }
1503
1504 //=======================================================================
1505 //function : onTextChange
1506 //purpose  :
1507 //=======================================================================
1508 void SMESHGUI_SewingDlg::onTextChange (const QString& theNewText)
1509 {
1510   QLineEdit* send = (QLineEdit*)sender();
1511
1512   if (myBusy) return;
1513   myBusy = true;
1514
1515   if (send)
1516     myEditCurrentArgument = send;
1517
1518   if      (send == LineEdit1)
1519     myOk1 = false;
1520   else if (send == LineEdit2)
1521     myOk2 = false;
1522   else if (send == LineEdit3)
1523     myOk3 = false;
1524   else if (send == LineEdit4)
1525     myOk4 = false;
1526   else if (send == LineEdit5)
1527     myOk5 = false;
1528   else if (send == LineEdit6)
1529     myOk6 = false;
1530
1531   // hilight entered elements/nodes
1532   SMDS_Mesh* aMesh = 0;
1533
1534   if (myActor)
1535     aMesh = myActor->GetObject()->GetMesh();
1536   else
1537     send->clear();
1538
1539   if (aMesh) {
1540     TColStd_MapOfInteger newIndices;
1541     
1542     if (GetConstructorId() != 3 || (send != LineEdit1 && send != LineEdit4)) {
1543       SMESH::SetPointRepresentation(true);
1544
1545       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1546         aViewWindow->SetSelectionMode(NodeSelection);
1547
1548       const SMDS_MeshNode * n = aMesh->FindNode(theNewText.toInt());
1549       if (n) {
1550         newIndices.Add(n->GetID());
1551         mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
1552         if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1553           aViewWindow->highlight( myActor->getIO(), true, true );
1554         
1555         if      (send == LineEdit1)
1556           myOk1 = true;
1557         else if (send == LineEdit2)
1558           myOk2 = true;
1559         else if (send == LineEdit3)
1560           myOk3 = true;
1561         else if (send == LineEdit4)
1562           myOk4 = true;
1563         else if (send == LineEdit5)
1564           myOk5 = true;
1565         else if (send == LineEdit6)
1566           myOk6 = true;
1567       }
1568     } else {
1569       SMESH::SetPointRepresentation(false);
1570
1571       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1572         aViewWindow->SetSelectionMode(CellSelection);
1573
1574       QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
1575
1576       bool isEvenOneExists = false;
1577
1578       for (int i = 0; i < aListId.count(); i++) {
1579         const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt());
1580         if (e) 
1581           newIndices.Add(e->GetID());
1582         
1583           if (!isEvenOneExists)
1584             isEvenOneExists = true;
1585       }
1586       
1587       mySelector->AddOrRemoveIndex(myActor->getIO(), newIndices, false);
1588       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1589         aViewWindow->highlight( myActor->getIO(), true, true );
1590       
1591       if (isEvenOneExists) {
1592         if (send == LineEdit1)
1593           myOk1 = true;
1594         else if(send == LineEdit4)
1595           myOk4 = true;
1596       } else {
1597         send->clear();
1598       }
1599     }
1600   }
1601
1602   UpdateButtons();
1603
1604   myBusy = false;
1605 }
1606
1607 //=================================================================================
1608 // function : SelectionIntoArgument()
1609 // purpose  : Called when selection as changed or other case
1610 //=================================================================================
1611 void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
1612 {
1613   if (myBusy) return;
1614
1615   // clear
1616   restoreDisplayMode();
1617   if (isSelectionChanged)
1618     myActor = 0;
1619
1620   QString aString = "";
1621
1622   myBusy = true;
1623   myEditCurrentArgument->setText(aString);
1624   ListCoincident->clear();
1625   ListEdit->clear();
1626   myBusy = false;
1627
1628   onSelectGroup(); // erase preview
1629
1630   if (!GroupButtons->isEnabled()) // inactive
1631     return;
1632
1633   buttonOk->setEnabled(false);
1634   buttonApply->setEnabled(false);
1635   DetectButton->setEnabled(false);
1636
1637   // get selected mesh
1638   SALOME_ListIO aList;
1639   mySelectionMgr->selectedObjects(aList);
1640
1641   int nbSel = aList.Extent();
1642   if (nbSel != 1)
1643     return;
1644
1645   Handle(SALOME_InteractiveObject) IO = aList.First();
1646   myMesh  = SMESH::GetMeshByIO(IO);
1647   myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
1648   if (myMesh->_is_nil())
1649     return;
1650
1651   CheckBoxPolyedrs->setEnabled( myMesh->NbVolumes() > 0 );
1652
1653   if ( myEditCurrentArgument == LineEditMesh )
1654   {
1655     if ( _PTR(SObject) meshSO = SMESH::FindSObject( myMesh ))
1656       LineEditMesh->setText( meshSO->GetName().c_str() );
1657     ListCoincident->clear();
1658     if ( AutoSewCheck->isChecked() )
1659     {
1660       buttonOk->setEnabled(true);
1661       buttonApply->setEnabled(true);
1662     }
1663     DetectButton->setEnabled( myMesh->NbFaces() > 0 );
1664     setDisplayMode();
1665     return;
1666   }
1667
1668   if (!myActor)
1669     return;
1670
1671   // get selected elements/nodes
1672   int aNbUnits = 0;
1673   if (( GetConstructorId() != 3 ) ||
1674       ( myEditCurrentArgument != LineEdit1 && myEditCurrentArgument != LineEdit4))
1675   {
1676     aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
1677     if (aNbUnits != 1)
1678       return;
1679   }
1680   else {
1681     aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
1682     if (aNbUnits < 1)
1683       return;
1684   }
1685
1686   myBusy = true;
1687   myEditCurrentArgument->setText(aString);
1688   myBusy = false;
1689
1690   // OK
1691   if (myEditCurrentArgument == LineEdit1)
1692     myOk1 = true;
1693   else if (myEditCurrentArgument == LineEdit2)
1694     myOk2 = true;
1695   else if (myEditCurrentArgument == LineEdit3)
1696     myOk3 = true;
1697   else if (myEditCurrentArgument == LineEdit4)
1698     myOk4 = true;
1699   else if (myEditCurrentArgument == LineEdit5)
1700     myOk5 = true;
1701   else if (myEditCurrentArgument == LineEdit6)
1702     myOk6 = true;
1703
1704   UpdateButtons();
1705 }
1706
1707 //=================================================================================
1708 // function : SetEditCurrentArgument()
1709 // purpose  :
1710 //=================================================================================
1711 void SMESHGUI_SewingDlg::SetEditCurrentArgument()
1712 {
1713   QPushButton* send = (QPushButton*)sender();
1714
1715   disconnect(mySelectionMgr, 0, this, 0);
1716   mySelectionMgr->clearSelected();
1717
1718   if (send == SelectButton1) {
1719     myEditCurrentArgument = LineEdit1;
1720     myOk1 = false;
1721   }
1722   else if (send == SelectButton2) {
1723     myEditCurrentArgument = LineEdit2;
1724     myOk2 = false;
1725   }
1726   else if (send == SelectButton3) {
1727     myEditCurrentArgument = LineEdit3;
1728     myOk3 = false;
1729   }
1730   else if (send == SelectButton4) {
1731     myEditCurrentArgument = LineEdit4;
1732     myOk4 = false;
1733   }
1734   else if (send == SelectButton5) {
1735     myEditCurrentArgument = LineEdit5;
1736     myOk5 = false;
1737   }
1738   else if (send == SelectButton6) {
1739     myEditCurrentArgument = LineEdit6;
1740     myOk6 = false;
1741   }
1742
1743   if (GetConstructorId() != 3 || (send != SelectButton1 && send != SelectButton4)) {
1744     SMESH::SetPointRepresentation(true);
1745
1746     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1747       aViewWindow->SetSelectionMode(NodeSelection);
1748
1749   } else {
1750     SMESH::SetPointRepresentation(false);
1751     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
1752       aViewWindow->SetSelectionMode(CellSelection);
1753   }
1754
1755   myEditCurrentArgument->setFocus();
1756   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
1757   SelectionIntoArgument(false);
1758 }
1759
1760 //=================================================================================
1761 // function : DeactivateActiveDialog()
1762 // purpose  :
1763 //=================================================================================
1764 void SMESHGUI_SewingDlg::DeactivateActiveDialog()
1765 {
1766   if (ConstructorsBox->isEnabled()) {
1767     ConstructorsBox->setEnabled(false);
1768     GroupArguments->setEnabled(false);
1769     GroupButtons->setEnabled(false);
1770     mySMESHGUI->ResetState();
1771     mySMESHGUI->SetActiveDialogBox(0);
1772   }
1773 }
1774
1775 //=================================================================================
1776 // function : ActivateThisDialog()
1777 // purpose  :
1778 //=================================================================================
1779 void SMESHGUI_SewingDlg::ActivateThisDialog()
1780 {
1781   /* Emit a signal to deactivate the active dialog */
1782   mySMESHGUI->EmitSignalDeactivateDialog();
1783   ConstructorsBox->setEnabled(true);
1784   GroupArguments->setEnabled(true);
1785   GroupButtons->setEnabled(true);
1786
1787   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
1788
1789   ConstructorsClicked(GetConstructorId());
1790   SelectionIntoArgument();
1791 }
1792
1793 //=================================================================================
1794 // function : enterEvent()
1795 // purpose  :
1796 //=================================================================================
1797 void SMESHGUI_SewingDlg::enterEvent (QEvent* e)
1798 {
1799   if (!ConstructorsBox->isEnabled()) {
1800     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI );
1801     if ( aViewWindow && !mySelector) {
1802       mySelector = aViewWindow->GetSelector();
1803     }
1804     ActivateThisDialog();
1805   }
1806 }
1807
1808 //=================================================================================
1809 // function : GetConstructorId()
1810 // purpose  :
1811 //=================================================================================
1812 int SMESHGUI_SewingDlg::GetConstructorId()
1813 {
1814   return GroupConstructors->checkedId();
1815 }
1816
1817 //=================================================================================
1818 // function : GetConstructorId()
1819 // purpose  :
1820 //=================================================================================
1821 bool SMESHGUI_SewingDlg::IsValid()
1822 {
1823   if ( myMesh->_is_nil() )
1824     return false;
1825
1826   if ( GetConstructorId() == 0 && ModeButGrp->checkedId() == MODE_AUTO )
1827   {
1828     if ( AutoSewCheck->isChecked() )
1829       return true;
1830
1831     int nbGroups = 0;
1832     if ( haveBorders() )
1833       for ( int i = 0; i < ListCoincident->count(); ++i )
1834       {
1835         int groupIndex = ListCoincident->item(i)->data( GROUP_INDEX ).toInt();
1836         nbGroups += ( !getGroupText( groupIndex ).isEmpty() );
1837       }
1838     return nbGroups > 0;
1839   }
1840   return (myOk1 && myOk2 && myOk3 && myOk4 && myOk5 && myOk6);
1841 }
1842
1843 //=======================================================================
1844 //function : UpdateButtons
1845 //purpose  : activate [Apply] buttons
1846 //=======================================================================
1847
1848 void SMESHGUI_SewingDlg::UpdateButtons()
1849 {
1850   bool ok = IsValid();
1851   buttonOk->setEnabled( ok );
1852   buttonApply->setEnabled( ok );
1853 }
1854
1855 //=================================================================================
1856 // function : keyPressEvent()
1857 // purpose  :
1858 //=================================================================================
1859 void SMESHGUI_SewingDlg::keyPressEvent( QKeyEvent* e )
1860 {
1861   QDialog::keyPressEvent( e );
1862   if ( e->isAccepted() )
1863     return;
1864
1865   if ( e->key() == Qt::Key_F1 ) {
1866     e->accept();
1867     ClickOnHelp();
1868   }
1869 }
1870
1871 SMESHGUI_SewingDlg::
1872 BorderGroupDisplayer::BorderGroupDisplayer( const SMESH::CoincidentFreeBorders& borders,
1873                                             int                                 groupIndex,
1874                                             QColor                              color,
1875                                             SMESH::SMESH_Mesh_ptr               mesh):
1876   myBorders   ( borders.borders ),
1877   myGroup     ( borders.coincidentGroups[ groupIndex ]),
1878   myColor     ( color ),
1879   myMesh      ( mesh ),
1880   myViewWindow( SMESH::GetCurrentVtkView() ),
1881   myIdPreview ( myViewWindow )
1882 {
1883   Update();
1884 }
1885
1886 SMESHGUI_SewingDlg::BorderGroupDisplayer::~BorderGroupDisplayer()
1887 {
1888   for ( size_t i = 0; i < myPartActors.size(); ++i )
1889   {
1890     if ( myPartActors[ i ]) {
1891       myViewWindow->RemoveActor( myPartActors[i] );
1892       myPartActors[i]->Delete();
1893     }
1894   }
1895   myIdPreview.SetPointsLabeled(false);
1896 }
1897
1898 void SMESHGUI_SewingDlg::BorderGroupDisplayer::Hide()
1899 {
1900   for ( size_t i = 0; i < myPartActors.size(); ++i )
1901     if ( myPartActors[ i ])
1902       myPartActors[ i ]->SetVisibility(false);
1903
1904   myIdPreview.SetPointsLabeled(false);
1905 }
1906
1907 void SMESHGUI_SewingDlg::BorderGroupDisplayer::ShowGroup( bool wholeBorders )
1908 {
1909   std::vector<int> ids;
1910   std::list<gp_XYZ> coords;
1911   for ( size_t i = 0; i < myPartActors.size(); ++i )
1912     if ( myPartActors[ i ])
1913     {
1914       myPartActors[ i ]->SetPointRepresentation( wholeBorders );
1915       myPartActors[ i ]->SetVisibility( true );
1916       if ( wholeBorders )
1917         getPartEnds( i, ids, coords );
1918     }
1919   if ( wholeBorders )
1920     myIdPreview.SetElemsData( ids, coords );
1921   myIdPreview.SetPointsLabeled( wholeBorders, true );
1922 }
1923
1924 void SMESHGUI_SewingDlg::BorderGroupDisplayer::ShowPart( int partIndex, bool toEdit )
1925 {
1926   if ( partIndex < (int) myPartActors.size() )
1927   {
1928     myPartActors[partIndex]->SetVisibility(true);
1929     myPartActors[partIndex]->SetPointRepresentation(toEdit);
1930
1931     if ( toEdit )
1932     {
1933       std::vector<int> ids;
1934       std::list<gp_XYZ> coords;
1935       getPartEnds( partIndex, ids, coords );
1936
1937       myIdPreview.SetElemsData( ids, coords );
1938       myIdPreview.SetPointsLabeled( true, /*show=*/true );
1939     }
1940   }
1941 }
1942
1943 void SMESHGUI_SewingDlg::BorderGroupDisplayer::getPartEnds( int                partIndex,
1944                                                             std::vector<int> & ids,
1945                                                             std::list<gp_XYZ>& coords)
1946 {
1947   const SMESH::FreeBorderPart& aPART = myGroup  [ partIndex ];
1948   const SMESH::FreeBorder&      aBRD = myBorders[ aPART.border ];
1949
1950   ids.push_back( aBRD.nodeIDs[ aPART.node1 ]);
1951   ids.push_back( aBRD.nodeIDs[ aPART.nodeLast ]);
1952
1953   SMDS_Mesh* mesh = myPartActors[ partIndex ]->GetObject()->GetMesh();
1954
1955   coords.push_back( SMESH_TNodeXYZ( mesh->FindNode( aPART.node1+1 )));
1956   coords.push_back( SMESH_TNodeXYZ( mesh->FindNode( aPART.nodeLast+1 )));
1957 }
1958
1959 void SMESHGUI_SewingDlg::BorderGroupDisplayer::Update()
1960 {
1961   Hide();
1962   myPartActors.resize( myGroup.length(), 0 );
1963
1964   for ( size_t i = 0; i < myPartActors.size(); ++i )
1965   {
1966     TVisualObjPtr obj;
1967     if ( myPartActors[ i ])
1968       obj = myPartActors[ i ]->GetObject();
1969     else
1970       obj = TVisualObjPtr( new SMESHGUI_PreVisualObj() );
1971     SMDS_Mesh* mesh = obj->GetMesh();
1972     mesh->Clear();
1973
1974     // add nodes
1975     const SMESH::FreeBorderPart& aPRT = myGroup[ i ];
1976     const SMESH::FreeBorder&     aBRD = myBorders[ aPRT.border ];
1977     for ( CORBA::ULong iN = 0; iN < aBRD.nodeIDs.length(); ++iN )
1978     {
1979       SMESH::double_array_var xyz = myMesh->GetNodeXYZ( aBRD.nodeIDs[ iN ]);
1980       if ( xyz->length() == 3 )
1981         mesh->AddNode( xyz[0], xyz[1], xyz[2] );
1982     }
1983
1984     // add edges
1985     bool isFwd = ( Abs( aPRT.node2 - aPRT.node1 ) == 1 ) ? aPRT.node2 > aPRT.node1 : aPRT.node2 < aPRT.node1;
1986     int dn     = isFwd ? +1 : -1;
1987     int size   = (int) aBRD.nodeIDs.length();
1988     int n2, n1 = aPRT.node1;
1989     for ( n2 = n1 + dn; ( n2 >= 0 && n2 < size ); n2 += dn )
1990     {
1991       mesh->AddEdgeWithID( n1+1, n2+1, mesh->NbEdges() + 1 );
1992       n1 = n2;
1993       if ( n2 == aPRT.nodeLast )
1994         break;
1995     }
1996     if ( n2 % size != aPRT.nodeLast )
1997     {
1998       if ( n2 < 0 ) n1 = size;
1999       else          n1 = 0;
2000       for ( n2 = n1 + dn; ( n2 >= 0 && n2 < size ); n2 += dn )
2001       {
2002         mesh->AddEdgeWithID( n1+1, n2+1, mesh->NbEdges() + 1 );
2003         n1 = n2;
2004         if ( n2 == aPRT.nodeLast )
2005           break;
2006       }
2007     }
2008
2009     if ( !myPartActors[ i ]) // TVisualObj must be filled before actor creation
2010     {
2011       myPartActors[ i ] = SMESH_Actor::New( obj, "", "", 1 );
2012       myPartActors[ i ]->SetEdgeColor( myColor.redF(), myColor.greenF(), myColor.blueF() );
2013       myPartActors[ i ]->SetLineWidth( 3 * SMESH::GetFloat("SMESH:element_width",1));
2014       myPartActors[ i ]->SetNodeColor( myColor.redF(), myColor.greenF(), myColor.blueF() );
2015       myPartActors[ i ]->SetMarkerStd( VTK::MT_POINT, 13 );
2016       myPartActors[ i ]->SetPickable ( false );
2017       myViewWindow->AddActor( myPartActors[ i ]);
2018     }
2019   }
2020 }
2021