Salome HOME
21854: Add persistent dimensions
[modules/geom.git] / src / MeasureGUI / MeasureGUI_ManageDimensionsDlg.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_ManageDimensionsDlg.cxx
25 // Author : Anton POLETAEV, Open CASCADE S.A.S.
26
27 #include "MeasureGUI_ManageDimensionsDlg.h"
28 #include "MeasureGUI_CreateDimensionDlg.h"
29 #include "MeasureGUI_DimensionFilter.h"
30
31 #include <GEOMGUI_DimensionProperty.h>
32 #include <GEOMUtils.hxx>
33 #include <GEOMGUI_OCCSelector.h>
34 #include <GEOM_AISDimension.hxx>
35 #include <GEOM_Constants.h>
36 #include <GEOMBase.h>
37 #include <DlgRef.h>
38
39 #include <SOCC_ViewModel.h>
40 #include <SOCC_Prs.h>
41 #include <SalomeApp_Application.h>
42 #include <SalomeApp_Study.h>
43 #include <LightApp_SelectionMgr.h>
44 #include <SUIT_ViewManager.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SUIT_MessageBox.h>
48
49 #include <AIS_ListOfInteractive.hxx>
50 #include <AIS_ListIteratorOfListOfInteractive.hxx>
51 #include <AIS_InteractiveContext.hxx>
52 #include <SelectMgr_Filter.hxx>
53 #include <SelectMgr_ListOfFilter.hxx>
54 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
55
56 #include <QTreeWidget>
57 #include <QPushButton>
58 #include <QGroupBox>
59 #include <QVBoxLayout>
60 #include <QHBoxLayout>
61 #include <QPixmap>
62
63 //=================================================================================
64 // function : Constructor
65 // purpose  :
66 //=================================================================================
67 MeasureGUI_ManageDimensionsDlg::MeasureGUI_ManageDimensionsDlg( GeometryGUI* theGUI, QWidget* theParent )
68 : GEOMBase_Skeleton( theGUI, theParent ),
69   myOperatedViewer( NULL ),
70   myCurrentSelection( Selection_None )
71 {
72   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
73
74   QPixmap aSelectorIcon = aResMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) );
75
76   setWindowTitle( tr( "MANAGE_DIMENSIONS_TITLE" ) );
77
78   mainFrame()->GroupConstructors->setVisible( false );
79   mainFrame()->GroupBoxName->setVisible( false );
80
81   // construct object selector pane
82   myObjectSelector = new DlgRef_1Sel( centralWidget() );
83   myObjectSelector->TextLabel1->setText( tr( "OBJECT_LABEL" ) );
84   myObjectSelector->LineEdit1->setReadOnly( true );
85   myObjectSelector->PushButton1->setIcon( aSelectorIcon );
86   myObjectSelector->PushButton1->setCheckable( true );
87
88   // construct dimension list view pane
89   myDimensionView = new MeasureGUI_1TreeWidget_4Button( centralWidget() );
90   myDimensionView->GroupBox->setTitle( tr( "DIMENSIONS_GROUP" ) );
91   myDimensionView->PushButton1->setText( tr( "ADD_BTN" ) );
92   myDimensionView->PushButton2->setText( tr( "REMOVE_BTN" ) );
93   myDimensionView->PushButton3->setText( tr( "SHOW_ALL_BTN" ) );
94   myDimensionView->PushButton4->setText( tr( "HIDE_ALL_BTN" ) );
95   myDimensionView->TreeWidget->setMinimumHeight( 250 );
96   myDimensionView->setEnabled( false );
97
98   connect( myDimensionView->PushButton1, SIGNAL( clicked() ), SLOT( OnAdd() ) );
99   connect( myDimensionView->PushButton2, SIGNAL( clicked() ), SLOT( OnRemove() ) );
100   connect( myDimensionView->PushButton3, SIGNAL( clicked() ), SLOT( OnShowAll() ) );
101   connect( myDimensionView->PushButton4, SIGNAL( clicked() ), SLOT( OnHideAll() ) );
102   connect( myDimensionView->TreeWidget, 
103            SIGNAL( itemChanged( QTreeWidgetItem*, int ) ),
104            SLOT( OnChangeItem( QTreeWidgetItem* ) ) );
105   connect( myDimensionView->TreeWidget,
106            SIGNAL( currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ) ),
107            SLOT( OnSelectItem() ) );
108
109   // populate tree with top-level items
110   myDimensionView->TreeWidget->setHeaderItem( new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( QString() ) ) );
111
112   // construct main frame layout
113   QVBoxLayout* aMainLayout = new QVBoxLayout( centralWidget() );
114   aMainLayout->setMargin( 0 );
115   aMainLayout->addWidget( myObjectSelector, 0 );
116   aMainLayout->addWidget( myDimensionView, 1 );
117
118   // signals and slots connections
119   connect( myObjectSelector->PushButton1, SIGNAL( clicked() ), SLOT( StartObjectSelection() ) );
120   connect( buttonOk(),    SIGNAL( clicked() ), SLOT( ClickOnOk() ) );
121   connect( buttonApply(), SIGNAL( clicked() ), SLOT( ClickOnApply() ) );
122
123   connect( this, SIGNAL( finished( int ) ), SLOT( OnFinish() ) );
124   
125   connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
126   connect( myGeomGUI, SIGNAL( SignalCloseAllDialogs() ),        this, SLOT( ClickOnCancel() ) );
127
128   myDimensionInteractor = new MeasureGUI_DimensionInteractor( theGUI, theParent ),
129
130   SelectionIntoArgument( Selection_Object );
131
132   if ( myEditObject.isNull() )
133   {
134     myObjectSelector->PushButton1->click();
135   }
136
137   setHelpFileName("managing_dimensions_page.html");
138 }
139
140 //=================================================================================
141 // function : Destructor
142 // purpose  :
143 //=================================================================================
144 MeasureGUI_ManageDimensionsDlg::~MeasureGUI_ManageDimensionsDlg()
145 {
146   StopSelection();
147 }
148
149 //=================================================================================
150 // function : StartSelection
151 // purpose  : Starts specific selection
152 //=================================================================================
153 void MeasureGUI_ManageDimensionsDlg::StartSelection( const Selection theSelection )
154 {
155   StopSelection();
156
157   myCurrentSelection = theSelection;
158
159   if ( theSelection == Selection_Object && AllowedToCancelChanges() )
160   {
161     /* -----------------------------------------------  *
162      *               selection of object                *
163      * ------------------------------------------------ */
164
165     globalSelection( GEOM_ALLSHAPES );
166     connect( myGeomGUI->getApp()->selectionMgr(),
167              SIGNAL( currentSelectionChanged() ),
168              this,
169              SLOT( OnSelection() ) );
170   }
171   else if ( theSelection == Selection_Dimension && !myEditObject.isNull() )
172   {
173     /* -----------------------------------------------  *
174      *               selection of dimension             *
175      * ------------------------------------------------ */
176
177     SalomeApp_Application* anApp = myGeomGUI->getApp();
178     if ( !anApp )
179     {
180       return;
181     }
182
183     SUIT_ViewManager* aViewMgr = anApp->activeViewManager();
184     if ( aViewMgr->getType() != SOCC_Viewer::Type() )
185     {
186       return;
187     }
188
189     myOperatedViewer = dynamic_cast<SOCC_Viewer*>( aViewMgr->getViewModel() );
190
191     globalSelection();
192
193     Handle(AIS_InteractiveContext) anAISContext = myOperatedViewer->getAISContext();
194
195     anAISContext->ClearCurrents( Standard_False );
196     anAISContext->ClearSelected( Standard_False );
197     anAISContext->OpenLocalContext( Standard_True, Standard_False );
198
199     Handle(MeasureGUI_DimensionFilter) aFilter = new MeasureGUI_DimensionFilter( myEditObject->GetStudyEntry() );
200
201     anAISContext->AddFilter( aFilter );
202
203     LightApp_SelectionMgr* aSelectionMgr = myGeomGUI->getApp()->selectionMgr();
204
205     QList<SUIT_Selector*> aSelectors;
206     aSelectionMgr->selectors( aSelectors );
207     QList<SUIT_Selector*>::iterator aSelectorIt = aSelectors.begin();
208     for ( ; aSelectorIt != aSelectors.end(); ++aSelectorIt )
209     {
210       SUIT_Selector* aSelector = *aSelectorIt;
211
212       GEOMGUI_OCCSelector* aGeomSelector = dynamic_cast<GEOMGUI_OCCSelector*>( aSelector );
213       if ( !aGeomSelector )
214       {
215         continue;
216       }
217
218       aGeomSelector->setEnabled( false );
219     }
220
221     connect( myOperatedViewer,
222              SIGNAL( selectionChanged() ),
223              this,
224              SLOT( OnSelection() ) );
225
226     myDimensionInteractor->Enable();
227
228     connect( myDimensionInteractor,
229              SIGNAL( InteractionFinished( Handle_AIS_InteractiveObject ) ),
230              this,
231              SLOT( OnInteractionFinished( Handle_AIS_InteractiveObject ) ) );
232
233     anAISContext->UpdateCurrentViewer();
234   }
235 }
236
237 //=================================================================================
238 // function : StopObjectSelection
239 // purpose  : Stops specific selection
240 //=================================================================================
241 void MeasureGUI_ManageDimensionsDlg::StopSelection()
242 {
243   if ( myCurrentSelection == Selection_Object )
244   {
245     /* -----------------------------------------------  *
246      *               selection of object                *
247      * ------------------------------------------------ */
248
249     myObjectSelector->PushButton1->setChecked( false );
250     disconnect( myGeomGUI->getApp()->selectionMgr(),
251                 SIGNAL( currentSelectionChanged() ),
252                 this,
253                 SLOT( OnSelection() ) );
254   }
255   else if ( myCurrentSelection == Selection_Dimension && myOperatedViewer )
256   {
257     /* -----------------------------------------------  *
258      *               selection of dimension             *
259      * ------------------------------------------------ */
260
261     Handle(AIS_InteractiveContext) anAISContext = myOperatedViewer->getAISContext();
262
263     anAISContext->CloseLocalContext();
264
265     LightApp_SelectionMgr* aSelectionMgr = myGeomGUI->getApp()->selectionMgr();
266
267     QList<SUIT_Selector*> aSelectors;
268     aSelectionMgr->selectors( aSelectors );
269     QList<SUIT_Selector*>::iterator aSelectorIt = aSelectors.begin();
270     for ( ; aSelectorIt != aSelectors.end(); ++aSelectorIt )
271     {
272       SUIT_Selector* aSelector = *aSelectorIt;
273
274       GEOMGUI_OCCSelector* aGeomSelector = dynamic_cast<GEOMGUI_OCCSelector*>( aSelector );
275       if ( !aGeomSelector )
276       {
277         continue;
278       }
279
280       aGeomSelector->setEnabled( true );
281     }
282
283     disconnect( myOperatedViewer,
284                 SIGNAL( selectionChanged() ),
285                 this,
286                 SLOT( OnSelection() ) );
287
288     myDimensionInteractor->Disable();
289
290     disconnect( myDimensionInteractor,
291                 SIGNAL( InteractionFinished( Handle_AIS_InteractiveObject ) ),
292                 this,
293                 SLOT( OnInteractionFinished( Handle_AIS_InteractiveObject ) ) );
294   }
295
296   myCurrentSelection = Selection_None;
297
298   globalSelection();
299 }
300
301 //=================================================================================
302 // function : OnSelection
303 // purpose  : 
304 //=================================================================================
305 void MeasureGUI_ManageDimensionsDlg::OnSelection()
306 {
307   SelectionIntoArgument( myCurrentSelection );
308 }
309
310 //=================================================================================
311 // function : SelectionIntoArgument
312 // purpose  : 
313 //=================================================================================
314 void MeasureGUI_ManageDimensionsDlg::SelectionIntoArgument( const Selection theSelection  )
315 {
316   if ( theSelection == Selection_Object )
317   {
318     /* -----------------------------------------------  *
319      *               selection of object                *
320      * ------------------------------------------------ */
321
322     LightApp_SelectionMgr* aSelectionMgr = myGeomGUI->getApp()->selectionMgr();
323     SALOME_ListIO aSelection;
324     aSelectionMgr->selectedObjects( aSelection );
325
326     GEOM::GeomObjPtr aSelected;
327
328     if ( aSelection.Extent() == 1 )
329     {
330       aSelected = GEOMBase::ConvertIOinGEOMObject( aSelection.First() );
331     }
332
333     SetEditObject( aSelected );
334     StartSelection( Selection_Dimension );
335   }
336   else if ( theSelection == Selection_Dimension && myOperatedViewer )
337   {
338     /* -----------------------------------------------  *
339      *               selection of dimension             *
340      * ------------------------------------------------ */
341
342     QTreeWidget* aDimensionList = myDimensionView->TreeWidget;
343
344     Handle(AIS_InteractiveContext) anAISContext = myOperatedViewer->getAISContext();
345
346     // non-single selection is prohibited
347     if ( anAISContext->NbSelected() != 1 )
348     {
349       aDimensionList->setCurrentIndex( QModelIndex() );
350       return;
351     }
352
353     anAISContext->InitSelected();
354
355     Handle(AIS_InteractiveObject) anAIS;
356
357     if ( anAISContext->HasOpenedContext() )
358     {
359       Handle(SelectMgr_EntityOwner) anAISOwner = anAISContext->SelectedOwner();
360       anAIS = Handle(AIS_InteractiveObject)::DownCast( anAISOwner->Selectable() );
361     }
362     else
363     {
364       anAIS = anAISContext->Current();
365     }
366
367     int aDimensionId = IdFromPrs( anAIS );
368
369     SelectInList( aDimensionId );
370
371     if ( aDimensionId >= 0 )
372     {
373       SelectInViewer( myOperatedViewer, aDimensionId );
374     }
375   }
376 }
377
378 //=================================================================================
379 // function : OnAdd
380 // purpose  :
381 //=================================================================================
382 void MeasureGUI_ManageDimensionsDlg::OnAdd()
383 {
384   QWidget* aParent = qobject_cast<QWidget*>( this->parent() );
385
386   this->Suspend();
387
388   MeasureGUI_CreateDimensionDlg* aCreateDlg = new MeasureGUI_CreateDimensionDlg( myEditObject, myGeomGUI, aParent );
389
390   connect( aCreateDlg, SIGNAL( finished( int ) ), this, SLOT( Resume() ) );
391
392   // this is necessary as the GEOMBase_Helper switches selection mode on destruction
393   connect( aCreateDlg, SIGNAL( destroyed( QObject* ) ), this, SLOT( Resume() ) );
394
395   aCreateDlg->updateGeometry();
396   aCreateDlg->resize( aCreateDlg->minimumSizeHint() );
397   aCreateDlg->show();
398 }
399
400 //=================================================================================
401 // function : OnRemove
402 // purpose  :
403 //=================================================================================
404 void MeasureGUI_ManageDimensionsDlg::OnRemove()
405 {
406   int aDimensionId = IdFromItem( myDimensionView->TreeWidget->currentItem() );
407   if ( aDimensionId < 0 )
408   {
409     return;
410   }
411
412   SalomeApp_Application* anApp = myGeomGUI->getApp();
413   if ( !anApp )
414   {
415     return;
416   }
417
418   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
419   if ( !aStudy )
420   {
421     return;
422   }
423
424   // get property data to change
425   GEOMGUI_DimensionProperty aProp =
426     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
427                                myEditObject->GetStudyEntry(),
428                                GEOM::propertyName( GEOM::Dimensions ),
429                                QVariant() )
430                                .value<GEOMGUI_DimensionProperty>();
431
432   aProp.RemoveRecord( aDimensionId );
433
434   // store modified property data
435   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
436                              myEditObject->GetStudyEntry(),
437                              GEOM::propertyName( GEOM::Dimensions ),
438                              aProp );
439
440   PopulateList();
441
442   RedisplayObject();
443 }
444
445 //=================================================================================
446 // function : OnChangeItem
447 // purpose  :
448 //=================================================================================
449 void MeasureGUI_ManageDimensionsDlg::OnChangeItem( QTreeWidgetItem* theItem )
450 {
451   int aDimensionId = IdFromItem( theItem );
452   if ( aDimensionId < 0 )
453   {
454     return;
455   }
456
457   SalomeApp_Application* anApp = myGeomGUI->getApp();
458   if ( !anApp )
459   {
460     return;
461   }
462
463   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
464   if ( !aStudy )
465   {
466     return;
467   }
468
469   // get property data to change
470   GEOMGUI_DimensionProperty aProp =
471     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
472                                myEditObject->GetStudyEntry(),
473                                GEOM::propertyName( GEOM::Dimensions ),
474                                QVariant() )
475                                .value<GEOMGUI_DimensionProperty>();
476
477   // change property data
478   bool isAnythingChanged = false;
479
480   QString aName = theItem->text( 0 );
481   if ( aProp.GetName( aDimensionId ) != aName )
482   {
483     isAnythingChanged = true;
484     aProp.SetName( aDimensionId, aName );
485   }
486
487   bool isVisible = theItem->checkState( 0 ) == Qt::Checked;
488   if ( aProp.IsVisible( aDimensionId ) != isVisible )
489   {
490     isAnythingChanged = true;
491     aProp.SetVisible( aDimensionId, isVisible );
492   }
493
494   // store property data
495   if ( !isAnythingChanged )
496   {
497     return;
498   }
499
500   // store modified property data
501   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
502                              myEditObject->GetStudyEntry(),
503                              GEOM::propertyName( GEOM::Dimensions ),
504                              aProp );
505
506   RedisplayObject();
507 }
508
509 //=================================================================================
510 // function : OnSelectItem
511 // purpose  :
512 //=================================================================================
513 void MeasureGUI_ManageDimensionsDlg::OnSelectItem()
514 {
515   if ( !myOperatedViewer )
516   {
517     return;
518   }
519
520   QTreeWidgetItem* aSelectedItem = myDimensionView->TreeWidget->currentItem();
521
522   SelectInViewer( myOperatedViewer, IdFromItem( aSelectedItem ) );
523 }
524
525 //=================================================================================
526 // function : OnShowAll
527 // purpose  :
528 //=================================================================================
529 void MeasureGUI_ManageDimensionsDlg::OnShowAll()
530 {
531   // read propety data
532   SalomeApp_Application* anApp = myGeomGUI->getApp();
533   if ( !anApp )
534   {
535     return;
536   }
537
538   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
539   if ( !aStudy )
540   {
541     return;
542   }
543
544   // get property data to change
545   GEOMGUI_DimensionProperty aProp =
546     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
547                                myEditObject->GetStudyEntry(),
548                                GEOM::propertyName( GEOM::Dimensions ),
549                                QVariant() )
550                                .value<GEOMGUI_DimensionProperty>();
551
552   QTreeWidget* aDimensionList = myDimensionView->TreeWidget;
553
554   bool isBlocked = aDimensionList->blockSignals( true );
555
556   for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
557   {
558     aProp.SetVisible( anIt, true );
559   }
560
561   // store modified property data
562   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
563                              myEditObject->GetStudyEntry(),
564                              GEOM::propertyName( GEOM::Dimensions ),
565                              aProp );
566
567   PopulateList();
568
569   RedisplayObject();
570
571   aDimensionList->blockSignals( isBlocked );
572 }
573
574 //=================================================================================
575 // function : OnHideAll
576 // purpose  :
577 //=================================================================================
578 void MeasureGUI_ManageDimensionsDlg::OnHideAll()
579 {
580   // read propety data
581   SalomeApp_Application* anApp = myGeomGUI->getApp();
582   if ( !anApp )
583   {
584     return;
585   }
586
587   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
588   if ( !aStudy )
589   {
590     return;
591   }
592
593   // get property data to change
594   GEOMGUI_DimensionProperty aProp =
595     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
596                                myEditObject->GetStudyEntry(),
597                                GEOM::propertyName( GEOM::Dimensions ),
598                                QVariant() )
599                                .value<GEOMGUI_DimensionProperty>();
600
601   QTreeWidget* aDimensionList = myDimensionView->TreeWidget;
602
603   bool isBlocked = aDimensionList->blockSignals( true );
604
605   for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
606   {
607     aProp.SetVisible( anIt, false );
608   }
609
610   // store modified property data
611   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
612                              myEditObject->GetStudyEntry(),
613                              GEOM::propertyName( GEOM::Dimensions ),
614                              aProp );
615
616   PopulateList();
617
618   RedisplayObject();
619
620   aDimensionList->blockSignals( isBlocked );
621 }
622
623 //=================================================================================
624 // function : OnInteractionFinished
625 // purpose  :
626 //=================================================================================
627 void MeasureGUI_ManageDimensionsDlg::OnInteractionFinished( Handle(AIS_InteractiveObject) theIO )
628 {
629   // update property data
630   SalomeApp_Application* anApp = myGeomGUI->getApp();
631   if ( !anApp )
632   {
633     return;
634   }
635
636   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
637   if ( !aStudy )
638   {
639     return;
640   }
641
642   gp_Ax3 aLCS;
643   TopoDS_Shape anParentSh;
644   if ( GEOMBase::GetShape( myEditObject.get(), anParentSh ) )
645   {
646     aLCS = gp_Ax3().Transformed( anParentSh.Location().Transformation() );
647   }
648
649   int aDimensionId = IdFromPrs( theIO );
650
651   // get property data to change
652   GEOMGUI_DimensionProperty aProp =
653     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
654                                myEditObject->GetStudyEntry(),
655                                GEOM::propertyName( GEOM::Dimensions ),
656                                QVariant() )
657                                .value<GEOMGUI_DimensionProperty>();
658
659   aProp.SetRecord( aDimensionId, Handle(AIS_Dimension)::DownCast( theIO ), aLCS );
660
661   // store modified property data
662   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
663                              myEditObject->GetStudyEntry(),
664                              GEOM::propertyName( GEOM::Dimensions ),
665                              aProp );
666 }
667
668 //=================================================================================
669 // function : Suspend
670 // purpose  :
671 //=================================================================================
672 void MeasureGUI_ManageDimensionsDlg::Suspend()
673 {
674   StopSelection();
675   hide();
676 }
677
678 //=================================================================================
679 // function : Suspend
680 // purpose  :
681 //=================================================================================
682 void MeasureGUI_ManageDimensionsDlg::Resume()
683 {
684   this->show();
685   if ( !myEditObject.isNull() )
686   {
687     PopulateList();
688     StartSelection( Selection_Dimension );
689   }
690 }
691
692 //=================================================================================
693 // function : ClickOnOk
694 // purpose  : 
695 //=================================================================================
696 void MeasureGUI_ManageDimensionsDlg::ClickOnOk()
697 {
698   setIsApplyAndClose( true );
699   if ( ClickOnApply() )
700   {
701     ClickOnCancel();
702   }
703 }
704
705 //=================================================================================
706 // function : ClickOnCancel
707 // purpose  : 
708 //=================================================================================
709 void MeasureGUI_ManageDimensionsDlg::ClickOnCancel()
710 {
711   if ( !AllowedToCancelChanges() )
712   {
713     return;
714   }
715
716   GEOMBase_Skeleton::ClickOnCancel();
717 }
718
719 //=================================================================================
720 // function : ClickOnApply
721 // purpose  : 
722 //=================================================================================
723 bool MeasureGUI_ManageDimensionsDlg::ClickOnApply()
724 {
725   if ( myEditObject.isNull() )
726   {
727     return true;
728   }
729
730   SalomeApp_Application* anApp = myGeomGUI->getApp();
731   if ( !anApp )
732   {
733     return true;
734   }
735
736   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
737   if ( !aStudy )
738   {
739     return true;
740   }
741
742   mySavedPropertyState = 
743     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
744                                myEditObject->GetStudyEntry(),
745                                GEOM::propertyName( GEOM::Dimensions ),
746                                QVariant() )
747                                .value<GEOMGUI_DimensionProperty>();
748
749   mySavedPropertyState.SaveToAttribute( aStudy, myEditObject->GetStudyEntry() );
750
751   return true;
752 }
753
754 //=================================================================================
755 // function : OnFinish
756 // purpose  : 
757 //=================================================================================
758 void MeasureGUI_ManageDimensionsDlg::OnFinish()
759 {
760   if ( myEditObject.isNull() )
761   {
762     GEOMBase_Skeleton::ClickOnCancel();
763     return;
764   }
765
766   SalomeApp_Application* anApp = myGeomGUI->getApp();
767   if ( !anApp )
768   {
769     GEOMBase_Skeleton::ClickOnCancel();
770     return;
771   }
772
773   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
774   if ( !aStudy )
775   {
776     GEOMBase_Skeleton::ClickOnCancel();
777     return;
778   }
779
780   // reset preview property state
781   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
782                              myEditObject->GetStudyEntry(),
783                              GEOM::propertyName( GEOM::Dimensions ),
784                              QVariant() );
785
786   redisplay( myEditObject.get() );
787 }
788
789 //=================================================================================
790 // function : enterEvent()
791 // purpose  :
792 //=================================================================================
793 void MeasureGUI_ManageDimensionsDlg::enterEvent( QEvent* )
794 {
795   if ( !mainFrame()->GroupConstructors->isEnabled() )
796   {
797     OnActivateThisDialog();
798   }
799 }
800
801 //=================================================================================
802 // function : OnActivateThisDialog
803 // purpose  :
804 //=================================================================================
805 void MeasureGUI_ManageDimensionsDlg::OnActivateThisDialog()
806 {
807   disconnect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
808   GEOMBase_Skeleton::ActivateThisDialog();
809   connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
810
811   SelectionIntoArgument( Selection_Object );
812
813   if ( myEditObject.isNull() )
814   {
815     myObjectSelector->PushButton1->click();
816   }
817 }
818
819 //=================================================================================
820 // function : OnDeactivateThisDialog
821 // purpose  :
822 //=================================================================================
823 void MeasureGUI_ManageDimensionsDlg::OnDeactivateThisDialog()
824 {
825   if ( AllowedToSaveChanges() )
826   {
827     ClickOnApply();
828   }
829
830   if ( !myEditObject.isNull() )
831   {
832     SalomeApp_Study* aStudy = NULL;
833     SalomeApp_Application* anApp = myGeomGUI->getApp();
834     if ( anApp )
835     {
836       aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
837     }
838
839     if ( aStudy )
840     {
841       aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
842                                  myEditObject->GetStudyEntry(),
843                                  GEOM::propertyName( GEOM::Dimensions ),
844                                  QVariant() );
845     }
846
847     redisplay( myEditObject.get() );
848   }
849
850   GEOMBase_Skeleton::DeactivateActiveDialog();
851 }
852
853 //=================================================================================
854 // function : SetEditObject
855 // purpose  :
856 //=================================================================================
857 void MeasureGUI_ManageDimensionsDlg::SetEditObject( const GEOM::GeomObjPtr& theObj )
858 {
859   RestoreState();
860
861   QString aName = GEOMBase::GetName( theObj.get() );
862
863   myObjectSelector->LineEdit1->setText( aName );
864
865   myEditObject = theObj;
866
867   if ( myEditObject.isNull() )
868   {
869     myDimensionView->setEnabled( false );
870
871     return;
872   }
873
874   SalomeApp_Application* anApp = myGeomGUI->getApp();
875   if ( !anApp )
876   {
877     return;
878   }
879
880   SUIT_ViewManager* aViewMgr = anApp->activeViewManager();
881   if ( aViewMgr->getType() != SOCC_Viewer::Type() )
882   {
883     return;
884   }
885
886   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
887   if ( !aStudy )
888   {
889     return;
890   }
891
892   mySavedPropertyState.LoadFromAttribute( getStudy(), myEditObject->GetStudyEntry() );
893
894   // set property state for preview
895   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
896                              myEditObject->GetStudyEntry(),
897                              GEOM::propertyName( GEOM::Dimensions ),
898                              mySavedPropertyState );
899
900   PopulateList();
901
902   myDimensionView->setEnabled( true );
903 }
904
905 //=================================================================================
906 // function : RestoreState
907 // purpose  :
908 //=================================================================================
909 void MeasureGUI_ManageDimensionsDlg::RestoreState()
910 {
911   if ( myEditObject.isNull() )
912   {
913     return;
914   }
915
916   SalomeApp_Application* anApp = myGeomGUI->getApp();
917   if ( !anApp )
918   {
919     return;
920   }
921
922   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
923   if ( !aStudy )
924   {
925     return;
926   }
927
928   QString aEntry = myEditObject->GetStudyEntry();
929
930   // reset preview property state
931   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
932                              myEditObject->GetStudyEntry(),
933                              GEOM::propertyName( GEOM::Dimensions ),
934                              QVariant() );
935
936   RedisplayObject();
937 }
938
939 //=================================================================================
940 // function : PopulateList
941 // purpose  :
942 //=================================================================================
943 void MeasureGUI_ManageDimensionsDlg::PopulateList()
944 {
945   QTreeWidget* aListView = myDimensionView->TreeWidget;
946
947   // clear list completely if object is null
948   if ( myEditObject.isNull() )
949   {
950     aListView->clear();
951     return;
952   }
953
954   // clear only groups data if object is ok
955   QTreeWidgetItem* aDistanceGroupItem = aListView->topLevelItem( GroupItem_Distance );
956   QTreeWidgetItem* aDiameterGroupItem = aListView->topLevelItem( GroupItem_Diameter );
957   QTreeWidgetItem* anAngleGroupItem   = aListView->topLevelItem( GroupItem_Angle );
958
959   // create group items if not exist yet
960   if ( !aDistanceGroupItem || !aDiameterGroupItem || !anAngleGroupItem )
961   {
962     aDistanceGroupItem = new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( tr( "DISTANCE_ITEM" ) ) );
963     aDiameterGroupItem = new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( tr( "DIAMETER_ITEM" ) ) );
964     anAngleGroupItem   = new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( tr( "ANGLE_ITEM" ) ) );
965
966     aListView->clear();
967
968     aListView->addTopLevelItem( aDistanceGroupItem );
969     aListView->addTopLevelItem( aDiameterGroupItem );
970     aListView->addTopLevelItem( anAngleGroupItem );
971     aListView->expandAll();
972   }
973
974   qDeleteAll( aDistanceGroupItem->takeChildren() );
975   qDeleteAll( aDiameterGroupItem->takeChildren() );
976   qDeleteAll( anAngleGroupItem->takeChildren() );
977
978   // collect all groupped items
979   QList<QTreeWidgetItem*> aDistItems;
980   QList<QTreeWidgetItem*> aDiamItems;
981   QList<QTreeWidgetItem*> anAngItems;
982
983   SalomeApp_Application* anApp = myGeomGUI->getApp();
984   if ( !anApp )
985   {
986     return;
987   }
988
989   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
990   if ( !aStudy )
991   {
992     return;
993   }
994
995   QString aEntry = myEditObject->GetStudyEntry();
996
997   // get property data to change
998   GEOMGUI_DimensionProperty aProp =
999     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
1000                                myEditObject->GetStudyEntry(),
1001                                GEOM::propertyName( GEOM::Dimensions ),
1002                                QVariant() )
1003                                .value<GEOMGUI_DimensionProperty>();
1004
1005   // read dimension records from property
1006   for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
1007   {
1008     QString aName  = aProp.GetName( anIt );
1009     bool isVisible = aProp.IsVisible( anIt );
1010     int aType      = aProp.GetType( anIt );
1011
1012     QTreeWidgetItem* anItem = new QTreeWidgetItem;
1013     anItem->setText( 0, aName );
1014     anItem->setCheckState( 0, isVisible ? Qt::Checked : Qt::Unchecked );
1015     anItem->setData( 0, Qt::UserRole, anIt );
1016     anItem->setFlags( Qt::ItemIsUserCheckable
1017                     | Qt::ItemIsSelectable
1018                     | Qt::ItemIsEditable
1019                     | Qt::ItemIsEnabled );
1020
1021     switch ( aType )
1022     {
1023       case GEOMGUI_DimensionProperty::DimensionType_Length   : aDistItems << anItem; break;
1024       case GEOMGUI_DimensionProperty::DimensionType_Diameter : aDiamItems << anItem; break;
1025       case GEOMGUI_DimensionProperty::DimensionType_Angle    : anAngItems << anItem; break;
1026     }
1027   }
1028
1029   aDistanceGroupItem->addChildren( aDistItems );
1030   aDiameterGroupItem->addChildren( aDiamItems );
1031   anAngleGroupItem->addChildren( anAngItems );
1032
1033   aListView->setItemHidden( aDistanceGroupItem, aDistItems.isEmpty() );
1034   aListView->setItemHidden( aDiameterGroupItem, aDiamItems.isEmpty() );
1035   aListView->setItemHidden( anAngleGroupItem,   anAngItems.isEmpty() );
1036 }
1037
1038 //=================================================================================
1039 // function : HasUnsavedChanges
1040 // purpose  :
1041 //=================================================================================
1042 bool MeasureGUI_ManageDimensionsDlg::HasUnsavedChanges()
1043 {
1044   if ( myEditObject.isNull() )
1045   {
1046     return false;
1047   }
1048
1049   SalomeApp_Application* anApp = myGeomGUI->getApp();
1050   if ( !anApp )
1051   {
1052     return false;
1053   }
1054
1055   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
1056   if ( !aStudy )
1057   {
1058     return false;
1059   }
1060
1061   GEOMGUI_DimensionProperty aCurrentState =
1062     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
1063                                myEditObject->GetStudyEntry(),
1064                                GEOM::propertyName( GEOM::Dimensions ),
1065                                QVariant() )
1066                                .value<GEOMGUI_DimensionProperty>();
1067
1068   return aCurrentState != mySavedPropertyState;
1069 }
1070
1071 //=================================================================================
1072 // function : AllowedToCancelChanges
1073 // purpose  :
1074 //=================================================================================
1075 bool MeasureGUI_ManageDimensionsDlg::AllowedToCancelChanges()
1076 {
1077   if ( !HasUnsavedChanges() )
1078   {
1079     return true;
1080   }
1081
1082   int aResponse = SUIT_MessageBox::warning( this,
1083                                             tr( "WRN_TITLE_UNSAVED" ),
1084                                             tr( "WRN_MSG_CHANGES_LOST" ),
1085                                             QMessageBox::Ok,
1086                                             QMessageBox::Cancel );
1087
1088   return aResponse == QMessageBox::Ok;
1089 }
1090
1091 //=================================================================================
1092 // function : AllowedToSaveChanges
1093 // purpose  :
1094 //=================================================================================
1095 bool MeasureGUI_ManageDimensionsDlg::AllowedToSaveChanges()
1096 {
1097   if ( !HasUnsavedChanges() )
1098   {
1099     return false;
1100   }
1101
1102   int aResponse = SUIT_MessageBox::warning( this,
1103                                             tr( "WRN_TITLE_UNSAVED" ),
1104                                             tr( "WRN_MSG_CHANGES_SAVE" ),
1105                                             QMessageBox::Ok,
1106                                             QMessageBox::Cancel );
1107
1108   return aResponse == QMessageBox::Ok;
1109 }
1110
1111 //=================================================================================
1112 // function : IdFromItem
1113 // purpose  :
1114 //=================================================================================
1115 int MeasureGUI_ManageDimensionsDlg::IdFromItem( QTreeWidgetItem* theItem )
1116 {
1117   if ( !theItem )
1118   {
1119     return -1;
1120   }
1121
1122   bool isIdOK = false;
1123   const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK );
1124
1125   return isIdOK ? anId : -1;
1126 }
1127
1128 //=================================================================================
1129 // function : IdFromPrs
1130 // purpose  :
1131 //=================================================================================
1132 int MeasureGUI_ManageDimensionsDlg::IdFromPrs( const Handle(AIS_InteractiveObject)& theAIS )
1133 {
1134   Handle(SALOME_InteractiveObject) anIO = Handle(SALOME_InteractiveObject)::DownCast( theAIS->GetOwner() );
1135
1136   if ( anIO.IsNull() )
1137   {
1138     return -1;
1139   }
1140
1141   QString anIOEntry   = anIO->getEntry();
1142   QString anEditEntry = myEditObject->GetStudyEntry();
1143   if ( anIOEntry != anEditEntry )
1144   {
1145     return -1;
1146   }
1147
1148   Handle(GEOM_AISLength) aLength = Handle(GEOM_AISLength)::DownCast( theAIS );
1149   if ( !aLength.IsNull() )
1150   {
1151     return aLength->GetId();
1152   }
1153
1154   Handle(GEOM_AISDiameter) aDiameter = Handle(GEOM_AISDiameter)::DownCast( theAIS );
1155   if ( !aDiameter.IsNull() )
1156   {
1157     return aDiameter->GetId();
1158   }
1159
1160   Handle(GEOM_AISAngle) anAngle = Handle(GEOM_AISAngle)::DownCast( theAIS );
1161   if ( !anAngle.IsNull() )
1162   {
1163     return anAngle->GetId();
1164   }
1165
1166   return -1;
1167 }
1168
1169 //=================================================================================
1170 // function : SelectInList
1171 // purpose  :
1172 //=================================================================================
1173 void MeasureGUI_ManageDimensionsDlg::SelectInList( const Handle(AIS_InteractiveObject)& theIO )
1174 {
1175   SelectInList( IdFromPrs( theIO ) );
1176 }
1177
1178 //=================================================================================
1179 // function : SelectInList
1180 // purpose  :
1181 //=================================================================================
1182 void MeasureGUI_ManageDimensionsDlg::SelectInList( const int theId )
1183 {
1184   QTreeWidget* aListOfDimension = myDimensionView->TreeWidget;
1185
1186   QAbstractItemModel* aModel = aListOfDimension->model();
1187   QModelIndexList aIndexes = aModel->match( aModel->index(0, 0),
1188                                             Qt::UserRole,
1189                                             QVariant( theId ),
1190                                             -1, Qt::MatchRecursive );
1191
1192   if ( aIndexes.isEmpty() )
1193   {
1194     aListOfDimension->setCurrentIndex( QModelIndex() );
1195     return;
1196   }
1197
1198   bool isBlocked = aListOfDimension->blockSignals( true );
1199   aListOfDimension->setCurrentIndex( aIndexes.first() );
1200   aListOfDimension->blockSignals( isBlocked );
1201 }
1202
1203 //=================================================================================
1204 // function : SelectInViewer
1205 // purpose  :
1206 //=================================================================================
1207 void MeasureGUI_ManageDimensionsDlg::SelectInViewer( SOCC_Viewer* theViewer, const int theId )
1208 {
1209   Handle(AIS_InteractiveContext) anAISContext = theViewer->getAISContext();
1210   if ( anAISContext.IsNull() )
1211   {
1212     return;
1213   }
1214
1215   Standard_Boolean isLocal = anAISContext->HasOpenedContext();
1216   if ( isLocal )
1217   {
1218     anAISContext->ClearSelected( Standard_False );
1219   }
1220   else
1221   {
1222     anAISContext->ClearCurrents( Standard_False );
1223   }
1224
1225   SOCC_Prs* aPrs = dynamic_cast<SOCC_Prs*>( theViewer->CreatePrs( myEditObject->GetStudyEntry() ) );
1226
1227   AIS_ListOfInteractive aListOfIO;
1228   aPrs->GetObjects( aListOfIO );
1229
1230   AIS_ListIteratorOfListOfInteractive anIt( aListOfIO );
1231   for ( ; anIt.More(); anIt.Next() )
1232   {
1233     const Handle(AIS_InteractiveObject)& anIO = anIt.Value();
1234     if ( IdFromPrs( anIO ) != theId )
1235     {
1236       if ( isLocal )
1237       {
1238         anAISContext->Deactivate( anIO, AIS_DSM_Line );
1239         anAISContext->Deactivate( anIO, AIS_DSM_Text );
1240       }
1241       continue;
1242     }
1243
1244     if ( isLocal )
1245     {
1246       anAISContext->AddOrRemoveSelected( anIO, Standard_False );
1247       anAISContext->Activate( anIO, AIS_DSM_Line );
1248       anAISContext->Activate( anIO, AIS_DSM_Text );
1249     }
1250     else
1251     {
1252       anAISContext->AddOrRemoveCurrentObject( anIO, Standard_False );
1253     }
1254
1255     anAISContext->UpdateCurrentViewer();
1256   }
1257 }
1258
1259 //=================================================================================
1260 // function : RedisplayObject
1261 // purpose  :
1262 //=================================================================================
1263 void MeasureGUI_ManageDimensionsDlg::RedisplayObject()
1264 {
1265   redisplay( myEditObject.get() );
1266
1267   if ( !myOperatedViewer )
1268   {
1269     return;
1270   }
1271
1272   QTreeWidgetItem* aSelectedItem = myDimensionView->TreeWidget->currentItem();
1273   if ( !aSelectedItem )
1274   {
1275     return;
1276   }
1277
1278   StartSelection( myCurrentSelection );
1279
1280   SelectInViewer( myOperatedViewer, IdFromItem( aSelectedItem ) );
1281 }