kspread Library API Documentation

kspread_functions_conversion.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998-2002 The KSpread Team
00003                            www.koffice.org/kspread
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 // built-in conversion functions
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <float.h>
00026 
00027 #include <kdebug.h>
00028 #include <klocale.h>
00029 
00030 #include <koscript_parser.h>
00031 #include <koscript_util.h>
00032 #include <koscript_func.h>
00033 #include <koscript_synext.h>
00034 
00035 #include "kspread_functions.h"
00036 #include "kspread_util.h"
00037 
00038 
00039 // prototypes
00040 bool kspreadfunc_arabic( KSContext& context );
00041 bool kspreadfunc_carx( KSContext& context );
00042 bool kspreadfunc_cary( KSContext& context );
00043 bool kspreadfunc_decsex( KSContext& context );
00044 bool kspreadfunc_polr( KSContext& context );
00045 bool kspreadfunc_pola( KSContext& context );
00046 bool kspreadfunc_roman( KSContext& context );
00047 bool kspreadfunc_sexdec( KSContext& context );
00048 bool kspreadfunc_AsciiToChar( KSContext& context );
00049 bool kspreadfunc_CharToAscii( KSContext& context );
00050 bool kspreadfunc_inttobool( KSContext & context );
00051 bool kspreadfunc_booltoint( KSContext & context );
00052 bool kspreadfunc_BoolToString( KSContext& context );
00053 bool kspreadfunc_NumberToString( KSContext& context );
00054 
00055 // registers all conversion functions
00056 void KSpreadRegisterConversionFunctions()
00057 {
00058    KSpreadFunctionRepository* repo = KSpreadFunctionRepository::self();
00059    repo->registerFunction( "ARABIC",  kspreadfunc_arabic );
00060    repo->registerFunction( "CARX",    kspreadfunc_carx );
00061    repo->registerFunction( "CARY",    kspreadfunc_cary );
00062    repo->registerFunction( "DECSEX",  kspreadfunc_decsex );
00063    repo->registerFunction( "POLR",    kspreadfunc_polr );
00064    repo->registerFunction( "POLA",    kspreadfunc_pola );
00065    repo->registerFunction( "ROMAN",   kspreadfunc_roman );
00066    repo->registerFunction( "SEXDEC",  kspreadfunc_sexdec );
00067 }
00068 
00069 // Function: POLR
00070 bool kspreadfunc_polr( KSContext& context )
00071 {
00072   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00073 
00074   if ( !KSUtil::checkArgumentsCount( context,2, "POLR",true ) )
00075     return false;
00076 
00077   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00078     return false;
00079 
00080   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00081     return false;
00082   double result=sqrt(pow(args[0]->doubleValue(),2)+pow(args[1]->doubleValue(),2));
00083   context.setValue( new KSValue(result));
00084 
00085   return true;
00086 }
00087 
00088 // Function: POLA
00089 bool kspreadfunc_pola( KSContext& context )
00090 {
00091   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00092 
00093   if ( !KSUtil::checkArgumentsCount( context,2, "POLA",true ) )
00094     return false;
00095 
00096   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00097     return false;
00098 
00099   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00100     return false;
00101   double result=acos(args[0]->doubleValue()/(sqrt(pow(args[0]->doubleValue(),2)+pow(args[1]->doubleValue(),2))));
00102   context.setValue( new KSValue(result));
00103 
00104   return true;
00105 }
00106 
00107 // Function: CARX
00108 bool kspreadfunc_carx( KSContext& context )
00109 {
00110   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00111 
00112   if ( !KSUtil::checkArgumentsCount( context,2, "CARX",true ) )
00113     return false;
00114 
00115   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00116     return false;
00117 
00118   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00119     return false;
00120   double result=args[0]->doubleValue()*cos(args[1]->doubleValue());
00121   context.setValue( new KSValue(result));
00122 
00123   return true;
00124 }
00125 
00126 // Function: CARY
00127 bool kspreadfunc_cary( KSContext& context )
00128 {
00129   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00130 
00131   if ( !KSUtil::checkArgumentsCount( context,2, "CARY",true ) )
00132     return false;
00133 
00134   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00135     return false;
00136 
00137   if ( !KSUtil::checkType( context, args[1], KSValue::DoubleType, true ) )
00138     return false;
00139   double result=args[0]->doubleValue()*sin(args[1]->doubleValue());
00140   context.setValue( new KSValue(result));
00141 
00142   return true;
00143 }
00144 
00145 // Function: DECSEX
00146 bool kspreadfunc_decsex( KSContext& context )
00147 {
00148   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00149   if ( !KSUtil::checkArgumentsCount( context,1, "DECSEX",true ) )
00150     return false;
00151 
00152   if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00153     return false;
00154   int inter;
00155   double val=args[0]->doubleValue();
00156   int hours,minutes,seconds;
00157   if(val>0)
00158     inter=1;
00159   else
00160     inter=-1;
00161   hours=inter*(int)(fabs(val));
00162 
00163   double workingVal = (val - (double)hours) * inter;
00164 
00165   /* try to do this without rounding errors */
00166   workingVal *= 60.0;
00167   minutes = (int)(floor(workingVal));
00168 
00169   workingVal -= minutes;
00170   workingVal *= 60;
00171 
00172   seconds = (int)(floor(workingVal));
00173   workingVal -= seconds;
00174 
00175   /* now we need to try to round up the seconds if that makes sense */
00176   if (workingVal >= 0.5)
00177   {
00178     seconds++;
00179     while (seconds >= 60)
00180     {
00181       minutes++;
00182       seconds -= 60;
00183     }
00184 
00185     while (minutes >= 60)
00186     {
00187       hours++;
00188       minutes -= 60;
00189     }
00190   }
00191 
00192   QTime _time(hours,minutes,seconds);
00193   context.setValue( new KSValue(_time));
00194 
00195   return true;
00196 }
00197 
00198 // Function: SEXDEC
00199 bool kspreadfunc_sexdec( KSContext& context )
00200 {
00201   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00202   double result;
00203   if ( !KSUtil::checkArgumentsCount( context,3, "SEXDEC",true ) )
00204     {
00205       if ( !KSUtil::checkArgumentsCount( context,1, "SEXDEC",true ) )
00206     return false;
00207       if ( !KSUtil::checkType( context, args[0], KSValue::TimeType, true ) )
00208     return false;
00209 
00210       result=args[0]->timeValue().hour()+(double)args[0]->timeValue().minute()/60.0+(double)args[0]->timeValue().second()/3600.0;
00211 
00212       context.setValue( new KSValue(result));
00213     }
00214   else
00215     {
00216       if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00217     return false;
00218       if ( !KSUtil::checkType( context, args[1], KSValue::IntType, true ) )
00219     return false;
00220       if ( !KSUtil::checkType( context, args[2], KSValue::IntType, true ) )
00221     return false;
00222       result=args[0]->intValue()+(double)args[1]->intValue()/60.0+(double)args[2]->intValue()/3600.0;
00223 
00224       context.setValue( new KSValue(result));
00225     }
00226 
00227   return true;
00228 }
00229 
00230 // Function: ROMAN
00231 bool kspreadfunc_roman( KSContext& context )
00232 {
00233     const QCString RNUnits[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
00234     const QCString RNTens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
00235     const QCString RNHundreds[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
00236     const QCString RNThousands[] = {"", "M", "MM", "MMM"};
00237 
00238 
00239     QValueList<KSValue::Ptr>& args = context.value()->listValue();
00240     if ( !KSUtil::checkArgumentsCount( context,1, "ROMAN",true ) )
00241         return false;
00242     int value;
00243     if ( !KSUtil::checkType( context, args[0], KSValue::IntType, true ) )
00244     {
00245         if ( !KSUtil::checkType( context, args[0], KSValue::DoubleType, true ) )
00246             return false;
00247         else
00248             value=(int)args[0]->doubleValue();
00249     }
00250     else
00251         value=(int)args[0]->intValue();
00252     if(value<0)
00253     {
00254         context.setValue( new KSValue(i18n("Err")));
00255         return true;
00256     }
00257     if(value>3999)
00258     {
00259         context.setValue( new KSValue(i18n("Value too big")));
00260         return true;
00261     }
00262     QString result;
00263 
00264     result= QString::fromLatin1( RNThousands[ ( value / 1000 ) ] +
00265                                  RNHundreds[ ( value / 100 ) % 10 ] +
00266                                  RNTens[ ( value / 10 ) % 10 ] +
00267                                  RNUnits[ ( value ) % 10 ] );
00268     context.setValue( new KSValue(result));
00269     return true;
00270 }
00271 
00272 // convert single roman character to deciman
00273 // return < 0 if invalid
00274 int kspreadfunc_arabic_helper( QChar c )
00275 {
00276   switch( c.upper().unicode() )
00277   {
00278     case 'M': return 1000;
00279     case 'D': return 500;
00280     case 'C': return 100;
00281     case 'L': return 50;
00282     case 'X': return 10;
00283     case 'V': return 5;
00284     case 'I': return 1;
00285   }
00286   return -1;
00287 }
00288 
00289 // Function: ARABIC
00290 bool kspreadfunc_arabic( KSContext& context )
00291 {
00292   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00293 
00294   if ( !KSUtil::checkArgumentsCount( context,1, "ARABIC", true ) )
00295     return false;
00296 
00297   if ( !KSUtil::checkType( context, args[0], KSValue::StringType, true ) )
00298     return false;
00299 
00300   QString roman = args[0]->stringValue();
00301   if( roman.isEmpty() ) return false;
00302 
00303   int val = 0;
00304   int lastd = 0;
00305   int d = 0;
00306 
00307   for( unsigned i=0; i < roman.length(); i++ )
00308   {
00309     d = kspreadfunc_arabic_helper( roman[i] );
00310 
00311     if( d < 0 )  return false;
00312 
00313     if( lastd < d ) val -= lastd;
00314       else val += lastd;
00315     lastd = d;
00316   }
00317   if( lastd < d ) val -= lastd;
00318     else val += lastd;
00319 
00320   context.setValue( new KSValue( val ) );
00321   return true;
00322 }
00323 
00324 
00325 // Function: AsciiToChar
00326 bool kspreadfunc_AsciiToChar( KSContext& context )
00327 {
00328   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00329   int val = -1;
00330   QString str;
00331 
00332   for (unsigned int i = 0; i < args.count(); i++)
00333   {
00334     if ( KSUtil::checkType( context, args[i], KSValue::IntType, false ) )
00335     {
00336       val = (int)args[i]->intValue();
00337       QChar c(val);
00338       str = str + c;
00339     }
00340     else return false;
00341   }
00342 
00343   context.setValue( new KSValue(str));
00344   return true;
00345 }
00346 
00347 // Function: CharToAscii
00348 bool kspreadfunc_CharToAscii( KSContext& context )
00349 {
00350   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00351 
00352   if (args.count() == 1)
00353   {
00354     if ( KSUtil::checkType( context, args.first(), KSValue::StringType, false ) )
00355     {
00356       QString val = args[0]->stringValue();
00357       if (val.length() == 1)
00358       {
00359     QChar c = val[0];
00360     context.setValue( new KSValue(c.unicode() ));
00361     return true;
00362       }
00363     }
00364   }
00365   return false;
00366 }
00367 
00368 // Function: inttobool
00369 bool kspreadfunc_inttobool( KSContext & context )
00370 {
00371   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00372 
00373   if (args.count() == 1)
00374   {
00375     if (KSUtil::checkType(context, args[0],
00376                           KSValue::IntType, true))
00377     {
00378       bool result = (args[0]->intValue() == 1 ? true : false);
00379 
00380       context.setValue( new KSValue(result) );
00381 
00382       return true;
00383     }
00384   }
00385 
00386   return false;
00387 }
00388 
00389 // Function: booltoint
00390 bool kspreadfunc_booltoint( KSContext & context )
00391 {
00392   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00393 
00394   if (args.count() == 1)
00395   {
00396     if (KSUtil::checkType(context, args[0],
00397                           KSValue::BoolType, true))
00398     {
00399       int val = (args[0]->boolValue() ? 1 : 0);
00400 
00401       context.setValue( new KSValue(val));
00402 
00403       return true;
00404     }
00405   }
00406 
00407   return false;
00408 }
00409 
00410 // Function: BoolToString
00411 bool kspreadfunc_BoolToString( KSContext& context )
00412 {
00413   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00414 
00415   if (args.count() == 1)
00416   {
00417     if ( KSUtil::checkType( context, args.first(), KSValue::BoolType, false ) )
00418     {
00419       QString val((args[0]->boolValue() ? "True" : "False"));
00420 
00421       context.setValue( new KSValue(val));
00422 
00423       return true;
00424     }
00425   }
00426 
00427   return false;
00428 }
00429 
00430 // Function: NumberToString
00431 bool kspreadfunc_NumberToString( KSContext& context )
00432 {
00433   QValueList<KSValue::Ptr>& args = context.value()->listValue();
00434 
00435   if (args.count() == 1)
00436   {
00437     if ( KSUtil::checkType( context, args.first(), KSValue::DoubleType, false ) )
00438     {
00439       QString val;
00440       val.setNum(args[0]->doubleValue(), 'g', 8);
00441 
00442       context.setValue( new KSValue(val));
00443 
00444       return true;
00445     }
00446   }
00447 
00448   return false;
00449 }
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:09 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003