00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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
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
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
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
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
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
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
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
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
00273
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
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
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
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
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
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
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
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 }