00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <stdlib.h>
00043 #include <ctype.h>
00044 #include <float.h>
00045 #include <math.h>
00046
00047 #include <qapplication.h>
00048 #include <qpopupmenu.h>
00049 #include <qregexp.h>
00050
00051 #include "kspread_canvas.h"
00052 #include "kspread_condition.h"
00053 #include "kspread_doc.h"
00054 #include "kspread_format.h"
00055 #include "kspread_global.h"
00056 #include "kspread_map.h"
00057 #include "kspread_sheet.h"
00058 #include "kspread_sheetprint.h"
00059 #include "kspread_style.h"
00060 #include "kspread_style_manager.h"
00061 #include "kspread_util.h"
00062 #include "ksploadinginfo.h"
00063 #include "kspread_genvalidationstyle.h"
00064 #include "kspread_locale.h"
00065 #include "kspread_value.h"
00066 #include "kspread_view.h"
00067 #include "kspread_value.h"
00068 #include "formula.h"
00069 #include "selection.h"
00070 #include "valueconverter.h"
00071 #include "valueformatter.h"
00072 #include "valueparser.h"
00073
00074 #include <KoStyleStack.h>
00075 #include <KoRect.h>
00076 #include <KoXmlNS.h>
00077 #include <KoDom.h>
00078 #include <KoXmlWriter.h>
00079 #include <KoOasisStyles.h>
00080
00081 #include <kmessagebox.h>
00082
00083 #include <kdebug.h>
00084
00085 using namespace KSpread;
00086
00087 #define BORDER_SPACE 1
00088
00089
00094 namespace Cell_LNS
00095 {
00096 QChar decimal_point = '\0';
00097 }
00098
00099 using namespace Cell_LNS;
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 class Cell::Extra
00113 {
00114 public:
00115 Extra() {}
00116
00117
00118 QString link;
00119
00120
00121 int mergedXCells;
00122 int mergedYCells;
00123
00124
00125 int extraXCells;
00126 int extraYCells;
00127
00128
00129
00130
00131 double extraWidth;
00132 double extraHeight;
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 QValueList<Cell*> obscuringCells;
00143
00144
00145 Conditions *conditions;
00146 Validity *validity;
00147
00148
00149 int nbLines;
00150
00151 private:
00152
00153 Extra& operator=( const Extra& );
00154 };
00155
00156
00157 class Cell::Private
00158 {
00159 public:
00160
00161 Private();
00162 ~Private();
00163
00164 public:
00165
00166
00167
00168
00169 int row;
00170 int column;
00171
00172
00173 Value value;
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 QString strText;
00196
00197
00198
00199
00200
00201 QString strOutText;
00202
00203
00204 KSpread::Formula *formula;
00205
00206
00207
00208 double textX;
00209 double textY;
00210 double textWidth;
00211 double textHeight;
00212
00213
00214 int fmAscent;
00215
00216
00217
00218 Cell *nextCell;
00219 Cell *previousCell;
00220
00221 bool hasExtra() const { return (cellExtra != 0); };
00222 Extra *extra();
00223
00224 Format *format;
00225 Q_UINT32 flags;
00226
00227 private:
00228
00229 Extra *cellExtra;
00230 };
00231
00232
00233 Cell::Private::Private()
00234 {
00235
00236 row = 0;
00237 column = 0;
00238 value = Value::empty();
00239 formula = 0;
00240
00241
00242 textX = 0.0;
00243 textY = 0.0;
00244 textWidth = 0.0;
00245 textHeight = 0.0;
00246 fmAscent = 0;
00247
00248 nextCell = 0;
00249 previousCell = 0;
00250
00251
00252 cellExtra = 0;
00253 format = 0;
00254 flags = 0;
00255 }
00256
00257
00258 Cell::Private::~Private()
00259 {
00260 delete cellExtra;
00261 delete formula;
00262 }
00263
00264
00265 Cell::Extra* Cell::Private::extra()
00266 {
00267 if ( !cellExtra ) {
00268 cellExtra = new Extra;
00269 cellExtra->conditions = 0;
00270 cellExtra->validity = 0;
00271
00272 cellExtra->mergedXCells = 0;
00273 cellExtra->mergedYCells = 0;
00274 cellExtra->extraXCells = 0;
00275 cellExtra->extraYCells = 0;
00276 cellExtra->extraWidth = 0.0;
00277 cellExtra->extraHeight = 0.0;
00278 cellExtra->nbLines = 0;
00279
00280 }
00281
00282 return cellExtra;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 Cell::Cell( Sheet * _sheet, int _column, int _row )
00294 {
00295 d = new Private;
00296 d->row = _row;
00297 d->column = _column;
00298 d->format = new Format(_sheet, _sheet->doc()->styleManager()->defaultStyle());
00299 d->format->setCell(this);
00300 clearAllErrors();
00301 }
00302
00303
00304 Cell::Cell( Sheet * _sheet, Style * _style, int _column, int _row )
00305 {
00306 d = new Private;
00307 d->row = _row;
00308 d->column = _column;
00309 d->format = new Format( _sheet, _style );
00310 d->format->setCell(this);
00311
00312 clearAllErrors();
00313 }
00314
00315 Format* Cell::format() const
00316 {
00317 return d->format;
00318 }
00319
00320
00321 Sheet * Cell::sheet() const
00322 {
00323 return d->format->sheet();
00324 }
00325
00326
00327 bool Cell::isDefault() const
00328 {
00329 return ( d->column == 0 );
00330 }
00331
00332
00333 int Cell::row() const
00334 {
00335
00336
00337
00338
00339 if ( isDefault() )
00340 {
00341 kdWarning(36001) << "Error: Calling Cell::row() for default cell" << endl;
00342 return 0;
00343 }
00344
00345 return d->row;
00346 }
00347
00348
00349
00350
00351 int Cell::column() const
00352 {
00353
00354
00355
00356 if ( isDefault() )
00357 {
00358 kdWarning(36001) << "Error: Calling Cell::column() for default cell" << endl;
00359 return 0;
00360 }
00361 return d->column;
00362 }
00363
00364
00365
00366
00367
00368 QString Cell::name() const
00369 {
00370 return name( d->column, d->row );
00371 }
00372
00373
00374
00375
00376 QString Cell::name( int col, int row )
00377 {
00378 return columnName( col ) + QString::number( row );
00379 }
00380
00381
00382
00383
00384
00385 QString Cell::fullName() const
00386 {
00387 return fullName( sheet(), d->column, d->row );
00388 }
00389
00390
00391
00392
00393 QString Cell::fullName( const Sheet* s, int col, int row )
00394 {
00395 return s->sheetName() + "!" + name( col, row );
00396 }
00397
00398
00399
00400
00401 QString Cell::columnName() const
00402 {
00403 return columnName( d->column );
00404 }
00405
00406 KLocale* Cell::locale() const
00407 {
00408 return d->format->sheet()->doc()->locale();
00409 }
00410
00411
00412
00413 QString Cell::columnName( uint column )
00414 {
00415 QString str;
00416 unsigned digits = 1;
00417 unsigned offset = 0;
00418
00419 column--;
00420
00421 if( column > 4058115285U ) return QString("@@@");
00422
00423 for( unsigned limit = 26; column >= limit+offset; limit *= 26, digits++ )
00424 offset += limit;
00425
00426 for( unsigned c = column - offset; digits; --digits, c/=26 )
00427 str.prepend( QChar( 'A' + (c%26) ) );
00428
00429 return str;
00430 }
00431
00432
00433
00434
00435 bool Cell::isFormula() const
00436 {
00437 return d->strText[0] == '=';
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 QString Cell::text() const
00448 {
00449 return d->strText;
00450 }
00451
00452
00453
00454
00455
00456
00457 QString Cell::strOutText() const
00458 {
00459 return d->strOutText;
00460 }
00461
00462 Formula *Cell::formula () const
00463 {
00464 return d->formula;
00465 }
00466
00467
00468
00469
00470 const Value Cell::value() const
00471 {
00472 return d->value;
00473 }
00474
00475
00476
00477
00478
00479
00480
00481
00482 void Cell::setValue( const Value& v )
00483 {
00484 if (v.type() != Value::Error)
00485 clearAllErrors();
00486
00487
00488
00489
00490
00491
00492
00493 if ( ( d->value == v ) && ( !isFormula() ) )
00494 return;
00495
00496 d->value = v;
00497
00498 setFlag(Flag_LayoutDirty);
00499 setFlag(Flag_TextFormatDirty);
00500
00501
00502 setOutputText();
00503
00504
00505 if (d->value.type() == Value::Error)
00506 d->strOutText = d->value.errorMessage ();
00507
00508
00509 valueChanged ();
00510
00511 if ( !format()->sheet()->isLoading() )
00512 format()->sheet()->setRegionPaintDirty(cellRect());
00513 }
00514
00515 void Cell::setCellValue (const Value &v, FormatType fmtType, const QString &txt)
00516 {
00517 if (!txt.isEmpty())
00518 d->strText = txt;
00519 else
00520 d->strText = sheet()->doc()->converter()->asString (v).asString();
00521 if (fmtType != No_format)
00522 format()->setFormatType (fmtType);
00523 setValue (v);
00524 }
00525
00526
00527
00528
00529 Cell* Cell::previousCell() const
00530 {
00531 return d->previousCell;
00532 }
00533
00534 Cell* Cell::nextCell() const
00535 {
00536 return d->nextCell;
00537 }
00538
00539 void Cell::setPreviousCell( Cell* c )
00540 {
00541 d->previousCell = c;
00542 }
00543
00544 void Cell::setNextCell( Cell* c )
00545 {
00546 d->nextCell = c;
00547 }
00548
00549 Validity* Cell::getValidity( int newStruct )
00550 {
00551 if ( (!newStruct) && (!d->hasExtra()))
00552
00553 return 0;
00554
00555 if( ( d->extra()->validity == 0 ) && ( newStruct == -1 ) )
00556 d->extra()->validity = new Validity;
00557 return d->extra()->validity;
00558 }
00559
00560 void Cell::removeValidity()
00561 {
00562 if (!d->hasExtra())
00563 return;
00564
00565 delete d->extra()->validity;
00566 d->extra()->validity = 0;
00567 }
00568
00569
00570 void Cell::copyFormat( const int column , const int row )
00571 {
00572 const Cell * cell = format()->sheet()->cellAt( column , row );
00573
00574 copyFormat( cell );
00575 }
00576
00577 void Cell::copyFormat( const Cell* cell )
00578 {
00579
00580 Q_ASSERT(cell);
00581
00582 d->value.setFormat(cell->d->value.format());
00583 format()->copy(*(cell->format()));
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 QValueList<Conditional> conditionList = cell->conditionList();
00616 if (d->hasExtra())
00617 delete d->extra()->conditions;
00618 if ( cell->d->hasExtra() && cell->d->extra()->conditions )
00619 setConditionList( conditionList );
00620 else
00621 if (d->hasExtra())
00622 d->extra()->conditions = 0;
00623
00624
00625 }
00626
00627 void Cell::copyAll( Cell *cell )
00628 {
00629 Q_ASSERT( !isDefault() );
00630 copyFormat( cell );
00631 copyContent( cell );
00632 }
00633
00634 void Cell::copyContent( const Cell* cell )
00635 {
00636 Q_ASSERT( !isDefault() );
00637
00638 if (cell->isFormula() && cell->column() > 0 && cell->row() > 0)
00639 {
00640
00641
00642 QString d = cell->encodeFormula();
00643 setCellText( cell->decodeFormula( d ) );
00644 }
00645 else
00646 setCellText( cell->text() );
00647
00648 }
00649
00650 void Cell::defaultStyle()
00651 {
00652 format()->defaultStyleFormat();
00653
00654 if (!d->hasExtra())
00655 return;
00656
00657 if ( d->extra()->conditions )
00658 {
00659 delete d->extra()->conditions;
00660 d->extra()->conditions = 0;
00661 }
00662
00663 delete d->extra()->validity;
00664 d->extra()->validity = 0L;
00665 }
00666
00667
00668
00669
00670
00671 void Cell::mergeCells( int _col, int _row, int _x, int _y )
00672 {
00673
00674 int extraXCells = d->hasExtra() ? d->extra()->extraXCells : 0;
00675 int extraYCells = d->hasExtra() ? d->extra()->extraYCells : 0;
00676 for ( int x = _col; x <= _col + extraXCells; ++x ) {
00677 for ( int y = _row; y <= _row + extraYCells; ++y ) {
00678 if ( x != _col || y != _row )
00679 format()->sheet()->nonDefaultCell( x, y )->unobscure(this);
00680 }
00681 }
00682
00683
00684 if ( _x == 0 && _y == 0 ) {
00685 clearFlag( Flag_Merged );
00686 if (d->hasExtra()) {
00687 d->extra()->extraXCells = 0;
00688 d->extra()->extraYCells = 0;
00689 d->extra()->extraWidth = 0.0;
00690 d->extra()->extraHeight = 0.0;
00691 d->extra()->mergedXCells = 0;
00692 d->extra()->mergedYCells = 0;
00693 }
00694
00695
00696 setFlag( Flag_LayoutDirty );
00697 return;
00698 }
00699
00700
00701 setFlag(Flag_Merged);
00702 d->extra()->extraXCells = _x;
00703 d->extra()->extraYCells = _y;
00704 d->extra()->mergedXCells = _x;
00705 d->extra()->mergedYCells = _y;
00706
00707
00708 for ( int x = _col; x <= _col + _x; ++x ) {
00709 for ( int y = _row; y <= _row + _y; ++y ) {
00710 if ( x != _col || y != _row )
00711 format()->sheet()->nonDefaultCell( x, y )->obscure( this, true );
00712 }
00713 }
00714
00715
00716 setFlag( Flag_LayoutDirty );
00717 }
00718
00719 void Cell::move( int col, int row )
00720 {
00721 setLayoutDirtyFlag();
00722 setCalcDirtyFlag();
00723 setDisplayDirtyFlag();
00724
00725
00726
00727
00728 if (d->hasExtra())
00729 d->extra()->obscuringCells.clear();
00730
00731
00732 int extraXCells = d->hasExtra() ? d->extra()->extraXCells : 0;
00733 int extraYCells = d->hasExtra() ? d->extra()->extraYCells : 0;
00734 for( int x = d->column; x <= d->column + extraXCells; ++x )
00735 for( int y = d->row; y <= d->row + extraYCells; ++y )
00736 if ( x != d->column || y != d->row )
00737 {
00738 Cell *cell = format()->sheet()->nonDefaultCell( x, y );
00739 cell->unobscure(this);
00740 }
00741
00742 d->column = col;
00743 d->row = row;
00744
00745 if (d->hasExtra())
00746 {
00747
00748
00749 d->extra()->mergedXCells = 0;
00750 d->extra()->mergedYCells = 0;
00751 }
00752
00753
00754 valueChanged ();
00755 }
00756
00757 void Cell::setLayoutDirtyFlag( bool format )
00758 {
00759 setFlag( Flag_LayoutDirty );
00760 if ( format )
00761 setFlag( Flag_TextFormatDirty );
00762
00763 if (!d->hasExtra())
00764 return;
00765
00766 QValueList<Cell*>::iterator it = d->extra()->obscuringCells.begin();
00767 QValueList<Cell*>::iterator end = d->extra()->obscuringCells.end();
00768 for ( ; it != end; ++it ) {
00769 (*it)->setLayoutDirtyFlag( format );
00770 }
00771 }
00772
00773 bool Cell::needsPrinting() const
00774 {
00775 if ( isDefault() )
00776 return false;
00777
00778 if ( !d->strText.stripWhiteSpace().isEmpty() ) {
00779 return true;
00780 }
00781
00782
00783 if ( format()->hasProperty( Format::PTopBorder )
00784 || format()->hasProperty( Format::PLeftBorder )
00785 || format()->hasProperty( Format::PRightBorder )
00786 || format()->hasProperty( Format::PBottomBorder )
00787 || format()->hasProperty( Format::PFallDiagonal )
00788 || format()->hasProperty( Format::PGoUpDiagonal ) ) {
00789 return true;
00790 }
00791
00792
00793 if ( format()->hasProperty( Format::PBackgroundBrush ) ) {
00794
00795 const QBrush& brush=backGroundBrush(column(),row());
00796
00797
00798
00799 if ( (brush.style() != Qt::NoBrush) &&
00800 (brush.color() != Qt::white || brush.pixmap()) )
00801 return true;
00802
00803 }
00804
00805 if ( format()->hasProperty( Format::PBackgroundColor ) ) {
00806 kdDebug() << "needsPrinting: Has background colour" << endl;
00807 QColor backgroundColor=bgColor(column(),row());
00808
00809
00810 if (backgroundColor != Qt::white)
00811 return true;
00812 }
00813
00814 return false;
00815 }
00816
00817 bool Cell::isEmpty() const
00818 {
00819 return isDefault() || d->strText.isEmpty();
00820 }
00821
00822
00823
00824
00825 bool Cell::isObscured() const
00826 {
00827 if (!d->hasExtra())
00828 return false;
00829
00830 return !( d->extra()->obscuringCells.isEmpty() );
00831 }
00832
00833
00834
00835
00836
00837 bool Cell::isPartOfMerged() const
00838 {
00839 if (!d->hasExtra())
00840 return false;
00841
00842 QValueList<Cell*>::const_iterator it = d->extra()->obscuringCells.begin();
00843 QValueList<Cell*>::const_iterator end = d->extra()->obscuringCells.end();
00844 for ( ; it != end; ++it ) {
00845 Cell *cell = *it;
00846
00847 if (cell->doesMergeCells()) {
00848
00849
00850
00851
00852 if (column() <= cell->column() + cell->d->extra()->mergedXCells
00853 && row() <= cell->row() + cell->mergedYCells() )
00854 return true;
00855 }
00856 }
00857
00858 return false;
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 Cell *Cell::ultimateObscuringCell() const
00871 {
00872 if (!d->hasExtra())
00873 return (Cell *) this;
00874
00875 else if (d->extra()->obscuringCells.isEmpty())
00876 return (Cell *) this;
00877
00878 else
00879 return d->extra()->obscuringCells.first();
00880
00881 #if 0
00882 QValueList<Cell*>::const_iterator it = d->extra()->obscuringCells.begin();
00883 QValueList<Cell*>::const_iterator end = d->extra()->obscuringCells.end();
00884 for ( ; it != end; ++it ) {
00885 Cell *cell = *it;
00886
00887 if (cell->doesMergeCells()) {
00888
00889
00890
00891
00892 if (column() <= cell->column() + cell->d->extra()->mergedXCells
00893 && row() <= cell->row() + cell->mergedYCells() )
00894 return true;
00895 }
00896 }
00897
00898 return false;
00899 #endif
00900 }
00901
00902
00903 QValueList<Cell*> Cell::obscuringCells() const
00904 {
00905 if (!d->hasExtra())
00906 {
00907 QValueList<Cell*> empty;
00908 return empty;
00909 }
00910 return d->extra()->obscuringCells;
00911 }
00912
00913 void Cell::clearObscuringCells()
00914 {
00915 if (!d->hasExtra())
00916 return;
00917 d->extra()->obscuringCells.clear();
00918 }
00919
00920 void Cell::obscure( Cell *cell, bool isForcing )
00921 {
00922 if (d->hasExtra())
00923 {
00924 d->extra()->obscuringCells.remove( cell );
00925 cell->clearObscuringCells();
00926 }
00927 if ( isForcing )
00928 {
00929 d->extra()->obscuringCells.prepend( cell );
00930 }
00931 else
00932 {
00933 d->extra()->obscuringCells.append( cell );
00934 }
00935 setFlag(Flag_LayoutDirty);
00936 format()->sheet()->setRegionPaintDirty( cellRect() );
00937 }
00938
00939 void Cell::unobscure( Cell * cell )
00940 {
00941 if (d->hasExtra())
00942 d->extra()->obscuringCells.remove( cell );
00943 setFlag( Flag_LayoutDirty );
00944 format()->sheet()->setRegionPaintDirty( cellRect() );
00945 }
00946
00947 QString Cell::encodeFormula( bool _era, int _col, int _row ) const
00948 {
00949 if ( _col == -1 )
00950 _col = d->column;
00951 if ( _row == -1 )
00952 _row = d->row;
00953
00954 QString erg = "";
00955
00956 if(d->strText.isEmpty())
00957 return d->strText;
00958
00959 bool fix1 = false;
00960 bool fix2 = false;
00961 bool onNumber = false;
00962 unsigned int pos = 0;
00963 const unsigned int length = d->strText.length();
00964
00965
00966
00967 while ( pos < length )
00968 {
00969 if ( d->strText[pos] == '"' )
00970 {
00971 erg += d->strText[pos++];
00972 while ( pos < length && d->strText[pos] != '"' )
00973 {
00974 erg += d->strText[pos++];
00975
00976 if ( pos < length && d->strText[pos] == '\\' && d->strText[pos+1] == '"' )
00977 {
00978 erg += d->strText[pos++];
00979 erg += d->strText[pos++];
00980 }
00981 }
00982 if ( pos < length )
00983 erg += d->strText[pos++];
00984
00985 onNumber = false;
00986 }
00987 else if ( d->strText[pos].isDigit() )
00988 {
00989 erg += d->strText[pos++];
00990 fix1 = fix2 = false;
00991 onNumber = true;
00992 }
00993 else if ( d->strText[pos] != '$' && !d->strText[pos].isLetter() )
00994 {
00995 erg += d->strText[pos++];
00996 fix1 = fix2 = false;
00997 onNumber = false;
00998 }
00999 else
01000 {
01001 QString tmp = "";
01002 if ( d->strText[pos] == '$' )
01003 {
01004 tmp = "$";
01005 pos++;
01006 fix1 = true;
01007 }
01008 if ( d->strText[pos].isLetter() )
01009 {
01010 QString buffer;
01011 unsigned int pos2 = 0;
01012 while ( pos < length && d->strText[pos].isLetter() )
01013 {
01014 tmp += d->strText[pos];
01015 buffer[pos2++] = d->strText[pos++];
01016 }
01017 if ( d->strText[pos] == '$' )
01018 {
01019 tmp += "$";
01020 pos++;
01021 fix2 = true;
01022 }
01023 if ( d->strText[pos].isDigit() )
01024 {
01025 const unsigned int oldPos = pos;
01026 while ( pos < length && d->strText[pos].isDigit() ) ++pos;
01027 int row = 0;
01028 if ( pos != oldPos )
01029 row = d->strText.mid(oldPos, pos-oldPos).toInt();
01030
01031
01032
01033 if ( ( d->strText[pos] == '!' ) ||
01034 d->strText[pos].isLetter() ||
01035 onNumber )
01036 {
01037 erg += tmp;
01038 fix1 = fix2 = false;
01039 pos = oldPos;
01040 }
01041 else
01042 {
01043
01044 int col = 0;
01045 col = util_decodeColumnLabelText( buffer );
01046 if ( fix1 )
01047 erg += QString( "$%1" ).arg( col );
01048 else
01049 if (_era)
01050 erg += QChar(0xA7) + QString( "%1" ).arg( col );
01051 else
01052 erg += QString( "#%1" ).arg( col - _col );
01053
01054 if ( fix2 )
01055 erg += QString( "$%1#").arg( row );
01056 else
01057 if (_era)
01058 erg += QChar(0xA7) + QString( "%1#" ).arg( row );
01059 else
01060 erg += QString( "#%1#" ).arg( row - _row );
01061 }
01062 }
01063 else
01064 {
01065 erg += tmp;
01066 fix1 = fix2 = false;
01067 }
01068 }
01069 else
01070 {
01071 erg += tmp;
01072 fix1 = false;
01073 }
01074 onNumber = false;
01075 }
01076 }
01077
01078 return erg;
01079 }
01080
01081 QString Cell::decodeFormula( const QString &_text, int _col, int _row) const
01082 {
01083 if ( _col == -1 )
01084 _col = d->column;
01085 if ( _row == -1 )
01086 _row = d->row;
01087
01088 QString erg = "";
01089 unsigned int pos = 0;
01090 const unsigned int length = _text.length();
01091
01092 if ( _text.isEmpty() )
01093 return QString();
01094
01095 while ( pos < length )
01096 {
01097 if ( _text[pos] == '"' )
01098 {
01099 erg += _text[pos++];
01100 while ( pos < length && _text[pos] != '"' )
01101 {
01102 erg += _text[pos++];
01103
01104 if ( pos < length && _text[pos] == '\\' && _text[pos+1] == '"' )
01105 {
01106 erg += _text[pos++];
01107 erg += _text[pos++];
01108 }
01109 }
01110 if ( pos < length )
01111 erg += _text[pos++];
01112 }
01113 else if ( _text[pos] == '#' || _text[pos] == '$' || _text[pos] == QChar(0xA7))
01114 {
01115 bool abs1 = false;
01116 bool abs2 = false;
01117 bool era1 = false;
01118 bool era2 = false;
01119
01120 QChar _t = _text[pos++];
01121 if ( _t == '$' )
01122 abs1 = true;
01123 else if ( _t == QChar(0xA7) )
01124 era1 = true;
01125
01126 int col = 0;
01127 unsigned int oldPos = pos;
01128 while ( pos < length && ( _text[pos].isDigit() || _text[pos] == '-' ) ) ++pos;
01129 if ( pos != oldPos )
01130 col = _text.mid(oldPos, pos-oldPos).toInt();
01131 if ( !abs1 && !era1 )
01132 col += _col;
01133
01134
01135 _t = _text[pos++];
01136 if ( _t == '$' )
01137 abs2 = true;
01138 else if ( _t == QChar(0xA7) )
01139 era2 = true;
01140
01141 int row = 0;
01142 oldPos = pos;
01143 while ( pos < length && ( _text[pos].isDigit() || _text[pos] == '-' ) ) ++pos;
01144 if ( pos != oldPos )
01145 row = _text.mid(oldPos, pos-oldPos).toInt();
01146 if ( !abs2 && !era2)
01147 row += _row;
01148
01149 ++pos;
01150 if ( row < 1 || col < 1 || row > KS_rowMax || col > KS_colMax )
01151 {
01152 kdDebug(36001) << "Cell::decodeFormula: row or column out of range (col: " << col << " | row: " << row << ")" << endl;
01153 erg = "=\"#### " + i18n("REFERENCE TO COLUMN OR ROW IS OUT OF RANGE") + "\"";
01154 return erg;
01155 }
01156 if ( abs1 )
01157 erg += "$";
01158 erg += Cell::columnName(col);
01159
01160 if ( abs2 )
01161 erg += "$";
01162 erg += QString::number( row );
01163 }
01164 else
01165 erg += _text[pos++];
01166 }
01167
01168 return erg;
01169 }
01170
01171
01172 void Cell::freeAllObscuredCells()
01173 {
01174
01175
01176
01177
01178 if (!d->hasExtra())
01179 return;
01180
01181 for ( int x = d->column + d->extra()->mergedXCells;
01182 x <= d->column + d->extra()->extraXCells; ++x ) {
01183 for ( int y = d->row + d->extra()->mergedYCells;
01184 y <= d->row + d->extra()->extraYCells; ++y ) {
01185 if ( x != d->column || y != d->row ) {
01186 Cell *cell = format()->sheet()->cellAt( x, y );
01187 cell->unobscure(this);
01188 }
01189 }
01190 }
01191
01192 d->extra()->extraXCells = d->extra()->mergedXCells;
01193 d->extra()->extraYCells = d->extra()->mergedYCells;
01194
01195 }
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216 void Cell::makeLayout( QPainter &_painter, int _col, int _row )
01217 {
01218
01219
01220
01221
01222
01223
01224
01225 if ( !testFlag( Flag_LayoutDirty ) )
01226 return;
01227
01228
01229 if (d->hasExtra())
01230 d->extra()->nbLines = 0;
01231 clearFlag( Flag_CellTooShortX );
01232 clearFlag( Flag_CellTooShortY );
01233
01234
01235
01236 freeAllObscuredCells();
01237 if (d->hasExtra())
01238 mergeCells( d->column, d->row,
01239 d->extra()->mergedXCells, d->extra()->mergedYCells );
01240
01241
01242
01243 ColumnFormat *cl1 = format()->sheet()->columnFormat( _col );
01244 RowFormat *rl1 = format()->sheet()->rowFormat( _row );
01245 if ( cl1->isHide()
01246 || ( rl1->dblHeight() <= format()->sheet()->doc()->unzoomItY( 2 ) ) ) {
01247 clearFlag( Flag_LayoutDirty );
01248 return;
01249 }
01250
01251
01252 setOutputText();
01253
01254
01255
01256 if ( d->strOutText.isEmpty() ) {
01257 d->strOutText = QString::null;
01258
01259 if ( isDefault() ) {
01260 clearFlag( Flag_LayoutDirty );
01261 return;
01262 }
01263 }
01264
01265
01266
01267
01268
01269
01270
01271
01272 applyZoomedFont( _painter, _col, _row );
01273 textSize( _painter );
01274
01275
01276
01277
01278 RowFormat *rl = format()->sheet()->rowFormat( d->row );
01279 ColumnFormat *cl = format()->sheet()->columnFormat( d->column );
01280
01281 double width = cl->dblWidth();
01282 double height = rl->dblHeight();
01283
01284
01285 if ( testFlag( Flag_Merged ) ) {
01286 int extraXCells = d->hasExtra() ? d->extra()->extraXCells : 0;
01287 int extraYCells = d->hasExtra() ? d->extra()->extraYCells : 0;
01288
01289
01290
01291
01292 for ( int x = _col + 1; x <= _col + extraXCells; x++ )
01293 width += format()->sheet()->columnFormat( x )->dblWidth();
01294
01295 for ( int y = _row + 1; y <= _row + extraYCells; y++ )
01296 height += format()->sheet()->rowFormat( y )->dblHeight();
01297 }
01298
01299
01300
01301
01302 if (d->hasExtra()) {
01303 d->extra()->extraWidth = width;
01304 d->extra()->extraHeight = height;
01305 }
01306
01307 QFontMetrics fm = _painter.fontMetrics();
01308 d->fmAscent = fm.ascent();
01309
01310
01311
01312
01313
01314
01315
01316
01317 int lines = 1;
01318 if ( d->textWidth > (width - 2 * BORDER_SPACE
01319 - format()->leftBorderWidth( _col, _row )
01320 - format()->rightBorderWidth( _col, _row ) )
01321 && format()->multiRow( _col, _row ) )
01322 {
01323
01324
01325
01326
01327 QString o = d->strOutText;
01328
01329
01330
01331
01332 if ( o.find(' ') != -1 )
01333 {
01334 d->strOutText = "";
01335
01336
01337 o += ' ';
01338
01339 int start = 0;
01340 int breakpos = 0;
01341 int pos1 = 0;
01342 int availableWidth = (int) ( width - 2 * BORDER_SPACE
01343 - format()->leftBorderWidth( _col, _row )
01344 - format()->rightBorderWidth( _col, _row ) );
01345
01346 do {
01347
01348 breakpos = o.find( ' ', breakpos );
01349 int linefeed = o.find( '\n', pos1 );
01350
01351
01352
01353
01354 int work_breakpos = breakpos;
01355 if (pos1 < linefeed && linefeed < breakpos)
01356 work_breakpos = linefeed;
01357
01358 double lineWidth = format()->sheet()->doc()
01359 ->unzoomItX( fm.width( d->strOutText.mid( start, (pos1 - start) )
01360 + o.mid( pos1, work_breakpos - pos1 ) ) );
01361
01362
01363 if (breakpos > linefeed && linefeed > 0)
01364 {
01365
01366 start = linefeed;
01367 lines++;
01368 }
01369
01370 if ( lineWidth <= availableWidth ) {
01371
01372 d->strOutText += o.mid( pos1, breakpos - pos1 );
01373 pos1 = breakpos;
01374 }
01375 else {
01376
01377 if ( o.at( pos1 ) == ' ' )
01378 pos1++;
01379
01380 if ( pos1 != 0 && breakpos != -1 ) {
01381 d->strOutText += "\n" + o.mid( pos1, breakpos - pos1 );
01382 lines++;
01383 }
01384 else
01385 d->strOutText += o.mid( pos1, breakpos - pos1 );
01386
01387 start = pos1;
01388 pos1 = breakpos;
01389 }
01390
01391 breakpos++;
01392 } while( o.find( ' ', breakpos ) != -1 );
01393 }
01394 else
01395 {
01396 lines = o.contains('\n');
01397 }
01398
01399 d->textHeight *= lines;
01400 if (lines > 1)
01401 d->extra()->nbLines = lines;
01402
01403 d->textX = 0.0;
01404
01405
01406
01407 QString t;
01408 int i;
01409 int pos = 0;
01410 d->textWidth = 0.0;
01411 do {
01412 i = d->strOutText.find( "\n", pos );
01413
01414 if ( i == -1 )
01415 t = d->strOutText.mid( pos, d->strOutText.length() - pos );
01416 else {
01417 t = d->strOutText.mid( pos, i - pos );
01418 pos = i + 1;
01419 }
01420
01421 double tw = format()->sheet()->doc()->unzoomItX( fm.width( t ) );
01422 if ( tw > d->textWidth )
01423 d->textWidth = tw;
01424 } while ( i != -1 );
01425 }
01426
01427
01428 offsetAlign( _col, _row );
01429
01430 int a = effAlignX();
01431
01432
01433 double indent = 0.0;
01434 if ( a == Format::Left && !isEmpty() )
01435 indent = format()->getIndent( _col, _row );
01436
01437
01438
01439 if ( format()->verticalText( _col, _row ) || format()->getAngle( _col, _row ) != 0 ) {
01440
01441
01442 if ( d->textHeight >= height )
01443 setFlag( Flag_CellTooShortX );
01444 }
01445
01446
01447
01448
01449
01450
01451
01452 if ( d->textWidth + indent > ( width - 2 * BORDER_SPACE
01453 - format()->leftBorderWidth( _col, _row )
01454 - format()->rightBorderWidth( _col, _row ) )
01455 && ( !d->hasExtra() || d->extra()->mergedYCells == 0 ) )
01456 {
01457 int c = d->column;
01458
01459
01460 int end = 0;
01461 while ( !end ) {
01462 ColumnFormat *cl2 = format()->sheet()->columnFormat( c + 1 );
01463 Cell *cell = format()->sheet()->visibleCellAt( c + 1, d->row );
01464
01465 if ( cell->isEmpty() ) {
01466 width += cl2->dblWidth() - 1;
01467 c++;
01468
01469
01470 if ( d->textWidth + indent <= ( width - 2 * BORDER_SPACE
01471 - format()->leftBorderWidth( _col, _row )
01472 - format()->rightBorderWidth( _col, _row ) ) )
01473 end = 1;
01474 }
01475 else
01476
01477 end = -1;
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492 if ( format()->align( _col, _row ) == Format::Left
01493 || ( format()->align( _col, _row ) == Format::Undefined
01494 && !value().isNumber() ) )
01495 {
01496 if ( c - d->column > d->extra()->mergedXCells ) {
01497 d->extra()->extraXCells = c - d->column;
01498 d->extra()->extraWidth = width;
01499 for ( int i = d->column + 1; i <= c; ++i ) {
01500 Cell *cell = format()->sheet()->nonDefaultCell( i, d->row );
01501 cell->obscure( this );
01502 }
01503
01504
01505 if ( end == -1 )
01506 setFlag( Flag_CellTooShortX );
01507 }
01508 else
01509 setFlag( Flag_CellTooShortX );
01510 }
01511 else
01512 setFlag( Flag_CellTooShortX );
01513 }
01514
01515
01516
01517
01518
01519 if ( format()->multiRow( _col, _row )
01520 && d->textHeight > ( height - 2 * BORDER_SPACE
01521 - format()->topBorderWidth( _col, _row )
01522 - format()->bottomBorderWidth( _col, _row ) ) )
01523 {
01524 int r = d->row;
01525 int end = 0;
01526
01527
01528 while ( !end ) {
01529 RowFormat *rl2 = format()->sheet()->rowFormat( r + 1 );
01530 Cell *cell = format()->sheet()->visibleCellAt( d->column, r + 1 );
01531
01532 if ( cell->isEmpty() ) {
01533 height += rl2->dblHeight() - 1.0;
01534 r++;
01535
01536
01537 if ( d->textHeight <= ( height - 2 * BORDER_SPACE
01538 - format()->topBorderWidth( _col, _row )
01539 - format()->bottomBorderWidth( _col, _row ) ) )
01540 end = 1;
01541 }
01542 else
01543
01544 end = -1;
01545 }
01546
01547
01548 if ( r - d->row > d->extra()->mergedYCells )
01549 {
01550 d->extra()->extraYCells = r - d->row;
01551 d->extra()->extraHeight = height;
01552
01553 for ( int i = d->row + 1; i <= r; ++i )
01554 {
01555 Cell *cell = format()->sheet()->nonDefaultCell( d->column, i );
01556 cell->obscure( this );
01557 }
01558
01559
01560 if ( end == -1 )
01561 setFlag( Flag_CellTooShortY );
01562 }
01563 else
01564 setFlag( Flag_CellTooShortY );
01565 }
01566
01567 clearFlag( Flag_LayoutDirty );
01568
01569 return;
01570 }
01571
01572
01573 void Cell::valueChanged ()
01574 {
01575 update();
01576
01577 format()->sheet()->valueChanged (this);
01578 }
01579
01580
01581
01582
01583
01584 void Cell::setOutputText()
01585 {
01586 if ( isDefault() ) {
01587 d->strOutText = QString::null;
01588
01589 if ( d->hasExtra() && d->extra()->conditions )
01590 d->extra()->conditions->checkMatches();
01591
01592 return;
01593 }
01594
01595
01596 if ( !testFlag(Flag_TextFormatDirty) )
01597 return;
01598
01599
01600 clearFlag( Flag_TextFormatDirty );
01601
01602
01603
01604 if ( (!hasError()) && isFormula() && format()->sheet()->getShowFormula()
01605 && !( format()->sheet()->isProtected() && format()->isHideFormula( d->column, d->row ) )
01606 || isEmpty() )
01607 d->strOutText = d->strText;
01608 else {
01609 d->strOutText = sheet()->doc()->formatter()->formatText (this,
01610 formatType());
01611 }
01612
01613
01614 if ( d->hasExtra() && d->extra()->conditions )
01615 d->extra()->conditions->checkMatches();
01616 }
01617
01618
01619
01620
01621
01622
01623
01624 void Cell::offsetAlign( int _col, int _row )
01625 {
01626 int a;
01627 Format::AlignY ay;
01628 int tmpAngle;
01629 bool tmpVerticalText;
01630 bool tmpMultiRow;
01631 int tmpTopBorderWidth = effTopBorderPen( _col, _row ).width();
01632
01633 if ( d->hasExtra()
01634 && d->extra()->conditions
01635 && d->extra()->conditions->matchedStyle() )
01636 {
01637 Style *style = d->extra()->conditions->matchedStyle();
01638
01639 if ( style->hasFeature( Style::SAlignX, true ) )
01640 a = style->alignX();
01641 else
01642 a = format()->align( _col, _row );
01643
01644 if ( style->hasFeature( Style::SVerticalText, true ) )
01645 tmpVerticalText = style->hasProperty( Style::PVerticalText );
01646 else
01647 tmpVerticalText = format()->verticalText( _col, _row );
01648
01649 if ( style->hasFeature( Style::SMultiRow, true ) )
01650 tmpMultiRow = style->hasProperty( Style::PMultiRow );
01651 else
01652 tmpMultiRow = format()->multiRow( _col, _row );
01653
01654 if ( style->hasFeature( Style::SAlignY, true ) )
01655 ay = style->alignY();
01656 else
01657 ay = format()->alignY( _col, _row );
01658
01659 if ( style->hasFeature( Style::SAngle, true ) )
01660 tmpAngle = style->rotateAngle();
01661 else
01662 tmpAngle = format()->getAngle( _col, _row );
01663 }
01664 else {
01665 a = format()->align( _col, _row );
01666 ay = format()->alignY( _col, _row );
01667 tmpAngle = format()->getAngle( _col, _row );
01668 tmpVerticalText = format()->verticalText( _col, _row );
01669 tmpMultiRow = format()->multiRow( _col, _row );
01670 }
01671
01672 RowFormat *rl = format()->sheet()->rowFormat( _row );
01673 ColumnFormat *cl = format()->sheet()->columnFormat( _col );
01674
01675 double w = cl->dblWidth();
01676 double h = rl->dblHeight();
01677
01678 if ( d->hasExtra() ) {
01679 if ( d->extra()->extraXCells ) w = d->extra()->extraWidth;
01680 if ( d->extra()->extraYCells ) h = d->extra()->extraHeight;
01681 }
01682
01683
01684
01685 switch( ay ) {
01686 case Format::Top:
01687 if ( tmpAngle == 0 )
01688 d->textY = tmpTopBorderWidth + BORDER_SPACE
01689 + (double) d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01690 else if ( tmpAngle < 0 )
01691 d->textY = tmpTopBorderWidth + BORDER_SPACE;
01692 else
01693 d->textY = tmpTopBorderWidth + BORDER_SPACE
01694 + ( (double)d->fmAscent * cos( tmpAngle * M_PI / 180 )
01695 / format()->sheet()->doc()->zoomedResolutionY() );
01696 break;
01697
01698 case Format::Bottom:
01699 if ( !tmpVerticalText && !tmpMultiRow && !tmpAngle ) {
01700 d->textY = h - BORDER_SPACE - effBottomBorderPen( _col, _row ).width();
01701 }
01702 else if ( tmpAngle != 0 ) {
01703 if ( h - BORDER_SPACE - d->textHeight
01704 - effBottomBorderPen( _col, _row ).width() > 0 )
01705 {
01706 if ( tmpAngle < 0 )
01707 d->textY = h - BORDER_SPACE - d->textHeight
01708 - effBottomBorderPen( _col, _row ).width();
01709 else
01710 d->textY = h - BORDER_SPACE - d->textHeight
01711 - effBottomBorderPen( _col, _row ).width()
01712 + ( (double) d->fmAscent * cos( tmpAngle * M_PI / 180 )
01713 / format()->sheet()->doc()->zoomedResolutionY() );
01714 }
01715 else if ( tmpAngle < 0 )
01716 d->textY = tmpTopBorderWidth + BORDER_SPACE ;
01717 else
01718 d->textY = tmpTopBorderWidth + BORDER_SPACE
01719 + ( (double) d->fmAscent * cos( tmpAngle * M_PI / 180 )
01720 / format()->sheet()->doc()->zoomedResolutionY() );
01721 }
01722 else if ( tmpMultiRow ) {
01723 int tmpline = d->hasExtra() ? d->extra()->nbLines : 0;
01724 if ( tmpline > 1 )
01725 tmpline--;
01726
01727 if ( h - BORDER_SPACE - d->textHeight * d->extra()->nbLines
01728 - effBottomBorderPen( _col, _row ).width() > 0 )
01729 d->textY = h - BORDER_SPACE - d->textHeight * tmpline
01730 - effBottomBorderPen( _col, _row ).width();
01731 else
01732 d->textY = tmpTopBorderWidth + BORDER_SPACE
01733 + (double) d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01734 }
01735 else {
01736 if ( h - BORDER_SPACE - d->textHeight
01737 - effBottomBorderPen( _col, _row ).width() > 0 )
01738 d->textY = h - BORDER_SPACE - d->textHeight
01739 - effBottomBorderPen( _col, _row ).width()
01740 + (double)d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01741 else
01742 d->textY = tmpTopBorderWidth + BORDER_SPACE
01743 + (double) d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01744 }
01745 break;
01746
01747 case Format::Middle:
01748 case Format::UndefinedY:
01749 if ( !tmpVerticalText && !tmpMultiRow && !tmpAngle ) {
01750 d->textY = ( h - d->textHeight ) / 2
01751 + (double) d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01752 }
01753 else if ( tmpAngle != 0 ) {
01754 if ( h - d->textHeight > 0 ) {
01755 if ( tmpAngle < 0 )
01756 d->textY = ( h - d->textHeight ) / 2 ;
01757 else
01758 d->textY = ( h - d->textHeight ) / 2 +
01759 (double) d->fmAscent * cos( tmpAngle * M_PI / 180 ) /
01760 format()->sheet()->doc()->zoomedResolutionY();
01761 }
01762 else {
01763 if ( tmpAngle < 0 )
01764 d->textY = tmpTopBorderWidth + BORDER_SPACE;
01765 else
01766 d->textY = tmpTopBorderWidth + BORDER_SPACE
01767 + ( (double)d->fmAscent * cos( tmpAngle * M_PI / 180 )
01768 / format()->sheet()->doc()->zoomedResolutionY() );
01769 }
01770 }
01771 else if ( tmpMultiRow ) {
01772 int tmpline = d->hasExtra() ? d->extra()->nbLines : 0;
01773 if ( tmpline == 0 )
01774 tmpline = 1;
01775
01776 if ( h - d->textHeight * tmpline > 0 )
01777 d->textY = ( h - d->textHeight * tmpline ) / 2
01778 + (double) d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01779 else
01780 d->textY = tmpTopBorderWidth + BORDER_SPACE
01781 + (double) d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01782 }
01783 else {
01784 if ( h - d->textHeight > 0 )
01785 d->textY = ( h - d->textHeight ) / 2
01786 + (double)d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01787 else
01788 d->textY = tmpTopBorderWidth + BORDER_SPACE
01789 + (double)d->fmAscent / format()->sheet()->doc()->zoomedResolutionY();
01790 }
01791 break;
01792 }
01793
01794 a = effAlignX();
01795 if ( format()->sheet()->getShowFormula()
01796 && !( format()->sheet()->isProtected() && format()->isHideFormula( _col, _row ) ) )
01797 a = Format::Left;
01798
01799
01800 switch ( a ) {
01801 case Format::Left:
01802 d->textX = effLeftBorderPen( _col, _row ).width() + BORDER_SPACE;
01803 break;
01804 case Format::Right:
01805 d->textX = ( w - BORDER_SPACE - d->textWidth
01806 - effRightBorderPen( _col, _row ).width() );
01807 break;
01808 case Format::Center:
01809 d->textX = ( w - d->textWidth ) / 2;
01810 break;
01811 }
01812 }
01813
01814
01815
01816
01817
01818
01819
01820 void Cell::textSize( QPainter &_paint )
01821 {
01822 QFontMetrics fm = _paint.fontMetrics();
01823
01824
01825 int tmpAngle;
01826 int _row = row();
01827 int _col = column();
01828 bool tmpVerticalText;
01829 bool fontUnderlined;
01830 Format::AlignY ay;
01831
01832
01833
01834 if ( d->hasExtra()
01835 && d->extra()->conditions
01836 && d->extra()->conditions->matchedStyle() )
01837 {
01838 Style *style = d->extra()->conditions->matchedStyle();
01839
01840 if ( style->hasFeature( Style::SAngle, true ) )
01841 tmpAngle = style->rotateAngle();
01842 else
01843 tmpAngle = format()->getAngle( _col, _row );
01844
01845 if ( style->hasFeature( Style::SVerticalText, true ) )
01846 tmpVerticalText = style->hasProperty( Style::PVerticalText );
01847 else
01848 tmpVerticalText = format()->verticalText( _col, _row );
01849
01850 if ( style->hasFeature( Style::SAlignY, true ) )
01851 ay = style->alignY();
01852 else
01853 ay = format()->alignY( _col, _row );
01854
01855 if ( style->hasFeature( Style::SFontFlag, true ) )
01856 fontUnderlined = ( style->fontFlags()
01857
01858 && (uint) Style::FUnderline );
01859 else
01860 fontUnderlined = format()->textFontUnderline( _col, _row );
01861 }
01862 else {
01863
01864 tmpAngle = format()->getAngle( _col, _row );
01865 tmpVerticalText = format()->verticalText( _col, _row );
01866 ay = format()->alignY( _col, _row );
01867 fontUnderlined = format()->textFontUnderline( _col, _row );
01868 }
01869
01870
01871
01872 if ( !tmpVerticalText && !tmpAngle ) {
01873
01874
01875 d->textWidth = format()->sheet()->doc()->unzoomItX( fm.width( d->strOutText ) );
01876 int offsetFont = 0;
01877 if ( ( ay == Format::Bottom ) && fontUnderlined ) {
01878 offsetFont = fm.underlinePos() + 1;
01879 }
01880
01881 d->textHeight = format()->sheet()->doc()->unzoomItY( fm.ascent() + fm.descent()
01882 + offsetFont );
01883 }
01884 else if ( tmpAngle!= 0 ) {
01885
01886
01887 d->textHeight = format()->sheet()->doc()
01888 ->unzoomItY( int( cos( tmpAngle * M_PI / 180 )
01889 * ( fm.ascent() + fm.descent() )
01890 + abs( int( ( fm.width( d->strOutText )
01891 * sin( tmpAngle * M_PI / 180 ) ) ) ) ) );
01892
01893 d->textWidth = format()->sheet()->doc()
01894 ->unzoomItX( int( abs( int( ( sin( tmpAngle * M_PI / 180 )
01895 * ( fm.ascent() + fm.descent() ) ) ) )
01896 + fm.width( d->strOutText )
01897 * cos ( tmpAngle * M_PI / 180 ) ) );
01898 }
01899 else {
01900
01901 int width = 0;
01902 for ( unsigned int i = 0; i < d->strOutText.length(); i++ )
01903 width = QMAX( width, fm.width( d->strOutText.at( i ) ) );
01904
01905 d->textWidth = format()->sheet()->doc()->unzoomItX( width );
01906 d->textHeight = format()->sheet()->doc()->unzoomItY( ( fm.ascent() + fm.descent() )
01907 * d->strOutText.length() );
01908 }
01909 }
01910
01911
01912
01913
01914
01915
01916
01917 void Cell::applyZoomedFont( QPainter &painter, int _col, int _row )
01918 {
01919 QFont tmpFont( format()->textFont( _col, _row ) );
01920
01921
01922
01923 if ( d->hasExtra()
01924 && d->extra()->conditions
01925 && d->extra()->conditions->matchedStyle() ) {
01926
01927 Style * s = d->extra()->conditions->matchedStyle();
01928
01929
01930 if ( s->hasFeature( Style::SFontSize, true ) )
01931 tmpFont.setPointSizeFloat( s->fontSize() );
01932
01933
01934 if ( s->hasFeature( Style::SFontFlag, true ) ) {
01935 uint flags = s->fontFlags();
01936
01937 tmpFont.setBold( flags & (uint) Style::FBold );
01938 tmpFont.setUnderline( flags & (uint) Style::FUnderline );
01939 tmpFont.setItalic( flags & (uint) Style::FItalic );
01940 tmpFont.setStrikeOut( flags & (uint) Style::FStrike );
01941 }
01942
01943
01944 if ( s->hasFeature( Style::SFontFamily, true ) )
01945 tmpFont.setFamily( s->fontFamily() );
01946 }
01947 #if 0
01948 else
01949
01950
01951
01952 if ( d->extra()->conditions
01953 && d->extra()->conditions->currentCondition( condition )
01954 && !(format()->sheet()->getShowFormula()
01955 && !( format()->sheet()->isProtected()
01956 && format()->isHideFormula( d->column, d->row ) ) ) )
01957 {
01958 if ( condition.fontcond )
01959 tmpFont = *(condition.fontcond);
01960 else
01961 tmpFont = condition.style->font();
01962 }
01963 #endif
01964
01965
01966 tmpFont.setPointSizeFloat( 0.01 * format()->sheet()->doc()->zoom()
01967 * tmpFont.pointSizeFloat() );
01968
01969 painter.setFont( tmpFont );
01970 }
01971
01972
01973
01974 void Cell::calculateTextParameters( QPainter &_painter,
01975 int _col, int _row )
01976 {
01977
01978 applyZoomedFont( _painter, _col, _row );
01979
01980
01981 textSize( _painter );
01982
01983
01984 offsetAlign( _col, _row );
01985 }
01986
01987
01988
01989
01990
01991
01992 bool Cell::makeFormula()
01993 {
01994 clearFormula ();
01995
01996 d->formula = new KSpread::Formula (sheet(), this);
01997 d->formula->setExpression (d->strText);
01998
01999 if (!d->formula->isValid ()) {
02000
02001 clearFormula();
02002
02003 if (format()->sheet()->doc()->getShowMessageError())
02004 {
02005 QString tmp(i18n("Error in cell %1\n\n"));
02006 tmp = tmp.arg( fullName() );
02007 KMessageBox::error( (QWidget*)0L, tmp);
02008 }
02009 setFlag(Flag_ParseError);
02010 Value v;
02011 v.setError ( "####" );
02012 setValue (v);
02013 return false;
02014 }
02015
02016
02017 setCalcDirtyFlag ();
02018
02019 return true;
02020 }
02021
02022 void Cell::clearFormula()
02023 {
02024 delete d->formula;
02025 d->formula = 0L;
02026 }
02027
02028 bool Cell::calc(bool delay)
02029 {
02030 if ( !isFormula() )
02031 return true;
02032
02033 if (d->formula == 0)
02034 {
02035 if ( testFlag( Flag_ParseError ) )
02036 return false;
02037 else
02038 {
02039
02040
02041
02042 makeFormula ();
02043
02044 if ( d->formula == 0 )
02045 return false;
02046 }
02047 }
02048
02049 if ( !testFlag( Flag_CalcDirty ) )
02050 return true;
02051
02052 if ( delay )
02053 {
02054 if ( format()->sheet()->doc()->delayCalculation() )
02055 return true;
02056 }
02057
02058 setFlag(Flag_LayoutDirty);
02059 setFlag(Flag_TextFormatDirty);
02060 clearFlag(Flag_CalcDirty);
02061
02062 Value result = d->formula->eval ();
02063 setValue (result);
02064 if (result.isNumber())
02065 checkNumberFormat();
02066
02067 clearFlag(Flag_CalcDirty);
02068 setFlag(Flag_LayoutDirty);
02069
02070 return true;
02071 }
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 void Cell::paintCell( const KoRect &rect, QPainter & painter,
02088 View *view,
02089 const KoPoint &coordinate,
02090 const QPoint &cellRef,
02091 int paintBorder,
02092 QPen & rightPen, QPen & bottomPen,
02093 QPen & leftPen, QPen & topPen,
02094 QValueList<QPoint> &mergedCellsPainted,
02095 bool drawCursor )
02096 {
02097 bool paintBorderRight = paintBorder & Border_Right;
02098 bool paintBorderBottom = paintBorder & Border_Bottom;
02099 bool paintBorderLeft = paintBorder & Border_Left;
02100 bool paintBorderTop = paintBorder & Border_Top;
02101
02102
02103
02104 if ( testFlag( Flag_PaintingCell ) )
02105 return;
02106
02107
02108 setFlag( Flag_PaintingCell );
02109
02110
02111
02112
02113
02114 static int paintingObscured = 0;
02115
02116 #if 0
02117 if (paintingObscured == 0)
02118 kdDebug(36001) << "painting cell " << name() << endl;
02119 else
02120 kdDebug(36001) << " painting obscured cell " << name() << endl;
02121 #endif
02122
02123
02124
02125 Q_ASSERT(!(paintingObscured > 0 && d->extra()->obscuringCells.isEmpty()));
02126
02127
02128 Q_ASSERT(isDefault()
02129 || (((cellRef.x() == d->column) && (cellRef.y() == d->row))));
02130
02131 Sheet::LayoutDirection sheetDir = format()->sheet()->layoutDirection();
02132
02133 double left = coordinate.x();
02134
02135 ColumnFormat * colFormat = format()->sheet()->columnFormat( cellRef.x() );
02136 RowFormat * rowFormat = format()->sheet()->rowFormat( cellRef.y() );
02137
02138
02139
02140
02141
02142 double width0 = colFormat->dblWidth();
02143 double height0 = rowFormat->dblHeight();
02144 double width = width0;
02145 double height = height0;
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155 if ( sheetDir == Sheet::RightToLeft && paintingObscured == 0
02156 && view && view->canvasWidget() )
02157 {
02158 double dwidth = view->doc()->unzoomItX(view->canvasWidget()->width());
02159 left = dwidth - coordinate.x() - width;
02160 }
02161
02162
02163
02164
02165 if (d->hasExtra()) {
02166 if (d->extra()->mergedXCells > 0 || d->extra()->mergedYCells > 0) {
02167
02168 if ( sheetDir == Sheet::RightToLeft ) {
02169 left -= d->extra()->extraWidth - width;
02170 }
02171 width0 = d->extra()->extraWidth;
02172 height0 = d->extra()->extraHeight;
02173 width = d->extra()->extraWidth;
02174 height = d->extra()->extraHeight;
02175 }
02176 else {
02177 #if 0
02178 width += d->extra()->extraXCells ? d->extra()->extraWidth : 0;
02179 height += d->extra()->extraYCells ? d->extra()->extraHeight : 0;
02180 #else
02181
02182 if ( d->extra()->extraXCells )
02183 width = d->extra()->extraWidth;
02184 if ( d->extra()->extraYCells )
02185 height = d->extra()->extraHeight;
02186 #endif
02187 }
02188 }
02189
02190
02191
02192
02193
02194
02195 bool selected = false;
02196 if ( view != NULL ) {
02197 selected = view->selectionInfo()->contains( cellRef );
02198
02199
02200 Cell *cell = format()->sheet()->cellAt( view->selectionInfo()->marker() );
02201 QPoint bottomRight( view->selectionInfo()->marker().x() + cell->extraXCells(),
02202 view->selectionInfo()->marker().y() + cell->extraYCells() );
02203 QRect markerArea( view->selectionInfo()->marker(), bottomRight );
02204 selected = selected && !( markerArea.contains( cellRef ) );
02205
02206
02207 if ( painter.device()->isExtDev() || !drawCursor )
02208 selected = false;
02209 }
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219 if ( testFlag( Flag_LayoutDirty ) )
02220 makeLayout( painter, cellRef.x(), cellRef.y() );
02221
02222
02223
02224
02225
02226
02227 const KoRect cellRect( left, coordinate.y(), width, height );
02228 const KoRect cellRect0( left, coordinate.y(), width0, height0 );
02229 if ( !cellRect.intersects( rect ) ) {
02230 clearFlag( Flag_PaintingCell );
02231 return;
02232 }
02233
02234
02235
02236
02237
02238
02239 QColor backgroundColor;
02240 if ( d->hasExtra() && d->extra()->conditions
02241 && d->extra()->conditions->matchedStyle()
02242 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SBackgroundColor, true ) )
02243 backgroundColor = d->extra()->conditions->matchedStyle()->bgColor();
02244 else
02245 backgroundColor = bgColor( cellRef.x(), cellRef.y() );
02246
02247
02248 if ( !isPartOfMerged() )
02249 paintBackground( painter, cellRect0, cellRef, selected, backgroundColor );
02250
02251
02252
02253 if ( painter.device()->devType() != QInternal::Printer
02254 || format()->sheet()->print()->printGrid())
02255 paintDefaultBorders( painter, rect, cellRect, cellRef,
02256 paintBorderRight, paintBorderBottom,
02257 paintBorderLeft, paintBorderTop,
02258 rightPen, bottomPen, leftPen, topPen );
02259
02260
02261
02262
02263
02264
02265
02266 paintingObscured++;
02267
02268 if (d->hasExtra() && (d->extra()->extraXCells > 0
02269 || d->extra()->extraYCells > 0)) {
02270
02271
02272 paintObscuredCells( rect, painter, view, cellRect, cellRef,
02273 paintBorderRight, paintBorderBottom,
02274 paintBorderLeft, paintBorderTop,
02275 rightPen, bottomPen, leftPen, topPen,
02276 mergedCellsPainted);
02277
02278
02279 if ( d->extra()->mergedXCells > 0 || d->extra()->mergedYCells > 0 )
02280 mergedCellsPainted.prepend( cellRef );
02281 }
02282 paintingObscured--;
02283
02284
02285
02286
02287
02288
02289
02290 if ( painter.device()->isExtDev() )
02291 painter.setClipping( false );
02292
02293
02294 if ( !isPartOfMerged() ) {
02295
02296 paintCellBorders( painter, rect, cellRect0,
02297 cellRef,
02298 paintBorderRight, paintBorderBottom,
02299 paintBorderLeft, paintBorderTop,
02300 rightPen, bottomPen, leftPen, topPen );
02301 }
02302
02303
02304 if ( painter.device()->isExtDev() )
02305 painter.setClipping( true );
02306
02307
02308 paintCellDiagonalLines( painter, cellRect0, cellRef );
02309
02310 paintPageBorders( painter, cellRect0, cellRef,
02311 paintBorderRight, paintBorderBottom );
02312
02313
02314
02315 if ( !isObscured() ) {
02316
02317
02318 if ( !painter.device()->isExtDev()
02319 || format()->sheet()->print()->printCommentIndicator() )
02320 paintCommentIndicator( painter, cellRect, cellRef, backgroundColor );
02321
02322
02323 if ( !painter.device()->isExtDev()
02324 || format()->sheet()->print()->printFormulaIndicator() )
02325 paintFormulaIndicator( painter, cellRect, backgroundColor );
02326
02327
02328 paintMoreTextIndicator( painter, cellRect, backgroundColor );
02329
02330
02331 #if 0
02332 if (highlightBorder != Border_None)
02333 paintCellHighlight ( painter, cellRect, cellRef, highlightBorder,
02334 rightHighlightPen, bottomHighlightPen,
02335 leftHighlightPen, topHighlightPen );
02336 #endif
02337
02338
02339
02340
02341
02342 if ( !d->strOutText.isEmpty()
02343 && ( !painter.device()->isExtDev()
02344 || !format()->getDontprintText( cellRef.x(), cellRef.y() ) )
02345 && !( format()->sheet()->isProtected()
02346 && format()->isHideAll( cellRef.x(), cellRef.y() ) ) )
02347 {
02348 paintText( painter, cellRect, cellRef );
02349 }
02350 }
02351
02352
02353
02354
02355 if ( isObscured() && paintingObscured == 0 &&
02356 !( sheetDir == Sheet::RightToLeft && painter.device()->isExtDev() ) )
02357 {
02358
02359
02360
02361
02362
02363
02364
02365
02366 if (d->hasExtra()) {
02367 QValueList<QPoint> listPoints;
02368 QValueList<Cell*>::iterator it = d->extra()->obscuringCells.begin();
02369 QValueList<Cell*>::iterator end = d->extra()->obscuringCells.end();
02370 for ( ; it != end; ++it ) {
02371 Cell *obscuringCell = *it;
02372
02373 listPoints.append( QPoint( obscuringCell->column(), obscuringCell->row() ) );
02374 }
02375
02376 QValueList<QPoint>::iterator it1 = listPoints.begin();
02377 QValueList<QPoint>::iterator end1 = listPoints.end();
02378 for ( ; it1 != end1; ++it1 ) {
02379 QPoint obscuringCellRef = *it1;
02380
02381
02382
02383
02384
02385
02386 if ( mergedCellsPainted.contains( obscuringCellRef ) )
02387 continue;
02388
02389 Cell *obscuringCell = format()->sheet()->cellAt( obscuringCellRef.x(),
02390 obscuringCellRef.y() );
02391
02392 if ( obscuringCell != 0 ) {
02393 double x = format()->sheet()->dblColumnPos( obscuringCellRef.x() );
02394 double y = format()->sheet()->dblRowPos( obscuringCellRef.y() );
02395 if ( view != 0 ) {
02396 x -= view->canvasWidget()->xOffset();
02397 y -= view->canvasWidget()->yOffset();
02398 }
02399
02400 KoPoint corner( x, y );
02401 painter.save();
02402
02403
02404
02405
02406 QPen rp( obscuringCell->effRightBorderPen( obscuringCellRef.x(),
02407 obscuringCellRef.y() ) );
02408 QPen bp( obscuringCell->effBottomBorderPen( obscuringCellRef.x(),
02409 obscuringCellRef.y() ) );
02410 QPen lp( obscuringCell->effLeftBorderPen( obscuringCellRef.x(),
02411 obscuringCellRef.y() ) );
02412 QPen tp( obscuringCell->effTopBorderPen( obscuringCellRef.x(),
02413 obscuringCellRef.y() ) );
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424 obscuringCell->paintCell( rect, painter, view,
02425 corner, obscuringCellRef,
02426 Border_Left|Border_Top|Border_Right|Border_Bottom,
02427 rp, bp, lp, tp,
02428 mergedCellsPainted);
02429 painter.restore();
02430 }
02431 }
02432 }
02433 }
02434
02435
02436 clearFlag( Flag_PaintingCell );
02437 }
02438
02439
02440
02441
02442
02443
02444
02445 #if 0
02446
02450 if ( d->style == Cell::ST_Button ) {
02451 QBrush fill( Qt::lightGray );
02452 QApplication::style().drawControl( QStyle::CE_PushButton, &_painter, this,
02453 QRect( _tx + 1, _ty + 1, w2 - 1, h2 - 1 ),
02454 defaultColorGroup );
02455 }
02456
02460 else if ( d->style == Cell::ST_Select ) {
02461 QApplication::style().drawComboButton( &_painter, _tx + 1, _ty + 1,
02462 w2 - 1, h2 - 1,
02463 defaultColorGroup, selected );
02464 }
02465 #endif
02466
02467
02468 #if 0
02469 void Cell::paintCellHighlight(QPainter& painter,
02470 const KoRect& cellRect,
02471 const QPoint& cellRef,
02472 const int highlightBorder,
02473 const QPen& rightPen,
02474 const QPen& bottomPen,
02475 const QPen& leftPen,
02476 const QPen& topPen
02477 )
02478 {
02479
02480
02481
02482
02483 QBrush nullBrush;
02484 painter.setBrush(nullBrush);
02485
02486 QRect zoomedCellRect = sheet()->doc()->zoomRect( cellRect );
02487
02488
02489
02490
02491 zoomedCellRect.setLeft(zoomedCellRect.left()+1);
02492
02493 zoomedCellRect.setTop(zoomedCellRect.top()+1);
02494
02495
02496 if ( cellRef.x() != KS_colMax )
02497 zoomedCellRect.setWidth( zoomedCellRect.width() - 1 );
02498 if ( cellRef.y() != KS_rowMax )
02499 zoomedCellRect.setHeight( zoomedCellRect.height() - 1 );
02500
02501 if (highlightBorder & Border_Top)
02502 {
02503 painter.setPen(topPen);
02504 painter.drawLine(zoomedCellRect.left(),zoomedCellRect.top(),zoomedCellRect.right(),zoomedCellRect.top());
02505 }
02506 if (highlightBorder & Border_Left)
02507 {
02508 painter.setPen(leftPen);
02509 painter.drawLine(zoomedCellRect.left(),zoomedCellRect.top(),zoomedCellRect.left(),zoomedCellRect.bottom());
02510 }
02511 if (highlightBorder & Border_Right)
02512 {
02513 painter.setPen(rightPen);
02514 painter.drawLine(zoomedCellRect.right(),zoomedCellRect.top(),zoomedCellRect.right(),zoomedCellRect.bottom());
02515 }
02516 if (highlightBorder & Border_Bottom)
02517 {
02518 painter.setPen(bottomPen);
02519 painter.drawLine(zoomedCellRect.left(),zoomedCellRect.bottom(),zoomedCellRect.right(),zoomedCellRect.bottom());
02520 }
02521
02522 if (highlightBorder & Border_SizeGrip)
02523 {
02524 QBrush brush(rightPen.color());
02525 painter.setBrush(brush);
02526 painter.setPen(rightPen);
02527 painter.drawRect(zoomedCellRect.right()-3,zoomedCellRect.bottom()-3,4,4);
02528 }
02529
02530
02531 }
02532 #endif
02533
02534
02535
02536
02537 void Cell::paintObscuredCells(const KoRect& rect, QPainter& painter,
02538 View* view,
02539 const KoRect &cellRect,
02540 const QPoint &cellRef,
02541 bool paintBorderRight,
02542 bool _paintBorderBottom,
02543 bool paintBorderLeft,
02544 bool _paintBorderTop,
02545 QPen & rightPen, QPen & _bottomPen,
02546 QPen & leftPen, QPen & _topPen,
02547 QValueList<QPoint> &mergedCellsPainted)
02548 {
02549
02550 if ( !extraXCells() && !extraYCells() )
02551 return;
02552
02553 double ypos = cellRect.y();
02554 int maxY = extraYCells();
02555 int maxX = extraXCells();
02556
02557
02558 for ( int y = 0; y <= maxY; ++y ) {
02559 double xpos = cellRect.x();
02560 RowFormat* rl = format()->sheet()->rowFormat( cellRef.y() + y );
02561
02562 for( int x = 0; x <= maxX; ++ x ) {
02563 ColumnFormat * cl = format()->sheet()->columnFormat( cellRef.x() + x );
02564 if ( y != 0 || x != 0 ) {
02565 uint column = cellRef.x() + x;
02566 uint row = cellRef.y() + y;
02567
02568 QPen topPen;
02569 QPen bottomPen;
02570 bool paintBorderTop;
02571 bool paintBorderBottom;
02572
02573 Cell *cell = format()->sheet()->cellAt( column, row );
02574 KoPoint corner( xpos, ypos );
02575
02576
02577
02578
02579
02580 topPen = _topPen;
02581 paintBorderTop = _paintBorderTop;
02582 if ( row > 1 && !cell->isPartOfMerged() ) {
02583 Cell *cellUp = format()->sheet()->cellAt( column, row - 1 );
02584
02585 if ( cellUp->isDefault() )
02586 paintBorderTop = false;
02587 else {
02588
02589
02590 cellUp = cellUp->ultimateObscuringCell();
02591
02592 topPen = cellUp->effBottomBorderPen( cellUp->column(),
02593 cellUp->row() );
02594
02595 #if 0
02596 int penWidth = QMAX(1, sheet()->doc()->zoomItY( topPen.width() ));
02597 topPen.setWidth( penWidth );
02598 #endif
02599 }
02600 }
02601
02602
02603
02604 bottomPen = _bottomPen;
02605 paintBorderBottom = _paintBorderBottom;
02606
02607 int paintBorder = Border_None;
02608 if (paintBorderLeft) paintBorder |= Cell::Border_Left;
02609 if (paintBorderRight) paintBorder |= Cell::Border_Right;
02610 if (paintBorderTop) paintBorder |= Cell::Border_Top;
02611 if (paintBorderBottom) paintBorder |= Cell::Border_Bottom;
02612
02613
02614
02615
02616
02617
02618
02619 cell->paintCell( rect, painter, view,
02620 corner,
02621 QPoint( cellRef.x() + x, cellRef.y() + y ),
02622 paintBorder,
02623 rightPen, bottomPen, leftPen, topPen,
02624 mergedCellsPainted);
02625 }
02626 xpos += cl->dblWidth();
02627 }
02628
02629 ypos += rl->dblHeight();
02630 }
02631 }
02632
02633
02634
02635
02636 void Cell::paintBackground( QPainter& painter, const KoRect &cellRect,
02637 const QPoint &cellRef, bool selected,
02638 QColor &backgroundColor )
02639 {
02640 QColorGroup defaultColorGroup = QApplication::palette().active();
02641 QRect zoomedCellRect = sheet()->doc()->zoomRect( cellRect );
02642
02643
02644
02645
02646
02647
02648
02649 if ( cellRef.x() != KS_colMax )
02650 zoomedCellRect.setWidth( zoomedCellRect.width() - 1 );
02651 if ( cellRef.y() != KS_rowMax )
02652 zoomedCellRect.setHeight( zoomedCellRect.height() - 1 );
02653
02654
02655 if ( selected )
02656 {
02657
02658
02659 QColor c;
02660
02661 int averageColor = (backgroundColor.red() + backgroundColor.green() + backgroundColor.blue()) / 3;
02662
02663 if (averageColor > 180)
02664 if (averageColor > 225)
02665 c = View::highlightColor();
02666 else
02667 c = backgroundColor.light( 115 );
02668 else
02669 c = backgroundColor.light( 125 );
02670
02671 painter.setBackgroundColor( c );
02672 }
02673 else {
02674 QColor bg( backgroundColor );
02675
02676
02677 if ( !painter.device()->isExtDev() ) {
02678 if ( bg.isValid() )
02679 painter.setBackgroundColor( bg );
02680 else
02681 painter.setBackgroundColor( defaultColorGroup.base() );
02682 }
02683 else {
02684
02685
02686 QBrush bb( bg );
02687 if ( !bg.isValid() )
02688 bb.setColor( Qt::white );
02689
02690 painter.fillRect( zoomedCellRect, bb );
02691 return;
02692 }
02693 }
02694
02695
02696 if ( !painter.device()->isExtDev() )
02697 painter.eraseRect( zoomedCellRect );
02698
02699
02700 QBrush bb;
02701 if ( d->hasExtra()
02702 && d->extra()->conditions
02703 && d->extra()->conditions->matchedStyle()
02704 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SBackgroundBrush, true ) )
02705 bb = d->extra()->conditions->matchedStyle()->backGroundBrush();
02706 else
02707 bb = backGroundBrush( cellRef.x(), cellRef.y() );
02708
02709
02710 if ( bb.style() != Qt::NoBrush )
02711 painter.fillRect( zoomedCellRect, bb );
02712
02713 backgroundColor = painter.backgroundColor();
02714 }
02715
02716
02717
02718
02719 void Cell::paintDefaultBorders( QPainter& painter, const KoRect &rect,
02720 const KoRect &cellRect,
02721 const QPoint &cellRef,
02722 bool paintBorderRight, bool ,
02723 bool paintBorderLeft, bool paintBorderTop,
02724 QPen const & rightPen, QPen const & ,
02725 QPen const & leftPen, QPen const & topPen )
02726 {
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742 Doc* doc = sheet()->doc();
02743
02744 Sheet::LayoutDirection sheetDir = format()->sheet()->layoutDirection();
02745 bool paintingToExternalDevice = painter.device()->isExtDev();
02746
02747
02748
02749
02750
02751
02752 bool paintTop;
02753 bool paintLeft;
02754 bool paintBottom=false;
02755 bool paintRight=false;
02756
02757 paintLeft = ( paintBorderLeft && leftPen.style() == Qt::NoPen
02758 && sheet()->getShowGrid() && sheetDir==Sheet::LeftToRight );
02759 paintRight = ( paintBorderRight && rightPen.style() == Qt::NoPen
02760 && sheet()->getShowGrid() && sheetDir==Sheet::RightToLeft );
02761 paintTop = ( paintBorderTop && topPen.style() == Qt::NoPen
02762 && sheet()->getShowGrid() );
02763
02764
02765
02766
02767
02768 painter.setPen( QPen( sheet()->doc()->gridColor(), 1, Qt::SolidLine ) );
02769
02770
02771 if (d->hasExtra()) {
02772 QValueList<Cell*>::const_iterator it = d->extra()->obscuringCells.begin();
02773 QValueList<Cell*>::const_iterator end = d->extra()->obscuringCells.end();
02774 for ( ; it != end; ++it ) {
02775 Cell *cell = *it;
02776
02777 paintTop = paintTop && ( cell->row() == cellRef.y() );
02778 paintBottom = false;
02779
02780 if ( sheetDir == Sheet::RightToLeft ) {
02781 paintRight = paintRight && ( cell->column() == cellRef.x() );
02782 paintLeft = false;
02783 }
02784 else {
02785 paintLeft = paintLeft && ( cell->column() == cellRef.x() );
02786 paintRight = false;
02787 }
02788 }
02789 }
02790
02791
02792 if ( paintLeft ) {
02793 int dt = 0;
02794 int db = 0;
02795
02796 #if 0
02797 if ( cellRef.x() > 1 ) {
02798 Cell *cell_west = format()->sheet()->cellAt( cellRef.x() - 1,
02799 cellRef.y() );
02800 QPen t = cell_west->effTopBorderPen( cellRef.x() - 1, cellRef.y() );
02801 QPen b = cell_west->effBottomBorderPen( cellRef.x() - 1, cellRef.y() );
02802
02803 if ( t.style() != Qt::NoPen )
02804 dt = ( t.width() + 1 )/2;
02805 if ( b.style() != Qt::NoPen )
02806 db = ( t.width() / 2);
02807 }
02808 #endif
02809
02810
02811
02812 if ( paintingToExternalDevice ) {
02813 if ( sheetDir == Sheet::RightToLeft )
02814 painter.drawLine( doc->zoomItX( QMAX( rect.left(), cellRect.right() ) ),
02815 doc->zoomItY( QMAX( rect.top(), cellRect.y() + dt ) ),
02816 doc->zoomItX( QMIN( rect.right(), cellRect.right() ) ),
02817 doc->zoomItY( QMIN( rect.bottom(), cellRect.bottom() - db ) ) );
02818 else
02819 painter.drawLine( doc->zoomItX( QMAX( rect.left(), cellRect.x() ) ),
02820 doc->zoomItY( QMAX( rect.top(), cellRect.y() + dt ) ),
02821 doc->zoomItX( QMIN( rect.right(), cellRect.x() ) ),
02822 doc->zoomItY( QMIN( rect.bottom(), cellRect.bottom() - db ) ) );
02823 }
02824 else {
02825 if ( sheetDir == Sheet::RightToLeft )
02826 painter.drawLine( doc->zoomItX( cellRect.right() ),
02827 doc->zoomItY( cellRect.y() + dt ),
02828 doc->zoomItX( cellRect.right() ),
02829 doc->zoomItY( cellRect.bottom() - db ) );
02830 else
02831 painter.drawLine( doc->zoomItX( cellRect.x() ),
02832 doc->zoomItY( cellRect.y() + dt ),
02833 doc->zoomItX( cellRect.x() ),
02834 doc->zoomItY( cellRect.bottom() - db ) );
02835 }
02836 }
02837
02838
02839
02840 if ( paintTop ) {
02841 int dl = 0;
02842 int dr = 0;
02843
02844 #if 0
02845 if ( cellRef.y() > 1 ) {
02846 Cell *cell_north = format()->sheet()->cellAt( cellRef.x(),
02847 cellRef.y() - 1 );
02848
02849 QPen l = cell_north->effLeftBorderPen( cellRef.x(), cellRef.y() - 1 );
02850 QPen r = cell_north->effRightBorderPen( cellRef.x(), cellRef.y() - 1 );
02851
02852 if ( l.style() != Qt::NoPen )
02853 dl = ( l.width() - 1 ) / 2 + 1;
02854 if ( r.style() != Qt::NoPen )
02855 dr = r.width() / 2;
02856 }
02857 #endif
02858
02859
02860
02861
02862
02863 if ( paintingToExternalDevice ) {
02864 painter.drawLine( doc->zoomItX( QMAX( rect.left(), cellRect.x() + dl ) ),
02865 doc->zoomItY( QMAX( rect.top(), cellRect.y() ) ),
02866 doc->zoomItX( QMIN( rect.right(), cellRect.right() - dr ) ),
02867 doc->zoomItY( QMIN( rect.bottom(), cellRect.y() ) ) );
02868 }
02869 else {
02870 painter.drawLine( doc->zoomItX( cellRect.x() + dl ),
02871 doc->zoomItY( cellRect.y() ),
02872 doc->zoomItX( cellRect.right() - dr ),
02873 doc->zoomItY( cellRect.y() ) );
02874 }
02875 }
02876
02877
02878
02879 if ( paintRight ) {
02880 int dt = 0;
02881 int db = 0;
02882
02883 #if 0
02884 if ( cellRef.x() < KS_colMax ) {
02885 Cell *cell_east = format()->sheet()->cellAt( cellRef.x() + 1,
02886 cellRef.y() );
02887
02888 QPen t = cell_east->effTopBorderPen( cellRef.x() + 1, cellRef.y() );
02889 QPen b = cell_east->effBottomBorderPen( cellRef.x() + 1, cellRef.y() );
02890
02891 if ( t.style() != Qt::NoPen )
02892 dt = ( t.width() + 1 ) / 2;
02893 if ( b.style() != Qt::NoPen )
02894 db = ( t.width() / 2);
02895 }
02896 #endif
02897
02898
02899
02900
02901
02902 if ( painter.device()->isExtDev() ) {
02903 if ( sheetDir == Sheet::RightToLeft )
02904 painter.drawLine( doc->zoomItX( QMAX( rect.left(), cellRect.x() ) ),
02905 doc->zoomItY( QMAX( rect.top(), cellRect.y() + dt ) ),
02906 doc->zoomItX( QMIN( rect.right(), cellRect.x() ) ),
02907 doc->zoomItY( QMIN( rect.bottom(), cellRect.bottom() - db ) ) );
02908 else
02909 painter.drawLine( doc->zoomItX( QMAX( rect.left(), cellRect.right() ) ),
02910 doc->zoomItY( QMAX( rect.top(), cellRect.y() + dt ) ),
02911 doc->zoomItX( QMIN( rect.right(), cellRect.right() ) ),
02912 doc->zoomItY( QMIN( rect.bottom(), cellRect.bottom() - db ) ) );
02913 }
02914 else {
02915 if ( sheetDir == Sheet::RightToLeft )
02916 painter.drawLine( doc->zoomItX( cellRect.x() ),
02917 doc->zoomItY( cellRect.y() + dt ),
02918 doc->zoomItX( cellRect.x() ),
02919 doc->zoomItY( cellRect.bottom() - db ) );
02920 else
02921 painter.drawLine( doc->zoomItX( cellRect.right() ),
02922 doc->zoomItY( cellRect.y() + dt ),
02923 doc->zoomItX( cellRect.right() ),
02924 doc->zoomItY( cellRect.bottom() - db ) );
02925 }
02926 }
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962 }
02963
02964
02965
02966
02967 void Cell::paintCommentIndicator( QPainter& painter,
02968 const KoRect &cellRect,
02969 const QPoint &,
02970 QColor &backgroundColor )
02971 {
02972 Doc * doc = sheet()->doc();
02973
02974
02975
02976 if ( ( format()->propertiesMask() & (uint) Format::PComment )
02977 && cellRect.width() > 10.0
02978 && cellRect.height() > 10.0
02979 && ( sheet()->print()->printCommentIndicator()
02980 || ( !painter.device()->isExtDev() && sheet()->getShowCommentIndicator() ) ) ) {
02981 QColor penColor = Qt::red;
02982
02983
02984 if ( qRed( backgroundColor.rgb() ) > 127 &&
02985 qGreen( backgroundColor.rgb() ) < 80 &&
02986 qBlue( backgroundColor.rgb() ) < 80 )
02987 {
02988 penColor = Qt::blue;
02989 }
02990
02991
02992 QPointArray point( 3 );
02993 if ( format()->sheet()->layoutDirection()==Sheet::RightToLeft ) {
02994 point.setPoint( 0, doc->zoomItX( cellRect.x() + 6.0 ),
02995 doc->zoomItY( cellRect.y() ) );
02996 point.setPoint( 1, doc->zoomItX( cellRect.x() ),
02997 doc->zoomItY( cellRect.y() ) );
02998 point.setPoint( 2, doc->zoomItX( cellRect.x() ),
02999 doc->zoomItY( cellRect.y() + 6.0 ) );
03000 }
03001 else {
03002 point.setPoint( 0, doc->zoomItX( cellRect.right() - 5.0 ),
03003 doc->zoomItY( cellRect.y() ) );
03004 point.setPoint( 1, doc->zoomItX( cellRect.right() ),
03005 doc->zoomItY( cellRect.y() ) );
03006 point.setPoint( 2, doc->zoomItX( cellRect.right() ),
03007 doc->zoomItY( cellRect.y() + 5.0 ) );
03008 }
03009
03010
03011 painter.setBrush( QBrush( penColor ) );
03012 painter.setPen( Qt::NoPen );
03013 painter.drawPolygon( point );
03014 }
03015 }
03016
03017
03018
03019
03020
03021 void Cell::paintFormulaIndicator( QPainter& painter,
03022 const KoRect &cellRect,
03023 QColor &backgroundColor )
03024 {
03025 if ( isFormula() &&
03026 format()->sheet()->getShowFormulaIndicator() &&
03027 cellRect.width() > 10.0 &&
03028 cellRect.height() > 10.0 )
03029 {
03030 Doc* doc = sheet()->doc();
03031
03032 QColor penColor = Qt::blue;
03033
03034 if ( qRed( backgroundColor.rgb() ) < 80 &&
03035 qGreen( backgroundColor.rgb() ) < 80 &&
03036 qBlue( backgroundColor.rgb() ) > 127 )
03037 {
03038 penColor = Qt::red;
03039 }
03040
03041
03042 QPointArray point( 3 );
03043 if ( format()->sheet()->layoutDirection()==Sheet::RightToLeft ) {
03044 point.setPoint( 0, doc->zoomItX( cellRect.right() - 6.0 ),
03045 doc->zoomItY( cellRect.bottom() ) );
03046 point.setPoint( 1, doc->zoomItX( cellRect.right() ),
03047 doc->zoomItY( cellRect.bottom() ) );
03048 point.setPoint( 2, doc->zoomItX( cellRect.right() ),
03049 doc->zoomItY( cellRect.bottom() - 6.0 ) );
03050 }
03051 else {
03052 point.setPoint( 0, doc->zoomItX( cellRect.x() ),
03053 doc->zoomItY( cellRect.bottom() - 6.0 ) );
03054 point.setPoint( 1, doc->zoomItX( cellRect.x() ),
03055 doc->zoomItY( cellRect.bottom() ) );
03056 point.setPoint( 2, doc->zoomItX( cellRect.x() + 6.0 ),
03057 doc->zoomItY( cellRect.bottom() ) );
03058 }
03059
03060
03061 painter.setBrush( QBrush( penColor ) );
03062 painter.setPen( Qt::NoPen );
03063 painter.drawPolygon( point );
03064 }
03065 }
03066
03067
03068
03069
03070 void Cell::paintMoreTextIndicator( QPainter& painter,
03071 const KoRect &cellRect,
03072 QColor &backgroundColor )
03073 {
03074
03075
03076 if( testFlag( Flag_CellTooShortX ) &&
03077 !painter.device()->isExtDev() &&
03078 cellRect.height() > 4.0 &&
03079 cellRect.width() > 4.0 )
03080 {
03081 Doc* doc = sheet()->doc();
03082
03083 QColor penColor = Qt::red;
03084
03085 if ( qRed( backgroundColor.rgb() ) > 127
03086 && qGreen( backgroundColor.rgb() ) < 80
03087 && qBlue( backgroundColor.rgb() ) < 80 )
03088 {
03089 penColor = Qt::blue;
03090 }
03091
03092
03093 QPointArray point( 3 );
03094 if ( d->strOutText.isRightToLeft() ) {
03095 point.setPoint( 0, doc->zoomItX( cellRect.left() + 4.0 ),
03096 doc->zoomItY( cellRect.y() + cellRect.height() / 2.0 -4.0 ) );
03097 point.setPoint( 1, doc->zoomItX( cellRect.left() ),
03098 doc->zoomItY( cellRect.y() + cellRect.height() / 2.0 ));
03099 point.setPoint( 2, doc->zoomItX( cellRect.left() + 4.0 ),
03100 doc->zoomItY( cellRect.y() + cellRect.height() / 2.0 +4.0 ) );
03101 }
03102 else {
03103 point.setPoint( 0, doc->zoomItX( cellRect.right() - 4.0 ),
03104 doc->zoomItY( cellRect.y() + cellRect.height() / 2.0 - 4.0 ) );
03105 point.setPoint( 1, doc->zoomItX( cellRect.right() ),
03106 doc->zoomItY( cellRect.y() + cellRect.height() / 2.0 ) );
03107 point.setPoint( 2, doc->zoomItX( cellRect.right() - 4.0 ),
03108 doc->zoomItY( cellRect.y() + cellRect.height() / 2.0 + 4.0 ) );
03109 }
03110
03111
03112 painter.setBrush( QBrush( penColor ) );
03113 painter.setPen( Qt::NoPen );
03114 painter.drawPolygon( point );
03115 }
03116 }
03117
03118
03119
03120
03121 void Cell::paintText( QPainter& painter,
03122 const KoRect &cellRect,
03123 const QPoint &cellRef )
03124 {
03125 Doc *doc = sheet()->doc();
03126
03127 ColumnFormat *colFormat = format()->sheet()->columnFormat( cellRef.x() );
03128
03129 QColorGroup defaultColorGroup = QApplication::palette().active();
03130 QColor textColorPrint = effTextColor( cellRef.x(), cellRef.y() );
03131
03132
03133 if ( !textColorPrint.isValid() ) {
03134 if ( painter.device()->isExtDev() )
03135 textColorPrint = Qt::black;
03136 else
03137 textColorPrint = QApplication::palette().active().text();
03138 }
03139
03140 QPen tmpPen( textColorPrint );
03141
03142
03143 applyZoomedFont( painter, cellRef.x(), cellRef.y() );
03144
03145
03146 if ( !d->hasExtra()
03147 || !d->extra()->conditions
03148 || !d->extra()->conditions->matchedStyle() ) {
03149 if ( value().isNumber()
03150 && !( format()->sheet()->getShowFormula()
03151 && !( format()->sheet()->isProtected()
03152 && format()->isHideFormula( d->column, d->row ) ) ) )
03153 {
03154 double v = value().asFloat();
03155 if ( format()->floatColor( cellRef.x(), cellRef.y()) == Format::NegRed
03156 && v < 0.0 )
03157 tmpPen.setColor( Qt::red );
03158 }
03159 }
03160
03161
03162 if ( !link().isEmpty() ) {
03163 tmpPen.setColor( QApplication::palette().active().link() );
03164 QFont f = painter.font();
03165 f.setUnderline( true );
03166 painter.setFont( f );
03167 }
03168
03169 #if 0
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186 if ( selected && ( cellRef.x() != marker.x() || cellRef.y() != marker.y() ) )
03187 {
03188 QPen p( tmpPen );
03189 p.setColor( defaultColorGroup.highlightedText() );
03190 painter.setPen( p );
03191 }
03192 else {
03193 painter.setPen(tmpPen);
03194 }
03195 #endif
03196 painter.setPen( tmpPen );
03197
03198 QString tmpText = d->strOutText;
03199 double tmpHeight = d->textHeight;
03200 double tmpWidth = d->textWidth;
03201
03202
03203
03204
03205
03206
03207
03208 if ( testFlag( Flag_CellTooShortX ) ) {
03209 d->strOutText = textDisplaying( painter );
03210
03211
03212 textSize( painter );
03213 offsetAlign( column(), row() );
03214 }
03215
03216
03217 if ( format()->sheet()->getHideZero()
03218 && value().isNumber()
03219 && value().asFloat() == 0 ) {
03220 d->strOutText = QString::null;
03221 }
03222
03223
03224
03225
03226
03227
03228 if ( colFormat->isHide() || ( cellRect.height() <= 2 ) ) {
03229 freeAllObscuredCells();
03230
03231 d->strOutText = "";
03232 }
03233
03234 double indent = 0.0;
03235 double offsetCellTooShort = 0.0;
03236 int a = effAlignX();
03237
03238
03239 if ( a == Format::Left && !isEmpty() ) {
03240
03241
03242
03243
03244
03245 if ( d->hasExtra()
03246 && d->extra()->conditions
03247 && d->extra()->conditions->matchedStyle()
03248 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SIndent, true ) )
03249 indent = d->extra()->conditions->matchedStyle()->indent();
03250 else
03251 indent = format()->getIndent( column(), row() );
03252 }
03253
03254
03255 if ( a == Format::Right && !isEmpty() && testFlag( Flag_CellTooShortX ) )
03256 offsetCellTooShort = format()->sheet()->doc()->unzoomItX( 4 );
03257
03258 QFontMetrics fm2 = painter.fontMetrics();
03259 double offsetFont = 0.0;
03260
03261 if ( format()->alignY( column(), row() ) == Format::Bottom
03262 && format()->textFontUnderline( column(), row() ) )
03263 offsetFont = format()->sheet()->doc()->unzoomItX( fm2.underlinePos() + 1 );
03264
03265 int tmpAngle;
03266 bool tmpMultiRow;
03267 bool tmpVerticalText;
03268
03269
03270 if ( d->hasExtra()
03271 && d->extra()->conditions
03272 && d->extra()->conditions->matchedStyle() )
03273 {
03274 Style *matchedStyle = d->extra()->conditions->matchedStyle();
03275
03276 if ( matchedStyle->hasFeature( Style::SAngle, true ) )
03277 tmpAngle = d->extra()->conditions->matchedStyle()->rotateAngle();
03278 else
03279 tmpAngle = format()->getAngle( cellRef.x(), cellRef.y() );
03280
03281 if ( matchedStyle->hasFeature( Style::SVerticalText, true ) )
03282 tmpVerticalText = matchedStyle->hasProperty( Style::PVerticalText );
03283 else
03284 tmpVerticalText = format()->verticalText( cellRef.x(), cellRef.y() );
03285
03286 if ( matchedStyle->hasFeature( Style::SMultiRow, true ) )
03287 tmpMultiRow = matchedStyle->hasProperty( Style::PMultiRow );
03288 else
03289 tmpMultiRow = format()->multiRow( cellRef.x(), cellRef.y() );
03290 }
03291 else {
03292 tmpAngle = format()->getAngle( cellRef.x(), cellRef.y() );
03293 tmpVerticalText = format()->verticalText( cellRef.x(), cellRef.y() );
03294 tmpMultiRow = format()->multiRow( cellRef.x(), cellRef.y() );
03295 }
03296
03297
03298
03299
03300
03301
03302
03303 if ( !tmpMultiRow && !tmpVerticalText && !tmpAngle ) {
03304
03305
03306 painter.drawText( doc->zoomItX( indent + cellRect.x() + d->textX - offsetCellTooShort ),
03307 doc->zoomItY( cellRect.y() + d->textY - offsetFont ), d->strOutText );
03308 }
03309 else if ( tmpAngle != 0 ) {
03310
03311
03312 int angle = tmpAngle;
03313 QFontMetrics fm = painter.fontMetrics();
03314
03315 painter.rotate( angle );
03316 double x;
03317 if ( angle > 0 )
03318 x = indent + cellRect.x() + d->textX;
03319 else
03320 x = indent + cellRect.x() + d->textX
03321 - doc->unzoomItX((int) (( fm.descent() + fm.ascent() ) * sin( angle * M_PI / 180 )));
03322 double y;
03323 if ( angle > 0 )
03324 y = cellRect.y() + d->textY;
03325 else
03326 y = cellRect.y() + d->textY + d->textHeight;
03327 painter.drawText( doc->zoomItX( x * cos( angle * M_PI / 180 ) +
03328 y * sin( angle * M_PI / 180 ) ),
03329 doc->zoomItY( -x * sin( angle * M_PI / 180 ) +
03330 y * cos( angle * M_PI / 180 ) ),
03331 d->strOutText );
03332 painter.rotate( -angle );
03333 }
03334 else if ( tmpMultiRow && !tmpVerticalText ) {
03335
03336
03337 QString t;
03338 int i;
03339 int pos = 0;
03340 double dy = 0.0;
03341 QFontMetrics fm = painter.fontMetrics();
03342 do {
03343 i = d->strOutText.find( "\n", pos );
03344 if ( i == -1 )
03345 t = d->strOutText.mid( pos, d->strOutText.length() - pos );
03346 else {
03347 t = d->strOutText.mid( pos, i - pos );
03348 pos = i + 1;
03349 }
03350
03351 int align = effAlignX();
03352 if ( format()->sheet()->getShowFormula()
03353 && !( format()->sheet()->isProtected()
03354 && format()->isHideFormula( d->column, d->row ) ) )
03355 align = Format::Left;
03356
03357
03358 switch ( align ) {
03359 case Format::Left:
03360 d->textX = effLeftBorderPen( cellRef.x(), cellRef.y() ).width() + BORDER_SPACE;
03361 break;
03362
03363 case Format::Right:
03364 d->textX = cellRect.width() - BORDER_SPACE - doc->unzoomItX( fm.width( t ) )
03365 - effRightBorderPen( cellRef.x(), cellRef.y() ).width();
03366 break;
03367
03368 case Format::Center:
03369 d->textX = ( cellRect.width() - doc->unzoomItX( fm.width( t ) ) ) / 2;
03370 }
03371
03372 painter.drawText( doc->zoomItX( indent + cellRect.x() + d->textX ),
03373 doc->zoomItY( cellRect.y() + d->textY + dy ), t );
03374 dy += doc->unzoomItY( fm.descent() + fm.ascent() );
03375 } while ( i != -1 );
03376 }
03377 else if ( tmpVerticalText && !d->strOutText.isEmpty() ) {
03378
03379
03380 QString t;
03381 int i = 0;
03382 int len = 0;
03383 double dy = 0.0;
03384 QFontMetrics fm = painter.fontMetrics();
03385 do {
03386 len = d->strOutText.length();
03387 t = d->strOutText.at( i );
03388 painter.drawText( doc->zoomItX( indent + cellRect.x() + d->textX ),
03389 doc->zoomItY( cellRect.y() + d->textY + dy ), t );
03390 dy += doc->unzoomItY( fm.descent() + fm.ascent() );
03391 i++;
03392 } while ( i != len );
03393 }
03394
03395
03396 if ( testFlag( Flag_CellTooShortX ) ) {
03397 d->strOutText = tmpText;
03398 d->textHeight = tmpHeight;
03399 d->textWidth = tmpWidth;
03400 }
03401
03402 if ( format()->sheet()->getHideZero() && value().isNumber()
03403 && value().asFloat() == 0 )
03404 d->strOutText = tmpText;
03405
03406 if ( colFormat->isHide() || ( cellRect.height() <= 2 ) )
03407 d->strOutText = tmpText;
03408 }
03409
03410
03411
03412
03413 void Cell::paintPageBorders( QPainter& painter,
03414 const KoRect &cellRect,
03415 const QPoint &cellRef,
03416 bool paintBorderRight,
03417 bool paintBorderBottom )
03418 {
03419
03420 if ( painter.device()->isExtDev() )
03421 return;
03422
03423 if ( ! format()->sheet()->isShowPageBorders() )
03424 return;
03425
03426 SheetPrint* print = format()->sheet()->print();
03427
03428 Sheet::LayoutDirection sheetDir = format()->sheet()->layoutDirection();
03429
03430 Doc* doc = sheet()->doc();
03431 int zcellRect_left = doc->zoomItX (cellRect.left());
03432 int zcellRect_right = doc->zoomItX (cellRect.right());
03433 int zcellRect_top = doc->zoomItY (cellRect.top());
03434 int zcellRect_bottom = doc->zoomItY (cellRect.bottom());
03435
03436
03437
03438 if ( cellRef.x() >= print->printRange().left()
03439 && cellRef.x() <= print->printRange().right() + 1
03440 && cellRef.y() >= print->printRange().top()
03441 && cellRef.y() <= print->printRange().bottom() + 1 )
03442 {
03443 if ( print->isOnNewPageX( cellRef.x() )
03444 && cellRef.y() <= print->printRange().bottom() )
03445 {
03446 painter.setPen( sheet()->doc()->pageBorderColor() );
03447
03448 if ( sheetDir == Sheet::RightToLeft )
03449 painter.drawLine( zcellRect_right, zcellRect_top,
03450 zcellRect_right, zcellRect_bottom );
03451 else
03452 painter.drawLine( zcellRect_left, zcellRect_top,
03453 zcellRect_left, zcellRect_bottom );
03454 }
03455
03456 if ( print->isOnNewPageY( cellRef.y() ) &&
03457 ( cellRef.x() <= print->printRange().right() ) )
03458 {
03459 painter.setPen( sheet()->doc()->pageBorderColor() );
03460 painter.drawLine( zcellRect_left, zcellRect_top,
03461 zcellRect_right, zcellRect_top );
03462 }
03463
03464 if ( paintBorderRight ) {
03465 if ( print->isOnNewPageX( cellRef.x() + 1 )
03466 && cellRef.y() <= print->printRange().bottom() ) {
03467 painter.setPen( sheet()->doc()->pageBorderColor() );
03468
03469 if ( sheetDir == Sheet::RightToLeft )
03470 painter.drawLine( zcellRect_left, zcellRect_top,
03471 zcellRect_left, zcellRect_bottom );
03472 else
03473 painter.drawLine( zcellRect_right, zcellRect_top,
03474 zcellRect_right, zcellRect_bottom );
03475 }
03476 }
03477
03478 if ( paintBorderBottom ) {
03479 if ( print->isOnNewPageY( cellRef.y() + 1 )
03480 && cellRef.x() <= print->printRange().right() ) {
03481 painter.setPen( sheet()->doc()->pageBorderColor() );
03482 painter.drawLine( zcellRect_left, zcellRect_bottom,
03483 zcellRect_right, zcellRect_bottom );
03484 }
03485 }
03486 }
03487 }
03488
03489
03490
03491
03492 void Cell::paintCellBorders( QPainter& painter, const KoRect& rect,
03493 const KoRect &cellRect,
03494 const QPoint &cellRef,
03495 bool paintRight, bool paintBottom,
03496 bool paintLeft, bool paintTop,
03497 QPen & _rightPen, QPen & _bottomPen,
03498 QPen & _leftPen, QPen & _topPen )
03499 {
03500
03501
03502
03503 if ( (!paintLeft) && (!paintRight) && (!paintTop) && (!paintBottom) )
03504 return;
03505
03506 Doc * doc = sheet()->doc();
03507
03508 Sheet::LayoutDirection sheetDir = format()->sheet()->layoutDirection();
03509
03510
03511
03512
03513 int zrect_left (doc->zoomItX (rect.left()));
03514 int zrect_right (doc->zoomItX (rect.right()));
03515 int zrect_top (doc->zoomItY (rect.top()));
03516 int zrect_bottom (doc->zoomItY (rect.bottom()));
03517 int zcellRect_left (doc->zoomItX (cellRect.left()));
03518 int zcellRect_right (doc->zoomItX (cellRect.right()));
03519 int zcellRect_top (doc->zoomItY (cellRect.top()));
03520 int zcellRect_bottom (doc->zoomItY (cellRect.bottom()));
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533 if (d->hasExtra()) {
03534 QValueList<Cell*>::const_iterator it = d->extra()->obscuringCells.begin();
03535 QValueList<Cell*>::const_iterator end = d->extra()->obscuringCells.end();
03536 for ( ; it != end; ++it ) {
03537 Cell* cell = *it;
03538
03539 int xDiff = cellRef.x() - cell->column();
03540 int yDiff = cellRef.y() - cell->row();
03541 paintLeft = paintLeft && xDiff == 0;
03542 paintTop = paintTop && yDiff == 0;
03543
03544
03545
03546 paintRight = paintRight && cell->mergedXCells() == xDiff;
03547 paintBottom = paintBottom && cell->mergedYCells() == yDiff;
03548 }
03549 }
03550
03551
03552
03553 QPen leftPen( _leftPen );
03554 QPen rightPen( _rightPen );
03555 QPen topPen( _topPen );
03556 QPen bottomPen( _bottomPen );
03557
03558
03559
03560
03561 int left_penWidth = QMAX( 1, doc->zoomItX( leftPen.width() ) );
03562 int right_penWidth = QMAX( 1, doc->zoomItX( rightPen.width() ) );
03563 int top_penWidth = QMAX( 1, doc->zoomItY( topPen.width() ) );
03564 int bottom_penWidth = QMAX( 1, doc->zoomItY( bottomPen.width() ) );
03565
03566 leftPen.setWidth( left_penWidth );
03567 rightPen.setWidth( right_penWidth );
03568 topPen.setWidth( top_penWidth );
03569 bottomPen.setWidth( bottom_penWidth );
03570
03571 if ( paintLeft && leftPen.style() != Qt::NoPen ) {
03572 int top = ( QMAX( 0, -1 + top_penWidth ) ) / 2 +
03573 ( ( QMAX( 0, -1 + top_penWidth ) ) % 2 );
03574 int bottom = ( QMAX( 0, -1 + bottom_penWidth ) ) / 2 + 1;
03575
03576 painter.setPen( leftPen );
03577
03578
03579
03580
03581
03582 if ( painter.device()->isExtDev() ) {
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593 if ( sheetDir == Sheet::RightToLeft )
03594 painter.drawLine( QMIN( zrect_right, zcellRect_right ),
03595 QMAX( zrect_top, zcellRect_top - top ),
03596 QMIN( zrect_right, zcellRect_right ),
03597 QMIN( zrect_bottom, zcellRect_bottom + bottom ) );
03598 else
03599 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03600 QMAX( zrect_top, zcellRect_top - top ),
03601 QMAX( zrect_left, zcellRect_left ),
03602 QMIN( zrect_bottom, zcellRect_bottom + bottom ) );
03603 }
03604 else {
03605 if ( sheetDir == Sheet::RightToLeft )
03606 painter.drawLine( zcellRect_right,
03607 zcellRect_top - top,
03608 zcellRect_right,
03609 zcellRect_bottom + bottom );
03610 else
03611 painter.drawLine( zcellRect_left,
03612 zcellRect_top - top,
03613 zcellRect_left,
03614 zcellRect_bottom + bottom );
03615 }
03616 }
03617
03618 if ( paintRight && rightPen.style() != Qt::NoPen ) {
03619 int top = ( QMAX( 0, -1 + top_penWidth ) ) / 2 +
03620 ( ( QMAX( 0, -1 + top_penWidth ) ) % 2 );
03621 int bottom = ( QMAX( 0, -1 + bottom_penWidth ) ) / 2 + 1;
03622
03623 painter.setPen( rightPen );
03624
03625
03626
03627
03628
03629 if ( painter.device()->isExtDev() ) {
03630 if ( sheetDir == Sheet::RightToLeft )
03631 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03632 QMAX( zrect_top, zcellRect_top - top ),
03633 QMAX( zrect_left, zcellRect_left ),
03634 QMIN( zrect_bottom, zcellRect_bottom + bottom ) );
03635 else {
03636
03637
03638
03639
03640 if ( zcellRect_right <= zrect_right + right_penWidth / 2)
03641 painter.drawLine( zcellRect_right,
03642 QMAX( zrect_top, zcellRect_top - top ),
03643 zcellRect_right,
03644 QMIN( zrect_bottom, zcellRect_bottom + bottom ) );
03645 }
03646 }
03647 else {
03648 if ( sheetDir == Sheet::RightToLeft )
03649 painter.drawLine( zcellRect_left,
03650 zcellRect_top - top,
03651 zcellRect_left,
03652 zcellRect_bottom + bottom );
03653 else
03654 painter.drawLine( zcellRect_right,
03655 zcellRect_top - top,
03656 zcellRect_right,
03657 zcellRect_bottom + bottom );
03658 }
03659 }
03660
03661 if ( paintTop && topPen.style() != Qt::NoPen ) {
03662 painter.setPen( topPen );
03663
03664
03665
03666
03667
03668
03669
03670 if ( painter.device()->isExtDev() ) {
03671 if ( zcellRect_top >= zrect_top + top_penWidth / 2)
03672 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03673 zcellRect_top,
03674 QMIN( zrect_right, zcellRect_right ),
03675 zcellRect_top );
03676 }
03677 else {
03678 painter.drawLine( zcellRect_left, zcellRect_top,
03679 zcellRect_right, zcellRect_top );
03680 }
03681 }
03682
03683 if ( paintBottom && bottomPen.style() != Qt::NoPen ) {
03684 painter.setPen( bottomPen );
03685
03686
03687
03688
03689
03690
03691
03692 if ( painter.device()->isExtDev() ) {
03693 if ( zcellRect_bottom <= zrect_bottom + bottom_penWidth / 2)
03694 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03695 zcellRect_bottom,
03696 QMIN( zrect_right, zcellRect_right ),
03697 zcellRect_bottom );
03698 }
03699 else {
03700 painter.drawLine( zcellRect_left, zcellRect_bottom,
03701 zcellRect_right, zcellRect_bottom );
03702 }
03703 }
03704
03705
03706
03707
03708
03709
03710
03711 return;
03712
03713 #if 0
03714
03715
03716
03717
03718 QPen vert_pen, horz_pen;
03719 int vert_penWidth, horz_penWidth;
03720
03721
03722 Cell *cell_north = format()->sheet()->cellAt( cellRef.x(),
03723 cellRef.y() - 1 );
03724 Cell *cell_northwest = format()->sheet()->cellAt( cellRef.x() - 1,
03725 cellRef.y() - 1 );
03726 Cell *cell_west = format()->sheet()->cellAt( cellRef.x() - 1,
03727 cellRef.y() );
03728 Cell *cell_northeast = format()->sheet()->cellAt( cellRef.x() + 1,
03729 cellRef.y() - 1 );
03730 Cell *cell_east = format()->sheet()->cellAt( cellRef.x() + 1,
03731 cellRef.y() );
03732 Cell *cell_south = format()->sheet()->cellAt( cellRef.x(),
03733 cellRef.y() + 1 );
03734 Cell *cell_southwest = format()->sheet()->cellAt( cellRef.x() - 1,
03735 cellRef.y() + 1 );
03736 Cell *cell_southeast = format()->sheet()->cellAt( cellRef.x() + 1,
03737 cellRef.y() + 1 );
03738
03739
03740 if ( cell_north->effLeftBorderValue( cellRef.x(), cellRef.y() - 1 )
03741 >= cell_northwest->effRightBorderValue( cellRef.x() - 1, cellRef.y() - 1 ) )
03742 vert_pen = cell_north->effLeftBorderPen( cellRef.x(), cellRef.y() - 1 );
03743 else
03744 vert_pen = cell_northwest->effRightBorderPen( cellRef.x() - 1,
03745 cellRef.y() - 1 );
03746
03747 vert_penWidth = QMAX( 1, doc->zoomItX( vert_pen.width() ) );
03748 vert_pen.setWidth( vert_penWidth );
03749
03750 if ( vert_pen.style() != Qt::NoPen ) {
03751 if ( cell_west->effTopBorderValue( cellRef.x() - 1, cellRef.y() )
03752 >= cell_northwest->effBottomBorderValue( cellRef.x() - 1, cellRef.y() - 1 ) )
03753 horz_pen = cell_west->effTopBorderPen( cellRef.x() - 1, cellRef.y() );
03754 else
03755 horz_pen = cell_northwest->effBottomBorderPen( cellRef.x() - 1,
03756 cellRef.y() - 1 );
03757
03758 horz_penWidth = QMAX( 1, doc->zoomItY( horz_pen.width() ) );
03759 int bottom = ( QMAX( 0, -1 + horz_penWidth ) ) / 2 + 1;
03760
03761 painter.setPen( vert_pen );
03762
03763
03764 if ( painter.device()->isExtDev() ) {
03765 if ( sheetDir == Sheet::RightToLeft )
03766 painter.drawLine( QMAX( zrect_left, zcellRect_right ),
03767 QMAX( zrect_top, zcellRect_top ),
03768 QMIN( zrect_right, zcellRect_right ),
03769 QMIN( zrect_bottom, zcellRect_top + bottom ) );
03770 else
03771 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03772 QMAX( zrect_top, zcellRect_top ),
03773 QMIN( zrect_right, zcellRect_left ),
03774 QMIN( zrect_bottom, zcellRect_top + bottom ) );
03775 }
03776 else {
03777 if ( sheetDir == Sheet::RightToLeft )
03778 painter.drawLine( zcellRect_right, zcellRect_top,
03779 zcellRect_right, zcellRect_top + bottom );
03780 else
03781 painter.drawLine( zcellRect_left, zcellRect_top,
03782 zcellRect_left, zcellRect_top + bottom );
03783 }
03784 }
03785
03786
03787 if ( cell_north->effRightBorderValue( cellRef.x(), cellRef.y() - 1 )
03788 >= cell_northeast->effLeftBorderValue( cellRef.x() + 1,
03789 cellRef.y() - 1 ) )
03790 vert_pen = cell_north->effRightBorderPen( cellRef.x(), cellRef.y() - 1 );
03791 else
03792 vert_pen = cell_northeast->effLeftBorderPen( cellRef.x() + 1,
03793 cellRef.y() - 1 );
03794
03795
03796 vert_penWidth = QMAX( 1, doc->zoomItX( vert_pen.width() ) );
03797 vert_pen.setWidth( vert_penWidth );
03798 if ( ( vert_pen.style() != Qt::NoPen ) && ( cellRef.x() < KS_colMax ) ) {
03799 if ( cell_east->effTopBorderValue( cellRef.x() + 1, cellRef.y() )
03800 >= cell_northeast->effBottomBorderValue( cellRef.x() + 1,
03801 cellRef.y() - 1 ) )
03802 horz_pen = cell_east->effTopBorderPen( cellRef.x() + 1, cellRef.y() );
03803 else
03804 horz_pen = cell_northeast->effBottomBorderPen( cellRef.x() + 1,
03805 cellRef.y() - 1 );
03806
03807
03808 horz_penWidth = QMAX( 1, doc->zoomItY( horz_pen.width() ) );
03809 int bottom = ( QMAX( 0, -1 + horz_penWidth ) ) / 2 + 1;
03810
03811 painter.setPen( vert_pen );
03812
03813
03814 if ( painter.device()->isExtDev() ) {
03815 if ( sheetDir == Sheet::RightToLeft )
03816 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03817 QMAX( zrect_top, zcellRect_top ),
03818 QMIN( zrect_right, zcellRect_left ),
03819 QMIN( zrect_bottom, zcellRect_top + bottom ) );
03820 else
03821 painter.drawLine( QMAX( zrect_left, zcellRect_right ),
03822 QMAX( zrect_top, zcellRect_top ),
03823 QMIN( zrect_right, zcellRect_right ),
03824 QMIN( zrect_bottom, zcellRect_top + bottom ) );
03825 }
03826 else {
03827 if ( sheetDir == Sheet::RightToLeft )
03828 painter.drawLine( zcellRect_left, zcellRect_top,
03829 zcellRect_left, zcellRect_top + bottom );
03830 else
03831 painter.drawLine( zcellRect_right, zcellRect_top,
03832 zcellRect_right, zcellRect_top + bottom );
03833 }
03834 }
03835
03836
03837 if ( cellRef.y() < KS_rowMax ) {
03838
03839 if ( cell_south->effLeftBorderValue( cellRef.x(), cellRef.y() + 1 )
03840 >= cell_southwest->effRightBorderValue( cellRef.x() - 1,
03841 cellRef.y() + 1 ) )
03842 vert_pen = cell_south->effLeftBorderPen( cellRef.x(), cellRef.y() + 1 );
03843 else
03844 vert_pen = cell_southwest->effRightBorderPen( cellRef.x() - 1,
03845 cellRef.y() + 1 );
03846
03847
03848 vert_penWidth = QMAX( 1, doc->zoomItY( vert_pen.width() ) );
03849 vert_pen.setWidth( vert_penWidth );
03850 if ( vert_pen.style() != Qt::NoPen ) {
03851 if ( cell_west->effBottomBorderValue( cellRef.x() - 1, cellRef.y() )
03852 >= cell_southwest->effTopBorderValue( cellRef.x() - 1,
03853 cellRef.y() + 1 ) )
03854 horz_pen = cell_west->effBottomBorderPen( cellRef.x() - 1,
03855 cellRef.y() );
03856 else
03857 horz_pen = cell_southwest->effTopBorderPen( cellRef.x() - 1,
03858 cellRef.y() + 1 );
03859
03860
03861 horz_penWidth = QMAX( 1, doc->zoomItX( horz_pen.width() ) );
03862 int bottom = ( QMAX( 0, -1 + horz_penWidth ) ) / 2;
03863
03864 painter.setPen( vert_pen );
03865
03866
03867 if ( painter.device()->isExtDev() ) {
03868 if ( sheetDir == Sheet::RightToLeft )
03869 painter.drawLine( QMAX( zrect_left, zcellRect_right ),
03870 QMAX( zrect_top, zcellRect_bottom - bottom ),
03871 QMIN( zrect_right, zcellRect_right ),
03872 QMIN( zrect_bottom, zcellRect_bottom ) );
03873 else
03874 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03875 QMAX( zrect_top, zcellRect_bottom - bottom ),
03876 QMIN( zrect_right, zcellRect_left ),
03877 QMIN( zrect_bottom, zcellRect_bottom ) );
03878 }
03879 else {
03880 if ( sheetDir == Sheet::RightToLeft )
03881 painter.drawLine( zcellRect_right, zcellRect_bottom - bottom,
03882 zcellRect_right, zcellRect_bottom );
03883 else
03884 painter.drawLine( zcellRect_left, zcellRect_bottom - bottom,
03885 zcellRect_left, zcellRect_bottom );
03886 }
03887 }
03888
03889
03890 if ( cell_south->effRightBorderValue( cellRef.x(), cellRef.y() + 1 )
03891 >= cell_southeast->effLeftBorderValue( cellRef.x() + 1,
03892 cellRef.y() + 1 ) )
03893 vert_pen = cell_south->effRightBorderPen( cellRef.x(), cellRef.y() + 1 );
03894 else
03895 vert_pen = cell_southeast->effLeftBorderPen( cellRef.x() + 1,
03896 cellRef.y() + 1 );
03897
03898
03899 vert_penWidth = QMAX( 1, doc->zoomItY( vert_pen.width() ) );
03900 vert_pen.setWidth( vert_penWidth );
03901 if ( ( vert_pen.style() != Qt::NoPen ) && ( cellRef.x() < KS_colMax ) ) {
03902 if ( cell_east ->effBottomBorderValue( cellRef.x() + 1, cellRef.y() )
03903 >= cell_southeast->effTopBorderValue( cellRef.x() + 1,
03904 cellRef.y() + 1 ) )
03905
03906 horz_pen = format()->sheet()->cellAt( cellRef.x() + 1, cellRef.y() )
03907 ->effBottomBorderPen( cellRef.x() + 1, cellRef.y() );
03908 else
03909 horz_pen = format()->sheet()->cellAt( cellRef.x() + 1, cellRef.y() + 1 )
03910 ->effTopBorderPen( cellRef.x() + 1, cellRef.y() + 1 );
03911
03912
03913 horz_penWidth = QMAX( 1, doc->zoomItX( horz_pen.width() ) );
03914 int bottom = ( QMAX( 0, -1 + horz_penWidth ) ) / 2;
03915
03916 painter.setPen( vert_pen );
03917
03918
03919 if ( painter.device()->isExtDev() ) {
03920 if ( sheetDir == Sheet::RightToLeft )
03921 painter.drawLine( QMAX( zrect_left, zcellRect_left ),
03922 QMAX( zrect_top, zcellRect_bottom - bottom ),
03923 QMIN( zrect_right, zcellRect_left ),
03924 QMIN( zrect_bottom, zcellRect_bottom ) );
03925 else
03926 painter.drawLine( QMAX( zrect_left, zcellRect_right ),
03927 QMAX( zrect_top, zcellRect_bottom - bottom ),
03928 QMIN( zrect_right, zcellRect_right ),
03929 QMIN( zrect_bottom, zcellRect_bottom ) );
03930 }
03931 else {
03932 if ( sheetDir == Sheet::RightToLeft )
03933 painter.drawLine( zcellRect_left, zcellRect_bottom - bottom,
03934 zcellRect_left, zcellRect_bottom );
03935 else
03936 painter.drawLine( zcellRect_right, zcellRect_bottom - bottom,
03937 zcellRect_right, zcellRect_bottom );
03938 }
03939 }
03940 }
03941 #endif
03942 }
03943
03944
03945
03946
03947 void Cell::paintCellDiagonalLines( QPainter& painter,
03948 const KoRect &cellRect,
03949 const QPoint &cellRef )
03950 {
03951 if ( isPartOfMerged() )
03952 return;
03953
03954 Doc* doc = sheet()->doc();
03955
03956 if ( effFallDiagonalPen( cellRef.x(), cellRef.y() ).style() != Qt::NoPen ) {
03957 painter.setPen( effFallDiagonalPen( cellRef.x(), cellRef.y() ) );
03958 painter.drawLine( doc->zoomItX( cellRect.x() ),
03959 doc->zoomItY( cellRect.y() ),
03960 doc->zoomItX( cellRect.right() ),
03961 doc->zoomItY( cellRect.bottom() ) );
03962 }
03963
03964 if ( effGoUpDiagonalPen( cellRef.x(), cellRef.y() ).style() != Qt::NoPen ) {
03965 painter.setPen( effGoUpDiagonalPen( cellRef.x(), cellRef.y() ) );
03966 painter.drawLine( doc->zoomItX( cellRect.x() ),
03967 doc->zoomItY( cellRect.bottom() ),
03968 doc->zoomItX( cellRect.right() ),
03969 doc->zoomItY( cellRect.y() ) );
03970 }
03971 }
03972
03973
03974
03975
03976
03977
03978 int Cell::defineAlignX()
03979 {
03980 int a = format()->align( column(), row() );
03981 if ( a == Format::Undefined )
03982 {
03983
03984 if ((formatType() == Text_format) || value().isString())
03985 a = (d->strOutText.isRightToLeft()) ?
03986 Format::Right : Format::Left;
03987 else {
03988 Value val = value();
03989 while (val.isArray()) val = val.element (0, 0);
03990 if (val.isBoolean() || val.isNumber())
03991 a = Format::Right;
03992 else
03993 a = Format::Left;
03994 }
03995 }
03996 return a;
03997 }
03998
03999 int Cell::effAlignX()
04000 {
04001 if ( d->hasExtra() && d->extra()->conditions
04002 && d->extra()->conditions->matchedStyle()
04003 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SAlignX, true ) )
04004 return d->extra()->conditions->matchedStyle()->alignX();
04005
04006 return defineAlignX();
04007 }
04008
04009
04010
04011
04012
04013
04014 QString Cell::textDisplaying( QPainter &_painter )
04015 {
04016 QFontMetrics fm = _painter.fontMetrics();
04017 int a = format()->align( column(), row() );
04018
04019 bool isNumeric = value().isNumber();
04020
04021 if ( !format()->verticalText( column(),row() ) ) {
04022
04023
04024
04025 double len = 0.0;
04026 int extraXCells = d->hasExtra() ? d->extra()->extraXCells : 0;
04027
04028 for ( int i = column(); i <= column() + extraXCells; i++ ) {
04029 ColumnFormat *cl2 = format()->sheet()->columnFormat( i );
04030 len += cl2->dblWidth() - 1.0;
04031 }
04032
04033 QString tmp;
04034 double tmpIndent = 0.0;
04035 if ( !isEmpty() )
04036 tmpIndent = format()->getIndent( column(), row() );
04037
04038
04039
04040 for ( int i = d->strOutText.length(); i != 0; i-- )
04041 {
04042
04043
04044 if ( a == Format::Left || a == Format::Undefined || isNumeric)
04045 tmp = d->strOutText.left(i);
04046 else if ( a == Format::Right)
04047 tmp = d->strOutText.right(i);
04048 else
04049 tmp = d->strOutText.mid( ( d->strOutText.length() - i ) / 2, i);
04050
04051 if (isNumeric)
04052 {
04053
04054
04055
04056
04057
04058
04059 if (!tmp.contains('.'))
04060 d->strOutText=QString().fill('#',20);
04061 }
04062
04063
04064 if ( format()->sheet()->doc()->unzoomItX( fm.width( tmp ) ) + tmpIndent
04065 < len - 4.0 - 1.0 )
04066 {
04067 if ( format()->getAngle( column(), row() ) != 0 )
04068 {
04069 QString tmp2;
04070 RowFormat *rl = format()->sheet()->rowFormat( row() );
04071 if ( d->textHeight > rl->dblHeight() )
04072 {
04073 for ( int j = d->strOutText.length(); j != 0; j-- )
04074 {
04075 tmp2 = d->strOutText.left( j );
04076 if ( format()->sheet()->doc()->unzoomItY( fm.width( tmp2 ) ) < rl->dblHeight() - 1.0 )
04077 {
04078 return d->strOutText.left( QMIN( tmp.length(), tmp2.length() ) );
04079 }
04080 }
04081 }
04082 else
04083 return tmp;
04084
04085 }
04086 else
04087 return tmp;
04088 }
04089 }
04090 return QString( "" );
04091 }
04092 else if ( format()->verticalText( column(), row() ) ) {
04093
04094
04095 RowFormat *rl = format()->sheet()->rowFormat( row() );
04096 double tmpIndent = 0.0;
04097
04098
04099 double len = 0.0;
04100 int extraXCells = d->hasExtra() ? d->extra()->extraXCells : 0;
04101
04102 for ( int i = column(); i <= column() + extraXCells; i++ ) {
04103 ColumnFormat *cl2 = format()->sheet()->columnFormat( i );
04104
04105
04106 len += cl2->dblWidth() - 1.0;
04107 }
04108
04109 if ( !isEmpty() )
04110 tmpIndent = format()->getIndent( column(), row() );
04111
04112 if ( ( d->textWidth + tmpIndent > len ) || d->textWidth == 0.0 )
04113 return QString( "" );
04114
04115 for ( int i = d->strOutText.length(); i != 0; i-- ) {
04116 if ( format()->sheet()->doc()->unzoomItY( fm.ascent() + fm.descent() ) * i
04117 < rl->dblHeight() - 1.0 )
04118 return d->strOutText.left( i );
04119 }
04120
04121 return QString( "" );
04122 }
04123
04124 ColumnFormat *cl = format()->sheet()->columnFormat( column() );
04125 double w = cl->dblWidth();
04126
04127 if ( d->hasExtra() && (d->extra()->extraWidth != 0.0) )
04128 w = d->extra()->extraWidth;
04129
04130 QString tmp;
04131 for ( int i = d->strOutText.length(); i != 0; i-- ) {
04132 tmp = d->strOutText.left( i );
04133
04134
04135 if ( format()->sheet()->doc()->unzoomItX( fm.width( tmp ) ) < w - 4.0 - 1.0 )
04136 return tmp;
04137 }
04138
04139 return QString::null;
04140 }
04141
04142
04143 double Cell::dblWidth( int _col, const Canvas *_canvas ) const
04144 {
04145 if ( _col < 0 )
04146 _col = d->column;
04147
04148 if ( _canvas )
04149 {
04150 if ( testFlag(Flag_Merged) )
04151 return d->extra()->extraWidth;
04152
04153 const ColumnFormat *cl = format()->sheet()->columnFormat( _col );
04154 return cl->dblWidth( _canvas );
04155 }
04156
04157 if ( testFlag(Flag_Merged) )
04158 return d->extra()->extraWidth;
04159
04160 const ColumnFormat *cl = format()->sheet()->columnFormat( _col );
04161 return cl->dblWidth();
04162 }
04163
04164 int Cell::width( int _col, const Canvas *_canvas ) const
04165 {
04166 return int( dblWidth( _col, _canvas ) );
04167 }
04168
04169 double Cell::dblHeight( int _row, const Canvas *_canvas ) const
04170 {
04171 if ( _row < 0 )
04172 _row = d->row;
04173
04174 if ( _canvas )
04175 {
04176 if ( testFlag(Flag_Merged) )
04177 return d->extra()->extraHeight;
04178
04179 const RowFormat *rl = format()->sheet()->rowFormat( _row );
04180 return rl->dblHeight( _canvas );
04181 }
04182
04183 if ( testFlag(Flag_Merged) )
04184 return d->extra()->extraHeight;
04185
04186 const RowFormat *rl = format()->sheet()->rowFormat( _row );
04187 return rl->dblHeight();
04188 }
04189
04190 int Cell::height( int _row, const Canvas *_canvas ) const
04191 {
04192 return int( dblHeight( _row, _canvas ) );
04193 }
04194
04196
04197
04198
04199
04201
04202 const QBrush& Cell::backGroundBrush( int _col, int _row ) const
04203 {
04204 if ( d->hasExtra() && (!d->extra()->obscuringCells.isEmpty()) )
04205 {
04206 const Cell* cell = d->extra()->obscuringCells.first();
04207 return cell->backGroundBrush( cell->column(), cell->row() );
04208 }
04209
04210 return format()->backGroundBrush( _col, _row );
04211 }
04212
04213 const QColor& Cell::bgColor( int _col, int _row ) const
04214 {
04215 if ( d->hasExtra() && (!d->extra()->obscuringCells.isEmpty()) )
04216 {
04217 const Cell* cell = d->extra()->obscuringCells.first();
04218 return cell->bgColor( cell->column(), cell->row() );
04219 }
04220
04221 return format()->bgColor( _col, _row );
04222 }
04223
04225
04226
04227
04228
04230
04231 void Cell::setLeftBorderPen( const QPen& p )
04232 {
04233 if ( column() == 1 )
04234 {
04235 Cell* cell = format()->sheet()->cellAt( column() - 1, row() );
04236 if ( cell && cell->format()->hasProperty( Format::PRightBorder )
04237 && format()->sheet()->cellAt( column(), row() ) == this )
04238 cell->format()->clearProperty( Format::PRightBorder );
04239 }
04240
04241 format()->setLeftBorderPen( p );
04242 }
04243
04244 void Cell::setTopBorderPen( const QPen& p )
04245 {
04246 if ( row() == 1 )
04247 {
04248 Cell* cell = format()->sheet()->cellAt( column(), row() - 1 );
04249 if ( cell && cell->format()->hasProperty( Format::PBottomBorder )
04250 && format()->sheet()->cellAt( column(), row() ) == this )
04251 cell->format()->clearProperty( Format::PBottomBorder );
04252 }
04253 format()->setTopBorderPen( p );
04254 }
04255
04256 void Cell::setRightBorderPen( const QPen& p )
04257 {
04258 Cell* cell = 0L;
04259 if ( column() < KS_colMax )
04260 cell = format()->sheet()->cellAt( column() + 1, row() );
04261
04262 if ( cell && cell->format()->hasProperty( Format::PLeftBorder )
04263 && format()->sheet()->cellAt( column(), row() ) == this )
04264 cell->format()->clearProperty( Format::PLeftBorder );
04265
04266 format()->setRightBorderPen( p );
04267 }
04268
04269 void Cell::setBottomBorderPen( const QPen& p )
04270 {
04271 Cell* cell = 0L;
04272 if ( row() < KS_rowMax )
04273 cell = format()->sheet()->cellAt( column(), row() + 1 );
04274
04275 if ( cell && cell->format()->hasProperty( Format::PTopBorder )
04276 && format()->sheet()->cellAt( column(), row() ) == this )
04277 cell->format()->clearProperty( Format::PTopBorder );
04278
04279 format()->setBottomBorderPen( p );
04280 }
04281
04282 const QPen& Cell::rightBorderPen( int _col, int _row ) const
04283 {
04284 if ( !format()->hasProperty( Format::PRightBorder ) && ( _col < KS_colMax ) )
04285 {
04286 Cell * cell = format()->sheet()->cellAt( _col + 1, _row );
04287 if ( cell && cell->format()->hasProperty( Format::PLeftBorder ) )
04288 return cell->leftBorderPen( _col + 1, _row );
04289 }
04290
04291 return format()->rightBorderPen( _col, _row );
04292 }
04293
04294 const QPen& Cell::leftBorderPen( int _col, int _row ) const
04295 {
04296 if ( !format()->hasProperty( Format::PLeftBorder ) )
04297 {
04298 const Cell * cell = format()->sheet()->cellAt( _col - 1, _row );
04299 if ( cell && cell->format()->hasProperty( Format::PRightBorder ) )
04300 return cell->rightBorderPen( _col - 1, _row );
04301 }
04302
04303 return format()->leftBorderPen( _col, _row );
04304 }
04305
04306 const QPen& Cell::bottomBorderPen( int _col, int _row ) const
04307 {
04308 if ( !format()->hasProperty( Format::PBottomBorder ) && ( _row < KS_rowMax ) )
04309 {
04310 const Cell * cell = format()->sheet()->cellAt( _col, _row + 1 );
04311 if ( cell && cell->format()->hasProperty( Format::PTopBorder ) )
04312 return cell->topBorderPen( _col, _row + 1 );
04313 }
04314
04315 return format()->bottomBorderPen( _col, _row );
04316 }
04317
04318 const QPen& Cell::topBorderPen( int _col, int _row ) const
04319 {
04320 if ( !format()->hasProperty( Format::PTopBorder ) )
04321 {
04322 const Cell * cell = format()->sheet()->cellAt( _col, _row - 1 );
04323 if ( cell->format()->hasProperty( Format::PBottomBorder ) )
04324 return cell->bottomBorderPen( _col, _row - 1 );
04325 }
04326
04327 return format()->topBorderPen( _col, _row );
04328 }
04329
04330 const QColor & Cell::effTextColor( int col, int row ) const
04331 {
04332 if ( d->hasExtra() && d->extra()->conditions
04333 && d->extra()->conditions->matchedStyle()
04334 && d->extra()->conditions->matchedStyle()->hasFeature( Style::STextPen, true ) )
04335 return d->extra()->conditions->matchedStyle()->pen().color();
04336
04337 return format()->textColor( col, row );
04338 }
04339
04340 const QPen& Cell::effLeftBorderPen( int col, int row ) const
04341 {
04342 if ( isPartOfMerged() )
04343 {
04344 Cell * cell = d->extra()->obscuringCells.first();
04345 return cell->effLeftBorderPen( cell->column(), cell->row() );
04346 }
04347
04348 if ( d->hasExtra() && d->extra()->conditions
04349 && d->extra()->conditions->matchedStyle()
04350 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SLeftBorder, true ) )
04351 return d->extra()->conditions->matchedStyle()->leftBorderPen();
04352
04353 return format()->leftBorderPen( col, row );
04354 }
04355
04356 const QPen& Cell::effTopBorderPen( int col, int row ) const
04357 {
04358 if ( isPartOfMerged() )
04359 {
04360 Cell * cell = d->extra()->obscuringCells.first();
04361 return cell->effTopBorderPen( cell->column(), cell->row() );
04362 }
04363
04364 if ( d->hasExtra() && d->extra()->conditions
04365 && d->extra()->conditions->matchedStyle()
04366 && d->extra()->conditions->matchedStyle()->hasFeature( Style::STopBorder, true ) )
04367 return d->extra()->conditions->matchedStyle()->topBorderPen();
04368
04369 return format()->topBorderPen( col, row );
04370 }
04371
04372 const QPen& Cell::effRightBorderPen( int col, int row ) const
04373 {
04374 if ( isPartOfMerged() )
04375 {
04376 Cell * cell = d->extra()->obscuringCells.first();
04377 return cell->effRightBorderPen( cell->column(), cell->row() );
04378 }
04379
04380 if ( d->hasExtra() && d->extra()->conditions
04381 && d->extra()->conditions->matchedStyle()
04382 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SRightBorder, true ) )
04383 return d->extra()->conditions->matchedStyle()->rightBorderPen();
04384
04385 return format()->rightBorderPen( col, row );
04386 }
04387
04388 const QPen& Cell::effBottomBorderPen( int col, int row ) const
04389 {
04390 if ( isPartOfMerged() )
04391 {
04392 Cell * cell = d->extra()->obscuringCells.first();
04393 return cell->effBottomBorderPen( cell->column(), cell->row() );
04394 }
04395
04396 if ( d->hasExtra() && d->extra()->conditions
04397 && d->extra()->conditions->matchedStyle()
04398 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SBottomBorder, true ) )
04399 return d->extra()->conditions->matchedStyle()->bottomBorderPen();
04400
04401 return format()->bottomBorderPen( col, row );
04402 }
04403
04404 const QPen & Cell::effGoUpDiagonalPen( int col, int row ) const
04405 {
04406 if ( d->hasExtra() && d->extra()->conditions
04407 && d->extra()->conditions->matchedStyle()
04408 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SGoUpDiagonal, true ) )
04409 return d->extra()->conditions->matchedStyle()->goUpDiagonalPen();
04410
04411 return format()->goUpDiagonalPen( col, row );
04412 }
04413
04414 const QPen & Cell::effFallDiagonalPen( int col, int row ) const
04415 {
04416 if ( d->hasExtra() && d->extra()->conditions
04417 && d->extra()->conditions->matchedStyle()
04418 && d->extra()->conditions->matchedStyle()->hasFeature( Style::SFallDiagonal, true ) )
04419 return d->extra()->conditions->matchedStyle()->fallDiagonalPen();
04420
04421 return format()->fallDiagonalPen( col, row );
04422 }
04423
04424 uint Cell::effBottomBorderValue( int col, int row ) const
04425 {
04426 if ( isPartOfMerged() )
04427 {
04428 Cell * cell = d->extra()->obscuringCells.first();
04429 return cell->effBottomBorderValue( cell->column(), cell->row() );
04430 }
04431
04432 if ( d->hasExtra() && d->extra()->conditions
04433 && d->extra()->conditions->matchedStyle() )
04434 return d->extra()->conditions->matchedStyle()->bottomPenValue();
04435
04436 return format()->bottomBorderValue( col, row );
04437 }
04438
04439 uint Cell::effRightBorderValue( int col, int row ) const
04440 {
04441 if ( isPartOfMerged() )
04442 {
04443 Cell * cell = d->extra()->obscuringCells.first();
04444 return cell->effRightBorderValue( cell->column(), cell->row() );
04445 }
04446
04447 if ( d->hasExtra() && d->extra()->conditions
04448 && d->extra()->conditions->matchedStyle() )
04449 return d->extra()->conditions->matchedStyle()->rightPenValue();
04450
04451 return format()->rightBorderValue( col, row );
04452 }
04453
04454 uint Cell::effLeftBorderValue( int col, int row ) const
04455 {
04456 if ( isPartOfMerged() )
04457 {
04458 Cell * cell = d->extra()->obscuringCells.first();
04459 return cell->effLeftBorderValue( cell->column(), cell->row() );
04460 }
04461
04462 if ( d->hasExtra() && d->extra()->conditions
04463 && d->extra()->conditions->matchedStyle() )
04464 return d->extra()->conditions->matchedStyle()->leftPenValue();
04465
04466 return format()->leftBorderValue( col, row );
04467 }
04468
04469 uint Cell::effTopBorderValue( int col, int row ) const
04470 {
04471 if ( isPartOfMerged() )
04472 {
04473 Cell * cell = d->extra()->obscuringCells.first();
04474 return cell->effTopBorderValue( cell->column(), cell->row() );
04475 }
04476
04477 if ( d->hasExtra() && d->extra()->conditions
04478 && d->extra()->conditions->matchedStyle() )
04479 return d->extra()->conditions->matchedStyle()->topPenValue();
04480
04481 return format()->topBorderValue( col, row );
04482 }
04483
04485
04486
04487
04489
04490 void Cell::incPrecision()
04491 {
04492
04493
04494 if ( !value().isNumber() )
04495 return;
04496 int tmpPreci = format()->precision( column(), row() );
04497
04498 if ( tmpPreci == -1 )
04499 {
04500 int pos = d->strOutText.find(decimal_point);
04501 if ( pos == -1 )
04502 pos = d->strOutText.find('.');
04503 if ( pos == -1 )
04504 format()->setPrecision(1);
04505 else
04506 {
04507 int start = 0;
04508 if ( d->strOutText.find('%') != -1 )
04509 start = 2;
04510 else if ( d->strOutText.find(locale()->currencySymbol()) == ((int)(d->strOutText.length()-locale()->currencySymbol().length())) )
04511 start = locale()->currencySymbol().length() + 1;
04512 else if ( (start=d->strOutText.find('E')) != -1 )
04513 start = d->strOutText.length() - start;
04514
04515
04516 format()->setPrecision( QMAX( 0, (int)d->strOutText.length() - start - pos ) );
04517 }
04518 }
04519 else if ( tmpPreci < 10 )
04520 {
04521 format()->setPrecision( ++tmpPreci );
04522 }
04523 setFlag(Flag_LayoutDirty);
04524 }
04525
04526 void Cell::decPrecision()
04527 {
04528
04529
04530 if ( !value().isNumber() )
04531 return;
04532 int preciTmp = format()->precision( column(), row() );
04533
04534 if ( format()->precision(column(),row()) == -1 )
04535 {
04536 int pos = d->strOutText.find( decimal_point );
04537 int start = 0;
04538 if ( d->strOutText.find('%') != -1 )
04539 start = 2;
04540 else if ( d->strOutText.find(locale()->currencySymbol()) == ((int)(d->strOutText.length()-locale()->currencySymbol().length())) )
04541 start = locale()->currencySymbol().length() + 1;
04542 else if ( (start = d->strOutText.find('E')) != -1 )
04543 start = d->strOutText.length() - start;
04544 else
04545 start = 0;
04546
04547 if ( pos == -1 )
04548 return;
04549
04550 format()->setPrecision(d->strOutText.length() - pos - 2 - start);
04551
04552
04553 }
04554 else if ( preciTmp > 0 )
04555 {
04556 format()->setPrecision( --preciTmp );
04557 }
04558 setFlag( Flag_LayoutDirty );
04559 }
04560
04561
04562
04563 void Cell::setNumber( double number )
04564 {
04565 setValue( Value( number ) );
04566
04567 d->strText.setNum( number );
04568 setDisplayText(d->strText);
04569 checkNumberFormat();
04570 }
04571
04572 void Cell::setCellText( const QString& _text, bool asText )
04573 {
04574
04575
04576
04577
04578
04579
04580
04581 if (_text.length() == 0) {
04582 d->strOutText = d->strText = "";
04583 setValue (Value::empty());
04584 return;
04585 }
04586
04587
04588 if (asText) {
04589 d->strOutText = _text;
04590 d->strText = _text;
04591 setValue (Value (_text));
04592
04593 return;
04594 }
04595
04596 QString oldText = d->strText;
04597 setDisplayText( _text );
04598 if(!format()->sheet()->isLoading() && !testValidity() )
04599 {
04600
04601 setDisplayText( oldText );
04602 }
04603 }
04604
04605 void Cell::setDisplayText( const QString& _text )
04606 {
04607 bool isLoading = format()->sheet()->isLoading();
04608
04609 if (!isLoading)
04610 format()->sheet()->doc()->emitBeginOperation( false );
04611
04612 d->strText = _text;
04613
04617 if ( !d->strText.isEmpty() && d->strText[0] == '=' )
04618 {
04619 setFlag(Flag_LayoutDirty);
04620 setFlag(Flag_TextFormatDirty);
04621
04622 if ( !makeFormula() )
04623 kdError(36001) << "ERROR: Syntax ERROR" << endl;
04624 setCalcDirtyFlag ();
04625 }
04626
04630 else
04631 {
04632
04633 checkTextInput();
04634
04635 setFlag(Flag_LayoutDirty);
04636 setFlag(Flag_TextFormatDirty);
04637 }
04638
04639 if ( !isLoading )
04640 format()->sheet()->doc()->emitEndOperation( QRect( d->column, d->row, 1, 1 ) );
04641 }
04642
04643 void Cell::setLink( const QString& link )
04644 {
04645 d->extra()->link = link;
04646
04647 if( !link.isEmpty() && d->strText.isEmpty() )
04648 setCellText( link );
04649 }
04650
04651 QString Cell::link() const
04652 {
04653 return d->hasExtra() ? d->extra()->link : QString::null;
04654 }
04655
04656 void Cell::update()
04657 {
04658
04659
04660
04661
04662 for (int x = d->column; x <= d->column + extraXCells(); x++)
04663 {
04664 for (int y = d->row; y <= d->row + extraYCells(); y++)
04665 {
04666 Cell* cell = format()->sheet()->cellAt(x,y);
04667 cell->setLayoutDirtyFlag();
04668 }
04669 }
04670
04671 setCalcDirtyFlag();
04672
04673
04674 updateChart(true);
04675 }
04676
04677 bool Cell::testValidity() const
04678 {
04679 bool valid = false;
04680 if( d->hasExtra() && d->extra()->validity && d->extra()->validity->m_restriction != Restriction::None )
04681 {
04682
04683 if ( d->extra()->validity->allowEmptyCell && d->strText.isEmpty() )
04684 return true;
04685
04686 if( value().isNumber() &&
04687 (d->extra()->validity->m_restriction == Restriction::Number ||
04688 (d->extra()->validity->m_restriction == Restriction::Integer &&
04689 value().asFloat() == ceil(value().asFloat()))))
04690 {
04691 switch( d->extra()->validity->m_cond)
04692 {
04693 case Conditional::Equal:
04694 valid = ( value().asFloat() - d->extra()->validity->valMin < DBL_EPSILON
04695 && value().asFloat() - d->extra()->validity->valMin >
04696 (0.0 - DBL_EPSILON));
04697 break;
04698 case Conditional::DifferentTo:
04699 valid = !( ( value().asFloat() - d->extra()->validity->valMin < DBL_EPSILON
04700 && value().asFloat() - d->extra()->validity->valMin >
04701 (0.0 - DBL_EPSILON)) );
04702 break;
04703 case Conditional::Superior:
04704 valid = ( value().asFloat() > d->extra()->validity->valMin);
04705 break;
04706 case Conditional::Inferior:
04707 valid = ( value().asFloat() <d->extra()->validity->valMin);
04708 break;
04709 case Conditional::SuperiorEqual:
04710 valid = ( value().asFloat() >= d->extra()->validity->valMin);
04711 break;
04712 case Conditional::InferiorEqual:
04713 valid = (value().asFloat() <= d->extra()->validity->valMin);
04714 break;
04715 case Conditional::Between:
04716 valid = ( value().asFloat() >= d->extra()->validity->valMin &&
04717 value().asFloat() <= d->extra()->validity->valMax);
04718 break;
04719 case Conditional::Different:
04720 valid = (value().asFloat() < d->extra()->validity->valMin ||
04721 value().asFloat() > d->extra()->validity->valMax);
04722 break;
04723 default :
04724 break;
04725 }
04726 }
04727 else if(d->extra()->validity->m_restriction==Restriction::Text)
04728 {
04729 valid = value().isString();
04730 }
04731 else if ( d->extra()->validity->m_restriction == Restriction::List )
04732 {
04733
04734 if ( value().isString() && d->extra()->validity->listValidity.contains( value().asString() ) )
04735 valid = true;
04736 }
04737 else if(d->extra()->validity->m_restriction==Restriction::TextLength)
04738 {
04739 if( value().isString() )
04740 {
04741 int len = d->strOutText.length();
04742 switch( d->extra()->validity->m_cond)
04743 {
04744 case Conditional::Equal:
04745 if (len == d->extra()->validity->valMin)
04746 valid = true;
04747 break;
04748 case Conditional::DifferentTo:
04749 if (len != d->extra()->validity->valMin)
04750 valid = true;
04751 break;
04752 case Conditional::Superior:
04753 if(len > d->extra()->validity->valMin)
04754 valid = true;
04755 break;
04756 case Conditional::Inferior:
04757 if(len < d->extra()->validity->valMin)
04758 valid = true;
04759 break;
04760 case Conditional::SuperiorEqual:
04761 if(len >= d->extra()->validity->valMin)
04762 valid = true;
04763 break;
04764 case Conditional::InferiorEqual:
04765 if(len <= d->extra()->validity->valMin)
04766 valid = true;
04767 break;
04768 case Conditional::Between:
04769 if(len >= d->extra()->validity->valMin && len <= d->extra()->validity->valMax)
04770 valid = true;
04771 break;
04772 case Conditional::Different:
04773 if(len <d->extra()->validity->valMin || len >d->extra()->validity->valMax)
04774 valid = true;
04775 break;
04776 default :
04777 break;
04778 }
04779 }
04780 }
04781 else if(d->extra()->validity->m_restriction == Restriction::Time && isTime())
04782 {
04783 switch( d->extra()->validity->m_cond)
04784 {
04785 case Conditional::Equal:
04786 valid = (value().asTime() == d->extra()->validity->timeMin);
04787 break;
04788 case Conditional::DifferentTo:
04789 valid = (value().asTime() != d->extra()->validity->timeMin);
04790 break;
04791 case Conditional::Superior:
04792 valid = (value().asTime() > d->extra()->validity->timeMin);
04793 break;
04794 case Conditional::Inferior:
04795 valid = (value().asTime() < d->extra()->validity->timeMin);
04796 break;
04797 case Conditional::SuperiorEqual:
04798 valid = (value().asTime() >= d->extra()->validity->timeMin);
04799 break;
04800 case Conditional::InferiorEqual:
04801 valid = (value().asTime() <= d->extra()->validity->timeMin);
04802 break;
04803 case Conditional::Between:
04804 valid = (value().asTime() >= d->extra()->validity->timeMin &&
04805 value().asTime() <= d->extra()->validity->timeMax);
04806 break;
04807 case Conditional::Different:
04808 valid = (value().asTime() < d->extra()->validity->timeMin ||
04809 value().asTime() > d->extra()->validity->timeMax);
04810 break;
04811 default :
04812 break;
04813
04814 }
04815 }
04816 else if(d->extra()->validity->m_restriction == Restriction::Date && isDate())
04817 {
04818 switch( d->extra()->validity->m_cond)
04819 {
04820 case Conditional::Equal:
04821 valid = (value().asDate() == d->extra()->validity->dateMin);
04822 break;
04823 case Conditional::DifferentTo:
04824 valid = (value().asDate() != d->extra()->validity->dateMin);
04825 break;
04826 case Conditional::Superior:
04827 valid = (value().asDate() > d->extra()->validity->dateMin);
04828 break;
04829 case Conditional::Inferior:
04830 valid = (value().asDate() < d->extra()->validity->dateMin);
04831 break;
04832 case Conditional::SuperiorEqual:
04833 valid = (value().asDate() >= d->extra()->validity->dateMin);
04834 break;
04835 case Conditional::InferiorEqual:
04836 valid = (value().asDate() <= d->extra()->validity->dateMin);
04837 break;
04838 case Conditional::Between:
04839 valid = (value().asDate() >= d->extra()->validity->dateMin &&
04840 value().asDate() <= d->extra()->validity->dateMax);
04841 break;
04842 case Conditional::Different:
04843 valid = (value().asDate() < d->extra()->validity->dateMin ||
04844 value().asDate() > d->extra()->validity->dateMax);
04845 break;
04846 default :
04847 break;
04848
04849 }
04850 }
04851 }
04852 else
04853 {
04854 valid= true;
04855 }
04856
04857 if(!valid &&d->extra()->validity != NULL && d->extra()->validity->displayMessage)
04858 {
04859 switch (d->extra()->validity->m_action )
04860 {
04861 case Action::Stop:
04862 KMessageBox::error((QWidget*)0L, d->extra()->validity->message,
04863 d->extra()->validity->title);
04864 break;
04865 case Action::Warning:
04866 KMessageBox::warningYesNo((QWidget*)0L, d->extra()->validity->message,
04867 d->extra()->validity->title);
04868 break;
04869 case Action::Information:
04870 KMessageBox::information((QWidget*)0L, d->extra()->validity->message,
04871 d->extra()->validity->title);
04872 break;
04873 }
04874 }
04875 if (!d->hasExtra())
04876 return true;
04877 return (valid || d->extra()->validity == NULL || d->extra()->validity->m_action != Action::Stop);
04878 }
04879
04880 FormatType Cell::formatType() const
04881 {
04882 return format()->getFormatType( d->column, d->row );
04883 }
04884
04885 double Cell::textWidth() const
04886 {
04887 return d->textWidth;
04888 }
04889
04890 double Cell::textHeight() const
04891 {
04892 return d->textHeight;
04893 }
04894
04895 int Cell::mergedXCells() const
04896 {
04897 return d->hasExtra() ? d->extra()->mergedXCells : 0;
04898 }
04899
04900 int Cell::mergedYCells() const
04901 {
04902 return d->hasExtra() ? d->extra()->mergedYCells : 0;
04903 }
04904
04905 int Cell::extraXCells() const
04906 {
04907 return d->hasExtra() ? d->extra()->extraXCells : 0;
04908 }
04909
04910 int Cell::extraYCells() const
04911 {
04912 return d->hasExtra() ? d->extra()->extraYCells : 0;
04913 }
04914
04915 double Cell::extraWidth() const
04916 {
04917 return d->hasExtra() ? d->extra()->extraWidth : 0;
04918 }
04919
04920 double Cell::extraHeight() const
04921 {
04922 return d->hasExtra() ? d->extra()->extraHeight : 0;
04923 }
04924
04925
04926 bool Cell::isDate() const
04927 {
04928 FormatType ft = formatType();
04929
04930 return (formatIsDate (ft) || ((ft == Generic_format) &&
04931 (value().format() == Value::fmt_Date)));
04932 }
04933
04934 bool Cell::isTime() const
04935 {
04936 FormatType ft = formatType();
04937
04938 return (formatIsTime (ft) || ((ft == Generic_format) &&
04939 (value().format() == Value::fmt_Time)));
04940 }
04941
04942 void Cell::setCalcDirtyFlag()
04943 {
04944 if ( !isFormula() )
04945 {
04946
04947 clearFlag(Flag_CalcDirty);
04948 return;
04949 }
04950 setFlag(Flag_CalcDirty);
04951 format()->sheet()->setRegionPaintDirty(cellRect());
04952 }
04953
04954
04955 bool Cell::updateChart(bool refresh)
04956 {
04957
04958 if ( d->row != 0 && d->column != 0 )
04959 {
04960 CellBinding *bind;
04961 for ( bind = format()->sheet()->firstCellBinding(); bind != 0L; bind = format()->sheet()->nextCellBinding() )
04962 {
04963 if ( bind->contains( d->column, d->row ) )
04964 {
04965 if (!refresh)
04966 return true;
04967
04968 bind->cellChanged( this );
04969 }
04970 }
04971 return true;
04972 }
04973 return false;
04974
04975 }
04976
04977 double Cell::getDouble ()
04978 {
04979 if (isDefault())
04980 return 0.0;
04981
04982 if (isDate())
04983 {
04984 QDate date = value().asDate();
04985 QDate dummy (1900, 1, 1);
04986 return (dummy.daysTo (date) + 1);
04987 }
04988 if (isTime())
04989 {
04990 QTime time = value().asTime();
04991 QTime dummy;
04992 return dummy.secsTo( time );
04993 }
04994 if (value().isNumber())
04995 return value().asFloat();
04996
04997 return 0.0;
04998 }
04999
05000 void Cell::convertToDouble ()
05001 {
05002 if (isDefault())
05003 return;
05004
05005 setValue (getDouble ());
05006 }
05007
05008 void Cell::convertToPercent ()
05009 {
05010 if (isDefault())
05011 return;
05012
05013 setValue (getDouble ());
05014 d->value.setFormat (Value::fmt_Percent);
05015 }
05016
05017 void Cell::convertToMoney ()
05018 {
05019 if (isDefault())
05020 return;
05021
05022 setValue (getDouble ());
05023 d->value.setFormat (Value::fmt_Money);
05024 format()->setPrecision (locale()->fracDigits());
05025 }
05026
05027 void Cell::convertToTime ()
05028 {
05029
05030
05031
05032
05033 if (isDefault() || isEmpty())
05034 return;
05035
05036 setValue (getDouble ());
05037 QTime time = value().asDateTime().time();
05038 int msec = (int) ( (value().asFloat() - (int) value().asFloat()) * 1000 );
05039 time = time.addMSecs( msec );
05040 setCellText( time.toString() );
05041 }
05042
05043 void Cell::convertToDate ()
05044 {
05045
05046
05047
05048
05049 if (isDefault() || isEmpty())
05050 return;
05051
05052 setValue (getDouble ());
05053
05054
05055 QDate date(1900, 1, 1);
05056 date = date.addDays( (int) value().asFloat() - 1 );
05057 date = value().asDateTime().date();
05058 setCellText (locale()->formatDate (date, true));
05059 }
05060
05061 void Cell::checkTextInput()
05062 {
05063
05064 clearAllErrors();
05065
05066 d->value = Value::empty();
05067
05068
05069 QString str = d->strText;
05070
05071 sheet()->doc()->parser()->parse (str, this);
05072
05073
05074
05075 if (isTime() && (formatType() != Time_format7))
05076 d->strText = locale()->formatTime( value().asDateTime().time(), true);
05077
05078
05079 if (format()->sheet()->getFirstLetterUpper() && value().isString() &&
05080 (!d->strText.isEmpty()))
05081 {
05082 QString str = value().asString();
05083 setValue( Value( str[0].upper() + str.right( str.length()-1 ) ) );
05084 }
05085 }
05086
05087
05088 void Cell::checkNumberFormat()
05089 {
05090 if ( formatType() == Number_format && value().isNumber() )
05091 {
05092 if ( value().asFloat() > 1e+10 )
05093 format()->setFormatType( Scientific_format );
05094 }
05095 }
05096
05097
05098
05099
05100
05101
05102 QDomElement Cell::save( QDomDocument& doc,
05103 int _x_offset, int _y_offset,
05104 bool force, bool copy, bool era )
05105 {
05106
05107 QDomElement cell = doc.createElement( "cell" );
05108 cell.setAttribute( "row", d->row - _y_offset );
05109 cell.setAttribute( "column", d->column - _x_offset );
05110
05111
05112
05113 QDomElement formatElement = format()->save( doc, d->column, d->row, force, copy );
05114 if ( formatElement.hasChildNodes() || formatElement.attributes().length() )
05115 cell.appendChild( formatElement );
05116
05117 if ( doesMergeCells() )
05118 {
05119 if ( extraXCells() )
05120 formatElement.setAttribute( "colspan", extraXCells() );
05121 if ( extraYCells() )
05122 formatElement.setAttribute( "rowspan", extraYCells() );
05123 }
05124
05125 if ( d->hasExtra() && d->extra()->conditions )
05126 {
05127 QDomElement conditionElement = d->extra()->conditions->saveConditions( doc );
05128
05129 if ( !conditionElement.isNull() )
05130 cell.appendChild( conditionElement );
05131 }
05132
05133 if ( d->hasExtra() && (d->extra()->validity != 0) )
05134 {
05135 QDomElement validity = doc.createElement("validity");
05136
05137 QDomElement param=doc.createElement("param");
05138 param.setAttribute("cond",(int)d->extra()->validity->m_cond);
05139 param.setAttribute("action",(int)d->extra()->validity->m_action);
05140 param.setAttribute("allow",(int)d->extra()->validity->m_restriction);
05141 param.setAttribute("valmin",d->extra()->validity->valMin);
05142 param.setAttribute("valmax",d->extra()->validity->valMax);
05143 param.setAttribute("displaymessage",d->extra()->validity->displayMessage);
05144 param.setAttribute("displayvalidationinformation",d->extra()->validity->displayValidationInformation);
05145 param.setAttribute("allowemptycell",d->extra()->validity->allowEmptyCell);
05146 if ( !d->extra()->validity->listValidity.isEmpty() )
05147 param.setAttribute( "listvalidity", d->extra()->validity->listValidity.join( ";" ) );
05148 validity.appendChild(param);
05149 QDomElement title = doc.createElement( "title" );
05150 title.appendChild( doc.createTextNode( d->extra()->validity->title ) );
05151 validity.appendChild( title );
05152 QDomElement message = doc.createElement( "message" );
05153 message.appendChild( doc.createCDATASection( d->extra()->validity->message ) );
05154 validity.appendChild( message );
05155
05156 QDomElement inputTitle = doc.createElement( "inputtitle" );
05157 inputTitle.appendChild( doc.createTextNode( d->extra()->validity->titleInfo ) );
05158 validity.appendChild( inputTitle );
05159
05160 QDomElement inputMessage = doc.createElement( "inputmessage" );
05161 inputMessage.appendChild( doc.createTextNode( d->extra()->validity->messageInfo ) );
05162 validity.appendChild( inputMessage );
05163
05164
05165
05166 QString tmp;
05167 if ( d->extra()->validity->timeMin.isValid() )
05168 {
05169 QDomElement timeMin = doc.createElement( "timemin" );
05170 tmp=d->extra()->validity->timeMin.toString();
05171 timeMin.appendChild( doc.createTextNode( tmp ) );
05172 validity.appendChild( timeMin );
05173 }
05174 if ( d->extra()->validity->timeMax.isValid() )
05175 {
05176 QDomElement timeMax = doc.createElement( "timemax" );
05177 tmp=d->extra()->validity->timeMax.toString();
05178 timeMax.appendChild( doc.createTextNode( tmp ) );
05179 validity.appendChild( timeMax );
05180 }
05181
05182 if ( d->extra()->validity->dateMin.isValid() )
05183 {
05184 QDomElement dateMin = doc.createElement( "datemin" );
05185 QString tmp("%1/%2/%3");
05186 tmp = tmp.arg(d->extra()->validity->dateMin.year()).arg(d->extra()->validity->dateMin.month()).arg(d->extra()->validity->dateMin.day());
05187 dateMin.appendChild( doc.createTextNode( tmp ) );
05188 validity.appendChild( dateMin );
05189 }
05190 if ( d->extra()->validity->dateMax.isValid() )
05191 {
05192 QDomElement dateMax = doc.createElement( "datemax" );
05193 QString tmp("%1/%2/%3");
05194 tmp = tmp.arg(d->extra()->validity->dateMax.year()).arg(d->extra()->validity->dateMax.month()).arg(d->extra()->validity->dateMax.day());
05195 dateMax.appendChild( doc.createTextNode( tmp ) );
05196 validity.appendChild( dateMax );
05197 }
05198
05199 cell.appendChild( validity );
05200 }
05201
05202 if ( format()->comment() )
05203 {
05204 QDomElement comment = doc.createElement( "comment" );
05205 comment.appendChild( doc.createCDATASection( *format()->comment() ) );
05206 cell.appendChild( comment );
05207 }
05208
05209
05210
05211
05212 if ( !d->strText.isEmpty() )
05213 {
05214
05215
05216 if ( isFormula() )
05217 {
05218 QDomElement text = doc.createElement( "text" );
05219
05220 text.appendChild( doc.createTextNode( encodeFormula( era ) ) );
05221 cell.appendChild( text );
05222
05223
05224 QDomElement formulaResult = doc.createElement( "result" );
05225 saveCellResult( doc, formulaResult, d->strOutText );
05226 cell.appendChild( formulaResult );
05227
05228 }
05229 else if ( !link().isEmpty() )
05230 {
05231
05232
05233 QDomElement text = doc.createElement( "text" );
05234 QString qml = "!<a href=\"" + link() + "\">" + d->strText + "</a>";
05235 text.appendChild( doc.createCDATASection( qml ) );
05236 cell.appendChild( text );
05237 }
05238 else
05239 {
05240
05241 QDomElement text = doc.createElement( "text" );
05242 saveCellResult( doc, text, d->strText );
05243 cell.appendChild( text );
05244 }
05245 }
05246 if ( cell.hasChildNodes() || cell.attributes().length() > 2 )
05247
05248 return cell;
05249 else
05250 return QDomElement();
05251 }
05252
05253 bool Cell::saveCellResult( QDomDocument& doc, QDomElement& result,
05254 QString str )
05255 {
05256 QString dataType = "Other";
05257
05258 if ( value().isNumber() )
05259 {
05260 if ( isDate() )
05261 {
05262
05263 QDate dd = value().asDateTime().date();
05264 dataType = "Date";
05265 str = "%1/%2/%3";
05266 str = str.arg(dd.year()).arg(dd.month()).arg(dd.day());
05267 }
05268 else if( isTime() )
05269 {
05270
05271 dataType = "Time";
05272 str = value().asDateTime().time().toString();
05273 }
05274 else
05275 {
05276
05277 dataType = "Num";
05278 if (value().isInteger())
05279 str = QString::number(value().asInteger());
05280 else
05281 str = QString::number(value().asFloat(), 'g', DBL_DIG);
05282 }
05283 }
05284
05285 if ( value().isBoolean() )
05286 {
05287 dataType = "Bool";
05288 str = value().asBoolean() ? "true" : "false";
05289 }
05290
05291 if ( value().isString() )
05292 {
05293 dataType = "Str";
05294 str = value().asString();
05295 }
05296
05297 result.setAttribute( "dataType", dataType );
05298 if ( !d->strOutText.isEmpty() )
05299 result.setAttribute( "outStr", d->strOutText );
05300 result.appendChild( doc.createTextNode( str ) );
05301
05302 return true;
05303 }
05304
05305 void Cell::saveOasisAnnotation( KoXmlWriter &xmlwriter )
05306 {
05307 if ( format()->comment() )
05308 {
05309
05310 xmlwriter.startElement( "office:annotation" );
05311 QStringList text = QStringList::split( "\n", *format()->comment() );
05312 for ( QStringList::Iterator it = text.begin(); it != text.end(); ++it ) {
05313 xmlwriter.startElement( "text:p" );
05314 xmlwriter.addTextNode( *it );
05315 xmlwriter.endElement();
05316 }
05317 xmlwriter.endElement();
05318 }
05319 }
05320
05321
05322
05323 QString Cell::saveOasisCellStyle( KoGenStyle ¤tCellStyle, KoGenStyles &mainStyles )
05324 {
05325 if ( d->hasExtra() && d->extra()->conditions )
05326 {
05327
05328 currentCellStyle = KoGenStyle( Doc::STYLE_CELL_AUTO, "table-cell" );
05329 d->extra()->conditions->saveOasisConditions( currentCellStyle );
05330 }
05331 return format()->saveOasisCellStyle( currentCellStyle, mainStyles );
05332 }
05333
05334
05335 bool Cell::saveOasis( KoXmlWriter& xmlwriter, KoGenStyles &mainStyles,
05336 int row, int column, int &repeated,
05337 GenValidationStyles &valStyle )
05338 {
05339 if ( !isPartOfMerged() )
05340 xmlwriter.startElement( "table:table-cell" );
05341 else
05342 xmlwriter.startElement( "table:covered-table-cell" );
05343 #if 0
05344
05345 QFont font;
05346 Value const value( cell->value() );
05347 if ( !cell->isDefault() )
05348 {
05349 font = cell->format()->textFont( i, row );
05350 m_styles.addFont( font );
05351
05352 if ( cell->format()->hasProperty( Format::PComment ) )
05353 hasComment = true;
05354 }
05355 #endif
05356
05357 if ( link().isEmpty() )
05358 saveOasisValue (xmlwriter);
05359
05360 KoGenStyle currentCellStyle;
05361 saveOasisCellStyle( currentCellStyle,mainStyles );
05362
05363 if ( !currentCellStyle.isDefaultStyle() )
05364 xmlwriter.addAttribute( "table:style-name", mainStyles.styles()[currentCellStyle] );
05365
05366
05367 if ( isEmpty() && !format()->hasProperty( Format::PComment ) &&
05368 !isPartOfMerged() && !doesMergeCells() )
05369 {
05370 int j = column + 1;
05371 Cell *nextCell = format()->sheet()->getNextCellRight( column, row );
05372 while ( nextCell )
05373 {
05374 if ( nextCell->column() != j || !nextCell->isEmpty() )
05375 {
05376 if ( isDefault() )
05377 {
05378
05379
05380 repeated = nextCell->column() - j + 1;
05381 }
05382
05383
05384 break;
05385 }
05386
05387 KoGenStyle nextCellStyle;
05388 nextCell->saveOasisCellStyle( nextCellStyle,mainStyles );
05389
05390 if ( nextCell->isPartOfMerged() || nextCell->doesMergeCells() ||
05391 nextCell->format()->hasProperty( Format::PComment ) ||
05392 !(nextCellStyle == currentCellStyle) )
05393 {
05394 break;
05395 }
05396 ++repeated;
05397 nextCell = format()->sheet()->getNextCellRight( j++, row );
05398 }
05399 kdDebug() << "Cell::saveOasis: empty cell in column " << column << " "
05400 << "repeated " << repeated << " time(s)" << endl;
05401
05402 if ( repeated > 1 )
05403 xmlwriter.addAttribute( "table:number-columns-repeated", QString::number( repeated ) );
05404 }
05405
05406
05407 if (d->hasExtra() && d->extra()->validity)
05408 {
05409 GenValidationStyle styleVal(d->extra()->validity);
05410 xmlwriter.addAttribute( "table:validation-name", valStyle.lookup( styleVal ) );
05411 }
05412 if ( isFormula() )
05413 {
05414
05415 QString formula( convertFormulaToOasisFormat( text() ) );
05416 xmlwriter.addAttribute( "table:formula", formula );
05417 }
05418 else if ( !link().isEmpty() )
05419 {
05420
05421 xmlwriter.startElement( "text:p" );
05422 xmlwriter.startElement( "text:a" );
05423
05424 if ( localReferenceAnchor( link() ) )
05425 xmlwriter.addAttribute( " xlink:href", ( "#"+link() ) );
05426 else
05427 xmlwriter.addAttribute( " xlink:href", link() );
05428 xmlwriter.addTextNode( text() );
05429 xmlwriter.endElement();
05430 xmlwriter.endElement();
05431 }
05432
05433 if ( doesMergeCells() )
05434 {
05435 int colSpan = mergedXCells() + 1;
05436 int rowSpan = mergedYCells() + 1;
05437
05438 if ( colSpan > 1 )
05439 xmlwriter.addAttribute( "table:number-columns-spanned", QString::number( colSpan ) );
05440
05441 if ( rowSpan > 1 )
05442 xmlwriter.addAttribute( "table:number-rows-spanned", QString::number( rowSpan ) );
05443 }
05444
05445 if ( !isEmpty() && link().isEmpty() )
05446 {
05447 xmlwriter.startElement( "text:p" );
05448 xmlwriter.addTextNode(strOutText());
05449 xmlwriter.endElement();
05450 }
05451
05452 saveOasisAnnotation( xmlwriter );
05453
05454 xmlwriter.endElement();
05455 return true;
05456 }
05457
05458 void Cell::saveOasisValue (KoXmlWriter &xmlWriter)
05459 {
05460 switch (value().format())
05461 {
05462 case Value::fmt_None: break;
05463 case Value::fmt_Boolean:
05464 {
05465 xmlWriter.addAttribute( "office:value-type", "boolean" );
05466 xmlWriter.addAttribute( "office:boolean-value", ( value().asBoolean() ?
05467 "true" : "false" ) );
05468 break;
05469 }
05470 case Value::fmt_Number:
05471 {
05472 xmlWriter.addAttribute( "office:value-type", "float" );
05473 xmlWriter.addAttribute( "office:value", QString::number( value().asFloat() ) );
05474 break;
05475 }
05476 case Value::fmt_Percent:
05477 {
05478 xmlWriter.addAttribute( "office:value-type", "percentage" );
05479 xmlWriter.addAttribute( "office:value",
05480 QString::number( value().asFloat() ) );
05481 break;
05482 }
05483 case Value::fmt_Money:
05484 {
05485 xmlWriter.addAttribute( "office:value-type", "currency" );
05486
05487
05488
05489 xmlWriter.addAttribute( "office:value",
05490 QString::number( value().asFloat() ) );
05491 break;
05492 }
05493 case Value::fmt_DateTime: break;
05494 case Value::fmt_Date:
05495 {
05496 xmlWriter.addAttribute( "office:value-type", "date" );
05497 xmlWriter.addAttribute( "office:date-value",
05498 value().asDate().toString( Qt::ISODate ) );
05499 break;
05500 }
05501 case Value::fmt_Time:
05502 {
05503 xmlWriter.addAttribute( "office:value-type", "time" );
05504 xmlWriter.addAttribute( "office:time-value",
05505 value().asTime().toString( "PThhHmmMssS" ) );
05506 break;
05507 }
05508 case Value::fmt_String:
05509 {
05510 xmlWriter.addAttribute( "office:value-type", "string" );
05511 xmlWriter.addAttribute( "office:string-value", value().asString() );
05512 break;
05513 }
05514 };
05515 }
05516
05517 QString Cell::convertFormulaToOasisFormat( const QString & formula ) const
05518 {
05519 QString s;
05520 QRegExp exp("(\\$?)([a-zA-Z]+)(\\$?)([0-9]+)");
05521 int n = exp.search( formula, 0 );
05522 kdDebug() << "Exp: " << formula << ", n: " << n << ", Length: " << formula.length()
05523 << ", Matched length: " << exp.matchedLength() << endl;
05524
05525 bool inQuote1 = false;
05526 bool inQuote2 = false;
05527 int i = 0;
05528 int l = (int) formula.length();
05529 if ( l <= 0 )
05530 return formula;
05531 while ( i < l )
05532 {
05533 if ( ( n != -1 ) && ( n < i ) )
05534 {
05535 n = exp.search( formula, i );
05536 kdDebug() << "Exp: " << formula.right( l - i ) << ", n: " << n << endl;
05537 }
05538 if ( formula[i] == '"' )
05539 {
05540 inQuote1 = !inQuote1;
05541 s += formula[i];
05542 ++i;
05543 continue;
05544 }
05545 if ( formula[i] == '\'' )
05546 {
05547
05548 inQuote2 = !inQuote2;
05549 ++i;
05550 continue;
05551 }
05552 if ( inQuote1 || inQuote2 )
05553 {
05554 s += formula[i];
05555 ++i;
05556 continue;
05557 }
05558 if ( ( formula[i] == '=' ) && ( formula[i + 1] == '=' ) )
05559 {
05560 s += '=';
05561 ++i;++i;
05562 continue;
05563 }
05564 if ( formula[i] == '!' )
05565 {
05566 insertBracket( s );
05567 s += '.';
05568 ++i;
05569 continue;
05570 }
05571 if ( formula[i] == ',' )
05572 {
05573 s += '.';
05574 ++i;
05575 continue;
05576 }
05577 if ( n == i )
05578 {
05579 int ml = exp.matchedLength();
05580 if ( formula[ i + ml ] == '!' )
05581 {
05582 kdDebug() << "No cell ref but sheet name" << endl;
05583 s += formula[i];
05584 ++i;
05585 continue;
05586 }
05587 if ( ( i > 0 ) && ( formula[i - 1] != '!' ) )
05588 s += "[.";
05589 for ( int j = 0; j < ml; ++j )
05590 {
05591 s += formula[i];
05592 ++i;
05593 }
05594 s += ']';
05595 continue;
05596 }
05597
05598 s += formula[i];
05599 ++i;
05600 }
05601
05602 return s;
05603 }
05604
05605 void Cell::loadOasisConditional( QDomElement * style )
05606 {
05607
05608 if ( style )
05609 {
05610
05611 QDomElement e;
05612 forEachElement( e, style->toElement() )
05613 {
05614
05615 if ( e.localName() == "map" && e.namespaceURI() == KoXmlNS::style )
05616 {
05617 if (d->hasExtra())
05618 delete d->extra()->conditions;
05619 d->extra()->conditions = new Conditions( this );
05620 d->extra()->conditions->loadOasisConditions( e );
05621 d->extra()->conditions->checkMatches();
05622 break;
05623 }
05624 }
05625
05626 }
05627 }
05628
05629 bool Cell::loadOasis( const QDomElement& element , KoOasisLoadingContext& oasisContext , Style* style )
05630 {
05631 kdDebug() << "*** Loading cell properties ***** at " << column() << "," << row () << endl;
05632
05633 QString text;
05634 kdDebug()<<" table:style-name: "<<element.attributeNS( KoXmlNS::table, "style-name", QString::null )<<endl;
05635
05636 QDomElement* cellStyle=0;
05637
05638 if ( element.hasAttributeNS( KoXmlNS::table, "style-name" ) )
05639 {
05640 oasisContext.fillStyleStack( element, KoXmlNS::table, "styleName", "table-cell" );
05641
05642 QString str = element.attributeNS( KoXmlNS::table, "style-name", QString::null );
05643 cellStyle = const_cast<QDomElement*>( oasisContext.oasisStyles().findStyle( str, "table-cell" ) );
05644
05645 if ( cellStyle )
05646 loadOasisConditional( const_cast<QDomElement *>( cellStyle ) );
05647 }
05648
05649 if (style)
05650 {
05651 format()->setStyle( style );
05652 }
05653
05654
05655 loadOasisCellText( element );
05656
05657
05658
05659
05660 bool isFormula = false;
05661 if ( element.hasAttributeNS( KoXmlNS::table, "formula" ) )
05662 {
05663 kdDebug()<<" formula :"<<element.attributeNS( KoXmlNS::table, "formula", QString::null )<<endl;
05664 isFormula = true;
05665 QString oasisFormula( element.attributeNS( KoXmlNS::table, "formula", QString::null ) );
05666
05667 if (oasisFormula.startsWith( "oooc:" ) )
05668 oasisFormula= oasisFormula.mid( 5 );
05669 else if (oasisFormula.startsWith( "kspr:" ) )
05670 oasisFormula= oasisFormula.mid( 5 );
05671
05672 checkForNamedAreas( oasisFormula );
05673 oasisFormula = Oasis::decodeFormula( oasisFormula, locale() );
05674 setCellText( oasisFormula );
05675 }
05676 else if ( d->strText.at(0) == '=' )
05677 d->strText.prepend('\'');
05678
05679
05680
05681
05682 if ( element.hasAttributeNS( KoXmlNS::table, "validation-name" ) )
05683 {
05684 kdDebug()<<" validation-name: "<<element.attributeNS( KoXmlNS::table, "validation-name", QString::null )<<endl;
05685 loadOasisValidation( element.attributeNS( KoXmlNS::table, "validation-name", QString::null ) );
05686 }
05687
05688
05689
05690
05691 if( element.hasAttributeNS( KoXmlNS::office, "value-type" ) )
05692 {
05693 QString valuetype = element.attributeNS( KoXmlNS::office, "value-type", QString::null );
05694 kdDebug()<<" value-type: " << valuetype << endl;
05695 if( valuetype == "boolean" )
05696 {
05697 QString val = element.attributeNS( KoXmlNS::office, "boolean-value", QString::null ).lower();
05698 if( ( val == "true" ) || ( val == "false" ) )
05699 {
05700 bool value = val == "true";
05701 setValue( value );
05702 if (!isFormula) setCellText( value ? i18n("True") : i18n("False" ) );
05703 }
05704 }
05705
05706
05707 else if( valuetype == "float" )
05708 {
05709 bool ok = false;
05710 double value = element.attributeNS( KoXmlNS::office, "value", QString::null ).toDouble( &ok );
05711 if ( !isFormula )
05712 if( ok )
05713 setValue( value );
05714 }
05715
05716
05717 else if( valuetype == "currency" )
05718 {
05719 bool ok = false;
05720 double value = element.attributeNS( KoXmlNS::office, "value", QString::null ).toDouble( &ok );
05721 if( ok )
05722 {
05723 if ( !isFormula )
05724 setValue( value );
05725 format()->setCurrency( 1, element.attributeNS( KoXmlNS::office, "currency", QString::null ) );
05726 format()->setFormatType (Money_format);
05727 }
05728 }
05729 else if( valuetype == "percentage" )
05730 {
05731 bool ok = false;
05732 double value = element.attributeNS( KoXmlNS::office, "value", QString::null ).toDouble( &ok );
05733 if( ok )
05734 {
05735 if ( !isFormula )
05736 setValue( value );
05737 format()->setFormatType (Percentage_format);
05738 }
05739 }
05740 else if ( valuetype == "date" )
05741 {
05742 QString value = element.attributeNS( KoXmlNS::office, "value", QString::null );
05743 if ( value.isEmpty() )
05744 value = element.attributeNS( KoXmlNS::office, "date-value", QString::null );
05745 kdDebug() << "Type: date, value: " << value << endl;
05746
05747
05748 int year = 0, month = 0, day = 0;
05749 bool ok = false;
05750
05751 int p1 = value.find( '-' );
05752 if ( p1 > 0 )
05753 year = value.left( p1 ).toInt( &ok );
05754
05755 kdDebug() << "year: " << value.left( p1 ) << endl;
05756
05757 int p2 = value.find( '-', ++p1 );
05758
05759 if ( ok )
05760 month = value.mid( p1, p2 - p1 ).toInt( &ok );
05761
05762 kdDebug() << "month: " << value.mid( p1, p2 - p1 ) << endl;
05763
05764 if ( ok )
05765 day = value.right( value.length() - p2 - 1 ).toInt( &ok );
05766
05767 kdDebug() << "day: " << value.right( value.length() - p2 ) << endl;
05768
05769 if ( ok )
05770 {
05771 setValue( QDate( year, month, day ) );
05772 format()->setFormatType (ShortDate_format);
05773 kdDebug() << "Set QDate: " << year << " - " << month << " - " << day << endl;
05774 }
05775
05776 }
05777 else if ( valuetype == "time" )
05778 {
05779 QString value = element.attributeNS( KoXmlNS::office, "value", QString::null );
05780 if ( value.isEmpty() )
05781 value = element.attributeNS( KoXmlNS::office, "time-value", QString::null );
05782 kdDebug() << "Type: time: " << value << endl;
05783
05784 int hours = 0, minutes = 0, seconds = 0;
05785 int l = value.length();
05786 QString num;
05787 bool ok = false;
05788 for ( int i = 0; i < l; ++i )
05789 {
05790 if ( value[i].isNumber() )
05791 {
05792 num += value[i];
05793 continue;
05794 }
05795 else if ( value[i] == 'H' )
05796 hours = num.toInt( &ok );
05797 else if ( value[i] == 'M' )
05798 minutes = num.toInt( &ok );
05799 else if ( value[i] == 'S' )
05800 seconds = num.toInt( &ok );
05801 else
05802 continue;
05803
05804 kdDebug() << "Num: " << num << endl;
05805
05806 num = "";
05807 if ( !ok )
05808 break;
05809 }
05810 kdDebug() << "Hours: " << hours << ", " << minutes << ", " << seconds << endl;
05811
05812 if ( ok )
05813 {
05814
05815
05816 setValue( QTime( hours % 24, minutes, seconds ) );
05817 format()->setFormatType (Time_format);
05818 }
05819 }
05820 else if( valuetype == "string" )
05821 {
05822 QString value = element.attributeNS( KoXmlNS::office, "value", QString::null );
05823 if ( value.isEmpty() && element.hasAttributeNS( KoXmlNS::office, "string-value" ))
05824 {
05825
05826 value = element.attributeNS( KoXmlNS::office, "string-value", QString::null );
05827 setValue( value );
05828 }
05829 format()->setFormatType (Text_format);
05830 }
05831 else
05832 kdDebug()<<" type of value found : "<<valuetype<<endl;
05833 }
05834
05835
05836
05837
05838 int colSpan = 1;
05839 int rowSpan = 1;
05840 if ( element.hasAttributeNS( KoXmlNS::table, "number-columns-spanned" ) )
05841 {
05842 bool ok = false;
05843 int span = element.attributeNS( KoXmlNS::table, "number-columns-spanned", QString::null ).toInt( &ok );
05844 if( ok ) colSpan = span;
05845 }
05846 if ( element.hasAttributeNS( KoXmlNS::table, "number-rows-spanned" ) )
05847 {
05848 bool ok = false;
05849 int span = element.attributeNS( KoXmlNS::table, "number-rows-spanned", QString::null ).toInt( &ok );
05850 if( ok ) rowSpan = span;
05851 }
05852 if ( colSpan > 1 || rowSpan > 1 )
05853 mergeCells( d->column, d->row, colSpan - 1, rowSpan - 1 );
05854
05855
05856
05857
05858 QDomElement annotationElement = KoDom::namedItemNS( element, KoXmlNS::office, "annotation" );
05859 if ( !annotationElement.isNull() )
05860 {
05861 QString comment;
05862 QDomNode node = annotationElement.firstChild();
05863 while( !node.isNull() )
05864 {
05865 QDomElement commentElement = node.toElement();
05866 if( !commentElement.isNull() )
05867 if( commentElement.localName() == "p" && commentElement.namespaceURI() == KoXmlNS::text )
05868 {
05869 if( !comment.isEmpty() ) comment.append( '\n' );
05870 comment.append( commentElement.text() );
05871 }
05872
05873 node = node.nextSibling();
05874 }
05875
05876 if( !comment.isEmpty() )
05877 format()->setComment( comment );
05878 }
05879
05880 QDomElement frame = KoDom::namedItemNS( element, KoXmlNS::draw, "frame" );
05881 if ( !frame.isNull() )
05882 loadOasisObjects( frame, oasisContext );
05883
05884 if (isFormula)
05885 setCalcDirtyFlag ();
05886
05887 return true;
05888 }
05889
05890 void Cell::loadOasisCellText( const QDomElement& parent )
05891 {
05892
05893 QDomElement textParagraphElement;
05894 QString cellText;
05895
05896 bool multipleTextParagraphsFound=false;
05897
05898 forEachElement( textParagraphElement , parent )
05899 {
05900 if ( textParagraphElement.localName()=="p" &&
05901 textParagraphElement.namespaceURI()== KoXmlNS::text )
05902 {
05903
05904 if (cellText.isEmpty())
05905 cellText = textParagraphElement.text();
05906 else
05907 {
05908 cellText += "\n"+textParagraphElement.text();
05909 multipleTextParagraphsFound=true;
05910 }
05911
05912 QDomElement textA = KoDom::namedItemNS( textParagraphElement, KoXmlNS::text, "a" );
05913 if( !textA.isNull() )
05914 {
05915 if ( textA.hasAttributeNS( KoXmlNS::xlink, "href" ) )
05916 {
05917 QString link = textA.attributeNS( KoXmlNS::xlink, "href", QString::null );
05918 cellText = textA.text();
05919 setCellText( cellText );
05920 setValue( cellText );
05921 if ( link[0]=='#' )
05922 link=link.remove( 0, 1 );
05923 setLink( link );
05924 }
05925 }
05926 }
05927 }
05928
05929 if (!cellText.isNull())
05930 {
05931 setCellText( cellText );
05932 setValue( cellText );
05933 }
05934
05935
05936 if ( multipleTextParagraphsFound )
05937 {
05938 format()->setMultiRow(true);
05939 }
05940 }
05941
05942 void Cell::loadOasisObjects( const QDomElement &parent, KoOasisLoadingContext& oasisContext )
05943 {
05944 for( QDomElement e = parent; !e.isNull(); e = e.nextSibling().toElement() )
05945 {
05946 if ( e.localName() == "frame" && e.namespaceURI() == KoXmlNS::draw )
05947 {
05948 EmbeddedObject *obj = 0;
05949 QDomNode object = KoDom::namedItemNS( e, KoXmlNS::draw, "object" );
05950 if ( !object.isNull() )
05951 {
05952 if ( !object.toElement().attributeNS( KoXmlNS::draw, "notify-on-update-of-ranges", QString::null).isNull() )
05953 obj = new EmbeddedChart( sheet()->doc(), sheet() );
05954 else
05955 obj = new EmbeddedKOfficeObject( sheet()->doc(), sheet() );
05956 }
05957 else
05958 {
05959 QDomNode image = KoDom::namedItemNS( e, KoXmlNS::draw, "image" );
05960 if ( !image.isNull() )
05961 obj = new EmbeddedPictureObject( sheet(), sheet()->doc()->pictureCollection() );
05962 else
05963 kdDebug() << "Object type wasn't loaded!" << endl;
05964 }
05965
05966 if ( obj )
05967 {
05968 obj->loadOasis( e, oasisContext );
05969 sheet()->doc()->insertObject( obj );
05970
05971 QString ref = e.attributeNS( KoXmlNS::table, "end-cell-address", QString::null );
05972 if ( ref.isNull() )
05973 continue;
05974
05975 ref = Oasis::decodeFormula( ref );
05976 Point point( ref );
05977 if ( !point.isValid() )
05978 continue;
05979
05980 KoRect geometry = obj->geometry();
05981 geometry.setLeft( geometry.left() + sheet()->columnPos( d->column, 0 ) );
05982 geometry.setTop( geometry.top() + sheet()->rowPos( d->row, 0 ) );
05983
05984 QString str = e.attributeNS( KoXmlNS::table, "end-x", QString::null );
05985 if ( !str.isNull() )
05986 {
05987 uint end_x = (uint) KoUnit::parseValue( str );
05988 geometry.setRight( sheet()->columnPos( point.column(), 0) + end_x );
05989 }
05990
05991 str = e.attributeNS( KoXmlNS::table, "end-y", QString::null );
05992 if ( !str.isNull() )
05993 {
05994 uint end_y = (uint) KoUnit::parseValue( str );
05995 geometry.setBottom( sheet()->rowPos( point.row(), 0) + end_y );
05996 }
05997
05998 obj->setGeometry( geometry );
05999 }
06000 }
06001 }
06002 }
06003
06004 void Cell::loadOasisValidation( const QString& validationName )
06005 {
06006 QDomElement element = sheet()->doc()->loadingInfo()->validation( validationName);
06007 if (d->hasExtra())
06008 delete d->extra()->validity;
06009 d->extra()->validity = new Validity;
06010 if ( element.hasAttributeNS( KoXmlNS::table, "condition" ) )
06011 {
06012 QString valExpression = element.attributeNS( KoXmlNS::table, "condition", QString::null );
06013 kdDebug()<<" element.attribute( table:condition ) "<<valExpression<<endl;
06014
06015
06016
06017
06018
06019
06020
06021
06022
06023
06024
06025
06026
06027 if ( valExpression.contains( "cell-content-text-length()" ) )
06028 {
06029
06030 valExpression = valExpression.remove("oooc:cell-content-text-length()" );
06031 kdDebug()<<" valExpression = :"<<valExpression<<endl;
06032 d->extra()->validity->m_restriction = Restriction::TextLength;
06033
06034 loadOasisValidationCondition( valExpression );
06035 }
06036 else if ( valExpression.contains( "cell-content-is-text()" ) )
06037 {
06038 d->extra()->validity->m_restriction = Restriction::Text;
06039 }
06040
06041 else if ( valExpression.contains( "cell-content-text-length-is-between" ) )
06042 {
06043 d->extra()->validity->m_restriction = Restriction::TextLength;
06044 d->extra()->validity->m_cond = Conditional::Between;
06045 valExpression = valExpression.remove( "oooc:cell-content-text-length-is-between(" );
06046 kdDebug()<<" valExpression :"<<valExpression<<endl;
06047 valExpression = valExpression.remove( ")" );
06048 QStringList listVal = QStringList::split( ",", valExpression );
06049 loadOasisValidationValue( listVal );
06050 }
06051 else if ( valExpression.contains( "cell-content-text-length-is-not-between" ) )
06052 {
06053 d->extra()->validity->m_restriction = Restriction::TextLength;
06054 d->extra()->validity->m_cond = Conditional::Different;
06055 valExpression = valExpression.remove( "oooc:cell-content-text-length-is-not-between(" );
06056 kdDebug()<<" valExpression :"<<valExpression<<endl;
06057 valExpression = valExpression.remove( ")" );
06058 kdDebug()<<" valExpression :"<<valExpression<<endl;
06059 QStringList listVal = QStringList::split( ",", valExpression );
06060 loadOasisValidationValue( listVal );
06061 }
06062 else if ( valExpression.contains( "cell-content-is-in-list(" ) )
06063 {
06064 d->extra()->validity->m_restriction = Restriction::List;
06065 valExpression = valExpression.remove( "oooc:cell-content-is-in-list(" );
06066 kdDebug()<<" valExpression :"<<valExpression<<endl;
06067 valExpression = valExpression.remove( ")" );
06068 d->extra()->validity->listValidity = QStringList::split( ";", valExpression );
06069
06070 }
06071
06072 else
06073 {
06074 if (valExpression.contains( "cell-content-is-whole-number()" ) )
06075 {
06076 d->extra()->validity->m_restriction = Restriction::Number;
06077 valExpression = valExpression.remove( "oooc:cell-content-is-whole-number() and " );
06078 }
06079 else if (valExpression.contains( "cell-content-is-decimal-number()" ) )
06080 {
06081 d->extra()->validity->m_restriction = Restriction::Integer;
06082 valExpression = valExpression.remove( "oooc:cell-content-is-decimal-number() and " );
06083 }
06084 else if (valExpression.contains( "cell-content-is-date()" ) )
06085 {
06086 d->extra()->validity->m_restriction = Restriction::Date;
06087 valExpression = valExpression.remove( "oooc:cell-content-is-date() and " );
06088 }
06089 else if (valExpression.contains( "cell-content-is-time()" ) )
06090 {
06091 d->extra()->validity->m_restriction = Restriction::Time;
06092 valExpression = valExpression.remove( "oooc:cell-content-is-time() and " );
06093 }
06094 kdDebug()<<"valExpression :"<<valExpression<<endl;
06095
06096 if ( valExpression.contains( "cell-content()" ) )
06097 {
06098 valExpression = valExpression.remove( "cell-content()" );
06099 loadOasisValidationCondition( valExpression );
06100 }
06101
06102
06103 if ( valExpression.contains( "cell-content-is-between(" ) )
06104 {
06105 valExpression = valExpression.remove( "cell-content-is-between(" );
06106 valExpression = valExpression.remove( ")" );
06107 QStringList listVal = QStringList::split( "," , valExpression );
06108 loadOasisValidationValue( listVal );
06109 d->extra()->validity->m_cond = Conditional::Between;
06110 }
06111 if ( valExpression.contains( "cell-content-is-not-between(" ) )
06112 {
06113 valExpression = valExpression.remove( "cell-content-is-not-between(" );
06114 valExpression = valExpression.remove( ")" );
06115 QStringList listVal = QStringList::split( ",", valExpression );
06116 loadOasisValidationValue( listVal );
06117 d->extra()->validity->m_cond = Conditional::Different;
06118 }
06119 }
06120 }
06121 if ( element.hasAttributeNS( KoXmlNS::table, "allow-empty-cell" ) )
06122 {
06123 kdDebug()<<" element.hasAttribute( table:allow-empty-cell ) :"<<element.hasAttributeNS( KoXmlNS::table, "allow-empty-cell" )<<endl;
06124 d->extra()->validity->allowEmptyCell = ( ( element.attributeNS( KoXmlNS::table, "allow-empty-cell", QString::null )=="true" ) ? true : false );
06125 }
06126 if ( element.hasAttributeNS( KoXmlNS::table, "base-cell-address" ) )
06127 {
06128
06129 }
06130
06131 QDomElement help = KoDom::namedItemNS( element, KoXmlNS::table, "help-message" );
06132 if ( !help.isNull() )
06133 {
06134 if ( help.hasAttributeNS( KoXmlNS::table, "title" ) )
06135 {
06136 kdDebug()<<"help.attribute( table:title ) :"<<help.attributeNS( KoXmlNS::table, "title", QString::null )<<endl;
06137 d->extra()->validity->titleInfo = help.attributeNS( KoXmlNS::table, "title", QString::null );
06138 }
06139 if ( help.hasAttributeNS( KoXmlNS::table, "display" ) )
06140 {
06141 kdDebug()<<"help.attribute( table:display ) :"<<help.attributeNS( KoXmlNS::table, "display", QString::null )<<endl;
06142 d->extra()->validity->displayValidationInformation = ( ( help.attributeNS( KoXmlNS::table, "display", QString::null )=="true" ) ? true : false );
06143 }
06144 QDomElement attrText = KoDom::namedItemNS( help, KoXmlNS::text, "p" );
06145 if ( !attrText.isNull() )
06146 {
06147 kdDebug()<<"help text :"<<attrText.text()<<endl;
06148 d->extra()->validity->messageInfo = attrText.text();
06149 }
06150 }
06151
06152 QDomElement error = KoDom::namedItemNS( element, KoXmlNS::table, "error-message" );
06153 if ( !error.isNull() )
06154 {
06155 if ( error.hasAttributeNS( KoXmlNS::table, "title" ) )
06156 d->extra()->validity->title = error.attributeNS( KoXmlNS::table, "title", QString::null );
06157 if ( error.hasAttributeNS( KoXmlNS::table, "message-type" ) )
06158 {
06159 QString str = error.attributeNS( KoXmlNS::table, "message-type", QString::null );
06160 if ( str == "warning" )
06161 d->extra()->validity->m_action = Action::Warning;
06162 else if ( str == "information" )
06163 d->extra()->validity->m_action = Action::Information;
06164 else if ( str == "stop" )
06165 d->extra()->validity->m_action = Action::Stop;
06166 else
06167 kdDebug()<<"validation : message type unknown :"<<str<<endl;
06168 }
06169
06170 if ( error.hasAttributeNS( KoXmlNS::table, "display" ) )
06171 {
06172 kdDebug()<<" display message :"<<error.attributeNS( KoXmlNS::table, "display", QString::null )<<endl;
06173 d->extra()->validity->displayMessage = (error.attributeNS( KoXmlNS::table, "display", QString::null )=="true");
06174 }
06175 QDomElement attrText = KoDom::namedItemNS( error, KoXmlNS::text, "p" );
06176 if ( !attrText.isNull() )
06177 d->extra()->validity->message = attrText.text();
06178 }
06179 }
06180
06181
06182 void Cell::loadOasisValidationValue( const QStringList &listVal )
06183 {
06184 bool ok = false;
06185 kdDebug()<<" listVal[0] :"<<listVal[0]<<" listVal[1] :"<<listVal[1]<<endl;
06186
06187 if ( d->extra()->validity->m_restriction == Restriction::Date )
06188 {
06189 d->extra()->validity->dateMin = QDate::fromString( listVal[0] );
06190 d->extra()->validity->dateMax = QDate::fromString( listVal[1] );
06191 }
06192 else if ( d->extra()->validity->m_restriction == Restriction::Time )
06193 {
06194 d->extra()->validity->timeMin = QTime::fromString( listVal[0] );
06195 d->extra()->validity->timeMax = QTime::fromString( listVal[1] );
06196 }
06197 else
06198 {
06199 d->extra()->validity->valMin = listVal[0].toDouble(&ok);
06200 if ( !ok )
06201 {
06202 d->extra()->validity->valMin = listVal[0].toInt(&ok);
06203 if ( !ok )
06204 kdDebug()<<" Try to parse this value :"<<listVal[0]<<endl;
06205
06206 #if 0
06207 if ( !ok )
06208 d->extra()->validity->valMin = listVal[0];
06209 #endif
06210 }
06211 ok=false;
06212 d->extra()->validity->valMax = listVal[1].toDouble(&ok);
06213 if ( !ok )
06214 {
06215 d->extra()->validity->valMax = listVal[1].toInt(&ok);
06216 if ( !ok )
06217 kdDebug()<<" Try to parse this value :"<<listVal[1]<<endl;
06218
06219 #if 0
06220 if ( !ok )
06221 d->extra()->validity->valMax = listVal[1];
06222 #endif
06223 }
06224 }
06225 }
06226
06227 void Cell::loadOasisValidationCondition( QString &valExpression )
06228 {
06229 QString value;
06230 if (valExpression.find( "<=" )==0 )
06231 {
06232 value = valExpression.remove( 0,2 );
06233 d->extra()->validity->m_cond = Conditional::InferiorEqual;
06234 }
06235 else if (valExpression.find( ">=" )==0 )
06236 {
06237 value = valExpression.remove( 0,2 );
06238 d->extra()->validity->m_cond = Conditional::SuperiorEqual;
06239 }
06240 else if (valExpression.find( "!=" )==0 )
06241 {
06242
06243 value = valExpression.remove( 0,2 );
06244 d->extra()->validity->m_cond = Conditional::DifferentTo;
06245 }
06246 else if ( valExpression.find( "<" )==0 )
06247 {
06248 value = valExpression.remove( 0,1 );
06249 d->extra()->validity->m_cond = Conditional::Inferior;
06250 }
06251 else if(valExpression.find( ">" )==0 )
06252 {
06253 value = valExpression.remove( 0,1 );
06254 d->extra()->validity->m_cond = Conditional::Superior;
06255 }
06256 else if (valExpression.find( "=" )==0 )
06257 {
06258 value = valExpression.remove( 0,1 );
06259 d->extra()->validity->m_cond = Conditional::Equal;
06260 }
06261 else
06262 kdDebug()<<" I don't know how to parse it :"<<valExpression<<endl;
06263 if ( d->extra()->validity->m_restriction == Restriction::Date )
06264 {
06265 d->extra()->validity->dateMin = QDate::fromString( value );
06266 }
06267 else if (d->extra()->validity->m_restriction == Restriction::Date )
06268 {
06269 d->extra()->validity->timeMin = QTime::fromString( value );
06270 }
06271 else
06272 {
06273 bool ok = false;
06274 d->extra()->validity->valMin = value.toDouble(&ok);
06275 if ( !ok )
06276 {
06277 d->extra()->validity->valMin = value.toInt(&ok);
06278 if ( !ok )
06279 kdDebug()<<" Try to parse this value :"<<value<<endl;
06280
06281 #if 0
06282 if ( !ok )
06283 d->extra()->validity->valMin = value;
06284 #endif
06285 }
06286 }
06287 }
06288
06289
06290 bool Cell::load( const QDomElement & cell, int _xshift, int _yshift,
06291 Paste::Mode pm, Paste::Operation op, bool paste )
06292 {
06293 bool ok;
06294
06295
06296
06297
06298
06299 d->row = cell.attribute( "row" ).toInt( &ok ) + _yshift;
06300 if ( !ok ) return false;
06301 d->column = cell.attribute( "column" ).toInt( &ok ) + _xshift;
06302 if ( !ok ) return false;
06303
06304
06305 if ( d->row < 1 || d->row > KS_rowMax )
06306 {
06307 kdDebug(36001) << "Cell::load: Value out of Range Cell:row=" << d->row << endl;
06308 return false;
06309 }
06310 if ( d->column < 1 || d->column > KS_colMax )
06311 {
06312 kdDebug(36001) << "Cell::load: Value out of Range Cell:column=" << d->column << endl;
06313 return false;
06314 }
06315
06316
06317
06318
06319 QDomElement f = cell.namedItem( "format" ).toElement();
06320 if ( !f.isNull()
06321 && ( (pm == Paste::Normal) || (pm == Paste::Format) || (pm == Paste::NoBorder) ) )
06322 {
06323
06324
06325 if ( !format()->load( f, pm, paste ) )
06326 return false;
06327
06328 if ( f.hasAttribute( "colspan" ) )
06329 {
06330 int i = f.attribute("colspan").toInt( &ok );
06331 if ( !ok ) return false;
06332
06333 if ( i < 0 || i > KS_spanMax )
06334 {
06335 kdDebug(36001) << "Value out of range Cell::colspan=" << i << endl;
06336 return false;
06337 }
06338 if (i || d->hasExtra())
06339 d->extra()->extraXCells = i;
06340 if ( i > 0 )
06341 {
06342 setFlag(Flag_Merged);
06343 }
06344 }
06345
06346 if ( f.hasAttribute( "rowspan" ) )
06347 {
06348 int i = f.attribute("rowspan").toInt( &ok );
06349 if ( !ok ) return false;
06350
06351 if ( i < 0 || i > KS_spanMax )
06352 {
06353 kdDebug(36001) << "Value out of range Cell::rowspan=" << i << endl;
06354 return false;
06355 }
06356 if (i || d->hasExtra())
06357 d->extra()->extraYCells = i;
06358 if ( i > 0 )
06359 {
06360 setFlag(Flag_Merged);
06361 }
06362 }
06363
06364 if ( testFlag( Flag_Merged ) )
06365 {
06366 if (d->hasExtra())
06367 mergeCells( d->column, d->row, d->extra()->extraXCells, d->extra()->extraYCells );
06368 }
06369
06370 }
06371
06372
06373
06374
06375 QDomElement conditionsElement = cell.namedItem( "condition" ).toElement();
06376 if ( !conditionsElement.isNull())
06377 {
06378 if (d->hasExtra())
06379 delete d->extra()->conditions;
06380 d->extra()->conditions = new Conditions( this );
06381 d->extra()->conditions->loadConditions( conditionsElement );
06382 d->extra()->conditions->checkMatches();
06383 }
06384 else if ((pm == Paste::Normal) || (pm == Paste::NoBorder))
06385 {
06386
06387 if (d->hasExtra())
06388 {
06389 delete d->extra()->conditions;
06390 d->extra()->conditions = 0;
06391 }
06392 }
06393
06394 QDomElement validity = cell.namedItem( "validity" ).toElement();
06395 if ( !validity.isNull())
06396 {
06397 QDomElement param = validity.namedItem( "param" ).toElement();
06398 if(!param.isNull())
06399 {
06400 d->extra()->validity = new Validity;
06401 if ( param.hasAttribute( "cond" ) )
06402 {
06403 d->extra()->validity->m_cond = (Conditional::Type) param.attribute("cond").toInt( &ok );
06404 if ( !ok )
06405 return false;
06406 }
06407 if ( param.hasAttribute( "action" ) )
06408 {
06409 d->extra()->validity->m_action = (Action::Type) param.attribute("action").toInt( &ok );
06410 if ( !ok )
06411 return false;
06412 }
06413 if ( param.hasAttribute( "allow" ) )
06414 {
06415 d->extra()->validity->m_restriction = (Restriction::Type) param.attribute("allow").toInt( &ok );
06416 if ( !ok )
06417 return false;
06418 }
06419 if ( param.hasAttribute( "valmin" ) )
06420 {
06421 d->extra()->validity->valMin = param.attribute("valmin").toDouble( &ok );
06422 if ( !ok )
06423 return false;
06424 }
06425 if ( param.hasAttribute( "valmax" ) )
06426 {
06427 d->extra()->validity->valMax = param.attribute("valmax").toDouble( &ok );
06428 if ( !ok )
06429 return false;
06430 }
06431 if ( param.hasAttribute( "displaymessage" ) )
06432 {
06433 d->extra()->validity->displayMessage = ( bool )param.attribute("displaymessage").toInt();
06434 }
06435 if ( param.hasAttribute( "displayvalidationinformation" ) )
06436 {
06437 d->extra()->validity->displayValidationInformation = ( bool )param.attribute("displayvalidationinformation").toInt();
06438 }
06439 if ( param.hasAttribute( "allowemptycell" ) )
06440 {
06441 d->extra()->validity->allowEmptyCell = ( bool )param.attribute("allowemptycell").toInt();
06442 }
06443 if ( param.hasAttribute("listvalidity") )
06444 {
06445 d->extra()->validity->listValidity=QStringList::split(";", param.attribute("listvalidity") );
06446 }
06447 }
06448 QDomElement inputTitle = validity.namedItem( "inputtitle" ).toElement();
06449 if (!inputTitle.isNull())
06450 {
06451 d->extra()->validity->titleInfo = inputTitle.text();
06452 }
06453 QDomElement inputMessage = validity.namedItem( "inputmessage" ).toElement();
06454 if (!inputMessage.isNull())
06455 {
06456 d->extra()->validity->messageInfo = inputMessage.text();
06457 }
06458
06459 QDomElement title = validity.namedItem( "title" ).toElement();
06460 if (!title.isNull())
06461 {
06462 d->extra()->validity->title = title.text();
06463 }
06464 QDomElement message = validity.namedItem( "message" ).toElement();
06465 if (!message.isNull())
06466 {
06467 d->extra()->validity->message = message.text();
06468 }
06469 QDomElement timeMin = validity.namedItem( "timemin" ).toElement();
06470 if ( !timeMin.isNull() )
06471 {
06472 d->extra()->validity->timeMin = toTime(timeMin);
06473 }
06474 QDomElement timeMax = validity.namedItem( "timemax" ).toElement();
06475 if ( !timeMax.isNull() )
06476 {
06477 d->extra()->validity->timeMax = toTime(timeMax);
06478 }
06479 QDomElement dateMin = validity.namedItem( "datemin" ).toElement();
06480 if ( !dateMin.isNull() )
06481 {
06482 d->extra()->validity->dateMin = toDate(dateMin);
06483 }
06484 QDomElement dateMax = validity.namedItem( "datemax" ).toElement();
06485 if ( !dateMax.isNull() )
06486 {
06487 d->extra()->validity->dateMax = toDate(dateMax);
06488 }
06489 }
06490 else if ((pm == Paste::Normal) || (pm == Paste::NoBorder))
06491 {
06492
06493 removeValidity();
06494 }
06495
06496
06497
06498
06499 QDomElement comment = cell.namedItem( "comment" ).toElement();
06500 if ( !comment.isNull() && ( pm == Paste::Normal || pm == Paste::Comment || pm == Paste::NoBorder ))
06501 {
06502 QString t = comment.text();
06503
06504 format()->setComment( t );
06505 }
06506
06507
06508
06509
06510
06511
06512
06513 QDomElement text = cell.namedItem( "text" ).toElement();
06514
06515 if ( !text.isNull() &&
06516 ( pm == Paste::Normal || pm == Paste::Text || pm == Paste::NoBorder || pm == Paste::Result ) )
06517 {
06518
06519
06520
06521 if ( cell.hasAttribute( "dataType" ) )
06522 text.setAttribute( "dataType", cell.attribute( "dataType" ) );
06523
06524 QDomElement result = cell.namedItem( "result" ).toElement();
06525 QString txt = text.text();
06526 if ((pm == Paste::Result) && (txt[0] == '='))
06527
06528
06529
06530
06531 d->strText = result.text();
06532 else
06533
06534 loadCellData(text, op);
06535
06536 if ( !result.isNull() )
06537 {
06538 QString dataType;
06539 QString t = result.text();
06540
06541 if ( result.hasAttribute( "dataType" ) )
06542 dataType = result.attribute( "dataType" );
06543 if ( result.hasAttribute( "outStr" ) )
06544 {
06545 d->strOutText = result.attribute( "outStr" );
06546 if ( !d->strOutText.isEmpty() )
06547 clearFlag( Flag_TextFormatDirty );
06548 }
06549
06550 bool clear = true;
06551
06552 if( dataType == "Bool" )
06553 {
06554 if ( t == "false" )
06555 setValue( false );
06556 else if ( t == "true" )
06557 setValue( true );
06558 else
06559 clear = false;
06560 }
06561 else if( dataType == "Num" )
06562 {
06563 bool ok = false;
06564 double dd = t.toDouble( &ok );
06565 if ( ok )
06566 setValue ( dd );
06567 else
06568 clear = false;
06569 }
06570 else if( dataType == "Date" )
06571 {
06572 bool ok = false;
06573 double dd = t.toDouble( &ok );
06574 if ( ok )
06575 setValue ( dd );
06576 else
06577 {
06578 int pos = t.find( '/' );
06579 int year = t.mid( 0, pos ).toInt();
06580 int pos1 = t.find( '/', pos + 1 );
06581 int month = t.mid( pos + 1, ( ( pos1 - 1 ) - pos ) ).toInt();
06582 int day = t.right( t.length() - pos1 - 1 ).toInt();
06583 QDate date( year, month, day );
06584 if ( date.isValid() )
06585 setValue( date );
06586 else
06587 clear = false;
06588 }
06589 }
06590 else if( dataType == "Time" )
06591 {
06592 bool ok = false;
06593 double dd = t.toDouble( &ok );
06594 if ( ok )
06595 setCellValue( dd );
06596 else
06597 {
06598 int hours = -1;
06599 int minutes = -1;
06600 int second = -1;
06601 int pos, pos1;
06602 pos = t.find( ':' );
06603 hours = t.mid( 0, pos ).toInt();
06604 pos1 = t.find( ':', pos + 1 );
06605 minutes = t.mid( pos + 1, ( ( pos1 - 1 ) - pos ) ).toInt();
06606 second = t.right( t.length() - pos1 - 1 ).toInt();
06607 QTime time( hours, minutes, second );
06608 if ( time.isValid() )
06609 setValue( time );
06610 else
06611 clear = false;
06612 }
06613 }
06614 else
06615 {
06616 setValue( t );
06617 }
06618
06619
06620
06621 }
06622 }
06623
06624 return true;
06625 }
06626
06627 bool Cell::loadCellData(const QDomElement & text, Paste::Operation op )
06628 {
06629
06630
06631 QString t = text.text();
06632 t = t.stripWhiteSpace();
06633
06634 setFlag(Flag_LayoutDirty);
06635 setFlag(Flag_TextFormatDirty);
06636
06637
06638 if( t[0] == '=' )
06639 {
06640 t = decodeFormula( t, d->column, d->row );
06641 setCellText (pasteOperation( t, d->strText, op ));
06642
06643 setFlag(Flag_CalcDirty);
06644 clearAllErrors();
06645
06646 if ( !makeFormula() )
06647 kdError(36001) << "ERROR: Syntax ERROR" << endl;
06648 }
06649
06650 else if (t[0] == '!' )
06651 {
06652
06653
06654
06655 bool inside_tag = false;
06656 QString qml_text;
06657 QString tag;
06658 QString qml_link;
06659
06660 for( unsigned i = 1; i < t.length(); i++ )
06661 {
06662 QChar ch = t[i];
06663 if( ch == '<' )
06664 {
06665 if( !inside_tag )
06666 {
06667 inside_tag = true;
06668 tag = QString::null;
06669 }
06670 }
06671 else if( ch == '>' )
06672 {
06673 if( inside_tag )
06674 {
06675 inside_tag = false;
06676 if( tag.startsWith( "a href=\"", true ) )
06677 if( tag.endsWith( "\"" ) )
06678 qml_link = tag.mid( 8, tag.length()-9 );
06679 tag = QString::null;
06680 }
06681 }
06682 else
06683 {
06684 if( !inside_tag )
06685 qml_text += ch;
06686 else
06687 tag += ch;
06688 }
06689 }
06690
06691 if( !qml_link.isEmpty() )
06692 d->extra()->link = qml_link;
06693 d->strText = qml_text;
06694 setValue( d->strText );
06695 }
06696 else
06697 {
06698 bool newStyleLoading = true;
06699 QString dataType;
06700
06701 if ( text.hasAttribute( "dataType" ) )
06702 {
06703 dataType = text.attribute( "dataType" );
06704 }
06705 else
06706 {
06707
06708 if (isDate() && ( t.contains('/') == 2 ))
06709 dataType = "Date";
06710 else if (isTime() && ( t.contains(':') == 2 ) )
06711 dataType = "Time";
06712 else
06713 {
06714 d->strText = pasteOperation( t, d->strText, op );
06715 checkTextInput();
06716
06717 newStyleLoading = false;
06718 }
06719 }
06720
06721 if ( newStyleLoading )
06722 {
06723 d->value = Value::empty();
06724 clearAllErrors();
06725
06726
06727 if( dataType == "Bool" )
06728 {
06729 bool val = (t.lower() == "true");
06730 setCellValue (val);
06731 }
06732
06733
06734 else if( dataType == "Num" )
06735 {
06736 bool ok = false;
06737 if (t.contains('.'))
06738 setValue ( Value( t.toDouble(&ok) ) );
06739 else
06740 setValue ( Value( t.toLong(&ok) ) );
06741 if ( !ok )
06742 {
06743 kdWarning(36001) << "Couldn't parse '" << t << "' as number." << endl;
06744 }
06745
06746 KLocale* locale = format()->sheet()->doc()->locale();
06747
06748
06749
06750 int precision = t.length() - t.find('.') - 1;
06751
06752 if ( formatType() == Percentage_format )
06753 {
06754 if (value().isInteger())
06755 t = locale->formatNumber( value().asInteger() * 100 );
06756 else
06757 t = locale->formatNumber( value().asFloat() * 100.0, precision );
06758 d->strText = pasteOperation( t, d->strText, op );
06759 d->strText += '%';
06760 }
06761 else
06762 {
06763 if (value().isInteger())
06764 t = locale->formatLong(value().asInteger());
06765 else
06766 t = locale->formatNumber(value().asFloat(), precision);
06767 d->strText = pasteOperation( t, d->strText, op );
06768 }
06769 }
06770
06771
06772 else if( dataType == "Date" )
06773 {
06774 int pos = t.find('/');
06775 int year = t.mid(0,pos).toInt();
06776 int pos1 = t.find('/',pos+1);
06777 int month = t.mid(pos+1,((pos1-1)-pos)).toInt();
06778 int day = t.right(t.length()-pos1-1).toInt();
06779 setValue( QDate(year,month,day) );
06780 if ( value().asDate().isValid() )
06781 d->strText = locale()->formatDate( value().asDate(), true );
06782 else
06783 {
06784 d->strText = pasteOperation( t, d->strText, op );
06785 checkTextInput();
06786 }
06787 }
06788
06789
06790 else if( dataType == "Time" )
06791 {
06792 int hours = -1;
06793 int minutes = -1;
06794 int second = -1;
06795 int pos, pos1;
06796 pos = t.find(':');
06797 hours = t.mid(0,pos).toInt();
06798 pos1 = t.find(':',pos+1);
06799 minutes = t.mid(pos+1,((pos1-1)-pos)).toInt();
06800 second = t.right(t.length()-pos1-1).toInt();
06801 setValue( QTime(hours,minutes,second) );
06802 if ( value().asTime().isValid() )
06803 d->strText = locale()->formatTime( value().asTime(), true );
06804 else
06805 {
06806 d->strText = pasteOperation( t, d->strText, op );
06807 checkTextInput();
06808 }
06809 }
06810
06811 else
06812 {
06813
06814 d->strText = pasteOperation( t, d->strText, op );
06815 setValue( d->strText );
06816 }
06817 }
06818 }
06819
06820 if ( text.hasAttribute( "outStr" ) )
06821 {
06822 d->strOutText = text.attribute( "outStr" );
06823 if ( !d->strOutText.isEmpty() )
06824 clearFlag( Flag_TextFormatDirty );
06825 }
06826
06827 if ( !format()->sheet()->isLoading() )
06828 setCellText( d->strText );
06829
06830 if ( d->hasExtra() && d->extra()->conditions )
06831 d->extra()->conditions->checkMatches();
06832
06833 return true;
06834 }
06835
06836 QTime Cell::toTime(const QDomElement &element)
06837 {
06838
06839 QString t = element.text();
06840 t = t.stripWhiteSpace();
06841 int hours = -1;
06842 int minutes = -1;
06843 int second = -1;
06844 int pos, pos1;
06845 pos = t.find(':');
06846 hours = t.mid(0,pos).toInt();
06847 pos1 = t.find(':',pos+1);
06848 minutes = t.mid(pos+1,((pos1-1)-pos)).toInt();
06849 second = t.right(t.length()-pos1-1).toInt();
06850 setValue( Value( QTime(hours,minutes,second)) );
06851 return value().asTime();
06852 }
06853
06854 QDate Cell::toDate(const QDomElement &element)
06855 {
06856 QString t = element.text();
06857 int pos;
06858 int pos1;
06859 int year = -1;
06860 int month = -1;
06861 int day = -1;
06862 pos = t.find('/');
06863 year = t.mid(0,pos).toInt();
06864 pos1 = t.find('/',pos+1);
06865 month = t.mid(pos+1,((pos1-1)-pos)).toInt();
06866 day = t.right(t.length()-pos1-1).toInt();
06867 setValue( Value( QDate(year,month,day) ) );
06868 return value().asDate();
06869 }
06870
06871 QString Cell::pasteOperation( const QString &new_text, const QString &old_text, Paste::Operation op )
06872 {
06873 if ( op == Paste::OverWrite )
06874 return new_text;
06875
06876 QString tmp_op;
06877 QString tmp;
06878 QString old;
06879
06880 if( !new_text.isEmpty() && new_text[0] == '=' )
06881 {
06882 tmp = new_text.right( new_text.length() - 1 );
06883 }
06884 else
06885 {
06886 tmp = new_text;
06887 }
06888
06889 if ( old_text.isEmpty() &&
06890 ( op == Paste::Add || op == Paste::Mul || op == Paste::Sub || op == Paste::Div ) )
06891 {
06892 old = "=0";
06893 }
06894
06895 if( !old_text.isEmpty() && old_text[0] == '=' )
06896 {
06897 old = old_text.right( old_text.length() - 1 );
06898 }
06899 else
06900 {
06901 old = old_text;
06902 }
06903
06904 bool b1, b2;
06905 tmp.toDouble( &b1 );
06906 old.toDouble( &b2 );
06907 if (b1 && !b2 && old.length() == 0)
06908 {
06909 old = "0";
06910 b2 = true;
06911 }
06912
06913 if( b1 && b2 )
06914 {
06915 switch( op )
06916 {
06917 case Paste::Add:
06918 tmp_op = QString::number(old.toDouble()+tmp.toDouble());
06919 break;
06920 case Paste::Mul :
06921 tmp_op = QString::number(old.toDouble()*tmp.toDouble());
06922 break;
06923 case Paste::Sub:
06924 tmp_op = QString::number(old.toDouble()-tmp.toDouble());
06925 break;
06926 case Paste::Div:
06927 tmp_op = QString::number(old.toDouble()/tmp.toDouble());
06928 break;
06929 default:
06930 Q_ASSERT( 0 );
06931 }
06932
06933 setFlag(Flag_LayoutDirty);
06934 clearAllErrors();
06935
06936 return tmp_op;
06937 }
06938 else if ( ( new_text[0] == '=' && old_text[0] == '=' ) ||
06939 ( b1 && old_text[0] == '=' ) || ( new_text[0] == '=' && b2 ) )
06940 {
06941 switch( op )
06942 {
06943 case Paste::Add :
06944 tmp_op="=("+old+")+"+"("+tmp+")";
06945 break;
06946 case Paste::Mul :
06947 tmp_op="=("+old+")*"+"("+tmp+")";
06948 break;
06949 case Paste::Sub:
06950 tmp_op="=("+old+")-"+"("+tmp+")";
06951 break;
06952 case Paste::Div:
06953 tmp_op="=("+old+")/"+"("+tmp+")";
06954 break;
06955 default :
06956 Q_ASSERT( 0 );
06957 }
06958
06959 tmp_op = decodeFormula( tmp_op, d->column, d->row );
06960 setFlag(Flag_LayoutDirty);
06961 clearAllErrors();
06962
06963 return tmp_op;
06964 }
06965
06966 tmp = decodeFormula( new_text, d->column, d->row );
06967 setFlag(Flag_LayoutDirty);
06968 clearAllErrors();
06969
06970 return tmp;
06971 }
06972
06973 QString Cell::testAnchor( int x, int y ) const
06974 {
06975 if( link().isEmpty() )
06976 return QString::null;
06977
06978 const Doc* doc = format()->sheet()->doc();
06979 int x1 = doc->zoomItX( d->textX );
06980 int y1 = doc->zoomItX( d->textY - d->textHeight );
06981 int x2 = doc->zoomItX( d->textX + d->textWidth );
06982 int y2 = doc->zoomItX( d->textY );
06983
06984 if( x > x1 ) if( x < x2 )
06985 if( y > y1 ) if( y < y2 )
06986 return link();
06987
06988 return QString::null;
06989 }
06990
06991 void Cell::sheetDies()
06992 {
06993
06994 if (d->hasExtra())
06995 {
06996 d->extra()->extraXCells = 0;
06997 d->extra()->extraYCells = 0;
06998 d->extra()->mergedXCells = 0;
06999 d->extra()->mergedYCells = 0;
07000 }
07001
07002
07003
07004 }
07005
07006 Cell::~Cell()
07007 {
07008 if ( d->nextCell )
07009 d->nextCell->setPreviousCell( d->previousCell );
07010 if ( d->previousCell )
07011 d->previousCell->setNextCell( d->nextCell );
07012
07013 if (d->hasExtra())
07014 {
07015 delete d->extra()->validity;
07016 }
07017
07018
07019 int extraXCells = d->hasExtra() ? d->extra()->extraXCells : 0;
07020 int extraYCells = d->hasExtra() ? d->extra()->extraYCells : 0;
07021 for( int x = 0; x <= extraXCells; ++x )
07022 for( int y = (x == 0) ? 1 : 0;
07023 y <= extraYCells; ++y )
07024 {
07025 Cell* cell = format()->sheet()->cellAt( d->column + x, d->row + y );
07026 if ( cell )
07027 cell->unobscure(this);
07028 }
07029
07030 d->value = Value::empty();
07031
07032 if (!isDefault())
07033 valueChanged ();
07034
07035 delete d->format;
07036 delete d;
07037 }
07038
07039 bool Cell::operator > ( const Cell & cell ) const
07040 {
07041 if ( value().isNumber() )
07042 {
07043 if ( cell.value().isNumber() )
07044 return value().asFloat() > cell.value().asFloat();
07045 else
07046 return false;
07047 }
07048 else if(isDate())
07049 {
07050 if( cell.isDate() )
07051 return value().asDate() > cell.value().asDate();
07052 else if (cell.value().isNumber())
07053 return true;
07054 else
07055 return false;
07056 }
07057 else if(isTime())
07058 {
07059 if( cell.isTime() )
07060 return value().asTime() > cell.value().asTime();
07061 else if( cell.isDate())
07062 return true;
07063 else if( cell.value().isNumber())
07064 return true;
07065 else
07066 return false;
07067 }
07068 else
07069 {
07070 if ( Map::respectCase )
07071 return value().asString().compare(cell.value().asString()) > 0;
07072 else
07073 return ( value().asString() ).lower().compare(cell.value().asString().lower()) > 0;
07074 }
07075 }
07076
07077 bool Cell::operator < ( const Cell & cell ) const
07078 {
07079 if ( value().isNumber() )
07080 {
07081 if ( cell.value().isNumber() )
07082 return value().asFloat() < cell.value().asFloat();
07083 else
07084 return true;
07085 }
07086 else if(isDate())
07087 {
07088 if( cell.isDate() )
07089 return value().asDateTime().date() < cell.value().asDateTime().date();
07090 else if( cell.value().isNumber())
07091 return false;
07092 else
07093 return true;
07094 }
07095 else if(isTime())
07096 {
07097 if( cell.isTime() )
07098 return value().asDateTime().time() < cell.value().asDateTime().time();
07099 else if(cell.isDate())
07100 return false;
07101 else if( cell.value().isNumber())
07102 return false;
07103 else
07104 return true;
07105 }
07106 else
07107 {
07108 if ( Map::respectCase )
07109 return value().asString().compare(cell.value().asString()) < 0;
07110 else
07111 return ( value().asString() ).lower().compare(cell.value().asString().lower()) < 0;
07112 }
07113 }
07114
07115 QRect Cell::cellRect()
07116 {
07117 Q_ASSERT(!isDefault());
07118 return QRect(QPoint(d->column, d->row), QPoint(d->column, d->row));
07119 }
07120
07121 QValueList<Conditional> Cell::conditionList() const
07122 {
07123 if ( !d->hasExtra() || !d->extra()->conditions )
07124 {
07125 QValueList<Conditional> emptyList;
07126 return emptyList;
07127 }
07128
07129 return d->extra()->conditions->conditionList();
07130 }
07131
07132 void Cell::setConditionList( const QValueList<Conditional> & newList )
07133 {
07134 if (d->hasExtra())
07135 delete d->extra()->conditions;
07136 d->extra()->conditions = new Conditions( this );
07137 d->extra()->conditions->setConditionList( newList );
07138 d->extra()->conditions->checkMatches();
07139 }
07140
07141 bool Cell::hasError() const
07142 {
07143 return ( testFlag(Flag_ParseError) ||
07144 testFlag(Flag_CircularCalculation) ||
07145 testFlag(Flag_DependancyError));
07146 }
07147
07148 void Cell::clearAllErrors()
07149 {
07150 clearFlag( Flag_ParseError );
07151 clearFlag( Flag_CircularCalculation );
07152 clearFlag( Flag_DependancyError );
07153 }
07154
07155 bool Cell::calcDirtyFlag()
07156 {
07157 return isFormula() ? testFlag( Flag_CalcDirty ) : false;
07158 }
07159
07160 bool Cell::layoutDirtyFlag() const
07161 {
07162 return testFlag( Flag_LayoutDirty );
07163 }
07164
07165 void Cell::clearDisplayDirtyFlag()
07166 {
07167 clearFlag( Flag_DisplayDirty );
07168 }
07169
07170 void Cell::setDisplayDirtyFlag()
07171 {
07172 setFlag( Flag_DisplayDirty );
07173 }
07174
07175 bool Cell::doesMergeCells() const
07176 {
07177 return testFlag( Flag_Merged );
07178 }
07179
07180 void Cell::clearFlag( CellFlags flag )
07181 {
07182 d->flags &= ~(Q_UINT32)flag;
07183 }
07184
07185 void Cell::setFlag( CellFlags flag )
07186 {
07187 d->flags |= (Q_UINT32)flag;
07188 }
07189
07190 bool Cell::testFlag( CellFlags flag ) const
07191 {
07192 return ( d->flags & (Q_UINT32)flag );
07193 }
07194
07195
07196 void Cell::checkForNamedAreas( QString & formula ) const
07197 {
07198 int l = formula.length();
07199 int i = 0;
07200 QString word;
07201 int start = 0;
07202 while ( i < l )
07203 {
07204 if ( formula[i].isLetterOrNumber() )
07205 {
07206 word += formula[i];
07207 ++i;
07208 continue;
07209 }
07210 if ( !word.isEmpty() )
07211 {
07212 if ( sheet()->doc()->loadingInfo()->findWordInAreaList(word) )
07213 {
07214 formula = formula.replace( start, word.length(), "'" + word + "'" );
07215 l = formula.length();
07216 ++i;
07217 kdDebug() << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
07218 }
07219 }
07220
07221 ++i;
07222 word = "";
07223 start = i;
07224 }
07225 if ( !word.isEmpty() )
07226 {
07227 if ( sheet()->doc()->loadingInfo()->findWordInAreaList(word) )
07228 {
07229 formula = formula.replace( start, word.length(), "'" + word + "'" );
07230 l = formula.length();
07231 ++i;
07232 kdDebug() << "Formula: " << formula << ", L: " << l << ", i: " << i + 1 <<endl;
07233 }
07234 }
07235 }