Quelle sdxmlexp.cxx
Sprache: C
/* -*- 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 .
*/
#include <sal/config.h>
#include <string_view>
#include <xmloff/autolayout.hxx>
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmltoken.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/presentation/XPresentationSupplier.hpp>
#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
#include <com/sun/star/geometry/RealPoint2D.hpp>
#include <com/sun/star/office/XAnnotationAccess.hpp>
#include <com/sun/star/uno/Any.hxx>
#include "sdxmlexp_impl.hxx"
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
#include <com/sun/star/presentation/XHandoutMasterSupplier.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/view/PaperOrientation.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/form/XFormsSupplier2.hpp>
#include <com/sun/star/presentation/XPresentationPage.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/Duration.hpp>
#include <com/sun/star/util/MeasureUnit.hpp>
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <tools/gen.hxx>
#include <sax/tools/converter.hxx>
#include <xmloff/xmlaustp.hxx>
#include <xmloff/families.hxx>
#include <xmloff/styleexp.hxx>
#include <xmloff/settingsstore.hxx>
#include <xmloff/table/XMLTableExport.hxx>
#include <xmloff/ProgressBarHelper.hxx>
#include "sdpropls.hxx"
#include <xmloff/xmlexppr.hxx>
#include <PropertySetMerger.hxx>
#include "layerexp.hxx"
#include "XMLNumberStylesExport.hxx"
#include <xmloff/animationexport.hxx>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <docmodel/uno/UnoTheme.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::office;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::geometry;
using namespace ::com::sun::star::text;
using namespace ::xmloff::token;
class ImpXMLEXPPageMasterInfo
{
sal_Int32 mnBorderBottom;
sal_Int32 mnBorderLeft;
sal_Int32 mnBorderRight;
sal_Int32 mnBorderTop;
sal_Int32 mnWidth;
sal_Int32 mnHeight;
view::PaperOrientation meOrientation;
OUString msName;
OUString msMasterPageName;
public :
ImpXMLEXPPageMasterInfo(
const SdXMLExport& rExp,
const Reference<XDrawPage>& xP
age);
bool operator ==(const ImpXMLEXPPageMasterInfo& rInfo) const ;
void SetName(const OUString& rStr);
const OUString& GetName() const { return msName; }
const OUString& GetMasterPageName() const { return msMasterPageName; }
sal_Int32 GetBorderBottom() const { return mnBorderBottom; }
sal_Int32 GetBorderLeft() const { return mnBorderLeft; }
sal_Int32 GetBorderRight() const { return mnBorderRight; }
sal_Int32 GetBorderTop() const { return mnBorderTop; }
sal_Int32 GetWidth() const { return mnWidth; }
sal_Int32 GetHeight() const { return mnHeight; }
view::PaperOrientation GetOrientation() const { return meOrientation; }
};
ImpXMLEXPPageMasterInfo::ImpXMLEXPPageMasterInfo(
const SdXMLExport& rExp,
const Reference<XDrawPage>& xPage)
: mnBorderBottom(0),
mnBorderLeft(0),
mnBorderRight(0),
mnBorderTop(0),
mnWidth(0),
mnHeight(0),
meOrientation(rExp.IsDraw() ? view::PaperOrientation_PORTRAIT : view::PaperOrientation_LANDSCAPE)
{
Reference <beans::XPropertySet> xPropSet(xPage, UNO_QUERY);
if (xPropSet.is())
{
Any aAny;
Reference< beans::XPropertySetInfo > xPropsInfo( xPropSet->getPropertySetInfo() );
if ( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"BorderBottom" _ustr))
{
aAny = xPropSet->getPropertyValue(u"BorderBottom" _ustr);
aAny >>= mnBorderBottom;
aAny = xPropSet->getPropertyValue(u"BorderLeft" _ustr);
aAny >>= mnBorderLeft;
aAny = xPropSet->getPropertyValue(u"BorderRight" _ustr);
aAny >>= mnBorderRight;
aAny = xPropSet->getPropertyValue(u"BorderTop" _ustr);
aAny >>= mnBorderTop;
}
if ( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"Width" _ustr))
{
aAny = xPropSet->getPropertyValue(u"Width" _ustr);
aAny >>= mnWidth;
aAny = xPropSet->getPropertyValue(u"Height" _ustr);
aAny >>= mnHeight;
}
if ( xPropsInfo.is() && xPropsInfo->hasPropertyByName(u"Orientation" _ustr))
{
aAny = xPropSet->getPropertyValue(u"Orientation" _ustr);
aAny >>= meOrientation;
}
}
Reference <container::XNamed> xMasterNamed(xPage, UNO_QUERY);
if (xMasterNamed.is())
{
msMasterPageName = xMasterNamed->getName();
}
}
bool ImpXMLEXPPageMasterInfo::operator ==(const ImpXMLEXPPageMasterInfo& rInfo) const
{
return ((mnBorderBottom == rInfo.mnBorderBottom)
&& (mnBorderLeft == rInfo.mnBorderLeft)
&& (mnBorderRight == rInfo.mnBorderRight)
&& (mnBorderTop == rInfo.mnBorderTop)
&& (mnWidth == rInfo.mnWidth)
&& (mnHeight == rInfo.mnHeight)
&& (meOrientation == rInfo.meOrientation));
}
void ImpXMLEXPPageMasterInfo::SetName(const OUString& rStr)
{
msName = rStr;
}
#define IMP_AUTOLAYOUT_INFO_MAX (35L)
class ImpXMLAutoLayoutInfo
{
sal_uInt16 mnType;
ImpXMLEXPPageMasterInfo* mpPageMasterInfo;
OUString msLayoutName;
tools::Rectangle maTitleRect;
tools::Rectangle maPresRect;
sal_Int32 mnGapX;
sal_Int32 mnGapY;
public :
ImpXMLAutoLayoutInfo(sal_uInt16 nTyp, ImpXMLEXPPageMasterInfo* pInf);
sal_uInt16 GetLayoutType() const { return mnType; }
ImpXMLEXPPageMasterInfo* GetPageMasterInfo() const { return mpPageMasterInfo; }
sal_Int32 GetGapX() const { return mnGapX; }
sal_Int32 GetGapY() const { return mnGapY; }
const OUString& GetLayoutName() const { return msLayoutName; }
void SetLayoutName(const OUString& rNew) { msLayoutName = rNew; }
const tools::Rectangle& GetTitleRectangle() const { return maTitleRect; }
const tools::Rectangle& GetPresRectangle() const { return maPresRect; }
static bool IsCreateNecessary(sal_uInt16 nTyp);
};
bool ImpXMLAutoLayoutInfo::IsCreateNecessary(sal_uInt16 nTyp)
{
if (nTyp == 5 /* AUTOLAYOUT_ORG */
|| nTyp == 20 /* AUTOLAYOUT_NONE */
|| nTyp >= IMP_AUTOLAYOUT_INFO_MAX)
return false ;
return true ;
}
ImpXMLAutoLayoutInfo::ImpXMLAutoLayoutInfo(sal_uInt16 nTyp, ImpXMLEXPPageMasterInfo* pInf)
: mnType(nTyp)
, mpPageMasterInfo(pInf)
, mnGapX(0)
, mnGapY(0)
{
// create full info (initialize with typical values)
Point aPagePos(0,0);
Size aPageSize(28000, 21000);
Size aPageInnerSize(28000, 21000);
if (mpPageMasterInfo)
{
aPagePos = Point(mpPageMasterInfo->GetBorderLeft(), mpPageMasterInfo->GetBorderTop());
aPageSize = Size(mpPageMasterInfo->GetWidth(), mpPageMasterInfo->GetHeight());
aPageInnerSize = aPageSize;
aPageInnerSize.AdjustWidth(-(mpPageMasterInfo->GetBorderLeft() + mpPageMasterInfo->GetBorderRight()));
aPageInnerSize.AdjustHeight(-(mpPageMasterInfo->GetBorderTop() + mpPageMasterInfo->GetBorderBottom()));
}
// title rectangle aligning
Point aTitlePos(aPagePos);
Size aTitleSize(aPageInnerSize);
if (mnType == 21 /* AUTOLAYOUT_NOTES */)
{
aTitleSize.setHeight(static_cast <tools::Long >(aTitleSize.Height() / 2.5));
Point aPos = aTitlePos;
aPos.AdjustY( tools::Long ( aTitleSize.Height() * 0.083 ) );
Size aPartArea = aTitleSize;
Size aSize;
// scale handout rectangle using actual page size
double fH = static_cast <double >(aPartArea.Width()) / aPageSize.Width();
double fV = static_cast <double >(aPartArea.Height()) / aPageSize.Height();
if ( fH > fV )
fH = fV;
aSize.setWidth( static_cast <tools::Long >(fH * aPageSize.Width()) );
aSize.setHeight( static_cast <tools::Long >(fH * aPageSize.Height()) );
aPos.AdjustX((aPartArea.Width() - aSize.Width()) / 2);
aPos.AdjustY((aPartArea.Height()- aSize.Height())/ 2);
aTitlePos = aPos;
aTitleSize = aSize;
}
else if (mnType == AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT || mnType == AUTOLAYOUT_VTITLE_VCONTENT)
{
Point aClassicTPos(
aTitlePos.X() + tools::Long ( aTitleSize.Width() * 0.0735 ),
aTitlePos.Y() + tools::Long ( aTitleSize.Height() * 0.083 ));
Size aClassicTSize(
tools::Long ( aTitleSize.Width() * 0.854 ),
tools::Long ( aTitleSize.Height() * 0.167 ));
Point aLPos(aPagePos);
Size aLSize(aPageInnerSize);
Point aClassicLPos(
aLPos.X() + tools::Long ( aLSize.Width() * 0.0735 ),
aLPos.Y() + tools::Long ( aLSize.Height() * 0.472 ));
Size aClassicLSize(
tools::Long ( aLSize.Width() * 0.854 ),
tools::Long ( aLSize.Height() * 0.444 ));
aTitlePos.setX( (aClassicTPos.X() + aClassicTSize.Width()) - aClassicTSize.Height() );
aTitlePos.setY( aClassicTPos.Y() );
aTitleSize.setWidth( aClassicTSize.Height() );
aTitleSize.setHeight( (aClassicLPos.Y() + aClassicLSize.Height()) - aClassicTPos.Y() );
}
else
{
aTitlePos.AdjustX( tools::Long ( aTitleSize.Width() * 0.0735 ) );
aTitlePos.AdjustY( tools::Long ( aTitleSize.Height() * 0.083 ) );
aTitleSize.setWidth( tools::Long ( aTitleSize.Width() * 0.854 ) );
aTitleSize.setHeight( tools::Long ( aTitleSize.Height() * 0.167 ) );
}
maTitleRect.SetPos(aTitlePos);
maTitleRect.SetSize(aTitleSize);
// layout rectangle aligning
Point aLayoutPos(aPagePos);
Size aLayoutSize(aPageInnerSize);
if (mnType == 21 /* AUTOLAYOUT_NOTES */)
{
aLayoutPos.AdjustX( tools::Long ( aLayoutSize.Width() * 0.0735 ) );
aLayoutPos.AdjustY( tools::Long ( aLayoutSize.Height() * 0.472 ) );
aLayoutSize.setWidth( tools::Long ( aLayoutSize.Width() * 0.854 ) );
aLayoutSize.setHeight( tools::Long ( aLayoutSize.Height() * 0.444 ) );
}
else if ((mnType >= 22 && mnType <= 26) || (mnType == 31)) // AUTOLAYOUT_HANDOUT*
{
// keep info for inner area in maPresRect, put info for gap size
// to maTitleRect position
mnGapX = (aPageSize.Width() - aPageInnerSize.Width()) / 2;
mnGapY = (aPageSize.Height() - aPageInnerSize.Height()) / 2;
if (!mnGapX)
mnGapX = aPageSize.Width() / 10;
if (!mnGapY)
mnGapY = aPageSize.Height() / 10;
if (mnGapX < aPageInnerSize.Width() / 10)
mnGapX = aPageInnerSize.Width() / 10;
if (mnGapY < aPageInnerSize.Height() / 10)
mnGapY = aPageInnerSize.Height() / 10;
}
else if (mnType == AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT || mnType == AUTOLAYOUT_VTITLE_VCONTENT)
{
Point aClassicTPos(
aTitlePos.X() + tools::Long ( aTitleSize.Width() * 0.0735 ),
aTitlePos.Y() + tools::Long ( aTitleSize.Height() * 0.083 ));
Size aClassicTSize(
tools::Long ( aTitleSize.Width() * 0.854 ),
tools::Long ( aTitleSize.Height() * 0.167 ));
Point aClassicLPos(
aLayoutPos.X() + tools::Long ( aLayoutSize.Width() * 0.0735 ),
aLayoutPos.Y() + tools::Long ( aLayoutSize.Height() * 0.472 ));
Size aClassicLSize(
tools::Long ( aLayoutSize.Width() * 0.854 ),
tools::Long ( aLayoutSize.Height() * 0.444 ));
aLayoutPos.setX( aClassicLPos.X() );
aLayoutPos.setY( aClassicTPos.Y() );
aLayoutSize.setWidth( (aClassicLPos.X() + aClassicLSize.Width())
- (aClassicTSize.Height() + (aClassicLPos.Y() - (aClassicTPos.Y() + aClassicTSize.Height()))));
aLayoutSize.setHeight( (aClassicLPos.Y() + aClassicLSize.Height()) - aClassicTPos.Y() );
}
else if ( mnType == AUTOLAYOUT_ONLY_TEXT )
{
aLayoutPos = aTitlePos;
aLayoutSize.setWidth( aTitleSize.Width() );
aLayoutSize.setHeight( tools::Long ( aLayoutSize.Height() * 0.825 ) );
}
else
{
aLayoutPos.AdjustX( tools::Long ( aLayoutSize.Width() * 0.0735 ) );
aLayoutPos.AdjustY( tools::Long ( aLayoutSize.Height() * 0.278 ) );
aLayoutSize.setWidth( tools::Long ( aLayoutSize.Width() * 0.854 ) );
aLayoutSize.setHeight( tools::Long ( aLayoutSize.Height() * 0.630 ) );
}
maPresRect.SetPos(aLayoutPos);
maPresRect.SetSize(aLayoutSize);
}
constexpr OUString gsPageLayoutNames( u"PageLayoutNames" _ustr );
SdXMLExport::SdXMLExport(
const css::uno::Reference< css::uno::XComponentContext >& xContext,
OUString const & implementationName,
bool bIsDraw, SvXMLExportFlags nExportFlags )
: SvXMLExport( xContext, implementationName, util::MeasureUnit::CM,
bIsDraw ? XML_GRAPHICS : XML_PRESENTATION, nExportFlags ),
mnDocMasterPageCount(0),
mnDocDrawPageCount(0),
mnObjectCount(0),
mpHandoutPageMaster(nullptr),
mbIsDraw(bIsDraw)
{
}
// XExporter
void SAL_CALL SdXMLExport::setSourceDocument( const Reference< lang::XComponent >& xDoc )
{
SvXMLExport::setSourceDocument( xDoc );
// prepare factory parts
mpSdPropHdlFactory = new XMLSdPropHdlFactory( GetModel(), *this );
// construct PropertySetMapper
rtl::Reference < XMLPropertySetMapper > xMapper = new XMLShapePropertySetMapper( mpSdPropHdlFactory, true );
// get or create text paragraph export
GetTextParagraphExport();
mpPropertySetMapper = new XMLShapeExportPropertyMapper( xMapper, *this );
// chain text attributes
mpPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(*this ));
// construct PresPagePropsMapper
xMapper = new XMLPropertySetMapper(aXMLSDPresPageProps, mpSdPropHdlFactory, true );
mpPresPagePropsMapper = new XMLPageExportPropertyMapper( xMapper, *this );
// add family name
GetAutoStylePool()->AddFamily(
XmlStyleFamily::SD_GRAPHICS_ID,
XML_STYLE_FAMILY_SD_GRAPHICS_NAME,
GetPropertySetMapper(),
XML_STYLE_FAMILY_SD_GRAPHICS_PREFIX);
GetAutoStylePool()->AddFamily(
XmlStyleFamily::SD_PRESENTATION_ID,
XML_STYLE_FAMILY_SD_PRESENTATION_NAME,
GetPropertySetMapper(),
XML_STYLE_FAMILY_SD_PRESENTATION_PREFIX);
GetAutoStylePool()->AddFamily(
XmlStyleFamily::SD_DRAWINGPAGE_ID,
XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME,
GetPresPagePropsMapper(),
XML_STYLE_FAMILY_SD_DRAWINGPAGE_PREFIX);
// prepare access to styles
Reference< style::XStyleFamiliesSupplier > xFamSup( GetModel(), UNO_QUERY );
if (xFamSup.is())
{
mxDocStyleFamilies = xFamSup->getStyleFamilies();
}
// prepare access to master pages
Reference < drawing::XMasterPagesSupplier > xMasterPagesSupplier(GetModel(), UNO_QUERY);
if (xMasterPagesSupplier.is())
{
mxDocMasterPages = xMasterPagesSupplier->getMasterPages();
if (mxDocMasterPages.is())
{
mnDocMasterPageCount = mxDocMasterPages->getCount();
maMasterPagesStyleNames.insert( maMasterPagesStyleNames.begin(), mnDocMasterPageCount, u"" _ustr );
}
}
// prepare access to draw pages
Reference <XDrawPagesSupplier> xDrawPagesSupplier(GetModel(), UNO_QUERY);
if (xDrawPagesSupplier.is())
{
mxDocDrawPages = xDrawPagesSupplier->getDrawPages();
if (mxDocDrawPages.is())
{
mnDocDrawPageCount = mxDocDrawPages->getCount();
maDrawPagesStyleNames.insert( maDrawPagesStyleNames.begin(), mnDocDrawPageCount, u"" _ustr );
maDrawNotesPagesStyleNames.insert( maDrawNotesPagesStyleNames.begin(), mnDocDrawPageCount, u"" _ustr );
if ( !mbIsDraw )
maDrawPagesAutoLayoutNames.realloc( mnDocDrawPageCount + 1 );
HeaderFooterPageSettingsImpl aEmptySettings;
maDrawPagesHeaderFooterSettings.insert( maDrawPagesHeaderFooterSettings.begin(), mnDocDrawPageCount, aEmptySettings );
maDrawNotesPagesHeaderFooterSettings.insert( maDrawNotesPagesHeaderFooterSettings.begin(), mnDocDrawPageCount, aEmptySettings );
}
}
// #82003# count all draw objects for use with progress bar.
// #88245# init mnObjectCount once, use counter itself as flag. It
// is initialized to 0.
if (!mnObjectCount)
{
if ( IsImpress() )
{
// #91587# add handout master count
Reference<presentation::XHandoutMasterSupplier> xHandoutSupp(GetModel(), UNO_QUERY);
if (xHandoutSupp.is())
{
Reference<XDrawPage> xHandoutPage(xHandoutSupp->getHandoutMasterPage());
if (xHandoutPage.is() && xHandoutPage->getCount())
mnObjectCount += ImpRecursiveObjectCount(xHandoutPage);
}
}
if (mxDocMasterPages.is())
{
for (sal_Int32 a(0); a < mnDocMasterPageCount; a++)
{
Any aAny(mxDocMasterPages->getByIndex(a));
Reference< drawing::XShapes > xMasterPage;
if ((aAny >>= xMasterPage) && xMasterPage.is())
{
mnObjectCount += ImpRecursiveObjectCount(xMasterPage);
}
if ( IsImpress() )
{
// #91587# take notes pages from master pages into account
Reference<presentation::XPresentationPage> xPresPage;
if ((aAny >>= xPresPage) && xPresPage.is())
{
Reference<XDrawPage> xNotesPage(xPresPage->getNotesPage());
if (xNotesPage.is() && xNotesPage->getCount())
mnObjectCount += ImpRecursiveObjectCount(xNotesPage);
}
}
}
}
if (mxDocDrawPages.is())
{
for (sal_Int32 a(0); a < mnDocDrawPageCount; a++)
{
Any aAny(mxDocDrawPages->getByIndex(a));
Reference< drawing::XShapes > xPage;
if ((aAny >>= xPage) && xPage.is())
{
mnObjectCount += ImpRecursiveObjectCount(xPage);
}
if ( IsImpress() )
{
// #91587# take notes pages from draw pages into account
Reference<presentation::XPresentationPage> xPresPage;
if ((aAny >>= xPresPage) && xPresPage.is())
{
Reference<XDrawPage> xNotesPage(xPresPage->getNotesPage());
if (xNotesPage.is() && xNotesPage->getCount())
mnObjectCount += ImpRecursiveObjectCount(xNotesPage);
}
}
}
}
// #82003# init progress bar
GetProgressBarHelper()->SetReference(mnObjectCount);
}
// add namespaces
GetNamespaceMap_().Add(
GetXMLToken(XML_NP_PRESENTATION),
GetXMLToken(XML_N_PRESENTATION),
XML_NAMESPACE_PRESENTATION);
GetNamespaceMap_().Add(
GetXMLToken(XML_NP_SMIL),
GetXMLToken(XML_N_SMIL_COMPAT),
XML_NAMESPACE_SMIL);
GetNamespaceMap_().Add(
GetXMLToken(XML_NP_ANIMATION),
GetXMLToken(XML_N_ANIMATION),
XML_NAMESPACE_ANIMATION);
if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
{
GetNamespaceMap_().Add(
GetXMLToken(XML_NP_OFFICE_EXT),
GetXMLToken(XML_N_OFFICE_EXT),
XML_NAMESPACE_OFFICE_EXT);
}
GetShapeExport()->enableLayerExport();
// #88546# enable progress bar increments
GetShapeExport()->enableHandleProgressBar();
}
// #82003# helper function for recursive object count
sal_uInt32 SdXMLExport::ImpRecursiveObjectCount(const Reference< drawing::XShapes >& xShapes)
{
sal_uInt32 nRetval(0);
if (xShapes.is())
{
sal_Int32 nCount = xShapes->getCount();
for (sal_Int32 a(0); a < nCount; a++)
{
Any aAny(xShapes->getByIndex(a));
Reference< drawing::XShapes > xGroup;
if ((aAny >>= xGroup) && xGroup.is())
{
// #93180# count group objects, too.
nRetval += 1 + ImpRecursiveObjectCount(xGroup);
}
else
{
nRetval++;
}
}
}
return nRetval;
}
SdXMLExport::~SdXMLExport()
{
// cleanup factory, decrease refcount. Should lead to destruction.
mpSdPropHdlFactory.clear();
// cleanup mapper, decrease refcount. Should lead to destruction.
mpPropertySetMapper.clear();
// cleanup presPage mapper, decrease refcount. Should lead to destruction.
mpPresPagePropsMapper.clear();
mvPageMasterInfoList.clear();
// clear auto-layout infos
mvAutoLayoutInfoList.clear();
}
void SdXMLExport::ImpPrepAutoLayoutInfos()
{
if (!IsImpress())
return ;
OUString aStr;
auto DrawPagesAutoLayoutNamesRange = asNonConstRange(maDrawPagesAutoLayoutNames);
Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
if ( xHandoutSupp.is() )
{
Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
if ( xHandoutPage.is() )
{
if (ImpPrepAutoLayoutInfo(xHandoutPage, aStr))
DrawPagesAutoLayoutNamesRange[0] = aStr;
}
}
// prepare name creation
for (sal_Int32 nCnt = 0; nCnt < mnDocDrawPageCount; nCnt++)
{
Any aAny(mxDocDrawPages->getByIndex(nCnt));
Reference<XDrawPage> xDrawPage;
if ((aAny >>= xDrawPage) && xDrawPage.is())
{
if (ImpPrepAutoLayoutInfo(xDrawPage, aStr))
DrawPagesAutoLayoutNamesRange[nCnt+1] = aStr;
}
}
}
bool SdXMLExport::ImpPrepAutoLayoutInfo(const Reference<XDrawPage>& xPage, OUString& rName)
{
rName.clear();
bool bRetval(false );
Reference <beans::XPropertySet> xPropSet(xPage, UNO_QUERY);
if (xPropSet.is())
{
sal_uInt16 nType = sal_uInt16();
Any aAny = xPropSet->getPropertyValue(u"Layout" _ustr);
if (aAny >>= nType)
{
if (ImpXMLAutoLayoutInfo::IsCreateNecessary(nType))
{
ImpXMLEXPPageMasterInfo* pInfo = nullptr;
// get master-page info
Reference < drawing::XMasterPageTarget > xMasterPageInt(xPage, UNO_QUERY);
if (xMasterPageInt.is())
{
Reference<XDrawPage> xUsedMasterPage(xMasterPageInt->getMasterPage());
if (xUsedMasterPage.is())
{
Reference < container::XNamed > xMasterNamed(xUsedMasterPage, UNO_QUERY);
if (xMasterNamed.is())
{
OUString sMasterPageName = xMasterNamed->getName();
pInfo = ImpGetPageMasterInfoByName(sMasterPageName);
}
}
}
// create entry and look for existence
ImpXMLAutoLayoutInfo* pNew;
auto it = std::find_if(mvAutoLayoutInfoList.begin(), mvAutoLayoutInfoList.end(),
[=](std::unique_ptr<ImpXMLAutoLayoutInfo> const & rInfo) { return nType == rInfo->GetLayoutType() && pInfo == rInfo->GetPageMasterInfo(); });
if (it != mvAutoLayoutInfoList.end())
{
pNew = it->get();
}
else
{
pNew = new ImpXMLAutoLayoutInfo(nType, pInfo);
mvAutoLayoutInfoList.emplace_back( pNew );
OUString sNewName =
"AL" + OUString::number(mvAutoLayoutInfoList.size() - 1) +
"T" + OUString::number(nType);
pNew->SetLayoutName(sNewName);
}
rName = pNew->GetLayoutName();
bRetval = true ;
}
}
}
return bRetval;
}
void SdXMLExport::ImpWriteAutoLayoutInfos()
{
for (const auto & pInfo : mvAutoLayoutInfoList)
{
if (pInfo)
{
// prepare presentation-page layout attributes, style-name
AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, pInfo->GetLayoutName());
// write draw-style attributes
SvXMLElementExport aDSE(*this , XML_NAMESPACE_STYLE, XML_PRESENTATION_PAGE_LAYOUT, true , true );
// write presentation placeholders
switch (pInfo->GetLayoutType())
{
case AUTOLAYOUT_TITLE :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderSubtitle, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_TITLE_CONTENT :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_CHART :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_TITLE_2CONTENT :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
break ;
}
case AUTOLAYOUT_TEXTCHART :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aRight);
break ;
}
case AUTOLAYOUT_TEXTCLIP :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aRight);
break ;
}
case AUTOLAYOUT_CHARTTEXT :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
break ;
}
case AUTOLAYOUT_TAB :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTable, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_CLIPTEXT :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
break ;
}
case AUTOLAYOUT_TEXTOBJ :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRight);
break ;
}
case AUTOLAYOUT_OBJ :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_TITLE_CONTENT_2CONTENT :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRightTop(aLeft);
aRightTop.AdjustLeft(aRightTop.GetWidth() * 1.05);
aRightTop.setHeight(tools::Long (aRightTop.GetHeight() * 0.477));
tools::Rectangle aRightBottom(aRightTop);
aRightBottom.AdjustTop(aRightBottom.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRightTop);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aRightBottom);
break ;
}
case AUTOLAYOUT_OBJTEXT :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
break ;
}
case AUTOLAYOUT_TITLE_CONTENT_OVER_CONTENT :
{
tools::Rectangle aTop(pInfo->GetPresRectangle());
aTop.setHeight(tools::Long (aTop.GetHeight() * 0.477));
tools::Rectangle aBottom(aTop);
aBottom.AdjustTop(aBottom.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTop);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aBottom);
break ;
}
case AUTOLAYOUT_TITLE_2CONTENT_CONTENT :
{
tools::Rectangle aLeftTop(pInfo->GetPresRectangle());
aLeftTop.setWidth(tools::Long (aLeftTop.GetWidth() * 0.488));
tools::Rectangle aRight(aLeftTop);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
aLeftTop.setHeight(tools::Long (aLeftTop.GetHeight() * 0.477));
tools::Rectangle aLeftBottom(aLeftTop);
aLeftBottom.AdjustTop(aLeftBottom.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeftTop);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aLeftBottom);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aRight);
break ;
}
case AUTOLAYOUT_TITLE_2CONTENT_OVER_CONTENT :
{
tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
aTopLeft.setHeight(tools::Long (aTopLeft.GetHeight() * 0.477));
tools::Rectangle aBottom(aTopLeft);
aBottom.AdjustTop(aBottom.GetHeight() * 1.095);
aTopLeft.setWidth(tools::Long (aTopLeft.GetWidth() * 0.488));
tools::Rectangle aTopRight(aTopLeft);
aTopRight.AdjustLeft(aTopRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopRight);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aBottom);
break ;
}
case AUTOLAYOUT_TEXTOVEROBJ :
{
tools::Rectangle aTop(pInfo->GetPresRectangle());
aTop.setHeight(tools::Long (aTop.GetHeight() * 0.477));
tools::Rectangle aBottom(aTop);
aBottom.AdjustTop(aBottom.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderOutline, aTop);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottom);
break ;
}
case AUTOLAYOUT_TITLE_4CONTENT :
{
tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
aTopLeft.setHeight(tools::Long (aTopLeft.GetHeight() * 0.477));
aTopLeft.setWidth(tools::Long (aTopLeft.GetWidth() * 0.488));
tools::Rectangle aBottomLeft(aTopLeft);
aBottomLeft.AdjustTop(aBottomLeft.GetHeight() * 1.095);
tools::Rectangle aTopRight(aTopLeft);
aTopRight.AdjustLeft(aTopRight.GetWidth() * 1.05);
tools::Rectangle aBottomRight(aTopRight);
aBottomRight.AdjustTop(aBottomRight.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aTopRight);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottomLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderObject, aBottomRight);
break ;
}
case AUTOLAYOUT_TITLE_ONLY :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
break ;
}
case AUTOLAYOUT_NOTES :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderPage, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderNotes, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_HANDOUT1 :
case AUTOLAYOUT_HANDOUT2 :
case AUTOLAYOUT_HANDOUT3 :
case AUTOLAYOUT_HANDOUT4 :
case AUTOLAYOUT_HANDOUT6 :
case AUTOLAYOUT_HANDOUT9 :
{
sal_Int32 nColCnt, nRowCnt;
sal_Int32 nGapX = pInfo->GetGapX();
sal_Int32 nGapY = pInfo->GetGapY();
switch (pInfo->GetLayoutType())
{
case 22 : nColCnt = 1; nRowCnt = 1; break ;
case 23 : nColCnt = 1; nRowCnt = 2; break ;
case 24 : nColCnt = 1; nRowCnt = 3; break ;
case 25 : nColCnt = 2; nRowCnt = 2; break ;
case 26 : nColCnt = 3; nRowCnt = 2; break ;
case 31 : nColCnt = 3; nRowCnt = 3; break ;
default : nColCnt = 0; nRowCnt = 0; break ; // FIXME - What is correct values?
}
Size aPartSize(pInfo->GetTitleRectangle().GetSize());
Point aPartPos(pInfo->GetTitleRectangle().TopLeft());
if (aPartSize.Width() > aPartSize.Height())
{
sal_Int32 nZwi(nColCnt);
nColCnt = nRowCnt;
nRowCnt = nZwi;
}
if (nColCnt == 0 || nRowCnt == 0)
break ;
aPartSize.setWidth( (aPartSize.Width() - ((nColCnt - 1) * nGapX)) / nColCnt );
aPartSize.setHeight( (aPartSize.Height() - ((nRowCnt - 1) * nGapY)) / nRowCnt );
Point aTmpPos(aPartPos);
for (sal_Int32 a = 0; a < nRowCnt; a++)
{
aTmpPos.setX(aPartPos.X());
for (sal_Int32 b = 0; b < nColCnt; b++)
{
tools::Rectangle aTmpRect(aTmpPos, aPartSize);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderHandout, aTmpRect);
aTmpPos.AdjustX( aPartSize.Width() + nGapX );
}
aTmpPos.AdjustY( aPartSize.Height() + nGapY );
}
break ;
}
case AUTOLAYOUT_VTITLE_VCONTENT_OVER_VCONTENT :
{
tools::Rectangle aTop(pInfo->GetPresRectangle());
aTop.setHeight(tools::Long (aTop.GetHeight() * 0.488));
tools::Rectangle aBottom(aTop);
aBottom.AdjustTop(aBottom.GetHeight() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, aTop);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderChart, aBottom);
break ;
}
case AUTOLAYOUT_VTITLE_VCONTENT :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_TITLE_VCONTENT :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_TITLE_2VTEXT :
{
tools::Rectangle aLeft(pInfo->GetPresRectangle());
aLeft.setWidth(tools::Long (aLeft.GetWidth() * 0.488));
tools::Rectangle aRight(aLeft);
aRight.AdjustLeft(aRight.GetWidth() * 1.05);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderVerticalOutline, aRight);
break ;
}
case AUTOLAYOUT_ONLY_TEXT :
{
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderSubtitle, pInfo->GetPresRectangle());
break ;
}
case AUTOLAYOUT_4CLIPART :
{
tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
aTopLeft.setHeight(tools::Long (aTopLeft.GetHeight() * 0.477));
aTopLeft.setWidth(tools::Long (aTopLeft.GetWidth() * 0.488));
tools::Rectangle aBottomLeft(aTopLeft);
aBottomLeft.AdjustTop(aBottomLeft.GetHeight() * 1.095);
tools::Rectangle aTopRight(aTopLeft);
aTopRight.AdjustLeft(aTopRight.GetWidth() * 1.05);
tools::Rectangle aBottomRight(aTopRight);
aBottomRight.AdjustTop(aBottomRight.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopRight);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomRight);
break ;
}
case AUTOLAYOUT_TITLE_6CONTENT :
{
tools::Rectangle aTopLeft(pInfo->GetPresRectangle());
aTopLeft.setHeight(tools::Long (aTopLeft.GetHeight() * 0.477));
aTopLeft.setWidth(tools::Long (aTopLeft.GetWidth() * 0.322));
tools::Rectangle aTopCenter(aTopLeft);
aTopCenter.AdjustLeft(aTopCenter.GetWidth() * 1.05);
tools::Rectangle aTopRight(aTopLeft);
aTopRight.AdjustLeft(aTopRight.GetWidth() * 2 * 1.05);
tools::Rectangle aBottomLeft(aTopLeft);
aBottomLeft.AdjustTop(aBottomLeft.GetHeight() * 1.095);
tools::Rectangle aBottomCenter(aTopCenter);
aBottomCenter.AdjustTop(aBottomCenter.GetHeight() * 1.095);
tools::Rectangle aBottomRight(aTopRight);
aBottomRight.AdjustTop(aBottomRight.GetHeight() * 1.095);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderTitle, pInfo->GetTitleRectangle());
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopCenter);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aTopRight);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomLeft);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomCenter);
ImpWriteAutoLayoutPlaceholder(XmlPlaceholderGraphic, aBottomRight);
break ;
}
default :
{
OSL_FAIL("XMLEXP: unknown autolayout export" );
break ;
}
}
}
}
}
void SdXMLExport::ImpWriteAutoLayoutPlaceholder(XmlPlaceholder ePl, const tools::Rectangle& rRect)
{
OUString aStr;
OUStringBuffer sStringBuffer;
// prepare presentation-placeholder attributes, presentation:object
switch (ePl)
{
case XmlPlaceholderTitle: aStr = "title" ; break ;
case XmlPlaceholderOutline: aStr = "outline" ; break ;
case XmlPlaceholderSubtitle: aStr = "subtitle" ; break ;
case XmlPlaceholderGraphic: aStr = "graphic" ; break ;
case XmlPlaceholderObject: aStr = "object" ; break ;
case XmlPlaceholderChart: aStr = "chart" ; break ;
case XmlPlaceholderTable: aStr = "table" ; break ;
case XmlPlaceholderPage: aStr = "page" ; break ;
case XmlPlaceholderNotes: aStr = "notes" ; break ;
case XmlPlaceholderHandout: aStr = "handout" ; break ;
case XmlPlaceholderVerticalTitle: aStr = "vertical_title" ; break ;
case XmlPlaceholderVerticalOutline: aStr = "vertical_outline" ; break ;
}
AddAttribute(XML_NAMESPACE_PRESENTATION, XML_OBJECT, aStr);
// svg:x,y,width,height
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, rRect.Left());
aStr = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_SVG, XML_X, aStr);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer, rRect.Top());
aStr = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_SVG, XML_Y, aStr);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
rRect.GetWidth());
aStr = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStr);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
rRect.GetHeight());
aStr = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStr);
// write presentation-placeholder
SvXMLElementExport aPPL(*this , XML_NAMESPACE_PRESENTATION, XML_PLACEHOLDER, true , true );
}
ImpXMLEXPPageMasterInfo* SdXMLExport::ImpGetOrCreatePageMasterInfo( const Reference< XDrawPage >& xMasterPage )
{
bool bDoesExist = false ;
ImpXMLEXPPageMasterInfo* pNewInfo = new ImpXMLEXPPageMasterInfo(*this , xMasterPage);
// compare with prev page-master infos
for ( size_t a = 0; !bDoesExist && a < mvPageMasterInfoList.size(); a++)
{
if ( mvPageMasterInfoList.at(a)
&& *mvPageMasterInfoList.at(a) == *pNewInfo
)
{
delete pNewInfo;
pNewInfo = mvPageMasterInfoList.at(a).get();
bDoesExist = true ;
}
}
// add entry when not found same page-master infos
if (!bDoesExist)
mvPageMasterInfoList.emplace_back( pNewInfo );
return pNewInfo;
}
void SdXMLExport::ImpPrepPageMasterInfos()
{
if ( IsImpress() )
{
// create page master info for handout master page
Reference< XHandoutMasterSupplier > xHMS( GetModel(), UNO_QUERY );
if ( xHMS.is() )
{
Reference< XDrawPage > xMasterPage( xHMS->getHandoutMasterPage() );
if ( xMasterPage.is() )
mpHandoutPageMaster = ImpGetOrCreatePageMasterInfo(xMasterPage);
}
}
// create page master infos for master pages
if (!mnDocMasterPageCount)
return ;
// look for needed page-masters, create these
for (sal_Int32 nMPageId = 0; nMPageId < mnDocMasterPageCount; nMPageId++)
{
Reference< XDrawPage > xMasterPage( mxDocMasterPages->getByIndex(nMPageId), UNO_QUERY );
ImpXMLEXPPageMasterInfo* pNewInfo = nullptr;
if (xMasterPage.is())
pNewInfo = ImpGetOrCreatePageMasterInfo(xMasterPage);
mvPageMasterUsageList.push_back( pNewInfo );
// look for page master of handout page
if (IsImpress())
{
pNewInfo = nullptr;
Reference< presentation::XPresentationPage > xPresPage(xMasterPage, UNO_QUERY);
if (xPresPage.is())
{
Reference< XDrawPage > xNotesPage(xPresPage->getNotesPage());
if (xNotesPage.is())
{
pNewInfo = ImpGetOrCreatePageMasterInfo(xNotesPage);
}
}
mvNotesPageMasterUsageList.push_back( pNewInfo );
}
}
}
void SdXMLExport::ImpWritePageMasterInfos()
{
// write created page-masters, create names for these
for ( size_t nCnt = 0; nCnt < mvPageMasterInfoList.size(); nCnt++)
{
ImpXMLEXPPageMasterInfo* pInfo = mvPageMasterInfoList.at(nCnt).get();
if (pInfo)
{
// create name
OUString sNewName = "PM" + OUString::number(nCnt);
pInfo->SetName(sNewName);
// prepare page-master attributes
OUString sString;
OUStringBuffer sStringBuffer;
sString = sNewName;
AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sString);
// write page-layout
SvXMLElementExport aPME(*this , XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT, true , true );
// prepare style:properties inside page-master
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
pInfo->GetBorderTop());
sString = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_TOP, sString);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
pInfo->GetBorderBottom());
sString = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_BOTTOM, sString);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
pInfo->GetBorderLeft());
sString = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_LEFT, sString);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
pInfo->GetBorderRight());
sString = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_FO, XML_MARGIN_RIGHT, sString);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
pInfo->GetWidth());
sString = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_FO, XML_PAGE_WIDTH, sString);
GetMM100UnitConverter().convertMeasureToXML(sStringBuffer,
pInfo->GetHeight());
sString = sStringBuffer.makeStringAndClear();
AddAttribute(XML_NAMESPACE_FO, XML_PAGE_HEIGHT, sString);
if (pInfo->GetOrientation() == view::PaperOrientation_PORTRAIT)
AddAttribute(XML_NAMESPACE_STYLE, XML_PRINT_ORIENTATION, XML_PORTRAIT);
else
AddAttribute(XML_NAMESPACE_STYLE, XML_PRINT_ORIENTATION, XML_LANDSCAPE);
// write style:properties
SvXMLElementExport aPMF(*this , XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_PROPERTIES, true , true );
}
}
}
ImpXMLEXPPageMasterInfo* SdXMLExport::ImpGetPageMasterInfoByName(std::u16string_view rName)
{
if (!rName.empty())
{
for (const auto & pInfo : mvPageMasterInfoList)
{
if (pInfo)
{
if (!pInfo->GetMasterPageName().isEmpty() && rName == pInfo->GetMasterPageName())
{
return pInfo.get();
}
}
}
}
return nullptr;
}
void SdXMLExport::ImpPrepDrawPageInfos()
{
// create draw:style-name entries for page export
// containing presentation page attributes AND background attributes
// fixed family for page-styles is "drawing-page" (XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)
sal_Int32 nCnt;
for (nCnt = 0; nCnt < mnDocDrawPageCount; nCnt++)
{
Reference<XDrawPage> xDrawPage;
mxDocDrawPages->getByIndex(nCnt) >>= xDrawPage;
maDrawPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xDrawPage );
Reference< presentation::XPresentationPage > xPresPage(xDrawPage, UNO_QUERY);
if (xPresPage.is())
{
maDrawNotesPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xPresPage->getNotesPage(), false );
maDrawPagesHeaderFooterSettings[nCnt] = ImpPrepDrawPageHeaderFooterDecls( xDrawPage );
maDrawNotesPagesHeaderFooterSettings[nCnt] = ImpPrepDrawPageHeaderFooterDecls( xPresPage->getNotesPage() );
}
}
}
static OUString findOrAppendImpl( std::vector< OUString >& rVector, const OUString& rText, std::u16string_view pPrefix )
{
// search rVector if there is already a string that equals rText
auto aIter = std::find(rVector.begin(), rVector.end(), rText);
sal_Int32 nIndex = std::distance(rVector.begin(), aIter) + 1;
// if nothing is found, append the string at the end of rVector
if ( aIter == rVector.end() )
rVector.push_back( rText );
// create a reference string with pPrefix and the index of the
// found or created rText
return pPrefix + OUString::number( nIndex );
}
static OUString findOrAppendImpl( std::vector< DateTimeDeclImpl >& rVector, const OUString& rText, bool bFixed, sal_Int32 nFormat, std::u16string_view pPrefix )
{
// search rVector if there is already a DateTimeDeclImpl with rText,bFixed and nFormat
auto aIter = std::find_if(rVector.begin(), rVector.end(),
[bFixed, &rText, nFormat](const DateTimeDeclImpl& rDecl) {
return (rDecl.mbFixed == bFixed) &&
(!bFixed || (rDecl.maStrText == rText)) &&
(bFixed || (rDecl.mnFormat == nFormat));
});
sal_Int32 nIndex = std::distance(rVector.begin(), aIter) + 1;
// if nothing is found, append a new DateTimeDeclImpl
if ( aIter == rVector.end() )
{
DateTimeDeclImpl aDecl;
aDecl.maStrText = rText;
aDecl.mbFixed = bFixed;
aDecl.mnFormat = nFormat;
rVector.push_back( aDecl );
}
// create a reference string with pPrefix and the index of the
// found or created DateTimeDeclImpl
return pPrefix + OUString::number( nIndex );
}
constexpr OUString gpStrHeaderTextPrefix = u"hdr" _ustr;
constexpr OUString gpStrFooterTextPrefix = u"ftr" _ustr;
constexpr OUString gpStrDateTimeTextPrefix = u"dtd" _ustr;
HeaderFooterPageSettingsImpl SdXMLExport::ImpPrepDrawPageHeaderFooterDecls( const Reference<XDrawPage>& xDrawPage )
{
HeaderFooterPageSettingsImpl aSettings;
if ( xDrawPage.is() ) try
{
Reference< XPropertySet > xSet( xDrawPage, UNO_QUERY_THROW );
Reference< XPropertySetInfo > xInfo( xSet->getPropertySetInfo() );
OUString aStrText;
static constexpr OUString aStrHeaderTextProp( u"HeaderText" _ustr );
if ( xInfo->hasPropertyByName( aStrHeaderTextProp ) )
{
xSet->getPropertyValue( aStrHeaderTextProp ) >>= aStrText;
if ( !aStrText.isEmpty() )
aSettings.maStrHeaderDeclName = findOrAppendImpl( maHeaderDeclsVector, aStrText, gpStrHeaderTextPrefix );
}
static constexpr OUString aStrFooterTextProp( u"FooterText" _ustr );
if ( xInfo->hasPropertyByName( aStrFooterTextProp ) )
{
xSet->getPropertyValue( aStrFooterTextProp ) >>= aStrText;
if ( !aStrText.isEmpty() )
aSettings.maStrFooterDeclName = findOrAppendImpl( maFooterDeclsVector, aStrText, gpStrFooterTextPrefix );
}
static constexpr OUString aStrDateTimeTextProp( u"DateTimeText" _ustr );
if ( xInfo->hasPropertyByName( aStrDateTimeTextProp ) )
{
bool bFixed = false ;
sal_Int32 nFormat = 0;
xSet->getPropertyValue( aStrDateTimeTextProp ) >>= aStrText;
xSet->getPropertyValue(u"IsDateTimeFixed" _ustr) >>= bFixed;
xSet->getPropertyValue(u"DateTimeFormat" _ustr) >>= nFormat;
if ( !bFixed || !aStrText.isEmpty() )
{
aSettings.maStrDateTimeDeclName = findOrAppendImpl( maDateTimeDeclsVector, aStrText, bFixed, nFormat, gpStrDateTimeTextPrefix );
if ( !bFixed )
addDataStyle( nFormat );
}
}
}
catch (const Exception&)
{
TOOLS_WARN_EXCEPTION("xmloff.draw" , "" );
}
return aSettings;
}
void SdXMLExport::ImpWriteHeaderFooterDecls()
{
OUStringBuffer sBuffer;
if ( !maHeaderDeclsVector.empty() )
{
// export header decls
const OUString aPrefix( gpStrHeaderTextPrefix );
sal_Int32 nIndex = 1;
for ( const auto & rDecl : maHeaderDeclsVector )
{
sBuffer.append( aPrefix + OUString::number( nIndex ) );
AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());
SvXMLElementExport aElem(*this , XML_NAMESPACE_PRESENTATION, XML_HEADER_DECL, true , true );
Characters(rDecl);
++nIndex;
}
}
if ( !maFooterDeclsVector.empty() )
{
// export footer decls
const OUString aPrefix( gpStrFooterTextPrefix );
sal_Int32 nIndex = 1;
for ( const auto & rDecl : maFooterDeclsVector )
{
sBuffer.append( aPrefix + OUString::number( nIndex ) );
AddAttribute(XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());
SvXMLElementExport aElem(*this , XML_NAMESPACE_PRESENTATION, XML_FOOTER_DECL, false , false );
Characters(rDecl);
++nIndex;
}
}
if ( maDateTimeDeclsVector.empty() )
return ;
// export footer decls
const OUString aPrefix( gpStrDateTimeTextPrefix );
sal_Int32 nIndex = 1;
for ( const auto & rDecl : maDateTimeDeclsVector )
{
sBuffer.append( aPrefix + OUString::number( nIndex ) );
AddAttribute( XML_NAMESPACE_PRESENTATION, XML_NAME, sBuffer.makeStringAndClear());
AddAttribute( XML_NAMESPACE_PRESENTATION, XML_SOURCE, rDecl.mbFixed ? XML_FIXED : XML_CURRENT_DATE );
if ( !rDecl.mbFixed )
AddAttribute( XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, getDataStyleName( rDecl.mnFormat ) );
SvXMLElementExport aElem(*this , XML_NAMESPACE_PRESENTATION, XML_DATE_TIME_DECL, false , false );
if ( rDecl.mbFixed )
Characters(rDecl.maStrText);
++nIndex;
}
}
void SdXMLExport::ImplExportHeaderFooterDeclAttributes( const HeaderFooterPageSettingsImpl& aSettings )
{
if ( !aSettings.maStrHeaderDeclName.isEmpty() )
AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_HEADER_NAME, aSettings.maStrHeaderDeclName );
if ( !aSettings.maStrFooterDeclName.isEmpty() )
AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_FOOTER_NAME, aSettings.maStrFooterDeclName );
if ( !aSettings.maStrDateTimeDeclName.isEmpty() )
AddAttribute( XML_NAMESPACE_PRESENTATION, XML_USE_DATE_TIME_NAME, aSettings.maStrDateTimeDeclName );
}
OUString SdXMLExport::ImpCreatePresPageStyleName( const Reference<XDrawPage>& xDrawPage, bool bExportBackground /* = true */ )
{
// create name
OUString sStyleName;
// create style for this page and add to auto style pool
Reference< beans::XPropertySet > xPropSet1(xDrawPage, UNO_QUERY);
if (xPropSet1.is())
{
Reference< beans::XPropertySet > xPropSet;
if ( bExportBackground )
{
// since the background items are in a different propertyset
// which itself is a property of the pages property set
// we now merge these two propertysets if possible to simulate
// a single propertyset with all draw page properties
static constexpr OUString aBackground(u"Background" _ustr);
Reference< beans::XPropertySet > xPropSet2;
Reference< beans::XPropertySetInfo > xInfo( xPropSet1->getPropertySetInfo() );
if ( xInfo.is() && xInfo->hasPropertyByName( aBackground ) )
{
Any aAny( xPropSet1->getPropertyValue( aBackground ) );
aAny >>= xPropSet2;
}
if ( xPropSet2.is() )
xPropSet = PropertySetMerger_CreateInstance( xPropSet1, xPropSet2 );
else
xPropSet = std::move(xPropSet1);
}
else
{
xPropSet = std::move(xPropSet1);
}
const rtl::Reference< SvXMLExportPropertyMapper > aMapperRef( GetPresPagePropsMapper() );
std::vector<XMLPropertyState> aPropStates(aMapperRef->Filter(*this , xPropSet));
if ( !aPropStates.empty() )
{
// there are filtered properties -> hard attributes
// try to find this style in AutoStylePool
sStyleName = GetAutoStylePool()->Find(XmlStyleFamily::SD_DRAWINGPAGE_ID, sStyleName, aPropStates);
if (sStyleName.isEmpty())
{
// Style did not exist, add it to AutoStalePool
sStyleName = GetAutoStylePool()->Add(XmlStyleFamily::SD_DRAWINGPAGE_ID, sStyleName, std::move(aPropStates));
}
}
}
return sStyleName;
}
void SdXMLExport::ImpPrepMasterPageInfos()
{
// create draw:style-name entries for master page export
// containing only background attributes
// fixed family for page-styles is "drawing-page" (XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME)
sal_Int32 nCnt;
for ( nCnt = 0; nCnt < mnDocMasterPageCount; nCnt++)
{
Reference<XDrawPage> xDrawPage;
mxDocMasterPages->getByIndex(nCnt) >>= xDrawPage;
maMasterPagesStyleNames[nCnt] = ImpCreatePresPageStyleName( xDrawPage );
}
if ( !IsImpress() )
return ;
Reference< presentation::XHandoutMasterSupplier > xHandoutSupp( GetModel(), UNO_QUERY );
if ( xHandoutSupp.is() )
{
Reference< XDrawPage > xHandoutPage( xHandoutSupp->getHandoutMasterPage() );
if ( xHandoutPage.is() )
{
maHandoutPageHeaderFooterSettings = ImpPrepDrawPageHeaderFooterDecls( xHandoutPage );
maHandoutMasterStyleName = ImpCreatePresPageStyleName( xHandoutPage, false );
}
}
}
void SdXMLExport::ImpWritePresentationStyles()
{
if (!IsImpress())
return ;
for (sal_Int32 nCnt = 0; nCnt < mnDocMasterPageCount; nCnt++)
{
Any aAny(mxDocMasterPages->getByIndex(nCnt));
Reference<container::XNamed> xNamed;
if (aAny >>= xNamed)
{
// write presentation styles (ONLY if presentation)
if (IsImpress() && mxDocStyleFamilies.is() && xNamed.is())
{
rtl::Reference<XMLStyleExport> aStEx(new XMLStyleExport(*this , GetAutoStylePool().get()));
const rtl::Reference< SvXMLExportPropertyMapper > aMapperRef( GetPropertySetMapper() );
OUString aPrefix( xNamed->getName() + "-" );
aStEx->exportStyleFamily(xNamed->getName(),
XML_STYLE_FAMILY_SD_PRESENTATION_NAME,
aMapperRef, false ,
XmlStyleFamily::SD_PRESENTATION_ID, &aPrefix);
}
}
}
}
void SdXMLExport::ExportMeta_()
{
uno::Sequence<beans::NamedValue> stats { { u"ObjectCount" _ustr, uno::Any(mnObjectCount) } };
// update document statistics at the model
uno::Reference<document::XDocumentPropertiesSupplier> xPropSup(GetModel(),
uno::UNO_QUERY_THROW);
uno::Reference<document::XDocumentProperties> xDocProps(
xPropSup->getDocumentProperties());
if (xDocProps.is()) {
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=95 H=97 G=95
¤ Dauer der Verarbeitung: 0.18 Sekunden
¤
*© Formatika GbR, Deutschland
2026-04-02