Salome HOME
[fix] Corrections for version value
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ImportImageOp.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROGUI_ImportImageOp.h"
20
21 #include "HYDROGUI_DataModel.h"
22 #include <HYDROGUI_DataObject.h>
23 #include "HYDROGUI_ImportImageDlg.h"
24 #include "HYDROGUI_Module.h"
25 #include "HYDROGUI_PrsImage.h"
26 #include "HYDROGUI_Tool2.h"
27 #include "HYDROGUI_UpdateFlags.h"
28
29 #include <HYDROData_Iterator.h>
30 #include <HYDROData_Tool.h>
31
32 #include <GraphicsView_ViewManager.h>
33 #include <GraphicsView_ViewPort.h>
34 #include <GraphicsView_Viewer.h>
35
36 #include <LightApp_Application.h>
37 #include <LightApp_UpdateFlags.h>
38
39 #include <STD_TabDesktop.h>
40 #include <SUIT_Desktop.h>
41 #include <SUIT_MessageBox.h>
42 #include <SUIT_ViewWindow.h>
43 #include <QtxWorkstack.h>
44 #include <QApplication>
45 #include <QFileInfo>
46
47 //#define _DEVDEBUG_
48 #include "HYDRO_trace.hxx"
49
50 HYDROGUI_ImportImageOp::HYDROGUI_ImportImageOp( HYDROGUI_Module* theModule,
51                                                 const bool theIsEdit )
52 : HYDROGUI_Operation( theModule ),
53   myIsEdit( theIsEdit ),
54   myEditedObject( 0 ),
55   myActiveViewManager( 0 ),
56   myPreviewViewManager( 0 ),
57   myRefViewManager( 0 ),
58   myPreviewPrs( 0 ),
59   myRefPreviewPrs( 0 ),
60   myPointType( HYDROGUI_PrsImage::None )
61 {
62   DEBTRACE("HYDROGUI_ImportImageOp");
63   setName( theIsEdit ? tr( "EDIT_IMPORTED_IMAGE" ) : tr( "IMPORT_IMAGE" ) );
64 }
65
66 HYDROGUI_ImportImageOp::~HYDROGUI_ImportImageOp()
67 {
68   DEBTRACE("~HYDROGUI_ImportImageOp");
69 }
70
71 void HYDROGUI_ImportImageOp::startOperation()
72 {
73   DEBTRACE("startOperation");
74   HYDROGUI_Operation::startOperation();
75
76   myEditedObject = 0;
77   myActiveViewManager = 0;
78   myPreviewViewManager = 0;
79   myRefViewManager = 0;
80   myPreviewPrs = 0;
81   myRefPreviewPrs = 0;
82   myPointType = HYDROGUI_PrsImage::None;
83   HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
84   aPanel->reset();
85   aPanel->setIsEdit( myIsEdit );
86
87   QString aRefImageName;
88
89   if( myIsEdit )
90   {
91     if ( isApplyAndClose() )
92       myEditedObject = Handle(HYDROData_Image)::DownCast( HYDROGUI_Tool::GetSelectedObject( module() ) );
93     if( !myEditedObject.IsNull() )
94     {
95       QImage anImage = myEditedObject->Image();
96       bool anIsByTwoPoints = myEditedObject->IsByTwoPoints();
97
98       QPoint aLocalPointA, aLocalPointB, aLocalPointC;
99       myEditedObject->GetLocalPoints( aLocalPointA, aLocalPointB, aLocalPointC );
100
101       // Create the edited image preview presentation in the viewer
102       onCreatePreview( anImage, NULL ); //TODO
103
104       // Set transformation local points A,B,C to the image preview presentation
105       setPresentationTrsfPoints( myPreviewPrs, anIsByTwoPoints, aLocalPointA, 
106         aLocalPointB, aLocalPointC );
107
108       // Build the existing image local and global points mapping 
109       // according to the current transformation mode.
110       HYDROData_Image::TransformationMode aTrsfMode = myEditedObject->GetTrsfMode();
111       QPointF aTrsfPointA, aTrsfPointB, aTrsfPointC;
112       HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
113       if ( aTrsfMode == HYDROData_Image::ReferenceImage )
114       {
115         // Compute global points using the transformation matrix of the reference image
116         Handle(HYDROData_Image) aRefImage = myEditedObject->GetTrsfReferenceImage();
117         if ( !aRefImage.IsNull() )
118         {
119           QTransform aRefTrsf = aRefImage->Trsf(); // The reference image transformation matrix
120           aTrsfPointA = aRefTrsf.map( aLocalPointA ); // Compute the global point A
121           aTrsfPointB = aRefTrsf.map( aLocalPointB ); // Compute the global point B
122           if ( !anIsByTwoPoints )
123           {
124             aTrsfPointC = aRefTrsf.map( aLocalPointC ); // Compute the global point C if used
125           }
126           // Build the local-global points map
127           // Use the reference image transformation mode for interpreting global points
128           computeTrsfData( aRefImage->GetTrsfMode(), anIsByTwoPoints, aLocalPointA, aLocalPointB, aLocalPointC,
129             aTrsfPointA, aTrsfPointB, aTrsfPointC, aDataMap );
130         }
131       }
132       else
133       {
134         // Get global points from the edited image
135         myEditedObject->GetGlobalPoints( aTrsfMode, aTrsfPointA, aTrsfPointB, aTrsfPointC );
136         // Build the local-global points map
137         computeTrsfData( aTrsfMode, anIsByTwoPoints, aLocalPointA, aLocalPointB, aLocalPointC,
138           aTrsfPointA, aTrsfPointB, aTrsfPointC, aDataMap );
139       }
140
141       // Initialize the dialog mode, local and global coordinates 
142       // except coordinates on the reference image
143       aPanel->setTransformationMode( aTrsfMode );
144       aPanel->setTransformationDataMap( aDataMap );
145       aPanel->setByTwoPoints( anIsByTwoPoints );
146
147       // Set points of the reference image
148       if ( aTrsfMode == HYDROData_Image::ReferenceImage )
149       {
150         Handle(HYDROData_Image) aRefImage;
151         myEditedObject->GetReferencePoints( aRefImage,
152                                          aTrsfPointA, aTrsfPointB, aTrsfPointC );
153         if ( !aRefImage.IsNull() )
154         {
155           aRefImageName = aRefImage->GetName();
156
157           // Create the reference image presentation in the viewer
158           onRefImageActivated( aRefImageName );
159
160           // Set transformation points A,B,C to the reference image presentation
161           setPresentationTrsfPoints( myRefPreviewPrs, anIsByTwoPoints, aTrsfPointA.toPoint(), 
162             aTrsfPointB.toPoint(), aTrsfPointC.toPoint() );
163
164           // Prepare A, B, C points on the reference image
165           HYDROGUI_ImportImageDlg::TransformationDataMap aRefDataMap;
166           aRefDataMap[ HYDROGUI_PrsImage::PointA ] = 
167             HYDROGUI_ImportImageDlg::TransformationData( aTrsfPointA.toPoint() );
168           aRefDataMap[ HYDROGUI_PrsImage::PointB ] = 
169             HYDROGUI_ImportImageDlg::TransformationData( aTrsfPointB.toPoint() );
170           if ( !anIsByTwoPoints )
171             aRefDataMap[ HYDROGUI_PrsImage::PointC ] = 
172             HYDROGUI_ImportImageDlg::TransformationData( aTrsfPointC.toPoint() );
173
174           // Initialize the dialog's A, B, C points coordinates of the reference image
175           aPanel->setTransformationDataMap( aRefDataMap, true, true );
176         }
177       }
178     }
179   }
180
181   HYDROGUI_ImportImageDlg::PrsPointDataList aPrsPointDataList;
182   getReferenceDataList( aPrsPointDataList );
183   aPanel->setPrsPointDataList( aPrsPointDataList );
184   // Select the current reference image in the dialog combobox
185   aPanel->setRefImageName( aRefImageName );
186 }
187
188 void HYDROGUI_ImportImageOp::setPresentationTrsfPoints( HYDROGUI_PrsImage* thePrs, 
189                                                         bool theIsByTwoPoints,
190                                                         const QPoint theLocalPointA, 
191                                                         const QPoint theLocalPointB, 
192                                                         const QPoint theLocalPointC )
193 {
194   DEBTRACE("setPresentationTrsfPoints");
195   // Set transformation points A,B,C to the image presentation
196   if( thePrs )
197   {
198     HYDROGUI_PrsImage::TransformationPointMap aPointMap =
199       thePrs->getTransformationPointMap();
200     if( !aPointMap.isEmpty() )
201     {
202       aPointMap[ HYDROGUI_PrsImage::PointA ].Point = theLocalPointA;
203       aPointMap[ HYDROGUI_PrsImage::PointB ].Point = theLocalPointB;
204       if ( !theIsByTwoPoints )
205         aPointMap[ HYDROGUI_PrsImage::PointC ].Point = theLocalPointC;
206
207       thePrs->setIsByTwoPoints( theIsByTwoPoints );
208       thePrs->setTransformationPointMap( aPointMap );
209     }
210   }
211 }
212
213 void HYDROGUI_ImportImageOp::getReferenceDataList(
214                         HYDROGUI_ImportImageDlg::PrsPointDataList& theList ) const
215 {
216   DEBTRACE("getReferenceDataList");
217   // Collect information about existing images and initialize the combobox 
218   // reference image selector in the dialog.
219   HYDROData_Iterator anIterator( doc(), KIND_IMAGE );
220   for( ; anIterator.More(); anIterator.Next() )
221   {
222     Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast( anIterator.Current() );
223     if( !anImageObj.IsNull() )
224     {
225       if( myIsEdit && IsEqual( anImageObj, myEditedObject ) )
226         continue;
227
228       QPoint aLocalPointA, aLocalPointB, aLocalPointC;
229       anImageObj->GetLocalPoints( aLocalPointA, aLocalPointB, aLocalPointC );
230       
231       HYDROData_Image::TransformationMode aImgTrsfMode;
232       QPointF aTrsfPointA, aTrsfPointB, aTrsfPointC;
233       anImageObj->GetGlobalPoints( aImgTrsfMode,
234                                    aTrsfPointA, aTrsfPointB, aTrsfPointC );
235
236       HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
237       computeTrsfData( aImgTrsfMode, false, aLocalPointA, aLocalPointB, aLocalPointC,
238         aTrsfPointA, aTrsfPointB, aTrsfPointC, aDataMap );
239
240       HYDROGUI_ImportImageDlg::PrsPointData aPrsPointData( anImageObj->GetName(), aDataMap );
241       theList.append( aPrsPointData );
242     }
243   }
244 }
245
246 void HYDROGUI_ImportImageOp::computeTrsfData( HYDROData_Image::TransformationMode theTrsfMode,
247                                               bool theIsByTwoPoints,
248                                               const QPoint& theLocalPointA,
249                                               const QPoint& theLocalPointB,
250                                               const QPoint& theLocalPointC,
251                                               const QPointF& theGlobalPointA,
252                                               const QPointF& theGlobalPointB,
253                                               const QPointF& theGlobalPointC,
254                                               HYDROGUI_ImportImageDlg::TransformationDataMap& theDataMap ) const
255 {
256   DEBTRACE("computeTrsfData");
257   // Build the local-global points map
258   HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
259   theDataMap[ HYDROGUI_PrsImage::PointA ] = 
260     HYDROGUI_ImportImageDlg::ComputeTrsfData( theTrsfMode, theLocalPointA, theGlobalPointA );
261   theDataMap[ HYDROGUI_PrsImage::PointB ] =
262     HYDROGUI_ImportImageDlg::ComputeTrsfData( theTrsfMode, theLocalPointB, theGlobalPointB );
263   if ( !theIsByTwoPoints )
264   {
265     theDataMap[ HYDROGUI_PrsImage::PointC ] =
266       HYDROGUI_ImportImageDlg::ComputeTrsfData( theTrsfMode, theLocalPointC, theGlobalPointC );
267   }
268 }
269
270 void HYDROGUI_ImportImageOp::abortOperation()
271 {
272   DEBTRACE("abortOperation");
273   closePreview();
274   HYDROGUI_Operation::abortOperation();
275 }
276
277 void HYDROGUI_ImportImageOp::commitOperation()
278 {
279   DEBTRACE("commitOperation");
280   if ( isApplyAndClose() )
281     closePreview();
282
283   HYDROGUI_Operation::commitOperation();
284 }
285
286 HYDROGUI_InputPanel* HYDROGUI_ImportImageOp::createInputPanel() const
287 {
288   DEBTRACE("createInputPanel");
289   HYDROGUI_InputPanel* aPanel = new HYDROGUI_ImportImageDlg( module(), getName() );
290   connect( aPanel, SIGNAL( createPreview( QImage, HYDROData_Image::ECW_FileInfo* ) ), 
291     SLOT( onCreatePreview( QImage, HYDROData_Image::ECW_FileInfo* ) ) );
292   connect( aPanel, SIGNAL( activatePointSelection( int ) ), SLOT( onActivatePointSelection( int ) ) );
293   connect( aPanel, SIGNAL( pointCoordChanged( bool, int, bool, int ) ), 
294                      SLOT( onPointCoordChanged( bool, int, bool, int ) ) );
295   connect( aPanel, SIGNAL( modeActivated( int ) ), SLOT( onModeActivated( int ) ) );
296   connect( aPanel, SIGNAL( refImageActivated( const QString& ) ),
297                      SLOT( onRefImageActivated( const QString& ) ) );
298   connect( aPanel, SIGNAL( setCIsUsed( bool ) ), SLOT( onSetCIsUsed( bool ) ) );
299   connect( aPanel, SIGNAL( filesSelected( const QStringList& ) ),
300                    SLOT( onFilesSelected( const QStringList& ) ) );
301   return aPanel;
302 }
303
304 void HYDROGUI_ImportImageOp::onSetCIsUsed( bool theCIsUsed )
305 {
306   DEBTRACE("onSetCIsUsed");
307   if ( myPreviewPrs )
308   {
309     myPreviewPrs->setIsByTwoPoints( !theCIsUsed );
310   }
311   if ( myRefPreviewPrs )
312   {
313     myRefPreviewPrs->setIsByTwoPoints( !theCIsUsed );
314   }
315 }
316
317 bool HYDROGUI_ImportImageOp::checkPoints( const QPointF& thePointA,
318                                           const QPointF& thePointB,
319                                           const QPointF& thePointC,
320                                           const bool     theIsByTwoPoints,
321                                           const QString& theLineErrMsg,
322                                           const QString& thePoinErrMsg,
323                                           QString&       theErrorMsg,
324                                           const bool     theIsToCheckInvertibles ) const
325 {
326   DEBTRACE("checkPoints");
327   double xa = thePointA.x();
328   double ya = thePointA.y();
329   double xb = thePointB.x();
330   double yb = thePointB.y();
331   double xc = thePointC.x();
332   double yc = thePointC.y();
333
334   if ( !theIsByTwoPoints )
335   {
336     // check that three input points don't belong to a single line
337     if ( ValuesEquals( ( yb - ya ) * ( xc - xa ), ( yc - ya ) * ( xb - xa ) ) )
338     {
339       theErrorMsg = theLineErrMsg;
340       return false;
341     }
342
343     if ( theIsToCheckInvertibles )
344     {
345       QTransform aTransform1( xa, ya, 1, xb, yb, 1, xc, yc, 1 );
346
347       bool anIsInvertible = false;
348       QTransform aTransform1Inverted = aTransform1.inverted( &anIsInvertible );
349       if( !anIsInvertible )
350       {
351         theErrorMsg = tr( "TRANSFORMATION_MATRIX_CANNOT_BE_COMPUTED" );
352         return false;
353       }
354     }
355   }
356   else 
357   {
358     // check that two points are not identical
359     if ( ValuesEquals( xa, xb ) && ValuesEquals( ya, yb ) )
360     {
361       theErrorMsg = thePoinErrMsg;
362       return false;
363     }
364   }
365
366   return true;
367 }
368
369 bool HYDROGUI_ImportImageOp::processApply( int& theUpdateFlags,
370                                            QString& theErrorMsg,
371                                            QStringList& theBrowseObjectsEntries )
372 {
373   DEBTRACE("processApply");
374   HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
375
376   if( !myIsEdit )
377   {
378     QString aFilePath = aPanel->getFileName();
379     if( aFilePath.isEmpty() )
380     {
381       theErrorMsg = tr( "SELECT_IMAGE_FILE" ).arg( aFilePath );
382       return false;
383     }
384   }
385
386   QString anImageName = aPanel->getImageName();
387   if( anImageName.isEmpty() )
388   {
389     theErrorMsg = tr( "SELECT_IMAGE_NAME" ).arg( anImageName );
390     return false;
391   }
392
393   if( !myIsEdit || ( !myEditedObject.IsNull() && myEditedObject->GetName() != anImageName ) )
394   {
395     // check that there are no other objects with the same name in the document
396     Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), anImageName );
397     if( !anObject.IsNull() )
398     {
399       theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anImageName );
400       return false;
401     }
402   }
403
404   HYDROData_Image::TransformationMode aTransformationMode = 
405     (HYDROData_Image::TransformationMode)aPanel->getTransformationMode();
406   
407   QPoint aPointA, aPointB, aPointC;
408   QPointF aTrsfPointA, aTrsfPointB, aTrsfPointC( INT_MIN, INT_MIN );
409   Handle(HYDROData_Image) aRefImageObj;
410
411   if ( aTransformationMode != HYDROData_Image::CartesianFromFile ) {
412     HYDROGUI_ImportImageDlg::TransformationDataMap aMap;
413     if( !aPanel->getTransformationDataMap( aMap ) )
414       return false;
415
416     bool anIsByTwoPoints = aPanel->isByTwoPoints();
417
418     aPointA = aMap[ HYDROGUI_PrsImage::PointA ].ImagePoint;
419     aPointB = aMap[ HYDROGUI_PrsImage::PointB ].ImagePoint;
420     aPointC = anIsByTwoPoints ? QPoint( INT_MIN, INT_MIN ) :
421                                 aMap[ HYDROGUI_PrsImage::PointC ].ImagePoint;
422
423     // first, we check correctness of image points
424     if ( !checkPoints( aPointA, aPointB, aPointC, anIsByTwoPoints, 
425                        tr( "POINTS_A_B_C_BELONG_TO_SINGLE_LINE" ),
426                        tr( "POINTS_A_B_ARE_IDENTICAL" ),
427                        theErrorMsg, true ) )
428       return false;
429
430     if ( aTransformationMode == HYDROData_Image::ReferenceImage )
431     {
432       QString aRefImageName = aPanel->getRefImageName();
433       if( aRefImageName.isEmpty() )
434       {
435         theErrorMsg = tr( "REFERENCE_IMAGE_IS_NOT_SELECTED" );
436         return false;
437       }
438
439       HYDROGUI_ImportImageDlg::TransformationDataMap aRefMap;
440       if( !aPanel->getTransformationDataMap( aRefMap, true ) )
441         return false;
442
443       aRefImageObj = Handle(HYDROData_Image)::DownCast(
444         HYDROGUI_Tool::FindObjectByName( module(), aRefImageName, KIND_IMAGE ) );
445       if( aRefImageObj.IsNull() ) {
446         return false;
447       }
448       else if ( !isReferenceCorrect() ) {
449         aRefImageObj->RemoveAllReferences();
450       }
451
452       aTrsfPointA = aRefMap[ HYDROGUI_PrsImage::PointA ].ImagePoint;
453       aTrsfPointB = aRefMap[ HYDROGUI_PrsImage::PointB ].ImagePoint;
454       if ( !anIsByTwoPoints )
455       aTrsfPointC = aRefMap[ HYDROGUI_PrsImage::PointC ].ImagePoint;
456
457       // the same check of correctness for the reference points
458       if ( !checkPoints( aTrsfPointA, aTrsfPointB, aTrsfPointC, anIsByTwoPoints, 
459                          tr( "REFERENCE_POINTS_A_B_C_BELONG_TO_SINGLE_LINE" ),
460                          tr( "REFERENCE_POINTS_A_B_ARE_IDENTICAL" ),
461                          theErrorMsg, false ) )
462         return false;
463     }
464     else
465     {
466       if ( aTransformationMode == HYDROData_Image::ManualGeodesic )
467       {
468         aTrsfPointA = aMap[ HYDROGUI_PrsImage::PointA ].GeodesicPoint;
469         aTrsfPointB = aMap[ HYDROGUI_PrsImage::PointB ].GeodesicPoint;
470         if ( !anIsByTwoPoints )
471           aTrsfPointC = aMap[ HYDROGUI_PrsImage::PointC ].GeodesicPoint;
472       }
473       else
474       {
475         aTrsfPointA = aMap[ HYDROGUI_PrsImage::PointA ].CartesianPoint;
476         aTrsfPointB = aMap[ HYDROGUI_PrsImage::PointB ].CartesianPoint;
477         if ( !anIsByTwoPoints )
478           aTrsfPointC = aMap[ HYDROGUI_PrsImage::PointC ].CartesianPoint;
479       }
480     }
481   }
482
483   Handle(HYDROData_Image) anImageObj;
484   if( myIsEdit )
485     anImageObj = myEditedObject;
486   else
487   {
488     anImageObj = Handle(HYDROData_Image)::DownCast( doc()->CreateObject( KIND_IMAGE ) );
489     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( anImageObj );
490     theBrowseObjectsEntries.append( anEntry );
491   }
492
493   if( anImageObj.IsNull() )
494     return false;
495
496   anImageObj->SetName( anImageName );
497   anImageObj->SetImage( myImage );
498   
499   if ( aTransformationMode == HYDROData_Image::CartesianFromFile ) {
500     QString aGeoreferencementFileName = aPanel->getGeoreferencementFileName();
501     if ( aGeoreferencementFileName.isEmpty() ) {
502       return false;
503     }
504
505     QPoint aLocalPointA( 0, 0 ),
506            aLocalPointB( anImageObj->Image().width(), 0 ), 
507            aLocalPointC( INT_MIN, INT_MIN );
508     anImageObj->SetLocalPoints( aLocalPointA, aLocalPointB, aLocalPointC, false );
509     if ( !anImageObj->SetGlobalPointsFromFile( aGeoreferencementFileName ) ) {
510       theErrorMsg = tr( "CANT_LOAD_GEOREFERENCEMENT_FILE" );
511       return false;
512     }
513   } else {
514     anImageObj->SetLocalPoints( aPointA, aPointB, aPointC, false );
515
516     if ( aTransformationMode == HYDROData_Image::ReferenceImage )
517     {
518       anImageObj->SetReferencePoints( aRefImageObj,
519                                     aTrsfPointA, aTrsfPointB, aTrsfPointC );
520     }
521     else
522     {
523       anImageObj->SetGlobalPoints( aTransformationMode,
524                                  aTrsfPointA, aTrsfPointB, aTrsfPointC );
525     }
526   }
527
528   if( !myIsEdit )
529   {
530     // Set imported file name for image
531     QString aFilePath = aPanel->getFileName();
532     anImageObj->SetFilePath( aFilePath );
533   }
534    
535   // must be done after all checks and before calling SetVisible() method below
536   if ( isApplyAndClose() )
537   {
538     //DEBTRACE("closePreview");
539     closePreview();
540   }
541
542   if( !myIsEdit )
543     module()->setObjectVisible( HYDROGUI_Tool::GetActiveGraphicsViewId( module() ), anImageObj, true );
544
545   anImageObj->Update();
546
547   theUpdateFlags = UF_Model;
548   if ( isApplyAndClose() )
549     theUpdateFlags |= UF_Viewer | UF_GV_Forced | UF_OCCViewer | UF_OCC_Forced;
550
551   if( isApplyAndClose() )
552   {
553     commitDocOperation(); // to save the modifications in the data model
554     return true;
555   }
556
557   if( SetNextFile() )
558   {
559     theErrorMsg = "";
560     module()->updateObjBrowser();
561     return false;         // and to continue the operation
562   }
563
564   /*if( myFiles.count() > 1 )
565   {
566     setIsApplyAndClose( true );
567   }*/
568   return true;
569 }
570
571 bool HYDROGUI_ImportImageOp::isReferenceCorrect() const
572 {
573   DEBTRACE("isReferenceCorrect");
574   bool isCorrect = true;
575
576   if( myIsEdit && !myEditedObject.IsNull() )
577   {
578     HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
579     Handle(HYDROData_Image) aRefImageObj = Handle(HYDROData_Image)::DownCast(
580       HYDROGUI_Tool::FindObjectByName( module(), aPanel->getRefImageName(), KIND_IMAGE ) );
581     if( !aRefImageObj.IsNull() )
582     {
583       bool isFoundEdited = false;
584       HYDROData_SequenceOfObjects aRefSeq = aRefImageObj->GetAllReferenceObjects();
585       for ( int i = 1, n = aRefSeq.Length(); i <= n && !isFoundEdited; ++i )
586       {
587         Handle(HYDROData_Entity) anObject = aRefSeq.Value( i );
588         isFoundEdited = anObject->GetName() == myEditedObject->GetName();
589       }
590       isCorrect = !isFoundEdited;
591     }
592   }
593   return isCorrect;
594 }
595
596 void HYDROGUI_ImportImageOp::apply()
597 {
598   DEBTRACE("apply");
599   HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
600
601   bool aCanApply = isReferenceCorrect();
602   if ( !aCanApply && !myEditedObject.IsNull() )
603   {
604     Handle(HYDROData_Image) aRefImageObj = Handle(HYDROData_Image)::DownCast(
605       HYDROGUI_Tool::FindObjectByName( module(), aPanel->getRefImageName(), KIND_IMAGE ) );
606     if ( !aRefImageObj.IsNull() )
607       aCanApply = SUIT_MessageBox::question( module()->getApp()->desktop(),
608                     tr( "CORRECT_INPUT_DATA" ), tr( "CONFIRM_REMOVE_REFERENCE_FROM_IMAGE" ).
609                     arg( aRefImageObj->GetName() ).arg( myEditedObject->GetName() ),
610                     QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes;
611   }
612   if ( aCanApply )
613     HYDROGUI_Operation::apply();
614   else {
615     aPanel->setRefImageName( "" );
616     onRefImageActivated( aPanel->getRefImageName() );
617   }
618 }
619
620 void HYDROGUI_ImportImageOp::onCreatePreview( QImage theImage, HYDROData_Image::ECW_FileInfo* theFileInfo )
621 {
622   DEBTRACE("onCreatePreview");
623   HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
624
625   myImage = theImage;
626
627   if( myPreviewPrs ) // if the image is changed by choosing another file
628   {
629     myPreviewPrs->setImage( myImage, true );
630     if ( sender() ) // reset the previous presentation settings
631     {
632       QString aFileName = aPanel->getFileName();
633
634       aPanel->reset();
635       aPanel->setIsEdit( myIsEdit );
636       // restore the file name
637       aPanel->setFileName( aFileName );
638       // fill the reference list
639       HYDROGUI_ImportImageDlg::PrsPointDataList aPrsPointDataList;
640       getReferenceDataList( aPrsPointDataList );
641       aPanel->setPrsPointDataList( aPrsPointDataList );
642     }
643     if( myPreviewViewManager )
644     {
645       if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
646       {
647         if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
648         {
649           DEBTRACE("myPreviewViewManager exists");
650 //          QTransform transform;
651 //          transform.scale(1.0, -1.0);
652 //          aViewPort->setTransform(transform, false);
653           aViewPort->onBoundingRectChanged();
654           aViewPort->fitAll();
655         }
656       }
657     }
658   }
659   else
660   {
661     LightApp_Application* anApp = module()->getApp();
662
663     myActiveViewManager = anApp->activeViewManager();
664
665     myPreviewPrs = new HYDROGUI_PrsImage( myIsEdit ? myEditedObject : 0 );
666     myPreviewPrs->setImage( myImage, true );
667
668     myPreviewViewManager =
669       dynamic_cast<GraphicsView_ViewManager*>( anApp->createViewManager( GraphicsView_Viewer::Type() ) );
670     if( myPreviewViewManager )
671     {
672       DEBTRACE("myPreviewViewManager created " << myPreviewViewManager);
673       connect( myPreviewViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
674                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
675
676       module()->setViewManagerRole( myPreviewViewManager, HYDROGUI_Module::VMR_TransformImage );
677       myPreviewViewManager->setTitle( tr( "TRANSFORM_IMAGE" ) );
678       if( GraphicsView_Viewer* aViewer = myPreviewViewManager->getViewer() )
679       {
680         if( GraphicsView_ViewPort* aViewPort = aViewer->getActiveViewPort() )
681         {
682           DEBTRACE("aViewPort " << aViewPort);
683           //aViewPort->setMousePositionEnabled( true ); //ouv: temporarily commented
684
685           QTransform transform;
686           transform.scale(1.0, -1.0);
687           aViewPort->setTransform(transform, false);
688           aViewPort->addItem( myPreviewPrs );
689           aViewPort->fitAll();
690           
691           if ( myEditedObject ) {
692             size_t aViewId = (size_t)aViewer;
693             module()->setObjectVisible( aViewId, myEditedObject, true );
694           }
695           
696           myPreviewPrs->setIsTransformationPointPreview( true );
697           myPreviewPrs->setTransformationPointCursorShape( module()->getPrefEditCursor().shape() );
698         }
699         connect( aViewer, SIGNAL( selectionChanged( GV_SelectionChangeStatus ) ),
700                  this, SLOT( onPointSelected() ) );
701       }
702     }
703   }
704
705   // Set the image name in the dialog
706   QString anImageName = aPanel->getImageName().simplified();
707   // If edit mode and the name was not set yet then get from the edited object
708   if( myIsEdit && anImageName.isEmpty() )
709   {
710     if( !myEditedObject.IsNull() )
711       anImageName = myEditedObject->GetName();
712   }
713   // If the name was not set then initialize it from the selected file name
714   if ( anImageName.isEmpty() )
715   {
716     anImageName = aPanel->getFileName();
717     if ( !anImageName.isEmpty() ) {
718         anImageName = QFileInfo( anImageName ).baseName();
719     }
720     // If no file name then generate a new image name
721     if ( anImageName.isEmpty() ) {
722       anImageName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_IMAGE_NAME" ) );
723     }
724   }
725   aPanel->setImageName( anImageName );
726
727   aPanel->setImageSize( myImage.size() );
728
729   if (!theFileInfo)
730     aPanel->initializePointSelection();
731   else
732      aPanel->ECW_initializePointSelection(theFileInfo);
733   onPointSelected( false );
734   onSetCIsUsed( !aPanel->isByTwoPoints() );
735 }
736
737 void HYDROGUI_ImportImageOp::onActivatePointSelection( int thePointType )
738 {
739   DEBTRACE("onActivatePointSelection");
740   myPointType = thePointType;
741   if( myPreviewPrs )
742     myPreviewPrs->setTransformationPointType( thePointType );
743   if( myRefPreviewPrs )
744     myRefPreviewPrs->setTransformationPointType( thePointType );
745 }
746
747 void HYDROGUI_ImportImageOp::onPointCoordChanged( bool theIsRef,
748                                                   int thePointType,
749                                                   bool theIsY,
750                                                   int theValue )
751 {
752   DEBTRACE("onPointCoordChanged");
753   if( !theIsRef && myPreviewPrs )
754     myPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
755   else if( theIsRef && myRefPreviewPrs )
756     myRefPreviewPrs->updateTransformationPoint( thePointType, theIsY, theValue );
757 }
758
759 void HYDROGUI_ImportImageOp::onModeActivated( int theMode )
760 {
761   DEBTRACE("onModeActivated " << theMode);
762   HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
763
764   QString aRefImageName;
765   if( theMode == HYDROData_Image::ReferenceImage )
766   {
767     aRefImageName = aPanel->getRefImageName();
768     if( aRefImageName.isEmpty() )
769       return; // do nothing in this case to avoid visual moving of preview prs
770     onRefImageActivated( aRefImageName );
771   }
772   else
773   {
774     if( myRefViewManager )
775     {
776       closeView( myRefViewManager );
777       myRefViewManager = 0;
778     }
779   }
780 }
781
782 void HYDROGUI_ImportImageOp::onRefImageActivated( const QString& theName )
783 {
784   DEBTRACE("onRefImageActivated " << theName.toStdString());
785   if( theName.isEmpty() ) {
786     if( myRefViewManager )
787       closeView( myRefViewManager );
788     myRefViewManager = 0;
789     return;
790   }
791
792   GraphicsView_ViewPort* aViewPort = 0;
793
794   LightApp_Application* anApp = module()->getApp();
795   ///// Get a view port for the reference image preview
796   if( myRefViewManager )
797   {
798     if( GraphicsView_Viewer* aViewer = myRefViewManager->getViewer() )
799     {
800       aViewPort = aViewer->getActiveViewPort();
801     }
802   }
803   else
804   {
805     anApp = module()->getApp();
806     // Init reference image preview
807     myRefViewManager =
808       dynamic_cast<GraphicsView_ViewManager*>( anApp->createViewManager( GraphicsView_Viewer::Type() ) );
809     if( myRefViewManager )
810     {
811       DEBTRACE("myRefViewManager created " << myRefViewManager);
812       connect( myRefViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
813                this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
814
815       module()->setViewManagerRole( myRefViewManager, HYDROGUI_Module::VMR_ReferenceImage );
816       myRefViewManager->setTitle( tr( "REFERENCE_IMAGE" ) );
817       if( GraphicsView_Viewer* aViewer = myRefViewManager->getViewer() )
818       {
819         aViewPort = aViewer->getActiveViewPort();
820         connect( aViewer, SIGNAL( selectionChanged( GV_SelectionChangeStatus ) ),
821                  this, SLOT( onRefPointSelected() ) );
822       }
823     }
824   }
825
826   if( !aViewPort )
827     return;
828   QTransform transform;
829   transform.scale(1.0, -1.0);
830   aViewPort->setTransform(transform, false);
831
832   size_t aViewId = (size_t)myRefViewManager->getViewer();
833
834   // Remove the old presentation of the reference image if any
835   if( myRefPreviewPrs )
836   {
837     module()->setObjectVisible( aViewId, myRefPreviewPrs->getObject(), false );
838
839     myRefPreviewPrs->setCaption( QString() );
840     aViewPort->removeItem( myRefPreviewPrs );
841
842     delete myRefPreviewPrs;
843     myRefPreviewPrs = 0;
844   }
845
846   // Create a new reference image presentation
847   QImage anImage;
848   Handle(HYDROData_Image) anImageObj = Handle(HYDROData_Image)::DownCast(
849     HYDROGUI_Tool::FindObjectByName( module(), theName, KIND_IMAGE ) );
850   HYDROGUI_ImportImageDlg* aPanel = (HYDROGUI_ImportImageDlg*)inputPanel();
851   if( !anImageObj.IsNull() )
852   {
853     anImage = anImageObj->Image();
854
855     myRefPreviewPrs = new HYDROGUI_PrsImage( anImageObj );
856     myRefPreviewPrs->setImage( anImage, true );
857
858     myRefPreviewPrs->setIsTransformationPointPreview( true );
859     myRefPreviewPrs->setTransformationPointType( myPointType );
860
861     myRefPreviewPrs->setIsByTwoPoints( aPanel->isByTwoPoints() );
862
863     myRefPreviewPrs->setTransformationPointCursorShape( module()->getPrefEditCursor().shape() );
864
865     // Add the new reference image presentation to the appropriate view
866     aViewPort->addItem( myRefPreviewPrs );
867
868     module()->setObjectVisible( aViewId, anImageObj, true );
869   }
870
871   aViewPort->fitAll();
872
873   // Split views horizontally
874   if( anApp->desktop()->inherits( "STD_TabDesktop" ) )
875   {
876     qApp->processEvents();
877     QtxWorkstack* aWorkstack = ( (STD_TabDesktop*)anApp->desktop() )->workstack();
878     aViewPort->activateWindow();
879     aViewPort->show();
880     aViewPort->setFocus(Qt::ActiveWindowFocusReason);
881     aWorkstack->splitHorizontal();
882   }
883
884   // Initialize the dialog
885   aPanel->setImageSize( anImage.size(), true );
886   aPanel->initializePointSelection();
887   onPointSelected( true );
888 }
889
890 void HYDROGUI_ImportImageOp::onLastViewClosed( SUIT_ViewManager* theViewManager )
891 {
892   DEBTRACE("onLastViewClosed");
893   closePreview();
894 }
895
896 void HYDROGUI_ImportImageOp::onPointSelected()
897 {
898   DEBTRACE("onPointSelected");
899   onPointSelected( myRefPreviewPrs && myRefPreviewPrs->isSelected() );
900 }
901
902 void HYDROGUI_ImportImageOp::onRefPointSelected()
903 {
904   DEBTRACE("onRefPointSelected");
905   onPointSelected( true );
906 }
907
908 void HYDROGUI_ImportImageOp::onPointSelected( bool theIsRefImage )
909 {
910   DEBTRACE("onPointSelected " << theIsRefImage);
911   HYDROGUI_PrsImage* aPrs = theIsRefImage ? myRefPreviewPrs : myPreviewPrs;
912   if( !aPrs )
913     return;
914
915   HYDROGUI_ImportImageDlg::TransformationDataMap aDataMap;
916
917   const HYDROGUI_PrsImage::TransformationPointMap& aPointMap =
918     aPrs->getTransformationPointMap();
919   
920   HYDROGUI_PrsImage::TransformationPointMapIterator anIter( aPointMap );
921   while( anIter.hasNext() )
922   {
923     int aPointType = anIter.next().key();
924     const HYDROGUI_PrsImage::TransformationPoint& aTransformationPoint = anIter.value();
925     const QPoint& aPoint = aTransformationPoint.Point;
926
927     HYDROGUI_ImportImageDlg::TransformationData aData( aPoint, QPointF(), QPointF() );
928     aDataMap[ aPointType ] = aData;
929   }
930
931   ( (HYDROGUI_ImportImageDlg*)inputPanel() )->setTransformationDataMap( aDataMap, true, theIsRefImage );
932 }
933
934 void HYDROGUI_ImportImageOp::closePreview()
935 {
936   DEBTRACE("closePreview");
937   closeView( myPreviewViewManager );
938   myPreviewViewManager = 0;
939   closeView( myRefViewManager );
940   myRefViewManager = 0;
941
942   if( myActiveViewManager )
943     HYDROGUI_Tool::SetActiveViewManager( module(), myActiveViewManager );
944 }
945
946 void HYDROGUI_ImportImageOp::closeView( GraphicsView_ViewManager* &aViewMgr )
947 {
948   DEBTRACE("closeView " << aViewMgr);
949   if( aViewMgr )
950   {
951     GraphicsView_ViewPort* aViewPort = 0;
952     if( GraphicsView_Viewer* aViewer = aViewMgr->getViewer() )
953     {
954       aViewPort = aViewer->getActiveViewPort();
955     }
956     disconnect( aViewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
957                 this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
958
959     // Nullify appropriate presentation pointer
960     HYDROGUI_PrsImage* aPrs = 0;
961     switch ( module()->getViewManagerRole( aViewMgr ) )
962     {
963       case HYDROGUI_Module::VMR_ReferenceImage:
964         DEBTRACE("  myRefPreviewPrs = 0");
965         aPrs = myRefPreviewPrs;
966         myRefPreviewPrs = 0;
967         break;
968       case HYDROGUI_Module::VMR_TransformImage:
969         DEBTRACE("  myPreviewPrs = 0");
970         aPrs = myPreviewPrs;
971         myPreviewPrs = 0;
972     }
973
974     // Remove the appropriate presentation from the view
975     if( aPrs )
976     {
977       if( aViewPort )
978       {
979         aViewPort->removeItem( aPrs );
980       }
981       delete aPrs;
982     }
983
984     // Delete the view
985     module()->removeViewManager(aViewMgr); // clean HYDROGUI module structure
986     aViewMgr->getActiveView()->hide();
987     module()->getApp()->removeViewManager( aViewMgr ); // aViewMgr is deleted here
988     aViewMgr = 0;
989     DEBTRACE("end of closeView");
990   }
991 }
992
993 void HYDROGUI_ImportImageOp::onFilesSelected( const QStringList& theFileNames )
994 {
995   DEBTRACE("onFilesSelected");
996   myFiles = theFileNames;
997   myFileIndex = -1;
998   SetNextFile();
999 }
1000
1001 bool HYDROGUI_ImportImageOp::SetNextFile()
1002 {
1003   DEBTRACE("SetNextFile");
1004   myFileIndex++;
1005   bool isEnabledEdit = myFiles.count()==1 || myFileIndex==myFiles.count();
1006   bool isValid = ( myFileIndex>=0 && myFileIndex<myFiles.count() );
1007   QString aFile = isValid ? myFiles[myFileIndex] : "";
1008
1009   HYDROGUI_ImportImageDlg* aPanel = dynamic_cast<HYDROGUI_ImportImageDlg*>( inputPanel() );
1010   aPanel->ActivateFile( aFile, isEnabledEdit );
1011   return isValid;
1012 }