Salome HOME
Merge remote-tracking branch 'origin/BR_IMPROVEMENTS' into BR_v14_rc
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_PriorityWidget.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_PriorityWidget.h"
20
21 #include "HYDROGUI_PriorityTableModel.h"
22
23 #include "HYDROData_PriorityQueue.h"
24
25 #include <SUIT_MessageBox.h>
26
27 #include <QComboBox>
28 #include <QHeaderView>
29 #include <QLayout>
30 #include <QTableView>
31 #include <QToolButton>
32
33
34 /**
35   Constructor.
36   @param theParent the parent object
37  */
38 HYDROGUI_PriorityWidget::Delegate::Delegate( QObject* theParent )
39  : QStyledItemDelegate( theParent )
40 {
41 }
42
43 /**
44  */
45 QWidget* HYDROGUI_PriorityWidget::Delegate::createEditor( 
46   QWidget* theParent, const QStyleOptionViewItem& theOption,
47   const QModelIndex& theIndex ) const
48 {
49   QComboBox* aComboBox = new QComboBox( theParent );
50
51   if ( theIndex.column() == 1 || theIndex.column() == 3 ) {
52     QMap<QString, QVariant> aMap = theIndex.data( Qt::UserRole ).toMap();
53     foreach ( QString aText, aMap.keys() ) {
54       aComboBox->addItem( aText, aMap.value( aText ).toInt() );
55     }
56   } else if ( theIndex.column() == 0 || theIndex.column() ==  2 ) {
57     QStringList anObjNames = theIndex.data( Qt::UserRole ).toStringList();
58     aComboBox->addItems( anObjNames );
59   }
60   
61   connect( aComboBox, SIGNAL( activated( int ) ), this, SLOT( finishEditing() ) );
62
63   return aComboBox;
64 }
65
66 /**
67  */
68 void HYDROGUI_PriorityWidget::Delegate::setEditorData( 
69   QWidget* theEditor, const QModelIndex& theIndex ) const
70 {
71   QComboBox* aComboBox = dynamic_cast<QComboBox*>( theEditor );
72
73   if ( aComboBox ) {
74     int anIndex = -1;
75
76     if ( theIndex.column() == 0 || theIndex.column() == 2 ) {
77       QString aText = theIndex.data( Qt::EditRole ).toString();
78       anIndex = aComboBox->findText( aText );
79     } else {
80       QVariant aData = theIndex.data( Qt::EditRole ).toInt();
81       anIndex = aComboBox->findData( aData );
82     }
83
84     if ( anIndex >= 0 ) {
85       aComboBox->setCurrentIndex( anIndex );
86     }
87   }
88 }
89
90 /**
91  */
92 void HYDROGUI_PriorityWidget::Delegate::setModelData( 
93   QWidget* theEditor, QAbstractItemModel* theModel, const QModelIndex& theIndex) const
94 {
95   QComboBox* aComboBox = dynamic_cast<QComboBox*>( theEditor );
96
97   if ( aComboBox ) {
98     int aColumn = theIndex.column();
99     if ( aColumn == 0 || aColumn == 2 ) {
100       QString aCurrentText = theIndex.data( Qt::EditRole ).toString();
101       QString aNewText = aComboBox->currentText();
102       if ( aNewText != aCurrentText ) {
103         theModel->setData( theIndex, aNewText );
104       }
105     } else {
106       theModel->setData( theIndex, aComboBox->itemData( aComboBox->currentIndex() ) );
107     }
108   }
109 }
110
111 /**
112  Emit signal indicating that the user has finished editing.
113  */
114 void HYDROGUI_PriorityWidget::Delegate::finishEditing()
115 {
116   QWidget* anEditor = qobject_cast<QWidget*>( sender() );
117   if ( anEditor ) {
118     emit commitData( anEditor );
119     emit closeEditor( anEditor );
120   }
121 }
122
123
124 /**
125   Constructor.
126   @param theParent the parent widget
127  */
128 HYDROGUI_PriorityWidget::HYDROGUI_PriorityWidget( QWidget* theParent )
129 : QWidget( theParent )
130 {
131   // Main layout
132   QVBoxLayout* aMainLayout = new QVBoxLayout( this );
133   aMainLayout->setMargin( 0 );
134   aMainLayout->setSpacing( 5 );
135
136   // Buttons
137   myAdd = new QToolButton;
138   myAdd->setText( tr( "ADD" ) );
139   myRemove = new QToolButton;
140   myRemove->setText( tr( "REMOVE" ) );
141   myClear = new QToolButton;
142   myClear->setText( tr( "CLEAR_ALL" ) );
143   
144   // Table view
145   myTable = new QTableView( this );
146   myTable->setItemDelegate( new Delegate( this ) );
147   myTable->setEditTriggers( QAbstractItemView::DoubleClicked |
148                             QAbstractItemView::SelectedClicked |
149                             QAbstractItemView::EditKeyPressed );
150   
151   // Set the custom model
152   HYDROGUI_PriorityTableModel* aModel = new HYDROGUI_PriorityTableModel();
153   myTable->setModel( aModel );
154
155   // Set resize mode
156   myTable->horizontalHeader()->setStretchLastSection( false);
157   myTable->horizontalHeader()->setResizeMode( 0, QHeaderView::Stretch );
158   myTable->horizontalHeader()->setResizeMode( 1, QHeaderView::ResizeToContents );
159   myTable->horizontalHeader()->setResizeMode( 2, QHeaderView::Stretch );
160   myTable->horizontalHeader()->setResizeMode( 3, QHeaderView::ResizeToContents );
161
162   myTable->verticalHeader()->setResizeMode( QHeaderView::ResizeToContents );
163  
164   // Layout
165   // buttons
166   QHBoxLayout* aButtonsLayout = new QHBoxLayout();
167   aButtonsLayout->addWidget( myAdd );
168   aButtonsLayout->addWidget( myRemove );
169   aButtonsLayout->addStretch( 1 );
170   aButtonsLayout->addWidget( myClear );
171
172   // main
173   aMainLayout->addLayout( aButtonsLayout );
174   aMainLayout->addWidget( myTable );
175   
176   // Update controls
177   updateControls();
178
179   // Connections
180   connect( myAdd, SIGNAL( clicked() ), this, SLOT( onAddRule() ) );
181   connect( myRemove, SIGNAL( clicked() ), this, SLOT( onRemoveRule() ) );
182   connect( myClear, SIGNAL( clicked() ), this, SLOT( onClearRules() ) );
183
184   connect ( myTable->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), 
185             this, SLOT( onSelectionChanged() ) );
186
187   connect( aModel, SIGNAL( showError( const QString& ) ), this, SLOT( onShowError( const QString& ) ) );
188 }
189
190 /**
191   Destructor.
192  */
193 HYDROGUI_PriorityWidget::~HYDROGUI_PriorityWidget()
194 {
195 }
196
197 /**
198   Add the new default constructed rule.
199  */
200 void HYDROGUI_PriorityWidget::onAddRule()
201 {
202   HYDROGUI_PriorityTableModel* aModel = 
203     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
204   if ( aModel ) {
205     if (aModel->createNewRule()) {
206       updateControls();
207     }
208   }
209 }
210
211 /**
212   Remove the selected rule.
213  */
214 void HYDROGUI_PriorityWidget::onRemoveRule()
215 {
216   HYDROGUI_PriorityTableModel* aModel = 
217     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
218
219   if (aModel) {
220     QList<int> aRows;
221
222     QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedRows();
223     foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
224       aRows << anIndex.row();
225     }
226     
227     if ( aModel->removeRows( aRows ) ) {
228       updateControls();
229     }
230   }
231 }
232
233 /**
234   Clear all rules.
235  */
236 void HYDROGUI_PriorityWidget::onClearRules()
237 {
238   HYDROGUI_PriorityTableModel* aModel = 
239     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
240   if ( aModel && aModel->removeAll() ) {
241     updateControls();
242   }
243 }
244
245 /**
246   Set objects which could be used for rules definition.
247   @param theObjects the ordered list of objects
248  */
249 void HYDROGUI_PriorityWidget::setObjects( const QList<Handle(HYDROData_Object)>& theObjects )
250 {
251   HYDROGUI_PriorityTableModel* aModel = 
252     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
253   if( aModel ) {
254     aModel->setObjects( theObjects );
255     updateControls();
256   }
257 }
258
259 /**
260   Get rules.
261   @return the list of rules
262  */
263 HYDROData_ListOfRules HYDROGUI_PriorityWidget::getRules() const
264 {
265   HYDROData_ListOfRules aRules;
266
267   HYDROGUI_PriorityTableModel* aModel = 
268     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
269   if( aModel ) {
270     aRules = aModel->getRules();
271   }
272
273   return aRules;
274 }
275
276 /**
277   Set rules.
278   @param theRules the list of rules
279 */
280 void HYDROGUI_PriorityWidget::setRules( const HYDROData_ListOfRules& theRules )
281 {
282   HYDROGUI_PriorityTableModel* aModel = 
283     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
284   if( aModel ) {
285     aModel->setRules( theRules );
286     updateControls();
287   }
288 }
289
290 /**
291  Slot called on table selection change.
292 */
293 void HYDROGUI_PriorityWidget::onSelectionChanged()
294 {
295   QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedRows();
296   myRemove->setEnabled( aSelectedIndexes.count() > 0 );
297 }
298
299 /**
300  Update GUI controls state.
301  */
302 void HYDROGUI_PriorityWidget::updateControls()
303 {
304   HYDROGUI_PriorityTableModel* aModel = 
305     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
306   if( aModel ) {
307     myAdd->setEnabled( aModel->canCreateNewRule() );
308     bool isTableNotEmpty = aModel->rowCount() > 0;
309     myClear->setEnabled( isTableNotEmpty );
310   }
311   onSelectionChanged();
312 }
313
314 /**
315  Show error message.
316  */
317 void HYDROGUI_PriorityWidget::onShowError( const QString& theMsg ) {
318   SUIT_MessageBox::warning( this, tr( "INCORRECT_INPUT" ), theMsg );
319 }