/* -*- 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 .
*/
/** Convenience class to extract values from the sequence of properties given to one of the XRenderable methods.
*/ class PrintOptions
{ public:
PrintOptions ( const vcl::PrinterOptionsHelper& rHelper,
std::vector<sal_Int32>&& rSlidesPerPage)
: mrProperties(rHelper),
maSlidesPerPage(std::move(rSlidesPerPage))
{
}
/** When the value of the property with name pName is a boolean then return its value. When the property is unknown then bDefaultValue is returned. Otherwise <FALSE/> is returned.
*/ bool GetBoolValue ( constchar* pName, constbool bDefaultValue) const
{ bool bValue = mrProperties.getBoolValue( pName, bDefaultValue ); return bValue;
}
/** Return <TRUE/> when the value of the property with name pName is an integer and its value is nTriggerValue. Otherwise <FALSE/> is returned.
*/ bool GetBoolValue ( constchar* pName, const sal_Int32 nTriggerValue) const
{
sal_Int32 nValue = static_cast<sal_Int32>(mrProperties.getIntValue( pName, 0 )); return nValue == nTriggerValue;
}
};
/** A collection of values that helps to reduce the number of arguments given to some functions. Note that not all values are set at the same time.
*/ class PrintInfo
{ public:
PrintInfo (
Printer* pPrinter, constbool bPrintMarkedOnly)
: mpPrinter(pPrinter),
mnDrawMode(DrawModeFlags::Default),
maPrintSize(0,0),
maPageSize(0,0),
meOrientation(Orientation::Portrait),
mbPrintMarkedOnly(bPrintMarkedOnly)
{}
/** Output one page of the document to the given printer. Note that more than one document page may be output to one printer page.
*/ void PrintPage (
Printer& rPrinter,
::sd::View& rPrintView,
SdPage& rPage,
View const * pView, constbool bPrintMarkedOnly, const SdrLayerIDSet& rVisibleLayers, const SdrLayerIDSet& rPrintableLayers)
{
rPrintView.ShowSdrPage(&rPage);
// Set the visible layers
SdrPageView* pPageView = rPrintView.GetSdrPageView();
OSL_ASSERT(pPageView!=nullptr);
pPageView->SetVisibleLayers(rVisibleLayers);
pPageView->SetPrintableLayers(rPrintableLayers);
if (pView!=nullptr && bPrintMarkedOnly)
pView->DrawMarkedObj(rPrinter); else
rPrintView.CompleteRedraw(&rPrinter,
vcl::Region(::tools::Rectangle(Point(0,0), rPage.GetSize())));
rPrinter.SetMapMode(aOriginalMapMode);
rPrintView.HideSdrPage();
}
/** Output a string (that typically is not part of a document page) to the given printer.
*/ void PrintMessage (
Printer& rPrinter, const OUString& rsPageString, const Point& rPageStringOffset)
{ const vcl::Font aOriginalFont (rPrinter.OutputDevice::GetFont());
rPrinter.SetFont(vcl::Font(FAMILY_SWISS, Size(0, 423)));
rPrinter.DrawText(rPageStringOffset, rsPageString);
rPrinter.SetFont(aOriginalFont);
}
/** Read the resources and process then into a sequence of properties that can be passed to the printing dialog.
*/ class DialogCreator
{ public:
DialogCreator (ViewShellBase &rBase, bool bImpress, sal_Int32 nCurPage)
: mrBase(rBase)
, mbImpress(bImpress)
, mnCurPage(nCurPage)
{
ProcessResource();
}
AddDialogControl( vcl::PrinterOptionsHelper::setBoolControlOpt(u"printdatetime"_ustr,
SdResId(STR_IMPRESS_PRINT_UI_IS_PRINT_DATE),
u".HelpID:vcl:PrintDialog:IsPrintDateTime:CheckBox"_ustr ,
u"IsPrintDateTime"_ustr , // Separate settings for time and date in Impress/Draw -> Print page, check that both are set
mbImpress ?
officecfg::Office::Impress::Print::Other::Date::get() &&
officecfg::Office::Impress::Print::Other::Time::get() :
officecfg::Office::Draw::Print::Other::Date::get() &&
officecfg::Office::Draw::Print::Other::Time::get()
)
);
Sequence<OUString> GetSlidesPerPageSequence()
{ const Sequence<OUString> aChoice (
CreateChoice(STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES, SAL_N_ELEMENTS(STR_IMPRESS_PRINT_UI_SLIDESPERPAGE_CHOICES)));
maSlidesPerPage.clear();
maSlidesPerPage.push_back(0); // first is using the default
std::transform(std::next(aChoice.begin()), aChoice.end(), std::back_inserter(maSlidesPerPage),
[](const OUString& rChoice) -> sal_Int32 { return rChoice.toInt32(); }); return aChoice;
}
};
/** The Prepare... methods of the DocumentRenderer::Implementation class create a set of PrinterPage objects that contain all necessary information to do the actual printing. There is one PrinterPage object per printed page. Derived classes implement the actual, mode specific printing.
This and all derived classes support the asynchronous printing process by not storing pointers to any data with lifetime shorter than the PrinterPage objects, i.e. slides, shapes, (one of) the outliner (of the document).
*/ class PrinterPage
{ public:
PrinterPage ( const PageKind ePageKind, const MapMode& rMapMode, constbool bPrintMarkedOnly,
OUString sPageString, const Point& rPageStringOffset, const DrawModeFlags nDrawMode, const Orientation eOrientation, const sal_uInt16 nPaperTray)
: mePageKind(ePageKind),
maMap(rMapMode),
mbPrintMarkedOnly(bPrintMarkedOnly),
msPageString(std::move(sPageString)),
maPageStringOffset(rPageStringOffset),
mnDrawMode(nDrawMode),
meOrientation(eOrientation),
mnPaperTray(nPaperTray)
{
}
// Clone the current page to create an independent instance for modifications. // This ensures that changes made to pNotesPage do not affect the original page.
rtl::Reference<SdPage> pNotesPage
= static_cast<SdPage*>(pPageToPrint->CloneSdrPage(rDocument).get());
// Adjusts the objects on the notes page to fit the new page size.
::tools::Rectangle aNewBorderRect(-1, -1, -1, -1);
pNotesPage->ScaleObjects(aPageSize, aNewBorderRect, true);
// If AutoGrowHeight property is enabled and the notes page has a lower border, // use the lower border but if there is no lower border, use the bottom margin // to determine the first page break position. // If AutoGrow is not enabled, the notes object defines the first page break.
::tools::Long nNotesPageBottom
= bAutoGrow ? (pNotesPage->GetLowerBorder() != 0)
? aPageSize.Height() - pNotesPage->GetLowerBorder()
: aPageSize.Height() - nBottom
: aNotesPt.Y() + aNotesSize.Height(); if (mbScaled)
{
sal_Int32 nTextHeight = aNotesPt.Y() + pOut->GetTextHeight(); if (bAutoGrow && (nTextHeight > nNotesPageBottom))
{
pNotesObj->SetMergedItem(SdrOnOffItem(SDRATTR_TEXT_AUTOGROWHEIGHT, false));
if (nUpperSpace != 0 && (i > 0) && (j == 0))
nLineHeight += nUpperSpace;
sal_Int32 nNextPosY = nCurrentPosY + nLineHeight;
if (nNextPosY > nNotesPageBottom)
{ // If the current or the next page matches the print page // calculate and add a page break, since we only want to add // a page break if the page is relevant. if (mnPageNumb == nActualPageNumb
|| mnPageNumb == nActualPageNumb + 1)
{ if (!aPageBreaks.empty())
{ // determine the page break at the bottom of the page // for pages that have both a previous and a following page
aPageBreaks.emplace_back(
nPrevParaIdx - aPageBreaks[0].first, nPrevLineLen);
} else
{ if (mnPageNumb == 1 || (nLineCount > 1 && j != 0))
{ // first page or multi-line paragraphs
aPageBreaks.emplace_back(nPrevParaIdx, nPrevLineLen);
} else
{ // single-line paragraphs
aPageBreaks.emplace_back(nPrevParaIdx + 1, 0);
}
}
// Collect the page objects of the handout master.
std::vector<SdrPageObj*> aHandoutPageObjects;
SdrObjListIter aShapeIter (&rHandoutPage); while (aShapeIter.IsMore())
{
SdrPageObj* pPageObj = dynamic_cast<SdrPageObj*>(aShapeIter.Next()); if (pPageObj)
aHandoutPageObjects.push_back(pPageObj);
} if (aHandoutPageObjects.empty()) return;
// Connect page objects with pages.
std::vector<SdrPageObj*>::iterator aPageObjIter (aHandoutPageObjects.begin()); for (std::vector<sal_uInt16>::const_iterator
iPageIndex(maPageIndices.begin()),
iEnd(maPageIndices.end());
iPageIndex!=iEnd && aPageObjIter!=aHandoutPageObjects.end();
++iPageIndex)
{ // Check if the page still exists. if (*iPageIndex >= rDocument.GetSdPageCount(PageKind::Standard)) continue;
// if there are more page objects than pages left, set the rest to invisible int nHangoverCount = 0; while (aPageObjIter != aHandoutPageObjects.end())
{
(*aPageObjIter++)->SetReferencedPage(nullptr);
nHangoverCount++;
}
// Hide outlines for objects that have pages attached. if (nHangoverCount > 0)
{ int nSkip = aHandoutPageObjects.size() - nHangoverCount;
aShapeIter.Reset(); while (aShapeIter.IsMore())
{
SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>(aShapeIter.Next()); if (pPathObj)
{ if (nSkip > 0)
--nSkip; else
pPathObj->SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
}
}
}
if (rHint.GetId() == SfxHintId::Dying)
{
mbIsDisposed = true;
}
}
/** Process the sequence of properties given to one of the XRenderable methods.
*/ void ProcessProperties (const css::uno::Sequence<css::beans::PropertyValue >& rOptions)
{
OSL_ASSERT(!mbIsDisposed); if (mbIsDisposed) return;
// The RenderDevice property is handled specially: its value is // stored in mpPrinter instead of being retrieved on demand.
Any aDev( getValue( u"RenderDevice"_ustr ) );
Reference<awt::XDevice> xRenderDevice;
/** Return the number of pages that are to be printed.
*/
sal_Int32 GetPrintPageCount() const
{
OSL_ASSERT(!mbIsDisposed); if (mbIsDisposed) return 0; else return maPrinterPages.size();
}
/** Return a sequence of properties that can be returned by the XRenderable::getRenderer() method.
*/
css::uno::Sequence<css::beans::PropertyValue> GetProperties () const
{
css::uno::Sequence<css::beans::PropertyValue> aProperties{
comphelper::makePropertyValue(u"ExtraPrintUIOptions"_ustr,
comphelper::containerToSequence(m_aUIProperties)),
comphelper::makePropertyValue(u"PageSize"_ustr, maPrintSize), // FIXME: is this always true ?
comphelper::makePropertyValue(u"PageIncludesNonprintableArea"_ustr, true)
};
return aProperties;
}
/** Print one of the prepared pages.
*/ void PrintPage (const sal_Int32 nIndex)
{
OSL_ASSERT(!mbIsDisposed); if (mbIsDisposed) return;
Printer& rPrinter (*mpPrinter);
std::shared_ptr<ViewShell> pViewShell (mrBase.GetMainViewShell()); if ( ! pViewShell) return;
// Set page orientation. if ( ! rPrinter.SetOrientation(pPage->GetOrientation()))
{
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.36Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.