kspread

kspread_sheetprint.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>,
00003    2003 Philipp Mller <philipp.mueller@gmx.de>
00004    2005 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "kspread_sheet.h"
00023 #include "selection.h"
00024 #include "kspread_locale.h"
00025 #include "kspread_doc.h"
00026 #include "kspread_undo.h"
00027 
00028 #include "kspread_sheetprint.h"
00029 
00030 #include "commands.h"
00031 #include <KoDocumentInfo.h>
00032 
00033 #include <kmessagebox.h>
00034 #include <kprinter.h>
00035 #include <kdebug.h>
00036 
00037 #include <qregexp.h>
00038 
00039 #include <pwd.h>
00040 #include <unistd.h>
00041 
00042 #include "kspread_sheetprint.moc"
00043 
00044 #define NO_MODIFICATION_POSSIBLE \
00045 do { \
00046   KMessageBox::error( 0, i18n ( "You cannot change a protected sheet" ) ); return; \
00047 } while(0)
00048 
00049 using namespace KSpread;
00050 
00051 SheetPrint::SheetPrint( Sheet* sheet )
00052 {
00053     m_pSheet = sheet;
00054     m_pDoc = m_pSheet->doc();
00055 
00056     m_bPrintGrid = false;
00057     m_bPrintCommentIndicator = false;
00058     m_bPrintFormulaIndicator = false;
00059     m_bPrintObjects = true;
00060     m_bPrintCharts = true;
00061     m_bPrintGraphics = true;
00062 
00063     m_leftBorder = 20.0;
00064     m_rightBorder = 20.0;
00065     m_topBorder = 20.0;
00066     m_bottomBorder = 20.0;
00067 
00068     m_paperFormat = KoPageFormat::defaultFormat();
00069     m_orientation = PG_PORTRAIT;
00070     m_paperWidth = MM_TO_POINT( KoPageFormat::width( m_paperFormat, m_orientation ) );
00071     m_paperHeight = MM_TO_POINT( KoPageFormat::height( m_paperFormat, m_orientation ) );
00072     m_printRange = QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) );
00073     m_lnewPageListX.append( 1 );
00074     m_lnewPageListY.append( 1 );
00075     m_maxCheckedNewPageX = 1;
00076     m_maxCheckedNewPageY = 1;
00077     m_dPrintRepeatColumnsWidth = 0.0;
00078     m_dPrintRepeatRowsHeight = 0.0;
00079     m_printRepeatColumns = qMakePair( 0, 0 );
00080     m_printRepeatRows = qMakePair( 0, 0 );
00081     m_dZoom = 1.0;
00082     m_iPageLimitX = 0;
00083     m_iPageLimitY = 0;
00084 
00085     calcPaperSize();
00086 }
00087 
00088 SheetPrint::~SheetPrint()
00089 {
00090   // nothing todo yet
00091 }
00092 
00093 QString SheetPrint::saveOasisSheetStyleLayout( KoGenStyles &mainStyles )
00094 {
00095     KoGenStyle pageLayout( KoGenStyle::STYLE_PAGELAYOUT );
00096     //pageLayout.addAttribute( "style:page-usage", "all" ); FIXME
00097     pageLayout.addPropertyPt( "fo:page-width", MM_TO_POINT( paperWidth() ) );
00098     pageLayout.addPropertyPt( "fo:page-height", MM_TO_POINT( paperHeight() ) );
00099     pageLayout.addProperty( "style:print-orientation", orientation() == PG_LANDSCAPE ? "landscape" : "portrait" );
00100     pageLayout.addPropertyPt( "fo:margin-left", MM_TO_POINT(leftBorder() ) );
00101     pageLayout.addPropertyPt( "fo:margin-top", MM_TO_POINT(topBorder() ) );
00102     pageLayout.addPropertyPt( "fo:margin-right", MM_TO_POINT(rightBorder() ) );
00103     pageLayout.addPropertyPt( "fo:margin-bottom", MM_TO_POINT(bottomBorder() ) );
00104     //necessary for print setup
00105     m_pSheet->saveOasisPrintStyleLayout( pageLayout );
00106 
00107     return mainStyles.lookup( pageLayout, "pm" );
00108 }
00109 
00110 
00111 QRect SheetPrint::cellsPrintRange()
00112 {
00113     // Find maximum right/bottom cell with content
00114     QRect cell_range;
00115     cell_range.setCoords( 1, 1, 1, 1 );
00116 
00117     Cell* c = m_pSheet->firstCell();
00118     for( ;c; c = c->nextCell() )
00119     {
00120         if ( c->needsPrinting() )
00121         {
00122             if ( c->column() > cell_range.right() )
00123                 cell_range.setRight( c->column() );
00124             if ( c->row() > cell_range.bottom() )
00125                 cell_range.setBottom( c->row() );
00126         }
00127     }
00128 
00129     // Now look at the children
00130     QPtrListIterator<KoDocumentChild> cit( m_pDoc->children() );
00131     double dummy;
00132     int i;
00133     for( ; cit.current(); ++cit )
00134     {
00135         //QRect, because KoChild doesn't use KoRect yet
00136         QRect bound = cit.current()->boundingRect();
00137 
00138         i = m_pSheet->leftColumn( bound.right(), dummy );
00139         if ( i > cell_range.right() )
00140             cell_range.setRight( i );
00141 
00142         i = m_pSheet->topRow( bound.bottom(), dummy );
00143         if ( i > cell_range.bottom() )
00144             cell_range.setBottom( i );
00145     }
00146     cell_range = cell_range.intersect( m_printRange );
00147 
00148     return cell_range;
00149 }
00150 
00151 int SheetPrint::pagesX( const QRect& cellsPrintRange )
00152 {
00153     int pages = 0;
00154 
00155     updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( cellsPrintRange.right() ) + prinsheetWidthPts() ) );
00156 
00157     for( int i = cellsPrintRange.left(); i <= cellsPrintRange.right(); i++  )
00158     {
00159         if( isOnNewPageX( i ) )
00160             pages++;
00161     }
00162     return pages;
00163 }
00164 
00165 int SheetPrint::pagesY( const QRect& cellsPrintRange )
00166 {
00167     int pages = 0;
00168 
00169     updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( cellsPrintRange.bottom() ) + prinsheetHeightPts() ) );
00170 
00171     for( int i = cellsPrintRange.top(); i <= cellsPrintRange.bottom(); i++  )
00172     {
00173         if( isOnNewPageY( i ) )
00174             pages++;
00175     }
00176     return pages;
00177 }
00178 
00179 
00180 bool SheetPrint::pageNeedsPrinting( QRect& page_range )
00181 {
00182    // bool filled = false;
00183 
00184     // Look at the cells
00185     for( int r = page_range.top();  r <= page_range.bottom() ; ++r )
00186         for( int c = page_range.left();  c <= page_range.right() ; ++c )
00187             if ( m_pSheet->cellAt( c, r )->needsPrinting() )
00188         {
00189             return true;
00190         }
00191                // filled = true;
00192 
00193     //Page empty, but maybe children on it?
00194     
00195         QRect intView = QRect( QPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.left() ) ),
00196                                        m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.top() ) ) ),
00197                                QPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.right() ) +
00198                                                         m_pSheet->columnFormat( page_range.right() )->dblWidth() ),
00199                                        m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.bottom() ) +
00200                                                         m_pSheet->rowFormat( page_range.bottom() )->dblHeight() ) ) );
00201 
00202         QPtrListIterator<KoDocumentChild> it( m_pDoc->children() );
00203         for( ;it.current(); ++it )
00204         {
00205             QRect bound = it.current()->boundingRect();
00206             if ( bound.intersects( intView ) )
00207         {
00208                 return true;
00209         }
00210         //filled = true;
00211         }
00212     
00213 
00214     //Page has no visible content on it, so we don't need to paint it
00215     return false;
00216 }
00217 
00218 bool SheetPrint::print( QPainter &painter, KPrinter *_printer )
00219 {
00220     kdDebug(36001)<<"PRINTING ...."<<endl;
00221 
00222     // Override the current grid pen setting, when set to disable
00223     QPen gridPen;
00224     bool oldShowGrid = m_pSheet->getShowGrid();
00225     m_pSheet->setShowGrid( m_bPrintGrid );
00226     if ( !m_bPrintGrid )
00227     {
00228         gridPen = QPen( m_pDoc->gridColor(), 1, Qt::SolidLine );
00229         QPen nopen;
00230         nopen.setStyle( NoPen );
00231         m_pDoc->setGridColor( Qt::white );
00232     }
00233 
00234     //Update m_dPrintRepeatColumnsWidth for repeated columns
00235     //just in case it isn't done yet
00236     if ( !m_pSheet->isShowPageBorders() && m_printRepeatColumns.first != 0 )
00237         updatePrintRepeatColumnsWidth();
00238 
00239     //Update m_dPrintRepeatRowsHeight for repeated rows
00240     //just in case it isn't done yet
00241     if ( !m_pSheet->isShowPageBorders() && m_printRepeatRows.first != 0 )
00242         updatePrintRepeatRowsHeight();
00243 
00244     //Calculate the range to be printed
00245     QRect cell_range = cellsPrintRange();
00246     kdDebug()<<"cellsPrintRange() :"<<cellsPrintRange()<<endl;
00247     //Ensure, that our newPage lists are generated for the whole sheet to print
00248     //For this we add to the lists the width/height of 1 page
00249     updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( cell_range.right() ) + prinsheetWidthPts() ) );
00250     updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( cell_range.bottom() ) + prinsheetHeightPts() ) );
00251 
00252     // Find out how many pages need printing
00253     // and which cells to print on which page.
00254     QValueList<QRect> page_list;  //contains the cols and rows of a page
00255     QValueList<KoRect> page_frame_list;  //contains the coordinate range of a page
00256     QValueList<KoPoint> page_frame_list_offset;  //contains the offset of the not repeated area
00257 
00258     QValueList<PrintNewPageEntry>::iterator itX;
00259     QValueList<PrintNewPageEntry>::iterator itY;
00260     for( itX = m_lnewPageListX.begin(); itX != m_lnewPageListX.end(); ++itX )
00261     {
00262         for( itY = m_lnewPageListY.begin(); itY != m_lnewPageListY.end(); ++itY )
00263         {
00264             QRect page_range( QPoint( (*itX).startItem(), (*itY).startItem() ),
00265                               QPoint( (*itX).endItem(),   (*itY).endItem() ) );
00266             kdDebug()<<" page_range :"<<page_range<<endl;
00267             //Append page when there is something to print
00268             if ( pageNeedsPrinting( page_range ) )
00269             {
00270                 KoRect view = KoRect( KoPoint( m_pSheet->dblColumnPos( page_range.left() ),
00271                                                m_pSheet->dblRowPos( page_range.top() ) ),
00272                                       KoPoint( m_pSheet->dblColumnPos( page_range.right() ) +
00273                                                m_pSheet->columnFormat( page_range.right() )->dblWidth(),
00274                                                m_pSheet->dblRowPos( page_range.bottom() ) +
00275                                                m_pSheet->rowFormat( page_range.bottom() )->dblHeight() ) );
00276                 page_list.append( page_range );
00277                 page_frame_list.append( view );
00278                 page_frame_list_offset.append( KoPoint( (*itX).offset(), (*itY).offset() ) );
00279             }
00280         }
00281     }
00282 
00283 
00284     kdDebug(36001) << "PRINTING " << page_list.count() << " pages" << endl;
00285     m_uprintPages = page_list.count();
00286 
00287 
00288     //Cache all object so they only need to be repainted once.
00289     QPtrListIterator<EmbeddedObject> itObject( m_pDoc->embeddedObjects() );
00290     for ( ; itObject.current(); ++itObject )
00291     {
00292       EmbeddedObject *obj = itObject.current();
00293       if ( obj->sheet() != m_pSheet ||
00294            !( (( obj->getType() == OBJECT_KOFFICE_PART || obj->getType() == OBJECT_PICTURE ) && m_bPrintObjects) ||
00295            ( obj->getType() == OBJECT_CHART && m_bPrintCharts ) ) )
00296         continue;
00297 
00298       QRect zoomRect = m_pDoc->zoomRect( itObject.current()->geometry() );
00299       QPixmap *p = new QPixmap( zoomRect.size() );
00300       QPainter painter(p);
00301       painter.fillRect( p->rect(), QColor("white") );
00302       painter.translate( -zoomRect.x(), -zoomRect.y() ); //we cant to paint at (0,0)
00303       bool const isSelected = itObject.current()->isSelected();
00304       itObject.current()->setSelected( false );
00305       itObject.current()->draw( &painter );
00306       painter.end();
00307       itObject.current()->setSelected( isSelected );
00308 
00309       PrintObject *po = new PrintObject();
00310       m_printObjects.append( po );
00311       po->obj = itObject.current();
00312       po->p = p;
00313     }
00314 
00315     if ( page_list.count() == 0 )
00316     {
00317         // nothing to print
00318         painter.setPen( QPen( Qt::black, 1 ) );
00319         painter.drawPoint( 1, 1 );
00320     }
00321     else
00322     {
00323 
00324         int pageNo = 1;
00325 
00326         //
00327         // Print all pages in the list
00328         //
00329         QValueList<QRect>::Iterator it = page_list.begin();
00330         QValueList<KoRect>::Iterator fit = page_frame_list.begin();
00331         QValueList<KoPoint>::Iterator fito = page_frame_list_offset.begin();
00332 
00333         for( ; it != page_list.end(); ++it, ++fit, ++fito, ++pageNo )
00334         {
00335             painter.setClipRect( 0, 0, m_pDoc->zoomItX( paperWidthPts() ),
00336                                     m_pDoc->zoomItY( paperHeightPts() ) );
00337             printHeaderFooter( painter, pageNo );
00338 
00339             painter.translate( m_pDoc->zoomItX( leftBorderPts() ),
00340                             m_pDoc->zoomItY( topBorderPts() ) );
00341 
00342             // Print the page
00343             printPage( painter, *it, *fit, *fito );
00344 
00345             painter.translate( - m_pDoc->zoomItX( leftBorderPts() ),
00346                             - m_pDoc->zoomItY( topBorderPts()  ) );
00347 
00348             if ( pageNo < (int)page_list.count() )
00349                 _printer->newPage();
00350         }
00351     }
00352 
00353     if ( !m_bPrintGrid )
00354     {
00355         // Restore the grid pen
00356         m_pDoc->setGridColor( gridPen.color() );
00357     }
00358     m_pSheet->setShowGrid( oldShowGrid );
00359 
00360     QValueList<PrintObject *>::iterator it;
00361     for ( it = m_printObjects.begin(); it != m_printObjects.end(); ++it )
00362       delete (*it)->p;
00363     m_printObjects.clear();
00364 
00365     return ( page_list.count() > 0 );
00366 }
00367 
00368 void SheetPrint::printPage( QPainter &_painter, const QRect& page_range,
00369                                    const KoRect& view, const KoPoint _childOffset )
00370 {
00371       kdDebug(36001) << "Rect x=" << page_range.left() << " y=" << page_range.top() << ", r="
00372       << page_range.right() << " b="  << page_range.bottom() << "  offsetx: "<< _childOffset.x()
00373       << "  offsety: " << _childOffset.y() <<"  view-x: "<<view.x()<< endl;
00374 
00375     //Don't paint on the page borders
00376     QRegion clipRegion( m_pDoc->zoomItX( leftBorderPts() ),
00377                         m_pDoc->zoomItY( topBorderPts() ),
00378                         m_pDoc->zoomItX( view.width() + _childOffset.x() ),
00379                         m_pDoc->zoomItY( view.height() + _childOffset.y() ) );
00380     _painter.setClipRegion( clipRegion );
00381 
00382     //
00383     // Draw the cells.
00384     //
00385     //Check if we have to repeat some rows and columns (top left rect)
00386     if ( ( _childOffset.x() != 0.0 ) && ( _childOffset.y() != 0.0 ) )
00387     {
00388         //QRect(left,top,width,height)  <<<< WIDTH AND HEIGHT!!!
00389         QRect _printRect( m_printRepeatColumns.first, m_printRepeatRows.first,
00390                           m_printRepeatColumns.second - m_printRepeatColumns.first + 1,
00391                           m_printRepeatRows.second - m_printRepeatRows.first + 1);
00392         KoPoint _topLeft( 0.0, 0.0 );
00393 
00394         printRect( _painter, _topLeft, _printRect, view, clipRegion );
00395     }
00396 
00397     //Check if we have to repeat some rows (left rect)
00398     if ( _childOffset.y() != 0 )
00399     {
00400         QRect _printRect( page_range.left(), m_printRepeatRows.first,
00401                           page_range.right() - page_range.left() + 1,
00402                           m_printRepeatRows.second - m_printRepeatRows.first + 1);
00403         KoPoint _topLeft( _childOffset.x(), 0.0 );
00404 
00405         printRect( _painter, _topLeft, _printRect, view, clipRegion );
00406     }
00407 
00408     //Check if we have to repeat some columns (top right rect)
00409     if ( _childOffset.x() != 0 )
00410     {
00411         QRect _printRect( m_printRepeatColumns.first, page_range.top(),
00412                           m_printRepeatColumns.second - m_printRepeatColumns.first + 1,
00413                           page_range.bottom() - page_range.top() + 1);
00414         KoPoint _topLeft( 0.0, _childOffset.y() );
00415 
00416         printRect( _painter, _topLeft, _printRect, view, clipRegion );
00417     }
00418 
00419 
00420     //Print the cells (right data rect)
00421     KoPoint _topLeft( _childOffset.x(), _childOffset.y() );
00422 
00423     printRect( _painter, _topLeft, page_range, view, clipRegion );
00424 }
00425 
00426 
00427 void SheetPrint::printRect( QPainter& painter, const KoPoint& topLeft,
00428                                    const QRect& printRect, const KoRect& view,
00429                                    QRegion &clipRegion )
00430 {
00431     //
00432     // Draw the cells.
00433     //
00434     Cell *cell;
00435     RowFormat *row_lay;
00436     ColumnFormat *col_lay;
00437 
00438     double xpos;
00439     double ypos =  topLeft.y();
00440 
00441     int regionBottom = printRect.bottom();
00442     int regionRight  = printRect.right();
00443     int regionLeft   = printRect.left();
00444     int regionTop    = printRect.top();
00445 
00446     //Calculate the output rect
00447     KoPoint bottomRight( topLeft );
00448     for ( int x = regionLeft; x <= regionRight; ++x )
00449         bottomRight.setX( bottomRight.x()
00450                           + m_pSheet->columnFormat( x )->dblWidth() );
00451     for ( int y = regionTop; y <= regionBottom; ++y )
00452         bottomRight.setY( bottomRight.y()
00453                           + m_pSheet->rowFormat( y )->dblHeight() );
00454     KoRect rect( topLeft, bottomRight );
00455 
00456     QValueList<QPoint> mergedCellsPainted;
00457     for ( int y = regionTop; y <= regionBottom; ++y )
00458     {
00459         row_lay = m_pSheet->rowFormat( y );
00460         xpos = topLeft.x();
00461 
00462         for ( int x = regionLeft; x <= regionRight; ++x )
00463         {
00464             col_lay = m_pSheet->columnFormat( x );
00465 
00466             cell = m_pSheet->cellAt( x, y );
00467 
00468             bool paintBordersBottom = false;
00469             bool paintBordersRight = false;
00470             bool paintBordersLeft = false;
00471             bool paintBordersTop = false;
00472 
00473             QPen rightPen  = cell->effRightBorderPen( x, y );
00474             QPen leftPen   = cell->effLeftBorderPen( x, y );
00475             QPen bottomPen = cell->effBottomBorderPen( x, y );
00476             QPen topPen    = cell->effTopBorderPen( x, y );
00477 
00478             // paint right border if rightmost cell or if the pen is more "worth" than the left border pen
00479             // of the cell on the left or if the cell on the right is not painted. In the latter case get
00480             // the pen that is of more "worth"
00481             if ( x >= KS_colMax )
00482               paintBordersRight = true;
00483             else
00484               if ( x == regionRight )
00485               {
00486                 paintBordersRight = true;
00487                 if ( cell->effRightBorderValue( x, y ) < m_pSheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
00488                   rightPen = m_pSheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
00489               }
00490               else
00491               {
00492                 paintBordersRight = true;
00493                 if ( cell->effRightBorderValue( x, y ) < m_pSheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
00494                   rightPen = m_pSheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
00495               }
00496 
00497             // similiar for other borders...
00498             // bottom border:
00499             if ( y >= KS_rowMax )
00500               paintBordersBottom = true;
00501             else
00502               if ( y == regionBottom )
00503               {
00504                 paintBordersBottom = true;
00505                 if ( cell->effBottomBorderValue( x, y ) < m_pSheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) )
00506                   bottomPen = m_pSheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
00507               }
00508               else
00509               {
00510                 paintBordersBottom = true;
00511                 if ( cell->effBottomBorderValue( x, y ) < m_pSheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) )
00512                   bottomPen = m_pSheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
00513               }
00514 
00515             // left border:
00516             if ( x == 1 )
00517               paintBordersLeft = true;
00518             else
00519               if ( x == regionLeft )
00520               {
00521                 paintBordersLeft = true;
00522                 if ( cell->effLeftBorderValue( x, y ) < m_pSheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
00523                   leftPen = m_pSheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
00524               }
00525               else
00526               {
00527                 paintBordersLeft = true;
00528                 if ( cell->effLeftBorderValue( x, y ) < m_pSheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
00529                   leftPen = m_pSheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
00530               }
00531 
00532             // top border:
00533             if ( y == 1 )
00534               paintBordersTop = true;
00535             else
00536               if ( y == regionTop )
00537               {
00538                 paintBordersTop = true;
00539                 if ( cell->effTopBorderValue( x, y ) < m_pSheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
00540                   topPen = m_pSheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
00541               }
00542               else
00543               {
00544                 paintBordersTop = true;
00545                 if ( cell->effTopBorderValue( x, y ) < m_pSheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
00546                   topPen = m_pSheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
00547               }
00548           
00549           int paintBorder=Cell::Border_None;
00550           if (paintBordersLeft) paintBorder |= Cell::Border_Left;
00551           if (paintBordersRight) paintBorder |= Cell::Border_Right;
00552           if (paintBordersTop) paintBorder |= Cell::Border_Top;
00553           if (paintBordersBottom) paintBorder |= Cell::Border_Bottom;
00554           
00555           QPen highlightPen;
00556 
00557             if ( m_pSheet->layoutDirection()==Sheet::RightToLeft )
00558               cell->paintCell( rect, painter, NULL,
00559                                KoPoint( view.width() - xpos -
00560                                    col_lay->dblWidth(), ypos ), QPoint( x, y ),
00561                                paintBorder,
00562                                rightPen, bottomPen, leftPen, topPen,
00563                    mergedCellsPainted);
00564             else
00565               cell->paintCell( rect, painter, NULL,
00566                                KoPoint( xpos, ypos ), QPoint( x, y ),
00567                                paintBorder,
00568                                rightPen, bottomPen, leftPen, topPen,
00569                    mergedCellsPainted);
00570 
00571             xpos += col_lay->dblWidth();
00572         }
00573 
00574         ypos += row_lay->dblHeight();
00575     }
00576 
00577     //
00578     // Draw the children
00579     //
00580     QRect zoomedView = m_pDoc->zoomRect( view );
00581     //QPtrListIterator<KoDocumentChild> it( m_pDoc->children() );
00582     //QPtrListIterator<EmbeddedObject> itObject( m_pDoc->embeddedObjects() );
00583 
00584     QValueList<PrintObject *>::iterator itObject;
00585     for ( itObject = m_printObjects.begin(); itObject != m_printObjects.end(); ++itObject ) {
00586           EmbeddedObject *obj = (*itObject)->obj;
00587 //        QString tmp=QString("Testing child %1/%2 %3/%4 against view %5/%6 %7/%8")
00588 //        .arg(it.current()->contentRect().left())
00589 //        .arg(it.current()->contentRect().top())
00590 //        .arg(it.current()->contentRect().right())
00591 //        .arg(it.current()->contentRect().bottom())
00592 //        .arg(view.left()).arg(view.top()).arg(zoomedView.right()).arg(zoomedView.bottom());
00593 //        kdDebug(36001)<<tmp<<" offset "<<_childOffset.x()<<"/"<<_childOffset.y()<<endl;
00594 
00595           KoRect const bound = obj->geometry();
00596           QRect zoomedBound = m_pDoc->zoomRect( KoRect(bound.left(), bound.top(),
00597               bound.width(), 
00598               bound.height() ) );
00599 #if 1
00600 //         kdDebug(36001)  << "printRect(): Bounding rect of view: " << view
00601 //             << endl;
00602 //         kdDebug(36001)  << "printRect(): Bounding rect of zoomed view: "
00603 //             << zoomedView << endl;
00604 //         kdDebug(36001)  << "printRect(): Bounding rect of child: " << bound
00605 //             << endl;
00606 //         kdDebug(36001)  << "printRect(): Bounding rect of zoomed child: "
00607 //             << zoomedBound << endl;
00608 #endif
00609     if ( obj->sheet() == m_pSheet  && zoomedBound.intersects( zoomedView ) )
00610     {
00611             painter.save();
00612 
00613             painter.translate( -zoomedView.left() + m_pDoc->zoomItX( topLeft.x() ),
00614                                 -zoomedView.top() + m_pDoc->zoomItY( topLeft.y() ) );
00615 
00616             //obj->draw( &painter );
00617             painter.drawPixmap( m_pDoc->zoomRect( obj->geometry() ).topLeft(), *(*itObject)->p ); //draw the cached object
00618 
00619             //painter.fillRect(zoomedBound, QBrush("red")); //for debug purpose
00620             painter.restore();
00621         }
00622     }
00623 
00624     //Don't let obscuring cells and children overpaint this area
00625     clipRegion -= QRegion ( m_pDoc->zoomItX( leftBorderPts() + topLeft.x() ),
00626                             m_pDoc->zoomItY( topBorderPts() + topLeft.y() ),
00627                             m_pDoc->zoomItX( xpos ),
00628                             m_pDoc->zoomItY( ypos ) );
00629     painter.setClipRegion( clipRegion );
00630 }
00631 
00632 
00633 void SheetPrint::printHeaderFooter( QPainter &painter, int pageNo )
00634 {
00635     double w;
00636     double headFootDistance = MM_TO_POINT( 10.0 /*mm*/ ) / m_dZoom;
00637     QFont font( "Times" );
00638     font.setPointSizeFloat( 0.01 * m_pDoc->zoom() *
00639                             /* Font size of 10 */ 10.0 / m_dZoom );
00640     painter.setFont( font );
00641     QFontMetrics fm = painter.fontMetrics();
00642 
00643     // print head line left
00644     w = fm.width( headLeft( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
00645     if ( w > 0 )
00646         painter.drawText( m_pDoc->zoomItX( leftBorderPts() ),
00647                           m_pDoc->zoomItY( headFootDistance ),
00648                           headLeft( pageNo, m_pSheet->sheetName() ) );
00649     // print head line middle
00650     w = fm.width( headMid( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
00651     if ( w > 0 )
00652         painter.drawText( (int) ( m_pDoc->zoomItX( leftBorderPts() ) +
00653                           ( m_pDoc->zoomItX( prinsheetWidthPts() ) -
00654                             w ) / 2.0 ),
00655                           m_pDoc->zoomItY( headFootDistance ),
00656                           headMid( pageNo, m_pSheet->sheetName() ) );
00657     // print head line right
00658     w = fm.width( headRight( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
00659     if ( w > 0 )
00660         painter.drawText( m_pDoc->zoomItX( leftBorderPts() +
00661                                            prinsheetWidthPts() ) - (int) w,
00662                           m_pDoc->zoomItY( headFootDistance ),
00663                           headRight( pageNo, m_pSheet->sheetName() ) );
00664 
00665     // print foot line left
00666     w = fm.width( footLeft( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
00667     if ( w > 0 )
00668         painter.drawText( m_pDoc->zoomItX( leftBorderPts() ),
00669                           m_pDoc->zoomItY( paperHeightPts() - headFootDistance ),
00670                           footLeft( pageNo, m_pSheet->sheetName() ) );
00671     // print foot line middle
00672     w = fm.width( footMid( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
00673     if ( w > 0 )
00674         painter.drawText( (int) ( m_pDoc->zoomItX( leftBorderPts() ) +
00675                           ( m_pDoc->zoomItX( prinsheetWidthPts() ) -
00676                             w ) / 2.0 ),
00677                           m_pDoc->zoomItY( paperHeightPts() - headFootDistance ),
00678                           footMid( pageNo, m_pSheet->sheetName() ) );
00679     // print foot line right
00680     w = fm.width( footRight( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
00681     if ( w > 0 )
00682         painter.drawText( m_pDoc->zoomItX( leftBorderPts() +
00683                                            prinsheetWidthPts() ) -
00684                                            (int) w,
00685                           m_pDoc->zoomItY( paperHeightPts() - headFootDistance ),
00686                           footRight( pageNo, m_pSheet->sheetName() ) );
00687 }
00688 
00689 
00690 bool SheetPrint::isOnNewPageX( int _column )
00691 {
00692     if( _column > m_maxCheckedNewPageX )
00693         updateNewPageX( _column );
00694 
00695     //Are these the edges of the print range?
00696     if ( _column == m_printRange.left() || _column == m_printRange.right() + 1 )
00697     {
00698         return true;
00699     }
00700 
00701     //beyond the print range it's always false
00702     if ( _column < m_printRange.left() || _column > m_printRange.right() )
00703     {
00704         return false;
00705     }
00706 
00707     //Now check if we find the column already in the list
00708     if ( m_lnewPageListX.findIndex( _column ) != -1 )
00709     {
00710         if( _column > m_maxCheckedNewPageX )
00711             m_maxCheckedNewPageX = _column;
00712         return true;
00713     }
00714     return false;
00715 }
00716 
00717 
00718 void SheetPrint::updateNewPageX( int _column )
00719 {
00720     float offset = 0.0;
00721 
00722     //Are these the edges of the print range?
00723     if ( _column == m_printRange.left() || _column == m_printRange.right() + 1 )
00724     {
00725         if( _column > m_maxCheckedNewPageX )
00726             m_maxCheckedNewPageX = _column;
00727         return;
00728     }
00729 
00730     //We don't check beyond the print range
00731     if ( _column < m_printRange.left() || _column > m_printRange.right() )
00732     {
00733         if( _column > m_maxCheckedNewPageX )
00734             m_maxCheckedNewPageX = _column;
00735         if ( _column > m_printRange.right() )
00736         {
00737             if ( m_lnewPageListX.last().endItem()==0 )
00738                 m_lnewPageListX.last().setEndItem( m_printRange.right() );
00739         }
00740         return;
00741     }
00742 
00743     //If we start, then add the left printrange
00744     if ( m_lnewPageListX.empty() )
00745         m_lnewPageListX.append( m_printRange.left() ); //Add the first entry
00746 
00747     //If _column is greater than the last entry, we need to calculate the result
00748     if ( _column > m_lnewPageListX.last().startItem() &&
00749          _column > m_maxCheckedNewPageX ) //this columns hasn't been calculated before
00750     {
00751         int startCol = m_lnewPageListX.last().startItem();
00752         int col = startCol;
00753         double x = m_pSheet->columnFormat( col )->dblWidth();
00754 
00755         //Add repeated column width, when necessary
00756         if ( col > m_printRepeatColumns.first )
00757         {
00758             x += m_dPrintRepeatColumnsWidth;
00759             offset = m_dPrintRepeatColumnsWidth;
00760         }
00761 
00762         while ( ( col <= _column ) && ( col < m_printRange.right() ) )
00763         {
00764             if ( x > prinsheetWidthPts() ) //end of page?
00765             {
00766                 //We found a new page, so add it to the list
00767                 m_lnewPageListX.append( col );
00768 
00769                 //Now store into the previous entry the enditem and the width
00770                 QValueList<PrintNewPageEntry>::iterator it;
00771                 it = findNewPageColumn( startCol );
00772                 (*it).setEndItem( col - 1 );
00773                 (*it).setSize( x - m_pSheet->columnFormat( col )->dblWidth() );
00774                 (*it).setOffset( offset );
00775 
00776                 //start a new page
00777                 startCol = col;
00778                 if ( col == _column )
00779                 {
00780                     if( _column > m_maxCheckedNewPageX )
00781                         m_maxCheckedNewPageX = _column;
00782                     return;
00783                 }
00784                 else
00785                 {
00786                     x = m_pSheet->columnFormat( col )->dblWidth();
00787                     if ( col >= m_printRepeatColumns.first )
00788                     {
00789                         x += m_dPrintRepeatColumnsWidth;
00790                         offset = m_dPrintRepeatColumnsWidth;
00791                     }
00792                 }
00793             }
00794 
00795             col++;
00796             x += m_pSheet->columnFormat( col )->dblWidth();
00797         }
00798     }
00799 
00800     if( _column > m_maxCheckedNewPageX )
00801         m_maxCheckedNewPageX = _column;
00802 }
00803 
00804 
00805 bool SheetPrint::isOnNewPageY( int _row )
00806 {
00807     if( _row > m_maxCheckedNewPageY )
00808         updateNewPageY( _row );
00809 
00810     //Are these the edges of the print range?
00811     if ( _row == m_printRange.top() || _row == m_printRange.bottom() + 1 )
00812     {
00813         return true;
00814     }
00815 
00816      //beyond the print range it's always false
00817     if ( _row < m_printRange.top() || _row > m_printRange.bottom() )
00818     {
00819         return false;
00820     }
00821 
00822     //Now check if we find the row already in the list
00823     if ( m_lnewPageListY.findIndex( _row ) != -1 )
00824     {
00825         if( _row > m_maxCheckedNewPageY )
00826             m_maxCheckedNewPageY = _row;
00827         return true;
00828     }
00829 
00830     return false;
00831 }
00832 
00833 
00834 void SheetPrint::updateNewPageY( int _row )
00835 {
00836     float offset = 0.0;
00837 
00838     //Are these the edges of the print range?
00839     if ( _row == m_printRange.top() || _row == m_printRange.bottom() + 1 )
00840     {
00841         if( _row > m_maxCheckedNewPageY )
00842             m_maxCheckedNewPageY = _row;
00843         return;
00844     }
00845 
00846      //beyond the print range it's always false
00847     if ( _row < m_printRange.top() || _row > m_printRange.bottom() )
00848     {
00849         if( _row > m_maxCheckedNewPageY )
00850             m_maxCheckedNewPageY = _row;
00851         if ( _row > m_printRange.bottom() )
00852         {
00853             if ( m_lnewPageListY.last().endItem()==0 )
00854                 m_lnewPageListY.last().setEndItem( m_printRange.bottom() );
00855         }
00856         return;
00857     }
00858 
00859     //If we start, then add the top printrange
00860     if ( m_lnewPageListY.empty() )
00861         m_lnewPageListY.append( m_printRange.top() ); //Add the first entry
00862 
00863     //If _column is greater than the last entry, we need to calculate the result
00864     if ( _row > m_lnewPageListY.last().startItem() &&
00865          _row > m_maxCheckedNewPageY ) //this columns hasn't been calculated before
00866     {
00867         int startRow = m_lnewPageListY.last().startItem();
00868         int row = startRow;
00869         double y = m_pSheet->rowFormat( row )->dblHeight();
00870 
00871         //Add repeated row height, when necessary
00872         if ( row > m_printRepeatRows.first )
00873         {
00874             y += m_dPrintRepeatRowsHeight;
00875             offset = m_dPrintRepeatRowsHeight;
00876         }
00877 
00878         while ( ( row <= _row ) && ( row < m_printRange.bottom() ) )
00879         {
00880             if ( y > prinsheetHeightPts() )
00881             {
00882                 //We found a new page, so add it to the list
00883                 m_lnewPageListY.append( row );
00884 
00885                 //Now store into the previous entry the enditem and the width
00886                 QValueList<PrintNewPageEntry>::iterator it;
00887                 it = findNewPageRow( startRow );
00888                 (*it).setEndItem( row - 1 );
00889                 (*it).setSize( y - m_pSheet->rowFormat( row )->dblHeight() );
00890                 (*it).setOffset( offset );
00891 
00892                 //start a new page
00893                 startRow = row;
00894                 if ( row == _row )
00895                 {
00896                     if( _row > m_maxCheckedNewPageY )
00897                         m_maxCheckedNewPageY = _row;
00898                     return;
00899                 }
00900                 else
00901                 {
00902                     y = m_pSheet->rowFormat( row )->dblHeight();
00903                     if ( row >= m_printRepeatRows.first )
00904                     {
00905                         y += m_dPrintRepeatRowsHeight;
00906                         offset = m_dPrintRepeatRowsHeight;
00907                     }
00908                 }
00909             }
00910 
00911             row++;
00912             y += m_pSheet->rowFormat( row )->dblHeight();
00913         }
00914     }
00915 
00916     if( _row > m_maxCheckedNewPageY )
00917         m_maxCheckedNewPageY = _row;
00918 }
00919 
00920 
00921 void SheetPrint::updateNewPageListX( int _col )
00922 {
00923     //If the new range is after the first entry, we need to delete the whole list
00924     if ( m_lnewPageListX.first().startItem() != m_printRange.left() ||
00925          _col == 0 )
00926     {
00927         m_lnewPageListX.clear();
00928         m_maxCheckedNewPageX = m_printRange.left();
00929         m_lnewPageListX.append( m_printRange.left() );
00930         return;
00931     }
00932 
00933     if ( _col < m_lnewPageListX.last().startItem() )
00934     {
00935         //Find the page entry for this column
00936         QValueList<PrintNewPageEntry>::iterator it;
00937         it = m_lnewPageListX.find( _col );
00938         while ( ( it == m_lnewPageListX.end() ) && _col > 0 )
00939         {
00940             _col--;
00941             it = m_lnewPageListX.find( _col );
00942         }
00943 
00944         //Remove later pages
00945         while ( it != m_lnewPageListX.end() )
00946             it = m_lnewPageListX.remove( it );
00947 
00948         //Add default page when list is now empty
00949         if ( m_lnewPageListX.empty() )
00950             m_lnewPageListX.append( m_printRange.left() );
00951     }
00952 
00953     m_maxCheckedNewPageX = _col;
00954 }
00955 
00956 void SheetPrint::updateNewPageListY( int _row )
00957 {
00958     //If the new range is after the first entry, we need to delete the whole list
00959     if ( m_lnewPageListY.first().startItem() != m_printRange.top() ||
00960          _row == 0 )
00961     {
00962         m_lnewPageListY.clear();
00963         m_maxCheckedNewPageY = m_printRange.top();
00964         m_lnewPageListY.append( m_printRange.top() );
00965         return;
00966     }
00967 
00968     if ( _row < m_lnewPageListY.last().startItem() )
00969     {
00970         //Find the page entry for this row
00971         QValueList<PrintNewPageEntry>::iterator it;
00972         it = m_lnewPageListY.find( _row );
00973         while ( ( it == m_lnewPageListY.end() ) && _row > 0 )
00974         {
00975             _row--;
00976             it = m_lnewPageListY.find( _row );
00977         }
00978 
00979         //Remove later pages
00980         while ( it != m_lnewPageListY.end() )
00981             it = m_lnewPageListY.remove( it );
00982 
00983         //Add default page when list is now empty
00984         if ( m_lnewPageListY.empty() )
00985             m_lnewPageListY.append( m_printRange.top() );
00986     }
00987 
00988     m_maxCheckedNewPageY = _row;
00989 }
00990 
00991 void SheetPrint::definePrintRange( Selection* selectionInfo )
00992 {
00993     if ( !selectionInfo->isSingular() )
00994     {
00995         KCommand* command = new DefinePrintRangeCommand( m_pSheet );
00996         m_pDoc->addCommand( command );
00997         setPrintRange( selectionInfo->selection() );
00998     }
00999 }
01000 
01001 void SheetPrint::resetPrintRange ()
01002 {
01003     KCommand* command = new DefinePrintRangeCommand( m_pSheet );
01004     m_pDoc->addCommand( command );
01005     setPrintRange( QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) ) );
01006 }
01007 
01008 void SheetPrint::replaceHeadFootLineMacro ( QString &_text, const QString &_search, const QString &_replace )
01009 {
01010     if ( _search != _replace )
01011         _text.replace ( QString( "<" + _search + ">" ), "<" + _replace + ">" );
01012 }
01013 
01014 QString SheetPrint::localizeHeadFootLine ( const QString &_text )
01015 {
01016     QString tmp = _text;
01017 
01018     /*
01019       i18n:
01020       Please use the same words (even upper/lower case) as in
01021       KoPageLayoutDia.cc function setupTab2(), without the brakets "<" and ">"
01022     */
01023     replaceHeadFootLineMacro ( tmp, "page",   i18n("page") );
01024     replaceHeadFootLineMacro ( tmp, "pages",  i18n("pages") );
01025     replaceHeadFootLineMacro ( tmp, "file",   i18n("file") );
01026     replaceHeadFootLineMacro ( tmp, "name",   i18n("name") );
01027     replaceHeadFootLineMacro ( tmp, "time",   i18n("time") );
01028     replaceHeadFootLineMacro ( tmp, "date",   i18n("date") );
01029     replaceHeadFootLineMacro ( tmp, "author", i18n("author") );
01030     replaceHeadFootLineMacro ( tmp, "email",  i18n("email") );
01031     replaceHeadFootLineMacro ( tmp, "org",    i18n("org") );
01032     replaceHeadFootLineMacro ( tmp, "sheet",  i18n("sheet") );
01033 
01034     return tmp;
01035 }
01036 
01037 
01038 QString SheetPrint::delocalizeHeadFootLine ( const QString &_text )
01039 {
01040     QString tmp = _text;
01041 
01042     /*
01043       i18n:
01044       Please use the same words (even upper/lower case) as in
01045       KoPageLayoutDia.cc function setupTab2(), without the brakets "<" and ">"
01046     */
01047     replaceHeadFootLineMacro ( tmp, i18n("page"),   "page" );
01048     replaceHeadFootLineMacro ( tmp, i18n("pages"),  "pages" );
01049     replaceHeadFootLineMacro ( tmp, i18n("file"),   "file" );
01050     replaceHeadFootLineMacro ( tmp, i18n("name"),   "name" );
01051     replaceHeadFootLineMacro ( tmp, i18n("time"),   "time" );
01052     replaceHeadFootLineMacro ( tmp, i18n("date"),   "date" );
01053     replaceHeadFootLineMacro ( tmp, i18n("author"), "author" );
01054     replaceHeadFootLineMacro ( tmp, i18n("email"),  "email" );
01055     replaceHeadFootLineMacro ( tmp, i18n("org"),    "org" );
01056     replaceHeadFootLineMacro ( tmp, i18n("sheet"),  "sheet" );
01057 
01058     return tmp;
01059 }
01060 
01061 
01062 KoHeadFoot SheetPrint::headFootLine() const
01063 {
01064     KoHeadFoot hf;
01065     hf.headLeft  = m_headLeft;
01066     hf.headRight = m_headRight;
01067     hf.headMid   = m_headMid;
01068     hf.footLeft  = m_footLeft;
01069     hf.footRight = m_footRight;
01070     hf.footMid   = m_footMid;
01071 
01072     return hf;
01073 }
01074 
01075 
01076 void SheetPrint::setHeadFootLine( const QString &_headl, const QString &_headm, const QString &_headr,
01077                                          const QString &_footl, const QString &_footm, const QString &_footr )
01078 {
01079     if ( m_pSheet->isProtected() )
01080         NO_MODIFICATION_POSSIBLE;
01081 
01082     m_headLeft  = _headl;
01083     m_headRight = _headr;
01084     m_headMid   = _headm;
01085     m_footLeft  = _footl;
01086     m_footRight = _footr;
01087     m_footMid   = _footm;
01088 
01089     m_pDoc->setModified( true );
01090 }
01091 
01092 void SheetPrint::setPaperOrientation( KoOrientation _orient )
01093 {
01094     if ( m_pSheet->isProtected() )
01095         NO_MODIFICATION_POSSIBLE;
01096 
01097     m_orientation = _orient;
01098     calcPaperSize();
01099     updatePrintRepeatColumnsWidth();
01100     updatePrintRepeatRowsHeight();
01101     updateNewPageListX( m_printRange.left() ); //Reset the list
01102     updateNewPageListY( m_printRange.top() ); //Reset the list
01103 
01104     if( m_pSheet->isShowPageBorders() )
01105         emit sig_updateView( m_pSheet );
01106 }
01107 
01108 
01109 KoPageLayout SheetPrint::paperLayout() const
01110 {
01111     KoPageLayout pl;
01112     pl.format = m_paperFormat;
01113     pl.orientation = m_orientation;
01114     pl.ptWidth  =  m_paperWidth;
01115     pl.ptHeight =  m_paperHeight;
01116     pl.ptLeft   =  m_leftBorder;
01117     pl.ptRight  =  m_rightBorder;
01118     pl.ptTop    =  m_topBorder;
01119     pl.ptBottom =  m_bottomBorder;
01120     return pl;
01121 }
01122 
01123 
01124 void SheetPrint::setPaperLayout( float _leftBorder, float _topBorder,
01125                                         float _rightBorder, float _bottomBorder,
01126                                         KoFormat _paper,
01127                                         KoOrientation _orientation )
01128 {
01129     if ( m_pSheet->isProtected() )
01130         NO_MODIFICATION_POSSIBLE;
01131 
01132     m_leftBorder   = _leftBorder;
01133     m_rightBorder  = _rightBorder;
01134     m_topBorder    = _topBorder;
01135     m_bottomBorder = _bottomBorder;
01136     m_paperFormat  = _paper;
01137 
01138     setPaperOrientation( _orientation ); //calcPaperSize() is done here already
01139 
01140 //    QPtrListIterator<KoView> it( views() );
01141 //    for( ;it.current(); ++it )
01142 //    {
01143 //        View *v = static_cast<View *>( it.current() );
01144           // We need to trigger the appropriate repaintings in the cells near the
01145           // border of the page. The easiest way for this is to turn the borders
01146           // off and on (or on and off if they were off).
01147 //        bool bBorderWasShown = v->activeSheet()->isShowPageBorders();
01148 //        v->activeSheet()->setShowPageBorders( !bBorderWasShown );
01149 //        v->activeSheet()->setShowPageBorders( bBorderWasShown );
01150 //    }
01151 
01152     m_pDoc->setModified( true );
01153 }
01154 
01155 void SheetPrint::setPaperLayout( float _leftBorder, float _topBorder,
01156                                         float _rightBorder, float _bottomBorder,
01157                                         const QString& _paper,
01158                                         const QString& _orientation )
01159 {
01160     if ( m_pSheet->isProtected() )
01161         NO_MODIFICATION_POSSIBLE;
01162 
01163     KoFormat f = paperFormat();
01164     KoOrientation newOrientation = orientation();
01165 
01166     if ( _orientation == "Portrait" )
01167         newOrientation = PG_PORTRAIT;
01168     else if ( _orientation == "Landscape" )
01169         newOrientation = PG_LANDSCAPE;
01170 
01171 
01172     QString paper( _paper );
01173     if ( paper[0].isDigit() ) // Custom format
01174     {
01175         const int i = paper.find( 'x' );
01176         if ( i < 0 )
01177         {
01178             // We have nothing useful, so assume ISO A4
01179             f = PG_DIN_A4;
01180         }
01181         else
01182         {
01183             f = PG_CUSTOM;
01184             m_paperWidth  = paper.left(i).toFloat();
01185             m_paperHeight = paper.mid(i+1).toFloat();
01186             if ( m_paperWidth < 10.0 )
01187                 m_paperWidth = KoPageFormat::width( PG_DIN_A4, newOrientation );
01188             if ( m_paperHeight < 10.0 )
01189                 m_paperHeight = KoPageFormat::height( PG_DIN_A4, newOrientation );
01190         }
01191     }
01192     else
01193     {
01194         f = KoPageFormat::formatFromString( paper );
01195         if ( f == PG_CUSTOM )
01196             // We have no idea about height or width, therefore assume ISO A4
01197             f = PG_DIN_A4;
01198     }
01199     setPaperLayout( _leftBorder, _topBorder, _rightBorder, _bottomBorder, f, newOrientation );
01200 }
01201 
01202 void SheetPrint::calcPaperSize()
01203 {
01204     if ( m_paperFormat != PG_CUSTOM )
01205     {
01206         m_paperWidth = KoPageFormat::width( m_paperFormat, m_orientation );
01207         m_paperHeight = KoPageFormat::height( m_paperFormat, m_orientation );
01208     }
01209 }
01210 
01211 QValueList<PrintNewPageEntry>::iterator SheetPrint::findNewPageColumn( int col )
01212 {
01213     QValueList<PrintNewPageEntry>::iterator it;
01214     for( it = m_lnewPageListX.begin(); it != m_lnewPageListX.end(); ++it )
01215     {
01216         if( (*it).startItem() == col )
01217             return it;
01218     }
01219     return it;
01220 //                QValueList<PrintNewPageEntry>::iterator it;
01221 //                it = m_lnewPageListX.find( startCol );
01222 }
01223 
01224 QValueList<PrintNewPageEntry>::iterator SheetPrint::findNewPageRow( int row )
01225 {
01226     QValueList<PrintNewPageEntry>::iterator it;
01227     for( it = m_lnewPageListY.begin(); it != m_lnewPageListY.end(); ++it )
01228     {
01229         if( (*it).startItem() == row )
01230             return it;
01231     }
01232     return it;
01233 }
01234 
01235 
01236 QString SheetPrint::paperFormatString()const
01237 {
01238     if ( m_paperFormat == PG_CUSTOM )
01239     {
01240         QString tmp;
01241         tmp.sprintf( "%fx%f", m_paperWidth, m_paperHeight );
01242         return tmp;
01243     }
01244 
01245     return KoPageFormat::formatString( m_paperFormat );
01246 }
01247 
01248 const char* SheetPrint::orientationString() const
01249 {
01250     switch( m_orientation )
01251     {
01252     case KPrinter::Portrait:
01253         return "Portrait";
01254     case KPrinter::Landscape:
01255         return "Landscape";
01256     }
01257 
01258     kdWarning(36001)<<"SheetPrint: Unknown orientation, using now portrait"<<endl;
01259     return 0;
01260 }
01261 
01262 QString SheetPrint::completeHeading( const QString &_data, int _page, const QString &_sheet ) const
01263 {
01264     QString page( QString::number( _page) );
01265     QString pages( QString::number( m_uprintPages ) );
01266 
01267     QString pathFileName(m_pDoc->url().path());
01268     if ( pathFileName.isNull() )
01269         pathFileName="";
01270 
01271     QString fileName(m_pDoc->url().fileName());
01272     if( fileName.isNull())
01273         fileName="";
01274 
01275     QString t(QTime::currentTime().toString());
01276     QString d(QDate::currentDate().toString());
01277     QString ta;
01278     if ( !_sheet.isEmpty() )
01279         ta = _sheet;
01280 
01281     KoDocumentInfo * info = m_pDoc->documentInfo();
01282     KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author" ));
01283     QString full_name;
01284     QString email_addr;
01285     QString organization;
01286     QString tmp;
01287     if ( !authorPage )
01288         kdWarning() << "Author information not found in Document Info !" << endl;
01289     else
01290     {
01291         full_name = authorPage->fullName();
01292         email_addr = authorPage->email();
01293         organization = authorPage->company();
01294     }
01295 
01296     char hostname[80];
01297     struct passwd *p;
01298 
01299     p = getpwuid(getuid());
01300     gethostname(hostname, sizeof(hostname));
01301 
01302     if(full_name.isEmpty())
01303     full_name=p->pw_gecos;
01304 
01305     if( email_addr.isEmpty())
01306     email_addr = QString("%1@%2").arg(p->pw_name).arg(hostname);
01307 
01308     tmp = _data;
01309     int pos = 0;
01310     while ( ( pos = tmp.find( "<page>", pos ) ) != -1 )
01311         tmp.replace( pos, 6, page );
01312     pos = 0;
01313     while ( ( pos = tmp.find( "<pages>", pos ) ) != -1 )
01314         tmp.replace( pos, 7, pages );
01315     pos = 0;
01316     while ( ( pos = tmp.find( "<file>", pos ) ) != -1 )
01317         tmp.replace( pos, 6, pathFileName );
01318     pos = 0;
01319     while ( ( pos = tmp.find( "<name>", pos ) ) != -1 )
01320         tmp.replace( pos, 6, fileName );
01321     pos = 0;
01322     while ( ( pos = tmp.find( "<time>", pos ) ) != -1 )
01323         tmp.replace( pos, 6, t );
01324     pos = 0;
01325     while ( ( pos = tmp.find( "<date>", pos ) ) != -1 )
01326         tmp.replace( pos, 6, d );
01327     pos = 0;
01328     while ( ( pos = tmp.find( "<author>", pos ) ) != -1 )
01329         tmp.replace( pos, 8, full_name );
01330     pos = 0;
01331     while ( ( pos = tmp.find( "<email>", pos ) ) != -1 )
01332         tmp.replace( pos, 7, email_addr );
01333     pos = 0;
01334     while ( ( pos = tmp.find( "<org>", pos ) ) != -1 )
01335         tmp.replace( pos, 5, organization );
01336     pos = 0;
01337     while ( ( pos = tmp.find( "<sheet>", pos ) ) != -1 )
01338         tmp.replace( pos, 7, ta );
01339 
01340     return tmp;
01341 }
01342 
01343 void SheetPrint::setPrintRange( const QRect &_printRange )
01344 {
01345     if ( m_pSheet->isProtected() )
01346         NO_MODIFICATION_POSSIBLE;
01347 
01348 
01349     if ( m_printRange == _printRange )
01350         return;
01351 
01352     int oldLeft = m_printRange.left();
01353     int oldTop = m_printRange.top();
01354     m_printRange = _printRange;
01355 
01356     //Refresh calculation of stored page breaks, the lower one of old and new
01357     if ( oldLeft != _printRange.left() )
01358         updateNewPageListX( QMIN( oldLeft, _printRange.left() ) );
01359     if ( oldTop != _printRange.top() )
01360         updateNewPageListY( QMIN( oldTop, _printRange.top() ) );
01361 
01362     m_pDoc->setModified( true );
01363 
01364     emit sig_updateView( m_pSheet );
01365 
01366 }
01367 
01368 void SheetPrint::setPageLimitX( int pages )
01369 {
01370   //We do want an update in any case because the sheet content
01371   //could have changed, thus we need to recalculate although
01372   //it's the same setting!
01373 //     if( m_iPageLimitX == pages )
01374 //         return;
01375 
01376     m_iPageLimitX = pages;
01377 
01378     if( pages == 0 )
01379         return;
01380 
01381     calculateZoomForPageLimitX();
01382 }
01383 
01384 void SheetPrint::setPageLimitY( int pages )
01385 {
01386   //We do want an update in any case because the sheet content
01387   //could have changed, thus we need to recalculate although
01388   //it's the same setting!
01389 //     if( m_iPageLimitY == pages )
01390 //         return;
01391 
01392     m_iPageLimitY = pages;
01393 
01394     if( pages == 0 )
01395         return;
01396 
01397     calculateZoomForPageLimitY();
01398 }
01399 
01400 void SheetPrint::calculateZoomForPageLimitX()
01401 {
01402     kdDebug() << "Calculating zoom for X limit" << endl;
01403     if( m_iPageLimitX == 0 )
01404         return;
01405 
01406     double origZoom = m_dZoom;
01407 
01408     if( m_dZoom < 1.0 )
01409         m_dZoom = 1.0;
01410 
01411     QRect printRange = cellsPrintRange();
01412     updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( printRange.right() ) + prinsheetWidthPts() ) );
01413     int currentPages = pagesX( printRange );
01414     
01415     if (currentPages <= m_iPageLimitX)
01416         return;
01417     
01418     //calculating a factor for scaling the zoom down makes it lots faster
01419     double factor = (double)m_iPageLimitX/(double)currentPages +
01420                     1-(double)currentPages/((double)currentPages+1); //add possible error;
01421     kdDebug() << "Calculated factor for scaling m_dZoom: " << factor << endl;
01422     m_dZoom = m_dZoom*factor;
01423     
01424     kdDebug() << "New exact zoom: " << m_dZoom << endl;
01425     
01426     if (m_dZoom < 0.01)
01427         m_dZoom = 0.01;
01428     if (m_dZoom > 1.0)
01429         m_dZoom = 1.0;
01430     
01431     m_dZoom = (((int)(m_dZoom*100 + 0.5))/100.0);
01432     
01433     kdDebug() << "New rounded zoom: " << m_dZoom << endl;
01434     
01435     updatePrintRepeatColumnsWidth();
01436     updateNewPageListX( 0 );
01437     updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( printRange.right() ) + prinsheetWidthPts() ) );
01438     currentPages = pagesX( printRange );
01439     
01440     kdDebug() << "Number of pages with this zoom: " << currentPages << endl;
01441     
01442     while( ( currentPages > m_iPageLimitX ) && ( m_dZoom > 0.01 ) )
01443     {
01444         m_dZoom -= 0.01;
01445         updatePrintRepeatColumnsWidth();
01446         updateNewPageListX( 0 );
01447         updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( printRange.right() ) + prinsheetWidthPts() ) );
01448         currentPages = pagesX( printRange );
01449         kdDebug() << "Looping -0.01; current zoom: " << m_dZoom << endl;
01450     }
01451 
01452     if ( m_dZoom < origZoom )
01453     {
01454         double newZoom = m_dZoom;
01455         m_dZoom += 1.0; //set it to something different
01456         setZoom( newZoom, false );
01457     }
01458     else
01459         m_dZoom = origZoom;
01460 }
01461 
01462 void SheetPrint::calculateZoomForPageLimitY()
01463 {
01464     kdDebug() << "Calculating zoom for Y limit" << endl;
01465     if( m_iPageLimitY == 0 )
01466         return;
01467 
01468     double origZoom = m_dZoom;
01469 
01470     if( m_dZoom < 1.0 )
01471         m_dZoom = 1.0;
01472 
01473     QRect printRange = cellsPrintRange();
01474     updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( printRange.bottom() ) + prinsheetHeightPts() ) );
01475     int currentPages = pagesY( printRange );
01476     
01477     if (currentPages <= m_iPageLimitY)
01478         return;
01479     
01480     double factor = (double)m_iPageLimitY/(double)currentPages +
01481                     1-(double)currentPages/((double)currentPages+1); //add possible error
01482     kdDebug() << "Calculated factor for scaling m_dZoom: " << factor << endl;
01483     m_dZoom = m_dZoom*factor;
01484     
01485     kdDebug() << "New exact zoom: " << m_dZoom << endl;
01486     
01487     if (m_dZoom < 0.01)
01488         m_dZoom = 0.01;
01489     if (m_dZoom > 1.0)
01490         m_dZoom = 1.0;
01491     
01492     m_dZoom = (((int)(m_dZoom*100 + 0.5))/100.0);
01493     
01494     kdDebug() << "New rounded zoom: " << m_dZoom << endl;
01495     
01496     updatePrintRepeatRowsHeight();
01497     updateNewPageListY( 0 );
01498     updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( printRange.bottom() ) + prinsheetHeightPts() ) );
01499     currentPages = pagesY( printRange );
01500     
01501     kdDebug() << "Number of pages with this zoom: " << currentPages << endl;
01502     
01503     while( ( currentPages > m_iPageLimitY ) && ( m_dZoom > 0.01 ) )
01504     {
01505         m_dZoom -= 0.01;
01506         updatePrintRepeatRowsHeight();
01507         updateNewPageListY( 0 );
01508         updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( printRange.bottom() ) + prinsheetHeightPts() ) );
01509         currentPages = pagesY( printRange );
01510         kdDebug() << "Looping -0.01; current zoom: " << m_dZoom << endl;
01511     }
01512 
01513     if ( m_dZoom < origZoom )
01514     {
01515         double newZoom = m_dZoom;
01516         m_dZoom += 1.0; //set it to something different
01517         setZoom( newZoom, false );
01518     }
01519     else
01520         m_dZoom = origZoom;
01521 }
01522 
01523 void SheetPrint::setPrintGrid( bool _printGrid )
01524 {
01525    if ( m_bPrintGrid == _printGrid )
01526         return;
01527 
01528     m_bPrintGrid = _printGrid;
01529     m_pDoc->setModified( true );
01530 }
01531 
01532 void SheetPrint::setPrintObjects( bool _printObjects )
01533 {
01534   if ( m_bPrintObjects == _printObjects )
01535     return;
01536 
01537   m_bPrintObjects = _printObjects;
01538   m_pDoc->setModified( true );
01539 }
01540 
01541 void SheetPrint::setPrintCharts( bool _printCharts )
01542 {
01543   if ( m_bPrintCharts == _printCharts )
01544     return;
01545 
01546   m_bPrintCharts = _printCharts;
01547   m_pDoc->setModified( true );
01548 }
01549 
01550 void SheetPrint::setPrintGraphics( bool _printGraphics )
01551 {
01552   if ( m_bPrintGraphics == _printGraphics )
01553     return;
01554 
01555   m_bPrintGraphics = _printGraphics;
01556   m_pDoc->setModified( true );
01557 }
01558 
01559 void SheetPrint::setPrintCommentIndicator( bool _printCommentIndicator )
01560 {
01561     if ( m_bPrintCommentIndicator == _printCommentIndicator )
01562         return;
01563 
01564     m_bPrintCommentIndicator = _printCommentIndicator;
01565     m_pDoc->setModified( true );
01566 }
01567 
01568 void SheetPrint::setPrintFormulaIndicator( bool _printFormulaIndicator )
01569 {
01570     if( m_bPrintFormulaIndicator == _printFormulaIndicator )
01571         return;
01572 
01573     m_bPrintFormulaIndicator = _printFormulaIndicator;
01574     m_pDoc->setModified( true );
01575 }
01576 void SheetPrint::updatePrintRepeatColumnsWidth()
01577 {
01578     m_dPrintRepeatColumnsWidth = 0.0;
01579     if( m_printRepeatColumns.first != 0 )
01580     {
01581         for( int i = m_printRepeatColumns.first; i <= m_printRepeatColumns.second; i++ )
01582         {
01583             m_dPrintRepeatColumnsWidth += m_pSheet->columnFormat( i )->dblWidth();
01584         }
01585     }
01586 }
01587 
01588 void SheetPrint::updatePrintRepeatRowsHeight()
01589 {
01590     m_dPrintRepeatRowsHeight = 0.0;
01591     if ( m_printRepeatRows.first != 0 )
01592     {
01593         for ( int i = m_printRepeatRows.first; i <= m_printRepeatRows.second; i++)
01594         {
01595             m_dPrintRepeatRowsHeight += m_pSheet->rowFormat( i )->dblHeight();
01596         }
01597     }
01598 }
01599 
01600 
01601 void SheetPrint::setPrintRepeatColumns( QPair<int, int> _printRepeatColumns )
01602 {
01603     //Bring arguments in order
01604     if ( _printRepeatColumns.first > _printRepeatColumns.second )
01605     {
01606         int tmp = _printRepeatColumns.first;
01607         _printRepeatColumns.first = _printRepeatColumns.second;
01608         _printRepeatColumns.second = tmp;
01609     }
01610 
01611     //If old are equal to the new setting, nothing is to be done at all
01612     if ( m_printRepeatColumns == _printRepeatColumns )
01613         return;
01614 
01615     int oldFirst = m_printRepeatColumns.first;
01616     m_printRepeatColumns = _printRepeatColumns;
01617 
01618     //Recalcualte the space needed for the repeated columns
01619     updatePrintRepeatColumnsWidth();
01620 
01621     //Refresh calculation of stored page breaks, the lower one of old and new
01622     updateNewPageListX( QMIN( oldFirst, _printRepeatColumns.first ) );
01623 
01624     //Refresh view, if page borders are shown
01625     if ( m_pSheet->isShowPageBorders() )
01626         emit sig_updateView( m_pSheet );
01627 
01628     m_pDoc->setModified( true );
01629 }
01630 
01631 void SheetPrint::setPrintRepeatRows( QPair<int, int> _printRepeatRows )
01632 {
01633     //Bring arguments in order
01634     if ( _printRepeatRows.first > _printRepeatRows.second )
01635     {
01636         int tmp = _printRepeatRows.first;
01637         _printRepeatRows.first = _printRepeatRows.second;
01638         _printRepeatRows.second = tmp;
01639     }
01640 
01641     //If old are equal to the new setting, nothing is to be done at all
01642     if ( m_printRepeatRows == _printRepeatRows )
01643         return;
01644 
01645     int oldFirst = m_printRepeatRows.first;
01646     m_printRepeatRows = _printRepeatRows;
01647 
01648     //Recalcualte the space needed for the repeated rows
01649     updatePrintRepeatRowsHeight();
01650 
01651     //Refresh calculation of stored page breaks, the lower one of old and new
01652     updateNewPageListY( QMIN( oldFirst, _printRepeatRows.first ) );
01653 
01654     //Refresh view, if page borders are shown
01655     if ( m_pSheet->isShowPageBorders() )
01656         emit sig_updateView( m_pSheet );
01657 
01658     m_pDoc->setModified( true );
01659 }
01660 
01661 void SheetPrint::insertColumn( int col, int nbCol )
01662 {
01663     //update print range, when it has been defined
01664     if ( m_printRange != QRect( QPoint(1, 1), QPoint(KS_colMax, KS_rowMax) ) )
01665     {
01666         int left = m_printRange.left();
01667         int right = m_printRange.right();
01668 
01669         for( int i = 0; i <= nbCol; i++ )
01670         {
01671             if ( left >= col ) left++;
01672             if ( right >= col ) right++;
01673         }
01674         //Validity checks
01675         if ( left > KS_colMax ) left = KS_colMax;
01676         if ( right > KS_colMax ) right = KS_colMax;
01677         setPrintRange( QRect( QPoint( left, m_printRange.top() ),
01678                               QPoint( right, m_printRange.bottom() ) ) );
01679     }
01680 }
01681 
01682 void SheetPrint::insertRow( int row, int nbRow )
01683 {
01684     //update print range, when it has been defined
01685     if ( m_printRange != QRect( QPoint(1, 1), QPoint(KS_colMax, KS_rowMax) ) )
01686     {
01687         int top = m_printRange.top();
01688         int bottom = m_printRange.bottom();
01689 
01690         for( int i = 0; i <= nbRow; i++ )
01691         {
01692             if ( top >= row ) top++;
01693             if ( bottom >= row ) bottom++;
01694         }
01695         //Validity checks
01696         if ( top > KS_rowMax ) top = KS_rowMax;
01697         if ( bottom > KS_rowMax ) bottom = KS_rowMax;
01698         setPrintRange( QRect( QPoint( m_printRange.left(), top ),
01699                               QPoint( m_printRange.right(), bottom ) ) );
01700     }
01701 }
01702 
01703 void SheetPrint::removeColumn( int col, int nbCol )
01704 {
01705     //update print range, when it has been defined
01706     if ( m_printRange != QRect( QPoint(1, 1), QPoint(KS_colMax, KS_rowMax) ) )
01707     {
01708         int left = m_printRange.left();
01709         int right = m_printRange.right();
01710 
01711         for( int i = 0; i <= nbCol; i++ )
01712         {
01713             if ( left > col ) left--;
01714             if ( right >= col ) right--;
01715         }
01716         //Validity checks
01717         if ( left < 1 ) left = 1;
01718         if ( right < 1 ) right = 1;
01719         setPrintRange( QRect( QPoint( left, m_printRange.top() ),
01720                               QPoint( right, m_printRange.bottom() ) ) );
01721     }
01722 
01723     //update repeat columns, when it has been defined
01724     if ( m_printRepeatColumns.first != 0 )
01725     {
01726         int left = m_printRepeatColumns.first;
01727         int right = m_printRepeatColumns.second;
01728 
01729         for( int i = 0; i <= nbCol; i++ )
01730         {
01731             if ( left > col ) left--;
01732             if ( right >= col ) right--;
01733         }
01734         //Validity checks
01735         if ( left < 1 ) left = 1;
01736         if ( right < 1 ) right = 1;
01737         setPrintRepeatColumns ( qMakePair( left, right ) );
01738     }
01739 }
01740 
01741 void SheetPrint::removeRow( int row, int nbRow )
01742 {
01743     //update print range, when it has been defined
01744     if ( m_printRange != QRect( QPoint(1, 1), QPoint(KS_colMax, KS_rowMax) ) )
01745     {
01746         int top = m_printRange.top();
01747         int bottom = m_printRange.bottom();
01748 
01749         for( int i = 0; i <= nbRow; i++ )
01750         {
01751             if ( top > row ) top--;
01752             if ( bottom >= row ) bottom--;
01753         }
01754         //Validity checks
01755         if ( top < 1 ) top = 1;
01756         if ( bottom < 1 ) bottom = 1;
01757         setPrintRange( QRect( QPoint( m_printRange.left(), top ),
01758                               QPoint( m_printRange.right(), bottom ) ) );
01759     }
01760 
01761     //update repeat rows, when it has been defined
01762     if ( m_printRepeatRows.first != 0 )
01763     {
01764         int top = m_printRepeatRows.first;
01765         int bottom = m_printRepeatRows.second;
01766 
01767         for( int i = 0; i <= nbRow; i++ )
01768         {
01769             if ( top > row ) top--;
01770             if ( bottom >= row ) bottom--;
01771         }
01772         //Validity checks
01773         if ( top < 1 ) top = 1;
01774         if ( bottom < 1 ) bottom = 1;
01775         setPrintRepeatRows( qMakePair( top, bottom ) );
01776     }
01777 }
01778 
01779 void SheetPrint::setZoom( double _zoom, bool checkPageLimit )
01780 {
01781     if( m_dZoom == _zoom )
01782     {
01783         return;
01784     }
01785 
01786     m_dZoom = _zoom;
01787     updatePrintRepeatColumnsWidth();
01788     updatePrintRepeatRowsHeight();
01789     updateNewPageListX( 0 );
01790     updateNewPageListY( 0 );
01791     if( m_pSheet->isShowPageBorders() )
01792         emit sig_updateView( m_pSheet );
01793 
01794     if( checkPageLimit )
01795     {
01796         calculateZoomForPageLimitX();
01797         calculateZoomForPageLimitY();
01798     }
01799 
01800     m_pDoc->setModified( true );
01801 }
01802 
01803 bool PrintNewPageEntry::operator==( PrintNewPageEntry const & entry ) const
01804 {
01805     return m_iStartItem == entry.m_iStartItem;
01806 }
01807 
KDE Home | KDE Accessibility Home | Description of Access Keys