diff options
Diffstat (limited to 'sc/source/ui/view/printfun.cxx')
-rw-r--r-- | sc/source/ui/view/printfun.cxx | 3176 |
1 files changed, 3176 insertions, 0 deletions
diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx new file mode 100644 index 000000000000..c60ab4946b9d --- /dev/null +++ b/sc/source/ui/view/printfun.cxx @@ -0,0 +1,3176 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include <editeng/eeitem.hxx> + +#include "printfun.hxx" + +#include <svx/svxids.hrc> +#include <editeng/adjitem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/brshitem.hxx> +#include <svtools/colorcfg.hxx> +#include <editeng/editstat.hxx> // EE_CNTRL_RTFSTYLESHEETS +#include <svx/fmview.hxx> +#include <editeng/frmdiritem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/paperinf.hxx> +#include <editeng/pbinitem.hxx> +#include <editeng/shaditem.hxx> +#include <editeng/sizeitem.hxx> +#include <svx/svdpagv.hxx> +#include <editeng/ulspitem.hxx> +#include <sfx2/app.hxx> +#include <sfx2/printer.hxx> +#include <sfx2/progress.hxx> +#include <tools/multisel.hxx> +#include <sfx2/docfile.hxx> +#include <tools/urlobj.hxx> +#include <svx/xoutbmp.hxx> + +#include "editutil.hxx" +#include "docsh.hxx" +#include "output.hxx" +#include "viewdata.hxx" +#include "viewopti.hxx" +#include "stlpool.hxx" +#include "pagepar.hxx" +#include "attrib.hxx" +#include "patattr.hxx" +#include "docpool.hxx" +#include "dociter.hxx" +#include "cell.hxx" +#include "drawutil.hxx" +#include "globstr.hrc" +#include "scresid.hxx" +#include "sc.hrc" +#include "pagedata.hxx" +#include "printopt.hxx" +#include "prevloc.hxx" +#include "scmod.hxx" +#include "drwlayer.hxx" +#include "fillinfo.hxx" +#include "postit.hxx" + +#include <vcl/lineinfo.hxx> +#include <tools/pstm.hxx> + +#include <boost/scoped_ptr.hpp> + +#define ZOOM_MIN 10 + +#define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue() +#define GET_USHORT(set,which) ((const SfxUInt16Item&)(set)->Get((which))).GetValue() +#define GET_SHOW(set,which) ( VOBJ_MODE_SHOW == ScVObjMode( ((const ScViewObjectModeItem&)(set)->Get((which))).GetValue()) ) + +//------------------------------------------------------------------------ + +ScPageRowEntry::ScPageRowEntry(const ScPageRowEntry& r) +{ + nStartRow = r.nStartRow; + nEndRow = r.nEndRow; + nPagesX = r.nPagesX; + if (r.pHidden && nPagesX) + { + pHidden = new sal_Bool[nPagesX]; + memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) ); + } + else + pHidden = NULL; +} + +const ScPageRowEntry& ScPageRowEntry::operator=(const ScPageRowEntry& r) +{ + delete[] pHidden; + + nStartRow = r.nStartRow; + nEndRow = r.nEndRow; + nPagesX = r.nPagesX; + if (r.pHidden && nPagesX) + { + pHidden = new sal_Bool[nPagesX]; + memcpy( pHidden, r.pHidden, nPagesX * sizeof(sal_Bool) ); + } + else + pHidden = NULL; + + return *this; +} + +void ScPageRowEntry::SetPagesX(size_t nNew) +{ + if (pHidden) + { + OSL_FAIL("SetPagesX nicht nach SetHidden"); + delete[] pHidden; + pHidden = NULL; + } + nPagesX = nNew; +} + +void ScPageRowEntry::SetHidden(size_t nX) +{ + if ( nX < nPagesX ) + { + if ( nX+1 == nPagesX ) // letzte Seite? + --nPagesX; + else + { + if (!pHidden) + { + pHidden = new sal_Bool[nPagesX]; + memset( pHidden, false, nPagesX * sizeof(sal_Bool) ); + } + pHidden[nX] = sal_True; + } + } +} + +sal_Bool ScPageRowEntry::IsHidden(size_t nX) const +{ + return nX>=nPagesX || ( pHidden && pHidden[nX] ); //! inline? +} + +size_t ScPageRowEntry::CountVisible() const +{ + if ( pHidden ) + { + size_t nVis = 0; + for (size_t i=0; i<nPagesX; i++) + if (!pHidden[i]) + ++nVis; + return nVis; + } + else + return nPagesX; +} + +//------------------------------------------------------------------------ + +long lcl_LineTotal(const ::editeng::SvxBorderLine* pLine) +{ + return pLine ? ( pLine->GetOutWidth() + pLine->GetInWidth() + pLine->GetDistance() ) : 0; +} + +void ScPrintFunc::Construct( const ScPrintOptions* pOptions ) +{ + pDocShell->UpdatePendingRowHeights( nPrintTab ); + pDoc = pDocShell->GetDocument(); + + SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen + if (pDocPrinter) + aOldPrinterMode = pDocPrinter->GetMapMode(); + + // einheitlicher MapMode ueber alle Aufrufe (z.B. Repaint !!!), + // weil die EditEngine sonst unterschiedliche Texthoehen liefert + pDev->SetMapMode(MAP_PIXEL); + + pPageEndX = NULL; + pPageEndY = NULL; + pPageRows = NULL; + pBorderItem = NULL; + pBackgroundItem = NULL; + pShadowItem = NULL; + + pEditEngine = NULL; + pEditDefaults = NULL; + + ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool(); + SfxStyleSheetBase* pStyleSheet = pStylePool->Find( + pDoc->GetPageStyle( nPrintTab ), + SFX_STYLE_FAMILY_PAGE ); + if (pStyleSheet) + pParamSet = &pStyleSheet->GetItemSet(); + else + { + OSL_FAIL("Seitenvorlage nicht gefunden" ); + pParamSet = NULL; + } + + if (!bState) + nZoom = 100; + nManualZoom = 100; + bClearWin = false; + bUseStyleColor = false; + bIsRender = false; + + InitParam(pOptions); + + pPageData = NULL; // wird nur zur Initialisierung gebraucht +} + +ScPrintFunc::ScPrintFunc( ScDocShell* pShell, SfxPrinter* pNewPrinter, SCTAB nTab, + long nPage, long nDocP, const ScRange* pArea, + const ScPrintOptions* pOptions, + ScPageBreakData* pData ) + : pDocShell ( pShell ), + pPrinter ( pNewPrinter ), + pDrawView ( NULL ), + nPrintTab ( nTab ), + nPageStart ( nPage ), + nDocPages ( nDocP ), + pUserArea ( pArea ), + bState ( false ), + bSourceRangeValid ( false ), + bPrintCurrentTable ( false ), + bMultiArea ( false ), + nTabPages ( 0 ), + nTotalPages ( 0 ), + nPagesX(0), + nPagesY(0), + nTotalY(0), + pPageData ( pData ) +{ + pDev = pPrinter; + aSrcOffset = pPrinter->PixelToLogic( pPrinter->GetPageOffsetPixel(), MAP_100TH_MM ); + Construct( pOptions ); +} + +ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, SCTAB nTab, + long nPage, long nDocP, const ScRange* pArea, + const ScPrintOptions* pOptions ) + : pDocShell ( pShell ), + pPrinter ( NULL ), + pDrawView ( NULL ), + nPrintTab ( nTab ), + nPageStart ( nPage ), + nDocPages ( nDocP ), + pUserArea ( pArea ), + bState ( false ), + bSourceRangeValid ( false ), + bPrintCurrentTable ( false ), + bMultiArea ( false ), + nTabPages ( 0 ), + nTotalPages ( 0 ), + nPagesX(0), + nPagesY(0), + nTotalY(0), + pPageData ( NULL ) +{ + pDev = pOutDev; + Construct( pOptions ); +} + +ScPrintFunc::ScPrintFunc( OutputDevice* pOutDev, ScDocShell* pShell, + const ScPrintState& rState, const ScPrintOptions* pOptions ) + : pDocShell ( pShell ), + pPrinter ( NULL ), + pDrawView ( NULL ), + pUserArea ( NULL ), + bSourceRangeValid ( false ), + bPrintCurrentTable ( false ), + bMultiArea ( false ), + nPagesX(0), + nPagesY(0), + nTotalY(0), + pPageData ( NULL ) +{ + pDev = pOutDev; + + nPrintTab = rState.nPrintTab; + nStartCol = rState.nStartCol; + nStartRow = rState.nStartRow; + nEndCol = rState.nEndCol; + nEndRow = rState.nEndRow; + nZoom = rState.nZoom; + nPagesX = rState.nPagesX; + nPagesY = rState.nPagesY; + nTabPages = rState.nTabPages; + nTotalPages = rState.nTotalPages; + nPageStart = rState.nPageStart; + nDocPages = rState.nDocPages; + bState = sal_True; + + Construct( pOptions ); +} +ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow, SCTAB nTab, + long nPage, long nDocP, const ScRange* pArea, + const ScPrintOptions* pOptions ) + : pDocShell ( pShell ), + pPrinter ( NULL ), + pDrawView ( NULL ), + nPrintTab ( nTab ), + nPageStart ( nPage ), + nDocPages ( nDocP ), + pUserArea ( pArea ), + bState ( false ), + bPrintCurrentTable ( false ), + bMultiArea ( false ), + nTabPages ( 0 ), + nTotalPages ( 0 ), + nPagesX(0), + nPagesY(0), + nTotalY(0), + pPageData ( NULL ) +{ + pDev = pWindow; + Construct( pOptions ); +} +ScPrintFunc::ScPrintFunc( ScDocShell* pShell, Window* pWindow, + const ScPrintState& rState, const ScPrintOptions* pOptions ) + : pDocShell ( pShell ), + pPrinter ( NULL ), + pDrawView ( NULL ), + pUserArea ( NULL ), + bPrintCurrentTable ( false ), + bMultiArea ( false ), + nPagesX(0), + nPagesY(0), + nTotalY(0), + pPageData ( NULL ) +{ + pDev = pWindow; + + nPrintTab = rState.nPrintTab; + nStartCol = rState.nStartCol; + nStartRow = rState.nStartRow; + nEndCol = rState.nEndCol; + nEndRow = rState.nEndRow; + nZoom = rState.nZoom; + nPagesX = rState.nPagesX; + nPagesY = rState.nPagesY; + nTabPages = rState.nTabPages; + nTotalPages = rState.nTotalPages; + nPageStart = rState.nPageStart; + nDocPages = rState.nDocPages; + bState = sal_True; + + Construct( pOptions ); +} + +void ScPrintFunc::GetPrintState( ScPrintState& rState ) +{ + rState.nPrintTab = nPrintTab; + rState.nStartCol = nStartCol; + rState.nStartRow = nStartRow; + rState.nEndCol = nEndCol; + rState.nEndRow = nEndRow; + rState.nZoom = nZoom; + rState.nPagesX = nPagesX; + rState.nPagesY = nPagesY; + rState.nTabPages = nTabPages; + rState.nTotalPages = nTotalPages; + rState.nPageStart = nPageStart; + rState.nDocPages = nDocPages; +} + +sal_Bool ScPrintFunc::GetLastSourceRange( ScRange& rRange ) const +{ + rRange = aLastSourceRange; + return bSourceRangeValid; +} + +void ScPrintFunc::FillPageData() +{ + if (pPageData) + { + sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() ); + ScPrintRangeData& rData = pPageData->GetData(nCount); // hochzaehlen + + rData.SetPrintRange( ScRange( nStartCol, nStartRow, nPrintTab, + nEndCol, nEndRow, nPrintTab ) ); + rData.SetPagesX( nPagesX, pPageEndX ); + rData.SetPagesY( nTotalY, pPageEndY ); + + // Einstellungen + rData.SetTopDown( aTableParam.bTopDown ); + rData.SetAutomatic( !aAreaParam.bPrintArea ); + } +} + +ScPrintFunc::~ScPrintFunc() +{ + ScAddress* pTripel = (ScAddress*) aNotePosList.First(); + while (pTripel) + { + delete pTripel; + pTripel = (ScAddress*) aNotePosList.Next(); + } + aNotePosList.Clear(); + + delete[] pPageEndX; + delete[] pPageEndY; + delete[] pPageRows; + delete pEditDefaults; + delete pEditEngine; + + // Druckereinstellungen werden jetzt von aussen wiederhergestellt + + // Fuer DrawingLayer/Charts muss der MapMode am Drucker (RefDevice) immer stimmen + SfxPrinter* pDocPrinter = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen + if (pDocPrinter) + pDocPrinter->SetMapMode(aOldPrinterMode); +} + +void ScPrintFunc::SetDrawView( FmFormView* pNew ) +{ + pDrawView = pNew; +} + +void lcl_HidePrint( ScTableInfo& rTabInfo, SCCOL nX1, SCCOL nX2 ) +{ + for (SCSIZE nArrY=1; nArrY+1<rTabInfo.mnArrCount; nArrY++) + { + RowInfo* pThisRowInfo = &rTabInfo.mpRowInfo[nArrY]; + for (SCCOL nX=nX1; nX<=nX2; nX++) + { + const CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nX+1]; + if (!rCellInfo.bEmptyCellText) + if (((const ScProtectionAttr&)rCellInfo.pPatternAttr-> + GetItem(ATTR_PROTECTION, rCellInfo.pConditionSet)).GetHidePrint()) + { + pThisRowInfo->pCellInfo[nX+1].pCell = NULL; + pThisRowInfo->pCellInfo[nX+1].bEmptyCellText = sal_True; + } + } + } +} + +// +// Ausgabe auf Device (static) +// +// wird benutzt fuer: +// - Clipboard/Bitmap +// - Ole-Object (DocShell::Draw) +// - Vorschau bei Vorlagen + +void ScPrintFunc::DrawToDev( ScDocument* pDoc, OutputDevice* pDev, double /* nPrintFactor */, + const Rectangle& rBound, ScViewData* pViewData, sal_Bool bMetaFile ) +{ + //! nPrintFactor auswerten !!! + + SCTAB nTab = 0; + if (pViewData) + nTab = pViewData->GetTabNo(); + + sal_Bool bDoGrid, bNullVal, bFormula; + ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool(); + SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE ); + if (pStyleSheet) + { + SfxItemSet& rSet = pStyleSheet->GetItemSet(); + bDoGrid = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_GRID)).GetValue(); + bNullVal = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_NULLVALS)).GetValue(); + bFormula = ((const SfxBoolItem&)rSet.Get(ATTR_PAGE_FORMULAS)).GetValue(); + } + else + { + const ScViewOptions& rOpt = pDoc->GetViewOptions(); + bDoGrid = rOpt.GetOption(VOPT_GRID); + bNullVal = rOpt.GetOption(VOPT_NULLVALS); + bFormula = rOpt.GetOption(VOPT_FORMULAS); + } + + MapMode aMode = pDev->GetMapMode(); + + Rectangle aRect = rBound; + + if (aRect.Right() < aRect.Left() || aRect.Bottom() < aRect.Top()) + aRect = Rectangle( Point(), pDev->GetOutputSize() ); + + SCCOL nX1 = 0; + SCROW nY1 = 0; + SCCOL nX2 = OLE_STD_CELLS_X - 1; + SCROW nY2 = OLE_STD_CELLS_Y - 1; + if (bMetaFile) + { + ScRange aRange = pDoc->GetRange( nTab, rBound ); + nX1 = aRange.aStart.Col(); + nY1 = aRange.aStart.Row(); + nX2 = aRange.aEnd.Col(); + nY2 = aRange.aEnd.Row(); + } + else if (pViewData) + { + ScSplitPos eWhich = pViewData->GetActivePart(); + ScHSplitPos eHWhich = WhichH(eWhich); + ScVSplitPos eVWhich = WhichV(eWhich); + nX1 = pViewData->GetPosX(eHWhich); + nY1 = pViewData->GetPosY(eVWhich); + nX2 = nX1 + pViewData->VisibleCellsX(eHWhich); + if (nX2>nX1) --nX2; + nY2 = nY1 + pViewData->VisibleCellsY(eVWhich); + if (nY2>nY1) --nY2; + } + + if (nX1 > MAXCOL) nX1 = MAXCOL; + if (nX2 > MAXCOL) nX2 = MAXCOL; + if (nY1 > MAXROW) nY1 = MAXROW; + if (nY2 > MAXROW) nY2 = MAXROW; + + long nDevSizeX = aRect.Right()-aRect.Left()+1; + long nDevSizeY = aRect.Bottom()-aRect.Top()+1; + + Rectangle aLines; + ScRange aRange( nX1,nY1,nTab, nX2,nY2,nTab ); + + long nTwipsSizeX = 0; + for (SCCOL i=nX1; i<=nX2; i++) + nTwipsSizeX += pDoc->GetColWidth( i, nTab ); + long nTwipsSizeY = (long) pDoc->GetRowHeight( nY1, nY2, nTab ); + + // wenn keine Linien, dann trotzdem Platz fuer den Aussenrahmen (20 Twips = 1pt) + // (HasLines initalisiert aLines auf 0,0,0,0) + nTwipsSizeX += aLines.Left() + Max( aLines.Right(), 20L ); + nTwipsSizeY += aLines.Top() + Max( aLines.Bottom(), 20L ); + + double nScaleX = (double) nDevSizeX / nTwipsSizeX; + double nScaleY = (double) nDevSizeY / nTwipsSizeY; + + //! Flag bei FillInfo uebergeben !!!!! + ScRange aERange; + sal_Bool bEmbed = pDoc->IsEmbedded(); + if (bEmbed) + { + pDoc->GetEmbedded(aERange); + pDoc->ResetEmbedded(); + } + + // Daten zusammenstellen + + ScTableInfo aTabInfo; + pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, + nScaleX, nScaleY, false, bFormula ); + lcl_HidePrint( aTabInfo, nX1, nX2 ); + + if (bEmbed) + pDoc->SetEmbedded(aERange); + + long nScrX = aRect.Left(); + long nScrY = aRect.Top(); + + // Wenn keine Linien, trotzdem Platz fuer Gitterlinien lassen + // (werden sonst abgeschnitten) + long nAddX = (long)( aLines.Left() * nScaleX ); + nScrX += ( nAddX ? nAddX : 1 ); + long nAddY = (long)( aLines.Top() * nScaleY ); + nScrY += ( nAddY ? nAddY : 1 ); + + ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nTab, + nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY ); + aOutputData.SetMetaFileMode(bMetaFile); + aOutputData.SetShowNullValues(bNullVal); + aOutputData.SetShowFormulas(bFormula); + + // #114135# + ScDrawLayer* pModel = pDoc->GetDrawLayer(); + FmFormView* pDrawView = NULL; + + if( pModel ) + { + pDrawView = new FmFormView( pModel, pDev ); + pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab)); + pDrawView->SetPrintPreview( sal_True ); + aOutputData.SetDrawView( pDrawView ); + } + + //! SetUseStyleColor ?? + + if ( bMetaFile && pDev->GetOutDevType() == OUTDEV_VIRDEV ) + aOutputData.SetSnapPixel(); + + Point aLogStart = pDev->PixelToLogic( Point(nScrX,nScrY), MAP_100TH_MM ); + long nLogStX = aLogStart.X(); + long nLogStY = aLogStart.Y(); + + //! nZoom fuer GetFont in OutputData ??? + + if (!bMetaFile && pViewData) + pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart())); + + // #i72502# + const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY)); + aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset); + + if (!bMetaFile && pViewData) + pDev->SetMapMode(aMode); + + aOutputData.DrawBackground(); + +#ifdef OS2 + if (bMetaFile && !bDoGrid) + { + // unter OS2 fuer Metafiles gesamte Flaeche benutzen, + // weil sonst die Groesse nicht erkannt wird + pDev->SetLineColor(); + pDev->SetFillColor(); + pDev->DrawRect( Rectangle( nScrX,nScrY, + nScrX+aOutputData.GetScrW(), nScrY+aOutputData.GetScrH() ) ); + } +#endif + + aOutputData.DrawShadow(); + aOutputData.DrawFrame(); + aOutputData.DrawStrings(); + + if (!bMetaFile && pViewData) + pDev->SetMapMode(pViewData->GetLogicMode(pViewData->GetActivePart())); + + aOutputData.DrawEdit(!bMetaFile); + + if (bDoGrid) + { + if (!bMetaFile && pViewData) + pDev->SetMapMode(aMode); + + aOutputData.DrawGrid( sal_True, false ); // keine Seitenumbrueche + + pDev->SetLineColor( COL_BLACK ); + + Size aOne = pDev->PixelToLogic( Size(1,1) ); + if (bMetaFile) + aOne = Size(1,1); // compatible with DrawGrid + long nRight = nScrX + aOutputData.GetScrW() - aOne.Width(); + long nBottom = nScrY + aOutputData.GetScrH() - aOne.Height(); + + sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); + + // extra line at the left edge for left-to-right, right for right-to-left + if ( bLayoutRTL ) + pDev->DrawLine( Point(nRight,nScrY), Point(nRight,nBottom) ); + else + pDev->DrawLine( Point(nScrX,nScrY), Point(nScrX,nBottom) ); + // extra line at the top in both cases + pDev->DrawLine( Point(nScrX,nScrY), Point(nRight,nScrY) ); + } + + // #i72502# + aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset); + aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset); + aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768# + + // #114135# + delete pDrawView; +} + +// +// Drucken +// + +void lcl_FillHFParam( ScPrintHFParam& rParam, const SfxItemSet* pHFSet ) +{ + // nDistance muss vorher unterschiedlich initalisiert sein + + if ( pHFSet == NULL ) + { + rParam.bEnable = false; + rParam.pBorder = NULL; + rParam.pBack = NULL; + rParam.pShadow = NULL; + } + else + { + rParam.bEnable = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_ON)).GetValue(); + rParam.bDynamic = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_DYNAMIC)).GetValue(); + rParam.bShared = ((const SfxBoolItem&) pHFSet->Get(ATTR_PAGE_SHARED)).GetValue(); + rParam.nHeight = ((const SvxSizeItem&) pHFSet->Get(ATTR_PAGE_SIZE)).GetSize().Height(); + const SvxLRSpaceItem* pHFLR = &(const SvxLRSpaceItem&) pHFSet->Get(ATTR_LRSPACE); + long nTmp; + nTmp = pHFLR->GetLeft(); + rParam.nLeft = nTmp < 0 ? 0 : sal_uInt16(nTmp); + nTmp = pHFLR->GetRight(); + rParam.nRight = nTmp < 0 ? 0 : sal_uInt16(nTmp); + rParam.pBorder = (const SvxBoxItem*) &pHFSet->Get(ATTR_BORDER); + rParam.pBack = (const SvxBrushItem*) &pHFSet->Get(ATTR_BACKGROUND); + rParam.pShadow = (const SvxShadowItem*)&pHFSet->Get(ATTR_SHADOW);; + +// jetzt doch wieder schon im Dialog: +// rParam.nHeight += rParam.nDistance; // nicht mehr im Dialog ??? + + if (rParam.pBorder) + rParam.nHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) + + lcl_LineTotal( rParam.pBorder->GetBottom() ); + + rParam.nManHeight = rParam.nHeight; + } + + if (!rParam.bEnable) + rParam.nHeight = 0; +} + +// bNew = TRUE: benutzten Bereich aus dem Dokument suchen +// bNew = FALSE: nur ganze Zeilen/Spalten begrenzen + +sal_Bool ScPrintFunc::AdjustPrintArea( sal_Bool bNew ) +{ + SCCOL nOldEndCol = nEndCol; // nur wichtig bei !bNew + SCROW nOldEndRow = nEndRow; + sal_Bool bChangeCol = sal_True; // bei bNew werden beide angepasst + sal_Bool bChangeRow = sal_True; + + sal_Bool bNotes = aTableParam.bNotes; + if ( bNew ) + { + nStartCol = 0; + nStartRow = 0; + if (!pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes )) + return false; // nix + } + else + { + sal_Bool bFound = sal_True; + bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL ); + bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW ); + sal_Bool bForcedChangeRow = false; + + // #i53558# Crop entire column of old row limit to real print area with + // some fuzzyness. + if (!bChangeRow && nStartRow == 0) + { + SCROW nPAEndRow; + bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nPAEndRow, bNotes ); + // Say we don't want to print more than ~1000 empty rows, which are + // about 14 pages intentionally left blank.. + const SCROW nFuzzy = 23*42; + if (nPAEndRow + nFuzzy < nEndRow) + { + bForcedChangeRow = sal_True; + nEndRow = nPAEndRow; + } + else + bFound = sal_True; // user seems to _want_ to print some empty rows + } + // TODO: in case we extend the number of columns we may have to do the + // same for horizontal cropping. + + if ( bChangeCol && bChangeRow ) + bFound = pDoc->GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ); + else if ( bChangeCol ) + bFound = pDoc->GetPrintAreaHor( nPrintTab, nStartRow, nEndRow, nEndCol, bNotes ); + else if ( bChangeRow ) + bFound = pDoc->GetPrintAreaVer( nPrintTab, nStartCol, nEndCol, nEndRow, bNotes ); + + if (!bFound) + return false; // leer + + if (bForcedChangeRow) + bChangeRow = sal_True; + } + + pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab, + false, sal_True ); // kein Refresh, incl. Attrs + + if ( bChangeCol ) + { + OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen + pRefDev->SetMapMode( MAP_PIXEL ); // wichtig fuer GetNeededSize + + pDoc->ExtendPrintArea( pRefDev, + nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow ); + // nEndCol wird veraendert + } + + if ( nEndCol < MAXCOL && pDoc->HasAttrib( + nEndCol,nStartRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_RIGHT ) ) + ++nEndCol; + if ( nEndRow < MAXROW && pDoc->HasAttrib( + nStartCol,nEndRow,nPrintTab, nEndCol,nEndRow,nPrintTab, HASATTR_SHADOW_DOWN ) ) + ++nEndRow; + + if (!bChangeCol) nEndCol = nOldEndCol; + if (!bChangeRow) nEndRow = nOldEndRow; + + return sal_True; +} + +long ScPrintFunc::TextHeight( const EditTextObject* pObject ) +{ + if (!pObject) + return 0; + + pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false ); + + return (long) pEditEngine->GetTextHeight(); +} + +// nZoom muss gesetzt sein !!! +// und der entsprechende Twip-MapMode eingestellt + +void ScPrintFunc::UpdateHFHeight( ScPrintHFParam& rParam ) +{ + DBG_ASSERT( aPageSize.Width(), "UpdateHFHeight ohne aPageSize"); + + if (rParam.bEnable && rParam.bDynamic) + { + // nHeight aus Inhalten berechnen + + MakeEditEngine(); + long nPaperWidth = ( aPageSize.Width() - nLeftMargin - nRightMargin - + rParam.nLeft - rParam.nRight ) * 100 / nZoom; + if (rParam.pBorder) + nPaperWidth -= ( rParam.pBorder->GetDistance(BOX_LINE_LEFT) + + rParam.pBorder->GetDistance(BOX_LINE_RIGHT) + + lcl_LineTotal(rParam.pBorder->GetLeft()) + + lcl_LineTotal(rParam.pBorder->GetRight()) ) * 100 / nZoom; + + if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE) + nPaperWidth -= ( rParam.pShadow->CalcShadowSpace(SHADOW_LEFT) + + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT) ) * 100L / nZoom; + + pEditEngine->SetPaperSize( Size( nPaperWidth, 10000 ) ); + + long nMaxHeight = 0; + if ( rParam.pLeft ) + { + nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetLeftArea() ) ); + nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetCenterArea() ) ); + nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pLeft->GetRightArea() ) ); + } + if ( rParam.pRight ) + { + nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetLeftArea() ) ); + nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetCenterArea() ) ); + nMaxHeight = Max( nMaxHeight, TextHeight( rParam.pRight->GetRightArea() ) ); + } + + rParam.nHeight = nMaxHeight + rParam.nDistance; + if (rParam.pBorder) + rParam.nHeight += rParam.pBorder->GetDistance(BOX_LINE_TOP) + + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM) + + lcl_LineTotal( rParam.pBorder->GetTop() ) + + lcl_LineTotal( rParam.pBorder->GetBottom() ); + if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE) + rParam.nHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) + + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM); + + if (rParam.nHeight < rParam.nManHeight) + rParam.nHeight = rParam.nManHeight; // eingestelltes Minimum + } +} + +void ScPrintFunc::InitParam( const ScPrintOptions* pOptions ) +{ + if (!pParamSet) + return; + + // TabPage "Seite" + const SvxLRSpaceItem* pLRItem = (const SvxLRSpaceItem*) &pParamSet->Get( ATTR_LRSPACE ); + long nTmp; + nTmp = pLRItem->GetLeft(); + nLeftMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp); + nTmp = pLRItem->GetRight(); + nRightMargin = nTmp < 0 ? 0 : sal_uInt16(nTmp); + const SvxULSpaceItem* pULItem = (const SvxULSpaceItem*) &pParamSet->Get( ATTR_ULSPACE ); + nTopMargin = pULItem->GetUpper(); + nBottomMargin = pULItem->GetLower(); + + const SvxPageItem* pPageItem = (const SvxPageItem*) &pParamSet->Get( ATTR_PAGE ); + nPageUsage = pPageItem->GetPageUsage(); + bLandscape = pPageItem->IsLandscape(); + aFieldData.eNumType = pPageItem->GetNumType(); + + bCenterHor = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_HORCENTER)).GetValue(); + bCenterVer = ((const SfxBoolItem&) pParamSet->Get(ATTR_PAGE_VERCENTER)).GetValue(); + + aPageSize = ((const SvxSizeItem&) pParamSet->Get(ATTR_PAGE_SIZE)).GetSize(); + if ( !aPageSize.Width() || !aPageSize.Height() ) + { + OSL_FAIL("PageSize Null ?!?!?"); + aPageSize = SvxPaperInfo::GetPaperSize( PAPER_A4 ); + } + + pBorderItem = (const SvxBoxItem*) &pParamSet->Get(ATTR_BORDER); + pBackgroundItem = (const SvxBrushItem*) &pParamSet->Get(ATTR_BACKGROUND); + pShadowItem = (const SvxShadowItem*) &pParamSet->Get(ATTR_SHADOW); + + // TabPage "Kopfzeile" + + aHdr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERLEFT); // Inhalt + aHdr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_HEADERRIGHT); + + const SvxSetItem* pHeaderSetItem; + const SfxItemSet* pHeaderSet = NULL; + if ( pParamSet->GetItemState( ATTR_PAGE_HEADERSET, false, + (const SfxPoolItem**)&pHeaderSetItem ) == SFX_ITEM_SET ) + { + pHeaderSet = &pHeaderSetItem->GetItemSet(); + // Kopfzeile hat unteren Abstand + aHdr.nDistance = ((const SvxULSpaceItem&) pHeaderSet->Get(ATTR_ULSPACE)).GetLower(); + } + lcl_FillHFParam( aHdr, pHeaderSet ); + + // TabPage "Fusszeile" + + aFtr.pLeft = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERLEFT); // Inhalt + aFtr.pRight = (const ScPageHFItem*) &pParamSet->Get(ATTR_PAGE_FOOTERRIGHT); + + const SvxSetItem* pFooterSetItem; + const SfxItemSet* pFooterSet = NULL; + if ( pParamSet->GetItemState( ATTR_PAGE_FOOTERSET, false, + (const SfxPoolItem**)&pFooterSetItem ) == SFX_ITEM_SET ) + { + pFooterSet = &pFooterSetItem->GetItemSet(); + // Fusszeile hat oberen Abstand + aFtr.nDistance = ((const SvxULSpaceItem&) pFooterSet->Get(ATTR_ULSPACE)).GetUpper(); + } + lcl_FillHFParam( aFtr, pFooterSet ); + + //------------------------------------------------------ + // Table-/Area-Params aus einzelnen Items zusammenbauen: + //------------------------------------------------------ + // TabPage "Tabelle" + + const SfxUInt16Item* pScaleItem = NULL; + const ScPageScaleToItem* pScaleToItem = NULL; + const SfxUInt16Item* pScaleToPagesItem = NULL; + SfxItemState eState; + + eState = pParamSet->GetItemState( ATTR_PAGE_SCALE, false, + (const SfxPoolItem**)&pScaleItem ); + if ( SFX_ITEM_DEFAULT == eState ) + pScaleItem = (const SfxUInt16Item*) + &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE ); + + eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, false, + (const SfxPoolItem**)&pScaleToItem ); + if ( SFX_ITEM_DEFAULT == eState ) + pScaleToItem = (const ScPageScaleToItem*) + &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO ); + + eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, false, + (const SfxPoolItem**)&pScaleToPagesItem ); + if ( SFX_ITEM_DEFAULT == eState ) + pScaleToPagesItem = (const SfxUInt16Item*) + &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETOPAGES ); + + DBG_ASSERT( pScaleItem && pScaleToItem && pScaleToPagesItem, "Missing ScaleItem! :-/" ); + + aTableParam.bCellContent = sal_True; + aTableParam.bNotes = GET_BOOL(pParamSet,ATTR_PAGE_NOTES); + aTableParam.bGrid = GET_BOOL(pParamSet,ATTR_PAGE_GRID); + aTableParam.bHeaders = GET_BOOL(pParamSet,ATTR_PAGE_HEADERS); + aTableParam.bFormulas = GET_BOOL(pParamSet,ATTR_PAGE_FORMULAS); + aTableParam.bNullVals = GET_BOOL(pParamSet,ATTR_PAGE_NULLVALS); + aTableParam.bCharts = GET_SHOW(pParamSet,ATTR_PAGE_CHARTS); + aTableParam.bObjects = GET_SHOW(pParamSet,ATTR_PAGE_OBJECTS); + aTableParam.bDrawings = GET_SHOW(pParamSet,ATTR_PAGE_DRAWINGS); + aTableParam.bTopDown = GET_BOOL(pParamSet,ATTR_PAGE_TOPDOWN); + aTableParam.bLeftRight = !aTableParam.bLeftRight; + aTableParam.nFirstPageNo = GET_USHORT(pParamSet,ATTR_PAGE_FIRSTPAGENO); + if (!aTableParam.nFirstPageNo) + aTableParam.nFirstPageNo = (sal_uInt16) nPageStart; // von vorheriger Tabelle + + if ( pScaleItem && pScaleToItem && pScaleToPagesItem ) + { + sal_uInt16 nScaleAll = pScaleItem->GetValue(); + sal_uInt16 nScaleToPages = pScaleToPagesItem->GetValue(); + + aTableParam.bScaleNone = (nScaleAll == 100); + aTableParam.bScaleAll = (nScaleAll > 0 ); + aTableParam.bScaleTo = pScaleToItem->IsValid(); + aTableParam.bScalePageNum = (nScaleToPages > 0 ); + aTableParam.nScaleAll = nScaleAll; + aTableParam.nScaleWidth = pScaleToItem->GetWidth(); + aTableParam.nScaleHeight = pScaleToItem->GetHeight(); + aTableParam.nScalePageNum = nScaleToPages; + } + else + { + aTableParam.bScaleNone = sal_True; + aTableParam.bScaleAll = false; + aTableParam.bScaleTo = false; + aTableParam.bScalePageNum = false; + aTableParam.nScaleAll = 0; + aTableParam.nScaleWidth = 0; + aTableParam.nScaleHeight = 0; + aTableParam.nScalePageNum = 0; + } + + // skip empty pages only if options with that flag are passed + aTableParam.bSkipEmpty = pOptions && pOptions->GetSkipEmpty(); + if ( pPageData ) + aTableParam.bSkipEmpty = false; + // Wenn pPageData gesetzt ist, interessieren fuer die Umbruch-Vorschau + // nur die Umbrueche, leere Seiten werden nicht speziell behandelt + + //------------------------------------------------------ + // TabPage "Bereiche": + //------------------------------------------------------ + + //! alle PrintAreas der Tabelle durchgehen !!! + const ScRange* pPrintArea = pDoc->GetPrintRange( nPrintTab, 0 ); + const ScRange* pRepeatCol = pDoc->GetRepeatColRange( nPrintTab ); + const ScRange* pRepeatRow = pDoc->GetRepeatRowRange( nPrintTab ); + + // ATTR_PAGE_PRINTTABLES wird ignoriert + + if ( pUserArea ) // UserArea (Selektion) hat Vorrang + { + bPrintCurrentTable = + aAreaParam.bPrintArea = sal_True; // Selektion + aAreaParam.aPrintArea = *pUserArea; + + // Die Tabellen-Abfrage ist schon in DocShell::Print, hier immer + aAreaParam.aPrintArea.aStart.SetTab(nPrintTab); + aAreaParam.aPrintArea.aEnd.SetTab(nPrintTab); + } + else if ( pDoc->HasPrintRange() ) + { + if ( pPrintArea ) // mindestens eine gesetzt ? + { + bPrintCurrentTable = + aAreaParam.bPrintArea = sal_True; + aAreaParam.aPrintArea = *pPrintArea; + + bMultiArea = ( pDoc->GetPrintRangeCount(nPrintTab) > 1 ); + } + else + { + // do not print hidden sheets with "Print entire sheet" flag + bPrintCurrentTable = pDoc->IsPrintEntireSheet( nPrintTab ) && pDoc->IsVisible( nPrintTab ); + aAreaParam.bPrintArea = !bPrintCurrentTable; // otherwise the table is always counted + } + } + else + { + // don't print hidden tables if there's no print range defined there + if ( pDoc->IsVisible( nPrintTab ) ) + { + aAreaParam.bPrintArea = false; + bPrintCurrentTable = sal_True; + } + else + { + aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted + bPrintCurrentTable = false; + } + } + + if ( pRepeatCol ) + { + aAreaParam.bRepeatCol = sal_True; + aAreaParam.aRepeatCol = *pRepeatCol; + nRepeatStartCol = pRepeatCol->aStart.Col(); + nRepeatEndCol = pRepeatCol->aEnd .Col(); + } + else + { + aAreaParam.bRepeatCol = false; + nRepeatStartCol = nRepeatEndCol = SCCOL_REPEAT_NONE; + } + + if ( pRepeatRow ) + { + aAreaParam.bRepeatRow = sal_True; + aAreaParam.aRepeatRow = *pRepeatRow; + nRepeatStartRow = pRepeatRow->aStart.Row(); + nRepeatEndRow = pRepeatRow->aEnd .Row(); + } + else + { + aAreaParam.bRepeatRow = false; + nRepeatStartRow = nRepeatEndRow = SCROW_REPEAT_NONE; + } + + // + // Seiten aufteilen + // + + if (!bState) + { + nTabPages = CountPages(); // berechnet auch Zoom + nTotalPages = nTabPages; + nTotalPages += CountNotePages(); + } + else + { + CalcPages(); // nur Umbrueche suchen + CountNotePages(); // Notizen zaehlen, auch wenn Seitenzahl schon bekannt + } + + if (nDocPages) + aFieldData.nTotalPages = nDocPages; + else + aFieldData.nTotalPages = nTotalPages; + + SetDateTime( Date(), Time() ); + + aFieldData.aTitle = pDocShell->GetTitle(); + const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject(); + aFieldData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ); + if ( aFieldData.aLongDocName.Len() ) + aFieldData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS ); + else + aFieldData.aShortDocName = aFieldData.aLongDocName = aFieldData.aTitle; + + // Druckereinstellungen (Orientation, Paper) jetzt erst bei DoPrint +} + +Size ScPrintFunc::GetDataSize() const +{ + Size aSize = aPageSize; + aSize.Width() -= nLeftMargin + nRightMargin; + aSize.Height() -= nTopMargin + nBottomMargin; + aSize.Height() -= aHdr.nHeight + aFtr.nHeight; + return aSize; +} + +void ScPrintFunc::GetScaleData( Size& rPhysSize, long& rDocHdr, long& rDocFtr ) +{ + rPhysSize = aPageSize; + rPhysSize.Width() -= nLeftMargin + nRightMargin; + rPhysSize.Height() -= nTopMargin + nBottomMargin; + + rDocHdr = aHdr.nHeight; + rDocFtr = aFtr.nHeight; +} + +void ScPrintFunc::SetDateTime( const Date& rDate, const Time& rTime ) +{ + aFieldData.aDate = rDate; + aFieldData.aTime = rTime; +} + +void lcl_DrawGraphic( const Graphic &rGraphic, OutputDevice *pOut, + const Rectangle &rGrf, const Rectangle &rOut ) +{ + const bool bNotInside = !rOut.IsInside( rGrf ); + if ( bNotInside ) + { + pOut->Push(); + pOut->IntersectClipRegion( rOut ); + } + + ((Graphic&)rGraphic).Draw( pOut, rGrf.TopLeft(), rGrf.GetSize() ); + + if ( bNotInside ) + pOut->Pop(); +} + +void lcl_DrawGraphic( const SvxBrushItem &rBrush, OutputDevice *pOut, OutputDevice* pRefDev, + const Rectangle &rOrg, const Rectangle &rOut ) +{ + Size aGrfSize(0,0); + const Graphic *pGraphic = rBrush.GetGraphic(); + SvxGraphicPosition ePos; + if ( pGraphic && pGraphic->IsSupportedGraphic() ) + { + const MapMode aMapMM( MAP_100TH_MM ); + if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL ) + aGrfSize = pRefDev->PixelToLogic( pGraphic->GetPrefSize(), aMapMM ); + else + aGrfSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(), + pGraphic->GetPrefMapMode(), aMapMM ); + ePos = rBrush.GetGraphicPos(); + } + else + ePos = GPOS_NONE; + + Point aPos; + Size aDrawSize = aGrfSize; + + bool bDraw = true; + switch ( ePos ) + { + case GPOS_LT: aPos = rOrg.TopLeft(); + break; + case GPOS_MT: aPos.Y() = rOrg.Top(); + aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2; + break; + case GPOS_RT: aPos.Y() = rOrg.Top(); + aPos.X() = rOrg.Right() - aGrfSize.Width(); + break; + + case GPOS_LM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2; + aPos.X() = rOrg.Left(); + break; + case GPOS_MM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2; + aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2; + break; + case GPOS_RM: aPos.Y() = rOrg.Top() + rOrg.GetSize().Height()/2 - aGrfSize.Height()/2; + aPos.X() = rOrg.Right() - aGrfSize.Width(); + break; + + case GPOS_LB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height(); + aPos.X() = rOrg.Left(); + break; + case GPOS_MB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height(); + aPos.X() = rOrg.Left() + rOrg.GetSize().Width()/2 - aGrfSize.Width()/2; + break; + case GPOS_RB: aPos.Y() = rOrg.Bottom() - aGrfSize.Height(); + aPos.X() = rOrg.Right() - aGrfSize.Width(); + break; + + case GPOS_AREA: + aPos = rOrg.TopLeft(); + aDrawSize = rOrg.GetSize(); + break; + case GPOS_TILED: + { + // use GraphicObject::DrawTiled instead of an own loop + // (pixel rounding is handled correctly, and a very small bitmap + // is duplicated into a bigger one for better performance) + + GraphicObject aObject( *pGraphic ); + + if( pOut->GetPDFWriter() && + (aObject.GetType() == GRAPHIC_BITMAP || aObject.GetType() == GRAPHIC_DEFAULT) ) + { + // For PDF export, every draw + // operation for bitmaps takes a noticeable + // amount of place (~50 characters). Thus, + // optimize between tile bitmap size and + // number of drawing operations here. + // + // A_out + // n_chars = k1 * ---------- + k2 * A_bitmap + // A_bitmap + // + // minimum n_chars is obtained for (derive for + // A_bitmap, set to 0, take positive + // solution): + // k1 + // A_bitmap = Sqrt( ---- A_out ) + // k2 + // + // where k1 is the number of chars per draw + // operation, and k2 is the number of chars + // per bitmap pixel. This is approximately 50 + // and 7 for current PDF writer, respectively. + // + const double k1( 50 ); + const double k2( 7 ); + const Size aSize( rOrg.GetSize() ); + const double Abitmap( k1/k2 * aSize.Width()*aSize.Height() ); + + aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0), + NULL, GRFMGR_DRAW_STANDARD, + ::std::max( 128, static_cast<int>( sqrt(sqrt( Abitmap)) + .5 ) ) ); + } + else + { + aObject.DrawTiled( pOut, rOrg, aGrfSize, Size(0,0) ); + } + + bDraw = false; + } + break; + + case GPOS_NONE: + bDraw = false; + break; + + default: DBG_ASSERT( !pOut, "new Graphic position?" ); + } + Rectangle aGrf( aPos,aDrawSize ); + if ( bDraw && aGrf.IsOver( rOut ) ) + { + lcl_DrawGraphic( *pGraphic, pOut, aGrf, rOut ); + } +} + +// Rahmen wird nach innen gezeichnet + +void ScPrintFunc::DrawBorder( long nScrX, long nScrY, long nScrW, long nScrH, + const SvxBoxItem* pBorderData, const SvxBrushItem* pBackground, + const SvxShadowItem* pShadow ) +{ + //! direkte Ausgabe aus SvxBoxItem !!! + + if (pBorderData) + if ( !pBorderData->GetTop() && !pBorderData->GetBottom() && !pBorderData->GetLeft() && + !pBorderData->GetRight() ) + pBorderData = NULL; + + if (!pBorderData && !pBackground && !pShadow) + return; // nichts zu tun + + long nLeft = 0; + long nRight = 0; + long nTop = 0; + long nBottom = 0; + + // aFrameRect - aussen um die Umrandung, ohne Schatten + if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE ) + { + nLeft += (long) ( pShadow->CalcShadowSpace(SHADOW_LEFT) * nScaleX ); + nRight += (long) ( pShadow->CalcShadowSpace(SHADOW_RIGHT) * nScaleX ); + nTop += (long) ( pShadow->CalcShadowSpace(SHADOW_TOP) * nScaleY ); + nBottom += (long) ( pShadow->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY ); + } + Rectangle aFrameRect( Point(nScrX+nLeft, nScrY+nTop), + Size(nScrW-nLeft-nRight, nScrH-nTop-nBottom) ); + + // Mitte der Umrandung, um Linien ueber OutputData zu zeichnen: + if (pBorderData) + { + nLeft += (long) ( lcl_LineTotal(pBorderData->GetLeft()) * nScaleX / 2 ); + nRight += (long) ( lcl_LineTotal(pBorderData->GetRight()) * nScaleX / 2 ); + nTop += (long) ( lcl_LineTotal(pBorderData->GetTop()) * nScaleY / 2 ); + nBottom += (long) ( lcl_LineTotal(pBorderData->GetBottom()) * nScaleY / 2 ); + } + long nEffHeight = nScrH - nTop - nBottom; + long nEffWidth = nScrW - nLeft - nRight; + if (nEffHeight<=0 || nEffWidth<=0) + return; // leer + + // SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed TRUE) + sal_Bool bCellContrast = bUseStyleColor; + + if ( pBackground && !bCellContrast ) + { + if (pBackground->GetGraphicPos() != GPOS_NONE) + { + OutputDevice* pRefDev; + if ( bIsRender ) + pRefDev = pDev; // don't use printer for PDF + else + pRefDev = pDoc->GetPrinter(); // use printer also for preview + + lcl_DrawGraphic( *pBackground, pDev, pRefDev, aFrameRect, aFrameRect ); + } + else + { + pDev->SetFillColor(pBackground->GetColor()); + pDev->SetLineColor(); + pDev->DrawRect(aFrameRect); + } + } + + if ( pShadow && pShadow->GetLocation() != SVX_SHADOW_NONE ) + { + if ( bCellContrast ) + pDev->SetFillColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); + else + pDev->SetFillColor(pShadow->GetColor()); + pDev->SetLineColor(); + long nShadowX = (long) ( pShadow->GetWidth() * nScaleX ); + long nShadowY = (long) ( pShadow->GetWidth() * nScaleY ); + switch (pShadow->GetLocation()) + { + case SVX_SHADOW_TOPLEFT: + pDev->DrawRect( Rectangle( + aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY, + aFrameRect.Right()-nShadowX, aFrameRect.Top() ) ); + pDev->DrawRect( Rectangle( + aFrameRect.Left()-nShadowX, aFrameRect.Top()-nShadowY, + aFrameRect.Left(), aFrameRect.Bottom()-nShadowY ) ); + break; + case SVX_SHADOW_TOPRIGHT: + pDev->DrawRect( Rectangle( + aFrameRect.Left()+nShadowX, aFrameRect.Top()-nShadowY, + aFrameRect.Right()+nShadowX, aFrameRect.Top() ) ); + pDev->DrawRect( Rectangle( + aFrameRect.Right(), aFrameRect.Top()-nShadowY, + aFrameRect.Right()+nShadowX, aFrameRect.Bottom()-nShadowY ) ); + break; + case SVX_SHADOW_BOTTOMLEFT: + pDev->DrawRect( Rectangle( + aFrameRect.Left()-nShadowX, aFrameRect.Bottom(), + aFrameRect.Right()-nShadowX, aFrameRect.Bottom()+nShadowY ) ); + pDev->DrawRect( Rectangle( + aFrameRect.Left()-nShadowX, aFrameRect.Top()+nShadowY, + aFrameRect.Left(), aFrameRect.Bottom()+nShadowY ) ); + break; + case SVX_SHADOW_BOTTOMRIGHT: + pDev->DrawRect( Rectangle( + aFrameRect.Left()+nShadowX, aFrameRect.Bottom(), + aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) ); + pDev->DrawRect( Rectangle( + aFrameRect.Right(), aFrameRect.Top()+nShadowY, + aFrameRect.Right()+nShadowX, aFrameRect.Bottom()+nShadowY ) ); + break; + default: + { + // added to avoid warnings + } + } + } + + if (pBorderData) + { + ScDocument* pBorderDoc = new ScDocument( SCDOCMODE_UNDO ); + pBorderDoc->InitUndo( pDoc, 0,0, sal_True,sal_True ); + if (pBorderData) + pBorderDoc->ApplyAttr( 0,0,0, *pBorderData ); + + ScTableInfo aTabInfo; + pBorderDoc->FillInfo( aTabInfo, 0,0, 0,0, 0, + nScaleX, nScaleY, false, false ); + DBG_ASSERT(aTabInfo.mnArrCount,"nArrCount == 0"); + + aTabInfo.mpRowInfo[1].nHeight = (sal_uInt16) nEffHeight; + aTabInfo.mpRowInfo[0].pCellInfo[1].nWidth = + aTabInfo.mpRowInfo[1].pCellInfo[1].nWidth = (sal_uInt16) nEffWidth; + + ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pBorderDoc, 0, + nScrX+nLeft, nScrY+nTop, 0,0, 0,0, nScaleX, nScaleY ); + aOutputData.SetUseStyleColor( bUseStyleColor ); + + if (pBorderData) + aOutputData.DrawFrame(); + + delete pBorderDoc; + } +} + +void ScPrintFunc::PrintColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY ) +{ + sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); + long nLayoutSign = bLayoutRTL ? -1 : 1; + + Size aOnePixel = pDev->PixelToLogic(Size(1,1)); + long nOneX = aOnePixel.Width(); + long nOneY = aOnePixel.Height(); + SCCOL nCol; + + long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY); + long nEndY = nScrY + nHeight - nOneY; + + long nPosX = nScrX; + if ( bLayoutRTL ) + { + for (nCol=nX1; nCol<=nX2; nCol++) + nPosX += (long)( pDoc->GetColWidth( nCol, nPrintTab ) * nScaleX ); + } + else + nPosX -= nOneX; + long nPosY = nScrY - nOneY; + String aText; + + for (nCol=nX1; nCol<=nX2; nCol++) + { + sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab ); + if (nDocW) + { + long nWidth = (long) (nDocW * nScaleX); + long nEndX = nPosX + nWidth * nLayoutSign; + + pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) ); + + aText = ::ScColToAlpha( nCol); + long nTextWidth = pDev->GetTextWidth(aText); + long nTextHeight = pDev->GetTextHeight(); + long nAddX = ( nWidth - nTextWidth ) / 2; + long nAddY = ( nHeight - nTextHeight ) / 2; + long nTextPosX = nPosX+nAddX; + if ( bLayoutRTL ) + nTextPosX -= nWidth; + pDev->DrawText( Point( nTextPosX,nPosY+nAddY ), aText ); + + nPosX = nEndX; + } + } +} + +void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY ) +{ + Size aOnePixel = pDev->PixelToLogic(Size(1,1)); + long nOneX = aOnePixel.Width(); + long nOneY = aOnePixel.Height(); + + sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); + + long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX); + long nEndX = nScrX + nWidth; + long nPosX = nScrX; + if ( !bLayoutRTL ) + { + nEndX -= nOneX; + nPosX -= nOneX; + } + long nPosY = nScrY - nOneY; + String aText; + + for (SCROW nRow=nY1; nRow<=nY2; nRow++) + { + sal_uInt16 nDocH = pDoc->GetRowHeight( nRow, nPrintTab ); + if (nDocH) + { + long nHeight = (long) (nDocH * nScaleY); + long nEndY = nPosY + nHeight; + + pDev->DrawRect( Rectangle( nPosX,nPosY,nEndX,nEndY ) ); + + aText = String::CreateFromInt32( nRow+1 ); + long nTextWidth = pDev->GetTextWidth(aText); + long nTextHeight = pDev->GetTextHeight(); + long nAddX = ( nWidth - nTextWidth ) / 2; + long nAddY = ( nHeight - nTextHeight ) / 2; + pDev->DrawText( Point( nPosX+nAddX,nPosY+nAddY ), aText ); + + nPosY = nEndY; + } + } +} + +void ScPrintFunc::LocateColHdr( SCCOL nX1, SCCOL nX2, long nScrX, long nScrY, + sal_Bool bRepCol, ScPreviewLocationData& rLocationData ) +{ + Size aOnePixel = pDev->PixelToLogic(Size(1,1)); + long nOneX = aOnePixel.Width(); + long nOneY = aOnePixel.Height(); + + long nHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY); + long nEndY = nScrY + nHeight - nOneY; + + long nPosX = nScrX - nOneX; + for (SCCOL nCol=nX1; nCol<=nX2; nCol++) + { + sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab ); + if (nDocW) + nPosX += (long) (nDocW * nScaleX); + } + Rectangle aCellRect( nScrX, nScrY, nPosX, nEndY ); + rLocationData.AddColHeaders( aCellRect, nX1, nX2, bRepCol ); +} + +void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY, + sal_Bool bRepRow, ScPreviewLocationData& rLocationData ) +{ + Size aOnePixel = pDev->PixelToLogic(Size(1,1)); + long nOneX = aOnePixel.Width(); + long nOneY = aOnePixel.Height(); + + sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); + + long nWidth = (long) (PRINT_HEADER_WIDTH * nScaleX); + long nEndX = nScrX + nWidth; + if ( !bLayoutRTL ) + nEndX -= nOneX; + + long nPosY = nScrY - nOneY; + nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); + Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY ); + rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow ); +} + +void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, + long nScrX, long nScrY, sal_Bool bRepCol, sal_Bool bRepRow, + ScPreviewLocationData& rLocationData ) +{ + // get MapMode for drawing objects (same MapMode as in ScOutputData::PrintDrawingLayer) + + Point aLogPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode); + long nLogStX = aLogPos.X(); + long nLogStY = aLogPos.Y(); + + SCCOL nCol; + Point aTwipOffset; + for (nCol=0; nCol<nX1; nCol++) + aTwipOffset.X() -= pDoc->GetColWidth( nCol, nPrintTab ); + aTwipOffset.Y() -= pDoc->GetRowHeight( 0, nY1-1, nPrintTab ); + + Point aMMOffset( aTwipOffset ); + aMMOffset.X() = (long)(aMMOffset.X() * HMM_PER_TWIPS); + aMMOffset.Y() = (long)(aMMOffset.Y() * HMM_PER_TWIPS); + aMMOffset += Point( nLogStX, nLogStY ); + MapMode aDrawMapMode( MAP_100TH_MM, aMMOffset, aLogicMode.GetScaleX(), aLogicMode.GetScaleY() ); + + // get pixel rectangle + + Size aOnePixel = pDev->PixelToLogic(Size(1,1)); + long nOneX = aOnePixel.Width(); + long nOneY = aOnePixel.Height(); + + long nPosX = nScrX - nOneX; + for (nCol=nX1; nCol<=nX2; nCol++) + { + sal_uInt16 nDocW = pDoc->GetColWidth( nCol, nPrintTab ); + if (nDocW) + nPosX += (long) (nDocW * nScaleX); + } + + long nPosY = nScrY - nOneY; + nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); + Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY ); + rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ), + bRepCol, bRepRow, aDrawMapMode ); +} + +void ScPrintFunc::PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, + long nScrX, long nScrY, + sal_Bool bShLeft, sal_Bool bShTop, sal_Bool bShRight, sal_Bool bShBottom ) +{ + // #i47547# nothing to do if the end of the print area is before the end of + // the repeat columns/rows (don't use negative size for ScOutputData) + if ( nX2 < nX1 || nY2 < nY1 ) + return; + + //! Flag bei FillInfo uebergeben !!!!! + ScRange aERange; + sal_Bool bEmbed = pDoc->IsEmbedded(); + if (bEmbed) + { + pDoc->GetEmbedded(aERange); + pDoc->ResetEmbedded(); + } + + Point aPos = OutputDevice::LogicToLogic(Point(nScrX,nScrY), aOffsetMode, aLogicMode); + long nLogStX = aPos.X(); + long nLogStY = aPos.Y(); + + // Daten zusammenstellen + + ScTableInfo aTabInfo; + pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nPrintTab, + nScaleX, nScaleY, sal_True, aTableParam.bFormulas ); + lcl_HidePrint( aTabInfo, nX1, nX2 ); + + if (bEmbed) + pDoc->SetEmbedded(aERange); + + ScOutputData aOutputData( pDev, OUTTYPE_PRINTER, aTabInfo, pDoc, nPrintTab, + nScrX, nScrY, nX1, nY1, nX2, nY2, nScaleX, nScaleY ); + + // #114135# + aOutputData.SetDrawView( pDrawView ); + + // test if all paint parts are hidden, then a paint is not necessary at all + const Point aMMOffset(aOutputData.PrePrintDrawingLayer(nLogStX, nLogStY)); + const bool bHideAllDrawingLayer( pDrawView && pDrawView->getHideOle() && pDrawView->getHideChart() + && pDrawView->getHideDraw() && pDrawView->getHideFormControl() ); + + if(!bHideAllDrawingLayer) + { + pDev->SetMapMode(aLogicMode); + // hier kein Clipping setzen (Mapmode wird verschoben) + + // #i72502# + aOutputData.PrintDrawingLayer(SC_LAYER_BACK, aMMOffset); + } + + pDev->SetMapMode(aOffsetMode); + + aOutputData.SetShowFormulas( aTableParam.bFormulas ); + aOutputData.SetShowNullValues( aTableParam.bNullVals ); + aOutputData.SetUseStyleColor( bUseStyleColor ); + + Color aGridColor( COL_BLACK ); + if ( bUseStyleColor ) + aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); + aOutputData.SetGridColor( aGridColor ); + + if ( !pPrinter ) + { + OutputDevice* pRefDev = pDoc->GetPrinter(); // auch fuer Preview den Drucker nehmen + Fraction aPrintFrac( nZoom, 100 ); // ohne nManualZoom + // MapMode, wie er beim Drucken herauskommen wuerde: + pRefDev->SetMapMode( MapMode( MAP_100TH_MM, Point(), aPrintFrac, aPrintFrac ) ); + + // when rendering (PDF), don't use printer as ref device, but printer's MapMode + // has to be set anyway, as charts still use it (#106409#) + if ( !bIsRender ) + aOutputData.SetRefDevice( pRefDev ); + } + + if( aTableParam.bCellContent ) + aOutputData.DrawBackground(); + + pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ); + pDev->SetClipRegion(); + + if( aTableParam.bCellContent ) + { + aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom ); + aOutputData.DrawFrame(); + aOutputData.DrawStrings(); + aOutputData.DrawEdit(false); + } + + if (aTableParam.bGrid) + aOutputData.DrawGrid( sal_True, false ); // keine Seitenumbrueche + + aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled + + // test if all paint parts are hidden, then a paint is not necessary at all + if(!bHideAllDrawingLayer) + { + // #i72502# + aOutputData.PrintDrawingLayer(SC_LAYER_FRONT, aMMOffset); + } + + // #i72502# + aOutputData.PrintDrawingLayer(SC_LAYER_INTERN, aMMOffset); + aOutputData.PostPrintDrawingLayer(aMMOffset); // #i74768# +} + +sal_Bool ScPrintFunc::IsMirror( long nPageNo ) // Raender spiegeln ? +{ + SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f ); + return ( eUsage == SVX_PAGE_MIRROR && (nPageNo & 1) ); +} + +sal_Bool ScPrintFunc::IsLeft( long nPageNo ) // linke Fussnoten ? +{ + SvxPageUsage eUsage = (SvxPageUsage) ( nPageUsage & 0x000f ); + sal_Bool bLeft; + if (eUsage == SVX_PAGE_LEFT) + bLeft = sal_True; + else if (eUsage == SVX_PAGE_RIGHT) + bLeft = false; + else + bLeft = (nPageNo & 1) != 0; + return bLeft; +} + +void ScPrintFunc::MakeTableString() +{ + pDoc->GetName( nPrintTab, aFieldData.aTabName ); +} + +void ScPrintFunc::MakeEditEngine() +{ + if (!pEditEngine) + { + // can't use document's edit engine pool here, + // because pool must have twips as default metric + pEditEngine = new ScHeaderEditEngine( EditEngine::CreatePool(), sal_True ); + + pEditEngine->EnableUndo(false); + pEditEngine->SetRefDevice( pDev ); + pEditEngine->SetWordDelimiters( + ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); + pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS ); + pEditEngine->EnableAutoColor( bUseStyleColor ); + + // Default-Set fuer Ausrichtung + pEditDefaults = new SfxItemSet( pEditEngine->GetEmptyItemSet() ); + + const ScPatternAttr& rPattern = (const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN); + rPattern.FillEditItemSet( pEditDefaults ); + // FillEditItemSet adjusts font height to 1/100th mm, + // but for header/footer twips is needed, as in the PatternAttr: + pEditDefaults->Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT ); + pEditDefaults->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK ); + pEditDefaults->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL ); + // dont use font color, because background color is not used + //! there's no way to set the background for note pages + pEditDefaults->ClearItem( EE_CHAR_COLOR ); + if (ScGlobal::IsSystemRTL()) + pEditDefaults->Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) ); + } + + pEditEngine->SetData( aFieldData ); // Seitennummer etc. setzen +} + +// nStartY = logic +void ScPrintFunc::PrintHF( long nPageNo, sal_Bool bHeader, long nStartY, + sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) +{ + const ScPrintHFParam& rParam = bHeader ? aHdr : aFtr; + + pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips + + sal_Bool bLeft = IsLeft(nPageNo) && !rParam.bShared; + const ScPageHFItem* pHFItem = bLeft ? rParam.pLeft : rParam.pRight; + + long nLineStartX = aPageRect.Left() + rParam.nLeft; + long nLineEndX = aPageRect.Right() - rParam.nRight; + long nLineWidth = nLineEndX - nLineStartX + 1; + + // Edit-Engine + + Point aStart( nLineStartX, nStartY ); + Size aPaperSize( nLineWidth, rParam.nHeight-rParam.nDistance ); + if ( rParam.pBorder ) + { + long nLeft = lcl_LineTotal( rParam.pBorder->GetLeft() ) + rParam.pBorder->GetDistance(BOX_LINE_LEFT); + long nTop = lcl_LineTotal( rParam.pBorder->GetTop() ) + rParam.pBorder->GetDistance(BOX_LINE_TOP); + aStart.X() += nLeft; + aStart.Y() += nTop; + aPaperSize.Width() -= nLeft + lcl_LineTotal( rParam.pBorder->GetRight() ) + rParam.pBorder->GetDistance(BOX_LINE_RIGHT); + aPaperSize.Height() -= nTop + lcl_LineTotal( rParam.pBorder->GetBottom() ) + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM); + } + + if ( rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE ) + { + long nLeft = rParam.pShadow->CalcShadowSpace(SHADOW_LEFT); + long nTop = rParam.pShadow->CalcShadowSpace(SHADOW_TOP); + aStart.X() += nLeft; + aStart.Y() += nTop; + aPaperSize.Width() -= nLeft + rParam.pShadow->CalcShadowSpace(SHADOW_RIGHT); + aPaperSize.Height() -= nTop + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM); + } + + aFieldData.nPageNo = nPageNo+aTableParam.nFirstPageNo; + MakeEditEngine(); + + pEditEngine->SetPaperSize(aPaperSize); + const EditTextObject* pObject; + + // Rahmen / Hintergrund + + Point aBorderStart( nLineStartX, nStartY ); + Size aBorderSize( nLineWidth, rParam.nHeight-rParam.nDistance ); + if ( rParam.bDynamic ) + { + // hier nochmal anpassen, wegen geraden/ungeraden Kopf/Fusszeilen + // und evtl. anderen Umbruechen durch Variablen (Seitennummer etc.) + + long nMaxHeight = 0; + nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetLeftArea() ) ); + nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetCenterArea() ) ); + nMaxHeight = Max( nMaxHeight, TextHeight( pHFItem->GetRightArea() ) ); + if (rParam.pBorder) + nMaxHeight += lcl_LineTotal( rParam.pBorder->GetTop() ) + + lcl_LineTotal( rParam.pBorder->GetBottom() ) + + rParam.pBorder->GetDistance(BOX_LINE_TOP) + + rParam.pBorder->GetDistance(BOX_LINE_BOTTOM); + if (rParam.pShadow && rParam.pShadow->GetLocation() != SVX_SHADOW_NONE) + nMaxHeight += rParam.pShadow->CalcShadowSpace(SHADOW_TOP) + + rParam.pShadow->CalcShadowSpace(SHADOW_BOTTOM); + + if (nMaxHeight < rParam.nManHeight-rParam.nDistance) + nMaxHeight = rParam.nManHeight-rParam.nDistance; // eingestelltes Minimum + + aBorderSize.Height() = nMaxHeight; + } + + if ( bDoPrint ) + { + double nOldScaleX = nScaleX; + double nOldScaleY = nScaleY; + nScaleX = nScaleY = 1.0; // direkt in Twips ausgeben + DrawBorder( aBorderStart.X(), aBorderStart.Y(), aBorderSize.Width(), aBorderSize.Height(), + rParam.pBorder, rParam.pBack, rParam.pShadow ); + nScaleX = nOldScaleX; + nScaleY = nOldScaleY; + + // Clipping fuer Text + + pDev->SetClipRegion( Rectangle( aStart, aPaperSize ) ); + + // links + + pObject = pHFItem->GetLeftArea(); + if (pObject) + { + pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) ); + pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false ); + Point aDraw = aStart; + long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight(); + if (nDif > 0) + aDraw.Y() += nDif / 2; + pEditEngine->Draw( pDev, aDraw, 0 ); + } + + // Mitte + + pObject = pHFItem->GetCenterArea(); + if (pObject) + { + pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) ); + pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false ); + Point aDraw = aStart; + long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight(); + if (nDif > 0) + aDraw.Y() += nDif / 2; + pEditEngine->Draw( pDev, aDraw, 0 ); + } + + // rechts + + pObject = pHFItem->GetRightArea(); + if (pObject) + { + pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); + pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, false ); + Point aDraw = aStart; + long nDif = aPaperSize.Height() - (long) pEditEngine->GetTextHeight(); + if (nDif > 0) + aDraw.Y() += nDif / 2; + pEditEngine->Draw( pDev, aDraw, 0 ); + } + + pDev->SetClipRegion(); + } + + if ( pLocationData ) + { + Rectangle aHeaderRect( aBorderStart, aBorderSize ); + pLocationData->AddHeaderFooter( aHeaderRect, bHeader, bLeft ); + } +} + +long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) +{ + if (bDoPrint) + pDev->SetMapMode(aTwipMode); + + MakeEditEngine(); + pEditDefaults->Put( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) ); + pEditEngine->SetDefaults( *pEditDefaults ); + + Font aMarkFont; + ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT; + ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).GetFont( aMarkFont, eColorMode ); + pDev->SetFont( aMarkFont ); + long nMarkLen = pDev->GetTextWidth( + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:"))); + // ohne Space, weil's eh selten so weit kommt + + Size aDataSize = aPageRect.GetSize(); + if ( nMarkLen > aDataSize.Width() / 2 ) // alles viel zu klein? + nMarkLen = aDataSize.Width() / 2; // Seite bruederlich aufteilen + aDataSize.Width() -= nMarkLen; + + pEditEngine->SetPaperSize( aDataSize ); + long nPosX = aPageRect.Left() + nMarkLen; + long nPosY = aPageRect.Top(); + + long nCount = 0; + sal_Bool bOk; + do + { + bOk = false; + ScAddress* pPos = (ScAddress*) aNotePosList.GetObject( nNoteStart+nCount ); + if (pPos) + { + ScBaseCell* pCell = pDoc->GetCell( *pPos); + if( const ScPostIt* pNote = pCell->GetNote() ) + { + if(const EditTextObject *pEditText = pNote->GetEditTextObject()) + pEditEngine->SetText(*pEditText); + long nTextHeight = pEditEngine->GetTextHeight(); + if ( nPosY + nTextHeight < aPageRect.Bottom() ) + { + if (bDoPrint) + { + pEditEngine->Draw( pDev, Point( nPosX, nPosY ), 0 ); + + String aMarkStr; + pPos->Format( aMarkStr, SCA_VALID, pDoc, pDoc->GetAddressConvention() ); + aMarkStr += ':'; + + // Zellposition auch per EditEngine, damit die Position stimmt + pEditEngine->SetText(aMarkStr); + pEditEngine->Draw( pDev, Point( aPageRect.Left(), nPosY ), 0 ); + } + + if ( pLocationData ) + { + Rectangle aTextRect( Point( nPosX, nPosY ), Size( aDataSize.Width(), nTextHeight ) ); + pLocationData->AddNoteText( aTextRect, *pPos ); + Rectangle aMarkRect( Point( aPageRect.Left(), nPosY ), Size( nMarkLen, nTextHeight ) ); + pLocationData->AddNoteMark( aMarkRect, *pPos ); + } + + nPosY += nTextHeight; + nPosY += 200; // Abstand + ++nCount; + bOk = sal_True; + } + } + } + } + while (bOk); + + return nCount; +} + +long ScPrintFunc::PrintNotes( long nPageNo, long nNoteStart, sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) +{ + if ( nNoteStart >= (long) aNotePosList.Count() || !aTableParam.bNotes ) + return 0; + + if ( bDoPrint && bClearWin ) + { + //! mit PrintPage zusammenfassen !!! + + Color aBackgroundColor( COL_WHITE ); + if ( bUseStyleColor ) + aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor ); + + pDev->SetMapMode(aOffsetMode); + pDev->SetLineColor(); + pDev->SetFillColor(aBackgroundColor); + pDev->DrawRect(Rectangle(Point(), + Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom), + (long)(aPageSize.Height() * nScaleY * 100 / nZoom)))); + } + + + // aPageRect auf linke / rechte Seiten anpassen + + Rectangle aTempRect = Rectangle( Point(), aPageSize ); + if (IsMirror(nPageNo)) + { + aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom; + aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom; + } + else + { + aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom; + aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom; + } + + if ( pPrinter && bDoPrint ) + { + OSL_FAIL( "StartPage does not exist anymore" ); + } + + if ( bDoPrint || pLocationData ) + { + // Kopf- und Fusszeilen + + if (aHdr.bEnable) + { + long nHeaderY = aPageRect.Top()-aHdr.nHeight; + PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData ); + } + if (aFtr.bEnable) + { + long nFooterY = aPageRect.Bottom()+aFtr.nDistance; + PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData ); + } + } + + long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData ); + + if ( pPrinter && bDoPrint ) + { + OSL_FAIL( "EndPage does not exist anymore" ); + } + + return nCount; +} + +void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, + sal_Bool bDoPrint, ScPreviewLocationData* pLocationData ) +{ + sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nPrintTab ); + long nLayoutSign = bLayoutRTL ? -1 : 1; + + // nPageNo is the page number within all sheets of one "start page" setting + + if ( bClearWin && bDoPrint ) + { + // muss genau zum Zeichnen des Rahmens in preview.cxx passen !!! + + Color aBackgroundColor( COL_WHITE ); + if ( bUseStyleColor ) + aBackgroundColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor ); + + pDev->SetMapMode(aOffsetMode); + pDev->SetLineColor(); + pDev->SetFillColor(aBackgroundColor); + pDev->DrawRect(Rectangle(Point(), + Size((long)(aPageSize.Width() * nScaleX * 100 / nZoom), + (long)(aPageSize.Height() * nScaleY * 100 / nZoom)))); + } + + + // aPageRect auf linke / rechte Seiten anpassen + + Rectangle aTempRect = Rectangle( Point(), aPageSize ); + if (IsMirror(nPageNo)) + { + aPageRect.Left() = ( aTempRect.Left() + nRightMargin ) * 100 / nZoom; + aPageRect.Right() = ( aTempRect.Right() - nLeftMargin ) * 100 / nZoom; + } + else + { + aPageRect.Left() = ( aTempRect.Left() + nLeftMargin ) * 100 / nZoom; + aPageRect.Right() = ( aTempRect.Right() - nRightMargin ) * 100 / nZoom; + } + + if ( aAreaParam.bRepeatCol ) + if ( nX1 > nRepeatStartCol && nX1 <= nRepeatEndCol ) + nX1 = nRepeatEndCol + 1; + sal_Bool bDoRepCol = (aAreaParam.bRepeatCol && nX1 > nRepeatEndCol); + if ( aAreaParam.bRepeatRow ) + if ( nY1 > nRepeatStartRow && nY1 <= nRepeatEndRow ) + nY1 = nRepeatEndRow + 1; + sal_Bool bDoRepRow = (aAreaParam.bRepeatRow && nY1 > nRepeatEndRow); + + // use new object hide flags in SdrPaintView + if(pDrawView) + { + pDrawView->setHideOle(!aTableParam.bObjects); + pDrawView->setHideChart(!aTableParam.bCharts); + pDrawView->setHideDraw(!aTableParam.bDrawings); + pDrawView->setHideFormControl(!aTableParam.bDrawings); + } + + if ( pPrinter && bDoPrint ) + { + OSL_FAIL( "StartPage does not exist anymore" ); + } + + // Kopf- und Fusszeilen (ohne Zentrierung) + + if (aHdr.bEnable) + { + long nHeaderY = aPageRect.Top()-aHdr.nHeight; + PrintHF( nPageNo, sal_True, nHeaderY, bDoPrint, pLocationData ); + } + if (aFtr.bEnable) + { + long nFooterY = aPageRect.Bottom()+aFtr.nDistance; + PrintHF( nPageNo, false, nFooterY, bDoPrint, pLocationData ); + } + + // Position ( Raender / zentrieren ) + + long nLeftSpace = aPageRect.Left(); // Document-Twips + long nTopSpace = aPageRect.Top(); + if ( bCenterHor || bLayoutRTL ) + { + long nDataWidth = 0; + SCCOL i; + for (i=nX1; i<=nX2; i++) + nDataWidth += pDoc->GetColWidth( i,nPrintTab ); + if (bDoRepCol) + for (i=nRepeatStartCol; i<=nRepeatEndCol; i++) + nDataWidth += pDoc->GetColWidth( i,nPrintTab ); + if (aTableParam.bHeaders) + nDataWidth += (long) PRINT_HEADER_WIDTH; + if (pBorderItem) + nDataWidth += pBorderItem->GetDistance(BOX_LINE_LEFT) + + pBorderItem->GetDistance(BOX_LINE_RIGHT); //! Line width? + if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) + nDataWidth += pShadowItem->CalcShadowSpace(SHADOW_LEFT) + + pShadowItem->CalcShadowSpace(SHADOW_RIGHT); + if ( bCenterHor ) + { + nLeftSpace += ( aPageRect.GetWidth() - nDataWidth ) / 2; // LTR or RTL + if (pBorderItem) + nLeftSpace -= lcl_LineTotal(pBorderItem->GetLeft()); + } + else if ( bLayoutRTL ) + nLeftSpace += aPageRect.GetWidth() - nDataWidth; // align to the right edge of the page + } + if ( bCenterVer ) + { + long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab); + if (bDoRepRow) + nDataHeight += pDoc->GetRowHeight( nRepeatStartRow, + nRepeatEndRow, nPrintTab); + if (aTableParam.bHeaders) + nDataHeight += (long) PRINT_HEADER_HEIGHT; + if (pBorderItem) + nDataHeight += pBorderItem->GetDistance(BOX_LINE_TOP) + + pBorderItem->GetDistance(BOX_LINE_BOTTOM); //! Line width? + if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) + nDataHeight += pShadowItem->CalcShadowSpace(SHADOW_TOP) + + pShadowItem->CalcShadowSpace(SHADOW_BOTTOM); + nTopSpace += ( aPageRect.GetHeight() - nDataHeight ) / 2; + if (pBorderItem) + nTopSpace -= lcl_LineTotal(pBorderItem->GetTop()); + } + + // calculate sizes of the elements for partitioning + // (header, repeat, data) + + long nHeaderWidth = 0; + long nHeaderHeight = 0; + long nRepeatWidth = 0; + long nRepeatHeight = 0; + long nContentWidth = 0; // scaled - not the same as nDataWidth above + long nContentHeight = 0; + if (aTableParam.bHeaders) + { + nHeaderWidth = (long) (PRINT_HEADER_WIDTH * nScaleX); + nHeaderHeight = (long) (PRINT_HEADER_HEIGHT * nScaleY); + } + if (bDoRepCol) + for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++) + nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); + if (bDoRepRow) + nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow, + nRepeatEndRow, nPrintTab, nScaleY); + for (SCCOL i=nX1; i<=nX2; i++) + nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); + nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, + nScaleY); + + // partition the page + + long nStartX = ((long) ( nLeftSpace * nScaleX )); + long nStartY = ((long) ( nTopSpace * nScaleY )); + long nInnerStartX = nStartX; + long nInnerStartY = nStartY; + if (pBorderItem) + { + nInnerStartX += (long) ( ( lcl_LineTotal(pBorderItem->GetLeft()) + + pBorderItem->GetDistance(BOX_LINE_LEFT) ) * nScaleX ); + nInnerStartY += (long) ( ( lcl_LineTotal(pBorderItem->GetTop()) + + pBorderItem->GetDistance(BOX_LINE_TOP) ) * nScaleY ); + } + if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) + { + nInnerStartX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_LEFT) * nScaleX ); + nInnerStartY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_TOP) * nScaleY ); + } + + if ( bLayoutRTL ) + { + // arrange elements starting from the right edge + nInnerStartX += nHeaderWidth + nRepeatWidth + nContentWidth; + + // make rounding easier so the elements are really next to each other in preview + Size aOffsetOnePixel = pDev->PixelToLogic( Size(1,1), aOffsetMode ); + long nOffsetOneX = aOffsetOnePixel.Width(); + nInnerStartX += nOffsetOneX / 2; + } + + long nFrameStartX = nInnerStartX; + long nFrameStartY = nInnerStartY; + + long nRepStartX = nInnerStartX + nHeaderWidth * nLayoutSign; // widths/heights are 0 if not used + long nRepStartY = nInnerStartY + nHeaderHeight; + long nDataX = nRepStartX + nRepeatWidth * nLayoutSign; + long nDataY = nRepStartY + nRepeatHeight; + long nEndX = nDataX + nContentWidth * nLayoutSign; + long nEndY = nDataY + nContentHeight; + long nFrameEndX = nEndX; + long nFrameEndY = nEndY; + + if ( bLayoutRTL ) + { + // each element's start position is its left edge + //! subtract one pixel less? + nInnerStartX -= nHeaderWidth; // used for header + nRepStartX -= nRepeatWidth; + nDataX -= nContentWidth; + + // continue right of the main elements again + nEndX += nHeaderWidth + nRepeatWidth + nContentWidth; + } + + // Seiten-Rahmen / Hintergrund + + //! nEndX/Y anpassen + + long nBorderEndX = nEndX; + long nBorderEndY = nEndY; + if (pBorderItem) + { + nBorderEndX += (long) ( ( lcl_LineTotal(pBorderItem->GetRight()) + + pBorderItem->GetDistance(BOX_LINE_RIGHT) ) * nScaleX ); + nBorderEndY += (long) ( ( lcl_LineTotal(pBorderItem->GetBottom()) + + pBorderItem->GetDistance(BOX_LINE_BOTTOM) ) * nScaleY ); + } + if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) + { + nBorderEndX += (long) ( pShadowItem->CalcShadowSpace(SHADOW_RIGHT) * nScaleX ); + nBorderEndY += (long) ( pShadowItem->CalcShadowSpace(SHADOW_BOTTOM) * nScaleY ); + } + + if ( bDoPrint ) + { + pDev->SetMapMode( aOffsetMode ); + DrawBorder( nStartX, nStartY, nBorderEndX-nStartX, nBorderEndY-nStartY, + pBorderItem, pBackgroundItem, pShadowItem ); + + pDev->SetMapMode( aTwipMode ); + } + + pDev->SetMapMode( aOffsetMode ); + + // Wiederholungszeilen/Spalten ausgeben + + if (bDoRepCol && bDoRepRow) + { + if ( bDoPrint ) + PrintArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow, + nRepStartX,nRepStartY, sal_True,sal_True,false,false ); + if ( pLocationData ) + LocateArea( nRepeatStartCol,nRepeatStartRow, nRepeatEndCol,nRepeatEndRow, + nRepStartX,nRepStartY, sal_True,sal_True, *pLocationData ); + } + if (bDoRepCol) + { + if ( bDoPrint ) + PrintArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, + sal_True,!bDoRepRow,false,sal_True ); + if ( pLocationData ) + LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,false, *pLocationData ); + } + if (bDoRepRow) + { + if ( bDoPrint ) + PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, + !bDoRepCol,sal_True,sal_True,false ); + if ( pLocationData ) + LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, false,sal_True, *pLocationData ); + } + + // Daten ausgeben + + if ( bDoPrint ) + PrintArea( nX1,nY1, nX2,nY2, nDataX,nDataY, !bDoRepCol,!bDoRepRow,sal_True,sal_True ); + if ( pLocationData ) + LocateArea( nX1,nY1, nX2,nY2, nDataX,nDataY, false,false, *pLocationData ); + + // Spalten-/Zeilenkoepfe ausgeben + // nach den Daten (ueber evtl. weitergezeichneten Schatten) + + Color aGridColor( COL_BLACK ); + if ( bUseStyleColor ) + aGridColor.SetColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); + + if (aTableParam.bHeaders) + { + if ( bDoPrint ) + { + pDev->SetLineColor( aGridColor ); + pDev->SetFillColor(); + pDev->SetMapMode(aOffsetMode); + } + + ScPatternAttr aPattern( pDoc->GetPool() ); + Font aFont; + ScAutoFontColorMode eColorMode = bUseStyleColor ? SC_AUTOCOL_DISPLAY : SC_AUTOCOL_PRINT; + aPattern.GetFont( aFont, eColorMode, pDev ); + pDev->SetFont( aFont ); + + if (bDoRepCol) + { + if ( bDoPrint ) + PrintColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY ); + if ( pLocationData ) + LocateColHdr( nRepeatStartCol,nRepeatEndCol, nRepStartX,nInnerStartY, sal_True, *pLocationData ); + } + if ( bDoPrint ) + PrintColHdr( nX1,nX2, nDataX,nInnerStartY ); + if ( pLocationData ) + LocateColHdr( nX1,nX2, nDataX,nInnerStartY, false, *pLocationData ); + if (bDoRepRow) + { + if ( bDoPrint ) + PrintRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY ); + if ( pLocationData ) + LocateRowHdr( nRepeatStartRow,nRepeatEndRow, nInnerStartX,nRepStartY, sal_True, *pLocationData ); + } + if ( bDoPrint ) + PrintRowHdr( nY1,nY2, nInnerStartX,nDataY ); + if ( pLocationData ) + LocateRowHdr( nY1,nY2, nInnerStartX,nDataY, false, *pLocationData ); + } + + // einfacher Rahmen + + if ( bDoPrint && ( aTableParam.bGrid || aTableParam.bHeaders ) ) + { + Size aOnePixel = pDev->PixelToLogic(Size(1,1)); + long nOneX = aOnePixel.Width(); + long nOneY = aOnePixel.Height(); + + long nLeftX = nFrameStartX; + long nTopY = nFrameStartY - nOneY; + long nRightX = nFrameEndX; + long nBottomY = nFrameEndY - nOneY; + if ( !bLayoutRTL ) + { + nLeftX -= nOneX; + nRightX -= nOneX; + } + pDev->SetMapMode(aOffsetMode); + pDev->SetLineColor( aGridColor ); + pDev->SetFillColor(); + pDev->DrawRect( Rectangle( nLeftX, nTopY, nRightX, nBottomY ) ); + // nEndX/Y ohne Rahmen-Anpassung + } + + if ( pPrinter && bDoPrint ) + { + OSL_FAIL( "EndPage does not exist anymore" ); + } + + aLastSourceRange = ScRange( nX1, nY1, nPrintTab, nX2, nY2, nPrintTab ); + bSourceRangeValid = sal_True; +} + +void ScPrintFunc::SetOffset( const Point& rOfs ) +{ + aSrcOffset = rOfs; +} + +void ScPrintFunc::SetManualZoom( sal_uInt16 nNewZoom ) +{ + nManualZoom = nNewZoom; +} + +void ScPrintFunc::SetClearFlag( sal_Bool bFlag ) +{ + bClearWin = bFlag; +} + +void ScPrintFunc::SetUseStyleColor( sal_Bool bFlag ) +{ + bUseStyleColor = bFlag; + if (pEditEngine) + pEditEngine->EnableAutoColor( bUseStyleColor ); +} + +void ScPrintFunc::SetRenderFlag( sal_Bool bFlag ) +{ + bIsRender = bFlag; // set when using XRenderable (PDF) +} + +void ScPrintFunc::SetExclusivelyDrawOleAndDrawObjects() +{ + aTableParam.bCellContent = false; + aTableParam.bNotes = false; + aTableParam.bGrid = false; + aTableParam.bHeaders = false; + aTableParam.bFormulas = false;; + aTableParam.bNullVals = false;; + aTableParam.bNullVals = false;; +} + +// +// UpdatePages wird nur von aussen gerufen, um die Umbrueche fuer die Anzeige +// richtig zu setzen - immer ohne UserArea +// + +sal_Bool ScPrintFunc::UpdatePages() +{ + if (!pParamSet) + return false; + + // Zoom + + nZoom = 100; + if (aTableParam.bScalePageNum || aTableParam.bScaleTo) + nZoom = ZOOM_MIN; // stimmt fuer Umbrueche + else if (aTableParam.bScaleAll) + { + nZoom = aTableParam.nScaleAll; + if ( nZoom <= ZOOM_MIN ) + nZoom = ZOOM_MIN; + } + + String aName = pDoc->GetPageStyle( nPrintTab ); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + if ( nTab==nPrintTab || pDoc->GetPageStyle(nTab)==aName ) + { + // Wiederholungszeilen / Spalten + pDoc->SetRepeatArea( nTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow ); + + // Umbrueche setzen + ResetBreaks(nTab); + pDocShell->PostPaint(0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID); + } + + return sal_True; +} + +long ScPrintFunc::CountPages() // setzt auch nPagesX, nPagesY +{ + sal_Bool bAreaOk = false; + + if (pDoc->HasTable( nPrintTab )) + { + if (aAreaParam.bPrintArea) // Druckbereich angegeben? + { + if ( bPrintCurrentTable ) + { + ScRange& rRange = aAreaParam.aPrintArea; + + // hier kein Vergleich der Tabellen mehr, die Area gilt immer fuer diese Tabelle + // wenn hier verglichen werden soll, muss die Tabelle der Druckbereiche beim + // Einfuegen von Tabellen etc. angepasst werden ! + + nStartCol = rRange.aStart.Col(); + nStartRow = rRange.aStart.Row(); + nEndCol = rRange.aEnd .Col(); + nEndRow = rRange.aEnd .Row(); + bAreaOk = AdjustPrintArea(false); // begrenzen + } + else + bAreaOk = false; + } + else // aus Dokument suchen + bAreaOk = AdjustPrintArea(sal_True); + } + + if (bAreaOk) + { + long nPages = 0; + size_t nY; + if (bMultiArea) + { + sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab ); + for (sal_uInt16 i=0; i<nRCount; i++) + { + CalcZoom(i); + if ( aTableParam.bSkipEmpty ) + for (nY=0; nY<nPagesY; nY++) + nPages += pPageRows[nY].CountVisible(); + else + nPages += ((long) nPagesX) * nPagesY; + if ( pPageData ) + FillPageData(); + } + } + else + { + CalcZoom(RANGENO_NORANGE); // Zoom berechnen + if ( aTableParam.bSkipEmpty ) + for (nY=0; nY<nPagesY; nY++) + nPages += pPageRows[nY].CountVisible(); + else + nPages += ((long) nPagesX) * nPagesY; + if ( pPageData ) + FillPageData(); + } + return nPages; + } + else + { + nPagesX = nPagesY = nTotalY = 0; + return 0; + } +} + +long ScPrintFunc::CountNotePages() +{ + if ( !aTableParam.bNotes || !bPrintCurrentTable ) + return 0; + + long nCount=0; + SCCOL nCol; + SCROW nRow; + + sal_Bool bError = false; + if (!aAreaParam.bPrintArea) + bError = !AdjustPrintArea(sal_True); // komplett aus Dok suchen + + sal_uInt16 nRepeats = 1; // wie oft durchgehen ? + if (bMultiArea) + nRepeats = pDoc->GetPrintRangeCount(nPrintTab); + if (bError) + nRepeats = 0; + + for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++) + { + sal_Bool bDoThis = sal_True; + if (bMultiArea) // alle Areas durchgehen + { + const ScRange* pThisRange = pDoc->GetPrintRange( nPrintTab, nStep ); + if ( pThisRange ) + { + nStartCol = pThisRange->aStart.Col(); + nStartRow = pThisRange->aStart.Row(); + nEndCol = pThisRange->aEnd .Col(); + nEndRow = pThisRange->aEnd .Row(); + bDoThis = AdjustPrintArea(false); + } + } + + if (bDoThis) + { + ScHorizontalCellIterator aIter( pDoc, nPrintTab, nStartCol,nStartRow, nEndCol,nEndRow ); + ScBaseCell* pCell = aIter.GetNext( nCol, nRow ); + while (pCell) + { + if (pCell->HasNote()) + { + aNotePosList.Insert( new ScAddress( nCol,nRow,nPrintTab ), LIST_APPEND ); + ++nCount; + } + + pCell = aIter.GetNext( nCol, nRow ); + } + } + } + + long nPages = 0; + long nNoteNr = 0; + long nNoteAdd; + do + { + nNoteAdd = PrintNotes( nPages, nNoteNr, false, NULL ); + if (nNoteAdd) + { + nNoteNr += nNoteAdd; + ++nPages; + } + } + while (nNoteAdd); + + return nPages; +} + +void ScPrintFunc::InitModes() // aus nZoom etc. die MapModes setzen +{ + aOffset = Point( aSrcOffset.X()*100/nZoom, aSrcOffset.Y()*100/nZoom ); + + long nEffZoom = nZoom * (long) nManualZoom; + nScaleX = nScaleY = HMM_PER_TWIPS; // Ausgabe in 1/100 mm + + Fraction aZoomFract( nEffZoom,10000 ); + Fraction aHorFract = aZoomFract; + + if ( !pPrinter && !bIsRender ) // adjust scale for preview + { + double nFact = pDocShell->GetOutputFactor(); + aHorFract = Fraction( (long)( nEffZoom / nFact ), 10000 ); + } + + aLogicMode = MapMode( MAP_100TH_MM, Point(), aHorFract, aZoomFract ); + + Point aLogicOfs( -aOffset.X(), -aOffset.Y() ); + aOffsetMode = MapMode( MAP_100TH_MM, aLogicOfs, aHorFract, aZoomFract ); + + Point aTwipsOfs( (long) ( -aOffset.X() / nScaleX + 0.5 ), (long) ( -aOffset.Y() / nScaleY + 0.5 ) ); + aTwipMode = MapMode( MAP_TWIP, aTwipsOfs, aHorFract, aZoomFract ); +} + +//-------------------------------------------------------------------- + +void ScPrintFunc::ApplyPrintSettings() +{ + if ( pPrinter ) + { + // + // Printer zum Drucken umstellen + // + + Size aEnumSize = aPageSize; + + + pPrinter->SetOrientation( bLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT ); + if ( bLandscape ) + { + // landscape is always interpreted as a rotation by 90 degrees ! + // this leads to non WYSIWIG but at least it prints! + // #i21775# + long nTemp = aEnumSize.Width(); + aEnumSize.Width() = aEnumSize.Height(); + aEnumSize.Height() = nTemp; + } + Paper ePaper = SvxPaperInfo::GetSvxPaper( aEnumSize, MAP_TWIP, sal_True ); + sal_uInt16 nPaperBin = ((const SvxPaperBinItem&)pParamSet->Get(ATTR_PAGE_PAPERBIN)).GetValue(); + + pPrinter->SetPaper( ePaper ); + if ( PAPER_USER == ePaper ) + { + MapMode aPrinterMode = pPrinter->GetMapMode(); + MapMode aLocalMode( MAP_TWIP ); + pPrinter->SetMapMode( aLocalMode ); + pPrinter->SetPaperSizeUser( aEnumSize ); + pPrinter->SetMapMode( aPrinterMode ); + } + + pPrinter->SetPaperBin( nPaperBin ); + } +} + +//-------------------------------------------------------------------- +// rPageRanges = Range fuer alle Tabellen +// nStartPage = in rPageRanges beginnen bei nStartPage +// nDisplayStart = lfd. Nummer fuer Anzeige der Seitennummer + +long ScPrintFunc::DoPrint( const MultiSelection& rPageRanges, + long nStartPage, long nDisplayStart, sal_Bool bDoPrint, + SfxProgress* pProgress, ScPreviewLocationData* pLocationData ) +{ + DBG_ASSERT(pDev,"Device == NULL"); + if (!pParamSet) + return 0; + + if ( pPrinter && bDoPrint ) + ApplyPrintSettings(); + + //-------------------------------------------------------------------- + + InitModes(); + if ( pLocationData ) + { + pLocationData->SetCellMapMode( aOffsetMode ); + pLocationData->SetPrintTab( nPrintTab ); + } + + MakeTableString(); + + if ( pProgress ) + pProgress->SetText( String( ScResId( SCSTR_STAT_PRINT ) ) ); + + //-------------------------------------------------------------------- + + long nPageNo = 0; + long nPrinted = 0; + long nEndPage = rPageRanges.GetTotalRange().Max(); + + sal_uInt16 nRepeats = 1; // wie oft durchgehen ? + if (bMultiArea) + nRepeats = pDoc->GetPrintRangeCount(nPrintTab); + for (sal_uInt16 nStep=0; nStep<nRepeats; nStep++) + { + if (bMultiArea) // Bereich neu belegen ? + { + CalcZoom(nStep); // setzt auch nStartCol etc. neu + InitModes(); + } + + SCCOL nX1; + SCROW nY1; + SCCOL nX2; + SCROW nY2; + size_t nCountX; + size_t nCountY; + + if (aTableParam.bTopDown) // von oben nach unten + { + nX1 = nStartCol; + for (nCountX=0; nCountX<nPagesX; nCountX++) + { + nX2 = pPageEndX[nCountX]; + for (nCountY=0; nCountY<nPagesY; nCountY++) + { + nY1 = pPageRows[nCountY].GetStartRow(); + nY2 = pPageRows[nCountY].GetEndRow(); + if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) ) + { + if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) ) + { + PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, + bDoPrint, pLocationData ); + + if ( pProgress ) + { + pProgress->SetState( nPageNo+nStartPage+1, nEndPage ); + pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug? + } + ++nPrinted; + } + ++nPageNo; + } + } + nX1 = nX2 + 1; + } + } + else // von links nach rechts + { + for (nCountY=0; nCountY<nPagesY; nCountY++) + { + nY1 = pPageRows[nCountY].GetStartRow(); + nY2 = pPageRows[nCountY].GetEndRow(); + nX1 = nStartCol; + for (nCountX=0; nCountX<nPagesX; nCountX++) + { + nX2 = pPageEndX[nCountX]; + if ( !aTableParam.bSkipEmpty || !pPageRows[nCountY].IsHidden(nCountX) ) + { + if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) ) + { + PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, + bDoPrint, pLocationData ); + + if ( pProgress ) + { + pProgress->SetState( nPageNo+nStartPage+1, nEndPage ); + pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug? + } + ++nPrinted; + } + ++nPageNo; + } + nX1 = nX2 + 1; + } + } + } + } + + aFieldData.aTabName = ScGlobal::GetRscString( STR_NOTES ); + + long nNoteNr = 0; + long nNoteAdd; + do + { + if ( nPageNo+nStartPage <= nEndPage ) + { + sal_Bool bPageSelected = rPageRanges.IsSelected( nPageNo+nStartPage+1 ); + nNoteAdd = PrintNotes( nPageNo+nStartPage, nNoteNr, bDoPrint && bPageSelected, + ( bPageSelected ? pLocationData : NULL ) ); + if ( nNoteAdd ) + { + nNoteNr += nNoteAdd; + if ( pProgress && bPageSelected ) + { + pProgress->SetState( nPageNo+nStartPage+1, nEndPage ); + pProgress->Reschedule(); //Mag der Anwender noch oder hat er genug? + } + if (bPageSelected) + { + ++nPrinted; + bSourceRangeValid = false; // last page was no cell range + } + ++nPageNo; + } + } + else + nNoteAdd = 0; + } + while (nNoteAdd); + + if ( bMultiArea ) + ResetBreaks(nPrintTab); // Breaks fuer Anzeige richtig + + return nPrinted; +} + +void ScPrintFunc::CalcZoom( sal_uInt16 nRangeNo ) // Zoom berechnen +{ + sal_uInt16 nRCount = pDoc->GetPrintRangeCount( nPrintTab ); + const ScRange* pThisRange = NULL; + if ( nRangeNo != RANGENO_NORANGE || nRangeNo < nRCount ) + pThisRange = pDoc->GetPrintRange( nPrintTab, nRangeNo ); + if ( pThisRange ) + { + nStartCol = pThisRange->aStart.Col(); + nStartRow = pThisRange->aStart.Row(); + nEndCol = pThisRange->aEnd .Col(); + nEndRow = pThisRange->aEnd .Row(); + } + + if (!AdjustPrintArea(false)) // leer + { + nZoom = 100; + nPagesX = nPagesY = nTotalY = 0; + return; + } + + pDoc->SetRepeatArea( nPrintTab, nRepeatStartCol,nRepeatEndCol, nRepeatStartRow,nRepeatEndRow ); + + if (aTableParam.bScalePageNum) + { + nZoom = 100; + sal_uInt16 nPagesToFit = aTableParam.nScalePageNum; + + sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; + while (true) + { + if (nZoom <= ZOOM_MIN) + break; + + CalcPages(); + bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit); + + if (bFitsPage) + { + if (nZoom == 100) + // If it fits at 100 %, it's good enough for me. + break; + + nLastFitZoom = nZoom; + nZoom = (nLastNonFitZoom + nZoom) / 2; + + if (nLastFitZoom == nZoom) + // It converged. Use this zoom level. + break; + } + else + { + if (nZoom - nLastFitZoom <= 1) + { + nZoom = nLastFitZoom; + CalcPages(); + break; + } + + nLastNonFitZoom = nZoom; + nZoom = (nLastFitZoom + nZoom) / 2; + } + } + } + else if (aTableParam.bScaleTo) + { + nZoom = 100; + sal_uInt16 nW = aTableParam.nScaleWidth; + sal_uInt16 nH = aTableParam.nScaleHeight; + + sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; + while (true) + { + if (nZoom <= ZOOM_MIN) + break; + + CalcPages(); + bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))); + + if (bFitsPage) + { + if (nZoom == 100) + // If it fits at 100 %, it's good enough for me. + break; + + nLastFitZoom = nZoom; + nZoom = (nLastNonFitZoom + nZoom) / 2; + + if (nLastFitZoom == nZoom) + // It converged. Use this zoom level. + break; + } + else + { + if (nZoom - nLastFitZoom <= 1) + { + nZoom = nLastFitZoom; + CalcPages(); + break; + } + + nLastNonFitZoom = nZoom; + nZoom = (nLastFitZoom + nZoom) / 2; + } + } + } + else if (aTableParam.bScaleAll) + { + nZoom = aTableParam.nScaleAll; + if ( nZoom <= ZOOM_MIN ) + nZoom = ZOOM_MIN; + CalcPages(); + } + else + { + DBG_ASSERT( aTableParam.bScaleNone, "kein Scale-Flag gesetzt" ); + nZoom = 100; + CalcPages(); + } +} + +Size ScPrintFunc::GetDocPageSize() +{ + // Hoehe Kopf-/Fusszeile anpassen + + InitModes(); // aTwipMode aus nZoom initialisieren + pDev->SetMapMode( aTwipMode ); // Kopf-/Fusszeilen in Twips + UpdateHFHeight( aHdr ); + UpdateHFHeight( aFtr ); + + // Seitengroesse in Document-Twips + // Berechnung Left / Right auch in PrintPage + + aPageRect = Rectangle( Point(), aPageSize ); + aPageRect.Left() = ( aPageRect.Left() + nLeftMargin ) * 100 / nZoom; + aPageRect.Right() = ( aPageRect.Right() - nRightMargin ) * 100 / nZoom; + aPageRect.Top() = ( aPageRect.Top() + nTopMargin ) * 100 / nZoom + aHdr.nHeight; + aPageRect.Bottom() = ( aPageRect.Bottom() - nBottomMargin ) * 100 / nZoom - aFtr.nHeight; + + Size aDocPageSize = aPageRect.GetSize(); + if (aTableParam.bHeaders) + { + aDocPageSize.Width() -= (long) PRINT_HEADER_WIDTH; + aDocPageSize.Height() -= (long) PRINT_HEADER_HEIGHT; + } + if (pBorderItem) + { + aDocPageSize.Width() -= lcl_LineTotal(pBorderItem->GetLeft()) + + lcl_LineTotal(pBorderItem->GetRight()) + + pBorderItem->GetDistance(BOX_LINE_LEFT) + + pBorderItem->GetDistance(BOX_LINE_RIGHT); + aDocPageSize.Height() -= lcl_LineTotal(pBorderItem->GetTop()) + + lcl_LineTotal(pBorderItem->GetBottom()) + + pBorderItem->GetDistance(BOX_LINE_TOP) + + pBorderItem->GetDistance(BOX_LINE_BOTTOM); + } + if (pShadowItem && pShadowItem->GetLocation() != SVX_SHADOW_NONE) + { + aDocPageSize.Width() -= pShadowItem->CalcShadowSpace(SHADOW_LEFT) + + pShadowItem->CalcShadowSpace(SHADOW_RIGHT); + aDocPageSize.Height() -= pShadowItem->CalcShadowSpace(SHADOW_TOP) + + pShadowItem->CalcShadowSpace(SHADOW_BOTTOM); + } + return aDocPageSize; +} + +void ScPrintFunc::ResetBreaks( SCTAB nTab ) // Breaks fuer Anzeige richtig setzen +{ + pDoc->SetPageSize( nTab, GetDocPageSize() ); + pDoc->UpdatePageBreaks( nTab, NULL ); +} + +void lcl_SetHidden( ScDocument* pDoc, SCTAB nPrintTab, ScPageRowEntry& rPageRowEntry, + SCCOL nStartCol, const SCCOL* pPageEndX ) +{ + size_t nPagesX = rPageRowEntry.GetPagesX(); + SCROW nStartRow = rPageRowEntry.GetStartRow(); + SCROW nEndRow = rPageRowEntry.GetEndRow(); + + sal_Bool bLeftIsEmpty = false; + ScRange aTempRange; + Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 ); + + for (size_t i=0; i<nPagesX; i++) + { + SCCOL nEndCol = pPageEndX[i]; + if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow, + bLeftIsEmpty, &aTempRange, &aTempRect ) ) + { + rPageRowEntry.SetHidden(i); + bLeftIsEmpty = sal_True; + } + else + bLeftIsEmpty = false; + + nStartCol = nEndCol+1; + } +} + +void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten aus nZoom +{ + if (!pPageEndX) pPageEndX = new SCCOL[MAXCOL+1]; + if (!pPageEndY) pPageEndY = new SCROW[MAXROW+1]; + if (!pPageRows) pPageRows = new ScPageRowEntry[MAXROW+1]; //! vorher zaehlen !!!! + + pDoc->SetPageSize( nPrintTab, GetDocPageSize() ); + if (aAreaParam.bPrintArea) + { + ScRange aRange( nStartCol, nStartRow, nPrintTab, nEndCol, nEndRow, nPrintTab ); + pDoc->UpdatePageBreaks( nPrintTab, &aRange ); + } + else + pDoc->UpdatePageBreaks( nPrintTab, NULL ); // sonst wird das Ende markiert + + // + // Seiteneinteilung nach Umbruechen in Col/RowFlags + // Von mehreren Umbruechen in einem ausgeblendeten Bereich zaehlt nur einer. + // + + nPagesX = 0; + nPagesY = 0; + nTotalY = 0; + + bool bVisCol = false; + for (SCCOL i=nStartCol; i<=nEndCol; i++) + { + bool bHidden = pDoc->ColHidden(i, nPrintTab); + bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE); + if ( i>nStartCol && bVisCol && bPageBreak ) + { + pPageEndX[nPagesX] = i-1; + ++nPagesX; + bVisCol = false; + } + if (!bHidden) + bVisCol = true; + } + if (bVisCol) // auch am Ende keine leeren Seiten + { + pPageEndX[nPagesX] = nEndCol; + ++nPagesX; + } + + bool bVisRow = false; + SCROW nPageStartRow = nStartRow; + SCROW nLastVisibleRow = -1; + + ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab)); + SCROW nNextPageBreak = pRowBreakIter->first(); + while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow) + // Skip until the page break position is at the start row or greater. + nNextPageBreak = pRowBreakIter->next(); + + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) + { + bool bPageBreak = (nNextPageBreak == nRow); + if (bPageBreak) + nNextPageBreak = pRowBreakIter->next(); + + if (nRow > nStartRow && bVisRow && bPageBreak ) + { + pPageEndY[nTotalY] = nRow-1; + ++nTotalY; + + if ( !aTableParam.bSkipEmpty || + !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) ) + { + pPageRows[nPagesY].SetStartRow( nPageStartRow ); + pPageRows[nPagesY].SetEndRow( nRow-1 ); + pPageRows[nPagesY].SetPagesX( nPagesX ); + if (aTableParam.bSkipEmpty) + lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); + ++nPagesY; + } + + nPageStartRow = nRow; + bVisRow = false; + } + + if (nRow <= nLastVisibleRow) + { + // This row is still visible. Don't bother calling RowHidden() to + // find out, for speed optimization. + bVisRow = true; + continue; + } + + SCROW nLastRow = -1; + if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow)) + { + bVisRow = true; + nLastVisibleRow = nLastRow; + } + else + // skip all hidden rows. + nRow = nLastRow; + } + + if (bVisRow) + { + pPageEndY[nTotalY] = nEndRow; + ++nTotalY; + + if ( !aTableParam.bSkipEmpty || + !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) ) + { + pPageRows[nPagesY].SetStartRow( nPageStartRow ); + pPageRows[nPagesY].SetEndRow( nEndRow ); + pPageRows[nPagesY].SetPagesX( nPagesX ); + if (aTableParam.bSkipEmpty) + lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); + ++nPagesY; + } + } +} + +//------------------------------------------------------------------------ +// class ScJobSetup +//------------------------------------------------------------------------ + +ScJobSetup::ScJobSetup( SfxPrinter* pPrinter ) +{ + eOrientation = pPrinter->GetOrientation(); + nPaperBin = pPrinter->GetPaperBin(); + ePaper = pPrinter->GetPaper(); + + if ( PAPER_USER == ePaper ) + { + aUserSize = pPrinter->GetPaperSize(); + aUserMapMode = pPrinter->GetMapMode(); + } +}; + + + + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |