summaryrefslogtreecommitdiffstats
path: root/kspread/kspread_functions_conversion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kspread/kspread_functions_conversion.cpp')
-rw-r--r--kspread/kspread_functions_conversion.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/kspread/kspread_functions_conversion.cpp b/kspread/kspread_functions_conversion.cpp
new file mode 100644
index 000000000..23f2ca015
--- /dev/null
+++ b/kspread/kspread_functions_conversion.cpp
@@ -0,0 +1,266 @@
+/* This file is part of the KDE project
+ Copyright (C) 1998-2002 The KSpread Team
+ www.koffice.org/kspread
+ Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+// built-in conversion functions
+
+#include "functions.h"
+#include "valuecalc.h"
+#include "valueconverter.h"
+
+using namespace KSpread;
+
+// prototypes
+Value func_arabic (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_carx (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_cary (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_decsex (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_polr (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_pola (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_roman (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_sexdec (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_AsciiToChar (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_CharToAscii (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_inttobool (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_booltoint (valVector args, ValueCalc *calc, FuncExtra *);
+Value func_ToString (valVector args, ValueCalc *calc, FuncExtra *);
+
+// registers all conversion functions
+void RegisterConversionFunctions()
+{
+ FunctionRepository* repo = FunctionRepository::self();
+ Function *f;
+
+ f = new Function ("ARABIC", func_arabic);
+ repo->add (f);
+ f = new Function ("CARX", func_carx);
+ f->setParamCount (2);
+ repo->add (f);
+ f = new Function ("CARY", func_cary);
+ f->setParamCount (2);
+ repo->add (f);
+ f = new Function ("DECSEX", func_decsex);
+ repo->add (f);
+ f = new Function ("POLR", func_polr);
+ f->setParamCount (2);
+ repo->add (f);
+ f = new Function ("POLA", func_pola);
+ f->setParamCount (2);
+ repo->add (f);
+ f = new Function ("ROMAN", func_roman);
+ repo->add (f);
+ f = new Function ("SEXDEC", func_sexdec);
+ f->setParamCount (1, 3);
+ repo->add (f);
+ f = new Function ("ASCIITOCHAR", func_AsciiToChar);
+ f->setParamCount (1, -1);
+ f->setAcceptArray ();
+ repo->add (f);
+ f = new Function ("CHARTOASCII", func_CharToAscii);
+ repo->add (f);
+ f = new Function ("BOOL2INT", func_booltoint);
+ repo->add (f);
+ f = new Function ("INT2BOOL", func_inttobool);
+ repo->add (f);
+ f = new Function ("BOOL2STRING", func_ToString);
+ repo->add (f);
+ f = new Function ("NUM2STRING", func_ToString);
+ repo->add (f);
+ f = new Function ("STRING", func_ToString);
+ repo->add (f);
+}
+
+// Function: POLR
+Value func_polr (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ // sqrt (a^2 + b^2)
+ Value a = args[0];
+ Value b = args[1];
+ Value res = calc->sqrt (calc->add (calc->sqr (a), calc->sqr (b)));
+ return res;
+}
+
+// Function: POLA
+Value func_pola (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ // acos (a / polr(a,b))
+ Value polr = func_polr (args, calc, 0);
+ if (calc->isZero (polr))
+ return Value::errorDIV0();
+ Value res = calc->acos (calc->div (args[0], polr));
+ return res;
+}
+
+// Function: CARX
+Value func_carx (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ // a * cos(b)
+ Value res = calc->mul (args[0], calc->cos (args[1]));
+ return res;
+}
+
+// Function: CARY
+Value func_cary (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ // a * sin(b)
+ Value res = calc->mul (args[0], calc->sin (args[1]));
+ return res;
+}
+
+// Function: DECSEX
+Value func_decsex (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ // original function was very compicated, but I see no reason for that,
+ // when it can be done as simply as this ...
+ // maybe it was due to all the infrastructure not being ready back then
+ return calc->conv()->asTime (calc->div (args[0], 24));
+}
+
+// Function: SEXDEC
+Value func_sexdec (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ if (args.count() == 1)
+ {
+ // convert given value to number
+ Value time = calc->conv()->asTime (args[0]);
+ return calc->mul (calc->conv()->asFloat (time), 24);
+ }
+
+ // convert h/m/s to number of hours
+ Value h = args[0];
+ Value m = args[1];
+
+ Value res = calc->add (h, calc->div (m, 60));
+ if (args.count() == 3) {
+ Value s = args[2];
+ res = calc->add (res, calc->div (s, 3600));
+ }
+ return res;
+}
+
+// Function: ROMAN
+Value func_roman (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ const TQCString RNUnits[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
+ const TQCString RNTens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
+ const TQCString RNHundreds[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
+ const TQCString RNThousands[] = {"", "M", "MM", "MMM"};
+
+ // precision loss is not a problem here, as we only use the 0-3999 range
+ long value = calc->conv()->asInteger (args[0]).asInteger ();
+ if ((value < 0) || (value > 3999))
+ return Value::errorNA();
+ TQString result;
+ result = TQString::fromLatin1 (RNThousands[(value / 1000)] +
+ RNHundreds[(value / 100) % 10] +
+ RNTens[(value / 10 ) % 10] +
+ RNUnits[(value) % 10]);
+ return Value (result);
+}
+
+// convert single roman character to decimal
+// return < 0 if invalid
+int func_arabic_helper (TQChar c)
+{
+ switch (c.upper().unicode())
+ {
+ case 'M': return 1000;
+ case 'D': return 500;
+ case 'C': return 100;
+ case 'L': return 50;
+ case 'X': return 10;
+ case 'V': return 5;
+ case 'I': return 1;
+ }
+ return -1;
+}
+
+// Function: ARABIC
+Value func_arabic (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ TQString roman = calc->conv()->asString (args[0]).asString();
+ if( roman.isEmpty() ) return Value::errorVALUE();
+
+ int val = 0, lastd = 0, d = 0;
+
+ for (unsigned i = 0; i < roman.length(); i++) {
+ d = func_arabic_helper( roman[i] );
+ if( d < 0 ) return Value::errorVALUE();
+
+ if( lastd < d ) val -= lastd;
+ else val += lastd;
+ lastd = d;
+ }
+ if( lastd < d ) val -= lastd;
+ else val += lastd;
+
+ return Value (val);
+}
+
+// helper for AsciiToChar
+void func_a2c_helper (ValueCalc *calc, TQString &s, Value val)
+{
+ if (val.isArray()) {
+ for (unsigned int row = 0; row < val.rows(); ++row)
+ for (unsigned int col = 0; col < val.columns(); ++col)
+ func_a2c_helper (calc, s, val.element (col, row));
+ } else {
+ int v = calc->conv()->asInteger (val).asInteger();
+ if (v == 0) return;
+ TQChar c (v);
+ s = s + c;
+ }
+}
+
+// Function: AsciiToChar
+Value func_AsciiToChar (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ TQString str;
+ for (unsigned int i = 0; i < args.count(); i++)
+ func_a2c_helper (calc, str, args[i]);
+ return Value (str);
+}
+
+// Function: CharToAscii
+Value func_CharToAscii (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ TQString val = calc->conv()->asString (args[0]).asString ();
+ if (val.length() == 1)
+ return Value (TQString (val[0]));
+ return Value::errorVALUE();
+}
+
+// Function: inttobool
+Value func_inttobool (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ return calc->conv()->asBoolean (args[0]);
+}
+
+// Function: booltoint
+Value func_booltoint (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ return calc->conv()->asInteger (args[0]);
+}
+
+// Function: BoolToString, NumberToString, String
+Value func_ToString (valVector args, ValueCalc *calc, FuncExtra *)
+{
+ return calc->conv()->asString (args[0]);
+}