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