File indexing completed on 2024-05-12 16:35:31
0001 /* This file is part of the KDE project 0002 Copyright (C) 1998-2002 The KSpread Team <calligra-devel@kde.org> 0003 Copyright (C) 2005 Tomas Mecir <mecirt@gmail.com> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; only 0008 version 2 of the License. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 // built-in logical functions 0022 #include "LogicModule.h" 0023 0024 #include "Function.h" 0025 #include "FunctionModuleRegistry.h" 0026 #include "ValueCalc.h" 0027 #include "ValueConverter.h" 0028 0029 using namespace Calligra::Sheets; 0030 0031 // prototypes (sorted alphabetically) 0032 Value func_and(valVector args, ValueCalc *calc, FuncExtra *); 0033 Value func_false(valVector args, ValueCalc *calc, FuncExtra *); 0034 Value func_if(valVector args, ValueCalc *calc, FuncExtra *); 0035 Value func_iferror(valVector args, ValueCalc *calc, FuncExtra *); 0036 Value func_ifna(valVector args, ValueCalc *calc, FuncExtra *); 0037 Value func_nand(valVector args, ValueCalc *calc, FuncExtra *); 0038 Value func_nor(valVector args, ValueCalc *calc, FuncExtra *); 0039 Value func_not(valVector args, ValueCalc *calc, FuncExtra *); 0040 Value func_or(valVector args, ValueCalc *calc, FuncExtra *); 0041 Value func_true(valVector args, ValueCalc *calc, FuncExtra *); 0042 Value func_xor(valVector args, ValueCalc *calc, FuncExtra *); 0043 0044 0045 CALLIGRA_SHEETS_EXPORT_FUNCTION_MODULE("kspreadlogicmodule.json", LogicModule) 0046 0047 0048 LogicModule::LogicModule(QObject* parent, const QVariantList&) 0049 : FunctionModule(parent) 0050 { 0051 Function *f; 0052 0053 f = new Function("FALSE", func_false); 0054 f->setParamCount(0); 0055 add(f); 0056 f = new Function("TRUE", func_true); 0057 f->setParamCount(0); 0058 add(f); 0059 f = new Function("NOT", func_not); 0060 f->setParamCount(1); 0061 add(f); 0062 f = new Function("AND", func_and); 0063 f->setParamCount(1, -1); 0064 f->setAcceptArray(); 0065 add(f); 0066 f = new Function("NAND", func_nand); 0067 f->setParamCount(1, -1); 0068 f->setAcceptArray(); 0069 add(f); 0070 f = new Function("NOR", func_nor); 0071 f->setParamCount(1, -1); 0072 f->setAcceptArray(); 0073 add(f); 0074 f = new Function("OR", func_or); 0075 f->setParamCount(1, -1); 0076 f->setAcceptArray(); 0077 add(f); 0078 f = new Function("XOR", func_xor); 0079 f->setParamCount(1, -1); 0080 f->setAcceptArray(); 0081 add(f); 0082 f = new Function("IF", func_if); 0083 f->setParamCount(2, 3); 0084 add(f); 0085 f = new Function("IFERROR", func_iferror); 0086 f->setParamCount(2); 0087 add(f); 0088 f = new Function("IFNA", func_ifna); 0089 f->setParamCount(2); 0090 add(f); 0091 } 0092 0093 QString LogicModule::descriptionFileName() const 0094 { 0095 return QString("logic.xml"); 0096 } 0097 0098 0099 // helper for most logical functions 0100 static bool asBool(Value val, ValueCalc *calc, bool* ok = 0) 0101 { 0102 return calc->conv()->asBoolean(val, ok).asBoolean(); 0103 } 0104 0105 /////////////////////////////////////////////////////////////////////////////// 0106 0107 0108 // 0109 // ArrayWalker: AND 0110 // 0111 void awAnd(ValueCalc *calc, Value &res, Value value, Value) 0112 { 0113 if (res.asBoolean()) 0114 res = Value(asBool(value, calc)); 0115 } 0116 0117 0118 // 0119 // ArrayWalker: OR 0120 // 0121 void awOr(ValueCalc *calc, Value &res, Value value, Value) 0122 { 0123 if (!res.asBoolean()) 0124 res = Value(asBool(value, calc)); 0125 } 0126 0127 0128 // 0129 // ArrayWalker: XOR 0130 // 0131 void awXor(ValueCalc *calc, Value &count, Value value, Value) 0132 { 0133 if (asBool(value, calc)) 0134 count = Value(count.asInteger() + 1); 0135 } 0136 0137 /////////////////////////////////////////////////////////////////////////////// 0138 0139 0140 // 0141 // Function: AND 0142 // 0143 Value func_and(valVector args, ValueCalc *calc, FuncExtra *) 0144 { 0145 Value result(true); 0146 int cnt = args.count(); 0147 for (int i = 0; i < cnt; ++i) { 0148 if (args[i].isError()) 0149 return args[i]; 0150 } 0151 for (int i = 0; i < cnt; ++i) { 0152 calc->arrayWalk(args[i], result, awAnd, Value(0)); 0153 if (! result.asBoolean()) 0154 // if any value is false, return false 0155 return result; 0156 } 0157 // nothing is false -> return true 0158 return result; 0159 } 0160 0161 0162 // 0163 // Function: FALSE 0164 // 0165 Value func_false(valVector, ValueCalc *, FuncExtra *) 0166 { 0167 return Value(false); 0168 } 0169 0170 0171 // 0172 // Function: IF 0173 // 0174 Value func_if(valVector args, ValueCalc *calc, FuncExtra *) 0175 { 0176 if ((args[0].isError())) 0177 return args[0]; 0178 bool ok = true; 0179 bool guard = asBool(args[0], calc, &ok); 0180 if (!ok) 0181 return Value::errorVALUE(); 0182 if (guard) 0183 return args[1]; 0184 // evaluated to false 0185 if (args.count() == 3) { 0186 if (args[2].isNull()) { 0187 return Value(0); 0188 } else { 0189 return args[2]; 0190 } 0191 } else { 0192 // only two arguments 0193 return Value(false); 0194 } 0195 } 0196 0197 0198 // 0199 // Function: IFERROR 0200 // 0201 Value func_iferror(valVector args, ValueCalc *, FuncExtra *) 0202 { 0203 if (args[0].isError()) 0204 return args[1]; 0205 return args[0]; 0206 } 0207 0208 0209 // 0210 // Function: IFNA 0211 // 0212 Value func_ifna(valVector args, ValueCalc *, FuncExtra *) 0213 { 0214 if (args[0] == Value::errorNA()) 0215 return args[1]; 0216 return args[0]; 0217 } 0218 0219 0220 // 0221 // Function: NAND 0222 // 0223 Value func_nand(valVector args, ValueCalc *calc, FuncExtra *extra) 0224 { 0225 // AND in reverse 0226 return Value(! func_and(args, calc, extra).asBoolean()); 0227 } 0228 0229 0230 // 0231 // Function: NOR 0232 // 0233 Value func_nor(valVector args, ValueCalc *calc, FuncExtra *extra) 0234 { 0235 // OR in reverse 0236 return Value(! func_or(args, calc, extra).asBoolean()); 0237 } 0238 0239 0240 // 0241 // Function: NOT 0242 // 0243 Value func_not(valVector args, ValueCalc *calc, FuncExtra *) 0244 { 0245 if (args[0].isError()) 0246 return args[0]; 0247 0248 bool ok = true; 0249 bool val = !asBool(args[0], calc, &ok); 0250 if (!ok) return Value::errorVALUE(); 0251 return Value(val); 0252 } 0253 0254 0255 // 0256 // Function: OR 0257 // 0258 Value func_or(valVector args, ValueCalc *calc, FuncExtra *) 0259 { 0260 Value result(false); 0261 int cnt = args.count(); 0262 for (int i = 0; i < cnt; ++i) { 0263 if (args[i].isError()) 0264 return args[i]; 0265 } 0266 for (int i = 0; i < cnt; ++i) { 0267 calc->arrayWalk(args[i], result, awOr, Value(0)); 0268 if (result.asBoolean()) 0269 // if any value is true, return true 0270 return result; 0271 } 0272 // nothing is true -> return false 0273 return result; 0274 } 0275 0276 0277 // 0278 // Function: TRUE 0279 // 0280 Value func_true(valVector, ValueCalc *, FuncExtra *) 0281 { 0282 return Value(true); 0283 } 0284 0285 0286 // 0287 // Function: XOR 0288 // 0289 Value func_xor(valVector args, ValueCalc *calc, FuncExtra *) 0290 { 0291 // exclusive OR - odd number of values must be true 0292 int cnt = args.count(); 0293 Value count(0); 0294 for (int i = 0; i < cnt; ++i) { 0295 if (args[i].isError()) 0296 return args[i]; 0297 } 0298 for (int i = 0; i < cnt; ++i) 0299 calc->arrayWalk(args[i], count, awXor, Value(0)); 0300 return Value((count.asInteger() & 1) == 1); 0301 } 0302 0303 #include "logic.moc"