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