From 8362bf63dea22bbf6736609b0f49c152f975eb63 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 20 Jan 2010 01:29:50 +0000 Subject: Added old abandoned KDE3 version of koffice git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kspread/kspread_sheetprint.cc | 1807 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1807 insertions(+) create mode 100644 kspread/kspread_sheetprint.cc (limited to 'kspread/kspread_sheetprint.cc') diff --git a/kspread/kspread_sheetprint.cc b/kspread/kspread_sheetprint.cc new file mode 100644 index 00000000..8b4ce0cc --- /dev/null +++ b/kspread/kspread_sheetprint.cc @@ -0,0 +1,1807 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis , + 2003 Philipp Mller + 2005 Raphael Langerhorst + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kspread_sheet.h" +#include "selection.h" +#include "kspread_locale.h" +#include "kspread_doc.h" +#include "kspread_undo.h" + +#include "kspread_sheetprint.h" + +#include "commands.h" +#include + +#include +#include +#include + +#include + +#include +#include + +#include "kspread_sheetprint.moc" + +#define NO_MODIFICATION_POSSIBLE \ +do { \ + KMessageBox::error( 0, i18n ( "You cannot change a protected sheet" ) ); return; \ +} while(0) + +using namespace KSpread; + +SheetPrint::SheetPrint( Sheet* sheet ) +{ + m_pSheet = sheet; + m_pDoc = m_pSheet->doc(); + + m_bPrintGrid = false; + m_bPrintCommentIndicator = false; + m_bPrintFormulaIndicator = false; + m_bPrintObjects = true; + m_bPrintCharts = true; + m_bPrintGraphics = true; + + m_leftBorder = 20.0; + m_rightBorder = 20.0; + m_topBorder = 20.0; + m_bottomBorder = 20.0; + + m_paperFormat = KoPageFormat::defaultFormat(); + m_orientation = PG_PORTRAIT; + m_paperWidth = MM_TO_POINT( KoPageFormat::width( m_paperFormat, m_orientation ) ); + m_paperHeight = MM_TO_POINT( KoPageFormat::height( m_paperFormat, m_orientation ) ); + m_printRange = QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) ); + m_lnewPageListX.append( 1 ); + m_lnewPageListY.append( 1 ); + m_maxCheckedNewPageX = 1; + m_maxCheckedNewPageY = 1; + m_dPrintRepeatColumnsWidth = 0.0; + m_dPrintRepeatRowsHeight = 0.0; + m_printRepeatColumns = qMakePair( 0, 0 ); + m_printRepeatRows = qMakePair( 0, 0 ); + m_dZoom = 1.0; + m_iPageLimitX = 0; + m_iPageLimitY = 0; + + calcPaperSize(); +} + +SheetPrint::~SheetPrint() +{ + // nothing todo yet +} + +QString SheetPrint::saveOasisSheetStyleLayout( KoGenStyles &mainStyles ) +{ + KoGenStyle pageLayout( KoGenStyle::STYLE_PAGELAYOUT ); + //pageLayout.addAttribute( "style:page-usage", "all" ); FIXME + pageLayout.addPropertyPt( "fo:page-width", MM_TO_POINT( paperWidth() ) ); + pageLayout.addPropertyPt( "fo:page-height", MM_TO_POINT( paperHeight() ) ); + pageLayout.addProperty( "style:print-orientation", orientation() == PG_LANDSCAPE ? "landscape" : "portrait" ); + pageLayout.addPropertyPt( "fo:margin-left", MM_TO_POINT(leftBorder() ) ); + pageLayout.addPropertyPt( "fo:margin-top", MM_TO_POINT(topBorder() ) ); + pageLayout.addPropertyPt( "fo:margin-right", MM_TO_POINT(rightBorder() ) ); + pageLayout.addPropertyPt( "fo:margin-bottom", MM_TO_POINT(bottomBorder() ) ); + //necessary for print setup + m_pSheet->saveOasisPrintStyleLayout( pageLayout ); + + return mainStyles.lookup( pageLayout, "pm" ); +} + + +QRect SheetPrint::cellsPrintRange() +{ + // Find maximum right/bottom cell with content + QRect cell_range; + cell_range.setCoords( 1, 1, 1, 1 ); + + Cell* c = m_pSheet->firstCell(); + for( ;c; c = c->nextCell() ) + { + if ( c->needsPrinting() ) + { + if ( c->column() > cell_range.right() ) + cell_range.setRight( c->column() ); + if ( c->row() > cell_range.bottom() ) + cell_range.setBottom( c->row() ); + } + } + + // Now look at the children + QPtrListIterator cit( m_pDoc->children() ); + double dummy; + int i; + for( ; cit.current(); ++cit ) + { + //QRect, because KoChild doesn't use KoRect yet + QRect bound = cit.current()->boundingRect(); + + i = m_pSheet->leftColumn( bound.right(), dummy ); + if ( i > cell_range.right() ) + cell_range.setRight( i ); + + i = m_pSheet->topRow( bound.bottom(), dummy ); + if ( i > cell_range.bottom() ) + cell_range.setBottom( i ); + } + cell_range = cell_range.intersect( m_printRange ); + + return cell_range; +} + +int SheetPrint::pagesX( const QRect& cellsPrintRange ) +{ + int pages = 0; + + updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( cellsPrintRange.right() ) + prinsheetWidthPts() ) ); + + for( int i = cellsPrintRange.left(); i <= cellsPrintRange.right(); i++ ) + { + if( isOnNewPageX( i ) ) + pages++; + } + return pages; +} + +int SheetPrint::pagesY( const QRect& cellsPrintRange ) +{ + int pages = 0; + + updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( cellsPrintRange.bottom() ) + prinsheetHeightPts() ) ); + + for( int i = cellsPrintRange.top(); i <= cellsPrintRange.bottom(); i++ ) + { + if( isOnNewPageY( i ) ) + pages++; + } + return pages; +} + + +bool SheetPrint::pageNeedsPrinting( QRect& page_range ) +{ + // bool filled = false; + + // Look at the cells + for( int r = page_range.top(); r <= page_range.bottom() ; ++r ) + for( int c = page_range.left(); c <= page_range.right() ; ++c ) + if ( m_pSheet->cellAt( c, r )->needsPrinting() ) + { + return true; + } + // filled = true; + + //Page empty, but maybe children on it? + + QRect intView = QRect( QPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.left() ) ), + m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.top() ) ) ), + QPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.right() ) + + m_pSheet->columnFormat( page_range.right() )->dblWidth() ), + m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.bottom() ) + + m_pSheet->rowFormat( page_range.bottom() )->dblHeight() ) ) ); + + QPtrListIterator it( m_pDoc->children() ); + for( ;it.current(); ++it ) + { + QRect bound = it.current()->boundingRect(); + if ( bound.intersects( intView ) ) + { + return true; + } + //filled = true; + } + + + //Page has no visible content on it, so we don't need to paint it + return false; +} + +bool SheetPrint::print( QPainter &painter, KPrinter *_printer ) +{ + kdDebug(36001)<<"PRINTING ...."<getShowGrid(); + m_pSheet->setShowGrid( m_bPrintGrid ); + if ( !m_bPrintGrid ) + { + gridPen = QPen( m_pDoc->gridColor(), 1, Qt::SolidLine ); + QPen nopen; + nopen.setStyle( NoPen ); + m_pDoc->setGridColor( Qt::white ); + } + + //Update m_dPrintRepeatColumnsWidth for repeated columns + //just in case it isn't done yet + if ( !m_pSheet->isShowPageBorders() && m_printRepeatColumns.first != 0 ) + updatePrintRepeatColumnsWidth(); + + //Update m_dPrintRepeatRowsHeight for repeated rows + //just in case it isn't done yet + if ( !m_pSheet->isShowPageBorders() && m_printRepeatRows.first != 0 ) + updatePrintRepeatRowsHeight(); + + //Calculate the range to be printed + QRect cell_range = cellsPrintRange(); + kdDebug()<<"cellsPrintRange() :"<rightColumn( m_pSheet->dblColumnPos( cell_range.right() ) + prinsheetWidthPts() ) ); + updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( cell_range.bottom() ) + prinsheetHeightPts() ) ); + + // Find out how many pages need printing + // and which cells to print on which page. + QValueList page_list; //contains the cols and rows of a page + QValueList page_frame_list; //contains the coordinate range of a page + QValueList page_frame_list_offset; //contains the offset of the not repeated area + + QValueList::iterator itX; + QValueList::iterator itY; + for( itX = m_lnewPageListX.begin(); itX != m_lnewPageListX.end(); ++itX ) + { + for( itY = m_lnewPageListY.begin(); itY != m_lnewPageListY.end(); ++itY ) + { + QRect page_range( QPoint( (*itX).startItem(), (*itY).startItem() ), + QPoint( (*itX).endItem(), (*itY).endItem() ) ); + kdDebug()<<" page_range :"<dblColumnPos( page_range.left() ), + m_pSheet->dblRowPos( page_range.top() ) ), + KoPoint( m_pSheet->dblColumnPos( page_range.right() ) + + m_pSheet->columnFormat( page_range.right() )->dblWidth(), + m_pSheet->dblRowPos( page_range.bottom() ) + + m_pSheet->rowFormat( page_range.bottom() )->dblHeight() ) ); + page_list.append( page_range ); + page_frame_list.append( view ); + page_frame_list_offset.append( KoPoint( (*itX).offset(), (*itY).offset() ) ); + } + } + } + + + kdDebug(36001) << "PRINTING " << page_list.count() << " pages" << endl; + m_uprintPages = page_list.count(); + + + //Cache all object so they only need to be repainted once. + QPtrListIterator itObject( m_pDoc->embeddedObjects() ); + for ( ; itObject.current(); ++itObject ) + { + EmbeddedObject *obj = itObject.current(); + if ( obj->sheet() != m_pSheet || + !( (( obj->getType() == OBJECT_KOFFICE_PART || obj->getType() == OBJECT_PICTURE ) && m_bPrintObjects) || + ( obj->getType() == OBJECT_CHART && m_bPrintCharts ) ) ) + continue; + + QRect zoomRect = m_pDoc->zoomRect( itObject.current()->geometry() ); + QPixmap *p = new QPixmap( zoomRect.size() ); + QPainter painter(p); + painter.fillRect( p->rect(), QColor("white") ); + painter.translate( -zoomRect.x(), -zoomRect.y() ); //we cant to paint at (0,0) + bool const isSelected = itObject.current()->isSelected(); + itObject.current()->setSelected( false ); + itObject.current()->draw( &painter ); + painter.end(); + itObject.current()->setSelected( isSelected ); + + PrintObject *po = new PrintObject(); + m_printObjects.append( po ); + po->obj = itObject.current(); + po->p = p; + } + + if ( page_list.count() == 0 ) + { + // nothing to print + painter.setPen( QPen( Qt::black, 1 ) ); + painter.drawPoint( 1, 1 ); + } + else + { + + int pageNo = 1; + + // + // Print all pages in the list + // + QValueList::Iterator it = page_list.begin(); + QValueList::Iterator fit = page_frame_list.begin(); + QValueList::Iterator fito = page_frame_list_offset.begin(); + + for( ; it != page_list.end(); ++it, ++fit, ++fito, ++pageNo ) + { + painter.setClipRect( 0, 0, m_pDoc->zoomItX( paperWidthPts() ), + m_pDoc->zoomItY( paperHeightPts() ) ); + printHeaderFooter( painter, pageNo ); + + painter.translate( m_pDoc->zoomItX( leftBorderPts() ), + m_pDoc->zoomItY( topBorderPts() ) ); + + // Print the page + printPage( painter, *it, *fit, *fito ); + + painter.translate( - m_pDoc->zoomItX( leftBorderPts() ), + - m_pDoc->zoomItY( topBorderPts() ) ); + + if ( pageNo < (int)page_list.count() ) + _printer->newPage(); + } + } + + if ( !m_bPrintGrid ) + { + // Restore the grid pen + m_pDoc->setGridColor( gridPen.color() ); + } + m_pSheet->setShowGrid( oldShowGrid ); + + QValueList::iterator it; + for ( it = m_printObjects.begin(); it != m_printObjects.end(); ++it ) + delete (*it)->p; + m_printObjects.clear(); + + return ( page_list.count() > 0 ); +} + +void SheetPrint::printPage( QPainter &_painter, const QRect& page_range, + const KoRect& view, const KoPoint _childOffset ) +{ + kdDebug(36001) << "Rect x=" << page_range.left() << " y=" << page_range.top() << ", r=" + << page_range.right() << " b=" << page_range.bottom() << " offsetx: "<< _childOffset.x() + << " offsety: " << _childOffset.y() <<" view-x: "<zoomItX( leftBorderPts() ), + m_pDoc->zoomItY( topBorderPts() ), + m_pDoc->zoomItX( view.width() + _childOffset.x() ), + m_pDoc->zoomItY( view.height() + _childOffset.y() ) ); + _painter.setClipRegion( clipRegion ); + + // + // Draw the cells. + // + //Check if we have to repeat some rows and columns (top left rect) + if ( ( _childOffset.x() != 0.0 ) && ( _childOffset.y() != 0.0 ) ) + { + //QRect(left,top,width,height) <<<< WIDTH AND HEIGHT!!! + QRect _printRect( m_printRepeatColumns.first, m_printRepeatRows.first, + m_printRepeatColumns.second - m_printRepeatColumns.first + 1, + m_printRepeatRows.second - m_printRepeatRows.first + 1); + KoPoint _topLeft( 0.0, 0.0 ); + + printRect( _painter, _topLeft, _printRect, view, clipRegion ); + } + + //Check if we have to repeat some rows (left rect) + if ( _childOffset.y() != 0 ) + { + QRect _printRect( page_range.left(), m_printRepeatRows.first, + page_range.right() - page_range.left() + 1, + m_printRepeatRows.second - m_printRepeatRows.first + 1); + KoPoint _topLeft( _childOffset.x(), 0.0 ); + + printRect( _painter, _topLeft, _printRect, view, clipRegion ); + } + + //Check if we have to repeat some columns (top right rect) + if ( _childOffset.x() != 0 ) + { + QRect _printRect( m_printRepeatColumns.first, page_range.top(), + m_printRepeatColumns.second - m_printRepeatColumns.first + 1, + page_range.bottom() - page_range.top() + 1); + KoPoint _topLeft( 0.0, _childOffset.y() ); + + printRect( _painter, _topLeft, _printRect, view, clipRegion ); + } + + + //Print the cells (right data rect) + KoPoint _topLeft( _childOffset.x(), _childOffset.y() ); + + printRect( _painter, _topLeft, page_range, view, clipRegion ); +} + + +void SheetPrint::printRect( QPainter& painter, const KoPoint& topLeft, + const QRect& printRect, const KoRect& view, + QRegion &clipRegion ) +{ + // + // Draw the cells. + // + Cell *cell; + RowFormat *row_lay; + ColumnFormat *col_lay; + + double xpos = 0; + double ypos = topLeft.y(); + + int regionBottom = printRect.bottom(); + int regionRight = printRect.right(); + int regionLeft = printRect.left(); + int regionTop = printRect.top(); + + //Calculate the output rect + KoPoint bottomRight( topLeft ); + for ( int x = regionLeft; x <= regionRight; ++x ) + bottomRight.setX( bottomRight.x() + + m_pSheet->columnFormat( x )->dblWidth() ); + for ( int y = regionTop; y <= regionBottom; ++y ) + bottomRight.setY( bottomRight.y() + + m_pSheet->rowFormat( y )->dblHeight() ); + KoRect rect( topLeft, bottomRight ); + + QValueList mergedCellsPainted; + for ( int y = regionTop; y <= regionBottom; ++y ) + { + row_lay = m_pSheet->rowFormat( y ); + xpos = topLeft.x(); + + for ( int x = regionLeft; x <= regionRight; ++x ) + { + col_lay = m_pSheet->columnFormat( x ); + + cell = m_pSheet->cellAt( x, y ); + + bool paintBordersBottom = false; + bool paintBordersRight = false; + bool paintBordersLeft = false; + bool paintBordersTop = false; + + QPen rightPen = cell->effRightBorderPen( x, y ); + QPen leftPen = cell->effLeftBorderPen( x, y ); + QPen bottomPen = cell->effBottomBorderPen( x, y ); + QPen topPen = cell->effTopBorderPen( x, y ); + + // paint right border if rightmost cell or if the pen is more "worth" than the left border pen + // of the cell on the left or if the cell on the right is not painted. In the latter case get + // the pen that is of more "worth" + if ( x >= KS_colMax ) + paintBordersRight = true; + else + if ( x == regionRight ) + { + paintBordersRight = true; + if ( cell->effRightBorderValue( x, y ) < m_pSheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) ) + rightPen = m_pSheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y ); + } + else + { + paintBordersRight = true; + if ( cell->effRightBorderValue( x, y ) < m_pSheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) ) + rightPen = m_pSheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y ); + } + + // similiar for other borders... + // bottom border: + if ( y >= KS_rowMax ) + paintBordersBottom = true; + else + if ( y == regionBottom ) + { + paintBordersBottom = true; + if ( cell->effBottomBorderValue( x, y ) < m_pSheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) ) + bottomPen = m_pSheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 ); + } + else + { + paintBordersBottom = true; + if ( cell->effBottomBorderValue( x, y ) < m_pSheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) ) + bottomPen = m_pSheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 ); + } + + // left border: + if ( x == 1 ) + paintBordersLeft = true; + else + if ( x == regionLeft ) + { + paintBordersLeft = true; + if ( cell->effLeftBorderValue( x, y ) < m_pSheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) ) + leftPen = m_pSheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y ); + } + else + { + paintBordersLeft = true; + if ( cell->effLeftBorderValue( x, y ) < m_pSheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) ) + leftPen = m_pSheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y ); + } + + // top border: + if ( y == 1 ) + paintBordersTop = true; + else + if ( y == regionTop ) + { + paintBordersTop = true; + if ( cell->effTopBorderValue( x, y ) < m_pSheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) ) + topPen = m_pSheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 ); + } + else + { + paintBordersTop = true; + if ( cell->effTopBorderValue( x, y ) < m_pSheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) ) + topPen = m_pSheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 ); + } + + int paintBorder=Cell::Border_None; + if (paintBordersLeft) paintBorder |= Cell::Border_Left; + if (paintBordersRight) paintBorder |= Cell::Border_Right; + if (paintBordersTop) paintBorder |= Cell::Border_Top; + if (paintBordersBottom) paintBorder |= Cell::Border_Bottom; + + QPen highlightPen; + + if ( m_pSheet->layoutDirection()==Sheet::RightToLeft ) + cell->paintCell( rect, painter, NULL, + KoPoint( view.width() - xpos - + col_lay->dblWidth(), ypos ), QPoint( x, y ), + paintBorder, + rightPen, bottomPen, leftPen, topPen, + mergedCellsPainted); + else + cell->paintCell( rect, painter, NULL, + KoPoint( xpos, ypos ), QPoint( x, y ), + paintBorder, + rightPen, bottomPen, leftPen, topPen, + mergedCellsPainted); + + xpos += col_lay->dblWidth(); + } + + ypos += row_lay->dblHeight(); + } + + // + // Draw the children + // + QRect zoomedView = m_pDoc->zoomRect( view ); + //QPtrListIterator it( m_pDoc->children() ); + //QPtrListIterator itObject( m_pDoc->embeddedObjects() ); + + QValueList::iterator itObject; + for ( itObject = m_printObjects.begin(); itObject != m_printObjects.end(); ++itObject ) { + EmbeddedObject *obj = (*itObject)->obj; +// QString tmp=QString("Testing child %1/%2 %3/%4 against view %5/%6 %7/%8") +// .arg(it.current()->contentRect().left()) +// .arg(it.current()->contentRect().top()) +// .arg(it.current()->contentRect().right()) +// .arg(it.current()->contentRect().bottom()) +// .arg(view.left()).arg(view.top()).arg(zoomedView.right()).arg(zoomedView.bottom()); +// kdDebug(36001)<geometry(); + QRect zoomedBound = m_pDoc->zoomRect( KoRect(bound.left(), bound.top(), + bound.width(), + bound.height() ) ); +#if 1 +// kdDebug(36001) << "printRect(): Bounding rect of view: " << view +// << endl; +// kdDebug(36001) << "printRect(): Bounding rect of zoomed view: " +// << zoomedView << endl; +// kdDebug(36001) << "printRect(): Bounding rect of child: " << bound +// << endl; +// kdDebug(36001) << "printRect(): Bounding rect of zoomed child: " +// << zoomedBound << endl; +#endif + if ( obj->sheet() == m_pSheet && zoomedBound.intersects( zoomedView ) ) + { + painter.save(); + + painter.translate( -zoomedView.left() + m_pDoc->zoomItX( topLeft.x() ), + -zoomedView.top() + m_pDoc->zoomItY( topLeft.y() ) ); + + //obj->draw( &painter ); + painter.drawPixmap( m_pDoc->zoomRect( obj->geometry() ).topLeft(), *(*itObject)->p ); //draw the cached object + + //painter.fillRect(zoomedBound, QBrush("red")); //for debug purpose + painter.restore(); + } + } + + //Don't let obscuring cells and children overpaint this area + clipRegion -= QRegion ( m_pDoc->zoomItX( leftBorderPts() + topLeft.x() ), + m_pDoc->zoomItY( topBorderPts() + topLeft.y() ), + m_pDoc->zoomItX( xpos ), + m_pDoc->zoomItY( ypos ) ); + painter.setClipRegion( clipRegion ); +} + + +void SheetPrint::printHeaderFooter( QPainter &painter, int pageNo ) +{ + double w; + double headFootDistance = MM_TO_POINT( 10.0 /*mm*/ ) / m_dZoom; + QFont font( "Times" ); + font.setPointSizeFloat( 0.01 * m_pDoc->zoom() * + /* Font size of 10 */ 10.0 / m_dZoom ); + painter.setFont( font ); + QFontMetrics fm = painter.fontMetrics(); + + // print head line left + w = fm.width( headLeft( pageNo, m_pSheet->sheetName() ) ) / m_dZoom; + if ( w > 0 ) + painter.drawText( m_pDoc->zoomItX( leftBorderPts() ), + m_pDoc->zoomItY( headFootDistance ), + headLeft( pageNo, m_pSheet->sheetName() ) ); + // print head line middle + w = fm.width( headMid( pageNo, m_pSheet->sheetName() ) ) / m_dZoom; + if ( w > 0 ) + painter.drawText( (int) ( m_pDoc->zoomItX( leftBorderPts() ) + + ( m_pDoc->zoomItX( prinsheetWidthPts() ) - + w ) / 2.0 ), + m_pDoc->zoomItY( headFootDistance ), + headMid( pageNo, m_pSheet->sheetName() ) ); + // print head line right + w = fm.width( headRight( pageNo, m_pSheet->sheetName() ) ) / m_dZoom; + if ( w > 0 ) + painter.drawText( m_pDoc->zoomItX( leftBorderPts() + + prinsheetWidthPts() ) - (int) w, + m_pDoc->zoomItY( headFootDistance ), + headRight( pageNo, m_pSheet->sheetName() ) ); + + // print foot line left + w = fm.width( footLeft( pageNo, m_pSheet->sheetName() ) ) / m_dZoom; + if ( w > 0 ) + painter.drawText( m_pDoc->zoomItX( leftBorderPts() ), + m_pDoc->zoomItY( paperHeightPts() - headFootDistance ), + footLeft( pageNo, m_pSheet->sheetName() ) ); + // print foot line middle + w = fm.width( footMid( pageNo, m_pSheet->sheetName() ) ) / m_dZoom; + if ( w > 0 ) + painter.drawText( (int) ( m_pDoc->zoomItX( leftBorderPts() ) + + ( m_pDoc->zoomItX( prinsheetWidthPts() ) - + w ) / 2.0 ), + m_pDoc->zoomItY( paperHeightPts() - headFootDistance ), + footMid( pageNo, m_pSheet->sheetName() ) ); + // print foot line right + w = fm.width( footRight( pageNo, m_pSheet->sheetName() ) ) / m_dZoom; + if ( w > 0 ) + painter.drawText( m_pDoc->zoomItX( leftBorderPts() + + prinsheetWidthPts() ) - + (int) w, + m_pDoc->zoomItY( paperHeightPts() - headFootDistance ), + footRight( pageNo, m_pSheet->sheetName() ) ); +} + + +bool SheetPrint::isOnNewPageX( int _column ) +{ + if( _column > m_maxCheckedNewPageX ) + updateNewPageX( _column ); + + //Are these the edges of the print range? + if ( _column == m_printRange.left() || _column == m_printRange.right() + 1 ) + { + return true; + } + + //beyond the print range it's always false + if ( _column < m_printRange.left() || _column > m_printRange.right() ) + { + return false; + } + + //Now check if we find the column already in the list + if ( m_lnewPageListX.findIndex( _column ) != -1 ) + { + if( _column > m_maxCheckedNewPageX ) + m_maxCheckedNewPageX = _column; + return true; + } + return false; +} + + +void SheetPrint::updateNewPageX( int _column ) +{ + float offset = 0.0; + + //Are these the edges of the print range? + if ( _column == m_printRange.left() || _column == m_printRange.right() + 1 ) + { + if( _column > m_maxCheckedNewPageX ) + m_maxCheckedNewPageX = _column; + return; + } + + //We don't check beyond the print range + if ( _column < m_printRange.left() || _column > m_printRange.right() ) + { + if( _column > m_maxCheckedNewPageX ) + m_maxCheckedNewPageX = _column; + if ( _column > m_printRange.right() ) + { + if ( m_lnewPageListX.last().endItem()==0 ) + m_lnewPageListX.last().setEndItem( m_printRange.right() ); + } + return; + } + + //If we start, then add the left printrange + if ( m_lnewPageListX.empty() ) + m_lnewPageListX.append( m_printRange.left() ); //Add the first entry + + //If _column is greater than the last entry, we need to calculate the result + if ( _column > m_lnewPageListX.last().startItem() && + _column > m_maxCheckedNewPageX ) //this columns hasn't been calculated before + { + int startCol = m_lnewPageListX.last().startItem(); + int col = startCol; + double x = m_pSheet->columnFormat( col )->dblWidth(); + + //Add repeated column width, when necessary + if ( col > m_printRepeatColumns.first ) + { + x += m_dPrintRepeatColumnsWidth; + offset = m_dPrintRepeatColumnsWidth; + } + + while ( ( col <= _column ) && ( col < m_printRange.right() ) ) + { + if ( x > prinsheetWidthPts() ) //end of page? + { + //We found a new page, so add it to the list + m_lnewPageListX.append( col ); + + //Now store into the previous entry the enditem and the width + QValueList::iterator it; + it = findNewPageColumn( startCol ); + (*it).setEndItem( col - 1 ); + (*it).setSize( x - m_pSheet->columnFormat( col )->dblWidth() ); + (*it).setOffset( offset ); + + //start a new page + startCol = col; + if ( col == _column ) + { + if( _column > m_maxCheckedNewPageX ) + m_maxCheckedNewPageX = _column; + return; + } + else + { + x = m_pSheet->columnFormat( col )->dblWidth(); + if ( col >= m_printRepeatColumns.first ) + { + x += m_dPrintRepeatColumnsWidth; + offset = m_dPrintRepeatColumnsWidth; + } + } + } + + col++; + x += m_pSheet->columnFormat( col )->dblWidth(); + } + } + + if( _column > m_maxCheckedNewPageX ) + m_maxCheckedNewPageX = _column; +} + + +bool SheetPrint::isOnNewPageY( int _row ) +{ + if( _row > m_maxCheckedNewPageY ) + updateNewPageY( _row ); + + //Are these the edges of the print range? + if ( _row == m_printRange.top() || _row == m_printRange.bottom() + 1 ) + { + return true; + } + + //beyond the print range it's always false + if ( _row < m_printRange.top() || _row > m_printRange.bottom() ) + { + return false; + } + + //Now check if we find the row already in the list + if ( m_lnewPageListY.findIndex( _row ) != -1 ) + { + if( _row > m_maxCheckedNewPageY ) + m_maxCheckedNewPageY = _row; + return true; + } + + return false; +} + + +void SheetPrint::updateNewPageY( int _row ) +{ + float offset = 0.0; + + //Are these the edges of the print range? + if ( _row == m_printRange.top() || _row == m_printRange.bottom() + 1 ) + { + if( _row > m_maxCheckedNewPageY ) + m_maxCheckedNewPageY = _row; + return; + } + + //beyond the print range it's always false + if ( _row < m_printRange.top() || _row > m_printRange.bottom() ) + { + if( _row > m_maxCheckedNewPageY ) + m_maxCheckedNewPageY = _row; + if ( _row > m_printRange.bottom() ) + { + if ( m_lnewPageListY.last().endItem()==0 ) + m_lnewPageListY.last().setEndItem( m_printRange.bottom() ); + } + return; + } + + //If we start, then add the top printrange + if ( m_lnewPageListY.empty() ) + m_lnewPageListY.append( m_printRange.top() ); //Add the first entry + + //If _column is greater than the last entry, we need to calculate the result + if ( _row > m_lnewPageListY.last().startItem() && + _row > m_maxCheckedNewPageY ) //this columns hasn't been calculated before + { + int startRow = m_lnewPageListY.last().startItem(); + int row = startRow; + double y = m_pSheet->rowFormat( row )->dblHeight(); + + //Add repeated row height, when necessary + if ( row > m_printRepeatRows.first ) + { + y += m_dPrintRepeatRowsHeight; + offset = m_dPrintRepeatRowsHeight; + } + + while ( ( row <= _row ) && ( row < m_printRange.bottom() ) ) + { + if ( y > prinsheetHeightPts() ) + { + //We found a new page, so add it to the list + m_lnewPageListY.append( row ); + + //Now store into the previous entry the enditem and the width + QValueList::iterator it; + it = findNewPageRow( startRow ); + (*it).setEndItem( row - 1 ); + (*it).setSize( y - m_pSheet->rowFormat( row )->dblHeight() ); + (*it).setOffset( offset ); + + //start a new page + startRow = row; + if ( row == _row ) + { + if( _row > m_maxCheckedNewPageY ) + m_maxCheckedNewPageY = _row; + return; + } + else + { + y = m_pSheet->rowFormat( row )->dblHeight(); + if ( row >= m_printRepeatRows.first ) + { + y += m_dPrintRepeatRowsHeight; + offset = m_dPrintRepeatRowsHeight; + } + } + } + + row++; + y += m_pSheet->rowFormat( row )->dblHeight(); + } + } + + if( _row > m_maxCheckedNewPageY ) + m_maxCheckedNewPageY = _row; +} + + +void SheetPrint::updateNewPageListX( int _col ) +{ + //If the new range is after the first entry, we need to delete the whole list + if ( m_lnewPageListX.first().startItem() != m_printRange.left() || + _col == 0 ) + { + m_lnewPageListX.clear(); + m_maxCheckedNewPageX = m_printRange.left(); + m_lnewPageListX.append( m_printRange.left() ); + return; + } + + if ( _col < m_lnewPageListX.last().startItem() ) + { + //Find the page entry for this column + QValueList::iterator it; + it = m_lnewPageListX.find( _col ); + while ( ( it == m_lnewPageListX.end() ) && _col > 0 ) + { + _col--; + it = m_lnewPageListX.find( _col ); + } + + //Remove later pages + while ( it != m_lnewPageListX.end() ) + it = m_lnewPageListX.remove( it ); + + //Add default page when list is now empty + if ( m_lnewPageListX.empty() ) + m_lnewPageListX.append( m_printRange.left() ); + } + + m_maxCheckedNewPageX = _col; +} + +void SheetPrint::updateNewPageListY( int _row ) +{ + //If the new range is after the first entry, we need to delete the whole list + if ( m_lnewPageListY.first().startItem() != m_printRange.top() || + _row == 0 ) + { + m_lnewPageListY.clear(); + m_maxCheckedNewPageY = m_printRange.top(); + m_lnewPageListY.append( m_printRange.top() ); + return; + } + + if ( _row < m_lnewPageListY.last().startItem() ) + { + //Find the page entry for this row + QValueList::iterator it; + it = m_lnewPageListY.find( _row ); + while ( ( it == m_lnewPageListY.end() ) && _row > 0 ) + { + _row--; + it = m_lnewPageListY.find( _row ); + } + + //Remove later pages + while ( it != m_lnewPageListY.end() ) + it = m_lnewPageListY.remove( it ); + + //Add default page when list is now empty + if ( m_lnewPageListY.empty() ) + m_lnewPageListY.append( m_printRange.top() ); + } + + m_maxCheckedNewPageY = _row; +} + +void SheetPrint::definePrintRange( Selection* selectionInfo ) +{ + if ( !selectionInfo->isSingular() ) + { + KCommand* command = new DefinePrintRangeCommand( m_pSheet ); + m_pDoc->addCommand( command ); + setPrintRange( selectionInfo->selection() ); + } +} + +void SheetPrint::resetPrintRange () +{ + KCommand* command = new DefinePrintRangeCommand( m_pSheet ); + m_pDoc->addCommand( command ); + setPrintRange( QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) ) ); +} + +void SheetPrint::replaceHeadFootLineMacro ( QString &_text, const QString &_search, const QString &_replace ) +{ + if ( _search != _replace ) + _text.replace ( QString( "<" + _search + ">" ), "<" + _replace + ">" ); +} + +QString SheetPrint::localizeHeadFootLine ( const QString &_text ) +{ + QString tmp = _text; + + /* + i18n: + Please use the same words (even upper/lower case) as in + KoPageLayoutDia.cc function setupTab2(), without the brakets "<" and ">" + */ + replaceHeadFootLineMacro ( tmp, "page", i18n("page") ); + replaceHeadFootLineMacro ( tmp, "pages", i18n("pages") ); + replaceHeadFootLineMacro ( tmp, "file", i18n("file") ); + replaceHeadFootLineMacro ( tmp, "name", i18n("name") ); + replaceHeadFootLineMacro ( tmp, "time", i18n("time") ); + replaceHeadFootLineMacro ( tmp, "date", i18n("date") ); + replaceHeadFootLineMacro ( tmp, "author", i18n("author") ); + replaceHeadFootLineMacro ( tmp, "email", i18n("email") ); + replaceHeadFootLineMacro ( tmp, "org", i18n("org") ); + replaceHeadFootLineMacro ( tmp, "sheet", i18n("sheet") ); + + return tmp; +} + + +QString SheetPrint::delocalizeHeadFootLine ( const QString &_text ) +{ + QString tmp = _text; + + /* + i18n: + Please use the same words (even upper/lower case) as in + KoPageLayoutDia.cc function setupTab2(), without the brakets "<" and ">" + */ + replaceHeadFootLineMacro ( tmp, i18n("page"), "page" ); + replaceHeadFootLineMacro ( tmp, i18n("pages"), "pages" ); + replaceHeadFootLineMacro ( tmp, i18n("file"), "file" ); + replaceHeadFootLineMacro ( tmp, i18n("name"), "name" ); + replaceHeadFootLineMacro ( tmp, i18n("time"), "time" ); + replaceHeadFootLineMacro ( tmp, i18n("date"), "date" ); + replaceHeadFootLineMacro ( tmp, i18n("author"), "author" ); + replaceHeadFootLineMacro ( tmp, i18n("email"), "email" ); + replaceHeadFootLineMacro ( tmp, i18n("org"), "org" ); + replaceHeadFootLineMacro ( tmp, i18n("sheet"), "sheet" ); + + return tmp; +} + + +KoHeadFoot SheetPrint::headFootLine() const +{ + KoHeadFoot hf; + hf.headLeft = m_headLeft; + hf.headRight = m_headRight; + hf.headMid = m_headMid; + hf.footLeft = m_footLeft; + hf.footRight = m_footRight; + hf.footMid = m_footMid; + + return hf; +} + + +void SheetPrint::setHeadFootLine( const QString &_headl, const QString &_headm, const QString &_headr, + const QString &_footl, const QString &_footm, const QString &_footr ) +{ + if ( m_pSheet->isProtected() ) + NO_MODIFICATION_POSSIBLE; + + m_headLeft = _headl; + m_headRight = _headr; + m_headMid = _headm; + m_footLeft = _footl; + m_footRight = _footr; + m_footMid = _footm; + + m_pDoc->setModified( true ); +} + +void SheetPrint::setPaperOrientation( KoOrientation _orient ) +{ + if ( m_pSheet->isProtected() ) + NO_MODIFICATION_POSSIBLE; + + m_orientation = _orient; + calcPaperSize(); + updatePrintRepeatColumnsWidth(); + updatePrintRepeatRowsHeight(); + updateNewPageListX( m_printRange.left() ); //Reset the list + updateNewPageListY( m_printRange.top() ); //Reset the list + + if( m_pSheet->isShowPageBorders() ) + emit sig_updateView( m_pSheet ); +} + + +KoPageLayout SheetPrint::paperLayout() const +{ + KoPageLayout pl; + pl.format = m_paperFormat; + pl.orientation = m_orientation; + pl.ptWidth = m_paperWidth; + pl.ptHeight = m_paperHeight; + pl.ptLeft = m_leftBorder; + pl.ptRight = m_rightBorder; + pl.ptTop = m_topBorder; + pl.ptBottom = m_bottomBorder; + return pl; +} + + +void SheetPrint::setPaperLayout( float _leftBorder, float _topBorder, + float _rightBorder, float _bottomBorder, + KoFormat _paper, + KoOrientation _orientation ) +{ + if ( m_pSheet->isProtected() ) + NO_MODIFICATION_POSSIBLE; + + m_leftBorder = _leftBorder; + m_rightBorder = _rightBorder; + m_topBorder = _topBorder; + m_bottomBorder = _bottomBorder; + m_paperFormat = _paper; + + setPaperOrientation( _orientation ); //calcPaperSize() is done here already + +// QPtrListIterator it( views() ); +// for( ;it.current(); ++it ) +// { +// View *v = static_cast( it.current() ); + // We need to trigger the appropriate repaintings in the cells near the + // border of the page. The easiest way for this is to turn the borders + // off and on (or on and off if they were off). +// bool bBorderWasShown = v->activeSheet()->isShowPageBorders(); +// v->activeSheet()->setShowPageBorders( !bBorderWasShown ); +// v->activeSheet()->setShowPageBorders( bBorderWasShown ); +// } + + m_pDoc->setModified( true ); +} + +void SheetPrint::setPaperLayout( float _leftBorder, float _topBorder, + float _rightBorder, float _bottomBorder, + const QString& _paper, + const QString& _orientation ) +{ + if ( m_pSheet->isProtected() ) + NO_MODIFICATION_POSSIBLE; + + KoFormat f = paperFormat(); + KoOrientation newOrientation = orientation(); + + if ( _orientation == "Portrait" ) + newOrientation = PG_PORTRAIT; + else if ( _orientation == "Landscape" ) + newOrientation = PG_LANDSCAPE; + + + QString paper( _paper ); + if ( paper[0].isDigit() ) // Custom format + { + const int i = paper.find( 'x' ); + if ( i < 0 ) + { + // We have nothing useful, so assume ISO A4 + f = PG_DIN_A4; + } + else + { + f = PG_CUSTOM; + m_paperWidth = paper.left(i).toFloat(); + m_paperHeight = paper.mid(i+1).toFloat(); + if ( m_paperWidth < 10.0 ) + m_paperWidth = KoPageFormat::width( PG_DIN_A4, newOrientation ); + if ( m_paperHeight < 10.0 ) + m_paperHeight = KoPageFormat::height( PG_DIN_A4, newOrientation ); + } + } + else + { + f = KoPageFormat::formatFromString( paper ); + if ( f == PG_CUSTOM ) + // We have no idea about height or width, therefore assume ISO A4 + f = PG_DIN_A4; + } + setPaperLayout( _leftBorder, _topBorder, _rightBorder, _bottomBorder, f, newOrientation ); +} + +void SheetPrint::calcPaperSize() +{ + if ( m_paperFormat != PG_CUSTOM ) + { + m_paperWidth = KoPageFormat::width( m_paperFormat, m_orientation ); + m_paperHeight = KoPageFormat::height( m_paperFormat, m_orientation ); + } +} + +QValueList::iterator SheetPrint::findNewPageColumn( int col ) +{ + QValueList::iterator it; + for( it = m_lnewPageListX.begin(); it != m_lnewPageListX.end(); ++it ) + { + if( (*it).startItem() == col ) + return it; + } + return it; +// QValueList::iterator it; +// it = m_lnewPageListX.find( startCol ); +} + +QValueList::iterator SheetPrint::findNewPageRow( int row ) +{ + QValueList::iterator it; + for( it = m_lnewPageListY.begin(); it != m_lnewPageListY.end(); ++it ) + { + if( (*it).startItem() == row ) + return it; + } + return it; +} + + +QString SheetPrint::paperFormatString()const +{ + if ( m_paperFormat == PG_CUSTOM ) + { + QString tmp; + tmp.sprintf( "%fx%f", m_paperWidth, m_paperHeight ); + return tmp; + } + + return KoPageFormat::formatString( m_paperFormat ); +} + +const char* SheetPrint::orientationString() const +{ + switch( m_orientation ) + { + case KPrinter::Portrait: + return "Portrait"; + case KPrinter::Landscape: + return "Landscape"; + } + + kdWarning(36001)<<"SheetPrint: Unknown orientation, using now portrait"<url().path()); + if ( pathFileName.isNull() ) + pathFileName=""; + + QString fileName(m_pDoc->url().fileName()); + if( fileName.isNull()) + fileName=""; + + QString t(QTime::currentTime().toString()); + QString d(QDate::currentDate().toString()); + QString ta; + if ( !_sheet.isEmpty() ) + ta = _sheet; + + KoDocumentInfo * info = m_pDoc->documentInfo(); + KoDocumentInfoAuthor * authorPage = static_cast(info->page( "author" )); + QString full_name; + QString email_addr; + QString organization; + QString tmp; + if ( !authorPage ) + kdWarning() << "Author information not found in Document Info !" << endl; + else + { + full_name = authorPage->fullName(); + email_addr = authorPage->email(); + organization = authorPage->company(); + } + + char hostname[80]; + struct passwd *p; + + p = getpwuid(getuid()); + gethostname(hostname, sizeof(hostname)); + + if(full_name.isEmpty()) + full_name=p->pw_gecos; + + if( email_addr.isEmpty()) + email_addr = QString("%1@%2").arg(p->pw_name).arg(hostname); + + tmp = _data; + int pos = 0; + while ( ( pos = tmp.find( "", pos ) ) != -1 ) + tmp.replace( pos, 6, page ); + pos = 0; + while ( ( pos = tmp.find( "", pos ) ) != -1 ) + tmp.replace( pos, 7, pages ); + pos = 0; + while ( ( pos = tmp.find( "", pos ) ) != -1 ) + tmp.replace( pos, 6, pathFileName ); + pos = 0; + while ( ( pos = tmp.find( "", pos ) ) != -1 ) + tmp.replace( pos, 6, fileName ); + pos = 0; + while ( ( pos = tmp.find( "