summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-01-28 13:38:20 +0100
committerMiklos Vajna <vmiklos@collabora.com>2022-01-28 19:15:37 +0100
commit8bac48991857d222f0e8f0c07b8c4e06649e1632 (patch)
treeafda78d51f88b78eb84b5b8989b3331ebfdad2ca /writerfilter
parent8c558549b7dc3348da207627663824043eed6204 (diff)
DOCX import: handle a subset of <w:ptab w:alignment="left">
The case when we can map it to a line break. This way the page number is visually inside the rectangle shape that is behind the field. The test intentionally uses \n as-is for line-break, because SwASCWriter::WriteStream() uses \n in the LINEEND_LF case even on Windows (and not SAL_NEWLINE_STRING), while SAL_NEWLINE_STRING is used for paragraph-break. Change-Id: Ic85e57b2391bfac73507727b17240f4d85fc2698 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129059 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx26
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/ptab.docxbin0 -> 15861 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx56
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx3
5 files changed, 87 insertions, 0 deletions
diff --git a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
index 3719a09e3323..c0468d9d55cc 100644
--- a/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl.cxx
@@ -19,6 +19,7 @@
#include <com/sun/star/text/XTextTablesSupplier.hpp>
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <vcl/scheduler.hxx>
@@ -230,6 +231,31 @@ CPPUNIT_TEST_FIXTURE(Test, testChartZOrder)
// of the shape.
CPPUNIT_ASSERT(xChart->supportsService("com.sun.star.text.TextEmbeddedObject"));
}
+
+CPPUNIT_TEST_FIXTURE(Test, testPTab)
+{
+ // Given a document that has a <w:ptab> to render a linebreak:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "ptab.docx";
+
+ // When opening that file:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the Writer doc model contains that linebreak:
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(getComponent(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies
+ = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
+ uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
+ auto xFooter = xStyle->getPropertyValue("FooterText").get<uno::Reference<text::XTextRange>>();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: <space><newline>1\n
+ // - Actual: <space><tab>1\n
+ // i.e. the layout height of the footer text was incorrect, the page number field was not
+ // visually inside the background shape.
+ CPPUNIT_ASSERT_EQUAL(OUString(" \n1" SAL_NEWLINE_STRING), xFooter->getString());
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/ptab.docx b/writerfilter/qa/cppunittests/dmapper/data/ptab.docx
new file mode 100644
index 000000000000..d1ae18a27a55
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/ptab.docx
Binary files differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index e8b5a3f40e5b..6a18d8d12da0 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1167,7 +1167,9 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
break;
case NS_ooxml::LN_CT_PTab_leader:
case NS_ooxml::LN_CT_PTab_relativeTo:
+ break;
case NS_ooxml::LN_CT_PTab_alignment:
+ m_pImpl->HandlePTab(nIntValue);
break;
case NS_ooxml::LN_CT_Cnf_lastRowLastColumn:
m_pImpl->appendGrabBag(m_pImpl->m_aInteropGrabBag, "lastRowLastColumn", OUString::number(nIntValue));
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index f0902918e0ff..952d225f52f7 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -3868,6 +3868,62 @@ void DomainMapper_Impl::HandleAltChunk(const OUString& rStreamName)
}
}
+void DomainMapper_Impl::HandlePTab(sal_Int32 nAlignment)
+{
+ // We only handle the case when the line already has content, so the left-aligned ptab is
+ // equivalent to a line break.
+ if (nAlignment != NS_ooxml::LN_Value_ST_PTabAlignment_left)
+ {
+ return;
+ }
+
+ if (m_aTextAppendStack.empty())
+ {
+ return;
+ }
+
+ uno::Reference<text::XTextAppend> xTextAppend = m_aTextAppendStack.top().xTextAppend;
+ if (!xTextAppend.is())
+ {
+ return;
+ }
+
+ uno::Reference<css::text::XTextRange> xInsertPosition
+ = m_aTextAppendStack.top().xInsertPosition;
+ if (!xInsertPosition.is())
+ {
+ xInsertPosition = xTextAppend->getEnd();
+ }
+ uno::Reference<text::XTextCursor> xCursor
+ = xTextAppend->createTextCursorByRange(xInsertPosition);
+
+ // Assume that we just inserted a tab character.
+ xCursor->goLeft(1, true);
+ if (xCursor->getString() != "\t")
+ {
+ return;
+ }
+
+ // Assume that there is some content before the tab character.
+ uno::Reference<text::XParagraphCursor> xParagraphCursor(xCursor, uno::UNO_QUERY);
+ if (!xParagraphCursor.is())
+ {
+ return;
+ }
+
+ xCursor->collapseToStart();
+ xParagraphCursor->gotoStartOfParagraph(true);
+ if (xCursor->isCollapsed())
+ {
+ return;
+ }
+
+ // Then select the tab again and replace with a line break.
+ xCursor->collapseToEnd();
+ xCursor->goRight(1, true);
+ xTextAppend->insertControlCharacter(xCursor, text::ControlCharacter::LINE_BREAK, true);
+}
+
static sal_Int16 lcl_ParseNumberingType( const OUString& rCommand )
{
sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR;
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 7238d129f766..7ede5cb2f91d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -1164,6 +1164,9 @@ public:
/// Handles <w:altChunk>.
void HandleAltChunk(const OUString& rStreamName);
+ /// Handles <w:ptab>.
+ void HandlePTab(sal_Int32 nAlignment);
+
void commentProps(const OUString& sId, const CommentProperties& rProps);
private: