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