src/qvcore/qvpropertycontainer.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <qvmath/qvdisjointset.h>
00026 
00027 #include "qvpropertycontainer.h"
00028 
00029 uint QVPropertyContainer::maxIdent = 0;
00030 
00031 QVPropertyContainer::QVPropertyContainer(const QString name):
00032         name(name), errorString(), variants(), safelyCopiedVariants(), minimum(),
00033         maximum(), _info(), io_flags(), link_flags(), insertion_order(),
00034         inputLinks(), outputLinks()
00035         {
00036         ident = getNewIdent();
00037         qDebug() << "QVPropertyContainer::QVPropertyContainer(" << name << ")";
00038         if(qvApp == NULL)
00039                 {
00040                 QString str = "QVPropertyContainer::QVPropertyContainer(): holder " + name +
00041                                           ": property holders cannot be created before the " +
00042                                           "QVApplication instance. Aborting now.";
00043                 std::cerr << qPrintable(str) << std::endl;
00044                 exit(1);
00045                 }
00046         else
00047                 qvApp->registerQVPropertyContainer(this);
00048         qDebug() << "QVPropertyContainer::QVPropertyContainer(" << name << ") <- return";
00049         }
00050 
00051 QVPropertyContainer & QVPropertyContainer::operator=(const QVPropertyContainer &cont)
00052         {
00053         name = cont.name;
00054         ident = cont.ident;
00055         errorString = cont.errorString;
00056         variants = cont.variants;
00057         safelyCopiedVariants = cont.safelyCopiedVariants;
00058         minimum = cont.minimum;
00059         maximum = cont.maximum;
00060         _info = cont._info;
00061         io_flags = cont.io_flags;
00062         link_flags = cont.link_flags;
00063         insertion_order = cont.insertion_order;
00064         inputLinks = cont.inputLinks;
00065         outputLinks = cont.outputLinks;
00066 
00067         return *this;
00068         }
00069 
00070 QVPropertyContainer::~QVPropertyContainer()
00071         {
00072         if(qvApp != NULL)
00073                 qvApp->deregisterQVPropertyContainer(this);
00074         // Not needed now: unlink();
00075         }
00076 
00077 void QVPropertyContainer::setName(const QString name)
00078         { this->name = name; }
00079 
00080 const QString QVPropertyContainer::getName() const
00081         { return this->name; }
00082 
00083 const uint QVPropertyContainer::getId() const
00084         { return this->ident; }
00085 
00086 bool QVPropertyContainer::operator==(const QVPropertyContainer &cont) const
00087         { return (ident == cont.ident); }
00088 
00089 QList<QString> QVPropertyContainer::getPropertyList() const
00090         { return variants.keys(); }
00091 
00092 bool QVPropertyContainer::containsProperty(const QString name) const
00093         { return variants.contains(name); }
00094 
00095 int QVPropertyContainer::getPropertyType(const QString name, bool *ok) const
00096         {
00097         if(not checkExists(name,"QVPropertyContainer::getPropertyType()"))
00098                 {
00099                 if(ok != NULL) *ok = FALSE;
00100                 return QVariant::Invalid;
00101                 }
00102         if(ok != NULL) *ok = TRUE;
00103         QVariant variant = variants.value(name);
00104         return variant.userType();
00105         }
00106 
00107 bool QVPropertyContainer::removeProperty(const QString name)
00108         {
00109         if(not checkExists(name,"QVPropertyContainer::removeProperty()"))
00110                 return FALSE;
00111         this->variants.remove(name);
00112         this->safelyCopiedVariants.remove(name);
00113         this->minimum.remove(name);
00114         this->maximum.remove(name);
00115         this->_info.remove(name);
00116         this->io_flags.remove(name);
00117         int i = this->insertion_order.indexOf(name);
00118         this->insertion_order.removeAt(i);
00119         return TRUE;
00120         }
00121 
00122 bool QVPropertyContainer::setPropertyRange(const QString name, const double & minimum, const double & maximum)
00123         {
00124         std::cerr << "WARNING: setPropertyRange() is deprecated. Specify range in the function addProperty instead." << std::endl;
00125         if(not checkExists(name,"QVPropertyContainer::setPropertyRange()"))
00126                 return FALSE;
00127         if(minimum <= getPropertyValue<double>(name) and
00128                 maximum >= getPropertyValue<double>(name))
00129                 {
00130                         this->minimum[name] = QVariant::fromValue(minimum);
00131                         this->maximum[name] = QVariant::fromValue(maximum);
00132                         return TRUE;
00133                 } else {
00134                         QString str =  "QVPropertyContainer::setPropertyRange(): property " +
00135                                                    name + " in holder " + getName() + " has value " +
00136                                                    QString("%1").arg(getPropertyValue<double>(name)) +
00137                                                    ", which is not valid for the range [" +
00138                                                    QString("%1,%2").arg(minimum).arg(maximum) + "]." ;
00139                         setLastError(str);
00140                         if(qvApp->isRunning()) {
00141                                 std::cerr << qPrintable("Warning: " + str + "\n");
00142                         } // Otherwise, qApp will show the error and won't start the program.
00143                         return FALSE;
00144                 }
00145         }
00146 
00147 bool QVPropertyContainer::setPropertyRange(QString name, int & minimum, int & maximum)
00148         { return setPropertyRange(name, static_cast<double>(minimum), static_cast<double>(maximum)); }
00149 
00150 bool QVPropertyContainer::hasRange(const QString name) const
00151         { return maximum.contains(name) and minimum.contains(name); }
00152 
00153 bool QVPropertyContainer::isInput(const QString name) const
00154         { return (io_flags[name] & inputFlag);};
00155 
00156 bool QVPropertyContainer::isOutput(const QString name) const
00157         { return (io_flags[name] & outputFlag);};
00158 
00159 bool QVPropertyContainer::isGUIInvisible(const QString name) const
00160         { return (io_flags[name] & guiInvisible);};
00161 
00162 bool QVPropertyContainer::isLinkedInput(const QString name) const
00163         { return (link_flags[name] & linkedInputFlag);};
00164 
00165 bool QVPropertyContainer::isLinkedOutput(const QString name) const
00166         { return (link_flags[name] & linkedOutputFlag);};
00167 
00168 QVariant QVPropertyContainer::getPropertyQVariantValue(const QString name, bool *ok) const
00169         {
00170         if (not checkExists(name,"QVPropertyContainer::getPropertyQVariantValue()"))
00171                 if(ok != NULL) *ok = FALSE;
00172         else
00173                 if(ok != NULL) *ok = TRUE;
00174         return variants[name];
00175         }
00176 
00177 QString QVPropertyContainer::getPropertyInfo(const QString name, bool *ok) const
00178         {
00179         if(not checkExists(name,"QVPropertyContainer::getPropertyInfo()"))
00180                 if(ok != NULL) *ok = FALSE;
00181         else
00182                 if(ok != NULL) *ok = TRUE;
00183         return this->_info[name];
00184         }
00185 
00186 QString QVPropertyContainer::getLastError() const
00187         {
00188         return errorString;
00189         }
00190 
00191 const QString QVPropertyContainer::infoInputProperties() const
00192         {
00193         qDebug() << "QVPropertyContainer::infoInputProperties(" << getName() << ")";
00194 
00195         QString info = QString("Input parameters for ") + getName() + QString(":\n");
00196         bool emptyInfo=TRUE;
00197 
00198         qDebug() << "QVPropertyContainer::infoInputProperties(): Properties " << insertion_order;
00199 
00200         foreach (QString property, insertion_order)
00201         //QListIterator<QString> i(insertion_order);
00202         //while (i.hasNext())
00203                 {
00204                 //const QString property = i.next();
00205 
00206                 if( not isInput(property) )
00207                         continue;
00208 
00209                 bool printableProperty = TRUE;
00210                 QString propertyInfo("  --" + property + "=");
00211 
00212                 switch(getPropertyType(property))
00213                         {
00214                         case QVariant::String:
00215                                 propertyInfo += QString() + "[text] " + "(def. '" + getPropertyValue<QString>(property) + "') ";
00216                                 break;
00217 
00218                         case QVariant::Double:
00219                                 propertyInfo += ( (maximum.contains(property) and minimum.contains(property))?
00220                                         "[" + QString().setNum(getPropertyMinimum<double>(property)) + "..."
00221                                                 + QString().setNum(getPropertyMaximum<double>(property)) + "] ":
00222                                         "[double] " ) + "(def. "+ QString().setNum(getPropertyValue<double>(property)) + ") ";
00223                                 break;
00224 
00225                         case QVariant::Int:
00226                                 propertyInfo += ( (maximum.contains(property) and minimum.contains(property))?
00227                                         "[" + QString().setNum(getPropertyMinimum<int>(property)) + "..." +
00228                                                 QString().setNum(getPropertyMaximum<int>(property)) + "] ":
00229                                         "[int] " ) + "(def. "+ QString().setNum(getPropertyValue<int>(property)) + ") ";
00230                                 break;
00231 
00232                         case QVariant::Bool:
00233                                 propertyInfo += "[true,false]" + (getPropertyValue<bool>(property) ?
00234                                                                 QString(" (def. true) "):QString("(def. false) "));
00235                                 break;
00236 
00237                         default:
00238                                 printableProperty = FALSE;
00239                                 break;
00240                         }
00241 
00242                 if (printableProperty)
00243                         {
00244                         info += propertyInfo + getPropertyInfo(property).rightJustified(100-propertyInfo.split('\n').last().length(),' ') + ".\n";
00245                         emptyInfo=FALSE;
00246                         }
00247                 }
00248 
00249         qDebug() << "QVPropertyContainer::infoInputProperties(" << getName() << ") <~ return";
00250 
00251         if(emptyInfo)
00252                 return QString("");
00253         
00254         return info;
00255         }
00256 
00257 bool QVPropertyContainer::correctRange(const QString name, const double & value) const
00258         {
00259         if(not maximum.contains(name) and not minimum.contains(name))
00260                 return TRUE;
00261         double maximum = getPropertyMaximum<double>(name);
00262         double minimum = getPropertyMinimum<double>(name);
00263         if(minimum <= value and maximum >= value)
00264                 return TRUE;
00265         else
00266                 {
00267                 QString str =  "QVPropertyContainer::setPropertyValue(): value " +
00268                                            QString("%1").arg(value) + " for property " +
00269                                            name + " in holder " + getName() +
00270                                            "is not valid for the range [" +
00271                                            QString("%1,%2").arg(minimum).arg(maximum) + 
00272                                            "] stablished for it." ;
00273                 setLastError(str);
00274                 if(qvApp->isRunning())
00275                         {
00276                         std::cerr << qPrintable("Warning: " + str + "\n");
00277                         } // Otherwise, qApp will show the error and won't start the program.
00278                 return FALSE;
00279                 }
00280         }
00281 
00282 bool QVPropertyContainer::correctRange(const char *name, const int & value) const
00283         { return correctRange(QString(name),static_cast<double>(value)); }
00284 
00285 bool QVPropertyContainer::correctRange(QString name, const int & value) const
00286         { return correctRange(name,static_cast<double>(value)); }
00287 
00288 bool QVPropertyContainer::checkExists(const QString name, const QString methodname) const
00289         {
00290         if(not variants.contains(name))
00291                 {
00292                 QString str =  methodname + ": property " + name +
00293                                            " doesn't exists in holder " + getName() + ".";
00294                 setLastError(str);
00295                 if(qvApp->isRunning()) {
00296                         std::cerr << qPrintable("Warning: " + str + "\n");
00297                 } // Otherwise, qApp will show the error and won't start the program.
00298                 return FALSE;
00299                 } else {
00300                 return TRUE;
00301                 }
00302         }
00303 
00304 bool QVPropertyContainer::checkIsNewProperty(const QString name, const QString methodname) const
00305         {
00306         if(variants.contains(name))
00307                 {
00308                 QString str =  methodname + "(): property " + name +
00309                                            " already exists in holder " + getName() + ".";
00310                 setLastError(str);
00311                 if(qvApp->isRunning()) {
00312                         std::cerr << qPrintable("Warning: " + str + "\n");
00313                 } // Otherwise, qApp will show the error and won't start the program.
00314                 return FALSE;
00315                 } else {
00316                 return TRUE;
00317                 }
00318         }
00319 
00320 bool QVPropertyContainer::linkProperty(QString prop_orig, QVPropertyContainer *qvp_dest, QString prop_dest, LinkType link_type)
00321         {
00322         bool ok1,ok2;
00323         QString errMsg;
00324         int t1,t2;
00325         QVPropertyContainer *qvp_orig=this, *qvp_err=NULL;
00326         
00327         t1 = qvp_orig->getPropertyType(prop_orig,&ok1);
00328         t2 = qvp_dest->getPropertyType(prop_dest,&ok2);
00329         if(qvApp->isRunning())
00330                 {
00331                 qvp_err = qvp_orig;
00332                 errMsg = QString("QVPropertyContainer::linkProperty(): Property holder %1:"
00333                                         "Cannot link properties after launching QVApplication.\n")
00334                                         .arg(prop_orig).arg(qvp_orig->getName());
00335                 }
00336         else if(qvp_orig == qvp_dest)
00337                 {
00338                 errMsg = QString("QVPropertyContainer::linkProperty(): Property holder %1: cannot link a QVPropertyContainer with itself.\n").arg(qvp_orig->getName());
00339                 qvp_err = qvp_orig;
00340                 }
00341         else if(not ok1)
00342                 {
00343                 errMsg = QString("QVPropertyContainer::linkProperty(): Property %1 does not exist in property holder %2.\n")
00344                                 .arg(prop_orig).arg(qvp_orig->getName());
00345                 qvp_err = qvp_orig;
00346                 }
00347         else if (not ok2)
00348                 {
00349                 errMsg = QString("QVPropertyContainer::linkProperty(): Property %1 does not exist in property holder %2.\n")
00350                                 .arg(prop_dest).arg(qvp_dest->getName());
00351                 qvp_err = qvp_dest;
00352                 }
00353         else if(t1 != t2)
00354                 {
00355                 errMsg = QString("QVPropertyContainer::linkProperty(): Properties %1 and %2 of QVPropertyContainers %3 and %4 respectively are not of the same type.\n").arg(prop_orig).arg(prop_dest).arg(qvp_orig->getName()).arg(qvp_dest->getName());
00356                 qvp_err = qvp_orig;
00357                 }
00358         else if(not (qvp_orig->io_flags[prop_orig] & outputFlag))
00359                 {
00360                 errMsg = QString("QVPropertyContainer::linkProperty(): Property %1 of property holder %2 is not of Output type, and cannot be linked as such.\n").arg(prop_orig).arg(qvp_orig->getName());
00361                 qvp_err = qvp_orig;
00362                 }
00363         else if(not (qvp_dest->io_flags[prop_dest] & inputFlag))
00364                 {
00365                 errMsg = QString("QVPropertyContainer::linkProperty(): Property %1 property holder %2 is not of Input type, and cannot be linked as such.\n").arg(prop_dest).arg(qvp_dest->getName());
00366                 qvp_err = qvp_dest;
00367                 }
00368 
00369         if(errMsg != QString())
00370                 {
00371                 qvp_err->setLastError(errMsg);
00372                 if(qvApp->isRunning()) {
00373                         std::cerr << qPrintable("Warning: " + errMsg + "\n");
00374                 } // Otherwise, qApp will show the error and won't start the program.
00375                 return FALSE;
00376                 }
00377         else
00378                 {
00379                 QVPropertyContainerLink *link = new
00380                          QVPropertyContainerLink(qvp_orig,prop_orig,qvp_dest,prop_dest,link_type);
00381                                 qvp_orig->outputLinks[prop_orig].push_back(link);
00382                                 qvp_dest->inputLinks[prop_dest] = link;
00383                 qvp_dest->link_flags[prop_dest] |= linkedInputFlag;
00384                 qvp_orig->link_flags[prop_orig] |= linkedOutputFlag;
00385 
00386                 // Now, we initialize the shared state, simply protected by the
00387                 // corresponding RWLock:
00388                 this->RWLock.lockForWrite();
00389                 safelyCopiedVariants[prop_orig] = variants[prop_orig];
00390                 this->RWLock.unlock();
00391 
00392                 return TRUE;
00393                 }
00394         }
00395 
00396 void QVPropertyContainer::linkProperty(QVPropertyContainer *container, LinkType linkType)
00397         {
00398         QList<QString> localProper = getPropertyList();
00399         QList<QString> inputProper = container->getPropertyList();
00400 
00401         qSort(localProper.begin(), localProper.end());
00402         qSort(inputProper.begin(), inputProper.end());
00403 
00404         int i=0, l=0;
00405         while ( (i < inputProper.size()) && (l < localProper.size()) )
00406                 {
00407                 QString localName = localProper[l];
00408                 QString inputName = inputProper[i];
00409                 if (
00410                         (localName == inputName) && // si tienen el mismo nombre
00411                         (getPropertyType(localName) == container->getPropertyType(inputName)) && // si tienen el mismo tipo
00412                         (io_flags[localName] & outputFlag) && // si una es de entrada
00413                         (container->io_flags[inputName] & inputFlag) && // y otra de salida
00414                         (!(io_flags[localName] & internalProp)) && // y no son propiedades internas
00415                         (!(container->io_flags[inputName] & internalProp))
00416                    )
00417                         linkProperty(localProper[l], container, inputProper[i], linkType);
00418 
00419                 if(localName <= inputName) l++;
00420                 if(localName >= inputName) i++;
00421                 }
00422         }
00423 
00424 void QVPropertyContainer::unlink()
00425         {
00426                 QMapIterator<QString, QVPropertyContainerLink*> i_in(inputLinks);
00427                 while (i_in.hasNext()) {
00428                         i_in.next();
00429                         QVPropertyContainerLink *link = i_in.value();
00430                         link->markedForDeletion = TRUE;
00431                         // Protect against a possible pending acquire() from our input
00432                         // in other holders:
00433                         link->SyncSemaphoreIn.release();
00434                 }
00435         
00436                 QMapIterator<QString, QList<QVPropertyContainerLink*> >i_out(outputLinks);
00437                 while (i_out.hasNext()) {
00438                         i_out.next();
00439                         QListIterator<QVPropertyContainerLink*> j_out(i_out.value());
00440                         while(j_out.hasNext()) {
00441                                 QVPropertyContainerLink *link = j_out.next();
00442                                 link->markedForDeletion = TRUE;
00443                                 // Protect against a possible pending acquire() for our output
00444                                 // in other holders:
00445                                 link->SyncSemaphoreOut.release();
00446                         }
00447                 }
00448         }
00449 
00450 void QVPropertyContainer::readInputProperties()
00451         {
00452         // We read every linked input property from its source, protecting
00453         // the read with a standard RWLock (that here we just lock for read).
00454         // The only caveat is that if a property is synchronously read, then
00455         // we must wait for the producer to write it first. We implement that
00456         // by waiting on the SyncSemaphoreOut of the link. Also, in this
00457         // case when we finish reading the property, we signal every possible
00458         // waiting writer that, regarding this specific link, it can write now
00459         // a new value if it needs to, because we have read the old value yet.
00460         // This is implemented by releasing the SyncSemaphoreIn associated to
00461         // the link.
00462         QMutableMapIterator<QString, QVPropertyContainerLink*> i(inputLinks);
00463         while (i.hasNext()) {
00464                 i.next();
00465                 QVPropertyContainerLink *link = i.value();
00466                 if(link->link_type == SynchronousLink and not link->markedForDeletion) {
00467                         link->SyncSemaphoreOut.acquire();
00468                 }
00469                 link->qvp_orig->RWLock.lockForRead();
00470                 //this->setPropertyValueQVariant(link->prop_dest,link->qvp_orig->safelyCopiedVariants[link->prop_orig]);
00471                 this->variants[link->prop_dest] = link->qvp_orig->safelyCopiedVariants[link->prop_orig];
00472                 link->qvp_orig->RWLock.unlock();
00473                 if(link->link_type == SynchronousLink and not link->markedForDeletion) {
00474                         link->SyncSemaphoreIn.release();
00475                 }
00476                 // Possible link deletion:
00477                 if(link->markedForDeletion) {
00478                         i.remove();
00479                         delete link;
00480                 }
00481         }
00482 }
00483 
00484 void QVPropertyContainer::writeOutputProperties()
00485         {
00486         QMutableMapIterator<QString, QList<QVPropertyContainerLink*> >i(outputLinks);
00487 
00488         // For every QVP synchronously linked to this QVP's output, we ask
00489         // for permision to write a new output (that will only be possible if
00490         // all of these QVP's have read their inputs already):
00491         while (i.hasNext()) {
00492                 i.next();
00493                 QListIterator<QVPropertyContainerLink*> j(i.value());
00494                 while(j.hasNext()) {
00495                         QVPropertyContainerLink *link = j.next();
00496                         if(link->link_type == SynchronousLink and not link->markedForDeletion) {
00497                                 link->SyncSemaphoreIn.acquire();
00498                         }
00499                 }
00500         }
00501 
00502         // Now, we write a new coherent state, simply protected by the
00503         // corresponding RWLock:
00504         i.toFront();
00505         this->RWLock.lockForWrite();
00506         while (i.hasNext()) {
00507                 i.next();
00508                 QString prop_orig = i.key();
00509                 safelyCopiedVariants[prop_orig] = variants[prop_orig];
00510         }
00511         this->RWLock.unlock();
00512 
00513         // Finally, we signal to QVP's synchronously linked to this QVP's output
00514         // that there is a new coherent output, by releasing the corresponding
00515         // semaphore.
00516         i.toFront();
00517         while (i.hasNext()) {
00518                 i.next();
00519                 QMutableListIterator<QVPropertyContainerLink*> j(i.value());
00520                 while(j.hasNext()) {
00521                         QVPropertyContainerLink *link = j.next();
00522                         if(link->link_type == SynchronousLink and not link->markedForDeletion) {
00523                                 link->SyncSemaphoreOut.release();
00524                         }
00525                         // Possible link deletion:
00526                         if(link->markedForDeletion) {
00527                                 j.remove();
00528                                 delete link;
00529                                 if(i.value().isEmpty()) {
00530                                         i.remove();
00531                                         break;
00532                                 }
00533                         }
00534                 }
00535         }
00536 }
00537 
00538 void QVPropertyContainer::setLastError(QString str) const
00539         { errorString = str; }
00540 
00541 bool QVPropertyContainer::areSynchronized(const QList<QVPropertyContainer> conts)
00542         {
00543         QVDisjointSet dSet(conts.size());
00544 
00545         for (int i = 0; i < conts.size(); i++)
00546                 for (int j = i+1; j < conts.size(); j++) // for each pair of container
00547                         {
00548                         bool find = false; // only need one syncrhonous property to be synchronized
00549 
00550                         if (conts.at(i).getId() == conts.at(j).getId()) // if they are the same container, they are synchronized
00551                                 {
00552                                 dSet.unify(i, j); // unify their sets
00553                                 find = true;
00554                                 }
00555                         if (!find)
00556                                 {
00557                                 const QMap<QString, QVPropertyContainerLink* > inLinksI = conts.at(i).getInputLinks();
00558                                 foreach(QVPropertyContainerLink* proConLink, inLinksI.values())        // for each first container's linked input property
00559                                         if ( (proConLink->qvp_orig->getId() == conts.at(j).getId()) &&   // if is linked from second container
00560                                              (proConLink->link_type == SynchronousLink)                ) // and is a synchronous link
00561                                                 {
00562                                                 dSet.unify(i, j); // unify their sets
00563                                                 find = true;
00564                                                 break;
00565                                                 }
00566                                 }
00567                         if (!find)
00568                                 {
00569                                 const QMap<QString, QVPropertyContainerLink* > inLinksJ = conts.at(j).getInputLinks();
00570                                 foreach(QVPropertyContainerLink* proConLink, inLinksJ.values())        // for each second container's linked input property
00571                                         if ( (proConLink->qvp_orig->getId() == conts.at(i).getId()) &&   // if is linked from first container
00572                                              (proConLink->link_type == SynchronousLink)                ) // and is a synchronous link
00573                                                 {
00574                                                 dSet.unify(i, j); // unify their sets
00575                                                 break;
00576                                                 }
00577                                 }
00578                         }
00579 
00580         return (dSet.numberOfSets() == 1);
00581         }
00582 
00583 template <> bool QVPropertyContainer::parseArgument<bool>(const QString parameter, const QString value)
00584         {
00585         if (value.toLower() == "true" || value.toLower() == "false")
00586                 {
00587                 //variants[parameter] = QVariant::fromValue<bool>(value.toLower() == "true");
00588                 setPropertyValue<bool>(parameter,value.toLower() == "true");
00589                 return TRUE;
00590                 }
00591         else {
00592                 errorString = "QVPropertyContainer::parseArgument(): holder " + getName() +
00593                                         ": value " + value +
00594                                         " is not a valid boolean value for parameter " +
00595                                         parameter + ".\n";
00596                 return FALSE;
00597                 }
00598         }
00599 
00600 template <> bool QVPropertyContainer::parseArgument<int>(const QString parameter, const QString value)
00601         {
00602         bool okInt;
00603         int intValue = value.toInt(&okInt);
00604         if(not okInt)
00605                 {
00606                 errorString = "QVPropertyContainer::parseArgument(): holder " + getName() +
00607                                         ": value " + value +
00608                                         " is not a valid integer value for parameter " +
00609                                         parameter + ".\n";
00610                 return FALSE;
00611                 }
00612         //variants[parameter] = QVariant::fromValue<int>(intValue);
00613         setPropertyValue<int>(parameter,intValue);
00614         return TRUE;
00615         }
00616 
00617 template <> bool QVPropertyContainer::parseArgument<double>(const QString parameter, const QString value)
00618         {
00619         bool okDouble;
00620         double doubleValue = value.toDouble(&okDouble);
00621         if(not okDouble)
00622                 {
00623                 errorString = "QVPropertyContainer::parseArgument(): holder " + getName() +
00624                                         ": value " + value +
00625                                         " is not a valid double value for parameter " +
00626                                         parameter + ".\n";
00627                 return FALSE;
00628                 }
00629         //variants[parameter] = QVariant::fromValue<double>(doubleValue);
00630         setPropertyValue<double>(parameter,doubleValue);
00631         return TRUE;
00632         }
00633 
00634 template <> bool QVPropertyContainer::parseArgument<QString>(const QString parameter, const QString value)
00635         {
00636         //variants[parameter] = QVariant::fromValue<QString>(value);
00637         setPropertyValue<QString>(parameter,value);
00638         return TRUE;
00639         }

Generated on Thu Jul 17 17:23:27 2008 for QVision by  doxygen 1.5.3