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