/* 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 = TQRect( TQPoint( 1, 1 ), TQPoint( 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 = tqMakePair( 0, 0 ); m_printRepeatRows = tqMakePair( 0, 0 ); m_dZoom = 1.0; m_iPageLimitX = 0; m_iPageLimitY = 0; calcPaperSize(); } SheetPrint::~SheetPrint() { // nothing todo yet } TQString 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" ); } TQRect SheetPrint::cellsPrintRange() { // Find maximum right/bottom cell with content TQRect 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 tqchildren TQPtrListIterator cit( m_pDoc->tqchildren() ); double dummy; int i; for( ; cit.current(); ++cit ) { //TQRect, because KoChild doesn't use KoRect yet TQRect 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 TQRect& 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 TQRect& 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( TQRect& 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 tqchildren on it? TQRect intView = TQRect( TQPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.left() ) ), m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.top() ) ) ), TQPoint( 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() ) ) ); TQPtrListIterator it( m_pDoc->tqchildren() ); for( ;it.current(); ++it ) { TQRect 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( TQPainter &painter, KPrinter *_printer ) { kdDebug(36001)<<"PRINTING ...."<getShowGrid(); m_pSheet->setShowGrid( m_bPrintGrid ); if ( !m_bPrintGrid ) { gridPen = TQPen( m_pDoc->gridColor(), 1, TQt::SolidLine ); TQPen nopen; nopen.setStyle( Qt::NoPen ); m_pDoc->setGridColor( TQt::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 TQRect 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. TQValueList page_list; //contains the cols and rows of a page TQValueList page_frame_list; //contains the coordinate range of a page TQValueList page_frame_list_offset; //contains the offset of the not repeated area TQValueList::iterator itX; TQValueList::iterator itY; for( itX = m_lnewPageListX.begin(); itX != m_lnewPageListX.end(); ++itX ) { for( itY = m_lnewPageListY.begin(); itY != m_lnewPageListY.end(); ++itY ) { TQRect page_range( TQPoint( (*itX).startItem(), (*itY).startItem() ), TQPoint( (*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. TQPtrListIterator 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; TQRect zoomRect = m_pDoc->zoomRect( itObject.current()->tqgeometry() ); TQPixmap *p = new TQPixmap( zoomRect.size() ); TQPainter painter(p); painter.fillRect( p->rect(), TQColor("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( TQPen( TQt::black, 1 ) ); painter.drawPoint( 1, 1 ); } else { int pageNo = 1; // // Print all pages in the list // TQValueList::Iterator it = page_list.begin(); TQValueList::Iterator fit = page_frame_list.begin(); TQValueList::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 ); TQValueList::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( TQPainter &_painter, const TQRect& 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 ) ) { //TQRect(left,top,width,height) <<<< WIDTH AND HEIGHT!!! TQRect _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 ) { TQRect _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 ) { TQRect _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( TQPainter& painter, const KoPoint& topLeft, const TQRect& printRect, const KoRect& view, TQRegion &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 ); TQValueList 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; TQPen rightPen = cell->effRightBorderPen( x, y ); TQPen leftPen = cell->effLeftBorderPen( x, y ); TQPen bottomPen = cell->effBottomBorderPen( x, y ); TQPen 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; TQPen highlightPen; if ( m_pSheet->layoutDirection()==Sheet::RightToLeft ) cell->paintCell( rect, painter, NULL, KoPoint( view.width() - xpos - col_lay->dblWidth(), ypos ), TQPoint( x, y ), paintBorder, rightPen, bottomPen, leftPen, topPen, mergedCellsPainted); else cell->paintCell( rect, painter, NULL, KoPoint( xpos, ypos ), TQPoint( x, y ), paintBorder, rightPen, bottomPen, leftPen, topPen, mergedCellsPainted); xpos += col_lay->dblWidth(); } ypos += row_lay->dblHeight(); } // // Draw the tqchildren // TQRect zoomedView = m_pDoc->zoomRect( view ); //TQPtrListIterator it( m_pDoc->tqchildren() ); //TQPtrListIterator itObject( m_pDoc->embeddedObjects() ); TQValueList::iterator itObject; for ( itObject = m_printObjects.begin(); itObject != m_printObjects.end(); ++itObject ) { EmbeddedObject *obj = (*itObject)->obj; // TQString tmp=TQString("Testing child %1/%2 %3/%4 against view %5/%6 %7/%8") // .tqarg(it.current()->contentRect().left()) // .tqarg(it.current()->contentRect().top()) // .tqarg(it.current()->contentRect().right()) // .tqarg(it.current()->contentRect().bottom()) // .tqarg(view.left()).tqarg(view.top()).tqarg(zoomedView.right()).tqarg(zoomedView.bottom()); // kdDebug(36001)<tqgeometry(); TQRect 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->tqgeometry() ).topLeft(), *(*itObject)->p ); //draw the cached object //painter.fillRect(zoomedBound, TQBrush("red")); //for debug purpose painter.restore(); } } //Don't let obscuring cells and tqchildren overpaint this area clipRegion -= TQRegion ( 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( TQPainter &painter, int pageNo ) { double w; double headFootDistance = MM_TO_POINT( 10.0 /*mm*/ ) / m_dZoom; TQFont font( "Times" ); font.setPointSizeFloat( 0.01 * m_pDoc->zoom() * /* Font size of 10 */ 10.0 / m_dZoom ); painter.setFont( font ); TQFontMetrics 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.tqfindIndex( _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 TQValueList::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.tqfindIndex( _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 TQValueList::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 TQValueList::iterator it; it = m_lnewPageListX.tqfind( _col ); while ( ( it == m_lnewPageListX.end() ) && _col > 0 ) { _col--; it = m_lnewPageListX.tqfind( _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 TQValueList::iterator it; it = m_lnewPageListY.tqfind( _row ); while ( ( it == m_lnewPageListY.end() ) && _row > 0 ) { _row--; it = m_lnewPageListY.tqfind( _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( TQRect( TQPoint( 1, 1 ), TQPoint( KS_colMax, KS_rowMax ) ) ); } void SheetPrint::replaceHeadFootLineMacro ( TQString &_text, const TQString &_search, const TQString &_tqreplace ) { if ( _search != _tqreplace ) _text.tqreplace ( TQString( "<" + _search + ">" ), "<" + _tqreplace + ">" ); } TQString SheetPrint::localizeHeadFootLine ( const TQString &_text ) { TQString 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; } TQString SheetPrint::delocalizeHeadFootLine ( const TQString &_text ) { TQString 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 TQString &_headl, const TQString &_headm, const TQString &_headr, const TQString &_footl, const TQString &_footm, const TQString &_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 // TQPtrListIterator 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 TQString& _paper, const TQString& _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; TQString paper( _paper ); if ( paper[0].isDigit() ) // Custom format { const int i = paper.tqfind( '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 ); } } TQValueList::iterator SheetPrint::findNewPageColumn( int col ) { TQValueList::iterator it; for( it = m_lnewPageListX.begin(); it != m_lnewPageListX.end(); ++it ) { if( (*it).startItem() == col ) return it; } return it; // TQValueList::iterator it; // it = m_lnewPageListX.tqfind( startCol ); } TQValueList::iterator SheetPrint::findNewPageRow( int row ) { TQValueList::iterator it; for( it = m_lnewPageListY.begin(); it != m_lnewPageListY.end(); ++it ) { if( (*it).startItem() == row ) return it; } return it; } TQString SheetPrint::paperFormatString()const { if ( m_paperFormat == PG_CUSTOM ) { TQString 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=""; TQString fileName(m_pDoc->url().fileName()); if( fileName.isNull()) fileName=""; TQString t(TQTime::currentTime().toString()); TQString d(TQDate::tqcurrentDate().toString()); TQString ta; if ( !_sheet.isEmpty() ) ta = _sheet; KoDocumentInfo * info = m_pDoc->documentInfo(); KoDocumentInfoAuthor * authorPage = static_cast(info->page( "author" )); TQString full_name; TQString email_addr; TQString organization; TQString 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 = TQString("%1@%2").tqarg(p->pw_name).tqarg(hostname); tmp = _data; int pos = 0; while ( ( pos = tmp.tqfind( "", pos ) ) != -1 ) tmp.tqreplace( pos, 6, page ); pos = 0; while ( ( pos = tmp.tqfind( "", pos ) ) != -1 ) tmp.tqreplace( pos, 7, pages ); pos = 0; while ( ( pos = tmp.tqfind( "", pos ) ) != -1 ) tmp.tqreplace( pos, 6, pathFileName ); pos = 0; while ( ( pos = tmp.tqfind( "", pos ) ) != -1 ) tmp.tqreplace( pos, 6, fileName ); pos = 0; while ( ( pos = tmp.tqfind( "