kspread

kspread_sheetprint.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>,
3 2003 Philipp Mller <philipp.mueller@gmx.de>
4 2005 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20*/
21
22#include "kspread_sheet.h"
23#include "selection.h"
24#include "kspread_locale.h"
25#include "kspread_doc.h"
26#include "kspread_undo.h"
27
28#include "kspread_sheetprint.h"
29
30#include "commands.h"
31#include <KoDocumentInfo.h>
32
33#include <tdemessagebox.h>
34#include <kprinter.h>
35#include <kdebug.h>
36
37#include <tqregexp.h>
38
39#include <pwd.h>
40#include <unistd.h>
41
42#include "kspread_sheetprint.moc"
43
44#define NO_MODIFICATION_POSSIBLE \
45do { \
46 KMessageBox::error( 0, i18n ( "You cannot change a protected sheet" ) ); return; \
47} while(0)
48
49using namespace KSpread;
50
51SheetPrint::SheetPrint( Sheet* sheet )
52{
53 m_pSheet = sheet;
54 m_pDoc = m_pSheet->doc();
55
56 m_bPrintGrid = false;
57 m_bPrintCommentIndicator = false;
58 m_bPrintFormulaIndicator = false;
59 m_bPrintObjects = true;
60 m_bPrintCharts = true;
61 m_bPrintGraphics = true;
62
63 m_leftBorder = 20.0;
64 m_rightBorder = 20.0;
65 m_topBorder = 20.0;
66 m_bottomBorder = 20.0;
67
68 m_paperFormat = KoPageFormat::defaultFormat();
69 m_orientation = PG_PORTRAIT;
70 m_paperWidth = MM_TO_POINT( KoPageFormat::width( m_paperFormat, m_orientation ) );
71 m_paperHeight = MM_TO_POINT( KoPageFormat::height( m_paperFormat, m_orientation ) );
72 m_printRange = TQRect( TQPoint( 1, 1 ), TQPoint( KS_colMax, KS_rowMax ) );
73 m_lnewPageListX.append( 1 );
74 m_lnewPageListY.append( 1 );
75 m_maxCheckedNewPageX = 1;
76 m_maxCheckedNewPageY = 1;
77 m_dPrintRepeatColumnsWidth = 0.0;
78 m_dPrintRepeatRowsHeight = 0.0;
79 m_printRepeatColumns = qMakePair( 0, 0 );
80 m_printRepeatRows = qMakePair( 0, 0 );
81 m_dZoom = 1.0;
82 m_iPageLimitX = 0;
83 m_iPageLimitY = 0;
84
85 calcPaperSize();
86}
87
88SheetPrint::~SheetPrint()
89{
90 // nothing todo yet
91}
92
93TQString SheetPrint::saveOasisSheetStyleLayout( KoGenStyles &mainStyles )
94{
95 KoGenStyle pageLayout( KoGenStyle::STYLE_PAGELAYOUT );
96 //pageLayout.addAttribute( "style:page-usage", "all" ); FIXME
97 pageLayout.addPropertyPt( "fo:page-width", MM_TO_POINT( paperWidth() ) );
98 pageLayout.addPropertyPt( "fo:page-height", MM_TO_POINT( paperHeight() ) );
99 pageLayout.addProperty( "style:print-orientation", orientation() == PG_LANDSCAPE ? "landscape" : "portrait" );
100 pageLayout.addPropertyPt( "fo:margin-left", MM_TO_POINT(leftBorder() ) );
101 pageLayout.addPropertyPt( "fo:margin-top", MM_TO_POINT(topBorder() ) );
102 pageLayout.addPropertyPt( "fo:margin-right", MM_TO_POINT(rightBorder() ) );
103 pageLayout.addPropertyPt( "fo:margin-bottom", MM_TO_POINT(bottomBorder() ) );
104 //necessary for print setup
105 m_pSheet->saveOasisPrintStyleLayout( pageLayout );
106
107 return mainStyles.lookup( pageLayout, "pm" );
108}
109
110
111TQRect SheetPrint::cellsPrintRange()
112{
113 // Find maximum right/bottom cell with content
114 TQRect cell_range;
115 cell_range.setCoords( 1, 1, 1, 1 );
116
117 Cell* c = m_pSheet->firstCell();
118 for( ;c; c = c->nextCell() )
119 {
120 if ( c->needsPrinting() )
121 {
122 if ( c->column() > cell_range.right() )
123 cell_range.setRight( c->column() );
124 if ( c->row() > cell_range.bottom() )
125 cell_range.setBottom( c->row() );
126 }
127 }
128
129 // Now look at the children
130 TQPtrListIterator<KoDocumentChild> cit( m_pDoc->children() );
131 double dummy;
132 int i;
133 for( ; cit.current(); ++cit )
134 {
135 //TQRect, because KoChild doesn't use KoRect yet
136 TQRect bound = cit.current()->boundingRect();
137
138 i = m_pSheet->leftColumn( bound.right(), dummy );
139 if ( i > cell_range.right() )
140 cell_range.setRight( i );
141
142 i = m_pSheet->topRow( bound.bottom(), dummy );
143 if ( i > cell_range.bottom() )
144 cell_range.setBottom( i );
145 }
146 cell_range = cell_range.intersect( m_printRange );
147
148 return cell_range;
149}
150
151int SheetPrint::pagesX( const TQRect& cellsPrintRange )
152{
153 int pages = 0;
154
155 updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( cellsPrintRange.right() ) + prinsheetWidthPts() ) );
156
157 for( int i = cellsPrintRange.left(); i <= cellsPrintRange.right(); i++ )
158 {
159 if( isOnNewPageX( i ) )
160 pages++;
161 }
162 return pages;
163}
164
165int SheetPrint::pagesY( const TQRect& cellsPrintRange )
166{
167 int pages = 0;
168
169 updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( cellsPrintRange.bottom() ) + prinsheetHeightPts() ) );
170
171 for( int i = cellsPrintRange.top(); i <= cellsPrintRange.bottom(); i++ )
172 {
173 if( isOnNewPageY( i ) )
174 pages++;
175 }
176 return pages;
177}
178
179
180bool SheetPrint::pageNeedsPrinting( TQRect& page_range )
181{
182 // bool filled = false;
183
184 // Look at the cells
185 for( int r = page_range.top(); r <= page_range.bottom() ; ++r )
186 for( int c = page_range.left(); c <= page_range.right() ; ++c )
187 if ( m_pSheet->cellAt( c, r )->needsPrinting() )
188 {
189 return true;
190 }
191 // filled = true;
192
193 //Page empty, but maybe children on it?
194
195 TQRect intView = TQRect( TQPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.left() ) ),
196 m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.top() ) ) ),
197 TQPoint( m_pDoc->zoomItX( m_pSheet->dblColumnPos( page_range.right() ) +
198 m_pSheet->columnFormat( page_range.right() )->dblWidth() ),
199 m_pDoc->zoomItY( m_pSheet->dblRowPos( page_range.bottom() ) +
200 m_pSheet->rowFormat( page_range.bottom() )->dblHeight() ) ) );
201
202 TQPtrListIterator<KoDocumentChild> it( m_pDoc->children() );
203 for( ;it.current(); ++it )
204 {
205 TQRect bound = it.current()->boundingRect();
206 if ( bound.intersects( intView ) )
207 {
208 return true;
209 }
210 //filled = true;
211 }
212
213
214 //Page has no visible content on it, so we don't need to paint it
215 return false;
216}
217
218bool SheetPrint::print( TQPainter &painter, KPrinter *_printer )
219{
220 kdDebug(36001)<<"PRINTING ...."<<endl;
221
222 // Override the current grid pen setting, when set to disable
223 TQPen gridPen;
224 bool oldShowGrid = m_pSheet->getShowGrid();
225 m_pSheet->setShowGrid( m_bPrintGrid );
226 if ( !m_bPrintGrid )
227 {
228 gridPen = TQPen( m_pDoc->gridColor(), 1, TQt::SolidLine );
229 TQPen nopen;
230 nopen.setStyle( TQt::NoPen );
231 m_pDoc->setGridColor( TQt::white );
232 }
233
234 //Update m_dPrintRepeatColumnsWidth for repeated columns
235 //just in case it isn't done yet
236 if ( !m_pSheet->isShowPageBorders() && m_printRepeatColumns.first != 0 )
237 updatePrintRepeatColumnsWidth();
238
239 //Update m_dPrintRepeatRowsHeight for repeated rows
240 //just in case it isn't done yet
241 if ( !m_pSheet->isShowPageBorders() && m_printRepeatRows.first != 0 )
242 updatePrintRepeatRowsHeight();
243
244 //Calculate the range to be printed
245 TQRect cell_range = cellsPrintRange();
246 kdDebug()<<"cellsPrintRange() :"<<cellsPrintRange()<<endl;
247 //Ensure, that our newPage lists are generated for the whole sheet to print
248 //For this we add to the lists the width/height of 1 page
249 updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( cell_range.right() ) + prinsheetWidthPts() ) );
250 updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( cell_range.bottom() ) + prinsheetHeightPts() ) );
251
252 // Find out how many pages need printing
253 // and which cells to print on which page.
254 TQValueList<TQRect> page_list; //contains the cols and rows of a page
255 TQValueList<KoRect> page_frame_list; //contains the coordinate range of a page
256 TQValueList<KoPoint> page_frame_list_offset; //contains the offset of the not repeated area
257
258 TQValueList<PrintNewPageEntry>::iterator itX;
259 TQValueList<PrintNewPageEntry>::iterator itY;
260 for( itX = m_lnewPageListX.begin(); itX != m_lnewPageListX.end(); ++itX )
261 {
262 for( itY = m_lnewPageListY.begin(); itY != m_lnewPageListY.end(); ++itY )
263 {
264 TQRect page_range( TQPoint( (*itX).startItem(), (*itY).startItem() ),
265 TQPoint( (*itX).endItem(), (*itY).endItem() ) );
266 kdDebug()<<" page_range :"<<page_range<<endl;
267 //Append page when there is something to print
268 if ( pageNeedsPrinting( page_range ) )
269 {
270 KoRect view = KoRect( KoPoint( m_pSheet->dblColumnPos( page_range.left() ),
271 m_pSheet->dblRowPos( page_range.top() ) ),
272 KoPoint( m_pSheet->dblColumnPos( page_range.right() ) +
273 m_pSheet->columnFormat( page_range.right() )->dblWidth(),
274 m_pSheet->dblRowPos( page_range.bottom() ) +
275 m_pSheet->rowFormat( page_range.bottom() )->dblHeight() ) );
276 page_list.append( page_range );
277 page_frame_list.append( view );
278 page_frame_list_offset.append( KoPoint( (*itX).offset(), (*itY).offset() ) );
279 }
280 }
281 }
282
283
284 kdDebug(36001) << "PRINTING " << page_list.count() << " pages" << endl;
285 m_uprintPages = page_list.count();
286
287
288 //Cache all object so they only need to be repainted once.
289 TQPtrListIterator<EmbeddedObject> itObject( m_pDoc->embeddedObjects() );
290 for ( ; itObject.current(); ++itObject )
291 {
292 EmbeddedObject *obj = itObject.current();
293 if ( obj->sheet() != m_pSheet ||
294 !( (( obj->getType() == OBJECT_KOFFICE_PART || obj->getType() == OBJECT_PICTURE ) && m_bPrintObjects) ||
295 ( obj->getType() == OBJECT_CHART && m_bPrintCharts ) ) )
296 continue;
297
298 TQRect zoomRect = m_pDoc->zoomRect( itObject.current()->geometry() );
299 TQPixmap *p = new TQPixmap( zoomRect.size() );
300 TQPainter painter(p);
301 painter.fillRect( p->rect(), TQColor("white") );
302 painter.translate( -zoomRect.x(), -zoomRect.y() ); //we cant to paint at (0,0)
303 bool const isSelected = itObject.current()->isSelected();
304 itObject.current()->setSelected( false );
305 itObject.current()->draw( &painter );
306 painter.end();
307 itObject.current()->setSelected( isSelected );
308
309 PrintObject *po = new PrintObject();
310 m_printObjects.append( po );
311 po->obj = itObject.current();
312 po->p = p;
313 }
314
315 if ( page_list.count() == 0 )
316 {
317 // nothing to print
318 painter.setPen( TQPen( TQt::black, 1 ) );
319 painter.drawPoint( 1, 1 );
320 }
321 else
322 {
323
324 int pageNo = 1;
325
326 //
327 // Print all pages in the list
328 //
329 TQValueList<TQRect>::Iterator it = page_list.begin();
330 TQValueList<KoRect>::Iterator fit = page_frame_list.begin();
331 TQValueList<KoPoint>::Iterator fito = page_frame_list_offset.begin();
332
333 for( ; it != page_list.end(); ++it, ++fit, ++fito, ++pageNo )
334 {
335 painter.setClipRect( 0, 0, m_pDoc->zoomItX( paperWidthPts() ),
336 m_pDoc->zoomItY( paperHeightPts() ) );
337 printHeaderFooter( painter, pageNo );
338
339 painter.translate( m_pDoc->zoomItX( leftBorderPts() ),
340 m_pDoc->zoomItY( topBorderPts() ) );
341
342 // Print the page
343 printPage( painter, *it, *fit, *fito );
344
345 painter.translate( - m_pDoc->zoomItX( leftBorderPts() ),
346 - m_pDoc->zoomItY( topBorderPts() ) );
347
348 if ( pageNo < (int)page_list.count() )
349 _printer->newPage();
350 }
351 }
352
353 if ( !m_bPrintGrid )
354 {
355 // Restore the grid pen
356 m_pDoc->setGridColor( gridPen.color() );
357 }
358 m_pSheet->setShowGrid( oldShowGrid );
359
360 TQValueList<PrintObject *>::iterator it;
361 for ( it = m_printObjects.begin(); it != m_printObjects.end(); ++it )
362 delete (*it)->p;
363 m_printObjects.clear();
364
365 return ( page_list.count() > 0 );
366}
367
368void SheetPrint::printPage( TQPainter &_painter, const TQRect& page_range,
369 const KoRect& view, const KoPoint _childOffset )
370{
371 kdDebug(36001) << "Rect x=" << page_range.left() << " y=" << page_range.top() << ", r="
372 << page_range.right() << " b=" << page_range.bottom() << " offsetx: "<< _childOffset.x()
373 << " offsety: " << _childOffset.y() <<" view-x: "<<view.x()<< endl;
374
375 //Don't paint on the page borders
376 TQRegion clipRegion( m_pDoc->zoomItX( leftBorderPts() ),
377 m_pDoc->zoomItY( topBorderPts() ),
378 m_pDoc->zoomItX( view.width() + _childOffset.x() ),
379 m_pDoc->zoomItY( view.height() + _childOffset.y() ) );
380 _painter.setClipRegion( clipRegion );
381
382 //
383 // Draw the cells.
384 //
385 //Check if we have to repeat some rows and columns (top left rect)
386 if ( ( _childOffset.x() != 0.0 ) && ( _childOffset.y() != 0.0 ) )
387 {
388 //TQRect(left,top,width,height) <<<< WIDTH AND HEIGHT!!!
389 TQRect _printRect( m_printRepeatColumns.first, m_printRepeatRows.first,
390 m_printRepeatColumns.second - m_printRepeatColumns.first + 1,
391 m_printRepeatRows.second - m_printRepeatRows.first + 1);
392 KoPoint _topLeft( 0.0, 0.0 );
393
394 printRect( _painter, _topLeft, _printRect, view, clipRegion );
395 }
396
397 //Check if we have to repeat some rows (left rect)
398 if ( _childOffset.y() != 0 )
399 {
400 TQRect _printRect( page_range.left(), m_printRepeatRows.first,
401 page_range.right() - page_range.left() + 1,
402 m_printRepeatRows.second - m_printRepeatRows.first + 1);
403 KoPoint _topLeft( _childOffset.x(), 0.0 );
404
405 printRect( _painter, _topLeft, _printRect, view, clipRegion );
406 }
407
408 //Check if we have to repeat some columns (top right rect)
409 if ( _childOffset.x() != 0 )
410 {
411 TQRect _printRect( m_printRepeatColumns.first, page_range.top(),
412 m_printRepeatColumns.second - m_printRepeatColumns.first + 1,
413 page_range.bottom() - page_range.top() + 1);
414 KoPoint _topLeft( 0.0, _childOffset.y() );
415
416 printRect( _painter, _topLeft, _printRect, view, clipRegion );
417 }
418
419
420 //Print the cells (right data rect)
421 KoPoint _topLeft( _childOffset.x(), _childOffset.y() );
422
423 printRect( _painter, _topLeft, page_range, view, clipRegion );
424}
425
426
427void SheetPrint::printRect( TQPainter& painter, const KoPoint& topLeft,
428 const TQRect& printRect, const KoRect& view,
429 TQRegion &clipRegion )
430{
431 //
432 // Draw the cells.
433 //
434 Cell *cell;
435 RowFormat *row_lay;
436 ColumnFormat *col_lay;
437
438 double xpos = 0;
439 double ypos = topLeft.y();
440
441 int regionBottom = printRect.bottom();
442 int regionRight = printRect.right();
443 int regionLeft = printRect.left();
444 int regionTop = printRect.top();
445
446 //Calculate the output rect
447 KoPoint bottomRight( topLeft );
448 for ( int x = regionLeft; x <= regionRight; ++x )
449 bottomRight.setX( bottomRight.x()
450 + m_pSheet->columnFormat( x )->dblWidth() );
451 for ( int y = regionTop; y <= regionBottom; ++y )
452 bottomRight.setY( bottomRight.y()
453 + m_pSheet->rowFormat( y )->dblHeight() );
454 KoRect rect( topLeft, bottomRight );
455
456 TQValueList<TQPoint> mergedCellsPainted;
457 for ( int y = regionTop; y <= regionBottom; ++y )
458 {
459 row_lay = m_pSheet->rowFormat( y );
460 xpos = topLeft.x();
461
462 for ( int x = regionLeft; x <= regionRight; ++x )
463 {
464 col_lay = m_pSheet->columnFormat( x );
465
466 cell = m_pSheet->cellAt( x, y );
467
468 bool paintBordersBottom = false;
469 bool paintBordersRight = false;
470 bool paintBordersLeft = false;
471 bool paintBordersTop = false;
472
473 TQPen rightPen = cell->effRightBorderPen( x, y );
474 TQPen leftPen = cell->effLeftBorderPen( x, y );
475 TQPen bottomPen = cell->effBottomBorderPen( x, y );
476 TQPen topPen = cell->effTopBorderPen( x, y );
477
478 // paint right border if rightmost cell or if the pen is more "worth" than the left border pen
479 // of the cell on the left or if the cell on the right is not painted. In the latter case get
480 // the pen that is of more "worth"
481 if ( x >= KS_colMax )
482 paintBordersRight = true;
483 else
484 if ( x == regionRight )
485 {
486 paintBordersRight = true;
487 if ( cell->effRightBorderValue( x, y ) < m_pSheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
488 rightPen = m_pSheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
489 }
490 else
491 {
492 paintBordersRight = true;
493 if ( cell->effRightBorderValue( x, y ) < m_pSheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
494 rightPen = m_pSheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
495 }
496
497 // similiar for other borders...
498 // bottom border:
499 if ( y >= KS_rowMax )
500 paintBordersBottom = true;
501 else
502 if ( y == regionBottom )
503 {
504 paintBordersBottom = true;
505 if ( cell->effBottomBorderValue( x, y ) < m_pSheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) )
506 bottomPen = m_pSheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
507 }
508 else
509 {
510 paintBordersBottom = true;
511 if ( cell->effBottomBorderValue( x, y ) < m_pSheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1) )
512 bottomPen = m_pSheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
513 }
514
515 // left border:
516 if ( x == 1 )
517 paintBordersLeft = true;
518 else
519 if ( x == regionLeft )
520 {
521 paintBordersLeft = true;
522 if ( cell->effLeftBorderValue( x, y ) < m_pSheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
523 leftPen = m_pSheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
524 }
525 else
526 {
527 paintBordersLeft = true;
528 if ( cell->effLeftBorderValue( x, y ) < m_pSheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
529 leftPen = m_pSheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
530 }
531
532 // top border:
533 if ( y == 1 )
534 paintBordersTop = true;
535 else
536 if ( y == regionTop )
537 {
538 paintBordersTop = true;
539 if ( cell->effTopBorderValue( x, y ) < m_pSheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
540 topPen = m_pSheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
541 }
542 else
543 {
544 paintBordersTop = true;
545 if ( cell->effTopBorderValue( x, y ) < m_pSheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
546 topPen = m_pSheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
547 }
548
549 int paintBorder=Cell::Border_None;
550 if (paintBordersLeft) paintBorder |= Cell::Border_Left;
551 if (paintBordersRight) paintBorder |= Cell::Border_Right;
552 if (paintBordersTop) paintBorder |= Cell::Border_Top;
553 if (paintBordersBottom) paintBorder |= Cell::Border_Bottom;
554
555 TQPen highlightPen;
556
557 if ( m_pSheet->layoutDirection()==Sheet::RightToLeft )
558 cell->paintCell( rect, painter, NULL,
559 KoPoint( view.width() - xpos -
560 col_lay->dblWidth(), ypos ), TQPoint( x, y ),
561 paintBorder,
562 rightPen, bottomPen, leftPen, topPen,
563 mergedCellsPainted);
564 else
565 cell->paintCell( rect, painter, NULL,
566 KoPoint( xpos, ypos ), TQPoint( x, y ),
567 paintBorder,
568 rightPen, bottomPen, leftPen, topPen,
569 mergedCellsPainted);
570
571 xpos += col_lay->dblWidth();
572 }
573
574 ypos += row_lay->dblHeight();
575 }
576
577 //
578 // Draw the children
579 //
580 TQRect zoomedView = m_pDoc->zoomRect( view );
581 //TQPtrListIterator<KoDocumentChild> it( m_pDoc->children() );
582 //TQPtrListIterator<EmbeddedObject> itObject( m_pDoc->embeddedObjects() );
583
584 TQValueList<PrintObject *>::iterator itObject;
585 for ( itObject = m_printObjects.begin(); itObject != m_printObjects.end(); ++itObject ) {
586 EmbeddedObject *obj = (*itObject)->obj;
587// TQString tmp=TQString("Testing child %1/%2 %3/%4 against view %5/%6 %7/%8")
588// .arg(it.current()->contentRect().left())
589// .arg(it.current()->contentRect().top())
590// .arg(it.current()->contentRect().right())
591// .arg(it.current()->contentRect().bottom())
592// .arg(view.left()).arg(view.top()).arg(zoomedView.right()).arg(zoomedView.bottom());
593// kdDebug(36001)<<tmp<<" offset "<<_childOffset.x()<<"/"<<_childOffset.y()<<endl;
594
595 KoRect const bound = obj->geometry();
596 TQRect zoomedBound = m_pDoc->zoomRect( KoRect(bound.left(), bound.top(),
597 bound.width(),
598 bound.height() ) );
599#if 1
600// kdDebug(36001) << "printRect(): Bounding rect of view: " << view
601// << endl;
602// kdDebug(36001) << "printRect(): Bounding rect of zoomed view: "
603// << zoomedView << endl;
604// kdDebug(36001) << "printRect(): Bounding rect of child: " << bound
605// << endl;
606// kdDebug(36001) << "printRect(): Bounding rect of zoomed child: "
607// << zoomedBound << endl;
608#endif
609 if ( obj->sheet() == m_pSheet && zoomedBound.intersects( zoomedView ) )
610 {
611 painter.save();
612
613 painter.translate( -zoomedView.left() + m_pDoc->zoomItX( topLeft.x() ),
614 -zoomedView.top() + m_pDoc->zoomItY( topLeft.y() ) );
615
616 //obj->draw( &painter );
617 painter.drawPixmap( m_pDoc->zoomRect( obj->geometry() ).topLeft(), *(*itObject)->p ); //draw the cached object
618
619 //painter.fillRect(zoomedBound, TQBrush("red")); //for debug purpose
620 painter.restore();
621 }
622 }
623
624 //Don't let obscuring cells and children overpaint this area
625 clipRegion -= TQRegion ( m_pDoc->zoomItX( leftBorderPts() + topLeft.x() ),
626 m_pDoc->zoomItY( topBorderPts() + topLeft.y() ),
627 m_pDoc->zoomItX( xpos ),
628 m_pDoc->zoomItY( ypos ) );
629 painter.setClipRegion( clipRegion );
630}
631
632
633void SheetPrint::printHeaderFooter( TQPainter &painter, int pageNo )
634{
635 double w;
636 double headFootDistance = MM_TO_POINT( 10.0 /*mm*/ ) / m_dZoom;
637 TQFont font( "Times" );
638 font.setPointSizeFloat( 0.01 * m_pDoc->zoom() *
639 /* Font size of 10 */ 10.0 / m_dZoom );
640 painter.setFont( font );
641 TQFontMetrics fm = painter.fontMetrics();
642
643 // print head line left
644 w = fm.width( headLeft( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
645 if ( w > 0 )
646 painter.drawText( m_pDoc->zoomItX( leftBorderPts() ),
647 m_pDoc->zoomItY( headFootDistance ),
648 headLeft( pageNo, m_pSheet->sheetName() ) );
649 // print head line middle
650 w = fm.width( headMid( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
651 if ( w > 0 )
652 painter.drawText( (int) ( m_pDoc->zoomItX( leftBorderPts() ) +
653 ( m_pDoc->zoomItX( prinsheetWidthPts() ) -
654 w ) / 2.0 ),
655 m_pDoc->zoomItY( headFootDistance ),
656 headMid( pageNo, m_pSheet->sheetName() ) );
657 // print head line right
658 w = fm.width( headRight( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
659 if ( w > 0 )
660 painter.drawText( m_pDoc->zoomItX( leftBorderPts() +
661 prinsheetWidthPts() ) - (int) w,
662 m_pDoc->zoomItY( headFootDistance ),
663 headRight( pageNo, m_pSheet->sheetName() ) );
664
665 // print foot line left
666 w = fm.width( footLeft( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
667 if ( w > 0 )
668 painter.drawText( m_pDoc->zoomItX( leftBorderPts() ),
669 m_pDoc->zoomItY( paperHeightPts() - headFootDistance ),
670 footLeft( pageNo, m_pSheet->sheetName() ) );
671 // print foot line middle
672 w = fm.width( footMid( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
673 if ( w > 0 )
674 painter.drawText( (int) ( m_pDoc->zoomItX( leftBorderPts() ) +
675 ( m_pDoc->zoomItX( prinsheetWidthPts() ) -
676 w ) / 2.0 ),
677 m_pDoc->zoomItY( paperHeightPts() - headFootDistance ),
678 footMid( pageNo, m_pSheet->sheetName() ) );
679 // print foot line right
680 w = fm.width( footRight( pageNo, m_pSheet->sheetName() ) ) / m_dZoom;
681 if ( w > 0 )
682 painter.drawText( m_pDoc->zoomItX( leftBorderPts() +
683 prinsheetWidthPts() ) -
684 (int) w,
685 m_pDoc->zoomItY( paperHeightPts() - headFootDistance ),
686 footRight( pageNo, m_pSheet->sheetName() ) );
687}
688
689
690bool SheetPrint::isOnNewPageX( int _column )
691{
692 if( _column > m_maxCheckedNewPageX )
693 updateNewPageX( _column );
694
695 //Are these the edges of the print range?
696 if ( _column == m_printRange.left() || _column == m_printRange.right() + 1 )
697 {
698 return true;
699 }
700
701 //beyond the print range it's always false
702 if ( _column < m_printRange.left() || _column > m_printRange.right() )
703 {
704 return false;
705 }
706
707 //Now check if we find the column already in the list
708 if ( m_lnewPageListX.findIndex( _column ) != -1 )
709 {
710 if( _column > m_maxCheckedNewPageX )
711 m_maxCheckedNewPageX = _column;
712 return true;
713 }
714 return false;
715}
716
717
718void SheetPrint::updateNewPageX( int _column )
719{
720 float offset = 0.0;
721
722 //Are these the edges of the print range?
723 if ( _column == m_printRange.left() || _column == m_printRange.right() + 1 )
724 {
725 if( _column > m_maxCheckedNewPageX )
726 m_maxCheckedNewPageX = _column;
727 return;
728 }
729
730 //We don't check beyond the print range
731 if ( _column < m_printRange.left() || _column > m_printRange.right() )
732 {
733 if( _column > m_maxCheckedNewPageX )
734 m_maxCheckedNewPageX = _column;
735 if ( _column > m_printRange.right() )
736 {
737 if ( m_lnewPageListX.last().endItem()==0 )
738 m_lnewPageListX.last().setEndItem( m_printRange.right() );
739 }
740 return;
741 }
742
743 //If we start, then add the left printrange
744 if ( m_lnewPageListX.empty() )
745 m_lnewPageListX.append( m_printRange.left() ); //Add the first entry
746
747 //If _column is greater than the last entry, we need to calculate the result
748 if ( _column > m_lnewPageListX.last().startItem() &&
749 _column > m_maxCheckedNewPageX ) //this columns hasn't been calculated before
750 {
751 int startCol = m_lnewPageListX.last().startItem();
752 int col = startCol;
753 double x = m_pSheet->columnFormat( col )->dblWidth();
754
755 //Add repeated column width, when necessary
756 if ( col > m_printRepeatColumns.first )
757 {
758 x += m_dPrintRepeatColumnsWidth;
759 offset = m_dPrintRepeatColumnsWidth;
760 }
761
762 while ( ( col <= _column ) && ( col < m_printRange.right() ) )
763 {
764 if ( x > prinsheetWidthPts() ) //end of page?
765 {
766 //We found a new page, so add it to the list
767 m_lnewPageListX.append( col );
768
769 //Now store into the previous entry the enditem and the width
770 TQValueList<PrintNewPageEntry>::iterator it;
771 it = findNewPageColumn( startCol );
772 (*it).setEndItem( col - 1 );
773 (*it).setSize( x - m_pSheet->columnFormat( col )->dblWidth() );
774 (*it).setOffset( offset );
775
776 //start a new page
777 startCol = col;
778 if ( col == _column )
779 {
780 if( _column > m_maxCheckedNewPageX )
781 m_maxCheckedNewPageX = _column;
782 return;
783 }
784 else
785 {
786 x = m_pSheet->columnFormat( col )->dblWidth();
787 if ( col >= m_printRepeatColumns.first )
788 {
789 x += m_dPrintRepeatColumnsWidth;
790 offset = m_dPrintRepeatColumnsWidth;
791 }
792 }
793 }
794
795 col++;
796 x += m_pSheet->columnFormat( col )->dblWidth();
797 }
798 }
799
800 if( _column > m_maxCheckedNewPageX )
801 m_maxCheckedNewPageX = _column;
802}
803
804
805bool SheetPrint::isOnNewPageY( int _row )
806{
807 if( _row > m_maxCheckedNewPageY )
808 updateNewPageY( _row );
809
810 //Are these the edges of the print range?
811 if ( _row == m_printRange.top() || _row == m_printRange.bottom() + 1 )
812 {
813 return true;
814 }
815
816 //beyond the print range it's always false
817 if ( _row < m_printRange.top() || _row > m_printRange.bottom() )
818 {
819 return false;
820 }
821
822 //Now check if we find the row already in the list
823 if ( m_lnewPageListY.findIndex( _row ) != -1 )
824 {
825 if( _row > m_maxCheckedNewPageY )
826 m_maxCheckedNewPageY = _row;
827 return true;
828 }
829
830 return false;
831}
832
833
834void SheetPrint::updateNewPageY( int _row )
835{
836 float offset = 0.0;
837
838 //Are these the edges of the print range?
839 if ( _row == m_printRange.top() || _row == m_printRange.bottom() + 1 )
840 {
841 if( _row > m_maxCheckedNewPageY )
842 m_maxCheckedNewPageY = _row;
843 return;
844 }
845
846 //beyond the print range it's always false
847 if ( _row < m_printRange.top() || _row > m_printRange.bottom() )
848 {
849 if( _row > m_maxCheckedNewPageY )
850 m_maxCheckedNewPageY = _row;
851 if ( _row > m_printRange.bottom() )
852 {
853 if ( m_lnewPageListY.last().endItem()==0 )
854 m_lnewPageListY.last().setEndItem( m_printRange.bottom() );
855 }
856 return;
857 }
858
859 //If we start, then add the top printrange
860 if ( m_lnewPageListY.empty() )
861 m_lnewPageListY.append( m_printRange.top() ); //Add the first entry
862
863 //If _column is greater than the last entry, we need to calculate the result
864 if ( _row > m_lnewPageListY.last().startItem() &&
865 _row > m_maxCheckedNewPageY ) //this columns hasn't been calculated before
866 {
867 int startRow = m_lnewPageListY.last().startItem();
868 int row = startRow;
869 double y = m_pSheet->rowFormat( row )->dblHeight();
870
871 //Add repeated row height, when necessary
872 if ( row > m_printRepeatRows.first )
873 {
874 y += m_dPrintRepeatRowsHeight;
875 offset = m_dPrintRepeatRowsHeight;
876 }
877
878 while ( ( row <= _row ) && ( row < m_printRange.bottom() ) )
879 {
880 if ( y > prinsheetHeightPts() )
881 {
882 //We found a new page, so add it to the list
883 m_lnewPageListY.append( row );
884
885 //Now store into the previous entry the enditem and the width
886 TQValueList<PrintNewPageEntry>::iterator it;
887 it = findNewPageRow( startRow );
888 (*it).setEndItem( row - 1 );
889 (*it).setSize( y - m_pSheet->rowFormat( row )->dblHeight() );
890 (*it).setOffset( offset );
891
892 //start a new page
893 startRow = row;
894 if ( row == _row )
895 {
896 if( _row > m_maxCheckedNewPageY )
897 m_maxCheckedNewPageY = _row;
898 return;
899 }
900 else
901 {
902 y = m_pSheet->rowFormat( row )->dblHeight();
903 if ( row >= m_printRepeatRows.first )
904 {
905 y += m_dPrintRepeatRowsHeight;
906 offset = m_dPrintRepeatRowsHeight;
907 }
908 }
909 }
910
911 row++;
912 y += m_pSheet->rowFormat( row )->dblHeight();
913 }
914 }
915
916 if( _row > m_maxCheckedNewPageY )
917 m_maxCheckedNewPageY = _row;
918}
919
920
921void SheetPrint::updateNewPageListX( int _col )
922{
923 //If the new range is after the first entry, we need to delete the whole list
924 if ( m_lnewPageListX.first().startItem() != m_printRange.left() ||
925 _col == 0 )
926 {
927 m_lnewPageListX.clear();
928 m_maxCheckedNewPageX = m_printRange.left();
929 m_lnewPageListX.append( m_printRange.left() );
930 return;
931 }
932
933 if ( _col < m_lnewPageListX.last().startItem() )
934 {
935 //Find the page entry for this column
936 TQValueList<PrintNewPageEntry>::iterator it;
937 it = m_lnewPageListX.find( _col );
938 while ( ( it == m_lnewPageListX.end() ) && _col > 0 )
939 {
940 _col--;
941 it = m_lnewPageListX.find( _col );
942 }
943
944 //Remove later pages
945 while ( it != m_lnewPageListX.end() )
946 it = m_lnewPageListX.remove( it );
947
948 //Add default page when list is now empty
949 if ( m_lnewPageListX.empty() )
950 m_lnewPageListX.append( m_printRange.left() );
951 }
952
953 m_maxCheckedNewPageX = _col;
954}
955
956void SheetPrint::updateNewPageListY( int _row )
957{
958 //If the new range is after the first entry, we need to delete the whole list
959 if ( m_lnewPageListY.first().startItem() != m_printRange.top() ||
960 _row == 0 )
961 {
962 m_lnewPageListY.clear();
963 m_maxCheckedNewPageY = m_printRange.top();
964 m_lnewPageListY.append( m_printRange.top() );
965 return;
966 }
967
968 if ( _row < m_lnewPageListY.last().startItem() )
969 {
970 //Find the page entry for this row
971 TQValueList<PrintNewPageEntry>::iterator it;
972 it = m_lnewPageListY.find( _row );
973 while ( ( it == m_lnewPageListY.end() ) && _row > 0 )
974 {
975 _row--;
976 it = m_lnewPageListY.find( _row );
977 }
978
979 //Remove later pages
980 while ( it != m_lnewPageListY.end() )
981 it = m_lnewPageListY.remove( it );
982
983 //Add default page when list is now empty
984 if ( m_lnewPageListY.empty() )
985 m_lnewPageListY.append( m_printRange.top() );
986 }
987
988 m_maxCheckedNewPageY = _row;
989}
990
991void SheetPrint::definePrintRange( Selection* selectionInfo )
992{
993 if ( !selectionInfo->isSingular() )
994 {
995 KCommand* command = new DefinePrintRangeCommand( m_pSheet );
996 m_pDoc->addCommand( command );
997 setPrintRange( selectionInfo->selection() );
998 }
999}
1000
1001void SheetPrint::resetPrintRange ()
1002{
1003 KCommand* command = new DefinePrintRangeCommand( m_pSheet );
1004 m_pDoc->addCommand( command );
1005 setPrintRange( TQRect( TQPoint( 1, 1 ), TQPoint( KS_colMax, KS_rowMax ) ) );
1006}
1007
1008void SheetPrint::replaceHeadFootLineMacro ( TQString &_text, const TQString &_search, const TQString &_replace )
1009{
1010 if ( _search != _replace )
1011 _text.replace ( TQString( "<" + _search + ">" ), "<" + _replace + ">" );
1012}
1013
1014TQString SheetPrint::localizeHeadFootLine ( const TQString &_text )
1015{
1016 TQString tmp = _text;
1017
1018 /*
1019 i18n:
1020 Please use the same words (even upper/lower case) as in
1021 KoPageLayoutDia.cpp function setupTab2(), without the brakets "<" and ">"
1022 */
1023 replaceHeadFootLineMacro ( tmp, "page", i18n("page") );
1024 replaceHeadFootLineMacro ( tmp, "pages", i18n("pages") );
1025 replaceHeadFootLineMacro ( tmp, "file", i18n("file") );
1026 replaceHeadFootLineMacro ( tmp, "name", i18n("name") );
1027 replaceHeadFootLineMacro ( tmp, "time", i18n("time") );
1028 replaceHeadFootLineMacro ( tmp, "date", i18n("date") );
1029 replaceHeadFootLineMacro ( tmp, "author", i18n("author") );
1030 replaceHeadFootLineMacro ( tmp, "email", i18n("email") );
1031 replaceHeadFootLineMacro ( tmp, "org", i18n("org") );
1032 replaceHeadFootLineMacro ( tmp, "sheet", i18n("sheet") );
1033
1034 return tmp;
1035}
1036
1037
1038TQString SheetPrint::delocalizeHeadFootLine ( const TQString &_text )
1039{
1040 TQString tmp = _text;
1041
1042 /*
1043 i18n:
1044 Please use the same words (even upper/lower case) as in
1045 KoPageLayoutDia.cpp function setupTab2(), without the brakets "<" and ">"
1046 */
1047 replaceHeadFootLineMacro ( tmp, i18n("page"), "page" );
1048 replaceHeadFootLineMacro ( tmp, i18n("pages"), "pages" );
1049 replaceHeadFootLineMacro ( tmp, i18n("file"), "file" );
1050 replaceHeadFootLineMacro ( tmp, i18n("name"), "name" );
1051 replaceHeadFootLineMacro ( tmp, i18n("time"), "time" );
1052 replaceHeadFootLineMacro ( tmp, i18n("date"), "date" );
1053 replaceHeadFootLineMacro ( tmp, i18n("author"), "author" );
1054 replaceHeadFootLineMacro ( tmp, i18n("email"), "email" );
1055 replaceHeadFootLineMacro ( tmp, i18n("org"), "org" );
1056 replaceHeadFootLineMacro ( tmp, i18n("sheet"), "sheet" );
1057
1058 return tmp;
1059}
1060
1061
1062KoHeadFoot SheetPrint::headFootLine() const
1063{
1064 KoHeadFoot hf;
1065 hf.headLeft = m_headLeft;
1066 hf.headRight = m_headRight;
1067 hf.headMid = m_headMid;
1068 hf.footLeft = m_footLeft;
1069 hf.footRight = m_footRight;
1070 hf.footMid = m_footMid;
1071
1072 return hf;
1073}
1074
1075
1076void SheetPrint::setHeadFootLine( const TQString &_headl, const TQString &_headm, const TQString &_headr,
1077 const TQString &_footl, const TQString &_footm, const TQString &_footr )
1078{
1079 if ( m_pSheet->isProtected() )
1080 NO_MODIFICATION_POSSIBLE;
1081
1082 m_headLeft = _headl;
1083 m_headRight = _headr;
1084 m_headMid = _headm;
1085 m_footLeft = _footl;
1086 m_footRight = _footr;
1087 m_footMid = _footm;
1088
1089 m_pDoc->setModified( true );
1090}
1091
1092void SheetPrint::setPaperOrientation( KoOrientation _orient )
1093{
1094 if ( m_pSheet->isProtected() )
1095 NO_MODIFICATION_POSSIBLE;
1096
1097 m_orientation = _orient;
1098 calcPaperSize();
1099 updatePrintRepeatColumnsWidth();
1100 updatePrintRepeatRowsHeight();
1101 updateNewPageListX( m_printRange.left() ); //Reset the list
1102 updateNewPageListY( m_printRange.top() ); //Reset the list
1103
1104 if( m_pSheet->isShowPageBorders() )
1105 emit sig_updateView( m_pSheet );
1106}
1107
1108
1109KoPageLayout SheetPrint::paperLayout() const
1110{
1111 KoPageLayout pl;
1112 pl.format = m_paperFormat;
1113 pl.orientation = m_orientation;
1114 pl.ptWidth = m_paperWidth;
1115 pl.ptHeight = m_paperHeight;
1116 pl.ptLeft = m_leftBorder;
1117 pl.ptRight = m_rightBorder;
1118 pl.ptTop = m_topBorder;
1119 pl.ptBottom = m_bottomBorder;
1120 return pl;
1121}
1122
1123
1124void SheetPrint::setPaperLayout( float _leftBorder, float _topBorder,
1125 float _rightBorder, float _bottomBorder,
1126 KoFormat _paper,
1127 KoOrientation _orientation )
1128{
1129 if ( m_pSheet->isProtected() )
1130 NO_MODIFICATION_POSSIBLE;
1131
1132 m_leftBorder = _leftBorder;
1133 m_rightBorder = _rightBorder;
1134 m_topBorder = _topBorder;
1135 m_bottomBorder = _bottomBorder;
1136 m_paperFormat = _paper;
1137
1138 setPaperOrientation( _orientation ); //calcPaperSize() is done here already
1139
1140// TQPtrListIterator<KoView> it( views() );
1141// for( ;it.current(); ++it )
1142// {
1143// View *v = static_cast<View *>( it.current() );
1144 // We need to trigger the appropriate repaintings in the cells near the
1145 // border of the page. The easiest way for this is to turn the borders
1146 // off and on (or on and off if they were off).
1147// bool bBorderWasShown = v->activeSheet()->isShowPageBorders();
1148// v->activeSheet()->setShowPageBorders( !bBorderWasShown );
1149// v->activeSheet()->setShowPageBorders( bBorderWasShown );
1150// }
1151
1152 m_pDoc->setModified( true );
1153}
1154
1155void SheetPrint::setPaperLayout( float _leftBorder, float _topBorder,
1156 float _rightBorder, float _bottomBorder,
1157 const TQString& _paper,
1158 const TQString& _orientation )
1159{
1160 if ( m_pSheet->isProtected() )
1161 NO_MODIFICATION_POSSIBLE;
1162
1163 KoFormat f = paperFormat();
1164 KoOrientation newOrientation = orientation();
1165
1166 if ( _orientation == "Portrait" )
1167 newOrientation = PG_PORTRAIT;
1168 else if ( _orientation == "Landscape" )
1169 newOrientation = PG_LANDSCAPE;
1170
1171
1172 TQString paper( _paper );
1173 if ( paper[0].isDigit() ) // Custom format
1174 {
1175 const int i = paper.find( 'x' );
1176 if ( i < 0 )
1177 {
1178 // We have nothing useful, so assume ISO A4
1179 f = PG_DIN_A4;
1180 }
1181 else
1182 {
1183 f = PG_CUSTOM;
1184 m_paperWidth = paper.left(i).toFloat();
1185 m_paperHeight = paper.mid(i+1).toFloat();
1186 if ( m_paperWidth < 10.0 )
1187 m_paperWidth = KoPageFormat::width( PG_DIN_A4, newOrientation );
1188 if ( m_paperHeight < 10.0 )
1189 m_paperHeight = KoPageFormat::height( PG_DIN_A4, newOrientation );
1190 }
1191 }
1192 else
1193 {
1194 f = KoPageFormat::formatFromString( paper );
1195 if ( f == PG_CUSTOM )
1196 // We have no idea about height or width, therefore assume ISO A4
1197 f = PG_DIN_A4;
1198 }
1199 setPaperLayout( _leftBorder, _topBorder, _rightBorder, _bottomBorder, f, newOrientation );
1200}
1201
1202void SheetPrint::calcPaperSize()
1203{
1204 if ( m_paperFormat != PG_CUSTOM )
1205 {
1206 m_paperWidth = KoPageFormat::width( m_paperFormat, m_orientation );
1207 m_paperHeight = KoPageFormat::height( m_paperFormat, m_orientation );
1208 }
1209}
1210
1211TQValueList<PrintNewPageEntry>::iterator SheetPrint::findNewPageColumn( int col )
1212{
1213 TQValueList<PrintNewPageEntry>::iterator it;
1214 for( it = m_lnewPageListX.begin(); it != m_lnewPageListX.end(); ++it )
1215 {
1216 if( (*it).startItem() == col )
1217 return it;
1218 }
1219 return it;
1220// TQValueList<PrintNewPageEntry>::iterator it;
1221// it = m_lnewPageListX.find( startCol );
1222}
1223
1224TQValueList<PrintNewPageEntry>::iterator SheetPrint::findNewPageRow( int row )
1225{
1226 TQValueList<PrintNewPageEntry>::iterator it;
1227 for( it = m_lnewPageListY.begin(); it != m_lnewPageListY.end(); ++it )
1228 {
1229 if( (*it).startItem() == row )
1230 return it;
1231 }
1232 return it;
1233}
1234
1235
1236TQString SheetPrint::paperFormatString()const
1237{
1238 if ( m_paperFormat == PG_CUSTOM )
1239 {
1240 TQString tmp;
1241 tmp.sprintf( "%fx%f", m_paperWidth, m_paperHeight );
1242 return tmp;
1243 }
1244
1245 return KoPageFormat::formatString( m_paperFormat );
1246}
1247
1248const char* SheetPrint::orientationString() const
1249{
1250 switch( m_orientation )
1251 {
1252 case KPrinter::Portrait:
1253 return "Portrait";
1254 case KPrinter::Landscape:
1255 return "Landscape";
1256 }
1257
1258 kdWarning(36001)<<"SheetPrint: Unknown orientation, using now portrait"<<endl;
1259 return 0;
1260}
1261
1262TQString SheetPrint::completeHeading( const TQString &_data, int _page, const TQString &_sheet ) const
1263{
1264 TQString page( TQString::number( _page) );
1265 TQString pages( TQString::number( m_uprintPages ) );
1266
1267 TQString pathFileName(m_pDoc->url().path());
1268 if ( pathFileName.isNull() )
1269 pathFileName="";
1270
1271 TQString fileName(m_pDoc->url().fileName());
1272 if( fileName.isNull())
1273 fileName="";
1274
1275 TQString t(TQTime::currentTime().toString());
1276 TQString d(TQDate::currentDate().toString());
1277 TQString ta;
1278 if ( !_sheet.isEmpty() )
1279 ta = _sheet;
1280
1281 KoDocumentInfo * info = m_pDoc->documentInfo();
1282 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author" ));
1283 TQString full_name;
1284 TQString email_addr;
1285 TQString organization;
1286 TQString tmp;
1287 if ( !authorPage )
1288 kdWarning() << "Author information not found in Document Info !" << endl;
1289 else
1290 {
1291 full_name = authorPage->fullName();
1292 email_addr = authorPage->email();
1293 organization = authorPage->company();
1294 }
1295
1296 char hostname[80];
1297 struct passwd *p;
1298
1299 p = getpwuid(getuid());
1300 gethostname(hostname, sizeof(hostname));
1301
1302 if(full_name.isEmpty())
1303 full_name=p->pw_gecos;
1304
1305 if( email_addr.isEmpty())
1306 email_addr = TQString("%1@%2").arg(p->pw_name).arg(hostname);
1307
1308 tmp = _data;
1309 int pos = 0;
1310 while ( ( pos = tmp.find( "<page>", pos ) ) != -1 )
1311 tmp.replace( pos, 6, page );
1312 pos = 0;
1313 while ( ( pos = tmp.find( "<pages>", pos ) ) != -1 )
1314 tmp.replace( pos, 7, pages );
1315 pos = 0;
1316 while ( ( pos = tmp.find( "<file>", pos ) ) != -1 )
1317 tmp.replace( pos, 6, pathFileName );
1318 pos = 0;
1319 while ( ( pos = tmp.find( "<name>", pos ) ) != -1 )
1320 tmp.replace( pos, 6, fileName );
1321 pos = 0;
1322 while ( ( pos = tmp.find( "<time>", pos ) ) != -1 )
1323 tmp.replace( pos, 6, t );
1324 pos = 0;
1325 while ( ( pos = tmp.find( "<date>", pos ) ) != -1 )
1326 tmp.replace( pos, 6, d );
1327 pos = 0;
1328 while ( ( pos = tmp.find( "<author>", pos ) ) != -1 )
1329 tmp.replace( pos, 8, full_name );
1330 pos = 0;
1331 while ( ( pos = tmp.find( "<email>", pos ) ) != -1 )
1332 tmp.replace( pos, 7, email_addr );
1333 pos = 0;
1334 while ( ( pos = tmp.find( "<org>", pos ) ) != -1 )
1335 tmp.replace( pos, 5, organization );
1336 pos = 0;
1337 while ( ( pos = tmp.find( "<sheet>", pos ) ) != -1 )
1338 tmp.replace( pos, 7, ta );
1339
1340 return tmp;
1341}
1342
1343void SheetPrint::setPrintRange( const TQRect &_printRange )
1344{
1345 if ( m_pSheet->isProtected() )
1346 NO_MODIFICATION_POSSIBLE;
1347
1348
1349 if ( m_printRange == _printRange )
1350 return;
1351
1352 int oldLeft = m_printRange.left();
1353 int oldTop = m_printRange.top();
1354 m_printRange = _printRange;
1355
1356 //Refresh calculation of stored page breaks, the lower one of old and new
1357 if ( oldLeft != _printRange.left() )
1358 updateNewPageListX( TQMIN( oldLeft, _printRange.left() ) );
1359 if ( oldTop != _printRange.top() )
1360 updateNewPageListY( TQMIN( oldTop, _printRange.top() ) );
1361
1362 m_pDoc->setModified( true );
1363
1364 emit sig_updateView( m_pSheet );
1365
1366}
1367
1368void SheetPrint::setPageLimitX( int pages )
1369{
1370 //We do want an update in any case because the sheet content
1371 //could have changed, thus we need to recalculate although
1372 //it's the same setting!
1373// if( m_iPageLimitX == pages )
1374// return;
1375
1376 m_iPageLimitX = pages;
1377
1378 if( pages == 0 )
1379 return;
1380
1381 calculateZoomForPageLimitX();
1382}
1383
1384void SheetPrint::setPageLimitY( int pages )
1385{
1386 //We do want an update in any case because the sheet content
1387 //could have changed, thus we need to recalculate although
1388 //it's the same setting!
1389// if( m_iPageLimitY == pages )
1390// return;
1391
1392 m_iPageLimitY = pages;
1393
1394 if( pages == 0 )
1395 return;
1396
1397 calculateZoomForPageLimitY();
1398}
1399
1400void SheetPrint::calculateZoomForPageLimitX()
1401{
1402 kdDebug() << "Calculating zoom for X limit" << endl;
1403 if( m_iPageLimitX == 0 )
1404 return;
1405
1406 double origZoom = m_dZoom;
1407
1408 if( m_dZoom < 1.0 )
1409 m_dZoom = 1.0;
1410
1411 TQRect printRange = cellsPrintRange();
1412 updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( printRange.right() ) + prinsheetWidthPts() ) );
1413 int currentPages = pagesX( printRange );
1414
1415 if (currentPages <= m_iPageLimitX)
1416 return;
1417
1418 //calculating a factor for scaling the zoom down makes it lots faster
1419 double factor = (double)m_iPageLimitX/(double)currentPages +
1420 1-(double)currentPages/((double)currentPages+1); //add possible error;
1421 kdDebug() << "Calculated factor for scaling m_dZoom: " << factor << endl;
1422 m_dZoom = m_dZoom*factor;
1423
1424 kdDebug() << "New exact zoom: " << m_dZoom << endl;
1425
1426 if (m_dZoom < 0.01)
1427 m_dZoom = 0.01;
1428 if (m_dZoom > 1.0)
1429 m_dZoom = 1.0;
1430
1431 m_dZoom = (((int)(m_dZoom*100 + 0.5))/100.0);
1432
1433 kdDebug() << "New rounded zoom: " << m_dZoom << endl;
1434
1435 updatePrintRepeatColumnsWidth();
1436 updateNewPageListX( 0 );
1437 updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( printRange.right() ) + prinsheetWidthPts() ) );
1438 currentPages = pagesX( printRange );
1439
1440 kdDebug() << "Number of pages with this zoom: " << currentPages << endl;
1441
1442 while( ( currentPages > m_iPageLimitX ) && ( m_dZoom > 0.01 ) )
1443 {
1444 m_dZoom -= 0.01;
1445 updatePrintRepeatColumnsWidth();
1446 updateNewPageListX( 0 );
1447 updateNewPageX( m_pSheet->rightColumn( m_pSheet->dblColumnPos( printRange.right() ) + prinsheetWidthPts() ) );
1448 currentPages = pagesX( printRange );
1449 kdDebug() << "Looping -0.01; current zoom: " << m_dZoom << endl;
1450 }
1451
1452 if ( m_dZoom < origZoom )
1453 {
1454 double newZoom = m_dZoom;
1455 m_dZoom += 1.0; //set it to something different
1456 setZoom( newZoom, false );
1457 }
1458 else
1459 m_dZoom = origZoom;
1460}
1461
1462void SheetPrint::calculateZoomForPageLimitY()
1463{
1464 kdDebug() << "Calculating zoom for Y limit" << endl;
1465 if( m_iPageLimitY == 0 )
1466 return;
1467
1468 double origZoom = m_dZoom;
1469
1470 if( m_dZoom < 1.0 )
1471 m_dZoom = 1.0;
1472
1473 TQRect printRange = cellsPrintRange();
1474 updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( printRange.bottom() ) + prinsheetHeightPts() ) );
1475 int currentPages = pagesY( printRange );
1476
1477 if (currentPages <= m_iPageLimitY)
1478 return;
1479
1480 double factor = (double)m_iPageLimitY/(double)currentPages +
1481 1-(double)currentPages/((double)currentPages+1); //add possible error
1482 kdDebug() << "Calculated factor for scaling m_dZoom: " << factor << endl;
1483 m_dZoom = m_dZoom*factor;
1484
1485 kdDebug() << "New exact zoom: " << m_dZoom << endl;
1486
1487 if (m_dZoom < 0.01)
1488 m_dZoom = 0.01;
1489 if (m_dZoom > 1.0)
1490 m_dZoom = 1.0;
1491
1492 m_dZoom = (((int)(m_dZoom*100 + 0.5))/100.0);
1493
1494 kdDebug() << "New rounded zoom: " << m_dZoom << endl;
1495
1496 updatePrintRepeatRowsHeight();
1497 updateNewPageListY( 0 );
1498 updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( printRange.bottom() ) + prinsheetHeightPts() ) );
1499 currentPages = pagesY( printRange );
1500
1501 kdDebug() << "Number of pages with this zoom: " << currentPages << endl;
1502
1503 while( ( currentPages > m_iPageLimitY ) && ( m_dZoom > 0.01 ) )
1504 {
1505 m_dZoom -= 0.01;
1506 updatePrintRepeatRowsHeight();
1507 updateNewPageListY( 0 );
1508 updateNewPageY( m_pSheet->bottomRow( m_pSheet->dblRowPos( printRange.bottom() ) + prinsheetHeightPts() ) );
1509 currentPages = pagesY( printRange );
1510 kdDebug() << "Looping -0.01; current zoom: " << m_dZoom << endl;
1511 }
1512
1513 if ( m_dZoom < origZoom )
1514 {
1515 double newZoom = m_dZoom;
1516 m_dZoom += 1.0; //set it to something different
1517 setZoom( newZoom, false );
1518 }
1519 else
1520 m_dZoom = origZoom;
1521}
1522
1523void SheetPrint::setPrintGrid( bool _printGrid )
1524{
1525 if ( m_bPrintGrid == _printGrid )
1526 return;
1527
1528 m_bPrintGrid = _printGrid;
1529 m_pDoc->setModified( true );
1530}
1531
1532void SheetPrint::setPrintObjects( bool _printObjects )
1533{
1534 if ( m_bPrintObjects == _printObjects )
1535 return;
1536
1537 m_bPrintObjects = _printObjects;
1538 m_pDoc->setModified( true );
1539}
1540
1541void SheetPrint::setPrintCharts( bool _printCharts )
1542{
1543 if ( m_bPrintCharts == _printCharts )
1544 return;
1545
1546 m_bPrintCharts = _printCharts;
1547 m_pDoc->setModified( true );
1548}
1549
1550void SheetPrint::setPrintGraphics( bool _printGraphics )
1551{
1552 if ( m_bPrintGraphics == _printGraphics )
1553 return;
1554
1555 m_bPrintGraphics = _printGraphics;
1556 m_pDoc->setModified( true );
1557}
1558
1559void SheetPrint::setPrintCommentIndicator( bool _printCommentIndicator )
1560{
1561 if ( m_bPrintCommentIndicator == _printCommentIndicator )
1562 return;
1563
1564 m_bPrintCommentIndicator = _printCommentIndicator;
1565 m_pDoc->setModified( true );
1566}
1567
1568void SheetPrint::setPrintFormulaIndicator( bool _printFormulaIndicator )
1569{
1570 if( m_bPrintFormulaIndicator == _printFormulaIndicator )
1571 return;
1572
1573 m_bPrintFormulaIndicator = _printFormulaIndicator;
1574 m_pDoc->setModified( true );
1575}
1576void SheetPrint::updatePrintRepeatColumnsWidth()
1577{
1578 m_dPrintRepeatColumnsWidth = 0.0;
1579 if( m_printRepeatColumns.first != 0 )
1580 {
1581 for( int i = m_printRepeatColumns.first; i <= m_printRepeatColumns.second; i++ )
1582 {
1583 m_dPrintRepeatColumnsWidth += m_pSheet->columnFormat( i )->dblWidth();
1584 }
1585 }
1586}
1587
1588void SheetPrint::updatePrintRepeatRowsHeight()
1589{
1590 m_dPrintRepeatRowsHeight = 0.0;
1591 if ( m_printRepeatRows.first != 0 )
1592 {
1593 for ( int i = m_printRepeatRows.first; i <= m_printRepeatRows.second; i++)
1594 {
1595 m_dPrintRepeatRowsHeight += m_pSheet->rowFormat( i )->dblHeight();
1596 }
1597 }
1598}
1599
1600
1601void SheetPrint::setPrintRepeatColumns( TQPair<int, int> _printRepeatColumns )
1602{
1603 //Bring arguments in order
1604 if ( _printRepeatColumns.first > _printRepeatColumns.second )
1605 {
1606 int tmp = _printRepeatColumns.first;
1607 _printRepeatColumns.first = _printRepeatColumns.second;
1608 _printRepeatColumns.second = tmp;
1609 }
1610
1611 //If old are equal to the new setting, nothing is to be done at all
1612 if ( m_printRepeatColumns == _printRepeatColumns )
1613 return;
1614
1615 int oldFirst = m_printRepeatColumns.first;
1616 m_printRepeatColumns = _printRepeatColumns;
1617
1618 //Recalcualte the space needed for the repeated columns
1619 updatePrintRepeatColumnsWidth();
1620
1621 //Refresh calculation of stored page breaks, the lower one of old and new
1622 updateNewPageListX( TQMIN( oldFirst, _printRepeatColumns.first ) );
1623
1624 //Refresh view, if page borders are shown
1625 if ( m_pSheet->isShowPageBorders() )
1626 emit sig_updateView( m_pSheet );
1627
1628 m_pDoc->setModified( true );
1629}
1630
1631void SheetPrint::setPrintRepeatRows( TQPair<int, int> _printRepeatRows )
1632{
1633 //Bring arguments in order
1634 if ( _printRepeatRows.first > _printRepeatRows.second )
1635 {
1636 int tmp = _printRepeatRows.first;
1637 _printRepeatRows.first = _printRepeatRows.second;
1638 _printRepeatRows.second = tmp;
1639 }
1640
1641 //If old are equal to the new setting, nothing is to be done at all
1642 if ( m_printRepeatRows == _printRepeatRows )
1643 return;
1644
1645 int oldFirst = m_printRepeatRows.first;
1646 m_printRepeatRows = _printRepeatRows;
1647
1648 //Recalcualte the space needed for the repeated rows
1649 updatePrintRepeatRowsHeight();
1650
1651 //Refresh calculation of stored page breaks, the lower one of old and new
1652 updateNewPageListY( TQMIN( oldFirst, _printRepeatRows.first ) );
1653
1654 //Refresh view, if page borders are shown
1655 if ( m_pSheet->isShowPageBorders() )
1656 emit sig_updateView( m_pSheet );
1657
1658 m_pDoc->setModified( true );
1659}
1660
1661void SheetPrint::insertColumn( int col, int nbCol )
1662{
1663 //update print range, when it has been defined
1664 if ( m_printRange != TQRect( TQPoint(1, 1), TQPoint(KS_colMax, KS_rowMax) ) )
1665 {
1666 int left = m_printRange.left();
1667 int right = m_printRange.right();
1668
1669 for( int i = 0; i <= nbCol; i++ )
1670 {
1671 if ( left >= col ) left++;
1672 if ( right >= col ) right++;
1673 }
1674 //Validity checks
1675 if ( left > KS_colMax ) left = KS_colMax;
1676 if ( right > KS_colMax ) right = KS_colMax;
1677 setPrintRange( TQRect( TQPoint( left, m_printRange.top() ),
1678 TQPoint( right, m_printRange.bottom() ) ) );
1679 }
1680}
1681
1682void SheetPrint::insertRow( int row, int nbRow )
1683{
1684 //update print range, when it has been defined
1685 if ( m_printRange != TQRect( TQPoint(1, 1), TQPoint(KS_colMax, KS_rowMax) ) )
1686 {
1687 int top = m_printRange.top();
1688 int bottom = m_printRange.bottom();
1689
1690 for( int i = 0; i <= nbRow; i++ )
1691 {
1692 if ( top >= row ) top++;
1693 if ( bottom >= row ) bottom++;
1694 }
1695 //Validity checks
1696 if ( top > KS_rowMax ) top = KS_rowMax;
1697 if ( bottom > KS_rowMax ) bottom = KS_rowMax;
1698 setPrintRange( TQRect( TQPoint( m_printRange.left(), top ),
1699 TQPoint( m_printRange.right(), bottom ) ) );
1700 }
1701}
1702
1703void SheetPrint::removeColumn( int col, int nbCol )
1704{
1705 //update print range, when it has been defined
1706 if ( m_printRange != TQRect( TQPoint(1, 1), TQPoint(KS_colMax, KS_rowMax) ) )
1707 {
1708 int left = m_printRange.left();
1709 int right = m_printRange.right();
1710
1711 for( int i = 0; i <= nbCol; i++ )
1712 {
1713 if ( left > col ) left--;
1714 if ( right >= col ) right--;
1715 }
1716 //Validity checks
1717 if ( left < 1 ) left = 1;
1718 if ( right < 1 ) right = 1;
1719 setPrintRange( TQRect( TQPoint( left, m_printRange.top() ),
1720 TQPoint( right, m_printRange.bottom() ) ) );
1721 }
1722
1723 //update repeat columns, when it has been defined
1724 if ( m_printRepeatColumns.first != 0 )
1725 {
1726 int left = m_printRepeatColumns.first;
1727 int right = m_printRepeatColumns.second;
1728
1729 for( int i = 0; i <= nbCol; i++ )
1730 {
1731 if ( left > col ) left--;
1732 if ( right >= col ) right--;
1733 }
1734 //Validity checks
1735 if ( left < 1 ) left = 1;
1736 if ( right < 1 ) right = 1;
1737 setPrintRepeatColumns ( qMakePair( left, right ) );
1738 }
1739}
1740
1741void SheetPrint::removeRow( int row, int nbRow )
1742{
1743 //update print range, when it has been defined
1744 if ( m_printRange != TQRect( TQPoint(1, 1), TQPoint(KS_colMax, KS_rowMax) ) )
1745 {
1746 int top = m_printRange.top();
1747 int bottom = m_printRange.bottom();
1748
1749 for( int i = 0; i <= nbRow; i++ )
1750 {
1751 if ( top > row ) top--;
1752 if ( bottom >= row ) bottom--;
1753 }
1754 //Validity checks
1755 if ( top < 1 ) top = 1;
1756 if ( bottom < 1 ) bottom = 1;
1757 setPrintRange( TQRect( TQPoint( m_printRange.left(), top ),
1758 TQPoint( m_printRange.right(), bottom ) ) );
1759 }
1760
1761 //update repeat rows, when it has been defined
1762 if ( m_printRepeatRows.first != 0 )
1763 {
1764 int top = m_printRepeatRows.first;
1765 int bottom = m_printRepeatRows.second;
1766
1767 for( int i = 0; i <= nbRow; i++ )
1768 {
1769 if ( top > row ) top--;
1770 if ( bottom >= row ) bottom--;
1771 }
1772 //Validity checks
1773 if ( top < 1 ) top = 1;
1774 if ( bottom < 1 ) bottom = 1;
1775 setPrintRepeatRows( qMakePair( top, bottom ) );
1776 }
1777}
1778
1779void SheetPrint::setZoom( double _zoom, bool checkPageLimit )
1780{
1781 if( m_dZoom == _zoom )
1782 {
1783 return;
1784 }
1785
1786 m_dZoom = _zoom;
1787 updatePrintRepeatColumnsWidth();
1788 updatePrintRepeatRowsHeight();
1789 updateNewPageListX( 0 );
1790 updateNewPageListY( 0 );
1791 if( m_pSheet->isShowPageBorders() )
1792 emit sig_updateView( m_pSheet );
1793
1794 if( checkPageLimit )
1795 {
1796 calculateZoomForPageLimitX();
1797 calculateZoomForPageLimitY();
1798 }
1799
1800 m_pDoc->setModified( true );
1801}
1802
1803bool PrintNewPageEntry::operator==( PrintNewPageEntry const & entry ) const
1804{
1805 return m_iStartItem == entry.m_iStartItem;
1806}
1807
const TQPen & effBottomBorderPen(int col, int row) const
int row() const
Returns the cell's row.
int column() const
Returns the cell's column.
void paintCell(const KoRect &rect, TQPainter &painter, View *view, const KoPoint &coordinate, const TQPoint &cellRef, int paintBorder, TQPen &rightPen, TQPen &bottomPen, TQPen &leftPen, TQPen &topPen, TQValueList< TQPoint > &mergedCellsPainted, bool drawCursor=true)
Paints the cell.
uint effRightBorderValue(int col, int row) const
const TQPen & effTopBorderPen(int col, int row) const
const TQPen & effRightBorderPen(int col, int row) const
bool needsPrinting() const
uint effLeftBorderValue(int col, int row) const
uint effTopBorderValue(int col, int row) const
const TQPen & effLeftBorderPen(int col, int row) const
uint effBottomBorderValue(int col, int row) const
The KSpread namespace.
Definition commands.h:39