tdf#103602 xmloff,sw: ODF 1.3 export: PageStyle with drawing-page style

Associate a style of family "drawing-page" with a style:master-page.

This fixes the small part of the draw:fill attribute problem that is
covered by OFFICE-3937 in ODF 1.3.

Exporting the "drawing-page" style is only allowed in ODF 1.3; all
property map entries have ODFSVER_ODF013 and this causes no style
to be exported for earlier versions.

Continue to export the invalid draw:fill attributes on the
style:page-layout for now, until the import of this is more widely
deployed.

This only works with Writer, because Calc doesn't implement FillStyle
properties on its page styles.

Change-Id: I4b24ae3eaf332723e24671e594eca5e36d48f525
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93671
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
diff --git a/include/xmloff/XMLPageExport.hxx b/include/xmloff/XMLPageExport.hxx
index 9800502..73a60ef 100644
--- a/include/xmloff/XMLPageExport.hxx
+++ b/include/xmloff/XMLPageExport.hxx
@@ -44,6 +44,7 @@ class SvXMLExportPropertyMapper;
struct XMLPageExportNameEntry
{
    OUString         sPageMasterName;
    OUString         sDrawingPageStyleName;
    OUString         sStyleName;
};

@@ -55,11 +56,12 @@ class XMLOFF_DLLPUBLIC XMLPageExport : public salhelper::SimpleReferenceObject
    css::uno::Reference< css::container::XNameAccess > xPageStyles;

    ::std::vector< XMLPageExportNameEntry > aNameVector;
    SAL_DLLPRIVATE bool findPageMasterName( const OUString& rStyleName, OUString& rPMName ) const;

    rtl::Reference < XMLPropertyHandlerFactory > xPageMasterPropHdlFactory;
    rtl::Reference < XMLPropertySetMapper > xPageMasterPropSetMapper;
    rtl::Reference < SvXMLExportPropertyMapper > xPageMasterExportPropMapper;
    rtl::Reference<XMLPropertySetMapper> m_xPageMasterDrawingPagePropSetMapper;
    rtl::Reference<SvXMLExportPropertyMapper> m_xPageMasterDrawingPageExportPropMapper;

protected:

@@ -67,7 +69,7 @@ protected:

    void collectPageMasterAutoStyle(
                const css::uno::Reference< css::beans::XPropertySet > & rPropSet,
                OUString& rPageMasterName );
                XMLPageExportNameEntry & rEntry);

    virtual void exportMasterPageContent(
                const css::uno::Reference< css::beans::XPropertySet > & rPropSet,
diff --git a/xmloff/source/style/XMLPageExport.cxx b/xmloff/source/style/XMLPageExport.cxx
index 56f7bf7..c0d416d 100644
--- a/xmloff/source/style/XMLPageExport.cxx
+++ b/xmloff/source/style/XMLPageExport.cxx
@@ -44,23 +44,29 @@ using namespace ::xmloff::token;
static const OUStringLiteral gsIsPhysical( "IsPhysical" );
static const OUStringLiteral gsFollowStyle( "FollowStyle" );

bool XMLPageExport::findPageMasterName( const OUString& rStyleName, OUString& rPMName ) const
namespace {

bool findPageMasterNameEntry(
        ::std::vector<XMLPageExportNameEntry> const& aNameVector,
        const OUString& rStyleName, XMLPageExportNameEntry & o_rEntry)
{
    auto pEntry = std::find_if(aNameVector.cbegin(), aNameVector.cend(),
        [&rStyleName](const XMLPageExportNameEntry& rEntry) { return rEntry.sStyleName == rStyleName; });

    if( pEntry != aNameVector.cend() )
    {
        rPMName = pEntry->sPageMasterName;
        o_rEntry = *pEntry;
        return true;
    }

    return false;
}

} // namespace

void XMLPageExport::collectPageMasterAutoStyle(
        const Reference < XPropertySet > & rPropSet,
        OUString& rPageMasterName )
        XMLPageExportNameEntry & rEntry)
{
    SAL_WARN_IF( !xPageMasterPropSetMapper.is(), "xmloff", "page master family/XMLPageMasterPropSetMapper not found" );
    if( xPageMasterPropSetMapper.is() )
@@ -69,9 +75,23 @@ void XMLPageExport::collectPageMasterAutoStyle(
        if( !aPropStates.empty())
        {
            OUString sParent;
            rPageMasterName = rExport.GetAutoStylePool()->Find( XmlStyleFamily::PAGE_MASTER, sParent, aPropStates );
            if (rPageMasterName.isEmpty())
                rPageMasterName = rExport.GetAutoStylePool()->Add(XmlStyleFamily::PAGE_MASTER, sParent, aPropStates);
            rEntry.sPageMasterName = rExport.GetAutoStylePool()->Find( XmlStyleFamily::PAGE_MASTER, sParent, aPropStates );
            if (rEntry.sPageMasterName.isEmpty())
            {
                rEntry.sPageMasterName = rExport.GetAutoStylePool()->Add(XmlStyleFamily::PAGE_MASTER, sParent, aPropStates);
            }
        }
    }
    assert(m_xPageMasterDrawingPageExportPropMapper.is());
    ::std::vector<XMLPropertyState> const aPropStates(
            m_xPageMasterDrawingPageExportPropMapper->Filter(rPropSet));
    if (!aPropStates.empty())
    {
        OUString sParent;
        rEntry.sDrawingPageStyleName = rExport.GetAutoStylePool()->Find(XmlStyleFamily::SD_DRAWINGPAGE_ID, sParent, aPropStates);
        if (rEntry.sDrawingPageStyleName.isEmpty())
        {
            rEntry.sDrawingPageStyleName = rExport.GetAutoStylePool()->Add(XmlStyleFamily::SD_DRAWINGPAGE_ID, sParent, aPropStates);
        }
    }
}
@@ -102,7 +122,7 @@ bool XMLPageExport::exportStyle(
    if( bAutoStyles )
    {
        XMLPageExportNameEntry aEntry;
        collectPageMasterAutoStyle( xPropSet, aEntry.sPageMasterName );
        collectPageMasterAutoStyle(xPropSet, aEntry);
        aEntry.sStyleName = rStyle->getName();
        aNameVector.push_back( aEntry );

@@ -131,9 +151,15 @@ bool XMLPageExport::exportStyle(
            GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
                                   sName);

        OUString sPMName;
        if( findPageMasterName( sName, sPMName ) )
            GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, GetExport().EncodeStyleName( sPMName ) );
        XMLPageExportNameEntry entry;
        if (findPageMasterNameEntry(aNameVector, sName, entry))
        {
            GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_PAGE_LAYOUT_NAME, GetExport().EncodeStyleName(entry.sPageMasterName));
            if (!entry.sDrawingPageStyleName.isEmpty())
            {
                GetExport().AddAttribute(XML_NAMESPACE_DRAW, XML_STYLE_NAME, GetExport().EncodeStyleName(entry.sDrawingPageStyleName));
            }
        }

        Reference<XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo();
        if ( xInfo.is() && xInfo->hasPropertyByName(gsFollowStyle) )
@@ -157,18 +183,25 @@ bool XMLPageExport::exportStyle(
    return true;
}

XMLPageExport::XMLPageExport( SvXMLExport& rExp ) :
    rExport( rExp )
{
    xPageMasterPropHdlFactory = new XMLPageMasterPropHdlFactory;
    xPageMasterPropSetMapper = new XMLPageMasterPropSetMapper(
XMLPageExport::XMLPageExport(SvXMLExport & rExp)
    : rExport(rExp)
    , xPageMasterPropHdlFactory(new XMLPageMasterPropHdlFactory)
    , xPageMasterPropSetMapper(new XMLPageMasterPropSetMapper(
                                aXMLPageMasterStyleMap,
                                xPageMasterPropHdlFactory );
    xPageMasterExportPropMapper = new XMLPageMasterExportPropMapper(
                                    xPageMasterPropSetMapper, rExp);

                                xPageMasterPropHdlFactory))
    , xPageMasterExportPropMapper(new XMLPageMasterExportPropMapper(
                                    xPageMasterPropSetMapper, rExp))
    , m_xPageMasterDrawingPagePropSetMapper(new XMLPageMasterPropSetMapper(
                                g_XMLPageMasterDrawingPageStyleMap,
                                xPageMasterPropHdlFactory))
      // use same class but with different map, need its ContextFilter()
    , m_xPageMasterDrawingPageExportPropMapper(new XMLPageMasterExportPropMapper(
                m_xPageMasterDrawingPagePropSetMapper, rExp))
{
    rExport.GetAutoStylePool()->AddFamily( XmlStyleFamily::PAGE_MASTER, XML_STYLE_FAMILY_PAGE_MASTER_NAME,
        xPageMasterExportPropMapper, XML_STYLE_FAMILY_PAGE_MASTER_PREFIX, false );
    rExport.GetAutoStylePool()->AddFamily(XmlStyleFamily::SD_DRAWINGPAGE_ID, XML_STYLE_FAMILY_SD_DRAWINGPAGE_NAME,
        m_xPageMasterDrawingPageExportPropMapper, XML_STYLE_FAMILY_SD_DRAWINGPAGE_PREFIX);

    Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(),
                                                       UNO_QUERY );
@@ -215,6 +248,9 @@ void XMLPageExport::exportStyles( bool bUsed, bool bAutoStyles )
void XMLPageExport::exportAutoStyles()
{
    rExport.GetAutoStylePool()->exportXML(XmlStyleFamily::PAGE_MASTER);
    // tdf#103602 this is called by both Writer and Calc but Calc doesn't
    // have fill properties yet
    rExport.GetAutoStylePool()->exportXML(XmlStyleFamily::SD_DRAWINGPAGE_ID);
}

void XMLPageExport::exportDefaultStyle()