00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <float.h>
00021
00022 #include <qcolor.h>
00023
00024 #include <kdebug.h>
00025 #include <klocale.h>
00026 #include <kmessagebox.h>
00027 #include <kstaticdeleter.h>
00028
00029 #include "kspread_canvas.h"
00030 #include "kspread_cell.h"
00031 #include "kspread_doc.h"
00032 #include "kspread_map.h"
00033 #include "kspread_sheet.h"
00034 #include "kspread_style.h"
00035 #include "kspread_style_manager.h"
00036 #include "kspread_undo.h"
00037 #include "kspread_view.h"
00038
00039 #include "manipulator.h"
00040
00041 using namespace KSpread;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 Manipulator::Manipulator()
00088 : Region(),
00089 KCommand(),
00090 m_sheet(0),
00091 m_creation(true),
00092 m_reverse(false),
00093 m_firstrun(true),
00094 m_format(true),
00095 m_register(true)
00096 {
00097 }
00098
00099 Manipulator::~Manipulator()
00100 {
00101 }
00102
00103 void Manipulator::execute()
00104 {
00105 if (!m_sheet)
00106 {
00107 kdWarning() << "Manipulator::execute(): No explicit m_sheet is set. "
00108 << "Manipulating all sheets of the region." << endl;
00109 }
00110
00111 bool successfully = true;
00112 successfully = preProcessing();
00113 if (!successfully)
00114 {
00115 kdWarning() << "Manipulator::execute(): preprocessing was not successful!" << endl;
00116 return;
00117 }
00118
00119 m_sheet->doc()->setModified(true);
00120 m_sheet->doc()->undoLock ();
00121 m_sheet->doc()->emitBeginOperation();
00122
00123 successfully = true;
00124 Region::Iterator endOfList(cells().end());
00125 for (Region::Iterator it = cells().begin(); it != endOfList; ++it)
00126 {
00127 successfully = successfully && process(*it);
00128 }
00129
00130 if (!successfully)
00131 {
00132 kdWarning() << "Manipulator::execute(): processing was not successful!" << endl;
00133 }
00134
00135 successfully = true;
00136 successfully = postProcessing();
00137 if (!successfully)
00138 {
00139 kdWarning() << "Manipulator::execute(): postprocessing was not successful!" << endl;
00140 }
00141
00142 m_sheet->setRegionPaintDirty( *this );
00143 m_sheet->doc()->emitEndOperation();
00144 m_sheet->doc()->undoUnlock ();
00145
00146
00147 if (m_firstrun && m_register)
00148 {
00149
00150 m_sheet->doc()->addCommand (this);
00151
00152 m_sheet->doc()->setModified (true);
00153 }
00154 m_firstrun = false;
00155 }
00156
00157 void Manipulator::unexecute()
00158 {
00159 m_reverse = !m_reverse;
00160 execute();
00161 m_reverse = !m_reverse;
00162 }
00163
00164 bool Manipulator::process(Element* element)
00165 {
00166 Sheet* sheet = m_sheet;
00167 if (m_sheet && sheet != m_sheet)
00168 {
00169 return true;
00170 }
00171
00172 QRect range = element->rect().normalize();
00173 if (m_format && element->isColumn())
00174 {
00175 for (int col = range.left(); col <= range.right(); ++col)
00176 {
00177 kdDebug() << "Processing column " << col << "." << endl;
00178 ColumnFormat* format = sheet->nonDefaultColumnFormat(col);
00179 process(format);
00180
00181 }
00182 }
00183 else if (m_format && element->isRow())
00184 {
00185 for (int row = range.top(); row <= range.bottom(); ++row)
00186 {
00187 kdDebug() << "Processing row " << row << "." << endl;
00188 RowFormat* format = sheet->nonDefaultRowFormat(row);
00189 process(format);
00190
00191 }
00192 }
00193 else
00194 {
00195 kdDebug() << "Processing cell(s) at " << range << "." << endl;
00196 for (int col = range.left(); col <= range.right(); ++col)
00197 {
00198 sheet->enableScrollBarUpdates(false);
00199 for (int row = range.top(); row <= range.bottom(); ++row)
00200 {
00201 Cell* cell = sheet->cellAt(col, row);
00202
00203
00204
00205
00206
00207
00208
00209 {
00210 if (cell == sheet->defaultCell() && m_creation)
00211 {
00212 Style* style = sheet->doc()->styleManager()->defaultStyle();
00213 cell = new Cell(sheet, style, col, row);
00214 sheet->insertCell(cell);
00215 }
00216
00217 if (!process(cell))
00218 {
00219 return false;
00220 }
00221 }
00222 }
00223 sheet->enableScrollBarUpdates(true);
00224 sheet->checkRangeVBorder(range.bottom());
00225 }
00226 sheet->checkRangeHBorder(range.right());
00227 }
00228 return true;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237 FormatManipulator::FormatManipulator()
00238 {
00239 m_properties = 0;
00240
00241 m_topBorderPen = QPen(QColor(), 0, Qt::NoPen);
00242 m_bottomBorderPen = QPen(QColor(), 0, Qt::NoPen);
00243 m_leftBorderPen = QPen(QColor(), 0, Qt::NoPen);
00244 m_rightBorderPen = QPen(QColor(), 0, Qt::NoPen);
00245 m_horizontalPen = QPen(QColor(), 0, Qt::NoPen);
00246 m_verticalPen = QPen(QColor(), 0, Qt::NoPen);
00247 m_fallDiagonalPen = QPen(QColor(), 0, Qt::NoPen);
00248 m_goUpDiagonalPen = QPen(QColor(), 0, Qt::NoPen);
00249 }
00250
00251 FormatManipulator::~FormatManipulator()
00252 {
00253 QValueList<layoutCell>::Iterator it2;
00254 for ( it2 = m_lstFormats.begin(); it2 != m_lstFormats.end(); ++it2 )
00255 {
00256 delete (*it2).l;
00257 }
00258 m_lstFormats.clear();
00259
00260 for ( it2 = m_lstRedoFormats.begin(); it2 != m_lstRedoFormats.end(); ++it2 )
00261 {
00262 delete (*it2).l;
00263 }
00264 m_lstRedoFormats.clear();
00265
00266 QValueList<layoutColumn>::Iterator it3;
00267 for ( it3 = m_lstColFormats.begin(); it3 != m_lstColFormats.end(); ++it3 )
00268 {
00269 delete (*it3).l;
00270 }
00271 m_lstColFormats.clear();
00272
00273 for ( it3 = m_lstRedoColFormats.begin(); it3 != m_lstRedoColFormats.end(); ++it3 )
00274 {
00275 delete (*it3).l;
00276 }
00277 m_lstRedoColFormats.clear();
00278
00279 QValueList<layoutRow>::Iterator it4;
00280 for ( it4 = m_lstRowFormats.begin(); it4 != m_lstRowFormats.end(); ++it4 )
00281 {
00282 delete (*it4).l;
00283 }
00284 m_lstRowFormats.clear();
00285
00286 for ( it4 = m_lstRedoRowFormats.begin(); it4 != m_lstRedoRowFormats.end(); ++it4 )
00287 {
00288 delete (*it4).l;
00289 }
00290 m_lstRedoRowFormats.clear();
00291 }
00292
00293 bool FormatManipulator::preProcessing ()
00294 {
00295 if (m_reverse)
00296 copyFormat (m_lstRedoFormats, m_lstRedoColFormats, m_lstRedoRowFormats);
00297 else
00298 copyFormat (m_lstFormats, m_lstColFormats, m_lstRowFormats);
00299 return true;
00300 }
00301
00302 bool FormatManipulator::process (Element *element)
00303 {
00304
00305 QRect range = element->rect().normalize();
00306
00307 if (!m_reverse) {
00308
00309 int top = range.top();
00310 int left = range.left();
00311 int bottom = range.bottom();
00312 int right = range.right();
00313
00314
00315 Cell * cell;
00316 if ( element->isColumn() )
00317 {
00318 for ( RowFormat * row = m_sheet->firstRow(); row; row = row->next() )
00319 {
00320 if ( !row->isDefault() )
00321 {
00322 for ( int col = left; col <= right; ++col )
00323 {
00324 cell = m_sheet->nonDefaultCell( col, row->row() );
00325 }
00326 }
00327 }
00328 }
00329
00330
00331 if ( element->isRow() )
00332 {
00333 for ( int row = top; row <= bottom; ++row )
00334 {
00335 cell = m_sheet->getFirstCellRow( row );
00336 while ( cell )
00337 {
00338 prepareCell( cell );
00339 cell = m_sheet->getNextCellRight( cell->column(), row );
00340 }
00341 RowFormat * rowFormat = m_sheet->nonDefaultRowFormat(row);
00342 doWork(rowFormat, row==top, row==bottom, false, false);
00343 }
00344 }
00345
00346 else if ( element->isColumn() )
00347 {
00348 for ( int col = left; col <= right; ++col )
00349 {
00350 cell = m_sheet->getFirstCellColumn( col );
00351 while ( cell )
00352 {
00353 prepareCell( cell );
00354 cell = m_sheet->getNextCellDown( col, cell->row() );
00355 }
00356 ColumnFormat * colFormat = m_sheet->nonDefaultColumnFormat( col );
00357 doWork(colFormat, false, false, col==left, col==right);
00358 }
00359
00360 for ( RowFormat * rowFormat = m_sheet->firstRow(); rowFormat; rowFormat = rowFormat->next() )
00361 {
00362 if ( !rowFormat->isDefault() && testCondition( rowFormat ) )
00363 {
00364 for ( int col = left; col <= right; ++col )
00365 {
00366 cell = m_sheet->nonDefaultCell(col, rowFormat->row() );
00367 doWork(cell->format(), false, false, col==left, col==right );
00368 }
00369 }
00370 }
00371 }
00372
00373 else
00374 {
00375 for ( int col = left; col <= right; ++col )
00376 {
00377 for ( int row = top; row <= bottom; ++row )
00378 {
00379 cell = m_sheet->nonDefaultCell(col,row);
00380 if ( !cell->isPartOfMerged() )
00381 {
00382 cell->setDisplayDirtyFlag();
00383 doWork(cell->format(), row==top, row==bottom, col==left, col==right);
00384 cell->clearDisplayDirtyFlag();
00385 }
00386 }
00387 }
00388 }
00389 }
00390 else
00391 {
00392 if( element->isColumn() )
00393 {
00394 QValueList<layoutColumn>::Iterator it2;
00395 for ( it2 = m_lstColFormats.begin(); it2 != m_lstColFormats.end(); ++it2 )
00396 {
00397 ColumnFormat * col = m_sheet->nonDefaultColumnFormat( (*it2).col );
00398 col->copy( *(*it2).l );
00399 }
00400 }
00401 else if( element->isRow() )
00402 {
00403 QValueList<layoutRow>::Iterator it2;
00404 for ( it2 = m_lstRowFormats.begin(); it2 != m_lstRowFormats.end(); ++it2 )
00405 {
00406 RowFormat * row = m_sheet->nonDefaultRowFormat( (*it2).row );
00407 row->copy( *(*it2).l );
00408 }
00409 }
00410
00411 QValueList<layoutCell>::Iterator it2;
00412 for ( it2 = m_lstFormats.begin(); it2 != m_lstFormats.end(); ++it2 )
00413 {
00414 Cell *cell = m_sheet->nonDefaultCell( (*it2).col,(*it2).row );
00415 cell->format()->copy( *(*it2).l );
00416 cell->setLayoutDirtyFlag();
00417 cell->setDisplayDirtyFlag();
00418 m_sheet->updateCell( cell, (*it2).col, (*it2).row );
00419 }
00420 }
00421 return true;
00422 }
00423
00424 void FormatManipulator::copyFormat(QValueList<layoutCell> & list,
00425 QValueList<layoutColumn> & listCol,
00426 QValueList<layoutRow> & listRow)
00427 {
00428 QValueList<layoutCell>::Iterator end = list.end();
00429 for (QValueList<layoutCell>::Iterator it2 = list.begin(); it2 != end; ++it2)
00430 {
00431 delete (*it2).l;
00432 }
00433 list.clear();
00434
00435 Cell * cell;
00436 Region::ConstIterator endOfList(cells().constEnd());
00437 for (Region::ConstIterator it = cells().constBegin(); it != endOfList; ++it)
00438 {
00439 QRect range = (*it)->rect().normalize();
00440 int bottom = range.bottom();
00441 int right = range.right();
00442
00443 if ( (*it)->isColumn() )
00444 {
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 for ( int col = range.left(); col <= right; ++col )
00456 {
00457 layoutColumn tmplayout;
00458 tmplayout.col = col;
00459 tmplayout.l = new ColumnFormat( m_sheet, col );
00460 tmplayout.l->copy( *(m_sheet->columnFormat( col )) );
00461 listCol.append(tmplayout);
00462
00463 cell = m_sheet->getFirstCellColumn( col );
00464 while ( cell )
00465 {
00466 if ( cell->isPartOfMerged() )
00467 {
00468 cell = m_sheet->getNextCellDown( col, cell->row() );
00469 continue;
00470 }
00471
00472 layoutCell tmplayout;
00473 tmplayout.col = col;
00474 tmplayout.row = cell->row();
00475 tmplayout.l = new Format( m_sheet, 0 );
00476 tmplayout.l->copy( *(m_sheet->cellAt( tmplayout.col, tmplayout.row )->format()) );
00477 list.append(tmplayout);
00478
00479 cell = m_sheet->getNextCellDown( col, cell->row() );
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 }
00500 else if ((*it)->isRow())
00501 {
00502 for ( int row = range.top(); row <= bottom; ++row )
00503 {
00504 layoutRow tmplayout;
00505 tmplayout.row = row;
00506 tmplayout.l = new RowFormat( m_sheet, row );
00507 tmplayout.l->copy( *(m_sheet->rowFormat( row )) );
00508 listRow.append(tmplayout);
00509
00510 cell = m_sheet->getFirstCellRow( row );
00511 while ( cell )
00512 {
00513 if ( cell->isPartOfMerged() )
00514 {
00515 cell = m_sheet->getNextCellRight( cell->column(), row );
00516 continue;
00517 }
00518 layoutCell tmplayout;
00519 tmplayout.col = cell->column();
00520 tmplayout.row = row;
00521 tmplayout.l = new Format( m_sheet, 0 );
00522 tmplayout.l->copy( *(m_sheet->cellAt( cell->column(), row )->format()) );
00523 list.append(tmplayout);
00524
00525 cell = m_sheet->getNextCellRight( cell->column(), row );
00526 }
00527 }
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 }
00546 else
00547 {
00548 for ( int row = range.top(); row <= bottom; ++row )
00549 for ( int col = range.left(); col <= right; ++col )
00550 {
00551 Cell * cell = m_sheet->nonDefaultCell( col, row );
00552 if ( !cell->isPartOfMerged() )
00553 {
00554 layoutCell tmplayout;
00555 tmplayout.col = col;
00556 tmplayout.row = row;
00557 tmplayout.l = new Format( m_sheet, 0 );
00558 tmplayout.l->copy( *(m_sheet->cellAt( col, row )->format()) );
00559 list.append(tmplayout);
00560 }
00561 }
00562 }
00563 }
00564 }
00565
00566 bool FormatManipulator::testCondition(RowFormat* row)
00567 {
00568 for (Q_UINT32 property = Format::PAlign;
00569 property <= Format::PHideFormula;
00570 property *= 2)
00571 {
00572 if (m_properties & property)
00573 {
00574 return ( row->hasProperty((Format::Properties) property) );
00575 }
00576 }
00577 return false;
00578 }
00579
00580 void FormatManipulator::doWork(Format* format,
00581 bool isTop, bool isBottom,
00582 bool isLeft, bool isRight)
00583 {
00584
00585
00586 if (m_properties & Format::PFont)
00587 {
00588 if ( !m_font.isEmpty() )
00589 format->setTextFontFamily( m_font );
00590 if ( m_size > 0 )
00591 format->setTextFontSize( m_size );
00592 if ( m_italic >= 0 )
00593 format->setTextFontItalic( (bool)m_italic );
00594 if ( m_bold >= 0 )
00595 format->setTextFontBold( (bool)m_bold );
00596 if ( m_underline >= 0 )
00597 format->setTextFontUnderline( (bool)m_underline );
00598 if ( m_strike >= 0 )
00599 format->setTextFontStrike( (bool)m_strike );
00600 }
00601
00602 if (m_properties & Format::PAngle)
00603 {
00604 format->setAngle( m_angle );
00605 }
00606
00607 if (m_properties & Format::PTextPen)
00608 {
00609 format->setTextColor( m_textColor );
00610 }
00611
00612 if (m_properties & Format::PBackgroundColor)
00613 {
00614 format->setBgColor( m_backgroundColor );
00615 }
00616
00617 if (m_properties & Format::PLeftBorder)
00618 {
00619 if (isLeft)
00620 {
00621 if (m_leftBorderPen.color().isValid())
00622 {
00623 format->setLeftBorderPen(m_leftBorderPen);
00624 }
00625 }
00626 else
00627 {
00628 if (m_verticalPen.color().isValid())
00629 {
00630 format->setLeftBorderPen(m_verticalPen);
00631 }
00632 }
00633 }
00634 if (m_properties & Format::PRightBorder)
00635 {
00636 if (isRight)
00637 {
00638 if (m_rightBorderPen.color().isValid())
00639 {
00640 format->setRightBorderPen(m_rightBorderPen);
00641 }
00642 }
00643 else
00644 {
00645 if (m_verticalPen.color().isValid())
00646 {
00647 format->setRightBorderPen(m_verticalPen);
00648 }
00649 }
00650 }
00651 if (m_properties & Format::PTopBorder)
00652 {
00653 if (isTop)
00654 {
00655 if (m_topBorderPen.color().isValid())
00656 {
00657 format->setTopBorderPen(m_topBorderPen);
00658 }
00659 }
00660 else
00661 {
00662 if (m_horizontalPen.color().isValid())
00663 {
00664 format->setTopBorderPen(m_horizontalPen);
00665 }
00666 }
00667 }
00668 if (m_properties & Format::PBottomBorder)
00669 {
00670 if (isBottom)
00671 {
00672 if (m_bottomBorderPen.color().isValid())
00673 {
00674 format->setBottomBorderPen(m_bottomBorderPen);
00675 }
00676 }
00677 else
00678 {
00679 if (m_horizontalPen.color().isValid())
00680 {
00681 format->setBottomBorderPen(m_horizontalPen);
00682 }
00683 }
00684 }
00685 if (m_properties & Format::PFallDiagonal)
00686 {
00687 format->setFallDiagonalPen(m_fallDiagonalPen);
00688 }
00689 if (m_properties & Format::PGoUpDiagonal)
00690 {
00691 format->setGoUpDiagonalPen(m_goUpDiagonalPen);
00692 }
00693
00694 if (m_properties & Format::PAlign)
00695 {
00696 format->setAlign( m_horAlign );
00697 }
00698
00699 if (m_properties & Format::PAlignY)
00700 {
00701 format->setAlignY( m_verAlign );
00702 }
00703 if (m_properties & Format::PPrefix)
00704 {
00705 format->setPrefix(m_prefix);
00706 }
00707 if (m_properties & Format::PPostfix)
00708 {
00709 format->setPostfix(m_postfix);
00710 }
00711 if (m_properties & Format::PBackgroundBrush)
00712 {
00713 format->setBackGroundBrush(m_backgroundBrush);
00714 }
00715 if (m_properties & Format::PFloatFormat)
00716 {
00717 format->setFloatFormat(m_floatFormat);
00718 }
00719 if (m_properties & Format::PFloatColor)
00720 {
00721 format->setFloatColor(m_floatColor);
00722 }
00723 if (m_properties & Format::PMultiRow)
00724 {
00725 format->setMultiRow(m_multiRow);
00726 }
00727 if (m_properties & Format::PVerticalText)
00728 {
00729 format->setVerticalText(m_verticalText);
00730 }
00731 if (m_properties & Format::PPrecision)
00732 {
00733 format->setPrecision(m_precision);
00734 }
00735 if (m_properties & Format::PFormatType)
00736 {
00737 format->setFormatType(m_formatType);
00738 if (m_formatType == Money_format)
00739 {
00740 format->setCurrency(m_currencyType, m_currencySymbol);
00741 }
00742 }
00743 if (m_properties & Format::PComment)
00744 {
00745 format->setComment(m_comment);
00746 }
00747 if (m_properties & Format::PIndent)
00748 {
00749 format->setIndent(m_indent);
00750 }
00751 if (m_properties & Format::PDontPrintText)
00752 {
00753 format->setDontPrintText(m_dontPrintText);
00754 }
00755 if (m_properties & Format::PCustomFormat)
00756 {
00757
00758 }
00759 if (m_properties & Format::PNotProtected)
00760 {
00761 format->setNotProtected(m_notProtected);
00762 }
00763 if (m_properties & Format::PHideAll)
00764 {
00765 format->setHideAll(m_hideAll);
00766 }
00767 if (m_properties & Format::PHideFormula)
00768 {
00769 format->setHideFormula(m_hideFormula);
00770 }
00771 }
00772
00773 void FormatManipulator::prepareCell(Cell* cell)
00774 {
00775 for (Q_UINT32 property = Format::PAlign;
00776 property <= Format::PHideFormula;
00777 property *= 2)
00778 {
00779 if (m_properties & property)
00780 {
00781 cell->format()->clearProperty((Format::Properties) property);
00782 cell->format()->clearNoFallBackProperties((Format::Properties) property);
00783 }
00784 }
00785 }
00786
00787
00788
00789
00790
00791
00792
00793 MergeManipulator::MergeManipulator()
00794 : Manipulator(),
00795 m_merge(true),
00796 m_mergeHorizontal(false),
00797 m_mergeVertical(false),
00798 m_unmerger(0)
00799 {
00800 }
00801
00802 MergeManipulator::~MergeManipulator()
00803 {
00804 delete m_unmerger;
00805 }
00806
00807 bool MergeManipulator::process(Element* element)
00808 {
00809 if (element->type() != Element::Range || element->isRow() || element->isColumn())
00810 {
00811
00812 return true;
00813 }
00814
00815
00816 if( m_sheet->isProtected() || m_sheet->workbook()->isProtected() )
00817 {
00818 return false;
00819 }
00820
00821 QRect range = element->rect().normalize();
00822 int left = range.left();
00823 int right = range.right();
00824 int top = range.top();
00825 int bottom = range.bottom();
00826 int height = range.height();
00827 int width = range.width();
00828
00829 bool doMerge = m_reverse ? (!m_merge) : m_merge;
00830
00831 if (doMerge)
00832 {
00833 if (m_mergeHorizontal)
00834 {
00835 for (int row = top; row <= bottom; ++row)
00836 {
00837 int rows = 0;
00838 for (int col = left; col <= right; ++col)
00839 {
00840 Cell *cell = m_sheet->cellAt( col, row );
00841 if (cell->doesMergeCells())
00842 {
00843 rows = QMAX(rows, cell->mergedYCells());
00844 cell->mergeCells( col, row, 0, 0 );
00845 }
00846 }
00847 Cell *cell = m_sheet->nonDefaultCell( left, row );
00848 if (!cell->isPartOfMerged())
00849 {
00850 cell->mergeCells( left, row, width - 1, rows );
00851 }
00852 }
00853 }
00854 else if (m_mergeVertical)
00855 {
00856 for (int col = left; col <= right; ++col)
00857 {
00858 int cols = 0;
00859 for (int row = top; row <= bottom; ++row)
00860 {
00861 Cell *cell = m_sheet->cellAt( col, row );
00862 if (cell->doesMergeCells())
00863 {
00864 cols = QMAX(cols, cell->mergedXCells());
00865 cell->mergeCells( col, row, 0, 0 );
00866 }
00867 }
00868 Cell *cell = m_sheet->nonDefaultCell( col, top );
00869 if (!cell->isPartOfMerged())
00870 {
00871 cell->mergeCells( col, top, cols, height - 1);
00872 }
00873 }
00874 }
00875 else
00876 {
00877 Cell *cell = m_sheet->nonDefaultCell( left, top );
00878 cell->mergeCells( left, top, width - 1, height - 1);
00879 }
00880 }
00881 else
00882 {
00883 for (int col = left; col <= right; ++col)
00884 {
00885 for (int row = top; row <= bottom; ++row)
00886 {
00887 Cell *cell = m_sheet->cellAt( col, row );
00888 if (!cell->doesMergeCells())
00889 {
00890 continue;
00891 }
00892 cell->mergeCells( col, row, 0, 0 );
00893 }
00894 }
00895 }
00896
00897 return true;
00898 }
00899
00900 QString MergeManipulator::name() const
00901 {
00902 if (m_merge)
00903 {
00904 if (m_mergeHorizontal)
00905 {
00906 return i18n("Merge Cells Horizontally");
00907 }
00908 else if (m_mergeVertical)
00909 {
00910 return i18n("Merge Cells Vertically");
00911 }
00912 else
00913 {
00914 return i18n("Merge Cells");
00915 }
00916 }
00917 return i18n("Dissociate Cells");
00918 }
00919
00920 bool MergeManipulator::preProcessing()
00921 {
00922 if (isColumnOrRowSelected())
00923 {
00924 KMessageBox::information( 0, i18n( "Merging of columns or rows is not supported." ) );
00925 return false;
00926 }
00927
00928 if (m_firstrun)
00929 {
00930
00931 Region mergedCells;
00932 ConstIterator endOfList = constEnd();
00933 for (ConstIterator it = constBegin(); it != endOfList; ++it)
00934 {
00935 Element* element = *it;
00936 QRect range = element->rect().normalize();
00937 int right = range.right();
00938 int bottom = range.bottom();
00939 for (int row = range.top(); row <= bottom; ++row)
00940 {
00941 for (int col = range.left(); col <= right; ++col)
00942 {
00943 Cell *cell = m_sheet->cellAt(col, row);
00944 if (cell->doesMergeCells())
00945 {
00946 QRect rect(col, row, cell->mergedXCells() + 1, cell->mergedYCells() + 1);
00947 mergedCells.add(rect);
00948 }
00949 }
00950 }
00951 }
00952
00953 if (m_merge)
00954 {
00955
00956
00957 m_unmerger = new MergeManipulator();
00958 if (!m_mergeHorizontal && !m_mergeVertical)
00959 {
00960 m_unmerger->setReverse(true);
00961 }
00962 m_unmerger->setSheet(m_sheet);
00963 m_unmerger->setRegisterUndo(false);
00964 m_unmerger->add(mergedCells);
00965 }
00966 else
00967 {
00968 clear();
00969 add(mergedCells);
00970 }
00971 }
00972
00973 if (m_merge)
00974 {
00975 if (m_reverse)
00976 {
00977 }
00978 else
00979 {
00980
00981
00982
00983
00984
00985
00986
00987 if (!m_mergeHorizontal && !m_mergeVertical)
00988 {
00989 m_unmerger->execute();
00990 }
00991 }
00992 }
00993 return true;
00994 }
00995
00996 bool MergeManipulator::postProcessing()
00997 {
00998 if (m_merge)
00999 {
01000 if (m_reverse)
01001 {
01002
01003 if (m_mergeHorizontal || m_mergeVertical)
01004 {
01005 m_unmerger->execute();
01006 }
01007 else
01008 {
01009 m_unmerger->unexecute();
01010 }
01011 }
01012 }
01013
01014 if (!m_reverse)
01015 {
01016 if (m_sheet->getAutoCalc())
01017 {
01018 m_sheet->recalc();
01019 }
01020 }
01021 else
01022 {
01023 m_sheet->refreshMergedCell();
01024 }
01025 return true;
01026 }
01027
01028
01029
01030
01031
01032
01033
01034 DilationManipulator::DilationManipulator()
01035 : Manipulator()
01036 {
01037 }
01038
01039 DilationManipulator::~DilationManipulator()
01040 {
01041 }
01042
01043 void DilationManipulator::execute()
01044 {
01045 Region extendedRegion;
01046 ConstIterator end(cells().constEnd());
01047 for (ConstIterator it = cells().constBegin(); it != end; ++it)
01048 {
01049 Element* element = *it;
01050 QRect area = element->rect().normalize();
01051
01052 ColumnFormat *col;
01053 RowFormat *rl;
01054
01055
01056 int left = area.left();
01057 int right = area.right();
01058 int top = area.top();
01059 int bottom = area.bottom();
01060
01061
01062 if (element->type() == Region::Element::Point)
01063 {
01064 Cell* cell = m_sheet->cellAt(left, top);
01065 if (cell->doesMergeCells())
01066 {
01067
01068
01069 right += cell->mergedXCells();
01070 bottom += cell->mergedYCells();
01071 }
01072 }
01073
01074 if ( right < KS_colMax )
01075 {
01076 do
01077 {
01078 right++;
01079 col = m_sheet->columnFormat( right );
01080 } while ( col->isHide() && right != KS_colMax );
01081 }
01082 if ( left > 1 )
01083 {
01084 do
01085 {
01086 left--;
01087 col = m_sheet->columnFormat( left );
01088 } while ( col->isHide() && left != 1);
01089 }
01090
01091 if ( bottom < KS_rowMax )
01092 {
01093 do
01094 {
01095 bottom++;
01096 rl = m_sheet->rowFormat( bottom );
01097 } while ( rl->isHide() && bottom != KS_rowMax );
01098 }
01099
01100 if ( top > 1 )
01101 {
01102 do
01103 {
01104 top--;
01105 rl = m_sheet->rowFormat( top );
01106 } while ( rl->isHide() && top != 1);
01107 }
01108
01109 area.setLeft(left);
01110 area.setRight(right);
01111 area.setTop(top);
01112 area.setBottom(bottom);
01113
01114 extendedRegion.add(area, element->sheet());
01115 }
01116 clear();
01117 add(extendedRegion);
01118 }
01119
01120 void DilationManipulator::unexecute()
01121 {
01122 kdError() << "DilationManipulator::unexecute(): "
01123 << "An undo of dilating a region is not possible." << endl;
01124 }
01125
01126
01127
01128
01129
01130
01131
01132 ResizeColumnManipulator::ResizeColumnManipulator()
01133 {
01134 }
01135
01136 ResizeColumnManipulator::~ResizeColumnManipulator()
01137 {
01138 }
01139
01140 bool ResizeColumnManipulator::process(Element* element)
01141 {
01142 QRect range = element->rect().normalize();
01143 for (int col = range.right(); col >= range.left(); --col)
01144 {
01145 ColumnFormat *format = m_sheet->nonDefaultColumnFormat( col );
01146 format->setDblWidth( QMAX( 2.0, m_reverse ? m_oldSize : m_newSize ) );
01147 }
01148 return true;
01149 }
01150
01151
01152
01153
01154
01155
01156
01157 ResizeRowManipulator::ResizeRowManipulator()
01158 {
01159 }
01160
01161 ResizeRowManipulator::~ResizeRowManipulator()
01162 {
01163 }
01164
01165 bool ResizeRowManipulator::process(Element* element)
01166 {
01167 QRect range = element->rect().normalize();
01168 for (int row = range.bottom(); row >= range.top(); --row)
01169 {
01170 RowFormat* rl = m_sheet->nonDefaultRowFormat( row );
01171 rl->setDblHeight( QMAX( 2.0, m_reverse ? m_oldSize : m_newSize ) );
01172 }
01173 return true;
01174 }
01175
01176
01177
01178
01179
01180
01181
01182 AdjustColumnRowManipulator::AdjustColumnRowManipulator()
01183 : Manipulator(),
01184 m_adjustColumn(false),
01185 m_adjustRow(false)
01186 {
01187 }
01188
01189 AdjustColumnRowManipulator::~AdjustColumnRowManipulator()
01190 {
01191 }
01192
01193 bool AdjustColumnRowManipulator::process(Element* element)
01194 {
01195 Sheet* sheet = m_sheet;
01196 if (m_sheet && sheet != m_sheet)
01197 {
01198 return true;
01199 }
01200
01201 QMap<int,double> heights;
01202 QMap<int,double> widths;
01203 if (m_reverse)
01204 {
01205 heights = m_oldHeights;
01206 widths = m_oldWidths;
01207 }
01208 else
01209 {
01210 heights = m_newHeights;
01211 widths = m_newWidths;
01212 }
01213
01214 QRect range = element->rect().normalize();
01215 if (m_adjustColumn)
01216 {
01217 if (element->isRow())
01218 {
01219 for (int row = range.top(); row <= range.bottom(); ++row)
01220 {
01221 Cell* cell = sheet->getFirstCellRow( row );
01222 while ( cell )
01223 {
01224 int col = cell->column();
01225 if ( !cell->isEmpty() && !cell->isObscured())
01226 {
01227 if (widths.contains(col) && widths[col] != -1.0)
01228 {
01229 ColumnFormat* format = sheet->nonDefaultColumnFormat(col);
01230 if ( kAbs(format->dblWidth() - widths[col] ) > DBL_EPSILON )
01231 {
01232 format->setDblWidth( QMAX( 2.0, widths[col] ) );
01233 }
01234 }
01235 }
01236 cell = sheet->getNextCellRight(col, row);
01237 }
01238 }
01239 }
01240 else
01241 {
01242 for (int col = range.left(); col <= range.right(); ++col)
01243 {
01244 if (widths.contains(col) && widths[col] != -1.0)
01245 {
01246 ColumnFormat* format = sheet->nonDefaultColumnFormat(col);
01247 if ( kAbs(format->dblWidth() - widths[col] ) > DBL_EPSILON )
01248 {
01249 format->setDblWidth( QMAX( 2.0, widths[col] ) );
01250 }
01251 }
01252 }
01253 }
01254 }
01255 if (m_adjustRow)
01256 {
01257 if (element->isColumn())
01258 {
01259 for (int col = range.left(); col <= range.right(); ++col)
01260 {
01261 Cell* cell = sheet->getFirstCellColumn( col );
01262 while ( cell )
01263 {
01264 int row = cell->row();
01265 if ( !cell->isEmpty() && !cell->isObscured())
01266 {
01267 if (heights.contains(row) && heights[row] != -1.0)
01268 {
01269 RowFormat* format = sheet->nonDefaultRowFormat(row);
01270 if ( kAbs(format->dblHeight() - heights[row] ) > DBL_EPSILON )
01271 {
01272 format->setDblHeight( QMAX( 2.0, heights[row] ) );
01273 }
01274 }
01275 }
01276 cell = sheet->getNextCellDown( col, row );
01277 }
01278 }
01279 }
01280 else
01281 {
01282 for (int row = range.top(); row <= range.bottom(); ++row)
01283 {
01284 if (heights.contains(row) && heights[row] != -1.0)
01285 {
01286 RowFormat* format = sheet->nonDefaultRowFormat(row);
01287 if ( kAbs(format->dblHeight() - heights[row] ) > DBL_EPSILON )
01288 {
01289 format->setDblHeight( QMAX( 2.0, heights[row] ) );
01290 }
01291 }
01292 }
01293 }
01294 }
01295 return true;
01296 }
01297
01298 bool AdjustColumnRowManipulator::preProcessing()
01299 {
01300 if (m_reverse)
01301 {
01302 }
01303 else
01304 {
01305 if (!m_newHeights.isEmpty() || !m_newWidths.isEmpty())
01306 {
01307 return true;
01308 }
01309
01310
01311 ConstIterator endOfList(cells().end());
01312 for (ConstIterator it = cells().begin(); it != endOfList; ++it)
01313 {
01314 Element* element = *it;
01315 QRect range = element->rect().normalize();
01316 if (element->isColumn())
01317 {
01318 for (int col = range.left(); col <= range.right(); ++col)
01319 {
01320 Cell* cell = m_sheet->getFirstCellColumn( col );
01321 while ( cell )
01322 {
01323 int row = cell->row();
01324 if (m_adjustColumn)
01325 {
01326 if (!m_newWidths.contains(col))
01327 {
01328 m_newWidths[col] = -1.0;
01329 ColumnFormat* format = m_sheet->columnFormat(col);
01330 m_oldWidths[col] = format->dblWidth();
01331 }
01332 if (!cell->isEmpty() && !cell->isObscured())
01333 {
01334 m_newWidths[col] = QMAX(adjustColumnHelper(cell, col, row),
01335 m_newWidths[col] );
01336 }
01337 }
01338 if (m_adjustRow)
01339 {
01340 if (!m_newHeights.contains(row))
01341 {
01342 m_newHeights[row] = -1.0;
01343 RowFormat* format = m_sheet->rowFormat(row);
01344 m_oldHeights[row] = format->dblHeight();
01345 }
01346 if (!cell->isEmpty() && !cell->isObscured())
01347 {
01348 m_newHeights[row] = QMAX(adjustRowHelper(cell, col, row),
01349 m_newHeights[row]);
01350 }
01351 }
01352 cell = m_sheet->getNextCellDown( col, row );
01353 }
01354 }
01355 }
01356 else if (element->isRow())
01357 {
01358 for (int row = range.top(); row <= range.bottom(); ++row)
01359 {
01360 Cell* cell = m_sheet->getFirstCellRow( row );
01361 while ( cell )
01362 {
01363 int col = cell->column();
01364 if (m_adjustColumn)
01365 {
01366 if (!m_newWidths.contains(col))
01367 {
01368 m_newWidths[col] = -1.0;
01369 ColumnFormat* format = m_sheet->columnFormat(col);
01370 m_oldWidths[col] = format->dblWidth();
01371 }
01372 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
01373 {
01374 m_newWidths[col] = QMAX(adjustColumnHelper(cell, col, row),
01375 m_newWidths[col] );
01376 }
01377 }
01378 if (m_adjustRow)
01379 {
01380 if (!m_newHeights.contains(row))
01381 {
01382 m_newHeights[row] = -1.0;
01383 RowFormat* format = m_sheet->rowFormat(row);
01384 m_oldHeights[row] = format->dblHeight();
01385 }
01386 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
01387 {
01388 m_newHeights[row] = QMAX(adjustRowHelper(cell, col, row),
01389 m_newHeights[row]);
01390 }
01391 }
01392 cell = m_sheet->getNextCellRight(col, row);
01393 }
01394 }
01395 }
01396 else
01397 {
01398 Cell* cell;
01399 for (int col = range.left(); col <= range.right(); ++col)
01400 {
01401 for ( int row = range.top(); row <= range.bottom(); ++row )
01402 {
01403 cell = m_sheet->cellAt( col, row );
01404 if (m_adjustColumn)
01405 {
01406 if (!m_newWidths.contains(col))
01407 {
01408 m_newWidths[col] = -1.0;
01409 ColumnFormat* format = m_sheet->columnFormat(col);
01410 m_oldWidths[col] = format->dblWidth();
01411 }
01412 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
01413 {
01414 m_newWidths[col] = QMAX(adjustColumnHelper(cell, col, row),
01415 m_newWidths[col] );
01416 }
01417 }
01418 if (m_adjustRow)
01419 {
01420 if (!m_newHeights.contains(row))
01421 {
01422 m_newHeights[row] = -1.0;
01423 RowFormat* format = m_sheet->rowFormat(row);
01424 m_oldHeights[row] = format->dblHeight();
01425 }
01426 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
01427 {
01428 m_newHeights[row] = QMAX(adjustRowHelper(cell, col, row),
01429 m_newHeights[row]);
01430 }
01431 }
01432 }
01433 }
01434 }
01435 }
01436 }
01437 return true;
01438 }
01439
01440 double AdjustColumnRowManipulator::adjustColumnHelper(Cell* cell, int col, int row )
01441 {
01442 double long_max = 0.0;
01443 cell->calculateTextParameters( m_sheet->painter(), col, row );
01444 if ( cell->textWidth() > long_max )
01445 {
01446 double indent = 0.0;
01447 Format::Align alignment = cell->format()->align(cell->column(), cell->row());
01448 if (alignment == Format::Undefined)
01449 {
01450 if (cell->value().isNumber() || cell->isDate() || cell->isTime())
01451 {
01452 alignment = Format::Right;
01453 }
01454 else
01455 {
01456 alignment = Format::Left;
01457 }
01458 }
01459
01460 if (alignment == Format::Left)
01461 {
01462 indent = cell->format()->getIndent( cell->column(), cell->row() );
01463 }
01464 long_max = indent + cell->textWidth()
01465 + cell->format()->leftBorderWidth( cell->column(), cell->row() )
01466 + cell->format()->rightBorderWidth( cell->column(), cell->row() );
01467 }
01468
01469
01470
01471 if ( long_max == 0.0 )
01472 {
01473 return -1.0;
01474 }
01475 else
01476 {
01477 return long_max + 4;
01478 }
01479 }
01480
01481 double AdjustColumnRowManipulator::adjustRowHelper(Cell* cell, int col, int row)
01482 {
01483 double long_max = 0.0;
01484 cell->calculateTextParameters( m_sheet->painter(), col, row);
01485 if ( cell->textHeight() > long_max )
01486 {
01487 long_max = cell->textHeight()
01488 + cell->format()->topBorderWidth(col, row)
01489 + cell->format()->bottomBorderWidth(col, row);
01490 }
01491
01492
01493
01494 if ( long_max == 0.0 )
01495 {
01496 return -1.0;
01497 }
01498 else
01499 {
01500 return long_max + 1;
01501 }
01502 }
01503
01504 QString AdjustColumnRowManipulator::name() const
01505 {
01506 if (m_adjustColumn && m_adjustRow)
01507 {
01508 return i18n("Adjust Columns/Rows");
01509 }
01510 else if (m_adjustColumn)
01511 {
01512 return i18n("Adjust Columns");
01513 }
01514 else
01515 {
01516 return i18n("Adjust Rows");
01517 }
01518 }
01519
01520
01521
01522
01523
01524
01525
01526 HideShowManipulator::HideShowManipulator()
01527 : m_manipulateColumns(false),
01528 m_manipulateRows(false)
01529 {
01530 }
01531
01532 HideShowManipulator::~HideShowManipulator()
01533 {
01534 }
01535
01536 bool HideShowManipulator::process(Element* element)
01537 {
01538 QRect range = element->rect().normalize();
01539 if (m_manipulateColumns)
01540 {
01541 for (int col = range.left(); col <= range.right(); ++col)
01542 {
01543 ColumnFormat* format = m_sheet->nonDefaultColumnFormat(col);
01544 format->setHide(!m_reverse);
01545 }
01546 }
01547 if (m_manipulateRows)
01548 {
01549 for (int row = range.top(); row <= range.bottom(); ++row)
01550 {
01551 RowFormat* format = m_sheet->nonDefaultRowFormat(row);
01552 format->setHide(!m_reverse);
01553 }
01554 }
01555 return true;
01556 }
01557
01558 bool HideShowManipulator::preProcessing()
01559 {
01560 Region region;
01561 ConstIterator endOfList = cells().constEnd();
01562 for (ConstIterator it = cells().constBegin(); it != endOfList; ++it)
01563 {
01564 if (m_reverse)
01565 {
01566 QRect range = (*it)->rect().normalize();
01567 if (m_manipulateColumns)
01568 {
01569 if (range.left() > 1)
01570 {
01571 int col;
01572 for (col = 1; col < range.left(); ++col)
01573 {
01574 ColumnFormat* format = m_sheet->columnFormat(col);
01575 if (!format->isHide())
01576 {
01577 break;
01578 }
01579 }
01580 if (col == range.left())
01581 {
01582 region.add(QRect(1, 1, range.left()-1, KS_rowMax));
01583 }
01584 }
01585 for (int col = range.left(); col <= range.right(); ++col)
01586 {
01587 ColumnFormat* format = m_sheet->columnFormat(col);
01588 if (format->isHide())
01589 {
01590 region.add(QRect(col, 1, 1, KS_rowMax));
01591 }
01592 }
01593 }
01594 if (m_manipulateRows)
01595 {
01596 if (range.top() > 1)
01597 {
01598 int row;
01599 for (row = 1; row < range.top(); ++row)
01600 {
01601 RowFormat* format = m_sheet->rowFormat(row);
01602 if (!format->isHide())
01603 {
01604 break;
01605 }
01606 }
01607 if (row == range.top())
01608 {
01609 region.add(QRect(1, 1, KS_colMax, range.top()-1));
01610 }
01611 }
01612 for (int row = range.top(); row <= range.bottom(); ++row)
01613 {
01614 RowFormat* format = m_sheet->rowFormat(row);
01615 if (format->isHide())
01616 {
01617 region.add(QRect(1, row, KS_colMax, 1));
01618 }
01619 }
01620 }
01621 }
01622
01623 if (((*it)->isRow() && m_manipulateColumns) ||
01624 ((*it)->isColumn() && m_manipulateRows))
01625 {
01626
01627 return false;
01628 }
01629 }
01630
01631 if (m_reverse)
01632 {
01633 clear();
01634 add(region);
01635 }
01636
01637 return true;
01638 }
01639
01640 bool HideShowManipulator::postProcessing()
01641 {
01642 if (m_manipulateColumns)
01643 {
01644 m_sheet->emitHideColumn();
01645 }
01646 if (m_manipulateRows)
01647 {
01648 m_sheet->emitHideRow();
01649 }
01650
01651 return true;
01652 }
01653
01654 QString HideShowManipulator::name() const
01655 {
01656 QString name;
01657 if (m_reverse)
01658 {
01659 name = "Show ";
01660 }
01661 else
01662 {
01663 name = "Hide ";
01664 }
01665 if (m_manipulateColumns)
01666 {
01667 name += "Columns";
01668 }
01669 if (m_manipulateColumns && m_manipulateRows)
01670 {
01671 name += "/";
01672 }
01673 if (m_manipulateRows)
01674 {
01675 name += "Rows";
01676 }
01677 return name;
01678 }
01679
01680
01681
01682
01683
01684
01685
01686
01687 ManipulatorManager* ManipulatorManager::m_self = 0;
01688 static KStaticDeleter<ManipulatorManager> staticManipulatorManagerDeleter;
01689
01690 ManipulatorManager* ManipulatorManager::self()
01691 {
01692 if (!m_self)
01693 {
01694 staticManipulatorManagerDeleter.setObject(m_self, new ManipulatorManager());
01695 }
01696 return m_self;
01697 }
01698
01699 ManipulatorManager::ManipulatorManager()
01700 {
01701 }
01702
01703 ManipulatorManager::~ManipulatorManager()
01704 {
01705 }
01706
01707 Manipulator* ManipulatorManager::create(const QString& type)
01708 {
01709 if (type == "bgcolor")
01710 {
01711 kdDebug() << "Background color manipulator created." << endl;
01712
01713 }
01714 else if (type == "textcolor")
01715 {
01716 kdDebug() << "Text color manipulator created." << endl;
01717
01718 }
01719
01720
01721 kdError() << "Unknown manipulator!" << endl;
01722 return 0;
01723 }