/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#pragma once
#include <memory>
#include <map>
#include <pagepar.hxx>
#include <editutil.hxx>
class SfxPrinter;
class ScDocShell;
class ScDocument;
class ScViewData;
class SfxItemSet;
class ScPageHFItem;
class EditTextObject;
class MultiSelection;
class ScPageBreakData;
class ScPreviewLocationData;
class ScPrintOptions;
class SvxBoxItem;
class SvxBrushItem;
class SvxShadowItem;
class FmFormView;
#define RANGENO_NORANGE USHRT_MAX
constexpr sal_Int64 PRINT_HEADER_WIDTH = o3tl::toTwips(1, o3tl::Length::cm);
constexpr sal_Int64 PRINT_HEADER_HEIGHT = o3tl::toTwips(12.8, o3tl::Length::pt);
// Settings for headers/footers
struct ScPrintHFParam
{
bool bEnable;
bool bDynamic;
bool bShared;
bool bSharedFirst;
tools::
Long nHeight;
// in total (height + distance + frames)
tools::
Long nManHeight;
// set size (min when dynamic)
sal_uInt16 nDistance;
sal_uInt16 nLeft;
// edges
sal_uInt16 nRight;
const ScPageHFItem* pLeft;
const ScPageHFItem* pRight;
const ScPageHFItem* pFirst;
const SvxBoxItem* pBorder;
const SvxBrushItem* pBack;
const SvxShadowItem* pShadow;
};
class ScPageRowEntry
{
private:
SCROW nStartRow;
SCROW nEndRow;
size_t nPagesX;
std::vector<
bool> aHidden;
//! Cache Number of really visible?
public:
ScPageRowEntry() { nStartRow = nEndRow = 0; nPagesX = 0; }
ScPageRowEntry(
const ScPageRowEntry& r);
ScPageRowEntry&
operator=(
const ScPageRowEntry& r);
SCROW GetStartRow()
const {
return nStartRow; }
SCROW GetEndRow()
const {
return nEndRow; }
size_t GetPagesX()
const {
return nPagesX; }
void SetStartRow(SCROW n) { nStartRow = n; }
void SetEndRow(SCROW n) { nEndRow = n; }
void SetPagesX(size_t nNew);
void SetHidden(size_t nX);
bool IsHidden(size_t nX)
const;
size_t CountVisible()
const;
};
namespace sc
{
struct PrintPageRangesInput
{
bool m_bSkipEmpty;
bool m_bPrintArea;
ScRange m_aRange;
Size m_aDocSize;
PrintPageRangesInput()
: m_bSkipEmpty(
false)
, m_bPrintArea(
false)
{}
PrintPageRangesInput(
bool bSkipEmpty,
bool bPrintArea, ScRange
const& rRange, Size
const& rDocSize)
: m_bSkipEmpty(bSkipEmpty)
, m_bPrintArea(bPrintArea)
, m_aRange(rRange)
, m_aDocSize(rDocSize)
{}
bool operator==(PrintPageRangesInput
const& rInput)
const
{
return
m_bSkipEmpty == rInput.m_bSkipEmpty &&
m_bPrintArea == rInput.m_bPrintArea &&
m_aRange == rInput.m_aRange &&
m_aDocSize == rInput.m_aDocSize;
}
PrintPageRangesInput&
operator=(PrintPageRangesInput
const& rInput)
{
m_bSkipEmpty = rInput.m_bSkipEmpty;
m_bPrintArea = rInput.m_bPrintArea;
m_aRange = rInput.m_aRange;
m_aDocSize = rInput.m_aDocSize;
return *
this;
}
SCROW getStartRow()
const
{
return m_aRange.aStart.Row();
}
SCROW getEndRow()
const
{
return m_aRange.aEnd.Row();
}
SCCOL getStartColumn()
const
{
return m_aRange.aStart.Col();
}
SCCOL getEndColumn()
const
{
return m_aRange.aEnd.Col();
}
SCTAB getPrintTab()
const
{
return m_aRange.aStart.Tab();
}
};
class PrintPageRanges
{
public:
PrintPageRanges();
// use shared_ptr to avoid copying this (potentially large) data back and forth
std::shared_ptr<std::vector<SCCOL>> m_xPageEndX;
std::shared_ptr<std::vector<SCROW>> m_xPageEndY;
std::shared_ptr<std::map<size_t, ScPageRowEntry>> m_xPageRows;
size_t m_nPagesX;
size_t m_nPagesY;
size_t m_nTotalY;
PrintPageRangesInput m_aInput;
void calculate(ScDocument& rDoc, PrintPageRangesInput
const& rInput);
};
}
// end sc namespace
// Used to save expensive-to-compute data from ScPrintFunc in between
// uses of ScPrintFunc
struct ScPrintState
{
SCTAB nPrintTab;
SCCOL nStartCol;
SCROW nStartRow;
SCCOL nEndCol;
SCROW nEndRow;
bool bPrintAreaValid;
// the 4 variables above are set
sal_uInt16 nZoom;
tools::
Long nTabPages;
tools::
Long nTotalPages;
tools::
Long nPageStart;
tools::
Long nDocPages;
// Additional state of page ranges
sc::PrintPageRanges m_aRanges;
ScPrintState()
: nPrintTab(0)
, nStartCol(0)
, nStartRow(0)
, nEndCol(0)
, nEndRow(0)
, bPrintAreaValid(
false)
, nZoom(0)
, nTabPages(0)
, nTotalPages(0)
, nPageStart(0)
, nDocPages(0)
{}
};
class ScPrintFunc
{
private:
ScDocShell& rDocShell;
ScDocument& rDoc;
VclPtr<SfxPrinter> pPrinter;
VclPtr<OutputDevice> pDev;
FmFormView* pDrawView;
MapMode aOldPrinterMode;
// MapMode before the call
Point aSrcOffset;
// Paper-1/100 mm
Point aOffset;
// scaled by a factor of page size
sal_uInt16 nManualZoom;
// Zoom in Preview (percent)
bool bClearWin;
// Clear output before
bool bUseStyleColor;
bool bIsRender;
SCTAB nPrintTab;
tools::
Long nPageStart;
// Offset for the first page
tools::
Long nDocPages;
// Number of Pages in Document
const ScRange* pUserArea;
// Selection, if set in dialog
const SfxItemSet* pParamSet;
// Selected template
bool bFromPrintState;
// created from State-struct
// Parameter from template:
sal_uInt16 nLeftMargin;
sal_uInt16 nTopMargin;
sal_uInt16 nRightMargin;
sal_uInt16 nBottomMargin;
bool bCenterHor;
bool bCenterVer;
bool bLandscape;
bool bSourceRangeValid;
SvxPageUsage nPageUsage;
Size aPageSize;
// Printer Twips
const SvxBoxItem* pBorderItem;
const SvxBrushItem* pBackgroundItem;
const SvxShadowItem* pShadowItem;
ScRange aLastSourceRange;
ScPrintHFParam aHdr;
ScPrintHFParam aFtr;
ScPageTableParam aTableParam;
ScPageAreaParam aAreaParam;
// Calculated values:
sal_uInt16 nZoom;
bool bPrintCurrentTable;
bool bMultiArea;
bool mbHasPrintRange;
tools::
Long nTabPages;
tools::
Long nTotalPages;
tools::Rectangle aPageRect;
// Document Twips
MapMode aLogicMode;
// Set in DoPrint
MapMode aOffsetMode;
MapMode aTwipMode;
double nScaleX;
double nScaleY;
SCCOL nRepeatStartCol;
SCCOL nRepeatEndCol;
SCROW nRepeatStartRow;
SCROW nRepeatEndRow;
SCCOL nStartCol;
SCROW nStartRow;
SCCOL nEndCol;
SCROW nEndRow;
bool bPrintAreaValid;
// the 4 variables above are set
sc::PrintPageRanges m_aRanges;
std::unique_ptr<ScHeaderEditEngine> pEditEngine;
std::unique_ptr<SfxItemSet> pEditDefaults;
ScHeaderFieldData aFieldData;
std::vector<ScAddress> aNotePosList;
// The order of notes
ScPageBreakData* pPageData;
// for recording the breaks etc.
Size aPrintPageSize;
// print page size in Print dialog
bool bPrintPageLandscape;
// print page orientation in Print dialog
bool bUsePrintDialogSetting;
// use Print dialog setting
public:
ScPrintFunc( ScDocShell& rShell, SfxPrinter* pNewPrinter, SCTAB nTab,
tools::
Long nPage = 0, tools::
Long nDocP = 0,
const ScRange* pArea = nullptr,
const ScPrintOptions* pOptions = nullptr,
ScPageBreakData* pData = nullptr,
Size aPrintPageSize = {},
bool bPrintPageLandscape =
false,
bool bUsePrintDialogSetting =
false );
ScPrintFunc( ScDocShell& rShell, SfxPrinter* pNewPrinter,
const ScPrintState& rState,
const ScPrintOptions* pOptions,
Size aPrintPageSize = {},
bool bPrintPageLandscape =
false,
bool bUsePrintDialogSetting =
false );
// ctors for device other than printer - for preview and pdf:
ScPrintFunc( OutputDevice* pOutDev, ScDocShell& rShell, SCTAB nTab,
tools::
Long nPage = 0, tools::
Long nDocP = 0,
const ScRange* pArea = nullptr,
const ScPrintOptions* pOptions = nullptr );
ScPrintFunc( OutputDevice* pOutDev, ScDocShell& rShell,
const ScPrintState& rState,
const ScPrintOptions* pOptions, Size aPrintPageSize = {},
bool bPrintPageLandscape =
false,
bool bUsePrintDialogSetting =
false);
~ScPrintFunc();
static void DrawToDev( ScDocument& rDoc, OutputDevice* pDev,
double nPrintFactor,
const tools::Rectangle& rBound, ScViewData& rViewData,
bool bMetaFile );
void SetDrawView( FmFormView* pNew );
void SetOffset(
const Point& rOfs );
void SetManualZoom( sal_uInt16 nNewZoom );
void SetDateTime(
const DateTime& );
void SetClearFlag(
bool bFlag );
void SetUseStyleColor(
bool bFlag );
void SetRenderFlag(
bool bFlag );
void SetExclusivelyDrawOleAndDrawObjects();
//for printing selected objects without surrounding cell contents
bool UpdatePages();
void ApplyPrintSettings();
// Already called from DoPrint()
tools::
Long DoPrint(
const MultiSelection& rPageRanges,
tools::
Long nStartPage, tools::
Long nDisplayStart,
bool bDoPrint,
ScPreviewLocationData* pLocationData );
// Query values - immediately
const Size& GetPageSize()
const {
return aPageSize; }
Size GetDataSize()
const;
void GetScaleData( Size& rPhysSize, tools::
Long& rDocHdr, tools::
Long& rDoc
Ftr );
tools::Long GetFirstPageNo() const { return aTableParam.nFirstPageNo; }
tools::Long GetTotalPages() const { return nTotalPages; }
sal_uInt16 GetZoom() const { return nZoom; }
void ResetBreaks( SCTAB nTab );
void GetPrintState(ScPrintState& rState);
bool GetLastSourceRange( ScRange& rRange ) const;
sal_uInt16 GetLeftMargin() const{return nLeftMargin;}
sal_uInt16 GetRightMargin() const{return nRightMargin;}
sal_uInt16 GetTopMargin() const{return nTopMargin;}
sal_uInt16 GetBottomMargin() const{return nBottomMargin;}
const ScPrintHFParam& GetHeader() const {return aHdr;}
const ScPrintHFParam& GetFooter() const {return aFtr;}
bool HasPrintRange() const { return mbHasPrintRange;}
private:
void Construct( const ScPrintOptions* pOptions );
void InitParam( const ScPrintOptions* pOptions );
void CalcZoom( sal_uInt16 nRangeNo );
void CalcPages();
tools::Long CountPages();
tools::Long CountNotePages();
bool AdjustPrintArea( bool bNew );
Size GetDocPageSize();
tools::Long TextHeight( const EditTextObject* pObject );
void MakeEditEngine();
void UpdateHFHeight( ScPrintHFParam& rParam );
void InitModes();
bool IsLeft( tools::Long nPageNo );
bool IsMirror( tools::Long nPageNo );
void MakeTableString(); // sets aTableStr
void PrintPage( tools::Long nPageNo,
SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
bool bDoPrint, ScPreviewLocationData* pLocationData );
void PrintArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
tools::Long nScrX, tools::Long nScrY,
bool bShLeft, bool bShTop, bool bShRight, bool bShBottom );
void LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
tools::Long nScrX, tools::Long nScrY, bool bRepCol, bool bRepRow,
ScPreviewLocationData& rLocationData );
void PrintColHdr( SCCOL nX1, SCCOL nX2, tools::Long nScrX, tools::Long nScrY );
void PrintRowHdr( SCROW nY1, SCROW nY2, tools::Long nScrX, tools::Long nScrY );
void LocateColHdr( SCCOL nX1, SCCOL nX2, tools::Long nScrX, tools::Long nScrY,
bool bRepCol, ScPreviewLocationData& rLocationData );
void LocateRowHdr( SCROW nY1, SCROW nY2, tools::Long nScrX, tools::Long nScrY,
bool bRepRow, ScPreviewLocationData& rLocationData );
void PrintHF( tools::Long nPageNo, bool bHeader, tools::Long nStartY,
bool bDoPrint, ScPreviewLocationData* pLocationData );
tools::Long PrintNotes( tools::Long nPageNo, tools::Long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData );
tools::Long DoNotes( tools::Long nNoteStart, bool bDoPrint, ScPreviewLocationData* pLocationData );
void DrawBorder( tools::Long nScrX, tools::Long nScrY, tools::Long nScrW, tools::Long nScrH,
const SvxBoxItem* pBorderData,
const SvxBrushItem* pBackground,
const SvxShadowItem* pShadow );
void FillPageData();
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */