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