Optika GUI Toolik Version of the Day
Optika_treeitem.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 <QStringList>
00042 #include <QFile>
00043 #include <QTextStream>
00044 #include <QSize>
00045 #include "Optika_treeitem.hpp"
00046 #include "Optika_treemodel.hpp"
00047 
00048 namespace Optika{
00049 
00050 TreeItem::TreeItem(const QString& name, RCP<ParameterEntry> parameter, TreeItem *parent, bool isHeader):
00051   name(name),
00052   parentItem(parent),
00053   parameterEntry(parameter),
00054   isHeader(isHeader)
00055 {
00056   myTypeId = getTypeId(parameter);
00057   if(isHeader){
00058     return;
00059   }
00060   else if(myTypeId == unrecognizedId && nonnull(parameterEntry)){
00061     this->docString = "Sorry, but we don't recognize the type of the " + name + " parameter.\n"
00062      + "No worries though. Everything should be fine.\n"
00063      "We'll just go ahead and set this parameter to its default value for you."
00064      "\n\nActual Documentation:\n" + QString::fromStdString(parameter->docString());
00065   }
00066   else if(nonnull(parameter)){
00067     this->docString = QString::fromStdString(parameter->docString());
00068   }
00069   else{
00070     this->docString = "";
00071   }
00072 }
00073 
00074 TreeItem::~TreeItem(){
00075   qDeleteAll(childItems);
00076 }
00077 
00078 void TreeItem::printOut() const{
00079   std::cout << name.toStdString() <<  ":     ";
00080   for(int i=0; i<childItems.size(); ++i){
00081     childItems.at(i)->printOut();
00082   }
00083 }
00084 
00085 void TreeItem::appendChild(TreeItem *item){
00086   childItems.append(item);
00087 }
00088 
00089 TreeItem *TreeItem::child(int row){
00090   return childItems.value(row);
00091 }
00092 
00093 int TreeItem::childCount() const{
00094   return childItems.count();
00095 }
00096 
00097 const QList<TreeItem*> TreeItem::getChildItems(){
00098   return childItems;
00099 }
00100 
00101 int TreeItem::columnCount() const{
00102   return 3;
00103 }
00104 
00105 QVariant TreeItem::data(int column, int role) const{
00106   if(role == Qt::ToolTipRole){
00107     if(name.compare(QString("Kurtis is awesome!"), Qt::CaseInsensitive) == 0){
00108       return QString("I know! I think I'm awesome too!\n"
00109       "You're pretty awesome yourself! You should send\n"
00110       "me an e-mail letting me know you found the easter egg.\n"
00111       "I'd enjoy that.\n"
00112       "kob0724@gmail.com or klnusbaum@gmail.com");
00113     }
00114     else if(name.compare(QString("Jim is awesome!"), Qt::CaseInsensitive) == 0){
00115       return QString("I know! I think he's awesome too!\n"
00116       "You're pretty awesome yourself! You should send\n"
00117       "Jim an e-mail letting him know you think he's awesome.\n"
00118       "He'd enjoy that.\n"
00119       "Tell him Kurtis sent you. jmwille@sandia.gov");
00120     }
00121     else if(name.compare(QString("Dr. Heroux is awesome!"), Qt::CaseInsensitive) == 0){
00122       return QString("I know! I think he's awesome too!\n"
00123       "You're pretty awesome yourself! You should send\n"
00124       "Dr. Heroux an e-mail letting him know you think he's awesome.\n"
00125       "He'd enjoy that.\n"
00126       "Tell him Kurtis sent you. maherou@sandia.gov");
00127     }
00128     return docString;
00129   }
00130   else if(role == Qt::DisplayRole && isHeader){
00131     if(column == 0){
00132       return "Parameter";
00133     }
00134     else if (column == 1){
00135       return "Value";
00136     }
00137     else if(column == 2){
00138       return "Type";
00139     }
00140   }
00141   else if(role == Qt::DisplayRole && myTypeId == unrecognizedId){
00142     if(column == 0){
00143       return name;
00144     }
00145     else if (column == 1){
00146       return QVariant("N/A");
00147     }
00148     else if(column == 2){
00149       return QVariant(unrecognizedId);
00150     }
00151   }
00152   else if(role == Qt::DisplayRole){
00153     if(column == 0){
00154       return name;
00155     }
00156     else if(column == 1 && 
00157       nonnull(parameterEntry) && 
00158       parameterEntry->isTwoDArray()
00159     )
00160     {
00161       return QString("Click to view 2D Array");
00162     }
00163     else if(column == 1 && 
00164       nonnull(parameterEntry) &&
00165       !parameterEntry->isList()
00166     )
00167     {
00168       std::string str = toString(parameterEntry->getAny());
00169       if(parameterEntry->isType<bool>()) {
00170         if(str == "0")
00171           str = "false";
00172         else if(str == "1")
00173           str = "true";
00174       }
00175       return QString::fromStdString(str);
00176     }
00177     else if(column == 2){
00178       return myTypeId;
00179     }
00180   }
00181   else if(role == TreeModel::getRawDataRole()){
00182     if(column == 1 && nonnull(parameterEntry) && parameterEntry->isArray()){
00183       return arrayEntryToVariant(parameterEntry, 
00184         getArrayType(myTypeId));
00185     }
00186     else if(column == 1 && nonnull(parameterEntry) && parameterEntry->isTwoDArray()){
00187       return arrayEntryToVariant(parameterEntry,
00188         getArrayType(myTypeId), true);
00189     }
00190     /*else{
00191       return parameterEntry->getAny();
00192     }*/
00193   }
00194   return QVariant();
00195 }
00196 
00197 TreeItem* TreeItem::parent(){
00198   return parentItem;
00199 }
00200 
00201 int TreeItem::row() const{
00202   if(parentItem){
00203     return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
00204   }
00205   return 0;
00206 }
00207 
00208 bool TreeItem::hasValidValue() const{
00209   if(is_null(parameterEntry->validator())){
00210     return true;
00211   }
00212   else{
00213     try{
00214       parameterEntry->validator()->validate(*parameterEntry, data(0).toString().toStdString(),
00215                     parentItem->data(0,Qt::DisplayRole).toString().toStdString());
00216       return true;
00217     }
00218     catch(std::exception& /*e*/){
00219       return false;
00220     }
00221   }
00222   //should never get here
00223   return true;
00224 
00225 }
00226 
00227 QString TreeItem::getCurrentInvalidValueMessage() const{
00228   if(parameterEntry->validator() == null){
00229     return "";
00230   }
00231   try{
00232     parameterEntry->validator()->validate(*parameterEntry, data(0).toString().toStdString(),
00233                   parentItem->data(0,Qt::DisplayRole).toString().toStdString());
00234     return "";
00235   }
00236   catch(std::exception& e){
00237     return QString::fromStdString(e.what());
00238   }
00239 }
00240   
00241 
00242 bool TreeItem::changeValue(QVariant value){
00243   if(myTypeId == intId){
00244     int newValue = value.value<int>();
00245     if(newValue != getValue<int>(*parameterEntry)){
00246       parameterEntry->setValue(newValue, false, parameterEntry->docString(), parameterEntry->validator());
00247     }
00248   }
00249   else if(myTypeId == shortId){
00250     short newValue = value.value<short>();
00251     if(newValue != getValue<short>(*parameterEntry)){
00252       parameterEntry->setValue(newValue, false, parameterEntry->docString(), parameterEntry->validator());
00253     }
00254   }
00255   else if(myTypeId == doubleId){
00256     double newValue = value.value<double>();
00257     if(newValue != getValue<double>(*parameterEntry)){
00258       parameterEntry->setValue(newValue, false, parameterEntry->docString(), parameterEntry->validator());
00259     }
00260   }
00261   else if(myTypeId == floatId){
00262     float newValue = value.value<float>();
00263     if(newValue != getValue<float>(*parameterEntry)){
00264       parameterEntry->setValue(newValue, false, parameterEntry->docString(), parameterEntry->validator());
00265     }
00266   }
00267   else if(myTypeId == boolId){
00268     bool newValue = value.value<bool>();
00269     if(newValue != getValue<bool>(*parameterEntry)){
00270       parameterEntry->setValue(newValue, false, parameterEntry->docString(), parameterEntry->validator());
00271     }
00272   }
00273   else if(myTypeId == stringId){
00274     std::string newValue = value.toString().toStdString();
00275     if(newValue != getValue<std::string>(*parameterEntry)){
00276       parameterEntry->setValue(newValue, false, parameterEntry->docString(), parameterEntry->validator());
00277     }
00278   }
00279   else if(myTypeId.contains(arrayId)){
00280     changeValueForArray(value, getArrayType(myTypeId));
00281   }
00282   else if(myTypeId.contains(twoDArrayId)){
00283     changeValueForArray(value, getArrayType(myTypeId), true);
00284   }
00285 
00286   return true;
00287 }
00288 
00289 void TreeItem::setValidator(RCP<const ParameterEntryValidator> validator){
00290   parameterEntry->setValidator(validator);
00291 }
00292 
00293 void TreeItem::changeValueForArray(QVariant value, QString type, bool twoD){
00294   if(type == intId){
00295     twoD ? 
00296     parameterEntry->setValue(value.value<TwoDArray<int> >(), false,
00297            parameterEntry->docString(), parameterEntry->validator())
00298     :
00299     parameterEntry->setValue(value.value<Array<int> >(), false,
00300            parameterEntry->docString(), parameterEntry->validator());
00301   }
00302   else if(type == shortId){
00303     twoD ? 
00304     parameterEntry->setValue(value.value<TwoDArray<short> >(), false,
00305            parameterEntry->docString(), parameterEntry->validator())
00306     :
00307     parameterEntry->setValue(value.value<Array<short> >(), false,
00308            parameterEntry->docString(), parameterEntry->validator());
00309   }
00310   else if(type == doubleId){
00311     twoD ? 
00312     parameterEntry->setValue(value.value<TwoDArray<double> >(), false,
00313            parameterEntry->docString(), parameterEntry->validator())
00314     :
00315     parameterEntry->setValue(value.value<Array<double> >(), false,
00316            parameterEntry->docString(), parameterEntry->validator());
00317   }
00318   else if(type == floatId){
00319     twoD ? 
00320     parameterEntry->setValue(value.value<TwoDArray<float> >(), false,
00321            parameterEntry->docString(), parameterEntry->validator())
00322     :
00323     parameterEntry->setValue(value.value<Array<float> >(), false,
00324            parameterEntry->docString(), parameterEntry->validator());
00325   }
00326   else if(type == stringId){
00327     twoD ? 
00328     parameterEntry->setValue(value.value<TwoDArray<std::string> >(), false,
00329            parameterEntry->docString(), parameterEntry->validator())
00330     :
00331     parameterEntry->setValue(value.value<Array<std::string> >(), false,
00332            parameterEntry->docString(), parameterEntry->validator());
00333   }
00334 }
00335 
00336 QString TreeItem::getTypeId(const RCP<const ParameterEntry> parameter){
00337   if(parameter.is_null()){
00338     return unrecognizedId;
00339   }
00340   else if(parameter->isList()){
00341     return listId;
00342   }
00343   else if(parameter->isType<int>()){
00344     return intId;
00345   }
00346   else if(parameter->isType<short>()){
00347     return shortId;
00348   }
00349   else if(parameter->isType<double>()){
00350     return doubleId;
00351   }
00352   else if(parameter->isType<float>()){
00353     return floatId;
00354   }
00355   else if(parameter->isType<bool>()){
00356     return boolId;
00357   }
00358   else if(parameter->isType<std::string>()){
00359     return stringId;
00360   }
00361   else if(parameter->isArray()){
00362     QString determinedId = determineArrayType(parameter);
00363     if( determinedId != unrecognizedId){
00364       return QString(arrayId + " "+ determinedId);
00365     }
00366     else{
00367       return unrecognizedId;
00368     }
00369   }
00370   else if(parameter->isTwoDArray()){
00371     QString determinedId = determineArrayType(parameter, true);
00372     if(determinedId != unrecognizedId){
00373       return QString(twoDArrayId + " "+ determinedId);
00374     }
00375     else{
00376       return unrecognizedId;
00377     }
00378   }
00379   else{
00380     return unrecognizedId;
00381   }
00382   //Should never get here
00383   //This is here to avoid compiler warnings
00384   return unrecognizedId;
00385 }
00386 
00387 
00388 } //end namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Defines