Salome HOME
Initial version
[modules/gui.git] / src / Qtx / QtxStdOperations.cxx
1 #include "QtxStdOperations.h"
2
3 #include <math.h>
4 #include <stdlib.h>
5
6 //================================================================
7 // Function : 
8 // Purpose  : 
9 //================================================================
10 QtxStdOperations::QtxStdOperations()
11 {
12 }
13
14 //================================================================
15 // Function : 
16 // Purpose  : 
17 //================================================================
18 QtxStdOperations::~QtxStdOperations()
19 {
20 }
21
22 //================================================================
23 // Function : 
24 // Purpose  : 
25 //================================================================
26 void QtxStdOperations::bracketsList( QStringList& list, bool open ) const
27 {
28     if( open )
29         list.append( "(" );
30     else
31         list.append( ")" );
32 }
33
34 //================================================================
35 // Function : 
36 // Purpose  : 
37 //================================================================
38 void QtxStdOperations::opersList( QStringList& list ) const
39 {
40     list += myOpers;
41 }
42
43 //================================================================
44 // Function : 
45 // Purpose  : 
46 //================================================================
47 void QtxStdOperations::addOperations( const QStringList& list )
48 {
49     QStringList::const_iterator anIt = list.begin(),
50                                 aLast = list.end();
51     for( ; anIt!=aLast; anIt++ )
52         if( myOpers.contains( *anIt )==0 )
53             myOpers.append( *anIt );
54 }
55
56 //================================================================
57 // Function : 
58 // Purpose  : 
59 //================================================================
60 void QtxStdOperations::addTypes( const ListOfTypes& list )
61 {
62     ListOfTypes::const_iterator anIt = list.begin(),
63                                 aLast = list.end();
64     for( ; anIt!=aLast; anIt++ )
65         if( myTypes.contains( *anIt )==0 )
66             myTypes.append( *anIt );
67 }
68
69 //================================================================
70 // Function : 
71 // Purpose  : 
72 //================================================================
73 QtxParser::Error QtxStdOperations::isValid( const QString& op,
74                                             const QVariant::Type t1,
75                                             const QVariant::Type t2 ) const
76 {
77     if( ( t1==QVariant::Invalid || myTypes.contains( t1 ) ) &&
78         ( t2==QVariant::Invalid || myTypes.contains( t2 ) ) &&
79         ( t1!=QVariant::Invalid || t2!=QVariant::Invalid ) )
80         if( prior( op, t1!=QVariant::Invalid && t2!=QVariant::Invalid ) > 0 )
81             return QtxParser::OK;
82         else
83             return QtxParser::InvalidOperation;
84     else
85         return QtxParser::OperandsNotMatch;
86 }
87
88
89
90
91
92
93
94
95 //================================================================
96 // Function : 
97 // Purpose  : 
98 //================================================================
99 QtxArithmetics::QtxArithmetics()
100 : QtxStdOperations()
101 {
102     QStringList aList;
103     aList.append( "+" );
104     aList.append( "-" );
105     aList.append( "*" );
106     aList.append( "/" );
107     aList.append( "=" );
108     aList.append( "<" );
109     aList.append( ">" );
110     aList.append( "<=" );
111     aList.append( ">=" );
112     aList.append( "<>" );
113     addOperations( aList );
114
115     ListOfTypes aTypes;
116     aTypes.append( QVariant::Int );
117     aTypes.append( QVariant::UInt );
118     aTypes.append( QVariant::Double );
119     addTypes( aTypes );
120 }
121
122 //================================================================
123 // Function : 
124 // Purpose  : 
125 //================================================================
126 QtxArithmetics::~QtxArithmetics()
127 {
128 }
129
130 //================================================================
131 // Function : 
132 // Purpose  : 
133 //================================================================
134 bool QtxArithmetics::createValue( const QString& str, QtxValue& v ) const
135 {
136     bool ok = false;
137     v = str.toInt( &ok );
138
139     if( !ok )
140     {
141         v = str.toDouble( &ok );
142         if( !ok )
143             ok = QtxStdOperations::createValue( str, v );
144     }
145     return ok;
146 }
147
148 //================================================================
149 // Function : 
150 // Purpose  : 
151 //================================================================
152 int QtxArithmetics::prior( const QString& op, bool isBin ) const
153 {
154     if( isBin )
155         if( op=="<" || op==">" || op=="=" || 
156             op=="<=" || op==">=" || op=="<>" )
157             return 1;
158         else if( op=="+" || op=="-" )
159             return 2;
160         else if( op=="*" || op=="/" )
161             return 3;
162         else
163             return 0;
164     else if( op=="+" || op=="-" )
165         return 5;
166     else
167         return 0;
168 }
169
170 void set( QVariant& v1, bool v2 )
171 {
172     v1 = QVariant( v2, 0 );
173 }
174
175 //================================================================
176 // Function : 
177 // Purpose  : 
178 //================================================================
179 QtxParser::Error QtxArithmetics::calculate( const QString& op, 
180                                                 QtxValue& v1, QtxValue& v2 ) const
181 {
182     QtxParser::Error err = QtxParser::OK;
183
184     if( v1.isValid() && v2.isValid() )
185         // binary operations
186         if( ( v1.type()==QVariant::Int || v1.type()==QVariant::UInt ) &&
187             ( v2.type()==QVariant::Int || v2.type()==QVariant::UInt ) )
188         {
189             int _v1 = v1.toInt(),
190                 _v2 = v2.toInt();
191
192             if( op=="+" )
193                 v1 = _v1 + _v2;
194             else if( op=="-" )
195                 v1 = _v1 - _v2;
196             else if( op=="*" )
197                 v1 = _v1 * _v2;
198             else if( op=="/" )
199                 if( _v2!=0 )
200                     if( _v1%_v2==0 )
201                         v1 = _v1 / _v2;
202                     else
203                         v1 = double( _v1 ) / double( _v2 );
204                 else
205                     err = QtxParser::InvalidResult;
206             else if( op=="<" )
207                 set( v1, _v1<_v2 );
208             else if( op==">" )
209                 set( v1, _v1>_v2 );
210             else if( op=="=" )
211                 set( v1, _v1==_v2 );
212             else if( op=="<=" )
213                 set( v1, _v1<=_v2 );
214             else if( op==">=" )
215                 set( v1, _v1>=_v2 );
216             else if( op=="<>" )
217                 set( v1, _v1!=_v2 );
218         }
219         else if( ( v1.type()==QVariant::Int || v1.type()==QVariant::Double ) &&
220                  ( v2.type()==QVariant::Int || v2.type()==QVariant::Double ) )
221         {
222             double _v1 = v1.toDouble(),
223                    _v2 = v2.toDouble();
224
225             if( op=="+" )
226                 v1 = _v1 + _v2;
227             else if( op=="-" )
228                 v1 = _v1 - _v2;
229             else if( op=="*" )
230                 v1 = _v1 * _v2;
231             else if( op=="/" )
232                 if( _v2!=0 )
233                     v1 = _v1 / _v2;
234                 else
235                     err = QtxParser::InvalidResult;
236             else if( op=="<" )
237                 set( v1, _v1<_v2 );
238             else if( op==">" )
239                 set( v1, _v1>_v2 );
240             else if( op=="=" )
241                 set( v1, _v1==_v2 );
242             else if( op=="<=" )
243                 set( v1, _v1<=_v2 );
244             else if( op==">=" )
245                 set( v1, _v1>=_v2 );
246             else if( op=="<>" )
247                 set( v1, _v1!=_v2 );
248         }
249     else
250         // prefix operations
251         if( op=="-" )
252             if( v2.type()==QVariant::Int )
253                 v2 = -v2.toInt();
254             else if( v2.type()==QVariant::Double )
255                 v2 = -v2.toDouble();
256
257     return err;
258 }
259
260
261
262
263
264
265
266
267
268
269
270 //================================================================
271 // Function : 
272 // Purpose  : 
273 //================================================================
274 QtxLogic::QtxLogic()
275 : QtxStdOperations()
276 {
277     QStringList aList;
278     aList.append( "and" );
279     aList.append( "&&" );
280     aList.append( "or" );
281     aList.append( "||" );
282     aList.append( "xor" );
283     aList.append( "not" );
284     aList.append( "!" );
285     aList.append( "imp" );
286     aList.append( "=" );
287     addOperations( aList );
288
289     ListOfTypes aTypes;
290     aTypes.append( QVariant::Bool );
291     addTypes( aTypes );
292 }
293
294 //================================================================
295 // Function : 
296 // Purpose  : 
297 //================================================================
298 QtxLogic::~QtxLogic()
299 {
300 }
301
302 //================================================================
303 // Function : 
304 // Purpose  : 
305 //================================================================
306 bool QtxLogic::createValue( const QString& str, QtxValue& v ) const
307 {
308     bool ok = true;
309     if( str.lower()=="true" )
310         v = true;
311     else if( str.lower()=="false" )
312         v = false;
313     else
314         ok = QtxStdOperations::createValue( str, v );
315
316     return ok;
317 }
318
319 //================================================================
320 // Function : 
321 // Purpose  : 
322 //================================================================
323 int QtxLogic::prior( const QString& op, bool isBin ) const
324 {
325     if( isBin )
326         if( op=="and" || op=="or" || op=="xor" ||
327             op=="&&"  || op=="||" ||
328             op=="imp" )
329             return 1;
330         else if( op=="=" )
331             return 2;
332         else 
333             return 0;
334     else if( op=="not" || op=="!" )
335             return 5;
336          else
337             return 0;
338 }
339
340 //================================================================
341 // Function : 
342 // Purpose  : 
343 //================================================================
344 QtxParser::Error QtxLogic::calculate( const QString& op,
345                                           QtxValue& v1, QtxValue& v2 ) const
346 {
347     QtxParser::Error err = QtxParser::OK;
348     if( v1.isValid() && v2.isValid() )
349         if( op=="and" || op=="&&" )
350             set( v1, v1.toBool() && v2.toBool() );
351         else if( op=="or" || op=="||" )
352             set( v1, v1.toBool() || v2.toBool() );
353         else if( op=="xor" )
354             set( v1, ( !v1.toBool() && v2.toBool() ) || ( v1.toBool() && !v2.toBool() ) );
355         else if( op=="imp" )
356             set( v1, !v1.toBool() || v2.toBool() );
357         else if( op=="=" )
358             set( v1, v1.toBool()==v2.toBool() );
359
360     else
361         if( op=="not" || op=="!" )
362             v2 = !v2.toBool();
363
364     return err;
365 }
366
367
368
369
370
371
372 //================================================================
373 // Function : 
374 // Purpose  : 
375 //================================================================
376 QtxFunctions::QtxFunctions()
377 : QtxStdOperations()
378 {
379     QStringList aList;
380     aList.append( "sqrt" );
381     aList.append( "abs" );
382     aList.append( "sin" );
383     aList.append( "cos" );
384     aList.append( "rad2grad" );
385     aList.append( "grad2rad" );
386     addOperations( aList );
387
388     ListOfTypes aTypes;
389     aTypes.append( QVariant::Int );
390     aTypes.append( QVariant::Double );
391     addTypes( aTypes );
392 }
393
394 //================================================================
395 // Function : 
396 // Purpose  : 
397 //================================================================
398 QtxFunctions::~QtxFunctions()
399 {
400 }
401
402 //================================================================
403 // Function : 
404 // Purpose  : 
405 //================================================================
406 bool QtxFunctions::createValue( const QString& str, QtxValue& v ) const
407 {
408     bool ok = false;
409     v = str.toInt( &ok );
410
411     if( !ok )
412     {
413         v = str.toDouble( &ok );
414         if( !ok )
415             ok = QtxStdOperations::createValue( str, v );
416     }
417     return ok;
418 }
419
420 //================================================================
421 // Function : 
422 // Purpose  : 
423 //================================================================
424 int QtxFunctions::prior( const QString& op, bool isBin ) const
425 {
426     if( isBin )
427         return 0;
428     else if( op=="sqrt" || op=="abs" || op=="sin" || op=="cos" ||
429              op=="rad2grad" || op=="grad2rad" )
430         return 1;
431     else
432         return 0;
433 }
434
435 //================================================================
436 // Function : 
437 // Purpose  : 
438 //================================================================
439 QtxParser::Error QtxFunctions::calculate( const QString& op,
440                                           QtxValue& v1, QtxValue& v2 ) const
441 {
442     QtxParser::Error err = QtxParser::OK;
443     double val = v2.toDouble();
444     if( op=="sqrt" )
445         if( val>=0 )
446             v2 = sqrt( val );
447         else
448             err = QtxParser::InvalidResult;
449     else if( op=="abs" )
450         if( v2.type()==QVariant::Int )
451             v2 = abs( v2.toInt() );
452         else 
453             v2 = fabs( v2.toDouble() );
454     else if( op=="sin" )
455         v2 = sin( val );
456     else if( op=="cos" )
457         v2 = cos( val );
458     else if( op=="grad2rad" )
459         v2 = val * 3.14159256 / 180.0;
460     else if( op=="rad2grad" )
461         v2 = val * 180.0 / 3.14159256;
462
463     return err;
464 }
465
466
467
468
469
470
471
472
473 //================================================================
474 // Function : 
475 // Purpose  : 
476 //================================================================
477 QtxStrings::QtxStrings()
478 : QtxStdOperations()
479 {
480     QStringList aList;
481     aList.append( "+" );
482     aList.append( "=" );
483     aList.append( "<" );
484     aList.append( ">" );
485     aList.append( "<=" );
486     aList.append( ">=" );
487     aList.append( "<>" );
488     aList.append( "length" );
489     aList.append( "lower" );
490     aList.append( "upper" );
491     addOperations( aList );
492
493     ListOfTypes aTypes;
494     aTypes.append( QVariant::Int );
495     aTypes.append( QVariant::Double );
496     aTypes.append( QVariant::String );
497     aTypes.append( QVariant::CString );
498     addTypes( aTypes );
499 }
500
501
502 //================================================================
503 // Function : 
504 // Purpose  : 
505 //================================================================
506 QtxStrings::~QtxStrings()
507 {
508 }
509
510 //================================================================
511 // Function : 
512 // Purpose  : 
513 //================================================================
514 bool QtxStrings::createValue( const QString& str, QtxValue& v ) const
515 {
516     QChar st = str[0],
517           fin = str[ ( int )( str.length()-1 ) ];
518     if( st=="'" && fin=="'" )
519     {
520         v = str.mid( 1, str.length()-2 );
521         return true;
522     }
523     else
524         return QtxStdOperations::createValue( str, v );
525 }
526
527 //================================================================
528 // Function : 
529 // Purpose  : 
530 //================================================================
531 int QtxStrings::prior( const QString& op, bool isBin ) const
532 {
533     if( isBin )
534         if( op=="+" ) 
535             return 2;
536         else if( op=="="  || op=="<"  || op==">"  ||
537                  op=="<=" || op==">=" || op=="<>" )
538             return 1;
539         else
540             return 0;
541     else
542         if( op=="length" || op=="lower" || op=="upper" )
543             return 5;
544         else
545             return 0;
546 }
547
548 //================================================================
549 // Function : 
550 // Purpose  : 
551 //================================================================
552 QtxParser::Error QtxStrings::calculate( const QString& op,
553                                             QtxValue& v1, QtxValue& v2 ) const
554 {
555     QtxParser::Error err = QtxParser::OK;
556     if( v1.isValid() && v2.isValid() )
557     {
558         QString _v1 = v1.toString(),
559                 _v2 = v2.toString();
560         if( op=="+" )
561             v1 = _v1 + _v2;
562         else if( op=="=" )
563             set( v1, _v1==_v2 );
564         else if( op=="<" )
565             set( v1, _v1<_v2 );
566         else if( op==">" )
567             set( v1, _v1>_v2 );
568         else if( op=="<>" )
569             set( v1, _v1!=_v2 );
570         else if( op=="<=" )
571             set( v1, _v1<_v2 || _v1==_v2 );
572         else if( op==">=" )
573             set( v1, _v1>_v2 || _v1==_v2 );
574     }
575     else if( !v1.isValid() && v2.isValid() )
576     {
577         QString val = v2.toString();
578         if( op=="length" )
579             v2 = ( int )val.length();
580         else if( op=="lower" )
581             v2 = val.lower();
582         else if( op=="upper" )
583             v2 = val.upper();
584     }
585
586     return err;
587 }
588
589
590
591
592
593
594 //================================================================
595 // Function : 
596 // Purpose  : 
597 //================================================================
598 QtxSets::QtxSets()
599 {
600     QStringList aList;
601     aList.append( "{" );
602     aList.append( "}" );
603     aList.append( "=" );
604     aList.append( "<>" );
605     aList.append( "+" );
606     aList.append( "-" );
607     aList.append( "*" );
608     aList.append( "in" );
609     aList.append( "count" );
610     addOperations( aList );
611
612     ListOfTypes aTypes;
613     aTypes.append( QVariant::List );
614     addTypes( aTypes );
615 }
616
617 //================================================================
618 // Function : 
619 // Purpose  : 
620 //================================================================
621 QtxSets::~QtxSets()
622 {
623 }
624
625 //================================================================
626 // Function : 
627 // Purpose  : 
628 //================================================================
629 void QtxSets::bracketsList( QStringList& list, bool open ) const
630 {
631     if( open )
632         list.append( "{" );
633     else 
634         list.append( "}" );
635     QtxStdOperations::bracketsList( list, open );
636 }
637
638 //================================================================
639 // Function : 
640 // Purpose  : 
641 //================================================================
642 bool QtxSets::createValue( const QString& str, QtxValue& val ) const
643 {
644     return QtxStdOperations::createValue( str, val );
645 }
646
647 //================================================================
648 // Function : 
649 // Purpose  : 
650 //================================================================
651 int QtxSets::prior( const QString& op, bool isBin ) const
652 {
653     if( isBin )
654         if( op=="=" || op=="<>" )
655             return 1;
656         else if( op=="+" || op=="-" || op=="*" )
657             return 2;
658         else if( op=="in" )
659             return 3;
660         else
661             return 0;
662
663     else 
664         if( op=="{" || op=="}" )
665             return 5;
666         else if( op=="count" )
667             return 4;
668         else
669             return 0;
670 }
671
672 //================================================================
673 // Function : 
674 // Purpose  : 
675 //================================================================
676 QtxParser::Error QtxSets::isValid( const QString& op,
677                                    const QVariant::Type t1,
678                                    const QVariant::Type t2 ) const
679 {
680     if( op=="{" )
681         return QtxParser::OK;
682     else if( op=="in" )
683         if( t1!=QVariant::Invalid && t2==QVariant::List )
684             return QtxParser::OK;
685         else
686             return QtxParser::OperandsNotMatch;
687     else
688         return QtxStdOperations::isValid( op, t1, t2 );
689 }
690
691 //================================================================
692 // Function : 
693 // Purpose  : 
694 //================================================================
695 void QtxSets::add( ValueSet& set, const QtxValue& v )
696 {
697     if( v.isValid() && set.contains( v )==0 )
698         set.append( v );
699 }
700
701 //================================================================
702 // Function : 
703 // Purpose  : 
704 //================================================================
705 void QtxSets::add( ValueSet& s1, const ValueSet& s2 )
706 {
707     ValueSet::const_iterator anIt = s2.begin(),
708                              aLast = s2.end();
709     for( ; anIt!=aLast; anIt++ )
710         add( s1, *anIt );
711 }
712
713 //================================================================
714 // Function : 
715 // Purpose  : 
716 //================================================================
717 void QtxSets::remove( ValueSet& set, const QtxValue& v )
718 {
719     set.remove( v );
720 }
721
722 //================================================================
723 // Function : 
724 // Purpose  : 
725 //================================================================
726 void QtxSets::remove( ValueSet& s1, const ValueSet& s2 )
727 {
728     ValueSet::const_iterator anIt = s2.begin(),
729                              aLast = s2.end();
730     for( ; anIt!=aLast; anIt++ )
731         s1.remove( *anIt );
732 }
733
734 //================================================================
735 // Function : 
736 // Purpose  : 
737 //================================================================
738 QtxParser::Error QtxSets::calculate( const QString& op, QtxValue& v1, QtxValue& v2 ) const
739 {
740     QtxParser::Error err = QtxParser::OK;
741
742     if( op!="{" )
743         if( op=="}" )
744         {
745             ValueSet aNewList;
746             add( aNewList, v1.toList() );
747             v1 = aNewList;
748         }
749
750         else if( op=="=" || op=="<>" || op=="+" || op=="-" || op=="*" )
751         {
752             ValueSet aNewList;
753             add( aNewList, v1.toList() );
754
755             if( op=="=" || op=="<>" || op=="-" )
756             {
757                 remove( aNewList, v2.toList() );
758
759                 if( op=="=" )
760                     set( v1, aNewList.isEmpty() );
761                 else if( op=="<>" )
762                     set( v1, !aNewList.isEmpty() );
763                 else
764                     v1 = aNewList;
765             }
766             else if( op=="+" )
767             {
768                 add( aNewList, v2.toList() );
769                 v1 = aNewList;
770             }
771             else if( op=="*" )
772             {
773                 ValueSet toDelete;
774                 add( toDelete, aNewList );
775                 remove( toDelete, v2.toList() );
776                 remove( aNewList, toDelete );
777                 v1 = aNewList;
778             }
779         }
780         else if( op=="count" )
781             v2 = ( int )v2.toList().count();
782         else if( op=="in" )
783         {
784             if( v1.type()==QVariant::List )
785             {
786                 bool res = true;
787                 ValueSet::const_iterator anIt = v1.toList().begin(),
788                                          aLast = v1.toList().end();
789                 for( ; anIt!=aLast && res; anIt++ )
790                     res = v2.toList().contains( *anIt )>0;
791
792                 set( v1, res );
793             }
794             else
795                 v1 = v2.toList().contains( v1 );
796         }
797
798     return err;
799 }