File indexing completed on 2024-04-28 16:21:36
0001 /* This file is part of the KDE project 0002 Copyright 2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0003 Copyright 2003,2004 Ariya Hidayat <ariya@kde.org> 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 #include "Value.h" 0022 #include "CalculationSettings.h" 0023 #include "CellStorage.h" 0024 #include "ValueStorage.h" 0025 #include "SheetsDebug.h" 0026 0027 #include <KLocalizedString> 0028 0029 #include <QString> 0030 #include <QTextStream> 0031 0032 #include <float.h> 0033 #include <math.h> 0034 #include <limits.h> 0035 0036 using namespace Calligra::Sheets; 0037 0038 class ValueArray 0039 { 0040 public: 0041 ValueArray() : m_size(0, 0) {} 0042 ValueArray(const ValueStorage& storage, const QSize& size) : m_size(size), m_storage(storage) {} 0043 0044 ValueStorage& storage() { return m_storage; } 0045 int rows() const { return qMax(m_size.height(), m_storage.rows()); } 0046 int columns() const { return qMax(m_size.width(), m_storage.columns()); } 0047 0048 bool operator==(const ValueArray& a) const { return rows() == a.rows() && columns() == a.columns() && m_storage == a.m_storage; } 0049 private: 0050 QSize m_size; 0051 ValueStorage m_storage; 0052 }; 0053 0054 class Q_DECL_HIDDEN Value::Private : public QSharedData 0055 { 0056 public: 0057 0058 Value::Type type: 4; 0059 Value::Format format: 4; 0060 0061 union { // 64 bits at max! 0062 // b is also secondarily used to indicate a null value if type == Empty, 0063 // without using up space for an explicit member variable. 0064 bool b; 0065 qint64 i; 0066 Number f; 0067 complex<Number>* pc; 0068 QString* ps; 0069 ValueArray* pa; 0070 }; 0071 0072 // create empty data 0073 Private() : type(Value::Empty), format(Value::fmt_None), ps(0) {} 0074 0075 Private(const Private& o) 0076 : QSharedData(o) 0077 , type(o.type) 0078 , format(o.format) { 0079 switch (type) { 0080 case Value::Empty: 0081 default: 0082 ps = 0; 0083 break; 0084 case Value::Boolean: 0085 b = o.b; 0086 break; 0087 case Value::Integer: 0088 i = o.i; 0089 break; 0090 case Value::Float: 0091 f = o.f; 0092 break; 0093 case Value::Complex: 0094 pc = new complex<Number>(*o.pc); 0095 break; 0096 case Value::String: 0097 case Value::Error: 0098 ps = new QString(*o.ps); 0099 break; 0100 case Value::Array: 0101 pa = new ValueArray(*o.pa); 0102 break; 0103 } 0104 } 0105 0106 // destroys data 0107 ~Private() { 0108 if (this == s_null) 0109 s_null = 0; 0110 clear(); 0111 } 0112 0113 // static empty data to be shared 0114 static Private* null() { 0115 if (!s_null) s_null = new Private; 0116 return s_null; 0117 } 0118 0119 // true if it's null (which is shared) 0120 bool isNull() { 0121 return this == s_null; 0122 } 0123 0124 /** Deletes all data. */ 0125 void clear() { 0126 if (type == Value::Array) delete pa; 0127 if (type == Value::Complex) delete pc; 0128 if (type == Value::Error) delete ps; 0129 if (type == Value::String) delete ps; 0130 type = Value::Empty; 0131 b = 0; 0132 } 0133 0134 /** set most probable formatting based on the type */ 0135 void setFormatByType(); 0136 0137 private: 0138 void operator=(const Value::Private& o); 0139 0140 static Private* s_null; 0141 }; 0142 0143 void Value::Private::setFormatByType() 0144 { 0145 switch (type) { 0146 case Value::Empty: 0147 format = Value::fmt_None; 0148 break; 0149 case Value::Boolean: 0150 format = Value::fmt_Boolean; 0151 break; 0152 case Value::Integer: 0153 case Value::Float: 0154 case Value::Complex: 0155 format = Value::fmt_Number; 0156 break; 0157 case Value::String: 0158 format = Value::fmt_String; 0159 break; 0160 case Value::Array: 0161 format = Value::fmt_None; 0162 break; 0163 case Value::CellRange: 0164 format = Value::fmt_None; 0165 break; 0166 case Value::Error: 0167 format = Value::fmt_String; 0168 break; 0169 }; 0170 } 0171 0172 // to be shared between all empty value 0173 Value::Private* Value::Private::s_null = 0; 0174 0175 // static things 0176 Value ks_value_empty; 0177 Value ks_value_null; 0178 Value ks_error_circle; 0179 Value ks_error_depend; 0180 Value ks_error_div0; 0181 Value ks_error_na; 0182 Value ks_error_name; 0183 Value ks_error_null; 0184 Value ks_error_num; 0185 Value ks_error_parse; 0186 Value ks_error_ref; 0187 Value ks_error_value; 0188 0189 // create an empty value 0190 Value::Value() 0191 : d(Private::null()) 0192 { 0193 } 0194 0195 // destructor 0196 Value::~Value() 0197 { 0198 } 0199 0200 // create value of certain type 0201 Value::Value(Value::Type _type) 0202 : d(Private::null()) 0203 { 0204 d->type = _type; 0205 d->setFormatByType(); 0206 } 0207 0208 // copy constructor 0209 Value::Value(const Value& _value) 0210 : d(_value.d) 0211 { 0212 } 0213 0214 // assignment operator 0215 Value& Value::operator=(const Value & _value) 0216 { 0217 d = _value.d; 0218 return *this; 0219 } 0220 0221 // comparison operator - returns true only if strictly identical, unlike equal()/compare() 0222 bool Value::operator==(const Value& o) const 0223 { 0224 if (d->type != o.d->type) 0225 return false; 0226 switch (d->type) { 0227 // null() (d->b == 1) and empty() (d->b == 0) are equal to this operator 0228 case Empty: return true; 0229 case Boolean: return o.d->b == d->b; 0230 case Integer: return o.d->i == d->i; 0231 case Float: return compare(o.d->f, d->f) == 0; 0232 case Complex: return (!d->pc && !o.d->pc) || ((d->pc && o.d->pc) && (*o.d->pc == *d->pc)); 0233 case String: return (!d->ps && !o.d->ps) || ((d->ps && o.d->ps) && (*o.d->ps == *d->ps)); 0234 case Array: return (!d->pa && !o.d->pa) || ((d->pa && o.d->pa) && (*o.d->pa == *d->pa)); 0235 case Error: return (!d->ps && !o.d->ps) || ((d->ps && o.d->ps) && (*o.d->ps == *d->ps)); 0236 default: break; 0237 } 0238 warnSheets << "Unhandled type in Value::operator==: " << d->type; 0239 return false; 0240 } 0241 0242 // create a boolean value 0243 Value::Value(bool b) 0244 : d(Private::null()) 0245 { 0246 d->type = Boolean; 0247 d->b = b; 0248 d->format = fmt_Boolean; 0249 } 0250 0251 // create an integer value 0252 Value::Value(qint64 i) 0253 : d(Private::null()) 0254 { 0255 d->type = Integer; 0256 d->i = i; 0257 d->format = fmt_Number; 0258 } 0259 0260 // create an integer value 0261 Value::Value(int i) 0262 : d(Private::null()) 0263 { 0264 d->type = Integer; 0265 d->i = static_cast<qint64>(i); 0266 d->format = fmt_Number; 0267 } 0268 0269 // create a floating-point value 0270 Value::Value(double f) 0271 : d(Private::null()) 0272 { 0273 d->type = Float; 0274 d->f = Number(f); 0275 d->format = fmt_Number; 0276 } 0277 0278 // create a floating-point value 0279 Value::Value(long double f) 0280 : d(Private::null()) 0281 { 0282 d->type = Float; 0283 d->f = Number(f); 0284 d->format = fmt_Number; 0285 } 0286 0287 0288 #ifdef CALLIGRA_SHEETS_HIGH_PRECISION_SUPPORT 0289 // create a floating-point value 0290 Value::Value(Number f) 0291 : d(Private::null()) 0292 { 0293 d->type = Float; 0294 d->f = f; 0295 d->format = fmt_Number; 0296 } 0297 #endif // CALLIGRA_SHEETS_HIGH_PRECISION_SUPPORT 0298 0299 // create a complex number value 0300 Value::Value(const complex<Number>& c) 0301 : d(Private::null()) 0302 { 0303 d->type = Complex; 0304 d->pc = new complex<Number>(c); 0305 d->format = fmt_Number; 0306 } 0307 0308 // create a string value 0309 Value::Value(const QString& s) 0310 : d(Private::null()) 0311 { 0312 d->type = String; 0313 d->ps = new QString(s); 0314 d->format = fmt_String; 0315 } 0316 0317 // create a string value 0318 Value::Value(const char *s) 0319 : d(Private::null()) 0320 { 0321 d->type = String; 0322 d->ps = new QString(s); 0323 d->format = fmt_String; 0324 } 0325 0326 // create a floating-point value from date/time 0327 Value::Value(const QDateTime& dt, const CalculationSettings* settings) 0328 : d(Private::null()) 0329 { 0330 const QDate refDate(settings->referenceDate()); 0331 const QTime refTime(0, 0); // reference time is midnight 0332 d->type = Float; 0333 d->f = Number(refDate.daysTo(dt.date())); 0334 d->f += static_cast<double>(refTime.msecsTo(dt.time())) / 86400000.0; // 24*60*60*1000 0335 d->format = fmt_DateTime; 0336 } 0337 0338 // create a floating-point value from time 0339 Value::Value(const QTime& time) 0340 : d(Private::null()) 0341 { 0342 const QTime refTime(0, 0); // reference time is midnight 0343 0344 d->type = Float; 0345 d->f = Number(static_cast<double>(refTime.msecsTo(time)) / 86400000.0); // 24*60*60*1000 0346 d->format = fmt_Time; 0347 } 0348 0349 // create a floating-point value from date 0350 Value::Value(const QDate& date, const CalculationSettings* settings) 0351 : d(Private::null()) 0352 { 0353 const QDate refDate(settings->referenceDate()); 0354 0355 d->type = Integer; 0356 d->i = refDate.daysTo(date); 0357 d->format = fmt_Date; 0358 } 0359 0360 // create an array value 0361 Value::Value(const ValueStorage& array, const QSize& size) 0362 : d(Private::null()) 0363 { 0364 d->type = Array; 0365 d->pa = new ValueArray(array, size); 0366 d->format = fmt_None; 0367 } 0368 0369 // return type of the value 0370 Value::Type Value::type() const 0371 { 0372 return d ? d->type : Empty; 0373 } 0374 0375 bool Value::isNull() const 0376 { 0377 return d ? d->type == Empty && d->b : false; 0378 } 0379 0380 // get the value as boolean 0381 bool Value::asBoolean() const 0382 { 0383 bool result = false; 0384 0385 if (type() == Value::Boolean) 0386 result = d->b; 0387 0388 return result; 0389 } 0390 0391 // get the value as integer 0392 qint64 Value::asInteger() const 0393 { 0394 qint64 result = 0; 0395 if (type() == Integer) 0396 result = d->i; 0397 else if (type() == Float) 0398 result = static_cast<qint64>(floor(numToDouble(d->f))); 0399 else if (type() == Complex) 0400 result = static_cast<qint64>(floor(numToDouble(d->pc->real()))); 0401 return result; 0402 } 0403 0404 // get the value as floating-point 0405 Number Value::asFloat() const 0406 { 0407 Number result = 0.0; 0408 if (type() == Float) 0409 result = d->f; 0410 else if (type() == Integer) 0411 result = static_cast<Number>(d->i); 0412 else if (type() == Complex) 0413 result = d->pc->real(); 0414 return result; 0415 } 0416 0417 // get the value as complex number 0418 complex<Number> Value::asComplex() const 0419 { 0420 complex<Number> result(0.0, 0.0); 0421 if (type() == Complex) 0422 result = *d->pc; 0423 else if (type() == Float) 0424 result = d->f; 0425 else if (type() == Integer) 0426 result = static_cast<Number>(d->i); 0427 return result; 0428 } 0429 0430 // get the value as string 0431 QString Value::asString() const 0432 { 0433 QString result; 0434 0435 if (type() == Value::String) 0436 if (d->ps) 0437 result = QString(*d->ps); 0438 0439 return result; 0440 } 0441 0442 QString Value::asStringWithDoubleQuotes() const 0443 { 0444 QString s = asString(); 0445 if (type() == Value::String) { 0446 if (!(s.startsWith(QLatin1Char('\"')) && s.endsWith(QLatin1Char('\"')))) { 0447 if (s.startsWith(QLatin1Char('\'')) && s.endsWith(QLatin1Char('\''))) 0448 s = s.mid(1, s.length()-2); 0449 s = QLatin1Char('\"') + s + QLatin1Char('\"'); 0450 } 0451 } 0452 return s; 0453 } 0454 0455 // get the value as QVariant 0456 QVariant Value::asVariant() const 0457 { 0458 QVariant result; 0459 0460 switch (d->type) { 0461 case Value::Empty: 0462 default: 0463 result = 0; 0464 break; 0465 case Value::Boolean: 0466 result = d->b; 0467 break; 0468 case Value::Integer: 0469 result = d->i; 0470 break; 0471 case Value::Float: 0472 result = (double) numToDouble(d->f); 0473 break; 0474 case Value::Complex: 0475 // FIXME: add support for complex numbers 0476 // pc = new complex<Number>( *o.pc ); 0477 break; 0478 case Value::String: 0479 case Value::Error: 0480 result = *d->ps; 0481 break; 0482 case Value::Array: 0483 // FIXME: not supported yet 0484 //result = ValueArray( d->pa ); 0485 break; 0486 } 0487 0488 return result; 0489 } 0490 0491 // set error message 0492 void Value::setError(const QString& msg) 0493 { 0494 d->clear(); 0495 d->type = Error; 0496 d->ps = new QString(msg); 0497 } 0498 0499 // get error message 0500 QString Value::errorMessage() const 0501 { 0502 QString result; 0503 0504 if (type() == Value::Error) 0505 if (d->ps) 0506 result = QString(*d->ps); 0507 0508 return result; 0509 } 0510 0511 // get the value as date/time 0512 QDateTime Value::asDateTime(const CalculationSettings* settings) const 0513 { 0514 QDateTime datetime(settings->referenceDate(), QTime(), Qt::UTC); 0515 0516 const int days = asInteger(); 0517 const int msecs = ::round((numToDouble(asFloat() - double(days))) * 86400000.0); // 24*60*60*1000 0518 datetime = datetime.addDays(days); 0519 datetime = datetime.addMSecs(msecs); 0520 0521 return datetime; 0522 } 0523 0524 // get the value as date 0525 QDate Value::asDate(const CalculationSettings* settings) const 0526 { 0527 QDate dt(settings->referenceDate()); 0528 0529 int i = asInteger(); 0530 dt = dt.addDays(i); 0531 0532 return dt; 0533 } 0534 0535 // get the value as time 0536 QTime Value::asTime() const 0537 { 0538 QTime dt(0, 0, 0, 0); 0539 0540 const int days = asInteger(); 0541 const int msecs = ::round(numToDouble(asFloat() - double(days)) * 86400000.0); // 24*60*60*1000 0542 dt = dt.addMSecs(msecs); 0543 0544 return dt; 0545 } 0546 0547 Value::Format Value::format() const 0548 { 0549 return d ? d->format : fmt_None; 0550 } 0551 0552 void Value::setFormat(Value::Format fmt) 0553 { 0554 d->format = fmt; 0555 } 0556 0557 Value Value::element(unsigned column, unsigned row) const 0558 { 0559 if (d->type != Array) return *this; 0560 if (!d->pa) return empty(); 0561 return d->pa->storage().lookup(column + 1, row + 1); 0562 } 0563 0564 Value Value::element(unsigned index) const 0565 { 0566 if (d->type != Array) return *this; 0567 if (!d->pa) return empty(); 0568 return d->pa->storage().data(index); 0569 } 0570 0571 void Value::setElement(unsigned column, unsigned row, const Value& v) 0572 { 0573 if (d->type != Array) return; 0574 if (!d->pa) d->pa = new ValueArray(); 0575 d->pa->storage().insert(column + 1, row + 1, v); 0576 } 0577 0578 unsigned Value::columns() const 0579 { 0580 if (d->type != Array) return 1; 0581 if (!d->pa) return 1; 0582 return d->pa->columns(); 0583 } 0584 0585 unsigned Value::rows() const 0586 { 0587 if (d->type != Array) return 1; 0588 if (!d->pa) return 1; 0589 return d->pa->rows(); 0590 } 0591 0592 unsigned Value::count() const 0593 { 0594 if (d->type != Array) return 1; 0595 if (!d->pa) return 1; 0596 return d->pa->storage().count(); 0597 } 0598 0599 // reference to empty value 0600 const Value& Value::empty() 0601 { 0602 return ks_value_empty; 0603 } 0604 0605 // reference to null value 0606 const Value& Value::null() 0607 { 0608 if (!ks_value_null.isNull()) 0609 ks_value_null.d->b = true; 0610 return ks_value_null; 0611 } 0612 0613 // reference to #CIRCLE! error 0614 const Value& Value::errorCIRCLE() 0615 { 0616 if (!ks_error_circle.isError()) 0617 ks_error_circle.setError(i18nc("Error: circular formula dependency", "#CIRCLE!")); 0618 return ks_error_circle; 0619 } 0620 0621 // reference to #DEPEND! error 0622 const Value& Value::errorDEPEND() 0623 { 0624 if (!ks_error_depend.isError()) 0625 ks_error_depend.setError(i18nc("Error: broken cell reference", "#DEPEND!")); 0626 return ks_error_depend; 0627 } 0628 0629 // reference to #DIV/0! error 0630 const Value& Value::errorDIV0() 0631 { 0632 if (!ks_error_div0.isError()) 0633 ks_error_div0.setError(i18nc("Error: division by zero", "#DIV/0!")); 0634 return ks_error_div0; 0635 } 0636 0637 // reference to #N/A error 0638 const Value& Value::errorNA() 0639 { 0640 if (!ks_error_na.isError()) 0641 ks_error_na.setError(i18nc("Error: not available", "#N/A")); 0642 return ks_error_na; 0643 } 0644 0645 // reference to #NAME? error 0646 const Value& Value::errorNAME() 0647 { 0648 if (!ks_error_name.isError()) 0649 ks_error_name.setError(i18nc("Error: unknown function name", "#NAME?")); 0650 return ks_error_name; 0651 } 0652 0653 // reference to #NUM! error 0654 const Value& Value::errorNUM() 0655 { 0656 if (!ks_error_num.isError()) 0657 ks_error_num.setError(i18nc("Error: number out of range", "#NUM!")); 0658 return ks_error_num; 0659 } 0660 0661 // reference to #NULL! error 0662 const Value& Value::errorNULL() 0663 { 0664 if (!ks_error_null.isError()) 0665 ks_error_null.setError(i18nc("Error: empty intersecting area", "#NULL!")); 0666 return ks_error_null; 0667 } 0668 0669 // reference to #PARSE! error 0670 const Value& Value::errorPARSE() 0671 { 0672 if (!ks_error_parse.isError()) 0673 ks_error_parse.setError(i18nc("Error: formula not parseable", "#PARSE!")); 0674 return ks_error_parse; 0675 } 0676 0677 // reference to #REF! error 0678 const Value& Value::errorREF() 0679 { 0680 if (!ks_error_ref.isError()) 0681 ks_error_ref.setError(i18nc("Error: invalid cell/array reference", "#REF!")); 0682 return ks_error_ref; 0683 } 0684 0685 // reference to #VALUE! error 0686 const Value& Value::errorVALUE() 0687 { 0688 if (!ks_error_value.isError()) 0689 ks_error_value.setError(i18nc("Error: wrong (number of) function argument(s)", "#VALUE!")); 0690 return ks_error_value; 0691 } 0692 0693 int Value::compare(Number v1, Number v2) 0694 { 0695 Number v3 = v1 - v2; 0696 if (v3 > DBL_EPSILON) return 1; 0697 if (v3 < -DBL_EPSILON) return -1; 0698 return 0; 0699 } 0700 0701 bool Value::isZero(Number v) 0702 { 0703 return abs(v) < DBL_EPSILON; 0704 } 0705 0706 bool Value::isZero() const 0707 { 0708 if (!isNumber()) return false; 0709 return isZero(asFloat()); 0710 } 0711 0712 bool Value::allowComparison(const Value& v) const 0713 { 0714 Value::Type t1 = d->type; 0715 Value::Type t2 = v.type(); 0716 0717 if ((t1 == Empty) && (t2 == Empty)) return true; 0718 if ((t1 == Empty) && (t2 == String)) return true; 0719 if ((t1 == Empty) && (t2 == Integer)) return true; 0720 if ((t1 == Empty) && (t2 == Float)) return true; 0721 if ((t1 == Empty) && (t2 == Boolean)) return true; 0722 0723 if ((t1 == Boolean) && (t2 == Boolean)) return true; 0724 if ((t1 == Boolean) && (t2 == Integer)) return true; 0725 if ((t1 == Boolean) && (t2 == Float)) return true; 0726 if ((t1 == Boolean) && (t2 == String)) return true; 0727 0728 if ((t1 == Integer) && (t2 == Boolean)) return true; 0729 if ((t1 == Integer) && (t2 == Integer)) return true; 0730 if ((t1 == Integer) && (t2 == Float)) return true; 0731 if ((t1 == Integer) && (t2 == String)) return true; 0732 0733 if ((t1 == Float) && (t2 == Boolean)) return true; 0734 if ((t1 == Float) && (t2 == Integer)) return true; 0735 if ((t1 == Float) && (t2 == Float)) return true; 0736 if ((t1 == Float) && (t2 == String)) return true; 0737 0738 if ((t1 == Complex) && (t2 == Boolean)) return true; 0739 if ((t1 == Complex) && (t2 == Integer)) return true; 0740 if ((t1 == Complex) && (t2 == Float)) return true; 0741 if ((t1 == Complex) && (t2 == String)) return true; 0742 0743 if ((t1 == String) && (t2 == Empty)) return true; 0744 if ((t1 == String) && (t2 == Boolean)) return true; 0745 if ((t1 == String) && (t2 == Integer)) return true; 0746 if ((t1 == String) && (t2 == Float)) return true; 0747 if ((t1 == String) && (t2 == Complex)) return true; 0748 if ((t1 == String) && (t2 == String)) return true; 0749 0750 // errors can be compared too ... 0751 if ((t1 == Error) && (t2 == Error)) return true; 0752 0753 return false; 0754 } 0755 0756 // compare values. looks strange in order to be compatible with Excel 0757 int Value::compare(const Value& v, Qt::CaseSensitivity cs) const 0758 { 0759 Value::Type t1 = d->type; 0760 Value::Type t2 = v.type(); 0761 0762 // errors always less than everything else 0763 if ((t1 == Error) && (t2 != Error)) 0764 return -1; 0765 if ((t2 == Error) && (t1 != Error)) 0766 return 1; 0767 0768 // comparing errors only yields 0 if they are the same 0769 if ((t1 == Error) && (t2 == Error)) 0770 return errorMessage() != v.errorMessage(); 0771 0772 // empty == empty 0773 if ((t1 == Empty) && (t2 == Empty)) 0774 return 0; 0775 0776 // empty value is always less than string 0777 // (except when the string is empty) 0778 if ((t1 == Empty) && (t2 == String)) 0779 return(v.asString().isEmpty()) ? 0 : -1; 0780 0781 // empty vs integer 0782 if ((t1 == Empty) && (t2 == Integer)) 0783 return -1; 0784 0785 // empty vs float 0786 if ((t1 == Empty) && (t2 == Float)) 0787 return -1; 0788 0789 // empty vs boolean 0790 if ((t1 == Empty) && (t2 == Boolean)) 0791 return -1; 0792 0793 // boolean vs boolean 0794 if ((t1 == Boolean) && (t2 == Boolean)) { 0795 bool p = asBoolean(); 0796 bool q = v.asBoolean(); 0797 if (p) return q ? 0 : 1; 0798 else return q ? -1 : 0; 0799 } 0800 0801 // boolean is always greater than integer 0802 if ((t1 == Boolean) && (t2 == Integer)) 0803 return 1; 0804 0805 // boolean is always greater than float 0806 if ((t1 == Boolean) && (t2 == Float)) 0807 return 1; 0808 0809 // boolean is always greater than string 0810 if ((t1 == Boolean) && (t2 == String)) 0811 return 1; 0812 0813 // integer is always less than boolean 0814 if ((t1 == Integer) && (t2 == Boolean)) 0815 return -1; 0816 0817 // integer vs integer 0818 if ((t1 == Integer) && (t2 == Integer)) { 0819 qint64 p = asInteger(); 0820 qint64 q = v.asInteger(); 0821 return (p == q) ? 0 : (p < q) ? -1 : 1; 0822 } 0823 0824 // integer vs float 0825 if ((t1 == Integer) && (t2 == Float)) 0826 return compare(asFloat(), v.asFloat()); 0827 0828 // integer is always less than string 0829 if ((t1 == Integer) && (t2 == String)) 0830 return -1; 0831 0832 // float is always less than boolean 0833 if ((t1 == Float) && (t2 == Boolean)) 0834 return -1; 0835 0836 // float vs integer 0837 if ((t1 == Float) && (t2 == Integer)) 0838 return compare(asFloat(), v.asFloat()); 0839 0840 // float vs float 0841 if ((t1 == Float) && (t2 == Float)) 0842 return compare(asFloat(), v.asFloat()); 0843 0844 // float is always less than string 0845 if ((t1 == Float) && (t2 == String)) 0846 return -1; 0847 0848 // TODO Stefan: Complex 0849 0850 // string is always greater than empty value 0851 // (except when the string is empty) 0852 if ((t1 == String) && (t2 == Empty)) 0853 return(asString().isEmpty()) ? 0 : 1; 0854 0855 // string is always less than boolean 0856 if ((t1 == String) && (t2 == Boolean)) 0857 return -1; 0858 0859 // string is always greater than integer 0860 if ((t1 == String) && (t2 == Integer)) 0861 return 1; 0862 0863 // string is always greater than float 0864 if ((t1 == String) && (t2 == Float)) 0865 return 1; 0866 0867 // The-Real-String comparison 0868 if ((t1 == String) && (t2 == String)) 0869 return asString().compare(v.asString(), cs); 0870 0871 // Undefined, actually allowComparison would return false 0872 return 0; 0873 } 0874 0875 bool Value::equal(const Value& v, Qt::CaseSensitivity cs) const 0876 { 0877 if (!allowComparison(v)) return false; 0878 return compare(v, cs) == 0; 0879 } 0880 0881 bool Value::less(const Value& v, Qt::CaseSensitivity cs) const 0882 { 0883 if (!allowComparison(v)) return false; 0884 return compare(v, cs) < 0; 0885 } 0886 0887 bool Value::greater(const Value& v, Qt::CaseSensitivity cs) const 0888 { 0889 if (!allowComparison(v)) return false; 0890 return compare(v, cs) > 0; 0891 } 0892 0893 QTextStream& operator<<(QTextStream& ts, Value::Type type) 0894 { 0895 switch (type) { 0896 case Value::Empty: ts << "Empty"; break; 0897 case Value::Boolean: ts << "Boolean"; break; 0898 case Value::Integer: ts << "Integer"; break; 0899 case Value::Float: ts << "Float"; break; 0900 case Value::Complex: ts << "Complex"; break; 0901 case Value::String: ts << "String"; break; 0902 case Value::Array: ts << "Array"; break; 0903 case Value::Error: ts << "Error"; break; 0904 default: ts << "Unknown!"; break; 0905 }; 0906 return ts; 0907 } 0908 0909 QTextStream& operator<<(QTextStream& ts, Value value) 0910 { 0911 ts << value.type(); 0912 switch (value.type()) { 0913 case Value::Empty: break; 0914 0915 case Value::Boolean: 0916 ts << ": "; 0917 if (value.asBoolean()) ts << "TRUE"; 0918 else ts << "FALSE"; 0919 break; 0920 0921 case Value::Integer: 0922 ts << ": " << value.asInteger(); break; 0923 0924 case Value::Float: 0925 ts << ": " << (double) numToDouble(value.asFloat()); break; 0926 0927 case Value::Complex: { 0928 const complex<Number> complex(value.asComplex()); 0929 ts << ": " << (double) numToDouble(complex.real()); 0930 if (complex.imag() >= 0.0) 0931 ts << '+'; 0932 ts << (double) numToDouble(complex.imag()) << 'i'; 0933 break; 0934 } 0935 0936 case Value::String: 0937 ts << ": " << value.asString(); break; 0938 0939 case Value::Array: { 0940 ts << ": {" << value.asString(); 0941 const int cols = value.columns(); 0942 const int rows = value.rows(); 0943 for (int row = 0; row < rows; ++row) { 0944 for (int col = 0; col < cols; ++col) { 0945 ts << value.element(col, row); 0946 if (col < cols - 1) 0947 ts << ';'; 0948 } 0949 if (row < rows - 1) 0950 ts << '|'; 0951 } 0952 ts << '}'; 0953 break; 0954 } 0955 0956 case Value::Error: 0957 ts << '(' << value.errorMessage() << ')'; break; 0958 0959 default: break; 0960 } 0961 return ts; 0962 } 0963 0964 /*************************************************************************** 0965 QHash/QSet support 0966 ****************************************************************************/ 0967 0968 namespace Calligra 0969 { 0970 namespace Sheets 0971 { 0972 uint qHash(const Value& value) 0973 { 0974 switch (value.type()) { 0975 case Value::Empty: 0976 case Value::CellRange: 0977 return 0; 0978 case Value::Boolean: 0979 return ::qHash(value.asBoolean()); 0980 case Value::Integer: 0981 return ::qHash(value.asInteger()); 0982 case Value::Float: 0983 return ::qHash((qint64)numToDouble(value.asFloat())); 0984 case Value::Complex: 0985 return ::qHash((qint64)value.asComplex().real()); 0986 case Value::String: 0987 return ::qHash(value.asString()); 0988 case Value::Array: 0989 return qHash(value.element(0, 0)); 0990 case Value::Error: 0991 return ::qHash(value.errorMessage()); 0992 } 0993 return 0; 0994 } 0995 } // namespace Sheets 0996 } // namespace Calligra 0997 0998 /*************************************************************************** 0999 QDebug support 1000 ****************************************************************************/ 1001 1002 QDebug operator<<(QDebug str, const Calligra::Sheets::Value& v) 1003 { 1004 QString string; 1005 QTextStream stream(&string); 1006 stream << v; 1007 str << string; 1008 return str; 1009 } 1010 1011 QDebug operator<<(QDebug stream, const Calligra::Sheets::Value::Format& f) 1012 { 1013 switch (f) { 1014 case Calligra::Sheets::Value::fmt_None: stream << "None"; break; 1015 case Calligra::Sheets::Value::fmt_Boolean: stream << "Boolean"; break; 1016 case Calligra::Sheets::Value::fmt_Number: stream << "Number"; break; 1017 case Calligra::Sheets::Value::fmt_Percent: stream << "Percent"; break; 1018 case Calligra::Sheets::Value::fmt_Money: stream << "Money"; break; 1019 case Calligra::Sheets::Value::fmt_DateTime: stream << "DateTime"; break; 1020 case Calligra::Sheets::Value::fmt_Date: stream << "Date"; break; 1021 case Calligra::Sheets::Value::fmt_Time: stream << "Time"; break; 1022 case Calligra::Sheets::Value::fmt_String: stream << "String"; break; 1023 } 1024 return stream; 1025 }