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