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