Salome HOME
copyrights in HYDRO files are updated
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_GeoreferencementDlg.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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 <CurveCreator_Utils.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, false );
232       anYg = HYDROGUI_Tool::GetCoordinateString( aGeoData.Yg, false );
233       aXd = HYDROGUI_Tool::GetCoordinateString( aGeoData.Xd, false );
234       anYd = HYDROGUI_Tool::GetCoordinateString( aGeoData.Yd, false );
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( aNameItem->flags() & ~Qt::ItemIsEnabled );
244     /* Bold font is not used in other tables. Keep the common style.
245     QFont aFont = aNameItem->font();
246     aFont.setBold( true );
247     aNameItem->setFont( aFont );
248     */ 
249     myTable->setItem( aRow, 0, aNameItem );
250
251     // "Xg" column
252     myTable->setItem( aRow, 1, new QTableWidgetItem( aXg ) );
253
254     // "Yg" column
255     myTable->setItem( aRow, 2, new QTableWidgetItem( anYg ) );
256
257     // "Xd" column
258     myTable->setItem( aRow, 3, new QTableWidgetItem( aXd ) );
259
260     // "Yd" column
261     myTable->setItem( aRow, 4, new QTableWidgetItem( anYd ) );
262   }
263
264   myTable->resizeColumnToContents( 0 );
265   myTable->resizeRowsToContents();
266
267   myIsModified = false;
268   
269   connect( myTable->model(), SIGNAL( dataChanged ( const QModelIndex&, const QModelIndex& ) ), 
270            this, SLOT( onDataChanged() ) );
271 }
272
273 void HYDROGUI_GeoreferencementDlg::getData( ProfilesGeoDataList& theData ) const
274 {
275   // Clear the list
276   theData.clear();
277
278   // Fill the map
279   bool isOk = false;
280   QString aXg, anYg, aXd, anYd;
281   for ( int aRow = 0; aRow < myTable->rowCount(); aRow++ ) {
282     QString aProfileName = myTable->item( aRow, 0 )->text();
283
284     aXg = myTable->item( aRow, 1 )->text();
285     anYg = myTable->item( aRow, 2 )->text();
286     aXd = myTable->item( aRow, 3 )->text();
287     anYd = myTable->item( aRow, 4 )->text();
288    
289     theData.append( ProfileGeoData( aProfileName, aXg, anYg, aXd, anYd ) );
290   }
291 }
292
293 void HYDROGUI_GeoreferencementDlg::onMousePress( 
294   SUIT_ViewWindow* theViewWindow, QMouseEvent* theEvent )
295 {
296   // Check the parameters
297   OCCViewer_ViewWindow* anOCCViewWindow = 
298     dynamic_cast<OCCViewer_ViewWindow*>(theViewWindow);
299   if ( !anOCCViewWindow || (theEvent->button() != Qt::LeftButton) ) {
300     return;
301   }
302   
303   // Check for current cell
304   int aRow = myTable->currentRow();
305   int aColumn = myTable->currentColumn();
306   if ( aRow < 0 || aColumn <= 0 ) {
307     return;
308   }
309
310   // Get the selected point coordinates
311   OCCViewer_ViewPort3d* aViewPort = anOCCViewWindow->getViewPort();
312   gp_Pnt aPnt = CurveCreator_Utils::ConvertClickToPoint( theEvent->x(), theEvent->y(), 
313                                                          aViewPort->getView() );
314
315   // Set the coordinates to the corresponding cells of the table
316   int aColumnX = aColumn < 3 ? 1 : 3;
317   int aColumnY = aColumnX + 1;
318   
319   QString aXStr = HYDROGUI_Tool::GetCoordinateString( aPnt.X(), false );
320   QString anYStr = HYDROGUI_Tool::GetCoordinateString( aPnt.Y(), false );
321   myTable->item( aRow, aColumnX )->setText( aXStr );
322   myTable->item( aRow, aColumnY )->setText( anYStr );
323 }
324
325 void HYDROGUI_GeoreferencementDlg::onDataChanged()
326 {
327   myIsModified = true;
328 }
329
330 bool HYDROGUI_GeoreferencementDlg::isModified() const
331 {
332   return myIsModified;
333 }