Salome HOME
Merge branch 'BR_v14_rc' of ssh://git.salome-platform.org/modules/hydro 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   connect( aModel, SIGNAL( ruleChanged() ), this, SIGNAL( ruleChanged() ) );
189 }
190
191 /**
192   Destructor.
193  */
194 HYDROGUI_PriorityWidget::~HYDROGUI_PriorityWidget()
195 {
196 }
197
198 /**
199   Add the new default constructed rule.
200  */
201 void HYDROGUI_PriorityWidget::onAddRule()
202 {
203   HYDROGUI_PriorityTableModel* aModel = 
204     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
205   if ( aModel ) {
206     if (aModel->createNewRule()) {
207       updateControls();
208       emit ruleChanged();
209     }
210   }
211 }
212
213 /**
214   Remove the selected rule.
215  */
216 void HYDROGUI_PriorityWidget::onRemoveRule()
217 {
218   HYDROGUI_PriorityTableModel* aModel = 
219     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
220
221   if (aModel) {
222     QList<int> aRows;
223
224     QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedRows();
225     foreach ( const QModelIndex& anIndex, aSelectedIndexes ) {
226       aRows << anIndex.row();
227     }
228     
229     if ( aModel->removeRows( aRows ) ) {
230       updateControls();
231       emit ruleChanged();
232     }
233   }
234 }
235
236 /**
237   Clear all rules.
238  */
239 void HYDROGUI_PriorityWidget::onClearRules()
240 {
241   HYDROGUI_PriorityTableModel* aModel = 
242     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
243   if ( aModel && aModel->removeAll() ) {
244     updateControls();
245     emit ruleChanged();
246   }
247 }
248
249 /**
250   Set objects which could be used for rules definition.
251   @param theObjects the ordered list of objects
252  */
253 void HYDROGUI_PriorityWidget::setObjects( const QList<Handle(HYDROData_Entity)>& theObjects )
254 {
255   HYDROGUI_PriorityTableModel* aModel = 
256     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
257   if( aModel ) {
258     aModel->setObjects( theObjects );
259     updateControls();
260   }
261 }
262
263 /**
264   Get rules.
265   @return the list of rules
266  */
267 HYDROData_ListOfRules HYDROGUI_PriorityWidget::getRules() const
268 {
269   HYDROData_ListOfRules aRules;
270
271   HYDROGUI_PriorityTableModel* aModel = 
272     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
273   if( aModel ) {
274     aRules = aModel->getRules();
275   }
276
277   return aRules;
278 }
279
280 /**
281   Set rules.
282   @param theRules the list of rules
283 */
284 void HYDROGUI_PriorityWidget::setRules( const HYDROData_ListOfRules& theRules )
285 {
286   HYDROGUI_PriorityTableModel* aModel = 
287     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
288   if( aModel ) {
289     aModel->setRules( theRules );
290     updateControls();
291   }
292 }
293
294 /**
295   Get table view.
296   @return the table view
297  */
298 QTableView* HYDROGUI_PriorityWidget::getTable() const
299 {
300   return myTable;
301 }
302
303 /**
304  Slot called on table selection change.
305 */
306 void HYDROGUI_PriorityWidget::onSelectionChanged()
307 {
308   QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedRows();
309   myRemove->setEnabled( aSelectedIndexes.count() > 0 );
310 }
311
312 /**
313  Update GUI controls state.
314  */
315 void HYDROGUI_PriorityWidget::updateControls()
316 {
317   HYDROGUI_PriorityTableModel* aModel = 
318     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
319   if( aModel ) {
320     myAdd->setEnabled( aModel->canCreateNewRule() );
321     bool isTableNotEmpty = aModel->rowCount() > 0;
322     myClear->setEnabled( isTableNotEmpty );
323   }
324   onSelectionChanged();
325 }
326
327 /**
328  Show error message.
329  */
330 void HYDROGUI_PriorityWidget::onShowError( const QString& theMsg ) {
331   SUIT_MessageBox::warning( this, tr( "INCORRECT_INPUT" ), theMsg );
332 }
333
334 /**
335  Undo last change in priority rules table.
336  */
337 void HYDROGUI_PriorityWidget::undoLastChange()
338 {
339   HYDROGUI_PriorityTableModel* aModel = 
340     dynamic_cast<HYDROGUI_PriorityTableModel*>( myTable->model() );
341   if ( aModel )
342     aModel->undoLastChange();
343 }