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