| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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 <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) |
| { |
| DBG_ERROR("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, sal_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 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); |
| |
| 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 |
| { |
| DBG_ERROR("Seitenvorlage nicht gefunden" ); |
| pParamSet = NULL; |
| } |
| |
| if (!bState) |
| nZoom = 100; |
| nManualZoom = 100; |
| bClearWin = sal_False; |
| bUseStyleColor = sal_False; |
| bIsRender = sal_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 ( sal_False ), |
| bSourceRangeValid ( sal_False ), |
| bPrintCurrentTable ( sal_False ), |
| bMultiArea ( sal_False ), |
| nTabPages ( 0 ), |
| nTotalPages ( 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 ( sal_False ), |
| bSourceRangeValid ( sal_False ), |
| bPrintCurrentTable ( sal_False ), |
| bMultiArea ( sal_False ), |
| nTabPages ( 0 ), |
| nTotalPages ( 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 ( sal_False ), |
| bPrintCurrentTable ( sal_False ), |
| bMultiArea ( sal_False ), |
| 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 ); |
| } |
| |
| 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 ) ); |
| // #123672# |
| if(maPageEndX.empty()) |
| { |
| OSL_ENSURE(false, "vector access error for maPageEndX (!)"); |
| } |
| else |
| { |
| rData.SetPagesX( nPagesX, &maPageEndX[0]); |
| } |
| |
| // #123672# |
| if(maPageEndY.empty()) |
| { |
| OSL_ENSURE(false, "vector access error for maPageEndY (!)"); |
| } |
| else |
| { |
| rData.SetPagesY( nTotalY, &maPageEndY[0]); |
| } |
| |
| // 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 pEditDefaults; |
| delete pEditEngine; |
| |
| // Druckereinstellungen werden jetzt von aussen wiederhergestellt |
| |
| // #64294# 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 ); |
| // sal_Bool bAddLines = pDoc->HasLines( aRange, aLines ); |
| |
| 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, sal_False, bFormula ); |
| lcl_HidePrint( aTabInfo, nX1, nX2 ); |
| |
| if (bEmbed) |
| pDoc->SetEmbedded(aERange); |
| |
| /* if (!bMetaFile) |
| pDev->SetMapMode(MAP_PIXEL); |
| */ |
| 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, sal_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 = sal_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 sal_False; // nix |
| } |
| else |
| { |
| sal_Bool bFound = sal_True; |
| bChangeCol = ( nStartCol == 0 && nEndCol == MAXCOL ); |
| bChangeRow = ( nStartRow == 0 && nEndRow == MAXROW ); |
| sal_Bool bForcedChangeRow = sal_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 sal_False; // leer |
| |
| if (bForcedChangeRow) |
| bChangeRow = sal_True; |
| } |
| |
| pDoc->ExtendMerge( nStartCol,nStartRow, nEndCol,nEndRow, nPrintTab, |
| sal_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->SetPageNo( nTotalPages ); |
| pEditEngine->SetTextNewDefaults( *pObject, *pEditDefaults, sal_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() ) |
| { |
| DBG_ERROR("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, sal_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, sal_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, sal_False, |
| (const SfxPoolItem**)&pScaleItem ); |
| if ( SFX_ITEM_DEFAULT == eState ) |
| pScaleItem = (const SfxUInt16Item*) |
| &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALE ); |
| |
| eState = pParamSet->GetItemState( ATTR_PAGE_SCALETO, sal_False, |
| (const SfxPoolItem**)&pScaleToItem ); |
| if ( SFX_ITEM_DEFAULT == eState ) |
| pScaleToItem = (const ScPageScaleToItem*) |
| &pParamSet->GetPool()->GetDefaultItem( ATTR_PAGE_SCALETO ); |
| |
| eState = pParamSet->GetItemState( ATTR_PAGE_SCALETOPAGES, sal_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 = sal_False; |
| aTableParam.bScaleTo = sal_False; |
| aTableParam.bScalePageNum = sal_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 = sal_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); |
| |
| // lcl_LimitRange( aAreaParam.aPrintArea, nPrintTab ); // ganze Zeilen/Spalten... |
| } |
| 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 |
| { |
| // #74834# don't print hidden tables if there's no print range defined there |
| if ( pDoc->IsVisible( nPrintTab ) ) |
| { |
| aAreaParam.bPrintArea = sal_False; |
| bPrintCurrentTable = sal_True; |
| } |
| else |
| { |
| aAreaParam.bPrintArea = sal_True; // otherwise the table is always counted |
| bPrintCurrentTable = sal_False; |
| } |
| } |
| |
| if ( pRepeatCol ) |
| { |
| aAreaParam.bRepeatCol = sal_True; |
| aAreaParam.aRepeatCol = *pRepeatCol; |
| nRepeatStartCol = pRepeatCol->aStart.Col(); |
| nRepeatEndCol = pRepeatCol->aEnd .Col(); |
| } |
| else |
| { |
| aAreaParam.bRepeatCol = sal_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 = sal_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 FASTBOOL 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; |
| |
| FASTBOOL bDraw = sal_True; |
| // FASTBOOL bRetouche = sal_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(); |
| // bRetouche = sal_False; |
| break; |
| case GPOS_TILED: |
| { |
| // #104004# 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) ) |
| { |
| // #104004# 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 = sal_False; |
| // bRetouche = sal_False; |
| } |
| break; |
| |
| case GPOS_NONE: |
| bDraw = sal_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 |
| |
| // #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True) |
| sal_Bool bCellContrast = bUseStyleColor && |
| Application::GetSettings().GetStyleSettings().GetHighContrastMode(); |
| |
| if ( pBackground && !bCellContrast ) |
| { |
| // Rectangle aBackRect( Point(nScrX+nLeft, nScrY+nTop), Size(nEffWidth,nEffHeight) ); |
| 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, sal_False, sal_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 ); |
| |
| // pDev->SetMapMode(aTwipMode); |
| |
| 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 ); |
| } |
| |
| // aOutputData.SetMetaFileMode(sal_True); |
| if( aTableParam.bCellContent ) |
| aOutputData.DrawBackground(); |
| |
| pDev->SetClipRegion( Rectangle( aPos, Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ); |
| pDev->SetClipRegion(); |
| |
| // aOutputData.SetMetaFileMode(sal_False); |
| if( aTableParam.bCellContent ) |
| { |
| aOutputData.DrawExtraShadow( bShLeft, bShTop, bShRight, bShBottom ); |
| aOutputData.DrawFrame(); |
| aOutputData.DrawStrings(); |
| |
| // pDev->SetMapMode(aLogicMode); |
| aOutputData.DrawEdit(sal_False); |
| } |
| |
| // pDev->SetMapMode(aOffsetMode); |
| if (aTableParam.bGrid) |
| aOutputData.DrawGrid( sal_True, sal_False ); // keine Seitenumbrueche |
| |
| /*!!!!!!!!!!! Notizen in Tabelle markieren ?????????????????????????? |
| |
| if (aTableParam.bNotes) |
| { |
| pDev->SetMapMode(aOffsetMode); |
| aOutputData.PrintNoteMarks(aNotePosList); |
| pDev->SetMapMode(aLogicMode); |
| } |
| */ |
| |
| aOutputData.AddPDFNotes(); // has no effect if not rendering PDF with notes enabled |
| |
| // pDev->SetMapMode(aDrawMode); |
| |
| // 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 = sal_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(sal_False); |
| pEditEngine->SetRefDevice( pDev ); |
| pEditEngine->SetWordDelimiters( |
| ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) ); |
| pEditEngine->SetControlWord( pEditEngine->GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS ); |
| pDoc->ApplyAsianEditSettings( *pEditEngine ); |
| 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 ); |
| // #69193# 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, sal_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, sal_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, sal_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 ); |
| //? aMarkFont.SetWeight( WEIGHT_BOLD ); |
| 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 = sal_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 ) |
| { |
| DBG_ERROR( "StartPage does not exist anymore" ); |
| // pPrinter->StartPage(); |
| } |
| |
| 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, sal_False, nFooterY, bDoPrint, pLocationData ); |
| } |
| } |
| |
| long nCount = DoNotes( nNoteStart, bDoPrint, pLocationData ); |
| |
| if ( pPrinter && bDoPrint ) |
| { |
| DBG_ERROR( "EndPage does not exist anymore" ); |
| // pPrinter->EndPage(); |
| } |
| |
| 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 ) |
| { |
| DBG_ERROR( "StartPage does not exist anymore" ); |
| // pPrinter->StartPage(); |
| } |
| |
| // 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, sal_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 )); |
| // nStartX -= aOffset.X(); // schon im MapMode |
| // nStartY -= aOffset.Y(); |
| |
| 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,sal_False,sal_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,sal_False,sal_True ); |
| if ( pLocationData ) |
| LocateArea( nRepeatStartCol,nY1, nRepeatEndCol,nY2, nRepStartX,nDataY, sal_True,sal_False, *pLocationData ); |
| } |
| if (bDoRepRow) |
| { |
| if ( bDoPrint ) |
| PrintArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, |
| !bDoRepCol,sal_True,sal_True,sal_False ); |
| if ( pLocationData ) |
| LocateArea( nX1,nRepeatStartRow, nX2,nRepeatEndRow, nDataX,nRepStartY, sal_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, sal_False,sal_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, sal_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, sal_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 ) |
| { |
| DBG_ERROR( "EndPage does not exist anymore" ); |
| // pPrinter->EndPage(); |
| } |
| |
| 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; |
| } |
| |
| // |
| // 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 sal_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 = sal_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(sal_False); // begrenzen |
| } |
| else |
| bAreaOk = sal_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++) |
| { |
| OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)"); |
| nPages += maPageRows[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++) |
| { |
| OSL_ENSURE(nY < maPageRows.size(), "vector access error for maPageRows (!)"); |
| nPages += maPageRows[nY].CountVisible(); |
| } |
| else |
| nPages += ((long) nPagesX) * nPagesY; |
| if ( pPageData ) |
| FillPageData(); |
| } |
| return nPages; |
| } |
| else |
| { |
| // nZoom = 100; // nZoom auf letztem Wert stehenlassen !!! |
| 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 = sal_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(sal_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, sal_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 = 1.0; // Ausgabe in Twips |
| 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, |
| 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(); |
| |
| //-------------------------------------------------------------------- |
| |
| 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++) |
| { |
| OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)"); |
| nX2 = maPageEndX[nCountX]; |
| for (nCountY=0; nCountY<nPagesY; nCountY++) |
| { |
| OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)"); |
| nY1 = maPageRows[nCountY].GetStartRow(); |
| nY2 = maPageRows[nCountY].GetEndRow(); |
| if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) ) |
| { |
| if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) ) |
| { |
| PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, |
| bDoPrint, pLocationData ); |
| ++nPrinted; |
| } |
| ++nPageNo; |
| } |
| } |
| nX1 = nX2 + 1; |
| } |
| } |
| else // von links nach rechts |
| { |
| for (nCountY=0; nCountY<nPagesY; nCountY++) |
| { |
| OSL_ENSURE(nCountY < maPageRows.size(), "vector access error for maPageRows (!)"); |
| nY1 = maPageRows[nCountY].GetStartRow(); |
| nY2 = maPageRows[nCountY].GetEndRow(); |
| nX1 = nStartCol; |
| for (nCountX=0; nCountX<nPagesX; nCountX++) |
| { |
| OSL_ENSURE(nCountX < maPageEndX.size(), "vector access error for maPageEndX (!)"); |
| nX2 = maPageEndX[nCountX]; |
| if ( !aTableParam.bSkipEmpty || !maPageRows[nCountY].IsHidden(nCountX) ) |
| { |
| if ( rPageRanges.IsSelected( nPageNo+nStartPage+1 ) ) |
| { |
| PrintPage( nPageNo+nDisplayStart, nX1, nY1, nX2, nY2, |
| bDoPrint, pLocationData ); |
| ++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 (bPageSelected) |
| { |
| ++nPrinted; |
| bSourceRangeValid = sal_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(sal_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 std::vector< SCCOL >& aPageEndX) |
| { |
| size_t nPagesX = rPageRowEntry.GetPagesX(); |
| SCROW nStartRow = rPageRowEntry.GetStartRow(); |
| SCROW nEndRow = rPageRowEntry.GetEndRow(); |
| |
| sal_Bool bLeftIsEmpty = sal_False; |
| ScRange aTempRange; |
| Rectangle aTempRect = pDoc->GetMMRect( 0,0, 0,0, 0 ); |
| |
| for (size_t i=0; i<nPagesX; i++) |
| { |
| OSL_ENSURE(i < aPageEndX.size(), "vector access error for maPageEndX (!)"); |
| SCCOL nEndCol = aPageEndX[i]; |
| if ( pDoc->IsPrintEmpty( nPrintTab, nStartCol, nStartRow, nEndCol, nEndRow, |
| bLeftIsEmpty, &aTempRange, &aTempRect ) ) |
| { |
| rPageRowEntry.SetHidden(i); |
| bLeftIsEmpty = sal_True; |
| } |
| else |
| bLeftIsEmpty = sal_False; |
| |
| nStartCol = nEndCol+1; |
| } |
| } |
| |
| void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten aus nZoom |
| { |
| // #123672# use dynamic mem to react on size changes |
| if(maPageEndX.size() < MAXCOL+1) |
| { |
| maPageEndX.resize(MAXCOL+1, SCCOL()); |
| } |
| |
| 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 |
| } |
| |
| const SCROW nRealCnt = nEndRow-nStartRow+1; |
| |
| // #123672# use dynamic mem to react on size changes |
| if(maPageEndY.size() < nRealCnt+1) |
| { |
| maPageEndY.resize(nRealCnt+1, SCROW()); |
| } |
| |
| // #123672# use dynamic mem to react on size changes |
| if(maPageRows.size() < nRealCnt+1) |
| { |
| maPageRows.resize(nRealCnt+1, ScPageRowEntry()); |
| } |
| |
| // |
| // 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; |
| SCCOL nLastCol = -1; |
| for (SCCOL i=nStartCol; i<=nEndCol; i++) |
| { |
| bool bHidden = pDoc->ColHidden(i, nPrintTab, nLastCol); |
| bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE); |
| if ( i>nStartCol && bVisCol && bPageBreak ) |
| { |
| OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)"); |
| maPageEndX[nPagesX] = i-1; |
| ++nPagesX; |
| bVisCol = false; |
| } |
| if (!bHidden) |
| bVisCol = true; |
| } |
| if (bVisCol) // auch am Ende keine leeren Seiten |
| { |
| OSL_ENSURE(nPagesX < maPageEndX.size(), "vector access error for maPageEndX (!)"); |
| maPageEndX[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 ) |
| { |
| OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)"); |
| maPageEndY[nTotalY] = nRow-1; |
| ++nTotalY; |
| |
| if ( !aTableParam.bSkipEmpty || |
| !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) ) |
| { |
| OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)"); |
| maPageRows[nPagesY].SetStartRow( nPageStartRow ); |
| maPageRows[nPagesY].SetEndRow( nRow-1 ); |
| maPageRows[nPagesY].SetPagesX( nPagesX ); |
| if (aTableParam.bSkipEmpty) |
| lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX ); |
| ++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) |
| { |
| OSL_ENSURE(nTotalY < maPageEndY.size(), "vector access error for maPageEndY (!)"); |
| maPageEndY[nTotalY] = nEndRow; |
| ++nTotalY; |
| |
| if ( !aTableParam.bSkipEmpty || |
| !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nEndRow ) ) |
| { |
| OSL_ENSURE(nPagesY < maPageRows.size(), "vector access error for maPageRows (!)"); |
| maPageRows[nPagesY].SetStartRow( nPageStartRow ); |
| maPageRows[nPagesY].SetEndRow( nEndRow ); |
| maPageRows[nPagesY].SetPagesX( nPagesX ); |
| if (aTableParam.bSkipEmpty) |
| lcl_SetHidden( pDoc, nPrintTab, maPageRows[nPagesY], nStartCol, maPageEndX ); |
| ++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(); |
| } |
| }; |
| |
| |
| |
| |
| |