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