Salome HOME
4daaf6039a403ab63f08b345a908ff0f57b79c4a
[modules/geom.git] / src / MeasureGUI / MeasureGUI_CreateDimensionDlg.cxx
1 // Copyright (C) 2007-2013  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.
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 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : MeasureGUI_CreateDimensionDlg.cxx
25 // Author : Anton POLETAEV, Open CASCADE S.A.S.
26
27 #include "MeasureGUI_CreateDimensionDlg.h"
28 #include "MeasureGUI_DimensionCreateTool.h"
29
30 #include <GEOM_Constants.h>
31 #include <GeometryGUI.h>
32 #include <GEOMBase.h>
33 #include <DlgRef.h>
34 #include <GEOMUtils.hxx>
35 #include <GEOMGUI_DimensionProperty.h>
36
37 #include <LightApp_SelectionMgr.h>
38 #include <SalomeApp_Application.h>
39 #include <SalomeApp_DataObject.h>
40 #include <SalomeApp_Study.h>
41 #include <SOCC_ViewModel.h>
42 #include <SOCC_Prs.h>
43 #include <SUIT_ViewWindow.h>
44 #include <SUIT_ViewManager.h>
45 #include <SUIT_MessageBox.h>
46 #include <SUIT_ResourceMgr.h>
47 #include <SUIT_Session.h>
48 #include <SUIT_Desktop.h>
49
50 #include <Aspect_PolygonOffsetMode.hxx>
51
52 //=================================================================================
53 // function : Constructor
54 // purpose  :
55 //=================================================================================
56 MeasureGUI_CreateDimensionDlg::MeasureGUI_CreateDimensionDlg( const GEOM::GeomObjPtr& theObj,
57                                                               GeometryGUI* theGUI,
58                                                               QWidget* theParent )
59 : GEOMBase_Skeleton( theGUI, theParent ),
60   myParentObj( theObj ),
61   myEditingViewer( NULL )
62 {
63   setWindowTitle( tr( "CREATE_DIMENSION_TITLE" ) );
64
65   // init "dimension type" radio buttons
66   QAbstractButton* aTypeButtonLength   = mainFrame()->RadioButton1;
67   QAbstractButton* aTypeButtonDiameter = mainFrame()->RadioButton2;
68   QAbstractButton* aTypeButtonAngle    = mainFrame()->RadioButton3;
69
70   mainFrame()->GroupConstructors->setTitle( tr( "DIMENSIONS" ) );
71   aTypeButtonDiameter->setText( tr( "DIAMETER" ) );
72   aTypeButtonLength->setText( tr( "LENGTH" ) );
73   aTypeButtonAngle->setText( tr( "ANGLE" ) );
74
75   // construct "arguments" pane
76   QGroupBox*   aGroupArgs       = new QGroupBox( tr( "ARGUMENTS" ), centralWidget() );
77   QVBoxLayout* aGroupArgsLayout = new QVBoxLayout( aGroupArgs );
78
79   myLengthArgs   = new LengthPane  ( centralWidget() );
80   myDiameterArgs = new DiameterPane( centralWidget() );
81   myAngleArgs    = new AnglePane   ( centralWidget() );
82
83   // connect selector pane signals
84   connect( myLengthArgs,   SIGNAL( StartSelection( const QList<TopAbs_ShapeEnum>& ) ),
85                            SLOT( OnStartSelection( const QList<TopAbs_ShapeEnum>& ) ) );
86   connect( myDiameterArgs, SIGNAL( StartSelection( const QList<TopAbs_ShapeEnum>& ) ),
87                            SLOT( OnStartSelection( const QList<TopAbs_ShapeEnum>& ) ) );
88   connect( myAngleArgs,    SIGNAL( StartSelection( const QList<TopAbs_ShapeEnum>& ) ), 
89                            SLOT( OnStartSelection( const QList<TopAbs_ShapeEnum>& ) ) );
90
91   connect( myLengthArgs,   SIGNAL( StopSelection() ), SLOT( OnStopSelection() ) );
92   connect( myDiameterArgs, SIGNAL( StopSelection() ), SLOT( OnStopSelection() ) );
93   connect( myAngleArgs,    SIGNAL( StopSelection() ), SLOT( OnStopSelection( ) ) );
94
95   connect( myLengthArgs,   SIGNAL( SelectionDone() ), SLOT( OnSelectionDone() ) );
96   connect( myDiameterArgs, SIGNAL( SelectionDone() ), SLOT( OnSelectionDone() ) );
97   connect( myAngleArgs,    SIGNAL( SelectionDone() ), SLOT( OnSelectionDone() ) );
98
99   aGroupArgsLayout->addWidget( myLengthArgs );
100   aGroupArgsLayout->addWidget( myDiameterArgs );
101   aGroupArgsLayout->addWidget( myAngleArgs );
102
103   // construct main layout
104   QVBoxLayout* aCustomWidLayout = new QVBoxLayout( centralWidget() );
105   aCustomWidLayout->setMargin( 0 ); 
106   aCustomWidLayout->setSpacing( 6 );
107   aCustomWidLayout->addWidget( aGroupArgs );
108
109   // add visibility rules for structural widgets
110   connect( aTypeButtonLength,   SIGNAL( toggled(bool) ), myLengthArgs,   SLOT( setVisible(bool) ) );
111   connect( aTypeButtonDiameter, SIGNAL( toggled(bool) ), myDiameterArgs, SLOT( setVisible(bool) ) );
112   connect( aTypeButtonAngle,    SIGNAL( toggled(bool) ), myAngleArgs,    SLOT( setVisible(bool) ) );
113
114   // signals and slots connections
115   connect( buttonOk(),    SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
116   connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
117
118   // map functional signals
119   myRBGroup->setId( aTypeButtonLength,   TypeButtonID_Length );
120   myRBGroup->setId( aTypeButtonDiameter, TypeButtonID_Diameter );
121   myRBGroup->setId( aTypeButtonAngle,    TypeButtonID_Angle );
122
123   connect( this, SIGNAL( constructorsClicked( int ) ), SLOT( ConstructTypeChanged( int ) ) );
124   connect( myLengthArgs,   SIGNAL( TabChanged() ), SLOT( OnArgumentTabChanged() ) );
125   connect( myDiameterArgs, SIGNAL( TabChanged() ), SLOT( OnArgumentTabChanged() ) );
126   connect( myAngleArgs,    SIGNAL( TabChanged() ), SLOT( OnArgumentTabChanged() ) );
127
128   myDimensionInteractor = new MeasureGUI_DimensionInteractor( theGUI, theParent );
129
130   Init();
131 }
132
133 //=================================================================================
134 // function : Destructor
135 // purpose  :
136 //=================================================================================
137 MeasureGUI_CreateDimensionDlg::~MeasureGUI_CreateDimensionDlg()
138 {
139 }
140
141 //=================================================================================
142 // function : ActiveArgs
143 // purpose  : 
144 //=================================================================================
145 MeasureGUI_CreateDimensionDlg::BaseSelectorPane* MeasureGUI_CreateDimensionDlg::ActiveArgs()
146 {
147   switch ( getConstructorId() )
148   {
149     case TypeButtonID_Length   : return myLengthArgs;
150     case TypeButtonID_Diameter : return myDiameterArgs;
151     case TypeButtonID_Angle    : return myAngleArgs;
152     default:
153       return NULL;
154   }
155 }
156
157 //=================================================================================
158 // function : GenerateName
159 // purpose  : 
160 //=================================================================================
161 QString MeasureGUI_CreateDimensionDlg::GenerateName( const QString& thePrefix )
162 {
163   QRegExp anExtractIds( "^" + thePrefix + "_([0-9]+)$" );
164
165   QSet<int> anOccupiedIds;
166
167   GEOMGUI_DimensionProperty aProp =
168     getStudy()->getObjectProperty( GEOM::sharedPropertiesId(),
169                                    myParentObj->GetStudyEntry(),
170                                    GEOM::propertyName( GEOM::Dimensions ),
171                                    QVariant() )
172                                    .value<GEOMGUI_DimensionProperty>();
173
174   // get names and convert to QStrings to perform index matching
175   for( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
176   {
177     if ( anExtractIds.indexIn( aProp.GetName( anIt ) ) == -1 )
178     {
179       continue;
180     }
181
182     anOccupiedIds.insert( anExtractIds.cap( 1 ).toInt() );
183   }
184
185   int aSearchId = 1;
186   while ( true )
187   {
188     if ( !anOccupiedIds.contains( aSearchId ) )
189     {
190       break;
191     }
192
193     aSearchId++;
194   }
195
196   return QString( thePrefix + "_%1" ).arg( aSearchId );
197 }
198
199 //=================================================================================
200 // function : ConstructTypeChanged
201 // purpose  : 
202 //=================================================================================
203 void MeasureGUI_CreateDimensionDlg::ConstructTypeChanged( int theType )
204 {
205   ActiveArgs()->Reset();
206
207   updateGeometry();
208
209   QString aName;
210   switch ( theType )
211   {
212     case TypeButtonID_Length   : aName = GenerateName( tr("NAME_LENGTH") );   break;
213     case TypeButtonID_Diameter : aName = GenerateName( tr("NAME_DIAMETER") ); break;
214     case TypeButtonID_Angle    : aName = GenerateName( tr("NAME_ANGLE") );    break;
215   }
216
217   myMainFrame->ResultName->setText( aName );
218
219   StopLocalEditing();
220   erasePreview();
221
222   updateGeometry();
223   resize( minimumSizeHint() );
224 }
225
226 //=================================================================================
227 // function : OnArgumentTabChanged
228 // purpose  : 
229 //=================================================================================
230 void MeasureGUI_CreateDimensionDlg::OnArgumentTabChanged()
231 {
232   StopLocalEditing();
233   erasePreview();
234 }
235
236 //=================================================================================
237 // function : OnStartSelection
238 // purpose  :
239 //=================================================================================
240 void MeasureGUI_CreateDimensionDlg::OnStartSelection( const QList<TopAbs_ShapeEnum>& theModes )
241 {
242   OnStopSelection();
243
244   StopLocalEditing();
245
246   QList<TopAbs_ShapeEnum>::const_iterator aModeIt = theModes.constBegin();
247   for ( ; aModeIt != theModes.constEnd(); ++aModeIt )
248   {
249     localSelection( myParentObj.get(), *aModeIt );
250   }
251
252   mySelectionModes = theModes;
253
254   connect( myGeomGUI->getApp()->selectionMgr(),
255            SIGNAL( currentSelectionChanged() ),
256            SLOT( SelectionIntoArgument() ) );
257 }
258
259 //=================================================================================
260 // function : OnStopSelection
261 // purpose  :
262 //=================================================================================
263 void MeasureGUI_CreateDimensionDlg::OnStopSelection()
264 {
265   globalSelection();
266
267   disconnect( myGeomGUI->getApp()->selectionMgr(),
268               SIGNAL( currentSelectionChanged() ),
269               this,
270               SLOT( SelectionIntoArgument() ) );
271 }
272
273 //=================================================================================
274 // function : SelectionIntoArgument
275 // purpose  : Handle model selection by active selector pane
276 //=================================================================================
277 void MeasureGUI_CreateDimensionDlg::SelectionIntoArgument()
278 {
279   LightApp_SelectionMgr* aSelectionMgr = myGeomGUI->getApp()->selectionMgr();
280   SALOME_ListIO aSelection;
281   aSelectionMgr->selectedObjects( aSelection );
282
283   if ( aSelection.Extent() != 1 )
284   {
285     ActiveArgs()->SelectionIntoArguments( GEOM::GeomObjPtr() );
286     return;
287   }
288
289   StopLocalEditing();
290
291   erasePreview();
292
293   ActiveArgs()->SelectionIntoArguments( getSelected( mySelectionModes ) );
294 }
295
296 //=================================================================================
297 // function : OnSelectionDone
298 // purpose  :
299 //=================================================================================
300 void MeasureGUI_CreateDimensionDlg::OnSelectionDone()
301 {
302   // create new dimension presentation
303   myDimension = CreateDimension();
304
305   if ( myDimension.IsNull() )
306   {
307     // can not create preview, repeat selection
308     SUIT_MessageBox::warning( this,
309                               tr( "WARNING_TITLE_CANNOT_CREATE_DIMENSION" ),
310                               tr( "WARNING_MSG_INVALID_ARGUMENTS" ) );
311
312     ActiveArgs()->Reset();
313
314     return;
315   }
316
317   // show preview of dimension object
318   SUIT_ViewWindow* aViewWindow = SUIT_Session::session()->activeApplication()->desktop()->activeWindow();
319
320   SOCC_Prs* aSalomePrs = dynamic_cast<SOCC_Prs*>( ( (SOCC_Viewer*)( aViewWindow->getViewManager()->getViewModel() ) )->CreatePrs( 0 ) );
321
322   aSalomePrs->AddObject( myDimension );
323
324   displayPreview( aSalomePrs );
325
326   StartLocalEditing();
327 }
328
329 //=================================================================================
330 // function : ClickOnOk
331 // purpose  : 
332 //=================================================================================
333 void MeasureGUI_CreateDimensionDlg::ClickOnOk()
334 {
335   setIsApplyAndClose( true );
336   if ( ClickOnApply() )
337   {
338     ClickOnCancel();
339   }
340 }
341
342 //=================================================================================
343 // function : ClickOnApply
344 // purpose  : 
345 //=================================================================================
346 bool MeasureGUI_CreateDimensionDlg::ClickOnApply()
347 {
348   StopLocalEditing();
349
350   if ( !AddDimensionToOwner() )
351   {
352     return false;
353   }
354
355   redisplay( myParentObj.get() );
356
357   if ( !isApplyAndClose() )
358   {
359     Init();
360   }
361
362   return true;
363 }
364
365 //=================================================================================
366 // function : StartLocalEditing
367 // purpose  : 
368 //=================================================================================
369 void MeasureGUI_CreateDimensionDlg::StartLocalEditing()
370 {
371   StopLocalEditing();
372
373   myDimensionInteractor->Enable();
374
375   if ( myDimension.IsNull() )
376   {
377     return;
378   }
379
380   SalomeApp_Application* anApp = myGeomGUI->getApp();
381
382   SUIT_ViewManager* aViewMgr = anApp->activeViewManager();
383
384   if ( aViewMgr->getType() != OCCViewer_Viewer::Type() )
385   {
386     return;
387   }
388
389   SOCC_Viewer* anOCCViewer = dynamic_cast<SOCC_Viewer*>( aViewMgr->getViewModel() );
390
391   myEditingViewer = anOCCViewer;
392   if ( !myEditingViewer )
393   {
394     return;
395   }
396
397   Handle(AIS_InteractiveContext) anAISContext = myEditingViewer->getAISContext();
398   Handle(V3d_Viewer)             aViewer3d    = myEditingViewer->getViewer3d();
399
400   aViewer3d->AddZLayer( myEditingLayer );
401
402   anAISContext->OpenLocalContext( Standard_False, Standard_False );
403   anAISContext->Load( myDimension, AIS_DSM_All );
404   anAISContext->SetZLayer( myDimension, myEditingLayer );
405   anAISContext->Activate( myDimension, AIS_DSM_Line );
406   anAISContext->Activate( myDimension, AIS_DSM_Text );
407 }
408
409 //=================================================================================
410 // function : StopLocalEditing
411 // purpose  : 
412 //=================================================================================
413 void MeasureGUI_CreateDimensionDlg::StopLocalEditing()
414 {
415   myDimensionInteractor->Disable();
416
417   if ( !myEditingViewer )
418   {
419     return;
420   }
421
422   Handle(AIS_InteractiveContext) anAISContext = myEditingViewer->getAISContext();
423   Handle(V3d_Viewer)             aViewer3d    = myEditingViewer->getViewer3d();
424
425   aViewer3d->RemoveZLayer( myEditingLayer );
426   anAISContext->CloseLocalContext();
427
428   myEditingViewer = NULL;
429 }
430
431 //=================================================================================
432 // function : Init
433 // purpose  : 
434 //=================================================================================
435 void MeasureGUI_CreateDimensionDlg::Init()
436 {
437   StopLocalEditing();
438
439   erasePreview();
440
441   myDiameterArgs->setVisible( false );
442   myAngleArgs   ->setVisible( false );
443   myLengthArgs  ->setVisible( true );
444   myLengthArgs->Reset();
445
446   myRBGroup->button( TypeButtonID_Length )->click();
447 }
448
449 //=================================================================================
450 // function : CreateDimensionPrs
451 // purpose  : 
452 //=================================================================================
453 Handle(AIS_Dimension) MeasureGUI_CreateDimensionDlg::CreateDimension()
454 {
455   Handle(AIS_Dimension) aDimensionIO;
456
457   // prepare dimension styling
458   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
459
460   QColor  aQColor       = aResMgr->colorValue  ( "Geometry", "dimensions_color", QColor( 0, 255, 0 ) );
461   int     aLineWidth    = aResMgr->integerValue( "Geometry", "dimensions_line_width", 1 );
462   double  aFontHeight   = aResMgr->doubleValue ( "Geometry", "dimensions_font_height", 10 );
463   double  anArrowLength = aResMgr->doubleValue ( "Geometry", "dimensions_arrow_length", 5 );
464   bool    isUnitsShown  = aResMgr->booleanValue( "Geometry", "dimensions_show_units", false );
465   QString aUnitsLength  = aResMgr->stringValue ( "Geometry", "dimensions_length_units", "m" );
466   QString aUnitsAngle   = aResMgr->stringValue ( "Geometry", "dimensions_angle_units", "deg" );
467
468   MeasureGUI_DimensionCreateTool aTool( myGeomGUI );
469
470   switch ( getConstructorId() )
471   {
472     // create length dimension
473     case TypeButtonID_Length :
474     {
475       LengthPane* aLengthPane = qobject_cast<LengthPane*>( ActiveArgs() );
476
477       switch (aLengthPane->ActiveTab())
478       {
479         case LengthPane::TabID_SingleEdge:
480         {
481           const GEOM::GeomObjPtr& anEdge = aLengthPane->GetSingleEdge();
482
483           aDimensionIO = aTool.LengthOnEdge( anEdge );
484           break;
485         }
486
487         case LengthPane::TabID_TwoPoints:
488         {
489           const GEOM::GeomObjPtr& aPoint1 = aLengthPane->GetPoint1();
490           const GEOM::GeomObjPtr& aPoint2 = aLengthPane->GetPoint2();
491
492           aDimensionIO = aTool.LengthByPoints( aPoint1, aPoint2 );
493           break;
494         }
495
496         case LengthPane::TabID_ParallelEdges:
497         {
498           const GEOM::GeomObjPtr& anEdge1 = aLengthPane->GetEdge1();
499           const GEOM::GeomObjPtr& anEdge2 = aLengthPane->GetEdge2();
500
501           aDimensionIO = aTool.LengthByParallelEdges( anEdge1, anEdge2 );
502           break;
503         }
504       }
505     }
506     break;
507
508     // create diameter dimension
509     case TypeButtonID_Diameter :
510     {
511       DiameterPane* aDiameterPane = qobject_cast<DiameterPane*>( ActiveArgs() );
512
513       const GEOM::GeomObjPtr& aShape = aDiameterPane->GetShape();
514
515       aDimensionIO = aTool.Diameter( aShape );
516       break;
517     }
518
519     // create angle dimension
520     case TypeButtonID_Angle :
521     {
522       AnglePane* anAnglePane = qobject_cast<AnglePane*>( ActiveArgs() );
523
524       switch (ActiveArgs()->ActiveTab())
525       {
526         case AnglePane::TabID_TwoEdges:
527         {
528           const GEOM::GeomObjPtr& anEdge1 = anAnglePane->GetEdge1();
529           const GEOM::GeomObjPtr& anEdge2 = anAnglePane->GetEdge2();
530
531           aDimensionIO = aTool.AngleByTwoEdges( anEdge1, anEdge2 );
532           break;
533         }
534
535         case AnglePane::TabID_ThreePoints:
536         {
537           const GEOM::GeomObjPtr& aPoint1 = anAnglePane->GetPoint1();
538           const GEOM::GeomObjPtr& aPoint2 = anAnglePane->GetPoint2();
539           const GEOM::GeomObjPtr& aPoint3 = anAnglePane->GetPoint3();
540
541           aDimensionIO = aTool.AngleByThreePoints( aPoint1, aPoint2, aPoint3 );
542           break;
543         }
544       }
545       break;
546     }
547   }
548
549   if ( aDimensionIO.IsNull() )
550   {
551     return NULL;
552   }
553
554   Quantity_Color aColor( aQColor.redF(), aQColor.greenF(), aQColor.blueF(), Quantity_TOC_RGB );
555
556   Handle(Prs3d_DimensionAspect) aStyle = new Prs3d_DimensionAspect();
557
558   aStyle->SetCommonColor( aColor );
559   aStyle->MakeUnitsDisplayed( (Standard_Boolean) isUnitsShown );
560   aStyle->MakeText3d( Standard_True );
561   aStyle->MakeTextShaded( Standard_True );
562   aStyle->TextAspect()->SetHeight( aFontHeight );
563   aStyle->ArrowAspect()->SetLength( anArrowLength );
564   aStyle->LineAspect()->SetWidth( aLineWidth );
565   aDimensionIO->SetDimensionAspect( aStyle );
566   aDimensionIO->SetPolygonOffsets( Aspect_POM_Fill, -1.0, -1.0 );
567
568   return aDimensionIO;
569 }
570
571 //=================================================================================
572 // class    : AddDimensionToOwner
573 // purpose  : 
574 //=================================================================================
575 bool MeasureGUI_CreateDimensionDlg::AddDimensionToOwner()
576 {
577   if ( myDimension.IsNull() )
578   {
579     return false;
580   }
581
582   gp_Ax3 aLCS;
583   TopoDS_Shape anParentSh;
584   if ( GEOMBase::GetShape( myParentObj.get(), anParentSh ) )
585   {
586     aLCS = GEOMUtils::GetPosition( anParentSh );
587   }
588
589   QString aName = getNewObjectName();
590
591   SalomeApp_Study* aStudy = getStudy();
592
593   GEOMGUI_DimensionProperty aProp =
594     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
595                                myParentObj->GetStudyEntry(),
596                                GEOM::propertyName( GEOM::Dimensions ),
597                                QVariant() )
598                                .value<GEOMGUI_DimensionProperty>();
599
600   // append new dimension record to data
601   aProp.AddRecord( myDimension, aLCS );
602   aProp.SetName( aProp.GetNumber() - 1, aName );
603   aProp.SetVisible( aProp.GetNumber() - 1, true );
604
605   // store modified property data
606   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
607                              myParentObj->GetStudyEntry(),
608                              GEOM::propertyName( GEOM::Dimensions ),
609                              aProp );
610
611   return true;
612 }
613
614 /* ------------------------------------------------------------------------------*
615  *                                                                               *
616  *                    Argument shape selector layout                             *
617  *                                                                               *
618  * ------------------------------------------------------------------------------*/
619
620 //=================================================================================
621 // class    : MeasureGUI_CreateDimensionDlg::LengthPane
622 // purpose  : Constructor
623 //=================================================================================
624 MeasureGUI_CreateDimensionDlg::LengthPane::LengthPane( QWidget* theParent )
625 : BaseSelectorPane( theParent )
626 {
627   myTabs                   = new QTabWidget( this );
628   mySingleEdgeSelectors    = new MeasureGUI_1Sel_Frame( this );
629   myTwoPointsSelectors     = new MeasureGUI_2Sel_Frame( this );
630   myParallelEdgesSelectors = new MeasureGUI_2Sel_Frame( this );
631
632   myTabs->addTab( mySingleEdgeSelectors,    MeasureGUI_CreateDimensionDlg::tr( "EDGE_LENGTH" ) );
633   myTabs->addTab( myTwoPointsSelectors,     MeasureGUI_CreateDimensionDlg::tr( "TWO_POINTS" ) );
634   myTabs->addTab( myParallelEdgesSelectors, MeasureGUI_CreateDimensionDlg::tr( "PARALLEL_EDGES" ) );
635
636   mySingleEdgeSelectors->PushButton1->setIcon( mySelectorIcon );
637   mySingleEdgeSelectors->TextLabel1->setText( MeasureGUI_CreateDimensionDlg::tr( "EDGE" ) );
638   mySingleEdgeSelectors->LineEdit1->setReadOnly( true );
639
640   myTwoPointsSelectors->PushButton1->setIcon( mySelectorIcon );
641   myTwoPointsSelectors->PushButton2->setIcon( mySelectorIcon );
642   myTwoPointsSelectors->TextLabel1->setText( MeasureGUI_CreateDimensionDlg::tr( "POINT_1" ) );
643   myTwoPointsSelectors->TextLabel2->setText( MeasureGUI_CreateDimensionDlg::tr( "POINT_2" ) );
644   myTwoPointsSelectors->LineEdit1->setReadOnly( true );
645   myTwoPointsSelectors->LineEdit2->setReadOnly( true );
646
647   myParallelEdgesSelectors->PushButton1->setIcon( mySelectorIcon );
648   myParallelEdgesSelectors->PushButton2->setIcon( mySelectorIcon );
649   myParallelEdgesSelectors->TextLabel1 ->setText( MeasureGUI_CreateDimensionDlg::tr( "EDGE_1" ) );
650   myParallelEdgesSelectors->TextLabel2 ->setText( MeasureGUI_CreateDimensionDlg::tr( "EDGE_2" ) );
651   myParallelEdgesSelectors->LineEdit1->setReadOnly( true );
652   myParallelEdgesSelectors->LineEdit2->setReadOnly( true );
653
654   QVBoxLayout* aLayout = new QVBoxLayout( this );
655
656   aLayout->setMargin( 0 );
657   aLayout->addWidget( myTabs );
658
659   SelectionModes anEdgeModes;
660   SelectionModes aPointModes;
661   anEdgeModes << TopAbs_EDGE;
662   aPointModes << TopAbs_VERTEX;
663
664   SetTabWidget( myTabs );
665   RegisterSelector( mySingleEdgeSelectors->LineEdit1,    mySingleEdgeSelectors->PushButton1,    anEdgeModes, TabID_SingleEdge );
666   RegisterSelector( myTwoPointsSelectors->LineEdit1,     myTwoPointsSelectors->PushButton1,     aPointModes, TabID_TwoPoints );
667   RegisterSelector( myTwoPointsSelectors->LineEdit2,     myTwoPointsSelectors->PushButton2,     aPointModes, TabID_TwoPoints );
668   RegisterSelector( myParallelEdgesSelectors->LineEdit1, myParallelEdgesSelectors->PushButton1, anEdgeModes, TabID_ParallelEdges );
669   RegisterSelector( myParallelEdgesSelectors->LineEdit2, myParallelEdgesSelectors->PushButton2, anEdgeModes, TabID_ParallelEdges );
670 }
671
672 //=================================================================================
673 // class    : MeasureGUI_CreateDimensionDlg::DiameterPane
674 // purpose  : Constructor
675 //=================================================================================
676 MeasureGUI_CreateDimensionDlg::DiameterPane::DiameterPane( QWidget* theParent )
677 : BaseSelectorPane( theParent )
678 {
679   myShapeSelector = new MeasureGUI_1Sel_Frame( this );
680   myShapeSelector->PushButton1->setIcon( mySelectorIcon );
681   myShapeSelector->TextLabel1 ->setText( MeasureGUI_CreateDimensionDlg::tr( "OBJECT" ) );
682
683   QVBoxLayout* aLayout = new QVBoxLayout( this );
684
685   aLayout->setMargin( 0 );
686   aLayout->addWidget( myShapeSelector );
687
688   SelectionModes aDiamModes;
689   aDiamModes << TopAbs_SHAPE
690              << TopAbs_FACE
691              << TopAbs_EDGE;
692
693   RegisterSelector( myShapeSelector->LineEdit1, myShapeSelector->PushButton1, aDiamModes );
694 }
695
696 //=================================================================================
697 // class    : MeasureGUI_CreateDimensionDlg::AnglePane
698 // purpose  : Constructor
699 //=================================================================================
700 MeasureGUI_CreateDimensionDlg::AnglePane::AnglePane( QWidget* theParent )
701 : BaseSelectorPane( theParent )
702 {
703   myTabs                 = new QTabWidget( this );
704   myTwoEdgesSelectors    = new MeasureGUI_2Sel_Frame( this );
705   myThreePointsSelectors = new MeasureGUI_3Sel_Frame( this );
706
707   myTabs->addTab( myTwoEdgesSelectors,    MeasureGUI_CreateDimensionDlg::tr( "TWO_EDGES" ) );
708   myTabs->addTab( myThreePointsSelectors, MeasureGUI_CreateDimensionDlg::tr( "THREE_POINTS" ) );
709
710   myTwoEdgesSelectors->PushButton1->setIcon( mySelectorIcon );
711   myTwoEdgesSelectors->PushButton2->setIcon( mySelectorIcon );
712   myTwoEdgesSelectors->TextLabel1 ->setText( MeasureGUI_CreateDimensionDlg::tr( "EDGE_1" ) );
713   myTwoEdgesSelectors->TextLabel2 ->setText( MeasureGUI_CreateDimensionDlg::tr( "EDGE_2" ) );
714
715   myThreePointsSelectors->PushButton1->setIcon( mySelectorIcon );
716   myThreePointsSelectors->PushButton2->setIcon( mySelectorIcon );
717   myThreePointsSelectors->PushButton3->setIcon( mySelectorIcon );
718   myThreePointsSelectors->TextLabel1 ->setText( MeasureGUI_CreateDimensionDlg::tr( "POINT_1" ) );
719   myThreePointsSelectors->TextLabel2 ->setText( MeasureGUI_CreateDimensionDlg::tr( "POINT_2" ) );
720   myThreePointsSelectors->TextLabel3 ->setText( MeasureGUI_CreateDimensionDlg::tr( "POINT_3" ) );
721
722   QVBoxLayout* aLayout = new QVBoxLayout( this );
723
724   aLayout->setMargin( 0 );
725   aLayout->addWidget( myTabs );
726
727   SelectionModes anEdgeModes;
728   SelectionModes aPointModes;
729   anEdgeModes << TopAbs_EDGE;
730   aPointModes << TopAbs_VERTEX;
731
732   SetTabWidget( myTabs );
733   RegisterSelector( myTwoEdgesSelectors->LineEdit1,    myTwoEdgesSelectors->PushButton1,    anEdgeModes, TabID_TwoEdges );
734   RegisterSelector( myTwoEdgesSelectors->LineEdit2,    myTwoEdgesSelectors->PushButton2,    anEdgeModes, TabID_TwoEdges );
735   RegisterSelector( myThreePointsSelectors->LineEdit1, myThreePointsSelectors->PushButton1, aPointModes, TabID_ThreePoints );
736   RegisterSelector( myThreePointsSelectors->LineEdit2, myThreePointsSelectors->PushButton2, aPointModes, TabID_ThreePoints );
737   RegisterSelector( myThreePointsSelectors->LineEdit3, myThreePointsSelectors->PushButton3, aPointModes, TabID_ThreePoints );
738 }
739
740 /* ------------------------------------------------------------------------------*
741  *                                                                               *
742  *                   Argument shape selection logics                             *
743  *                                                                               *
744  * ------------------------------------------------------------------------------*/
745
746 //=================================================================================
747 // class    : MeasureGUI_CreateDimensionDlg::BaseSelectorPane
748 // purpose  : Constructor
749 //=================================================================================
750 MeasureGUI_CreateDimensionDlg::BaseSelectorPane::BaseSelectorPane( QWidget* theParent )
751 : QWidget( theParent ),
752   myTabs( NULL )
753 {
754   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
755   mySelectorIcon = aResMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) );
756 }
757
758 //=================================================================================
759 // function : BaseSelectorPane::Reset
760 // purpose  : Reset selector line edits and controls
761 //=================================================================================
762 void MeasureGUI_CreateDimensionDlg::BaseSelectorPane::Reset( bool theOpenDefaultTab )
763 {
764   if ( theOpenDefaultTab && myTabs )
765   {
766     myTabs->setCurrentIndex( 0 );
767   }
768
769   QMap< int, QList<QLineEdit*> >::iterator aTabsIt = mySelectors.begin();
770   for ( ; aTabsIt != mySelectors.end(); ++aTabsIt )
771   {
772     QList<QLineEdit*>& aSelectors = *aTabsIt;
773     QList<QLineEdit*>::iterator aSelectorIt = aSelectors.begin();
774     for ( ; aSelectorIt != aSelectors.end(); ++aSelectorIt )
775     {
776       QLineEdit* aSelector = *aSelectorIt;
777       aSelector->clear();
778       mySelectedShapes[aSelector] = GEOM::GeomObjPtr();
779     }
780   }
781
782   QLineEdit* aFirstSelector = mySelectors[ ActiveTab() ].first();
783
784   mySelectionButtons[aFirstSelector]->click();
785 }
786
787 //=================================================================================
788 // function : BaseSelectorPane::ActiveTab
789 // purpose  : Returns active tab
790 //=================================================================================
791 int MeasureGUI_CreateDimensionDlg::BaseSelectorPane::ActiveTab() const
792 {
793   return myTabs != NULL ? myTabs->currentIndex() : 0;
794 }
795
796 //=================================================================================
797 // function : BaseSelectorPane::SelectionIntoArgument
798 // purpose  : Populates current selector
799 //=================================================================================
800 void MeasureGUI_CreateDimensionDlg::BaseSelectorPane::SelectionIntoArguments( const GEOM::GeomObjPtr& theSelected )
801 {
802   if ( theSelected.isNull() )
803   {
804     myCurrentSelector->clear();
805     mySelectedShapes[myCurrentSelector] = GEOM::GeomObjPtr();
806     return;
807   }
808
809   QString aName = GEOMBase::GetName( theSelected.get() );
810
811   myCurrentSelector->setText( aName );
812
813   mySelectedShapes[myCurrentSelector] = theSelected;
814
815   // find next empty selector (iterate to the last)
816   QList<QLineEdit*>& aCurrentSelectors = mySelectors[ ActiveTab() ];
817   int aCurrentPos = aCurrentSelectors.indexOf( myCurrentSelector );
818   int aSelectorIt = aCurrentPos + 1;
819   for ( ; aSelectorIt != aCurrentSelectors.size(); ++aSelectorIt )
820   {
821     QLineEdit* aNextSelector = aCurrentSelectors[aSelectorIt];
822     if ( mySelectedShapes[aNextSelector].isNull() )
823     {
824       mySelectionButtons[aNextSelector]->click();
825       return;
826     }
827   }
828
829   // find next empty selector (itearte from the first)
830   aSelectorIt = 0;
831   for ( ; aSelectorIt != aCurrentPos; ++aSelectorIt )
832   {
833     QLineEdit* aNextSelector = aCurrentSelectors[aSelectorIt];
834     if ( mySelectedShapes[aNextSelector].isNull() )
835     {
836       mySelectionButtons[aNextSelector]->click();
837       return;
838     }
839   }
840
841   // stop selector switching
842   myCurrentSelector->setEnabled( false );
843   mySelectionButtons[myCurrentSelector]->setDown( false );
844
845   // every selector is populated - construct presentation
846   emit StopSelection();
847   emit SelectionDone();
848 }
849
850 //=================================================================================
851 // function : BaseSelectorPane::GetSelection
852 // purpose  : 
853 //=================================================================================
854 GEOM::GeomObjPtr MeasureGUI_CreateDimensionDlg::BaseSelectorPane::GetSelection( QLineEdit* theSelector ) const
855 {
856   return mySelectedShapes[theSelector];
857 }
858
859 //=================================================================================
860 // function : BaseSelectorPane::OnSelectorClicked
861 // purpose  : Handle activation of selector controls pair {edit, button}
862 //=================================================================================
863 void MeasureGUI_CreateDimensionDlg::BaseSelectorPane::OnSelectorClicked()
864 {
865   // clicked "selector" button
866   QAbstractButton* aSender = qobject_cast<QAbstractButton*>( sender() );
867   if ( !aSender )
868   {
869     return;
870   }
871
872   // get "selector" controls on the active tab
873   QList<QLineEdit*>& aCurrentSelectors = mySelectors[ ActiveTab() ];
874
875   // iterate over controls on the tab and process them
876   for ( int aSelectorIt = 0; aSelectorIt < aCurrentSelectors.size(); ++aSelectorIt )
877   {
878     QLineEdit* aSelector = aCurrentSelectors[aSelectorIt];
879     QPushButton* aButton = mySelectionButtons[aSelector];
880
881     bool isClickedOnes = (aButton == aSender);
882
883     aSelector->setEnabled( isClickedOnes );
884
885     if ( isClickedOnes )
886     {
887       myCurrentSelector = aSelector;
888       myCurrentSelector->setFocus();
889     }
890
891     aButton->setDown( isClickedOnes );
892   }
893
894   emit StartSelection( mySelectionModes[myCurrentSelector] );
895 }
896
897 //=================================================================================
898 // function : BaseSelectorPane::OnTabChanged
899 // purpose  :
900 //=================================================================================
901 void MeasureGUI_CreateDimensionDlg::BaseSelectorPane::OnTabChanged()
902 {
903   QList<QLineEdit*>& aSelectors = mySelectors[ ActiveTab() ];
904   QList<QLineEdit*>::iterator aSelectorIt = aSelectors.begin();
905   for ( ; aSelectorIt != aSelectors.end(); ++aSelectorIt )
906   {
907     QLineEdit* aSelector = *aSelectorIt;
908
909     aSelector->clear();
910
911     mySelectedShapes[aSelector] = GEOM::GeomObjPtr();
912   }
913
914   QLineEdit* aFirstSelector = mySelectors[ ActiveTab() ].first();
915
916   mySelectionButtons[aFirstSelector]->click();
917
918   emit TabChanged();
919 }
920
921 //=================================================================================
922 // function : BaseSelectorPane::SetTabWidget
923 // purpose  :
924 //=================================================================================
925 void MeasureGUI_CreateDimensionDlg::BaseSelectorPane::SetTabWidget( QTabWidget* theTabs )
926 {
927   myTabs = theTabs;
928   connect( myTabs, SIGNAL( currentChanged( int ) ), this, SLOT( OnTabChanged() ) );
929 }
930
931 //=================================================================================
932 // function : BaseSelectorPane::RegisterSelector
933 // purpose  :
934 //=================================================================================
935 void MeasureGUI_CreateDimensionDlg::BaseSelectorPane::RegisterSelector( QLineEdit* theSelectorEdit,
936                                                                         QPushButton* theSelectorButton,
937                                                                         const SelectionModes& theSelectorModes,
938                                                                         const int theTab )
939 {
940   if ( !mySelectors.contains( theTab ) )
941   {
942     mySelectors.insert( theTab, QList<QLineEdit*>() );
943   }
944   mySelectors[theTab].append( theSelectorEdit );
945
946   mySelectionButtons[theSelectorEdit] = theSelectorButton;
947   mySelectionModes  [theSelectorEdit] = theSelectorModes;
948
949   connect( theSelectorButton, SIGNAL( clicked() ), this, SLOT( OnSelectorClicked() ) );
950 }