kspread

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