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 information functions 0022 0023 #include "InformationModule.h" 0024 0025 #include <CalligraVersionWrapper.h> 0026 #ifdef Q_OS_WIN 0027 #include <windows.h> 0028 #else 0029 #include <sys/utsname.h> 0030 #endif 0031 0032 #include <QDir> 0033 #include <KLocalizedString> 0034 0035 #include "SheetsDebug.h" 0036 #include "CalculationSettings.h" 0037 #include "Function.h" 0038 #include "FunctionModuleRegistry.h" 0039 #include "ValueCalc.h" 0040 #include "ValueConverter.h" 0041 #include "Map.h" 0042 #include "Sheet.h" 0043 #include "Region.h" 0044 #include "Cell.h" 0045 #include "Formula.h" 0046 #include "CellStorage.h" 0047 0048 #include <KoDocument.h> 0049 #include <KoPart.h> 0050 #include <KoApplication.h> 0051 0052 using namespace Calligra::Sheets; 0053 0054 // prototypes (sorted alphabetically) 0055 Value func_errortype(valVector args, ValueCalc *calc, FuncExtra *); 0056 Value func_filename(valVector args, ValueCalc *calc, FuncExtra *); 0057 Value func_formula(valVector args, ValueCalc *calc, FuncExtra *); 0058 Value func_info(valVector args, ValueCalc *calc, FuncExtra *); 0059 Value func_isblank(valVector args, ValueCalc *calc, FuncExtra *); 0060 Value func_isdate(valVector args, ValueCalc *calc, FuncExtra *); 0061 Value func_iserr(valVector args, ValueCalc *calc, FuncExtra *); 0062 Value func_iserror(valVector args, ValueCalc *calc, FuncExtra *); 0063 Value func_iseven(valVector args, ValueCalc *calc, FuncExtra *); 0064 Value func_isformula(valVector args, ValueCalc *calc, FuncExtra *); 0065 Value func_islogical(valVector args, ValueCalc *calc, FuncExtra *); 0066 Value func_isna(valVector args, ValueCalc *calc, FuncExtra *); 0067 Value func_isnottext(valVector args, ValueCalc *calc, FuncExtra *); 0068 Value func_isnum(valVector args, ValueCalc *calc, FuncExtra *); 0069 Value func_isodd(valVector args, ValueCalc *calc, FuncExtra *); 0070 Value func_isref(valVector args, ValueCalc *calc, FuncExtra *); 0071 Value func_istext(valVector args, ValueCalc *calc, FuncExtra *); 0072 Value func_istime(valVector args, ValueCalc *calc, FuncExtra *); 0073 Value func_n(valVector args, ValueCalc *calc, FuncExtra *); 0074 Value func_na(valVector args, ValueCalc *calc, FuncExtra *); 0075 Value func_type(valVector args, ValueCalc *calc, FuncExtra *); 0076 Value func_version(valVector args, ValueCalc *calc, FuncExtra *); 0077 0078 CALLIGRA_SHEETS_EXPORT_FUNCTION_MODULE("kspreadinformationmodule.json", InformationModule) 0079 0080 0081 InformationModule::InformationModule(QObject* parent, const QVariantList&) 0082 : FunctionModule(parent) 0083 { 0084 Function *f; 0085 0086 f = new Function("ERRORTYPE", func_errortype); 0087 add(f); 0088 f = new Function("FILENAME", func_filename); 0089 f->setParamCount(0); 0090 add(f); 0091 f = new Function("FORMULA", func_formula); 0092 f->setParamCount(1); 0093 f->setNeedsExtra(true); 0094 add(f); 0095 f = new Function("INFO", func_info); 0096 add(f); 0097 f = new Function("ISBLANK", func_isblank); 0098 add(f); 0099 f = new Function("ISDATE", func_isdate); 0100 add(f); 0101 f = new Function("ISERR", func_iserr); 0102 add(f); 0103 f = new Function("ISERROR", func_iserror); 0104 add(f); 0105 f = new Function("ISEVEN", func_iseven); 0106 f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETISEVEN"); 0107 add(f); 0108 f = new Function("ISFORMULA", func_isformula); 0109 f->setNeedsExtra(true); 0110 add(f); 0111 f = new Function("ISLOGICAL", func_islogical); 0112 add(f); 0113 f = new Function("ISNA", func_isna); 0114 add(f); 0115 f = new Function("ISNONTEXT", func_isnottext); 0116 add(f); 0117 f = new Function("ISNOTTEXT", func_isnottext); 0118 add(f); 0119 f = new Function("ISNUM", func_isnum); 0120 add(f); 0121 f = new Function("ISNUMBER", func_isnum); 0122 add(f); 0123 f = new Function("ISODD", func_isodd); 0124 f->setAlternateName("COM.SUN.STAR.SHEET.ADDIN.ANALYSIS.GETISODD"); 0125 add(f); 0126 f = new Function("ISREF", func_isref); 0127 f->setNeedsExtra(true); 0128 f->setAcceptArray(); 0129 add(f); 0130 f = new Function("ISTEXT", func_istext); 0131 add(f); 0132 f = new Function("ISTIME", func_istime); 0133 add(f); 0134 f = new Function("N", func_n); 0135 add(f); 0136 f = new Function("NA", func_na); 0137 f->setParamCount(0); 0138 add(f); 0139 f = new Function("TYPE", func_type); 0140 f->setAcceptArray(); 0141 add(f); 0142 } 0143 0144 QString InformationModule::descriptionFileName() const 0145 { 0146 return QString("information.xml"); 0147 } 0148 0149 // Function: ERROR.TYPE 0150 Value func_errortype(valVector args, ValueCalc *, FuncExtra *) 0151 { 0152 if (! args[0].isError()) { 0153 // its an error if the argument isn't an error... 0154 return Value::errorVALUE(); 0155 } 0156 0157 if (args[0] == Value::errorNULL()) { 0158 return Value(1); 0159 } else if (args[0] == Value::errorDIV0()) { 0160 return Value(2); 0161 } else if (args[0] == Value::errorVALUE()) { 0162 return Value(3); 0163 } else if (args[0] == Value::errorREF()) { 0164 return Value(4); 0165 } else if (args[0] == Value::errorNAME()) { 0166 return Value(5); 0167 } else if (args[0] == Value::errorNUM()) { 0168 return Value(6); 0169 } else if (args[0] == Value::errorNA()) { 0170 return Value(7); 0171 } else if (args[0] == Value::errorCIRCLE()) { 0172 // non-standard error type 0173 return Value(101); 0174 } else if (args[0] == Value::errorDEPEND()) { 0175 // non-standard error type 0176 return Value(102); 0177 } else if (args[0] == Value::errorPARSE()) { 0178 // non-standard error type 0179 return Value(103); 0180 } else { 0181 // something I didn't think of... 0182 debugSheets << "Unexpected error type"; 0183 return Value(0); 0184 } 0185 } 0186 // Function: INFO 0187 Value func_info(valVector args, ValueCalc *calc, FuncExtra *) 0188 { 0189 QString type = calc->conv()->asString(args[0]).asString().toLower(); 0190 0191 if (type == "directory") 0192 return Value(QDir::currentPath()); 0193 0194 if (type == "release") 0195 return Value(CalligraVersionWrapper::versionString()); 0196 0197 if (type == "numfile") { 0198 KoApplication *app = qobject_cast<KoApplication*>(qApp); 0199 if(! app) { 0200 return Value(0); 0201 } else { 0202 0203 QSet<QString> nameList; 0204 QList<KoPart*> parts = app->partList(); 0205 foreach(KoPart* part, parts) { 0206 nameList.insert(part->document()->objectName()); 0207 } 0208 return Value(nameList.size()); 0209 } 0210 } 0211 0212 if (type == "recalc") { 0213 QString result; 0214 if (!calc->settings()->isAutoCalculationEnabled()) 0215 result = i18n("Manual"); 0216 else 0217 result = i18n("Automatic"); 0218 return Value(result); 0219 } 0220 0221 if (type == "memavail") 0222 // not supported 0223 return Value::errorVALUE(); 0224 if (type == "memused") 0225 // not supported 0226 return Value::errorVALUE(); 0227 if (type == "origin") 0228 // not supported 0229 return Value::errorVALUE(); 0230 0231 if (type == "system") { 0232 #ifndef Q_OS_WIN 0233 struct utsname name; 0234 if (uname(&name) >= 0) 0235 return Value(QString(name.sysname)); 0236 #else 0237 return Value(QString("Windows")); 0238 #endif 0239 } 0240 0241 if (type == "totmem") 0242 // not supported 0243 return Value::errorVALUE(); 0244 0245 if (type == "osversion") { 0246 #ifndef Q_OS_WIN 0247 struct utsname name; 0248 if (uname(&name) >= 0) { 0249 QString os = QString("%1 %2 (%3)").arg(name.sysname). 0250 arg(name.release).arg(name.machine); 0251 return Value(os); 0252 } 0253 #else 0254 OSVERSIONINFO versionInfo; 0255 SYSTEM_INFO sysInfo; 0256 QString architecture; 0257 0258 versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 0259 0260 GetVersionEx(&versionInfo); 0261 GetSystemInfo(&sysInfo); 0262 0263 switch(sysInfo.wProcessorArchitecture) { 0264 case PROCESSOR_ARCHITECTURE_AMD64: 0265 architecture = QString("x86_64"); 0266 break; 0267 case PROCESSOR_ARCHITECTURE_IA64: 0268 architecture = QString("ia64"); 0269 break; 0270 case PROCESSOR_ARCHITECTURE_INTEL: 0271 architecture = QString("x86"); 0272 break; 0273 default: 0274 architecture = QString("unknown"); 0275 } 0276 0277 QString os = QString("Windows %1.%2 (%3)").arg(versionInfo.dwMajorVersion).arg(versionInfo.dwMinorVersion).arg(architecture); 0278 0279 return Value(os); 0280 #endif 0281 } 0282 0283 return Value::errorVALUE(); 0284 } 0285 0286 // Function: ISBLANK 0287 Value func_isblank(valVector args, ValueCalc *, FuncExtra *) 0288 { 0289 return Value(args[0].isEmpty()); 0290 } 0291 0292 // Function: ISLOGICAL 0293 Value func_islogical(valVector args, ValueCalc *, FuncExtra *) 0294 { 0295 return Value(args[0].isBoolean()); 0296 } 0297 0298 // Function: ISTEXT 0299 Value func_istext(valVector args, ValueCalc *, FuncExtra *) 0300 { 0301 return Value(args[0].isString()); 0302 } 0303 0304 // Function: ISREF 0305 Value func_isref(valVector args, ValueCalc * /*calc*/, FuncExtra *e) 0306 { 0307 if (args[0].isError()) return args[0]; // errors pass through 0308 // no reference ? 0309 if ((e == 0) || (e->ranges[0].col1 == -1) || (e->ranges[0].row1 == -1)) 0310 return Value(false); 0311 // if we are here, it is a reference (cell/range) 0312 return Value(true); 0313 } 0314 0315 // Function: ISNOTTEXT 0316 Value func_isnottext(valVector args, ValueCalc *, FuncExtra *) 0317 { 0318 return Value(args[0].isString() ? false : true); 0319 } 0320 0321 // Function: ISNUM 0322 Value func_isnum(valVector args, ValueCalc *, FuncExtra *) 0323 { 0324 return Value(args[0].isNumber()); 0325 } 0326 0327 // Function: ISTIME 0328 Value func_istime(valVector args, ValueCalc *, FuncExtra *) 0329 { 0330 return Value((args[0].format() == Value::fmt_Time) 0331 || (args[0].format() == Value::fmt_DateTime)); 0332 } 0333 0334 // Function: ISDATE 0335 Value func_isdate(valVector args, ValueCalc *, FuncExtra *) 0336 { 0337 return Value((args[0].format() == Value::fmt_Date) 0338 || (args[0].format() == Value::fmt_DateTime)); 0339 } 0340 0341 // Function: ISODD 0342 Value func_isodd(valVector args, ValueCalc *calc, FuncExtra *) 0343 { 0344 return Value(calc->isEven(args[0]) ? false : true); 0345 } 0346 0347 // Function: ISEVEN 0348 Value func_iseven(valVector args, ValueCalc *calc, FuncExtra *) 0349 { 0350 if (args[0].isError()) 0351 return args[0]; 0352 return Value(calc->isEven(args[0])); 0353 } 0354 0355 // Function: ISFORMULA 0356 Value func_isformula(valVector /*args*/, ValueCalc */*calc*/, FuncExtra *e) 0357 { 0358 const Calligra::Sheets::Region ®ion = e->regions[0]; 0359 QPoint p = region.firstRange().topLeft(); 0360 CellStorage *s = region.firstSheet()->cellStorage(); 0361 Formula formula = s->formula(p.x(), p.y()); 0362 return Value(formula.isValid()); 0363 } 0364 0365 // Function: ISERR 0366 Value func_iserr(valVector args, ValueCalc *, FuncExtra *) 0367 { 0368 return Value((args[0].isError() && 0369 (args[0].errorMessage() != Value::errorNA().errorMessage()))); 0370 } 0371 0372 // Function: ISERROR 0373 Value func_iserror(valVector args, ValueCalc *, FuncExtra *) 0374 { 0375 return Value(args[0].isError()); 0376 } 0377 0378 // Function: ISNA 0379 Value func_isna(valVector args, ValueCalc *, FuncExtra *) 0380 { 0381 return Value((args[0].isError() && 0382 (args[0].errorMessage() == Value::errorNA().errorMessage()))); 0383 } 0384 0385 // Function: TYPE 0386 Value func_type(valVector args, ValueCalc *, FuncExtra *) 0387 { 0388 // Returns 1 for numbers, 2 for text, 4 for boolean, 16 for error, 0389 // 64 for arrays 0390 if (args[0].isArray()) 0391 return Value(64); 0392 if (args[0].isNumber()) 0393 return Value(1); 0394 if (args[0].isString()) 0395 return Value(2); 0396 if (args[0].isBoolean()) 0397 return Value(4); 0398 if (args[0].isError()) 0399 return Value(16); 0400 0401 // something else ? 0402 return Value(0); 0403 } 0404 0405 Value func_filename(valVector, ValueCalc *calc, FuncExtra *) 0406 { 0407 return Value(calc->settings()->fileName()); 0408 } 0409 0410 Value func_formula(valVector, ValueCalc *, FuncExtra *e) 0411 { 0412 if(e->ranges[0].col1 < 1 || e->ranges[0].row1 < 1) 0413 return Value::errorVALUE(); 0414 const Calligra::Sheets::Cell c(e->sheet, e->ranges[0].col1, e->ranges[0].row1); 0415 if (c.isNull()) 0416 return Value::errorVALUE(); 0417 if (!c.isFormula()) 0418 return Value::errorNA(); 0419 return Value(c.formula().expression()); 0420 } 0421 0422 // Function: N 0423 Value func_n(valVector args, ValueCalc *calc, FuncExtra *) 0424 { 0425 return calc->conv()->asFloat(args[0]); 0426 } 0427 0428 // Function: NA 0429 Value func_na(valVector, ValueCalc *, FuncExtra *) 0430 { 0431 return Value::errorNA(); 0432 } 0433 0434 #include "information.moc"