kspread

manipulator.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
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 //BEGIN Non-contiguous selection adaption todos
00044 // TODO Stefan: InsertColumn
00045 // TODO Stefan: InsertRow
00046 // TODO Stefan: DeleteColumn
00047 // TODO Stefan: DeleteRow
00048 
00049 // TODO Stefan: SortInc
00050 // TODO Stefan: SortDec
00051 // TODO Stefan: FillSelection ?
00052 
00053 // TODO Stefan: RemoveComment (works, but not a manipulator yet)
00054 // TODO Stefan: ClearText (works, but not a manipulator yet)
00055 // TODO Stefan: ClearValidity (works, but not a manipulator yet)
00056 // TODO Stefan: Validity (works, but not a manipulator yet)
00057 // TODO Stefan: Conditional (works, but not a manipulator yet)
00058 // TODO Stefan: Copy (works, but not a manipulator yet)
00059 // TODO Stefan: Delete (works, but not a manipulator yet)
00060 // TODO Stefan: Cut (works, but not a manipulator yet)
00061 // TODO Stefan: Paste (works, but not a manipulator yet)
00062 // TODO Stefan: Paste Special (works, but not a manipulator yet)
00063 // TODO Stefan: Paste with insertion (works, but not a manipulator yet)
00064 
00065 // TODO Stefan: more ????
00066 //END
00067 
00068 
00069 //BEGIN NOTE Stefan: some words on operations
00070 //
00071 // 1. SubTotal
00072 // a) Makes no sense to extend to non-contiguous selections (NCS) as
00073 //    it refers to a change in one column.
00074 // b) No special undo command available yet.
00075 //
00076 // 2. AutoSum
00077 // a) should insert cell at the end of the selection, if the last
00078 //    is not empty
00079 // b) opens an editor, if the user's intention is fuzzy -> hard to
00080 //    convert to NCS
00081 //END
00082 
00083 /***************************************************************************
00084   class Manipulator
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;   // do nothing if pre-processing fails
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   // add me to undo if needed
00147   if (m_firstrun && m_register)
00148   {
00149     // addCommand itself checks for undo lock
00150     m_sheet->doc()->addCommand (this);
00151     // if we add something to undo, then the document surely is modified ...
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; // TODO Stefan: element->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         // TODO Stefan: process cells with this property
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         // TODO Stefan: process cells with this property
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 /* (Tomas) don't force working on obscurring cells - most manipulators don't want this, and those that do can do that manually ... Plus I think that no manipulator should do it anyway ...
00202         if ( cell->isPartOfMerged() )
00203         {
00204           cell = cell->obscuringCells().first();
00205         }
00206 */
00207         //if (testCondition(cell))
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   class FormatManipulator
00231 ****************************************************************************/
00232 
00233 FormatManipulator::FormatManipulator()
00234 {
00235   m_properties = 0;
00236   // initialize pens with invalid color
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   // see what is selected; if nothing, take marker position
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     // create cells in rows if complete columns selected
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     // complete rows selected ?
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     // complete columns selected ?
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     // cell region selected
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   {  // undoing
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       /* Don't need to go through the loop twice...
00442         for (int i = range.left(); i <= right; ++i)
00443         {
00444         layoutColumn tmplayout;
00445         tmplayout.col = i;
00446         tmplayout.l = new ColumnFormat( m_sheet, i );
00447         tmplayout.l->copy( *(m_sheet->columnFormat( i )) );
00448         listCol.append(tmplayout);
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         Cell * cell = m_sheet->firstCell();
00480         for( ; cell; cell = cell->nextCell() )
00481         {
00482         int col = cell->column();
00483         if ( range.left() <= col && right >= col
00484             && !cell->isPartOfMerged())
00485         {
00486           layoutCell tmplayout;
00487           tmplayout.col = cell->column();
00488           tmplayout.row = cell->row();
00489           tmplayout.l = new Format( m_sheet, 0 );
00490           tmplayout.l->copy( *(m_sheet->cellAt( tmplayout.col, tmplayout.row )) );
00491           list.append(tmplayout);
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         Cell * cell = m_sheet->firstCell();
00526         for( ; cell; cell = cell->nextCell() )
00527         {
00528         int row = cell->row();
00529         if ( range.top() <= row && bottom >= row
00530             && !cell->isPartOfMerged())
00531         {
00532           layoutCell tmplayout;
00533           tmplayout.col = cell->column();
00534           tmplayout.row = cell->row();
00535           tmplayout.l = new Format( m_sheet, 0 );
00536           tmplayout.l->copy( *(m_sheet->cellAt( tmplayout.col, tmplayout.row )) );
00537           list.append(tmplayout);
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   // SetSelectionFontWorker
00581   // SetSelectionSizeWorker
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   // SetSelectionAngleWorker
00598   if (m_properties & Format::PAngle)
00599   {
00600     format->setAngle( m_angle );
00601   }
00602   // SetSelectionTextColorWorker
00603   if (m_properties & Format::PTextPen)
00604   {
00605     format->setTextColor( m_textColor );
00606   }
00607   // SetSelectionBgColorWorker
00608   if (m_properties & Format::PBackgroundColor)
00609   {
00610     format->setBgColor( m_backgroundColor );
00611   }
00612   // SetSelectionBorderAllWorker
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   // SetSelectionAlignWorker
00690   if (m_properties & Format::PAlign)
00691   {
00692     format->setAlign( m_horAlign );
00693   }
00694   // SetSelectionAlignYWorker
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     //TODO
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   class MergeManipulator
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     // TODO Stefan: remove these elements?!
00808     return true;
00809   }
00810 
00811   // sanity check
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 // dissociate
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) // MergeManipulator
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     // reduce the region to the region occupied by merged cells
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) // MergeManipulator
00950     {
00951       // we're in the manipulator's first execution
00952       // initialize the undo manipulator
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 // DissociateManipulator
00963     {
00964       clear();
00965       add(mergedCells);
00966     }
00967   }
00968 
00969   if (m_merge) // MergeManipulator
00970   {
00971     if (m_reverse) // dissociate
00972     {
00973     }
00974     else // merge
00975     {
00976       // Dissociate cells before merging the whole region.
00977       // For horizontal/vertical merging the cells stay
00978       // as they are. E.g. the region contains a merged cell
00979       // occupying two rows. Then the horizontal merge should
00980       // keep the height of two rows and extend the merging to the
00981       // region's width. In this case the unmerging is done while
00982       // processing each region element.
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) // MergeManipulator
00995   {
00996     if (m_reverse) // dissociate
00997     {
00998       // restore the old merge status
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   class DilationManipulator
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   //look at if column is hiding.
01051   //if it's hiding refreshing column+1 (or column -1 )
01052   int left = area.left();
01053   int right = area.right();
01054   int top = area.top();
01055   int bottom = area.bottom();
01056 
01057   // a merged cells is selected
01058   if (element->type() == Region::Element::Point)
01059   {
01060     Cell* cell = m_sheet->cellAt(left, top);
01061     if (cell->doesMergeCells())
01062     {
01063       // extend to the merged region
01064       // prevents artefacts of the selection rectangle
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   class ResizeColumnManipulator
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   class ResizeRowManipulator
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   class AdjustColumnRowManipulator
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; // TODO Stefan: element->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 //     createUndo();
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   // add 4 because long_max is the length of the text
01466   // but column has borders
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   //  add 1 because long_max is the height of the text
01489   //  but row has borders
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   class HideShowManipulator
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 /*      KMessageBox::error( this, i18n( "Area is too large." ) );*/
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   class ManipulatorManager
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 //     return new FontColorManipulator();
01709   }
01710   else if (type == "textcolor")
01711   {
01712     kdDebug() << "Text color manipulator created." << endl;
01713 //     return new FontColorManipulator();
01714   }
01715 
01716   // no manipulator of this type found
01717   kdError() << "Unknown manipulator!" << endl;
01718   return 0;
01719 }
KDE Home | KDE Accessibility Home | Description of Access Keys