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