Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/gui.git] / src / Qtx / QtxEvalExpr.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:      QtxEvalExpr.cxx
23 // Author:    Alexander SOLOVYOV, Sergey TELKOV
24 //
25 #include "QtxEvalExpr.h"
26
27 #include <QStack>
28
29 #include <math.h>
30
31 /*!
32   \class QtxEvalExpr
33   \brief String expression evaluator.
34 */
35
36 /*!
37   \brief Constructor.
38
39   The evaluator is initalized by standard operations. Use another constructor with parameter
40   \a stdSets = \c false to avoid initialization of evaluator with standard operations.
41
42   \param expr expression to be evaluated
43 */
44 QtxEvalExpr::QtxEvalExpr( const QString& expr )
45 {
46   intialize( true, expr );
47 }
48
49 /*!
50   \brief Constructor.
51   \param stdSets if \c true, the evaluator is initalized by standard operations
52   \param expr expression to be evaluated
53 */
54 QtxEvalExpr::QtxEvalExpr( const bool stdSets, const QString& expr )
55 {
56   intialize( stdSets, expr );
57 }
58
59 /*!
60   \brief Destructor.
61 */
62 QtxEvalExpr::~QtxEvalExpr()
63 {
64   delete myParser;
65 }
66
67 /*!
68   \brief Initialize the evaluator.
69   \param stdSets if \c true, the evaluator is initalized by standard operations
70   \param expr expression to be evaluated
71 */
72 void QtxEvalExpr::intialize( const bool stdSets, const QString& expr )
73 {
74   myParser = new QtxEvalParser();
75   if ( stdSets )
76   {
77     myParser->setAutoDeleteOperationSets( true );
78     myParser->insertOperationSet( new QtxEvalSetLogic() );
79     myParser->insertOperationSet( new QtxEvalSetArithmetic() );
80     myParser->insertOperationSet( new QtxEvalSetString() );
81     myParser->insertOperationSet( new QtxEvalSetMath() );
82     myParser->insertOperationSet( new QtxEvalSetSets() );
83     myParser->insertOperationSet( new QtxEvalSetConst() );
84   }
85   setExpression( expr );
86 }
87
88 /*!
89   \brief Evaluate the expression.
90   \param expr expression to be evaluated
91   \return result of the evaluation
92 */
93 QVariant QtxEvalExpr::calculate( const QString& expr )
94 {
95   if ( !expr.isEmpty() )
96     setExpression( expr );
97   return myParser->calculate();
98 }
99
100 /*!
101   \brief Get the expression.
102   \return expression string
103 */
104 QString QtxEvalExpr::expression() const
105 {
106   return myExpr;
107 }
108
109 /*!
110   \brief Set the expression.
111   \param expr expression string
112 */
113 void QtxEvalExpr::setExpression( const QString& expr )
114 {
115   if ( expr == expression() )
116     return;
117
118   myExpr = expr;
119   myParser->setExpression( myExpr );
120 }
121
122 /*!
123   \brief Get the code of latest parsing error.
124   \return the code of the last error
125 */
126 QtxEvalExpr::Error QtxEvalExpr::error() const
127 {
128   return myParser->error();
129 }
130
131 /*!
132   \brief Get the expression parser.
133   \return expression parser
134 */
135 QtxEvalParser* QtxEvalExpr::parser() const
136 {
137   return myParser;
138 }
139
140 /*!
141   \brief Get current set of operations.
142   \return operations set
143   \sa insertOperationSet(), removeOperationSet(), operationSet()
144 */
145 QList<QtxEvalSet*> QtxEvalExpr::operationSets() const
146 {
147   return myParser->operationSets();
148 }
149
150 /*!
151   \brief Install the operation.
152   \param operation to be added
153   \param idx index in the list at which the operation shoud be inserted
154   \sa operationSets(), removeOperationSet(), operationSet()
155 */
156 void QtxEvalExpr::insertOperationSet( QtxEvalSet* set, const int idx )
157 {
158   myParser->insertOperationSet( set, idx );
159 }
160
161 /*!
162   \brief Remove the operation.
163   \param operation to be removed
164   \sa operationSets(), insertOperationSet(), operationSet()
165 */
166 void QtxEvalExpr::removeOperationSet( QtxEvalSet* set )
167 {
168   myParser->removeOperationSet( set );
169 }
170
171 /*!
172   \brief Get the operation by name.
173   \param name operation name
174   \return operation of 0 if not found
175   \sa operationSets(), insertOperationSet(), removeOperationSet()
176 */
177 QtxEvalSet* QtxEvalExpr::operationSet( const QString& name ) const
178 {
179   return myParser->operationSet( name );
180 }
181
182 /*!
183   \brief Get the 'auto-delete operations' flag value.
184   \return \c true if all operations shoud be automatically deleted when the evaluator is destroyed
185   \sa setAutoDeleteOperationSets()
186 */
187 bool QtxEvalExpr::autoDeleteOperationSets() const
188 {
189   return myParser->autoDeleteOperationSets();
190 }
191
192 /*!
193   \brief Set the 'auto-delete operations' flag value.
194   \param on if \c true, all operations shoud be automatically deleted when the evaluator is destroyed
195   \sa autoDeleteOperationSets()
196 */
197 void QtxEvalExpr::setAutoDeleteOperationSets( const bool on )
198 {
199   myParser->setAutoDeleteOperationSets( on );
200 }
201
202 /*!
203   \class QtxEvalParser
204   \brief Expression parser.
205
206   This class provides the functionality to calculate value of the expression using defined set of operations.
207   Standard operations (arithmetics, logic, strings, etc) are implemented in the corresponding successors of the
208   QtxEvalSet class: QtxEvalSetArithmetic, QtxEvalSetLogic, QtxEvalSetMath, QtxEvalSetString, ...
209
210   The parser allows using parameters with help of methods has(), set(), remove(), value(). It uses
211   postfix representation of expressions and uses class QtxEvalSet in order to make certain operation.
212
213   Every instance of parser contains only one postfix - thus, if the expression is changed, the postfix
214   must be rebuilt. In order to increase performance of frequent calculations for many of expressions it is 
215   recommended to use different instances of the parser for each expression.
216 */
217
218 /*!
219   \brief Constructor.
220 */
221 QtxEvalParser::QtxEvalParser()
222 : myAutoDel( false )
223 {
224   setError( QtxEvalExpr::OK );
225 }
226
227 /*!
228   \brief Destructor.
229 */
230 QtxEvalParser::~QtxEvalParser()
231 {
232   if ( autoDeleteOperationSets() )
233     qDeleteAll( mySets );
234 }
235
236 /*!
237   \brief Get current operations set.
238   \return current operations set
239 */
240 QList<QtxEvalSet*> QtxEvalParser::operationSets() const
241 {
242   return mySets;
243 }
244
245 /*!
246   \brief Get the operations set by \a name.
247   \param name the name of the operation set
248   \return operation set or 0 if not found
249 */
250 QtxEvalSet* QtxEvalParser::operationSet( const QString& name ) const
251 {
252   QtxEvalSet* set = 0;
253   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !set; ++it )
254   {
255     if ( (*it)->name() == name )
256       set = *it;
257   }
258   return set;
259 }
260
261 /*!
262   \brief Install the operations set.
263   \param operations set to be added
264   \param idx index in the list at which the operations set shoud be inserted
265   \sa operationSets(), removeOperationSet(), operationSet()
266 */
267 void QtxEvalParser::insertOperationSet( QtxEvalSet* set, const int idx )
268 {
269   if ( mySets.contains( set ) )
270     return;
271
272   int index = idx < 0 ? mySets.count() : idx;
273   index = qMin( index, mySets.count() );
274   mySets.insert( index, set );
275 }
276
277 /*!
278   \brief Remove the operations set.
279   \param operations set to be removed
280   \sa operationSets(), insertOperationSet(), operationSet()
281 */
282 void QtxEvalParser::removeOperationSet( QtxEvalSet* set )
283 {
284   mySets.removeAll( set );
285 }
286
287 /*!
288   \brief Get the 'auto-delete operations' flag value.
289   \return \c true if all operations shoud be automatically deleted when the parser is destroyed
290   \sa setAutoDeleteOperationSets()
291 */
292 bool QtxEvalParser::autoDeleteOperationSets() const
293 {
294   return myAutoDel;
295 }
296
297 /*!
298   \brief Set the 'auto-delete operations' flag value.
299   \param on if \c true, all operations shoud be automatically deleted when the parser is destroyed
300   \sa autoDeleteOperationSets()
301 */
302 void QtxEvalParser::setAutoDeleteOperationSets( const bool on )
303 {
304   myAutoDel = on;
305 }
306
307 /*!
308   \brief Search elements of the list as substrings starting from \a offset.
309   \param list list of substrings
310   \param str string in which the searching is performed
311   \param offset starting index for search
312   \param matchLen returning matching length of any substring
313   \param listind returning index of the found substring in the \a list
314   \return position of first found substring inside the \a str or -1 if no matches is found
315 */
316 int QtxEvalParser::search( const QStringList& list, const QString& str,
317                            int offset, int& matchLen, int& listind )
318 {
319   int min = -1;
320   QStringList::const_iterator anIt = list.begin(), aLast = list.end();
321   for ( int ind = 0; anIt != aLast; anIt++, ind++ )
322   {
323     int pos = str.indexOf( *anIt, offset );
324     if ( pos >= 0 && ( min < 0 || min > pos ||
325                        ( min == pos && matchLen < (int)(*anIt).length() ) ) )
326     {
327       min = pos;
328       listind = ind;
329       matchLen = (*anIt).length();
330     }
331   }
332   if ( min < 0 )
333     matchLen = 0;
334   return min;
335 }
336
337 /*!
338   \brief Get the substring field from the string \a str.
339   \param str source string
340   \param pos start position of the substring
341   \param len length of the substring
342   \return substring (leading and trailing spaces are truncated)
343 */
344 QString QtxEvalParser::note( const QString& str, int pos, int len )
345 {
346     return str.mid( pos, len ).trimmed();
347 }
348
349 /*!
350   \brief Prepare to the parsing.
351
352   Performs the first step of the parsing:
353   - find tokens
354   - determine tokens types
355   - create unsorted pseudo-postfix (with brackets)
356
357   \param expr string expression
358   \param post postfix to be created
359   \return \c true on success and \c false if error is found
360 */
361 bool QtxEvalParser::prepare( const QString& expr, Postfix& post )
362 {
363   int pos = 0;
364   int len = expr.length();
365   QStack<int> aBracketStack;
366   QStringList anOpers, anOpenBr, aCloseBr;
367   if ( !checkOperations() )
368     return false;
369
370   bracketsList( anOpenBr, true );
371   bracketsList( aCloseBr, false );
372   operationList( anOpers );
373
374   while ( pos < len && error() == QtxEvalExpr::OK )
375   {
376     PostfixItem item;
377     while ( pos < len && expr[pos].isSpace() )
378       pos++;
379     if ( pos >= len )
380       break;
381
382     int mBrLen = 0, mLen = 0, br_ind = -1, op_ind = -1;
383     int oPos = search( anOpenBr, expr, pos, mBrLen, br_ind );
384     int cPos = oPos == pos ? -1 : search( aCloseBr, expr, pos, mBrLen, br_ind );
385     int opPos = search( anOpers, expr, pos, mLen, op_ind );
386
387     if ( expr[pos] == QChar( '\'' ) )
388     {
389       int vpos = pos + 1;
390       while ( vpos < (int)expr.length() && expr[vpos] != QChar( '\'' ) )
391         vpos++;
392
393       mLen = vpos - pos + 1;
394
395       int res = createValue( note( expr, pos, mLen ), item.myValue );
396       item.myType = res ? Value : Param;
397       post.append( item );
398       pos = vpos + 1;
399       continue;
400     }
401
402     if ( oPos == pos )
403     {
404       aBracketStack.push( br_ind );
405       item.myValue = note( expr, pos, mBrLen );
406       item.myType = Open;
407       post.append( item );
408     }
409     else if ( cPos == pos )
410     {
411       if ( aBracketStack.count() == 0 )
412       {
413         setError( QtxEvalExpr::ExcessClose );
414         break;
415       }
416       if ( br_ind != aBracketStack.top() )
417       {
418         setError( QtxEvalExpr::BracketsNotMatch );
419         break;
420       }
421       else
422       {
423         aBracketStack.pop();
424         item.myValue = note( expr, pos, mBrLen );
425         item.myType = Close;
426         post.append( item );
427       }
428     }
429     else
430       mBrLen = 0;
431
432     if ( opPos == pos )
433     {
434       mBrLen = 0;
435       item.myValue = note( expr, pos, mLen );
436       item.myType = Binary;
437
438       if ( oPos == pos )
439         post.insert( post.count() - 1, item );
440       else
441         post.append( item );
442     }
443     else
444     {
445       mLen = 0;
446       if ( oPos != pos && cPos != pos )
447       {
448               int i; 
449         for ( i = pos + 1; i < (int)expr.length(); i++ )
450         {
451           if ( expr[i].isSpace() )
452             break;
453         }
454
455         int vpos = i;
456         if ( oPos >= 0 && oPos < vpos )
457           vpos = oPos;
458         if ( cPos >= 0 && cPos < vpos )
459           vpos = cPos;
460         if ( opPos >= 0 && opPos < vpos )
461           vpos = opPos;
462
463         while( vpos < (int)expr.length() && 
464                ( expr[vpos].isLetter() || expr[vpos].isDigit() || expr[vpos]=='_' ) )
465           vpos++;
466
467         mLen = vpos - pos;
468         bool res = createValue( note( expr, pos, mLen ), item.myValue );
469         item.myType = res ? Value : Param;
470         post.append( item );
471       }
472     }
473
474     pos += mBrLen + mLen;
475   }
476
477   //Bracket checking
478   int brValue = 0;
479   for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
480   {
481     if ( (*anIt).myType == Open )
482       brValue++;
483     else if ( (*anIt).myType == Close )
484     {
485       if ( brValue > 0 )
486         brValue--;
487       else
488       {
489         setError( QtxEvalExpr::ExcessClose );
490         break;
491       }
492     }
493   }
494
495   if ( brValue > 0 )
496     setError( QtxEvalExpr::CloseExpected );
497
498   return error() == QtxEvalExpr::OK;
499 }
500
501 /*!
502   \brief Analyze the operations used.
503   
504   Second step of the parsing: analyze the types of the operations used in the expression.
505
506   \param post unsorted postfix
507   \return \c true on success and \c false if error is found
508 */
509 bool QtxEvalParser::setOperationTypes( Postfix& post )
510 {
511   if ( !checkOperations() )
512     return false;
513
514   QStringList anOpen, aClose;
515   bracketsList( anOpen, true );
516   bracketsList( aClose, false );
517
518   Postfix::iterator aPrev, aNext;
519   for ( Postfix::iterator anIt = post.begin(); anIt != post.end(); ++anIt )
520   {
521     aPrev = anIt;
522     aPrev--;
523     aNext = anIt;
524     aNext++;
525     if ( (*anIt).myType != Binary )
526       continue;
527
528     if ( ( anIt == post.begin() || (*aPrev).myType == Open ||
529            (*aPrev).myType == Pre || (*aPrev).myType == Binary ) &&  aNext != post.end() &&
530          ( (*aNext).myType == Value || (*aNext).myType == Param ||
531            (*aNext).myType == Open  || (*aNext).myType == Binary ) )
532       (*anIt).myType = Pre;
533     else if ( anIt != post.begin() && ( (*aPrev).myType == Close || (*aPrev).myType == Param ||
534                                         (*aPrev).myType == Value || (*aPrev).myType == Pre ||
535                                         (*aPrev).myType == Post || (*aPrev).myType == Binary ) &&
536               ( aNext == post.end() || (*aNext).myType == Close ) )
537       (*anIt).myType = Post;
538
539     if ( anOpen.contains( (*anIt).myValue.toString() ) )
540       (*anIt).myType = Pre;
541     else if ( aClose.contains( (*anIt).myValue.toString() ) )
542       (*anIt).myType = Post;
543   }
544
545   return error() == QtxEvalExpr::OK;
546 }
547
548 /*!
549   \brief Get the number of the globar brackets pairs.
550
551   For example, the expression '((2+3))' has 2 global brackets pairs.
552
553   \param post postfix to be checked
554   \param f starting position for the search
555   \param l last position for the search
556   \return number of brackets pairs
557 */
558 int QtxEvalParser::globalBrackets( const QtxEvalParser::Postfix& post, int f, int l )
559 {
560   int i;
561   int start_br = 0;
562   int fin_br = 0;
563   int br = 0;
564   int br_num = 0;
565   int min_br_num = (l-f+1)*5;
566     
567   for( i=f; i<=l; i++ )
568     if( post[ i ].myType==QtxEvalParser::Open )
569       start_br++;
570     else
571       break;
572   for( i=l; i>=f; i-- )
573     if( post[ i ].myType==QtxEvalParser::Close )
574       fin_br++;
575     else
576       break;
577
578   br = start_br<fin_br ? start_br : fin_br;
579   for( i=f+br; i<=l-br; i++ )
580   {
581     if( post[i].myType==QtxEvalParser::Open )
582       br_num++;
583     else if( post[i].myType==QtxEvalParser::Close )
584       br_num--;
585     if( br_num<min_br_num )
586       min_br_num = br_num;
587   }
588   
589   return br+min_br_num;
590 }
591
592 /*!
593   \brief Sort the operations in the postfix.
594
595   Third step of parsing: sort the postfix operations in order to convert it to real postfix.
596
597   \param post source postfix
598   \param res returning resulting postfix
599   \param anOpen list of open brackets
600   \param aClose list of close brackets
601   \param f start index of postfix for sorting
602   \param l last index of postfix for sorting
603   \return \c true on success and \c false if error is found
604 */
605 bool QtxEvalParser::sort( const Postfix& post, Postfix& res, const QStringList& anOpen,
606                           const QStringList& aClose, int f, int l )
607 {
608   if ( l < f )
609     return true;
610
611   if ( f < 0 )
612     f = 0;
613
614   if ( l < 0 )
615     l = post.count() - 1;
616
617   int br = globalBrackets( post, f, l );
618   f += br;
619   l -= br;
620
621   if ( f == l && f >= 0 )
622     res.append( post[f] );
623
624   if ( l <= f )
625     return true;
626
627   if ( !checkOperations() )
628     return false;
629
630   int min = -1;
631   QIntList argmin;
632   QList<PostfixItemType> min_types;
633
634   for ( int i = 0, j = f; j <= l; i++, j++ )
635   {
636     const PostfixItem& item = post[j];
637     PostfixItemType tt = item.myType;
638     if ( tt == Binary || tt == Pre || tt == Post )
639     {
640       int cur_pr = priority( item.myValue.toString(), tt == Binary );
641       if ( cur_pr > 0 )
642       {
643         if ( min < 0 || min >= cur_pr )
644         {
645           if ( min == cur_pr )
646           {
647             argmin.append( f + i );
648             min_types.append( tt );
649           }
650           else
651           {
652             min = cur_pr;
653             argmin.clear();
654             argmin.append( f + i );
655             min_types.clear(); min_types.append( tt );
656           }
657         }
658       }
659       else
660       {
661         setError( QtxEvalExpr::InvalidOperation );
662         break;
663       }
664     }
665     else if ( tt == Open )
666     {
667       QString opBr = item.myValue.toString();
668       int ind = anOpen.indexOf( opBr ), brValue = 0;
669       while ( j <= l )
670       {
671         const PostfixItem& anItem = post[j];
672         if ( anItem.myType == Open )
673           brValue++;
674
675         if ( anItem.myType == Close )
676         {
677           brValue--;
678           QString clBr = anItem.myValue.toString();
679           if ( aClose.indexOf( clBr ) == ind && brValue == 0 )
680             break;
681         }
682         i++; j++;
683       }
684
685       if ( brValue > 0 )
686       {
687         setError( QtxEvalExpr::CloseExpected );
688           break;
689       }
690     }
691   }
692
693   if ( error() == QtxEvalExpr::OK )
694   {
695     if ( min >= 0 )
696     {
697       Postfix one;
698       QList<Postfix> parts;
699       QIntList::const_iterator anIt = argmin.begin(), aLast = argmin.end();
700       bool ok = sort( post, one, anOpen, aClose, f, *anIt - 1 );
701       parts.append( one );
702       one.clear();
703       for ( ; anIt != aLast && ok; anIt++ )
704       {
705         QIntList::const_iterator aNext = anIt; aNext++;
706         ok = sort( post, one, anOpen, aClose, *anIt + 1, aNext == aLast ? l : *aNext - 1 );
707         parts.append( one );
708         one.clear();
709       }
710
711       if ( !ok )
712         return false;
713
714       QStack<PostfixItem> aStack;
715       QList<Postfix>::const_iterator aPIt = parts.begin();
716       QList<PostfixItemType>::const_iterator aTIt = min_types.begin();
717       res += (*aPIt);
718       aPIt++;
719       anIt = argmin.begin();
720       for ( ; anIt != aLast; anIt++, aPIt++, aTIt++ )
721       {
722         if ( *aTIt == Pre )
723         {
724           if ( anOpen.contains( post[*anIt].myValue.toString() ) == 0 )
725           {
726             res += (*aPIt);
727             aStack.push( post[ *anIt ] );
728           }
729           else
730           {
731             res.append( post[*anIt] );
732             res += *aPIt;
733           }
734         }
735         else
736         {
737           res += *aPIt;
738           while ( !aStack.isEmpty() )
739           {
740             res.append( aStack.top() );
741             aStack.pop();
742           }
743           res.append( post[*anIt] );
744         }
745       }
746       while ( !aStack.isEmpty() )
747       {
748         res.append( aStack.top() );
749         aStack.pop();
750       }
751     }
752     else
753     { //there are no operations
754       for ( int k = f; k <= l; k++ )
755       {
756         if ( post.at( k ).myType==Value || post.at( k ).myType == Param )
757           res.append( post.at( k ) );
758       }
759     }
760   }
761
762   return error() == QtxEvalExpr::OK;
763 }
764
765 /*!
766   \brief Parse the expression and build the posfix.
767
768   If by parsing error is found, the function returns \c false. In this case the code of the error
769   can be retrieved with error() method.
770
771   \param expr string expression
772   \return \c true on success and \c false if error is found
773 */
774 bool QtxEvalParser::parse( const QString& expr )
775 {
776   myPostfix.clear();
777
778   if ( !checkOperations() )
779     return false;
780
781   Postfix p;
782   QStringList opens, closes;
783
784   setError( QtxEvalExpr::OK );
785   bracketsList( opens, true );
786   bracketsList( closes, false );
787
788   return prepare( expr, p ) && setOperationTypes( p ) && sort( p, myPostfix, opens, closes );
789 }
790
791 /*!
792   \brief Calculate the operation.
793
794   The result of the operation is returned in the parameter \a v1.
795
796   \param op operation name
797   \param v1 first argument (not valid for unary prefix operations)
798   \param v2 second argument (not valid for unary postfix operations)
799   \return \c true on success and \c false if error is found
800 */
801 bool QtxEvalParser::calculate( const QString& op, QVariant& v1, QVariant& v2 )
802 {
803   QtxEvalExpr::Error err = isValid( op, v1.type(), v2.type() );
804   if ( err == QtxEvalExpr::OK )
805     setError( calculation( op, v1, v2 ) );
806   else
807     setError( err );
808
809   return error() == QtxEvalExpr::OK;
810 }
811
812 /*!
813   \brief Calculate the expression without postfix rebuilding.
814   \return QVariant as result (it is invalid if there were errors during calculation)
815 */
816 QVariant QtxEvalParser::calculate()
817 {
818   if ( !checkOperations() )
819     return QVariant();
820
821   setError( QtxEvalExpr::OK );
822
823   QStringList anOpen, aClose;
824   bracketsList( anOpen, true );
825   bracketsList( aClose, false );
826
827   QStack<QVariant> aStack;
828   Postfix::iterator anIt = myPostfix.begin(), aLast = myPostfix.end();
829   for ( ; anIt != aLast && error() == QtxEvalExpr::OK; anIt++ )
830   {
831     QString nn = (*anIt).myValue.toString();
832     if ( (*anIt).myType == Param )
833     {
834       if ( hasParameter( nn ) )
835       {
836         QVariant& v = myParams[nn];
837         if ( v.isValid() )
838           aStack.push( v );
839         else
840           setError( QtxEvalExpr::InvalidToken );
841       }
842       else
843         setError( QtxEvalExpr::InvalidToken );
844     }
845     else if ( (*anIt).myType == Value )
846       aStack.push( (*anIt).myValue );
847     else if ( (*anIt).myType == Pre || (*anIt).myType == Post )
848     {
849       if ( anOpen.contains( nn ) )
850       {
851         QVariant inv;
852         if ( calculate( nn, inv, inv ) )
853           aStack.push( QVariant() );
854       }
855       else if ( aClose.contains( nn ) )
856       {
857         QList<QVariant> set;
858         while ( true )
859         {
860           if ( aStack.isEmpty() )
861           {
862             setError( QtxEvalExpr::StackUnderflow );
863             break;
864           }
865           if ( aStack.top().isValid() )
866           {
867             set.append( aStack.top() );
868             aStack.pop();
869           }
870           else
871           {
872             aStack.pop();
873             break;
874           }
875         }
876
877         QVariant qSet = set, inv;
878         if ( calculate( nn, qSet, inv ) )
879           aStack.push( set );
880       }
881       else if ( aStack.count() >= 1 )
882       {
883         QVariant inv;
884         QVariant* v1 = &aStack.top(), *v2 = &inv; //"post-" case
885         if ( (*anIt).myType == Pre )
886         {
887           v2 = &aStack.top();
888           v1 = &inv;
889         }
890         calculate( nn, *v1, *v2 );
891       }
892       else
893         setError( QtxEvalExpr::StackUnderflow );
894     }
895     else if ( (*anIt).myType == Binary )
896     {
897       if ( aStack.count() >= 2 )
898       {
899         QVariant v2 = aStack.top();
900         aStack.pop();
901         calculate( nn, aStack.top(), v2 );
902       }
903       else
904         setError( QtxEvalExpr::StackUnderflow );
905     }
906   }
907
908   QVariant res;
909   if ( error() == QtxEvalExpr::OK )
910   {
911     int count = aStack.count();
912     if ( count == 0 )
913       setError( QtxEvalExpr::StackUnderflow );
914     else if( count == 1 )
915       res = aStack.top();
916     else
917       setError( QtxEvalExpr::ExcessData );
918   }
919   return res;
920 }
921
922 /*!
923   \brief Change the expression, rebuild the postfix and calculate it.
924   \param expr new expression
925   \return QVariant as result (it is invalid if there were errors during calculation)
926 */
927 QVariant QtxEvalParser::calculate( const QString& expr )
928 {
929   setExpression( expr );
930   return calculate();
931 }
932
933 /*!
934   \brief Change the expression and rebuild the postfix.
935   \param expr new expression
936   \return \c true on success and \c false if error is found
937 */
938 bool QtxEvalParser::setExpression( const QString& expr )
939 {
940   return parse( expr );
941 }
942
943 /*!
944   \brief Check if the parser contains specified parameter.
945   \param name parameter name
946   \return \c true, if the parser contains parameter
947 */
948 bool QtxEvalParser::hasParameter( const QString& name ) const
949 {
950   return myParams.contains( name.trimmed() );
951 }
952
953 /*!
954   \brief Set parameters value.
955   \param name parameter name
956   \param value parameter value
957 */
958 void QtxEvalParser::setParameter( const QString& name, const QVariant& value )
959 {
960   myParams.insert( name.trimmed(), value );
961 }
962
963 /*!
964   \brief Remove parameter.
965   \param name parameter name
966   \return \c true on success
967 */
968 bool QtxEvalParser::removeParameter( const QString& name )
969 {
970   return myParams.remove( name.trimmed() );
971 }
972
973 /*!
974   \brief Get the parameter value.
975   \param name parameter name
976   \return parameter value or invalud QVariant if there is no such parameter
977 */
978 QVariant QtxEvalParser::parameter( const QString& name ) const
979 {
980   QVariant res;
981   if ( myParams.contains( name.trimmed() ) )
982     res = myParams[name.trimmed()].toString();
983   return res;
984 }
985
986 /*!
987   \brief Search first parameter with assigned invalid value.
988   \param name used to retrieve the name of the parameter if it is found
989   \return \c true if parameter is found
990 */
991 bool QtxEvalParser::firstInvalid( QString& name ) const
992 {
993   for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
994   {
995     if ( !anIt.value().isValid() )
996     {
997       name = anIt.key();
998       return true;
999     }
1000   }
1001   return false;
1002 }
1003
1004 /*!
1005   \brief Remove all parameters with assigned invalid values.
1006 */
1007 void QtxEvalParser::removeInvalids()
1008 {
1009   QStringList toDelete;
1010   for ( ParamMap::const_iterator anIt = myParams.begin(); anIt != myParams.end(); anIt++ )
1011   {
1012     if ( !anIt.value().isValid() )
1013       toDelete.append( anIt.key() );
1014   }
1015
1016   for ( QStringList::const_iterator aLIt = toDelete.begin(); aLIt != toDelete.end(); aLIt++ )
1017     myParams.remove( *aLIt );
1018 }
1019
1020 /*!
1021   \brief Get the code of the latest parsing error.
1022   \return last error code
1023 */
1024 QtxEvalExpr::Error QtxEvalParser::error() const
1025 {
1026   return myError;
1027 }
1028
1029 /*!
1030   \brief Set the error vode.
1031   \internal
1032   \param err error code
1033 */
1034 void QtxEvalParser::setError( QtxEvalExpr::Error err )
1035 {
1036   myError = err;
1037 }
1038
1039 /*!
1040   \brief Dump the current postfix contents to the string.
1041   \return string representation of the internal parser postfix
1042 */
1043 QString QtxEvalParser::dump() const
1044 {
1045   return dump( myPostfix );
1046 }
1047
1048 /*!
1049   \brief Dump the postfix contents to the string.
1050   \param post postfix to be dumped
1051   \return string representation of the postfix
1052 */
1053 QString QtxEvalParser::dump( const Postfix& post ) const
1054 {
1055   QString res;
1056
1057   if ( !checkOperations() )
1058     return res;
1059
1060   for ( Postfix::const_iterator anIt = post.begin(); anIt != post.end(); anIt++ )
1061   {
1062     if ( (*anIt).myType == Value && (*anIt).myValue.type() == QVariant::String )
1063       res += "'" + (*anIt).myValue.toString() + "'";
1064     else
1065       res += (*anIt).myValue.toString();
1066     
1067     if ( (*anIt).myType == Pre )
1068       res += "(pre)";
1069     else if ( (*anIt).myType == Post )
1070       res += "(post)";
1071     else if ( (*anIt).myType == Binary )
1072       res += "(bin)";
1073
1074     res += "_";
1075   }
1076
1077   return res;
1078 }
1079
1080 /*!
1081   \brief Get the list of the parameters names.
1082   \return parameters names
1083 */
1084 QStringList QtxEvalParser::parameters() const
1085 {
1086   QStringList lst;
1087   for ( Postfix::const_iterator anIt = myPostfix.begin(); anIt != myPostfix.end(); anIt++ )
1088   {
1089     if ( (*anIt).myType == Param )
1090     {
1091       QString name = (*anIt).myValue.toString();
1092       if ( !lst.contains( name ) )
1093         lst.append( name );
1094     }
1095   }
1096   return lst;
1097 }
1098
1099 /*!
1100   \brief Remove all parameters.
1101 */
1102 void QtxEvalParser::clearParameters()
1103 {
1104   myParams.clear();
1105 }
1106
1107 /*!
1108   \brief Get the string representation for the list of QVariant values.
1109   \param list list to be converted
1110   \return string representation for the list
1111 */
1112 QString QtxEvalParser::toString( const QList<QVariant>& list )
1113 {
1114   QString res = "set : [ ";
1115   for ( QList<QVariant>::const_iterator anIt = list.begin(); anIt != list.end(); anIt++ )
1116     res += (*anIt).toString() + " ";
1117   res += "]";
1118   return res;
1119 }
1120
1121 /*!
1122   \brief Get names of all operations used in the expression.
1123   \param list returning list of the operations names
1124 */
1125 void QtxEvalParser::operationList( QStringList& list ) const
1126 {
1127   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1128   {
1129     QStringList custom;
1130     QtxEvalSet* set = *it;
1131     set->operationList( custom );
1132     for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
1133     {
1134       if ( !list.contains( *sIt ) )
1135         list.append( *sIt );
1136     }
1137   }
1138 }
1139
1140 /*!
1141   \brief Get list of brackets.
1142   \param list returning list of brackets
1143   \param open if \c true, collect opening brackets, or closing brackets otherwise
1144 */
1145 void QtxEvalParser::bracketsList( QStringList& list, bool open ) const
1146 {
1147   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1148   {
1149     QStringList custom;
1150     QtxEvalSet* set = *it;
1151     set->bracketsList( custom, open );
1152     for ( QStringList::const_iterator sIt = custom.begin(); sIt != custom.end(); ++sIt )
1153     {
1154       if ( !list.contains( *sIt ) )
1155         list.append( *sIt );
1156     }
1157   }
1158 }
1159
1160 /*!
1161   \brief Create value.
1162   \param str parsed string
1163   \param val returning value
1164   \return \c true on success
1165 */
1166 bool QtxEvalParser::createValue( const QString& str, QVariant& val ) const
1167 {
1168   bool ok = false;
1169   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && !ok; ++it )
1170     ok = (*it)->createValue( str, val );
1171   return ok;
1172 }
1173
1174 /*!
1175   \brief Get the operation priority level.
1176   \param op operation
1177   \param isBin \c true if the operation is binary and \c false if it is unary
1178   \return operation priority
1179 */
1180 int QtxEvalParser::priority( const QString& op, bool isBin ) const
1181 {
1182   int i = 0;
1183   int priority = 0;
1184   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end() && priority <= 0; ++it, i++ )
1185     priority = (*it)->priority( op, isBin );
1186
1187   return priority > 0 ? priority + i * 50 : 0;
1188 }
1189
1190 /*!
1191   \brief Check operation validity.
1192
1193   If the operation is valid, QtxEvalExpr::OK is returned.
1194
1195   \param op operation
1196   \param t1 first operand type
1197   \param t2 second operand type
1198   \return error code (QtxEvalExpr::Error)
1199 */
1200 QtxEvalExpr::Error QtxEvalParser::isValid( const QString& op,
1201                                            const QVariant::Type t1, const QVariant::Type t2 ) const
1202 {
1203   QtxEvalExpr::Error err = QtxEvalExpr::OK;
1204   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1205   {
1206     err = (*it)->isValid( op, t1, t2 );
1207     if ( err == QtxEvalExpr::OK )
1208       break;
1209   }
1210   return err;
1211 }
1212
1213 /*!
1214   \brief Perform calculation
1215   
1216   The result of the operation is returned in the parameter \a v1.
1217   If the operation is calculated correctly, the function returns QtxEvalExpr::OK.
1218
1219   \param op operation name
1220   \param v1 first argument (not valid for unary prefix operations)
1221   \param v2 second argument (not valid for unary postfix operations)
1222   \return error code (QtxEvalExpr::Error)
1223 */
1224 QtxEvalExpr::Error QtxEvalParser::calculation( const QString& op, QVariant& v1, QVariant& v2 ) const
1225 {
1226   QVariant nv1, nv2;
1227   for ( SetList::const_iterator it = mySets.begin(); it != mySets.end(); ++it )
1228   {
1229     nv1 = v1;
1230     nv2 = v2;
1231     if ( (*it)->isValid( op, v1.type(), v2.type() ) == QtxEvalExpr::OK )
1232     {
1233       QtxEvalExpr::Error err = (*it)->calculate( op, nv1, nv2 );
1234       if ( err == QtxEvalExpr::OK || err == QtxEvalExpr::InvalidResult )
1235       {
1236         v1 = nv1;
1237         v2 = nv2;
1238         return err;
1239       }
1240     }
1241   }
1242   return QtxEvalExpr::InvalidOperation;
1243 }
1244
1245 /*!
1246   \brief Check current operations set.
1247   \return \c false if current set of operations is empty
1248 */
1249 bool QtxEvalParser::checkOperations() const
1250 {
1251   if ( !mySets.isEmpty() )
1252     return true;
1253
1254   QtxEvalParser* that = (QtxEvalParser*)this;
1255   that->setError( QtxEvalExpr::OperationsNull );
1256   return false;
1257 }
1258
1259 /*!
1260   \class QtxEvalSet
1261   \brief Generic class for all the operations sets used in expressions.
1262 */
1263
1264 /*!
1265   \brief Constructor.
1266 */
1267 QtxEvalSet::QtxEvalSet()
1268 {
1269 }
1270
1271 /*!
1272   \brief Destructor.
1273 */
1274 QtxEvalSet::~QtxEvalSet()
1275 {
1276 }
1277
1278 /*!
1279   \fn void QtxEvalSet::operationList( QStringList& list ) const;
1280   \brief Get the list of possible operations.
1281   \param list returning list of operations supported by the class
1282 */
1283
1284 /*!
1285   \fn void QtxEvalSet::bracketsList( QStringList& list, bool open ) const;
1286   \brief Get list of brackets.
1287   \param list returning list of brackets
1288   \param open if \c true, collect opening brackets, or closing brackets otherwise
1289 */
1290
1291 /*!
1292   \brief Create value from its string representation.
1293
1294   By default, the string value is set, that corresponds to the parameter.
1295   Base implementation always returns \c false (it means that string 
1296   is evaluated to the parameter).
1297   Successor class can re-implement this method to return \c true 
1298   if the argument being parsed can be evaluated as custom value.
1299
1300   \param str string representration of the value
1301   \param val returning value
1302   \return \c true if \a str can be evaluated as custom value and \c false
1303           otherwise (parameter)
1304 */
1305 bool QtxEvalSet::createValue( const QString& str, QVariant& val ) const
1306 {
1307   val = str;
1308   return false;
1309 }
1310
1311 /*!
1312   \fn int QtxEvalSet::priority( const QString& op, bool isBin ) const;
1313   \brief Get the operation priority.
1314
1315   Operation priority counts from 1.
1316   If the operation is impossible, this function should return value <= 0.
1317   
1318   \param op operation
1319   \param isBin \c true if the operation is binary and \c false if it is unary
1320   \return operation priority
1321 */
1322
1323 /*!
1324   \fn QtxEvalExpr::Error QtxEvalSet::isValid( const QString& op, const QVariant::Type t1, 
1325                                               const QVariant::Type t2 ) const;
1326   \brief Check operation validity.
1327
1328   If the operation is valid, QtxEvalExpr::OK is returned.
1329   If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
1330   or QtxEvalExpr::InvalidOperation.
1331
1332   \param op operation
1333   \param t1 first operand type
1334   \param t2 second operand type
1335   \return error code (QtxEvalExpr::Error)
1336 */
1337
1338 /*!
1339   \fn QtxEvalExpr::Error QtxEvalSet::calculate( const QString& op, QVariant& v1,
1340                                                 QVariant& v2 ) const;
1341   \brief Calculate the operation.
1342
1343   Process binary operation with values \a v1 and \a v2.
1344   For unary operation the \v2 is invalid.
1345   The result of the operation is returned in the parameter \a v1.
1346
1347   \param op operation name
1348   \param v1 first argument (not valid for unary prefix operations)
1349   \param v2 second argument (not valid for unary postfix operations)
1350   \return error code (QtxEvalExpr::Error)
1351 */
1352
1353 /*!
1354   \fn QString QtxEvalSet::name() const;
1355   \brief Get unique operations set name.
1356
1357   Should be redefined in the successor classes.
1358
1359   \return operations set name
1360 */
1361
1362 /*!
1363   \class QtxEvalSetBase
1364   \brief Generic class. Provides functionality for standard operations sets.
1365 */
1366
1367 /*!
1368   \brief Constructor.
1369 */
1370 QtxEvalSetBase::QtxEvalSetBase()
1371 {
1372 }
1373
1374 /*!
1375   \brief Destructor.
1376 */
1377 QtxEvalSetBase::~QtxEvalSetBase()
1378 {
1379 }
1380
1381 /*!
1382   \brief Get list of brackets.
1383   \param list returning list of brackets
1384   \param open if \c true, collect opening brackets, or closing brackets otherwise
1385 */
1386 void QtxEvalSetBase::bracketsList( QStringList& list, bool open ) const
1387 {
1388   list.append( open ? "(" : ")" );
1389 }
1390
1391 /*!
1392   \brief Get the list of possible operations.
1393   \param list returning list of operations supported by the class
1394 */
1395 void QtxEvalSetBase::operationList( QStringList& list ) const
1396 {
1397   list += myOpers;
1398 }
1399
1400 /*!
1401   \brief Add operation names to the internal list of operations.
1402   \param list operations to be added
1403 */
1404 void QtxEvalSetBase::addOperations( const QStringList& list )
1405 {
1406   for ( QStringList::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
1407   {
1408     if ( !myOpers.contains( *anIt ) )
1409       myOpers.append( *anIt );
1410   }
1411 }
1412
1413 /*!
1414   \brief Add operand types.
1415   \param list operand types to be added
1416 */
1417 void QtxEvalSetBase::addTypes( const ListOfTypes& list )
1418 {
1419   for ( ListOfTypes::const_iterator anIt = list.begin(); anIt != list.end(); ++anIt )
1420   {
1421     if ( !myTypes.contains( *anIt ) )
1422       myTypes.append( *anIt );
1423   }
1424 }
1425
1426 /*!
1427   \brief Check operation validity.
1428
1429   If the operation is valid, QtxEvalExpr::OK is returned.
1430   If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
1431   or QtxEvalExpr::InvalidOperation.
1432
1433   \param op operation
1434   \param t1 first operand type
1435   \param t2 second operand type
1436   \return error code (QtxEvalExpr::Error)
1437 */
1438 QtxEvalExpr::Error QtxEvalSetBase::isValid( const QString& op,
1439                                             const QVariant::Type t1, const QVariant::Type t2 ) const
1440 {
1441   if ( ( t1 == QVariant::Invalid || myTypes.contains( t1 ) ) &&
1442        ( t2 == QVariant::Invalid || myTypes.contains( t2 ) ) &&
1443        ( t1 != QVariant::Invalid || t2 != QVariant::Invalid ) )
1444   {
1445     if ( priority( op, t1 != QVariant::Invalid && t2 != QVariant::Invalid ) > 0 )
1446       return QtxEvalExpr::OK;
1447     else
1448       return QtxEvalExpr::InvalidOperation;
1449   }
1450   else
1451     return QtxEvalExpr::OperandsNotMatch;
1452 }
1453
1454 /*!
1455   \class QtxEvalSetArithmetic
1456   \brief Provides set of arithmetical operations for the parser.
1457 */
1458
1459 /*!
1460   \brief Constructor.
1461 */
1462 QtxEvalSetArithmetic::QtxEvalSetArithmetic()
1463 : QtxEvalSetBase()
1464 {
1465   addOperations( QString( "+;-;*;/;=;<;>;<=;>=;<>;!=" ).split( ";" ) );
1466
1467   ListOfTypes aTypes;
1468   aTypes.append( QVariant::Int );
1469   aTypes.append( QVariant::UInt );
1470   aTypes.append( QVariant::Double );
1471   addTypes( aTypes );
1472 }
1473
1474 /*!
1475   \brief Destructor.
1476 */
1477 QtxEvalSetArithmetic::~QtxEvalSetArithmetic()
1478 {
1479 }
1480
1481 /*!
1482   \brief Get operations set name.
1483   \return operations set name
1484 */
1485 QString QtxEvalSetArithmetic::Name()
1486 {
1487   return "Arithmetic";
1488 }
1489
1490 /*!
1491   \brief Get operations set name.
1492   \return operations set name
1493 */
1494 QString QtxEvalSetArithmetic::name() const
1495 {
1496   return Name();
1497 }
1498
1499 /*!
1500   \brief Create value from its string representation.
1501
1502   Creates numbers from string representation.
1503
1504   \param str string representration of the value
1505   \param val returning value
1506   \return \c true if \a str can be evaluated as custom value and \c false
1507           otherwise (parameter)
1508 */
1509 bool QtxEvalSetArithmetic::createValue( const QString& str, QVariant& val ) const
1510 {
1511   bool ok = false;
1512   val = str.toInt( &ok );
1513
1514   if ( !ok )
1515   {
1516     val = str.toDouble( &ok );
1517     if ( !ok )
1518       ok = QtxEvalSetBase::createValue( str, val );
1519   }
1520   return ok;
1521 }
1522
1523 /*!
1524   \brief Get the operation priority.
1525
1526   Operation priority counts from 1.
1527   If the operation is impossible, this function returns value <= 0.
1528   
1529   \param op operation
1530   \param isBin \c true if the operation is binary and \c false if it is unary
1531   \return operation priority
1532 */
1533 int QtxEvalSetArithmetic::priority( const QString& op, bool isBin ) const
1534 {
1535   if ( isBin )
1536   {
1537     if ( op == "<" || op == ">" || op == "=" ||
1538          op == "<=" || op == ">=" || op == "<>" || op == "!=" )
1539       return 1;
1540     else if ( op == "+" || op == "-" )
1541       return 2;
1542     else if( op == "*" || op == "/" )
1543       return 3;
1544     else
1545       return 0;
1546   }
1547   else if ( op == "+" || op == "-" )
1548     return 5;
1549   else
1550     return 0;
1551 }
1552
1553 /*!
1554   \brief Calculate the operation.
1555
1556   Process binary operation with values \a v1 and \a v2.
1557   For unary operation the \v2 is invalid.
1558   The result of the operation is returned in the parameter \a v1.
1559
1560   \param op operation name
1561   \param v1 first argument (not valid for unary prefix operations)
1562   \param v2 second argument (not valid for unary postfix operations)
1563   \return error code (QtxEvalExpr::Error)
1564 */
1565 QtxEvalExpr::Error QtxEvalSetArithmetic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1566 {
1567   QtxEvalExpr::Error err = QtxEvalExpr::OK;
1568
1569   if ( v1.isValid() && v2.isValid() )
1570   {
1571     // binary operations
1572     if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::UInt ) &&
1573          ( v2.type() == QVariant::Int || v2.type() == QVariant::UInt ) )
1574     {
1575       int _v1 = v1.toInt();
1576       int _v2 = v2.toInt();
1577
1578       if ( op == "+" )
1579         v1 = _v1 + _v2;
1580       else if ( op == "-" )
1581         v1 = _v1 - _v2;
1582       else if ( op == "*" )
1583         v1 = _v1 * _v2;
1584       else if ( op == "/" )
1585       {
1586         if ( _v2 != 0 )
1587         {
1588           if ( _v1 % _v2 == 0 )
1589             v1 = _v1 / _v2;
1590           else
1591             v1 = double( _v1 ) / double( _v2 );
1592         }
1593         else
1594           err = QtxEvalExpr::InvalidResult;
1595       }
1596       else if ( op == "<" )
1597         v1 = _v1 < _v2;
1598       else if ( op == ">" )
1599         v1 = _v1 > _v2;
1600       else if ( op == "=" )
1601         v1 = _v1 == _v2;
1602       else if ( op == "<=" )
1603         v1 = _v1 <= _v2;
1604       else if ( op == ">=" )
1605         v1 = _v1 >= _v2;
1606       else if ( op == "<>" || op == "!=" )
1607         v1 = _v1 != _v2;
1608     }
1609     else if ( ( v1.type() == QVariant::Int || v1.type() == QVariant::Double ) &&
1610               ( v2.type() == QVariant::Int || v2.type() == QVariant::Double ) )
1611     {
1612       double _v1 = v1.toDouble();
1613       double _v2 = v2.toDouble();
1614
1615       if ( op == "+" )
1616         v1 = _v1 + _v2;
1617       else if ( op == "-" )
1618         v1 = _v1 - _v2;
1619       else if ( op == "*" )
1620           v1 = _v1 * _v2;
1621       else if ( op == "/" )
1622       {
1623         if ( _v2 != 0 )
1624           v1 = _v1 / _v2;
1625         else
1626           err = QtxEvalExpr::InvalidResult;
1627       }
1628       else if ( op == "<" )
1629         v1 = _v1 < _v2;
1630       else if ( op == ">" )
1631         v1 = _v1 > _v2;
1632       else if ( op == "=" )
1633         v1 = _v1 == _v2;
1634       else if ( op == "<=" )
1635         v1 = _v1 <= _v2;
1636       else if ( op == ">=" )
1637         v1 = _v1 >= _v2;
1638       else if ( op == "<>" || op == "!=" )
1639         v1 = _v1 != _v2;
1640     }
1641     else // prefix operations
1642     {
1643       if ( op == "-" )
1644       {
1645         if ( v2.type() == QVariant::Int )
1646           v2 = -v2.toInt();
1647         else if ( v2.type() == QVariant::Double )
1648           v2 = -v2.toDouble();
1649       }
1650     }
1651   }
1652
1653   return err;
1654 }
1655
1656 /*!
1657   \class QtxEvalSetLogic
1658   \brief Provides set of logical operations for the parser.
1659 */
1660
1661 /*!
1662   \brief Constructor.
1663 */
1664 QtxEvalSetLogic::QtxEvalSetLogic()
1665 : QtxEvalSetBase()
1666 {
1667   addOperations( QString( "and;&&;or;||;xor;not;!;imp;=" ).split( ";" ) );
1668
1669   ListOfTypes aTypes;
1670   aTypes.append( QVariant::Bool );
1671   aTypes.append( QVariant::Int );
1672   aTypes.append( QVariant::UInt );
1673   addTypes( aTypes );
1674 }
1675
1676 /*!
1677   \brief Destructor.
1678 */
1679 QtxEvalSetLogic::~QtxEvalSetLogic()
1680 {
1681 }
1682
1683 /*!
1684   \brief Get operations set name.
1685   \return operations set name
1686 */
1687 QString QtxEvalSetLogic::Name()
1688 {
1689   return "Logic";
1690 }
1691
1692 /*!
1693   \brief Get operations set name.
1694   \return operations set name
1695 */
1696 QString QtxEvalSetLogic::name() const
1697 {
1698   return Name();
1699 }
1700
1701 /*!
1702   \brief Create value from its string representation.
1703
1704   Create \c true or \c false value from string representation.
1705
1706   \param str string representration of the value
1707   \param val returning value
1708   \return \c true if \a str can be evaluated as custom value and \c false
1709           otherwise (parameter)
1710 */
1711 bool QtxEvalSetLogic::createValue( const QString& str, QVariant& val ) const
1712 {
1713   bool ok = true;
1714   QString valStr = str.toLower();
1715   if ( valStr == "true" || valStr == "yes" )
1716     val = QVariant( true );
1717   else if ( valStr == "false" || valStr == "no" )
1718     val = QVariant( false );
1719   else
1720     ok = QtxEvalSetBase::createValue( str, val );
1721
1722   return ok;
1723 }
1724
1725 /*!
1726   \brief Get the operation priority.
1727
1728   Operation priority counts from 1.
1729   If the operation is impossible, this function returns value <= 0.
1730   
1731   \param op operation
1732   \param isBin \c true if the operation is binary and \c false if it is unary
1733   \return operation priority
1734 */
1735 int QtxEvalSetLogic::priority( const QString& op, bool isBin ) const
1736 {
1737   if ( isBin )
1738   {
1739     if ( op == "and" || op == "or" || op == "xor" || op == "&&" || op == "||" || op == "imp" )
1740       return 1;
1741     else if ( op == "=" )
1742       return 2;
1743     else 
1744       return 0;
1745   }
1746   else if ( op == "not" || op == "!" )
1747     return 5;
1748   else
1749     return 0;
1750 }
1751
1752 /*!
1753   \brief Calculate the operation.
1754
1755   Process binary operation with values \a v1 and \a v2.
1756   For unary operation the \v2 is invalid.
1757   The result of the operation is returned in the parameter \a v1.
1758
1759   \param op operation name
1760   \param v1 first argument (not valid for unary prefix operations)
1761   \param v2 second argument (not valid for unary postfix operations)
1762   \return error code (QtxEvalExpr::Error)
1763 */
1764 QtxEvalExpr::Error QtxEvalSetLogic::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1765 {
1766   QtxEvalExpr::Error err = QtxEvalExpr::OK;
1767   int val1 = intValue( v1 );
1768   int val2 = intValue( v2 );
1769   if ( v1.isValid() && v2.isValid() )
1770   {
1771     if ( op == "and" || op == "&&" )
1772       v1 = val1 && val2;
1773     else if ( op == "or" || op == "||" )
1774       v1 = val1 || val2;
1775     else if ( op == "xor" )
1776       v1 = ( !val1 && val2 ) || ( val1 && !val2 );
1777     else if ( op == "imp" )
1778       v1 = !val1 || val2;
1779     else if ( op == "=" )
1780       v1 = val1 == val2;
1781   }
1782   else if ( op == "not" || op == "!" )
1783     v2 = !val2;
1784
1785   return err;
1786 }
1787
1788 /*!
1789   \brief Convert value to the integer.
1790
1791   Note: the value is converted to the integer (not boolean) in order
1792   to compare integer numbers correctly.
1793
1794   \param v value being converted
1795   \return converted value
1796 */
1797 int QtxEvalSetLogic::intValue( const QVariant& v ) const
1798 {
1799   int res = 0;
1800   switch ( v.type() )
1801   {
1802   case QVariant::Bool:
1803     res = v.toBool() ? 1 : 0;
1804     break;
1805   case QVariant::Int:
1806   case QVariant::UInt:
1807     res = v.toInt();
1808     break;
1809   default:
1810     break;
1811   }
1812   return res;
1813 }
1814
1815 /*!
1816   \class QtxEvalSetMath
1817   \brief Provides a set of more complex operations (mathematical functions)
1818          for the parser (sqrt, sin, cos, etc).
1819 */
1820
1821 /*!
1822   \brief Constructor.
1823 */
1824 QtxEvalSetMath::QtxEvalSetMath()
1825 : QtxEvalSetBase()
1826 {
1827   addOperations( QString( "sqrt;abs;sin;cos;rad2grad;grad2rad" ).split( ";" ) );
1828
1829   ListOfTypes aTypes;
1830   aTypes.append( QVariant::Int );
1831   aTypes.append( QVariant::Double );
1832   addTypes( aTypes );
1833 }
1834
1835 /*!
1836   \brief Destructor.
1837 */
1838 QtxEvalSetMath::~QtxEvalSetMath()
1839 {
1840 }
1841
1842 /*!
1843   \brief Get operations set name.
1844   \return operations set name
1845 */
1846 QString QtxEvalSetMath::Name()
1847 {
1848   return "Math";
1849 }
1850
1851 /*!
1852   \brief Get operations set name.
1853   \return operations set name
1854 */
1855 QString QtxEvalSetMath::name() const
1856 {
1857   return Name();
1858 }
1859
1860 /*!
1861   \brief Create value from its string representation.
1862
1863   Creates numbers from string representation.
1864
1865   \param str string representration of the value
1866   \param val returning value
1867   \return \c true if \a str can be evaluated as custom value and \c false
1868           otherwise (parameter)
1869 */
1870 bool QtxEvalSetMath::createValue( const QString& str, QVariant& val ) const
1871 {
1872   bool ok = false;
1873   val = str.toInt( &ok );
1874
1875   if ( !ok )
1876   {
1877     val = str.toDouble( &ok );
1878     if ( !ok )
1879       ok = QtxEvalSetBase::createValue( str, val );
1880   }
1881   return ok;
1882 }
1883
1884 /*!
1885   \brief Get the operation priority.
1886
1887   Operation priority counts from 1.
1888   If the operation is impossible, this function returns value <= 0.
1889   
1890   \param op operation
1891   \param isBin \c true if the operation is binary and \c false if it is unary
1892   \return operation priority
1893 */
1894 int QtxEvalSetMath::priority( const QString& op, bool isBin ) const
1895 {
1896   if ( isBin )
1897     return 0;
1898   else if ( op == "sqrt" || op == "abs" || op == "sin" ||
1899             op == "cos" || op == "rad2grad" || op == "grad2rad" )
1900     return 1;
1901   else
1902     return 0;
1903 }
1904
1905 /*!
1906   \brief Calculate the operation.
1907
1908   Process binary operation with values \a v1 and \a v2.
1909   For unary operation the \v2 is invalid.
1910   The result of the operation is returned in the parameter \a v1.
1911
1912   \param op operation name
1913   \param v1 first argument (not valid for unary prefix operations)
1914   \param v2 second argument (not valid for unary postfix operations)
1915   \return error code (QtxEvalExpr::Error)
1916 */
1917 QtxEvalExpr::Error QtxEvalSetMath::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
1918 {
1919   QtxEvalExpr::Error err = QtxEvalExpr::OK;
1920   double val = v2.toDouble();
1921   if ( op == "sqrt" )
1922   {
1923     if ( val >= 0 )
1924       v2 = sqrt( val );
1925     else
1926       err = QtxEvalExpr::InvalidResult;
1927   }
1928   else if ( op == "abs" )
1929   {
1930     if ( v2.type() == QVariant::Int )
1931       v2 = abs( v2.toInt() );
1932     else 
1933       v2 = fabs( v2.toDouble() );
1934   }
1935   else if ( op == "sin" )
1936     v2 = sin( val );
1937   else if ( op == "cos" )
1938     v2 = cos( val );
1939   else if ( op == "grad2rad" )
1940     v2 = val * 3.14159256 / 180.0;
1941   else if ( op == "rad2grad" )
1942     v2 = val * 180.0 / 3.14159256;
1943
1944   return err;
1945 }
1946
1947 /*!
1948   \class QtxEvalSetString
1949   \brief Provides set of string operations for the parser.
1950 */
1951
1952 /*!
1953   \brief Constructor.
1954 */
1955 QtxEvalSetString::QtxEvalSetString()
1956 : QtxEvalSetBase()
1957 {
1958   addOperations( QString( "+;=;<;>;<=;>=;<>;!=;length;lower;upper" ).split( ";" ) );
1959
1960   ListOfTypes aTypes;
1961   aTypes.append( QVariant::Int );
1962   aTypes.append( QVariant::Double );
1963   aTypes.append( QVariant::String );
1964   addTypes( aTypes );
1965 }
1966
1967 /*!
1968   \brief Destructor.
1969 */
1970 QtxEvalSetString::~QtxEvalSetString()
1971 {
1972 }
1973
1974 /*!
1975   \brief Get operations set name.
1976   \return operations set name
1977 */
1978 QString QtxEvalSetString::Name()
1979 {
1980   return "String";
1981 }
1982
1983 /*!
1984   \brief Get operations set name.
1985   \return operations set name
1986 */
1987 QString QtxEvalSetString::name() const
1988 {
1989   return Name();
1990 }
1991
1992 /*!
1993   \brief Create value from its string representation.
1994
1995   Creates string value from Qt string representation.
1996
1997   \param str string representration of the value
1998   \param val returning value
1999   \return \c true if \a str can be evaluated as custom value and \c false
2000           otherwise (parameter)
2001 */
2002 bool QtxEvalSetString::createValue( const QString& str, QVariant& val ) const
2003 {
2004   bool ok = false;
2005   if ( str.length() > 1 && str[0] == '\'' && str[str.length() - 1] == '\'' )
2006   {
2007     val = str.mid( 1, str.length() - 2 );
2008     ok = true;
2009   }
2010   else
2011     ok = QtxEvalSetBase::createValue( str, val );
2012   return ok;
2013 }
2014
2015 /*!
2016   \brief Get the operation priority.
2017
2018   Operation priority counts from 1.
2019   If the operation is impossible, this function returns value <= 0.
2020   
2021   \param op operation
2022   \param isBin \c true if the operation is binary and \c false if it is unary
2023   \return operation priority
2024 */
2025 int QtxEvalSetString::priority( const QString& op, bool isBin ) const
2026 {
2027   if ( isBin )
2028   {
2029     if ( op == "+" ) 
2030       return 2;
2031     else if ( op == "=" || op == "<" || op == ">" ||
2032               op == "<=" || op == ">=" || op == "<>" || op == "!=" )
2033       return 1;
2034     else
2035       return 0;
2036   }
2037   else if ( op == "length" || op == "lower" || op=="upper" )
2038     return 5;
2039   else
2040     return 0;
2041 }
2042
2043 /*!
2044   \brief Calculate the operation.
2045
2046   Process binary operation with values \a v1 and \a v2.
2047   For unary operation the \v2 is invalid.
2048   The result of the operation is returned in the parameter \a v1.
2049
2050   \param op operation name
2051   \param v1 first argument (not valid for unary prefix operations)
2052   \param v2 second argument (not valid for unary postfix operations)
2053   \return error code (QtxEvalExpr::Error)
2054 */
2055 QtxEvalExpr::Error QtxEvalSetString::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
2056 {
2057   QtxEvalExpr::Error err = QtxEvalExpr::OK;
2058   if ( v1.isValid() && v2.isValid() )
2059   {
2060     QString _v1 = v1.toString();
2061     QString _v2 = v2.toString();
2062     if ( op == "+" )
2063       v1 = _v1 + _v2;
2064     else if ( op == "=" )
2065       v1 = _v1 ==_v2;
2066     else if ( op == "<" )
2067       v1 = _v1 < _v2;
2068     else if ( op == ">" )
2069       v1 = _v1 > _v2;
2070     else if ( op == "<>" || op == "!=" )
2071       v1 = _v1 != _v2;
2072     else if ( op == "<=" )
2073       v1 = _v1 < _v2 || _v1 == _v2;
2074     else if ( op == ">=" )
2075       v1 = _v1 > _v2 || _v1 == _v2;
2076   }
2077   else if ( !v1.isValid() && v2.isValid() )
2078   {
2079     QString val = v2.toString();
2080     if ( op == "length" )
2081       v2 = (int)val.length();
2082     else if ( op == "lower" )
2083       v2 = val.toLower();
2084     else if ( op == "upper" )
2085       v2 = val.toUpper();
2086   }
2087   return err;
2088 }
2089
2090 /*!
2091   \class QtxEvalSetSets
2092   \brief Provides set of operations with sequences for the parser.
2093 */
2094
2095 /*!
2096   \brief Constructor.
2097 */
2098 QtxEvalSetSets::QtxEvalSetSets()
2099 : QtxEvalSetBase()
2100 {
2101   addOperations( QString( "{;};=;<>;!=;+;-;*;in;count" ).split( ";" ) );
2102
2103   ListOfTypes aTypes;
2104   aTypes.append( QVariant::List );
2105   addTypes( aTypes );
2106 }
2107
2108 /*!
2109   \brief Destructor.
2110 */
2111 QtxEvalSetSets::~QtxEvalSetSets()
2112 {
2113 }
2114
2115 /*!
2116   \brief Get operations set name.
2117   \return operations set name
2118 */
2119 QString QtxEvalSetSets::Name()
2120 {
2121   return "Sets";
2122 }
2123
2124 /*!
2125   \brief Get operations set name.
2126   \return operations set name
2127 */
2128 QString QtxEvalSetSets::name() const
2129 {
2130   return Name();
2131 }
2132
2133 /*!
2134   \brief Get list of brackets.
2135   \param list returning list of brackets
2136   \param open if \c true, collect opening brackets, or closing brackets otherwise
2137 */
2138 void QtxEvalSetSets::bracketsList( QStringList& list, bool open ) const
2139 {
2140   list.append( open ? "{" : "}" );
2141   QtxEvalSetBase::bracketsList( list, open );
2142 }
2143
2144 /*!
2145   \brief Get the operation priority.
2146
2147   Operation priority counts from 1.
2148   If the operation is impossible, this function returns value <= 0.
2149   
2150   \param op operation
2151   \param isBin \c true if the operation is binary and \c false if it is unary
2152   \return operation priority
2153 */
2154 int QtxEvalSetSets::priority( const QString& op, bool isBin ) const
2155 {
2156   if ( isBin )
2157   {
2158     if ( op == "=" || op == "<>" || op == "!=" )
2159       return 1;
2160     else if ( op == "+" || op == "-" || op == "*" )
2161       return 2;
2162     else if ( op == "in" )
2163       return 3;
2164     else
2165       return 0;
2166   }
2167   else if ( op == "{" || op == "}" )
2168     return 5;
2169   else if ( op == "count" )
2170     return 4;
2171   else
2172     return 0;
2173 }
2174
2175 /*!
2176   \brief Check operation validity.
2177
2178   If the operation is valid, QtxEvalExpr::OK is returned.
2179   If types of operands are invalid, the function returns QtxEvalExpr::OperandsNotMatch
2180   or QtxEvalExpr::InvalidOperation.
2181
2182   \param op operation
2183   \param t1 first operand type
2184   \param t2 second operand type
2185   \return error code (QtxEvalExpr::Error)
2186 */
2187 QtxEvalExpr::Error QtxEvalSetSets::isValid( const QString& op,
2188                                             const QVariant::Type t1, const QVariant::Type t2 ) const
2189 {
2190   if ( op == "{" )
2191     return QtxEvalExpr::OK;
2192
2193   if ( op != "in" )
2194     return QtxEvalSetBase::isValid( op, t1, t2 );
2195
2196   if ( t1 != QVariant::Invalid && t2 == QVariant::List )
2197     return QtxEvalExpr::OK;
2198   else
2199     return QtxEvalExpr::OperandsNotMatch;
2200 }
2201
2202 /*!
2203   \brief Add new value \a v to the sequence \a set.
2204   \param set sequence
2205   \param v value to be added
2206 */
2207 void QtxEvalSetSets::add( ValueSet& set, const QVariant& v )
2208 {
2209   if ( v.isValid() && !set.contains( v ) )
2210     set.append( v );
2211 }
2212
2213 /*!
2214   \brief Add all values from sequence \a s2 to the sequence \a s1.
2215   \param s1 destination sequence
2216   \param s2 source sequence
2217 */
2218 void QtxEvalSetSets::add( ValueSet& s1, const ValueSet& s2 )
2219 {
2220   for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
2221     add( s1, *anIt );
2222 }
2223
2224 /*!
2225   \brief Remove value \a v from sequence \a set.
2226   \param set sequence
2227   \param v value to be removed
2228 */
2229 void QtxEvalSetSets::remove( ValueSet& set, const QVariant& v )
2230 {
2231   set.removeAll( v );
2232 }
2233
2234 /*!
2235   \brief Remove all values listed in the sequence \a s2 from the sequence \a s1.
2236   \param s1 sequence from which items are removed
2237   \param s2 sequence which items are removed
2238 */
2239 void QtxEvalSetSets::remove( ValueSet& s1, const ValueSet& s2 )
2240 {
2241   for ( ValueSet::const_iterator anIt = s2.begin(); anIt != s2.end(); ++anIt )
2242     s1.removeAll( *anIt );
2243 }
2244
2245 /*!
2246   \brief Calculate the operation.
2247
2248   Process binary operation with values \a v1 and \a v2.
2249   For unary operation the \v2 is invalid.
2250   The result of the operation is returned in the parameter \a v1.
2251
2252   \param op operation name
2253   \param v1 first argument (not valid for unary prefix operations)
2254   \param v2 second argument (not valid for unary postfix operations)
2255   \return error code (QtxEvalExpr::Error)
2256 */
2257 QtxEvalExpr::Error QtxEvalSetSets::calculate( const QString& op, QVariant& v1, QVariant& v2 ) const
2258 {
2259   QtxEvalExpr::Error err = QtxEvalExpr::OK;
2260
2261   if ( op != "{" )
2262   {
2263     if ( op == "}" )
2264     {
2265       ValueSet aNewList;
2266       add( aNewList, v1.toList() );
2267       v1 = aNewList;
2268     }
2269     else if ( op == "=" || op == "<>" || op == "!=" || op == "+" || op == "-" || op == "*" )
2270     {
2271       ValueSet aNewList;
2272       add( aNewList, v1.toList() );
2273       if ( op == "=" || op == "<>" || op == "!=" || op == "-" )
2274       {
2275         remove( aNewList, v2.toList() );
2276         if ( op == "=" )
2277           v1 = aNewList.isEmpty() && v1.toList().count() == v2.toList().count();
2278         else if ( op == "<>" || op == "!=" )
2279           v1 = !aNewList.isEmpty() || v1.toList().count() != v2.toList().count();
2280         else
2281           v1 = aNewList;
2282       }
2283       else if ( op == "+" )
2284       {
2285         add( aNewList, v2.toList() );
2286         v1 = aNewList;
2287       }
2288       else if ( op == "*" )
2289       {
2290         ValueSet toDelete;
2291         add( toDelete, aNewList );
2292         remove( toDelete, v2.toList() );
2293         remove( aNewList, toDelete );
2294         v1 = aNewList;
2295       }
2296     }
2297     else if ( op== "count" )
2298       v2 = (int)v2.toList().count();
2299     else if ( op == "in" )
2300     {
2301       if ( v1.type() == QVariant::List )
2302       {
2303         bool res = true;
2304         ValueSet lst1 = v1.toList();
2305         ValueSet lst2 = v2.toList();
2306         for ( ValueSet::const_iterator anIt = lst1.begin(); anIt != lst1.end() && res; ++anIt )
2307           res = lst2.contains( *anIt );
2308
2309         v1 = res;
2310       }
2311       else
2312               v1 = QVariant( v2.toList().contains( v1 ) );
2313     }
2314   }
2315   return err;
2316 }
2317
2318 /*!
2319   \class QtxEvalSetConst
2320   \brief Provides different standard constants.
2321 */
2322 QtxEvalSetConst::QtxEvalSetConst()
2323 : QtxEvalSet()
2324 {
2325 }
2326
2327 /*!
2328   \brief Destructor.
2329 */
2330 QtxEvalSetConst::~QtxEvalSetConst()
2331 {
2332 }
2333
2334 /*!
2335   \brief Get operations set name.
2336   \return operations set name
2337 */
2338 QString QtxEvalSetConst::Name()
2339 {
2340   return "Const";
2341 }
2342
2343 /*!
2344   \brief Get operations set name.
2345   \return operations set name
2346 */
2347 QString QtxEvalSetConst::name() const
2348 {
2349   return Name();
2350 }
2351
2352 /*!
2353   \brief Create value from its string representation.
2354
2355   Convert constant name to its value.
2356
2357   \param str string representration of the constant
2358   \param val returning value
2359   \return \c true if \a str can be evaluated as custom value and \c false
2360           otherwise (parameter)
2361 */
2362 bool QtxEvalSetConst::createValue( const QString& str, QVariant& val ) const
2363 {
2364   bool ok = true;
2365   if ( str == "pi" )            // PI number
2366     val = QVariant( 3.141593 );
2367   else if ( str == "exp" )      // Exponent value (e)
2368     val = QVariant( 2.718282 );
2369   else if ( str == "g" )        // Free fall acceleration (g)
2370     val = QVariant( 9.80665 );
2371   else
2372     ok = false;
2373
2374   return ok;
2375 }
2376
2377 /*!
2378   \brief Get the list of possible operations.
2379   \param list returning list of operations supported by the class (not used)
2380 */
2381 void QtxEvalSetConst::operationList( QStringList& /*list*/ ) const
2382 {
2383 }
2384
2385 /*!
2386   \brief Get list of brackets.
2387   \param list returning list of brackets (not used)
2388   \param open if \c true, collect opening brackets, or closing brackets otherwise (not used)
2389 */
2390 void QtxEvalSetConst::bracketsList( QStringList& /*list*/, bool /*open*/ ) const
2391 {
2392 }
2393
2394 /*!
2395   \brief Get the operation priority.
2396
2397   Operation priority counts from 1.
2398   If the operation is impossible, this function returns value <= 0.
2399   
2400   \param op operation (not used)
2401   \param isBin \c true if the operation is binary and \c false if it is unary (not used)
2402   \return operation priority
2403 */
2404 int QtxEvalSetConst::priority( const QString& /*op*/, bool /*isBin*/ ) const
2405 {
2406   return 0;
2407 }
2408
2409 /*!
2410   \brief Check operation validity.
2411
2412   Always returns QtxEvalExpr::InvalidOperation.
2413
2414   \param op operation (not used)
2415   \param t1 first operand type (not used)
2416   \param t2 second operand type (not used)
2417   \return error code (QtxEvalExpr::Error)
2418 */
2419 QtxEvalExpr::Error QtxEvalSetConst::isValid( const QString&       /*op*/, 
2420                                              const QVariant::Type /*t1*/,
2421                                              const QVariant::Type /*t2*/ ) const
2422 {
2423   return QtxEvalExpr::InvalidOperation;
2424 }
2425
2426 /*!
2427   \brief Calculate the operation.
2428
2429   Always returns QtxEvalExpr::InvalidOperation.
2430
2431   \param op operation name (not used)
2432   \param v1 first argument (not valid for unary prefix operations) (not used)
2433   \param v2 second argument (not valid for unary postfix operations) (not used)
2434   \return error code (QtxEvalExpr::Error)
2435 */
2436 QtxEvalExpr::Error QtxEvalSetConst::calculate( const QString&, QVariant&, QVariant& ) const
2437 {
2438   return QtxEvalExpr::InvalidOperation;
2439 }