xmloff/Library_xo.mk                       |    1 
 xmloff/qa/unit/data/clearing-break.fodt    |   28 +++++++++++++
 xmloff/qa/unit/text.cxx                    |   36 +++++++++++++++++
 xmloff/source/text/txtparai.cxx            |   10 ++++
 xmloff/source/text/xmllinebreakcontext.cxx |   59 +++++++++++++++++++++++++++++
 xmloff/source/text/xmllinebreakcontext.hxx |   31 +++++++++++++++
 6 files changed, 164 insertions(+), 1 deletion(-)

New commits:
commit a64eae6ae3ce47d70f7d56aabd3d4a385c69c1ca
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Mar 16 09:40:48 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Mar 16 10:48:23 2022 +0100

    sw clearing breaks: add ODF import
    
    Map
    
            <text:line-break loext:clear="..."/>
    
    to com.sun.star.text.LineBreak and set its Clear property based on the
    XML attribute.
    
    Change-Id: I76d375de23146592c2327df16aa5066ee2a6598d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131645
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/xmloff/Library_xo.mk b/xmloff/Library_xo.mk
index 5117f520d1ba..f9e453a1f863 100644
--- a/xmloff/Library_xo.mk
+++ b/xmloff/Library_xo.mk
@@ -354,6 +354,7 @@ $(eval $(call gb_Library_add_exception_objects,xo,\
     xmloff/source/text/XMLTextShapeStyleContext \
     xmloff/source/text/XMLTextTableContext \
     xmloff/source/text/XMLTrackedChangesImportContext \
+    xmloff/source/text/xmllinebreakcontext \
     xmloff/source/text/txtdrope \
     xmloff/source/text/txtdropi \
     xmloff/source/text/txtexppr \
diff --git a/xmloff/qa/unit/data/clearing-break.fodt 
b/xmloff/qa/unit/data/clearing-break.fodt
new file mode 100644
index 000000000000..b80ff0d74b30
--- /dev/null
+++ b/xmloff/qa/unit/data/clearing-break.fodt
@@ -0,0 +1,28 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office: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:automatic-styles>
+    <style:style style:name="fr1" style:family="graphic">
+      <style:graphic-properties fo:margin-left="0.318cm" 
fo:margin-right="0.318cm" fo:margin-top="0cm" fo:margin-bottom="0cm" 
style:wrap="parallel" style:vertical-pos="from-top" 
style:vertical-rel="paragraph" style:horizontal-pos="from-left" 
style:horizontal-rel="paragraph"/>
+    </style:style>
+  </office:automatic-styles>
+  <office:body>
+    <office:text>
+      <text:p><draw:frame draw:style-name="fr1" draw:name="Picture 1" 
text:anchor-type="char" svg:x="0cm" svg:y="0cm" svg:width="1.806cm" 
svg:height="1.806cm" draw:z-index="0"><draw:image 
draw:mime-type="image/png"><office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAQAAAAAYLlVAAAABGdBTUEAALGPC/xhBQAAAAFz
+       UkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAA
+       AAJiS0dEAACqjSMyAAAACW9GRnMAAAAGAAAAAAAMc1XTAAAACXBIWXMAAA3XAAAN1wFCKJt4
+       AAAACXZwQWcAAABMAAAAQACdMTgbAAABzUlEQVRo3u3ZPU/CQBjA8X+Jxs3ESUDj4iK+LA5+
+       BBfjqBE1cXB2MlFAEqMgxvhNNL4sLsK3UPQL6ObkoAETz+FKW2mxCPRYnucWUu76/OC59C49
+       cGOCKqrD9kHRc6ddPv7oW2WCwMh0nF63Myz7Tm8hPTNu0pgHMER3scepTbgK6enJNND83RLn
+       /878yRaPmgBZFDuMsNLeWB9gmFQHP77MIg9gsYciR50NFKvtjIy10yk84pSZA7DYpwR8scmF
+       QQCMuoQMpzbh0iAARrlnVn90CWHTsZcAiHPPdINQAuqsc2MQAAnKDUKWEhZ10twaBEDSJWQo
+       YlFj7S9CzwEegkXWIbQsRAQASFJhpplwbRAACS+hANRJBxMiAkDcJeQ4sQkBhYgMoJ+Ozlwo
+       2YQ7AJ6CRxyiUGnVy3hVKb0Af9v7hUG2Wy9TEQCUelFTDULB2S+YKYGOMcpM6UIccOQnRA6A
+       cSp6ibfI+wkGADBGpTEd8xz1AaAfTQ7huA8AvUw5hVjuA0D/C5OaMN8XACRZ8F0zCggKAQhA
+       AAIQgAAEIAABCEAAAhCAAAQgAAH4zg3feY4w3Xs44M5+oW0qvCWoGcvaIlM3x/f/ab+O738A
+       hOCNQr34oD4AAAAldEVYdGNyZWF0ZS1kYXRlADIwMTAtMTItMjBUMTc6MDg6MzYrMDE6MDB6
+       5RscAAAAJXRFWHRtb2RpZnktZGF0ZQAyMDEwLTEyLTIwVDE3OjA4OjM3KzAxOjAwgyNmnAAA
+       AABJRU5ErkJggg==
+      </office:binary-data></draw:image></draw:frame>foo<text:line-break 
loext:clear="all"/>bar</text:p>
+    </office:text>
+  </office:body>
+</office:document>
diff --git a/xmloff/qa/unit/text.cxx b/xmloff/qa/unit/text.cxx
index e0289183d2c4..c24e6855f543 100644
--- a/xmloff/qa/unit/text.cxx
+++ b/xmloff/qa/unit/text.cxx
@@ -304,6 +304,42 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, 
testClearingBreakExport)
     assertXPath(pXmlDoc, "//text:line-break", "clear", "all");
 }
 
+CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testClearingBreakImport)
+{
+    // Given an ODF document with a clearing break:
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"clearing-break.fodt";
+
+    // When loading that document:
+    getComponent() = loadFromDesktop(aURL);
+
+    // Then make sure that the "clear" attribute is not lost on import:
+    uno::Reference<text::XTextDocument> xTextDocument(getComponent(), 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xParagraphsAccess(xTextDocument->getText(),
+                                                                    
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParagraphs = 
xParagraphsAccess->createEnumeration();
+    uno::Reference<container::XEnumerationAccess> 
xParagraph(xParagraphs->nextElement(),
+                                                             uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xPortions = 
xParagraph->createEnumeration();
+    // First portion is the image.
+    xPortions->nextElement();
+    // Second portion is "foo".
+    xPortions->nextElement();
+    // Without the accompanying fix in place, this failed with:
+    // An uncaught exception of type 
com.sun.star.container.NoSuchElementException
+    // i.e. the line break was a non-clearing one, so we only had 2 portions, 
not 4 (image, text,
+    // linebreak, text).
+    uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(), 
uno::UNO_QUERY);
+    OUString aTextPortionType;
+    xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+    CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"), aTextPortionType);
+    uno::Reference<text::XTextContent> xLineBreak;
+    xPortion->getPropertyValue("LineBreak") >>= xLineBreak;
+    uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, 
uno::UNO_QUERY);
+    sal_Int16 eClear{};
+    xLineBreakProps->getPropertyValue("Clear") >>= eClear;
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), eClear);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/txtparai.cxx b/xmloff/source/text/txtparai.cxx
index 20f2b5c6388e..f7da8c72427e 100644
--- a/xmloff/source/text/txtparai.cxx
+++ b/xmloff/source/text/txtparai.cxx
@@ -59,6 +59,7 @@
 #include <txtlists.hxx>
 
 #include "txtparaimphint.hxx"
+#include "xmllinebreakcontext.hxx"
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -1396,7 +1397,14 @@ css::uno::Reference< css::xml::sax::XFastContextHandler 
> XMLImpSpanContext_Impl
         break;
 
     case XML_ELEMENT(TEXT, XML_LINE_BREAK):
-        pContext = new XMLCharContext( rImport, ControlCharacter::LINE_BREAK );
+        if (xAttrList->hasAttribute(XML_ELEMENT(LO_EXT, XML_CLEAR)))
+        {
+            pContext = new SvXMLLineBreakContext(rImport, 
*rImport.GetTextImport());
+        }
+        else
+        {
+            pContext = new XMLCharContext(rImport, 
ControlCharacter::LINE_BREAK);
+        }
         rIgnoreLeadingSpace = false;
         break;
 
diff --git a/xmloff/source/text/xmllinebreakcontext.cxx 
b/xmloff/source/text/xmllinebreakcontext.cxx
new file mode 100644
index 000000000000..97d8c918b356
--- /dev/null
+++ b/xmloff/source/text/xmllinebreakcontext.cxx
@@ -0,0 +1,59 @@
+/* -*- 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/.
+ */
+
+#include "xmllinebreakcontext.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+
+#include <xmloff/xmlement.hxx>
+#include <xmloff/xmlimp.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmluconv.hxx>
+
+using namespace com::sun::star;
+using namespace xmloff::token;
+
+namespace
+{
+const SvXMLEnumMapEntry<sal_Int16> pXML_LineBreakClear_Enum[] = {
+    { XML_NONE, 0 }, { XML_LEFT, 1 }, { XML_RIGHT, 2 }, { XML_ALL, 3 }, { 
XML_TOKEN_INVALID, 0 }
+};
+}
+
+SvXMLLineBreakContext::SvXMLLineBreakContext(SvXMLImport& rImport, 
XMLTextImportHelper& rHelper)
+    : SvXMLImportContext(rImport)
+    , m_rHelper(rHelper)
+{
+}
+
+void SvXMLLineBreakContext::startFastElement(
+    sal_Int32 /*nElement*/, const 
uno::Reference<xml::sax::XFastAttributeList>& xAttrList)
+{
+    uno::Reference<lang::XMultiServiceFactory> 
xFactory(GetImport().GetModel(), uno::UNO_QUERY);
+    if (!xFactory.is())
+        return;
+
+    uno::Reference<text::XTextContent> xLineBreak(
+        xFactory->createInstance("com.sun.star.text.LineBreak"), 
uno::UNO_QUERY);
+
+    sal_Int16 eClear = 0;
+    OUString aClear = xAttrList->getValue(XML_ELEMENT(LO_EXT, XML_CLEAR));
+    if (SvXMLUnitConverter::convertEnum(eClear, aClear, 
pXML_LineBreakClear_Enum))
+    {
+        uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, 
uno::UNO_QUERY);
+        xLineBreakProps->setPropertyValue("Clear", uno::makeAny(eClear));
+    }
+
+    m_rHelper.InsertTextContent(xLineBreak);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/text/xmllinebreakcontext.hxx 
b/xmloff/source/text/xmllinebreakcontext.hxx
new file mode 100644
index 000000000000..ef1f744bb44d
--- /dev/null
+++ b/xmloff/source/text/xmllinebreakcontext.hxx
@@ -0,0 +1,31 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <xmloff/dllapi.h>
+#include <xmloff/xmlictxt.hxx>
+
+class XMLTextImportHelper;
+
+/// Handles <text:line-break loext:clear="..."> when the attribute is present.
+class XMLOFF_DLLPUBLIC SvXMLLineBreakContext : public SvXMLImportContext
+{
+    XMLTextImportHelper& m_rHelper;
+
+public:
+    SvXMLLineBreakContext(SvXMLImport& rImport, XMLTextImportHelper& rHelper);
+
+protected:
+    void SAL_CALL startFastElement(
+        sal_Int32 nElement,
+        const css::uno::Reference<css::xml::sax::XFastAttributeList>& 
xAttrList) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to