kspread Library API Documentation

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