Salome HOME
Issues ##68, 88: Swith between GEOM and HYDRO.
[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 "HYDROGUI_Tool.h"
26
27 #include <GEOMUtils.hxx>
28
29 #include <OCCViewer_ViewWindow.h>
30 #include <OCCViewer_ViewManager.h>
31 #include <OCCViewer_ViewPort3d.h>
32
33 #include <AIS_InteractiveContext.hxx>
34
35 #include <QTableWidget>
36 #include <QItemDelegate>
37 #include <QHeaderView>
38 #include <QRadioButton>
39 #include <QPushButton>
40 #include <QLineEdit>
41 #include <QButtonGroup>
42 #include <QGroupBox>
43 #include <QLayout>
44 #include <QMouseEvent>
45
46 //! Profile data structre constructor
47 HYDROGUI_GeoreferencementDlg::ProfileGeoData::ProfileGeoData( 
48   const QString& theName,
49   const QString& theXg, const QString& theYg, 
50   const QString& theXd, const QString& theYd)
51 {
52   this->Name = theName;
53   this->isEmpty = theXg.isEmpty() && theYg.isEmpty() &&
54                  theXd.isEmpty() && theYd.isEmpty();
55   this->isIncomplete = !isEmpty;
56
57   if ( isIncomplete ) {
58     bool isOk = false;
59
60     this->Xg= theXg.toDouble( &isOk );
61     if ( isOk ) {
62       this->Yg = theYg.toDouble( &isOk );
63       if ( isOk ) {
64         this->Xd = theXd.toDouble( &isOk );
65         if ( isOk ) {
66           this->Yd = theYd.toDouble( &isOk );
67           this->isIncomplete = !isOk;
68         }
69       }
70     }
71   }
72 }
73
74 //! Custom item delegate (line edit with double validator)
75 class HYDROGUI_GeoreferencementDlg::Delegate : public QItemDelegate
76 {
77 public:
78   Delegate( QObject* = 0 );
79   
80   QWidget* createEditor( QWidget*, const QStyleOptionViewItem&,
81                          const QModelIndex& ) const;
82   
83   void setEditorData( QWidget*, const QModelIndex& ) const;
84   void setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const;
85 };
86
87 HYDROGUI_GeoreferencementDlg::Delegate::Delegate( QObject* theParent )
88  : QItemDelegate( theParent )
89 {
90 }
91
92 QWidget* HYDROGUI_GeoreferencementDlg::Delegate::createEditor( 
93   QWidget* theParent, const QStyleOptionViewItem& theOption,
94   const QModelIndex& theIndex ) const
95 {
96   QWidget* anEditor = 0;
97
98   if ( theIndex.column() > 0 ) {
99     QLineEdit* aLineEdit = new QLineEdit( theParent );
100     QDoubleValidator* aDoubleValidator = new QDoubleValidator();
101     aDoubleValidator->setNotation( QDoubleValidator::StandardNotation );
102     aDoubleValidator->setDecimals( 2 );
103     aLineEdit->setValidator( aDoubleValidator );
104     anEditor = aLineEdit;
105   } else {
106     anEditor = QItemDelegate::createEditor( theParent, theOption, theIndex );
107   }
108
109   return anEditor;
110 }
111
112 void HYDROGUI_GeoreferencementDlg::Delegate::setEditorData( 
113   QWidget* theEditor, const QModelIndex& theIndex ) const
114 {
115   if ( QLineEdit* aLineEdit = dynamic_cast<QLineEdit*>( theEditor ) ) {
116     aLineEdit->setText( theIndex.data( Qt::EditRole ).toString() );
117   } else {
118     QItemDelegate::setEditorData( theEditor, theIndex );
119   }
120 }
121
122 void HYDROGUI_GeoreferencementDlg::Delegate::setModelData( 
123   QWidget* theEditor, QAbstractItemModel* theModel, const QModelIndex& theIndex) const
124 {
125   if ( QLineEdit* aLineEdit = dynamic_cast<QLineEdit*>( theEditor ) ) {
126     theModel->setData( theIndex, aLineEdit->text() );
127   } else {
128     QItemDelegate::setModelData( theEditor, theModel, theIndex );
129   }
130 }
131
132 HYDROGUI_GeoreferencementDlg::HYDROGUI_GeoreferencementDlg( HYDROGUI_Module* theModule, const QString& theTitle )
133 : HYDROGUI_InputPanel( theModule, theTitle ), myIsModified( false )
134 {
135   // Mode selector (all/selected)
136   QGroupBox* aModeGroup = new QGroupBox( tr( "PROFILES" ), this );
137
138   QRadioButton* anAllRB = new QRadioButton( tr( "ALL_MODE" ), aModeGroup );
139   QRadioButton* aSelectedRB = new QRadioButton( tr( "SELECTED_MODE" ), aModeGroup );
140
141   myModeButtons = new QButtonGroup( aModeGroup );
142   myModeButtons->addButton( anAllRB, AllProfiles );
143   myModeButtons->addButton( aSelectedRB, SelectedProfiles );
144
145   QBoxLayout* aModeSelectorLayout = new QVBoxLayout( aModeGroup );
146   aModeSelectorLayout->setMargin( 5 );
147   aModeSelectorLayout->setSpacing( 5 );
148   aModeSelectorLayout->addWidget( anAllRB );
149   aModeSelectorLayout->addWidget( aSelectedRB );
150
151   // Update selection button
152   myUpdateSelBtn = new QPushButton( mainFrame() );
153   myUpdateSelBtn->setText( tr("UPDATE_SELECTION") );
154   QBoxLayout* anUpdateSelLayout = new QHBoxLayout( mainFrame() );
155   anUpdateSelLayout->addWidget( myUpdateSelBtn );
156   anUpdateSelLayout->addStretch();
157
158   // Table
159   myTable = new QTableWidget( mainFrame() );
160   myTable->setItemDelegate( new Delegate( this ) );
161   myTable->verticalHeader()->setVisible( false );
162   myTable->setSelectionBehavior( QAbstractItemView::SelectItems );
163   myTable->setSelectionMode( QAbstractItemView::SingleSelection );
164   myTable->setColumnCount( 5 );
165   QStringList aColumnNames;
166   aColumnNames << tr( "PROFILE_HEADER" ) << tr( "XG_HEADER" ) << tr( "YG_HEADER" ) << 
167                                             tr( "XD_HEADER" ) << tr( "YD_HEADER" );
168   myTable->setHorizontalHeaderLabels( aColumnNames );
169
170   // Layout
171   addWidget( aModeGroup );
172   addLayout( anUpdateSelLayout );
173   addWidget( myTable );
174
175   // Connect signals and slots
176   connect( myModeButtons, SIGNAL( buttonClicked( int ) ), this, SLOT( onModeActivated( int ) ) );
177   connect( myUpdateSelBtn, SIGNAL( clicked() ), this, SIGNAL( updateSelection() ) );
178   connect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
179            this, SLOT( onDataChanged() ) );
180 }
181
182 HYDROGUI_GeoreferencementDlg::~HYDROGUI_GeoreferencementDlg()
183 {
184 }
185
186 void HYDROGUI_GeoreferencementDlg::onModeActivated( int theMode )
187 {
188   myUpdateSelBtn->setEnabled( theMode == SelectedProfiles );
189   emit modeActivated( theMode );
190 }
191
192 void HYDROGUI_GeoreferencementDlg::reset()
193 {
194   // Activate the "All" mode
195   myModeButtons->button( AllProfiles )->setChecked( true );
196
197   // Clear the table widget
198   myTable->setRowCount( 0 );
199 }
200
201 void HYDROGUI_GeoreferencementDlg::setMode( const int theMode )
202 {
203   bool isBlocked = myModeButtons->blockSignals( true );
204
205   QAbstractButton* aModeButton = myModeButtons->button( theMode );
206   if ( aModeButton ) {
207     aModeButton->setChecked( true );
208   }
209
210   myUpdateSelBtn->setEnabled( theMode == SelectedProfiles );
211
212   myModeButtons->blockSignals( isBlocked );
213 }
214
215 void HYDROGUI_GeoreferencementDlg::setData( const ProfilesGeoDataList& theData )
216 {
217   disconnect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
218               this, SLOT( onDataChanged() ) );
219
220   myTable->setRowCount( 0 );
221
222   foreach ( const ProfileGeoData& aGeoData, theData ) {
223     // Check the current profile name
224     if ( aGeoData.Name.isEmpty() ) {
225       continue;
226     }
227
228     // Get georeferencement data for the current profile
229     QString aXg, anYg, aXd, anYd;
230     if ( !aGeoData.isEmpty ) {
231       aXg = HYDROGUI_Tool::GetCoordinateString( aGeoData.Xg );
232       anYg = HYDROGUI_Tool::GetCoordinateString( aGeoData.Yg );
233       aXd = HYDROGUI_Tool::GetCoordinateString( aGeoData.Xd );
234       anYd = HYDROGUI_Tool::GetCoordinateString( aGeoData.Yd );
235     }
236     
237     // Insert row with the data
238     int aRow = myTable->rowCount();
239     myTable->insertRow( aRow );
240
241     // "Profile" column
242     QTableWidgetItem* aNameItem = new QTableWidgetItem( aGeoData.Name );
243     aNameItem->setFlags( Qt::ItemIsEnabled );
244     QFont aFont = aNameItem->font();
245     aFont.setBold( true );
246     aNameItem->setFont( aFont ); 
247     myTable->setItem( aRow, 0, aNameItem );
248
249     // "Xg" column
250     myTable->setItem( aRow, 1, new QTableWidgetItem( aXg ) );
251
252     // "Yg" column
253     myTable->setItem( aRow, 2, new QTableWidgetItem( anYg ) );
254
255     // "Xd" column
256     myTable->setItem( aRow, 3, new QTableWidgetItem( aXd ) );
257
258     // "Yd" column
259     myTable->setItem( aRow, 4, new QTableWidgetItem( anYd ) );
260   }
261
262   myTable->resizeColumnToContents( 0 );
263   myTable->resizeRowsToContents();
264
265   myIsModified = false;
266   
267   connect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
268            this, SLOT( onDataChanged() ) );
269 }
270
271 void HYDROGUI_GeoreferencementDlg::getData( ProfilesGeoDataList& theData ) const
272 {
273   // Clear the list
274   theData.clear();
275
276   // Fill the map
277   bool isOk = false;
278   QString aXg, anYg, aXd, anYd;
279   for ( int aRow = 0; aRow < myTable->rowCount(); aRow++ ) {
280     QString aProfileName = myTable->item( aRow, 0 )->text();
281
282     aXg = myTable->item( aRow, 1 )->text();
283     anYg = myTable->item( aRow, 2 )->text();
284     aXd = myTable->item( aRow, 3 )->text();
285     anYd = myTable->item( aRow, 4 )->text();
286    
287     theData.append( ProfileGeoData( aProfileName, aXg, anYg, aXd, anYd ) );
288   }
289 }
290
291 void HYDROGUI_GeoreferencementDlg::onMousePress( 
292   SUIT_ViewWindow* theViewWindow, QMouseEvent* theEvent )
293 {
294   // Check the parameters
295   OCCViewer_ViewWindow* anOCCViewWindow = 
296     dynamic_cast<OCCViewer_ViewWindow*>(theViewWindow);
297   if ( !anOCCViewWindow || (theEvent->button() != Qt::LeftButton) ) {
298     return;
299   }
300   
301   // Check for current cell
302   int aRow = myTable->currentRow();
303   int aColumn = myTable->currentColumn();
304   if ( aRow < 0 || aColumn <= 0 ) {
305     return;
306   }
307
308   // Get the selected point coordinates
309   OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
310   gp_Pnt aPnt = GEOMUtils::ConvertClickToPoint( theEvent->x(), theEvent->y(), 
311                                                 aViewPort->getView() );
312
313   // Set the coordinates to the corresponding cells of the table
314   int aColumnX = aColumn < 3 ? 1 : 3;
315   int aColumnY = aColumnX + 1;
316   
317   QString aXStr = HYDROGUI_Tool::GetCoordinateString( aPnt.X() );
318   QString anYStr = HYDROGUI_Tool::GetCoordinateString( aPnt.Y() );
319   myTable->item( aRow, aColumnX )->setText( aXStr );
320   myTable->item( aRow, aColumnY )->setText( anYStr );
321 }
322
323 void HYDROGUI_GeoreferencementDlg::onDataChanged()
324 {
325   myIsModified = true;
326 }
327
328 bool HYDROGUI_GeoreferencementDlg::isModified() const
329 {
330   return myIsModified;
331 }