Optika GUI Toolik Version of the Day
Optika_delegate.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //         Optika: A Tool For Developing Parameter Obtaining GUIs
00005 //                Copyright (2009) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, with Sandia Corporation, the 
00008 // U.S. Government retains certain rights in this software.
00009 // 
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kurtis Nusbaum (klnusbaum@gmail.com) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 #include <QtGui>
00042 #include <QSpinBox>
00043 #include <QDoubleSpinBox>
00044 #include <QLineEdit>
00045 #include <QComboBox>
00046 #include <QFileDialog>
00047 #include "Optika_delegate.hpp"
00048 #include "Teuchos_StandardParameterEntryValidators.hpp"
00049 
00050 namespace Optika{
00051 
00052 Delegate::Delegate(QObject *parent):QItemDelegate(parent){}
00053 
00054 QWidget* Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/ , const QModelIndex &index ) const{
00055   QWidget *editor = 0;
00056   if(index.column() != 1)
00057     return editor;
00058 
00059   RCP<const ParameterEntryValidator> paramValidator = ((TreeModel*)(index.model()))->getValidator(index);
00060   QString itemType = ((TreeModel*)(index.model()))->itemType(index);
00061 
00062   if(itemType == intId){
00063     editor = new QSpinBox(parent);
00064     RCP<const EnhancedNumberValidator <int> > intValidator;
00065     if(!is_null(paramValidator)){
00066       intValidator = rcp_dynamic_cast<const EnhancedNumberValidator<int> >(paramValidator);
00067     }
00068     ValidatorApplier<int>::applyToSpinBox(intValidator, (QSpinBox*)editor);
00069   }
00070   else if(itemType == shortId){
00071     editor = new QSpinBox(parent);
00072     RCP<const EnhancedNumberValidator<short> > shortValidator;
00073     if(!is_null(paramValidator)){
00074       shortValidator = rcp_dynamic_cast<const EnhancedNumberValidator<short> >(paramValidator);
00075     }
00076     ValidatorApplier<short>::applyToSpinBox(shortValidator, (QSpinBox*)editor);
00077   }
00078 /*  else if(itemType == longlongId){
00079     editor = new QwwLongSpinBox(parent);
00080     RCP<const EnhancedNumberValidator<long long> > longlongValidator;
00081     if(!is_null(paramValidator)){
00082       longlongValidator = rcp_dynamic_cast<const EnhancedNumberValidator<long long> >(paramValidator);
00083     }
00084     EnhancedNumberValidator<long long>::applyToSpinBox(longlongValidator, (QDoubleSpinBox*)editor);
00085   }*/
00086   else if(itemType == doubleId){
00087     //editor = new QLineEdit(parent);
00088     editor = new QLineEdit(parent);
00089     RCP<const EnhancedNumberValidator<double> > doubleValidator;
00090     if(!is_null(paramValidator)){
00091       doubleValidator = rcp_dynamic_cast<const EnhancedNumberValidator<double> >(paramValidator);
00092     }
00093     ValidatorApplier<double>::applyToLineEdit(doubleValidator, (QLineEdit*)editor);
00094   }
00095   else if(itemType == floatId){
00096     editor = new QLineEdit(parent);
00097     RCP<const EnhancedNumberValidator<float> > floatValidator; 
00098     if(!is_null(paramValidator)){
00099       floatValidator = rcp_dynamic_cast<const EnhancedNumberValidator<float> >(paramValidator);
00100     }
00101     ValidatorApplier<float>::applyToLineEdit(floatValidator, (QLineEdit*)editor);
00102   }
00103   else if(itemType == boolId){
00104     editor = new QComboBox(parent);
00105     static_cast<QComboBox*>(editor)->addItem(getBoolEditorTrue());
00106     static_cast<QComboBox*>(editor)->addItem(getBoolEditorFalse());
00107   }
00108   else if(itemType == stringId){
00109     if(is_null(paramValidator)){
00110       editor = new QLineEdit(parent);
00111     }
00112     else if(!is_null(rcp_dynamic_cast<const FileNameValidator>(paramValidator))){
00113       QString paramName = 
00114         ((TreeModel*)(index.model()))->data(index.sibling(index.row(), 0),Qt::DisplayRole).toString();
00115       QString currentPath = ((TreeModel*)(index.model()))->data(index,Qt::DisplayRole).toString();
00116       if(currentPath.size() == 0){
00117         currentPath = QDir::homePath();
00118       }
00119       // Hack.
00120       if(paramName.indexOf("Input Directory", 0, Qt::CaseInsensitive) > -1 ||
00121          paramName.indexOf("Output Directory", 0, Qt::CaseInsensitive) > -1){
00122         QString dirname = QFileDialog::getExistingDirectory(parent, paramName,
00123           currentPath, QFileDialog::ShowDirsOnly);
00124         if(dirname != ""){
00125           ((TreeModel*)(index.model()))->setData(index, dirname);
00126         }
00127       }
00128       else{
00129         QString filename;
00130         if(rcp_dynamic_cast<const FileNameValidator>(paramValidator)->fileMustExist()){
00131           filename = QFileDialog::getOpenFileName(parent, paramName, currentPath);
00132         }
00133         else{
00134           filename = QFileDialog::getSaveFileName(parent, paramName, currentPath);
00135         }
00136         if(filename != ""){
00137           ((TreeModel*)(index.model()))->setData(index, filename);
00138         }
00139       }
00140     }
00141     else if(paramValidator->validStringValues()->size() != 0){
00142       RCP<const Array<std::string> > options = paramValidator->validStringValues();
00143       editor = new QComboBox(parent);
00144       for(Array<std::string>::const_iterator itr = options->begin(); itr != options->end(); ++itr){
00145         static_cast<QComboBox*>(editor)->addItem(QString::fromStdString(*itr));
00146       }
00147     }
00148     else{
00149       editor = new QLineEdit(parent);
00150     }
00151   }
00152   else if(itemType.contains(arrayId)){
00153     editor = getArrayEditor(index, getArrayType(itemType), parent);
00154   }
00155   else if(itemType.contains(twoDArrayId)){
00156     editor = getArrayEditor(index, getArrayType(itemType), parent, true);
00157   }
00158 
00159   return editor;
00160 }
00161 
00162 void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const{
00163   QString itemType = ((TreeModel*)(index.model()))->itemType(index);
00164   QVariant value = index.model()->data(index);
00165   if(itemType == intId){
00166     static_cast<QSpinBox*>(editor)->setValue(value.toInt());
00167   }
00168   else if(itemType == shortId){
00169     static_cast<QSpinBox*>(editor)->setValue(value.toInt());
00170   }
00171   else if(itemType == doubleId){
00172     static_cast<QLineEdit*>(editor)->setText(value.toString());
00173   }
00174   else if(itemType == floatId){
00175     static_cast<QLineEdit*>(editor)->setText(value.toString());
00176   }
00177   else if(itemType == boolId){
00178     static_cast<QComboBox*>(editor)->setEditText(value.toString());
00179   }
00180   else if(itemType == stringId){
00181     RCP<const ParameterEntryValidator> validator = ((TreeModel*)(index.model()))->getValidator(index);
00182     if(is_null(validator) || validator->validStringValues()->size()==0)
00183       static_cast<QLineEdit*>(editor)->setText(value.toString());
00184     else
00185       static_cast<QComboBox*>(editor)->setEditText(value.toString());
00186   }
00187   else if(itemType.contains(arrayId)){
00188     setArrayWidgetData(editor, getArrayType(itemType), index);
00189   }
00190   else if(itemType.contains(twoDArrayId)){
00191     setArrayWidgetData(editor, getArrayType(itemType), index, true);
00192   }
00193 }
00194 
00195 void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const{
00196   QString itemType = ((TreeModel*)(index.model()))->itemType(index);
00197   if(itemType == intId){
00198     QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
00199     spinBox->interpretText();
00200     model->setData(index, spinBox->value(), Qt::EditRole);
00201   }
00202   else if(itemType == shortId){
00203     QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
00204     spinBox->interpretText();
00205     model->setData(index, (short)spinBox->value(), Qt::EditRole);
00206   }
00207   else if(itemType == doubleId){
00208     QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
00209     model->setData(index, lineEdit->text(), Qt::EditRole);
00210   }
00211   else if(itemType == floatId){
00212     QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
00213     model->setData(index, lineEdit->text(), Qt::EditRole);
00214   }
00215   else if(itemType == boolId){
00216     bool value = static_cast<QComboBox*>(editor)->currentText() 
00217       == getBoolEditorTrue(); 
00218     model->setData(index, value, Qt::EditRole);
00219   }
00220   else if(itemType == stringId){
00221     RCP<const ParameterEntryValidator> validator = 
00222       static_cast<const TreeModel*>(index.model())->getValidator(index);
00223     QString value;
00224     if(is_null(validator)){
00225       value = static_cast<QLineEdit*>(editor)->text();
00226     }
00227     else{
00228       value = static_cast<QComboBox*>(editor)->currentText(); 
00229     }
00230     model->setData(index, value, Qt::EditRole);
00231   }
00232   else if(itemType.contains(arrayId)){
00233     QVariant value = extractValueFromArray(editor, getArrayType(itemType));
00234     model->setData(index, value, Qt::EditRole);
00235   }
00236   else if(itemType.contains(twoDArrayId)){
00237     QVariant value = extractValueFromArray(editor, getArrayType(itemType), true);
00238     model->setData(index, value, Qt::EditRole);
00239   }
00240 }
00241 
00242  
00243 
00244 void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const{
00245   editor->setGeometry(option.rect);
00246 }
00247 
00248 QWidget* Delegate::getArrayEditor(const QModelIndex& index, QString type, QWidget *parent, bool isTwoD) const{
00249   TreeModel* model = (TreeModel*)index.model();
00250   QString name = model->data(
00251     index.sibling(index.row(),0),Qt::DisplayRole).toString();
00252   RCP<const ParameterEntryValidator> validator = 
00253     model->getValidator(index);
00254   if(type == intId){
00255     if(isTwoD){
00256       return new Int2DArrayWidget(name, type, validator, parent);
00257     }
00258     else{
00259       return new IntArrayWidget(name, type, validator, parent);
00260     }
00261   }
00262   else if(type == shortId){
00263     if(isTwoD){
00264       return new Short2DArrayWidget(name, type, validator, parent);
00265     }
00266     else{
00267       return new ShortArrayWidget(name, type, validator, parent);
00268     }
00269   }
00270   else if(type == doubleId){
00271     if(isTwoD){
00272       return new Double2DArrayWidget(name, type, validator, parent);
00273     }
00274     else{
00275       return new DoubleArrayWidget(name, type, validator, parent);
00276     }
00277   }
00278   else if(type == floatId){
00279     if(isTwoD){
00280       return new Float2DArrayWidget(name, type, validator, parent);
00281     }
00282     else{
00283       return new FloatArrayWidget(name, type, validator, parent);
00284     }
00285   }
00286   else if(type == stringId){
00287     if(isTwoD){
00288       return new String2DArrayWidget(name, type, validator, parent);
00289     }
00290     else{
00291       return new StringArrayWidget(name, type, validator, parent);
00292     }
00293   }
00294   else{
00295     return 0;
00296   }
00297 }
00298 
00299 void Delegate::setArrayWidgetData(QWidget* editor, QString type, const QModelIndex& index, bool isTwoD) const{
00300   QVariant newData = index.model()->data(index, TreeModel::getRawDataRole());
00301   if(type == intId){
00302     isTwoD ?
00303     ((Int2DArrayWidget*)editor)->initData(newData.value<TwoDArray<int> >())
00304     :
00305     ((IntArrayWidget*)editor)->initData(newData.value<Array<int> >());
00306   }
00307   else if(type == shortId){
00308     isTwoD ?
00309     ((Short2DArrayWidget*)editor)->initData(newData.value<TwoDArray<short> >())
00310     :
00311     ((ShortArrayWidget*)editor)->initData(newData.value<Array<short> >());
00312   }
00313   else if(type == doubleId){
00314     isTwoD ?
00315     ((Double2DArrayWidget*)editor)->initData(newData.value<TwoDArray<double> >())
00316     :
00317     ((DoubleArrayWidget*)editor)->initData(newData.value<Array<double> >());
00318   }
00319   else if(type == floatId){
00320     isTwoD ?
00321     ((Float2DArrayWidget*)editor)->initData(newData.value<TwoDArray<float> >())
00322     :
00323     ((FloatArrayWidget*)editor)->initData(newData.value<Array<float> >());
00324   }
00325   else if(type == stringId){
00326     isTwoD ?
00327     ((String2DArrayWidget*)editor)->initData(newData.value<TwoDArray<std::string> >())
00328     :
00329     ((StringArrayWidget*)editor)->initData(newData.value<Array<std::string> >());
00330   }
00331 }
00332 
00333 QVariant Delegate::extractValueFromArray(QWidget* editor, QString type, bool isTwoD) const
00334 {
00335   if(type == intId){
00336     return (isTwoD ?
00337     QVariant::fromValue(((Int2DArrayWidget*)editor)->getData())
00338     :
00339     QVariant::fromValue(((IntArrayWidget*)editor)->getData()));
00340   }
00341   else if(type == shortId){
00342     return (isTwoD ?
00343     QVariant::fromValue(((Short2DArrayWidget*)editor)->getData())
00344     :
00345     QVariant::fromValue(((ShortArrayWidget*)editor)->getData()));
00346   }
00347   else if(type == doubleId){
00348     return (isTwoD ?
00349     QVariant::fromValue(((Double2DArrayWidget*)editor)->getData())
00350     :
00351     QVariant::fromValue(((DoubleArrayWidget*)editor)->getData()));
00352   }
00353   else if(type == floatId){
00354     return (isTwoD ?
00355     QVariant::fromValue(((Float2DArrayWidget*)editor)->getData())
00356     :
00357     QVariant::fromValue(((FloatArrayWidget*)editor)->getData()));
00358   }
00359   else if(type == stringId){
00360     return (isTwoD ?
00361     QVariant::fromValue(((String2DArrayWidget*)editor)->getData())
00362     :
00363     QVariant::fromValue(((StringArrayWidget*)editor)->getData()));
00364   }
00365   else{
00366     return QVariant();
00367   }
00368 }
00369 
00370 } //End namespace
00371 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines