00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdlib.h>
00023 #include <ctype.h>
00024 #include <float.h>
00025 #include <math.h>
00026 #include <pwd.h>
00027 #include <unistd.h>
00028
00029 #include <qapplication.h>
00030 #include <qclipboard.h>
00031 #include <qpicture.h>
00032 #include <qregexp.h>
00033
00034 #include <qlayout.h>
00035 #include <qvbox.h>
00036 #include <qcheckbox.h>
00037 #include <qlabel.h>
00038 #include <qlineedit.h>
00039 #include <kmessagebox.h>
00040
00041 #include <kfind.h>
00042 #include <kfinddialog.h>
00043 #include <kreplace.h>
00044 #include <kreplacedialog.h>
00045 #include <kprinter.h>
00046 #include <koDocumentInfo.h>
00047 #include <koOasisStyles.h>
00048 #include <koUnit.h>
00049 #include <koStyleStack.h>
00050 #include <koOasisSettings.h>
00051 #include <koxmlns.h>
00052 #include <kodom.h>
00053
00054 #include "dependencies.h"
00055
00056 #include "ksprsavinginfo.h"
00057 #include "kspread_cluster.h"
00058 #include "kspread_sheet.h"
00059 #include "kspread_sheetprint.h"
00060 #include "kspread_locale.h"
00061 #include "kspread_selection.h"
00062 #include "kspread_global.h"
00063 #include "kspread_undo.h"
00064 #include "kspread_map.h"
00065 #include "kspread_doc.h"
00066 #include "kspread_util.h"
00067 #include "kspread_canvas.h"
00068 #include "kspread_style.h"
00069 #include "kspread_style_manager.h"
00070 #include "ksploadinginfo.h"
00071 #include "KSpreadTableIface.h"
00072
00073 #include <kdebug.h>
00074 #include <kmdcodec.h>
00075 #include <assert.h>
00076
00077 #include <koChart.h>
00078 #include "kspread_sheet.moc"
00079
00080 #define NO_MODIFICATION_POSSIBLE \
00081 do { \
00082 KMessageBox::error( 0, i18n ( "You cannot change a protected sheet" ) ); return; \
00083 } while(0)
00084
00085
00086
00087
00088
00089
00090
00091 CellBinding::CellBinding( KSpreadSheet *_sheet, const QRect& _area )
00092 {
00093 m_rctDataArea = _area;
00094
00095 m_pSheet = _sheet;
00096 m_pSheet->addCellBinding( this );
00097
00098 m_bIgnoreChanges = false;
00099 }
00100
00101 CellBinding::~CellBinding()
00102 {
00103 m_pSheet->removeCellBinding( this );
00104 }
00105
00106 void CellBinding::cellChanged( KSpreadCell *_cell )
00107 {
00108 if ( m_bIgnoreChanges )
00109 return;
00110
00111 emit changed( _cell );
00112 }
00113
00114 bool CellBinding::contains( int _x, int _y )
00115 {
00116 return m_rctDataArea.contains( QPoint( _x, _y ) );
00117 }
00118
00119
00120
00121
00122
00123
00124
00125 ChartBinding::ChartBinding( KSpreadSheet *_sheet, const QRect& _area, ChartChild *_child )
00126 : CellBinding( _sheet, _area )
00127 {
00128 m_child = _child;
00129 }
00130
00131 ChartBinding::~ChartBinding()
00132 {
00133 }
00134
00135 void ChartBinding::cellChanged( KSpreadCell* )
00136 {
00137 kdDebug(36001) << "######### void ChartBinding::cellChanged( KSpreadCell* )" << endl;
00138
00139 if ( m_bIgnoreChanges )
00140 return;
00141
00142 kdDebug(36001) << "with=" << m_rctDataArea.width() << " height=" << m_rctDataArea.height() << endl;
00143
00144 KoChart::Data matrix( m_rctDataArea.height(), m_rctDataArea.width() );
00145
00146 KSpreadCell* cell;
00147 for ( int y = 0; y < m_rctDataArea.height(); y++ )
00148 for ( int x = 0; x < m_rctDataArea.width(); x++ )
00149 {
00150 cell = m_pSheet->cellAt( m_rctDataArea.left() + x, m_rctDataArea.top() + y );
00151 if ( cell && cell->value().isNumber() )
00152 matrix.cell( y, x ) = KoChart::Value( cell->value().asFloat() );
00153 else if ( cell )
00154 matrix.cell( y, x ) = KoChart::Value( cell->value().asString() );
00155 else
00156 matrix.cell( y, x ) = KoChart::Value();
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 m_child->chart()->setData( matrix );
00168
00169
00170
00172
00173 }
00174
00175
00176
00177
00178
00179 KSpreadTextDrag::KSpreadTextDrag( QWidget * dragSource, const char * name )
00180 : QTextDrag( dragSource, name )
00181 {
00182 }
00183
00184 KSpreadTextDrag::~KSpreadTextDrag()
00185 {
00186 }
00187
00188
00189 QByteArray KSpreadTextDrag::encodedData( const char * mime ) const
00190 {
00191 if ( strcmp( selectionMimeType(), mime ) == 0)
00192 return m_kspread;
00193 else
00194 return QTextDrag::encodedData( mime );
00195 }
00196
00197 bool KSpreadTextDrag::canDecode( QMimeSource* e )
00198 {
00199 if ( e->provides( selectionMimeType() ) )
00200 return true;
00201 return QTextDrag::canDecode(e);
00202 }
00203
00204 const char * KSpreadTextDrag::format( int i ) const
00205 {
00206 if ( i < 4 )
00207 return QTextDrag::format(i);
00208 else if ( i == 4 )
00209 return selectionMimeType();
00210 else return 0;
00211 }
00212
00213 const char * KSpreadTextDrag::selectionMimeType()
00214 {
00215 return "application/x-kspread-snippet";
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 class SheetPrivate
00225 {
00226 public:
00227
00228 KSpreadMap* workbook;
00229
00230 DCOPObject* dcop;
00231
00232 QString name;
00233 int id;
00234
00235 KSpreadSheet::LayoutDirection layoutDirection;
00236
00237
00238 bool hide;
00239
00240
00241 QCString password;
00242
00243
00244 bool showGrid;
00245 bool showFormula;
00246 bool showFormulaIndicator;
00247 bool autoCalc;
00248 bool lcMode;
00249 bool showColumnNumber;
00250 bool hideZero;
00251 bool firstLetterUpper;
00252
00253
00254 KSpreadCluster cells;
00255 KSpreadRowCluster rows;
00256 KSpreadColumnCluster columns;
00257
00258
00259 KSpreadCell* defaultCell;
00260 KSpreadFormat* defaultFormat;
00261 RowFormat* defaultRowFormat;
00262 ColumnFormat* defaultColumnFormat;
00263
00264
00265 KSpreadSheetPrint* print;
00266
00267
00268 QValueList<QRect> paintDirtyList;
00269
00270
00271 QPainter *painter;
00272 QWidget *widget;
00273
00274
00275
00276 QPtrList<CellBinding> cellBindings;
00277
00278
00279
00280 bool showPageBorders;
00281
00282
00283
00284
00285
00286 int maxRow;
00287 int maxColumn;
00288
00289
00290
00291 double sizeMaxX;
00292 double sizeMaxY;
00293
00294
00295 bool scrollBarUpdates;
00296
00297 QPen emptyPen;
00298 QBrush emptyBrush;
00299 QColor emptyColor;
00300
00301 int scrollPosX;
00302 int scrollPosY;
00303
00304 KSpread::DependencyManager *dependencies;
00305 };
00306
00307 int KSpreadSheet::s_id = 0L;
00308 QIntDict<KSpreadSheet>* KSpreadSheet::s_mapSheets;
00309
00310 KSpreadSheet* KSpreadSheet::find( int _id )
00311 {
00312 if ( !s_mapSheets )
00313 return 0L;
00314
00315 return (*s_mapSheets)[ _id ];
00316 }
00317
00318 KSpreadSheet::KSpreadSheet (KSpreadMap* map,
00319 const QString &sheetName, const char *_name )
00320 : QObject( map, _name )
00321 {
00322 if ( s_mapSheets == 0L )
00323 s_mapSheets = new QIntDict<KSpreadSheet>;
00324 d = new SheetPrivate;
00325
00326 d->workbook = map;
00327
00328 d->id = s_id++;
00329 s_mapSheets->insert( d->id, this );
00330
00331 d->layoutDirection = LeftToRight;
00332
00333 d->defaultFormat = new KSpreadFormat (this, d->workbook->doc()->styleManager()->defaultStyle());
00334 d->emptyPen.setStyle( Qt::NoPen );
00335 d->dcop = 0;
00336 d->name = sheetName;
00337
00338 dcopObject();
00339 d->cellBindings.setAutoDelete( FALSE );
00340
00341
00342
00343 d->cells.setAutoDelete( true );
00344 d->rows.setAutoDelete( true );
00345 d->columns.setAutoDelete( true );
00346
00347 d->defaultCell = new KSpreadCell( this, d->workbook->doc()->styleManager()->defaultStyle(), 0, 0);
00348 d->defaultRowFormat = new RowFormat( this, 0 );
00349 d->defaultRowFormat->setDefault();
00350 d->defaultColumnFormat = new ColumnFormat( this, 0 );
00351 d->defaultColumnFormat->setDefault();
00352
00353 d->widget = new QWidget();
00354 d->painter = new QPainter;
00355 d->painter->begin( d->widget );
00356
00357 d->maxColumn = 256;
00358 d->maxRow = 256;
00359 d->sizeMaxX = KS_colMax * d->defaultColumnFormat->dblWidth();
00360 d->sizeMaxY = KS_rowMax * d->defaultRowFormat->dblHeight();
00361
00362 d->scrollBarUpdates = true;
00363
00364 setHidden( false );
00365 d->showGrid=true;
00366 d->showFormula=false;
00367 d->showFormulaIndicator=true;
00368 d->showPageBorders = FALSE;
00369
00370 d->lcMode=false;
00371 d->showColumnNumber=false;
00372 d->hideZero=false;
00373 d->firstLetterUpper=false;
00374 d->autoCalc=true;
00375
00376 if ( !_name )
00377 {
00378 QCString s;
00379 s.sprintf("Sheet%i", s_id );
00380 QObject::setName( s.data() );
00381 }
00382 d->print = new KSpreadSheetPrint( this );
00383
00384
00385 d->dependencies = new KSpread::DependencyManager (this);
00386 }
00387
00388 QString KSpreadSheet::sheetName() const
00389 {
00390 return d->name;
00391 }
00392
00393 KSpreadMap* KSpreadSheet::workbook()
00394 {
00395 return d->workbook;
00396 }
00397
00398 KSpreadDoc* KSpreadSheet::doc()
00399 {
00400 return d->workbook->doc();
00401 }
00402
00403 int KSpreadSheet::id() const
00404 {
00405 return d->id;
00406 }
00407
00408 KSpreadSheet::LayoutDirection KSpreadSheet::layoutDirection() const
00409 {
00410 return d->layoutDirection;
00411 }
00412
00413 void KSpreadSheet::setLayoutDirection( LayoutDirection dir )
00414 {
00415 d->layoutDirection = dir;
00416 }
00417
00418 bool KSpreadSheet::isRightToLeft() const
00419 {
00420 return d->layoutDirection == RightToLeft;
00421 }
00422
00423 bool KSpreadSheet::isHidden() const
00424 {
00425 return d->hide;
00426 }
00427
00428 void KSpreadSheet::setHidden( bool hidden )
00429 {
00430 d->hide = hidden;
00431 }
00432
00433 bool KSpreadSheet::getShowGrid() const
00434 {
00435 return d->showGrid;
00436 }
00437
00438 void KSpreadSheet::setShowGrid( bool _showGrid )
00439 {
00440 d->showGrid=_showGrid;
00441 }
00442
00443 bool KSpreadSheet::getShowFormula() const
00444 {
00445 return d->showFormula;
00446 }
00447
00448 void KSpreadSheet::setShowFormula( bool _showFormula )
00449 {
00450 d->showFormula=_showFormula;
00451 }
00452
00453 bool KSpreadSheet::getShowFormulaIndicator() const
00454 {
00455 return d->showFormulaIndicator;
00456 }
00457
00458 void KSpreadSheet::setShowFormulaIndicator( bool _showFormulaIndicator )
00459 {
00460 d->showFormulaIndicator=_showFormulaIndicator;
00461 }
00462
00463 bool KSpreadSheet::getLcMode() const
00464 {
00465 return d->lcMode;
00466 }
00467
00468 void KSpreadSheet::setLcMode( bool _lcMode )
00469 {
00470 d->lcMode=_lcMode;
00471 }
00472
00473 bool KSpreadSheet::getAutoCalc() const
00474 {
00475 return d->autoCalc;
00476 }
00477
00478 void KSpreadSheet::setAutoCalc( bool _AutoCalc )
00479 {
00480 d->autoCalc=_AutoCalc;
00481 }
00482
00483 bool KSpreadSheet::getShowColumnNumber() const
00484 {
00485 return d->showColumnNumber;
00486 }
00487
00488 void KSpreadSheet::setShowColumnNumber( bool _showColumnNumber )
00489 {
00490 d->showColumnNumber=_showColumnNumber;
00491 }
00492
00493 bool KSpreadSheet::getHideZero() const
00494 {
00495 return d->hideZero;
00496 }
00497
00498 void KSpreadSheet::setHideZero( bool _hideZero )
00499 {
00500 d->hideZero=_hideZero;
00501 }
00502
00503 bool KSpreadSheet::getFirstLetterUpper() const
00504 {
00505 return d->firstLetterUpper;
00506 }
00507
00508 void KSpreadSheet::setFirstLetterUpper( bool _firstUpper )
00509 {
00510 d->firstLetterUpper=_firstUpper;
00511 }
00512
00513 bool KSpreadSheet::isShowPageBorders() const
00514 {
00515 return d->showPageBorders;
00516 }
00517
00518 bool KSpreadSheet::isEmpty( unsigned long int x, unsigned long int y ) const
00519 {
00520 const KSpreadCell* c = cellAt( x, y );
00521 if ( !c || c->isEmpty() )
00522 return true;
00523
00524 return false;
00525 }
00526
00527 KSpreadCell* KSpreadSheet::defaultCell() const
00528 {
00529 return d->defaultCell;
00530 }
00531
00532 KSpreadFormat* KSpreadSheet::defaultFormat()
00533 {
00534 return d->defaultFormat;
00535 }
00536
00537 const KSpreadFormat* KSpreadSheet::defaultFormat() const
00538 {
00539 return d->defaultFormat;
00540 }
00541
00542 const ColumnFormat* KSpreadSheet::columnFormat( int _column ) const
00543 {
00544 const ColumnFormat *p = d->columns.lookup( _column );
00545 if ( p != 0L )
00546 return p;
00547
00548 return d->defaultColumnFormat;
00549 }
00550
00551 ColumnFormat* KSpreadSheet::columnFormat( int _column )
00552 {
00553 ColumnFormat *p = d->columns.lookup( _column );
00554 if ( p != 0L )
00555 return p;
00556
00557 return d->defaultColumnFormat;
00558 }
00559
00560 const RowFormat* KSpreadSheet::rowFormat( int _row ) const
00561 {
00562 const RowFormat *p = d->rows.lookup( _row );
00563 if ( p != 0L )
00564 return p;
00565
00566 return d->defaultRowFormat;
00567 }
00568
00569 RowFormat* KSpreadSheet::rowFormat( int _row )
00570 {
00571 RowFormat *p = d->rows.lookup( _row );
00572 if ( p != 0L )
00573 return p;
00574
00575 return d->defaultRowFormat;
00576 }
00577
00578 KSpreadValue KSpreadSheet::value (int col, int row) const
00579 {
00580 KSpreadCell *cell = d->cells.lookup (col, row);
00581 if (cell)
00582 return cell->value ();
00583 KSpreadValue empty;
00584 return empty;
00585 }
00586
00587 KSpreadValue KSpreadSheet::valueRange (int col1, int row1,
00588 int col2, int row2) const
00589 {
00590 return d->cells.valueRange (col1, row1, col2, row2);
00591 }
00592
00593 void KSpreadSheet::password( QCString & passwd ) const
00594 {
00595 passwd = d->password;
00596 }
00597
00598 bool KSpreadSheet::isProtected() const
00599 {
00600 return !d->password.isNull();
00601 }
00602
00603 void KSpreadSheet::setProtected( QCString const & passwd )
00604 {
00605 d->password = passwd;
00606 }
00607
00608 bool KSpreadSheet::checkPassword( QCString const & passwd ) const
00609 {
00610 return ( passwd == d->password );
00611 }
00612
00613 KSpreadSheetPrint* KSpreadSheet::print() const
00614 {
00615 return d->print;
00616 }
00617
00618 QPainter& KSpreadSheet::painter()
00619 {
00620 return *d->painter;
00621 }
00622
00623 QWidget* KSpreadSheet::widget()const
00624 {
00625 return d->widget;
00626 }
00627
00628 CellBinding* KSpreadSheet::firstCellBinding()
00629 {
00630 return d->cellBindings.first();
00631 }
00632
00633 CellBinding* KSpreadSheet::nextCellBinding()
00634 {
00635 return d->cellBindings.next();
00636 }
00637
00638 void KSpreadSheet::setDefaultHeight( double height )
00639 {
00640 if ( isProtected() )
00641 NO_MODIFICATION_POSSIBLE;
00642
00643 d->defaultRowFormat->setDblHeight( height );
00644 }
00645
00646 void KSpreadSheet::setDefaultWidth( double width )
00647 {
00648 if ( isProtected() )
00649 NO_MODIFICATION_POSSIBLE;
00650
00651 d->defaultColumnFormat->setDblWidth( width );
00652 }
00653
00654 double KSpreadSheet::sizeMaxX() const
00655 {
00656 return d->sizeMaxX;
00657 }
00658
00659 double KSpreadSheet::sizeMaxY() const
00660 {
00661 return d->sizeMaxY;
00662 }
00663
00664 int KSpreadSheet::maxColumn() const
00665 {
00666 return d->maxColumn;
00667 }
00668
00669 int KSpreadSheet::maxRow() const
00670 {
00671 return d->maxRow;
00672 }
00673
00674 const QPen& KSpreadSheet::emptyPen() const
00675 {
00676 return d->emptyPen;
00677 }
00678
00679 const QBrush& KSpreadSheet::emptyBrush() const
00680 {
00681 return d->emptyBrush;
00682 }
00683
00684 const QColor& KSpreadSheet::emptyColor() const
00685 {
00686 return d->emptyColor;
00687 }
00688
00689 KSpread::DependencyManager *KSpreadSheet::dependencies ()
00690 {
00691 return d->dependencies;
00692 }
00693
00694 int KSpreadSheet::leftColumn( double _xpos, double &_left,
00695 const KSpreadCanvas *_canvas ) const
00696 {
00697 if ( _canvas )
00698 {
00699 _xpos += _canvas->xOffset();
00700 _left = -_canvas->xOffset();
00701 }
00702 else
00703 _left = 0.0;
00704
00705 int col = 1;
00706 double x = columnFormat( col )->dblWidth( _canvas );
00707 while ( x < _xpos )
00708 {
00709
00710 if ( col >= KS_colMax )
00711 {
00712 kdDebug(36001) << "KSpreadSheet:leftColumn: invalid column (col: " << col + 1 << ")" << endl;
00713 return KS_colMax + 1;
00714 }
00715 _left += columnFormat( col )->dblWidth( _canvas );
00716 col++;
00717 x += columnFormat( col )->dblWidth( _canvas );
00718 }
00719
00720 return col;
00721 }
00722
00723 int KSpreadSheet::rightColumn( double _xpos, const KSpreadCanvas *_canvas ) const
00724 {
00725 if ( _canvas )
00726 _xpos += _canvas->xOffset();
00727
00728 int col = 1;
00729 double x = 0.0;
00730 while ( x < _xpos )
00731 {
00732
00733 if ( col > KS_colMax )
00734 {
00735 kdDebug(36001) << "KSpreadSheet:rightColumn: invalid column (col: " << col << ")" << endl;
00736 return KS_colMax + 1;
00737 }
00738 x += columnFormat( col )->dblWidth( _canvas );
00739 col++;
00740 }
00741
00742 return col - 1;
00743 }
00744
00745 QRect KSpreadSheet::visibleRect( KSpreadCanvas const * const _canvas ) const
00746 {
00747 int top = 0;
00748 int left = 0;
00749
00750 double x = 0;
00751 double y = 0;
00752 double width = 0;
00753 double height = 0;
00754
00755 if ( _canvas )
00756 {
00757 y += _canvas->yOffset() * _canvas->zoom();
00758 x += _canvas->xOffset() * _canvas->zoom();
00759 width = _canvas->width();
00760 height = _canvas->height();
00761 }
00762
00763 double yn = rowFormat( top )->dblHeight( _canvas );
00764 while ( yn < y )
00765 {
00766 if ( top >= KS_rowMax )
00767 break;
00768
00769 ++top;
00770 yn += rowFormat( top )->dblHeight( _canvas );
00771 }
00772
00773 int bottom = top + 1;
00774
00775 y += height;
00776 while ( yn < y )
00777 {
00778 if ( bottom > KS_rowMax )
00779 break;
00780
00781 ++bottom;
00782 yn += rowFormat( bottom )->dblHeight( _canvas );
00783 }
00784
00785 double xn = columnFormat( left )->dblWidth( _canvas );
00786 while ( xn < x )
00787 {
00788 if ( left >= KS_colMax )
00789 break;
00790
00791 ++left;
00792 xn += columnFormat( left )->dblWidth( _canvas );
00793 }
00794 x += width;
00795
00796 int right = left + 1;
00797
00798 while ( xn < x )
00799 {
00800 if ( right > KS_colMax )
00801 break;
00802
00803 ++right;
00804 xn += columnFormat( right )->dblWidth( _canvas );
00805 }
00806 x += width;
00807
00808 return QRect( left, top, right - left + 1, bottom - top + 1 );
00809 }
00810
00811 int KSpreadSheet::topRow( double _ypos, double & _top,
00812 const KSpreadCanvas *_canvas ) const
00813 {
00814 if ( _canvas )
00815 {
00816 _ypos += _canvas->yOffset();
00817 _top = -_canvas->yOffset();
00818 }
00819 else
00820 _top = 0.0;
00821
00822 int row = 1;
00823 double y = rowFormat( row )->dblHeight( _canvas );
00824 while ( y < _ypos )
00825 {
00826
00827 if ( row >= KS_rowMax )
00828 {
00829 kdDebug(36001) << "KSpreadSheet:topRow: invalid row (row: " << row + 1 << ")" << endl;
00830 return KS_rowMax + 1;
00831 }
00832 _top += rowFormat( row )->dblHeight( _canvas );
00833 row++;
00834 y += rowFormat( row )->dblHeight( _canvas );
00835 }
00836
00837 return row;
00838 }
00839
00840 int KSpreadSheet::bottomRow( double _ypos, const KSpreadCanvas *_canvas ) const
00841 {
00842 if ( _canvas )
00843 _ypos += _canvas->yOffset();
00844
00845 int row = 1;
00846 double y = 0.0;
00847 while ( y < _ypos )
00848 {
00849
00850 if ( row > KS_rowMax )
00851 {
00852 kdDebug(36001) << "KSpreadSheet:bottomRow: invalid row (row: " << row << ")" << endl;
00853 return KS_rowMax + 1;
00854 }
00855 y += rowFormat( row )->dblHeight( _canvas );
00856 row++;
00857 }
00858
00859 return row - 1;
00860 }
00861
00862 double KSpreadSheet::dblColumnPos( int _col, const KSpreadCanvas *_canvas ) const
00863 {
00864 double x = 0.0;
00865 if ( _canvas )
00866 x -= _canvas->xOffset();
00867 for ( int col = 1; col < _col; col++ )
00868 {
00869
00870 if ( col > KS_colMax )
00871 {
00872 kdDebug(36001) << "KSpreadSheet:columnPos: invalid column (col: " << col << ")" << endl;
00873 return x;
00874 }
00875
00876 x += columnFormat( col )->dblWidth( _canvas );
00877 }
00878
00879 return x;
00880 }
00881
00882 int KSpreadSheet::columnPos( int _col, const KSpreadCanvas *_canvas ) const
00883 {
00884 return (int)dblColumnPos( _col, _canvas );
00885 }
00886
00887
00888 double KSpreadSheet::dblRowPos( int _row, const KSpreadCanvas *_canvas ) const
00889 {
00890 double y = 0.0;
00891 if ( _canvas )
00892 y -= _canvas->yOffset();
00893
00894 for ( int row = 1 ; row < _row ; row++ )
00895 {
00896
00897 if ( row > KS_rowMax )
00898 {
00899 kdDebug(36001) << "KSpreadSheet:rowPos: invalid row (row: " << row << ")" << endl;
00900 return y;
00901 }
00902
00903 y += rowFormat( row )->dblHeight( _canvas );
00904 }
00905
00906 return y;
00907 }
00908
00909 int KSpreadSheet::rowPos( int _row, const KSpreadCanvas *_canvas ) const
00910 {
00911 return (int)dblRowPos( _row, _canvas );
00912 }
00913
00914
00915 void KSpreadSheet::adjustSizeMaxX ( double _x )
00916 {
00917 d->sizeMaxX += _x;
00918 }
00919
00920 void KSpreadSheet::adjustSizeMaxY ( double _y )
00921 {
00922 d->sizeMaxY += _y;
00923 }
00924
00925 KSpreadCell* KSpreadSheet::visibleCellAt( int _column, int _row, bool _scrollbar_update )
00926 {
00927 KSpreadCell* cell = cellAt( _column, _row, _scrollbar_update );
00928 if ( cell->obscuringCells().isEmpty() )
00929 return cell;
00930 else
00931 return cell->obscuringCells().last();
00932 }
00933
00934 KSpreadCell* KSpreadSheet::firstCell() const
00935 {
00936 return d->cells.firstCell();
00937 }
00938
00939 RowFormat* KSpreadSheet::firstRow() const
00940 {
00941 return d->rows.first();
00942 }
00943
00944 ColumnFormat* KSpreadSheet::firstCol() const
00945 {
00946 return d->columns.first();
00947 }
00948
00949 KSpreadCell* KSpreadSheet::cellAt( int _column, int _row ) const
00950 {
00951 KSpreadCell *p = d->cells.lookup( _column, _row );
00952 if ( p != 0L )
00953 return p;
00954
00955 return d->defaultCell;
00956 }
00957
00958 KSpreadCell* KSpreadSheet::cellAt( int _column, int _row, bool _scrollbar_update )
00959 {
00960 if ( _column > KS_colMax ) {
00961 _column = KS_colMax;
00962 kdDebug (36001) << "KSpreadSheet::cellAt: column range: (col: " << _column << ")" << endl;
00963 }
00964 if ( _row > KS_rowMax) {
00965 kdDebug (36001) << "KSpreadSheet::cellAt: row out of range: (row: " << _row << ")" << endl;
00966 _row = KS_rowMax;
00967 }
00968
00969 if ( _scrollbar_update && d->scrollBarUpdates )
00970 {
00971 checkRangeHBorder( _column );
00972 checkRangeVBorder( _row );
00973 }
00974
00975 KSpreadCell *p = d->cells.lookup( _column, _row );
00976 if ( p != 0L )
00977 return p;
00978
00979 return d->defaultCell;
00980 }
00981
00982 ColumnFormat* KSpreadSheet::nonDefaultColumnFormat( int _column, bool force_creation )
00983 {
00984 ColumnFormat *p = d->columns.lookup( _column );
00985 if ( p != 0L || !force_creation )
00986 return p;
00987
00988 p = new ColumnFormat( this, _column );
00989
00990 p->setDblWidth( d->defaultColumnFormat->dblWidth() );
00991
00992 d->columns.insertElement( p, _column );
00993
00994 return p;
00995 }
00996
00997 RowFormat* KSpreadSheet::nonDefaultRowFormat( int _row, bool force_creation )
00998 {
00999 RowFormat *p = d->rows.lookup( _row );
01000 if ( p != 0L || !force_creation )
01001 return p;
01002
01003 p = new RowFormat( this, _row );
01004
01005 p->setDblHeight( d->defaultRowFormat->dblHeight() );
01006
01007 d->rows.insertElement( p, _row );
01008
01009 return p;
01010 }
01011
01012 KSpreadCell* KSpreadSheet::nonDefaultCell( int _column, int _row,
01013 bool _scrollbar_update, KSpreadStyle * _style )
01014 {
01015 if ( _scrollbar_update && d->scrollBarUpdates )
01016 {
01017 checkRangeHBorder( _column );
01018 checkRangeVBorder( _row );
01019 }
01020
01021 KSpreadCell * p = d->cells.lookup( _column, _row );
01022 if ( p != 0L )
01023 return p;
01024
01025 KSpreadCell * cell = 0;
01026
01027 if ( _style )
01028 cell = new KSpreadCell( this, _style, _column, _row );
01029 else
01030 cell = new KSpreadCell( this, _column, _row );
01031
01032 insertCell( cell );
01033
01034 return cell;
01035 }
01036
01037 void KSpreadSheet::setText( int _row, int _column, const QString& _text, bool asString )
01038 {
01039 KSpreadCell * cell = nonDefaultCell( _column, _row );
01040
01041 if ( isProtected() )
01042 {
01043 if ( !cell->notProtected( _column, _row ) )
01044 NO_MODIFICATION_POSSIBLE;
01045 }
01046
01047 if ( !doc()->undoLocked() )
01048 {
01049 KSpreadUndoSetText *undo = new KSpreadUndoSetText( doc(), this, cell->text(), _column, _row,cell->formatType() );
01050 doc()->addCommand( undo );
01051 }
01052
01053
01054 cell->setCellText( _text, asString );
01055
01056 if(_text.at(0)=='!')
01057 emit sig_updateView( this, QRect(_column,_row,_column,_row) );
01058 }
01059
01060 void KSpreadSheet::setLayoutDirtyFlag()
01061 {
01062 KSpreadCell * c = d->cells.firstCell();
01063 for( ; c; c = c->nextCell() )
01064 c->setLayoutDirtyFlag();
01065 }
01066
01067 void KSpreadSheet::setCalcDirtyFlag()
01068 {
01069 KSpreadCell* c = d->cells.firstCell();
01070 for( ; c; c = c->nextCell() )
01071 {
01072 if ( !(c->isObscured() && c->isObscuringForced()) )
01073 c->setCalcDirtyFlag();
01074 }
01075 }
01076
01077 void KSpreadSheet::recalc()
01078 {
01079
01080
01081 setCalcDirtyFlag();
01082
01083 emit sig_updateView( this );
01084 }
01085
01086 void KSpreadSheet::valueChanged (KSpreadCell *cell)
01087 {
01088
01089
01090
01091
01092 KSpreadPoint c;
01093 c.setRow (cell->row());
01094 c.setColumn (cell->column());
01095 c.sheet = this;
01096
01097
01098 d->dependencies->cellChanged (c);
01099
01100
01101 doc()->setModified (true);
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 class KSpreadUndoAction* KSpreadSheet::CellWorkerTypeA::createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r )
01199 {
01200 QString title = getUndoTitle();
01201 return new KSpreadUndoCellFormat( doc, sheet, r, title );
01202 }
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 KSpreadSheet::SelectionType KSpreadSheet::workOnCells( KSpreadSelection* selectionInfo, CellWorker & worker )
01352 {
01353
01354 QRect selection(selectionInfo->selection());
01355 bool selected = !(selectionInfo->singleCellSelection());
01356
01357 int top = selection.top();
01358 int left = selection.left();
01359 int bottom = selection.bottom();
01360 int right = selection.right();
01361
01362 KSpreadSheet::SelectionType result;
01363
01364 doc()->emitBeginOperation();
01365
01366
01367 KSpreadCell * cell;
01368 KSpreadStyle * s = doc()->styleManager()->defaultStyle();
01369
01370 if ( !worker.type_B && selected && util_isColumnSelected(selection) )
01371 {
01372 for ( RowFormat * rw = d->rows.first(); rw; rw = rw->next() )
01373 {
01374 if ( worker.testCondition( rw ) )
01375 {
01376 for ( int col = left; col <= right; ++col )
01377 {
01378 cell = nonDefaultCell( col, rw->row(), false, s );
01379 }
01380 }
01381 }
01382 }
01383
01384
01385 if ( !doc()->undoLocked() )
01386 {
01387 KSpreadUndoAction * undo = worker.createUndoAction(doc(), this, selection);
01388
01389 if ( undo != 0L )
01390 doc()->addCommand( undo );
01391 }
01392
01393
01394 if ( selected && util_isRowSelected(selection) )
01395 {
01396 for ( int row = top; row <= bottom; ++row )
01397 {
01398 cell = getFirstCellRow( row );
01399 while ( cell )
01400 {
01401 if ( worker.testCondition( cell ) )
01402 {
01403 if ( worker.type_B )
01404 worker.doWork( cell, false, cell->column(), row );
01405 else
01406 worker.prepareCell( cell );
01407 }
01408 cell = getNextCellRight( cell->column(), row );
01409 }
01410 }
01411
01412 if ( worker.type_B )
01413 {
01414
01415 ;
01416 }
01417 else
01418 {
01419
01420 for ( int i = top; i <= bottom; ++i )
01421 {
01422 RowFormat * rw = nonDefaultRowFormat(i);
01423 worker.doWork( rw );
01424 }
01425
01426 for ( int row = top; row <= bottom; ++row )
01427 {
01428 cell = getFirstCellRow( row );
01429 while ( cell )
01430 {
01431 if ( worker.testCondition( cell ) )
01432 {
01433 worker.doWork( cell, false, cell->column(), row );
01434 }
01435 cell = getNextCellRight( cell->column(), row );
01436 }
01437 }
01438
01439 }
01440 result = CompleteRows;
01441 }
01442
01443 else if ( selected && util_isColumnSelected(selection) )
01444 {
01445 for ( int col = selection.left(); col <= right; ++col )
01446 {
01447 cell = getFirstCellColumn( col );
01448 while ( cell )
01449 {
01450 if ( worker.testCondition( cell ) )
01451 {
01452 if ( worker.type_B )
01453 worker.doWork( cell, false, col, cell->row() );
01454 else
01455 worker.prepareCell( cell );
01456 }
01457
01458 cell = getNextCellDown( col, cell->row() );
01459 }
01460 }
01461
01462 if ( worker.type_B )
01463 {
01464 ;
01465 }
01466 else
01467 {
01468
01469 for ( int i = left; i <= right; ++i )
01470 {
01471 ColumnFormat * cl = nonDefaultColumnFormat( i );
01472 worker.doWork( cl );
01473 }
01474
01475 for ( RowFormat * rw = d->rows.first(); rw; rw = rw->next() )
01476 {
01477 if ( worker.testCondition( rw ) )
01478 {
01479 for ( int i = left; i <= right; ++i )
01480 {
01481 cell = nonDefaultCell( i, rw->row(), false, s );
01482 worker.doWork( cell, false, i, rw->row() );
01483 }
01484 }
01485 }
01486 }
01487 result = CompleteColumns;
01488 }
01489
01490 else
01491 {
01492 for ( int x = left; x <= right; ++x )
01493 {
01494 for ( int y = top; y <= bottom; ++y )
01495 {
01496 cell = cellAt( x, y );
01497 if ( worker.testCondition( cell ) )
01498 {
01499 if ( cell == d->defaultCell && worker.create_if_default )
01500 {
01501 cell = new KSpreadCell( this, s, x, y );
01502 insertCell( cell );
01503 }
01504 if ( cell != d->defaultCell )
01505 {
01506
01507 worker.doWork( cell, true, x, y );
01508 }
01509 }
01510 }
01511 }
01512 result = CellRegion;
01513 }
01514
01515
01516 emit sig_updateView( this );
01517
01518 if (worker.emit_signal)
01519 {
01520 emit sig_updateView( this, selection );
01521 }
01522
01523 return result;
01524 }
01525
01526 struct SetSelectionFontWorker : public KSpreadSheet::CellWorkerTypeA
01527 {
01528 const char *_font;
01529 int _size;
01530 signed char _bold;
01531 signed char _italic;
01532 signed char _underline;
01533 signed char _strike;
01534 SetSelectionFontWorker( const char *font, int size, signed char bold, signed char italic,signed char underline, signed char strike )
01535 : _font( font ), _size( size ), _bold( bold ), _italic( italic ), _underline( underline ), _strike( strike ) { }
01536
01537 QString getUndoTitle() { return i18n("Change Font"); }
01538 bool testCondition( RowFormat* rw ) {
01539 return ( rw->hasProperty( KSpreadCell::PFont ) );
01540 }
01541 void doWork( RowFormat* rw ) {
01542 if ( _font )
01543 rw->setTextFontFamily( _font );
01544 if ( _size > 0 )
01545 rw->setTextFontSize( _size );
01546 if ( _italic >= 0 )
01547 rw->setTextFontItalic( (bool)_italic );
01548 if ( _bold >= 0 )
01549 rw->setTextFontBold( (bool)_bold );
01550 if ( _underline >= 0 )
01551 rw->setTextFontUnderline( (bool)_underline );
01552 if ( _strike >= 0 )
01553 rw->setTextFontStrike( (bool)_strike );
01554 }
01555 void doWork( ColumnFormat* cl ) {
01556 if ( _font )
01557 cl->setTextFontFamily( _font );
01558 if ( _size > 0 )
01559 cl->setTextFontSize( _size );
01560 if ( _italic >= 0 )
01561 cl->setTextFontItalic( (bool)_italic );
01562 if ( _bold >= 0 )
01563 cl->setTextFontBold( (bool)_bold );
01564 if ( _underline >= 0 )
01565 cl->setTextFontUnderline( (bool)_underline );
01566 if ( _strike >= 0 )
01567 cl->setTextFontStrike( (bool)_strike );
01568 }
01569 void prepareCell( KSpreadCell* cell ) {
01570 cell->clearProperty( KSpreadCell::PFont );
01571 cell->clearNoFallBackProperties( KSpreadCell::PFont );
01572 }
01573 bool testCondition( KSpreadCell* cell ) {
01574 return ( !cell->isObscuringForced() );
01575 }
01576 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
01577 if ( cellRegion )
01578 cell->setDisplayDirtyFlag();
01579 if ( _font )
01580 cell->setTextFontFamily( _font );
01581 if ( _size > 0 )
01582 cell->setTextFontSize( _size );
01583 if ( _italic >= 0 )
01584 cell->setTextFontItalic( (bool)_italic );
01585 if ( _bold >= 0 )
01586 cell->setTextFontBold( (bool)_bold );
01587 if ( _underline >= 0 )
01588 cell->setTextFontUnderline( (bool)_underline );
01589 if ( _strike >= 0 )
01590 cell->setTextFontStrike( (bool)_strike );
01591 if ( cellRegion )
01592 cell->clearDisplayDirtyFlag();
01593 }
01594 };
01595
01596 void KSpreadSheet::setSelectionFont( KSpreadSelection* selectionInfo,
01597 const char *_font, int _size,
01598 signed char _bold, signed char _italic,
01599 signed char _underline, signed char _strike)
01600 {
01601 SetSelectionFontWorker w( _font, _size, _bold, _italic, _underline, _strike );
01602 workOnCells( selectionInfo, w );
01603 }
01604
01605 struct SetSelectionSizeWorker : public KSpreadSheet::CellWorkerTypeA {
01606 int _size, size;
01607 SetSelectionSizeWorker( int __size, int size2 ) : _size( __size ), size( size2 ) { }
01608
01609 QString getUndoTitle() { return i18n("Change Font"); }
01610 bool testCondition( RowFormat* rw ) {
01611 return ( rw->hasProperty( KSpreadCell::PFont ) );
01612 }
01613 void doWork( RowFormat* rw ) {
01614 rw->setTextFontSize( size + _size) ;
01615 }
01616 void doWork( ColumnFormat* cl ) {
01617 cl->setTextFontSize( size + _size );
01618 }
01619 void prepareCell( KSpreadCell* cell ) {
01620 cell->clearProperty( KSpreadCell::PFont );
01621 cell->clearNoFallBackProperties( KSpreadCell::PFont );
01622 }
01623 bool testCondition( KSpreadCell* cell ) {
01624 return ( !cell->isObscuringForced() );
01625 }
01626 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
01627 if ( cellRegion )
01628 cell->setDisplayDirtyFlag();
01629 cell->setTextFontSize( size + _size );
01630 if ( cellRegion )
01631 cell->clearDisplayDirtyFlag();
01632 }
01633 };
01634
01635 void KSpreadSheet::setSelectionSize( KSpreadSelection* selectionInfo, int _size )
01636 {
01637 int size;
01638 KSpreadCell* c;
01639 QPoint marker(selectionInfo->marker());
01640 c = cellAt(marker);
01641 size = c->textFontSize(marker.x(), marker.y());
01642
01643 SetSelectionSizeWorker w( _size, size );
01644 workOnCells( selectionInfo, w );
01645 }
01646
01647
01648 struct SetSelectionUpperLowerWorker : public KSpreadSheet::CellWorker {
01649 int _type;
01650 KSpreadSheet * _s;
01651 SetSelectionUpperLowerWorker( int type, KSpreadSheet * s )
01652 : KSpreadSheet::CellWorker( false ), _type( type ), _s( s ) { }
01653
01654 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
01655 return new KSpreadUndoChangeAreaTextCell( doc, sheet, r );
01656 }
01657 bool testCondition( KSpreadCell* c ) {
01658 return ( !c->value().isNumber() && !c->value().isBoolean() &&!c->isFormula() && !c->isDefault()
01659 && !c->text().isEmpty() && c->text()[0] != '*' && c->text()[0] != '!'
01660 && !c->isObscuringForced() );
01661 }
01662 void doWork( KSpreadCell* cell, bool, int, int )
01663 {
01664 cell->setDisplayDirtyFlag();
01665 if ( _type == -1 )
01666 cell->setCellText( (cell->text().lower()));
01667 else if ( _type == 1 )
01668 cell->setCellText( (cell->text().upper()));
01669 cell->clearDisplayDirtyFlag();
01670 }
01671 };
01672
01673 void KSpreadSheet::setSelectionUpperLower( KSpreadSelection* selectionInfo,
01674 int _type )
01675 {
01676 SetSelectionUpperLowerWorker w( _type, this );
01677 workOnCells( selectionInfo, w );
01678 }
01679
01680
01681 struct SetSelectionFirstLetterUpperWorker : public KSpreadSheet::CellWorker
01682 {
01683 KSpreadChanges * _c;
01684 KSpreadSheet * _s;
01685 SetSelectionFirstLetterUpperWorker( KSpreadSheet * s )
01686 : KSpreadSheet::CellWorker( false ), _s( s ) { }
01687
01688 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
01689 return new KSpreadUndoChangeAreaTextCell( doc, sheet, r );
01690 }
01691 bool testCondition( KSpreadCell* c ) {
01692 return ( !c->value().isNumber() && !c->value().isBoolean() &&!c->isFormula() && !c->isDefault()
01693 && !c->text().isEmpty() && c->text()[0] != '*' && c->text()[0] != '!'
01694 && !c->isObscuringForced() );
01695 }
01696 void doWork( KSpreadCell* cell, bool, int, int )
01697 {
01698
01699 cell->setDisplayDirtyFlag();
01700 QString tmp = cell->text();
01701 int len = tmp.length();
01702 cell->setCellText( (tmp.at(0).upper()+tmp.right(len-1)) );
01703 cell->clearDisplayDirtyFlag();
01704 }
01705 };
01706
01707 void KSpreadSheet::setSelectionfirstLetterUpper( KSpreadSelection* selectionInfo)
01708 {
01709 SetSelectionFirstLetterUpperWorker w( this );
01710 workOnCells( selectionInfo, w );
01711 }
01712
01713
01714 struct SetSelectionVerticalTextWorker : public KSpreadSheet::CellWorker {
01715 bool _b;
01716 SetSelectionVerticalTextWorker( bool b ) : KSpreadSheet::CellWorker( ), _b( b ) { }
01717
01718 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
01719 QString title=i18n("Vertical Text");
01720 return new KSpreadUndoCellFormat( doc, sheet, r, title );
01721 }
01722 bool testCondition( KSpreadCell* cell ) {
01723 return ( !cell->isObscuringForced() );
01724 }
01725 void doWork( KSpreadCell* cell, bool, int, int ) {
01726 cell->setDisplayDirtyFlag();
01727 cell->setVerticalText( _b );
01728 cell->setMultiRow( false );
01729 cell->setAngle( 0 );
01730 cell->clearDisplayDirtyFlag();
01731 }
01732 };
01733
01734 void KSpreadSheet::setSelectionVerticalText( KSpreadSelection* selectionInfo,
01735 bool _b )
01736 {
01737 SetSelectionVerticalTextWorker w( _b );
01738 workOnCells( selectionInfo, w );
01739 }
01740
01741
01742 struct SetSelectionCommentWorker : public KSpreadSheet::CellWorker {
01743 QString _comment;
01744 SetSelectionCommentWorker( QString comment ) : KSpreadSheet::CellWorker( ), _comment( comment ) { }
01745
01746 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
01747 QString title=i18n("Add Comment");
01748 return new KSpreadUndoCellFormat( doc, sheet, r, title );
01749 }
01750 bool testCondition( KSpreadCell* cell ) {
01751 return ( !cell->isObscuringForced() );
01752 }
01753 void doWork( KSpreadCell* cell, bool, int, int ) {
01754 cell->setDisplayDirtyFlag();
01755 cell->setComment( _comment );
01756 cell->clearDisplayDirtyFlag();
01757 }
01758 };
01759
01760 void KSpreadSheet::setSelectionComment( KSpreadSelection* selectionInfo,
01761 const QString &_comment)
01762 {
01763 SetSelectionCommentWorker w( _comment );
01764 workOnCells( selectionInfo, w );
01765 }
01766
01767
01768 struct SetSelectionAngleWorker : public KSpreadSheet::CellWorkerTypeA {
01769 int _value;
01770 SetSelectionAngleWorker( int value ) : _value( value ) { }
01771
01772 QString getUndoTitle() { return i18n("Change Angle"); }
01773 KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ){
01774 return new KSpreadUndoChangeAngle( doc, sheet, r );
01775 }
01776
01777 bool testCondition( RowFormat* rw ) {
01778 return ( rw->hasProperty( KSpreadCell::PAngle ) );
01779 }
01780 void doWork( RowFormat* rw ) {
01781 rw->setAngle( _value );
01782 }
01783 void doWork( ColumnFormat* cl ) {
01784 cl->setAngle( _value );
01785 }
01786 void prepareCell( KSpreadCell* cell ) {
01787 cell->clearProperty( KSpreadCell::PAngle );
01788 cell->clearNoFallBackProperties( KSpreadCell::PAngle );
01789 }
01790 bool testCondition( KSpreadCell* cell ) {
01791 return ( !cell->isObscuringForced() );
01792 }
01793 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
01794 if ( cellRegion )
01795 cell->setDisplayDirtyFlag();
01796 cell->setAngle( _value );
01797 if ( cellRegion ) {
01798 cell->setVerticalText(false);
01799 cell->setMultiRow( false );
01800 cell->clearDisplayDirtyFlag();
01801 }
01802 }
01803 };
01804
01805 void KSpreadSheet::setSelectionAngle( KSpreadSelection* selectionInfo,
01806 int _value )
01807 {
01808 SetSelectionAngleWorker w( _value );
01809 workOnCells( selectionInfo, w );
01810 }
01811
01812 struct SetSelectionRemoveCommentWorker : public KSpreadSheet::CellWorker {
01813 SetSelectionRemoveCommentWorker( ) : KSpreadSheet::CellWorker( false ) { }
01814
01815 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
01816 QString title=i18n("Remove Comment");
01817 return new KSpreadUndoCellFormat( doc, sheet, r, title );
01818 }
01819 bool testCondition( KSpreadCell* cell ) {
01820 return ( !cell->isObscuringForced() );
01821 }
01822 void doWork( KSpreadCell* cell, bool, int, int ) {
01823 cell->setDisplayDirtyFlag();
01824 cell->setComment( "" );
01825 cell->clearDisplayDirtyFlag();
01826 }
01827 };
01828
01829 void KSpreadSheet::setSelectionRemoveComment( KSpreadSelection* selectionInfo )
01830 {
01831 if(areaIsEmpty(selectionInfo->selection(), Comment))
01832 return;
01833 SetSelectionRemoveCommentWorker w;
01834 workOnCells( selectionInfo, w );
01835 }
01836
01837
01838 struct SetSelectionTextColorWorker : public KSpreadSheet::CellWorkerTypeA {
01839 const QColor& tb_Color;
01840 SetSelectionTextColorWorker( const QColor& _tb_Color ) : tb_Color( _tb_Color ) { }
01841
01842 QString getUndoTitle() { return i18n("Change Text Color"); }
01843 bool testCondition( RowFormat* rw ) {
01844 return ( rw->hasProperty( KSpreadCell::PTextPen ) );
01845 }
01846 void doWork( RowFormat* rw ) {
01847 rw->setTextColor( tb_Color );
01848 }
01849 void doWork( ColumnFormat* cl ) {
01850 cl->setTextColor( tb_Color );
01851 }
01852 void prepareCell( KSpreadCell* cell ) {
01853 cell->clearProperty( KSpreadCell::PTextPen );
01854 cell->clearNoFallBackProperties( KSpreadCell::PTextPen );
01855 }
01856 bool testCondition( KSpreadCell* cell ) {
01857 return ( !cell->isObscuringForced() );
01858 }
01859 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
01860 if ( cellRegion )
01861 cell->setDisplayDirtyFlag();
01862 cell->setTextColor( tb_Color );
01863 if ( cellRegion )
01864 cell->clearDisplayDirtyFlag();
01865 }
01866 };
01867
01868 void KSpreadSheet::setSelectionTextColor( KSpreadSelection* selectionInfo,
01869 const QColor &tb_Color )
01870 {
01871 SetSelectionTextColorWorker w( tb_Color );
01872 workOnCells( selectionInfo, w );
01873 }
01874
01875
01876 struct SetSelectionBgColorWorker : public KSpreadSheet::CellWorkerTypeA {
01877 const QColor& bg_Color;
01878 SetSelectionBgColorWorker( const QColor& _bg_Color ) : bg_Color( _bg_Color ) { }
01879
01880 QString getUndoTitle() { return i18n("Change Background Color"); }
01881 bool testCondition( RowFormat* rw ) {
01882 return ( rw->hasProperty( KSpreadCell::PBackgroundColor ) );
01883 }
01884 void doWork( RowFormat* rw ) {
01885 rw->setBgColor( bg_Color );
01886 }
01887 void doWork( ColumnFormat* cl ) {
01888 cl->setBgColor( bg_Color );
01889 }
01890 void prepareCell( KSpreadCell* cell ) {
01891 cell->clearProperty( KSpreadCell::PBackgroundColor );
01892 cell->clearNoFallBackProperties( KSpreadCell::PBackgroundColor );
01893 }
01894 bool testCondition( KSpreadCell* cell ) {
01895 return ( !cell->isObscuringForced() );
01896 }
01897 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
01898 if ( cellRegion )
01899 cell->setDisplayDirtyFlag();
01900 cell->setBgColor( bg_Color );
01901 if ( cellRegion )
01902 cell->clearDisplayDirtyFlag();
01903 }
01904 };
01905
01906 void KSpreadSheet::setSelectionbgColor( KSpreadSelection* selectionInfo,
01907 const QColor &bg_Color )
01908 {
01909 SetSelectionBgColorWorker w( bg_Color );
01910 workOnCells( selectionInfo, w );
01911 }
01912
01913
01914 struct SetSelectionBorderColorWorker : public KSpreadSheet::CellWorker {
01915 const QColor& bd_Color;
01916 SetSelectionBorderColorWorker( const QColor& _bd_Color ) : KSpreadSheet::CellWorker( false ), bd_Color( _bd_Color ) { }
01917
01918 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
01919 QString title=i18n("Change Border Color");
01920 return new KSpreadUndoCellFormat( doc, sheet, r, title );
01921 }
01922 bool testCondition( KSpreadCell* cell ) {
01923 return ( !cell->isObscuringForced() );
01924 }
01925 void doWork( KSpreadCell* cell, bool, int, int ) {
01926 cell->setDisplayDirtyFlag();
01927 int it_Row = cell->row();
01928 int it_Col = cell->column();
01929 if ( cell->topBorderStyle( it_Row, it_Col )!=Qt::NoPen )
01930 cell->setTopBorderColor( bd_Color );
01931 if ( cell->leftBorderStyle( it_Row, it_Col )!=Qt::NoPen )
01932 cell->setLeftBorderColor( bd_Color );
01933 if ( cell->fallDiagonalStyle( it_Row, it_Col )!=Qt::NoPen )
01934 cell->setFallDiagonalColor( bd_Color );
01935 if ( cell->goUpDiagonalStyle( it_Row, it_Col )!=Qt::NoPen )
01936 cell->setGoUpDiagonalColor( bd_Color );
01937 if ( cell->bottomBorderStyle( it_Row, it_Col )!=Qt::NoPen )
01938 cell->setBottomBorderColor( bd_Color );
01939 if ( cell->rightBorderStyle( it_Row, it_Col )!=Qt::NoPen )
01940 cell->setRightBorderColor( bd_Color );
01941 cell->clearDisplayDirtyFlag();
01942 }
01943 };
01944
01945 void KSpreadSheet::setSelectionBorderColor( KSpreadSelection* selectionInfo,
01946 const QColor &bd_Color )
01947 {
01948 SetSelectionBorderColorWorker w( bd_Color );
01949 workOnCells( selectionInfo, w );
01950 }
01951
01952
01953 void KSpreadSheet::setSeries( const QPoint &_marker, double start, double end, double step, Series mode, Series type)
01954 {
01955 doc()->emitBeginOperation();
01956
01957 QString cellText;
01958
01959 int x,y;
01960
01961
01962
01963
01964 int numberOfCells;
01965 if (end > start)
01966 numberOfCells = (int) ((end - start) / step + 1);
01967 else if ( end <start )
01968 numberOfCells = (int) ((start - end) / step + 1);
01969 else
01970 numberOfCells = 1;
01971 if (type == Geometric)
01972 {
01973
01974
01975
01976
01977 numberOfCells = (int)( (log((double)end) / log((double)start)) +
01978 DBL_EPSILON) + 1;
01979 }
01980
01981 KSpreadCell * cell = NULL;
01982
01983
01984
01985
01986 QRect undoRegion;
01987
01988 undoRegion.setLeft(_marker.x());
01989 undoRegion.setTop(_marker.y());
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002 if ( mode == Column )
02003 {
02004 for ( y = _marker.y(); y <= (_marker.y() + numberOfCells - 1); y++ )
02005 {
02006 cell = cellAt( _marker.x(), y );
02007
02008 if ( cell->isObscuringForced() )
02009 {
02010
02011 cell = cell->obscuringCells().first();
02012 undoRegion.setLeft(QMIN(undoRegion.left(), cell->column()));
02013 }
02014
02015
02016
02017
02018
02019 numberOfCells += cell->extraYCells();
02020 y += cell->extraYCells();
02021 }
02022 undoRegion.setRight( _marker.x() );
02023 undoRegion.setBottom( y - 1 );
02024 }
02025 else if(mode == Row)
02026 {
02027 for ( x = _marker.x(); x <=(_marker.x() + numberOfCells - 1); x++ )
02028 {
02029
02030
02031 cell = cellAt( x,_marker.y() );
02032
02033 if ( cell->isObscuringForced() )
02034 {
02035 cell = cell->obscuringCells().first();
02036 undoRegion.setTop(QMIN(undoRegion.top(), cell->row()));
02037 }
02038 numberOfCells += cell->extraXCells();
02039 x += cell->extraXCells();
02040 }
02041 undoRegion.setBottom( _marker.y() );
02042 undoRegion.setRight( x - 1 );
02043 }
02044
02045 kdDebug() << "Saving undo information" << endl;
02046
02047 if ( !doc()->undoLocked() )
02048 {
02049 KSpreadUndoChangeAreaTextCell *undo = new
02050 KSpreadUndoChangeAreaTextCell( doc(), this, undoRegion );
02051 doc()->addCommand( undo );
02052 }
02053
02054 kdDebug() << "Saving undo information done" << endl;
02055
02056 x = _marker.x();
02057 y = _marker.y();
02058
02059
02060 double incr;
02061 KSpreadStyle * s = doc()->styleManager()->defaultStyle();
02062 if (step >= 0 && start < end)
02063 {
02064 for ( incr = start; incr <= end; )
02065 {
02066 cell = nonDefaultCell( x, y, false, s );
02067
02068 if ( cell->isObscuringForced() )
02069 {
02070 cell = cell->obscuringCells().first();
02071 }
02072
02073
02074
02075 cell->setNumber( incr );
02076 if (mode == Column)
02077 {
02078 ++y;
02079 if (cell->isForceExtraCells())
02080 {
02081 y += cell->extraYCells();
02082 }
02083 }
02084 else if (mode == Row)
02085 {
02086 ++x;
02087 if (cell->isForceExtraCells())
02088 {
02089 x += cell->extraXCells();
02090 }
02091 }
02092 else
02093 {
02094 kdDebug(36001) << "Error in Series::mode" << endl;
02095 return;
02096 }
02097
02098 if (type == Linear)
02099 incr = incr + step;
02100 else if (type == Geometric)
02101 incr = incr * step;
02102 else
02103 {
02104 kdDebug(36001) << "Error in Series::type" << endl;
02105 return;
02106 }
02107 }
02108 }
02109 else
02110 if (step >= 0 && start > end)
02111 {
02112 for ( incr = start; incr >= end; )
02113 {
02114 cell = nonDefaultCell( x, y, false, s );
02115
02116 if (cell->isObscuringForced())
02117 {
02118 cell = cell->obscuringCells().first();
02119 }
02120
02121
02122 cell->setNumber( incr );
02123 if (mode == Column)
02124 {
02125 ++y;
02126 if (cell->isForceExtraCells())
02127 {
02128 y += cell->extraYCells();
02129 }
02130 }
02131 else if (mode == Row)
02132 {
02133 ++x;
02134 if (cell->isForceExtraCells())
02135 {
02136 x += cell->extraXCells();
02137 }
02138 }
02139 else
02140 {
02141 kdDebug(36001) << "Error in Series::mode" << endl;
02142 return;
02143 }
02144
02145 if (type == Linear)
02146 incr = incr + step;
02147 else if (type == Geometric)
02148 incr = incr * step;
02149 else
02150 {
02151 kdDebug(36001) << "Error in Series::type" << endl;
02152 return;
02153 }
02154 }
02155 }
02156 else
02157 {
02158 for ( incr = start; incr <= end; )
02159 {
02160 cell = nonDefaultCell( x, y, false, s );
02161
02162 if (cell->isObscuringForced())
02163 {
02164 cell = cell->obscuringCells().first();
02165 }
02166
02167
02168 cell->setNumber( incr );
02169 if (mode == Column)
02170 {
02171 ++y;
02172 if (cell->isForceExtraCells())
02173 {
02174 y += cell->extraYCells();
02175 }
02176 }
02177 else if (mode == Row)
02178 {
02179 ++x;
02180 if (cell->isForceExtraCells())
02181 {
02182 x += cell->extraXCells();
02183 }
02184 }
02185 else
02186 {
02187 kdDebug(36001) << "Error in Series::mode" << endl;
02188 return;
02189 }
02190
02191 if (type == Linear)
02192 incr = incr + step;
02193 else if (type == Geometric)
02194 {
02195
02196 incr = incr * step;
02197
02198
02199 if (step == 1)
02200 return;
02201 }
02202 else
02203 {
02204 kdDebug(36001) << "Error in Series::type" << endl;
02205 return;
02206 }
02207 }
02208 }
02209
02210 emit sig_updateView( this );
02211 }
02212
02213
02214 struct SetSelectionPercentWorker : public KSpreadSheet::CellWorkerTypeA
02215 {
02216 bool b;
02217 SetSelectionPercentWorker( bool _b ) : b( _b ) { }
02218
02219 QString getUndoTitle() { return i18n("Format Percent"); }
02220 bool testCondition( RowFormat* rw ) {
02221
02222 return ( true );
02223 }
02224 void doWork( RowFormat* rw ) {
02225
02226 rw->setFormatType( b ? Percentage_format : Generic_format);
02227 }
02228 void doWork( ColumnFormat* cl ) {
02229 cl->setFormatType( b ? Percentage_format : Generic_format);
02230 }
02231 void prepareCell( KSpreadCell* cell ) {
02232 cell->clearProperty(KSpreadCell::PFormatType);
02233 cell->clearNoFallBackProperties( KSpreadCell::PFormatType );
02234 }
02235 bool testCondition( KSpreadCell* cell ) {
02236 return ( !cell->isObscuringForced() );
02237 }
02238 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
02239 if ( cellRegion )
02240 cell->setDisplayDirtyFlag();
02241 cell->setFormatType( b ? Percentage_format : Generic_format);
02242 if ( cellRegion )
02243 cell->clearDisplayDirtyFlag();
02244 }
02245 };
02246
02247 void KSpreadSheet::setSelectionPercent( KSpreadSelection* selectionInfo, bool b )
02248 {
02249 SetSelectionPercentWorker w( b );
02250 workOnCells( selectionInfo, w );
02251 }
02252
02253
02254 void KSpreadSheet::refreshRemoveAreaName(const QString & _areaName)
02255 {
02256 KSpreadCell * c = d->cells.firstCell();
02257 QString tmp = "'" + _areaName + "'";
02258 for( ;c ; c = c->nextCell() )
02259 {
02260 if ( c->isFormula() )
02261 {
02262 if (c->text().find(tmp) != -1)
02263 {
02264 if ( !c->makeFormula() )
02265 kdError(36001) << "ERROR: Syntax ERROR" << endl;
02266 }
02267 }
02268 }
02269 }
02270
02271 void KSpreadSheet::refreshChangeAreaName(const QString & _areaName)
02272 {
02273 KSpreadCell * c = d->cells.firstCell();
02274 QString tmp = "'" + _areaName + "'";
02275 for( ;c ; c = c->nextCell() )
02276 {
02277 if ( c->isFormula() )
02278 {
02279 if (c->text().find(tmp) != -1)
02280 {
02281 if ( !c->makeFormula() )
02282 kdError(36001) << "ERROR: Syntax ERROR" << endl;
02283 else
02284 {
02285
02286 c->setCalcDirtyFlag();
02287 }
02288 }
02289 }
02290 }
02291 }
02292
02293 void KSpreadSheet::changeCellTabName( QString const & old_name, QString const & new_name )
02294 {
02295 KSpreadCell* c = d->cells.firstCell();
02296 for( ;c; c = c->nextCell() )
02297 {
02298 if( c->isFormula() )
02299 {
02300 if(c->text().find(old_name)!=-1)
02301 {
02302 int nb = c->text().contains(old_name+"!");
02303 QString tmp=old_name+"!";
02304 int len = tmp.length();
02305 tmp=c->text();
02306
02307 for( int i=0; i<nb; i++ )
02308 {
02309 int pos = tmp.find( old_name+"!" );
02310 tmp.replace( pos, len, new_name+"!" );
02311 }
02312 c->setCellText(tmp);
02313 }
02314 }
02315 }
02316 }
02317
02318 bool KSpreadSheet::shiftRow( const QRect &rect,bool makeUndo )
02319 {
02320 KSpreadUndoInsertCellRow * undo = 0;
02321 if ( !doc()->undoLocked() &&makeUndo)
02322 {
02323 undo = new KSpreadUndoInsertCellRow( doc(), this, rect );
02324 doc()->addCommand( undo );
02325 }
02326
02327 bool res=true;
02328 bool result;
02329 for( int i=rect.top(); i<=rect.bottom(); i++ )
02330 {
02331 for( int j=0; j<=(rect.right()-rect.left()); j++ )
02332 {
02333 result = d->cells.shiftRow( QPoint(rect.left(),i) );
02334 if( !result )
02335 res=false;
02336 }
02337 }
02338 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02339 for( ; it.current(); ++it )
02340 {
02341 for(int i = rect.top(); i <= rect.bottom(); i++ )
02342 it.current()->changeNameCellRef( QPoint( rect.left(), i ), false,
02343 KSpreadSheet::ColumnInsert, name(),
02344 ( rect.right() - rect.left() + 1),
02345 undo);
02346 }
02347 refreshChart(QPoint(rect.left(),rect.top()), false, KSpreadSheet::ColumnInsert);
02348 refreshMergedCell();
02349 recalc();
02350 emit sig_updateView( this );
02351
02352 return res;
02353 }
02354
02355 bool KSpreadSheet::shiftColumn( const QRect& rect,bool makeUndo )
02356 {
02357 KSpreadUndoInsertCellCol * undo = 0;
02358 if ( !doc()->undoLocked() &&makeUndo)
02359 {
02360 undo = new KSpreadUndoInsertCellCol( doc(), this,rect);
02361 doc()->addCommand( undo );
02362 }
02363
02364 bool res=true;
02365 bool result;
02366 for( int i =rect.left(); i<=rect.right(); i++ )
02367 {
02368 for( int j=0; j<=(rect.bottom()-rect.top()); j++ )
02369 {
02370 result = d->cells.shiftColumn( QPoint(i,rect.top()) );
02371 if(!result)
02372 res=false;
02373 }
02374 }
02375
02376 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02377 for( ; it.current(); ++it )
02378 {
02379 for(int i=rect.left();i<=rect.right();i++)
02380 it.current()->changeNameCellRef( QPoint( i, rect.top() ), false,
02381 KSpreadSheet::RowInsert, name(),
02382 ( rect.bottom() - rect.top() + 1 ),
02383 undo );
02384 }
02385 refreshChart(QPoint(rect.left(),rect.top()), false, KSpreadSheet::RowInsert);
02386 refreshMergedCell();
02387 recalc();
02388 emit sig_updateView( this );
02389
02390 return res;
02391 }
02392
02393 void KSpreadSheet::unshiftColumn( const QRect & rect,bool makeUndo )
02394 {
02395 KSpreadUndoRemoveCellCol * undo = 0;
02396 if ( !doc()->undoLocked() && makeUndo )
02397 {
02398 undo = new KSpreadUndoRemoveCellCol( doc(), this, rect );
02399 doc()->addCommand( undo );
02400 }
02401
02402 for(int i =rect.top();i<=rect.bottom();i++)
02403 for(int j=rect.left();j<=rect.right();j++)
02404 d->cells.remove(j,i);
02405
02406 for(int i =rect.left();i<=rect.right();i++)
02407 for(int j=0;j<=(rect.bottom()-rect.top());j++)
02408 d->cells.unshiftColumn( QPoint(i,rect.top()) );
02409
02410 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02411 for( ; it.current(); ++it )
02412 for(int i=rect.left();i<=rect.right();i++)
02413 it.current()->changeNameCellRef( QPoint( i, rect.top() ), false,
02414 KSpreadSheet::RowRemove, name(),
02415 ( rect.bottom() - rect.top() + 1 ),
02416 undo );
02417
02418 refreshChart( QPoint(rect.left(),rect.top()), false, KSpreadSheet::RowRemove );
02419 refreshMergedCell();
02420 recalc();
02421 emit sig_updateView( this );
02422 }
02423
02424 void KSpreadSheet::unshiftRow( const QRect & rect,bool makeUndo )
02425 {
02426 KSpreadUndoRemoveCellRow * undo = 0;
02427 if ( !doc()->undoLocked() && makeUndo )
02428 {
02429 undo = new KSpreadUndoRemoveCellRow( doc(), this, rect );
02430 doc()->addCommand( undo );
02431 }
02432 for(int i =rect.top();i<=rect.bottom();i++)
02433 for(int j=rect.left();j<=rect.right();j++)
02434 d->cells.remove(j,i);
02435
02436 for(int i =rect.top();i<=rect.bottom();i++)
02437 for(int j=0;j<=(rect.right()-rect.left());j++)
02438 d->cells.unshiftRow( QPoint(rect.left(),i) );
02439
02440 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02441 for( ; it.current(); ++it )
02442 for(int i=rect.top();i<=rect.bottom();i++)
02443 it.current()->changeNameCellRef( QPoint( rect.left(), i ), false,
02444 KSpreadSheet::ColumnRemove, name(),
02445 ( rect.right() - rect.left() + 1 ),
02446 undo);
02447
02448 refreshChart(QPoint(rect.left(),rect.top()), false, KSpreadSheet::ColumnRemove );
02449 refreshMergedCell();
02450 recalc();
02451 emit sig_updateView( this );
02452 }
02453
02454 bool KSpreadSheet::insertColumn( int col, int nbCol, bool makeUndo )
02455 {
02456 KSpreadUndoInsertColumn * undo = 0;
02457 if ( !doc()->undoLocked() && makeUndo)
02458 {
02459 undo = new KSpreadUndoInsertColumn( doc(), this, col, nbCol );
02460 doc()->addCommand( undo );
02461 }
02462
02463 bool res=true;
02464 bool result;
02465 for( int i=0; i<=nbCol; i++ )
02466 {
02467
02468 d->sizeMaxX -= columnFormat( KS_colMax )->dblWidth();
02469
02470 result = d->cells.insertColumn( col );
02471 d->columns.insertColumn( col );
02472 if(!result)
02473 res = false;
02474
02475
02476 d->sizeMaxX += columnFormat( col+i )->dblWidth();
02477 }
02478
02479 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02480 for( ; it.current(); ++it )
02481 it.current()->changeNameCellRef( QPoint( col, 1 ), true,
02482 KSpreadSheet::ColumnInsert, name(),
02483 nbCol + 1, undo );
02484
02485
02486 d->print->insertColumn( col, nbCol );
02487
02488 refreshChart( QPoint( col, 1 ), true, KSpreadSheet::ColumnInsert );
02489 refreshMergedCell();
02490 recalc();
02491 emit sig_updateHBorder( this );
02492 emit sig_updateView( this );
02493
02494 return res;
02495 }
02496
02497 bool KSpreadSheet::insertRow( int row, int nbRow, bool makeUndo )
02498 {
02499 KSpreadUndoInsertRow *undo = 0;
02500 if ( !doc()->undoLocked() && makeUndo)
02501 {
02502 undo = new KSpreadUndoInsertRow( doc(), this, row, nbRow );
02503 doc()->addCommand( undo );
02504 }
02505
02506 bool res=true;
02507 bool result;
02508 for( int i=0; i<=nbRow; i++ )
02509 {
02510
02511 d->sizeMaxY -= rowFormat( KS_rowMax )->dblHeight();
02512
02513 result = d->cells.insertRow( row );
02514 d->rows.insertRow( row );
02515 if( !result )
02516 res = false;
02517
02518
02519 d->sizeMaxY += rowFormat( row )->dblHeight();
02520 }
02521
02522 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02523 for( ; it.current(); ++it )
02524 it.current()->changeNameCellRef( QPoint( 1, row ), true,
02525 KSpreadSheet::RowInsert, name(),
02526 nbRow + 1, undo );
02527
02528
02529 d->print->insertRow( row, nbRow );
02530
02531 refreshChart( QPoint( 1, row ), true, KSpreadSheet::RowInsert );
02532 refreshMergedCell();
02533 recalc();
02534 emit sig_updateVBorder( this );
02535 emit sig_updateView( this );
02536
02537 return res;
02538 }
02539
02540 void KSpreadSheet::removeColumn( int col, int nbCol, bool makeUndo )
02541 {
02542 KSpreadUndoRemoveColumn *undo = 0;
02543 if ( !doc()->undoLocked() && makeUndo)
02544 {
02545 undo = new KSpreadUndoRemoveColumn( doc(), this, col, nbCol );
02546 doc()->addCommand( undo );
02547 }
02548
02549 for( int i = 0; i <= nbCol; ++i )
02550 {
02551
02552 d->sizeMaxX -= columnFormat( col )->dblWidth();
02553
02554 d->cells.removeColumn( col );
02555 d->columns.removeColumn( col );
02556
02557
02558 d->sizeMaxX += columnFormat( KS_colMax )->dblWidth();
02559 }
02560
02561 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02562 for( ; it.current(); ++it )
02563 it.current()->changeNameCellRef( QPoint( col, 1 ), true,
02564 KSpreadSheet::ColumnRemove, name(),
02565 nbCol + 1, undo );
02566
02567
02568 d->print->removeColumn( col, nbCol );
02569
02570 refreshChart( QPoint( col, 1 ), true, KSpreadSheet::ColumnRemove );
02571 refreshMergedCell();
02572 recalc();
02573 emit sig_updateHBorder( this );
02574 emit sig_updateView( this );
02575 }
02576
02577 void KSpreadSheet::removeRow( int row, int nbRow, bool makeUndo )
02578 {
02579 KSpreadUndoRemoveRow *undo = 0;
02580 if ( !doc()->undoLocked() && makeUndo )
02581 {
02582 undo = new KSpreadUndoRemoveRow( doc(), this, row, nbRow );
02583 doc()->addCommand( undo );
02584 }
02585
02586 for( int i=0; i<=nbRow; i++ )
02587 {
02588
02589 d->sizeMaxY -= rowFormat( row )->dblHeight();
02590
02591 d->cells.removeRow( row );
02592 d->rows.removeRow( row );
02593
02594
02595 d->sizeMaxY += rowFormat( KS_rowMax )->dblHeight();
02596 }
02597
02598 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
02599 for( ; it.current(); ++it )
02600 it.current()->changeNameCellRef( QPoint( 1, row ), true,
02601 KSpreadSheet::RowRemove, name(),
02602 nbRow + 1, undo );
02603
02604
02605 d->print->removeRow( row, nbRow );
02606
02607 refreshChart( QPoint( 1, row ), true, KSpreadSheet::RowRemove );
02608 refreshMergedCell();
02609 recalc();
02610 emit sig_updateVBorder( this );
02611 emit sig_updateView( this );
02612 }
02613
02614 void KSpreadSheet::hideRow( int _row, int nbRow, QValueList<int>_list )
02615 {
02616 if ( !doc()->undoLocked() )
02617 {
02618 KSpreadUndoHideRow *undo ;
02619 if( nbRow!=-1 )
02620 undo= new KSpreadUndoHideRow( doc(), this, _row, nbRow );
02621 else
02622 undo= new KSpreadUndoHideRow( doc(), this, _row, nbRow, _list );
02623 doc()->addCommand( undo );
02624 }
02625
02626 RowFormat *rl;
02627 if( nbRow!=-1 )
02628 {
02629 for( int i=0; i<=nbRow; i++ )
02630 {
02631 rl=nonDefaultRowFormat( _row+i );
02632 rl->setHide(true);
02633 }
02634 }
02635 else
02636 {
02637 QValueList<int>::Iterator it;
02638 for( it = _list.begin(); it != _list.end(); ++it )
02639 {
02640 rl=nonDefaultRowFormat( *it );
02641 rl->setHide(true);
02642 }
02643 }
02644 emitHideRow();
02645 }
02646
02647 void KSpreadSheet::emitHideRow()
02648 {
02649 emit sig_updateVBorder( this );
02650 emit sig_updateView( this );
02651 }
02652
02653 void KSpreadSheet::showRow( int _row, int nbRow, QValueList<int>_list )
02654 {
02655 if ( !doc()->undoLocked() )
02656 {
02657 KSpreadUndoShowRow *undo;
02658 if(nbRow!=-1)
02659 undo = new KSpreadUndoShowRow( doc(), this, _row,nbRow );
02660 else
02661 undo = new KSpreadUndoShowRow( doc(), this, _row,nbRow, _list );
02662 doc()->addCommand( undo );
02663 }
02664
02665 RowFormat *rl;
02666 if( nbRow!=-1 )
02667 {
02668 for( int i=0; i<=nbRow; i++ )
02669 {
02670 rl=nonDefaultRowFormat( _row + i );
02671 rl->setHide( false );
02672 }
02673 }
02674 else
02675 {
02676 QValueList<int>::Iterator it;
02677 for( it = _list.begin(); it != _list.end(); ++it )
02678 {
02679 rl=nonDefaultRowFormat( *it );
02680 rl->setHide( false );
02681 }
02682 }
02683 emit sig_updateVBorder( this );
02684 emit sig_updateView( this );
02685 }
02686
02687
02688 void KSpreadSheet::hideColumn( int _col, int nbCol, QValueList<int>_list )
02689 {
02690 if ( !doc()->undoLocked() )
02691 {
02692 KSpreadUndoHideColumn *undo;
02693 if( nbCol!=-1 )
02694 undo= new KSpreadUndoHideColumn( doc(), this, _col, nbCol );
02695 else
02696 undo= new KSpreadUndoHideColumn( doc(), this, _col, nbCol, _list );
02697 doc()->addCommand( undo );
02698 }
02699
02700 ColumnFormat *cl;
02701 if( nbCol != -1 )
02702 {
02703 for( int i=0; i<=nbCol; i++ )
02704 {
02705 cl=nonDefaultColumnFormat( _col + i );
02706 cl->setHide( true );
02707 }
02708 }
02709 else
02710 {
02711 QValueList<int>::Iterator it;
02712 for( it = _list.begin(); it != _list.end(); ++it )
02713 {
02714 cl=nonDefaultColumnFormat( *it );
02715 cl->setHide( true );
02716 }
02717 }
02718 emitHideColumn();
02719 }
02720
02721 void KSpreadSheet::emitHideColumn()
02722 {
02723 emit sig_updateHBorder( this );
02724 emit sig_updateView( this );
02725 }
02726
02727
02728 void KSpreadSheet::showColumn( int _col, int nbCol, QValueList<int>_list )
02729 {
02730 if ( !doc()->undoLocked() )
02731 {
02732 KSpreadUndoShowColumn *undo;
02733 if( nbCol != -1 )
02734 undo = new KSpreadUndoShowColumn( doc(), this, _col, nbCol );
02735 else
02736 undo = new KSpreadUndoShowColumn( doc(), this, _col, nbCol, _list );
02737 doc()->addCommand( undo );
02738 }
02739
02740 ColumnFormat *cl;
02741 if( nbCol != -1 )
02742 {
02743 for( int i=0; i<=nbCol; i++ )
02744 {
02745 cl=nonDefaultColumnFormat( _col + i );
02746 cl->setHide( false );
02747 }
02748 }
02749 else
02750 {
02751 QValueList<int>::Iterator it;
02752 for( it = _list.begin(); it != _list.end(); ++it )
02753 {
02754 cl=nonDefaultColumnFormat( *it );
02755 cl->setHide( false );
02756 }
02757 }
02758 emit sig_updateHBorder( this );
02759 emit sig_updateView( this );
02760 }
02761
02762
02763 void KSpreadSheet::refreshChart(const QPoint & pos, bool fullRowOrColumn, ChangeRef ref)
02764 {
02765 KSpreadCell * c = d->cells.firstCell();
02766 for( ;c; c = c->nextCell() )
02767 {
02768 if ( (ref == ColumnInsert || ref == ColumnRemove) && fullRowOrColumn
02769 && c->column() >= (pos.x() - 1))
02770 {
02771 if (c->updateChart())
02772 return;
02773 }
02774 else if ( (ref == ColumnInsert || ref == ColumnRemove )&& !fullRowOrColumn
02775 && c->column() >= (pos.x() - 1) && c->row() == pos.y() )
02776 {
02777 if (c->updateChart())
02778 return;
02779 }
02780 else if ((ref == RowInsert || ref == RowRemove) && fullRowOrColumn
02781 && c->row() >= (pos.y() - 1))
02782 {
02783 if (c->updateChart())
02784 return;
02785 }
02786 else if ( (ref == RowInsert || ref == RowRemove) && !fullRowOrColumn
02787 && c->column() == pos.x() && c->row() >= (pos.y() - 1) )
02788 {
02789 if (c->updateChart())
02790 return;
02791 }
02792 }
02793
02794
02795
02796 if (c == 0L)
02797 {
02798 CellBinding * bind;
02799 for ( bind = firstCellBinding(); bind != 0L; bind = nextCellBinding() )
02800 {
02801 bind->cellChanged( 0 );
02802 }
02803
02804
02805
02806 }
02807
02808 }
02809
02810 void KSpreadSheet::refreshMergedCell()
02811 {
02812 KSpreadCell* c = d->cells.firstCell();
02813 for( ;c; c = c->nextCell() )
02814 {
02815 if(c->isForceExtraCells())
02816 c->forceExtraCells( c->column(), c->row(), c->extraXCells(), c->extraYCells() );
02817 }
02818 }
02819
02820
02821 void KSpreadSheet::changeNameCellRef( const QPoint & pos, bool fullRowOrColumn,
02822 ChangeRef ref, QString tabname, int nbCol,
02823 KSpreadUndoInsertRemoveAction * undo )
02824 {
02825 bool correctDefaultSheetName = (tabname == name());
02826 KSpreadCell* c = d->cells.firstCell();
02827 for( ;c; c = c->nextCell() )
02828 {
02829 if( c->isFormula() )
02830 {
02831 QString origText = c->text();
02832 unsigned int i = 0;
02833 bool error = false;
02834 QString newText;
02835
02836 bool correctSheetName = correctDefaultSheetName;
02837
02838 QChar origCh;
02839 for ( ; i < origText.length(); ++i )
02840 {
02841 origCh = origText[i];
02842 if ( origCh != ':' && origCh != '$' && !origCh.isLetter() )
02843 {
02844 newText += origCh;
02845
02846 correctSheetName = correctDefaultSheetName;
02847 }
02848 else
02849
02850 {
02851
02852 QString str;
02853 bool sheetNameFound = false;
02854 for( ; ( i < origText.length() ) &&
02855 ( ( origText[i].isLetter() || origText[i].isDigit() || origText[i] == '$' ) ||
02856 ( sheetNameFound && origText[i].isSpace() ) )
02857 ; ++i )
02858 {
02859 str += origText[i];
02860 if ( origText[i] == '!' )
02861 sheetNameFound = true;
02862 }
02863
02864 if ( origText[i] == '!' )
02865 {
02866 newText += str + '!';
02867
02868 correctSheetName = ( newText.right( tabname.length()+1 ) == tabname+"!" );
02869 }
02870 else
02871 {
02872
02873 KSpreadPoint point( str );
02874 if ( point.isValid() )
02875 {
02876 int col = point.pos.x();
02877 int row = point.pos.y();
02878 QString newPoint;
02879
02880
02881 if ( point.columnFixed )
02882 newPoint = '$';
02883
02884 if( ref == ColumnInsert
02885 && correctSheetName
02886 && col + nbCol <= KS_colMax
02887 && col >= pos.x()
02888 && ( fullRowOrColumn || row == pos.y() ) )
02889 {
02890 newPoint += KSpreadCell::columnName( col + nbCol );
02891 }
02892 else if( ref == ColumnRemove
02893 && correctSheetName
02894 && col > pos.x()
02895 && ( fullRowOrColumn || row == pos.y() ) )
02896 {
02897 newPoint += KSpreadCell::columnName( col - nbCol );
02898 }
02899 else
02900 newPoint += KSpreadCell::columnName( col );
02901
02902
02903 if ( point.rowFixed )
02904 newPoint += '$';
02905
02906 if( ref == RowInsert
02907 && correctSheetName
02908 && row + nbCol <= KS_rowMax
02909 && row >= pos.y()
02910 && ( fullRowOrColumn || col == pos.x() ) )
02911 {
02912 newPoint += QString::number( row + nbCol );
02913 }
02914 else if( ref == RowRemove
02915 && correctSheetName
02916 && row > pos.y()
02917 && ( fullRowOrColumn || col == pos.x() ) )
02918 {
02919 newPoint += QString::number( row - nbCol );
02920 }
02921 else
02922 newPoint += QString::number( row );
02923
02924 if( correctSheetName &&
02925 ( ( ref == ColumnRemove
02926 && col == pos.x()
02927 && ( fullRowOrColumn || row == pos.y() ) ) ||
02928 ( ref == RowRemove
02929 && row == pos.y()
02930 && ( fullRowOrColumn || col == pos.x() ) ) ||
02931 ( ref == ColumnInsert
02932 && col + nbCol > KS_colMax
02933 && col >= pos.x()
02934 && ( fullRowOrColumn || row == pos.y() ) ) ||
02935 ( ref == RowInsert
02936 && row + nbCol > KS_rowMax
02937 && row >= pos.y()
02938 && ( fullRowOrColumn || col == pos.x() ) ) ) )
02939 {
02940 newPoint = "#" + i18n("Dependency") + "!";
02941 error = true;
02942 }
02943
02944 newText += newPoint;
02945 }
02946 else
02947 {
02948 kdDebug(36001) << "Copying (unchanged) : '" << str << "'" << endl;
02949 newText += str;
02950 }
02951
02952 if ( i < origText.length() ) {
02953 newText += origText[i];
02954 if( origText[i] != ':' )
02955 correctSheetName = correctDefaultSheetName;
02956 }
02957 }
02958 }
02959 }
02960
02961 if ( error && undo != 0 )
02962 {
02963 QString formulaText = c->text();
02964 int origCol = c->column();
02965 int origRow = c->row();
02966
02967 if ( ref == ColumnInsert && origCol >= pos.x() )
02968 origCol -= nbCol;
02969 if ( ref == RowInsert && origRow >= pos.y() )
02970 origRow -= nbCol;
02971
02972 if ( ref == ColumnRemove && origCol >= pos.x() )
02973 origCol += nbCol;
02974 if ( ref == RowRemove && origRow >= pos.y() )
02975 origRow += nbCol;
02976
02977 undo->saveFormulaReference( this, origCol, origRow, formulaText );
02978 }
02979
02980 c->setCellText( newText );
02981 }
02982 }
02983 }
02984
02985 #if 0
02986 void KSpreadSheet::replace( const QString &_find, const QString &_replace, long options,
02987 KSpreadCanvas *canvas )
02988 {
02989 KSpreadSelection* selectionInfo = canvas->view()->selectionInfo();
02990
02991
02992 QRect region( selectionInfo->selection() );
02993 QPoint marker( selectionInfo->marker() );
02994
02995 if (options & KReplaceDialog::SelectedText)
02996 {
02997
02998
02999 if ( util_isRowSelected(region) )
03000 {
03001 }
03002
03003 else if ( util_isColumnSelected(region) )
03004 {
03005 }
03006 }
03007 else
03008 {
03009
03010 region.setCoords( 1, 1, d->maxRow, d->maxColumn );
03011 }
03012
03013
03014
03015 KReplace dialog( _find, _replace, options );
03016 QObject::connect(
03017 &dialog, SIGNAL( highlight( const QString &, int, int, const QRect & ) ),
03018 canvas, SLOT( highlight( const QString &, int, int, const QRect & ) ) );
03019 QObject::connect(
03020 &dialog, SIGNAL( replace( const QString &, int, int,int, const QRect & ) ),
03021 canvas, SLOT( replace( const QString &, int, int,int, const QRect & ) ) );
03022
03023
03024 if ( !doc()->undoLocked() )
03025 {
03026 KSpreadUndoChangeAreaTextCell *undo = new KSpreadUndoChangeAreaTextCell( doc(), this, region );
03027 doc()->addCommand( undo );
03028 }
03029
03030 QRect cellRegion( 0, 0, 0, 0 );
03031 bool bck = options & KFindDialog::FindBackwards;
03032
03033 int colStart = !bck ? region.left() : region.right();
03034 int colEnd = !bck ? region.right() : region.left();
03035 int rowStart = !bck ? region.top() :region.bottom();
03036 int rowEnd = !bck ? region.bottom() : region.top();
03037 if ( options & KFindDialog::FromCursor ) {
03038 colStart = marker.x();
03039 rowStart = marker.y();
03040 }
03041 KSpreadCell *cell;
03042 for (int row = rowStart ; !bck ? row < rowEnd : row > rowEnd ; !bck ? ++row : --row )
03043 {
03044 for(int col = colStart ; !bck ? col < colEnd : col > colEnd ; !bck ? ++col : --col )
03045 {
03046 cell = cellAt( col, row );
03047 if ( !cell->isDefault() && !cell->isObscured() && !cell->isFormula() )
03048 {
03049 QString text = cell->text();
03050 cellRegion.setTop( row );
03051 cellRegion.setLeft( col );
03052 if (!dialog.replace( text, cellRegion ))
03053 return;
03054 }
03055 }
03056 }
03057 }
03058 #endif
03059
03060 void KSpreadSheet::borderBottom( KSpreadSelection* selectionInfo,
03061 const QColor &_color )
03062 {
03063 QRect selection( selectionInfo->selection() );
03064
03065 QPen pen( _color,1,SolidLine);
03066
03067
03068 if ( util_isRowSelected(selection) )
03069 {
03070 if ( !doc()->undoLocked() )
03071 {
03072 QString title = i18n("Change Border");
03073 KSpreadUndoCellFormat * undo =
03074 new KSpreadUndoCellFormat( doc(), this, selection, title );
03075 doc()->addCommand( undo );
03076 }
03077
03078 int row = selection.bottom();
03079 KSpreadCell * c = getFirstCellRow( row );
03080 while ( c )
03081 {
03082 c->clearProperty( KSpreadCell::PBottomBorder );
03083 c->clearNoFallBackProperties( KSpreadCell::PBottomBorder );
03084
03085 c = getNextCellRight( c->column(), row );
03086 }
03087
03088 RowFormat * rw = nonDefaultRowFormat(selection.bottom());
03089 rw->setBottomBorderPen(pen);
03090
03091 emit sig_updateView( this );
03092 return;
03093 }
03094
03095 else if ( util_isColumnSelected(selection) )
03096 {
03097
03098 return;
03099 }
03100 else
03101 {
03102 if ( !doc()->undoLocked() )
03103 {
03104 QString title=i18n("Change Border");
03105 KSpreadUndoCellFormat *undo =
03106 new KSpreadUndoCellFormat( doc(), this, selection,title );
03107 doc()->addCommand( undo );
03108 }
03109
03110 KSpreadCell* cell;
03111 int y = selection.bottom();
03112 for ( int x = selection.left(); x <= selection.right(); ++x )
03113 {
03114 cell = nonDefaultCell( x, y );
03115 if ( cell->isObscuringForced() )
03116 cell = cell->obscuringCells().first();
03117 cell->setBottomBorderPen( pen );
03118 }
03119 emit sig_updateView( this, selection );
03120 }
03121 }
03122
03123 void KSpreadSheet::borderRight( KSpreadSelection* selectionInfo,
03124 const QColor &_color )
03125 {
03126 QRect selection( selectionInfo->selection() );
03127
03128 QPen pen( _color,1,SolidLine);
03129
03130 if ( util_isRowSelected(selection) )
03131 {
03132
03133 return;
03134 }
03135
03136 else if ( util_isColumnSelected(selection) )
03137 {
03138
03139 if ( !doc()->undoLocked() )
03140 {
03141 QString title = i18n("Change Border");
03142 KSpreadUndoCellFormat * undo =
03143 new KSpreadUndoCellFormat( doc(), this, selection, title );
03144 doc()->addCommand( undo );
03145 }
03146
03147 int col = selection.right();
03148 KSpreadCell * c = getFirstCellColumn( col );
03149 while ( c )
03150 {
03151 if ( !c->isObscuringForced() )
03152 {
03153 c->clearProperty( KSpreadCell::PRightBorder );
03154 c->clearNoFallBackProperties( KSpreadCell::PRightBorder );
03155 }
03156 c = getNextCellDown( col, c->row() );
03157 }
03158
03159 RowFormat * rw = d->rows.first();
03160
03161 ColumnFormat * cl = nonDefaultColumnFormat(selection.right());
03162 cl->setRightBorderPen(pen);
03163
03164 KSpreadCell * cell;
03165 rw = d->rows.first();
03166 for( ; rw; rw = rw->next() )
03167 {
03168 if ( !rw->isDefault() && (rw->hasProperty(KSpreadCell::PRightBorder)))
03169 {
03170 for(int i = selection.left(); i <= selection.right(); i++)
03171 {
03172 cell = nonDefaultCell( i, rw->row() );
03173 if ( cell->isObscuringForced() )
03174 cell = cell->obscuringCells().first();
03175 cell->setRightBorderPen(pen);
03176 }
03177 }
03178 }
03179
03180 emit sig_updateView( this );
03181 return;
03182 }
03183 else
03184 {
03185 if ( !doc()->undoLocked() )
03186 {
03187 QString title=i18n("Change Border");
03188 KSpreadUndoCellFormat *undo =
03189 new KSpreadUndoCellFormat( doc(), this, selection, title );
03190 doc()->addCommand( undo );
03191 }
03192
03193 KSpreadCell* cell;
03194 int x = selection.right();
03195 for ( int y = selection.top(); y <= selection.bottom(); y++ )
03196 {
03197 cell = nonDefaultCell( x, y );
03198 if ( cell->isObscuringForced() )
03199 cell = cell->obscuringCells().first();
03200 cell->setRightBorderPen(pen);
03201 }
03202 emit sig_updateView( this, selection );
03203 }
03204 }
03205
03206 void KSpreadSheet::borderLeft( KSpreadSelection* selectionInfo,
03207 const QColor &_color )
03208 {
03209 QString title = i18n("Change Border");
03210 QRect selection( selectionInfo->selection() );
03211
03212 QPen pen( _color,1,SolidLine);
03213
03214
03215 if ( util_isColumnSelected(selection) )
03216 {
03217 RowFormat* rw =d->rows.first();
03218
03219 if ( !doc()->undoLocked() )
03220 {
03221 KSpreadUndoCellFormat *undo =
03222 new KSpreadUndoCellFormat( doc(), this, selection, title );
03223 doc()->addCommand( undo );
03224 }
03225
03226 int col = selection.left();
03227 KSpreadCell * c = getFirstCellColumn( col );
03228 while ( c )
03229 {
03230 c->clearProperty( KSpreadCell::PLeftBorder );
03231 c->clearNoFallBackProperties( KSpreadCell::PLeftBorder );
03232
03233 c = getNextCellDown( col, c->row() );
03234 }
03235
03236
03237 ColumnFormat * cl = nonDefaultColumnFormat( col );
03238 cl->setLeftBorderPen(pen);
03239
03240 KSpreadCell * cell;
03241 rw = d->rows.first();
03242 for( ; rw; rw = rw->next() )
03243 {
03244 if ( !rw->isDefault() && (rw->hasProperty(KSpreadCell::PLeftBorder)))
03245 {
03246 for(int i = selection.left(); i <= selection.right(); ++i)
03247 {
03248 cell = nonDefaultCell( i, rw->row() );
03249 if ( cell->isObscuringForced() )
03250 continue;
03251 cell->setLeftBorderPen(pen);
03252 }
03253 }
03254 }
03255
03256 emit sig_updateView( this );
03257 return;
03258 }
03259 else
03260 {
03261 if ( !doc()->undoLocked() )
03262 {
03263 KSpreadUndoCellFormat *undo = new KSpreadUndoCellFormat( doc(), this,
03264 selection,title );
03265 doc()->addCommand( undo );
03266 }
03267
03268 KSpreadCell* cell;
03269 int x = selection.left();
03270 for ( int y = selection.top(); y <= selection.bottom(); y++ )
03271 {
03272 cell = nonDefaultCell( x, y );
03273 if ( cell->isObscuringForced() )
03274 continue;
03275 cell->setLeftBorderPen(pen);
03276 }
03277 emit sig_updateView( this, selection );
03278 }
03279 }
03280
03281 void KSpreadSheet::borderTop( KSpreadSelection* selectionInfo,
03282 const QColor &_color )
03283 {
03284
03285
03286
03287 QRect selection( selectionInfo->selection() );
03288
03289 QString title = i18n("Change Border");
03290 QPen pen( _color, 1, SolidLine);
03291
03292 if ( util_isRowSelected(selection) )
03293 {
03294 if ( !doc()->undoLocked() )
03295 {
03296 KSpreadUndoCellFormat * undo =
03297 new KSpreadUndoCellFormat( doc(), this, selection, title );
03298 doc()->addCommand( undo );
03299 }
03300
03301 int row = selection.top();
03302 KSpreadCell * c = getFirstCellRow( row );
03303 while ( c )
03304 {
03305 c->clearProperty( KSpreadCell::PTopBorder );
03306 c->clearNoFallBackProperties( KSpreadCell::PTopBorder );
03307
03308 c = getNextCellRight( c->column(), row );
03309 }
03310
03311 RowFormat * rw = nonDefaultRowFormat( row );
03312 rw->setTopBorderPen( pen );
03313
03314 emit sig_updateView( this );
03315 return;
03316 }
03317
03318
03319 else
03320 {
03321 if ( !doc()->undoLocked() )
03322 {
03323 KSpreadUndoCellFormat *undo =
03324 new KSpreadUndoCellFormat( doc(), this, selection, title );
03325 doc()->addCommand( undo );
03326 }
03327
03328 KSpreadCell* cell;
03329 int y = selection.top();
03330 for ( int x = selection.left(); x <= selection.right(); x++ )
03331 {
03332 cell = nonDefaultCell( x, y );
03333 if ( cell->isObscuringForced() )
03334 continue;
03335 cell->setTopBorderPen(pen);
03336 }
03337 emit sig_updateView( this, selection );
03338 }
03339 }
03340
03341 void KSpreadSheet::borderOutline( KSpreadSelection* selectionInfo,
03342 const QColor &_color )
03343 {
03344 QRect selection( selectionInfo->selection() );
03345
03346 if ( !doc()->undoLocked() )
03347 {
03348 QString title = i18n("Change Border");
03349 KSpreadUndoCellFormat *undo = new KSpreadUndoCellFormat( doc(), this,
03350 selection, title );
03351 doc()->addCommand( undo );
03352 }
03353
03354 QPen pen( _color, 1, SolidLine );
03355
03356
03357 if ( util_isRowSelected(selection) )
03358 {
03359 int row = selection.top();
03360 KSpreadCell * c = getFirstCellRow( row );
03361 while ( c )
03362 {
03363 c->clearProperty( KSpreadCell::PTopBorder );
03364 c->clearNoFallBackProperties( KSpreadCell::PTopBorder );
03365
03366 c = getNextCellRight( c->column(), row );
03367 }
03368
03369 row = selection.bottom();
03370 c = getFirstCellRow( row );
03371 while ( c )
03372 {
03373 c->clearProperty( KSpreadCell::PBottomBorder );
03374 c->clearNoFallBackProperties( KSpreadCell::PBottomBorder );
03375
03376 c = getNextCellRight( c->column(), row );
03377 }
03378
03379 RowFormat * rw = nonDefaultRowFormat( selection.top() );
03380 rw->setTopBorderPen(pen);
03381 rw=nonDefaultRowFormat(selection.bottom());
03382 rw->setBottomBorderPen(pen);
03383 KSpreadCell* cell;
03384 int bottom = selection.bottom();
03385 int left = selection.left();
03386 for ( int y = selection.top(); y <= bottom; ++y )
03387 {
03388 cell = nonDefaultCell( left, y );
03389 if ( cell->isObscuringForced() )
03390 continue;
03391 cell->setLeftBorderPen( pen );
03392 }
03393 emit sig_updateView( this );
03394 return;
03395 }
03396
03397 else if ( util_isColumnSelected(selection) )
03398 {
03399 int col = selection.left();
03400 KSpreadCell * c = getFirstCellColumn( col );
03401 while ( c )
03402 {
03403 c->clearProperty( KSpreadCell::PLeftBorder );
03404 c->clearNoFallBackProperties( KSpreadCell::PLeftBorder );
03405
03406 c = getNextCellDown( col, c->row() );
03407 }
03408
03409 col = selection.right();
03410 c = getFirstCellColumn( col );
03411 while ( c )
03412 {
03413 c->clearProperty( KSpreadCell::PRightBorder );
03414 c->clearNoFallBackProperties( KSpreadCell::PRightBorder );
03415
03416 c = getNextCellDown( col, c->row() );
03417 }
03418
03419 ColumnFormat *cl=nonDefaultColumnFormat(selection.left());
03420 cl->setLeftBorderPen(pen);
03421 cl=nonDefaultColumnFormat(selection.right());
03422 cl->setRightBorderPen(pen);
03423 KSpreadCell* cell;
03424 for ( int x = selection.left(); x <= selection.right(); x++ )
03425 {
03426 cell = nonDefaultCell( x, selection.top() );
03427 if ( cell->isObscuringForced() )
03428 continue;
03429 cell->setTopBorderPen( pen );
03430 }
03431 emit sig_updateView( this );
03432 return;
03433 }
03434 else
03435 {
03436 KSpreadCell* cell;
03437 for ( int x = selection.left(); x <= selection.right(); x++ )
03438 {
03439 cell = nonDefaultCell( x, selection.top() );
03440 if ( !cell->isObscuringForced() )
03441 cell->setTopBorderPen( pen );
03442
03443 cell = nonDefaultCell( x, selection.bottom() );
03444 if ( cell->isObscuringForced() )
03445 cell = cell->obscuringCells().first();
03446 cell->setBottomBorderPen( pen );
03447 }
03448 for ( int y = selection.top(); y <= selection.bottom(); y++ )
03449 {
03450 cell = nonDefaultCell( selection.left(), y );
03451 if ( !cell->isObscuringForced() )
03452 cell->setLeftBorderPen( pen );
03453
03454 cell = nonDefaultCell( selection.right(), y );
03455 if ( cell->isObscuringForced() )
03456 cell = cell->obscuringCells().first();
03457 cell->setRightBorderPen( pen );
03458 }
03459 emit sig_updateView( this, selection );
03460 }
03461 }
03462
03463 struct SetSelectionBorderAllWorker : public KSpreadSheet::CellWorkerTypeA {
03464 QPen pen;
03465 SetSelectionBorderAllWorker( const QColor& color ) : pen( color, 1, QPen::SolidLine ) { }
03466
03467 QString getUndoTitle() { return i18n("Change Border"); }
03468 bool testCondition( RowFormat* rw ) {
03469 return ( rw->hasProperty( KSpreadCell::PRightBorder )
03470 || rw->hasProperty( KSpreadCell::PLeftBorder )
03471 || rw->hasProperty( KSpreadCell::PTopBorder )
03472 || rw->hasProperty( KSpreadCell::PBottomBorder ) );
03473 }
03474 void doWork( RowFormat* rw ) {
03475 rw->setTopBorderPen( pen );
03476 rw->setRightBorderPen( pen );
03477 rw->setLeftBorderPen( pen );
03478 rw->setBottomBorderPen( pen );
03479 }
03480 void doWork( ColumnFormat* cl ) {
03481 cl->setTopBorderPen( pen );
03482 cl->setRightBorderPen( pen );
03483 cl->setLeftBorderPen( pen );
03484 cl->setBottomBorderPen( pen );
03485 }
03486 void prepareCell( KSpreadCell* c ) {
03487 c->clearProperty( KSpreadCell::PTopBorder );
03488 c->clearNoFallBackProperties( KSpreadCell::PTopBorder );
03489 c->clearProperty( KSpreadCell::PBottomBorder );
03490 c->clearNoFallBackProperties( KSpreadCell::PBottomBorder );
03491 c->clearProperty( KSpreadCell::PLeftBorder );
03492 c->clearNoFallBackProperties( KSpreadCell::PLeftBorder );
03493 c->clearProperty( KSpreadCell::PRightBorder );
03494 c->clearNoFallBackProperties( KSpreadCell::PRightBorder );
03495 }
03496
03497 bool testCondition( KSpreadCell * ) { return true; }
03498
03499 void doWork( KSpreadCell* cell, bool, int, int ) {
03500
03501
03502 cell->setTopBorderPen( pen );
03503 cell->setRightBorderPen( pen );
03504 cell->setLeftBorderPen( pen );
03505 cell->setBottomBorderPen( pen );
03506
03507
03508 }
03509 };
03510
03511 void KSpreadSheet::borderAll( KSpreadSelection * selectionInfo,
03512 const QColor & _color )
03513 {
03514 if ( selectionInfo->singleCellSelection() )
03515 {
03516 borderOutline( selectionInfo, _color );
03517 }
03518 else
03519 {
03520 SetSelectionBorderAllWorker w( _color );
03521 workOnCells( selectionInfo, w );
03522 }
03523 }
03524
03525 struct SetSelectionBorderRemoveWorker : public KSpreadSheet::CellWorkerTypeA {
03526 QPen pen;
03527 SetSelectionBorderRemoveWorker() : pen( Qt::black, 1, Qt::NoPen ) { }
03528 QString getUndoTitle() { return i18n("Change Border"); }
03529 bool testCondition( RowFormat* rw ) {
03530 return ( rw->hasProperty( KSpreadCell::PRightBorder )
03531 || rw->hasProperty( KSpreadCell::PLeftBorder )
03532 || rw->hasProperty( KSpreadCell::PTopBorder )
03533 || rw->hasProperty( KSpreadCell::PBottomBorder )
03534 || rw->hasProperty( KSpreadCell::PFallDiagonal )
03535 || rw->hasProperty( KSpreadCell::PGoUpDiagonal ) );
03536 }
03537 void doWork( RowFormat* rw ) {
03538 rw->setTopBorderPen( pen );
03539 rw->setRightBorderPen( pen );
03540 rw->setLeftBorderPen( pen );
03541 rw->setBottomBorderPen( pen);
03542 rw->setFallDiagonalPen( pen );
03543 rw->setGoUpDiagonalPen (pen );
03544 }
03545 void doWork( ColumnFormat* cl ) {
03546 cl->setTopBorderPen( pen );
03547 cl->setRightBorderPen( pen );
03548 cl->setLeftBorderPen( pen );
03549 cl->setBottomBorderPen( pen);
03550 cl->setFallDiagonalPen( pen );
03551 cl->setGoUpDiagonalPen (pen );
03552 }
03553 void prepareCell( KSpreadCell* c ) {
03554 c->clearProperty( KSpreadCell::PTopBorder );
03555 c->clearNoFallBackProperties( KSpreadCell::PTopBorder );
03556 c->clearProperty( KSpreadCell::PLeftBorder );
03557 c->clearNoFallBackProperties( KSpreadCell::PLeftBorder );
03558 c->clearProperty( KSpreadCell::PRightBorder );
03559 c->clearNoFallBackProperties( KSpreadCell::PRightBorder );
03560 c->clearProperty( KSpreadCell::PBottomBorder );
03561 c->clearNoFallBackProperties( KSpreadCell::PBottomBorder );
03562 c->clearProperty( KSpreadCell::PFallDiagonal );
03563 c->clearNoFallBackProperties( KSpreadCell::PFallDiagonal );
03564 c->clearProperty( KSpreadCell::PGoUpDiagonal );
03565 c->clearNoFallBackProperties( KSpreadCell::PGoUpDiagonal );
03566 }
03567
03568 bool testCondition(KSpreadCell* ){ return true; }
03569
03570 void doWork( KSpreadCell* cell, bool, int, int ) {
03571
03572
03573 cell->setTopBorderPen( pen );
03574 cell->setRightBorderPen( pen );
03575 cell->setLeftBorderPen( pen );
03576 cell->setBottomBorderPen( pen);
03577 cell->setFallDiagonalPen( pen );
03578 cell->setGoUpDiagonalPen (pen );
03579
03580
03581 }
03582 };
03583
03584
03585 void KSpreadSheet::borderRemove( KSpreadSelection* selectionInfo )
03586 {
03587 SetSelectionBorderRemoveWorker w;
03588 workOnCells( selectionInfo, w );
03589 }
03590
03591
03592 void KSpreadSheet::sortByRow( const QRect &area, int ref_row, SortingOrder mode )
03593 {
03594 KSpreadPoint point;
03595 point.sheet = this;
03596 point.sheetName = d->name;
03597 point.pos = area.topLeft();
03598 point.columnFixed = false;
03599 point.rowFixed = false;
03600
03601 sortByRow( area, ref_row, 0, 0, mode, mode, mode, 0, false, false, point,true );
03602 }
03603
03604 void KSpreadSheet::sortByColumn( const QRect &area, int ref_column, SortingOrder mode )
03605 {
03606 KSpreadPoint point;
03607 point.sheet = this;
03608 point.sheetName = d->name;
03609 point.pos = area.topLeft();
03610 point.columnFixed = false;
03611 point.rowFixed = false;
03612
03613 sortByColumn( area, ref_column, 0, 0, mode, mode, mode, 0, false, false,
03614 point,true );
03615 }
03616
03617 void KSpreadSheet::checkCellContent(KSpreadCell * cell1, KSpreadCell * cell2, int & ret)
03618 {
03619 if ( cell1->isEmpty() )
03620 {
03621 ret = 1;
03622 return;
03623 }
03624 else if ( cell1->isObscured() && cell1->isObscuringForced() )
03625 {
03626 ret = 1;
03627 return;
03628 }
03629 else if ( cell2->isEmpty() )
03630 {
03631 ret = 2;
03632 return;
03633 }
03634 ret = 0;
03635 }
03636
03637 void KSpreadSheet::sortByRow( const QRect &area, int key1, int key2, int key3,
03638 SortingOrder order1, SortingOrder order2,
03639 SortingOrder order3,
03640 QStringList const * firstKey, bool copyFormat,
03641 bool headerRow, KSpreadPoint const & outputPoint, bool respectCase )
03642 {
03643 QRect r( area );
03644 KSpreadMap::respectCase = respectCase;
03645 Q_ASSERT( order1 == Increase || order1 == Decrease );
03646
03647
03648 Q_ASSERT( util_isColumnSelected(r) == FALSE );
03649
03650
03651 if ( util_isRowSelected(r) )
03652 {
03653 r.setLeft( KS_colMax );
03654 r.setRight( 0 );
03655
03656
03657
03658
03659 for ( int row = r.top(); row <= r.bottom(); ++row )
03660 {
03661 KSpreadCell * c = getFirstCellRow( row );
03662 int col;
03663 while ( c )
03664 {
03665 col = c->column();
03666 if ( !c->isEmpty() )
03667 {
03668 if ( col > r.right() )
03669 r.rRight() = col;
03670 if ( col < r.left() )
03671 r.rLeft() = col;
03672 }
03673 c = getNextCellRight( col, row );
03674 }
03675 }
03676
03677
03678 if ( r.right() < r.left() )
03679 {
03680 KSpreadMap::respectCase = true;
03681 return;
03682 }
03683 }
03684
03685 QRect target( outputPoint.pos.x(), outputPoint.pos.y(), r.width(), r.height() );
03686
03687 doc()->emitBeginOperation();
03688
03689 if ( !doc()->undoLocked() )
03690 {
03691 KSpreadUndoSort *undo = new KSpreadUndoSort( doc(), this, target );
03692 doc()->addCommand( undo );
03693 }
03694
03695 if (target.topLeft() != r.topLeft())
03696 {
03697 int targetLeft = target.left();
03698 int targetTop = target.top();
03699 int sourceTop = r.top();
03700 int sourceLeft = r.left();
03701
03702 key1 = key1 - sourceTop + targetTop;
03703 key2 = key2 - sourceTop + targetTop;
03704 key3 = key3 - sourceTop + targetTop;
03705
03706 for ( int x = 0; x < r.width(); ++x)
03707 {
03708 for ( int y = 0; y < r.height(); ++y )
03709 {
03710
03711 copyCells( sourceLeft + x, sourceTop + y,
03712 targetLeft + x, targetTop + y, copyFormat );
03713 }
03714 }
03715 }
03716
03717
03718
03719
03720 KSpreadCell * cell;
03721 KSpreadCell * cell1;
03722 KSpreadCell * cell2;
03723 KSpreadCell * bestCell;
03724 int status = 0;
03725
03726 for ( int d = target.left(); d <= target.right(); ++d )
03727 {
03728 cell1 = cellAt( d, key1 );
03729 if ( cell1->isObscured() && cell1->isObscuringForced() )
03730 {
03731 KSpreadCell* obscuring = cell1->obscuringCells().first();
03732 cell = cellAt( obscuring->column(), key1 );
03733 cell1 = cellAt( obscuring->column() + cell->extraXCells() + 1,
03734 obscuring->column());
03735 d = obscuring->column() + cell->extraXCells() + 1;
03736 }
03737
03738
03739 bestCell = cell1;
03740 int bestX = d;
03741 for ( int x = d + 1 ; x <= target.right(); x++ )
03742 {
03743 cell2 = cellAt( x, key1 );
03744
03745 checkCellContent(cell2, bestCell, status);
03746 if (status == 1)
03747 continue;
03748 else if (status == 2)
03749 {
03750
03751 bestCell = cell2;
03752 bestX = x;
03753 continue;
03754 }
03755
03756 if ( firstKey )
03757 {
03758 int i1 = firstKey->findIndex( cell2->text() );
03759 int i2 = firstKey->findIndex( bestCell->text() );
03760
03761 if ( i1 != -1 && i2 != -1 )
03762 {
03763 if ( (order1 == Increase && i1 < i2 )
03764 || (order1 == Decrease && i1 > i2) )
03765 {
03766 bestCell = cell2;
03767 bestX = x;
03768 continue;
03769 }
03770
03771 if ( i1 == i2 )
03772 {
03773
03774 if (key2 <= 0)
03775 continue;
03776
03777 KSpreadCell * cell22 = cellAt( x, key2 );
03778 KSpreadCell * bestCell2 = cellAt( bestX, key2 );
03779
03780 if ( cell22->isEmpty() )
03781 {
03782
03783 continue;
03784 }
03785 else if ( cell22->isObscured() && cell22->isObscuringForced() )
03786 {
03787
03788 continue;
03789 }
03790 else if ( bestCell2->isEmpty() )
03791 {
03792
03793 bestCell = cell2;
03794 bestX = x;
03795 continue;
03796 }
03797
03798 if ( (order2 == Increase && *cell22 < *bestCell2)
03799 || (order2 == Decrease && *cell22 > *bestCell2) )
03800 {
03801 bestCell = cell2;
03802 bestX = x;
03803 continue;
03804 }
03805 else if ( (order2 == Increase && *cell22 > *bestCell2)
03806 || (order2 == Decrease && *cell22 < *bestCell2) )
03807 {
03808
03809 continue;
03810 }
03811 else
03812 {
03813
03814 if (key3 <= 0)
03815 continue;
03816
03817 KSpreadCell * cell23 = cellAt( x, key3 );
03818 KSpreadCell * bestCell3 = cellAt( bestX, key3 );
03819
03820 if ( cell23->isEmpty() )
03821 {
03822
03823 continue;
03824 }
03825 else if ( cell23->isObscured() && cell23->isObscuringForced() )
03826 {
03827
03828 continue;
03829 }
03830 else if ( bestCell3->isEmpty() )
03831 {
03832
03833 bestCell = cell2;
03834 bestX = x;
03835 continue;
03836 }
03837 if ( (order3 == Increase && *cell23 < *bestCell3)
03838 || (order3 == Decrease && *cell23 > *bestCell3) )
03839 {
03840
03841
03842 continue;
03843 }
03844 else
03845 {
03846 bestCell = cell2;
03847 bestX = x;
03848 continue;
03849 }
03850 }
03851 }
03852 continue;
03853 }
03854 else if ( i1 != -1 && i2 == -1 )
03855 {
03856
03857 bestCell = cell2;
03858 bestX = x;
03859 continue;
03860 }
03861 else if ( i2 != -1 && i1 == -1 )
03862 {
03863
03864
03865 continue;
03866 }
03867
03868
03869 }
03870
03871
03872 if ( (order1 == Increase && *cell2 < *bestCell)
03873 || (order1 == Decrease && *cell2 > *bestCell) )
03874 {
03875 bestCell = cell2;
03876 bestX = x;
03877 continue;
03878 }
03879 else if ( (order1 == Increase && *cell2 > *bestCell)
03880 || (order1 == Decrease && *cell2 < *bestCell) )
03881 {
03882
03883 continue;
03884 }
03885 else
03886 {
03887
03888
03889 if (key2 <= 0)
03890 continue;
03891 KSpreadCell * cell22 = cellAt( d, key2 );
03892 KSpreadCell * bestCell2 = cellAt( x, key2 );
03893
03894 checkCellContent(cell2, bestCell, status);
03895 if (status == 1)
03896 continue;
03897 else if (status == 2)
03898 {
03899
03900 bestCell = cell2;
03901 bestX = x;
03902 continue;
03903 }
03904
03905 if ( (order2 == Increase && *cell22 > *bestCell2)
03906 || (order2 == Decrease && *cell22 < *bestCell2) )
03907 {
03908 bestCell = cell2;
03909 bestX = x;
03910 continue;
03911 }
03912 else
03913 if ( (order2 == Increase && *cell22 > *bestCell2)
03914 || (order2 == Decrease && *cell22 < *bestCell2) )
03915 {
03916
03917 continue;
03918 }
03919 else
03920 {
03921
03922 if (key3 == 0)
03923 continue;
03924 KSpreadCell * cell23 = cellAt( d, key3 );
03925 KSpreadCell * bestCell3 = cellAt( x, key3 );
03926
03927 checkCellContent(cell2, bestCell, status);
03928 if (status == 1)
03929 continue;
03930 else if (status == 2)
03931 {
03932
03933 bestCell = cell2;
03934 bestX = x;
03935 continue;
03936 }
03937 if ( (order3 == Increase && *cell23 > *bestCell3)
03938 || (order3 == Decrease && *cell23 < *bestCell3) )
03939 {
03940 bestCell = cell2;
03941 bestX = x;
03942 continue;
03943 }
03944 else
03945 {
03946
03947
03948 continue;
03949 }
03950 }
03951 }
03952 }
03953
03954
03955 if ( d != bestX )
03956 {
03957 int top = target.top();
03958 if (headerRow)
03959 ++top;
03960
03961 for( int y = target.bottom(); y >= top; --y )
03962 {
03963 if ( y != key1 && y != key2 && y != key3 )
03964 swapCells( d, y, bestX, y, copyFormat );
03965 }
03966 if (key3 > 0)
03967 swapCells( d, key3, bestX, key3, copyFormat );
03968 if (key2 > 0)
03969 swapCells( d, key2, bestX, key2, copyFormat );
03970 swapCells( d, key1, bestX, key1, copyFormat );
03971 }
03972 }
03973 KSpreadMap::respectCase = true;
03974
03975 emit sig_updateView( this );
03976 }
03977
03978 void KSpreadSheet::sortByColumn( const QRect &area, int key1, int key2, int key3,
03979 SortingOrder order1, SortingOrder order2,
03980 SortingOrder order3,
03981 QStringList const * firstKey, bool copyFormat,
03982 bool headerRow,
03983 KSpreadPoint const & outputPoint, bool respectCase )
03984 {
03985 QRect r( area );
03986 KSpreadMap::respectCase = respectCase;
03987
03988 Q_ASSERT( order1 == Increase || order1 == Decrease );
03989
03990
03991 Q_ASSERT( util_isRowSelected(r) == FALSE );
03992
03993
03994 if ( util_isColumnSelected(r) )
03995 {
03996 r.setTop( KS_rowMax );
03997 r.setBottom( 0 );
03998
03999
04000
04001
04002 for ( int col = r.left(); col <= r.right(); ++col )
04003 {
04004 KSpreadCell * c = getFirstCellColumn( col );
04005 int row;
04006 while ( c )
04007 {
04008 row = c->row();
04009 if ( !c->isEmpty() )
04010 {
04011 if ( row > r.bottom() )
04012 r.rBottom() = row;
04013 if ( row < r.top() )
04014 r.rTop() = row;
04015 }
04016 c = getNextCellDown( col, row );
04017 }
04018 }
04019
04020
04021 if ( r.bottom() < r.top() )
04022 {
04023 KSpreadMap::respectCase = true;
04024 return;
04025 }
04026 }
04027 QRect target( outputPoint.pos.x(), outputPoint.pos.y(), r.width(), r.height() );
04028
04029 if ( !doc()->undoLocked() )
04030 {
04031 KSpreadUndoSort *undo = new KSpreadUndoSort( doc(), this, target );
04032 doc()->addCommand( undo );
04033 }
04034
04035 doc()->emitBeginOperation();
04036
04037 if (target.topLeft() != r.topLeft())
04038 {
04039 int targetLeft = target.left();
04040 int targetTop = target.top();
04041 int sourceTop = r.top();
04042 int sourceLeft = r.left();
04043
04044 key1 = key1 - sourceLeft + targetLeft;
04045 key2 = key2 - sourceLeft + targetLeft;
04046 key3 = key3 - sourceLeft + targetLeft;
04047
04048 for ( int x = 0; x < r.width(); ++x)
04049 {
04050 for ( int y = 0; y < r.height(); ++y )
04051 {
04052
04053 copyCells( sourceLeft + x, sourceTop + y,
04054 targetLeft + x, targetTop + y, copyFormat );
04055 }
04056 }
04057 }
04058
04059
04060
04061
04062
04063
04064 KSpreadCell * cell;
04065 KSpreadCell * cell1;
04066 KSpreadCell * cell2;
04067 KSpreadCell * bestCell;
04068 int status = 0;
04069
04070 int d = target.top();
04071
04072 if (headerRow)
04073 ++d;
04074
04075 for ( ; d <= target.bottom(); ++d )
04076 {
04077
04078 cell1 = cellAt( key1, d );
04079 if ( cell1->isObscured() && cell1->isObscuringForced() )
04080 {
04081 KSpreadCell* obscuring = cell1->obscuringCells().first();
04082 cell = cellAt( key1, obscuring->row() );
04083 cell1 = cellAt( key1, obscuring->row() + cell->extraYCells() + 1 );
04084 d = obscuring->row() + cell->extraYCells() + 1;
04085 }
04086
04087 bestCell = cell1;
04088 int bestY = d;
04089
04090 for ( int y = d + 1 ; y <= target.bottom(); ++y )
04091 {
04092 cell2 = cellAt( key1, y );
04093
04094 if ( cell2->isEmpty() )
04095 {
04096
04097 continue;
04098 }
04099 else if ( cell2->isObscured() && cell2->isObscuringForced() )
04100 {
04101
04102 continue;
04103 }
04104 else if ( bestCell->isEmpty() )
04105 {
04106
04107 bestCell = cell2;
04108 bestY = y;
04109 continue;
04110 }
04111
04112 if ( firstKey )
04113 {
04114 int i1 = firstKey->findIndex( cell2->text() );
04115 int i2 = firstKey->findIndex( bestCell->text() );
04116
04117 if ( i1 != -1 && i2 != -1 )
04118 {
04119 if ( (order1 == Increase && i1 < i2 )
04120 || (order1 == Decrease && i1 > i2) )
04121 {
04122 bestCell = cell2;
04123 bestY = y;
04124 continue;
04125 }
04126
04127 if ( i1 == i2 )
04128 {
04129
04130 if (key2 <= 0)
04131 continue;
04132 KSpreadCell * cell22 = cellAt( key2, d );
04133 KSpreadCell * bestCell2 = cellAt( key2, y );
04134
04135 if ( cell22->isEmpty() )
04136 {
04137
04138 continue;
04139 }
04140 else if ( cell22->isObscured() && cell22->isObscuringForced() )
04141 {
04142
04143 continue;
04144 }
04145 else if ( bestCell2->isEmpty() )
04146 {
04147
04148 bestCell = cell2;
04149 bestY = y;
04150 continue;
04151 }
04152
04153 if ( (order2 == Increase && *cell22 > *bestCell2)
04154 || (order2 == Decrease && *cell22 < *bestCell2) )
04155 {
04156 bestCell = cell2;
04157 bestY = y;
04158 continue;
04159 }
04160 else if ( (order2 == Increase && *cell22 < *bestCell2)
04161 || (order2 == Decrease && *cell22 > *bestCell2) )
04162 {
04163
04164 continue;
04165 }
04166 else
04167 {
04168
04169 if (key3 <= 0)
04170 continue;
04171 KSpreadCell * cell23 = cellAt( key3, d );
04172 KSpreadCell * bestCell3 = cellAt( key3, y );
04173
04174 checkCellContent(cell2, bestCell, status);
04175 if (status == 1)
04176 continue;
04177 else if (status == 2)
04178 {
04179
04180 bestCell = cell2;
04181 bestY = y;
04182 continue;
04183 }
04184
04185 if ( (order3 == Increase && *cell23 < *bestCell3)
04186 || (order3 == Decrease && *cell23 > *bestCell3) )
04187 {
04188 bestCell = cell2;
04189 bestY = y;
04190 continue;
04191 }
04192 else
04193 {
04194
04195
04196 continue;
04197 }
04198 }
04199 }
04200 continue;
04201 }
04202 else if ( i1 != -1 && i2 == -1 )
04203 {
04204
04205 bestCell = cell2;
04206 bestY = y;
04207 continue;
04208 }
04209 else if ( i2 != -1 && i1 == -1 )
04210 {
04211
04212
04213 continue;
04214 }
04215
04216
04217 }
04218
04219
04220
04221 if ( (order1 == Increase && *cell2 < *bestCell)
04222 || (order1 == Decrease && *cell2 > *bestCell) )
04223 {
04224 bestCell = cell2;
04225 bestY = y;
04226 }
04227 else if ( (order1 == Increase && *cell2 > *bestCell)
04228 || (order1 == Decrease && *cell2 < *bestCell) )
04229 {
04230
04231 continue;
04232 }
04233 else
04234 {
04235
04236
04237 if (key2 == 0)
04238 continue;
04239 KSpreadCell * cell22 = cellAt( key2, y );
04240 KSpreadCell * bestCell2 = cellAt( key2, bestY );
04241
04242 if ( cell22->isEmpty() )
04243 {
04244
04245 continue;
04246 }
04247 else if ( cell22->isObscured() && cell22->isObscuringForced() )
04248 {
04249
04250 continue;
04251 }
04252 else if ( bestCell2->isEmpty() )
04253 {
04254
04255 bestCell = cell2;
04256 bestY = y;
04257 continue;
04258 }
04259
04260 if ( (order2 == Increase && *cell22 < *bestCell2)
04261 || (order2 == Decrease && *cell22 > *bestCell2) )
04262 {
04263 bestCell = cell2;
04264 bestY = y;
04265 continue;
04266 }
04267 else if ( (order2 == Increase && *cell22 > *bestCell2)
04268 || (order2 == Decrease && *cell22 < *bestCell2) )
04269 {
04270 continue;
04271 }
04272 else
04273 {
04274
04275 if (key3 == 0)
04276 continue;
04277 KSpreadCell * cell23 = cellAt( key3, y );
04278 KSpreadCell * bestCell3 = cellAt( key3, bestY );
04279
04280 if ( cell23->isEmpty() )
04281 {
04282
04283 continue;
04284 }
04285 else if ( cell23->isObscured() && cell23->isObscuringForced() )
04286 {
04287
04288 continue;
04289 }
04290 else if ( bestCell3->isEmpty() )
04291 {
04292
04293 bestCell = cell2;
04294 bestY = y;
04295 continue;
04296 }
04297
04298 if ( (order3 == Increase && *cell23 < *bestCell3)
04299 || (order3 == Decrease && *cell23 > *bestCell3) )
04300 {
04301 bestCell = cell2;
04302 bestY = y;
04303 continue;
04304 }
04305 else
04306 {
04307
04308
04309 continue;
04310 }
04311 }
04312 }
04313 }
04314
04315
04316 if ( d != bestY )
04317 {
04318 for (int x = target.left(); x <= target.right(); ++x)
04319 {
04320 if ( x != key1 && x != key2 && x != key3)
04321 swapCells( x, d, x, bestY, copyFormat );
04322 }
04323 if (key3 > 0)
04324 swapCells( key3, d, key3, bestY, copyFormat );
04325 if (key2 > 0)
04326 swapCells( key2, d, key2, bestY, copyFormat );
04327 swapCells( key1, d, key1, bestY, copyFormat );
04328 }
04329 }
04330
04331 KSpreadMap::respectCase = true;
04332 emit sig_updateView( this );
04333 }
04334
04335
04336 void KSpreadSheet::copyCells( int x1, int y1, int x2, int y2, bool cpFormat )
04337 {
04338 KSpreadCell * sourceCell = cellAt( x1, y1 );
04339 KSpreadCell * targetCell = cellAt( x2, y2 );
04340
04341 if ( sourceCell->isDefault() && targetCell->isDefault())
04342 {
04343
04344 return;
04345 }
04346
04347 targetCell = nonDefaultCell(x2, y2);
04348
04349
04350 targetCell->copyContent( sourceCell );
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365 if (cpFormat)
04366 {
04367 targetCell->copyFormat( sourceCell );
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396 }
04397 }
04398
04399 void KSpreadSheet::swapCells( int x1, int y1, int x2, int y2, bool cpFormat )
04400 {
04401 KSpreadCell * ref1 = cellAt( x1, y1 );
04402 KSpreadCell * ref2 = cellAt( x2, y2 );
04403
04404 if ( ref1->isDefault() )
04405 {
04406 if ( !ref2->isDefault() )
04407 {
04408 ref1 = nonDefaultCell( x1, y1 );
04409
04410 }
04411 else
04412 return;
04413 }
04414 else
04415 if ( ref2->isDefault() )
04416 {
04417 ref2 = nonDefaultCell( x2, y2 );
04418
04419 }
04420
04421
04422
04423
04424
04425
04426 if (!ref1->isFormula() && !ref2->isFormula())
04427 {
04428 KSpreadCell *tmp = new KSpreadCell( this, -1, -1 );
04429
04430 tmp->copyContent( ref1 );
04431 ref1->copyContent( ref2 );
04432 ref2->copyContent( tmp );
04433
04434 delete tmp;
04435 }
04436 else
04437 if ( ref1->isFormula() && ref2->isFormula() )
04438 {
04439 QString d = ref1->encodeFormula();
04440 ref1->setCellText( ref1->decodeFormula( ref2->encodeFormula( ) ) );
04441 ref1->setCalcDirtyFlag();
04442 ref1->calc(false);
04443 ref2->setCellText( ref2->decodeFormula( d ) );
04444 ref2->setCalcDirtyFlag();
04445 ref2->calc(false);
04446 }
04447 else
04448 if (ref1->isFormula() && !ref2->isFormula() )
04449 {
04450 QString d = ref1->encodeFormula();
04451 ref1->setCellText(ref2->text());
04452 ref2->setCellText(ref2->decodeFormula(d));
04453 ref2->setCalcDirtyFlag();
04454 ref2->calc(false);
04455 }
04456 else
04457 if (!ref1->isFormula() && ref2->isFormula() )
04458 {
04459 QString d = ref2->encodeFormula();
04460 ref2->setCellText(ref1->text());
04461 ref1->setCellText(ref1->decodeFormula(d));
04462 ref1->setCalcDirtyFlag();
04463 ref1->calc(false);
04464 }
04465
04466 if (cpFormat)
04467 {
04468 KSpreadFormat::Align a = ref1->align( ref1->column(), ref1->row() );
04469 ref1->setAlign( ref2->align( ref2->column(), ref2->row() ) );
04470 ref2->setAlign(a);
04471
04472 KSpreadFormat::AlignY ay = ref1->alignY( ref1->column(), ref1->row() );
04473 ref1->setAlignY( ref2->alignY( ref2->column(), ref2->row() ) );
04474 ref2->setAlignY(ay);
04475
04476 QFont textFont = ref1->textFont( ref1->column(), ref1->row() );
04477 ref1->setTextFont( ref2->textFont( ref2->column(), ref2->row() ) );
04478 ref2->setTextFont(textFont);
04479
04480 QColor textColor = ref1->textColor( ref1->column(), ref1->row() );
04481 ref1->setTextColor( ref2->textColor( ref2->column(), ref2->row() ) );
04482 ref2->setTextColor(textColor);
04483
04484 QColor bgColor = ref1->bgColor( ref1->column(), ref1->row() );
04485 ref1->setBgColor( ref2->bgColor( ref2->column(), ref2->row() ) );
04486 ref2->setBgColor(bgColor);
04487
04488 QPen lbp = ref1->leftBorderPen( ref1->column(), ref1->row() );
04489 ref1->setLeftBorderPen( ref2->leftBorderPen( ref2->column(), ref2->row() ) );
04490 ref2->setLeftBorderPen(lbp);
04491
04492 QPen tbp = ref1->topBorderPen( ref1->column(), ref1->row() );
04493 ref1->setTopBorderPen( ref2->topBorderPen( ref2->column(), ref2->row() ) );
04494 ref2->setTopBorderPen(tbp);
04495
04496 QPen bbp = ref1->bottomBorderPen( ref1->column(), ref1->row() );
04497 ref1->setBottomBorderPen( ref2->bottomBorderPen( ref2->column(), ref2->row() ) );
04498 ref2->setBottomBorderPen(bbp);
04499
04500 QPen rbp = ref1->rightBorderPen( ref1->column(), ref1->row() );
04501 ref1->setRightBorderPen( ref2->rightBorderPen( ref2->column(), ref2->row() ) );
04502 ref2->setRightBorderPen(rbp);
04503
04504 QPen fdp = ref1->fallDiagonalPen( ref1->column(), ref1->row() );
04505 ref1->setFallDiagonalPen( ref2->fallDiagonalPen( ref2->column(), ref2->row() ) );
04506 ref2->setFallDiagonalPen(fdp);
04507
04508 QPen udp = ref1->goUpDiagonalPen( ref1->column(), ref1->row() );
04509 ref1->setGoUpDiagonalPen( ref2->goUpDiagonalPen( ref2->column(), ref2->row() ) );
04510 ref2->setGoUpDiagonalPen(udp);
04511
04512 QBrush bgBrush = ref1->backGroundBrush( ref1->column(), ref1->row() );
04513 ref1->setBackGroundBrush( ref2->backGroundBrush( ref2->column(), ref2->row() ) );
04514 ref2->setBackGroundBrush(bgBrush);
04515
04516 int pre = ref1->precision( ref1->column(), ref1->row() );
04517 ref1->setPrecision( ref2->precision( ref2->column(), ref2->row() ) );
04518 ref2->setPrecision(pre);
04519
04520 QString prefix = ref1->prefix( ref1->column(), ref1->row() );
04521 ref1->setPrefix( ref2->prefix( ref2->column(), ref2->row() ) );
04522 ref2->setPrefix(prefix);
04523
04524 QString postfix = ref1->postfix( ref1->column(), ref1->row() );
04525 ref1->setPostfix( ref2->postfix( ref2->column(), ref2->row() ) );
04526 ref2->setPostfix(postfix);
04527
04528 KSpreadFormat::FloatFormat f = ref1->floatFormat( ref1->column(), ref1->row() );
04529 ref1->setFloatFormat( ref2->floatFormat( ref2->column(), ref2->row() ) );
04530 ref2->setFloatFormat(f);
04531
04532 KSpreadFormat::FloatColor c = ref1->floatColor( ref1->column(), ref1->row() );
04533 ref1->setFloatColor( ref2->floatColor( ref2->column(), ref2->row() ) );
04534 ref2->setFloatColor(c);
04535
04536 bool multi = ref1->multiRow( ref1->column(), ref1->row() );
04537 ref1->setMultiRow( ref2->multiRow( ref2->column(), ref2->row() ) );
04538 ref2->setMultiRow(multi);
04539
04540 bool vert = ref1->verticalText( ref1->column(), ref1->row() );
04541 ref1->setVerticalText( ref2->verticalText( ref2->column(), ref2->row() ) );
04542 ref2->setVerticalText(vert);
04543
04544 bool print = ref1->getDontprintText( ref1->column(), ref1->row() );
04545 ref1->setDontPrintText( ref2->getDontprintText( ref2->column(), ref2->row() ) );
04546 ref2->setDontPrintText(print);
04547
04548 double ind = ref1->getIndent( ref1->column(), ref1->row() );
04549 ref1->setIndent( ref2->getIndent( ref2->column(), ref2->row() ) );
04550 ref2->setIndent( ind );
04551
04552 QValueList<KSpreadConditional> conditionList = ref1->conditionList();
04553 ref1->setConditionList(ref2->conditionList());
04554 ref2->setConditionList(conditionList);
04555
04556 QString com = ref1->comment( ref1->column(), ref1->row() );
04557 ref1->setComment( ref2->comment( ref2->column(), ref2->row() ) );
04558 ref2->setComment(com);
04559
04560 int angle = ref1->getAngle( ref1->column(), ref1->row() );
04561 ref1->setAngle( ref2->getAngle( ref2->column(), ref2->row() ) );
04562 ref2->setAngle(angle);
04563
04564 FormatType form = ref1->getFormatType( ref1->column(), ref1->row() );
04565 ref1->setFormatType( ref2->getFormatType( ref2->column(), ref2->row() ) );
04566 ref2->setFormatType(form);
04567 }
04568 }
04569
04570 void KSpreadSheet::refreshPreference()
04571 {
04572 if ( getAutoCalc() )
04573 recalc();
04574
04575 emit sig_updateHBorder( this );
04576 emit sig_updateView( this );
04577 }
04578
04579
04580 bool KSpreadSheet::areaIsEmpty(const QRect &area, TestType _type)
04581 {
04582
04583 if ( util_isRowSelected(area) )
04584 {
04585 for ( int row = area.top(); row <= area.bottom(); ++row )
04586 {
04587 KSpreadCell * c = getFirstCellRow( row );
04588 while ( c )
04589 {
04590 if ( !c->isObscuringForced())
04591 {
04592 switch( _type )
04593 {
04594 case Text :
04595 if ( !c->text().isEmpty())
04596 return false;
04597 break;
04598 case Validity:
04599 if ( c->getValidity(0))
04600 return false;
04601 break;
04602 case Comment:
04603 if ( !c->comment(c->column(), row).isEmpty())
04604 return false;
04605 break;
04606 case ConditionalCellAttribute:
04607 if ( c->conditionList().count()> 0)
04608 return false;
04609 break;
04610 }
04611 }
04612
04613 c = getNextCellRight( c->column(), row );
04614 }
04615 }
04616 }
04617
04618 else if ( util_isColumnSelected(area) )
04619 {
04620 for ( int col = area.left(); col <= area.right(); ++col )
04621 {
04622 KSpreadCell * c = getFirstCellColumn( col );
04623 while ( c )
04624 {
04625 if ( !c->isObscuringForced() )
04626 {
04627 switch( _type )
04628 {
04629 case Text :
04630 if ( !c->text().isEmpty())
04631 return false;
04632 break;
04633 case Validity:
04634 if ( c->getValidity(0))
04635 return false;
04636 break;
04637 case Comment:
04638 if ( !c->comment(col, c->row()).isEmpty())
04639 return false;
04640 break;
04641 case ConditionalCellAttribute:
04642 if ( c->conditionList().count()> 0)
04643 return false;
04644 break;
04645 }
04646 }
04647
04648 c = getNextCellDown( col, c->row() );
04649 }
04650 }
04651 }
04652 else
04653 {
04654 KSpreadCell * cell;
04655
04656 int right = area.right();
04657 int bottom = area.bottom();
04658 for ( int x = area.left(); x <= right; ++x )
04659 for ( int y = area.top(); y <= bottom; ++y )
04660 {
04661 cell = cellAt( x, y );
04662 if (!cell->isObscuringForced() )
04663 {
04664 switch( _type )
04665 {
04666 case Text :
04667 if ( !cell->text().isEmpty())
04668 return false;
04669 break;
04670 case Validity:
04671 if ( cell->getValidity(0))
04672 return false;
04673 break;
04674 case Comment:
04675 if ( !cell->comment(x, y).isEmpty())
04676 return false;
04677 break;
04678 case ConditionalCellAttribute:
04679 if ( cell->conditionList().count()> 0)
04680 return false;
04681 break;
04682 }
04683 }
04684 }
04685 }
04686 return true;
04687 }
04688
04689 struct SetSelectionMultiRowWorker : public KSpreadSheet::CellWorker
04690 {
04691 bool enable;
04692 SetSelectionMultiRowWorker( bool _enable )
04693 : KSpreadSheet::CellWorker( ), enable( _enable ) { }
04694
04695 class KSpreadUndoAction* createUndoAction( KSpreadDoc * doc, KSpreadSheet * sheet, QRect & r )
04696 {
04697 QString title = i18n("Multirow");
04698 return new KSpreadUndoCellFormat( doc, sheet, r, title );
04699 }
04700
04701 bool testCondition( KSpreadCell * cell )
04702 {
04703 return ( !cell->isObscuringForced() );
04704 }
04705
04706 void doWork( KSpreadCell * cell, bool, int, int )
04707 {
04708 cell->setDisplayDirtyFlag();
04709 cell->setMultiRow( enable );
04710 cell->setVerticalText( false );
04711 cell->setAngle( 0 );
04712 cell->clearDisplayDirtyFlag();
04713 }
04714 };
04715
04716 void KSpreadSheet::setSelectionMultiRow( KSpreadSelection* selectionInfo,
04717 bool enable )
04718 {
04719 SetSelectionMultiRowWorker w( enable );
04720 workOnCells( selectionInfo, w );
04721 }
04722
04723
04724 struct SetSelectionAlignWorker
04725 : public KSpreadSheet::CellWorkerTypeA
04726 {
04727 KSpreadFormat::Align _align;
04728 SetSelectionAlignWorker( KSpreadFormat::Align align ) : _align( align ) {}
04729 QString getUndoTitle() { return i18n("Change Horizontal Alignment"); }
04730 bool testCondition( RowFormat* rw ) {
04731 return ( rw->hasProperty( KSpreadCell::PAlign ) );
04732 }
04733 void doWork( RowFormat* rw ) {
04734 rw->setAlign( _align );
04735 }
04736 void doWork( ColumnFormat* cl ) {
04737 cl->setAlign( _align );
04738 }
04739 void prepareCell( KSpreadCell* c ) {
04740 c->clearProperty( KSpreadCell::PAlign );
04741 c->clearNoFallBackProperties( KSpreadCell::PAlign );
04742 }
04743 bool testCondition( KSpreadCell* cell ) {
04744 return ( !cell->isObscuringForced() );
04745 }
04746 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
04747 if ( cellRegion )
04748 cell->setDisplayDirtyFlag();
04749 cell->setAlign( _align );
04750 if ( cellRegion )
04751 cell->clearDisplayDirtyFlag();
04752 }
04753 };
04754
04755
04756 void KSpreadSheet::setSelectionAlign( KSpreadSelection* selectionInfo,
04757 KSpreadFormat::Align _align )
04758 {
04759 SetSelectionAlignWorker w( _align );
04760 workOnCells( selectionInfo, w );
04761 }
04762
04763
04764 struct SetSelectionAlignYWorker : public KSpreadSheet::CellWorkerTypeA {
04765 KSpreadFormat::AlignY _alignY;
04766 SetSelectionAlignYWorker( KSpreadFormat::AlignY alignY )
04767 : _alignY( alignY )
04768 {
04769 kdDebug() << "AlignY: " << _alignY << endl;
04770 }
04771 QString getUndoTitle() { return i18n("Change Vertical Alignment"); }
04772 bool testCondition( RowFormat* rw ) {
04773 return ( rw->hasProperty( KSpreadCell::PAlignY ) );
04774 }
04775 void doWork( RowFormat* rw ) {
04776 rw->setAlignY( _alignY );
04777 }
04778 void doWork( ColumnFormat* cl ) {
04779 cl->setAlignY( _alignY );
04780 }
04781 void prepareCell( KSpreadCell* c ) {
04782 c->clearProperty( KSpreadCell::PAlignY );
04783 c->clearNoFallBackProperties( KSpreadCell::PAlignY );
04784 }
04785 bool testCondition( KSpreadCell* cell ) {
04786 kdDebug() << "testCondition" << endl;
04787 return ( !cell->isObscuringForced() );
04788 }
04789 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
04790 if ( cellRegion )
04791 cell->setDisplayDirtyFlag();
04792 kdDebug() << "cell->setAlignY: " << _alignY << endl;
04793 cell->setAlignY( _alignY );
04794 if ( cellRegion )
04795 cell->clearDisplayDirtyFlag();
04796 }
04797 };
04798
04799
04800 void KSpreadSheet::setSelectionAlignY( KSpreadSelection* selectionInfo,
04801 KSpreadFormat::AlignY _alignY )
04802 {
04803 kdDebug() << "setSelectionAlignY: " << _alignY << endl;
04804 SetSelectionAlignYWorker w( _alignY );
04805 workOnCells( selectionInfo, w );
04806 }
04807
04808
04809 struct SetSelectionPrecisionWorker : public KSpreadSheet::CellWorker {
04810 int _delta;
04811 SetSelectionPrecisionWorker( int delta ) : KSpreadSheet::CellWorker( ), _delta( delta ) { }
04812
04813 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
04814 QString title=i18n("Change Precision");
04815 return new KSpreadUndoCellFormat( doc, sheet, r, title );
04816 }
04817 bool testCondition( KSpreadCell* cell ) {
04818 return ( !cell->isObscuringForced() );
04819 }
04820 void doWork( KSpreadCell* cell, bool, int, int ) {
04821 cell->setDisplayDirtyFlag();
04822 if ( _delta == 1 )
04823 cell->incPrecision();
04824 else
04825 cell->decPrecision();
04826 cell->clearDisplayDirtyFlag();
04827 }
04828 };
04829
04830 void KSpreadSheet::setSelectionPrecision( KSpreadSelection* selectionInfo,
04831 int _delta )
04832 {
04833 SetSelectionPrecisionWorker w( _delta );
04834 workOnCells( selectionInfo, w );
04835 }
04836
04837 struct SetSelectionStyleWorker : public KSpreadSheet::CellWorkerTypeA
04838 {
04839 KSpreadStyle * m_style;
04840 SetSelectionStyleWorker( KSpreadStyle * style )
04841 : m_style( style )
04842 {
04843 }
04844
04845 QString getUndoTitle()
04846 {
04847 return i18n("Apply Style");
04848 }
04849
04850 void doWork( RowFormat* rw )
04851 {
04852 rw->setKSpreadStyle( m_style );
04853 }
04854
04855 void doWork( ColumnFormat* cl )
04856 {
04857 cl->setKSpreadStyle( m_style );
04858 }
04859
04860 bool testCondition( KSpreadCell* cell )
04861 {
04862 return ( !cell->isObscuringForced() && cell->kspreadStyle() != m_style );
04863 }
04864
04865 void doWork( KSpreadCell* cell, bool cellRegion, int, int )
04866 {
04867 if ( cellRegion )
04868 cell->setDisplayDirtyFlag();
04869
04870 cell->setKSpreadStyle( m_style );
04871
04872 if ( cellRegion )
04873 cell->clearDisplayDirtyFlag();
04874 }
04875 };
04876
04877
04878 void KSpreadSheet::setSelectionStyle( KSpreadSelection * selectionInfo, KSpreadStyle * style )
04879 {
04880 SetSelectionStyleWorker w( style );
04881 workOnCells( selectionInfo, w );
04882 }
04883
04884 struct SetSelectionMoneyFormatWorker : public KSpreadSheet::CellWorkerTypeA
04885 {
04886 bool b;
04887 KSpreadDoc *m_pDoc;
04888 SetSelectionMoneyFormatWorker( bool _b,KSpreadDoc* _doc ) : b( _b ), m_pDoc(_doc) { }
04889 QString getUndoTitle() { return i18n("Format Money"); }
04890 bool testCondition( RowFormat* rw ) {
04891 return ( rw->hasProperty( KSpreadCell::PFormatType )
04892 || rw->hasProperty( KSpreadCell::PPrecision ) );
04893 }
04894 void doWork( RowFormat* rw ) {
04895 rw->setFormatType( b ? Money_format : Generic_format );
04896 rw->setPrecision( b ? m_pDoc->locale()->fracDigits() : 0 );
04897 }
04898 void doWork( ColumnFormat* cl ) {
04899 cl->setFormatType( b ? Money_format : Generic_format );
04900 cl->setPrecision( b ? m_pDoc->locale()->fracDigits() : 0 );
04901 }
04902 void prepareCell( KSpreadCell* c ) {
04903 c->clearProperty( KSpreadCell::PPrecision );
04904 c->clearNoFallBackProperties( KSpreadCell::PPrecision );
04905 c->clearProperty( KSpreadCell::PFormatType );
04906 c->clearNoFallBackProperties( KSpreadCell::PFormatType );
04907 }
04908 bool testCondition( KSpreadCell* cell ) {
04909 return ( !cell->isObscuringForced() );
04910 }
04911 void doWork( KSpreadCell* cell, bool cellRegion, int, int ) {
04912 if ( cellRegion )
04913 cell->setDisplayDirtyFlag();
04914 cell->setFormatType( b ? Money_format : Generic_format );
04915 cell->setPrecision( b ? m_pDoc->locale()->fracDigits() : 0 );
04916 if ( cellRegion )
04917 cell->clearDisplayDirtyFlag();
04918 }
04919 };
04920
04921
04922 void KSpreadSheet::setSelectionMoneyFormat( KSpreadSelection* selectionInfo,
04923 bool b )
04924 {
04925 SetSelectionMoneyFormatWorker w( b,doc() );
04926 workOnCells( selectionInfo, w );
04927 }
04928
04929
04930 struct IncreaseIndentWorker : public KSpreadSheet::CellWorkerTypeA {
04931 double tmpIndent, valIndent;
04932 IncreaseIndentWorker( double _tmpIndent, double _valIndent ) : tmpIndent( _tmpIndent ), valIndent( _valIndent ) { }
04933 QString getUndoTitle() { return i18n("Increase Indent"); }
04934 bool testCondition( RowFormat* rw ) {
04935 return ( rw->hasProperty( KSpreadCell::PIndent ) );
04936 }
04937 void doWork( RowFormat* rw ) {
04938 rw->setIndent( tmpIndent+valIndent );
04939 rw->setAlign( KSpreadCell::Left );
04940 }
04941 void doWork( ColumnFormat* cl ) {
04942 cl->setIndent( tmpIndent+valIndent );
04943 cl->setAlign( KSpreadCell::Left );
04944 }
04945 void prepareCell( KSpreadCell* c ) {
04946 c->clearProperty( KSpreadCell::PIndent );
04947 c->clearNoFallBackProperties( KSpreadCell::PIndent );
04948 c->clearProperty( KSpreadCell::PAlign );
04949 c->clearNoFallBackProperties( KSpreadCell::PAlign );
04950 }
04951 bool testCondition( KSpreadCell* cell ) {
04952 return ( !cell->isObscuringForced() );
04953 }
04954 void doWork( KSpreadCell* cell, bool cellRegion, int x, int y ) {
04955 if ( cellRegion ) {
04956 if(cell->align(x,y)!=KSpreadCell::Left)
04957 {
04958 cell->setAlign(KSpreadCell::Left);
04959 cell->setIndent( 0.0 );
04960 }
04961 cell->setDisplayDirtyFlag();
04962 cell->setIndent( cell->getIndent(x,y) +valIndent );
04963 cell->clearDisplayDirtyFlag();
04964 } else {
04965 cell->setIndent( tmpIndent+valIndent);
04966 cell->setAlign( KSpreadCell::Left);
04967 }
04968 }
04969 };
04970
04971
04972 void KSpreadSheet::increaseIndent(KSpreadSelection* selectionInfo)
04973 {
04974 double valIndent = doc()->getIndentValue();
04975 QPoint marker(selectionInfo->marker());
04976 KSpreadCell* c = cellAt( marker );
04977 double tmpIndent = c->getIndent( marker.x(), marker.y() );
04978
04979 IncreaseIndentWorker w( tmpIndent, valIndent );
04980 workOnCells( selectionInfo, w );
04981 }
04982
04983
04984 struct DecreaseIndentWorker : public KSpreadSheet::CellWorkerTypeA {
04985 double tmpIndent, valIndent;
04986 DecreaseIndentWorker( double _tmpIndent, double _valIndent ) : tmpIndent( _tmpIndent ), valIndent( _valIndent ) { }
04987 QString getUndoTitle() { return i18n("Decrease Indent"); }
04988 bool testCondition( RowFormat* rw ) {
04989 return ( rw->hasProperty( KSpreadCell::PIndent ) );
04990 }
04991 void doWork( RowFormat* rw ) {
04992 rw->setIndent( QMAX( 0.0, tmpIndent - valIndent ) );
04993 }
04994 void doWork( ColumnFormat* cl ) {
04995 cl->setIndent( QMAX( 0.0, tmpIndent - valIndent ) );
04996 }
04997 void prepareCell( KSpreadCell* c ) {
04998 c->clearProperty( KSpreadCell::PIndent );
04999 c->clearNoFallBackProperties( KSpreadCell::PIndent );
05000 }
05001 bool testCondition( KSpreadCell* cell ) {
05002 return ( !cell->isObscuringForced() );
05003 }
05004 void doWork( KSpreadCell* cell, bool cellRegion, int x, int y ) {
05005 if ( cellRegion ) {
05006 cell->setDisplayDirtyFlag();
05007 cell->setIndent( QMAX( 0.0, cell->getIndent( x, y ) - valIndent ) );
05008 cell->clearDisplayDirtyFlag();
05009 } else {
05010 cell->setIndent( QMAX( 0.0, tmpIndent - valIndent ) );
05011 }
05012 }
05013 };
05014
05015
05016 void KSpreadSheet::decreaseIndent( KSpreadSelection* selectionInfo )
05017 {
05018 double valIndent = doc()->getIndentValue();
05019 QPoint marker(selectionInfo->marker());
05020 KSpreadCell* c = cellAt( marker );
05021 double tmpIndent = c->getIndent( marker.x(), marker.y() );
05022
05023 DecreaseIndentWorker w( tmpIndent, valIndent );
05024 workOnCells( selectionInfo, w );
05025 }
05026
05027
05028 int KSpreadSheet::adjustColumnHelper( KSpreadCell * c, int _col, int _row )
05029 {
05030 double long_max = 0.0;
05031 c->calculateTextParameters( painter(), _col, _row );
05032 if ( c->textWidth() > long_max )
05033 {
05034 double indent = 0.0;
05035 int a = c->align( c->column(), c->row() );
05036 if ( a == KSpreadCell::Undefined )
05037 {
05038 if ( c->value().isNumber() || c->isDate() || c->isTime())
05039 a = KSpreadCell::Right;
05040 else
05041 a = KSpreadCell::Left;
05042 }
05043
05044 if ( a == KSpreadCell::Left )
05045 indent = c->getIndent( c->column(), c->row() );
05046 long_max = indent + c->textWidth()
05047 + c->leftBorderWidth( c->column(), c->row() )
05048 + c->rightBorderWidth( c->column(), c->row() );
05049 }
05050 return (int)long_max;
05051 }
05052
05053 int KSpreadSheet::adjustColumn( KSpreadSelection* selectionInfo, int _col )
05054 {
05055 QRect selection(selectionInfo->selection());
05056 double long_max = 0.0;
05057 if ( _col == -1 )
05058 {
05059 if ( util_isColumnSelected(selection) )
05060 {
05061 for ( int col = selection.left(); col <= selection.right(); ++col )
05062 {
05063 KSpreadCell * c = getFirstCellColumn( col );
05064 while ( c )
05065 {
05066 if ( !c->isEmpty() && !c->isObscured() )
05067 {
05068 long_max = QMAX( adjustColumnHelper( c, col, c->row() ), long_max );
05069 }
05070 c = getNextCellDown( col, c->row() );
05071 }
05072 }
05073 }
05074 }
05075 else
05076 {
05077 if ( util_isColumnSelected(selection) )
05078 {
05079 for ( int col = selection.left(); col <= selection.right(); ++col )
05080 {
05081 KSpreadCell * c = getFirstCellColumn( col );
05082 while ( c )
05083 {
05084 if ( !c->isEmpty() && !c->isObscured())
05085 {
05086 long_max = QMAX( adjustColumnHelper( c, col, c->row() ), long_max );
05087 }
05088 c = getNextCellDown( col, c->row() );
05089 }
05090 }
05091 }
05092 else
05093 {
05094 int x = _col;
05095 KSpreadCell * cell;
05096 for ( int y = selection.top(); y <= selection.bottom(); ++y )
05097 {
05098 cell = cellAt( x, y );
05099 if ( cell != d->defaultCell && !cell->isEmpty()
05100 && !cell->isObscured() )
05101 {
05102 long_max = QMAX( adjustColumnHelper( cell, x, y ), long_max );
05103 }
05104 }
05105 }
05106 }
05107
05108
05109
05110 if( long_max == 0 )
05111 return -1;
05112 else
05113 return ( (int)long_max + 4 );
05114 }
05115
05116 int KSpreadSheet::adjustRow( KSpreadSelection* selectionInfo, int _row )
05117 {
05118 QRect selection(selectionInfo->selection());
05119 double long_max = 0.0;
05120 if( _row == -1 )
05121 {
05122 if ( util_isRowSelected(selection) )
05123 {
05124 for ( int row = selection.top(); row <= selection.bottom(); ++row )
05125 {
05126 KSpreadCell * c = getFirstCellRow( row );
05127 while ( c )
05128 {
05129 if ( !c->isEmpty() && !c->isObscured() )
05130 {
05131 c->calculateTextParameters( painter(), c->column(), row );
05132 if( c->textHeight() > long_max )
05133 long_max = c->textHeight()
05134 + c->topBorderWidth( c->column(), c->row() )
05135 + c->bottomBorderWidth( c->column(), c->row() );
05136 }
05137 c = getNextCellRight( c->column(), row );
05138 }
05139 }
05140 }
05141 }
05142 else
05143 {
05144 if ( util_isRowSelected(selection) )
05145 {
05146 for ( int row = selection.top(); row <= selection.bottom(); ++row )
05147 {
05148 KSpreadCell * c = getFirstCellRow( row );
05149 while ( c )
05150 {
05151 if ( !c->isEmpty() && !c->isObscured() )
05152 {
05153 c->calculateTextParameters( painter(), c->column(), row );
05154 if ( c->textHeight() > long_max )
05155 long_max = c->textHeight()
05156 + c->topBorderWidth( c->column(), c->row() )
05157 + c->bottomBorderWidth( c->column(), c->row() );
05158 }
05159 c = getNextCellRight( c->column(), row );
05160 }
05161 }
05162 }
05163 else
05164 {
05165 int y = _row;
05166 KSpreadCell * cell;
05167 for ( int x = selection.left(); x <= selection.right(); ++x )
05168 {
05169 cell = cellAt( x, y );
05170 if ( cell != d->defaultCell && !cell->isEmpty()
05171 && !cell->isObscured() )
05172 {
05173 cell->calculateTextParameters( painter(), x, y );
05174 if ( cell->textHeight() > long_max )
05175 long_max = cell->textHeight()
05176 + cell->topBorderWidth( cell->column(), cell->row() )
05177 + cell->bottomBorderWidth( cell->column(), cell->row() );
05178 }
05179 }
05180 }
05181 }
05182
05183
05184 if( long_max == 0.0 )
05185 return -1;
05186 else
05187 return ( (int)long_max + 4 );
05188 }
05189
05190 struct ClearTextSelectionWorker : public KSpreadSheet::CellWorker {
05191 KSpreadSheet * _s;
05192
05193 ClearTextSelectionWorker( KSpreadSheet * s )
05194 : KSpreadSheet::CellWorker( ), _s( s ) { }
05195
05196 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
05197 return new KSpreadUndoChangeAreaTextCell( doc, sheet, r );
05198 }
05199 bool testCondition( KSpreadCell* cell ) {
05200 return ( !cell->isObscured() );
05201 }
05202 void doWork( KSpreadCell* cell, bool, int, int )
05203 {
05204 cell->setCellText( "" );
05205 }
05206 };
05207
05208 void KSpreadSheet::clearTextSelection( KSpreadSelection* selectionInfo )
05209 {
05210 if (areaIsEmpty(selectionInfo->selection()))
05211 return;
05212
05213 ClearTextSelectionWorker w( this );
05214 workOnCells( selectionInfo, w );
05215 }
05216
05217
05218 struct ClearValiditySelectionWorker : public KSpreadSheet::CellWorker {
05219 ClearValiditySelectionWorker( ) : KSpreadSheet::CellWorker( ) { }
05220
05221 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
05222 return new KSpreadUndoConditional( doc, sheet, r );
05223 }
05224 bool testCondition( KSpreadCell* cell ) {
05225 return ( !cell->isObscured() );
05226 }
05227 void doWork( KSpreadCell* cell, bool, int, int ) {
05228 cell->removeValidity();
05229 }
05230 };
05231
05232 void KSpreadSheet::clearValiditySelection( KSpreadSelection* selectionInfo )
05233 {
05234 if(areaIsEmpty(selectionInfo->selection(), Validity))
05235 return;
05236
05237 ClearValiditySelectionWorker w;
05238 workOnCells( selectionInfo, w );
05239 }
05240
05241
05242 struct ClearConditionalSelectionWorker : public KSpreadSheet::CellWorker
05243 {
05244 ClearConditionalSelectionWorker( ) : KSpreadSheet::CellWorker( ) { }
05245
05246 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc,
05247 KSpreadSheet* sheet,
05248 QRect& r )
05249 {
05250 return new KSpreadUndoConditional( doc, sheet, r );
05251 }
05252 bool testCondition( KSpreadCell* cell )
05253 {
05254 return ( !cell->isObscured() );
05255 }
05256 void doWork( KSpreadCell* cell, bool, int, int )
05257 {
05258 QValueList<KSpreadConditional> emptyList;
05259 cell->setConditionList(emptyList);
05260 }
05261 };
05262
05263 void KSpreadSheet::clearConditionalSelection( KSpreadSelection* selectionInfo )
05264 {
05265 ClearConditionalSelectionWorker w;
05266 workOnCells( selectionInfo, w );
05267 }
05268
05269 void KSpreadSheet::fillSelection( KSpreadSelection * selectionInfo, int direction )
05270 {
05271 QRect rct( selectionInfo->selection() );
05272 int right = rct.right();
05273 int bottom = rct.bottom();
05274 int left = rct.left();
05275 int top = rct.top();
05276 int width = rct.width();
05277 int height = rct.height();
05278
05279 QDomDocument undoDoc = saveCellRect( rct );
05280 loadSelectionUndo( undoDoc, rct, left - 1, top - 1, false, 0 );
05281
05282 QDomDocument doc;
05283
05284 switch( direction )
05285 {
05286 case Right:
05287 doc = saveCellRect( QRect( left, top, 1, height ) );
05288 break;
05289
05290 case Up:
05291 doc = saveCellRect( QRect( left, bottom, width, 1 ) );
05292 break;
05293
05294 case Left:
05295 doc = saveCellRect( QRect( right, top, 1, height ) );
05296 break;
05297
05298 case Down:
05299 doc = saveCellRect( QRect( left, top, width, 1 ) );
05300 break;
05301 };
05302
05303
05304 QBuffer buffer;
05305 buffer.open( IO_WriteOnly );
05306 QTextStream str( &buffer );
05307 str.setEncoding( QTextStream::UnicodeUTF8 );
05308 str << doc;
05309 buffer.close();
05310
05311 int i;
05312 switch( direction )
05313 {
05314 case Right:
05315 for ( i = left + 1; i <= right; ++i )
05316 {
05317 paste( buffer.buffer(), QRect( i, top, 1, 1 ), false );
05318 }
05319 break;
05320
05321 case Up:
05322 for ( i = bottom + 1; i >= top; --i )
05323 {
05324 paste( buffer.buffer(), QRect( left, i, 1, 1 ), false );
05325 }
05326 break;
05327
05328 case Left:
05329 for ( i = right - 1; i >= left; --i )
05330 {
05331 paste( buffer.buffer(), QRect( i, top, 1, 1 ), false );
05332 }
05333 break;
05334
05335 case Down:
05336 for ( i = top + 1; i <= bottom; ++i )
05337 {
05338 paste( buffer.buffer(), QRect( left, i, 1, 1 ), false );
05339 }
05340 break;
05341 }
05342
05343 this->doc()->setModified( true );
05344 }
05345
05346
05347 struct DefaultSelectionWorker : public KSpreadSheet::CellWorker {
05348 DefaultSelectionWorker( ) : KSpreadSheet::CellWorker( true, false, true ) { }
05349
05350 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
05351 QString title=i18n("Default Parameters");
05352 return new KSpreadUndoCellFormat( doc, sheet, r, title );
05353 }
05354 bool testCondition( KSpreadCell* ) {
05355 return true;
05356 }
05357 void doWork( KSpreadCell* cell, bool, int, int ) {
05358 cell->defaultStyle();
05359 }
05360 };
05361
05362 void KSpreadSheet::defaultSelection( KSpreadSelection* selectionInfo )
05363 {
05364 QRect selection(selectionInfo->selection());
05365 DefaultSelectionWorker w;
05366 SelectionType st = workOnCells( selectionInfo, w );
05367 switch ( st ) {
05368 case CompleteRows:
05369 RowFormat *rw;
05370 for ( int i = selection.top(); i <= selection.bottom(); i++ ) {
05371 rw = nonDefaultRowFormat( i );
05372 rw->defaultStyleFormat();
05373 }
05374 emit sig_updateView( this, selection );
05375 return;
05376 case CompleteColumns:
05377 ColumnFormat *cl;
05378 for ( int i = selection.left(); i <= selection.right(); i++ ) {
05379 cl=nonDefaultColumnFormat( i );
05380 cl->defaultStyleFormat();
05381 }
05382 emit sig_updateView( this, selection );
05383 return;
05384 case CellRegion:
05385 emit sig_updateView( this, selection );
05386 return;
05387 }
05388 }
05389
05390
05391 struct SetConditionalWorker : public KSpreadSheet::CellWorker
05392 {
05393 QValueList<KSpreadConditional> conditionList;
05394 SetConditionalWorker( QValueList<KSpreadConditional> _tmp ) :
05395 KSpreadSheet::CellWorker( ), conditionList( _tmp ) { }
05396
05397 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc,
05398 KSpreadSheet* sheet, QRect& r )
05399 {
05400 return new KSpreadUndoConditional( doc, sheet, r );
05401 }
05402
05403 bool testCondition( KSpreadCell* )
05404 {
05405 return true;
05406 }
05407
05408 void doWork( KSpreadCell* cell, bool, int, int )
05409 {
05410 if ( !cell->isObscured() )
05411 {
05412 cell->setConditionList(conditionList);
05413 cell->setDisplayDirtyFlag();
05414 }
05415 }
05416 };
05417
05418 void KSpreadSheet::setConditional( KSpreadSelection* selectionInfo,
05419 QValueList<KSpreadConditional> const & newConditions)
05420 {
05421 QRect selection(selectionInfo->selection());
05422 if ( !doc()->undoLocked() )
05423 {
05424 KSpreadUndoConditional * undo = new KSpreadUndoConditional( doc(), this, selection );
05425 doc()->addCommand( undo );
05426 }
05427
05428 int l = selection.left();
05429 int r = selection.right();
05430 int t = selection.top();
05431 int b = selection.bottom();
05432
05433 KSpreadCell * cell;
05434 KSpreadStyle * s = doc()->styleManager()->defaultStyle();
05435 for (int x = l; x <= r; ++x)
05436 {
05437 for (int y = t; y <= b; ++y)
05438 {
05439 cell = nonDefaultCell( x, y, false, s );
05440 cell->setConditionList( newConditions );
05441 cell->setDisplayDirtyFlag();
05442 }
05443 }
05444
05445 emit sig_updateView( this, selectionInfo->selection() );
05446 }
05447
05448
05449 struct SetValidityWorker : public KSpreadSheet::CellWorker {
05450 KSpreadValidity tmp;
05451 SetValidityWorker( KSpreadValidity _tmp ) : KSpreadSheet::CellWorker( ), tmp( _tmp ) { }
05452
05453 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
05454 return new KSpreadUndoConditional( doc, sheet, r );
05455 }
05456 bool testCondition( KSpreadCell* ) {
05457 return true;
05458 }
05459 void doWork( KSpreadCell* cell, bool, int, int ) {
05460 if ( !cell->isObscured() ) {
05461 cell->setDisplayDirtyFlag();
05462 if ( tmp.m_allow==Allow_All )
05463 cell->removeValidity();
05464 else
05465 {
05466 KSpreadValidity *tmpValidity = cell->getValidity();
05467 tmpValidity->message=tmp.message;
05468 tmpValidity->title=tmp.title;
05469 tmpValidity->valMin=tmp.valMin;
05470 tmpValidity->valMax=tmp.valMax;
05471 tmpValidity->m_cond=tmp.m_cond;
05472 tmpValidity->m_action=tmp.m_action;
05473 tmpValidity->m_allow=tmp.m_allow;
05474 tmpValidity->timeMin=tmp.timeMin;
05475 tmpValidity->timeMax=tmp.timeMax;
05476 tmpValidity->dateMin=tmp.dateMin;
05477 tmpValidity->dateMax=tmp.dateMax;
05478 tmpValidity->displayMessage=tmp.displayMessage;
05479 tmpValidity->allowEmptyCell=tmp.allowEmptyCell;
05480 tmpValidity->displayValidationInformation=tmp.displayValidationInformation;
05481 tmpValidity->titleInfo=tmp.titleInfo;
05482 tmpValidity->messageInfo=tmp.messageInfo;
05483 tmpValidity->listValidity=tmp.listValidity;
05484 }
05485 cell->clearDisplayDirtyFlag();
05486 }
05487 }
05488 };
05489
05490 void KSpreadSheet::setValidity(KSpreadSelection* selectionInfo,
05491 KSpreadValidity tmp )
05492 {
05493 SetValidityWorker w( tmp );
05494 workOnCells( selectionInfo, w );
05495 }
05496
05497
05498 struct GetWordSpellingWorker : public KSpreadSheet::CellWorker {
05499 QString& listWord;
05500 GetWordSpellingWorker( QString& _listWord ) : KSpreadSheet::CellWorker( false, false, true ), listWord( _listWord ) { }
05501
05502 class KSpreadUndoAction* createUndoAction( KSpreadDoc*, KSpreadSheet*, QRect& ) {
05503 return 0L;
05504 }
05505 bool testCondition( KSpreadCell* ) {
05506 return true;
05507 }
05508 void doWork( KSpreadCell* c, bool cellRegion, int, int ) {
05509 if ( !c->isObscured() || cellRegion ) {
05510 if ( !c->isFormula() && !c->value().isNumber() && !c->value().asString().isEmpty() && !c->isTime()
05511 && !c->isDate()
05512 && !c->text().isEmpty())
05513 {
05514 listWord+=c->text()+'\n';
05515 }
05516 }
05517 }
05518 };
05519
05520 QString KSpreadSheet::getWordSpelling(KSpreadSelection* selectionInfo )
05521 {
05522 QString listWord;
05523 GetWordSpellingWorker w( listWord );
05524 workOnCells( selectionInfo, w );
05525 return listWord;
05526 }
05527
05528
05529 struct SetWordSpellingWorker : public KSpreadSheet::CellWorker {
05530 QStringList& list;
05531 int pos;
05532 KSpreadSheet * sheet;
05533 SetWordSpellingWorker( QStringList & _list,KSpreadSheet * s )
05534 : KSpreadSheet::CellWorker( false, false, true ), list( _list ), pos( 0 ), sheet( s ) { }
05535
05536 class KSpreadUndoAction* createUndoAction( KSpreadDoc* doc, KSpreadSheet* sheet, QRect& r ) {
05537 return new KSpreadUndoChangeAreaTextCell( doc, sheet, r );
05538 }
05539 bool testCondition( KSpreadCell* ) {
05540 return true;
05541 }
05542 void doWork( KSpreadCell* c, bool cellRegion, int, int )
05543 {
05544 if ( !c->isObscured() || cellRegion ) {
05545 if ( !c->isFormula() && !c->value().isNumber() && !c->value().asString().isEmpty() && !c->isTime()
05546 && !c->isDate()
05547 && !c->text().isEmpty())
05548 {
05549
05550
05551 c->setCellText( list[pos] );
05552 pos++;
05553 }
05554 }
05555 }
05556 };
05557
05558 void KSpreadSheet::setWordSpelling(KSpreadSelection* selectionInfo,
05559 const QString _listWord )
05560 {
05561 QStringList list = QStringList::split ( '\n', _listWord );
05562 SetWordSpellingWorker w( list, this );
05563 workOnCells( selectionInfo, w );
05564 }
05565
05566 static QString cellAsText( KSpreadCell* cell, unsigned int max )
05567 {
05568 QString result;
05569 if( !cell->isDefault() )
05570 {
05571 int l = max - cell->strOutText().length();
05572 if (cell->defineAlignX() == KSpreadFormat::Right )
05573 {
05574 for ( int i = 0; i < l; ++i )
05575 result += " ";
05576 result += cell->strOutText();
05577 }
05578 else if (cell->defineAlignX() == KSpreadFormat::Left )
05579 {
05580 result += " ";
05581 result += cell->strOutText();
05582
05583 for ( int i = 1; i < l; ++i )
05584 result += " ";
05585 }
05586 else
05587 {
05588 int i;
05589 int s = (int) l / 2;
05590 for ( i = 0; i < s; ++i )
05591 result += " ";
05592 result += cell->strOutText();
05593 for ( i = s; i < l; ++i )
05594 result += " ";
05595 }
05596 }
05597 else
05598 {
05599 for ( unsigned int i = 0; i < max; ++i )
05600 result += " ";
05601 }
05602
05603 return result;
05604 }
05605
05606 QString KSpreadSheet::copyAsText( KSpreadSelection* selectionInfo )
05607 {
05608
05609 if ( selectionInfo->singleCellSelection() )
05610 {
05611 KSpreadCell * cell = cellAt( selectionInfo->marker() );
05612 if( !cell->isDefault() )
05613 return cell->strOutText();
05614 return "";
05615 }
05616
05617 QRect selection(selectionInfo->selection());
05618
05619
05620 unsigned top = selection.bottom();
05621 unsigned bottom = selection.top();
05622 unsigned left = selection.right();
05623 unsigned right = selection.left();
05624
05625 unsigned max = 1;
05626 for( KSpreadCell *c = d->cells.firstCell();c; c = c->nextCell() )
05627 {
05628 if ( !c->isDefault() )
05629 {
05630 QPoint p( c->column(), c->row() );
05631 if ( selection.contains( p ) )
05632 {
05633 top = QMIN( top, (unsigned) c->row() );
05634 left = QMIN( left, (unsigned) c->column() );
05635 bottom = QMAX( bottom, (unsigned) c->row() );
05636 right = QMAX( right, (unsigned) c->column() );
05637
05638 if ( c->strOutText().length() > max )
05639 max = c->strOutText().length();
05640 }
05641 }
05642 }
05643
05644 ++max;
05645
05646 QString result;
05647 for ( unsigned y = top; y <= bottom; ++y)
05648 {
05649 for ( unsigned x = left; x <= right; ++x)
05650 {
05651 KSpreadCell *cell = cellAt( x, y );
05652 result += cellAsText( cell, max );
05653 }
05654 result += "\n";
05655 }
05656
05657 return result;
05658 }
05659
05660 void KSpreadSheet::copySelection( KSpreadSelection* selectionInfo )
05661 {
05662 QRect rct;
05663
05664 rct = selectionInfo->selection();
05665
05666 QDomDocument doc = saveCellRect( rct, true );
05667
05668
05669 QBuffer buffer;
05670 buffer.open( IO_WriteOnly );
05671 QTextStream str( &buffer );
05672 str.setEncoding( QTextStream::UnicodeUTF8 );
05673 str << doc;
05674 buffer.close();
05675
05676 KSpreadTextDrag * kd = new KSpreadTextDrag( 0L );
05677 kd->setPlain( copyAsText(selectionInfo) );
05678 kd->setKSpread( buffer.buffer() );
05679
05680 QApplication::clipboard()->setData( kd );
05681 }
05682
05683 void KSpreadSheet::cutSelection( KSpreadSelection* selectionInfo )
05684 {
05685 QRect rct;
05686
05687 rct = selectionInfo->selection();
05688
05689 QDomDocument doc = saveCellRect( rct, true, true );
05690
05691
05692 QBuffer buffer;
05693 buffer.open( IO_WriteOnly );
05694 QTextStream str( &buffer );
05695 str.setEncoding( QTextStream::UnicodeUTF8 );
05696 str << doc;
05697 buffer.close();
05698
05699 KSpreadTextDrag * kd = new KSpreadTextDrag( 0L );
05700 kd->setPlain( copyAsText(selectionInfo) );
05701 kd->setKSpread( buffer.buffer() );
05702
05703 QApplication::clipboard()->setData( kd );
05704
05705 deleteSelection( selectionInfo, true );
05706 }
05707
05708 void KSpreadSheet::paste( const QRect &pasteArea, bool makeUndo,
05709 PasteMode sp, Operation op, bool insert, int insertTo, bool pasteFC )
05710 {
05711 QMimeSource * mime = QApplication::clipboard()->data();
05712 if ( !mime )
05713 return;
05714
05715 QByteArray b;
05716
05717 if ( mime->provides( KSpreadTextDrag::selectionMimeType() ) )
05718 {
05719 b = mime->encodedData( KSpreadTextDrag::selectionMimeType() );
05720 }
05721 else if( mime->provides( "text/plain" ) )
05722 {
05723
05724
05725 QString _text = QApplication::clipboard()->text();
05726 doc()->emitBeginOperation();
05727 pasteTextPlain( _text, pasteArea);
05728 emit sig_updateView( this );
05729
05730 return;
05731 }
05732 else
05733 return;
05734
05735
05736 doc()->emitBeginOperation();
05737 paste( b, pasteArea, makeUndo, sp, op, insert, insertTo, pasteFC );
05738 emit sig_updateView( this );
05739
05740 }
05741
05742
05743 void KSpreadSheet::pasteTextPlain( QString &_text, QRect pasteArea)
05744 {
05745
05746
05747 if( _text.isEmpty() )
05748 return;
05749
05750 QString tmp = _text;
05751 int i;
05752 int mx = pasteArea.left();
05753 int my = pasteArea.top();
05754 int rows = 1;
05755 int len = tmp.length();
05756
05757
05758 for ( i = 0; i < len; ++i )
05759 {
05760 if ( tmp[i] == '\n' )
05761 ++rows;
05762 }
05763
05764 KSpreadCell * cell = nonDefaultCell( mx, my );
05765 if ( rows == 1 )
05766 {
05767 if ( !doc()->undoLocked() )
05768 {
05769 KSpreadUndoSetText * undo = new KSpreadUndoSetText( doc(), this , cell->text(), mx, my, cell->formatType() );
05770 doc()->addCommand( undo );
05771 }
05772 }
05773 else
05774 {
05775 QRect rect(mx, my, mx, my + rows - 1);
05776 KSpreadUndoChangeAreaTextCell * undo = new KSpreadUndoChangeAreaTextCell( doc(), this , rect );
05777 doc()->addCommand( undo );
05778 }
05779
05780 i = 0;
05781 QString rowtext;
05782
05783 while ( i < rows )
05784 {
05785 int p = 0;
05786
05787 p = tmp.find('\n');
05788
05789 if (p < 0)
05790 p = tmp.length();
05791
05792 rowtext = tmp.left(p);
05793
05794 if ( !isProtected() || cell->notProtected( mx, my + i ) )
05795 {
05796 cell->setCellText( rowtext );
05797 cell->updateChart();
05798 }
05799
05800
05801 ++i;
05802 cell = nonDefaultCell( mx, my + i );
05803
05804 if (!cell || p == (int) tmp.length())
05805 break;
05806
05807
05808 tmp = tmp.right(tmp.length() - p - 1);
05809 }
05810
05811 if (!isLoading())
05812 refreshMergedCell();
05813
05814 emit sig_updateView( this );
05815 emit sig_updateHBorder( this );
05816 emit sig_updateVBorder( this );
05817 }
05818
05819 void KSpreadSheet::paste( const QByteArray & b, const QRect & pasteArea, bool makeUndo,
05820 PasteMode sp, Operation op, bool insert, int insertTo, bool pasteFC )
05821 {
05822 kdDebug(36001) << "Parsing " << b.size() << " bytes" << endl;
05823
05824 QBuffer buffer( b );
05825 buffer.open( IO_ReadOnly );
05826 QDomDocument doc;
05827 doc.setContent( &buffer );
05828 buffer.close();
05829
05830
05831
05832 int mx = pasteArea.left();
05833 int my = pasteArea.top();
05834
05835 loadSelection( doc, pasteArea, mx - 1, my - 1, makeUndo, sp, op, insert,
05836 insertTo, pasteFC );
05837 }
05838
05839 bool KSpreadSheet::loadSelection( const QDomDocument& doc, const QRect &pasteArea,
05840 int _xshift, int _yshift, bool makeUndo,
05841 PasteMode sp, Operation op, bool insert,
05842 int insertTo, bool pasteFC )
05843 {
05844 QDomElement e = doc.documentElement();
05845
05846
05847
05848 if (!isLoading() && makeUndo)
05849 loadSelectionUndo( doc, pasteArea, _xshift, _yshift, insert, insertTo );
05850
05851 int rowsInClpbrd = e.attribute( "rows" ).toInt();
05852 int columnsInClpbrd = e.attribute( "columns" ).toInt();
05853
05854
05855 const int pasteWidth = ( pasteArea.width() >= columnsInClpbrd
05856 && util_isRowSelected(pasteArea) == FALSE
05857 && e.namedItem( "rows" ).toElement().isNull() )
05858 ? pasteArea.width() : columnsInClpbrd;
05859 const int pasteHeight = ( pasteArea.height() >= rowsInClpbrd
05860 && util_isColumnSelected(pasteArea) == FALSE
05861 && e.namedItem( "columns" ).toElement().isNull())
05862 ? pasteArea.height() : rowsInClpbrd;
05863
05864
05865
05866
05867
05868
05869
05870
05871 if ( !e.namedItem( "columns" ).toElement().isNull() && !isProtected() )
05872 {
05873 _yshift = 0;
05874
05875
05876 for( int i = 1; i <= pasteWidth; ++i )
05877 {
05878 if(!insert)
05879 {
05880 d->cells.clearColumn( _xshift + i );
05881 d->columns.removeElement( _xshift + i );
05882 }
05883 }
05884
05885
05886 QDomElement c = e.firstChild().toElement();
05887 for( ; !c.isNull(); c = c.nextSibling().toElement() )
05888 {
05889 if ( c.tagName() == "column" )
05890 {
05891 ColumnFormat *cl = new ColumnFormat( this, 0 );
05892 if ( cl->load( c, _xshift, sp, pasteFC ) )
05893 insertColumnFormat( cl );
05894 else
05895 delete cl;
05896 }
05897 }
05898
05899 }
05900
05901 if ( !e.namedItem( "rows" ).toElement().isNull() && !isProtected() )
05902 {
05903 _xshift = 0;
05904
05905
05906 for( int i = 1; i <= pasteHeight; ++i )
05907 {
05908 d->cells.clearRow( _yshift + i );
05909 d->rows.removeElement( _yshift + i );
05910 }
05911
05912
05913 QDomElement c = e.firstChild().toElement();
05914 for( ; !c.isNull(); c = c.nextSibling().toElement() )
05915 {
05916 if ( c.tagName() == "row" )
05917 {
05918 RowFormat *cl = new RowFormat( this, 0 );
05919 if ( cl->load( c, _yshift, sp, pasteFC ) )
05920 insertRowFormat( cl );
05921 else
05922 delete cl;
05923 }
05924 }
05925 }
05926
05927 KSpreadCell* refreshCell = 0;
05928 KSpreadCell *cell;
05929 KSpreadCell *cellBackup = NULL;
05930 QDomElement c = e.firstChild().toElement();
05931 for( ; !c.isNull(); c = c.nextSibling().toElement() )
05932 {
05933 if ( c.tagName() == "cell" )
05934 {
05935 int row = c.attribute( "row" ).toInt() + _yshift;
05936 int col = c.attribute( "column" ).toInt() + _xshift;
05937
05938
05939 for (int roff = 0; row + roff - _yshift <= pasteHeight; roff += rowsInClpbrd)
05940 {
05941 for (int coff = 0; col + coff - _xshift <= pasteWidth; coff += columnsInClpbrd)
05942 {
05943
05944
05945
05946 cell = nonDefaultCell( col + coff, row + roff );
05947 if ( isProtected() && !cell->notProtected( col + coff, row + roff ) )
05948 continue;
05949
05950 cellBackup = new KSpreadCell(this, cell->column(), cell->row());
05951 cellBackup->copyAll(cell);
05952
05953 if ( !cell->load( c, _xshift + coff, _yshift + roff, sp, op, pasteFC ) )
05954 {
05955 cell->copyAll(cellBackup);
05956 }
05957 else
05958 {
05959 if( cell->isFormula() )
05960 {
05961 cell->setCalcDirtyFlag();
05962 }
05963 }
05964
05965 delete cellBackup;
05966
05967
05968
05969 cell = cellAt( col + coff, row + roff );
05970 if( !refreshCell && cell->updateChart( false ) )
05971 {
05972 refreshCell = cell;
05973 }
05974 }
05975 }
05976 }
05977 }
05978
05979
05980
05981
05982
05983
05984
05985 if ( refreshCell )
05986 refreshCell->updateChart();
05987 this->doc()->setModified( true );
05988
05989 if(!isLoading())
05990 refreshMergedCell();
05991
05992 emit sig_updateView( this );
05993 emit sig_updateHBorder( this );
05994 emit sig_updateVBorder( this );
05995
05996 return true;
05997 }
05998
05999 void KSpreadSheet::loadSelectionUndo( const QDomDocument & d, const QRect &loadArea,
06000 int _xshift, int _yshift, bool insert,
06001 int insertTo)
06002 {
06003 QDomElement e = d.documentElement();
06004 QDomElement c = e.firstChild().toElement();
06005 int rowsInClpbrd = e.attribute( "rows" ).toInt();
06006 int columnsInClpbrd = e.attribute( "columns" ).toInt();
06007
06008 const int pasteWidth = ( loadArea.width() >= columnsInClpbrd &&
06009 util_isRowSelected(loadArea) == FALSE &&
06010 e.namedItem( "rows" ).toElement().isNull() )
06011 ? loadArea.width() : columnsInClpbrd;
06012 const int pasteHeight = ( loadArea.height() >= rowsInClpbrd &&
06013 util_isColumnSelected(loadArea) == FALSE &&
06014 e.namedItem( "columns" ).toElement().isNull() )
06015 ? loadArea.height() : rowsInClpbrd;
06016 QRect rect;
06017 if ( !e.namedItem( "columns" ).toElement().isNull() )
06018 {
06019 if ( !doc()->undoLocked() )
06020 {
06021 KSpreadUndoCellPaste *undo = new KSpreadUndoCellPaste( doc(), this, pasteWidth, 0, _xshift,_yshift,rect,insert );
06022 doc()->addCommand( undo );
06023 }
06024 if(insert)
06025 insertColumn( _xshift+1,pasteWidth-1,false);
06026 return;
06027 }
06028
06029 if ( !e.namedItem( "rows" ).toElement().isNull() )
06030 {
06031 if ( !doc()->undoLocked() )
06032 {
06033 KSpreadUndoCellPaste *undo = new KSpreadUndoCellPaste( doc(), this, 0,pasteHeight, _xshift,_yshift,rect,insert );
06034 doc()->addCommand( undo );
06035 }
06036 if(insert)
06037 insertRow( _yshift+1,pasteHeight-1,false);
06038 return;
06039 }
06040
06041 rect.setRect( _xshift+1, _yshift+1, pasteWidth, pasteHeight );
06042
06043 if(!c.isNull())
06044 {
06045 if ( !doc()->undoLocked() )
06046 {
06047 KSpreadUndoCellPaste *undo = new KSpreadUndoCellPaste( doc(), this, 0,0,_xshift,_yshift,rect,insert,insertTo );
06048 doc()->addCommand( undo );
06049 }
06050 if(insert)
06051 {
06052 if(insertTo==-1)
06053 shiftRow(rect,false);
06054 else if(insertTo==1)
06055 shiftColumn(rect,false);
06056 }
06057 }
06058 }
06059
06060 bool KSpreadSheet::testAreaPasteInsert()const
06061 {
06062 QMimeSource* mime = QApplication::clipboard()->data();
06063 if ( !mime )
06064 return false;
06065
06066 QByteArray b;
06067
06068 if ( mime->provides( "application/x-kspread-snippet" ) )
06069 b = mime->encodedData( "application/x-kspread-snippet" );
06070 else
06071 return false;
06072
06073 QBuffer buffer( b );
06074 buffer.open( IO_ReadOnly );
06075 QDomDocument d;
06076 d.setContent( &buffer );
06077 buffer.close();
06078
06079 QDomElement e = d.documentElement();
06080 if ( !e.namedItem( "columns" ).toElement().isNull() )
06081 return false;
06082
06083 if ( !e.namedItem( "rows" ).toElement().isNull() )
06084 return false;
06085
06086 QDomElement c = e.firstChild().toElement();
06087 for( ; !c.isNull(); c = c.nextSibling().toElement() )
06088 {
06089 if ( c.tagName() == "cell" )
06090 return true;
06091 }
06092 return false;
06093 }
06094
06095 void KSpreadSheet::deleteCells( const QRect& rect )
06096 {
06097
06098 QPtrStack<KSpreadCell> cellStack;
06099
06100 QRect tmpRect;
06101 bool extraCell = false;
06102 if (rect.width() == 1 && rect.height() == 1 )
06103 {
06104 KSpreadCell * cell = nonDefaultCell( rect.x(), rect.y() );
06105 if (cell->isForceExtraCells())
06106 {
06107 extraCell = true;
06108 tmpRect = rect;
06109 }
06110 }
06111
06112 int right = rect.right();
06113 int left = rect.left();
06114 int bottom = rect.bottom();
06115 int col;
06116 for ( int row = rect.top(); row <= bottom; ++row )
06117 {
06118 KSpreadCell * c = getFirstCellRow( row );
06119 while ( c )
06120 {
06121 col = c->column();
06122 if ( col < left )
06123 {
06124 c = getNextCellRight( left - 1, row );
06125 continue;
06126 }
06127 if ( col > right )
06128 break;
06129
06130 if ( !c->isDefault() )
06131 cellStack.push( c );
06132
06133 c = getNextCellRight( col, row );
06134 }
06135 }
06136
06137 d->cells.setAutoDelete( false );
06138
06139
06140 while ( !cellStack.isEmpty() )
06141 {
06142 KSpreadCell * cell = cellStack.pop();
06143
06144 d->cells.remove( cell->column(), cell->row() );
06145 cell->setCalcDirtyFlag();
06146 setRegionPaintDirty(cell->cellRect());
06147
06148 delete cell;
06149 }
06150
06151 d->cells.setAutoDelete( true );
06152
06153 setLayoutDirtyFlag();
06154
06155
06156
06157
06158 KSpreadCell * c = d->cells.firstCell();
06159 for( ;c; c = c->nextCell() )
06160 {
06161 if ( c->isForceExtraCells() && !c->isDefault() )
06162 c->forceExtraCells( c->column(), c->row(),
06163 c->extraXCells(), c->extraYCells() );
06164 }
06165 doc()->setModified( true );
06166 }
06167
06168 void KSpreadSheet::deleteSelection( KSpreadSelection* selectionInfo, bool undo )
06169 {
06170 QRect r( selectionInfo->selection() );
06171
06172 if ( undo && !doc()->undoLocked() )
06173 {
06174 KSpreadUndoDelete *undo = new KSpreadUndoDelete( doc(), this, r );
06175 doc()->addCommand( undo );
06176 }
06177
06178
06179 if ( util_isRowSelected(r) )
06180 {
06181 for( int i = r.top(); i <= r.bottom(); ++i )
06182 {
06183 d->cells.clearRow( i );
06184 d->rows.removeElement( i );
06185 }
06186
06187 emit sig_updateVBorder( this );
06188 }
06189
06190 else if ( util_isColumnSelected(r) )
06191 {
06192 for( int i = r.left(); i <= r.right(); ++i )
06193 {
06194 d->cells.clearColumn( i );
06195 d->columns.removeElement( i );
06196 }
06197
06198 emit sig_updateHBorder( this );
06199 }
06200 else
06201 {
06202
06203 deleteCells( r );
06204 }
06205 refreshMergedCell();
06206 emit sig_updateView( this );
06207 }
06208
06209 void KSpreadSheet::updateView()
06210 {
06211 emit sig_updateView( this );
06212 }
06213
06214 void KSpreadSheet::updateView( QRect const & rect )
06215 {
06216 emit sig_updateView( this, rect );
06217 }
06218
06219 void KSpreadSheet::refreshView( const QRect & rect )
06220 {
06221
06222 QRect tmp(rect);
06223 KSpreadCell * c = d->cells.firstCell();
06224 for( ;c; c = c->nextCell() )
06225 {
06226 if ( !c->isDefault() && c->row() >= rect.top() &&
06227 c->row() <= rect.bottom() && c->column() >= rect.left() &&
06228 c->column() <= rect.right() )
06229 if(c->isForceExtraCells())
06230 {
06231 int right=QMAX(tmp.right(),c->column()+c->extraXCells());
06232 int bottom=QMAX(tmp.bottom(),c->row()+c->extraYCells());
06233
06234 tmp.setRight(right);
06235 tmp.setBottom(bottom);
06236 }
06237 }
06238 deleteCells( rect );
06239 emit sig_updateView( this, tmp );
06240 }
06241
06242
06243 void KSpreadSheet::changeMergedCell( int m_iCol, int m_iRow, int m_iExtraX, int m_iExtraY)
06244 {
06245 if( m_iExtraX==0 && m_iExtraY==0)
06246 {
06247 dissociateCell( QPoint( m_iCol,m_iRow));
06248 return;
06249 }
06250
06251 QRect rect;
06252 rect.setCoords(m_iCol,m_iRow,m_iCol+m_iExtraX,m_iRow+m_iExtraY);
06253
06254 mergeCells(rect);
06255 }
06256
06257 void KSpreadSheet::mergeCells( const QRect &area )
06258 {
06259
06260 if( isProtected() )
06261 return;
06262 if( workbook()->isProtected() )
06263 return;
06264
06265
06266 if( area.width() == 1 && area.height() == 1)
06267 return;
06268
06269 QPoint topLeft = area.topLeft();
06270
06271 KSpreadCell *cell = nonDefaultCell( topLeft );
06272 cell->forceExtraCells( topLeft.x(), topLeft.y(),
06273 area.width() - 1, area.height() - 1);
06274
06275 if ( getAutoCalc() )
06276 recalc();
06277
06278 emit sig_updateView( this, area );
06279 }
06280
06281 void KSpreadSheet::dissociateCell( const QPoint &cellRef )
06282 {
06283 QPoint marker(cellRef);
06284 KSpreadCell *cell = nonDefaultCell( marker );
06285 if(!cell->isForceExtraCells())
06286 return;
06287
06288 int x = cell->extraXCells() + 1;
06289 if( x == 0 )
06290 x = 1;
06291 int y = cell->extraYCells() + 1;
06292 if( y == 0 )
06293 y = 1;
06294
06295 cell->forceExtraCells( marker.x() ,marker.y(), 0, 0 );
06296 QRect selection( marker.x() - 1, marker.y() - 1, x + 2, y + 2 );
06297 refreshMergedCell();
06298 emit sig_updateView( this, selection );
06299 }
06300
06301 bool KSpreadSheet::testListChoose(KSpreadSelection* selectionInfo)
06302 {
06303 QRect selection( selectionInfo->selection() );
06304 QPoint marker( selectionInfo->marker() );
06305
06306 KSpreadCell *cell = cellAt( marker.x(), marker.y() );
06307 QString tmp=cell->text();
06308
06309 KSpreadCell* c = firstCell();
06310 bool different=false;
06311 int col;
06312 for( ;c; c = c->nextCell() )
06313 {
06314 col = c->column();
06315 if ( selection.left() <= col && selection.right() >= col &&
06316 !c->isObscuringForced() &&
06317 !(col==marker.x() && c->row()==marker.y()))
06318 {
06319 if(!c->isFormula() && !c->value().isNumber() && !c->value().asString().isEmpty()
06320 && !c->isTime() &&!c->isDate() )
06321 {
06322 if(c->text()!=tmp)
06323 different=true;
06324 }
06325
06326 }
06327 }
06328 return different;
06329 }
06330
06331
06332
06333
06334 QDomDocument KSpreadSheet::saveCellRect( const QRect &_rect, bool copy, bool era )
06335 {
06336 QDomDocument dd( "spreadsheet-snippet" );
06337 dd.appendChild( dd.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );
06338 QDomElement spread = dd.createElement( "spreadsheet-snippet" );
06339 spread.setAttribute( "rows", _rect.bottom() - _rect.top() + 1 );
06340 spread.setAttribute( "columns", _rect.right() - _rect.left() + 1 );
06341 dd.appendChild( spread );
06342
06343
06344
06345
06346 if ( util_isRowSelected( _rect ) )
06347 {
06348 QDomElement rows = dd.createElement("rows");
06349 rows.setAttribute( "count", _rect.bottom() - _rect.top() + 1 );
06350 spread.appendChild( rows );
06351
06352
06353 KSpreadCell* c = d->cells.firstCell();
06354 for( ;c; c = c->nextCell() )
06355 {
06356 if ( !c->isDefault()&&!c->isObscuringForced() )
06357 {
06358 QPoint p( c->column(), c->row() );
06359 if ( _rect.contains( p ) )
06360 spread.appendChild( c->save( dd, 0, _rect.top() - 1, copy, copy, era ) );
06361 }
06362 }
06363
06364
06365
06366 RowFormat* lay;
06367 for( int y = _rect.top(); y <= _rect.bottom(); ++y )
06368 {
06369 lay = rowFormat( y );
06370 if ( lay && !lay->isDefault() )
06371 {
06372 QDomElement e = lay->save( dd, _rect.top() - 1, copy );
06373 if ( !e.isNull() )
06374 spread.appendChild( e );
06375 }
06376 }
06377
06378 return dd;
06379 }
06380
06381
06382
06383
06384 if ( util_isColumnSelected( _rect ) )
06385 {
06386 QDomElement columns = dd.createElement("columns");
06387 columns.setAttribute( "count", _rect.right() - _rect.left() + 1 );
06388 spread.appendChild( columns );
06389
06390
06391 KSpreadCell* c = d->cells.firstCell();
06392 for( ;c; c = c->nextCell() )
06393 {
06394 if ( !c->isDefault()&&!c->isObscuringForced())
06395 {
06396 QPoint p( c->column(), c->row() );
06397 if ( _rect.contains( p ) )
06398 spread.appendChild( c->save( dd, _rect.left() - 1, 0, copy, copy, era ) );
06399 }
06400 }
06401
06402
06403
06404 ColumnFormat* lay;
06405 for( int x = _rect.left(); x <= _rect.right(); ++x )
06406 {
06407 lay = columnFormat( x );
06408 if ( lay && !lay->isDefault() )
06409 {
06410 QDomElement e = lay->save( dd, _rect.left() - 1, copy );
06411 if ( !e.isNull() )
06412 spread.appendChild( e );
06413 }
06414 }
06415
06416 return dd;
06417 }
06418
06419
06420
06421
06422
06423
06424 KSpreadCell *cell;
06425 bool insert;
06426 for (int i=_rect.left();i<=_rect.right();i++)
06427 for(int j=_rect.top();j<=_rect.bottom();j++)
06428 {
06429 insert = false;
06430 cell = cellAt( i, j );
06431 if ( cell == d->defaultCell )
06432 {
06433 cell = new KSpreadCell( this, i, j );
06434 insertCell( cell );
06435 insert=true;
06436 }
06437 spread.appendChild( cell->save( dd, _rect.left() - 1, _rect.top() - 1, true, copy, era ) );
06438 if( insert )
06439 d->cells.remove(i,j);
06440 }
06441
06442 return dd;
06443 }
06444
06445 QDomElement KSpreadSheet::saveXML( QDomDocument& dd )
06446 {
06447 QDomElement sheet = dd.createElement( "table" );
06448 sheet.setAttribute( "name", d->name );
06449
06450
06451
06452 sheet.setAttribute( "layoutDirection", (d->layoutDirection == RightToLeft) ? "rtl" : "ltr" );
06453 sheet.setAttribute( "columnnumber", (int)d->showColumnNumber);
06454 sheet.setAttribute( "borders", (int)d->showPageBorders);
06455 sheet.setAttribute( "hide", (int)d->hide);
06456 sheet.setAttribute( "hidezero", (int)d->hideZero);
06457 sheet.setAttribute( "firstletterupper", (int)d->firstLetterUpper);
06458 sheet.setAttribute( "grid", (int)d->showGrid );
06459 sheet.setAttribute( "printGrid", (int)d->print->printGrid() );
06460 sheet.setAttribute( "printCommentIndicator", (int)d->print->printCommentIndicator() );
06461 sheet.setAttribute( "printFormulaIndicator", (int)d->print->printFormulaIndicator() );
06462 if ( doc()->specialOutputFlag() == KoDocument::SaveAsKOffice1dot1 )
06463 sheet.setAttribute( "formular", (int)d->showFormula);
06464 else
06465 sheet.setAttribute( "showFormula", (int)d->showFormula);
06466 sheet.setAttribute( "showFormulaIndicator", (int)d->showFormulaIndicator);
06467 sheet.setAttribute( "lcmode", (int)d->lcMode);
06468 sheet.setAttribute( "autoCalc", (int)d->autoCalc);
06469 sheet.setAttribute( "borders1.2", 1);
06470 if ( !d->password.isNull() )
06471 {
06472 if ( d->password.size() > 0 )
06473 {
06474 QCString str = KCodecs::base64Encode( d->password );
06475 sheet.setAttribute( "protected", QString( str.data() ) );
06476 }
06477 else
06478 sheet.setAttribute( "protected", "" );
06479 }
06480
06481
06482 QDomElement paper = dd.createElement( "paper" );
06483 paper.setAttribute( "format", d->print->paperFormatString() );
06484 paper.setAttribute( "orientation", d->print->orientationString() );
06485 sheet.appendChild( paper );
06486
06487 QDomElement borders = dd.createElement( "borders" );
06488 borders.setAttribute( "left", d->print->leftBorder() );
06489 borders.setAttribute( "top", d->print->topBorder() );
06490 borders.setAttribute( "right", d->print->rightBorder() );
06491 borders.setAttribute( "bottom", d->print->bottomBorder() );
06492 paper.appendChild( borders );
06493
06494 QDomElement head = dd.createElement( "head" );
06495 paper.appendChild( head );
06496 if ( !d->print->headLeft().isEmpty() )
06497 {
06498 QDomElement left = dd.createElement( "left" );
06499 head.appendChild( left );
06500 left.appendChild( dd.createTextNode( d->print->headLeft() ) );
06501 }
06502 if ( !d->print->headMid().isEmpty() )
06503 {
06504 QDomElement center = dd.createElement( "center" );
06505 head.appendChild( center );
06506 center.appendChild( dd.createTextNode( d->print->headMid() ) );
06507 }
06508 if ( !d->print->headRight().isEmpty() )
06509 {
06510 QDomElement right = dd.createElement( "right" );
06511 head.appendChild( right );
06512 right.appendChild( dd.createTextNode( d->print->headRight() ) );
06513 }
06514 QDomElement foot = dd.createElement( "foot" );
06515 paper.appendChild( foot );
06516 if ( !d->print->footLeft().isEmpty() )
06517 {
06518 QDomElement left = dd.createElement( "left" );
06519 foot.appendChild( left );
06520 left.appendChild( dd.createTextNode( d->print->footLeft() ) );
06521 }
06522 if ( !d->print->footMid().isEmpty() )
06523 {
06524 QDomElement center = dd.createElement( "center" );
06525 foot.appendChild( center );
06526 center.appendChild( dd.createTextNode( d->print->footMid() ) );
06527 }
06528 if ( !d->print->footRight().isEmpty() )
06529 {
06530 QDomElement right = dd.createElement( "right" );
06531 foot.appendChild( right );
06532 right.appendChild( dd.createTextNode( d->print->footRight() ) );
06533 }
06534
06535
06536 QDomElement printrange = dd.createElement( "printrange-rect" );
06537 QRect _printRange = d->print->printRange();
06538 int left = _printRange.left();
06539 int right = _printRange.right();
06540 int top = _printRange.top();
06541 int bottom = _printRange.bottom();
06542
06543 if ( left == 1 && right == KS_colMax )
06544 {
06545 left = 0;
06546 right = 0;
06547 }
06548
06549 if ( top == 1 && bottom == KS_rowMax )
06550 {
06551 top = 0;
06552 bottom = 0;
06553 }
06554 printrange.setAttribute( "left-rect", left );
06555 printrange.setAttribute( "right-rect", right );
06556 printrange.setAttribute( "bottom-rect", bottom );
06557 printrange.setAttribute( "top-rect", top );
06558 sheet.appendChild( printrange );
06559
06560
06561 QDomElement printRepeatColumns = dd.createElement( "printrepeatcolumns" );
06562 printRepeatColumns.setAttribute( "left", d->print->printRepeatColumns().first );
06563 printRepeatColumns.setAttribute( "right", d->print->printRepeatColumns().second );
06564 sheet.appendChild( printRepeatColumns );
06565
06566
06567 QDomElement printRepeatRows = dd.createElement( "printrepeatrows" );
06568 printRepeatRows.setAttribute( "top", d->print->printRepeatRows().first );
06569 printRepeatRows.setAttribute( "bottom", d->print->printRepeatRows().second );
06570 sheet.appendChild( printRepeatRows );
06571
06572
06573 sheet.setAttribute( "printZoom", d->print->zoom() );
06574
06575
06576 sheet.setAttribute( "printPageLimitX", d->print->pageLimitX() );
06577 sheet.setAttribute( "printPageLimitY", d->print->pageLimitY() );
06578
06579
06580 KSpreadCell* c = d->cells.firstCell();
06581 for( ;c; c = c->nextCell() )
06582 {
06583 if ( !c->isDefault() )
06584 {
06585 QDomElement e = c->save( dd );
06586 if ( !e.isNull() )
06587 sheet.appendChild( e );
06588 }
06589 }
06590
06591
06592 RowFormat* rl = d->rows.first();
06593 for( ; rl; rl = rl->next() )
06594 {
06595 if ( !rl->isDefault() )
06596 {
06597 QDomElement e = rl->save( dd );
06598 if ( e.isNull() )
06599 return QDomElement();
06600 sheet.appendChild( e );
06601 }
06602 }
06603
06604
06605 ColumnFormat* cl = d->columns.first();
06606 for( ; cl; cl = cl->next() )
06607 {
06608 if ( !cl->isDefault() )
06609 {
06610 QDomElement e = cl->save( dd );
06611 if ( e.isNull() )
06612 return QDomElement();
06613 sheet.appendChild( e );
06614 }
06615 }
06616
06617 QPtrListIterator<KoDocumentChild> chl( doc()->children() );
06618 for( ; chl.current(); ++chl )
06619 {
06620 if ( ((KSpreadChild*)chl.current())->sheet() == this )
06621 {
06622 QDomElement e;
06623 KSpreadChild * child = (KSpreadChild *) chl.current();
06624
06625
06626 if ( child->inherits("ChartChild") )
06627 {
06628 e = ((ChartChild *) child)->save( dd );
06629 }
06630 else
06631 e = chl.current()->save( dd );
06632
06633 if ( e.isNull() )
06634 return QDomElement();
06635 sheet.appendChild( e );
06636 }
06637 }
06638
06639 return sheet;
06640 }
06641
06642 bool KSpreadSheet::isLoading()
06643 {
06644 return doc()->isLoading();
06645 }
06646
06647 void KSpreadSheet::checkContentDirection( QString const & name )
06648 {
06649
06650 if ( (name.isRightToLeft()) )
06651 setLayoutDirection( RightToLeft );
06652 else
06653 setLayoutDirection( LeftToRight );
06654
06655 emit sig_refreshView();
06656 }
06657
06658 bool KSpreadSheet::loadSheetStyleFormat( QDomElement *style )
06659 {
06660 QString hleft, hmiddle, hright;
06661 QString fleft, fmiddle, fright;
06662 QDomNode header = KoDom::namedItemNS( *style, KoXmlNS::style, "header" );
06663
06664 if ( !header.isNull() )
06665 {
06666 kdDebug() << "Header exists" << endl;
06667 QDomNode part = KoDom::namedItemNS( header, KoXmlNS::style, "region-left" );
06668 if ( !part.isNull() )
06669 {
06670 hleft = getPart( part );
06671 kdDebug() << "Header left: " << hleft << endl;
06672 }
06673 else
06674 kdDebug() << "Style:region:left doesn't exist!" << endl;
06675 part = KoDom::namedItemNS( header, KoXmlNS::style, "region-center" );
06676 if ( !part.isNull() )
06677 {
06678 hmiddle = getPart( part );
06679 kdDebug() << "Header middle: " << hmiddle << endl;
06680 }
06681 part = KoDom::namedItemNS( header, KoXmlNS::style, "region-right" );
06682 if ( !part.isNull() )
06683 {
06684 hright = getPart( part );
06685 kdDebug() << "Header right: " << hright << endl;
06686 }
06687 }
06688
06689 QDomNode headerleft = KoDom::namedItemNS( *style, KoXmlNS::style, "header-left" );
06690 if ( !headerleft.isNull() )
06691 {
06692 QDomElement e = headerleft.toElement();
06693 if ( e.hasAttributeNS( KoXmlNS::style, "display" ) )
06694 kdDebug()<<"header.hasAttribute( style:display ) :"<<e.hasAttributeNS( KoXmlNS::style, "display" )<<endl;
06695 else
06696 kdDebug()<<"header left doesn't has attribute style:display \n";
06697 }
06698
06699 QDomNode footerleft = KoDom::namedItemNS( *style, KoXmlNS::style, "footer-left" );
06700 if ( !footerleft.isNull() )
06701 {
06702 QDomElement e = footerleft.toElement();
06703 if ( e.hasAttributeNS( KoXmlNS::style, "display" ) )
06704 kdDebug()<<"footer.hasAttribute( style:display ) :"<<e.hasAttributeNS( KoXmlNS::style, "display" )<<endl;
06705 else
06706 kdDebug()<<"footer left doesn't has attribute style:display \n";
06707 }
06708
06709 QDomNode footer = KoDom::namedItemNS( *style, KoXmlNS::style, "footer" );
06710
06711 if ( !footer.isNull() )
06712 {
06713 QDomNode part = KoDom::namedItemNS( footer, KoXmlNS::style, "region-left" );
06714 if ( !part.isNull() )
06715 {
06716 fleft = getPart( part );
06717 kdDebug() << "Footer left: " << fleft << endl;
06718 }
06719 part = KoDom::namedItemNS( footer, KoXmlNS::style, "region-center" );
06720 if ( !part.isNull() )
06721 {
06722 fmiddle = getPart( part );
06723 kdDebug() << "Footer middle: " << fmiddle << endl;
06724 }
06725 part = KoDom::namedItemNS( footer, KoXmlNS::style, "region-right" );
06726 if ( !part.isNull() )
06727 {
06728 fright = getPart( part );
06729 kdDebug() << "Footer right: " << fright << endl;
06730 }
06731 }
06732
06733 print()->setHeadFootLine( hleft, hmiddle, hright,
06734 fleft, fmiddle, fright );
06735 return true;
06736 }
06737
06738 void KSpreadSheet::replaceMacro( QString & text, const QString & old, const QString & newS )
06739 {
06740 int n = text.find( old );
06741 if ( n != -1 )
06742 text = text.replace( n, old.length(), newS );
06743 }
06744
06745
06746 QString KSpreadSheet::getPart( const QDomNode & part )
06747 {
06748 QString result;
06749 QDomElement e = KoDom::namedItemNS( part, KoXmlNS::text, "p" );
06750 while ( !e.isNull() )
06751 {
06752 QString text = e.text();
06753 kdDebug() << "PART: " << text << endl;
06754
06755 QDomElement macro = KoDom::namedItemNS( e, KoXmlNS::text, "time" );
06756 if ( !macro.isNull() )
06757 replaceMacro( text, macro.text(), "<time>" );
06758
06759 macro = KoDom::namedItemNS( e, KoXmlNS::text, "date" );
06760 if ( !macro.isNull() )
06761 replaceMacro( text, macro.text(), "<date>" );
06762
06763 macro = KoDom::namedItemNS( e, KoXmlNS::text, "page-number" );
06764 if ( !macro.isNull() )
06765 replaceMacro( text, macro.text(), "<page>" );
06766
06767 macro = KoDom::namedItemNS( e, KoXmlNS::text, "page-count" );
06768 if ( !macro.isNull() )
06769 replaceMacro( text, macro.text(), "<pages>" );
06770
06771 macro = KoDom::namedItemNS( e, KoXmlNS::text, "sheet-name" );
06772 if ( !macro.isNull() )
06773 replaceMacro( text, macro.text(), "<sheet>" );
06774
06775 macro = KoDom::namedItemNS( e, KoXmlNS::text, "title" );
06776 if ( !macro.isNull() )
06777 replaceMacro( text, macro.text(), "<name>" );
06778
06779 macro = KoDom::namedItemNS( e, KoXmlNS::text, "file-name" );
06780 if ( !macro.isNull() )
06781 replaceMacro( text, macro.text(), "<file>" );
06782
06783
06784 if ( !result.isEmpty() )
06785 result += '\n';
06786 result += text;
06787 e = e.nextSibling().toElement();
06788 }
06789
06790 return result;
06791 }
06792
06793
06794 bool KSpreadSheet::loadOasis( const QDomElement& sheetElement, const KoOasisStyles& oasisStyles )
06795 {
06796 d->layoutDirection = LeftToRight;
06797 if ( sheetElement.hasAttributeNS( KoXmlNS::table, "style-name" ) )
06798 {
06799 QString stylename = sheetElement.attributeNS( KoXmlNS::table, "style-name", QString::null );
06800 kdDebug()<<" style of table :"<<stylename<<endl;
06801 QDomElement *style = oasisStyles.styles()[stylename];
06802 Q_ASSERT( style );
06803 kdDebug()<<" style :"<<style<<endl;
06804 if ( style )
06805 {
06806 QDomElement properties( KoDom::namedItemNS( *style, KoXmlNS::style, "table-properties" ) );
06807 if ( !properties.isNull() )
06808 {
06809 if ( properties.hasAttributeNS( KoXmlNS::table, "display" ) )
06810 {
06811 bool visible = (properties.attributeNS( KoXmlNS::table, "display", QString::null ) == "true" ? true : false );
06812 d->hide = !visible;
06813 }
06814 }
06815 if ( style->hasAttributeNS( KoXmlNS::style, "master-page-name" ) )
06816 {
06817 QString masterPageStyleName = style->attributeNS( KoXmlNS::style, "master-page-name", QString::null );
06818 kdDebug()<<"style->attribute( style:master-page-name ) :"<<masterPageStyleName <<endl;
06819 QDomElement *masterStyle = oasisStyles.masterPages()[masterPageStyleName];
06820 kdDebug()<<"oasisStyles.styles()[masterPageStyleName] :"<<masterStyle<<endl;
06821 if ( masterStyle )
06822 {
06823 loadSheetStyleFormat( masterStyle );
06824 if ( masterStyle->hasAttributeNS( KoXmlNS::style, "page-layout-name" ) )
06825 {
06826 QString masterPageLayoutStyleName=masterStyle->attributeNS( KoXmlNS::style, "page-layout-name", QString::null );
06827 kdDebug()<<"masterPageLayoutStyleName :"<<masterPageLayoutStyleName<<endl;
06828 QDomElement *masterLayoutStyle = oasisStyles.styles()[masterPageLayoutStyleName];
06829 kdDebug()<<"masterLayoutStyle :"<<masterLayoutStyle<<endl;
06830 KoStyleStack styleStack;
06831 styleStack.setTypeProperties( "page-layout" );
06832 styleStack.push( *masterLayoutStyle );
06833 loadOasisMasterLayoutPage( styleStack );
06834 }
06835 }
06836 }
06837 }
06838 }
06839
06840 int rowIndex = 1;
06841 int indexCol = 1;
06842 QDomNode rowNode = sheetElement.firstChild();
06843 while( !rowNode.isNull() )
06844 {
06845 kdDebug()<<" rowIndex :"<<rowIndex<<" indexCol :"<<indexCol<<endl;
06846 QDomElement rowElement = rowNode.toElement();
06847 if( !rowElement.isNull() )
06848 {
06849 kdDebug()<<" KSpreadSheet::loadOasis rowElement.tagName() :"<<rowElement.localName()<<endl;
06850 if ( rowElement.namespaceURI() == KoXmlNS::table )
06851 {
06852 if ( rowElement.localName()=="table-column" )
06853 {
06854 kdDebug ()<<" table-column found : index column before "<< indexCol<<endl;
06855 loadColumnFormat( rowElement, oasisStyles, indexCol );
06856 kdDebug ()<<" table-column found : index column after "<< indexCol<<endl;
06857 }
06858 else if( rowElement.localName() == "table-row" )
06859 {
06860 kdDebug()<<" table-row found :index row before "<<rowIndex<<endl;
06861 loadRowFormat( rowElement, rowIndex, oasisStyles, rowNode.isNull() );
06862 kdDebug()<<" table-row found :index row after "<<rowIndex<<endl;
06863 }
06864 }
06865 }
06866 rowNode = rowNode.nextSibling();
06867 }
06868
06869 if ( sheetElement.hasAttributeNS( KoXmlNS::table, "print-ranges" ) )
06870 {
06871
06872 QString range = sheetElement.attributeNS( KoXmlNS::table, "print-ranges", QString::null );
06873 KSpreadRange p( translateOpenCalcPoint( range ) );
06874 if ( sheetName() == p.sheetName )
06875 d->print->setPrintRange( p.range );
06876 }
06877
06878
06879 if ( sheetElement.hasAttributeNS( KoXmlNS::table, "protected" ) )
06880 {
06881 QCString passwd( "" );
06882 if ( sheetElement.hasAttributeNS( KoXmlNS::table, "protection-key" ) )
06883 {
06884 QString p = sheetElement.attributeNS( KoXmlNS::table, "protection-key", QString::null );
06885 QCString str( p.latin1() );
06886 kdDebug(30518) << "Decoding password: " << str << endl;
06887 passwd = KCodecs::base64Decode( str );
06888 }
06889 kdDebug(30518) << "Password hash: '" << passwd << "'" << endl;
06890 d->password = passwd;
06891 }
06892 return true;
06893 }
06894
06895
06896 void KSpreadSheet::loadOasisMasterLayoutPage( KoStyleStack &styleStack )
06897 {
06898 float left = 0.0;
06899 float right = 0.0;
06900 float top = 0.0;
06901 float bottom = 0.0;
06902 float width = 0.0;
06903 float height = 0.0;
06904 QString orientation = "Portrait";
06905 QString format;
06906
06907
06908
06909
06910 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "page-width" ) )
06911 {
06912 width = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "page-width" ) ) );
06913 }
06914 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "page-height" ) )
06915 {
06916 height = KoUnit::toMM( KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "page-height" ) ) );
06917 }
06918 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "margin-top" ) )
06919 {
06920 top = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "margin-top" ) ) );
06921 }
06922 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "margin-bottom" ) )
06923 {
06924 bottom = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "margin-bottom" ) ) );
06925 }
06926 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "margin-left" ) )
06927 {
06928 left = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "margin-left" ) ) );
06929 }
06930 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "margin-right" ) )
06931 {
06932 right = KoUnit::toMM(KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::fo, "margin-right" ) ) );
06933 }
06934 if ( styleStack.hasAttributeNS( KoXmlNS::style, "writing-mode" ) )
06935 {
06936 kdDebug()<<"styleStack.hasAttribute( style:writing-mode ) :"<<styleStack.hasAttributeNS( KoXmlNS::style, "writing-mode" )<<endl;
06937 d->layoutDirection = ( styleStack.attributeNS( KoXmlNS::style, "writing-mode" )=="lr-tb" ) ? LeftToRight : RightToLeft;
06938
06939
06940
06941
06942
06943
06944
06945
06946
06947
06948 }
06949 if ( styleStack.hasAttributeNS( KoXmlNS::style, "print-orientation" ) )
06950 {
06951 orientation = ( styleStack.attributeNS( KoXmlNS::style, "print-orientation" )=="landscape" ) ? "Landscape" : "Portrait" ;
06952 }
06953 if ( styleStack.hasAttributeNS( KoXmlNS::style, "num-format" ) )
06954 {
06955
06956
06957
06958
06959 kdDebug()<<" num-format :"<<styleStack.attributeNS( KoXmlNS::style, "num-format" )<<endl;
06960
06961 }
06962 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "background-color" ) )
06963 {
06964
06965 kdDebug()<<" fo:background-color :"<<styleStack.attributeNS( KoXmlNS::fo, "background-color" )<<endl;
06966 }
06967 if ( styleStack.hasAttributeNS( KoXmlNS::style, "print" ) )
06968 {
06969
06970 QString str = styleStack.attributeNS( KoXmlNS::style, "print" );
06971 kdDebug()<<" style:print :"<<str<<endl;
06972
06973 if (str.contains( "headers" ) )
06974 {
06975
06976 }
06977 if ( str.contains( "grid" ) )
06978 {
06979 d->print->setPrintGrid( true );
06980 }
06981 if ( str.contains( "annotations" ) )
06982 {
06983
06984 }
06985 if ( str.contains( "objects" ) )
06986 {
06987
06988 }
06989 if ( str.contains( "charts" ) )
06990 {
06991
06992 }
06993 if ( str.contains( "drawings" ) )
06994 {
06995
06996 }
06997 if ( str.contains( "formulas" ) )
06998 {
06999 d->showFormula = true;
07000 }
07001 if ( str.contains( "zero-values" ) )
07002 {
07003
07004 }
07005 }
07006 if ( styleStack.hasAttributeNS( KoXmlNS::style, "table-centering" ) )
07007 {
07008 QString str = styleStack.attributeNS( KoXmlNS::style, "table-centering" );
07009
07010 kdDebug()<<" styleStack.attribute( style:table-centering ) :"<<str<<endl;
07011 #if 0
07012 if ( str == "horizontal" )
07013 {
07014 }
07015 else if ( str == "vertical" )
07016 {
07017 }
07018 else if ( str == "both" )
07019 {
07020 }
07021 else if ( str == "none" )
07022 {
07023 }
07024 else
07025 kdDebug()<<" table-centering unknown :"<<str<<endl;
07026 #endif
07027 }
07028 format = QString( "%1x%2" ).arg( width ).arg( height );
07029 kdDebug()<<" format : "<<format<<endl;
07030 d->print->setPaperLayout( left, top, right, bottom, format, orientation );
07031
07032 kdDebug()<<" left margin :"<<left<<" right :"<<right<<" top :"<<top<<" bottom :"<<bottom<<endl;
07033
07034
07035
07036
07037
07038 }
07039
07040
07041 bool KSpreadSheet::loadColumnFormat(const QDomElement& column, const KoOasisStyles& oasisStyles, int & indexCol )
07042 {
07043 kdDebug()<<"bool KSpreadSheet::loadColumnFormat(const QDomElement& column, const KoOasisStyles& oasisStyles, unsigned int & indexCol ) index Col :"<<indexCol<<endl;
07044
07045 bool collapsed = ( column.attributeNS( KoXmlNS::table, "visibility", QString::null ) == "collapse" );
07046 KSpreadFormat layout( this , doc()->styleManager()->defaultStyle() );
07047 int number = 1;
07048 double width = 10;
07049 if ( column.hasAttributeNS( KoXmlNS::table, "number-columns-repeated" ) )
07050 {
07051 bool ok = true;
07052 number = column.attributeNS( KoXmlNS::table, "number-columns-repeated", QString::null ).toInt( &ok );
07053 if ( !ok )
07054 number = 1;
07055 kdDebug() << "Repeated: " << number << endl;
07056 }
07057
07058 KoStyleStack styleStack;
07059 styleStack.setTypeProperties("table-column");
07060 if ( column.hasAttributeNS( KoXmlNS::table, "default-cell-style-name" ) )
07061 {
07062
07063 QString str = column.attributeNS( KoXmlNS::table, "default-cell-style-name", QString::null );
07064 kdDebug()<<" default-cell-style-name :"<<str<<endl;
07065 QDomElement *style = oasisStyles.styles()[str];
07066 kdDebug()<<"default column style :"<<style<<endl;
07067 if ( style )
07068 {
07069 styleStack.push( *style );
07070 layout.loadOasisStyleProperties( styleStack, oasisStyles );
07071 styleStack.pop();
07072 }
07073 }
07074
07075 styleStack.setTypeProperties("table-column");
07076 if ( column.hasAttributeNS( KoXmlNS::table, "style-name" ) )
07077 {
07078 QString str = column.attributeNS( KoXmlNS::table, "style-name", QString::null );
07079 QDomElement *style = oasisStyles.styles()[str];
07080 styleStack.push( *style );
07081 kdDebug()<<" style column:"<<style<<"style name : "<<str<<endl;
07082 }
07083
07084 if ( styleStack.hasAttributeNS( KoXmlNS::style, "column-width" ) )
07085 {
07086 width = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::style, "column-width" ) , -1 );
07087 kdDebug()<<" style:column-width : width :"<<width<<endl;
07088 }
07089
07090 bool insertPageBreak = false;
07091 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "break-before" ) )
07092 {
07093 QString str = styleStack.attributeNS( KoXmlNS::fo, "break-before" );
07094 if ( str == "page" )
07095 {
07096 insertPageBreak = true;
07097 }
07098 else
07099 kdDebug()<<" str :"<<str<<endl;
07100 }
07101
07102
07103 if ( number>30 )
07104 number = 30;
07105
07106 for ( int i = 0; i < number; ++i )
07107 {
07108 kdDebug()<<"index col :"<<indexCol<<endl;
07109 ColumnFormat * col = new ColumnFormat( this, indexCol );
07110 col->copy( layout );
07111 col->setWidth( width );
07112
07113
07114
07115
07116 if ( collapsed )
07117 col->setHide( true );
07118
07119 insertColumnFormat( col );
07120 ++indexCol;
07121 }
07122 kdDebug()<<" after index column !!!!!!!!!!!!!!!!!! :"<<indexCol<<endl;
07123 return true;
07124 }
07125
07126
07127 bool KSpreadSheet::loadRowFormat( const QDomElement& row, int &rowIndex,const KoOasisStyles& oasisStyles, bool isLast )
07128 {
07129 kdDebug()<<"KSpreadSheet::loadRowFormat( const QDomElement& row, int &rowIndex,const KoOasisStyles& oasisStyles, bool isLast )***********\n";
07130 double height = -1.0;
07131 KSpreadFormat layout( this , doc()->styleManager()->defaultStyle() );
07132 KoStyleStack styleStack;
07133 styleStack.setTypeProperties( "table-row" );
07134 int backupRow = rowIndex;
07135 if ( row.hasAttributeNS( KoXmlNS::table, "style-name" ) )
07136 {
07137 QString str = row.attributeNS( KoXmlNS::table, "style-name", QString::null );
07138 QDomElement *style = oasisStyles.styles()[str];
07139 styleStack.push( *style );
07140 kdDebug()<<" style column:"<<style<<"style name : "<<str<<endl;
07141 }
07142 layout.loadOasisStyleProperties( styleStack, oasisStyles );
07143 styleStack.setTypeProperties( "table-row" );
07144 if ( styleStack.hasAttributeNS( KoXmlNS::style, "row-height" ) )
07145 {
07146 height = KoUnit::parseValue( styleStack.attributeNS( KoXmlNS::style, "row-height" ) , -1 );
07147 kdDebug()<<" properties style:row-height : height :"<<height<<endl;
07148 }
07149
07150 int number = 1;
07151 if ( row.hasAttributeNS( KoXmlNS::table, "number-rows-repeated" ) )
07152 {
07153 bool ok = true;
07154 int n = row.attributeNS( KoXmlNS::table, "number-rows-repeated", QString::null ).toInt( &ok );
07155 if ( ok )
07156 number = n;
07157 kdDebug() << "Row repeated: " << number << endl;
07158 }
07159 bool collapse = false;
07160 if ( row.hasAttributeNS( KoXmlNS::table, "visibility" ) )
07161 {
07162 QString visible = row.attributeNS( KoXmlNS::table, "visibility", QString::null );
07163 kdDebug()<<" row.attribute( table:visibility ) "<<visible<<endl;
07164 if ( visible == "collapse" )
07165 collapse=true;
07166 else
07167 kdDebug()<<" visible row not implemented/supported : "<<visible<<endl;
07168
07169 }
07170 kdDebug()<<" height !!!!!!!!!!!!!!!!!!!!!!! :"<<height<<endl;
07171
07172 if ( isLast )
07173 {
07174 if ( number > 30 )
07175 number = 30;
07176 }
07177 else
07178 {
07179 if ( number > 256 )
07180 number = 256;
07181 }
07182
07183 bool insertPageBreak = false;
07184 if ( styleStack.hasAttributeNS( KoXmlNS::fo, "break-before" ) )
07185 {
07186 QString str = styleStack.attributeNS( KoXmlNS::fo, "break-before" );
07187 if ( str == "page" )
07188 {
07189 insertPageBreak = true;
07190 }
07191 else
07192 kdDebug()<<" str :"<<str<<endl;
07193 }
07194
07195
07196 for ( int i = 0; i < number; ++i )
07197 {
07198 kdDebug()<<" create non defaultrow format :"<<rowIndex<<endl;
07199 kdDebug()<<" number :"<<number<<endl;
07200 RowFormat * rowL = nonDefaultRowFormat( rowIndex );
07201 rowL->copy( layout );
07202 kdDebug()<<"height :"<<height<<endl;
07203 if ( height != -1 )
07204 {
07205 kdDebug() << "Setting row height to " << height << endl;
07206 rowL->setHeight( height );
07207 if ( collapse )
07208 rowL->setHide( true );
07209 }
07210 ++rowIndex;
07211 }
07212
07213 int columnIndex = 0;
07214 QDomNode cellNode = row.firstChild();
07215 while( !cellNode.isNull() )
07216 {
07217 QDomElement cellElement = cellNode.toElement();
07218 if( !cellElement.isNull() )
07219 {
07220 ++columnIndex;
07221 kdDebug()<<"bool KSpreadSheet::loadRowFormat( const QDomElement& row, int &rowIndex,const KoOasisStyles& oasisStyles, bool isLast ) cellElement.tagName() :"<<cellElement.tagName()<<endl;
07222 if( cellElement.localName() == "table-cell" && cellElement.namespaceURI() == KoXmlNS::table)
07223 {
07224 kdDebug()<<" create cell at row index :"<<backupRow<<endl;
07225 KSpreadCell* cell = nonDefaultCell( columnIndex, backupRow );
07226 cell->loadOasis( cellElement, oasisStyles );
07227 bool haveStyle = cellElement.hasAttributeNS( KoXmlNS::table, "style-name" );
07228 int cols = 1;
07229 if( cellElement.hasAttributeNS( KoXmlNS::table, "number-columns-repeated" ) )
07230 {
07231 bool ok = false;
07232 cols = cellElement.attributeNS( KoXmlNS::table, "number-columns-repeated", QString::null ).toInt( &ok );
07233 if ( !haveStyle && ( cell->isEmpty() && cell->comment( columnIndex, backupRow ).isEmpty() ) )
07234 {
07235
07236 columnIndex +=cols - 1;
07237 }
07238 else
07239 {
07240 if( ok )
07241 {
07242 for( int i = 0; i < cols; i++ )
07243 {
07244 if( i != 0 )
07245 {
07246 ++columnIndex;
07247 KSpreadCell* target = nonDefaultCell( columnIndex, backupRow );
07248 target->copyAll( cell );
07249 }
07250
07251 for ( int newRow = backupRow+1; newRow < backupRow + number;++newRow )
07252 {
07253 KSpreadCell* target = nonDefaultCell( columnIndex, newRow );
07254 target->copyAll( cell );
07255 }
07256 }
07257 }
07258 else
07259 {
07260
07261 for ( int newRow = backupRow+1; newRow < backupRow + number;++newRow )
07262 {
07263 KSpreadCell* target = nonDefaultCell( columnIndex, newRow );
07264 target->copyAll( cell );
07265 }
07266 }
07267 }
07268 }
07269 else
07270 {
07271 if ( haveStyle )
07272 {
07273 for ( int newRow = backupRow+1; newRow < backupRow + number;++newRow )
07274 {
07275 KSpreadCell* target = nonDefaultCell( columnIndex, newRow );
07276 target->copyAll( cell );
07277 }
07278 }
07279 }
07280 }
07281 }
07282 cellNode = cellNode.nextSibling();
07283 }
07284
07285 return true;
07286 }
07287
07288 QString KSpreadSheet::translateOpenCalcPoint( const QString & str )
07289 {
07290 bool inQuote = false;
07291
07292 int l = str.length();
07293 int colonPos = -1;
07294 QString range;
07295 bool isRange = false;
07296
07297 for ( int i = 0; i < l; ++i )
07298 {
07299 if ( str[i] == '$' )
07300 continue;
07301 if ( str[i] == '\'' )
07302 {
07303 inQuote = !inQuote;
07304 }
07305 else if ( str[i] == '.' )
07306 {
07307 if ( !inQuote )
07308 {
07309 if ( i != 0 && i != (colonPos + 1) )
07310 range += '!';
07311 }
07312 else
07313 range += '.';
07314 }
07315 else if ( str[i] == ':' )
07316 {
07317 if ( !inQuote )
07318 {
07319 isRange = true;
07320 colonPos = i;
07321 }
07322 range += ':';
07323 }
07324 else
07325 range += str[i];
07326 }
07327 return range;
07328 }
07329
07330 void KSpreadSheet::maxRowCols( int & maxCols, int & maxRows )
07331 {
07332 const KSpreadCell * cell = firstCell();
07333 while ( cell )
07334 {
07335 if ( cell->column() > maxCols )
07336 maxCols = cell->column();
07337
07338 if ( cell->row() > maxRows )
07339 maxRows = cell->row();
07340
07341 cell = cell->nextCell();
07342 }
07343
07344 const RowFormat * row = firstRow();
07345 while ( row )
07346 {
07347 if ( row->row() > maxRows )
07348 maxRows = row->row();
07349
07350 row = row->next();
07351 }
07352 const ColumnFormat* col = firstCol();
07353 while ( col )
07354 {
07355 if ( col->column() > maxCols )
07356 maxCols = col->column();
07357
07358 col = col->next();
07359 }
07360 }
07361
07362
07363 void KSpreadSheet::saveOasisHeaderFooter( KoXmlWriter &xmlWriter ) const
07364 {
07365 QString headerLeft = print()->headLeft();
07366 QString headerCenter= print()->headMid();
07367 QString headerRight = print()->headRight();
07368
07369 QString footerLeft = print()->footLeft();
07370 QString footerCenter= print()->footMid();
07371 QString footerRight = print()->footRight();
07372
07373 xmlWriter.startElement( "style:header");
07374 if ( ( !headerLeft.isEmpty() )
07375 || ( !headerCenter.isEmpty() )
07376 || ( !headerRight.isEmpty() ) )
07377 {
07378 xmlWriter.startElement( "style:region-left" );
07379 xmlWriter.startElement( "text:p" );
07380 convertPart( headerLeft, xmlWriter );
07381 xmlWriter.endElement();
07382 xmlWriter.endElement();
07383
07384 xmlWriter.startElement( "style:region-center" );
07385 xmlWriter.startElement( "text:p" );
07386 convertPart( headerCenter, xmlWriter );
07387 xmlWriter.endElement();
07388 xmlWriter.endElement();
07389
07390 xmlWriter.startElement( "style:region-right" );
07391 xmlWriter.startElement( "text:p" );
07392 convertPart( headerRight, xmlWriter );
07393 xmlWriter.endElement();
07394 xmlWriter.endElement();
07395 }
07396 else
07397 {
07398 xmlWriter.startElement( "text:p" );
07399
07400 xmlWriter.startElement( "text:sheet-name" );
07401 xmlWriter.addTextNode( "???" );
07402 xmlWriter.endElement();
07403
07404 xmlWriter.endElement();
07405 }
07406 xmlWriter.endElement();
07407
07408
07409 xmlWriter.startElement( "style:footer");
07410 if ( ( !footerLeft.isEmpty() )
07411 || ( !footerCenter.isEmpty() )
07412 || ( !footerRight.isEmpty() ) )
07413 {
07414 xmlWriter.startElement( "style:region-left" );
07415 xmlWriter.startElement( "text:p" );
07416 convertPart( footerLeft, xmlWriter );
07417 xmlWriter.endElement();
07418 xmlWriter.endElement();
07419
07420 xmlWriter.startElement( "style:region-center" );
07421 xmlWriter.startElement( "text:p" );
07422 convertPart( footerCenter, xmlWriter );
07423 xmlWriter.endElement();
07424 xmlWriter.endElement();
07425
07426 xmlWriter.startElement( "style:region-right" );
07427 xmlWriter.startElement( "text:p" );
07428 convertPart( footerRight, xmlWriter );
07429 xmlWriter.endElement();
07430 xmlWriter.endElement();
07431 }
07432 else
07433 {
07434
07435 xmlWriter.startElement( "text:p" );
07436
07437 xmlWriter.startElement( "text:sheet-name" );
07438 xmlWriter.addTextNode( "Page " );
07439
07440 xmlWriter.startElement( "text:page-number" );
07441 xmlWriter.addTextNode( "1" );
07442 xmlWriter.endElement();
07443
07444
07445 xmlWriter.endElement();
07446
07447 xmlWriter.endElement();
07448 }
07449 xmlWriter.endElement();
07450
07451
07452 }
07453
07454 void KSpreadSheet::addText( const QString & text, KoXmlWriter & writer ) const
07455 {
07456 if ( !text.isEmpty() )
07457 writer.addTextNode( text );
07458 }
07459
07460 void KSpreadSheet::convertPart( const QString & part, KoXmlWriter & xmlWriter ) const
07461 {
07462 QString text;
07463 QString var;
07464
07465 bool inVar = false;
07466 uint i = 0;
07467 uint l = part.length();
07468 while ( i < l )
07469 {
07470 if ( inVar || part[i] == '<' )
07471 {
07472 inVar = true;
07473 var += part[i];
07474 if ( part[i] == '>' )
07475 {
07476 inVar = false;
07477 if ( var == "<page>" )
07478 {
07479 addText( text, xmlWriter );
07480 xmlWriter.startElement( "text:page-number" );
07481 xmlWriter.addTextNode( "1" );
07482 xmlWriter.endElement();
07483 }
07484 else if ( var == "<pages>" )
07485 {
07486 addText( text, xmlWriter );
07487 xmlWriter.startElement( "text:page-count" );
07488 xmlWriter.addTextNode( "99" );
07489 xmlWriter.endElement();
07490 }
07491 else if ( var == "<date>" )
07492 {
07493 addText( text, xmlWriter );
07494 #if 0 //FIXME
07495 QDomElement t = dd.createElement( "text:date" );
07496 t.setAttribute( "text:date-value", "0-00-00" );
07497
07498 t.appendChild( dd.createTextNode( QDate::currentDate().toString() ) );
07499 parent.appendChild( t );
07500 #endif
07501 }
07502 else if ( var == "<time>" )
07503 {
07504 addText( text, xmlWriter );
07505
07506 xmlWriter.startElement( "text:time" );
07507 xmlWriter.addTextNode( QTime::currentTime().toString() );
07508 xmlWriter.endElement();
07509 }
07510 else if ( var == "<file>" )
07511 {
07512 addText( text, xmlWriter );
07513 xmlWriter.startElement( "text:file-name" );
07514 xmlWriter.addAttribute( "text:display", "full" );
07515 xmlWriter.addTextNode( "???" );
07516 xmlWriter.endElement();
07517 }
07518 else if ( var == "<name>" )
07519 {
07520 addText( text, xmlWriter );
07521
07522 xmlWriter.startElement( "text:title" );
07523 xmlWriter.addTextNode( "???" );
07524 xmlWriter.endElement();
07525 }
07526 else if ( var == "<author>" )
07527 {
07528 KSpreadDoc* sdoc = d->workbook->doc();
07529 KoDocumentInfo * docInfo = sdoc->documentInfo();
07530 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
07531
07532 text += authorPage->fullName();
07533
07534 addText( text, xmlWriter );
07535 }
07536 else if ( var == "<email>" )
07537 {
07538 KSpreadDoc* sdoc = d->workbook->doc();
07539 KoDocumentInfo * docInfo = sdoc->documentInfo();
07540 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
07541
07542 text += authorPage->email();
07543 addText( text, xmlWriter );
07544
07545 }
07546 else if ( var == "<org>" )
07547 {
07548 KSpreadDoc* sdoc = d->workbook->doc();
07549 KoDocumentInfo * docInfo = sdoc->documentInfo();
07550 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
07551
07552 text += authorPage->company();
07553 addText( text, xmlWriter );
07554
07555 }
07556 else if ( var == "<sheet>" )
07557 {
07558 addText( text, xmlWriter );
07559
07560 xmlWriter.startElement( "text:sheet-name" );
07561 xmlWriter.addTextNode( "???" );
07562 xmlWriter.endElement();
07563 }
07564 else
07565 {
07566
07567 text += var;
07568 addText( text, xmlWriter );
07569 }
07570
07571 text = "";
07572 var = "";
07573 }
07574 }
07575 else
07576 {
07577 text += part[i];
07578 }
07579 ++i;
07580 }
07581 if ( !text.isEmpty() || !var.isEmpty() )
07582 {
07583
07584 addText( text+var, xmlWriter );
07585 }
07586 kdDebug()<<" text end :"<<text<<" var :"<<var<<endl;
07587 }
07588
07589
07590 void KSpreadSheet::loadOasisSettings( const KoOasisSettings::NamedMap &settings )
07591 {
07592
07593 KoOasisSettings::Items items = settings.entry( d->name );
07594 if ( items.isNull() )
07595 return;
07596 d->hideZero = items.parseConfigItemBool( "ShowZeroValues" );
07597 d->showGrid = items.parseConfigItemBool( "ShowGrid" );
07598 d->firstLetterUpper = items.parseConfigItemBool( "FirstLetterUpper" );
07599
07600 int cursorX = items.parseConfigItemInt( "CursorPositionX" );
07601 int cursorY = items.parseConfigItemInt( "CursorPositionY" );
07602
07603 doc()->loadingInfo()->addMarkerSelection( this, QPoint( cursorX, cursorY ) );
07604 kdDebug()<<"d->hideZero :"<<d->hideZero<<" d->showGrid :"<<d->showGrid<<" d->firstLetterUpper :"<<d->firstLetterUpper<<" cursorX :"<<cursorX<<" cursorY :"<<cursorY<< endl;
07605
07606 d->showFormulaIndicator = items.parseConfigItemBool("ShowFormulaIndicator" );
07607 d->showPageBorders = items.parseConfigItemBool( "ShowPageBorders" );
07608 d->lcMode = items.parseConfigItemBool( "lcmode" );
07609 d->autoCalc = items.parseConfigItemBool( "autoCalc" );
07610 d->showColumnNumber = items.parseConfigItemBool( "ShowPageBorders" );
07611 d->firstLetterUpper = items.parseConfigItemBool( "FirstLetterUpper" );
07612 }
07613
07614 void KSpreadSheet::saveOasisSettings( KoXmlWriter &settingsWriter, const QPoint& marker ) const
07615 {
07616
07617 settingsWriter.addConfigItem( "ShowZeroValues", d->hideZero );
07618 settingsWriter.addConfigItem( "ShowGrid", d->showGrid );
07619
07620
07621 settingsWriter.addConfigItem( "FirstLetterUpper", d->firstLetterUpper);
07622
07623
07624
07625 settingsWriter.addConfigItem( "CursorPositionX", marker.x() );
07626 settingsWriter.addConfigItem( "CursorPositionY", marker.y() );
07627
07628 settingsWriter.addConfigItem( "ShowFormulaIndicator", d->showFormulaIndicator );
07629 settingsWriter.addConfigItem( "ShowPageBorders",d->showPageBorders );
07630 settingsWriter.addConfigItem( "lcmode", d->lcMode );
07631 settingsWriter.addConfigItem( "autoCalc", d->autoCalc );
07632 settingsWriter.addConfigItem( "ShowPageNumber", d->showColumnNumber );
07633 settingsWriter.addConfigItem( "FirstLetterUpper", d->firstLetterUpper );
07634 }
07635
07636
07637 bool KSpreadSheet::saveOasis( KoXmlWriter & xmlWriter, KoGenStyles &mainStyles, KSpreadGenValidationStyles &valStyle )
07638 {
07639 int maxCols= 1;
07640 int maxRows= 1;
07641 xmlWriter.startElement( "table:table" );
07642 xmlWriter.addAttribute( "table:name", d->name );
07643 xmlWriter.addAttribute( "table:style-name", saveOasisSheetStyleName(mainStyles ) );
07644 if ( !d->password.isEmpty() )
07645 {
07646 xmlWriter.addAttribute("table:protected", "true" );
07647 QCString str = KCodecs::base64Encode( d->password );
07648 xmlWriter.addAttribute("table:protection-key", QString( str.data() ) );
07649 }
07650 QRect _printRange = d->print->printRange();
07651 if ( _printRange != ( QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) ) ) )
07652 {
07653 QString range= convertRangeToRef( d->name, _printRange );
07654 kdDebug()<<" range : "<<range<<endl;
07655 xmlWriter.addAttribute( "table:print-ranges", range );
07656 }
07657
07658 maxRowCols( maxCols, maxRows );
07659 saveOasisColRowCell( xmlWriter, mainStyles, maxCols, maxRows, valStyle );
07660 xmlWriter.endElement();
07661 return true;
07662 }
07663
07664 void KSpreadSheet::saveOasisPrintStyleLayout( KoGenStyle &style ) const
07665 {
07666 QString printParameter;
07667 if ( d->print->printGrid() )
07668 printParameter="grid ";
07669 if ( d->showFormula )
07670 printParameter="formulas ";
07671 if ( !printParameter.isEmpty() )
07672 style.addProperty( "style:print", printParameter );
07673 }
07674
07675 QString KSpreadSheet::saveOasisSheetStyleName( KoGenStyles &mainStyles )
07676 {
07677 KoGenStyle pageStyle( KSpreadDoc::STYLE_PAGE, "table" );
07678
07679 KoGenStyle pageMaster( KSpreadDoc::STYLE_PAGEMASTER );
07680 pageMaster.addAttribute( "style:page-layout-name", d->print->saveOasisSheetStyleLayout( mainStyles ) );
07681
07682 QBuffer buffer;
07683 buffer.open( IO_WriteOnly );
07684 KoXmlWriter elementWriter( &buffer );
07685 saveOasisHeaderFooter(elementWriter);
07686
07687 QString elementContents = QString::fromUtf8( buffer.buffer(), buffer.buffer().size() );
07688 pageMaster.addChildElement( "headerfooter", elementContents );
07689 pageStyle.addAttribute( "style:master-page-name", mainStyles.lookup( pageMaster, "Standard" ) );
07690
07691 pageStyle.addProperty( "table:display", !d->hide );
07692 return mainStyles.lookup( pageStyle, "ta" );
07693 }
07694
07695
07696 void KSpreadSheet::saveOasisColRowCell( KoXmlWriter& xmlWriter, KoGenStyles &mainStyles, int maxCols, int maxRows, KSpreadGenValidationStyles &valStyle )
07697 {
07698 int i = 1;
07699 while ( i <= maxCols )
07700 {
07701 ColumnFormat * column = columnFormat( i );
07702 KoGenStyle styleCurrent( KSpreadDoc::STYLE_COLUMN, "table-column" );
07703 styleCurrent.addPropertyPt( "style:column-width", column->dblWidth() );
07704 styleCurrent.addProperty( "fo:break-before", "auto" );
07705
07706 bool hide = column->isHide();
07707 int j = i + 1;
07708 int repeated = 1;
07709 while ( j <= maxCols )
07710 {
07711 const ColumnFormat *nextColumn = columnFormat( j );
07712 KoGenStyle nextStyle( KSpreadDoc::STYLE_COLUMN, "table-column" );
07713 nextStyle.addPropertyPt( "style:column-width", nextColumn->dblWidth() );
07714 nextStyle.addProperty( "fo:break-before", "auto" );
07715
07716
07717 if ( ( nextStyle==styleCurrent ) && ( hide == nextColumn->isHide() ) )
07718 ++repeated;
07719 else
07720 break;
07721 ++j;
07722 }
07723 xmlWriter.startElement( "table:table-column" );
07724 xmlWriter.addAttribute( "table:style-name", mainStyles.lookup( styleCurrent, "co" ) );
07725 KoGenStyle styleColCurrent( KSpreadDoc::STYLE_CELL, "table-cell" );
07726 column->saveOasisCellStyle(styleColCurrent,mainStyles );
07727
07728 xmlWriter.addAttribute( "table:default-cell-style-name", mainStyles.lookup( styleColCurrent, "ce" ) );
07729 if ( hide )
07730 xmlWriter.addAttribute( "table:visibility", "collapse" );
07731
07732 if ( repeated > 1 )
07733 xmlWriter.addAttribute( "table:number-columns-repeated", repeated );
07734 xmlWriter.endElement();
07735 i += repeated;
07736 }
07737
07738 for ( i = 1; i <= maxRows; ++i )
07739 {
07740 const RowFormat * row = rowFormat( i );
07741 KoGenStyle rowStyle( KSpreadDoc::STYLE_ROW, "table-row" );
07742 rowStyle.addPropertyPt( "style:row-height", row->dblHeight());
07743 rowStyle.addProperty( "fo:break-before", "auto" );
07744
07745 xmlWriter.startElement( "table:table-row" );
07746 xmlWriter.addAttribute( "table:style-name", mainStyles.lookup( rowStyle, "ro" ) );
07747
07748 if ( row->isHide() )
07749 xmlWriter.addAttribute( "table:visibility", "collapse" );
07750
07751 saveOasisCells( xmlWriter, mainStyles, i, maxCols, valStyle );
07752
07753 xmlWriter.endElement();
07754 }
07755 }
07756
07757 void KSpreadSheet::saveOasisCells( KoXmlWriter& xmlWriter, KoGenStyles &mainStyles, int row, int maxCols, KSpreadGenValidationStyles &valStyle )
07758 {
07759 int i = 1;
07760 while ( i <= maxCols )
07761 {
07762 int repeated = 1;
07763 KSpreadCell* cell = cellAt( i, row );
07764 cell->saveOasis( xmlWriter, mainStyles, row, i, maxCols, repeated, valStyle );
07765 i += repeated;
07766 }
07767 }
07768
07769 bool KSpreadSheet::loadXML( const QDomElement& sheet )
07770 {
07771 bool ok = false;
07772 if ( !doc()->loadingInfo() || !doc()->loadingInfo()->loadTemplate() )
07773 {
07774 d->name = sheet.attribute( "name" );
07775 if ( d->name.isEmpty() )
07776 {
07777 doc()->setErrorMessage( i18n("Invalid document. Sheet name is empty.") );
07778 return false;
07779 }
07780 }
07781
07782 bool detectDirection = true;
07783 d->layoutDirection = LeftToRight;
07784 QString layoutDir = sheet.attribute( "layoutDirection" );
07785 if( !layoutDir.isEmpty() )
07786 {
07787 if( layoutDir == "rtl" )
07788 {
07789 detectDirection = false;
07790 d->layoutDirection = RightToLeft;
07791 }
07792 else if( layoutDir == "ltr" )
07793 {
07794 detectDirection = false;
07795 d->layoutDirection = LeftToRight;
07796 }
07797 }
07798 if( detectDirection )
07799 checkContentDirection( d->name );
07800
07801
07802
07803
07804
07805 if (d->name[0] == ' ')
07806 {
07807 d->name.remove(0,1);
07808 }
07809 for (unsigned int i=0; i < d->name.length(); i++)
07810 {
07811 if ( !(d->name[i].isLetterOrNumber() ||
07812 d->name[i] == ' ' || d->name[i] == '.' ||
07813 d->name[i] == '_'))
07814 {
07815 d->name[i] = '_';
07816 }
07817 }
07818
07819
07820 QString testName;
07821 QString baseName;
07822 int nameSuffix = 0;
07823
07824 testName = d->name;
07825 baseName = d->name;
07826
07827
07828 d->name = "";
07829 while (workbook()->findSheet(testName) != NULL)
07830 {
07831 nameSuffix++;
07832 testName = baseName + '_' + QString::number(nameSuffix);
07833 }
07834 d->name = testName;
07835
07836 kdDebug(36001)<<"KSpreadSheet::loadXML: table name="<<d->name<<endl;
07837 setName(d->name.utf8());
07838 (dynamic_cast<KSpreadSheetIface*>(dcopObject()))->sheetNameHasChanged();
07839
07840 if( sheet.hasAttribute( "grid" ) )
07841 {
07842 d->showGrid = (int)sheet.attribute("grid").toInt( &ok );
07843
07844 }
07845 if( sheet.hasAttribute( "printGrid" ) )
07846 {
07847 d->print->setPrintGrid( (int)sheet.attribute("printGrid").toInt( &ok ) );
07848
07849 }
07850 if( sheet.hasAttribute( "printCommentIndicator" ) )
07851 {
07852 d->print->setPrintCommentIndicator( (int)sheet.attribute("printCommentIndicator").toInt( &ok ) );
07853
07854 }
07855 if( sheet.hasAttribute( "printFormulaIndicator" ) )
07856 {
07857 d->print->setPrintFormulaIndicator( (int)sheet.attribute("printFormulaIndicator").toInt( &ok ) );
07858
07859 }
07860 if( sheet.hasAttribute( "hide" ) )
07861 {
07862 d->hide = (int)sheet.attribute("hide").toInt( &ok );
07863
07864 }
07865 if( sheet.hasAttribute( "showFormula" ) )
07866 {
07867 d->showFormula = (int)sheet.attribute("showFormula").toInt( &ok );
07868
07869 }
07870
07871 if( sheet.hasAttribute( "formular" ) )
07872 {
07873 d->showFormula = (int)sheet.attribute("formular").toInt( &ok );
07874
07875 }
07876 if( sheet.hasAttribute( "showFormulaIndicator" ) )
07877 {
07878 d->showFormulaIndicator = (int)sheet.attribute("showFormulaIndicator").toInt( &ok );
07879
07880 }
07881 if( sheet.hasAttribute( "borders" ) )
07882 {
07883 d->showPageBorders = (int)sheet.attribute("borders").toInt( &ok );
07884
07885 }
07886 if( sheet.hasAttribute( "lcmode" ) )
07887 {
07888 d->lcMode = (int)sheet.attribute("lcmode").toInt( &ok );
07889
07890 }
07891 if ( sheet.hasAttribute( "autoCalc" ) )
07892 {
07893 d->autoCalc = ( int )sheet.attribute( "autoCalc" ).toInt( &ok );
07894
07895 }
07896 if( sheet.hasAttribute( "columnnumber" ) )
07897 {
07898 d->showColumnNumber = (int)sheet.attribute("columnnumber").toInt( &ok );
07899
07900 }
07901 if( sheet.hasAttribute( "hidezero" ) )
07902 {
07903 d->hideZero = (int)sheet.attribute("hidezero").toInt( &ok );
07904
07905 }
07906 if( sheet.hasAttribute( "firstletterupper" ) )
07907 {
07908 d->firstLetterUpper = (int)sheet.attribute("firstletterupper").toInt( &ok );
07909
07910 }
07911
07912
07913 QDomElement paper = sheet.namedItem( "paper" ).toElement();
07914 if ( !paper.isNull() )
07915 {
07916 QString format = paper.attribute( "format" );
07917 QString orientation = paper.attribute( "orientation" );
07918
07919
07920 QDomElement borders = paper.namedItem( "borders" ).toElement();
07921 if ( !borders.isNull() )
07922 {
07923 float left = borders.attribute( "left" ).toFloat();
07924 float right = borders.attribute( "right" ).toFloat();
07925 float top = borders.attribute( "top" ).toFloat();
07926 float bottom = borders.attribute( "bottom" ).toFloat();
07927 d->print->setPaperLayout( left, top, right, bottom, format, orientation );
07928 }
07929 QString hleft, hright, hcenter;
07930 QString fleft, fright, fcenter;
07931
07932 QDomElement head = paper.namedItem( "head" ).toElement();
07933 if ( !head.isNull() )
07934 {
07935 QDomElement left = head.namedItem( "left" ).toElement();
07936 if ( !left.isNull() )
07937 hleft = left.text();
07938 QDomElement center = head.namedItem( "center" ).toElement();
07939 if ( !center.isNull() )
07940 hcenter = center.text();
07941 QDomElement right = head.namedItem( "right" ).toElement();
07942 if ( !right.isNull() )
07943 hright = right.text();
07944 }
07945
07946 QDomElement foot = paper.namedItem( "foot" ).toElement();
07947 if ( !foot.isNull() )
07948 {
07949 QDomElement left = foot.namedItem( "left" ).toElement();
07950 if ( !left.isNull() )
07951 fleft = left.text();
07952 QDomElement center = foot.namedItem( "center" ).toElement();
07953 if ( !center.isNull() )
07954 fcenter = center.text();
07955 QDomElement right = foot.namedItem( "right" ).toElement();
07956 if ( !right.isNull() )
07957 fright = right.text();
07958 }
07959 d->print->setHeadFootLine( hleft, hcenter, hright, fleft, fcenter, fright);
07960 }
07961
07962
07963 QDomElement printrange = sheet.namedItem( "printrange-rect" ).toElement();
07964 if ( !printrange.isNull() )
07965 {
07966 int left = printrange.attribute( "left-rect" ).toInt();
07967 int right = printrange.attribute( "right-rect" ).toInt();
07968 int bottom = printrange.attribute( "bottom-rect" ).toInt();
07969 int top = printrange.attribute( "top-rect" ).toInt();
07970 if ( left == 0 )
07971 {
07972 left = 1;
07973 right = KS_colMax;
07974 }
07975 if ( top == 0 )
07976 {
07977 top = 1;
07978 bottom = KS_rowMax;
07979 }
07980 d->print->setPrintRange( QRect( QPoint( left, top ), QPoint( right, bottom ) ) );
07981 }
07982
07983
07984 if( sheet.hasAttribute( "printZoom" ) )
07985 {
07986 double zoom = sheet.attribute( "printZoom" ).toDouble( &ok );
07987 if ( ok )
07988 {
07989 d->print->setZoom( zoom );
07990 }
07991 }
07992
07993
07994 if( sheet.hasAttribute( "printPageLimitX" ) )
07995 {
07996 int pageLimit = sheet.attribute( "printPageLimitX" ).toInt( &ok );
07997 if ( ok )
07998 {
07999 d->print->setPageLimitX( pageLimit );
08000 }
08001 }
08002
08003
08004 if( sheet.hasAttribute( "printPageLimitY" ) )
08005 {
08006 int pageLimit = sheet.attribute( "printPageLimitY" ).toInt( &ok );
08007 if ( ok )
08008 {
08009 d->print->setPageLimitY( pageLimit );
08010 }
08011 }
08012
08013
08014 QDomNode n = sheet.firstChild();
08015 while( !n.isNull() )
08016 {
08017 QDomElement e = n.toElement();
08018 if ( !e.isNull() && e.tagName() == "cell" )
08019 {
08020 KSpreadCell *cell = new KSpreadCell( this, 0, 0 );
08021 if ( cell->load( e, 0, 0 ) )
08022 insertCell( cell );
08023 else
08024 delete cell;
08025 }
08026 else if ( !e.isNull() && e.tagName() == "row" )
08027 {
08028 RowFormat *rl = new RowFormat( this, 0 );
08029 if ( rl->load( e ) )
08030 insertRowFormat( rl );
08031 else
08032 delete rl;
08033 }
08034 else if ( !e.isNull() && e.tagName() == "column" )
08035 {
08036 ColumnFormat *cl = new ColumnFormat( this, 0 );
08037 if ( cl->load( e ) )
08038 insertColumnFormat( cl );
08039 else
08040 delete cl;
08041 }
08042 else if ( !e.isNull() && e.tagName() == "object" )
08043 {
08044 KSpreadChild *ch = new KSpreadChild( doc(), this );
08045 if ( ch->load( e ) )
08046 insertChild( ch );
08047 else
08048 delete ch;
08049 }
08050 else if ( !e.isNull() && e.tagName() == "chart" )
08051 {
08052 ChartChild *ch = new ChartChild( doc(), this );
08053 if ( ch->load( e ) )
08054 insertChild( ch );
08055 else
08056 delete ch;
08057 }
08058
08059 n = n.nextSibling();
08060 }
08061
08062
08063 QDomElement printrepeatcolumns = sheet.namedItem( "printrepeatcolumns" ).toElement();
08064 if ( !printrepeatcolumns.isNull() )
08065 {
08066 int left = printrepeatcolumns.attribute( "left" ).toInt();
08067 int right = printrepeatcolumns.attribute( "right" ).toInt();
08068 d->print->setPrintRepeatColumns( qMakePair( left, right ) );
08069 }
08070
08071
08072 QDomElement printrepeatrows = sheet.namedItem( "printrepeatrows" ).toElement();
08073 if ( !printrepeatrows.isNull() )
08074 {
08075 int top = printrepeatrows.attribute( "top" ).toInt();
08076 int bottom = printrepeatrows.attribute( "bottom" ).toInt();
08077 d->print->setPrintRepeatRows( qMakePair( top, bottom ) );
08078 }
08079
08080 if( !sheet.hasAttribute( "borders1.2" ) )
08081 {
08082 convertObscuringBorders();
08083 }
08084
08085 if ( sheet.hasAttribute( "protected" ) )
08086 {
08087 QString passwd = sheet.attribute( "protected" );
08088
08089 if ( passwd.length() > 0 )
08090 {
08091 QCString str( passwd.latin1() );
08092 d->password = KCodecs::base64Decode( str );
08093 }
08094 else
08095 d->password = QCString( "" );
08096 }
08097
08098 return true;
08099 }
08100
08101
08102 bool KSpreadSheet::loadChildren( KoStore* _store )
08103 {
08104 QPtrListIterator<KoDocumentChild> it( doc()->children() );
08105 for( ; it.current(); ++it )
08106 {
08107 if ( ((KSpreadChild*)it.current())->sheet() == this )
08108 {
08109 if ( !it.current()->loadDocument( _store ) )
08110 return false;
08111 }
08112 }
08113
08114 return true;
08115 }
08116
08117 void KSpreadSheet::setShowPageBorders( bool b )
08118 {
08119 if ( b == d->showPageBorders )
08120 return;
08121
08122 d->showPageBorders = b;
08123 emit sig_updateView( this );
08124 }
08125
08126 void KSpreadSheet::addCellBinding( CellBinding *_bind )
08127 {
08128 d->cellBindings.append( _bind );
08129
08130 doc()->setModified( true );
08131 }
08132
08133 void KSpreadSheet::removeCellBinding( CellBinding *_bind )
08134 {
08135 d->cellBindings.removeRef( _bind );
08136
08137 doc()->setModified( true );
08138 }
08139
08140 KSpreadSheet* KSpreadSheet::findSheet( const QString & _name )
08141 {
08142 if ( !workbook() )
08143 return 0L;
08144
08145 return workbook()->findSheet( _name );
08146 }
08147
08148
08149 void KSpreadSheet::insertCell( KSpreadCell *_cell )
08150 {
08151
08152 d->cells.insert( _cell, _cell->column(), _cell->row() );
08153
08154 if ( d->scrollBarUpdates )
08155 {
08156 checkRangeHBorder ( _cell->column() );
08157 checkRangeVBorder ( _cell->row() );
08158 }
08159 }
08160
08161 void KSpreadSheet::insertColumnFormat( ColumnFormat *l )
08162 {
08163 d->columns.insertElement( l, l->column() );
08164 }
08165
08166 void KSpreadSheet::insertRowFormat( RowFormat *l )
08167 {
08168 d->rows.insertElement( l, l->row() );
08169 }
08170
08171 void KSpreadSheet::update()
08172 {
08173 KSpreadCell* c = d->cells.firstCell();
08174 for( ;c; c = c->nextCell() )
08175 {
08176 updateCell(c, c->column(), c->row());
08177 }
08178 }
08179
08180 void KSpreadSheet::updateCellArea( const QRect &cellArea )
08181 {
08182 if ( doc()->isLoading() || doc()->delayCalculation() || (!getAutoCalc()))
08183 return;
08184
08185 setRegionPaintDirty( cellArea );
08186 }
08187
08188 void KSpreadSheet::updateCell( KSpreadCell *, int _column, int _row )
08189 {
08190 QRect cellArea(QPoint(_column, _row), QPoint(_column, _row));
08191
08192 updateCellArea(cellArea);
08193 }
08194
08195 void KSpreadSheet::emit_updateRow( RowFormat *_format, int _row )
08196 {
08197 if ( doc()->isLoading() )
08198 return;
08199
08200 KSpreadCell* c = d->cells.firstCell();
08201 for( ;c; c = c->nextCell() )
08202 if ( c->row() == _row )
08203 c->setLayoutDirtyFlag( true );
08204
08205 emit sig_updateVBorder( this );
08206 emit sig_updateView( this );
08207 emit sig_maxRow(maxRow());
08208 _format->clearDisplayDirtyFlag();
08209 }
08210
08211 void KSpreadSheet::emit_updateColumn( ColumnFormat *_format, int _column )
08212 {
08213 if ( doc()->isLoading() )
08214 return;
08215
08216 KSpreadCell* c = d->cells.firstCell();
08217 for( ;c; c = c->nextCell() )
08218 if ( c->column() == _column )
08219 c->setLayoutDirtyFlag( true );
08220
08221 emit sig_updateHBorder( this );
08222 emit sig_updateView( this );
08223 emit sig_maxColumn( maxColumn() );
08224 _format->clearDisplayDirtyFlag();
08225 }
08226
08227 void KSpreadSheet::insertChart( const QRect& _rect, KoDocumentEntry& _e, const QRect& _data )
08228 {
08229 kdDebug(36001) << "Creating document" << endl;
08230 KoDocument* dd = _e.createDoc();
08231 kdDebug(36001) << "Created" << endl;
08232 if ( !dd )
08233
08234 return;
08235
08236 kdDebug(36001) << "NOW FETCHING INTERFACE" << endl;
08237
08238 if ( !dd->initDoc(KoDocument::InitDocEmbedded) )
08239 return;
08240
08241 ChartChild * ch = new ChartChild( doc(), this, dd, _rect );
08242 ch->setDataArea( _data );
08243 ch->update();
08244 ch->chart()->setCanChangeValue( false );
08245
08246
08247
08248 KoChart::WizardExtension * wiz = ch->chart()->wizardExtension();
08249
08250 if ( wiz && wiz->show())
08251 insertChild( ch );
08252 else
08253 delete ch;
08254 }
08255
08256 void KSpreadSheet::insertChild( const QRect& _rect, KoDocumentEntry& _e )
08257 {
08258 KoDocument* d = _e.createDoc( doc() );
08259 if ( !d )
08260 {
08261 kdDebug() << "Error inserting child!" << endl;
08262 return;
08263 }
08264 if ( !d->initDoc(KoDocument::InitDocEmbedded) )
08265 return;
08266
08267 KSpreadChild* ch = new KSpreadChild( doc(), this, d, _rect );
08268
08269 insertChild( ch );
08270 }
08271
08272 void KSpreadSheet::insertChild( KSpreadChild *_child )
08273 {
08274
08275 doc()->insertChild( _child );
08276
08277 updateView( _child->boundingRect() );
08278
08279
08280
08281 }
08282
08283 void KSpreadSheet::deleteChild( KSpreadChild* child )
08284 {
08285 QPointArray polygon = child->framePointArray();
08286
08287 emit sig_removeChild( child );
08288
08289 child->setDeleted(true);
08290 delete child;
08291
08293
08294 }
08295
08296 void KSpreadSheet::changeChildGeometry( KSpreadChild *_child, const QRect& _rect )
08297 {
08298 _child->setGeometry( _rect );
08299
08300 emit sig_updateChildGeometry( _child );
08301 }
08302
08303
08304
08305
08306
08307
08308
08309
08310 bool KSpreadSheet::saveChildren( KoStore* _store, const QString &_path )
08311 {
08312 int i = 0;
08313
08314 QPtrListIterator<KoDocumentChild> it( doc()->children() );
08315 for( ; it.current(); ++it )
08316 {
08317 if ( ((KSpreadChild*)it.current())->sheet() == this )
08318 {
08319 QString path = QString( "%1/%2" ).arg( _path ).arg( i++ );
08320 if ( !it.current()->document()->saveToStore( _store, path ) )
08321 return false;
08322 }
08323 }
08324 return true;
08325 }
08326
08327 KSpreadSheet::~KSpreadSheet()
08328 {
08329
08330 s_mapSheets->remove( d->id );
08331
08332
08333
08334
08335 if( s_mapSheets->count()==0)
08336 s_id=0L;
08337
08338 KSpreadCell* c = d->cells.firstCell();
08339 for( ; c; c = c->nextCell() )
08340 c->sheetDies();
08341
08342 d->cells.clear();
08343
08344 d->painter->end();
08345 delete d->painter;
08346 delete d->widget;
08347
08348 delete d->defaultFormat;
08349 delete d->defaultCell;
08350 delete d->defaultRowFormat;
08351 delete d->defaultColumnFormat;
08352 delete d->print;
08353 delete d->dcop;
08354
08355 delete d->dependencies;
08356
08357 delete d;
08358 }
08359
08360
08361 void KSpreadSheet::checkRangeHBorder ( int _column )
08362 {
08363 if ( d->scrollBarUpdates && _column > d->maxColumn )
08364 {
08365 d->maxColumn = _column;
08366 emit sig_maxColumn( _column );
08367 }
08368 }
08369
08370 void KSpreadSheet::checkRangeVBorder ( int _row )
08371 {
08372 if ( d->scrollBarUpdates && _row > d->maxRow )
08373 {
08374 d->maxRow = _row;
08375 emit sig_maxRow( _row );
08376 }
08377 }
08378
08379
08380 void KSpreadSheet::enableScrollBarUpdates( bool _enable )
08381 {
08382 d->scrollBarUpdates = _enable;
08383 }
08384
08385 DCOPObject* KSpreadSheet::dcopObject()
08386 {
08387 if ( !d->dcop )
08388 d->dcop = new KSpreadSheetIface( this );
08389
08390 return d->dcop;
08391 }
08392
08393 void KSpreadSheet::hideSheet(bool _hide)
08394 {
08395 setHidden(_hide);
08396 if(_hide)
08397 emit sig_SheetHidden(this);
08398 else
08399 emit sig_SheetShown(this);
08400 }
08401
08402 void KSpreadSheet::removeSheet()
08403 {
08404 emit sig_SheetRemoved(this);
08405 }
08406
08407 bool KSpreadSheet::setSheetName( const QString& name, bool init, bool )
08408 {
08409 if ( workbook()->findSheet( name ) )
08410 return FALSE;
08411
08412 if ( isProtected() )
08413 return false;
08414
08415 if ( d->name == name )
08416 return TRUE;
08417
08418 QString old_name = d->name;
08419 d->name = name;
08420
08421 if ( init )
08422 return TRUE;
08423
08424 QPtrListIterator<KSpreadSheet> it( workbook()->sheetList() );
08425 for ( ; it.current(); ++it )
08426 it.current()->changeCellTabName( old_name, name );
08427
08428 doc()->changeAreaSheetName( old_name, name );
08429 emit sig_nameChanged( this, old_name );
08430
08431 setName(name.utf8());
08432 (dynamic_cast<KSpreadSheetIface*>(dcopObject()))->sheetNameHasChanged();
08433
08434 return TRUE;
08435 }
08436
08437
08438 void KSpreadSheet::updateLocale()
08439 {
08440 doc()->emitBeginOperation(true);
08441 setRegionPaintDirty(QRect(QPoint(1,1), QPoint(KS_colMax, KS_rowMax)));
08442
08443 KSpreadCell* c = d->cells.firstCell();
08444 for( ;c; c = c->nextCell() )
08445 {
08446 QString _text = c->text();
08447 c->setDisplayText( _text );
08448 }
08449 emit sig_updateView( this );
08450
08451 }
08452
08453 KSpreadCell* KSpreadSheet::getFirstCellColumn(int col) const
08454 { return d->cells.getFirstCellColumn(col); }
08455
08456 KSpreadCell* KSpreadSheet::getLastCellColumn(int col) const
08457 { return d->cells.getLastCellColumn(col); }
08458
08459 KSpreadCell* KSpreadSheet::getFirstCellRow(int row) const
08460 { return d->cells.getFirstCellRow(row); }
08461
08462 KSpreadCell* KSpreadSheet::getLastCellRow(int row) const
08463 { return d->cells.getLastCellRow(row); }
08464
08465 KSpreadCell* KSpreadSheet::getNextCellUp(int col, int row) const
08466 { return d->cells.getNextCellUp(col, row); }
08467
08468 KSpreadCell* KSpreadSheet::getNextCellDown(int col, int row) const
08469 { return d->cells.getNextCellDown(col, row); }
08470
08471 KSpreadCell* KSpreadSheet::getNextCellLeft(int col, int row) const
08472 { return d->cells.getNextCellLeft(col, row); }
08473
08474 KSpreadCell* KSpreadSheet::getNextCellRight(int col, int row) const
08475 { return d->cells.getNextCellRight(col, row); }
08476
08477 void KSpreadSheet::convertObscuringBorders()
08478 {
08479
08480
08481
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491
08492 KSpreadCell* c = d->cells.firstCell();
08493 QPen topPen, bottomPen, leftPen, rightPen;
08494 for( ;c; c = c->nextCell() )
08495 {
08496 if (c->extraXCells() > 0 || c->extraYCells() > 0)
08497 {
08498 topPen = c->topBorderPen(c->column(), c->row());
08499 leftPen = c->leftBorderPen(c->column(), c->row());
08500 rightPen = c->rightBorderPen(c->column(), c->row());
08501 bottomPen = c->bottomBorderPen(c->column(), c->row());
08502
08503 c->setTopBorderStyle(Qt::NoPen);
08504 c->setLeftBorderStyle(Qt::NoPen);
08505 c->setRightBorderStyle(Qt::NoPen);
08506 c->setBottomBorderStyle(Qt::NoPen);
08507
08508 for (int x = c->column(); x < c->column() + c->extraXCells(); x++)
08509 {
08510 nonDefaultCell( x, c->row() )->setTopBorderPen(topPen);
08511 nonDefaultCell( x, c->row() + c->extraYCells() )->
08512 setBottomBorderPen(bottomPen);
08513 }
08514 for (int y = c->row(); y < c->row() + c->extraYCells(); y++)
08515 {
08516 nonDefaultCell( c->column(), y )->setLeftBorderPen(leftPen);
08517 nonDefaultCell( c->column() + c->extraXCells(), y )->
08518 setRightBorderPen(rightPen);
08519 }
08520 }
08521 }
08522 }
08523
08524
08525
08526
08527
08528 void KSpreadSheet::setRegionPaintDirty( QRect const & region )
08529 {
08530 QValueList<QRect>::iterator it = d->paintDirtyList.begin();
08531 QValueList<QRect>::iterator end = d->paintDirtyList.end();
08532
08533 while ( it != end )
08534 {
08535 if ( (*it).contains( region ) )
08536 return;
08537
08538 ++it;
08539 }
08540
08541 d->paintDirtyList.append( region );
08542 }
08543
08544 void KSpreadSheet::clearPaintDirtyData()
08545 {
08546 d->paintDirtyList.clear();
08547 }
08548
08549 bool KSpreadSheet::cellIsPaintDirty( QPoint const & cell )
08550 {
08551 QValueList<QRect>::iterator it;
08552 QValueList<QRect>::iterator end = d->paintDirtyList.end();
08553 bool found = false;
08554
08555
08556
08557
08558
08559
08560 for ( it = d->paintDirtyList.begin(); it != end && !found; ++it )
08561 {
08562 found = (*it).contains( cell );
08563 }
08564 return found;
08565 }
08566
08567 #ifndef NDEBUG
08568 void KSpreadSheet::printDebug()
08569 {
08570 int iMaxColumn = maxColumn();
08571 int iMaxRow = maxRow();
08572
08573 kdDebug(36001) << "Cell | Content | DataT | Text" << endl;
08574 KSpreadCell *cell;
08575 for ( int currentrow = 1 ; currentrow < iMaxRow ; ++currentrow )
08576 {
08577 for ( int currentcolumn = 1 ; currentcolumn < iMaxColumn ; currentcolumn++ )
08578 {
08579 cell = cellAt( currentcolumn, currentrow );
08580 if ( !cell->isDefault() && !cell->isEmpty() )
08581 {
08582 QString cellDescr = KSpreadCell::name( currentcolumn, currentrow );
08583 cellDescr = cellDescr.rightJustify( 4,' ' );
08584
08585
08586
08587 cellDescr += " | ";
08588 cellDescr += cell->value().type();
08589 cellDescr += " | ";
08590 cellDescr += cell->text();
08591 if ( cell->isFormula() )
08592 cellDescr += QString(" [result: %1]").arg( cell->value().asString() );
08593 kdDebug(36001) << cellDescr << endl;
08594 }
08595 }
08596 }
08597 }
08598 #endif
08599
08600
08601
08602
08603
08604
08605
08606 KSpreadChild::KSpreadChild( KSpreadDoc *parent, KSpreadSheet *_sheet, KoDocument* doc, const QRect& geometry )
08607 : KoDocumentChild( parent, doc, geometry )
08608 {
08609 m_pSheet = _sheet;
08610 }
08611
08612 KSpreadChild::KSpreadChild( KSpreadDoc *parent, KSpreadSheet *_sheet ) : KoDocumentChild( parent )
08613 {
08614 m_pSheet = _sheet;
08615 }
08616
08617
08618 KSpreadChild::~KSpreadChild()
08619 {
08620 }
08621
08622
08623
08624
08625
08626
08627
08628 ChartChild::ChartChild( KSpreadDoc *_spread, KSpreadSheet *_sheet, KoDocument* doc, const QRect& geometry )
08629 : KSpreadChild( _spread, _sheet, doc, geometry )
08630 {
08631 m_pBinding = 0;
08632 }
08633
08634 ChartChild::ChartChild( KSpreadDoc *_spread, KSpreadSheet *_sheet )
08635 : KSpreadChild( _spread, _sheet )
08636 {
08637 m_pBinding = 0;
08638 }
08639
08640 ChartChild::~ChartChild()
08641 {
08642 if ( isDeleted() )
08643 delete m_pBinding;
08644 }
08645
08646 void ChartChild::setDataArea( const QRect& _data )
08647 {
08648 if ( m_pBinding == 0L )
08649 m_pBinding = new ChartBinding( m_pSheet, _data, this );
08650 else
08651 m_pBinding->setDataArea( _data );
08652 }
08653
08654 void ChartChild::update()
08655 {
08656 if ( m_pBinding )
08657 m_pBinding->cellChanged( 0 );
08658 }
08659
08660 bool ChartChild::load( const QDomElement& element )
08661 {
08662 if ( !KSpreadChild::load( element ) )
08663 return false;
08664
08665 if ( element.hasAttribute( "left-cell" ) &&
08666 element.hasAttribute( "top-cell" ) &&
08667 element.hasAttribute( "right-cell" ) &&
08668 element.hasAttribute( "bottom-cell" ) )
08669 {
08670 QRect r;
08671 r.setCoords( element.attribute( "left-cell" ).toInt(),
08672 element.attribute( "top-cell" ).toInt(),
08673 element.attribute( "right-cell" ).toInt(),
08674 element.attribute( "bottom-cell" ).toInt() );
08675
08676 setDataArea( r );
08677 }
08678
08679 return true;
08680 }
08681
08682 QDomElement ChartChild::save( QDomDocument& doc )
08683 {
08684 QDomElement element = KSpreadChild::save( doc );
08685 element.setTagName( "chart" );
08686
08687 element.setAttribute( "left-cell", m_pBinding->dataArea().left() );
08688 element.setAttribute( "right-cell", m_pBinding->dataArea().right() );
08689 element.setAttribute( "top-cell", m_pBinding->dataArea().top() );
08690 element.setAttribute( "bottom-cell", m_pBinding->dataArea().bottom() );
08691
08692 return element;
08693 }
08694
08695 bool ChartChild::loadDocument( KoStore* _store )
08696 {
08697 bool res = KSpreadChild::loadDocument( _store );
08698 if ( !res )
08699 return res;
08700
08701
08702 if ( !m_pBinding )
08703 return true;
08704
08705 update();
08706
08707 chart()->setCanChangeValue( false );
08708 return true;
08709 }
08710
08711 KoChart::Part* ChartChild::chart()
08712 {
08713 assert( document()->inherits( "KoChart::Part" ) );
08714 return static_cast<KoChart::Part *>( document() );
08715 }