Salome HOME
refs #1336: default size for columns of Strickler table
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_StricklerTableDlg.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_StricklerTableDlg.h>
20 #include <HYDROGUI_LineEditDoubleValidator.h>
21 #include <HYDROGUI_Tool.h>
22 #include <HYDROData_StricklerTable.h>
23 #include <SUIT_FileDlg.h>
24 #ifndef LIGHT_MODE
25 #include <SUIT_ResourceMgr.h>
26 #include <SUIT_Session.h>
27 #endif
28 #include <QBoxLayout>
29 #include <QColorDialog>
30 #include <QGroupBox>
31 #include <QHeaderView>
32 #include <QLabel>
33 #include <QLineEdit>
34 #include <QPainter>
35 #include <QTableWidget>
36 #include <QToolButton>
37
38 HYDROGUI_ColorDelegate::HYDROGUI_ColorDelegate( QWidget* theParent )
39 {
40 }
41
42 HYDROGUI_ColorDelegate::~HYDROGUI_ColorDelegate()
43 {
44 }
45
46 void HYDROGUI_ColorDelegate::paint( QPainter* thePainter, const QStyleOptionViewItem& theOption,
47                                     const QModelIndex& theIndex ) const
48 {
49   QColor aColor = theIndex.data( Qt::BackgroundColorRole ).value<QColor>();
50   thePainter->fillRect( theOption.rect, aColor );
51 }
52
53 QWidget* HYDROGUI_ColorDelegate::createEditor( QWidget* theParent,
54                                                const QStyleOptionViewItem& theOption,
55                                                const QModelIndex& theIndex ) const
56 {
57   QColor aColor = theIndex.data( Qt::BackgroundColorRole ).value<QColor>();
58   QColor aNewColor = QColorDialog::getColor( aColor );
59   if( aNewColor.isValid() )
60   {
61     QAbstractItemModel* aModel = const_cast<QAbstractItemModel*>( theIndex.model() );
62     QVariant aValue = qVariantFromValue( aNewColor );
63     aModel->setData( theIndex, aValue, Qt::BackgroundColorRole );
64   }
65   return 0;
66 }
67
68 void HYDROGUI_ColorDelegate::setEditorData( QWidget* theEditor, const QModelIndex& theIndex ) const
69 {
70 }
71
72 void HYDROGUI_ColorDelegate::setModelData( QWidget* theEditor, QAbstractItemModel* theModel,
73                                            const QModelIndex& theIndex ) const
74 {
75 }
76
77 QSize   HYDROGUI_ColorDelegate::sizeHint( const QStyleOptionViewItem& theOption, const QModelIndex& theIndex ) const
78 {
79   return theOption.rect.size();
80 }
81
82
83
84 const int COLUMNS_COUNT = 4;
85
86
87 HYDROGUI_StricklerTableDlg::HYDROGUI_StricklerTableDlg( HYDROGUI_Module* theModule, const QString& theTitle, int theType )
88 : HYDROGUI_InputPanel( theModule, theTitle ),
89   myType( theType )
90 {
91     QString fileGroupTitle = theType == Export ? tr( "EXPORT_STRICKLER_TABLE_FILE" ) : tr( "IMPORT_STRICKLER_TABLE_FILE" );
92
93     // Import Strickler table from file
94     QGroupBox* aFileNameGroup = new QGroupBox( fileGroupTitle, this );
95     aFileNameGroup->setVisible( theType != Edit );
96
97     QLabel* aFileNameLabel = new QLabel( tr( "FILE_NAME" ), aFileNameGroup );
98
99     myFileName = new QLineEdit( aFileNameGroup );
100     myFileName->setReadOnly( true );
101
102     QToolButton* aBrowseBtn = new QToolButton( aFileNameGroup );
103 #ifndef LIGHT_MODE
104     SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
105     aBrowseBtn->setIcon( aResMgr->loadPixmap( "HYDRO", tr( "BROWSE_ICO" ) ) );
106 #endif
107
108     QBoxLayout* aFileNameLayout = new QHBoxLayout( aFileNameGroup );
109     aFileNameLayout->setMargin( 5 );
110     aFileNameLayout->setSpacing( 5 );
111     aFileNameLayout->addWidget( aFileNameLabel );
112     aFileNameLayout->addWidget( myFileName );
113     aFileNameLayout->addWidget( aBrowseBtn );
114
115     // Strickler table name
116     QGroupBox* aNameGroup = new QGroupBox( tr( "STRICKLER_TABLE_NAME" ), this );
117
118     QLabel* anImageNameLabel = new QLabel( tr( "NAME" ), aNameGroup );
119     myName = new QLineEdit( aNameGroup );
120
121     QGroupBox* aAttrNameGroup = new QGroupBox( tr( "STRICKLER_TABLE_ATTR_NAME" ), this );
122     aAttrNameGroup->setVisible( theType == Edit );
123     QLabel* aAttrNameLabel = new QLabel( tr( "ATTR_NAME" ), aAttrNameGroup );
124     myAttrName = new QLineEdit( aAttrNameGroup );
125
126     QBoxLayout* anImageNameLayout = new QHBoxLayout( aNameGroup );
127     anImageNameLayout->setMargin( 5 );
128     anImageNameLayout->setSpacing( 5 );
129     anImageNameLayout->addWidget( anImageNameLabel );
130     anImageNameLayout->addWidget( myName );
131
132     QBoxLayout* anAttrNameLayout = new QHBoxLayout( aAttrNameGroup );
133     anAttrNameLayout->setMargin( 5 );
134     anAttrNameLayout->setSpacing( 5 );
135     anAttrNameLayout->addWidget( aAttrNameLabel );
136     anAttrNameLayout->addWidget( myAttrName );
137
138     // Strickler table
139     QGroupBox* aTableGroup = new QGroupBox( tr( "STRICKLER_TABLE_TABLE" ), this );
140     aTableGroup->setVisible( theType == Edit );
141
142     // Main layout
143     QVBoxLayout* aTableLayout = new QVBoxLayout( aTableGroup );
144     aTableLayout->setMargin( 5 );
145     aTableLayout->setSpacing( 5 );
146
147     // Buttons
148     myAddBtn = new QToolButton;
149     myAddBtn->setText( tr( "ADD" ) );
150     myRemoveBtn = new QToolButton;
151     myRemoveBtn->setText( tr( "REMOVE" ) );
152     myClearBtn = new QToolButton;
153     myClearBtn->setText( tr( "CLEAR_ALL" ) );
154
155     // Table
156     myTable = new QTableWidget( mainFrame() );
157     myTable->setItemDelegateForColumn( 1, new HYDROGUI_LineEditDoubleValidator( this ) );
158     myTable->setItemDelegateForColumn( 3, new HYDROGUI_ColorDelegate( this ) );
159     myTable->setEditTriggers( QAbstractItemView::DoubleClicked |
160         QAbstractItemView::SelectedClicked |
161         QAbstractItemView::EditKeyPressed );
162
163     myTable->setColumnCount( COLUMNS_COUNT );
164
165     QStringList aColumnNames;
166     aColumnNames << tr( "STRICKLER_TYPE" ) << tr( "STRICKLER_COEFFICIENT" ) << tr( "ATTR_VALUE" ) << tr( "COLOR" );
167     myTable->setHorizontalHeaderLabels( aColumnNames );
168
169     myTable->horizontalHeader()->setStretchLastSection( false );
170     myTable->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Interactive );
171     myTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Interactive );
172     myTable->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Interactive );
173     myTable->horizontalHeader()->setSectionResizeMode( 3, QHeaderView::Interactive );
174     myTable->verticalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents );
175
176     const int default_size = 50;
177     myTable->horizontalHeader()->setMinimumSectionSize( default_size  );
178     myTable->horizontalHeader()->resizeSection( 0, 300 );
179     myTable->horizontalHeader()->resizeSection( 1, 75 );
180     myTable->horizontalHeader()->resizeSection( 2, 75 );
181     myTable->horizontalHeader()->resizeSection( 3, 75 );
182
183     // Layout
184     // buttons
185     QHBoxLayout* aButtonsLayout = new QHBoxLayout();
186     aButtonsLayout->addWidget( myAddBtn );
187     aButtonsLayout->addWidget( myRemoveBtn );
188     aButtonsLayout->addStretch( 1 );
189     aButtonsLayout->addWidget( myClearBtn );
190
191     // main
192     aTableLayout->addLayout( aButtonsLayout );
193     aTableLayout->addWidget( myTable );
194
195     // Common
196     addWidget( aFileNameGroup );
197     addWidget( aNameGroup );
198     addWidget( aAttrNameGroup );
199     addWidget( aTableGroup );
200
201     // Update controls
202     updateControls();
203
204     // Connections
205     connect( aBrowseBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
206     connect( myAddBtn, SIGNAL( clicked() ), this, SLOT( onAddCoefficient() ) );
207     connect( myRemoveBtn, SIGNAL( clicked() ), this, SLOT( onRemoveCoefficient() ) );
208     connect( myClearBtn, SIGNAL( clicked() ), this, SLOT( onClearCoefficients() ) );
209     connect( myTable->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), 
210         this, SLOT( onSelectionChanged() ) );  
211
212     setMinimumWidth( 450 );
213
214     if ( theType != Edit )
215         addStretch();
216 }
217
218 HYDROGUI_StricklerTableDlg::~HYDROGUI_StricklerTableDlg()
219 {
220 }
221
222 void HYDROGUI_StricklerTableDlg::reset()
223 {
224     myFileName->clear();
225
226     myName->clear();
227 }
228
229 QString HYDROGUI_StricklerTableDlg::getFileName() const
230 {
231     return myFileName->text();
232 }
233
234 void HYDROGUI_StricklerTableDlg::setFileName( const QString& theName )
235 {
236     myFileName->setText( theName );
237 }
238
239 void HYDROGUI_StricklerTableDlg::setTableName( const QString& theName )
240 {
241     myName->setText(theName);
242 }
243
244 QString HYDROGUI_StricklerTableDlg::getTableName() const
245 {
246     return myName->text();
247 }
248
249 bool HYDROGUI_StricklerTableDlg::isTableNameReadOnly() const
250 {
251     return myName->isReadOnly();
252 }
253
254 void HYDROGUI_StricklerTableDlg::setTableNameReadOnly( bool on )
255 {
256     myName->setReadOnly( on );
257 }
258
259 void HYDROGUI_StricklerTableDlg::getGuiData( Handle(HYDROData_StricklerTable)& theTable ) const
260 {
261   if( theTable.IsNull() )
262     return;
263
264   theTable->SetAttrName( myAttrName->text() );
265   theTable->Clear();
266   for ( int i = 0; i < myTable->rowCount(); i++ )
267   {
268     QTableWidgetItem* typeItem = myTable->item( i, 0 );
269     QString aType = typeItem->data( Qt::DisplayRole ).toString();
270
271     QTableWidgetItem* coeffItem = myTable->item( i, 1 );
272     QString aCoeffStr = coeffItem->data( Qt::DisplayRole ).toString();
273     double aCoeff = aCoeffStr.toDouble();
274
275     QTableWidgetItem* attrValueItem = myTable->item( i, 2 );
276     QString anAttrValue = attrValueItem->data( Qt::DisplayRole ).toString();
277
278     QTableWidgetItem* colorItem = myTable->item( i, 3 );
279     QColor aColor = colorItem->backgroundColor();
280
281     theTable->Set( aType, aCoeff );
282     theTable->SetAttrValue( aType, anAttrValue );
283     theTable->SetColor( aType, aColor );
284   }
285 }
286
287 void HYDROGUI_StricklerTableDlg::setGuiData( const Handle(HYDROData_StricklerTable)& theTable )
288 {
289   myAttrName->setText( theTable->GetAttrName() );
290
291   if( theTable.IsNull() )
292   {
293     myTable->setRowCount( 0 );
294     return;
295   }
296
297   QStringList aTypes = theTable->GetTypes();
298   myTable->setRowCount( 0 );
299   foreach( QString aType, aTypes )
300   {
301     // Check the current Strickler type
302     if( aType.isEmpty() )
303       continue;
304
305     // Get Strickler data for the current Strickler type
306     QString aCoefficient = HYDROGUI_Tool::GetCoordinateString( theTable->Get( aType, 0.0 ), false );
307     QString anAttrValue = theTable->GetAttrValue( aType );
308     QColor aColor = theTable->GetColor( aType );
309
310     // Insert row with the data
311     int aRow = myTable->rowCount();
312     myTable->insertRow( aRow );
313
314     // "Type" column
315     QTableWidgetItem* aTypeItem = new QTableWidgetItem( aType );    
316     myTable->setItem( aRow, 0, aTypeItem );
317
318     // "Coefficient" column
319     myTable->setItem( aRow, 1, new QTableWidgetItem( aCoefficient ) );
320
321     // "Attribute value" column
322     myTable->setItem( aRow, 2, new QTableWidgetItem( anAttrValue ) );
323
324     // "Color" column
325     QTableWidgetItem* anItem = new QTableWidgetItem();
326     anItem->setBackgroundColor( aColor );
327     myTable->setItem( aRow, 3, anItem );
328   }
329
330   //myTable->resizeColumnToContents( 0 );
331   myTable->resizeRowsToContents();
332
333   updateControls();
334 }
335
336 void HYDROGUI_StricklerTableDlg::updateControls()
337 {
338     bool isTableNotEmpty = myTable->rowCount() > 0;
339     myClearBtn->setEnabled( isTableNotEmpty );  
340     onSelectionChanged();
341 }
342
343 void HYDROGUI_StricklerTableDlg::removeRows( const QList<int> theRows )
344 {
345     QList<int> aSortedRows = theRows;
346     qSort( aSortedRows );
347
348     int aRowToRemove = -1;
349     int aNbRemoved = 0;
350     foreach ( int aRow, aSortedRows ) {
351         aRowToRemove = aRow - aNbRemoved;
352         if ( myTable->model()->removeRow( aRowToRemove ) ) {
353             aNbRemoved++;
354         }
355     }
356
357     if ( aNbRemoved > 0 )
358         updateControls();
359 }
360
361 void HYDROGUI_StricklerTableDlg::onBrowse()
362 {
363     QString aFilter( tr( "STRICKLER_TABLE_FILTER" ) );
364     QString aFileName = SUIT_FileDlg::getFileName( this, "", aFilter, myFileName->parent()->property( "title" ).toString(), myType == Import );
365     if ( !aFileName.isEmpty() )
366     {
367         setFileName( aFileName );
368         emit fileSelected( aFileName );
369     }
370 }
371
372 /**
373 Add the new default constructed Strickler coefficient.
374 */
375 void HYDROGUI_StricklerTableDlg::onAddCoefficient()
376 {
377     int aRow = myTable->rowCount();
378     myTable->insertRow( aRow );
379
380     for( int i=0; i<COLUMNS_COUNT; i++ )
381     {
382       myTable->setItem( aRow, i, new QTableWidgetItem() );
383     }
384
385     // Set default type (=> generate unique type name) and coefficient
386     //...
387
388     updateControls();  
389 }
390
391 /**
392 Remove the selected Strickler coefficient.
393 */
394 void HYDROGUI_StricklerTableDlg::onRemoveCoefficient()
395 {
396     QList<int> aRows;
397     QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedIndexes();
398     foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
399       int aRowIndex = anIndex.row();
400       if ( !aRows.contains( aRowIndex ) )
401         aRows << aRowIndex;
402     }
403
404     removeRows( aRows );
405 }
406
407 /**
408 Clear all Strickler coefficients.
409 */
410 void HYDROGUI_StricklerTableDlg::onClearCoefficients()
411 {
412     QList<int> aRows;
413     for ( int i=0; i< myTable->rowCount(); i++ ) {
414         aRows << i;
415     }
416
417     removeRows( aRows );
418 }
419
420 /**
421 Slot called on table selection change.
422 */
423 void HYDROGUI_StricklerTableDlg::onSelectionChanged()
424 {
425     QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedIndexes();
426     myRemoveBtn->setEnabled( aSelectedIndexes.count() > 0 );
427 }