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