Salome HOME
57bfafb6f4df207c3210b54852eb9be1f1d6f736
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_GeoreferencementDlg.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_GeoreferencementDlg.h"
24
25 #include <GEOMUtils.hxx>
26
27 #include <OCCViewer_ViewWindow.h>
28 #include <OCCViewer_ViewManager.h>
29 #include <OCCViewer_ViewPort3d.h>
30
31 #include <AIS_InteractiveContext.hxx>
32
33 #include <QTableWidget>
34 #include <QItemDelegate>
35 #include <QHeaderView>
36 #include <QRadioButton>
37 #include <QPushButton>
38 #include <QLineEdit>
39 #include <QButtonGroup>
40 #include <QGroupBox>
41 #include <QLayout>
42 #include <QMouseEvent>
43
44 //! Profile data structre constructor
45 HYDROGUI_GeoreferencementDlg::ProfileGeoData::ProfileGeoData( 
46   const QString& theXg, const QString& theYg, 
47   const QString& theXd, const QString& theYd)
48 {
49   this->isEmpty = theXg.isEmpty() && theYg.isEmpty() &&
50                  theXd.isEmpty() && theYd.isEmpty();
51   this->isIncomplete = !isEmpty;
52
53   if ( isIncomplete ) {
54     bool isOk = false;
55
56     this->Xg= theXg.toDouble( &isOk );
57     if ( isOk ) {
58       this->Yg = theYg.toDouble( &isOk );
59       if ( isOk ) {
60         this->Xd = theXd.toDouble( &isOk );
61         if ( isOk ) {
62           this->Yd = theYd.toDouble( &isOk );
63           this->isIncomplete = !isOk;
64         }
65       }
66     }
67   }
68 }
69
70 //! Custom item delegate (line edit with double validator)
71 class HYDROGUI_GeoreferencementDlg::Delegate : public QItemDelegate
72 {
73 public:
74   Delegate( QObject* = 0 );
75   
76   QWidget* createEditor( QWidget*, const QStyleOptionViewItem&,
77                          const QModelIndex& ) const;
78   
79   void setEditorData( QWidget*, const QModelIndex& ) const;
80   void setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const;
81 };
82
83 HYDROGUI_GeoreferencementDlg::Delegate::Delegate( QObject* theParent )
84  : QItemDelegate( theParent )
85 {
86 }
87
88 QWidget* HYDROGUI_GeoreferencementDlg::Delegate::createEditor( 
89   QWidget* theParent, const QStyleOptionViewItem& theOption,
90   const QModelIndex& theIndex ) const
91 {
92   QWidget* anEditor = 0;
93
94   if ( theIndex.column() > 0 ) {
95     QLineEdit* aLineEdit = new QLineEdit( theParent );
96     aLineEdit->setValidator( new QDoubleValidator( aLineEdit ) );
97     anEditor = aLineEdit;
98   } else {
99     anEditor = QItemDelegate::createEditor( theParent, theOption, theIndex );
100   }
101
102   return anEditor;
103 }
104
105 void HYDROGUI_GeoreferencementDlg::Delegate::setEditorData( 
106   QWidget* theEditor, const QModelIndex& theIndex ) const
107 {
108   if ( QLineEdit* aLineEdit = dynamic_cast<QLineEdit*>( theEditor ) ) {
109     aLineEdit->setText( theIndex.data( Qt::EditRole ).toString() );
110   } else {
111     QItemDelegate::setEditorData( theEditor, theIndex );
112   }
113 }
114
115 void HYDROGUI_GeoreferencementDlg::Delegate::setModelData( 
116   QWidget* theEditor, QAbstractItemModel* theModel, const QModelIndex& theIndex) const
117 {
118   if ( QLineEdit* aLineEdit = dynamic_cast<QLineEdit*>( theEditor ) ) {
119     theModel->setData( theIndex, aLineEdit->text() );
120   } else {
121     QItemDelegate::setModelData( theEditor, theModel, theIndex );
122   }
123 }
124
125 HYDROGUI_GeoreferencementDlg::HYDROGUI_GeoreferencementDlg( HYDROGUI_Module* theModule, const QString& theTitle )
126 : HYDROGUI_InputPanel( theModule, theTitle ), myIsModified( false )
127 {
128   // Mode selector (all/selected)
129   QGroupBox* aModeGroup = new QGroupBox( tr( "PROFILES" ), this );
130
131   QRadioButton* anAllRB = new QRadioButton( tr( "ALL_MODE" ), aModeGroup );
132   QRadioButton* aSelectedRB = new QRadioButton( tr( "SELECTED_MODE" ), aModeGroup );
133
134   myModeButtons = new QButtonGroup( aModeGroup );
135   myModeButtons->addButton( anAllRB, AllProfiles );
136   myModeButtons->addButton( aSelectedRB, SelectedProfiles );
137
138   QBoxLayout* aModeSelectorLayout = new QVBoxLayout( aModeGroup );
139   aModeSelectorLayout->setMargin( 5 );
140   aModeSelectorLayout->setSpacing( 5 );
141   aModeSelectorLayout->addWidget( anAllRB );
142   aModeSelectorLayout->addWidget( aSelectedRB );
143
144   // Update selection button
145   myUpdateSelBtn = new QPushButton( mainFrame() );
146   myUpdateSelBtn->setText( tr("UPDATE_SELECTION") );
147   QBoxLayout* anUpdateSelLayout = new QHBoxLayout( mainFrame() );
148   anUpdateSelLayout->addWidget( myUpdateSelBtn );
149   anUpdateSelLayout->addStretch();
150
151   // Table
152   myTable = new QTableWidget( mainFrame() );
153   myTable->setItemDelegate( new Delegate( this ) );
154   myTable->verticalHeader()->setVisible( false );
155   myTable->setSelectionBehavior( QAbstractItemView::SelectItems );
156   myTable->setSelectionMode( QAbstractItemView::SingleSelection );
157   myTable->setColumnCount( 5 );
158   QStringList aColumnNames;
159   aColumnNames << tr( "PROFILE_HEADER" ) << tr( "XG_HEADER" ) << tr( "YG_HEADER" ) << 
160                                             tr( "XD_HEADER" ) << tr( "YD_HEADER" );
161   myTable->setHorizontalHeaderLabels( aColumnNames );
162
163   // Layout
164   addWidget( aModeGroup );
165   addLayout( anUpdateSelLayout );
166   addWidget( myTable );
167
168   // Connect signals and slots
169   connect( myModeButtons, SIGNAL( buttonClicked( int ) ), this, SLOT( onModeActivated( int ) ) );
170   connect( myUpdateSelBtn, SIGNAL( clicked() ), this, SIGNAL( updateSelection() ) );
171   connect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
172            this, SLOT( onDataChanged() ) );
173 }
174
175 HYDROGUI_GeoreferencementDlg::~HYDROGUI_GeoreferencementDlg()
176 {
177 }
178
179 void HYDROGUI_GeoreferencementDlg::onModeActivated( int theMode )
180 {
181   myUpdateSelBtn->setEnabled( theMode == SelectedProfiles );
182   emit modeActivated( theMode );
183 }
184
185 void HYDROGUI_GeoreferencementDlg::reset()
186 {
187   // Activate the "All" mode
188   myModeButtons->button( AllProfiles )->setChecked( true );
189
190   // Clear the table widget
191   myTable->setRowCount( 0 );
192 }
193
194 void HYDROGUI_GeoreferencementDlg::setMode( const int theMode )
195 {
196   bool isBlocked = myModeButtons->blockSignals( true );
197
198   QAbstractButton* aModeButton = myModeButtons->button( theMode );
199   if ( aModeButton ) {
200     aModeButton->setChecked( true );
201   }
202
203   myUpdateSelBtn->setEnabled( theMode == SelectedProfiles );
204
205   myModeButtons->blockSignals( isBlocked );
206 }
207
208 void HYDROGUI_GeoreferencementDlg::setData( const ProfilesGeoDataMap& theMap )
209 {
210   disconnect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
211               this, SLOT( onDataChanged() ) );
212
213   myTable->setRowCount( 0 );
214
215   foreach ( const QString& aProfileName, theMap.keys() ) {
216     // Check the current profile name
217     if ( aProfileName.isEmpty() ) {
218       continue;
219     }
220
221     // Get georeferencement data for the current profile
222     ProfileGeoData aGeoData = theMap.value( aProfileName );
223     QString aXg, anYg, aXd, anYd;
224     if ( !aGeoData.isEmpty ) {
225       aXg = getString( aGeoData.Xg );
226       anYg = getString( aGeoData.Yg );
227       aXd = getString( aGeoData.Xd );
228       anYd = getString( aGeoData.Yd );
229     }
230     
231     // Insert row with the data
232     int aRow = myTable->rowCount();
233     myTable->insertRow( aRow );
234
235     // "Profile" column
236     QTableWidgetItem* aNameItem = new QTableWidgetItem( aProfileName );
237     aNameItem->setFlags( Qt::ItemIsEnabled );
238     QFont aFont = aNameItem->font();
239     aFont.setBold( true );
240     aNameItem->setFont( aFont ); 
241     myTable->setItem( aRow, 0, aNameItem );
242
243     // "Xg" column
244     myTable->setItem( aRow, 1, new QTableWidgetItem( aXg ) );
245
246     // "Yg" column
247     myTable->setItem( aRow, 2, new QTableWidgetItem( anYg ) );
248
249     // "Xd" column
250     myTable->setItem( aRow, 3, new QTableWidgetItem( aXd ) );
251
252     // "Yd" column
253     myTable->setItem( aRow, 4, new QTableWidgetItem( anYd ) );
254   }
255
256   myTable->resizeColumnToContents( 0 );
257   myTable->resizeRowsToContents();
258
259   myIsModified = false;
260   
261   connect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
262            this, SLOT( onDataChanged() ) );
263 }
264
265 void HYDROGUI_GeoreferencementDlg::getData( ProfilesGeoDataMap& theMap )
266 {
267   // Clear the map
268   theMap.clear();
269
270   // Fill the map
271   bool isOk = false;
272   QString aXg, anYg, aXd, anYd;
273   for ( int aRow = 0; aRow < myTable->rowCount(); aRow++ ) {
274     QString aProfileName = myTable->item( aRow, 0 )->text();
275
276     aXg = myTable->item( aRow, 1 )->text();
277     anYg = myTable->item( aRow, 2 )->text();
278     aXd = myTable->item( aRow, 3 )->text();
279     anYd = myTable->item( aRow, 4 )->text();
280    
281     theMap.insert( aProfileName, ProfileGeoData( aXg, anYg, aXd, anYd ) );
282   }
283 }
284
285 void HYDROGUI_GeoreferencementDlg::onMousePress( 
286   SUIT_ViewWindow* theViewWindow, QMouseEvent* theEvent )
287 {
288   // Check the parameters
289   OCCViewer_ViewWindow* anOCCViewWindow = 
290     dynamic_cast<OCCViewer_ViewWindow*>(theViewWindow);
291   if ( !anOCCViewWindow || (theEvent->button() != Qt::LeftButton) ) {
292     return;
293   }
294   
295   // Check for current cell
296   int aRow = myTable->currentRow();
297   int aColumn = myTable->currentColumn();
298   if ( aRow < 0 || aColumn <= 0 ) {
299     return;
300   }
301
302   // Get the selected point coordinates
303   OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
304   gp_Pnt aPnt = GEOMUtils::ConvertClickToPoint( theEvent->x(), theEvent->y(), 
305                                                 aViewPort->getView() );
306
307   // Set the coordinates to the corresponding cells of the table
308   int aColumnX = aColumn < 3 ? 1 : 3;
309   int aColumnY = aColumnX + 1;
310   
311   myTable->item( aRow, aColumnX )->setText( getString( aPnt.X() ) );
312   myTable->item( aRow, aColumnY )->setText( getString( aPnt.Y() ) );
313 }
314
315 QString HYDROGUI_GeoreferencementDlg::getString( const double theNumber ) const
316 {
317   return QString::number( theNumber, 'g', 12 );
318 }
319
320 void HYDROGUI_GeoreferencementDlg::onDataChanged()
321 {
322   myIsModified = true;
323 }
324
325 bool HYDROGUI_GeoreferencementDlg::isModified() const
326 {
327   return myIsModified;
328 }