Back to index

salome-gui  6.5.0
QtxEvalExpr.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File:      QtxEvalExpr.cxx
00021 // Author:    Alexander SOLOVYOV, Sergey TELKOV
00022 //
00023 #include "QtxEvalExpr.h"
00024 
00025 #include <QStack>
00026 
00027 #include <math.h>
00028 
00042 QtxEvalExpr::QtxEvalExpr( const QString& expr )
00043 {
00044   intialize( true, expr );
00045 }
00046 
00052 QtxEvalExpr::QtxEvalExpr( const bool stdSets, const QString& expr )
00053 {
00054   intialize( stdSets, expr );
00055 }
00056 
00060 QtxEvalExpr::~QtxEvalExpr()
00061 {
00062   delete myParser;
00063 }
00064 
00070 void QtxEvalExpr::intialize( const bool stdSets, const QString& expr )
00071 {
00072   myParser = new QtxEvalParser();
00073   if ( stdSets )
00074   {
00075     myParser->setAutoDeleteOperationSets( true );
00076     myParser->insertOperationSet( new QtxEvalSetLogic() );
00077     myParser->insertOperationSet( new QtxEvalSetArithmetic() );
00078     myParser->insertOperationSet( new QtxEvalSetString() );
00079     myParser->insertOperationSet( new QtxEvalSetMath() );
00080     myParser->insertOperationSet( new QtxEvalSetSets() );
00081     myParser->insertOperationSet( new QtxEvalSetConst() );
00082   }
00083   setExpression( expr );
00084 }
00085 
00091 QVariant QtxEvalExpr::calculate( const QString& expr )
00092 {
00093   if ( !expr.isEmpty() )
00094     setExpression( expr );
00095   return myParser->calculate();
00096 }
00097 
00102 QString QtxEvalExpr::expression() const
00103 {
00104   return myExpr;
00105 }
00106 
00111 void QtxEvalExpr::setExpression( const QString& expr )
00112 {
00113   if ( expr == expression() )
00114     return;
00115 
00116   myExpr = expr;
00117   myParser->setExpression( myExpr );
00118 }
00119 
00124 QtxEvalExpr::Error QtxEvalExpr::error() const
00125 {
00126   return myParser->error();
00127 }
00128 
00133 QtxEvalParser* QtxEvalExpr::parser() const
00134 {
00135   return myParser;
00136 }
00137 
00143 QList<QtxEvalSet*> QtxEvalExpr::operationSets() const
00144 {
00145   return myParser->operationSets();
00146 }
00147 
00154 void QtxEvalExpr::insertOperationSet( QtxEvalSet* set, const int idx )
00155 {
00156   myParser->insertOperationSet( set, idx );
00157 }
00158 
00164 void QtxEvalExpr::removeOperationSet( QtxEvalSet* set )
00165 {
00166   myParser->removeOperationSet( set );
00167 }
00168 
00175 QtxEvalSet* QtxEvalExpr::operationSet( const QString& name ) const
00176 {
00177   return myParser->operationSet( name );
00178 }
00179 
00185 bool QtxEvalExpr::autoDeleteOperationSets() const
00186 {
00187   return myParser->autoDeleteOperationSets();
00188 }
00189 
00195 void QtxEvalExpr::setAutoDeleteOperationSets( const bool on )
00196 {
00197   myParser->setAutoDeleteOperationSets( on );
00198 }
00199 
00219 QtxEvalParser::QtxEvalParser()
00220 : myAutoDel( false )
00221 {
00222   setError( QtxEvalExpr::OK );
00223 }
00224 
00228 QtxEvalParser::~QtxEvalParser()
00229 {
00230   if ( autoDeleteOperationSets() )
00231     qDeleteAll( mySets );
00232 }
00233 
00238 QList<QtxEvalSet*> QtxEvalParser::operationSets() const
00239 {
00240   return mySets;
00241 }
00242 
00248 QtxEvalSet* QtxEvalParser::operationSet( const QString& name ) const
00249 {
00250   QtxEvalSet* set = 0;
00251   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !set; ++it )
00252   {
00253     if ( (*it)->name() == name )
00254       set = *it;
00255   }
00256   return set;
00257 }
00258 
00265 void QtxEvalParser::insertOperationSet( QtxEvalSet* set, const int idx )
00266 {
00267   if ( mySets.contains( set ) )
00268     return;
00269 
00270   int index = idx < 0 ? mySets.count() : idx;
00271   index = qMin( index, mySets.count() );
00272   mySets.insert( index, set );
00273 }
00274 
00280 void QtxEvalParser::removeOperationSet( QtxEvalSet* set )
00281 {
00282   mySets.removeAll( set );
00283 }
00284 
00290 bool QtxEvalParser::autoDeleteOperationSets() const
00291 {
00292   return myAutoDel;
00293 }
00294 
00300 void QtxEvalParser::setAutoDeleteOperationSets( const bool on )
00301 {
00302   myAutoDel = on;
00303 }
00304 
00314 int QtxEvalParser::search( const QStringList& list, const QString& str,
00315                            int offset, int& matchLen, int& listind )
00316 {
00317   int min = -1;
00318   QStringList::const_iterator anIt = list.begin(), aLast = list.end();
00319   for ( int ind = 0; anIt != aLast; anIt++, ind++ )
00320   {
00321     int pos = str.indexOf( *anIt, offset );
00322     if ( pos >= 0 && ( min < 0 || min > pos ||
00323                        ( min == pos && matchLen < (int)(*anIt).length() ) ) )
00324     {
00325       min = pos;
00326       listind = ind;
00327       matchLen = (*anIt).length();
00328     }
00329   }
00330   if ( min < 0 )
00331     matchLen = 0;
00332   return min;
00333 }
00334 
00342 QString QtxEvalParser::note( const QString& str, int pos, int len )
00343 {
00344     return str.mid( pos, len ).trimmed();
00345 }
00346 
00359 bool QtxEvalParser::prepare( const QString& expr, Postfix& post )
00360 {
00361   int pos = 0;
00362   int len = expr.length();
00363   QStack<int> aBracketStack;
00364   QStringList anOpers, anOpenBr, aCloseBr;
00365   if ( !checkOperations() )
00366     return false;
00367 
00368   bracketsList( anOpenBr, true );
00369   bracketsList( aCloseBr, false );
00370   operationList( anOpers );
00371 
00372   while ( pos < len && error() == QtxEvalExpr::OK )
00373   {
00374     PostfixItem item;
00375     while ( pos < len && expr[pos].isSpace() )
00376       pos++;
00377     if ( pos >= len )
00378       break;
00379 
00380     int mBrLen = 0, mLen = 0, br_ind = -1, op_ind = -1;
00381     int oPos = search( anOpenBr, expr, pos, mBrLen, br_ind );
00382     int cPos = oPos == pos ? -1 : search( aCloseBr, expr, pos, mBrLen, br_ind );
00383     int opPos = search( anOpers, expr, pos, mLen, op_ind );
00384 
00385     if ( expr[pos] == QChar( '\'' ) )
00386     {
00387       int vpos = pos + 1;
00388       while ( vpos < (int)expr.length() && expr[vpos] != QChar( '\'' ) )
00389         vpos++;
00390 
00391       mLen = vpos - pos + 1;
00392 
00393       int res = createValue( note( expr, pos, mLen ), item.myValue );
00394       item.myType = res ? Value : Param;
00395       post.append( item );
00396       pos = vpos + 1;
00397       continue;
00398     }
00399 
00400     if ( oPos == pos )
00401     {
00402       aBracketStack.push( br_ind );
00403       item.myValue = note( expr, pos, mBrLen );
00404       item.myType = Open;
00405       post.append( item );
00406     }
00407     else if ( cPos == pos )
00408     {
00409       if ( aBracketStack.count() == 0 )
00410       {
00411         setError( QtxEvalExpr::ExcessClose );
00412         break;
00413       }
00414       if ( br_ind != aBracketStack.top() )
00415       {
00416         setError( QtxEvalExpr::BracketsNotMatch );
00417         break;
00418       }
00419       else
00420       {
00421         aBracketStack.pop();
00422         item.myValue = note( expr, pos, mBrLen );
00423         item.myType = Close;
00424         post.append( item );
00425       }
00426     }
00427     else
00428       mBrLen = 0;
00429 
00430     if ( opPos == pos )
00431     {
00432       mBrLen = 0;
00433       item.myValue = note( expr, pos, mLen );
00434       item.myType = Binary;
00435 
00436       if ( oPos == pos )
00437         post.insert( post.count() - 1, item );
00438       else
00439         post.append( item );
00440     }
00441     else
00442     {
00443       mLen = 0;
00444       if ( oPos != pos && cPos != pos )
00445       {
00446               int i; 
00447         for ( i = pos + 1; i < (int)expr.length(); i++ )
00448         {
00449           if ( expr[i].isSpace() )
00450             break;
00451         }
00452 
00453         int vpos = i;
00454         if ( oPos >= 0 && oPos < vpos )
00455           vpos = oPos;
00456         if ( cPos >= 0 && cPos < vpos )
00457           vpos = cPos;
00458         if ( opPos >= 0 && opPos < vpos )
00459           vpos = opPos;
00460 
00461         while( vpos < (int)expr.length() && 
00462                ( expr[vpos].isLetter() || expr[vpos].isDigit() || expr[vpos]=='_' ) )
00463           vpos++;
00464 
00465         mLen = vpos - pos;
00466         bool res = createValue( note( expr, pos, mLen ), item.myValue );
00467         item.myType = res ? Value : Param;
00468         post.append( item );
00469       }
00470     }
00471 
00472     pos += mBrLen + mLen;
00473   }
00474 
00475   //Bracket checking
00476   int brValue = 0;
00477   for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
00478   {
00479     if ( (*anIt).myType == Open )
00480       brValue++;
00481     else if ( (*anIt).myType == Close )
00482     {
00483       if ( brValue > 0 )
00484         brValue--;
00485       else
00486       {
00487         setError( QtxEvalExpr::ExcessClose );
00488         break;
00489       }
00490     }
00491   }
00492 
00493   if ( brValue > 0 )
00494     setError( QtxEvalExpr::CloseExpected );
00495 
00496   return error() == QtxEvalExpr::OK;
00497 }
00498 
00507 bool QtxEvalParser::setOperationTypes( Postfix& post )
00508 {
00509   if ( !checkOperations() )
00510     return false;
00511 
00512   QStringList anOpen, aClose;
00513   bracketsList( anOpen, true );
00514   bracketsList( aClose, false );
00515 
00516   Postfix::iterator aPrev, aNext;
00517   for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
00518   {
00519     aPrev = anIt;
00520     aPrev--;
00521     aNext = anIt;
00522     aNext++;
00523     if ( (*anIt).myType != Binary )
00524       continue;
00525 
00526     if ( ( anIt == post.begin() || (*aPrev).myType == Open ||
00527            (*aPrev).myType == Pre || (*aPrev).myType == Binary ) &&  aNext != post.end() &&
00528          ( (*aNext).myType == Value || (*aNext).myType == Param ||
00529            (*aNext).myType == Open  || (*aNext).myType == Binary ) )
00530       (*anIt).myType = Pre;
00531     else if ( anIt != post.begin() && ( (*aPrev).myType == Close || (*aPrev).myType == Param ||
00532                                         (*aPrev).myType == Value || (*aPrev).myType == Pre ||
00533                                         (*aPrev).myType == Post || (*aPrev).myType == Binary ) &&
00534               ( aNext == post.end() || (*aNext).myType == Close ) )
00535       (*anIt).myType = Post;
00536 
00537     if ( anOpen.contains( (*anIt).myValue.toString() ) )
00538       (*anIt).myType = Pre;
00539     else if ( aClose.contains( (*anIt).myValue.toString() ) )
00540       (*anIt).myType = Post;
00541   }
00542 
00543   return error() == QtxEvalExpr::OK;
00544 }
00545 
00556 int QtxEvalParser::globalBrackets( const QtxEvalParser::Postfix& post, int f, int l )
00557 {
00558   int i;
00559   int start_br = 0;
00560   int fin_br = 0;
00561   int br = 0;
00562   int br_num = 0;
00563   int min_br_num = (l-f+1)*5;
00564     
00565   for( i=f; i<=l; i++ )
00566     if( post[ i ].myType==QtxEvalParser::Open )
00567       start_br++;
00568     else
00569       break;
00570   for( i=l; i>=f; i-- )
00571     if( post[ i ].myType==QtxEvalParser::Close )
00572       fin_br++;
00573     else
00574       break;
00575 
00576   br = start_br<fin_br ? start_br : fin_br;
00577   for( i=f+br; i<=l-br; i++ )
00578   {
00579     if( post[i].myType==QtxEvalParser::Open )
00580       br_num++;
00581     else if( post[i].myType==QtxEvalParser::Close )
00582       br_num--;
00583     if( br_num<min_br_num )
00584       min_br_num = br_num;
00585   }
00586   
00587   return br+min_br_num;
00588 }
00589 
00603 bool QtxEvalParser::sort( const Postfix& post, Postfix& res, const QStringList& anOpen,
00604                           const QStringList& aClose, int f, int l )
00605 {
00606   if ( l < f )
00607     return true;
00608 
00609   if ( f < 0 )
00610     f = 0;
00611 
00612   if ( l < 0 )
00613     l = post.count() - 1;
00614 
00615   int br = globalBrackets( post, f, l );
00616   f += br;
00617   l -= br;
00618 
00619   if ( f == l && f >= 0 )
00620     res.append( post[f] );
00621 
00622   if ( l <= f )
00623     return true;
00624 
00625   if ( !checkOperations() )
00626     return false;
00627 
00628   int min = -1;
00629   QIntList argmin;
00630   QList<PostfixItemType> min_types;
00631 
00632   for ( int i = 0, j = f; j <= l; i++, j++ )
00633   {
00634     const PostfixItem& item = post[j];
00635     PostfixItemType tt = item.myType;
00636     if ( tt == Binary || tt == Pre || tt == Post )
00637     {
00638       int cur_pr = priority( item.myValue.toString(), tt == Binary );
00639       if ( cur_pr > 0 )
00640       {
00641         if ( min < 0 || min >= cur_pr )
00642         {
00643           if ( min == cur_pr )
00644           {
00645             argmin.append( f + i );
00646             min_types.append( tt );
00647           }
00648           else
00649           {
00650             min = cur_pr;
00651             argmin.clear();
00652             argmin.append( f + i );
00653             min_types.clear(); min_types.append( tt );
00654           }
00655         }
00656       }
00657       else
00658       {
00659         setError( QtxEvalExpr::InvalidOperation );
00660         break;
00661       }
00662     }
00663     else if ( tt == Open )
00664     {
00665       QString opBr = item.myValue.toString();
00666       int ind = anOpen.indexOf( opBr ), brValue = 0;
00667       while ( j <= l )
00668       {
00669         const PostfixItem& anItem = post[j];
00670         if ( anItem.myType == Open )
00671           brValue++;
00672 
00673         if ( anItem.myType == Close )
00674         {
00675           brValue--;
00676           QString clBr = anItem.myValue.toString();
00677           if ( aClose.indexOf( clBr ) == ind && brValue == 0 )
00678             break;
00679         }
00680         i++; j++;
00681       }
00682 
00683       if ( brValue > 0 )
00684       {
00685         setError( QtxEvalExpr::CloseExpected );
00686           break;
00687       }
00688     }
00689   }
00690 
00691   if ( error() == QtxEvalExpr::OK )
00692   {
00693     if ( min >= 0 )
00694     {
00695       Postfix one;
00696       QList<Postfix> parts;
00697       QIntList::const_iterator anIt = argmin.begin(), aLast = argmin.end();
00698       bool ok = sort( post, one, anOpen, aClose, f, *anIt - 1 );
00699       parts.append( one );
00700       one.clear();
00701       for ( ; anIt != aLast && ok; anIt++ )
00702       {
00703         QIntList::const_iterator aNext = anIt; aNext++;
00704         ok = sort( post, one, anOpen, aClose, *anIt + 1, aNext == aLast ? l : *aNext - 1 );
00705         parts.append( one );
00706         one.clear();
00707       }
00708 
00709       if ( !ok )
00710         return false;
00711 
00712       QStack<PostfixItem> aStack;
00713       QList<Postfix>::const_iterator aPIt = parts.begin();
00714       QList<PostfixItemType>::const_iterator aTIt = min_types.begin();
00715       res += (*aPIt);
00716       aPIt++;
00717       anIt = argmin.begin();
00718       for ( ; anIt != aLast; anIt++, aPIt++, aTIt++ )
00719       {
00720         if ( *aTIt == Pre )
00721         {
00722           if ( anOpen.contains( post[*anIt].myValue.toString() ) == 0 )
00723           {
00724             res += (*aPIt);
00725             aStack.push( post[ *anIt ] );
00726           }
00727           else
00728           {
00729             res.append( post[*anIt] );
00730             res += *aPIt;
00731           }
00732         }
00733         else
00734         {
00735           res += *aPIt;
00736           while ( !aStack.isEmpty() )
00737           {
00738             res.append( aStack.top() );
00739             aStack.pop();
00740           }
00741           res.append( post[*anIt] );
00742         }
00743       }
00744       while ( !aStack.isEmpty() )
00745       {
00746         res.append( aStack.top() );
00747         aStack.pop();
00748       }
00749     }
00750     else
00751     { //there are no operations
00752       for ( int k = f; k <= l; k++ )
00753       {
00754         if ( post.at( k ).myType==Value || post.at( k ).myType == Param )
00755           res.append( post.at( k ) );
00756       }
00757     }
00758   }
00759 
00760   return error() == QtxEvalExpr::OK;
00761 }
00762 
00772 bool QtxEvalParser::parse( const QString& expr )
00773 {
00774   myPostfix.clear();
00775 
00776   if ( !checkOperations() )
00777     return false;
00778 
00779   Postfix p;
00780   QStringList opens, closes;
00781 
00782   setError( QtxEvalExpr::OK );
00783   bracketsList( opens, true );
00784   bracketsList( closes, false );
00785 
00786   return prepare( expr, p ) && setOperationTypes( p ) && sort( p, myPostfix, opens, closes );
00787 }
00788 
00799 bool QtxEvalParser::calculate( const QString& op, QVariant& v1, QVariant& v2 )
00800 {
00801   QtxEvalExpr::Error err = isValid( op, v1.type(), v2.type() );
00802   if ( err == QtxEvalExpr::OK )
00803     setError( calculation( op, v1, v2 ) );
00804   else
00805     setError( err );
00806 
00807   return error() == QtxEvalExpr::OK;
00808 }
00809 
00814 QVariant QtxEvalParser::calculate()
00815 {
00816   if ( !checkOperations() )
00817     return QVariant();
00818 
00819   setError( QtxEvalExpr::OK );
00820 
00821   QStringList anOpen, aClose;
00822   bracketsList( anOpen, true );
00823   bracketsList( aClose, false );
00824 
00825   QStack<QVariant> aStack;
00826   Postfix::iterator anIt = myPostfix.begin(), aLast = myPostfix.end();
00827   for ( ; anIt != aLast && error() == QtxEvalExpr::OK; anIt++ )
00828   {
00829     QString nn = (*anIt).myValue.toString();
00830     if ( (*anIt).myType == Param )
00831     {
00832       if ( hasParameter( nn ) )
00833       {
00834         QVariant& v = myParams[nn];
00835         if ( v.isValid() )
00836           aStack.push( v );
00837         else
00838           setError( QtxEvalExpr::InvalidToken );
00839       }
00840       else
00841         setError( QtxEvalExpr::InvalidToken );
00842     }
00843     else if ( (*anIt).myType == Value )
00844       aStack.push( (*anIt).myValue );
00845     else if ( (*anIt).myType == Pre || (*anIt).myType == Post )
00846     {
00847       if ( anOpen.contains( nn ) )
00848       {
00849         QVariant inv;
00850         if ( calculate( nn, inv, inv ) )
00851           aStack.push( QVariant() );
00852       }
00853       else if ( aClose.contains( nn ) )
00854       {
00855         QList<QVariant> set;
00856         while ( true )
00857         {
00858           if ( aStack.isEmpty() )
00859           {
00860             setError( QtxEvalExpr::StackUnderflow );
00861             break;
00862           }
00863           if ( aStack.top().isValid() )
00864           {
00865             set.append( aStack.top() );
00866             aStack.pop();
00867           }
00868           else
00869           {
00870             aStack.pop();
00871             break;
00872           }
00873         }
00874 
00875         QVariant qSet = set, inv;
00876         if ( calculate( nn, qSet, inv ) )
00877           aStack.push( set );
00878       }
00879       else if ( aStack.count() >= 1 )
00880       {
00881         QVariant inv;
00882         QVariant* v1 = &aStack.top(), *v2 = &inv; //"post-" case
00883         if ( (*anIt).myType == Pre )
00884         {
00885           v2 = &aStack.top();
00886           v1 = &inv;
00887         }
00888         calculate( nn, *v1, *v2 );
00889       }
00890       else
00891         setError( QtxEvalExpr::StackUnderflow );
00892     }
00893     else if ( (*anIt).myType == Binary )
00894     {
00895       if ( aStack.count() >= 2 )
00896       {
00897         QVariant v2 = aStack.top();
00898         aStack.pop();
00899         calculate( nn, aStack.top(), v2 );
00900       }
00901       else
00902         setError( QtxEvalExpr::StackUnderflow );
00903     }
00904   }
00905 
00906   QVariant res;
00907   if ( error() == QtxEvalExpr::OK )
00908   {
00909     int count = aStack.count();
00910     if ( count == 0 )
00911       setError( QtxEvalExpr::StackUnderflow );
00912     else if( count == 1 )
00913       res = aStack.top();
00914     else
00915       setError( QtxEvalExpr::ExcessData );
00916   }
00917   return res;
00918 }
00919 
00925 QVariant QtxEvalParser::calculate( const QString& expr )
00926 {
00927   setExpression( expr );
00928   return calculate();
00929 }
00930 
00936 bool QtxEvalParser::setExpression( const QString& expr )
00937 {
00938   return parse( expr );
00939 }
00940 
00946 bool QtxEvalParser::hasParameter( const QString& name ) const
00947 {
00948   return myParams.contains( name.trimmed() );
00949 }
00950 
00956 void QtxEvalParser::setParameter( const QString& name, const QVariant& value )
00957 {
00958   myParams.insert( name.trimmed(), value );
00959 }
00960 
00966 bool QtxEvalParser::removeParameter( const QString& name )
00967 {
00968   return myParams.remove( name.trimmed() );
00969 }
00970 
00976 QVariant QtxEvalParser::parameter( const QString& name ) const
00977 {
00978   QVariant res;
00979   if ( myParams.contains( name.trimmed() ) )
00980     res = myParams[name.trimmed()].toString();
00981   return res;
00982 }
00983 
00989 bool QtxEvalParser::firstInvalid( QString& name ) const
00990 {
00991   for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
00992   {
00993     if ( !anIt.value().isValid() )
00994     {
00995       name = anIt.key();
00996       return true;
00997     }
00998   }
00999   return false;
01000 }
01001 
01005 void QtxEvalParser::removeInvalids()
01006 {
01007   QStringList toDelete;
01008   for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
01009   {
01010     if ( !anIt.value().isValid() )
01011       toDelete.append( anIt.key() );
01012   }
01013 
01014   for ( QStringList::const_iterator aLIt = toDelete.begin(); aLIt != toDelete.end(); aLIt++ )
01015     myParams.remove( *aLIt );
01016 }
01017 
01022 QtxEvalExpr::Error QtxEvalParser::error() const
01023 {
01024   return myError;
01025 }
01026 
01032 void QtxEvalParser::setError( QtxEvalExpr::Error err )
01033 {
01034   myError = err;
01035 }
01036 
01041 QString QtxEvalParser::dump() const
01042 {
01043   return dump( myPostfix );
01044 }
01045 
01051 QString QtxEvalParser::dump( const Postfix& post ) const
01052 {
01053   QString res;
01054 
01055   if ( !checkOperations() )
01056     return res;
01057 
01058   for ( Postfix::const_iterator anIt = post.begin(); anIt != post.end(); anIt++ )
01059   {
01060     if ( (*anIt).myType == Value && (*anIt).myValue.type() == QVariant::String )
01061       res += "'" + (*anIt).myValue.toString() + "'";
01062     else
01063       res += (*anIt).myValue.toString();
01064     
01065     if ( (*anIt).myType == Pre )
01066       res += "(pre)";
01067     else if ( (*anIt).myType == Post )
01068       res += "(post)";
01069     else if ( (*anIt).myType == Binary )
01070       res += "(bin)";
01071 
01072     res += "_";
01073   }
01074 
01075   return res;
01076 }
01077 
01082 QStringList QtxEvalParser::parameters() const
01083 {
01084   QStringList lst;
01085   for ( Postfix::const_iterator anIt = myPostfix.begin(); anIt != myPostfix.end(); anIt++ )
01086   {
01087     if ( (*anIt).myType == Param )
01088     {
01089       QString name = (*anIt).myValue.toString();
01090       if ( !lst.contains( name ) )
01091         lst.append( name );
01092     }
01093   }
01094   return lst;
01095 }
01096 
01100 void QtxEvalParser::clearParameters()
01101 {
01102   myParams.clear();
01103 }
01104 
01110 QString QtxEvalParser::toString( const QList<QVariant>& list )
01111 {
01112   QString res = "set : [ ";
01113   for ( QList<QVariant>::const_iterator anIt = list.begin(); anIt != list.end(); anIt++ )
01114     res += (*anIt).toString() + " ";
01115   res += "]";
01116   return res;
01117 }
01118 
01123 void QtxEvalParser::operationList( QStringList& list ) const
01124 {
01125   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
01126   {
01127     QStringList custom;
01128     QtxEvalSet* set = *it;
01129     set->operationList( custom );
01130     for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
01131     {
01132       if ( !list.contains( *sIt ) )
01133         list.append( *sIt );
01134     }
01135   }
01136 }
01137 
01143 void QtxEvalParser::bracketsList( QStringList& list, bool open ) const
01144 {
01145   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
01146   {
01147     QStringList custom;
01148     QtxEvalSet* set = *it;
01149     set->bracketsList( custom, open );
01150     for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
01151     {
01152       if ( !list.contains( *sIt ) )
01153         list.append( *sIt );
01154     }
01155   }
01156 }
01157 
01164 bool QtxEvalParser::createValue( const QString& str, QVariant& val ) const
01165 {
01166   bool ok = false;
01167   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !ok; ++it )
01168     ok = (*it)->createValue( str, val );
01169   return ok;
01170 }
01171 
01178 int QtxEvalParser::priority( const QString& op, bool isBin ) const
01179 {
01180   int i = 0;
01181   int priority = 0;
01182   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && priority <= 0; ++it, i++ )
01183     priority = (*it)->priority( op, isBin );
01184 
01185   return priority > 0 ? priority + i * 50 : 0;
01186 }
01187 
01198 QtxEvalExpr::Error QtxEvalParser::isValid( const QString& op,
01199                                            const QVariant::Type t1, const QVariant::Type t2 ) const
01200 {
01201   QtxEvalExpr::Error err = QtxEvalExpr::OK;
01202   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
01203   {
01204     err = (*it)->isValid( op, t1, t2 );
01205     if ( err == QtxEvalExpr::OK )
01206       break;
01207   }
01208   return err;
01209 }
01210 
01222 QtxEvalExpr::Error QtxEvalParser::calculation( const QString& op, QVariant& v1, QVariant& v2 ) const
01223 {
01224   QVariant nv1, nv2;
01225   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
01226   {
01227     nv1 = v1;
01228     nv2 = v2;
01229     if ( (*it)->isValid( op, v1.type(), v2.type() ) == QtxEvalExpr::OK )
01230     {
01231       QtxEvalExpr::Error err = (*it)->calculate( op, nv1, nv2 );
01232       if ( err == QtxEvalExpr::OK || err == QtxEvalExpr::InvalidResult )
01233       {
01234         v1 = nv1;
01235         v2 = nv2;
01236         return err;
01237       }
01238     }
01239   }
01240   return QtxEvalExpr::InvalidOperation;
01241 }
01242 
01247 bool QtxEvalParser::checkOperations() const
01248 {
01249   if ( !mySets.isEmpty() )
01250     return true;
01251 
01252   QtxEvalParser* that = (QtxEvalParser*)this;
01253   that->setError( QtxEvalExpr::OperationsNull );
01254   return false;
01255 }
01256 
01265 QtxEvalSet::QtxEvalSet()
01266 {
01267 }
01268 
01272 QtxEvalSet::~QtxEvalSet()
01273 {
01274 }
01275 
01303 bool QtxEvalSet::createValue( const QString& str, QVariant& val ) const
01304 {
01305   val = str;
01306   return false;
01307 }
01308 
01368 QtxEvalSetBase::QtxEvalSetBase()
01369 {
01370 }
01371 
01375 QtxEvalSetBase::~QtxEvalSetBase()
01376 {
01377 }
01378 
01384 void QtxEvalSetBase::bracketsList( QStringList& list, bool open ) const
01385 {
01386   list.append( open ? "(" : ")" );
01387 }
01388 
01393 void QtxEvalSetBase::operationList( QStringList& list ) const
01394 {
01395   list += myOpers;
01396 }
01397 
01402 void QtxEvalSetBase::addOperations( const QStringList& list )
01403 {
01404   for ( QStringList::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
01405   {
01406     if ( !myOpers.contains( *anIt ) )
01407       myOpers.append( *anIt );
01408   }
01409 }
01410 
01415 void QtxEvalSetBase::addTypes( const ListOfTypes& list )
01416 {
01417   for ( ListOfTypes::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
01418   {
01419     if ( !myTypes.contains( *anIt ) )
01420       myTypes.append( *anIt );
01421   }
01422 }
01423 
01436 QtxEvalExpr::Error QtxEvalSetBase::isValid( const QString& op,
01437                                             const QVariant::Type t1, const QVariant::Type t2 ) const
01438 {
01439   if ( ( t1 == QVariant::Invalid || myTypes.contains( t1 ) ) &&
01440        ( t2 == QVariant::Invalid || myTypes.contains( t2 ) ) &&
01441        ( t1 != QVariant::Invalid || t2 != QVariant::Invalid ) )
01442   {
01443     if ( priority( op, t1 != QVariant::Invalid && t2 != QVariant::Invalid ) > 0 )
01444       return QtxEvalExpr::OK;
01445     else
01446       return QtxEvalExpr::InvalidOperation;
01447   }
01448   else
01449     return QtxEvalExpr::OperandsNotMatch;
01450 }
01451 
01460 QtxEvalSetArithmetic::QtxEvalSetArithmetic()
01461 : QtxEvalSetBase()
01462 {
01463   addOperations( QString( "+;-;*;/;=;<;>;<=;>=;<>;!=" ).split( ";" ) );
01464 
01465   ListOfTypes aTypes;
01466   aTypes.append( QVariant::Int );
01467   aTypes.append( QVariant::UInt );
01468   aTypes.append( QVariant::Double );
01469   addTypes( aTypes );
01470 }
01471 
01475 QtxEvalSetArithmetic::~QtxEvalSetArithmetic()
01476 {
01477 }
01478 
01483 QString QtxEvalSetArithmetic::Name()
01484 {
01485   return "Arithmetic";
01486 }
01487 
01492 QString QtxEvalSetArithmetic::name() const
01493 {
01494   return Name();
01495 }
01496 
01507 bool QtxEvalSetArithmetic::createValue( const QString& str, QVariant& val ) const
01508 {
01509   bool ok = false;
01510   val = str.toInt( &ok );
01511 
01512   if ( !ok )
01513   {
01514     val = str.toDouble( &ok );
01515     if ( !ok )
01516       ok = QtxEvalSetBase::createValue( str, val );
01517   }
01518   return ok;
01519 }
01520 
01531 int QtxEvalSetArithmetic::priority( const QString& op, bool isBin ) const
01532 {
01533   if ( isBin )
01534   {
01535     if ( op == "<" || op == ">" || op == "=" ||
01536          op == "<=" || op == ">=" || op == "<>" || op == "!=" )
01537       return 1;
01538     else if ( op == "+" || op == "-" )
01539       return 2;
01540     else if( op == "*" || op == "/" )
01541       return 3;
01542     else
01543       return 0;
01544   }
01545   else if ( op == "+" || op == "-" )
01546     return 5;
01547   else
01548     return 0;
01549 }
01550 
01563 QtxEvalExpr::Error QtxEvalSetArithmetic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
01564 {
01565   QtxEvalExpr::Error err = QtxEvalExpr::OK;
01566 
01567   if ( v1.isValid() && v2.isValid() )
01568   {
01569     // binary operations
01570     if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::UInt ) &&
01571          ( v2.type() == QVariant::Int || v2.type() == QVariant::UInt ) )
01572     {
01573       int _v1 = v1.toInt();
01574       int _v2 = v2.toInt();
01575 
01576       if ( op == "+" )
01577         v1 = _v1 + _v2;
01578       else if ( op == "-" )
01579         v1 = _v1 - _v2;
01580       else if ( op == "*" )
01581         v1 = _v1 * _v2;
01582       else if ( op == "/" )
01583       {
01584         if ( _v2 != 0 )
01585         {
01586           if ( _v1 % _v2 == 0 )
01587             v1 = _v1 / _v2;
01588           else
01589             v1 = double( _v1 ) / double( _v2 );
01590         }
01591         else
01592           err = QtxEvalExpr::InvalidResult;
01593       }
01594       else if ( op == "<" )
01595         v1 = _v1 < _v2;
01596       else if ( op == ">" )
01597         v1 = _v1 > _v2;
01598       else if ( op == "=" )
01599         v1 = _v1 == _v2;
01600       else if ( op == "<=" )
01601         v1 = _v1 <= _v2;
01602       else if ( op == ">=" )
01603         v1 = _v1 >= _v2;
01604       else if ( op == "<>" || op == "!=" )
01605         v1 = _v1 != _v2;
01606     }
01607     else if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::Double ) &&
01608               ( v2.type() == QVariant::Int || v2.type() == QVariant::Double ) )
01609     {
01610       double _v1 = v1.toDouble();
01611       double _v2 = v2.toDouble();
01612 
01613       if ( op == "+" )
01614         v1 = _v1 + _v2;
01615       else if ( op == "-" )
01616         v1 = _v1 - _v2;
01617       else if ( op == "*" )
01618           v1 = _v1 * _v2;
01619       else if ( op == "/" )
01620       {
01621         if ( _v2 != 0 )
01622           v1 = _v1 / _v2;
01623         else
01624           err = QtxEvalExpr::InvalidResult;
01625       }
01626       else if ( op == "<" )
01627         v1 = _v1 < _v2;
01628       else if ( op == ">" )
01629         v1 = _v1 > _v2;
01630       else if ( op == "=" )
01631         v1 = _v1 == _v2;
01632       else if ( op == "<=" )
01633         v1 = _v1 <= _v2;
01634       else if ( op == ">=" )
01635         v1 = _v1 >= _v2;
01636       else if ( op == "<>" || op == "!=" )
01637         v1 = _v1 != _v2;
01638     }
01639     else // prefix operations
01640     {
01641       if ( op == "-" )
01642       {
01643         if ( v2.type() == QVariant::Int )
01644           v2 = -v2.toInt();
01645         else if ( v2.type() == QVariant::Double )
01646           v2 = -v2.toDouble();
01647       }
01648     }
01649   }
01650 
01651   return err;
01652 }
01653 
01662 QtxEvalSetLogic::QtxEvalSetLogic()
01663 : QtxEvalSetBase()
01664 {
01665   addOperations( QString( "and;&&;or;||;xor;not;!;imp;=" ).split( ";" ) );
01666 
01667   ListOfTypes aTypes;
01668   aTypes.append( QVariant::Bool );
01669   aTypes.append( QVariant::Int );
01670   aTypes.append( QVariant::UInt );
01671   addTypes( aTypes );
01672 }
01673 
01677 QtxEvalSetLogic::~QtxEvalSetLogic()
01678 {
01679 }
01680 
01685 QString QtxEvalSetLogic::Name()
01686 {
01687   return "Logic";
01688 }
01689 
01694 QString QtxEvalSetLogic::name() const
01695 {
01696   return Name();
01697 }
01698 
01709 bool QtxEvalSetLogic::createValue( const QString& str, QVariant& val ) const
01710 {
01711   bool ok = true;
01712   QString valStr = str.toLower();
01713   if ( valStr == "true" || valStr == "yes" )
01714     val = QVariant( true );
01715   else if ( valStr == "false" || valStr == "no" )
01716     val = QVariant( false );
01717   else
01718     ok = QtxEvalSetBase::createValue( str, val );
01719 
01720   return ok;
01721 }
01722 
01733 int QtxEvalSetLogic::priority( const QString& op, bool isBin ) const
01734 {
01735   if ( isBin )
01736   {
01737     if ( op == "and" || op == "or" || op == "xor" || op == "&&" || op == "||" || op == "imp" )
01738       return 1;
01739     else if ( op == "=" )
01740       return 2;
01741     else 
01742       return 0;
01743   }
01744   else if ( op == "not" || op == "!" )
01745     return 5;
01746   else
01747     return 0;
01748 }
01749 
01762 QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
01763 {
01764   QtxEvalExpr::Error err = QtxEvalExpr::OK;
01765   int val1 = intValue( v1 );
01766   int val2 = intValue( v2 );
01767   if ( v1.isValid() && v2.isValid() )
01768   {
01769     if ( op == "and" || op == "&&" )
01770       v1 = val1 && val2;
01771     else if ( op == "or" || op == "||" )
01772       v1 = val1 || val2;
01773     else if ( op == "xor" )
01774       v1 = ( !val1 && val2 ) || ( val1 && !val2 );
01775     else if ( op == "imp" )
01776       v1 = !val1 || val2;
01777     else if ( op == "=" )
01778       v1 = val1 == val2;
01779   }
01780   else if ( op == "not" || op == "!" )
01781     v2 = !val2;
01782 
01783   return err;
01784 }
01785 
01795 int QtxEvalSetLogic::intValue( const QVariant& v ) const
01796 {
01797   int res = 0;
01798   switch ( v.type() )
01799   {
01800   case QVariant::Bool:
01801     res = v.toBool() ? 1 : 0;
01802     break;
01803   case QVariant::Int:
01804   case QVariant::UInt:
01805     res = v.toInt();
01806     break;
01807   default:
01808     break;
01809   }
01810   return res;
01811 }
01812 
01822 QtxEvalSetMath::QtxEvalSetMath()
01823 : QtxEvalSetBase()
01824 {
01825   addOperations( QString( "sqrt;abs;sin;cos;rad2grad;grad2rad" ).split( ";" ) );
01826 
01827   ListOfTypes aTypes;
01828   aTypes.append( QVariant::Int );
01829   aTypes.append( QVariant::Double );
01830   addTypes( aTypes );
01831 }
01832 
01836 QtxEvalSetMath::~QtxEvalSetMath()
01837 {
01838 }
01839 
01844 QString QtxEvalSetMath::Name()
01845 {
01846   return "Math";
01847 }
01848 
01853 QString QtxEvalSetMath::name() const
01854 {
01855   return Name();
01856 }
01857 
01868 bool QtxEvalSetMath::createValue( const QString& str, QVariant& val ) const
01869 {
01870   bool ok = false;
01871   val = str.toInt( &ok );
01872 
01873   if ( !ok )
01874   {
01875     val = str.toDouble( &ok );
01876     if ( !ok )
01877       ok = QtxEvalSetBase::createValue( str, val );
01878   }
01879   return ok;
01880 }
01881 
01892 int QtxEvalSetMath::priority( const QString& op, bool isBin ) const
01893 {
01894   if ( isBin )
01895     return 0;
01896   else if ( op == "sqrt" || op == "abs" || op == "sin" ||
01897             op == "cos" || op == "rad2grad" || op == "grad2rad" )
01898     return 1;
01899   else
01900     return 0;
01901 }
01902 
01915 QtxEvalExpr::Error QtxEvalSetMath::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
01916 {
01917   QtxEvalExpr::Error err = QtxEvalExpr::OK;
01918   double val = v2.toDouble();
01919   if ( op == "sqrt" )
01920   {
01921     if ( val >= 0 )
01922       v2 = sqrt( val );
01923     else
01924       err = QtxEvalExpr::InvalidResult;
01925   }
01926   else if ( op == "abs" )
01927   {
01928     if ( v2.type() == QVariant::Int )
01929       v2 = abs( v2.toInt() );
01930     else 
01931       v2 = fabs( v2.toDouble() );
01932   }
01933   else if ( op == "sin" )
01934     v2 = sin( val );
01935   else if ( op == "cos" )
01936     v2 = cos( val );
01937   else if ( op == "grad2rad" )
01938     v2 = val * 3.14159256 / 180.0;
01939   else if ( op == "rad2grad" )
01940     v2 = val * 180.0 / 3.14159256;
01941 
01942   return err;
01943 }
01944 
01953 QtxEvalSetString::QtxEvalSetString()
01954 : QtxEvalSetBase()
01955 {
01956   addOperations( QString( "+;=;<;>;<=;>=;<>;!=;length;lower;upper" ).split( ";" ) );
01957 
01958   ListOfTypes aTypes;
01959   aTypes.append( QVariant::Int );
01960   aTypes.append( QVariant::Double );
01961   aTypes.append( QVariant::String );
01962   addTypes( aTypes );
01963 }
01964 
01968 QtxEvalSetString::~QtxEvalSetString()
01969 {
01970 }
01971 
01976 QString QtxEvalSetString::Name()
01977 {
01978   return "String";
01979 }
01980 
01985 QString QtxEvalSetString::name() const
01986 {
01987   return Name();
01988 }
01989 
02000 bool QtxEvalSetString::createValue( const QString& str, QVariant& val ) const
02001 {
02002   bool ok = false;
02003   if ( str.length() > 1 && str[0] == '\'' && str[str.length() - 1] == '\'' )
02004   {
02005     val = str.mid( 1, str.length() - 2 );
02006     ok = true;
02007   }
02008   else
02009     ok = QtxEvalSetBase::createValue( str, val );
02010   return ok;
02011 }
02012 
02023 int QtxEvalSetString::priority( const QString& op, bool isBin ) const
02024 {
02025   if ( isBin )
02026   {
02027     if ( op == "+" ) 
02028       return 2;
02029     else if ( op == "=" || op == "<" || op == ">" ||
02030               op == "<=" || op == ">=" || op == "<>" || op == "!=" )
02031       return 1;
02032     else
02033       return 0;
02034   }
02035   else if ( op == "length" || op == "lower" || op=="upper" )
02036     return 5;
02037   else
02038     return 0;
02039 }
02040 
02053 QtxEvalExpr::Error QtxEvalSetString::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
02054 {
02055   QtxEvalExpr::Error err = QtxEvalExpr::OK;
02056   if ( v1.isValid() && v2.isValid() )
02057   {
02058     QString _v1 = v1.toString();
02059     QString _v2 = v2.toString();
02060     if ( op == "+" )
02061       v1 = _v1 + _v2;
02062     else if ( op == "=" )
02063       v1 = _v1 ==_v2;
02064     else if ( op == "<" )
02065       v1 = _v1 < _v2;
02066     else if ( op == ">" )
02067       v1 = _v1 > _v2;
02068     else if ( op == "<>" || op == "!=" )
02069       v1 = _v1 != _v2;
02070     else if ( op == "<=" )
02071       v1 = _v1 < _v2 || _v1 == _v2;
02072     else if ( op == ">=" )
02073       v1 = _v1 > _v2 || _v1 == _v2;
02074   }
02075   else if ( !v1.isValid() && v2.isValid() )
02076   {
02077     QString val = v2.toString();
02078     if ( op == "length" )
02079       v2 = (int)val.length();
02080     else if ( op == "lower" )
02081       v2 = val.toLower();
02082     else if ( op == "upper" )
02083       v2 = val.toUpper();
02084   }
02085   return err;
02086 }
02087 
02096 QtxEvalSetSets::QtxEvalSetSets()
02097 : QtxEvalSetBase()
02098 {
02099   addOperations( QString( "{;};=;<>;!=;+;-;*;in;count" ).split( ";" ) );
02100 
02101   ListOfTypes aTypes;
02102   aTypes.append( QVariant::List );
02103   addTypes( aTypes );
02104 }
02105 
02109 QtxEvalSetSets::~QtxEvalSetSets()
02110 {
02111 }
02112 
02117 QString QtxEvalSetSets::Name()
02118 {
02119   return "Sets";
02120 }
02121 
02126 QString QtxEvalSetSets::name() const
02127 {
02128   return Name();
02129 }
02130 
02136 void QtxEvalSetSets::bracketsList( QStringList& list, bool open ) const
02137 {
02138   list.append( open ? "{" : "}" );
02139   QtxEvalSetBase::bracketsList( list, open );
02140 }
02141 
02152 int QtxEvalSetSets::priority( const QString& op, bool isBin ) const
02153 {
02154   if ( isBin )
02155   {
02156     if ( op == "=" || op == "<>" || op == "!=" )
02157       return 1;
02158     else if ( op == "+" || op == "-" || op == "*" )
02159       return 2;
02160     else if ( op == "in" )
02161       return 3;
02162     else
02163       return 0;
02164   }
02165   else if ( op == "{" || op == "}" )
02166     return 5;
02167   else if ( op == "count" )
02168     return 4;
02169   else
02170     return 0;
02171 }
02172 
02185 QtxEvalExpr::Error QtxEvalSetSets::isValid( const QString& op,
02186                                             const QVariant::Type t1, const QVariant::Type t2 ) const
02187 {
02188   if ( op == "{" )
02189     return QtxEvalExpr::OK;
02190 
02191   if ( op != "in" )
02192     return QtxEvalSetBase::isValid( op, t1, t2 );
02193 
02194   if ( t1 != QVariant::Invalid && t2 == QVariant::List )
02195     return QtxEvalExpr::OK;
02196   else
02197     return QtxEvalExpr::OperandsNotMatch;
02198 }
02199 
02205 void QtxEvalSetSets::add( ValueSet& set, const QVariant& v )
02206 {
02207   if ( v.isValid() && !set.contains( v ) )
02208     set.append( v );
02209 }
02210 
02216 void QtxEvalSetSets::add( ValueSet& s1, const ValueSet& s2 )
02217 {
02218   for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
02219     add( s1, *anIt );
02220 }
02221 
02227 void QtxEvalSetSets::remove( ValueSet& set, const QVariant& v )
02228 {
02229   set.removeAll( v );
02230 }
02231 
02237 void QtxEvalSetSets::remove( ValueSet& s1, const ValueSet& s2 )
02238 {
02239   for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
02240     s1.removeAll( *anIt );
02241 }
02242 
02255 QtxEvalExpr::Error QtxEvalSetSets::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
02256 {
02257   QtxEvalExpr::Error err = QtxEvalExpr::OK;
02258 
02259   if ( op != "{" )
02260   {
02261     if ( op == "}" )
02262     {
02263       ValueSet aNewList;
02264       add( aNewList, v1.toList() );
02265       v1 = aNewList;
02266     }
02267     else if ( op == "=" || op == "<>" || op == "!=" || op == "+" || op == "-" || op == "*" )
02268     {
02269       ValueSet aNewList;
02270       add( aNewList, v1.toList() );
02271       if ( op == "=" || op == "<>" || op == "!=" || op == "-" )
02272       {
02273         remove( aNewList, v2.toList() );
02274         if ( op == "=" )
02275           v1 = aNewList.isEmpty() && v1.toList().count() == v2.toList().count();
02276         else if ( op == "<>" || op == "!=" )
02277           v1 = !aNewList.isEmpty() || v1.toList().count() != v2.toList().count();
02278         else
02279           v1 = aNewList;
02280       }
02281       else if ( op == "+" )
02282       {
02283         add( aNewList, v2.toList() );
02284         v1 = aNewList;
02285       }
02286       else if ( op == "*" )
02287       {
02288         ValueSet toDelete;
02289         add( toDelete, aNewList );
02290         remove( toDelete, v2.toList() );
02291         remove( aNewList, toDelete );
02292         v1 = aNewList;
02293       }
02294     }
02295     else if ( op== "count" )
02296       v2 = (int)v2.toList().count();
02297     else if ( op == "in" )
02298     {
02299       if ( v1.type() == QVariant::List )
02300       {
02301         bool res = true;
02302         ValueSet lst1 = v1.toList();
02303         ValueSet lst2 = v2.toList();
02304         for ( ValueSet::const_iterator anIt = lst1.begin(); anIt != lst1.end() && res; ++anIt )
02305           res = lst2.contains( *anIt );
02306 
02307         v1 = res;
02308       }
02309       else
02310               v1 = QVariant( v2.toList().contains( v1 ) );
02311     }
02312   }
02313   return err;
02314 }
02315 
02320 QtxEvalSetConst::QtxEvalSetConst()
02321 : QtxEvalSet()
02322 {
02323 }
02324 
02328 QtxEvalSetConst::~QtxEvalSetConst()
02329 {
02330 }
02331 
02336 QString QtxEvalSetConst::Name()
02337 {
02338   return "Const";
02339 }
02340 
02345 QString QtxEvalSetConst::name() const
02346 {
02347   return Name();
02348 }
02349 
02360 bool QtxEvalSetConst::createValue( const QString& str, QVariant& val ) const
02361 {
02362   bool ok = true;
02363   if ( str == "pi" )            // PI number
02364     val = QVariant( 3.141593 );
02365   else if ( str == "exp" )      // Exponent value (e)
02366     val = QVariant( 2.718282 );
02367   else if ( str == "g" )        // Free fall acceleration (g)
02368     val = QVariant( 9.80665 );
02369   else
02370     ok = false;
02371 
02372   return ok;
02373 }
02374 
02379 void QtxEvalSetConst::operationList( QStringList& /*list*/ ) const
02380 {
02381 }
02382 
02388 void QtxEvalSetConst::bracketsList( QStringList& /*list*/, bool /*open*/ ) const
02389 {
02390 }
02391 
02402 int QtxEvalSetConst::priority( const QString& /*op*/, bool /*isBin*/ ) const
02403 {
02404   return 0;
02405 }
02406 
02417 QtxEvalExpr::Error QtxEvalSetConst::isValid( const QString&       /*op*/, 
02418                                              const QVariant::Type /*t1*/,
02419                                              const QVariant::Type /*t2*/ ) const
02420 {
02421   return QtxEvalExpr::InvalidOperation;
02422 }
02423 
02434 QtxEvalExpr::Error QtxEvalSetConst::calculate( const QString&, QVariant&, QVariant& ) const
02435 {
02436   return QtxEvalExpr::InvalidOperation;
02437 }