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