1 // Copyright ( C ) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright ( C ) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : MeasureGUI_AnnotationDlg.cxx
25 #include "MeasureGUI.h"
26 #include "MeasureGUI_AnnotationDlg.h"
27 #include "MeasureGUI_AnnotationInteractor.h"
31 #include <GEOMBase_Skeleton.h>
32 #include <GEOM_Displayer.h>
33 #include <GeometryGUI.h>
34 #include <GEOMGUI_AnnotationMgr.h>
35 #include <GEOMGUI_TextTreeWdg.h>
38 #include <SOCC_ViewModel.h>
40 #include <SalomeApp_Application.h>
41 #include <SalomeApp_Study.h>
42 #include <SalomeApp_Tools.h>
43 #include <SalomeApp_IntSpinBox.h>
44 #include <SalomeApp_DoubleSpinBox.h>
46 #include <LightApp_SelectionMgr.h>
48 #include <OCCViewer_ViewModel.h>
49 #include <OCCViewer_ViewManager.h>
50 #include <OCCViewer_ViewWindow.h>
51 #include <OCCViewer_ViewPort3d.h>
52 #include <SVTK_ViewModel.h>
53 #include <SALOME_Prs.h>
54 #include <SALOME_ListIO.hxx>
56 #include <SUIT_Desktop.h>
57 #include <SUIT_MessageBox.h>
58 #include <SUIT_OverrideCursor.h>
59 #include <SUIT_ResourceMgr.h>
60 #include <SUIT_Session.h>
61 #include <SUIT_ViewWindow.h>
62 #include <SUIT_ViewManager.h>
65 #include <QGridLayout>
67 #include <QHeaderView>
68 #include <QInputDialog>
71 #include <QPushButton>
73 #include <QTableWidget>
74 #include <QVBoxLayout>
76 #include <AIS_InteractiveContext.hxx>
77 #include <AIS_ListOfInteractive.hxx>
78 #include <AIS_ListIteratorOfListOfInteractive.hxx>
80 #include <Bnd_Box.hxx>
81 #include <BRepAdaptor_CompCurve.hxx>
82 #include <BRepAdaptor_Curve.hxx>
83 #include <BRepAdaptor_Surface.hxx>
84 #include <BRepBndLib.hxx>
85 #include <BRep_Tool.hxx>
87 #include <SelectMgr_ViewerSelector.hxx>
91 #include <TopExp_Explorer.hxx>
92 #include <TopTools_IndexedMapOfShape.hxx>
93 #include <TColStd_IndexedMapOfInteger.hxx>
94 #include <TColStd_MapOfInteger.hxx>
95 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
97 #include <NCollection_Handle.hxx>
101 #include <SALOMEDS_wrap.hxx>
102 #include <GEOMImpl_Types.hxx>
108 //=======================================================================
109 //function : MeasureGUI_AnnotationDlg
111 //=======================================================================
113 MeasureGUI_AnnotationDlg::MeasureGUI_AnnotationDlg( GeometryGUI* theGeometryGUI, const bool theIsCreate,
114 QWidget* parent, bool modal, Qt::WindowFlags fl )
115 : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl ),
116 myIsCreation( theIsCreate ), myShapeNameModified( false )
118 myEditCurrentArgument = 0;
120 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
121 QPixmap iconSelect( resMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
123 setWindowTitle( myIsCreation ? tr( "CREATE_ANNOTATION_TITLE" ) : tr( "EDIT_ANNOTATION_TITLE" ) );
125 // Shape type button group
126 mainFrame()->GroupBoxName->hide();
127 mainFrame()->GroupConstructors->hide();
130 QGroupBox* propGroup = new QGroupBox( tr( "ANNOTATION_PROPERTIES" ), centralWidget() );
131 QGridLayout* propLayout = new QGridLayout( propGroup );
132 propLayout->setMargin( 9 );
133 propLayout->setSpacing( 6 );
135 QLabel* textLabel = new QLabel( tr( "ANNOTATION_TEXT" ), propGroup );
136 myTextEdit = new QLineEdit( propGroup );
137 propLayout->addWidget( textLabel, 0, 0 );
138 propLayout->addWidget( myTextEdit, 0, 1, 1, 2 );
141 QLabel* shapeLabel = new QLabel( tr( "ANNOTATION_SHAPE" ), propGroup );
142 myShapeSelBtn = new QPushButton( propGroup );
143 myShapeSelBtn->setIcon( iconSelect );
144 myShapeSelBtn->setEnabled( myIsCreation );
145 myShapeName = new QLineEdit( propGroup );
146 myShapeName->setReadOnly( true );
147 myShapeName->setEnabled( myIsCreation );
150 myIsScreenFixed = new QCheckBox( tr( "ANNOTATION_IS_SCREEN_FIXED" ), propGroup );
151 myIsScreenFixed->setChecked( false ); // 3D, not fixed
153 propLayout->addWidget( shapeLabel, 1, 0 );
154 propLayout->addWidget( myShapeSelBtn, 1, 1 );
155 propLayout->addWidget( myShapeName, 1, 2 );
156 propLayout->addWidget( myIsScreenFixed, 2, 0, 1, 3 );
157 propLayout->setColumnStretch( 2, 5 );
159 QLabel* shapeTypeLabel = new QLabel( tr( "ANNOTATION_SUB_SHAPE" ), propGroup );
160 mySubShapeTypeCombo = new QComboBox( propGroup );
161 mySubShapeTypeCombo->setEnabled( myIsCreation );
162 mySubShapeTypeCombo->addItem( tr( "WHOLE_SHAPE" ), TopAbs_SHAPE );
163 mySubShapeTypeCombo->addItem( tr( "GEOM_VERTEX" ), TopAbs_VERTEX );
164 mySubShapeTypeCombo->addItem( tr( "GEOM_EDGE" ), TopAbs_EDGE );
165 mySubShapeTypeCombo->addItem( tr( "GEOM_FACE" ), TopAbs_FACE );
166 mySubShapeTypeCombo->addItem( tr( "GEOM_SOLID" ), TopAbs_SOLID );
167 mySubShapeTypeCombo->setCurrentIndex( 0 ); // SHAPE
169 propLayout->addWidget( shapeTypeLabel, 3, 0 );
170 propLayout->addWidget( mySubShapeTypeCombo, 3, 1, 1, 2 );
173 mySubShapeSelBtn = new QPushButton( propGroup );
174 mySubShapeSelBtn->setIcon( iconSelect );
175 mySubShapeSelBtn->setEnabled( myIsCreation );
176 mySubShapeName = new QLineEdit( propGroup );
177 mySubShapeName->setReadOnly( true );
178 mySubShapeName->setEnabled( myIsCreation );
180 propLayout->addWidget( mySubShapeSelBtn, 4, 1 );
181 propLayout->addWidget( mySubShapeName, 4, 2 );
183 QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
184 layout->setMargin( 0 );
185 layout->setSpacing( 6 );
186 layout->addWidget( propGroup );
188 setHelpFileName( "annotation_page.html" );
190 LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
191 connect( aSelMgr, SIGNAL( currentSelectionChanged() ), this,
192 SLOT( SelectionIntoArgument() ) );
193 connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
194 connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
196 myInteractor = new MeasureGUI_AnnotationInteractor( theGeometryGUI, parent );
197 myInteractor->Enable();
199 connect( myInteractor, SIGNAL( SignalInteractionFinished( Handle_GEOM_Annotation ) ),
200 this, SLOT( onDragged( Handle_GEOM_Annotation ) ) );
205 //=======================================================================
206 //function : ~MeasureGUI_AnnotationDlg
208 //=======================================================================
210 MeasureGUI_AnnotationDlg::~MeasureGUI_AnnotationDlg() {
213 //=================================================================================
215 // purpose : fills annotation properties with default values( in create mode ) or
216 // the values of modified object
217 //=================================================================================
218 void MeasureGUI_AnnotationDlg::Init()
220 if ( myIsCreation ) {
222 // default presentation values
223 myIsPositionDefined = false;
224 myAnnotationProperties.Text = tr( "ANNOTATION_PREFIX" );
225 myAnnotationProperties.IsVisible = false;
226 myAnnotationProperties.IsScreenFixed = false;
227 myAnnotationProperties.Attach = gp_Pnt( 0, 0, 0 );
228 myAnnotationProperties.ShapeIndex = -1;
229 myAnnotationProperties.ShapeType = ( int ) TopAbs_SHAPE;
231 // update internal controls and fields following to default values
232 activateSelectionArgument( myShapeSelBtn );
234 myTextEdit->setText( myAnnotationProperties.Text );
235 myShapeNameModified = false;
236 myIsScreenFixed->setChecked( myAnnotationProperties.IsScreenFixed );
238 int aSubShapeTypeIndex = -1;
239 int aTypesCount = mySubShapeTypeCombo->count();
240 for ( int i = 0; i < aTypesCount && aSubShapeTypeIndex < 0; i++ ) {
241 int aType = mySubShapeTypeCombo->itemData( i ).toInt();
242 if ( aType == myAnnotationProperties.ShapeType )
243 aSubShapeTypeIndex = i;
245 mySubShapeTypeCombo->setCurrentIndex( aSubShapeTypeIndex );
247 mySelectionMode = ( TopAbs_ShapeEnum ) myAnnotationProperties.ShapeType;
248 SelectionIntoArgument();
249 updateSubShapeEnableState();
252 connect( myShapeSelBtn, SIGNAL( clicked() ), this,
253 SLOT( SetEditCurrentArgument() ) );
254 connect( mySubShapeSelBtn, SIGNAL( clicked() ), this,
255 SLOT( SetEditCurrentArgument() ) );
257 connect( myTextEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChange() ) );
258 connect( myIsScreenFixed, SIGNAL( clicked( bool ) ), this, SLOT( onTypeChange() ) );
259 connect( mySubShapeTypeCombo, SIGNAL( currentIndexChanged( int ) ),
260 this, SLOT( onSubShapeTypeChange() ) );
262 //SelectionIntoArgument();
266 myIsPositionDefined = true;
267 mySelectionMode = TopAbs_SHAPE;
269 GEOMGUI_TextTreeWdg* aTextTreeWdg = myGeomGUI->GetTextTreeWdg();
270 // text tree widget should be not empty
271 QMap<QString, QList<int> > anAnnotations;
272 aTextTreeWdg->getSelected( anAnnotations );
273 // there is only one annotation selected when edit is started
274 QMap<QString, QList<int> >::const_iterator anIt = anAnnotations.begin();
275 myEditAnnotationEntry = anIt.key();
276 myEditAnnotationIndex = anIt.value()[0];
278 SalomeApp_Study* aStudy = getStudy();
279 _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( myEditAnnotationEntry.toStdString() );
280 const Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations = GEOMGUI_AnnotationAttrs::FindAttributes( aSObj );
281 if ( !aShapeAnnotations.IsNull() ) {
282 aShapeAnnotations->GetProperties( myEditAnnotationIndex, myAnnotationProperties );
284 myShape = GEOM::GEOM_Object::_narrow( GeometryGUI::ClientSObjectToObject(aSObj) );
287 /// fill dialog controls
288 myTextEdit->setText( myAnnotationProperties.Text );
289 myShapeNameModified = false;
290 myIsScreenFixed->setChecked( myAnnotationProperties.IsScreenFixed );
292 int aSubShapeTypeIndex = -1;
293 int aTypesCount = mySubShapeTypeCombo->count();
294 for ( int i = 0; i < aTypesCount && aSubShapeTypeIndex < 0; i++ ) {
295 int aType = mySubShapeTypeCombo->itemData( i ).toInt();
296 if ( aType == myAnnotationProperties.ShapeType )
297 aSubShapeTypeIndex = i;
299 mySubShapeTypeCombo->setCurrentIndex( aSubShapeTypeIndex );
301 QString aShapeName = "";
302 _PTR(GenericAttribute) anAttr;
303 if ( aSObj && aSObj->FindAttribute( anAttr, "AttributeName") ) {
304 _PTR(AttributeName) aNameAttr( anAttr );
306 aShapeName = aNameAttr->Value().c_str();
308 myShapeName->setText( aShapeName );
310 QString aSubShapeName = "";
311 TopAbs_ShapeEnum aShapeType = ( TopAbs_ShapeEnum ) myAnnotationProperties.ShapeType;
312 if ( aShapeType != TopAbs_SHAPE ) {
313 aSubShapeName = QString( "%1:%2_%3" ).arg( aShapeName )
314 .arg( GEOMBase::TypeName( aShapeType ) )
315 .arg( myAnnotationProperties.ShapeIndex );
317 mySubShapeName->setText( aSubShapeName );
319 mySelectionMode = ( TopAbs_ShapeEnum ) myAnnotationProperties.ShapeType;
320 //SelectionIntoArgument();
321 updateSubShapeEnableState();
324 connect( myTextEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChange() ) );
325 connect( myIsScreenFixed, SIGNAL( clicked( bool ) ), this, SLOT( onTypeChange() ) );
327 myGeomGUI->GetAnnotationMgr()->SetPreviewStyle( myEditAnnotationEntry, myEditAnnotationIndex, true );
329 SalomeApp_Application* anApp = myGeomGUI->getApp();
332 OCCViewer_ViewManager* aVM = (OCCViewer_ViewManager*)anApp->getViewManager( OCCViewer_Viewer::Type(), false );
333 OCCViewer_Viewer* aViewer = (OCCViewer_Viewer*)aVM->getViewModel();
334 aViewer->unHighlightAll( true, true );
341 //=================================================================================
342 // function : activateSelection
343 // purpose : Activate local selection
344 //=================================================================================
345 void MeasureGUI_AnnotationDlg::activateSelection()
347 globalSelection( GEOM_ALLOBJECTS );
348 if ( !myShape->_is_nil() && mySelectionMode != TopAbs_SHAPE ) {
349 localSelection( myShape.get(), mySelectionMode );
353 //=================================================================================
354 // function : getShapeType()
356 //=================================================================================
357 TopAbs_ShapeEnum MeasureGUI_AnnotationDlg::getShapeType() const
359 return ( TopAbs_ShapeEnum ) mySubShapeTypeCombo->itemData(
360 mySubShapeTypeCombo->currentIndex() ).toInt();
363 //=================================================================================
364 // function : ClickOnOk()
366 //=================================================================================
367 void MeasureGUI_AnnotationDlg::ClickOnOk()
369 setIsApplyAndClose( true );
370 if ( ClickOnApply() )
372 setIsApplyAndClose( false );
375 //=================================================================================
376 // function : ClickOnApply()
378 //=================================================================================
379 bool MeasureGUI_AnnotationDlg::ClickOnApply()
381 if ( !isApplyAndClose() ) {
382 setIsDisableBrowsing( true );
383 setIsDisplayResult( false );
387 if ( !isValid( msg ) ) {
392 SUIT_OverrideCursor wc;
393 SUIT_Session::session()->activeApplication()->putInfo( "" );
397 if ( !execute( /*isApplyAndClose()*/ ) ) {
402 } catch ( const SALOME::SALOME_Exception& e ) {
403 SalomeApp_Tools::QtCatchCorbaException( e );
409 if ( !isApplyAndClose() ) {
410 setIsDisableBrowsing( false );
411 setIsDisplayResult( true );
414 if ( !myShape->_is_nil() ) {
415 redisplay( myShape.get() );
418 if ( myIsCreation ) {
420 if ( !isApplyAndClose() )
427 //=================================================================================
428 // function : SetEditCurrentArgument()
429 // purpose : process click on shape/sub-shape button. It stores as current edit argument
430 // the corresponded line edit, set focus in it and unpress other button if it was pressed
431 //=================================================================================
432 void MeasureGUI_AnnotationDlg::SetEditCurrentArgument()
434 QPushButton* aSelectButton = ( QPushButton* ) sender();
436 activateSelectionArgument( aSelectButton );
438 SelectionIntoArgument();
441 //=================================================================================
442 // function : activateSelectionArgument()
443 // purpose : it stores as current edit argument the corresponded line edit,
444 // sets the focus on it and unpresses other button if it was pressed
445 //=================================================================================
446 void MeasureGUI_AnnotationDlg::activateSelectionArgument
448 QPushButton* theSelectionButton ) {
449 QPushButton* anOtherButton = 0;
450 if ( theSelectionButton == myShapeSelBtn ) {
451 myEditCurrentArgument = myShapeName;
452 anOtherButton = mySubShapeSelBtn;
453 // throw down current sub-shape selection
454 TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
456 mySubShapeTypeCombo->setCurrentIndex( 0 );
457 mySubShapeName->setText( "" );
459 myAnnotationProperties.ShapeType = aShapeType;
460 myAnnotationProperties.ShapeIndex = -1;
462 mySelectionMode = aShapeType;
464 updateSubShapeEnableState();
465 } else if ( theSelectionButton == mySubShapeSelBtn ) {
466 myEditCurrentArgument = mySubShapeName;
467 anOtherButton = myShapeSelBtn;
469 myEditCurrentArgument = 0;
471 if ( myEditCurrentArgument )
472 myEditCurrentArgument->setFocus();
474 theSelectionButton->setDown( true );
475 anOtherButton->setDown( false );
478 //=================================================================================
479 // function : SelectionIntoArgument()
480 // purpose : Called when selection has changed. Sets the current selection in the
481 // annotation property and redisplays presentation
482 //=================================================================================
483 void MeasureGUI_AnnotationDlg::SelectionIntoArgument()
485 if ( myIsCreation && myEditCurrentArgument )
487 myEditCurrentArgument->setText( "" );
489 GEOM::GeomObjPtr anObj = getSelected( mySelectionMode );
491 bool hasAttachPoint = false;
492 gp_Pnt anAttachPoint( 0, 0, 0 );
493 int aSubShapeIndex = -1;
494 if ( myEditCurrentArgument == myShapeName ) { // Selection of a shape is active
495 if ( anObj->_is_nil() || mySelectionMode != TopAbs_SHAPE ) {
496 myShape = GEOM::GEOM_Object::_nil();
499 QString aName = GEOMBase::GetName( anObj.get() );
500 myEditCurrentArgument->setText( aName );
501 if ( !myShapeNameModified ) {
502 myTextEdit->setText( aName );
504 // modified state should not be changed as modification was performed not manually
505 myShapeNameModified = false;
509 bool aNullShape = myShape->_is_nil();
510 mySubShapeTypeCombo->setEnabled( !aNullShape );
511 updateSubShapeEnableState();
518 GEOMBase::GetShape( myShape.get(), aShape );
520 hasAttachPoint = getPickedPoint( anAttachPoint, aShape );
521 if ( !hasAttachPoint ) {
523 anAttachPoint = getAttachPoint( aShape, hasAttachPoint );
526 } else if ( myEditCurrentArgument == mySubShapeName ) {
527 if ( !myShape->_is_nil() ) {
529 if ( anObj->_is_nil() ) {
530 myEditCurrentArgument->setText( QString() );
534 QString aName = GEOMBase::GetName( anObj.get() );
535 myEditCurrentArgument->setText( aName );
537 TopTools_IndexedMapOfShape aMainMap;
538 TopoDS_Shape aMainShape;
539 TopoDS_Shape aSubShape;
540 GEOMBase::GetShape( myShape.get(), aMainShape );
541 GEOMBase::GetShape( anObj.get(), aSubShape );
542 TopExp::MapShapes( aMainShape, getShapeType(), aMainMap );
544 if ( aMainMap.Contains( aSubShape ) ) {
545 aSubShapeIndex = aMainMap.FindIndex( aSubShape );
548 if ( !aSubShape.IsNull() ) {
551 GEOMBase::GetShape( myShape.get(), aShape );
553 hasAttachPoint = getPickedPoint( anAttachPoint, aSubShape );
554 if ( !hasAttachPoint ) {
556 anAttachPoint = getAttachPoint( aSubShape, hasAttachPoint );
561 myAnnotationProperties.ShapeIndex = aSubShapeIndex;
565 if ( !myShape->_is_nil() ) {
568 GEOMBase::GetShape( myShape.get(), aShape );
569 gp_Ax3 aShapeLCS = gp_Ax3().Transformed( aShape.Location().Transformation() );
570 aToShapeLCS.SetTransformation( gp_Ax3(), aShapeLCS );
573 myAnnotationProperties.Attach = anAttachPoint.Transformed( aToShapeLCS );
575 if ( hasAttachPoint && !myIsPositionDefined ) {
577 gp_Pnt aPosition = getDefaultPosition( anAttachPoint );
579 myAnnotationProperties.Position = ( !myAnnotationProperties.IsScreenFixed ) ?
580 aPosition.Transformed( aToShapeLCS ) : aPosition;
582 myIsPositionDefined = true;
584 else if ( !hasAttachPoint ) {
586 myIsPositionDefined = false;
592 //=======================================================================
593 //function : closeEvent
595 //=======================================================================
596 void MeasureGUI_AnnotationDlg::closeEvent( QCloseEvent* theEv )
598 if ( myInteractor ) {
599 myInteractor->Disable();
601 GEOMBase_Skeleton::closeEvent( theEv );
604 //=======================================================================
605 //function : onTextChange
606 //purpose : change annotation text
607 //=======================================================================
608 void MeasureGUI_AnnotationDlg::onTextChange()
610 myAnnotationProperties.Text = myTextEdit->text();
611 if ( !myShapeNameModified )
612 myShapeNameModified = true;
616 //=======================================================================
617 //function : onTypeChange
618 //purpose : change annotation type: 2D or 3D
619 //=======================================================================
620 void MeasureGUI_AnnotationDlg::onTypeChange()
622 const bool isScreenFixedBefore = myAnnotationProperties.IsScreenFixed;
624 myAnnotationProperties.IsScreenFixed = myIsScreenFixed->isChecked();
626 // convert point position from screen space to 3D space
627 if ( myIsPositionDefined ) {
629 SUIT_ViewWindow* anActiveView = GEOMBase_Helper::getActiveView();
630 OCCViewer_ViewWindow* anOccView = NULL;
631 if ( anActiveView ) {
633 anOccView = qobject_cast<OCCViewer_ViewWindow*>( anActiveView );
639 GEOMBase::GetShape( myShape.get(), aShape );
640 const gp_Ax3 aShapeLCS = gp_Ax3().Transformed( aShape.Location().Transformation() );
642 gp_Trsf aToShapeLCS, aFrShapeLCS;
643 aFrShapeLCS.SetTransformation( aShapeLCS, gp_Ax3() );
644 aToShapeLCS.SetTransformation( gp_Ax3(), aShapeLCS );
646 const Handle(V3d_View) aView3d = anOccView->getViewPort()->getView();
647 const gp_Pnt aPosition = myAnnotationProperties.Position;
648 const gp_Pnt aAttach3d = myAnnotationProperties.Attach.Transformed( aFrShapeLCS );
649 if ( !isScreenFixedBefore ) {
651 gp_Pnt aPosition3d = aPosition.Transformed( aFrShapeLCS );
652 gp_Pnt aPosition2d = GEOM_Annotation::ConvertPosition2d( aPosition3d, aAttach3d, aView3d );
653 myAnnotationProperties.Position = aPosition2d;
657 gp_Pnt aPosition3d = GEOM_Annotation::ConvertPosition3d( aPosition, aAttach3d, aView3d );
658 aPosition3d = aPosition3d.Transformed( aToShapeLCS );
659 myAnnotationProperties.Position = aPosition3d;
667 //=======================================================================
668 //function : onSubShapeTypeChange
670 //=======================================================================
671 void MeasureGUI_AnnotationDlg::onSubShapeTypeChange()
673 const TopAbs_ShapeEnum aShapeType = getShapeType();
675 activateSelectionArgument( aShapeType == TopAbs_SHAPE ? myShapeSelBtn : mySubShapeSelBtn );
677 myAnnotationProperties.ShapeType = aShapeType;
679 if ( aShapeType != mySelectionMode ) {
680 mySubShapeName->setText( "" );
681 myAnnotationProperties.ShapeIndex = -1;
682 mySelectionMode = aShapeType;
685 updateSubShapeEnableState();
691 //=================================================================================
692 // function : onDragged
694 //=================================================================================
695 void MeasureGUI_AnnotationDlg::onDragged( Handle_GEOM_Annotation theAnnotation )
698 GEOMBase::GetShape( myShape.get(), aShape );
699 gp_Ax3 aShapeLCS = gp_Ax3().Transformed( aShape.Location().Transformation() );
701 aToShapeLCS.SetTransformation( gp_Ax3(), aShapeLCS );
703 if ( !myAnnotationProperties.IsScreenFixed ) {
704 myAnnotationProperties.Position = theAnnotation->GetPosition().Transformed( aToShapeLCS );
706 if ( !myIsCreation ) {
707 myGeomGUI->GetAnnotationMgr()->storeFixedPosition( myEditAnnotationEntry, 0 );
711 myAnnotationProperties.Position = theAnnotation->GetPosition();
715 #define RETURN_WITH_MSG( a, b ) \
717 theMessage += ( b ); \
721 //=================================================================================
722 // function : createOperation
724 //=================================================================================
725 GEOM::GEOM_IOperations_ptr MeasureGUI_AnnotationDlg::createOperation()
727 return getGeomEngine()->GetILocalOperations( getStudyId() );
730 //=================================================================================
731 // function : isValid()
732 // purpose : Verify validity of input data
733 //=================================================================================
734 bool MeasureGUI_AnnotationDlg::isValid( QString& theMessage )
736 SalomeApp_Study* study = getStudy();
737 RETURN_WITH_MSG( !study, tr( "GEOM_NO_STUDY" ) )
738 RETURN_WITH_MSG( study->studyDS()->GetProperties()->IsLocked(),
739 tr( "GEOM_STUDY_LOCKED" ) )
741 if ( myIsCreation ) {
742 RETURN_WITH_MSG( myShape->_is_nil(), tr( "NO_SHAPE" ) )
744 //RETURN_WITH_MSG( CORBA::is_nil( myShape ), tr( "NO_FIELD" ) )
747 if ( getShapeType() != TopAbs_SHAPE ) {
748 if ( myIsCreation ) {
749 RETURN_WITH_MSG( myAnnotationProperties.ShapeIndex < 0, tr( "NO_SUB_SHAPE" ) )
751 //RETURN_WITH_MSG( CORBA::is_nil( myShape ), tr( "NO_FIELD" ) )
755 if ( myIsCreation ) {
756 RETURN_WITH_MSG( !myIsPositionDefined, tr( "NO_POSITION" ) )
762 //=================================================================================
763 // function : execute
765 //=================================================================================
766 bool MeasureGUI_AnnotationDlg::execute()
769 if ( !isValid( anError ) )
772 SalomeApp_Study* aStudy = getStudy();
773 _PTR(SObject) aSObj = aStudy->studyDS()->FindObjectID( myShape->GetStudyEntry() );
775 Handle(GEOMGUI_AnnotationAttrs) aShapeAnnotations =
776 GEOMGUI_AnnotationAttrs::FindOrCreateAttributes( aSObj, aStudy );
778 if ( myIsCreation ) {
779 myAnnotationProperties.IsVisible = true; // initially created annotation is hidden
781 aShapeAnnotations->Append( myAnnotationProperties );
783 myGeomGUI->emitAnnotationsUpdated( QString( myShape->GetStudyEntry() ) );
785 erasePreview( true );
787 globalSelection( myGeomGUI->getLocalSelectionMode() , true );
789 myGeomGUI->GetAnnotationMgr()->Display( myShape->GetStudyEntry(), aShapeAnnotations->GetNbAnnotation()-1 );
793 aShapeAnnotations->SetProperties( myEditAnnotationIndex, myAnnotationProperties );
794 myGeomGUI->emitAnnotationsUpdated( QString( myShape->GetStudyEntry() ) );
799 //=================================================================================
800 // function : buildPrs
801 // purpose : creates annotation presentation object and corresponded SALOME presentation
802 //=================================================================================
803 SALOME_Prs* MeasureGUI_AnnotationDlg::buildPrs()
805 QString aEntry = myIsCreation ?
806 myGeomGUI->GetAnnotationMgr()->makeAnnotationEntry( myShape->GetStudyEntry(), - 1 ) :
807 myGeomGUI->GetAnnotationMgr()->makeAnnotationEntry( myEditAnnotationEntry, myEditAnnotationIndex );
809 SALOME_Prs* aPrs = myGeomGUI->GetAnnotationMgr()->CreatePresentation(
810 myAnnotationProperties, myShape.get(), 0, aEntry );
812 // set preview style for the created presentation
813 AIS_ListOfInteractive aIObjects;
814 ((SOCC_Prs*)aPrs)->GetObjects( aIObjects );
815 AIS_ListOfInteractive::Iterator aIOIt( aIObjects );
816 for ( ; aIOIt.More(); aIOIt.Next() ) {
818 Handle( GEOM_Annotation ) aPresentation = Handle( GEOM_Annotation )::DownCast( aIOIt.Value() );
819 aPresentation->SetTextColor( Quantity_NOC_VIOLET );
820 aPresentation->SetLineColor( Quantity_NOC_VIOLET );
821 aPresentation->SetDepthCulling( Standard_False );
827 //=================================================================================
828 // function : updateSubShapeEnableState
829 // purpose : creates annotation presentation object and corresponded SALOME presentation
830 //=================================================================================
831 void MeasureGUI_AnnotationDlg::updateSubShapeEnableState()
836 bool isWholeShape = getShapeType() == TopAbs_SHAPE;
837 bool aNullShape = myShape->_is_nil();
838 mySubShapeSelBtn->setEnabled( !aNullShape && !isWholeShape );
839 mySubShapeName->setEnabled( !aNullShape && !isWholeShape );
842 //=================================================================================
843 // function : redisplayPreview
844 // purpose : creates annotation presentation object and corresponded SALOME presentation
845 //=================================================================================
846 void MeasureGUI_AnnotationDlg::redisplayPreview()
848 if ( myIsCreation ) {
851 if ( !isValid( aMess ) ) {
852 erasePreview( true );
856 erasePreview( false );
859 SUIT_OverrideCursor wc;
860 getDisplayer()->SetToActivate( true );
862 if ( SALOME_Prs* aPrs = buildPrs() )
863 displayPreview( aPrs );
864 } catch ( const SALOME::SALOME_Exception& e ) {
865 SalomeApp_Tools::QtCatchCorbaException( e );
870 myGeomGUI->GetAnnotationMgr()->Redisplay( myEditAnnotationEntry, myEditAnnotationIndex,
871 myAnnotationProperties );
875 if ( myIsCreation && !myShape->_is_nil() ) {
876 anEntry = myGeomGUI->GetAnnotationMgr()->makeAnnotationEntry( myShape->GetStudyEntry(), -1 );
878 else if ( !myIsCreation ) {
879 anEntry = myGeomGUI->GetAnnotationMgr()->makeAnnotationEntry( myEditAnnotationEntry, myEditAnnotationIndex );
882 myInteractor->SetEditEntry( anEntry );
885 //=================================================================================
886 // function : getPickedPoint
887 // purpose : finds picked point in active viewer on the selected shape
888 //=================================================================================
889 bool MeasureGUI_AnnotationDlg::getPickedPoint( gp_Pnt& thePnt, const TopoDS_Shape& theShape )
891 if ( theShape.ShapeType() == TopAbs_VERTEX )
894 thePnt = getAttachPoint( theShape, isOk );
898 const SUIT_ViewWindow* anActiveView = GEOMBase_Helper::getActiveView();
902 const OCCViewer_ViewWindow* anOccView = qobject_cast<const OCCViewer_ViewWindow*>( anActiveView );
903 if ( !anOccView || !anOccView->underMouse() )
906 OCCViewer_ViewManager* aVM = ( OCCViewer_ViewManager* )anOccView->getViewManager();
907 OCCViewer_Viewer* aViewer = aVM->getOCCViewer();
909 Handle(AIS_InteractiveContext) anAISContext = aViewer->getAISContext();
910 Handle(SelectMgr_ViewerSelector) aSelector;
911 if ( anAISContext->HasOpenedContext() )
912 aSelector = anAISContext->LocalSelector();
914 aSelector = anAISContext->MainSelector();
916 if ( aSelector->NbPicked() < 1 )
919 thePnt = aSelector->PickedPoint( 1 );
923 //=================================================================================
924 // function : getAttachPoint
925 // purpose : computes default attachment point on the shape
926 //=================================================================================
927 gp_Pnt MeasureGUI_AnnotationDlg::getAttachPoint( const TopoDS_Shape& theShape, bool& theIsOk )
929 gp_Pnt aPnt( 0.0, 0.0, 0.0 );
931 if ( theShape.ShapeType() == TopAbs_COMPSOLID
932 || theShape.ShapeType() == TopAbs_SOLID
933 || theShape.ShapeType() == TopAbs_SHELL )
936 BRepBndLib::Add( theShape, aBox );
937 const gp_Pnt aMin = aBox.CornerMin();
938 const gp_Pnt aMax = aBox.CornerMax();
939 aPnt = gp_Pnt( (aMin.X() + aMax.X()) / 2.0,
940 (aMin.Y() + aMax.Y()) / 2.0,
941 (aMin.Z() + aMax.Z()) / 2.0 );
943 else if ( theShape.ShapeType() == TopAbs_FACE )
945 BRepAdaptor_Surface aFace( TopoDS::Face( theShape ) );
946 const Standard_Real aU1 = aFace.FirstUParameter();
947 const Standard_Real aU2 = aFace.LastUParameter();
948 const Standard_Real aV1 = aFace.FirstVParameter();
949 const Standard_Real aV2 = aFace.LastVParameter();
950 aPnt = aFace.Value( ( aU1 + aU2 ) / 2.0, ( aV1 + aV2 ) / 2.0 );
952 else if ( theShape.ShapeType() == TopAbs_WIRE )
954 BRepAdaptor_CompCurve aWire( TopoDS::Wire( theShape ) );
955 const Standard_Real aP1 = aWire.FirstParameter();
956 const Standard_Real aP2 = aWire.LastParameter();
957 aPnt = aWire.Value( ( aP1 + aP2 ) / 2.0 );
959 else if ( theShape.ShapeType() == TopAbs_EDGE )
961 BRepAdaptor_Curve aEdge( TopoDS::Edge( theShape ) );
962 const Standard_Real aP1 = aEdge.FirstParameter();
963 const Standard_Real aP2 = aEdge.LastParameter();
964 aPnt = aEdge.Value( ( aP1 + aP2 ) / 2.0 );
966 else if ( theShape.ShapeType() == TopAbs_VERTEX )
968 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( theShape ) );
978 //=================================================================================
979 // function : getDefaultPosition
980 // purpose : computes default position for the given attachment point
981 //=================================================================================
982 gp_Pnt MeasureGUI_AnnotationDlg::getDefaultPosition( const gp_Pnt& theAttach )
984 SUIT_ViewWindow* anActiveView = GEOMBase_Helper::getActiveView();
985 if ( !anActiveView ) {
987 return myAnnotationProperties.IsScreenFixed ? gp::Origin() : theAttach;
990 OCCViewer_ViewWindow* anOccView = qobject_cast<OCCViewer_ViewWindow*>( anActiveView );
993 return myAnnotationProperties.IsScreenFixed ? gp::Origin() : theAttach;
996 OCCViewer_ViewPort3d* aViewPort = anOccView->getViewPort();
998 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1000 const QFont aFont = aResMgr->fontValue( "Geometry", "shape_annotation_font", QFont( "Y14.5M-2009", 24 ) );
1002 const Handle(V3d_View) aView3d = aViewPort->getView();
1004 const Standard_Real aFontHeight =( aFont.pixelSize() != -1 ) ? aFont.pixelSize() : aFont.pointSize();
1006 return GEOM_Annotation::GetDefaultPosition( myAnnotationProperties.IsScreenFixed,
1007 theAttach, aFontHeight * 1.5, aView3d );