kspread_value.cc
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kspread_value.h"
00021
00022 #include <float.h>
00023 #include <math.h>
00024 #include <limits.h>
00025
00026 #include <qstring.h>
00027 #include <qtextstream.h>
00028
00029
00030
00031 class ValueArray
00032 {
00033 public:
00034 KSpreadValue** ptr;
00035 unsigned columns;
00036 unsigned rows;
00037
00038 ValueArray(): ptr(0), columns(0), rows(0) {};
00039
00040 ~ValueArray()
00041 {
00042 clear();
00043 };
00044
00045 ValueArray( const ValueArray& va )
00046 {
00047 operator=( va );
00048 }
00049
00050 ValueArray& operator= ( const ValueArray& va )
00051 {
00052 init( va.columns, va.rows );
00053 unsigned count = columns * rows;
00054 for( unsigned i = 0; i < count; i++ )
00055 if( va.ptr[i] )
00056 ptr[i] = new KSpreadValue( *va.ptr[i] );
00057 return *this;
00058 }
00059
00060 void clear()
00061 {
00062 if( !ptr ) return;
00063 unsigned count = columns * rows;
00064 if( !count ) return;
00065 for( unsigned i = 0; i < count; i++ )
00066 delete ptr[i];
00067 delete [] ptr;
00068 ptr = 0;
00069 }
00070
00071 void init( unsigned c, unsigned r )
00072 {
00073 if( ptr ) clear();
00074 columns = c; rows = r;
00075 unsigned count = columns * rows;
00076 ptr = new KSpreadValue* [count];
00077 for( unsigned i = 0; i < count; i++ )
00078 ptr[i] = (KSpreadValue*)0;
00079 }
00080
00081 KSpreadValue* at( unsigned c, unsigned r )
00082 {
00083 if( !ptr ) return 0;
00084 if( c >= columns ) return 0;
00085 if( r >= rows ) return 0;
00086 return ptr[r*columns+c];
00087 };
00088
00089 void set( unsigned c, unsigned r, KSpreadValue* v )
00090 {
00091 if( !ptr ) return;
00092 if( c >= columns ) return;
00093 if( r >= rows ) return;
00094 delete ptr[r*columns+c];
00095 ptr[r*columns+c] = v;
00096 }
00097
00098 };
00099
00100
00101
00102 class KSpreadValueData
00103 {
00104 public:
00105
00106 KSpreadValue::Type type:4;
00107 KSpreadValue::Format format:4;
00108
00109
00110 unsigned int count:24;
00111
00112 union
00113 {
00114 bool b;
00115 long i;
00116 double f;
00117 QString* ps;
00118 ValueArray* pa;
00119 };
00120
00121
00122 KSpreadValueData(): type( KSpreadValue::Empty ),
00123 format (KSpreadValue::fmt_None), count( 1 ), ps( 0 ) { };
00124
00125
00126 ~KSpreadValueData(){ if( this == s_null ) s_null = 0;
00127 if( type == KSpreadValue::Array ) delete pa;
00128 if( type == KSpreadValue::String ) delete ps;
00129 if( type == KSpreadValue::Error ) delete ps;
00130 }
00131
00132
00133 static KSpreadValueData* null()
00134 { if( !s_null) s_null = new KSpreadValueData; else s_null->ref(); return s_null; }
00135
00136
00137 void ref() { count++; }
00138
00139
00140 void unref()
00141 { --count; if( !count ) delete this; }
00142
00143
00144 bool isNull(){ return this == s_null; }
00145
00147 void setFormatByType ();
00148
00149 private:
00150
00151 static KSpreadValueData* s_null;
00152 };
00153
00154 void KSpreadValueData::setFormatByType ()
00155 {
00156 switch (type) {
00157 case KSpreadValue::Empty:
00158 format = KSpreadValue::fmt_None;
00159 break;
00160 case KSpreadValue::Boolean:
00161 format = KSpreadValue::fmt_Boolean;
00162 break;
00163 case KSpreadValue::Integer:
00164 format = KSpreadValue::fmt_Number;
00165 break;
00166 case KSpreadValue::Float:
00167 format = KSpreadValue::fmt_Number;
00168 break;
00169 case KSpreadValue::String:
00170 format = KSpreadValue::fmt_String;
00171 break;
00172 case KSpreadValue::Array:
00173 format = KSpreadValue::fmt_None;
00174 break;
00175 case KSpreadValue::CellRange:
00176 format = KSpreadValue::fmt_None;
00177 break;
00178 case KSpreadValue::Error:
00179 format = KSpreadValue::fmt_String;
00180 break;
00181 };
00182 }
00183
00184
00185 KSpreadValueData* KSpreadValueData::s_null = 0;
00186
00187
00188 KSpreadValue ks_value_empty;
00189 KSpreadValue ks_error_div0;
00190 KSpreadValue ks_error_na;
00191 KSpreadValue ks_error_name;
00192 KSpreadValue ks_error_null;
00193 KSpreadValue ks_error_num;
00194 KSpreadValue ks_error_ref;
00195 KSpreadValue ks_error_value;
00196
00197
00198 KSpreadValue::KSpreadValue()
00199 {
00200 d = KSpreadValueData::null();
00201 }
00202
00203
00204 KSpreadValue::~KSpreadValue()
00205 {
00206 d->unref();
00207 }
00208
00209
00210 KSpreadValue::KSpreadValue( KSpreadValue::Type _type )
00211 {
00212 d = new KSpreadValueData;
00213 d->type = _type;
00214 d->setFormatByType ();
00215 }
00216
00217
00218 KSpreadValue::KSpreadValue( const KSpreadValue& _value )
00219 {
00220 d = KSpreadValueData::null();
00221 assign( _value );
00222 }
00223
00224
00225 KSpreadValue& KSpreadValue::operator=( const KSpreadValue& _value )
00226 {
00227 return assign( _value );
00228 }
00229
00230
00231 KSpreadValue::KSpreadValue( bool b )
00232 {
00233 d = KSpreadValueData::null();
00234 setValue( b );
00235 }
00236
00237
00238 KSpreadValue::KSpreadValue( long i )
00239 {
00240 d = KSpreadValueData::null();
00241 setValue ( i );
00242 }
00243
00244
00245 KSpreadValue::KSpreadValue( int i )
00246 {
00247 d = KSpreadValueData::null();
00248 setValue ( i );
00249 }
00250
00251
00252 KSpreadValue::KSpreadValue( double f )
00253 {
00254 d = KSpreadValueData::null();
00255 setValue( f );
00256 }
00257
00258
00259 KSpreadValue::KSpreadValue( const QString& s )
00260 {
00261 d = KSpreadValueData::null();
00262 setValue( s );
00263 }
00264
00265
00266 KSpreadValue::KSpreadValue( const QDateTime& dt )
00267 {
00268 d = KSpreadValueData::null();
00269 setValue( dt );
00270 }
00271
00272
00273 KSpreadValue::KSpreadValue( const QTime& dt )
00274 {
00275 d = KSpreadValueData::null();
00276 setValue( dt );
00277 }
00278
00279
00280 KSpreadValue::KSpreadValue( const QDate& dt )
00281 {
00282 d = KSpreadValueData::null();
00283 setValue( dt );
00284 }
00285
00286
00287 KSpreadValue::KSpreadValue( unsigned columns, unsigned rows )
00288 {
00289 d = new KSpreadValueData;
00290 d->type = Array;
00291 d->format = fmt_None;
00292 d->pa = new ValueArray;
00293 d->pa->init( columns, rows );
00294 }
00295
00296
00297
00298 KSpreadValue& KSpreadValue::assign( const KSpreadValue& _value )
00299 {
00300 d->unref();
00301 d = _value.d;
00302 d->ref();
00303 return *this;
00304 }
00305
00306
00307 KSpreadValue::Type KSpreadValue::type() const
00308 {
00309 return d ? d->type : Empty;
00310 }
00311
00312
00313 void KSpreadValue::setValue( bool b )
00314 {
00315 detach();
00316 d->type = Boolean;
00317 d->b = b;
00318 d->format = fmt_Boolean;
00319 }
00320
00321
00322 bool KSpreadValue::asBoolean() const
00323 {
00324 bool result = false;
00325
00326 if( type() == KSpreadValue::Boolean )
00327 result = d->b;
00328
00329 return result;
00330 }
00331
00332
00333 void KSpreadValue::setValue( long i )
00334 {
00335 detach();
00336 d->type = Integer;
00337 d->i = i;
00338 d->format = fmt_Number;
00339 }
00340
00341
00342 void KSpreadValue::setValue( int i )
00343 {
00344 detach();
00345 d->type = Integer;
00346 d->i = static_cast<long>( i );
00347 d->format = fmt_Number;
00348 }
00349
00350
00351 long KSpreadValue::asInteger() const
00352 {
00353 long result = 0;
00354
00355 if( type() == KSpreadValue::Integer )
00356 result = d->i;
00357
00358 if( type() == KSpreadValue::Float )
00359 result = static_cast<int>(d->f);
00360
00361 return result;
00362 }
00363
00364 void KSpreadValue::setValue( const KSpreadValue& v )
00365 {
00366 assign( v );
00367 }
00368
00369
00370 void KSpreadValue::setValue( double f )
00371 {
00372 detach();
00373 d->type = Float;
00374 d->f = f;
00375 d->format = fmt_Number;
00376 }
00377
00378
00379 double KSpreadValue::asFloat() const
00380 {
00381 double result = 0.0;
00382
00383 if( type() == KSpreadValue::Float )
00384 result = d->f;
00385
00386 if( type() == KSpreadValue::Integer )
00387 result = static_cast<double>(d->i);
00388
00389 return result;
00390 }
00391
00392
00393 void KSpreadValue::setValue( const QString& s )
00394 {
00395 detach();
00396 d->type = String;
00397 d->ps = new QString( s );
00398 d->format = fmt_String;
00399 }
00400
00401
00402 QString KSpreadValue::asString() const
00403 {
00404 QString result;
00405
00406 if( type() == KSpreadValue::String )
00407 if( d->ps )
00408 result = QString( *d->ps );
00409
00410 return result;
00411 }
00412
00413
00414 void KSpreadValue::setError( const QString& msg )
00415 {
00416 detach();
00417 d->type = Error;
00418 d->ps = new QString( msg );
00419 }
00420
00421
00422 QString KSpreadValue::errorMessage() const
00423 {
00424 QString result;
00425
00426 if( type() == KSpreadValue::Error )
00427 if( d->ps )
00428 result = QString( *d->ps );
00429
00430 return result;
00431 }
00432
00433
00434
00435
00436 void KSpreadValue::setValue( const QDateTime& dt )
00437 {
00438
00439 QDate refDate( 1899, 12, 31 );
00440 QTime refTime( 0, 0 );
00441
00442 double f = refDate.daysTo( dt.date() ) + 1.0;
00443 f += refTime.secsTo( dt.time() ) / 86400.0;
00444
00445 setValue( f );
00446 d->format = fmt_DateTime;
00447 }
00448
00449 void KSpreadValue::setValue( const QTime& time )
00450 {
00451
00452 QTime refTime( 0, 0 );
00453 double f = refTime.msecsTo( time ) / 86400000.0;
00454
00455 setValue( f );
00456 d->format = fmt_Time;
00457 }
00458
00459 void KSpreadValue::setValue( const QDate& date )
00460 {
00461
00462 QDate refDate = QDate( 1899, 12, 31 );
00463 double f = refDate.daysTo( date ) + 1.0;
00464
00465 setValue( f );
00466 d->format = fmt_Date;
00467 }
00468
00469
00470 QDateTime KSpreadValue::asDateTime() const
00471 {
00472 return QDateTime( asDate(), asTime() );
00473 }
00474
00475
00476 QDate KSpreadValue::asDate() const
00477 {
00478 QDate dt( 1899, 12, 30 );
00479
00480 double f = asFloat();
00481 dt = dt.addDays( (int) f );
00482
00483 return dt;
00484 }
00485
00486
00487 QTime KSpreadValue::asTime() const
00488 {
00489 QTime dt;
00490
00491 double f = asFloat();
00492 dt = dt.addMSecs( qRound( (f-(int)f) * 86400 * 1000 ) );
00493
00494 return dt;
00495 }
00496
00497 KSpreadValue::Format KSpreadValue::format() const
00498 {
00499 return d ? d->format : fmt_None;
00500 }
00501
00502 void KSpreadValue::setFormat (KSpreadValue::Format fmt)
00503 {
00504 d->format = fmt;
00505 }
00506
00507 KSpreadValue KSpreadValue::element( unsigned column, unsigned row ) const
00508 {
00509 if( d->type != Array ) return empty();
00510 if( !d->pa ) return empty();
00511 KSpreadValue* v = d->pa->at( column, row );
00512 return v ? KSpreadValue( *v ) : empty();
00513 }
00514
00515 void KSpreadValue::setElement( unsigned column, unsigned row, const KSpreadValue& v )
00516 {
00517 if( d->type != Array ) return;
00518 if( !d->pa ) return;
00519 detach();
00520 d->pa->set( column, row, new KSpreadValue( v ) );
00521 }
00522
00523 unsigned KSpreadValue::columns() const
00524 {
00525 if( d->type != Array ) return 0;
00526 if( !d->pa ) return 0;
00527 return d->pa->columns;
00528 }
00529
00530 unsigned KSpreadValue::rows() const
00531 {
00532 if( d->type != Array ) return 0;
00533 if( !d->pa ) return 0;
00534 return d->pa->rows;
00535 }
00536
00537
00538 const KSpreadValue& KSpreadValue::empty()
00539 {
00540 return ks_value_empty;
00541 }
00542
00543
00544 const KSpreadValue& KSpreadValue::errorDIV0()
00545 {
00546 if( !ks_error_div0.isError() )
00547 ks_error_div0.setError( "#DIV/0!" );
00548 return ks_error_div0;
00549 }
00550
00551
00552 const KSpreadValue& KSpreadValue::errorNA()
00553 {
00554 if( !ks_error_na.isError() )
00555 ks_error_na.setError( "#N/A" );
00556 return ks_error_na;
00557 }
00558
00559
00560 const KSpreadValue& KSpreadValue::errorNAME()
00561 {
00562 if( !ks_error_name.isError() )
00563 ks_error_name.setError( "#NAME?" );
00564 return ks_error_name;
00565 }
00566
00567
00568 const KSpreadValue& KSpreadValue::errorNUM()
00569 {
00570 if( !ks_error_num.isError() )
00571 ks_error_num.setError( "#NUM!" );
00572 return ks_error_num;
00573 }
00574
00575
00576 const KSpreadValue& KSpreadValue::errorNULL()
00577 {
00578 if( !ks_error_null.isError() )
00579 ks_error_null.setError( "#NULL!" );
00580 return ks_error_null;
00581 }
00582
00583
00584 const KSpreadValue& KSpreadValue::errorREF()
00585 {
00586 if( !ks_error_ref.isError() )
00587 ks_error_ref.setError( "#REF!" );
00588 return ks_error_ref;
00589 }
00590
00591
00592 const KSpreadValue& KSpreadValue::errorVALUE()
00593 {
00594 if( !ks_error_value.isError() )
00595 ks_error_value.setError( "#VALUE!" );
00596 return ks_error_value;
00597 }
00598
00599
00600 void KSpreadValue::detach()
00601 {
00602 if( d->isNull() || ( d->count > 1 ) )
00603 {
00604 KSpreadValueData* n;
00605 n = new KSpreadValueData;
00606
00607 n->type = d->type;
00608 switch( n->type )
00609 {
00610 case Empty: break;
00611 case Boolean: n->b = d->b; break;
00612 case Integer: n->i = d->i; break;
00613 case Float: n->f = d->f; break;
00614 case String: n->ps = new QString( *d->ps ); break;
00615 case Array: n->pa = new ValueArray; *n->pa = (*d->pa); break;
00616 case Error: n->ps = new QString( *d->ps ); break;
00617 default: break;
00618 }
00619
00620 d->unref();
00621 d = n;
00622 }
00623 }
00624
00625 int KSpreadValue::compare( double v1, double v2 )
00626 {
00627 double v3 = v1 - v2;
00628 if( v3 > DBL_EPSILON ) return 1;
00629 if( v3 < -DBL_EPSILON ) return -1;
00630 return 0;
00631 }
00632
00633 bool KSpreadValue::isZero( double v )
00634 {
00635 return fabs( v ) < DBL_EPSILON;
00636 }
00637
00638 bool KSpreadValue::isZero() const
00639 {
00640 if( !isNumber() ) return false;
00641 return isZero( asFloat() );
00642 }
00643
00644 bool KSpreadValue::allowComparison( const KSpreadValue& v ) const
00645 {
00646 KSpreadValue::Type t1 = d->type;
00647 KSpreadValue::Type t2 = v.type();
00648
00649 if( ( t1 == Empty ) && ( t2 == Empty ) ) return true;
00650 if( ( t1 == Empty ) && ( t2 == String ) ) return true;
00651
00652 if( ( t1 == Boolean ) && ( t2 == Boolean ) ) return true;
00653 if( ( t1 == Boolean ) && ( t2 == Integer ) ) return true;
00654 if( ( t1 == Boolean ) && ( t2 == Float ) ) return true;
00655 if( ( t1 == Boolean ) && ( t2 == String ) ) return true;
00656
00657 if( ( t1 == Integer ) && ( t2 == Boolean ) ) return true;
00658 if( ( t1 == Integer ) && ( t2 == Integer ) ) return true;
00659 if( ( t1 == Integer ) && ( t2 == Float ) ) return true;
00660 if( ( t1 == Integer ) && ( t2 == String ) ) return true;
00661
00662 if( ( t1 == Float ) && ( t2 == Boolean ) ) return true;
00663 if( ( t1 == Float ) && ( t2 == Integer ) ) return true;
00664 if( ( t1 == Float ) && ( t2 == Float ) ) return true;
00665 if( ( t1 == Float ) && ( t2 == String ) ) return true;
00666
00667 if( ( t1 == String ) && ( t2 == Empty ) ) return true;
00668 if( ( t1 == String ) && ( t2 == Boolean ) ) return true;
00669 if( ( t1 == String ) && ( t2 == Integer ) ) return true;
00670 if( ( t1 == String ) && ( t2 == Float ) ) return true;
00671 if( ( t1 == String ) && ( t2 == String ) ) return true;
00672
00673 return false;
00674 }
00675
00676
00677 int KSpreadValue::compare( const KSpreadValue& v ) const
00678 {
00679 KSpreadValue::Type t1 = d->type;
00680 KSpreadValue::Type t2 = v.type();
00681
00682
00683 if( ( t1 == Error ) && ( t2 != Error ) )
00684 return -1;
00685 if( ( t2 == Error ) && ( t1 != Error ) )
00686 return 1;
00687
00688
00689 if( ( t1 == Error ) && ( t2 == Error ) )
00690 return errorMessage() != v.errorMessage();
00691
00692
00693 if( ( t1 == Empty ) && ( t2 == Empty ) )
00694 return 0;
00695
00696
00697
00698 if( ( t1 == Empty ) && ( t2 == String ) )
00699 return( v.asString().isEmpty() ) ? 0 : -1;
00700
00701
00702 if( ( t1 == Boolean ) && ( t2 == Boolean ) )
00703 {
00704 bool p = asBoolean();
00705 bool q = v.asBoolean();
00706 if( p ) return q ? 0 : 1;
00707 else return q ? -1 : 0;
00708 }
00709
00710
00711 if( ( t1 == Boolean ) && ( t2 == Integer ) )
00712 return 1;
00713
00714
00715 if( ( t1 == Boolean ) && ( t2 == Float ) )
00716 return 1;
00717
00718
00719 if( ( t1 == Boolean ) && ( t2 == String ) )
00720 return 1;
00721
00722
00723 if( ( t1 == Integer ) && ( t2 == Boolean ) )
00724 return -1;
00725
00726
00727 if( ( t1 == Integer ) && ( t2 == Integer ) )
00728 {
00729 long p = asInteger();
00730 long q = v.asInteger();
00731 return ( p == q ) ? 0 : ( p < q ) ? -1 : 1;
00732 }
00733
00734
00735 if( ( t1 == Integer ) && ( t2 == Float ) )
00736 return compare( asFloat(), v.asFloat() );
00737
00738
00739 if( ( t1 == Integer ) && ( t2 == String ) )
00740 return -1;
00741
00742
00743 if( ( t1 == Float ) && ( t2 == Boolean ) )
00744 return -1;
00745
00746
00747 if( ( t1 == Float ) && ( t2 == Integer ) )
00748 return compare( asFloat(), v.asFloat() );
00749
00750
00751 if( ( t1 == Float ) && ( t2 == Float ) )
00752 return compare( asFloat(), v.asFloat() );
00753
00754
00755 if( ( t1 == Float ) && ( t2 == String ) )
00756 return -1;
00757
00758
00759
00760 if( ( t1 == String ) && ( t2 == Empty ) )
00761 return( asString().isEmpty() ) ? 0 : 1;
00762
00763
00764 if( ( t1 == String ) && ( t2 == Boolean ) )
00765 return -1;
00766
00767
00768 if( ( t1 == String ) && ( t2 == Integer ) )
00769 return 1;
00770
00771
00772 if( ( t1 == String ) && ( t2 == Float ) )
00773 return 1;
00774
00775
00776 if( ( t1 == String ) && ( t2 == String ) )
00777 return asString().compare( v.asString() );
00778
00779
00780 return 0;
00781 }
00782
00783 bool KSpreadValue::equal( const KSpreadValue& v ) const
00784 {
00785 return compare( v ) == 0;
00786 }
00787
00788 bool KSpreadValue::less( const KSpreadValue& v ) const
00789 {
00790 return compare( v ) < 0;
00791 }
00792
00793 bool KSpreadValue::greater( const KSpreadValue& v ) const
00794 {
00795 return compare( v ) > 0;
00796 }
00797
00798 QTextStream& operator<<( QTextStream& ts, KSpreadValue::Type type )
00799 {
00800 switch( type )
00801 {
00802 case KSpreadValue::Empty: ts << "Empty"; break;
00803 case KSpreadValue::Boolean: ts << "Boolean"; break;
00804 case KSpreadValue::Integer: ts << "Integer"; break;
00805 case KSpreadValue::Float: ts << "Float"; break;
00806 case KSpreadValue::String: ts << "String"; break;
00807 case KSpreadValue::Array: ts << "Array"; break;
00808 case KSpreadValue::Error: ts << "Error"; break;
00809 default: ts << "Unknown!"; break;
00810 };
00811 return ts;
00812 }
00813
00814 QTextStream& operator<<( QTextStream& ts, KSpreadValue value )
00815 {
00816 ts << value.type();
00817 switch( value.type() )
00818 {
00819 case KSpreadValue::Empty: break;
00820
00821 case KSpreadValue::Boolean:
00822 ts << ": ";
00823 if (value.asBoolean()) ts << "TRUE";
00824 else ts << "FALSE"; break;
00825
00826 case KSpreadValue::Integer:
00827 ts << ": " << value.asInteger(); break;
00828
00829 case KSpreadValue::Float:
00830 ts << ": " << value.asFloat(); break;
00831
00832 case KSpreadValue::String:
00833 ts << ": " << value.asString(); break;
00834
00835 case KSpreadValue::Error:
00836 ts << "(" << value.errorMessage() << ")"; break;
00837
00838 default: break;
00839 }
00840 return ts;
00841 }
This file is part of the documentation for kspread Library Version 1.4.2.