Salome HOME
Merge remote-tracking branch 'origin/BR_IMPROVEMENTS' into BR_v14_rc
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_GeoreferencementOp.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_GeoreferencementOp.h"
20
21 #include "HYDROGUI_GeoreferencementDlg.h"
22 #include "HYDROGUI_DataModel.h"
23 #include "HYDROGUI_Module.h"
24 #include "HYDROGUI_Tool.h"
25 #include "HYDROGUI_UpdateFlags.h"
26
27 #include <HYDROData_Profile.h>
28 #include <HYDROData_Iterator.h>
29 #include <HYDROData_Entity.h>
30
31 #include <LightApp_Application.h>
32 #include <LightApp_UpdateFlags.h>
33
34 #include <SUIT_Desktop.h>
35 #include <SUIT_MessageBox.h>
36 #include <SUIT_ViewWindow.h>
37
38 #include <OCCViewer_ViewManager.h>
39
40 #include <gp_XY.hxx>
41
42 HYDROGUI_GeoreferencementOp::HYDROGUI_GeoreferencementOp( HYDROGUI_Module* theModule, const int theInitialMode )
43 : HYDROGUI_Operation( theModule ),
44   myInitialMode( theInitialMode )
45 {
46   setName( tr( "PROFILES_GEOREFERENCEMENT" ) );
47 }
48
49 HYDROGUI_GeoreferencementOp::~HYDROGUI_GeoreferencementOp()
50 {
51 }
52
53 void HYDROGUI_GeoreferencementOp::startOperation()
54 {
55   HYDROGUI_Operation::startOperation();
56
57   HYDROGUI_GeoreferencementDlg* aPanel = 
58     ::qobject_cast<HYDROGUI_GeoreferencementDlg*>( inputPanel() );
59   if ( !aPanel ) {
60     return;
61   }
62
63   aPanel->reset();
64
65   if ( myInitialMode == All ) {
66     onModeActivated( HYDROGUI_GeoreferencementDlg::AllProfiles );
67   } else if ( myInitialMode == Selected ) {
68     onModeActivated( HYDROGUI_GeoreferencementDlg::SelectedProfiles );
69   }
70
71   LightApp_Application* anApp = module()->getApp();
72   OCCViewer_ViewManager* aViewManager =
73     dynamic_cast<OCCViewer_ViewManager*>( anApp->getViewManager( OCCViewer_Viewer::Type(), false ) );
74   if ( aViewManager ) {
75     connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
76              aPanel, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ), 
77              Qt::UniqueConnection );
78   }
79
80   connect( anApp->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
81            this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ), Qt::UniqueConnection );
82 }
83
84 void HYDROGUI_GeoreferencementOp::abortOperation()
85 {
86   LightApp_Application* anApp = module()->getApp();
87   if ( anApp && anApp->desktop() ) {
88     anApp->desktop()->disconnect( this );
89   }
90
91   HYDROGUI_Operation::abortOperation();
92 }
93
94 void HYDROGUI_GeoreferencementOp::commitOperation()
95 {
96   LightApp_Application* anApp = module()->getApp();
97   if ( anApp && anApp->desktop() ) {
98     anApp->desktop()->disconnect( this );
99   }
100
101   HYDROGUI_Operation::commitOperation();
102 }
103
104 HYDROGUI_InputPanel* HYDROGUI_GeoreferencementOp::createInputPanel() const
105 {
106   HYDROGUI_InputPanel* aPanel = new HYDROGUI_GeoreferencementDlg( module(), getName() );
107   connect( aPanel, SIGNAL( modeActivated( int ) ), SLOT( onModeActivated( int ) ) );
108   connect( aPanel, SIGNAL( updateSelection() ), SLOT( onUpdateSelection() ) );
109
110   return aPanel;
111 }
112
113 bool HYDROGUI_GeoreferencementOp::processApply( int& theUpdateFlags,
114                                                 QString& theErrorMsg,
115                                                 QStringList& theBrowseObjectsEntries )
116 {
117   theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init;
118
119   return store( theErrorMsg );
120 }
121
122 void HYDROGUI_GeoreferencementOp::onModeActivated( const int theActualMode )
123 {
124   QString anErrorMsg;
125
126   // Get the panel
127   HYDROGUI_GeoreferencementDlg* aPanel = 
128     ::qobject_cast<HYDROGUI_GeoreferencementDlg*>( inputPanel() );
129   if ( !aPanel ) {
130     return;
131   }
132
133   aPanel->setMode( theActualMode == HYDROGUI_GeoreferencementDlg::AllProfiles ?
134                    HYDROGUI_GeoreferencementDlg::SelectedProfiles :
135                    HYDROGUI_GeoreferencementDlg::AllProfiles);
136
137   // Store the dialog data to the data model
138   bool isToStore = false;
139   // Check if modifications exists
140   if ( aPanel->isModified() ) {
141     // Show confirmation dialog
142     SUIT_MessageBox::StandardButtons aButtons = 
143       SUIT_MessageBox::Yes | SUIT_MessageBox::No;
144
145     isToStore = SUIT_MessageBox::question( module()->getApp()->desktop(),
146                                            tr( "CONFIRMATION" ),
147                                            tr( "CONFIRM_STORE" ),
148                                            aButtons, 
149                                            SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
150   }
151   // Store modifications if needed
152   if ( isToStore )
153   {
154     startDocOperation();
155     if ( !store( anErrorMsg ) )
156     {
157       abortDocOperation();
158
159       anErrorMsg.append( "\n" + tr( "INPUT_VALID_DATA" ) );
160       SUIT_MessageBox::critical( module()->getApp()->desktop(),
161                                  tr( "INSUFFICIENT_INPUT_DATA" ),
162                                  anErrorMsg );
163       return;
164     }
165     else
166     {
167       commitDocOperation();
168     }
169   }
170
171   aPanel->setMode( theActualMode );
172
173   // Get the list of profiles
174   HYDROData_SequenceOfObjects aSeqOfProfiles;
175   
176   if( theActualMode == HYDROGUI_GeoreferencementDlg::AllProfiles ) {
177     HYDROData_Iterator aProfilesIter( doc(), KIND_PROFILE );
178     while ( aProfilesIter.More() ) {
179       aSeqOfProfiles.Append( aProfilesIter.Current() );
180       aProfilesIter.Next();
181     }
182   } else if ( theActualMode == HYDROGUI_GeoreferencementDlg::SelectedProfiles ) {
183     aSeqOfProfiles = HYDROGUI_Tool::GetSelectedObjects( module() );
184   }
185
186   // Set the profiles to the panel
187   setPanelData( aSeqOfProfiles );
188 }
189
190 void HYDROGUI_GeoreferencementOp::onWindowActivated( SUIT_ViewWindow* theViewWindow )
191 {
192   if ( !theViewWindow ) {
193     return;
194   }
195
196   OCCViewer_ViewManager* aViewManager =
197     dynamic_cast<OCCViewer_ViewManager*>( theViewWindow->getViewManager() );
198
199   if ( aViewManager ) {
200     HYDROGUI_GeoreferencementDlg* aPanel = 
201       ::qobject_cast<HYDROGUI_GeoreferencementDlg*>( inputPanel() );
202     if ( aPanel ) {
203       connect( aViewManager, SIGNAL( mousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
204                aPanel, SLOT( onMousePress( SUIT_ViewWindow*, QMouseEvent* ) ),
205                Qt::UniqueConnection);
206     }
207   }
208 }
209
210 bool HYDROGUI_GeoreferencementOp::store( QString& theErrorMsg )
211 {
212   // Clear the error string
213   theErrorMsg.clear();
214   
215   HYDROGUI_Module* aModule = module();
216
217   // Get the panel
218   HYDROGUI_GeoreferencementDlg* aPanel = 
219     ::qobject_cast<HYDROGUI_GeoreferencementDlg*>( inputPanel() );
220   if ( !aPanel ) {
221     return false;
222   }
223
224   // Get georeferencement data from the panel
225   HYDROGUI_GeoreferencementDlg::ProfilesGeoDataList aGeoDataList;
226   aPanel->getData( aGeoDataList );
227   if ( aGeoDataList.empty() ) {
228     return true;
229   }
230
231   // Check the data validity
232   foreach ( const HYDROGUI_GeoreferencementDlg::ProfileGeoData& aGeoData, aGeoDataList ) {
233     if ( aGeoData.isIncomplete ) {
234       theErrorMsg = tr( "INCOMPLETE_DATA" ).arg( aGeoData.Name );
235       return false;
236     }
237   }
238
239   // Store the data in the data model
240   foreach ( const HYDROGUI_GeoreferencementDlg::ProfileGeoData& aGeoData, aGeoDataList ) {
241     Handle(HYDROData_Profile) aProfile = 
242       Handle(HYDROData_Profile)::DownCast(
243         HYDROGUI_Tool::FindObjectByName( module(), aGeoData.Name, KIND_PROFILE ) );
244     if ( !aProfile.IsNull() ) {
245       if ( !aGeoData.isEmpty ) {
246         if ( !aProfile->IsValid() ) // Show the profile after it became valid
247           aModule->setObjectVisible( HYDROGUI_Tool::GetActiveOCCViewId( aModule ), aProfile, true );
248
249         aProfile->SetLeftPoint( gp_XY( aGeoData.Xg, aGeoData.Yg ), false );
250         aProfile->SetRightPoint( gp_XY( aGeoData.Xd, aGeoData.Yd ), false );
251       } else {
252         aProfile->Invalidate();
253         aModule->setObjectVisible( HYDROGUI_Tool::GetActiveOCCViewId( aModule ), aProfile, false );
254       }
255
256       aProfile->Update();
257     }
258   }
259
260   aModule->update( UF_Model | UF_OCCViewer | UF_OCC_Forced );
261
262   return true;
263 }
264
265 void HYDROGUI_GeoreferencementOp::onUpdateSelection()
266 {
267   // Get the selected profiles
268   HYDROData_SequenceOfObjects aSeqOfProfiles = 
269     HYDROGUI_Tool::GetSelectedObjects( module() );
270
271   // Set them to the dialog
272   setPanelData( aSeqOfProfiles );
273 }
274
275 void HYDROGUI_GeoreferencementOp::setPanelData( 
276   const HYDROData_SequenceOfObjects& theProfiles )
277 {
278   // Get the panel
279   HYDROGUI_GeoreferencementDlg* aPanel = 
280     ::qobject_cast<HYDROGUI_GeoreferencementDlg*>( inputPanel() );
281   if ( !aPanel ) {
282     return;
283   }
284
285   // Get georeferencement data from the data model
286   HYDROGUI_GeoreferencementDlg::ProfilesGeoDataList aData;
287
288   HYDROData_SequenceOfObjects::Iterator anIter( theProfiles );
289   for ( ; anIter.More(); anIter.Next() ) {
290     Handle(HYDROData_Profile) aProfile =
291         Handle(HYDROData_Profile)::DownCast( anIter.Value() );
292     if ( aProfile.IsNull() ) {
293       continue;
294     }
295
296     HYDROGUI_GeoreferencementDlg::ProfileGeoData aGeoData( aProfile->GetName() );
297
298     gp_XY aFirstPoint, aLastPoint;
299     if ( aProfile->GetLeftPoint( aFirstPoint, false ) &&
300          aProfile->GetRightPoint( aLastPoint, false ) ) {
301       aGeoData = 
302         HYDROGUI_GeoreferencementDlg::ProfileGeoData( aGeoData.Name, 
303                                                       aFirstPoint.X(), aFirstPoint.Y(),
304                                                       aLastPoint.X(), aLastPoint.Y() );
305     }
306    
307     aData.append( aGeoData );
308   }
309
310   // Set the collected data to the dialog
311   aPanel->setData( aData );
312 }