KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1808 lines
59KB

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