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