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