Salome HOME
Copyright update 2020
[modules/geom.git] / src / MeasureGUI / MeasureGUI_ManageDimensionsDlg.cxx
1 // Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : MeasureGUI_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, this ),
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( !myGeomGUI || !myGeomGUI->getApp() || !myGeomGUI->getApp()->selectionMgr() )
249     return;
250
251   if ( myCurrentSelection == Selection_Object )
252   {
253     /* -----------------------------------------------  *
254      *               selection of object                *
255      * ------------------------------------------------ */
256
257     myObjectSelector->PushButton1->setChecked( false );
258     disconnect( myGeomGUI->getApp()->selectionMgr(),
259                 SIGNAL( currentSelectionChanged() ),
260                 this,
261                 SLOT( OnSelection() ) );
262   }
263   else if ( myCurrentSelection == Selection_Dimension && myOperatedViewer )
264   {
265     /* -----------------------------------------------  *
266      *               selection of dimension             *
267      * ------------------------------------------------ */
268
269     Handle(AIS_InteractiveContext) anAISContext = myOperatedViewer->getAISContext();
270 #if OCC_VERSION_LARGE <= 0x07030000
271     anAISContext->CloseLocalContext();
272 #else
273     anAISContext->Deactivate();
274     anAISContext->Activate(0);
275 #endif
276
277     LightApp_SelectionMgr* aSelectionMgr = myGeomGUI->getApp()->selectionMgr();
278
279     QList<SUIT_Selector*> aSelectors;
280     aSelectionMgr->selectors( aSelectors );
281     QList<SUIT_Selector*>::iterator aSelectorIt = aSelectors.begin();
282     for ( ; aSelectorIt != aSelectors.end(); ++aSelectorIt )
283     {
284       SUIT_Selector* aSelector = *aSelectorIt;
285
286       GEOMGUI_OCCSelector* aGeomSelector = dynamic_cast<GEOMGUI_OCCSelector*>( aSelector );
287       if ( !aGeomSelector )
288       {
289         continue;
290       }
291
292       aGeomSelector->setEnabled( true );
293     }
294
295     disconnect( myOperatedViewer,
296                 SIGNAL( selectionChanged() ),
297                 this,
298                 SLOT( OnSelection() ) );
299
300     myDimensionInteractor->Disable();
301
302     disconnect( myDimensionInteractor,
303                 SIGNAL( InteractionFinished( Handle_AIS_InteractiveObject ) ),
304                 this,
305                 SLOT( OnInteractionFinished( Handle_AIS_InteractiveObject ) ) );
306   }
307
308   myCurrentSelection = Selection_None;
309
310   globalSelection();
311 }
312
313 //=================================================================================
314 // function : OnSelection
315 // purpose  : 
316 //=================================================================================
317 void MeasureGUI_ManageDimensionsDlg::OnSelection()
318 {
319   SelectionIntoArgument( myCurrentSelection );
320 }
321
322 //=================================================================================
323 // function : SelectionIntoArgument
324 // purpose  : 
325 //=================================================================================
326 void MeasureGUI_ManageDimensionsDlg::SelectionIntoArgument( const Selection theSelection  )
327 {
328   if ( theSelection == Selection_Object )
329   {
330     /* -----------------------------------------------  *
331      *               selection of object                *
332      * ------------------------------------------------ */
333
334     LightApp_SelectionMgr* aSelectionMgr = myGeomGUI->getApp()->selectionMgr();
335     SALOME_ListIO aSelection;
336     aSelectionMgr->selectedObjects( aSelection );
337
338     GEOM::GeomObjPtr aSelected;
339
340     if ( aSelection.Extent() == 1 )
341     {
342       aSelected = GEOMBase::ConvertIOinGEOMObject( aSelection.First() );
343     }
344
345     SetEditObject( aSelected );
346     StartSelection( Selection_Dimension );
347   }
348   else if ( theSelection == Selection_Dimension && myOperatedViewer )
349   {
350     /* -----------------------------------------------  *
351      *               selection of dimension             *
352      * ------------------------------------------------ */
353
354     QTreeWidget* aDimensionList = myDimensionView->TreeWidget;
355
356     Handle(AIS_InteractiveContext) anAISContext = myOperatedViewer->getAISContext();
357
358     // non-single selection is prohibited
359     if ( anAISContext->NbSelected() != 1 )
360     {
361       aDimensionList->setCurrentIndex( QModelIndex() );
362       return;
363     }
364
365     anAISContext->InitSelected();
366
367     Handle(AIS_InteractiveObject) anAIS;
368 #if OCC_VERSION_LARGE <= 0x07030000
369     if ( anAISContext->HasOpenedContext() )
370     {
371       Handle(SelectMgr_EntityOwner) anAISOwner = anAISContext->SelectedOwner();
372       anAIS = Handle(AIS_InteractiveObject)::DownCast( anAISOwner->Selectable() );
373     }
374     else
375     {
376 #endif
377       anAIS = anAISContext->Current();
378 #if OCC_VERSION_LARGE <= 0x07030000
379     }
380 #endif
381
382     int aDimensionId = IdFromPrs( anAIS );
383
384     SelectInList( aDimensionId );
385
386     if ( aDimensionId >= 0 )
387     {
388       SelectInViewer( myOperatedViewer, aDimensionId );
389     }
390   }
391 }
392
393 //=================================================================================
394 // function : OnAdd
395 // purpose  :
396 //=================================================================================
397 void MeasureGUI_ManageDimensionsDlg::OnAdd()
398 {
399   if(!myCreateDialog) {
400     QWidget* aParent = qobject_cast<QWidget*>( this->parent() );
401     this->Suspend();
402     myCreateDialog = new MeasureGUI_CreateDimensionDlg( myEditObject, myGeomGUI, aParent );
403     connect( myCreateDialog, SIGNAL( finished( int ) ), this, SLOT( Resume() ) );
404     // this is necessary as the GEOMBase_Helper switches selection mode on destruction
405     connect( myCreateDialog, SIGNAL( destroyed( QObject* ) ), this, SLOT( Resume() ) );
406     connect( myCreateDialog, SIGNAL( applyClicked() ), this, SLOT( OnDimensionAdded() ) );
407     myCreateDialog->updateGeometry();
408     myCreateDialog->resize( myCreateDialog->minimumSizeHint() );
409     myCreateDialog->show();
410   } else {
411     myCreateDialog->activateWindow();
412   }
413   myObjectSelector->setEnabled(false);
414   myDimensionView->setEnabled(false);
415 }
416
417 //=================================================================================
418 // function : OnRemove
419 // purpose  :
420 //=================================================================================
421 void MeasureGUI_ManageDimensionsDlg::OnRemove()
422 {
423   int aDimensionId = IdFromItem( myDimensionView->TreeWidget->currentItem() );
424   if ( aDimensionId < 0 )
425   {
426     return;
427   }
428
429   SalomeApp_Application* anApp = myGeomGUI->getApp();
430   if ( !anApp )
431   {
432     return;
433   }
434
435   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
436   if ( !aStudy )
437   {
438     return;
439   }
440
441   // get property data to change
442   GEOMGUI_DimensionProperty aProp =
443     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
444                                myEditObject->GetStudyEntry(),
445                                GEOM::propertyName( GEOM::Dimensions ),
446                                QVariant() )
447                                .value<GEOMGUI_DimensionProperty>();
448
449   aProp.RemoveRecord( aDimensionId );
450
451   // store modified property data
452   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
453                              myEditObject->GetStudyEntry(),
454                              GEOM::propertyName( GEOM::Dimensions ),
455                              aProp );
456
457   PopulateList();
458
459   RedisplayObject();
460 }
461
462 //=================================================================================
463 // function : OnChangeItem
464 // purpose  :
465 //=================================================================================
466 void MeasureGUI_ManageDimensionsDlg::OnChangeItem( QTreeWidgetItem* theItem )
467 {
468   int aDimensionId = IdFromItem( theItem );
469   if ( aDimensionId < 0 )
470   {
471     return;
472   }
473
474   SalomeApp_Application* anApp = myGeomGUI->getApp();
475   if ( !anApp )
476   {
477     return;
478   }
479
480   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
481   if ( !aStudy )
482   {
483     return;
484   }
485
486   // get property data to change
487   GEOMGUI_DimensionProperty aProp =
488     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
489                                myEditObject->GetStudyEntry(),
490                                GEOM::propertyName( GEOM::Dimensions ),
491                                QVariant() )
492                                .value<GEOMGUI_DimensionProperty>();
493
494   // change property data
495   bool isAnythingChanged = false;
496
497   QString aName = theItem->text( 0 );
498   if ( aProp.GetName( aDimensionId ) != aName )
499   {
500     isAnythingChanged = true;
501     aProp.SetName( aDimensionId, aName );
502   }
503
504   bool isVisible = theItem->checkState( 0 ) == Qt::Checked;
505   if ( aProp.IsVisible( aDimensionId ) != isVisible )
506   {
507     isAnythingChanged = true;
508     aProp.SetVisible( aDimensionId, isVisible );
509   }
510
511   // store property data
512   if ( !isAnythingChanged )
513   {
514     return;
515   }
516
517   // store modified property data
518   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
519                              myEditObject->GetStudyEntry(),
520                              GEOM::propertyName( GEOM::Dimensions ),
521                              aProp );
522
523   RedisplayObject();
524 }
525
526 //=================================================================================
527 // function : OnSelectItem
528 // purpose  :
529 //=================================================================================
530 void MeasureGUI_ManageDimensionsDlg::OnSelectItem()
531 {
532   if ( !myOperatedViewer )
533   {
534     return;
535   }
536
537   QTreeWidgetItem* aSelectedItem = myDimensionView->TreeWidget->currentItem();
538
539   SelectInViewer( myOperatedViewer, IdFromItem( aSelectedItem ) );
540 }
541
542 //=================================================================================
543 // function : OnShowAll
544 // purpose  :
545 //=================================================================================
546 void MeasureGUI_ManageDimensionsDlg::OnShowAll()
547 {
548   // read property data
549   SalomeApp_Application* anApp = myGeomGUI->getApp();
550   if ( !anApp )
551   {
552     return;
553   }
554
555   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
556   if ( !aStudy )
557   {
558     return;
559   }
560
561   // get property data to change
562   GEOMGUI_DimensionProperty aProp =
563     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
564                                myEditObject->GetStudyEntry(),
565                                GEOM::propertyName( GEOM::Dimensions ),
566                                QVariant() )
567                                .value<GEOMGUI_DimensionProperty>();
568
569   QTreeWidget* aDimensionList = myDimensionView->TreeWidget;
570
571   bool isBlocked = aDimensionList->blockSignals( true );
572
573   for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
574   {
575     aProp.SetVisible( anIt, true );
576   }
577
578   // store modified property data
579   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
580                              myEditObject->GetStudyEntry(),
581                              GEOM::propertyName( GEOM::Dimensions ),
582                              aProp );
583
584   PopulateList();
585
586   RedisplayObject();
587
588   aDimensionList->blockSignals( isBlocked );
589 }
590
591 //=================================================================================
592 // function : OnHideAll
593 // purpose  :
594 //=================================================================================
595 void MeasureGUI_ManageDimensionsDlg::OnHideAll()
596 {
597   // read property data
598   SalomeApp_Application* anApp = myGeomGUI->getApp();
599   if ( !anApp )
600   {
601     return;
602   }
603
604   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
605   if ( !aStudy )
606   {
607     return;
608   }
609
610   // get property data to change
611   GEOMGUI_DimensionProperty aProp =
612     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
613                                myEditObject->GetStudyEntry(),
614                                GEOM::propertyName( GEOM::Dimensions ),
615                                QVariant() )
616                                .value<GEOMGUI_DimensionProperty>();
617
618   QTreeWidget* aDimensionList = myDimensionView->TreeWidget;
619
620   bool isBlocked = aDimensionList->blockSignals( true );
621
622   for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
623   {
624     aProp.SetVisible( anIt, false );
625   }
626
627   // store modified property data
628   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
629                              myEditObject->GetStudyEntry(),
630                              GEOM::propertyName( GEOM::Dimensions ),
631                              aProp );
632
633   PopulateList();
634
635   RedisplayObject();
636
637   aDimensionList->blockSignals( isBlocked );
638 }
639
640 //=================================================================================
641 // function : OnInteractionFinished
642 // purpose  :
643 //=================================================================================
644 void MeasureGUI_ManageDimensionsDlg::OnInteractionFinished( Handle_AIS_InteractiveObject theIO )
645 {
646   // update property data
647   SalomeApp_Application* anApp = myGeomGUI->getApp();
648   if ( !anApp )
649   {
650     return;
651   }
652
653   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
654   if ( !aStudy )
655   {
656     return;
657   }
658
659   gp_Ax3 aLCS;
660   TopoDS_Shape anParentSh;
661   if ( GEOMBase::GetShape( myEditObject.get(), anParentSh ) )
662   {
663     aLCS = gp_Ax3().Transformed( anParentSh.Location().Transformation() );
664   }
665
666   int aDimensionId = IdFromPrs( theIO );
667
668   // get property data to change
669   GEOMGUI_DimensionProperty aProp =
670     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
671                                myEditObject->GetStudyEntry(),
672                                GEOM::propertyName( GEOM::Dimensions ),
673                                QVariant() )
674                                .value<GEOMGUI_DimensionProperty>();
675
676   aProp.SetRecord( aDimensionId, Handle(AIS_Dimension)::DownCast( theIO ), aLCS );
677
678   // store modified property data
679   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
680                              myEditObject->GetStudyEntry(),
681                              GEOM::propertyName( GEOM::Dimensions ),
682                              aProp );
683 }
684
685 //=================================================================================
686 // function : Suspend
687 // purpose  :
688 //=================================================================================
689 void MeasureGUI_ManageDimensionsDlg::Suspend()
690 {
691   StopSelection();
692 }
693
694 //=================================================================================
695 // function : Suspend
696 // purpose  :
697 //=================================================================================
698 void MeasureGUI_ManageDimensionsDlg::Resume()
699 {
700   if(myCreateDialog){
701     myCreateDialog = 0;
702     myObjectSelector->setEnabled(true);
703     myDimensionView->setEnabled(true);
704   }
705
706   if ( !myEditObject.isNull() )
707   {
708     PopulateList();
709     StartSelection( Selection_Dimension );
710   }
711 }
712
713 //=================================================================================
714 // function : Suspend
715 // purpose  :
716 //=================================================================================
717 void MeasureGUI_ManageDimensionsDlg::OnDimensionAdded() {
718   if ( !myEditObject.isNull() )
719   {
720     PopulateList();
721   }
722 }
723
724 //=================================================================================
725 // function : ClickOnOk
726 // purpose  : 
727 //=================================================================================
728 void MeasureGUI_ManageDimensionsDlg::ClickOnOk()
729 {
730   setIsApplyAndClose( true );
731   if ( ClickOnApply() )
732   {
733     ClickOnCancel();
734   }
735 }
736
737 //=================================================================================
738 // function : ClickOnCancel
739 // purpose  : 
740 //=================================================================================
741 void MeasureGUI_ManageDimensionsDlg::ClickOnCancel()
742 {
743   if ( !AllowedToCancelChanges() )
744   {
745     return;
746   }
747   
748   if( myCreateDialog ) {
749     myCreateDialog->close();
750     myCreateDialog = 0;
751   }
752   
753   GEOMBase_Skeleton::ClickOnCancel();
754 }
755
756 //=================================================================================
757 // function : ClickOnApply
758 // purpose  : 
759 //=================================================================================
760 bool MeasureGUI_ManageDimensionsDlg::ClickOnApply()
761 {
762   if ( myEditObject.isNull() )
763   {
764     return true;
765   }
766
767   SalomeApp_Application* anApp = myGeomGUI->getApp();
768   if ( !anApp )
769   {
770     return true;
771   }
772
773   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
774   if ( !aStudy )
775   {
776     return true;
777   }
778
779   mySavedPropertyState = 
780     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
781                                myEditObject->GetStudyEntry(),
782                                GEOM::propertyName( GEOM::Dimensions ),
783                                QVariant() )
784                                .value<GEOMGUI_DimensionProperty>();
785
786   mySavedPropertyState.SaveToAttribute( myEditObject->GetStudyEntry() );
787
788   myGeomGUI->emitDimensionsUpdated( QString( myEditObject->GetStudyEntry() ) );
789
790   return true;
791 }
792
793 //=================================================================================
794 // function : OnFinish
795 // purpose  : 
796 //=================================================================================
797 void MeasureGUI_ManageDimensionsDlg::OnFinish()
798 {
799   if ( myEditObject.isNull() )
800   {
801     GEOMBase_Skeleton::ClickOnCancel();
802     return;
803   }
804
805   SalomeApp_Application* anApp = myGeomGUI->getApp();
806   if ( !anApp )
807   {
808     GEOMBase_Skeleton::ClickOnCancel();
809     return;
810   }
811
812   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
813   if ( !aStudy )
814   {
815     GEOMBase_Skeleton::ClickOnCancel();
816     return;
817   }
818
819   // reset preview property state
820   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
821                              myEditObject->GetStudyEntry(),
822                              GEOM::propertyName( GEOM::Dimensions ),
823                              QVariant() );
824
825   if ( myIsNeedRedisplay ) {
826     redisplay( myEditObject.get() );
827   }
828   
829   myGeomGUI->emitDimensionsUpdated( QString( myEditObject->GetStudyEntry() ) );
830 }
831
832 //=================================================================================
833 // function : enterEvent()
834 // purpose  :
835 //=================================================================================
836 void MeasureGUI_ManageDimensionsDlg::enterEvent( QEvent* )
837 {
838   if ( !mainFrame()->GroupConstructors->isEnabled() )
839   {
840     OnActivateThisDialog();
841   }
842 }
843
844 //=================================================================================
845 // function : OnActivateThisDialog
846 // purpose  :
847 //=================================================================================
848 void MeasureGUI_ManageDimensionsDlg::OnActivateThisDialog()
849 {
850   disconnect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
851   GEOMBase_Skeleton::ActivateThisDialog();
852   connect( myGeomGUI, SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( OnDeactivateThisDialog() ) );
853
854   SelectionIntoArgument( Selection_Object );
855
856   if ( myEditObject.isNull() )
857   {
858     myObjectSelector->PushButton1->click();
859   }
860 }
861
862 //=================================================================================
863 // function : OnDeactivateThisDialog
864 // purpose  :
865 //=================================================================================
866 void MeasureGUI_ManageDimensionsDlg::OnDeactivateThisDialog()
867 {
868   if ( AllowedToSaveChanges() )
869   {
870     ClickOnApply();
871   }
872
873   if ( !myEditObject.isNull() )
874   {
875     SalomeApp_Study* aStudy = NULL;
876     SalomeApp_Application* anApp = myGeomGUI->getApp();
877     if ( anApp )
878     {
879       aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
880     }
881
882     if ( aStudy )
883     {
884       aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
885                                  myEditObject->GetStudyEntry(),
886                                  GEOM::propertyName( GEOM::Dimensions ),
887                                  QVariant() );
888     }
889
890     redisplay( myEditObject.get() );
891   }
892
893   GEOMBase_Skeleton::DeactivateActiveDialog();
894 }
895
896 //=================================================================================
897 // function : SetEditObject
898 // purpose  :
899 //=================================================================================
900 void MeasureGUI_ManageDimensionsDlg::SetEditObject( const GEOM::GeomObjPtr& theObj )
901 {
902   RestoreState();
903
904   QString aName = GEOMBase::GetName( theObj.get() );
905
906   myObjectSelector->LineEdit1->setText( aName );
907
908   myEditObject = theObj;
909
910   if ( myEditObject.isNull() )
911   {
912     myDimensionView->TreeWidget->clear();
913     myDimensionView->setEnabled( false );
914     return;
915   }
916
917   SalomeApp_Application* anApp = myGeomGUI->getApp();
918   if ( !anApp )
919   {
920     return;
921   }
922
923   SUIT_ViewManager* aViewMgr = anApp->activeViewManager();
924   if ( aViewMgr->getType() != SOCC_Viewer::Type() )
925   {
926     return;
927   }
928
929   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
930   if ( !aStudy )
931   {
932     return;
933   }
934
935   mySavedPropertyState.LoadFromAttribute( myEditObject->GetStudyEntry() );
936
937   // set property state for preview
938   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
939                              myEditObject->GetStudyEntry(),
940                              GEOM::propertyName( GEOM::Dimensions ),
941                              mySavedPropertyState );
942
943   PopulateList();
944
945   myDimensionView->setEnabled( true );
946 }
947
948 //=================================================================================
949 // function : RestoreState
950 // purpose  :
951 //=================================================================================
952 void MeasureGUI_ManageDimensionsDlg::RestoreState()
953 {
954   if ( myEditObject.isNull() )
955   {
956     return;
957   }
958
959   SalomeApp_Application* anApp = myGeomGUI->getApp();
960   if ( !anApp )
961   {
962     return;
963   }
964
965   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
966   if ( !aStudy )
967   {
968     return;
969   }
970
971   QString aEntry = myEditObject->GetStudyEntry();
972
973   // reset preview property state
974   aStudy->setObjectProperty( GEOM::sharedPropertiesId(),
975                              myEditObject->GetStudyEntry(),
976                              GEOM::propertyName( GEOM::Dimensions ),
977                              QVariant() );
978 }
979
980 //=================================================================================
981 // function : PopulateList
982 // purpose  :
983 //=================================================================================
984 void MeasureGUI_ManageDimensionsDlg::PopulateList()
985 {
986   QTreeWidget* aListView = myDimensionView->TreeWidget;
987
988   // clear list completely if object is null
989   if ( myEditObject.isNull() )
990   {
991     aListView->clear();
992     return;
993   }
994
995   // clear only groups data if object is ok
996   QTreeWidgetItem* aDistanceGroupItem = aListView->topLevelItem( GroupItem_Distance );
997   QTreeWidgetItem* aDiameterGroupItem = aListView->topLevelItem( GroupItem_Diameter );
998   QTreeWidgetItem* anAngleGroupItem   = aListView->topLevelItem( GroupItem_Angle );
999
1000   // create group items if not exist yet
1001   if ( !aDistanceGroupItem || !aDiameterGroupItem || !anAngleGroupItem )
1002   {
1003     aDistanceGroupItem = new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( tr( "DISTANCE_ITEM" ) ) );
1004     aDiameterGroupItem = new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( tr( "DIAMETER_ITEM" ) ) );
1005     anAngleGroupItem   = new QTreeWidgetItem( (QTreeWidget*)NULL, QStringList( tr( "ANGLE_ITEM" ) ) );
1006
1007     aListView->clear();
1008
1009     aListView->addTopLevelItem( aDistanceGroupItem );
1010     aListView->addTopLevelItem( aDiameterGroupItem );
1011     aListView->addTopLevelItem( anAngleGroupItem );
1012     aListView->expandAll();
1013   }
1014
1015   qDeleteAll( aDistanceGroupItem->takeChildren() );
1016   qDeleteAll( aDiameterGroupItem->takeChildren() );
1017   qDeleteAll( anAngleGroupItem->takeChildren() );
1018
1019   // collect all groupped items
1020   QList<QTreeWidgetItem*> aDistItems;
1021   QList<QTreeWidgetItem*> aDiamItems;
1022   QList<QTreeWidgetItem*> anAngItems;
1023
1024   SalomeApp_Application* anApp = myGeomGUI->getApp();
1025   if ( !anApp )
1026   {
1027     return;
1028   }
1029
1030   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
1031   if ( !aStudy )
1032   {
1033     return;
1034   }
1035
1036   QString aEntry = myEditObject->GetStudyEntry();
1037
1038   // get property data to change
1039   GEOMGUI_DimensionProperty aProp =
1040     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
1041                                myEditObject->GetStudyEntry(),
1042                                GEOM::propertyName( GEOM::Dimensions ),
1043                                QVariant() )
1044                                .value<GEOMGUI_DimensionProperty>();
1045
1046   // read dimension records from property
1047   for ( int anIt = 0; anIt < aProp.GetNumber(); ++anIt )
1048   {
1049     QString aName  = aProp.GetName( anIt );
1050     bool isVisible = aProp.IsVisible( anIt );
1051     int aType      = aProp.GetType( anIt );
1052
1053     QTreeWidgetItem* anItem = new QTreeWidgetItem;
1054     anItem->setText( 0, aName );
1055     anItem->setCheckState( 0, isVisible ? Qt::Checked : Qt::Unchecked );
1056     anItem->setData( 0, Qt::UserRole, anIt );
1057     anItem->setFlags( Qt::ItemIsUserCheckable
1058                     | Qt::ItemIsSelectable
1059                     | Qt::ItemIsEditable
1060                     | Qt::ItemIsEnabled );
1061
1062     switch ( aType )
1063     {
1064       case GEOMGUI_DimensionProperty::DimensionType_Length   : aDistItems << anItem; break;
1065       case GEOMGUI_DimensionProperty::DimensionType_Diameter : aDiamItems << anItem; break;
1066       case GEOMGUI_DimensionProperty::DimensionType_Angle    : anAngItems << anItem; break;
1067     }
1068   }
1069
1070   aDistanceGroupItem->addChildren( aDistItems );
1071   aDiameterGroupItem->addChildren( aDiamItems );
1072   anAngleGroupItem->addChildren( anAngItems );
1073
1074   aListView->setItemHidden( aDistanceGroupItem, aDistItems.isEmpty() );
1075   aListView->setItemHidden( aDiameterGroupItem, aDiamItems.isEmpty() );
1076   aListView->setItemHidden( anAngleGroupItem,   anAngItems.isEmpty() );
1077 }
1078
1079 //=================================================================================
1080 // function : HasUnsavedChanges
1081 // purpose  :
1082 //=================================================================================
1083 bool MeasureGUI_ManageDimensionsDlg::HasUnsavedChanges()
1084 {
1085   if ( myEditObject.isNull() )
1086   {
1087     return false;
1088   }
1089
1090   SalomeApp_Application* anApp = myGeomGUI->getApp();
1091   if ( !anApp )
1092   {
1093     return false;
1094   }
1095
1096   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
1097   if ( !aStudy )
1098   {
1099     return false;
1100   }
1101
1102   GEOMGUI_DimensionProperty aCurrentState =
1103     aStudy->getObjectProperty( GEOM::sharedPropertiesId(),
1104                                myEditObject->GetStudyEntry(),
1105                                GEOM::propertyName( GEOM::Dimensions ),
1106                                QVariant() )
1107                                .value<GEOMGUI_DimensionProperty>();
1108
1109   return aCurrentState != mySavedPropertyState;
1110 }
1111
1112 //=================================================================================
1113 // function : AllowedToCancelChanges
1114 // purpose  :
1115 //=================================================================================
1116 bool MeasureGUI_ManageDimensionsDlg::AllowedToCancelChanges()
1117 {
1118   if ( !HasUnsavedChanges() )
1119   {
1120     return true;
1121   }
1122
1123   int aResponse = SUIT_MessageBox::warning( this,
1124                                             tr( "WRN_TITLE_UNSAVED" ),
1125                                             tr( "WRN_MSG_CHANGES_LOST" ),
1126                                             QMessageBox::Ok,
1127                                             QMessageBox::Cancel );
1128   myIsNeedRedisplay = ( aResponse == QMessageBox::Ok );
1129   return myIsNeedRedisplay;
1130 }
1131
1132 //=================================================================================
1133 // function : AllowedToSaveChanges
1134 // purpose  :
1135 //=================================================================================
1136 bool MeasureGUI_ManageDimensionsDlg::AllowedToSaveChanges()
1137 {
1138   if ( !HasUnsavedChanges() )
1139   {
1140     return false;
1141   }
1142
1143   int aResponse = SUIT_MessageBox::warning( this,
1144                                             tr( "WRN_TITLE_UNSAVED" ),
1145                                             tr( "WRN_MSG_CHANGES_SAVE" ),
1146                                             QMessageBox::Ok,
1147                                             QMessageBox::Cancel );
1148
1149   return aResponse == QMessageBox::Ok;
1150 }
1151
1152 //=================================================================================
1153 // function : IdFromItem
1154 // purpose  :
1155 //=================================================================================
1156 int MeasureGUI_ManageDimensionsDlg::IdFromItem( QTreeWidgetItem* theItem )
1157 {
1158   if ( !theItem )
1159   {
1160     return -1;
1161   }
1162
1163   bool isIdOK = false;
1164   const int anId = theItem->data( 0, Qt::UserRole ).toInt( &isIdOK );
1165
1166   return isIdOK ? anId : -1;
1167 }
1168
1169 //=================================================================================
1170 // function : IdFromPrs
1171 // purpose  :
1172 //=================================================================================
1173 int MeasureGUI_ManageDimensionsDlg::IdFromPrs( const Handle(AIS_InteractiveObject)& theAIS )
1174 {
1175   Handle(SALOME_InteractiveObject) anIO = Handle(SALOME_InteractiveObject)::DownCast( theAIS->GetOwner() );
1176
1177   if ( anIO.IsNull() )
1178   {
1179     return -1;
1180   }
1181
1182   QString anIOEntry   = anIO->getEntry();
1183   QString anEditEntry = myEditObject->GetStudyEntry();
1184   if ( anIOEntry != anEditEntry )
1185   {
1186     return -1;
1187   }
1188
1189   Handle(GEOM_AISLength) aLength = Handle(GEOM_AISLength)::DownCast( theAIS );
1190   if ( !aLength.IsNull() )
1191   {
1192     return aLength->GetId();
1193   }
1194
1195   Handle(GEOM_AISDiameter) aDiameter = Handle(GEOM_AISDiameter)::DownCast( theAIS );
1196   if ( !aDiameter.IsNull() )
1197   {
1198     return aDiameter->GetId();
1199   }
1200
1201   Handle(GEOM_AISAngle) anAngle = Handle(GEOM_AISAngle)::DownCast( theAIS );
1202   if ( !anAngle.IsNull() )
1203   {
1204     return anAngle->GetId();
1205   }
1206
1207   return -1;
1208 }
1209
1210 //=================================================================================
1211 // function : SelectInList
1212 // purpose  :
1213 //=================================================================================
1214 void MeasureGUI_ManageDimensionsDlg::SelectInList( const Handle(AIS_InteractiveObject)& theIO )
1215 {
1216   SelectInList( IdFromPrs( theIO ) );
1217 }
1218
1219 //=================================================================================
1220 // function : SelectInList
1221 // purpose  :
1222 //=================================================================================
1223 void MeasureGUI_ManageDimensionsDlg::SelectInList( const int theId )
1224 {
1225   QTreeWidget* aListOfDimension = myDimensionView->TreeWidget;
1226
1227   QAbstractItemModel* aModel = aListOfDimension->model();
1228   QModelIndexList aIndexes = aModel->match( aModel->index(0, 0),
1229                                             Qt::UserRole,
1230                                             QVariant( theId ),
1231                                             -1, Qt::MatchRecursive );
1232
1233   if ( aIndexes.isEmpty() )
1234   {
1235     aListOfDimension->setCurrentIndex( QModelIndex() );
1236     return;
1237   }
1238
1239   bool isBlocked = aListOfDimension->blockSignals( true );
1240   aListOfDimension->setCurrentIndex( aIndexes.first() );
1241   aListOfDimension->blockSignals( isBlocked );
1242 }
1243
1244 //=================================================================================
1245 // function : SelectInViewer
1246 // purpose  :
1247 //=================================================================================
1248 void MeasureGUI_ManageDimensionsDlg::SelectInViewer( SOCC_Viewer* theViewer, const int theId )
1249 {
1250   Handle(AIS_InteractiveContext) anAISContext = theViewer->getAISContext();
1251   if ( anAISContext.IsNull() )
1252   {
1253     return;
1254   }
1255 #if OCC_VERSION_LARGE <= 0x07030000
1256   Standard_Boolean isLocal = anAISContext->HasOpenedContext();
1257   if ( isLocal )
1258   {
1259     anAISContext->ClearSelected( Standard_False );
1260   }
1261   else
1262   {
1263 #endif
1264     anAISContext->ClearCurrents( Standard_False );
1265 #if OCC_VERSION_LARGE <= 0x07030000
1266   }
1267 #endif
1268   SOCC_Prs* aPrs = dynamic_cast<SOCC_Prs*>( theViewer->CreatePrs( myEditObject->GetStudyEntry() ) );
1269
1270   AIS_ListOfInteractive aListOfIO;
1271   aPrs->GetObjects( aListOfIO );
1272
1273   AIS_ListIteratorOfListOfInteractive anIt( aListOfIO );
1274   for ( ; anIt.More(); anIt.Next() )
1275   {
1276     const Handle(AIS_InteractiveObject)& anIO = anIt.Value();
1277     if ( IdFromPrs( anIO ) != theId )
1278     {
1279 #if OCC_VERSION_LARGE <= 0x07030000
1280       if ( isLocal )
1281       {
1282 #endif
1283         anAISContext->Deactivate( anIO, AIS_DSM_Line );
1284         anAISContext->Deactivate( anIO, AIS_DSM_Text );
1285       }
1286       continue;
1287 #if OCC_VERSION_LARGE <= 0x07030000
1288     }
1289
1290     if ( isLocal )
1291     {
1292 #endif
1293       anAISContext->AddOrRemoveSelected( anIO, Standard_False );
1294       anAISContext->Activate( anIO, AIS_DSM_Line );
1295       anAISContext->Activate( anIO, AIS_DSM_Text );
1296 #if OCC_VERSION_LARGE <= 0x07030000
1297     }
1298     else
1299     {
1300 #endif
1301       anAISContext->AddOrRemoveCurrentObject( anIO, Standard_False );
1302 #if OCC_VERSION_LARGE <= 0x07030000
1303     }
1304 #endif
1305
1306     anAISContext->UpdateCurrentViewer();
1307   }
1308 }
1309
1310 //=================================================================================
1311 // function : RedisplayObject
1312 // purpose  :
1313 //=================================================================================
1314 void MeasureGUI_ManageDimensionsDlg::RedisplayObject()
1315 {
1316   redisplay( myEditObject.get() );
1317
1318   if ( !myOperatedViewer )
1319   {
1320     return;
1321   }
1322
1323   QTreeWidgetItem* aSelectedItem = myDimensionView->TreeWidget->currentItem();
1324   if ( !aSelectedItem )
1325   {
1326     return;
1327   }
1328
1329   StartSelection( myCurrentSelection );
1330
1331   SelectInViewer( myOperatedViewer, IdFromItem( aSelectedItem ) );
1332 }