KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
7.9KB

  1. /* This file is part of the KDE project
  2. Copyright (C) 1998-2002 The KSpread Team
  3. www.koffice.org/kspread
  4. Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com>
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public License
  14. along with this library; see the file COPYING.LIB. If not, write to
  15. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. * Boston, MA 02110-1301, USA.
  17. */
  18. // built-in conversion functions
  19. #include "functions.h"
  20. #include "valuecalc.h"
  21. #include "valueconverter.h"
  22. using namespace KSpread;
  23. // prototypes
  24. Value func_arabic (valVector args, ValueCalc *calc, FuncExtra *);
  25. Value func_carx (valVector args, ValueCalc *calc, FuncExtra *);
  26. Value func_cary (valVector args, ValueCalc *calc, FuncExtra *);
  27. Value func_decsex (valVector args, ValueCalc *calc, FuncExtra *);
  28. Value func_polr (valVector args, ValueCalc *calc, FuncExtra *);
  29. Value func_pola (valVector args, ValueCalc *calc, FuncExtra *);
  30. Value func_roman (valVector args, ValueCalc *calc, FuncExtra *);
  31. Value func_sexdec (valVector args, ValueCalc *calc, FuncExtra *);
  32. Value func_AsciiToChar (valVector args, ValueCalc *calc, FuncExtra *);
  33. Value func_CharToAscii (valVector args, ValueCalc *calc, FuncExtra *);
  34. Value func_inttobool (valVector args, ValueCalc *calc, FuncExtra *);
  35. Value func_booltoint (valVector args, ValueCalc *calc, FuncExtra *);
  36. Value func_ToString (valVector args, ValueCalc *calc, FuncExtra *);
  37. // registers all conversion functions
  38. void RegisterConversionFunctions()
  39. {
  40. FunctionRepository* repo = FunctionRepository::self();
  41. Function *f;
  42. f = new Function ("ARABIC", func_arabic);
  43. repo->add (f);
  44. f = new Function ("CARX", func_carx);
  45. f->setParamCount (2);
  46. repo->add (f);
  47. f = new Function ("CARY", func_cary);
  48. f->setParamCount (2);
  49. repo->add (f);
  50. f = new Function ("DECSEX", func_decsex);
  51. repo->add (f);
  52. f = new Function ("POLR", func_polr);
  53. f->setParamCount (2);
  54. repo->add (f);
  55. f = new Function ("POLA", func_pola);
  56. f->setParamCount (2);
  57. repo->add (f);
  58. f = new Function ("ROMAN", func_roman);
  59. repo->add (f);
  60. f = new Function ("SEXDEC", func_sexdec);
  61. f->setParamCount (1, 3);
  62. repo->add (f);
  63. f = new Function ("ASCIITOCHAR", func_AsciiToChar);
  64. f->setParamCount (1, -1);
  65. f->setAcceptArray ();
  66. repo->add (f);
  67. f = new Function ("CHARTOASCII", func_CharToAscii);
  68. repo->add (f);
  69. f = new Function ("BOOL2INT", func_booltoint);
  70. repo->add (f);
  71. f = new Function ("INT2BOOL", func_inttobool);
  72. repo->add (f);
  73. f = new Function ("BOOL2STRING", func_ToString);
  74. repo->add (f);
  75. f = new Function ("NUM2STRING", func_ToString);
  76. repo->add (f);
  77. f = new Function ("STRING", func_ToString);
  78. repo->add (f);
  79. }
  80. // Function: POLR
  81. Value func_polr (valVector args, ValueCalc *calc, FuncExtra *)
  82. {
  83. // sqrt (a^2 + b^2)
  84. Value a = args[0];
  85. Value b = args[1];
  86. Value res = calc->sqrt (calc->add (calc->sqr (a), calc->sqr (b)));
  87. return res;
  88. }
  89. // Function: POLA
  90. Value func_pola (valVector args, ValueCalc *calc, FuncExtra *)
  91. {
  92. // acos (a / polr(a,b))
  93. Value polr = func_polr (args, calc, 0);
  94. if (calc->isZero (polr))
  95. return Value::errorDIV0();
  96. Value res = calc->acos (calc->div (args[0], polr));
  97. return res;
  98. }
  99. // Function: CARX
  100. Value func_carx (valVector args, ValueCalc *calc, FuncExtra *)
  101. {
  102. // a * cos(b)
  103. Value res = calc->mul (args[0], calc->cos (args[1]));
  104. return res;
  105. }
  106. // Function: CARY
  107. Value func_cary (valVector args, ValueCalc *calc, FuncExtra *)
  108. {
  109. // a * sin(b)
  110. Value res = calc->mul (args[0], calc->sin (args[1]));
  111. return res;
  112. }
  113. // Function: DECSEX
  114. Value func_decsex (valVector args, ValueCalc *calc, FuncExtra *)
  115. {
  116. // original function was very compicated, but I see no reason for that,
  117. // when it can be done as simply as this ...
  118. // maybe it was due to all the infrastructure not being ready back then
  119. return calc->conv()->asTime (calc->div (args[0], 24));
  120. }
  121. // Function: SEXDEC
  122. Value func_sexdec (valVector args, ValueCalc *calc, FuncExtra *)
  123. {
  124. if (args.count() == 1)
  125. {
  126. // convert given value to number
  127. Value time = calc->conv()->asTime (args[0]);
  128. return calc->mul (calc->conv()->asFloat (time), 24);
  129. }
  130. // convert h/m/s to number of hours
  131. Value h = args[0];
  132. Value m = args[1];
  133. Value res = calc->add (h, calc->div (m, 60));
  134. if (args.count() == 3) {
  135. Value s = args[2];
  136. res = calc->add (res, calc->div (s, 3600));
  137. }
  138. return res;
  139. }
  140. // Function: ROMAN
  141. Value func_roman (valVector args, ValueCalc *calc, FuncExtra *)
  142. {
  143. const TQCString RNUnits[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
  144. const TQCString RNTens[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
  145. const TQCString RNHundreds[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
  146. const TQCString RNThousands[] = {"", "M", "MM", "MMM"};
  147. // precision loss is not a problem here, as we only use the 0-3999 range
  148. long value = calc->conv()->asInteger (args[0]).asInteger ();
  149. if ((value < 0) || (value > 3999))
  150. return Value::errorNA();
  151. TQString result;
  152. result = TQString::fromLatin1 (RNThousands[(value / 1000)] +
  153. RNHundreds[(value / 100) % 10] +
  154. RNTens[(value / 10 ) % 10] +
  155. RNUnits[(value) % 10]);
  156. return Value (result);
  157. }
  158. // convert single roman character to decimal
  159. // return < 0 if invalid
  160. int func_arabic_helper (TQChar c)
  161. {
  162. switch (c.upper().unicode())
  163. {
  164. case 'M': return 1000;
  165. case 'D': return 500;
  166. case 'C': return 100;
  167. case 'L': return 50;
  168. case 'X': return 10;
  169. case 'V': return 5;
  170. case 'I': return 1;
  171. }
  172. return -1;
  173. }
  174. // Function: ARABIC
  175. Value func_arabic (valVector args, ValueCalc *calc, FuncExtra *)
  176. {
  177. TQString roman = calc->conv()->asString (args[0]).asString();
  178. if( roman.isEmpty() ) return Value::errorVALUE();
  179. int val = 0, lastd = 0, d = 0;
  180. for (unsigned i = 0; i < roman.length(); i++) {
  181. d = func_arabic_helper( roman[i] );
  182. if( d < 0 ) return Value::errorVALUE();
  183. if( lastd < d ) val -= lastd;
  184. else val += lastd;
  185. lastd = d;
  186. }
  187. if( lastd < d ) val -= lastd;
  188. else val += lastd;
  189. return Value (val);
  190. }
  191. // helper for AsciiToChar
  192. void func_a2c_helper (ValueCalc *calc, TQString &s, Value val)
  193. {
  194. if (val.isArray()) {
  195. for (unsigned int row = 0; row < val.rows(); ++row)
  196. for (unsigned int col = 0; col < val.columns(); ++col)
  197. func_a2c_helper (calc, s, val.element (col, row));
  198. } else {
  199. int v = calc->conv()->asInteger (val).asInteger();
  200. if (v == 0) return;
  201. TQChar c (v);
  202. s = s + c;
  203. }
  204. }
  205. // Function: AsciiToChar
  206. Value func_AsciiToChar (valVector args, ValueCalc *calc, FuncExtra *)
  207. {
  208. TQString str;
  209. for (unsigned int i = 0; i < args.count(); i++)
  210. func_a2c_helper (calc, str, args[i]);
  211. return Value (str);
  212. }
  213. // Function: CharToAscii
  214. Value func_CharToAscii (valVector args, ValueCalc *calc, FuncExtra *)
  215. {
  216. TQString val = calc->conv()->asString (args[0]).asString ();
  217. if (val.length() == 1)
  218. return Value (TQString (val[0]));
  219. return Value::errorVALUE();
  220. }
  221. // Function: inttobool
  222. Value func_inttobool (valVector args, ValueCalc *calc, FuncExtra *)
  223. {
  224. return calc->conv()->asBoolean (args[0]);
  225. }
  226. // Function: booltoint
  227. Value func_booltoint (valVector args, ValueCalc *calc, FuncExtra *)
  228. {
  229. return calc->conv()->asInteger (args[0]);
  230. }
  231. // Function: BoolToString, NumberToString, String
  232. Value func_ToString (valVector args, ValueCalc *calc, FuncExtra *)
  233. {
  234. return calc->conv()->asString (args[0]);
  235. }