Optika GUI Toolik  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Optika_delegate.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Optika: A Tool For Developing Parameter Obtaining GUIs
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, with Sandia Corporation, the
8 // U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Kurtis Nusbaum (klnusbaum@gmail.com)
38 //
39 // ***********************************************************************
40 // @HEADER
41 #include <QtGui>
42 #include <QSpinBox>
43 #include <QDoubleSpinBox>
44 #include <QLineEdit>
45 #include <QComboBox>
46 #include <QFileDialog>
47 #include "Optika_delegate.hpp"
49 
50 namespace Optika{
51 
52 Delegate::Delegate(QObject *parent):QItemDelegate(parent){}
53 
54 QWidget* Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/ , const QModelIndex &index ) const{
55  QWidget *editor = 0;
56  if(index.column() != 1)
57  return editor;
58 
59  RCP<const ParameterEntryValidator> paramValidator = ((TreeModel*)(index.model()))->getValidator(index);
60  QString itemType = ((TreeModel*)(index.model()))->itemType(index);
61 
62  if(itemType == intId){
63  editor = new QSpinBox(parent);
65  if(!is_null(paramValidator)){
66  intValidator = rcp_dynamic_cast<const EnhancedNumberValidator<int> >(paramValidator);
67  }
68  ValidatorApplier<int>::applyToSpinBox(intValidator, (QSpinBox*)editor);
69  }
70  else if(itemType == shortId){
71  editor = new QSpinBox(parent);
73  if(!is_null(paramValidator)){
74  shortValidator = rcp_dynamic_cast<const EnhancedNumberValidator<short> >(paramValidator);
75  }
76  ValidatorApplier<short>::applyToSpinBox(shortValidator, (QSpinBox*)editor);
77  }
78 /* else if(itemType == longlongId){
79  editor = new QwwLongSpinBox(parent);
80  RCP<const EnhancedNumberValidator<long long> > longlongValidator;
81  if(!is_null(paramValidator)){
82  longlongValidator = rcp_dynamic_cast<const EnhancedNumberValidator<long long> >(paramValidator);
83  }
84  EnhancedNumberValidator<long long>::applyToSpinBox(longlongValidator, (QDoubleSpinBox*)editor);
85  }*/
86  else if(itemType == doubleId){
87  //editor = new QLineEdit(parent);
88  editor = new QLineEdit(parent);
90  if(!is_null(paramValidator)){
91  doubleValidator = rcp_dynamic_cast<const EnhancedNumberValidator<double> >(paramValidator);
92  }
93  ValidatorApplier<double>::applyToLineEdit(doubleValidator, (QLineEdit*)editor);
94  }
95  else if(itemType == floatId){
96  editor = new QLineEdit(parent);
98  if(!is_null(paramValidator)){
99  floatValidator = rcp_dynamic_cast<const EnhancedNumberValidator<float> >(paramValidator);
100  }
101  ValidatorApplier<float>::applyToLineEdit(floatValidator, (QLineEdit*)editor);
102  }
103  else if(itemType == boolId){
104  editor = new QComboBox(parent);
105  static_cast<QComboBox*>(editor)->addItem(getBoolEditorTrue());
106  static_cast<QComboBox*>(editor)->addItem(getBoolEditorFalse());
107  }
108  else if(itemType == stringId){
109  if(is_null(paramValidator)){
110  editor = new QLineEdit(parent);
111  }
112  else if(!is_null(rcp_dynamic_cast<const FileNameValidator>(paramValidator))){
113  QString paramName =
114  ((TreeModel*)(index.model()))->data(index.sibling(index.row(), 0),Qt::DisplayRole).toString();
115  QString currentPath = ((TreeModel*)(index.model()))->data(index,Qt::DisplayRole).toString();
116  if(currentPath.size() == 0){
117  currentPath = QDir::homePath();
118  }
119  // Hack.
120  if(paramName.indexOf("Input Directory", 0, Qt::CaseInsensitive) > -1 ||
121  paramName.indexOf("Output Directory", 0, Qt::CaseInsensitive) > -1){
122  QString dirname = QFileDialog::getExistingDirectory(parent, paramName,
123  currentPath, QFileDialog::ShowDirsOnly);
124  if(dirname != ""){
125  ((TreeModel*)(index.model()))->setData(index, dirname);
126  }
127  }
128  else{
129  QString filename;
130  if(rcp_dynamic_cast<const FileNameValidator>(paramValidator)->fileMustExist()){
131  filename = QFileDialog::getOpenFileName(parent, paramName, currentPath);
132  }
133  else{
134  filename = QFileDialog::getSaveFileName(parent, paramName, currentPath);
135  }
136  if(filename != ""){
137  ((TreeModel*)(index.model()))->setData(index, filename);
138  }
139  }
140  }
141  else if(paramValidator->validStringValues()->size() != 0){
142  RCP<const Array<std::string> > options = paramValidator->validStringValues();
143  editor = new QComboBox(parent);
144  for(Array<std::string>::const_iterator itr = options->begin(); itr != options->end(); ++itr){
145  static_cast<QComboBox*>(editor)->addItem(QString::fromStdString(*itr));
146  }
147  }
148  else{
149  editor = new QLineEdit(parent);
150  }
151  }
152  else if(itemType.contains(arrayId)){
153  editor = getArrayEditor(index, getArrayType(itemType), parent);
154  }
155  else if(itemType.contains(twoDArrayId)){
156  editor = getArrayEditor(index, getArrayType(itemType), parent, true);
157  }
158 
159  return editor;
160 }
161 
162 void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const{
163  QString itemType = ((TreeModel*)(index.model()))->itemType(index);
164  QVariant value = index.model()->data(index);
165  if(itemType == intId){
166  static_cast<QSpinBox*>(editor)->setValue(value.toInt());
167  }
168  else if(itemType == shortId){
169  static_cast<QSpinBox*>(editor)->setValue(value.toInt());
170  }
171  else if(itemType == doubleId){
172  static_cast<QLineEdit*>(editor)->setText(value.toString());
173  }
174  else if(itemType == floatId){
175  static_cast<QLineEdit*>(editor)->setText(value.toString());
176  }
177  else if(itemType == boolId){
178  static_cast<QComboBox*>(editor)->setEditText(value.toString());
179  }
180  else if(itemType == stringId){
181  RCP<const ParameterEntryValidator> validator = ((TreeModel*)(index.model()))->getValidator(index);
182  if(is_null(validator) || validator->validStringValues()->size()==0)
183  static_cast<QLineEdit*>(editor)->setText(value.toString());
184  else
185  static_cast<QComboBox*>(editor)->setEditText(value.toString());
186  }
187  else if(itemType.contains(arrayId)){
188  setArrayWidgetData(editor, getArrayType(itemType), index);
189  }
190  else if(itemType.contains(twoDArrayId)){
191  setArrayWidgetData(editor, getArrayType(itemType), index, true);
192  }
193 }
194 
195 void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const{
196  QString itemType = ((TreeModel*)(index.model()))->itemType(index);
197  if(itemType == intId){
198  QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
199  spinBox->interpretText();
200  model->setData(index, spinBox->value(), Qt::EditRole);
201  }
202  else if(itemType == shortId){
203  QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
204  spinBox->interpretText();
205  model->setData(index, (short)spinBox->value(), Qt::EditRole);
206  }
207  else if(itemType == doubleId){
208  QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
209  model->setData(index, lineEdit->text(), Qt::EditRole);
210  }
211  else if(itemType == floatId){
212  QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
213  model->setData(index, lineEdit->text(), Qt::EditRole);
214  }
215  else if(itemType == boolId){
216  bool value = static_cast<QComboBox*>(editor)->currentText()
217  == getBoolEditorTrue();
218  model->setData(index, value, Qt::EditRole);
219  }
220  else if(itemType == stringId){
222  static_cast<const TreeModel*>(index.model())->getValidator(index);
223  QString value;
224  if(is_null(validator)){
225  value = static_cast<QLineEdit*>(editor)->text();
226  }
227  else{
228  value = static_cast<QComboBox*>(editor)->currentText();
229  }
230  model->setData(index, value, Qt::EditRole);
231  }
232  else if(itemType.contains(arrayId)){
233  QVariant value = extractValueFromArray(editor, getArrayType(itemType));
234  model->setData(index, value, Qt::EditRole);
235  }
236  else if(itemType.contains(twoDArrayId)){
237  QVariant value = extractValueFromArray(editor, getArrayType(itemType), true);
238  model->setData(index, value, Qt::EditRole);
239  }
240 }
241 
242 
243 
244 void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const{
245  editor->setGeometry(option.rect);
246 }
247 
248 QWidget* Delegate::getArrayEditor(const QModelIndex& index, QString type, QWidget *parent, bool isTwoD) const{
249  TreeModel* model = (TreeModel*)index.model();
250  QString name = model->data(
251  index.sibling(index.row(),0),Qt::DisplayRole).toString();
253  model->getValidator(index);
254  if(type == intId){
255  if(isTwoD){
256  return new Int2DArrayWidget(name, type, validator, parent);
257  }
258  else{
259  return new IntArrayWidget(name, type, validator, parent);
260  }
261  }
262  else if(type == shortId){
263  if(isTwoD){
264  return new Short2DArrayWidget(name, type, validator, parent);
265  }
266  else{
267  return new ShortArrayWidget(name, type, validator, parent);
268  }
269  }
270  else if(type == doubleId){
271  if(isTwoD){
272  return new Double2DArrayWidget(name, type, validator, parent);
273  }
274  else{
275  return new DoubleArrayWidget(name, type, validator, parent);
276  }
277  }
278  else if(type == floatId){
279  if(isTwoD){
280  return new Float2DArrayWidget(name, type, validator, parent);
281  }
282  else{
283  return new FloatArrayWidget(name, type, validator, parent);
284  }
285  }
286  else if(type == stringId){
287  if(isTwoD){
288  return new String2DArrayWidget(name, type, validator, parent);
289  }
290  else{
291  return new StringArrayWidget(name, type, validator, parent);
292  }
293  }
294  else{
295  return 0;
296  }
297 }
298 
299 void Delegate::setArrayWidgetData(QWidget* editor, QString type, const QModelIndex& index, bool isTwoD) const{
300  QVariant newData = index.model()->data(index, TreeModel::getRawDataRole());
301  if(type == intId){
302  isTwoD ?
303  ((Int2DArrayWidget*)editor)->initData(newData.value<TwoDArray<int> >())
304  :
305  ((IntArrayWidget*)editor)->initData(newData.value<Array<int> >());
306  }
307  else if(type == shortId){
308  isTwoD ?
309  ((Short2DArrayWidget*)editor)->initData(newData.value<TwoDArray<short> >())
310  :
311  ((ShortArrayWidget*)editor)->initData(newData.value<Array<short> >());
312  }
313  else if(type == doubleId){
314  isTwoD ?
315  ((Double2DArrayWidget*)editor)->initData(newData.value<TwoDArray<double> >())
316  :
317  ((DoubleArrayWidget*)editor)->initData(newData.value<Array<double> >());
318  }
319  else if(type == floatId){
320  isTwoD ?
321  ((Float2DArrayWidget*)editor)->initData(newData.value<TwoDArray<float> >())
322  :
323  ((FloatArrayWidget*)editor)->initData(newData.value<Array<float> >());
324  }
325  else if(type == stringId){
326  isTwoD ?
327  ((String2DArrayWidget*)editor)->initData(newData.value<TwoDArray<std::string> >())
328  :
329  ((StringArrayWidget*)editor)->initData(newData.value<Array<std::string> >());
330  }
331 }
332 
333 QVariant Delegate::extractValueFromArray(QWidget* editor, QString type, bool isTwoD) const
334 {
335  if(type == intId){
336  return (isTwoD ?
337  QVariant::fromValue(((Int2DArrayWidget*)editor)->getData())
338  :
339  QVariant::fromValue(((IntArrayWidget*)editor)->getData()));
340  }
341  else if(type == shortId){
342  return (isTwoD ?
343  QVariant::fromValue(((Short2DArrayWidget*)editor)->getData())
344  :
345  QVariant::fromValue(((ShortArrayWidget*)editor)->getData()));
346  }
347  else if(type == doubleId){
348  return (isTwoD ?
349  QVariant::fromValue(((Double2DArrayWidget*)editor)->getData())
350  :
351  QVariant::fromValue(((DoubleArrayWidget*)editor)->getData()));
352  }
353  else if(type == floatId){
354  return (isTwoD ?
355  QVariant::fromValue(((Float2DArrayWidget*)editor)->getData())
356  :
357  QVariant::fromValue(((FloatArrayWidget*)editor)->getData()));
358  }
359  else if(type == stringId){
360  return (isTwoD ?
361  QVariant::fromValue(((String2DArrayWidget*)editor)->getData())
362  :
363  QVariant::fromValue(((StringArrayWidget*)editor)->getData()));
364  }
365  else{
366  return QVariant();
367  }
368 }
369 
370 } //End namespace
371 
The delegate used in the MVC framework for Optika.
A 2DArrayWidget used for editing arrays whose template type is short.
A widget for editing an array of strings.
QString shortId
bool is_null(const boost::shared_ptr< T > &p)
static const QString & getBoolEditorTrue()
Gets the value the delegate uses to represent "true" when constructing comboboxes for boolean paramet...
QString intId
A 2DArrayWidget used for editing arrays whose template type is std::string.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
A 2DArrayWidget used for editing arrays whose template type is float.
A widget for editing Arrays of type short.
A 1D widget for editing Arrays of type int.
A 2DArrayWidget used for editing arrays whose template type is double.
A 2DArrayWidget used for editing arrays whose template type is int.
std::string filename
void setArrayWidgetData(QWidget *editor, QString type, const QModelIndex &index, bool isTwoD=false) const
Sets the data in an array widget to the current values found at index.
static const QString & getBoolEditorFalse()
Gets the value the delegate uses to represent "false" when constructing comboboxes for boolean parame...
QVariant extractValueFromArray(QWidget *editor, QString type, bool isTwoD=false) const
Gets an array from an ArrayWidget and puts it into a QVariant.
QString floatId
QString twoDArrayId
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
Delegate(QObject *parent=0)
Constructs a Delegate.
A widget for editing Arrays of type short.
RCP< const ParameterEntryValidator > getValidator(const QModelIndex &index) const
Gets the validator for a particular TreeItem.
QString doubleId
static void applyToSpinBox(RCP< const EnhancedNumberValidator< S > > validator, QSpinBox *spinBox)
Applied attributes of the validator to the spin box.
QString stringId
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const
QString boolId
A widget for editing Arrays of type double.
static void applyToLineEdit(RCP< const EnhancedNumberValidator< S > > validator, QLineEdit *lineEdit)
QString arrayId
TreeModel is a type of QAbstractItemModel that has a Tree like structure.
QWidget * getArrayEditor(const QModelIndex &index, QString type, QWidget *parent, bool isTwoD=false) const
Creates an ArrayWidget to edit the parameter at the given QModelIndex.
QString getArrayType(QString itemType)
Given a type string, determines the template type of the Array.
static const int getRawDataRole()
Returns constant representing the RawDataRole.