Optika GUI Toolik Version of the Day
Optika_ArrayWidget.hpp
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 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Kurtis Nusbaum (klnusbaum@gmail.com) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 #ifndef OPTIKA_ARRAYWIDGET_HPP_
00029 #define OPTIKA_ARRAYWIDGET_HPP_
00030 
00031 #include <QDialog>
00032 #include <QModelIndex>
00033 #include <QPushButton>
00034 #include <QGridLayout>
00035 #include <QDoubleSpinBox>
00036 #include <QComboBox>
00037 #include <QLineEdit>
00038 #include <QGridLayout>
00039 #include <QScrollArea>
00040 #include <QLabel>
00041 #include <vector>
00042 #include "Optika_treemodel.hpp"
00043 #include "Optika_FileNameWidget.hpp"
00044 
00045 namespace Optika {
00046 
00047 
00053 template <class S>
00054 class GenericArrayWidget : public QDialog{
00055 public:
00063   GenericArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):
00064     QDialog(parent),
00065     model((TreeModel*)index.model()),
00066     index(index), 
00067     entryValidator(model->getValidator(index)),
00068     baseArray(model->getArray<S>(index)),
00069     type(type)
00070   {
00071     setModal(true);
00072     setSizeGripEnabled(true);
00073     arrayContainer = new QWidget(this);
00074 
00075     QScrollArea *scrollArea = new QScrollArea(this);
00076     scrollArea->setWidget(arrayContainer);
00077     scrollArea->setWidgetResizable(true);
00078 
00079     QPushButton *doneButton = new QPushButton(tr("Done"));
00080     QPushButton *cancelButton = new QPushButton(tr("Cancel"));
00081     connect(doneButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
00082     connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(reject()));
00083     QGridLayout *layout = new QGridLayout(this);
00084     layout->addWidget(scrollArea,0,0,1,3);
00085     layout->addWidget(doneButton,1,2);
00086     layout->addWidget(cancelButton,1,1);
00087 
00088     this->setLayout(layout);
00089 
00090     setWindowTitle(model->data(index.sibling(index.row(),0),Qt::DisplayRole).toString());
00091   }
00092   
00098   QString getType(){
00099     return type;
00100   }
00101 
00108   virtual std::string saveData() = 0;
00109 
00116   virtual void initializeValues(QString values) = 0;
00117 
00122   virtual void accept() =0;
00123 
00124 protected:
00128   typedef std::vector<QWidget*> WVector;
00129 
00133   WVector widgetVector;
00134 
00138   TreeModel *model;
00139 
00144   QModelIndex index;
00145 
00149   Teuchos::RCP<const Teuchos::ParameterEntryValidator> entryValidator;  
00150 
00155   void setupArrayLayout(){
00156     QGridLayout *widgetLayout = new QGridLayout(arrayContainer);
00157     for(int i=0; i<baseArray.size(); ++i){
00158       widgetLayout->addWidget(new QLabel("Item: " +QString::number(i)),0,i,Qt::AlignLeft);
00159       QWidget* editorWidget = getEditorWidget();
00160       widgetLayout->addWidget(editorWidget,1,i,Qt::AlignLeft);
00161       widgetVector.push_back(editorWidget);
00162     }
00163     arrayContainer->setLayout(widgetLayout);
00164   }
00165 
00166 private:
00171   QWidget *arrayContainer;
00172   
00176   Teuchos::Array<S> baseArray;
00177 
00181   QString type;
00182   
00186   virtual QWidget* getEditorWidget() = 0;
00187 };
00188 
00192 class IntArrayWidget: public GenericArrayWidget<int>{
00193   Q_OBJECT
00194 public:
00203   IntArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):GenericArrayWidget<int>(index, type, parent){
00204     setupArrayLayout();
00205     initializeValues(index.model()->data(index).toString()); 
00206   }
00207 
00208 public slots:
00209   void accept(){
00210     model->setData(index, QString::fromStdString(saveData()), Qt::EditRole);
00211     done(QDialog::Accepted);
00212   }
00213 
00214   std::string saveData(){
00215     Teuchos::Array<int> toReturn;
00216     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it){
00217       toReturn.push_back(((QSpinBox*)(*it))->value());
00218     }
00219     return toReturn.toString();
00220   }
00221 
00222   void initializeValues(QString values){
00223     QStringList valueList = getValues(values); 
00224     int i =0;
00225     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it, ++i){
00226       static_cast<QSpinBox*>(*it)->setValue(valueList.at(i).toInt());
00227     }
00228 
00229   }
00230 
00231 private:
00232   QWidget* getEditorWidget(){
00233     QSpinBox *newSpin = new QSpinBox(this);
00234     Teuchos::RCP<const EnhancedNumberValidator<int> > validator = Teuchos::null;
00235     if(!Teuchos::is_null(entryValidator)){
00236       validator = Teuchos::rcp_dynamic_cast<const ArrayNumberValidator<int> >(entryValidator,true)->getPrototype();
00237     }
00238     EnhancedNumberValidator<int>::applyToSpinBox(validator, newSpin);
00239     return newSpin;
00240   }
00241 };
00242 
00246 class ShortArrayWidget: public GenericArrayWidget<short>
00247 {
00248   Q_OBJECT
00249 public:
00258   ShortArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):GenericArrayWidget<short>(index, type, parent){
00259     setupArrayLayout();
00260     initializeValues(index.model()->data(index).toString()); 
00261   }
00262 
00263 public slots:
00264   void accept(){
00265     model->setData(index, QString::fromStdString(saveData()), Qt::EditRole);
00266     done(QDialog::Accepted);
00267   }
00268 
00269   std::string saveData(){
00270     Teuchos::Array<short> toReturn;
00271     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it){
00272       toReturn.push_back(((QSpinBox*)(*it))->value());
00273     }
00274     return toReturn.toString();
00275   }
00276 
00277   void initializeValues(QString values){
00278     QStringList valueList = getValues(values); 
00279     int i =0;
00280     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it, ++i){
00281       static_cast<QSpinBox*>(*it)->setValue((short)valueList.at(i).toInt());
00282     }
00283 
00284   }
00285 
00286 private:
00287   QWidget* getEditorWidget(){
00288     QSpinBox *newSpin = new QSpinBox(this);
00289     Teuchos::RCP<const EnhancedNumberValidator<short> > validator = Teuchos::null;
00290     if(!Teuchos::is_null(entryValidator)){
00291       validator = Teuchos::rcp_dynamic_cast<const ArrayNumberValidator<short> >(entryValidator,true)->getPrototype();
00292     }
00293     EnhancedNumberValidator<short>::applyToSpinBox(validator, newSpin);
00294     return newSpin;
00295   }
00296 };
00297 
00301 /*
00302 class LongLongArrayWidget: public GenericArrayWidget<long long int>{
00303   Q_OBJECT
00304 public:
00305   **
00306    * Constructs an LongLongArrayWidget.
00307    *
00308    * @param index The index of the array that is being edited.
00309    * @param type The type of the array.
00310    * @param parent The parent widget.
00311    *
00312   LongLongArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):GenericArrayWidget<long long int>(index, type, parent){
00313     setupArrayLayout();
00314     initializeValues(index.model()->data(index).toString()); 
00315   }
00316 
00317 public slots:
00318   void accept(){
00319     model->setData(index, QString::fromStdString(saveData()), Qt::EditRole);
00320     done(QDialog::Accepted);
00321   }
00322 
00323   std::string saveData(){
00324     Teuchos::Array<long long int> toReturn;
00325     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it){
00326       toReturn.push_back(((QwwLongSpinBox*)(*it))->value());
00327     }
00328     return toReturn.toString();
00329   }
00330 
00331   void initializeValues(QString values){
00332     QStringList valueList = getValues(values); 
00333     int i =0;
00334     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it, ++i){
00335       static_cast<QwwLongSpinBox*>(*it)->setValue(valueList.at(i).toLongLong());
00336     }
00337 
00338   }
00339 
00340 private:
00341   QWidget* getEditorWidget(){
00342     QSpinBox *newSpin = new QwwLongSpinBox(this);
00343     Teuchos::RCP<const EnhancedNumberValidator<long long int> > validator = null;
00344     if(!Teuchos::is_null(entryValidator)){
00345       validator = Teuchos::rcp_dynamic_cast<const EnhancedNumberValidator<long long int> >(entryValidator,true);
00346     }
00347     EnhancedNumberValidator<long long int>::applyToSpinBox(validator, newSpin);
00348     return newSpin;
00349   }
00350 };*/
00351 
00355 class DoubleArrayWidget: public GenericArrayWidget<double>
00356 {
00357   Q_OBJECT
00358 public:
00366   DoubleArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):GenericArrayWidget<double>(index, type, parent){
00367     setupArrayLayout();
00368     initializeValues(index.model()->data(index).toString()); 
00369   }
00370 
00371 public slots:
00372   void accept(){
00373     model->setData(index, QString::fromStdString(saveData()), Qt::EditRole);
00374     done(QDialog::Accepted);
00375   }
00376 
00377   std::string saveData(){
00378     Teuchos::Array<double> toReturn;
00379     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it){
00380       toReturn.push_back(((QDoubleSpinBox*)(*it))->value());
00381     }
00382     return toReturn.toString();
00383   }
00384 
00385   void initializeValues(QString values){
00386     QStringList valueList = getValues(values); 
00387     int i =0;
00388     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it, ++i){
00389       static_cast<QDoubleSpinBox*>(*it)->setValue(valueList.at(i).toDouble());
00390     }
00391   }
00392 
00393 private:
00394   QWidget* getEditorWidget(){
00395     QDoubleSpinBox *newSpin = new QDoubleSpinBox(this);
00396     Teuchos::RCP<const EnhancedNumberValidator<double> > validator = Teuchos::null;
00397     if(!Teuchos::is_null(entryValidator)){
00398       validator = Teuchos::rcp_dynamic_cast<const ArrayNumberValidator<double> >(entryValidator,true)->getPrototype();
00399     }
00400     EnhancedNumberValidator<double>::applyToSpinBox(validator, newSpin);
00401     return newSpin;
00402   }
00403 };
00404 
00408 class FloatArrayWidget: public GenericArrayWidget<float>
00409 {
00410   Q_OBJECT
00411 public:
00419   FloatArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):GenericArrayWidget<float>(index, type, parent){
00420     setupArrayLayout();
00421     initializeValues(index.model()->data(index).toString()); 
00422   }
00423 
00424 public slots:
00425   void accept(){
00426     model->setData(index, QString::fromStdString(saveData()), Qt::EditRole);
00427     done(QDialog::Accepted);
00428   }
00429 
00430   std::string saveData(){
00431     Teuchos::Array<float> toReturn;
00432     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it){
00433       toReturn.push_back(((QDoubleSpinBox*)(*it))->value());
00434     }
00435     return toReturn.toString();
00436   } 
00437 
00438   void initializeValues(QString values){
00439     QStringList valueList = getValues(values); 
00440     int i =0;
00441     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it, ++i){
00442       static_cast<QDoubleSpinBox*>(*it)->setValue(valueList.at(i).toDouble());
00443     }
00444 
00445   }
00446 
00447 private:
00448   QWidget* getEditorWidget(){
00449     QDoubleSpinBox *newSpin = new QDoubleSpinBox(this);
00450     Teuchos::RCP<const EnhancedNumberValidator<float> > validator = Teuchos::null;
00451     if(!Teuchos::is_null(entryValidator)){
00452       validator = Teuchos::rcp_dynamic_cast<const ArrayNumberValidator<float> >(entryValidator,true)->getPrototype();
00453     }
00454     EnhancedNumberValidator<float>::applyToSpinBox(validator, newSpin);
00455     return newSpin;
00456   }
00457 };
00458 
00462 class StringArrayWidget : public GenericArrayWidget<std::string>{
00463   Q_OBJECT
00464 public:
00472   StringArrayWidget(const QModelIndex index, QString type, QWidget *parent=0):GenericArrayWidget<std::string>(index, type, parent){
00473     setupArrayLayout();
00474     initializeValues(index.model()->data(index).toString()); 
00475   }
00476 
00477   void accept(){
00478     model->setData(index, QString::fromStdString(saveData()), Qt::EditRole);
00479     done(QDialog::Accepted);
00480   }
00481 
00482   std::string saveData(){
00483     Teuchos::Array<std::string> toReturn;
00484     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it){
00485       if(Teuchos::is_null(entryValidator)){
00486         toReturn.push_back(((QLineEdit*)(*it))->text().toStdString());
00487       }
00488       else if(!Teuchos::is_null(Teuchos::rcp_dynamic_cast<const ArrayFileNameValidator>(entryValidator))){
00489         toReturn.push_back(((FileNameWidget*)(*it))->getCurrentFileName().toStdString());
00490       }
00491       else if(entryValidator->validStringValues()->size() !=0){
00492         toReturn.push_back(((QComboBox*)(*it))->currentText().toStdString());
00493       }
00494       else{
00495         toReturn.push_back(((QLineEdit*)(*it))->text().toStdString());
00496       }
00497     }
00498     return toReturn.toString();
00499   } 
00500 
00501   void initializeValues(QString values){
00502     QStringList valueList = getValues(values); 
00503     int i =0;
00504     for(WVector::iterator it = widgetVector.begin(); it != widgetVector.end(); ++it, ++i){
00505       if(Teuchos::is_null(entryValidator)){
00506         static_cast<QLineEdit*>(*it)->setText(valueList.at(i));
00507       }
00508       else if(!Teuchos::is_null(Teuchos::rcp_dynamic_cast<const ArrayFileNameValidator>(entryValidator))){
00509         static_cast<FileNameWidget*>(*it)->setCurrentFileName(valueList.at(i));
00510       }
00511       else if(entryValidator->validStringValues()->size() !=0){
00512         int currentIndex = static_cast<QComboBox*>(*it)->findText(valueList.at(i));
00513         if(currentIndex >= 0){
00514           static_cast<QComboBox*>(*it)->setCurrentIndex(static_cast<QComboBox*>(*it)->findText(valueList.at(i)));
00515         }
00516       }
00517       else{
00518         static_cast<QLineEdit*>(*it)->setText(valueList.at(i));
00519       }
00520     }
00521 
00522   }
00523 
00524 private:
00525   QWidget* getEditorWidget(){
00526     if(Teuchos::is_null(entryValidator)){
00527       return new QLineEdit(this);
00528     }
00529     else if(!Teuchos::is_null(Teuchos::rcp_dynamic_cast<const ArrayFileNameValidator>(entryValidator))){
00530       return new FileNameWidget("", Teuchos::rcp_dynamic_cast<const ArrayFileNameValidator>(entryValidator)->getPrototype()->fileMustExist(), this);
00531     }
00532     else if(entryValidator->validStringValues()->size() != 0){
00533       Teuchos::RCP<const Teuchos::Array<std::string> > options = entryValidator->validStringValues();
00534       QComboBox *newCombo = new QComboBox(this);
00535       for(Teuchos::Array<std::string>::const_iterator itr = options->begin(); itr != options->end(); ++itr){
00536         newCombo->addItem(QString::fromStdString(*itr));
00537       }
00538       return newCombo;
00539     }
00540     else{
00541       return new QLineEdit(this);
00542     }
00543   }
00544 };
00545 
00546 
00547 }
00548 
00549 #endif //OPTIKA_ARRAYWIDGET_HPP_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends