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 }