1 // Copyright (C) 2007-2013 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.
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 #include "HYDROGUI_ImportImageOp.h"
25 #include "HYDROGUI_DataModel.h"
26 #include "HYDROGUI_ImportImageDlg.h"
27 #include "HYDROGUI_Module.h"
28 #include "HYDROGUI_PrsImage.h"
29 #include "HYDROGUI_Tool.h"
30 #include "HYDROGUI_UpdateFlags.h"
32 #include <HYDROData_Iterator.h>
33 #include <HYDROData_Lambert93.h>
35 #include <HYDROData_OperationsFactory.h>
37 #include <GraphicsView_ViewManager.h>
38 #include <GraphicsView_ViewPort.h>
39 #include <GraphicsView_Viewer.h>
41 #include <LightApp_Application.h>
42 #include <LightApp_UpdateFlags.h>
44 #include <STD_TabDesktop.h>
45 #include <SUIT_Desktop.h>
46 #include <QtxWorkstack.h>
47 #include <QApplication>
49 HYDROGUI_ImportImageOp::HYDROGUI_ImportImageOp( HYDROGUI_Module* theModule,
50 const bool theIsEdit )
51 : HYDROGUI_Operation( theModule ),
52 myIsEdit( theIsEdit ),
54 myActiveViewManager( 0 ),
55 myPreviewViewManager( 0 ),
56 myRefViewManager( 0 ),
59 myPointType( HYDROGUI_PrsImage::None )
61 setName( theIsEdit ? tr( "EDIT_IMPORTED_IMAGE" ) : tr( "IMPORT_IMAGE" ) );
64 HYDROGUI_ImportImageOp::~HYDROGUI_ImportImageOp()
68 void HYDROGUI_ImportImageOp::startOperation()
70 HYDROGUI_Operation::startOperation();
72 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
74 aPanel->setIsEdit( myIsEdit );
78 myEditedObject = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
79 if( !myEditedObject.IsNull() )
81 QImage anImage = myEditedObject->Image();
83 int aTransformationMode = myEditedObject->TrsfMode();
84 if( aTransformationMode == HYDROGUI_ImportImageDlg::RefImage )
85 aTransformationMode = HYDROGUI_ImportImageDlg::ManualCartesian;
86 aPanel->setTransformationMode( aTransformationMode );
88 QPoint aPointA1, aPointB1, aPointC1;
89 QPointF aPointA2, aPointB2, aPointC2;
90 QPointF aPointA3, aPointB3, aPointC3;
91 myEditedObject->TrsfPoints( aPointA1, aPointB1, aPointC1,
92 aPointA2, aPointB2, aPointC2,
93 aPointA3, aPointB3, aPointC3 );
95 onCreatePreview( anImage );
99 HYDROGUI_PrsImage::TransformationPointMap aPointMap =
100 myPreviewPrs->getTransformationPointMap();
101 if( !aPointMap.isEmpty() )
103 aPointMap[ HYDROGUI_PrsImage::PointA ].Point = aPointA1;
104 aPointMap[ HYDROGUI_PrsImage::PointB ].Point = aPointB1;
105 aPointMap[ HYDROGUI_PrsImage::PointC ].Point = aPointC1;
106 myPreviewPrs->setTransformationPointMap( aPointMap );
110 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
111 aDataMap[ HYDROGUI_PrsImage::PointA ] =
112 HYDROGUI_ImportImageDlg::TransformationData( aPointA1, aPointA2, aPointA3 );
113 aDataMap[ HYDROGUI_PrsImage::PointB ] =
114 HYDROGUI_ImportImageDlg::TransformationData( aPointB1, aPointB2, aPointB3 );
115 aDataMap[ HYDROGUI_PrsImage::PointC ] =
116 HYDROGUI_ImportImageDlg::TransformationData( aPointC1, aPointC2, aPointC3 );
117 aPanel->setTransformationDataMap( aDataMap );
121 // collect information about existing images
122 HYDROGUI_ImportImageDlg::PrsPointDataList aPrsPointDataList;
123 HYDROData_Iterator anIterator( doc(), KIND_IMAGE );
124 for( ; anIterator.More(); anIterator.Next() )
126 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast( anIterator.Current() );
127 if( !anImageObj.IsNull() )
129 if( myIsEdit && IsEqual( anImageObj, myEditedObject ) )
132 QPoint aPointA1, aPointB1, aPointC1;
133 QPointF aPointA2, aPointB2, aPointC2;
134 QPointF aPointA3, aPointB3, aPointC3;
135 anImageObj->TrsfPoints( aPointA1, aPointB1, aPointC1,
136 aPointA2, aPointB2, aPointC2,
137 aPointA3, aPointB3, aPointC3 );
139 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
140 aDataMap[ HYDROGUI_PrsImage::PointA ] =
141 HYDROGUI_ImportImageDlg::TransformationData( aPointA1, aPointA2, aPointA3 );
142 aDataMap[ HYDROGUI_PrsImage::PointB ] =
143 HYDROGUI_ImportImageDlg::TransformationData( aPointB1, aPointB2, aPointB3 );
144 aDataMap[ HYDROGUI_PrsImage::PointC ] =
145 HYDROGUI_ImportImageDlg::TransformationData( aPointC1, aPointC2, aPointC3 );
147 HYDROGUI_ImportImageDlg::PrsPointData aPrsPointData( anImageObj->GetName(), aDataMap );
148 aPrsPointDataList.append( aPrsPointData );
151 aPanel->setPrsPointDataList( aPrsPointDataList );
154 void HYDROGUI_ImportImageOp::abortOperation()
158 HYDROGUI_Operation::abortOperation();
161 void HYDROGUI_ImportImageOp::commitOperation()
165 HYDROGUI_Operation::commitOperation();
168 HYDROGUI_InputPanel* HYDROGUI_ImportImageOp::createInputPanel() const
170 HYDROGUI_InputPanel* aPanel = new HYDROGUI_ImportImageDlg( module(), getName() );
171 connect( aPanel, SIGNAL( createPreview( QImage ) ),
172 this, SLOT( onCreatePreview( QImage ) ) );
173 connect( aPanel, SIGNAL( activatePointSelection( int ) ),
174 this, SLOT( onActivatePointSelection( int ) ) );
175 connect( aPanel, SIGNAL( pointCoordChanged( bool, int, bool, int ) ),
176 this, SLOT( onPointCoordChanged( bool, int, bool, int ) ) );
177 connect( aPanel, SIGNAL( modeActivated( int ) ),
178 this, SLOT( onModeActivated( int ) ) );
179 connect( aPanel, SIGNAL( refImageActivated( const QString& ) ),
180 this, SLOT( onRefImageActivated( const QString& ) ) );
184 bool HYDROGUI_ImportImageOp::processApply( int& theUpdateFlags,
185 QString& theErrorMsg )
187 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
189 QString anImageName = aPanel->getImageName();
190 if( anImageName.isEmpty() )
193 if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anImageName ) )
195 // check that there are no other objects with the same name in the document
196 Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), anImageName );
197 if( !anObject.IsNull() )
199 theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anImageName );
204 int aTransformationMode = aPanel->getTransformationMode();
205 bool anIsRefImage = aTransformationMode == HYDROGUI_ImportImageDlg::RefImage;
207 HYDROGUI_ImportImageDlg::TransformationDataMap aMap;
208 if( !aPanel->getTransformationDataMap( aMap ) )
211 HYDROGUI_ImportImageDlg::TransformationDataMap aRefMap;
212 if( anIsRefImage && !aPanel->getTransformationDataMap( aRefMap, true ) )
215 QPoint aPointA = aMap[ HYDROGUI_PrsImage::PointA ].ImagePoint;
216 QPoint aPointB = aMap[ HYDROGUI_PrsImage::PointB ].ImagePoint;
217 QPoint aPointC = aMap[ HYDROGUI_PrsImage::PointC ].ImagePoint;
219 QPointF aLPointA = aMap[ HYDROGUI_PrsImage::PointA ].LambertPoint;
220 QPointF aLPointB = aMap[ HYDROGUI_PrsImage::PointB ].LambertPoint;
221 QPointF aLPointC = aMap[ HYDROGUI_PrsImage::PointC ].LambertPoint;
223 QPointF aCPointA = aMap[ HYDROGUI_PrsImage::PointA ].CartesianPoint;
224 QPointF aCPointB = aMap[ HYDROGUI_PrsImage::PointB ].CartesianPoint;
225 QPointF aCPointC = aMap[ HYDROGUI_PrsImage::PointC ].CartesianPoint;
227 QPoint aRefPointA, aRefPointB, aRefPointC;
230 aRefPointA = aRefMap[ HYDROGUI_PrsImage::PointA ].ImagePoint;
231 aRefPointB = aRefMap[ HYDROGUI_PrsImage::PointB ].ImagePoint;
232 aRefPointC = aRefMap[ HYDROGUI_PrsImage::PointC ].ImagePoint;
235 int xa = aPointA.x();
236 int ya = aPointA.y();
237 int xb = aPointB.x();
238 int yb = aPointB.y();
239 int xc = aPointC.x();
240 int yc = aPointC.y();
242 double xca = aCPointA.x();
243 double yca = aCPointA.y();
244 double xcb = aCPointB.x();
245 double ycb = aCPointB.y();
246 double xcc = aCPointC.x();
247 double ycc = aCPointC.y();
249 int xra = aRefPointA.x();
250 int yra = aRefPointA.y();
251 int xrb = aRefPointB.x();
252 int yrb = aRefPointB.y();
253 int xrc = aRefPointC.x();
254 int yrc = aRefPointC.y();
256 // first, check that three input points don't belong to a single line
257 if( ( yb - ya ) * ( xc - xa ) == ( yc - ya ) * ( xb - xa ) )
259 theErrorMsg = tr( "POINTS_A_B_C_BELONG_TO_SINGLE_LINE" );
263 // the same check for the reference points
265 ( ( yrb - yra ) * ( xrc - xra ) == ( yrc - yra ) * ( xrb - xra ) ) )
267 theErrorMsg = tr( "REFERENCE_POINTS_A_B_C_BELONG_TO_SINGLE_LINE" );
271 QTransform aTransform1( xa, ya, 1, xb, yb, 1, xc, yc, 1 );
272 QTransform aTransform2( xca, yca, 1, xcb, ycb, 1, xcc, ycc, 1 );
273 QTransform aTransform3( xra, yra, 1, xrb, yrb, 1, xrc, yrc, 1 );
275 bool anIsInvertible = false;
276 QTransform aTransform1Inverted = aTransform1.inverted( &anIsInvertible );
277 if( !anIsInvertible )
279 theErrorMsg = tr( "TRANSFORMATION_MATRIX_CANNOT_BE_COMPUTED" );
283 QTransform aTransform;
285 aTransform = aTransform1Inverted * aTransform3 * myRefTransform;
287 aTransform = aTransform1Inverted * aTransform2;
289 Handle(HYDROData_Image) anImageObj;
291 anImageObj = myEditedObject;
293 anImageObj = Handle(HYDROData_Image)::DownCast( doc()->CreateObject( KIND_IMAGE ) );
295 if( anImageObj.IsNull() )
298 anImageObj->SetName( anImageName );
300 anImageObj->SetImage( myImage );
301 anImageObj->SetTrsf( aTransform );
305 aCPointA = QPointF( aTransform.map( aPointA ) );
306 aCPointB = QPointF( aTransform.map( aPointB ) );
307 aCPointC = QPointF( aTransform.map( aPointC ) );
309 // compute Lambert93 points
317 double xla = 0, yla = 0, xlb = 0, ylb = 0, xlc = 0, ylc = 0;
318 HYDROData_Lambert93::toGeo( xca, yca, yla, xla );
319 HYDROData_Lambert93::toGeo( xcb, ycb, ylb, xlb );
320 HYDROData_Lambert93::toGeo( xcc, ycc, ylc, xlc );
322 aLPointA = QPointF( xla * 3600.0, yla * 3600.0 ); // convert degrees to seconds
323 aLPointB = QPointF( xlb * 3600.0, ylb * 3600.0 ); // convert degrees to seconds
324 aLPointC = QPointF( xlc * 3600.0, ylc * 3600.0 ); // convert degrees to seconds
327 anImageObj->SetTrsfMode( aTransformationMode );
328 anImageObj->SetTrsfPoints( aPointA, aPointB, aPointC,
329 aLPointA, aLPointB, aLPointC,
330 aCPointA, aCPointB, aCPointC );
334 // Set imported file name for image
335 QString aFilePath = aPanel->getFileName();
336 anImageObj->SetFilePath( aFilePath );
339 // must be done after all checks and before calling SetVisible() method below
343 module()->setObjectVisible( HYDROGUI_Tool::GetActiveGraphicsViewId( module() ), anImageObj, true );
346 anImageObj->Update();
348 theUpdateFlags = UF_Model | UF_Viewer | UF_GV_Forced | UF_OCCViewer | UF_OCC_Forced;
352 void HYDROGUI_ImportImageOp::onCreatePreview( QImage theImage )
354 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
358 if( myPreviewPrs ) // if the image is changed by choosing another file
360 myPreviewPrs->setImage( myImage );
361 myPreviewPrs->compute();
363 if( myPreviewViewManager )
365 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
367 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
369 aViewPort->onBoundingRectChanged();
377 LightApp_Application* anApp = module()->getApp();
379 myActiveViewManager = anApp->activeViewManager();
381 myPreviewPrs = new HYDROGUI_PrsImage( myIsEdit ? myEditedObject : 0 );
382 myPreviewPrs->setImage( myImage );
383 myPreviewPrs->compute();
385 myPreviewViewManager =
386 dynamic_cast<GraphicsView_ViewManager*>( anApp->createViewManager( GraphicsView_Viewer::Type() ) );
387 if( myPreviewViewManager )
389 connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
390 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
392 module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_TransformImage );
393 myPreviewViewManager->setTitle( tr( "TRANSFORM_IMAGE" ) );
394 if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
396 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
398 //aViewPort->setMousePositionEnabled( true ); //ouv: temporarily commented
400 aViewPort->addItem( myPreviewPrs );
403 myPreviewPrs->setIsTransformationPointPreview( true );
405 connect( aViewer, SIGNAL( selectionChanged( GV_SelectionChangeStatus ) ),
406 this, SLOT( onPointSelected() ) );
413 if( !myEditedObject.IsNull() )
414 anImageName = myEditedObject->GetName();
417 anImageName = HYDROGUI_Tool::GenerateObjectName( module(), "Image" );
418 aPanel->setImageName( anImageName );
421 aPanel->setImageSize( myImage.size() );
423 aPanel->initializePointSelection();
424 onPointSelected( false );
427 void HYDROGUI_ImportImageOp::onActivatePointSelection( int thePointType )
429 myPointType = thePointType;
431 myPreviewPrs->setTransformationPointType( thePointType );
432 if( myRefPreviewPrs )
433 myRefPreviewPrs->setTransformationPointType( thePointType );
436 void HYDROGUI_ImportImageOp::onPointCoordChanged( bool theIsRef,
441 if( !theIsRef && myPreviewPrs )
442 myPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
443 else if( theIsRef && myRefPreviewPrs )
444 myRefPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
447 void HYDROGUI_ImportImageOp::onModeActivated( int theMode )
449 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
451 QString aRefImageName;
452 if( theMode == HYDROGUI_ImportImageDlg::RefImage )
454 aRefImageName = aPanel->getRefImageName();
455 if( aRefImageName.isEmpty() )
456 return; // do nothing in this case to avoid visual moving of preview prs
457 onRefImageActivated( aRefImageName );
461 if( myRefViewManager )
463 closeView( myRefViewManager );
468 void HYDROGUI_ImportImageOp::onRefImageActivated( const QString& theName )
470 myRefTransform.reset();
471 GraphicsView_ViewPort* aViewPort = 0;
473 LightApp_Application* anApp = module()->getApp();
474 ///// Get a view port for the reference image preview
475 if( myRefViewManager )
477 if( GraphicsView_Viewer* aViewer = myRefViewManager->getViewer() )
479 aViewPort = aViewer->getActiveViewPort();
484 anApp = module()->getApp();
485 // Init reference image preview
487 dynamic_cast<GraphicsView_ViewManager*>( anApp->createViewManager( GraphicsView_Viewer::Type() ) );
488 if( myRefViewManager )
490 connect( myRefViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
491 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
493 module()->setViewManagerRole( myRefViewManager, HYDROGUI_Module::VMR_ReferenceImage );
494 myRefViewManager->setTitle( tr( "REFERENCE_IMAGE" ) );
495 if( GraphicsView_Viewer* aViewer = myRefViewManager->getViewer() )
497 aViewPort = aViewer->getActiveViewPort();
498 connect( aViewer, SIGNAL( selectionChanged( GV_SelectionChangeStatus ) ),
499 this, SLOT( onPointSelected() ) );
503 qApp->processEvents();
508 // Remove the old presentation of the reference image if any
509 if( myRefPreviewPrs )
511 myRefPreviewPrs->setCaption( QString() );
512 aViewPort->removeItem( myRefPreviewPrs );
514 delete myRefPreviewPrs;
518 // Create a new reference image presentation
520 Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast(
521 HYDROGUI_Tool::FindObjectByName( module(), theName, KIND_IMAGE ) );
522 if( !anImageObj.IsNull() )
524 anImage = anImageObj->Image();
525 myRefTransform = anImageObj->Trsf();
527 myRefPreviewPrs = new HYDROGUI_PrsImage( anImageObj );
528 myRefPreviewPrs->setImage( anImage );
529 myRefPreviewPrs->compute();
531 myRefPreviewPrs->setIsTransformationPointPreview( true );
532 myRefPreviewPrs->setTransformationPointType( myPointType );
534 // Add the new reference image presentation to the appropriate view
535 aViewPort->addItem( myRefPreviewPrs );
540 // Split views horizontally
541 if( anApp->desktop()->inherits( "STD_TabDesktop" ) )
543 QtxWorkstack* aWorkstack = ( (STD_TabDesktop*)anApp->desktop() )->workstack();
544 aViewPort->activateWindow();
546 aViewPort->setFocus(Qt::ActiveWindowFocusReason);
547 aWorkstack->splitHorizontal();
550 // Initialize the dialog
551 HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
552 aPanel->setImageSize( anImage.size(), true );
553 aPanel->initializePointSelection();
554 onPointSelected( true );
557 void HYDROGUI_ImportImageOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
562 void HYDROGUI_ImportImageOp::onPointSelected()
564 onPointSelected( myRefPreviewPrs && myRefPreviewPrs->isSelected() );
567 void HYDROGUI_ImportImageOp::onPointSelected( bool theIsRefImage )
569 HYDROGUI_PrsImage* aPrs = theIsRefImage ? myRefPreviewPrs : myPreviewPrs;
573 HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
575 const HYDROGUI_PrsImage::TransformationPointMap& aPointMap =
576 aPrs->getTransformationPointMap();
577 HYDROGUI_PrsImage::TransformationPointMapIterator anIter( aPointMap );
578 while( anIter.hasNext() )
580 int aPointType = anIter.next().key();
581 const HYDROGUI_PrsImage::TransformationPoint& aTransformationPoint = anIter.value();
582 const QPoint& aPoint = aTransformationPoint.Point;
584 HYDROGUI_ImportImageDlg::TransformationData aData( aPoint, QPointF(), QPointF() );
585 aDataMap[ aPointType ] = aData;
588 ( (HYDROGUI_ImportImageDlg*)inputPanel() )->setTransformationDataMap( aDataMap, true, theIsRefImage );
591 void HYDROGUI_ImportImageOp::closePreview()
593 closeView( myPreviewViewManager );
594 closeView( myRefViewManager );
596 if( myActiveViewManager )
597 HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
600 void HYDROGUI_ImportImageOp::closeView( GraphicsView_ViewManager* &aViewMgr )
602 // It's very strange, but without calling this method (it's quite safe) a crash is stably reproduced.
603 // Scenario: create any non-Graphics view, activate import op, click apply.
604 // Result: a few SIGSEGVs coming from processEvents(), then crash.
607 if( GraphicsView_Viewer* aViewer = aViewMgr->getViewer() )
609 if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
611 aViewPort->onBoundingRectChanged();
614 disconnect( aViewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
615 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
617 // Nullify appropriate presentation pointer
618 switch ( module()->getViewManagerRole( aViewMgr ) )
620 case HYDROGUI_Module::VMR_ReferenceImage:
623 case HYDROGUI_Module::VMR_TransformImage:
627 // Delete the view and all its presentations
628 module()->getApp()->removeViewManager( aViewMgr ); // aViewMgr is deleted here