Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "scitems.hxx"
21 : #include <editeng/eeitem.hxx>
22 :
23 : #include "printfun.hxx"
24 :
25 : #include <svx/svxids.hrc>
26 : #include <editeng/adjustitem.hxx>
27 : #include <editeng/boxitem.hxx>
28 : #include <editeng/brushitem.hxx>
29 : #include <svtools/colorcfg.hxx>
30 : #include <editeng/editstat.hxx>
31 : #include <svx/fmview.hxx>
32 : #include <editeng/frmdiritem.hxx>
33 : #include <editeng/lrspitem.hxx>
34 : #include <editeng/paperinf.hxx>
35 : #include <editeng/pbinitem.hxx>
36 : #include <editeng/shaditem.hxx>
37 : #include <editeng/sizeitem.hxx>
38 : #include <svx/svdpagv.hxx>
39 : #include <editeng/ulspitem.hxx>
40 : #include <sfx2/app.hxx>
41 : #include <sfx2/printer.hxx>
42 : #include <tools/multisel.hxx>
43 : #include <sfx2/docfile.hxx>
44 : #include <tools/urlobj.hxx>
45 : #include <svx/xoutbmp.hxx>
46 :
47 : #include "editutil.hxx"
48 : #include "docsh.hxx"
49 : #include "output.hxx"
50 : #include "viewdata.hxx"
51 : #include "viewopti.hxx"
52 : #include "stlpool.hxx"
53 : #include "pagepar.hxx"
54 : #include "attrib.hxx"
55 : #include "patattr.hxx"
56 : #include "docpool.hxx"
57 : #include "dociter.hxx"
58 : #include "formulacell.hxx"
59 : #include "drawutil.hxx"
60 : #include "globstr.hrc"
61 : #include "scresid.hxx"
62 : #include "sc.hrc"
63 : #include "pagedata.hxx"
64 : #include "printopt.hxx"
65 : #include "prevloc.hxx"
66 : #include "scmod.hxx"
67 : #include "drwlayer.hxx"
68 : #include "fillinfo.hxx"
69 : #include "postit.hxx"
70 :
71 : #include <vcl/lineinfo.hxx>
72 :
73 : #include <boost/scoped_ptr.hpp>
74 : #include <com/sun/star/document/XDocumentProperties.hpp>
75 :
76 : #define ZOOM_MIN 10
77 :
78 : #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue()
79 : #define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue()
80 : #define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) )
81 :
82 322 : ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r)
83 : {
84 322 : nStartRow = r.nStartRow;
85 322 : nEndRow = r.nEndRow;
86 322 : nPagesX = r.nPagesX;
87 322 : if (r.pHidden && nPagesX)
88 : {
89 0 : pHidden = new bool[nPagesX];
90 0 : memcpy( pHidden, r.pHidden, nPagesX * sizeof(bool) );
91 : }
92 : else
93 322 : pHidden = NULL;
94 322 : }
95 :
96 0 : const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r)
97 : {
98 0 : delete[] pHidden;
99 :
100 0 : nStartRow = r.nStartRow;
101 0 : nEndRow = r.nEndRow;
102 0 : nPagesX = r.nPagesX;
103 0 : if (r.pHidden && nPagesX)
104 : {
105 0 : pHidden = new bool[nPagesX];
106 0 : memcpy( pHidden, r.pHidden, nPagesX * sizeof(bool) );
107 : }
108 : else
109 0 : pHidden = NULL;
110 :
111 0 : return *this;
112 : }
113 :
114 79 : void ScPageRowEntry::SetPagesX(size_t nNew)
115 : {
116 79 : if (pHidden)
117 : {
118 : OSL_FAIL("SetPagesX nicht nach SetHidden");
119 0 : delete[] pHidden;
120 0 : pHidden = NULL;
121 : }
122 79 : nPagesX = nNew;
123 79 : }
124 :
125 0 : void ScPageRowEntry::SetHidden(size_t nX)
126 : {
127 0 : if ( nX < nPagesX )
128 : {
129 0 : if ( nX+1 == nPagesX ) // last page?
130 0 : --nPagesX;
131 : else
132 : {
133 0 : if (!pHidden)
134 : {
135 0 : pHidden = new bool[nPagesX];
136 0 : memset( pHidden, false, nPagesX * sizeof(bool) );
137 : }
138 0 : pHidden[nX] = true;
139 : }
140 : }
141 0 : }
142 :
143 54 : bool ScPageRowEntry::IsHidden(size_t nX) const
144 : {
145 54 : return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline?
146 : }
147 :
148 26 : size_t ScPageRowEntry::CountVisible() const
149 : {
150 26 : if ( pHidden )
151 : {
152 0 : size_t nVis = 0;
153 0 : for (size_t i=0; i<nPagesX; i++)
154 0 : if (!pHidden[i])
155 0 : ++nVis;
156 0 : return nVis;
157 : }
158 : else
159 26 : return nPagesX;
160 : }
161 :
162 5720 : static long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine)
163 : {
164 5720 : return pLine ? ( pLine->GetScaledWidth() ) : 0;
165 : }
166 :
167 296 : void ScPrintFunc::Construct( const ScPrintOptions* pOptions )
168 : {
169 296 : pDocShell->UpdatePendingRowHeights( nPrintTab );
170 296 : pDoc = pDocShell->GetDocument();
171 :
172 296 : SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use the printer, even for preview
173 296 : if (pDocPrinter)
174 296 : aOldPrinterMode = pDocPrinter->GetMapMode();
175 :
176 : // unified MapMode for all calls (e.g. Repaint!!!)
177 : // else, EditEngine outputs different text heights
178 296 : pDev->SetMapMode(MAP_PIXEL);
179 :
180 296 : pBorderItem = NULL;
181 296 : pBackgroundItem = NULL;
182 296 : pShadowItem = NULL;
183 :
184 296 : pEditEngine = NULL;
185 296 : pEditDefaults = NULL;
186 :
187 296 : ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
188 : SfxStyleSheetBase* pStyleSheet = pStylePool->Find(
189 : pDoc->GetPageStyle( nPrintTab ),
190 296 : SFX_STYLE_FAMILY_PAGE );
191 296 : if (pStyleSheet)
192 296 : pParamSet = &pStyleSheet->GetItemSet();
193 : else
194 : {
195 : OSL_FAIL("Seitenvorlage nicht gefunden" );
196 0 : pParamSet = NULL;
197 : }
198 :
199 296 : if (!bState)
200 252 : nZoom = 100;
201 296 : nManualZoom = 100;
202 296 : bClearWin = false;
203 296 : bUseStyleColor = false;
204 296 : bIsRender = false;
205 :
206 296 : InitParam(pOptions);
207 :
208 296 : pPageData = NULL; // wird nur zur Initialisierung gebraucht
209 296 : }
210 :
211 226 : ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab,
212 : long nPage, long nDocP, const ScRange* pArea,
213 : const ScPrintOptions* pOptions,
214 : ScPageBreakData* pData )
215 : : pDocShell ( pShell ),
216 : pPrinter ( pNewPrinter ),
217 : pDrawView ( NULL ),
218 : nPrintTab ( nTab ),
219 : nPageStart ( nPage ),
220 : nDocPages ( nDocP ),
221 : pUserArea ( pArea ),
222 : bState ( false ),
223 : bSourceRangeValid ( false ),
224 : bPrintCurrentTable ( false ),
225 : bMultiArea ( false ),
226 : mbHasPrintRange(true),
227 : nTabPages ( 0 ),
228 : nTotalPages ( 0 ),
229 : nPagesX(0),
230 : nPagesY(0),
231 : nTotalY(0),
232 226 : pPageData ( pData )
233 : {
234 226 : pDev = pPrinter;
235 226 : aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM );
236 226 : Construct( pOptions );
237 226 : }
238 :
239 26 : ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab,
240 : long nPage, long nDocP, const ScRange* pArea,
241 : const ScPrintOptions* pOptions )
242 : : pDocShell ( pShell ),
243 : pPrinter ( NULL ),
244 : pDrawView ( NULL ),
245 : nPrintTab ( nTab ),
246 : nPageStart ( nPage ),
247 : nDocPages ( nDocP ),
248 : pUserArea ( pArea ),
249 : bState ( false ),
250 : bSourceRangeValid ( false ),
251 : bPrintCurrentTable ( false ),
252 : bMultiArea ( false ),
253 : mbHasPrintRange(true),
254 : nTabPages ( 0 ),
255 : nTotalPages ( 0 ),
256 : nPagesX(0),
257 : nPagesY(0),
258 : nTotalY(0),
259 26 : pPageData ( NULL )
260 : {
261 26 : pDev = pOutDev;
262 26 : Construct( pOptions );
263 26 : }
264 :
265 44 : ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell,
266 : const ScPrintState& rState, const ScPrintOptions* pOptions )
267 : : pDocShell ( pShell ),
268 : pPrinter ( NULL ),
269 : pDrawView ( NULL ),
270 : pUserArea ( NULL ),
271 : bSourceRangeValid ( false ),
272 : bPrintCurrentTable ( false ),
273 : bMultiArea ( false ),
274 : mbHasPrintRange(true),
275 : nPagesX(0),
276 : nPagesY(0),
277 : nTotalY(0),
278 44 : pPageData ( NULL )
279 : {
280 44 : pDev = pOutDev;
281 :
282 44 : nPrintTab = rState.nPrintTab;
283 44 : nStartCol = rState.nStartCol;
284 44 : nStartRow = rState.nStartRow;
285 44 : nEndCol = rState.nEndCol;
286 44 : nEndRow = rState.nEndRow;
287 44 : nZoom = rState.nZoom;
288 44 : nPagesX = rState.nPagesX;
289 44 : nPagesY = rState.nPagesY;
290 44 : nTabPages = rState.nTabPages;
291 44 : nTotalPages = rState.nTotalPages;
292 44 : nPageStart = rState.nPageStart;
293 44 : nDocPages = rState.nDocPages;
294 44 : bState = true;
295 :
296 44 : Construct( pOptions );
297 44 : }
298 :
299 26 : void ScPrintFunc::GetPrintState( ScPrintState& rState )
300 : {
301 26 : rState.nPrintTab = nPrintTab;
302 26 : rState.nStartCol = nStartCol;
303 26 : rState.nStartRow = nStartRow;
304 26 : rState.nEndCol = nEndCol;
305 26 : rState.nEndRow = nEndRow;
306 26 : rState.nZoom = nZoom;
307 26 : rState.nPagesX = nPagesX;
308 26 : rState.nPagesY = nPagesY;
309 26 : rState.nTabPages = nTabPages;
310 26 : rState.nTotalPages = nTotalPages;
311 26 : rState.nPageStart = nPageStart;
312 26 : rState.nDocPages = nDocPages;
313 26 : }
314 :
315 16 : bool ScPrintFunc::HasPrintRange() const
316 : {
317 16 : return mbHasPrintRange;
318 : }
319 :
320 0 : bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const
321 : {
322 0 : rRange = aLastSourceRange;
323 0 : return bSourceRangeValid;
324 : }
325 :
326 1 : void ScPrintFunc::FillPageData()
327 : {
328 1 : if (pPageData)
329 : {
330 1 : sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() );
331 1 : ScPrintRangeData& rData = pPageData->GetData(nCount); // count up
332 :
333 : rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab,
334 1 : nEndCol, nEndRow, nPrintTab ) );
335 : // #i123672#
336 1 : if(maPageEndX.empty())
337 : {
338 : OSL_ENSURE(false, "vector access error for maPageEndX (!)");
339 : }
340 : else
341 : {
342 1 : rData.SetPagesX( nPagesX, &maPageEndX[0]);
343 : }
344 :
345 : // #i123672#
346 1 : if(maPageEndY.empty())
347 : {
348 : OSL_ENSURE(false, "vector access error for maPageEndY (!)");
349 : }
350 : else
351 : {
352 1 : rData.SetPagesY( nTotalY, &maPageEndY[0]);
353 : }
354 :
355 : // Settings
356 1 : rData.SetTopDown( aTableParam.bTopDown );
357 1 : rData.SetAutomatic( !aAreaParam.bPrintArea );
358 : }
359 1 : }
360 :
361 592 : ScPrintFunc::~ScPrintFunc()
362 : {
363 296 : delete pEditDefaults;
364 296 : delete pEditEngine;
365 :
366 : // Printer settings are now restored from outside
367 :
368 : // For DrawingLayer/Charts, the MapMode of the printer (RefDevice) must always be correct
369 296 : SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // use Preview also for the printer
370 296 : if (pDocPrinter)
371 296 : pDocPrinter->SetMapMode(aOldPrinterMode);
372 296 : }
373 :
374 54 : void ScPrintFunc::SetDrawView( FmFormView* pNew )
375 : {
376 54 : pDrawView = pNew;
377 54 : }
378 :
379 38 : static void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 )
380 : {
381 207 : for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++)
382 : {
383 169 : RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY];
384 751 : for (SCCOL nX=nX1; nX<=nX2; nX++)
385 : {
386 582 : const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1];
387 582 : if (!rCellInfo.bEmptyCellText)
388 67 : if (((const ScProtectionAttr&)rCellInfo.pPatternAttr->
389 67 : GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint())
390 : {
391 0 : pThisRowInfo->pCellInfo[nX+1].maCell.clear();
392 0 : pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = true;
393 : }
394 : }
395 : }
396 38 : }
397 :
398 :
399 : // output to Device (static)
400 : //
401 : // us used for:
402 : // - Clipboard/Bitmap
403 : // - Ole-Object (DocShell::Draw)
404 : // - Preview of templates
405 :
406 5 : void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */,
407 : const Rectangle& rBound, ScViewData* pViewData, bool bMetaFile )
408 : {
409 : //! evaluate nPrintFactor !!!
410 :
411 5 : SCTAB nTab = 0;
412 5 : if (pViewData)
413 5 : nTab = pViewData->GetTabNo();
414 :
415 : bool bDoGrid, bNullVal, bFormula;
416 5 : ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
417 5 : SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
418 5 : if (pStyleSheet)
419 : {
420 5 : SfxItemSet& rSet = pStyleSheet->GetItemSet();
421 5 : bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue();
422 5 : bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue();
423 5 : bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue();
424 : }
425 : else
426 : {
427 0 : const ScViewOptions& rOpt = pDoc->GetViewOptions();
428 0 : bDoGrid = rOpt.GetOption(VOPT_GRID);
429 0 : bNullVal = rOpt.GetOption(VOPT_NULLVALS);
430 0 : bFormula = rOpt.GetOption(VOPT_FORMULAS);
431 : }
432 :
433 5 : MapMode aMode = pDev->GetMapMode();
434 :
435 5 : Rectangle aRect = rBound;
436 :
437 5 : if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top())
438 0 : aRect = Rectangle( Point(), pDev->GetOutputSize() );
439 :
440 5 : SCCOL nX1 = 0;
441 5 : SCROW nY1 = 0;
442 5 : SCCOL nX2 = OLE_STD_CELLS_X - 1;
443 5 : SCROW nY2 = OLE_STD_CELLS_Y - 1;
444 5 : if (bMetaFile)
445 : {
446 5 : ScRange aRange = pDoc->GetRange( nTab, rBound );
447 5 : nX1 = aRange.aStart.Col();
448 5 : nY1 = aRange.aStart.Row();
449 5 : nX2 = aRange.aEnd.Col();
450 5 : nY2 = aRange.aEnd.Row();
451 : }
452 0 : else if (pViewData)
453 : {
454 0 : ScSplitPos eWhich = pViewData->GetActivePart();
455 0 : ScHSplitPos eHWhich = WhichH(eWhich);
456 0 : ScVSplitPos eVWhich = WhichV(eWhich);
457 0 : nX1 = pViewData->GetPosX(eHWhich);
458 0 : nY1 = pViewData->GetPosY(eVWhich);
459 0 : nX2 = nX1 + pViewData->VisibleCellsX(eHWhich);
460 0 : if (nX2>nX1) --nX2;
461 0 : nY2 = nY1 + pViewData->VisibleCellsY(eVWhich);
462 0 : if (nY2>nY1) --nY2;
463 : }
464 :
465 5 : if (nX1 > MAXCOL) nX1 = MAXCOL;
466 5 : if (nX2 > MAXCOL) nX2 = MAXCOL;
467 5 : if (nY1 > MAXROW) nY1 = MAXROW;
468 5 : if (nY2 > MAXROW) nY2 = MAXROW;
469 :
470 5 : long nDevSizeX = aRect.Right()-aRect.Left()+1;
471 5 : long nDevSizeY = aRect.Bottom()-aRect.Top()+1;
472 :
473 5 : Rectangle aLines;
474 5 : ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab );
475 :
476 5 : long nTwipsSizeX = 0;
477 25 : for (SCCOL i=nX1; i<=nX2; i++)
478 20 : nTwipsSizeX += pDoc->GetColWidth( i, nTab );
479 5 : long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab );
480 :
481 : // if no lines, still space for the outline frame (20 Twips = 1pt)
482 : // (HasLines initalizes aLines to 0,0,0,0)
483 5 : nTwipsSizeX += aLines.Left() + std::max( aLines.Right(), 20L );
484 5 : nTwipsSizeY += aLines.Top() + std::max( aLines.Bottom(), 20L );
485 :
486 5 : double nScaleX = (double) nDevSizeX / nTwipsSizeX;
487 5 : double nScaleY = (double) nDevSizeY / nTwipsSizeY;
488 :
489 : //! hand over Flag at FillInfo !!!!!
490 5 : ScRange aERange;
491 5 : bool bEmbed = pDoc->IsEmbedded();
492 5 : if (bEmbed)
493 : {
494 0 : pDoc->GetEmbedded(aERange);
495 0 : pDoc->ResetEmbedded();
496 : }
497 :
498 : // Assemble data
499 :
500 10 : ScTableInfo aTabInfo;
501 : pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab,
502 5 : nScaleX, nScaleY, false, bFormula );
503 5 : lcl_HidePrint( aTabInfo, nX1, nX2 );
504 :
505 5 : if (bEmbed)
506 0 : pDoc->SetEmbedded(aERange);
507 :
508 5 : long nScrX = aRect.Left();
509 5 : long nScrY = aRect.Top();
510 :
511 : // If no lines, still leave space for grid lines
512 : // (would be elseways cut away)
513 5 : long nAddX = (long)( aLines.Left() * nScaleX );
514 5 : nScrX += ( nAddX ? nAddX : 1 );
515 5 : long nAddY = (long)( aLines.Top() * nScaleY );
516 5 : nScrY += ( nAddY ? nAddY : 1 );
517 :
518 : ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab,
519 10 : nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
520 5 : aOutputData.SetMetaFileMode(bMetaFile);
521 5 : aOutputData.SetShowNullValues(bNullVal);
522 5 : aOutputData.SetShowFormulas(bFormula);
523 :
524 : // #114135#
525 5 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
526 5 : FmFormView* pDrawView = NULL;
527 :
528 5 : if( pModel )
529 : {
530 5 : pDrawView = new FmFormView( pModel, pDev );
531 5 : pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
532 5 : pDrawView->SetPrintPreview( true );
533 5 : aOutputData.SetDrawView( pDrawView );
534 : }
535 :
536 : //! SetUseStyleColor ??
537 :
538 5 : if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV )
539 5 : aOutputData.SetSnapPixel();
540 :
541 5 : Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM );
542 5 : long nLogStX = aLogStart.X();
543 5 : long nLogStY = aLogStart.Y();
544 :
545 : //! nZoom for GetFont in OutputData ???
546 :
547 5 : if (!bMetaFile && pViewData)
548 0 : pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
549 :
550 : // #i72502#
551 5 : const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
552 5 : aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
553 :
554 5 : if (!bMetaFile && pViewData)
555 0 : pDev->SetMapMode(aMode);
556 :
557 5 : aOutputData.DrawBackground();
558 5 : aOutputData.DrawShadow();
559 5 : aOutputData.DrawFrame();
560 5 : aOutputData.DrawStrings();
561 :
562 5 : if (!bMetaFile && pViewData)
563 0 : pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart()));
564 :
565 5 : aOutputData.DrawEdit(!bMetaFile);
566 :
567 5 : if (bDoGrid)
568 : {
569 0 : if (!bMetaFile && pViewData)
570 0 : pDev->SetMapMode(aMode);
571 :
572 0 : aOutputData.DrawGrid( true, false ); // no page breaks
573 :
574 0 : pDev->SetLineColor( COL_BLACK );
575 :
576 0 : Size aOne = pDev->PixelToLogic( Size(1,1) );
577 0 : if (bMetaFile)
578 0 : aOne = Size(1,1); // compatible with DrawGrid
579 0 : long nRight = nScrX + aOutputData.GetScrW() - aOne.Width();
580 0 : long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height();
581 :
582 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
583 :
584 : // extra line at the left edge for left-to-right, right for right-to-left
585 0 : if ( bLayoutRTL )
586 0 : pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) );
587 : else
588 0 : pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) );
589 : // extra line at the top in both cases
590 0 : pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) );
591 : }
592 :
593 : // #i72502#
594 5 : aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
595 5 : aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
596 5 : aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
597 :
598 : // #114135#
599 10 : delete pDrawView;
600 5 : }
601 :
602 :
603 : // Printing
604 :
605 :
606 592 : static void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet )
607 : {
608 : // nDistance must be initialized differently before
609 :
610 592 : if ( pHFSet == NULL )
611 : {
612 0 : rParam.bEnable = false;
613 0 : rParam.pBorder = NULL;
614 0 : rParam.pBack = NULL;
615 0 : rParam.pShadow = NULL;
616 : }
617 : else
618 : {
619 592 : rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue();
620 592 : rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue();
621 592 : rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue();
622 592 : rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height();
623 592 : const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE);
624 : long nTmp;
625 592 : nTmp = pHFLR->GetLeft();
626 592 : rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp);
627 592 : nTmp = pHFLR->GetRight();
628 592 : rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp);
629 592 : rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER);
630 592 : rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND);
631 592 : rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);
632 :
633 : // now back in the dialog:
634 : // rParam.nHeight += rParam.nDistance; // not in the dialog any more ???
635 :
636 592 : if (rParam.pBorder)
637 592 : rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
638 592 : lcl_LineTotal( rParam.pBorder->GetBottom() );
639 :
640 592 : rParam.nManHeight = rParam.nHeight;
641 : }
642 :
643 592 : if (!rParam.bEnable)
644 4 : rParam.nHeight = 0;
645 592 : }
646 :
647 : // bNew = TRUE: search for used part of the document
648 : // bNew = FALSE: only limit whole lines/columns
649 :
650 294 : bool ScPrintFunc::AdjustPrintArea( bool bNew )
651 : {
652 294 : SCCOL nOldEndCol = nEndCol; // only important for !bNew
653 294 : SCROW nOldEndRow = nEndRow;
654 294 : bool bChangeCol = true; // at bNew both are being adjusted
655 294 : bool bChangeRow = true;
656 :
657 294 : bool bNotes = aTableParam.bNotes;
658 294 : if ( bNew )
659 : {
660 260 : nStartCol = 0;
661 260 : nStartRow = 0;
662 260 : if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ))
663 230 : return false; // nix
664 : }
665 : else
666 : {
667 34 : bool bFound = true;
668 34 : bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL );
669 34 : bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW );
670 34 : bool bForcedChangeRow = false;
671 :
672 : // #i53558# Crop entire column of old row limit to real print area with
673 : // some fuzzyness.
674 34 : if (!bChangeRow && nStartRow == 0)
675 : {
676 : SCROW nPAEndRow;
677 34 : bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes );
678 : // Say we don't want to print more than ~1000 empty rows, which are
679 : // about 14 pages intentionally left blank..
680 34 : const SCROW nFuzzy = 23*42;
681 34 : if (nPAEndRow + nFuzzy < nEndRow)
682 : {
683 0 : bForcedChangeRow = true;
684 0 : nEndRow = nPAEndRow;
685 : }
686 : else
687 34 : bFound = true; // user seems to _want_ to print some empty rows
688 : }
689 : // TODO: in case we extend the number of columns we may have to do the
690 : // same for horizontal cropping.
691 :
692 34 : if ( bChangeCol && bChangeRow )
693 0 : bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes );
694 34 : else if ( bChangeCol )
695 0 : bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes );
696 34 : else if ( bChangeRow )
697 0 : bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes );
698 :
699 34 : if (!bFound)
700 0 : return false; // empty
701 :
702 34 : if (bForcedChangeRow)
703 0 : bChangeRow = true;
704 : }
705 :
706 : pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab,
707 64 : false ); // no Refresh, incl. Attrs
708 :
709 64 : if ( bChangeCol )
710 : {
711 30 : OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
712 30 : pRefDev->SetMapMode( MAP_PIXEL ); // important for GetNeededSize
713 :
714 : pDoc->ExtendPrintArea( pRefDev,
715 30 : nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow );
716 : // changing nEndCol
717 : }
718 :
719 128 : if ( nEndCol < MAXCOL && pDoc->HasAttrib(
720 64 : nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) )
721 0 : ++nEndCol;
722 128 : if ( nEndRow < MAXROW && pDoc->HasAttrib(
723 64 : nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) )
724 0 : ++nEndRow;
725 :
726 64 : if (!bChangeCol) nEndCol = nOldEndCol;
727 64 : if (!bChangeRow) nEndRow = nOldEndRow;
728 :
729 64 : return true;
730 : }
731 :
732 3984 : long ScPrintFunc::TextHeight( const EditTextObject* pObject )
733 : {
734 3984 : if (!pObject)
735 522 : return 0;
736 :
737 3462 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
738 :
739 3462 : return (long) pEditEngine->GetTextHeight();
740 : }
741 :
742 : // nZoom must be set !!!
743 : // and the respective Twip-MapMode configured
744 :
745 616 : void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam )
746 : {
747 : OSL_ENSURE( aPageSize.Width(), "UpdateHFHeight ohne aPageSize");
748 :
749 616 : if (rParam.bEnable && rParam.bDynamic)
750 : {
751 : // calculate nHeight from content
752 :
753 610 : MakeEditEngine();
754 610 : long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin -
755 610 : rParam.nLeft - rParam.nRight ) * 100 / nZoom;
756 610 : if (rParam.pBorder)
757 1220 : nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) +
758 1220 : rParam.pBorder->GetDistance(BOX_LINE_RIGHT) +
759 1220 : lcl_LineTotal(rParam.pBorder->GetLeft()) +
760 1220 : lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom;
761 :
762 610 : if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
763 0 : nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) +
764 0 : rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom;
765 :
766 610 : pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) );
767 :
768 610 : long nMaxHeight = 0;
769 610 : if ( rParam.pLeft )
770 : {
771 610 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) );
772 610 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) );
773 610 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) );
774 : }
775 610 : if ( rParam.pRight )
776 : {
777 610 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) );
778 610 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) );
779 610 : nMaxHeight = std::max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) );
780 : }
781 :
782 610 : rParam.nHeight = nMaxHeight + rParam.nDistance;
783 610 : if (rParam.pBorder)
784 1220 : rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) +
785 1220 : rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) +
786 610 : lcl_LineTotal( rParam.pBorder->GetTop() ) +
787 610 : lcl_LineTotal( rParam.pBorder->GetBottom() );
788 610 : if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
789 0 : rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
790 0 : rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
791 :
792 610 : if (rParam.nHeight < rParam.nManHeight)
793 610 : rParam.nHeight = rParam.nManHeight; // configured minimum
794 : }
795 616 : }
796 :
797 296 : void ScPrintFunc::InitParam( const ScPrintOptions* pOptions )
798 : {
799 296 : if (!pParamSet)
800 296 : return;
801 :
802 : // TabPage "Page"
803 296 : const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE );
804 : long nTmp;
805 296 : nTmp = pLRItem->GetLeft();
806 296 : nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
807 296 : nTmp = pLRItem->GetRight();
808 296 : nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp);
809 296 : const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE );
810 296 : nTopMargin = pULItem->GetUpper();
811 296 : nBottomMargin = pULItem->GetLower();
812 :
813 296 : const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE );
814 296 : nPageUsage = pPageItem->GetPageUsage();
815 296 : bLandscape = pPageItem->IsLandscape();
816 296 : aFieldData.eNumType = pPageItem->GetNumType();
817 :
818 296 : bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue();
819 296 : bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue();
820 :
821 296 : aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
822 296 : if ( !aPageSize.Width() || !aPageSize.Height() )
823 : {
824 : OSL_FAIL("PageSize Null ?!?!?");
825 0 : aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );
826 : }
827 :
828 296 : pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER);
829 296 : pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND);
830 296 : pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW);
831 :
832 : // TabPage "Headline"
833 :
834 296 : aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Content
835 296 : aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT);
836 :
837 : const SvxSetItem* pHeaderSetItem;
838 296 : const SfxItemSet* pHeaderSet = NULL;
839 296 : if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false,
840 296 : (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET )
841 : {
842 296 : pHeaderSet = &pHeaderSetItem->GetItemSet();
843 : // Headline has space below
844 296 : aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower();
845 : }
846 296 : lcl_FillHFParam( aHdr, pHeaderSet );
847 :
848 : // TabPage "Footline"
849 :
850 296 : aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Content
851 296 : aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT);
852 :
853 : const SvxSetItem* pFooterSetItem;
854 296 : const SfxItemSet* pFooterSet = NULL;
855 296 : if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false,
856 296 : (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET )
857 : {
858 296 : pFooterSet = &pFooterSetItem->GetItemSet();
859 : // Footline has space above
860 296 : aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper();
861 : }
862 296 : lcl_FillHFParam( aFtr, pFooterSet );
863 :
864 :
865 : // Compile Table-/Area-Params from single Items
866 :
867 : // TabPage "Table"
868 :
869 296 : const SfxUInt16Item* pScaleItem = NULL;
870 296 : const ScPageScaleToItem* pScaleToItem = NULL;
871 296 : const SfxUInt16Item* pScaleToPagesItem = NULL;
872 : SfxItemState eState;
873 :
874 : eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false,
875 296 : (const SfxPoolItem**)&pScaleItem );
876 296 : if ( SFX_ITEM_DEFAULT == eState )
877 : pScaleItem = (const SfxUInt16Item*)
878 294 : &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE );
879 :
880 : eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false,
881 296 : (const SfxPoolItem**)&pScaleToItem );
882 296 : if ( SFX_ITEM_DEFAULT == eState )
883 : pScaleToItem = (const ScPageScaleToItem*)
884 296 : &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO );
885 :
886 : eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false,
887 296 : (const SfxPoolItem**)&pScaleToPagesItem );
888 296 : if ( SFX_ITEM_DEFAULT == eState )
889 : pScaleToPagesItem = (const SfxUInt16Item*)
890 296 : &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES );
891 :
892 : OSL_ENSURE( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" );
893 :
894 296 : aTableParam.bCellContent = true;
895 296 : aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES);
896 296 : aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID);
897 296 : aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS);
898 296 : aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS);
899 296 : aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS);
900 296 : aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS);
901 296 : aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS);
902 296 : aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS);
903 296 : aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN);
904 296 : aTableParam.bLeftRight = !aTableParam.bLeftRight;
905 296 : aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO);
906 296 : if (!aTableParam.nFirstPageNo)
907 14 : aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // from previous table
908 :
909 296 : if ( pScaleItem && pScaleToItem && pScaleToPagesItem )
910 : {
911 296 : sal_uInt16 nScaleAll = pScaleItem->GetValue();
912 296 : sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue();
913 :
914 296 : aTableParam.bScaleNone = (nScaleAll == 100);
915 296 : aTableParam.bScaleAll = (nScaleAll > 0 );
916 296 : aTableParam.bScaleTo = pScaleToItem->IsValid();
917 296 : aTableParam.bScalePageNum = (nScaleToPages > 0 );
918 296 : aTableParam.nScaleAll = nScaleAll;
919 296 : aTableParam.nScaleWidth = pScaleToItem->GetWidth();
920 296 : aTableParam.nScaleHeight = pScaleToItem->GetHeight();
921 296 : aTableParam.nScalePageNum = nScaleToPages;
922 : }
923 : else
924 : {
925 0 : aTableParam.bScaleNone = true;
926 0 : aTableParam.bScaleAll = false;
927 0 : aTableParam.bScaleTo = false;
928 0 : aTableParam.bScalePageNum = false;
929 0 : aTableParam.nScaleAll = 0;
930 0 : aTableParam.nScaleWidth = 0;
931 0 : aTableParam.nScaleHeight = 0;
932 0 : aTableParam.nScalePageNum = 0;
933 : }
934 :
935 : // skip empty pages only if options with that flag are passed
936 296 : aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty();
937 296 : if ( pPageData )
938 1 : aTableParam.bSkipEmpty = false;
939 : // If pPageData is set, only the breaks are interesting for the
940 : // pagebreak preview, empty pages are not addressed separately.
941 :
942 296 : aTableParam.bForceBreaks = pOptions && pOptions->GetForceBreaks();
943 :
944 :
945 : // TabPage "Parts":
946 :
947 :
948 : //! walk throuch all PrintAreas of the table !!!
949 296 : const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 );
950 296 : const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab );
951 296 : const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab );
952 :
953 : // ignoring ATTR_PAGE_PRINTTABLES
954 :
955 296 : bool bHasPrintRange = pDoc->HasPrintRange();
956 296 : sal_uInt16 nPrintRangeCount = pDoc->GetPrintRangeCount(nPrintTab);
957 296 : bool bPrintEntireSheet = pDoc->IsPrintEntireSheet(nPrintTab);
958 :
959 296 : if (!bPrintEntireSheet && !nPrintRangeCount)
960 0 : mbHasPrintRange = false;
961 :
962 296 : if ( pUserArea ) // UserArea (selection) has prority
963 : {
964 : bPrintCurrentTable =
965 0 : aAreaParam.bPrintArea = true; // Selection
966 0 : aAreaParam.aPrintArea = *pUserArea;
967 :
968 : // The table-query is already in DocShell::Print, here always
969 0 : aAreaParam.aPrintArea.aStart.SetTab(nPrintTab);
970 0 : aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab);
971 : }
972 296 : else if (bHasPrintRange)
973 : {
974 296 : if ( pPrintArea ) // at least one set?
975 : {
976 : bPrintCurrentTable =
977 2 : aAreaParam.bPrintArea = true;
978 2 : aAreaParam.aPrintArea = *pPrintArea;
979 :
980 2 : bMultiArea = nPrintRangeCount > 1;
981 : }
982 : else
983 : {
984 : // do not print hidden sheets with "Print entire sheet" flag
985 294 : bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab );
986 294 : aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted
987 : }
988 : }
989 : else
990 : {
991 : // don't print hidden tables if there's no print range defined there
992 0 : if ( pDoc->IsVisible( nPrintTab ) )
993 : {
994 0 : aAreaParam.bPrintArea = false;
995 0 : bPrintCurrentTable = true;
996 : }
997 : else
998 : {
999 0 : aAreaParam.bPrintArea = true; // otherwise the table is always counted
1000 0 : bPrintCurrentTable = false;
1001 : }
1002 : }
1003 :
1004 296 : if ( pRepeatCol )
1005 : {
1006 2 : aAreaParam.bRepeatCol = true;
1007 2 : aAreaParam.aRepeatCol = *pRepeatCol;
1008 2 : nRepeatStartCol = pRepeatCol->aStart.Col();
1009 2 : nRepeatEndCol = pRepeatCol->aEnd .Col();
1010 : }
1011 : else
1012 : {
1013 294 : aAreaParam.bRepeatCol = false;
1014 294 : nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE;
1015 : }
1016 :
1017 296 : if ( pRepeatRow )
1018 : {
1019 5 : aAreaParam.bRepeatRow = true;
1020 5 : aAreaParam.aRepeatRow = *pRepeatRow;
1021 5 : nRepeatStartRow = pRepeatRow->aStart.Row();
1022 5 : nRepeatEndRow = pRepeatRow->aEnd .Row();
1023 : }
1024 : else
1025 : {
1026 291 : aAreaParam.bRepeatRow = false;
1027 291 : nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE;
1028 : }
1029 :
1030 :
1031 : // Split pages
1032 :
1033 :
1034 296 : if (!bState)
1035 : {
1036 252 : nTabPages = CountPages(); // also calculates zoom
1037 252 : nTotalPages = nTabPages;
1038 252 : nTotalPages += CountNotePages();
1039 : }
1040 : else
1041 : {
1042 44 : CalcPages(); // search breaks only
1043 44 : CountNotePages(); // Count notes, even if number of pages is already known
1044 : }
1045 :
1046 296 : if (nDocPages)
1047 54 : aFieldData.nTotalPages = nDocPages;
1048 : else
1049 242 : aFieldData.nTotalPages = nTotalPages;
1050 :
1051 296 : SetDateTime( Date( Date::SYSTEM ), Time( Time::SYSTEM ) );
1052 :
1053 296 : if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
1054 2 : aFieldData.aTitle = pDocShell->getDocProperties()->getTitle();
1055 : else
1056 294 : aFieldData.aTitle = pDocShell->GetTitle();
1057 :
1058 296 : const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
1059 296 : aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
1060 296 : if ( !aFieldData.aLongDocName.isEmpty() )
1061 222 : aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
1062 : else
1063 74 : aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle;
1064 :
1065 : // Printer settings (Orientation, Paper) at DoPrint
1066 : }
1067 :
1068 0 : Size ScPrintFunc::GetDataSize() const
1069 : {
1070 0 : Size aSize = aPageSize;
1071 0 : aSize.Width() -= nLeftMargin + nRightMargin;
1072 0 : aSize.Height() -= nTopMargin + nBottomMargin;
1073 0 : aSize.Height() -= aHdr.nHeight + aFtr.nHeight;
1074 0 : return aSize;
1075 : }
1076 :
1077 0 : void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr )
1078 : {
1079 0 : rPhysSize = aPageSize;
1080 0 : rPhysSize.Width() -= nLeftMargin + nRightMargin;
1081 0 : rPhysSize.Height() -= nTopMargin + nBottomMargin;
1082 :
1083 0 : rDocHdr = aHdr.nHeight;
1084 0 : rDocFtr = aFtr.nHeight;
1085 0 : }
1086 :
1087 350 : void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime )
1088 : {
1089 350 : aFieldData.aDate = rDate;
1090 350 : aFieldData.aTime = rTime;
1091 350 : }
1092 :
1093 0 : static void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut,
1094 : const Rectangle &rGrf, const Rectangle &rOut )
1095 : {
1096 0 : const bool bNotInside = !rOut.IsInside( rGrf );
1097 0 : if ( bNotInside )
1098 : {
1099 0 : pOut->Push();
1100 0 : pOut->IntersectClipRegion( rOut );
1101 : }
1102 :
1103 0 : ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() );
1104 :
1105 0 : if ( bNotInside )
1106 0 : pOut->Pop();
1107 0 : }
1108 :
1109 0 : static void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev,
1110 : const Rectangle &rOrg, const Rectangle &rOut,
1111 : OUString const & referer )
1112 : {
1113 0 : Size aGrfSize(0,0);
1114 0 : const Graphic *pGraphic = rBrush.GetGraphic(referer);
1115 : SvxGraphicPosition ePos;
1116 0 : if ( pGraphic && pGraphic->IsSupportedGraphic() )
1117 : {
1118 0 : const MapMode aMapMM( MAP_100TH_MM );
1119 0 : if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1120 0 : aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM );
1121 : else
1122 : aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1123 0 : pGraphic->GetPrefMapMode(), aMapMM );
1124 0 : ePos = rBrush.GetGraphicPos();
1125 : }
1126 : else
1127 0 : ePos = GPOS_NONE;
1128 :
1129 0 : Point aPos;
1130 0 : Size aDrawSize = aGrfSize;
1131 :
1132 0 : bool bDraw = true;
1133 0 : switch ( ePos )
1134 : {
1135 0 : case GPOS_LT: aPos = rOrg.TopLeft();
1136 0 : break;
1137 0 : case GPOS_MT: aPos.Y() = rOrg.Top();
1138 0 : aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1139 0 : break;
1140 0 : case GPOS_RT: aPos.Y() = rOrg.Top();
1141 0 : aPos.X() = rOrg.Right() - aGrfSize.Width();
1142 0 : break;
1143 :
1144 0 : case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1145 0 : aPos.X() = rOrg.Left();
1146 0 : break;
1147 0 : case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1148 0 : aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1149 0 : break;
1150 0 : case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2;
1151 0 : aPos.X() = rOrg.Right() - aGrfSize.Width();
1152 0 : break;
1153 :
1154 0 : case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1155 0 : aPos.X() = rOrg.Left();
1156 0 : break;
1157 0 : case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1158 0 : aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2;
1159 0 : break;
1160 0 : case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height();
1161 0 : aPos.X() = rOrg.Right() - aGrfSize.Width();
1162 0 : break;
1163 :
1164 : case GPOS_AREA:
1165 0 : aPos = rOrg.TopLeft();
1166 0 : aDrawSize = rOrg.GetSize();
1167 0 : break;
1168 : case GPOS_TILED:
1169 : {
1170 : // use GraphicObject::DrawTiled instead of an own loop
1171 : // (pixel rounding is handled correctly, and a very small bitmap
1172 : // is duplicated into a bigger one for better performance)
1173 :
1174 0 : GraphicObject aObject( *pGraphic );
1175 :
1176 0 : if( pOut->GetPDFWriter() &&
1177 0 : (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) )
1178 : {
1179 : // For PDF export, every draw
1180 : // operation for bitmaps takes a noticeable
1181 : // amount of place (~50 characters). Thus,
1182 : // optimize between tile bitmap size and
1183 : // number of drawing operations here.
1184 : //
1185 : // A_out
1186 : // n_chars = k1 * ---------- + k2 * A_bitmap
1187 : // A_bitmap
1188 : //
1189 : // minimum n_chars is obtained for (derive for
1190 : // A_bitmap, set to 0, take positive
1191 : // solution):
1192 : // k1
1193 : // A_bitmap = Sqrt( ---- A_out )
1194 : // k2
1195 : //
1196 : // where k1 is the number of chars per draw
1197 : // operation, and k2 is the number of chars
1198 : // per bitmap pixel. This is approximately 50
1199 : // and 7 for current PDF writer, respectively.
1200 :
1201 0 : const double k1( 50 );
1202 0 : const double k2( 7 );
1203 0 : const Size aSize( rOrg.GetSize() );
1204 0 : const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() );
1205 :
1206 : aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0),
1207 : NULL, GRFMGR_DRAW_STANDARD,
1208 0 : ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) );
1209 : }
1210 : else
1211 : {
1212 0 : aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) );
1213 : }
1214 :
1215 0 : bDraw = false;
1216 : }
1217 0 : break;
1218 :
1219 : case GPOS_NONE:
1220 0 : bDraw = false;
1221 0 : break;
1222 :
1223 : default: OSL_ENSURE( !pOut, "new Graphic position?" );
1224 : }
1225 0 : Rectangle aGrf( aPos,aDrawSize );
1226 0 : if ( bDraw && aGrf.IsOver( rOut ) )
1227 : {
1228 0 : lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut );
1229 : }
1230 0 : }
1231 :
1232 : // Rahmen wird nach innen gezeichnet
1233 :
1234 99 : void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH,
1235 : const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground,
1236 : const SvxShadowItem* pShadow )
1237 : {
1238 : //! direkte Ausgabe aus SvxBoxItem !!!
1239 :
1240 99 : if (pBorderData)
1241 198 : if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() &&
1242 99 : !pBorderData->GetRight() )
1243 99 : pBorderData = NULL;
1244 :
1245 99 : if (!pBorderData && !pBackground && !pShadow)
1246 0 : return; // nichts zu tun
1247 :
1248 99 : long nLeft = 0;
1249 99 : long nRight = 0;
1250 99 : long nTop = 0;
1251 99 : long nBottom = 0;
1252 :
1253 : // aFrameRect - ouside around frame, without shadow
1254 99 : if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1255 : {
1256 0 : nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
1257 0 : nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
1258 0 : nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY );
1259 0 : nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
1260 : }
1261 : Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop),
1262 99 : Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) );
1263 :
1264 : // center of frame, to paint lines through OutputData
1265 99 : if (pBorderData)
1266 : {
1267 0 : nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 );
1268 0 : nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 );
1269 0 : nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 );
1270 0 : nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 );
1271 : }
1272 99 : long nEffHeight = nScrH - nTop - nBottom;
1273 99 : long nEffWidth = nScrW - nLeft - nRight;
1274 99 : if (nEffHeight<=0 || nEffWidth<=0)
1275 0 : return; // enmpty
1276 :
1277 99 : if ( pBackground )
1278 : {
1279 99 : if (pBackground->GetGraphicPos() != GPOS_NONE)
1280 : {
1281 : OutputDevice* pRefDev;
1282 0 : if ( bIsRender )
1283 0 : pRefDev = pDev; // don't use printer for PDF
1284 : else
1285 0 : pRefDev = pDoc->GetPrinter(); // use printer also for preview
1286 0 : OUString referer;
1287 0 : if (pDocShell->HasName()) {
1288 0 : referer = pDocShell->GetMedium()->GetName();
1289 : }
1290 0 : lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect, referer );
1291 : }
1292 : else
1293 : {
1294 99 : pDev->SetFillColor(pBackground->GetColor());
1295 99 : pDev->SetLineColor();
1296 99 : pDev->DrawRect(aFrameRect);
1297 : }
1298 : }
1299 :
1300 99 : if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE )
1301 : {
1302 0 : pDev->SetFillColor(pShadow->GetColor());
1303 0 : pDev->SetLineColor();
1304 0 : long nShadowX = (long) ( pShadow->GetWidth() * nScaleX );
1305 0 : long nShadowY = (long) ( pShadow->GetWidth() * nScaleY );
1306 0 : switch (pShadow->GetLocation())
1307 : {
1308 : case SVX_SHADOW_TOPLEFT:
1309 : pDev->DrawRect( Rectangle(
1310 0 : aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1311 0 : aFrameRect.Right()-nShadowX, aFrameRect.Top() ) );
1312 : pDev->DrawRect( Rectangle(
1313 0 : aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY,
1314 0 : aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) );
1315 0 : break;
1316 : case SVX_SHADOW_TOPRIGHT:
1317 : pDev->DrawRect( Rectangle(
1318 0 : aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY,
1319 0 : aFrameRect.Right()+nShadowX, aFrameRect.Top() ) );
1320 : pDev->DrawRect( Rectangle(
1321 0 : aFrameRect.Right(), aFrameRect.Top()-nShadowY,
1322 0 : aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) );
1323 0 : break;
1324 : case SVX_SHADOW_BOTTOMLEFT:
1325 : pDev->DrawRect( Rectangle(
1326 0 : aFrameRect.Left()-nShadowX, aFrameRect.Bottom(),
1327 0 : aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) );
1328 : pDev->DrawRect( Rectangle(
1329 0 : aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY,
1330 0 : aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) );
1331 0 : break;
1332 : case SVX_SHADOW_BOTTOMRIGHT:
1333 : pDev->DrawRect( Rectangle(
1334 0 : aFrameRect.Left()+nShadowX, aFrameRect.Bottom(),
1335 0 : aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1336 : pDev->DrawRect( Rectangle(
1337 0 : aFrameRect.Right(), aFrameRect.Top()+nShadowY,
1338 0 : aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) );
1339 0 : break;
1340 : default:
1341 : {
1342 : // added to avoid warnings
1343 : }
1344 : }
1345 : }
1346 :
1347 99 : if (pBorderData)
1348 : {
1349 0 : ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO );
1350 0 : pBorderDoc->InitUndo( pDoc, 0,0, true,true );
1351 0 : if (pBorderData)
1352 0 : pBorderDoc->ApplyAttr( 0,0,0, *pBorderData );
1353 :
1354 0 : ScTableInfo aTabInfo;
1355 : pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0,
1356 0 : nScaleX, nScaleY, false, false );
1357 : OSL_ENSURE(aTabInfo.mnArrCount,"nArrCount == 0");
1358 :
1359 0 : aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight;
1360 0 : aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth =
1361 0 : aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth;
1362 :
1363 : ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0,
1364 0 : nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY );
1365 0 : aOutputData.SetUseStyleColor( bUseStyleColor );
1366 :
1367 0 : if (pBorderData)
1368 0 : aOutputData.DrawFrame();
1369 :
1370 0 : delete pBorderDoc;
1371 : }
1372 : }
1373 :
1374 6 : void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY )
1375 : {
1376 6 : bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1377 6 : long nLayoutSign = bLayoutRTL ? -1 : 1;
1378 :
1379 6 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1380 6 : long nOneX = aOnePixel.Width();
1381 6 : long nOneY = aOnePixel.Height();
1382 : SCCOL nCol;
1383 :
1384 6 : long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1385 6 : long nEndY = nScrY + nHeight - nOneY;
1386 :
1387 6 : long nPosX = nScrX;
1388 6 : if ( bLayoutRTL )
1389 : {
1390 0 : for (nCol=nX1; nCol<=nX2; nCol++)
1391 0 : nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX );
1392 : }
1393 : else
1394 6 : nPosX -= nOneX;
1395 6 : long nPosY = nScrY - nOneY;
1396 6 : OUString aText;
1397 :
1398 12 : for (nCol=nX1; nCol<=nX2; nCol++)
1399 : {
1400 6 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1401 6 : if (nDocW)
1402 : {
1403 6 : long nWidth = (long) (nDocW * nScaleX);
1404 6 : long nEndX = nPosX + nWidth * nLayoutSign;
1405 :
1406 6 : pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1407 :
1408 6 : aText = ::ScColToAlpha( nCol);
1409 6 : long nTextWidth = pDev->GetTextWidth(aText);
1410 6 : long nTextHeight = pDev->GetTextHeight();
1411 6 : long nAddX = ( nWidth - nTextWidth ) / 2;
1412 6 : long nAddY = ( nHeight - nTextHeight ) / 2;
1413 6 : long nTextPosX = nPosX+nAddX;
1414 6 : if ( bLayoutRTL )
1415 0 : nTextPosX -= nWidth;
1416 6 : pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText );
1417 :
1418 6 : nPosX = nEndX;
1419 : }
1420 6 : }
1421 6 : }
1422 :
1423 6 : void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY )
1424 : {
1425 6 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1426 6 : long nOneX = aOnePixel.Width();
1427 6 : long nOneY = aOnePixel.Height();
1428 :
1429 6 : bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1430 :
1431 6 : long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1432 6 : long nEndX = nScrX + nWidth;
1433 6 : long nPosX = nScrX;
1434 6 : if ( !bLayoutRTL )
1435 : {
1436 6 : nEndX -= nOneX;
1437 6 : nPosX -= nOneX;
1438 : }
1439 6 : long nPosY = nScrY - nOneY;
1440 6 : OUString aText;
1441 :
1442 12 : for (SCROW nRow=nY1; nRow<=nY2; nRow++)
1443 : {
1444 6 : sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab );
1445 6 : if (nDocH)
1446 : {
1447 6 : long nHeight = (long) (nDocH * nScaleY);
1448 6 : long nEndY = nPosY + nHeight;
1449 :
1450 6 : pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) );
1451 :
1452 6 : aText = OUString::number( nRow+1 );
1453 6 : long nTextWidth = pDev->GetTextWidth(aText);
1454 6 : long nTextHeight = pDev->GetTextHeight();
1455 6 : long nAddX = ( nWidth - nTextWidth ) / 2;
1456 6 : long nAddY = ( nHeight - nTextHeight ) / 2;
1457 6 : pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText );
1458 :
1459 6 : nPosY = nEndY;
1460 : }
1461 6 : }
1462 6 : }
1463 :
1464 2 : void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY,
1465 : bool bRepCol, ScPreviewLocationData& rLocationData )
1466 : {
1467 2 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1468 2 : long nOneX = aOnePixel.Width();
1469 2 : long nOneY = aOnePixel.Height();
1470 :
1471 2 : long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
1472 2 : long nEndY = nScrY + nHeight - nOneY;
1473 :
1474 2 : long nPosX = nScrX - nOneX;
1475 4 : for (SCCOL nCol=nX1; nCol<=nX2; nCol++)
1476 : {
1477 2 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1478 2 : if (nDocW)
1479 2 : nPosX += (long) (nDocW * nScaleX);
1480 : }
1481 2 : Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY );
1482 2 : rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol );
1483 2 : }
1484 :
1485 2 : void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY,
1486 : bool bRepRow, ScPreviewLocationData& rLocationData )
1487 : {
1488 2 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1489 2 : long nOneX = aOnePixel.Width();
1490 2 : long nOneY = aOnePixel.Height();
1491 :
1492 2 : bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
1493 :
1494 2 : long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
1495 2 : long nEndX = nScrX + nWidth;
1496 2 : if ( !bLayoutRTL )
1497 2 : nEndX -= nOneX;
1498 :
1499 2 : long nPosY = nScrY - nOneY;
1500 2 : nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1501 2 : Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY );
1502 2 : rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow );
1503 2 : }
1504 :
1505 21 : void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1506 : long nScrX, long nScrY, bool bRepCol, bool bRepRow,
1507 : ScPreviewLocationData& rLocationData )
1508 : {
1509 : // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer)
1510 :
1511 21 : Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1512 21 : long nLogStX = aLogPos.X();
1513 21 : long nLogStY = aLogPos.Y();
1514 :
1515 : SCCOL nCol;
1516 21 : Point aTwipOffset;
1517 21 : for (nCol=0; nCol<nX1; nCol++)
1518 0 : aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab );
1519 21 : aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab );
1520 :
1521 21 : Point aMMOffset( aTwipOffset );
1522 21 : aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS);
1523 21 : aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS);
1524 21 : aMMOffset += Point( nLogStX, nLogStY );
1525 21 : MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() );
1526 :
1527 : // get pixel rectangle
1528 :
1529 21 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
1530 21 : long nOneX = aOnePixel.Width();
1531 21 : long nOneY = aOnePixel.Height();
1532 :
1533 21 : long nPosX = nScrX - nOneX;
1534 47 : for (nCol=nX1; nCol<=nX2; nCol++)
1535 : {
1536 26 : sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab );
1537 26 : if (nDocW)
1538 26 : nPosX += (long) (nDocW * nScaleX);
1539 : }
1540 :
1541 21 : long nPosY = nScrY - nOneY;
1542 21 : nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY);
1543 21 : Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY );
1544 : rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ),
1545 21 : bRepCol, bRepRow, aDrawMapMode );
1546 21 : }
1547 :
1548 33 : void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
1549 : long nScrX, long nScrY,
1550 : bool bShLeft, bool bShTop, bool bShRight, bool bShBottom )
1551 : {
1552 : // #i47547# nothing to do if the end of the print area is before the end of
1553 : // the repeat columns/rows (don't use negative size for ScOutputData)
1554 33 : if ( nX2 < nX1 || nY2 < nY1 )
1555 33 : return;
1556 :
1557 : //! hand over Flag at FillInfo !!!!!
1558 33 : ScRange aERange;
1559 33 : bool bEmbed = pDoc->IsEmbedded();
1560 33 : if (bEmbed)
1561 : {
1562 0 : pDoc->GetEmbedded(aERange);
1563 0 : pDoc->ResetEmbedded();
1564 : }
1565 :
1566 33 : Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode);
1567 33 : long nLogStX = aPos.X();
1568 33 : long nLogStY = aPos.Y();
1569 :
1570 : // Assemble data
1571 :
1572 33 : ScTableInfo aTabInfo;
1573 : pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab,
1574 33 : nScaleX, nScaleY, true, aTableParam.bFormulas );
1575 33 : lcl_HidePrint( aTabInfo, nX1, nX2 );
1576 :
1577 33 : if (bEmbed)
1578 0 : pDoc->SetEmbedded(aERange);
1579 :
1580 : ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab,
1581 66 : nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY );
1582 :
1583 : // #114135#
1584 33 : aOutputData.SetDrawView( pDrawView );
1585 :
1586 : // test if all paint parts are hidden, then a paint is not necessary at all
1587 33 : const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY));
1588 33 : const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart()
1589 33 : && pDrawView->getHideDraw() && pDrawView->getHideFormControl() );
1590 :
1591 33 : if(!bHideAllDrawingLayer)
1592 : {
1593 33 : pDev->SetMapMode(aLogicMode);
1594 : // don's set Clipping here (Mapmode is being moved)
1595 :
1596 : // #i72502#
1597 33 : aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset);
1598 : }
1599 :
1600 33 : pDev->SetMapMode(aOffsetMode);
1601 :
1602 33 : aOutputData.SetShowFormulas( aTableParam.bFormulas );
1603 33 : aOutputData.SetShowNullValues( aTableParam.bNullVals );
1604 33 : aOutputData.SetUseStyleColor( bUseStyleColor );
1605 :
1606 33 : Color aGridColor( COL_BLACK );
1607 33 : if ( bUseStyleColor )
1608 33 : aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
1609 33 : aOutputData.SetGridColor( aGridColor );
1610 :
1611 33 : if ( !pPrinter )
1612 : {
1613 33 : OutputDevice* pRefDev = pDoc->GetPrinter(); // use the printer also for Preview
1614 33 : Fraction aPrintFrac( nZoom, 100 ); // without nManualZoom
1615 : // MapMode, as it would arrive at the printer:
1616 33 : pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) );
1617 :
1618 : // when rendering (PDF), don't use printer as ref device, but printer's MapMode
1619 : // has to be set anyway, as charts still use it (#106409#)
1620 33 : if ( !bIsRender )
1621 33 : aOutputData.SetRefDevice( pRefDev );
1622 : }
1623 :
1624 33 : if( aTableParam.bCellContent )
1625 33 : aOutputData.DrawBackground();
1626 :
1627 : pDev->SetClipRegion(Region(Rectangle(
1628 33 : aPos, Size(aOutputData.GetScrW(), aOutputData.GetScrH()))));
1629 33 : pDev->SetClipRegion();
1630 :
1631 33 : if( aTableParam.bCellContent )
1632 : {
1633 33 : aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom );
1634 33 : aOutputData.DrawFrame();
1635 33 : aOutputData.DrawStrings();
1636 33 : aOutputData.DrawEdit(false);
1637 : }
1638 :
1639 33 : if (aTableParam.bGrid)
1640 0 : aOutputData.DrawGrid( true, false ); // no page breaks
1641 :
1642 33 : aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled
1643 :
1644 : // test if all paint parts are hidden, then a paint is not necessary at all
1645 33 : if(!bHideAllDrawingLayer)
1646 : {
1647 : // #i72502#
1648 33 : aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset);
1649 : }
1650 :
1651 : // #i72502#
1652 33 : aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset);
1653 66 : aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768#
1654 : }
1655 :
1656 54 : bool ScPrintFunc::IsMirror( long nPageNo ) // Mirror margins?
1657 : {
1658 54 : SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1659 54 : return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) );
1660 : }
1661 :
1662 108 : bool ScPrintFunc::IsLeft( long nPageNo ) // left foot notes?
1663 : {
1664 108 : SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f );
1665 : bool bLeft;
1666 108 : if (eUsage == SVX_PAGE_LEFT)
1667 0 : bLeft = true;
1668 108 : else if (eUsage == SVX_PAGE_RIGHT)
1669 0 : bLeft = false;
1670 : else
1671 108 : bLeft = (nPageNo & 1) != 0;
1672 108 : return bLeft;
1673 : }
1674 :
1675 54 : void ScPrintFunc::MakeTableString()
1676 : {
1677 54 : OUString aTmp;
1678 54 : pDoc->GetName(nPrintTab, aTmp);
1679 54 : aFieldData.aTabName = aTmp;
1680 54 : }
1681 :
1682 718 : void ScPrintFunc::MakeEditEngine()
1683 : {
1684 718 : if (!pEditEngine)
1685 : {
1686 : // can't use document's edit engine pool here,
1687 : // because pool must have twips as default metric
1688 294 : pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), true );
1689 :
1690 294 : pEditEngine->EnableUndo(false);
1691 : //fdo#45869 we want text to be positioned as it would be for the the
1692 : //high dpi printed output, not as would be ideal for the 96dpi preview
1693 : //window itself
1694 294 : pEditEngine->SetRefDevice(pPrinter ? pPrinter : pDoc->GetRefDevice());
1695 : pEditEngine->SetWordDelimiters(
1696 294 : ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );
1697 294 : pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
1698 294 : pDoc->ApplyAsianEditSettings( *pEditEngine );
1699 294 : pEditEngine->EnableAutoColor( bUseStyleColor );
1700 :
1701 : // Default-Set for alignment
1702 294 : pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
1703 :
1704 294 : const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN);
1705 294 : rPattern.FillEditItemSet( pEditDefaults );
1706 : // FillEditItemSet adjusts font height to 1/100th mm,
1707 : // but for header/footer twips is needed, as in the PatternAttr:
1708 294 : pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
1709 294 : pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
1710 294 : pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
1711 : // dont use font color, because background color is not used
1712 : //! there's no way to set the background for note pages
1713 294 : pEditDefaults->ClearItem( EE_CHAR_COLOR );
1714 294 : if (ScGlobal::IsSystemRTL())
1715 0 : pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
1716 : }
1717 :
1718 718 : pEditEngine->SetData( aFieldData ); // Set page count etc.
1719 718 : }
1720 :
1721 : // nStartY = logic
1722 108 : void ScPrintFunc::PrintHF( long nPageNo, bool bHeader, long nStartY,
1723 : bool bDoPrint, ScPreviewLocationData* pLocationData )
1724 : {
1725 108 : const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr;
1726 :
1727 108 : pDev->SetMapMode( aTwipMode ); // Head-/Footlines in Twips
1728 :
1729 108 : bool bLeft = IsLeft(nPageNo) && !rParam.bShared;
1730 108 : const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight;
1731 :
1732 108 : long nLineStartX = aPageRect.Left() + rParam.nLeft;
1733 108 : long nLineEndX = aPageRect.Right() - rParam.nRight;
1734 108 : long nLineWidth = nLineEndX - nLineStartX + 1;
1735 :
1736 : // Edit-Engine
1737 :
1738 108 : Point aStart( nLineStartX, nStartY );
1739 108 : Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1740 108 : if ( rParam.pBorder )
1741 : {
1742 108 : long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT);
1743 108 : long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP);
1744 108 : aStart.X() += nLeft;
1745 108 : aStart.Y() += nTop;
1746 108 : aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT);
1747 108 : aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1748 : }
1749 :
1750 108 : if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE )
1751 : {
1752 0 : long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT);
1753 0 : long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP);
1754 0 : aStart.X() += nLeft;
1755 0 : aStart.Y() += nTop;
1756 0 : aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT);
1757 0 : aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1758 : }
1759 :
1760 108 : aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo;
1761 108 : MakeEditEngine();
1762 :
1763 108 : pEditEngine->SetPaperSize(aPaperSize);
1764 :
1765 : // Frame / Background
1766 :
1767 108 : Point aBorderStart( nLineStartX, nStartY );
1768 108 : Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance );
1769 108 : if ( rParam.bDynamic )
1770 : {
1771 : // adjust here again, for even/odd head-/footlines
1772 : // and probably other breaks by variable (page number etc.)
1773 :
1774 108 : long nMaxHeight = 0;
1775 108 : nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) );
1776 108 : nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) );
1777 108 : nMaxHeight = std::max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) );
1778 108 : if (rParam.pBorder)
1779 216 : nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) +
1780 216 : lcl_LineTotal( rParam.pBorder->GetBottom() ) +
1781 216 : rParam.pBorder->GetDistance(BOX_LINE_TOP) +
1782 216 : rParam.pBorder->GetDistance(BOX_LINE_BOTTOM);
1783 108 : if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE)
1784 0 : nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) +
1785 0 : rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM);
1786 :
1787 108 : if (nMaxHeight < rParam.nManHeight-rParam.nDistance)
1788 108 : nMaxHeight = rParam.nManHeight-rParam.nDistance; // configured Minimum
1789 :
1790 108 : aBorderSize.Height() = nMaxHeight;
1791 : }
1792 :
1793 108 : if ( bDoPrint )
1794 : {
1795 66 : double nOldScaleX = nScaleX;
1796 66 : double nOldScaleY = nScaleY;
1797 66 : nScaleX = nScaleY = 1.0; // output directly in Twips
1798 264 : DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(),
1799 330 : rParam.pBorder, rParam.pBack, rParam.pShadow );
1800 66 : nScaleX = nOldScaleX;
1801 66 : nScaleY = nOldScaleY;
1802 :
1803 : // Clipping for Text
1804 :
1805 66 : pDev->SetClipRegion(Region(Rectangle(aStart, aPaperSize)));
1806 :
1807 : // left
1808 :
1809 66 : const EditTextObject* pObject = pHFItem->GetLeftArea();
1810 66 : if (pObject)
1811 : {
1812 66 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1813 66 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1814 66 : Point aDraw = aStart;
1815 66 : long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1816 66 : if (nDif > 0)
1817 66 : aDraw.Y() += nDif / 2;
1818 66 : pEditEngine->Draw( pDev, aDraw, 0 );
1819 : }
1820 :
1821 : // center
1822 :
1823 66 : pObject = pHFItem->GetCenterArea();
1824 66 : if (pObject)
1825 : {
1826 66 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1827 66 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1828 66 : Point aDraw = aStart;
1829 66 : long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1830 66 : if (nDif > 0)
1831 66 : aDraw.Y() += nDif / 2;
1832 66 : pEditEngine->Draw( pDev, aDraw, 0 );
1833 : }
1834 :
1835 : // right
1836 :
1837 66 : pObject = pHFItem->GetRightArea();
1838 66 : if (pObject)
1839 : {
1840 66 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1841 66 : pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false );
1842 66 : Point aDraw = aStart;
1843 66 : long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight();
1844 66 : if (nDif > 0)
1845 66 : aDraw.Y() += nDif / 2;
1846 66 : pEditEngine->Draw( pDev, aDraw, 0 );
1847 : }
1848 :
1849 66 : pDev->SetClipRegion();
1850 : }
1851 :
1852 108 : if ( pLocationData )
1853 : {
1854 42 : Rectangle aHeaderRect( aBorderStart, aBorderSize );
1855 42 : pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft );
1856 : }
1857 108 : }
1858 :
1859 0 : long ScPrintFunc::DoNotes( long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData )
1860 : {
1861 0 : if (bDoPrint)
1862 0 : pDev->SetMapMode(aTwipMode);
1863 :
1864 0 : MakeEditEngine();
1865 0 : pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1866 0 : pEditEngine->SetDefaults( *pEditDefaults );
1867 :
1868 0 : Font aMarkFont;
1869 0 : ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
1870 0 : ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode );
1871 0 : pDev->SetFont( aMarkFont );
1872 0 : long nMarkLen = pDev->GetTextWidth(OUString("GW99999:"));
1873 : // without Space-Char, because it rarle arrives there
1874 :
1875 0 : Size aDataSize = aPageRect.GetSize();
1876 0 : if ( nMarkLen > aDataSize.Width() / 2 ) // everything much too small?
1877 0 : nMarkLen = aDataSize.Width() / 2; // split the page appropriately
1878 0 : aDataSize.Width() -= nMarkLen;
1879 :
1880 0 : pEditEngine->SetPaperSize( aDataSize );
1881 0 : long nPosX = aPageRect.Left() + nMarkLen;
1882 0 : long nPosY = aPageRect.Top();
1883 :
1884 0 : long nCount = 0;
1885 0 : long nSize = aNotePosList.size();
1886 : bool bOk;
1887 0 : do
1888 : {
1889 0 : bOk = false;
1890 0 : if ( nNoteStart + nCount < nSize)
1891 : {
1892 0 : ScAddress &rPos = aNotePosList[ nNoteStart + nCount ];
1893 :
1894 0 : if( const ScPostIt* pNote = pDoc->GetNote( rPos ) )
1895 : {
1896 0 : if(const EditTextObject *pEditText = pNote->GetEditTextObject())
1897 0 : pEditEngine->SetText(*pEditText);
1898 0 : long nTextHeight = pEditEngine->GetTextHeight();
1899 0 : if ( nPosY + nTextHeight < aPageRect.Bottom() )
1900 : {
1901 0 : if (bDoPrint)
1902 : {
1903 0 : pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 );
1904 :
1905 0 : OUString aMarkStr(rPos.Format(SCA_VALID, pDoc, pDoc->GetAddressConvention()));
1906 0 : aMarkStr += ":";
1907 :
1908 : // cell position also via EditEngine, for correct positioning
1909 0 : pEditEngine->SetText(aMarkStr);
1910 0 : pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 );
1911 : }
1912 :
1913 0 : if ( pLocationData )
1914 : {
1915 0 : Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) );
1916 0 : pLocationData->AddNoteText( aTextRect, rPos );
1917 0 : Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) );
1918 0 : pLocationData->AddNoteMark( aMarkRect, rPos );
1919 : }
1920 :
1921 0 : nPosY += nTextHeight;
1922 0 : nPosY += 200; // Distance
1923 0 : ++nCount;
1924 0 : bOk = true;
1925 : }
1926 : }
1927 : }
1928 : }
1929 : while (bOk);
1930 :
1931 0 : return nCount;
1932 : }
1933 :
1934 64 : long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData )
1935 : {
1936 64 : if ( nNoteStart >= (long) aNotePosList.size() || !aTableParam.bNotes )
1937 64 : return 0;
1938 :
1939 0 : if ( bDoPrint && bClearWin )
1940 : {
1941 : //! aggregate PrintPage !!!
1942 :
1943 0 : Color aBackgroundColor( COL_WHITE );
1944 0 : if ( bUseStyleColor )
1945 0 : aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1946 :
1947 0 : pDev->SetMapMode(aOffsetMode);
1948 0 : pDev->SetLineColor();
1949 0 : pDev->SetFillColor(aBackgroundColor);
1950 : pDev->DrawRect(Rectangle(Point(),
1951 0 : Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
1952 0 : (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
1953 : }
1954 :
1955 :
1956 : // adjust aPageRect for left/right page
1957 :
1958 0 : Rectangle aTempRect = Rectangle( Point(), aPageSize );
1959 0 : if (IsMirror(nPageNo))
1960 : {
1961 0 : aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
1962 0 : aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
1963 : }
1964 : else
1965 : {
1966 0 : aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
1967 0 : aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
1968 : }
1969 :
1970 0 : if ( pPrinter && bDoPrint )
1971 : {
1972 : OSL_FAIL( "StartPage does not exist anymore" );
1973 : }
1974 :
1975 0 : if ( bDoPrint || pLocationData )
1976 : {
1977 : // Head and foot lines
1978 :
1979 0 : if (aHdr.bEnable)
1980 : {
1981 0 : long nHeaderY = aPageRect.Top()-aHdr.nHeight;
1982 0 : PrintHF( nPageNo, true, nHeaderY, bDoPrint, pLocationData );
1983 : }
1984 0 : if (aFtr.bEnable)
1985 : {
1986 0 : long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
1987 0 : PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
1988 : }
1989 : }
1990 :
1991 0 : long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData );
1992 :
1993 0 : if ( pPrinter && bDoPrint )
1994 : {
1995 : OSL_FAIL( "EndPage does not exist anymore" );
1996 : }
1997 :
1998 0 : return nCount;
1999 : }
2000 :
2001 54 : void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
2002 : bool bDoPrint, ScPreviewLocationData* pLocationData )
2003 : {
2004 54 : bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab );
2005 54 : long nLayoutSign = bLayoutRTL ? -1 : 1;
2006 :
2007 : // nPageNo is the page number within all sheets of one "start page" setting
2008 :
2009 54 : if ( bClearWin && bDoPrint )
2010 : {
2011 : // must exactly fit to painting the frame in preview.cxx !!!
2012 :
2013 33 : Color aBackgroundColor( COL_WHITE );
2014 33 : if ( bUseStyleColor )
2015 33 : aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
2016 :
2017 33 : pDev->SetMapMode(aOffsetMode);
2018 33 : pDev->SetLineColor();
2019 33 : pDev->SetFillColor(aBackgroundColor);
2020 : pDev->DrawRect(Rectangle(Point(),
2021 33 : Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom),
2022 66 : (long)(aPageSize.Height() * nScaleY * 100 / nZoom))));
2023 : }
2024 :
2025 :
2026 : // adjust aPageRect for left/right page
2027 :
2028 54 : Rectangle aTempRect = Rectangle( Point(), aPageSize );
2029 54 : if (IsMirror(nPageNo))
2030 : {
2031 0 : aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom;
2032 0 : aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom;
2033 : }
2034 : else
2035 : {
2036 54 : aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom;
2037 54 : aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom;
2038 : }
2039 :
2040 54 : if ( aAreaParam.bRepeatCol )
2041 0 : if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol )
2042 0 : nX1 = nRepeatEndCol + 1;
2043 54 : bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol);
2044 54 : if ( aAreaParam.bRepeatRow )
2045 0 : if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow )
2046 0 : nY1 = nRepeatEndRow + 1;
2047 54 : bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow);
2048 :
2049 : // use new object hide flags in SdrPaintView
2050 54 : if(pDrawView)
2051 : {
2052 54 : pDrawView->setHideOle(!aTableParam.bObjects);
2053 54 : pDrawView->setHideChart(!aTableParam.bCharts);
2054 54 : pDrawView->setHideDraw(!aTableParam.bDrawings);
2055 54 : pDrawView->setHideFormControl(!aTableParam.bDrawings);
2056 : }
2057 :
2058 54 : if ( pPrinter && bDoPrint )
2059 : {
2060 : OSL_FAIL( "StartPage does not exist anymore" );
2061 : }
2062 :
2063 : // head and foot lines (without centering)
2064 :
2065 54 : if (aHdr.bEnable)
2066 : {
2067 54 : long nHeaderY = aPageRect.Top()-aHdr.nHeight;
2068 54 : PrintHF( nPageNo, true, nHeaderY, bDoPrint, pLocationData );
2069 : }
2070 54 : if (aFtr.bEnable)
2071 : {
2072 54 : long nFooterY = aPageRect.Bottom()+aFtr.nDistance;
2073 54 : PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData );
2074 : }
2075 :
2076 : // Position ( margins / centering )
2077 :
2078 54 : long nLeftSpace = aPageRect.Left(); // Document-Twips
2079 54 : long nTopSpace = aPageRect.Top();
2080 54 : if ( bCenterHor || bLayoutRTL )
2081 : {
2082 0 : long nDataWidth = 0;
2083 : SCCOL i;
2084 0 : for (i=nX1; i<=nX2; i++)
2085 0 : nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2086 0 : if (bDoRepCol)
2087 0 : for (i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2088 0 : nDataWidth += pDoc->GetColWidth( i,nPrintTab );
2089 0 : if (aTableParam.bHeaders)
2090 0 : nDataWidth += (long) PRINT_HEADER_WIDTH;
2091 0 : if (pBorderItem)
2092 0 : nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) +
2093 0 : pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width?
2094 0 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2095 0 : nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2096 0 : pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2097 0 : if ( bCenterHor )
2098 : {
2099 0 : nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL
2100 0 : if (pBorderItem)
2101 0 : nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft());
2102 : }
2103 0 : else if ( bLayoutRTL )
2104 0 : nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page
2105 : }
2106 54 : if ( bCenterVer )
2107 : {
2108 0 : long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab);
2109 0 : if (bDoRepRow)
2110 : nDataHeight += pDoc->GetRowHeight( nRepeatStartRow,
2111 0 : nRepeatEndRow, nPrintTab);
2112 0 : if (aTableParam.bHeaders)
2113 0 : nDataHeight += (long) PRINT_HEADER_HEIGHT;
2114 0 : if (pBorderItem)
2115 0 : nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) +
2116 0 : pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width?
2117 0 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2118 0 : nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2119 0 : pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2120 0 : nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2;
2121 0 : if (pBorderItem)
2122 0 : nTopSpace -= lcl_LineTotal(pBorderItem->GetTop());
2123 : }
2124 :
2125 : // calculate sizes of the elements for partitioning
2126 : // (header, repeat, data)
2127 :
2128 54 : long nHeaderWidth = 0;
2129 54 : long nHeaderHeight = 0;
2130 54 : long nRepeatWidth = 0;
2131 54 : long nRepeatHeight = 0;
2132 54 : long nContentWidth = 0; // scaled - not the same as nDataWidth above
2133 54 : long nContentHeight = 0;
2134 54 : if (aTableParam.bHeaders)
2135 : {
2136 8 : nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX);
2137 8 : nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY);
2138 : }
2139 54 : if (bDoRepCol)
2140 0 : for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++)
2141 0 : nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2142 54 : if (bDoRepRow)
2143 : nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow,
2144 0 : nRepeatEndRow, nPrintTab, nScaleY);
2145 118 : for (SCCOL i=nX1; i<=nX2; i++)
2146 64 : nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX);
2147 : nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab,
2148 54 : nScaleY);
2149 :
2150 : // partition the page
2151 :
2152 54 : long nStartX = ((long) ( nLeftSpace * nScaleX ));
2153 54 : long nStartY = ((long) ( nTopSpace * nScaleY ));
2154 54 : long nInnerStartX = nStartX;
2155 54 : long nInnerStartY = nStartY;
2156 54 : if (pBorderItem)
2157 : {
2158 108 : nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) +
2159 108 : pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX );
2160 108 : nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) +
2161 108 : pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY );
2162 : }
2163 54 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2164 : {
2165 0 : nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX );
2166 0 : nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY );
2167 : }
2168 :
2169 54 : if ( bLayoutRTL )
2170 : {
2171 : // arrange elements starting from the right edge
2172 0 : nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth;
2173 :
2174 : // make rounding easier so the elements are really next to each other in preview
2175 0 : Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode );
2176 0 : long nOffsetOneX = aOffsetOnePixel.Width();
2177 0 : nInnerStartX += nOffsetOneX / 2;
2178 : }
2179 :
2180 54 : long nFrameStartX = nInnerStartX;
2181 54 : long nFrameStartY = nInnerStartY;
2182 :
2183 54 : long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used
2184 54 : long nRepStartY = nInnerStartY + nHeaderHeight;
2185 54 : long nDataX = nRepStartX + nRepeatWidth * nLayoutSign;
2186 54 : long nDataY = nRepStartY + nRepeatHeight;
2187 54 : long nEndX = nDataX + nContentWidth * nLayoutSign;
2188 54 : long nEndY = nDataY + nContentHeight;
2189 54 : long nFrameEndX = nEndX;
2190 54 : long nFrameEndY = nEndY;
2191 :
2192 54 : if ( bLayoutRTL )
2193 : {
2194 : // each element's start position is its left edge
2195 : //! subtract one pixel less?
2196 0 : nInnerStartX -= nHeaderWidth; // used for header
2197 0 : nRepStartX -= nRepeatWidth;
2198 0 : nDataX -= nContentWidth;
2199 :
2200 : // continue right of the main elements again
2201 0 : nEndX += nHeaderWidth + nRepeatWidth + nContentWidth;
2202 : }
2203 :
2204 : // Page frame / background
2205 :
2206 : //! adjust nEndX/Y
2207 :
2208 54 : long nBorderEndX = nEndX;
2209 54 : long nBorderEndY = nEndY;
2210 54 : if (pBorderItem)
2211 : {
2212 108 : nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) +
2213 108 : pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX );
2214 108 : nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) +
2215 108 : pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY );
2216 : }
2217 54 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2218 : {
2219 0 : nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX );
2220 0 : nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY );
2221 : }
2222 :
2223 54 : if ( bDoPrint )
2224 : {
2225 33 : pDev->SetMapMode( aOffsetMode );
2226 : DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY,
2227 33 : pBorderItem, pBackgroundItem, pShadowItem );
2228 :
2229 33 : pDev->SetMapMode( aTwipMode );
2230 : }
2231 :
2232 54 : pDev->SetMapMode( aOffsetMode );
2233 :
2234 : // Output repeating rows/columns
2235 :
2236 54 : if (bDoRepCol && bDoRepRow)
2237 : {
2238 0 : if ( bDoPrint )
2239 : PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2240 0 : nRepStartX,nRepStartY, true, true, false, false );
2241 0 : if ( pLocationData )
2242 : LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow,
2243 0 : nRepStartX,nRepStartY, true, true, *pLocationData );
2244 : }
2245 54 : if (bDoRepCol)
2246 : {
2247 0 : if ( bDoPrint )
2248 : PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY,
2249 0 : true, !bDoRepRow, false, true );
2250 0 : if ( pLocationData )
2251 0 : LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, true, false, *pLocationData );
2252 : }
2253 54 : if (bDoRepRow)
2254 : {
2255 0 : if ( bDoPrint )
2256 : PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY,
2257 0 : !bDoRepCol, true, true, false );
2258 0 : if ( pLocationData )
2259 0 : LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false, true, *pLocationData );
2260 : }
2261 :
2262 : // output data
2263 :
2264 54 : if ( bDoPrint )
2265 33 : PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow, true, true );
2266 54 : if ( pLocationData )
2267 21 : LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData );
2268 :
2269 : // output column/row headers
2270 : // after data (throug probably shadow)
2271 :
2272 54 : Color aGridColor( COL_BLACK );
2273 54 : if ( bUseStyleColor )
2274 54 : aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
2275 :
2276 54 : if (aTableParam.bHeaders)
2277 : {
2278 8 : if ( bDoPrint )
2279 : {
2280 6 : pDev->SetLineColor( aGridColor );
2281 6 : pDev->SetFillColor();
2282 6 : pDev->SetMapMode(aOffsetMode);
2283 : }
2284 :
2285 8 : ScPatternAttr aPattern( pDoc->GetPool() );
2286 16 : Font aFont;
2287 8 : ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT;
2288 8 : aPattern.GetFont( aFont, eColorMode, pDev );
2289 8 : pDev->SetFont( aFont );
2290 :
2291 8 : if (bDoRepCol)
2292 : {
2293 0 : if ( bDoPrint )
2294 0 : PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY );
2295 0 : if ( pLocationData )
2296 0 : LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, true, *pLocationData );
2297 : }
2298 8 : if ( bDoPrint )
2299 6 : PrintColHdr( nX1,nX2, nDataX,nInnerStartY );
2300 8 : if ( pLocationData )
2301 2 : LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData );
2302 8 : if (bDoRepRow)
2303 : {
2304 0 : if ( bDoPrint )
2305 0 : PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY );
2306 0 : if ( pLocationData )
2307 0 : LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, true, *pLocationData );
2308 : }
2309 8 : if ( bDoPrint )
2310 6 : PrintRowHdr( nY1,nY2, nInnerStartX,nDataY );
2311 8 : if ( pLocationData )
2312 10 : LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData );
2313 : }
2314 :
2315 : // simple frame
2316 :
2317 54 : if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) )
2318 : {
2319 6 : Size aOnePixel = pDev->PixelToLogic(Size(1,1));
2320 6 : long nOneX = aOnePixel.Width();
2321 6 : long nOneY = aOnePixel.Height();
2322 :
2323 6 : long nLeftX = nFrameStartX;
2324 6 : long nTopY = nFrameStartY - nOneY;
2325 6 : long nRightX = nFrameEndX;
2326 6 : long nBottomY = nFrameEndY - nOneY;
2327 6 : if ( !bLayoutRTL )
2328 : {
2329 6 : nLeftX -= nOneX;
2330 6 : nRightX -= nOneX;
2331 : }
2332 6 : pDev->SetMapMode(aOffsetMode);
2333 6 : pDev->SetLineColor( aGridColor );
2334 6 : pDev->SetFillColor();
2335 6 : pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) );
2336 : // nEndX/Y without frame-adaption
2337 : }
2338 :
2339 54 : if ( pPrinter && bDoPrint )
2340 : {
2341 : OSL_FAIL( "EndPage does not exist anymore" );
2342 : }
2343 :
2344 54 : aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab );
2345 54 : bSourceRangeValid = true;
2346 54 : }
2347 :
2348 54 : void ScPrintFunc::SetOffset( const Point& rOfs )
2349 : {
2350 54 : aSrcOffset = rOfs;
2351 54 : }
2352 :
2353 54 : void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom )
2354 : {
2355 54 : nManualZoom = nNewZoom;
2356 54 : }
2357 :
2358 54 : void ScPrintFunc::SetClearFlag( bool bFlag )
2359 : {
2360 54 : bClearWin = bFlag;
2361 54 : }
2362 :
2363 54 : void ScPrintFunc::SetUseStyleColor( bool bFlag )
2364 : {
2365 54 : bUseStyleColor = bFlag;
2366 54 : if (pEditEngine)
2367 54 : pEditEngine->EnableAutoColor( bUseStyleColor );
2368 54 : }
2369 :
2370 0 : void ScPrintFunc::SetRenderFlag( bool bFlag )
2371 : {
2372 0 : bIsRender = bFlag; // set when using XRenderable (PDF)
2373 0 : }
2374 :
2375 0 : void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects()
2376 : {
2377 0 : aTableParam.bCellContent = false;
2378 0 : aTableParam.bNotes = false;
2379 0 : aTableParam.bGrid = false;
2380 0 : aTableParam.bHeaders = false;
2381 0 : aTableParam.bFormulas = false;
2382 0 : aTableParam.bNullVals = false;
2383 0 : }
2384 :
2385 :
2386 : // UpdatePages is only called from outside to set the breaks correctly for viewing
2387 : // - always without UserArea
2388 :
2389 :
2390 225 : bool ScPrintFunc::UpdatePages()
2391 : {
2392 225 : if (!pParamSet)
2393 0 : return false;
2394 :
2395 : // Zoom
2396 :
2397 225 : nZoom = 100;
2398 225 : if (aTableParam.bScalePageNum || aTableParam.bScaleTo)
2399 0 : nZoom = ZOOM_MIN; // correct for breaks
2400 225 : else if (aTableParam.bScaleAll)
2401 : {
2402 225 : nZoom = aTableParam.nScaleAll;
2403 225 : if ( nZoom <= ZOOM_MIN )
2404 0 : nZoom = ZOOM_MIN;
2405 : }
2406 :
2407 225 : OUString aName = pDoc->GetPageStyle( nPrintTab );
2408 225 : SCTAB nTabCount = pDoc->GetTableCount();
2409 461 : for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2410 236 : if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName )
2411 : {
2412 : // Repeating rows/columns
2413 232 : pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2414 :
2415 : // set breaks
2416 232 : ResetBreaks(nTab);
2417 232 : pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID);
2418 : }
2419 :
2420 225 : return true;
2421 : }
2422 :
2423 252 : long ScPrintFunc::CountPages() // sets also nPagesX, nPagesY
2424 : {
2425 252 : bool bAreaOk = false;
2426 :
2427 252 : if (pDoc->HasTable( nPrintTab ))
2428 : {
2429 252 : if (aAreaParam.bPrintArea) // Specify print area?
2430 : {
2431 2 : if ( bPrintCurrentTable )
2432 : {
2433 2 : ScRange& rRange = aAreaParam.aPrintArea;
2434 :
2435 : // Here, no comparison of the tables any more. Area is always valid for this table
2436 : // If comparison should be done here, the table of print ranges must be adjusted
2437 : // when inserting tables etc.!
2438 :
2439 2 : nStartCol = rRange.aStart.Col();
2440 2 : nStartRow = rRange.aStart.Row();
2441 2 : nEndCol = rRange.aEnd .Col();
2442 2 : nEndRow = rRange.aEnd .Row();
2443 2 : bAreaOk = AdjustPrintArea(false); // limit
2444 : }
2445 : else
2446 0 : bAreaOk = false;
2447 : }
2448 : else // search from document
2449 250 : bAreaOk = AdjustPrintArea(true);
2450 : }
2451 :
2452 252 : if (bAreaOk)
2453 : {
2454 32 : long nPages = 0;
2455 : size_t nY;
2456 32 : if (bMultiArea)
2457 : {
2458 0 : sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2459 0 : for (sal_uInt16 i=0; i<nRCount; i++)
2460 : {
2461 0 : CalcZoom(i);
2462 0 : if ( aTableParam.bSkipEmpty )
2463 0 : for (nY=0; nY<nPagesY; nY++)
2464 : {
2465 : OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)");
2466 0 : nPages += maPageRows[nY].CountVisible();
2467 : }
2468 : else
2469 0 : nPages += ((long) nPagesX) * nPagesY;
2470 0 : if ( pPageData )
2471 0 : FillPageData();
2472 : }
2473 : }
2474 : else
2475 : {
2476 32 : CalcZoom(RANGENO_NORANGE); // calculate Zoom
2477 32 : if ( aTableParam.bSkipEmpty )
2478 52 : for (nY=0; nY<nPagesY; nY++)
2479 : {
2480 : OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)");
2481 26 : nPages += maPageRows[nY].CountVisible();
2482 : }
2483 : else
2484 6 : nPages += ((long) nPagesX) * nPagesY;
2485 32 : if ( pPageData )
2486 1 : FillPageData();
2487 : }
2488 32 : return nPages;
2489 : }
2490 : else
2491 : {
2492 220 : nPagesX = nPagesY = nTotalY = 0;
2493 220 : return 0;
2494 : }
2495 : }
2496 :
2497 296 : long ScPrintFunc::CountNotePages()
2498 : {
2499 296 : if ( !aTableParam.bNotes || !bPrintCurrentTable )
2500 286 : return 0;
2501 :
2502 10 : bool bError = false;
2503 10 : if (!aAreaParam.bPrintArea)
2504 10 : bError = !AdjustPrintArea(true); // completely search in Doc
2505 :
2506 10 : sal_uInt16 nRepeats = 1; // how often go through it ?
2507 10 : if (bMultiArea)
2508 0 : nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2509 10 : if (bError)
2510 10 : nRepeats = 0;
2511 :
2512 10 : for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2513 : {
2514 0 : bool bDoThis = true;
2515 0 : if (bMultiArea) // go through all Areas
2516 : {
2517 0 : const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep );
2518 0 : if ( pThisRange )
2519 : {
2520 0 : nStartCol = pThisRange->aStart.Col();
2521 0 : nStartRow = pThisRange->aStart.Row();
2522 0 : nEndCol = pThisRange->aEnd .Col();
2523 0 : nEndRow = pThisRange->aEnd .Row();
2524 0 : bDoThis = AdjustPrintArea(false);
2525 : }
2526 : }
2527 :
2528 0 : if (bDoThis)
2529 : {
2530 0 : for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
2531 : {
2532 0 : if (pDoc->HasColNotes(nCol, nPrintTab))
2533 : {
2534 0 : for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
2535 : {
2536 0 : if ( pDoc->HasNote(nCol, nRow, nPrintTab) )
2537 0 : aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) );
2538 : }
2539 : }
2540 : }
2541 : }
2542 : }
2543 :
2544 10 : long nPages = 0;
2545 10 : long nNoteNr = 0;
2546 : long nNoteAdd;
2547 10 : do
2548 : {
2549 10 : nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL );
2550 10 : if (nNoteAdd)
2551 : {
2552 0 : nNoteNr += nNoteAdd;
2553 0 : ++nPages;
2554 : }
2555 : }
2556 : while (nNoteAdd);
2557 :
2558 10 : return nPages;
2559 : }
2560 :
2561 362 : void ScPrintFunc::InitModes() // set MapModes from nZoom etc.
2562 : {
2563 362 : aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom );
2564 :
2565 362 : long nEffZoom = nZoom * (long) nManualZoom;
2566 362 : nScaleX = nScaleY = HMM_PER_TWIPS; // output in 1/100 mm
2567 :
2568 362 : Fraction aZoomFract( nEffZoom,10000 );
2569 362 : Fraction aHorFract = aZoomFract;
2570 :
2571 362 : if ( !pPrinter && !bIsRender ) // adjust scale for preview
2572 : {
2573 124 : double nFact = pDocShell->GetOutputFactor();
2574 124 : aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 );
2575 : }
2576 :
2577 362 : aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract );
2578 :
2579 362 : Point aLogicOfs( -aOffset.X(), -aOffset.Y() );
2580 362 : aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract );
2581 :
2582 362 : Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) );
2583 362 : aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract );
2584 362 : }
2585 :
2586 0 : void ScPrintFunc::ApplyPrintSettings()
2587 : {
2588 0 : if ( pPrinter )
2589 : {
2590 :
2591 : // Configure Printer to Printing
2592 :
2593 :
2594 0 : Size aEnumSize = aPageSize;
2595 :
2596 :
2597 0 : pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT );
2598 0 : if ( bLandscape )
2599 : {
2600 : // landscape is always interpreted as a rotation by 90 degrees !
2601 : // this leads to non WYSIWIG but at least it prints!
2602 : // #i21775#
2603 0 : long nTemp = aEnumSize.Width();
2604 0 : aEnumSize.Width() = aEnumSize.Height();
2605 0 : aEnumSize.Height() = nTemp;
2606 : }
2607 0 : Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, true );
2608 0 : sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue();
2609 :
2610 0 : pPrinter->SetPaper( ePaper );
2611 0 : if ( PAPER_USER == ePaper )
2612 : {
2613 0 : MapMode aPrinterMode = pPrinter->GetMapMode();
2614 0 : MapMode aLocalMode( MAP_TWIP );
2615 0 : pPrinter->SetMapMode( aLocalMode );
2616 0 : pPrinter->SetPaperSizeUser( aEnumSize );
2617 0 : pPrinter->SetMapMode( aPrinterMode );
2618 : }
2619 :
2620 0 : pPrinter->SetPaperBin( nPaperBin );
2621 : }
2622 0 : }
2623 :
2624 :
2625 : // rPageRanges = range for all tables
2626 : // nStartPage = rPageRanges starts at nStartPage
2627 : // nDisplayStart = continuous number for displaying the page number
2628 :
2629 54 : long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges,
2630 : long nStartPage, long nDisplayStart, bool bDoPrint,
2631 : ScPreviewLocationData* pLocationData )
2632 : {
2633 : OSL_ENSURE(pDev,"Device == NULL");
2634 54 : if (!pParamSet)
2635 0 : return 0;
2636 :
2637 54 : if ( pPrinter && bDoPrint )
2638 0 : ApplyPrintSettings();
2639 :
2640 54 : InitModes();
2641 54 : if ( pLocationData )
2642 : {
2643 21 : pLocationData->SetCellMapMode( aOffsetMode );
2644 21 : pLocationData->SetPrintTab( nPrintTab );
2645 : }
2646 :
2647 54 : MakeTableString();
2648 :
2649 54 : long nPageNo = 0;
2650 54 : long nPrinted = 0;
2651 54 : long nEndPage = rPageRanges.GetTotalRange().Max();
2652 :
2653 54 : sal_uInt16 nRepeats = 1;
2654 54 : if (bMultiArea)
2655 0 : nRepeats = pDoc->GetPrintRangeCount(nPrintTab);
2656 108 : for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++)
2657 : {
2658 54 : if (bMultiArea) // replace area
2659 : {
2660 0 : CalcZoom(nStep); // also sets nStartCol etc. new
2661 0 : InitModes();
2662 : }
2663 :
2664 : SCCOL nX1;
2665 : SCROW nY1;
2666 : SCCOL nX2;
2667 : SCROW nY2;
2668 : size_t nCountX;
2669 : size_t nCountY;
2670 :
2671 54 : if (aTableParam.bTopDown) // top-bottom
2672 : {
2673 54 : nX1 = nStartCol;
2674 108 : for (nCountX=0; nCountX<nPagesX; nCountX++)
2675 : {
2676 : OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)");
2677 54 : nX2 = maPageEndX[nCountX];
2678 108 : for (nCountY=0; nCountY<nPagesY; nCountY++)
2679 : {
2680 : OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)");
2681 54 : nY1 = maPageRows[nCountY].GetStartRow();
2682 54 : nY2 = maPageRows[nCountY].GetEndRow();
2683 54 : if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) )
2684 : {
2685 54 : if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2686 : {
2687 : PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2688 54 : bDoPrint, pLocationData );
2689 54 : ++nPrinted;
2690 : }
2691 54 : ++nPageNo;
2692 : }
2693 : }
2694 54 : nX1 = nX2 + 1;
2695 : }
2696 : }
2697 : else // left to right
2698 : {
2699 0 : for (nCountY=0; nCountY<nPagesY; nCountY++)
2700 : {
2701 : OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)");
2702 0 : nY1 = maPageRows[nCountY].GetStartRow();
2703 0 : nY2 = maPageRows[nCountY].GetEndRow();
2704 0 : nX1 = nStartCol;
2705 0 : for (nCountX=0; nCountX<nPagesX; nCountX++)
2706 : {
2707 : OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)");
2708 0 : nX2 = maPageEndX[nCountX];
2709 0 : if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) )
2710 : {
2711 0 : if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) )
2712 : {
2713 : PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2,
2714 0 : bDoPrint, pLocationData );
2715 0 : ++nPrinted;
2716 : }
2717 0 : ++nPageNo;
2718 : }
2719 0 : nX1 = nX2 + 1;
2720 : }
2721 : }
2722 : }
2723 : }
2724 :
2725 54 : aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES );
2726 :
2727 54 : long nNoteNr = 0;
2728 : long nNoteAdd;
2729 54 : do
2730 : {
2731 54 : if ( nPageNo+nStartPage <= nEndPage )
2732 : {
2733 54 : bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 );
2734 54 : nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected,
2735 108 : ( bPageSelected ? pLocationData : NULL ) );
2736 54 : if ( nNoteAdd )
2737 : {
2738 0 : nNoteNr += nNoteAdd;
2739 0 : if (bPageSelected)
2740 : {
2741 0 : ++nPrinted;
2742 0 : bSourceRangeValid = false; // last page was no cell range
2743 : }
2744 0 : ++nPageNo;
2745 : }
2746 : }
2747 : else
2748 0 : nNoteAdd = 0;
2749 : }
2750 : while (nNoteAdd);
2751 :
2752 54 : if ( bMultiArea )
2753 0 : ResetBreaks(nPrintTab); //breaks correct for displaying
2754 :
2755 54 : return nPrinted;
2756 : }
2757 :
2758 32 : void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // calculate zoom
2759 : {
2760 32 : sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab );
2761 32 : const ScRange* pThisRange = NULL;
2762 32 : if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount )
2763 0 : pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo );
2764 32 : if ( pThisRange )
2765 : {
2766 0 : nStartCol = pThisRange->aStart.Col();
2767 0 : nStartRow = pThisRange->aStart.Row();
2768 0 : nEndCol = pThisRange->aEnd .Col();
2769 0 : nEndRow = pThisRange->aEnd .Row();
2770 : }
2771 :
2772 32 : if (!AdjustPrintArea(false)) // empty
2773 : {
2774 0 : nZoom = 100;
2775 0 : nPagesX = nPagesY = nTotalY = 0;
2776 32 : return;
2777 : }
2778 :
2779 32 : pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow );
2780 :
2781 32 : if (aTableParam.bScalePageNum)
2782 : {
2783 0 : nZoom = 100;
2784 0 : sal_uInt16 nPagesToFit = aTableParam.nScalePageNum;
2785 :
2786 : // If manual breaks are forced, calculate minimum # pages required
2787 0 : if (aTableParam.bForceBreaks)
2788 : {
2789 0 : sal_uInt16 nMinPages = 0;
2790 0 : std::set<SCROW> aRowBreaks;
2791 0 : std::set<SCCOL> aColBreaks;
2792 0 : pDoc->GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2793 0 : pDoc->GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2794 0 : nMinPages = (aRowBreaks.size() + 1) * (aColBreaks.size() + 1);
2795 :
2796 : // #i54993# use min forced by breaks if it's > # pages in
2797 : // scale parameter to avoid bottoming out at <= ZOOM_MIN
2798 0 : nPagesToFit = nMinPages > nPagesToFit ? nMinPages : nPagesToFit;
2799 : }
2800 :
2801 0 : sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2802 : while (true)
2803 : {
2804 0 : if (nZoom <= ZOOM_MIN)
2805 0 : break;
2806 :
2807 0 : CalcPages();
2808 0 : bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit);
2809 :
2810 0 : if (bFitsPage)
2811 : {
2812 0 : if (nZoom == 100)
2813 : // If it fits at 100 %, it's good enough for me.
2814 0 : break;
2815 :
2816 0 : nLastFitZoom = nZoom;
2817 0 : nZoom = (nLastNonFitZoom + nZoom) / 2;
2818 :
2819 0 : if (nLastFitZoom == nZoom)
2820 : // It converged. Use this zoom level.
2821 0 : break;
2822 : }
2823 : else
2824 : {
2825 0 : if (nZoom - nLastFitZoom <= 1)
2826 : {
2827 0 : nZoom = nLastFitZoom;
2828 0 : CalcPages();
2829 0 : break;
2830 : }
2831 :
2832 0 : nLastNonFitZoom = nZoom;
2833 0 : nZoom = (nLastFitZoom + nZoom) / 2;
2834 : }
2835 0 : }
2836 : }
2837 32 : else if (aTableParam.bScaleTo)
2838 : {
2839 0 : nZoom = 100;
2840 0 : sal_uInt16 nW = aTableParam.nScaleWidth;
2841 0 : sal_uInt16 nH = aTableParam.nScaleHeight;
2842 :
2843 : // If manual breaks are forced, calculate minimum # pages required
2844 0 : if (aTableParam.bForceBreaks)
2845 : {
2846 0 : sal_uInt16 nMinPagesW = 0, nMinPagesH = 0;
2847 0 : std::set<SCROW> aRowBreaks;
2848 0 : std::set<SCCOL> aColBreaks;
2849 0 : pDoc->GetAllRowBreaks(aRowBreaks, nPrintTab, false, true);
2850 0 : pDoc->GetAllColBreaks(aColBreaks, nPrintTab, false, true);
2851 0 : nMinPagesW = aColBreaks.size() + 1;
2852 0 : nMinPagesH = aRowBreaks.size() + 1;
2853 :
2854 : // #i54993# use min forced by breaks if it's > # pages in
2855 : // scale parameters to avoid bottoming out at <= ZOOM_MIN
2856 0 : nW = nMinPagesW > nW ? nMinPagesW : nW;
2857 0 : nH = nMinPagesH > nH ? nMinPagesH : nH;
2858 : }
2859 :
2860 0 : sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0;
2861 : while (true)
2862 : {
2863 0 : if (nZoom <= ZOOM_MIN)
2864 0 : break;
2865 :
2866 0 : CalcPages();
2867 0 : bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH)));
2868 :
2869 0 : if (bFitsPage)
2870 : {
2871 0 : if (nZoom == 100)
2872 : // If it fits at 100 %, it's good enough for me.
2873 0 : break;
2874 :
2875 0 : nLastFitZoom = nZoom;
2876 0 : nZoom = (nLastNonFitZoom + nZoom) / 2;
2877 :
2878 0 : if (nLastFitZoom == nZoom)
2879 : // It converged. Use this zoom level.
2880 0 : break;
2881 : }
2882 : else
2883 : {
2884 0 : if (nZoom - nLastFitZoom <= 1)
2885 : {
2886 0 : nZoom = nLastFitZoom;
2887 0 : CalcPages();
2888 0 : break;
2889 : }
2890 :
2891 0 : nLastNonFitZoom = nZoom;
2892 0 : nZoom = (nLastFitZoom + nZoom) / 2;
2893 : }
2894 0 : }
2895 : }
2896 32 : else if (aTableParam.bScaleAll)
2897 : {
2898 32 : nZoom = aTableParam.nScaleAll;
2899 32 : if ( nZoom <= ZOOM_MIN )
2900 0 : nZoom = ZOOM_MIN;
2901 32 : CalcPages();
2902 : }
2903 : else
2904 : {
2905 : OSL_ENSURE( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" );
2906 0 : nZoom = 100;
2907 0 : CalcPages();
2908 : }
2909 : }
2910 :
2911 308 : Size ScPrintFunc::GetDocPageSize()
2912 : {
2913 : // Adjust height of head/foot line
2914 :
2915 308 : InitModes(); // initialize aTwipMode from nZoom
2916 308 : pDev->SetMapMode( aTwipMode ); // head/foot line in Twips
2917 308 : UpdateHFHeight( aHdr );
2918 308 : UpdateHFHeight( aFtr );
2919 :
2920 : // Page size in Document-Twips
2921 : // Calculating Left / Right also in PrintPage
2922 :
2923 308 : aPageRect = Rectangle( Point(), aPageSize );
2924 308 : aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom;
2925 308 : aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom;
2926 308 : aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight;
2927 308 : aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight;
2928 :
2929 308 : Size aDocPageSize = aPageRect.GetSize();
2930 308 : if (aTableParam.bHeaders)
2931 : {
2932 10 : aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH;
2933 10 : aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT;
2934 : }
2935 308 : if (pBorderItem)
2936 : {
2937 924 : aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) +
2938 616 : lcl_LineTotal(pBorderItem->GetRight()) +
2939 616 : pBorderItem->GetDistance(BOX_LINE_LEFT) +
2940 924 : pBorderItem->GetDistance(BOX_LINE_RIGHT);
2941 924 : aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) +
2942 616 : lcl_LineTotal(pBorderItem->GetBottom()) +
2943 616 : pBorderItem->GetDistance(BOX_LINE_TOP) +
2944 924 : pBorderItem->GetDistance(BOX_LINE_BOTTOM);
2945 : }
2946 308 : if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE)
2947 : {
2948 0 : aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) +
2949 0 : pShadowItem->CalcShadowSpace(SHADOW_RIGHT);
2950 0 : aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) +
2951 0 : pShadowItem->CalcShadowSpace(SHADOW_BOTTOM);
2952 : }
2953 308 : return aDocPageSize;
2954 : }
2955 :
2956 232 : void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Set Breaks correctly for view
2957 : {
2958 232 : pDoc->SetPageSize( nTab, GetDocPageSize() );
2959 232 : pDoc->UpdatePageBreaks( nTab, NULL );
2960 232 : }
2961 :
2962 70 : static void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry,
2963 : SCCOL nStartCol, const std::vector< SCCOL >& rPageEndX )
2964 : {
2965 70 : size_t nPagesX = rPageRowEntry.GetPagesX();
2966 70 : SCROW nStartRow = rPageRowEntry.GetStartRow();
2967 70 : SCROW nEndRow = rPageRowEntry.GetEndRow();
2968 :
2969 70 : bool bLeftIsEmpty = false;
2970 70 : ScRange aTempRange;
2971 70 : Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 );
2972 :
2973 140 : for (size_t i=0; i<nPagesX; i++)
2974 : {
2975 : OSL_ENSURE(i < rPageEndX.size(), "vector access error for maPageEndX (!)");
2976 70 : SCCOL nEndCol = rPageEndX[i];
2977 70 : if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow,
2978 70 : bLeftIsEmpty, &aTempRange, &aTempRect ) )
2979 : {
2980 0 : rPageRowEntry.SetHidden(i);
2981 0 : bLeftIsEmpty = true;
2982 : }
2983 : else
2984 70 : bLeftIsEmpty = false;
2985 :
2986 70 : nStartCol = nEndCol+1;
2987 : }
2988 70 : }
2989 :
2990 76 : void ScPrintFunc::CalcPages() // calculates aPageRect and pages from nZoom
2991 : {
2992 : // #i123672# use dynamic mem to react on size changes
2993 76 : if (maPageEndX.size() < MAXCOL+1)
2994 : {
2995 76 : maPageEndX.resize(MAXCOL+1, SCCOL());
2996 : }
2997 :
2998 76 : pDoc->SetPageSize( nPrintTab, GetDocPageSize() );
2999 76 : if (aAreaParam.bPrintArea)
3000 : {
3001 2 : ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab );
3002 2 : pDoc->UpdatePageBreaks( nPrintTab, &aRange );
3003 : }
3004 : else
3005 : {
3006 74 : pDoc->UpdatePageBreaks( nPrintTab, NULL ); // else, end is marked
3007 : }
3008 :
3009 76 : const size_t nRealCnt = nEndRow-nStartRow+1;
3010 :
3011 : // #i123672# use dynamic mem to react on size changes
3012 76 : if (maPageEndY.size() < nRealCnt+1)
3013 : {
3014 76 : maPageEndY.resize(nRealCnt+1, SCROW());
3015 : }
3016 :
3017 : // #i123672# use dynamic mem to react on size changes
3018 76 : if (maPageRows.size() < nRealCnt+1)
3019 : {
3020 76 : maPageRows.resize(nRealCnt+1, ScPageRowEntry());
3021 : }
3022 :
3023 :
3024 : // Page alignment/splitting after breaks in Col/RowFlags
3025 : // Of several breaks in a hidden area, only one counts.
3026 :
3027 :
3028 76 : nPagesX = 0;
3029 76 : nPagesY = 0;
3030 76 : nTotalY = 0;
3031 :
3032 76 : bool bVisCol = false;
3033 217 : for (SCCOL i=nStartCol; i<=nEndCol; i++)
3034 : {
3035 141 : bool bHidden = pDoc->ColHidden(i, nPrintTab);
3036 141 : bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE);
3037 141 : if ( i>nStartCol && bVisCol && bPageBreak )
3038 : {
3039 : OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)");
3040 6 : maPageEndX[nPagesX] = i-1;
3041 6 : ++nPagesX;
3042 6 : bVisCol = false;
3043 : }
3044 141 : if (!bHidden)
3045 141 : bVisCol = true;
3046 : }
3047 76 : if (bVisCol) // also at the end, no empty pages
3048 : {
3049 : OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)");
3050 76 : maPageEndX[nPagesX] = nEndCol;
3051 76 : ++nPagesX;
3052 : }
3053 :
3054 76 : bool bVisRow = false;
3055 76 : SCROW nPageStartRow = nStartRow;
3056 76 : SCROW nLastVisibleRow = -1;
3057 :
3058 76 : ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab));
3059 76 : SCROW nNextPageBreak = pRowBreakIter->first();
3060 152 : while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow)
3061 : // Skip until the page break position is at the start row or greater.
3062 0 : nNextPageBreak = pRowBreakIter->next();
3063 :
3064 322 : for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
3065 : {
3066 246 : bool bPageBreak = (nNextPageBreak == nRow);
3067 246 : if (bPageBreak)
3068 3 : nNextPageBreak = pRowBreakIter->next();
3069 :
3070 246 : if (nRow > nStartRow && bVisRow && bPageBreak )
3071 : {
3072 : OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)");
3073 3 : maPageEndY[nTotalY] = nRow-1;
3074 3 : ++nTotalY;
3075 :
3076 3 : if ( !aTableParam.bSkipEmpty ||
3077 0 : !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) )
3078 : {
3079 : OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)");
3080 3 : maPageRows[nPagesY].SetStartRow( nPageStartRow );
3081 3 : maPageRows[nPagesY].SetEndRow( nRow-1 );
3082 3 : maPageRows[nPagesY].SetPagesX( nPagesX );
3083 3 : if (aTableParam.bSkipEmpty)
3084 0 : lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX );
3085 3 : ++nPagesY;
3086 : }
3087 :
3088 3 : nPageStartRow = nRow;
3089 3 : bVisRow = false;
3090 : }
3091 :
3092 246 : if (nRow <= nLastVisibleRow)
3093 : {
3094 : // This row is still visible. Don't bother calling RowHidden() to
3095 : // find out, for speed optimization.
3096 170 : bVisRow = true;
3097 170 : continue;
3098 : }
3099 :
3100 76 : SCROW nLastRow = -1;
3101 76 : if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow))
3102 : {
3103 76 : bVisRow = true;
3104 76 : nLastVisibleRow = nLastRow;
3105 : }
3106 : else
3107 : // skip all hidden rows.
3108 0 : nRow = nLastRow;
3109 : }
3110 :
3111 76 : if (bVisRow)
3112 : {
3113 : OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)");
3114 76 : maPageEndY[nTotalY] = nEndRow;
3115 76 : ++nTotalY;
3116 :
3117 146 : if ( !aTableParam.bSkipEmpty ||
3118 70 : !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) )
3119 : {
3120 : OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)");
3121 76 : maPageRows[nPagesY].SetStartRow( nPageStartRow );
3122 76 : maPageRows[nPagesY].SetEndRow( nEndRow );
3123 76 : maPageRows[nPagesY].SetPagesX( nPagesX );
3124 76 : if (aTableParam.bSkipEmpty)
3125 70 : lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX );
3126 76 : ++nPagesY;
3127 : }
3128 76 : }
3129 178 : }
3130 :
3131 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|