sw floattable: teach the ODT filter about SwFormatFlySplit

Map the IsSplitAllowed text frame property to <draw:frame
loext:may-break-between-pages="...">. This is meant to be always a
direct formatting, so doesn't go to the style / autostyle.

Change-Id: I439fe372271e4b7db511b5e2150e2a3c2e0acf25
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147499
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna 2023-02-23 08:21:46 +01:00
parent 988cdcc186
commit 2da16ff9f0
8 changed files with 110 additions and 1 deletions

View File

@ -3511,6 +3511,8 @@ namespace xmloff::token {
XML_FILL_USE_SLIDE_BACKGROUND, XML_FILL_USE_SLIDE_BACKGROUND,
XML_MAY_BREAK_BETWEEN_PAGES,
XML_TOKEN_END XML_TOKEN_END
}; };

View File

@ -3477,13 +3477,19 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
</rng:optional> </rng:optional>
</rng:define> </rng:define>
<!-- https://issues.oasis-open.org/browse/OFFICE-4136 -->
<rng:define name="draw-frame-attlist" combine="interleave"> <rng:define name="draw-frame-attlist" combine="interleave">
<!-- https://issues.oasis-open.org/browse/OFFICE-4136 -->
<rng:optional> <rng:optional>
<rng:attribute name="loext:decorative"> <rng:attribute name="loext:decorative">
<rng:ref name="boolean"/> <rng:ref name="boolean"/>
</rng:attribute> </rng:attribute>
</rng:optional> </rng:optional>
<!-- TODO(vmiklos) no proposal for multi-page floating tables -->
<rng:optional>
<rng:attribute name="loext:may-break-between-pages">
<rng:ref name="boolean"/>
</rng:attribute>
</rng:optional>
</rng:define> </rng:define>
</rng:grammar> </rng:grammar>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:styles>
<style:style style:name="Frame" style:family="graphic"/>
</office:styles>
<office:automatic-styles>
<style:style style:name="Table1" style:family="table">
<style:table-properties style:width="6.743cm"/>
</style:style>
<style:style style:name="Table1.A" style:family="table-column">
<style:table-column-properties style:column-width="6.743cm"/>
</style:style>
<style:style style:name="Table1.1" style:family="table-row">
<style:table-row-properties style:min-row-height="3.196cm"/>
</style:style>
<style:style style:name="fr1" style:family="graphic" style:parent-style-name="Frame">
<style:graphic-properties fo:margin-left="0.318cm" fo:margin-right="0.318cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none"/>
</style:style>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="21.59cm" fo:page-height="10.941cm" fo:margin-top="2.54cm" fo:margin-bottom="2.54cm" fo:margin-left="2.54cm" fo:margin-right="2.54cm"/>
</style:page-layout>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="pm1"/>
</office:master-styles>
<office:body>
<office:text>
<text:p><draw:frame draw:style-name="fr1" draw:name="Frame1" text:anchor-type="paragraph" svg:x="-0.009cm" svg:y="0.002cm" svg:width="6.743cm" draw:z-index="0" loext:may-break-between-pages="true"><draw:text-box fo:min-height="0cm"><table:table table:name="Table1" table:style-name="Table1"><table:table-column table:style-name="Table1.A"/><table:table-row table:style-name="Table1.1"><table:table-cell office:value-type="string"><text:p>A1</text:p></table:table-cell></table:table-row><table:table-row table:style-name="Table1.1"><table:table-cell office:value-type="string"><text:p>A2</text:p></table:table-cell></table:table-row></table:table></draw:text-box></draw:frame>anchor text</text:p>
</office:text>
</office:body>
</office:document>

View File

@ -17,6 +17,7 @@
#include <com/sun/star/text/TextContentAnchorType.hpp> #include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/text/XTextFramesSupplier.hpp>
#include <comphelper/propertysequence.hxx> #include <comphelper/propertysequence.hxx>
#include <comphelper/propertyvalue.hxx> #include <comphelper/propertyvalue.hxx>
@ -956,6 +957,56 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testThemeExport)
"#c0c0c0"); "#c0c0c0");
} }
CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFloatingTableExport)
{
// Given a document with a floating table:
mxComponent = loadFromDesktop("private:factory/swriter");
// Insert a table:
uno::Sequence<beans::PropertyValue> aArgs = {
comphelper::makePropertyValue("Rows", static_cast<sal_Int32>(1)),
comphelper::makePropertyValue("Columns", static_cast<sal_Int32>(1)),
};
dispatchCommand(mxComponent, ".uno:InsertTable", aArgs);
// Select it:
dispatchCommand(mxComponent, ".uno:SelectAll", {});
// Wrap in a fly:
aArgs = {
comphelper::makePropertyValue("AnchorType", static_cast<sal_uInt16>(0)),
};
dispatchCommand(mxComponent, ".uno:InsertFrame", aArgs);
// Mark it as a floating table:
uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xFrame(
xTextFramesSupplier->getTextFrames()->getByName("Frame1"), uno::UNO_QUERY);
xFrame->setPropertyValue("IsSplitAllowed", uno::Any(true));
// When saving to ODT:
save("writer8");
// Then make sure we write a floating table, not a textframe containing a table:
xmlDocUniquePtr pXmlDoc = parseExport("content.xml");
// Without the accompanying fix in place, this test would have failed with:
// - XPath '//draw:frame' no attribute 'may-break-between-pages' exist
// i.e. no floating table was exported.
assertXPath(pXmlDoc, "//draw:frame", "may-break-between-pages", "true");
}
CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFloatingTableImport)
{
// Given a document with a floating table (loext:may-break-between-pages="true"), when importing
// that document:
loadFromURL(u"floattable.fodt");
// Then make sure that the matching text frame property is set:
uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<beans::XPropertySet> xFrame(
xTextFramesSupplier->getTextFrames()->getByName("Frame1"), uno::UNO_QUERY);
bool bIsSplitAllowed = false;
// Without the accompanying fix in place, this test would have failed, the property was false.
xFrame->getPropertyValue("IsSplitAllowed") >>= bIsSplitAllowed;
CPPUNIT_ASSERT(bIsSplitAllowed);
}
CPPUNIT_PLUGIN_IMPLEMENT(); CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View File

@ -3514,6 +3514,8 @@ namespace xmloff::token {
TOKEN("fill-use-slide-background", XML_FILL_USE_SLIDE_BACKGROUND), TOKEN("fill-use-slide-background", XML_FILL_USE_SLIDE_BACKGROUND),
TOKEN("may-break-between-pages", XML_MAY_BREAK_BETWEEN_PAGES),
#if OSL_DEBUG_LEVEL > 0 #if OSL_DEBUG_LEVEL > 0
{ 0, nullptr, std::nullopt, XML_TOKEN_END } { 0, nullptr, std::nullopt, XML_TOKEN_END }
#else #else

View File

@ -370,6 +370,7 @@ class XMLTextFrameContext_Impl : public SvXMLImportContext
bool bOwnBase64Stream : 1; bool bOwnBase64Stream : 1;
bool mbMultipleContent : 1; // This context is created based on a multiple content (image) bool mbMultipleContent : 1; // This context is created based on a multiple content (image)
bool m_isDecorative = false; bool m_isDecorative = false;
bool m_isSplitAllowed = false;
void Create(); void Create();
@ -687,6 +688,11 @@ void XMLTextFrameContext_Impl::Create()
xPropSet->setPropertyValue("Decorative", uno::Any(true)); xPropSet->setPropertyValue("Decorative", uno::Any(true));
} }
if (m_isSplitAllowed && xPropSetInfo->hasPropertyByName("IsSplitAllowed"))
{
xPropSet->setPropertyValue("IsSplitAllowed", uno::Any(true));
}
if( XML_TEXT_FRAME_OBJECT != nType && if( XML_TEXT_FRAME_OBJECT != nType &&
XML_TEXT_FRAME_OBJECT_OLE != nType && XML_TEXT_FRAME_OBJECT_OLE != nType &&
XML_TEXT_FRAME_APPLET != nType && XML_TEXT_FRAME_APPLET != nType &&
@ -1073,6 +1079,10 @@ XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
case XML_ELEMENT(DRAW, XML_DECORATIVE): case XML_ELEMENT(DRAW, XML_DECORATIVE):
::sax::Converter::convertBool(m_isDecorative, aIter.toString()); ::sax::Converter::convertBool(m_isDecorative, aIter.toString());
break; break;
case XML_ELEMENT(LO_EXT, XML_MAY_BREAK_BETWEEN_PAGES):
case XML_ELEMENT(DRAW, XML_MAY_BREAK_BETWEEN_PAGES):
sax::Converter::convertBool(m_isSplitAllowed, aIter.toString());
break;
default: default:
SAL_INFO("xmloff", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << " value=" << aIter.toString()); SAL_INFO("xmloff", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(aIter.getToken()) << " value=" << aIter.toString());
} }

View File

@ -3015,6 +3015,12 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes(
GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_DECORATIVE, XML_TRUE); GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_DECORATIVE, XML_TRUE);
} }
if (xPropSetInfo->hasPropertyByName("IsSplitAllowed")
&& rPropSet->getPropertyValue("IsSplitAllowed").get<bool>())
{
GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_MAY_BREAK_BETWEEN_PAGES, XML_TRUE);
}
return nShapeFeatures; return nShapeFeatures;
} }

View File

@ -3255,4 +3255,5 @@ plain-text
alias alias
tag tag
fill-use-slide-background fill-use-slide-background
may-break-between-pages
TOKEN_END_DUMMY TOKEN_END_DUMMY