summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2020-02-05 16:11:40 +0100
committerMiklos Vajna <vmiklos@collabora.com>2020-02-06 09:08:17 +0100
commit3d6a5de8f4579187e5949b212e4625773bb20e6f (patch)
tree8d0271a002bed16074089eeb0385ea74db7b3791 /writerfilter
parent07e5498fdeaefd72cd86f0413dfaea56724097b3 (diff)
DOCX import: don't give up on floating tables in headers completely
This reverts commit 213d6390a2cc59d174173f4359c161625a9c4bdc (tdf#108272 DOCX table-only header: fix SAX parser error, 2020-02-03), except its testcase and replaces it with a better fix that does not import all floating-table-in-header as non-floating tables. See the new testcase, which is 1 pages in Word, it was 3 pages in Writer, and with the better fix it's now 1 pages in Writer as well. Change-Id: Ica3500120f12222d7cf766d55c17d78164865026 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88037 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/CppunitTest_writerfilter_dmapper.mk1
-rw-r--r--writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx77
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docxbin0 -> 15046 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableManager.cxx10
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableManager.hxx6
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx11
-rw-r--r--writerfilter/source/dmapper/PropertyMap.cxx12
7 files changed, 98 insertions, 19 deletions
diff --git a/writerfilter/CppunitTest_writerfilter_dmapper.mk b/writerfilter/CppunitTest_writerfilter_dmapper.mk
index 8c0e7e2d37d3..270844557d3b 100644
--- a/writerfilter/CppunitTest_writerfilter_dmapper.mk
+++ b/writerfilter/CppunitTest_writerfilter_dmapper.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,writerfilter_dmapper, \
writerfilter/qa/cppunittests/dmapper/DomainMapper_Impl \
writerfilter/qa/cppunittests/dmapper/GraphicImport \
writerfilter/qa/cppunittests/dmapper/TextEffectsHandler \
+ writerfilter/qa/cppunittests/dmapper/PropertyMap \
))
$(eval $(call gb_CppunitTest_use_libraries,writerfilter_dmapper, \
diff --git a/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx b/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
new file mode 100644
index 000000000000..06c5611afe37
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/PropertyMap.cxx
@@ -0,0 +1,77 @@
+/* -*- 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 <test/bootstrapfixture.hxx>
+#include <unotest/macros_test.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+
+#include <comphelper/processfactory.hxx>
+
+using namespace ::com::sun::star;
+
+namespace
+{
+/// Tests for writerfilter/source/dmapper/PropertyMap.cxx.
+class Test : public test::BootstrapFixture, public unotest::MacrosTest
+{
+private:
+ uno::Reference<uno::XComponentContext> mxComponentContext;
+ uno::Reference<lang::XComponent> mxComponent;
+
+public:
+ void setUp() override;
+ void tearDown() override;
+ uno::Reference<lang::XComponent>& getComponent() { return mxComponent; }
+};
+
+void Test::setUp()
+{
+ test::BootstrapFixture::setUp();
+
+ mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
+ mxDesktop.set(frame::Desktop::create(mxComponentContext));
+}
+
+void Test::tearDown()
+{
+ if (mxComponent.is())
+ mxComponent->dispose();
+
+ test::BootstrapFixture::tearDown();
+}
+
+char const DATA_DIRECTORY[] = "/writerfilter/qa/cppunittests/dmapper/data/";
+
+CPPUNIT_TEST_FIXTURE(Test, testFloatingTableHeader)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "floating-table-header.docx";
+ getComponent() = loadFromDesktop(aURL);
+ uno::Reference<frame::XModel> xModel(getComponent(), uno::UNO_QUERY);
+ uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+ xModel->getCurrentController(), uno::UNO_QUERY);
+ uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
+ uno::UNO_QUERY);
+ xCursor->jumpToLastPage();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 3
+ // i.e. a document which is 1 page in Word was imported as a 3 page one.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), xCursor->getPage());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docx b/writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docx
new file mode 100644
index 000000000000..3840b2550d5b
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/floating-table-header.docx
Binary files differ
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index 9847476618a0..313a918a3eb4 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -50,7 +50,7 @@ DomainMapperTableManager::DomainMapperTableManager() :
m_nGridAfter(0),
m_nHeaderRepeat(0),
m_nTableWidth(0),
- m_bIsUnfloatTable(false),
+ m_bIsInShape(false),
m_aTmpPosition(),
m_aTmpTableProperties(),
m_bPushCurrentWidth(false),
@@ -339,8 +339,8 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm)
case NS_ooxml::LN_CT_TblPrBase_tblpPr:
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
- // Ignore <w:tblpPr> in shape text or in table-only header, those tables should be always non-floating ones.
- if (!m_bIsUnfloatTable && pProperties.get())
+ // Ignore <w:tblpPr> in shape text, those tables should be always non-floating ones.
+ if (!m_bIsInShape && pProperties.get())
{
TablePositionHandlerPtr pHandler = m_aTmpPosition.back();
if ( !pHandler )
@@ -425,9 +425,9 @@ TablePositionHandler* DomainMapperTableManager::getCurrentTableRealPosition()
return nullptr;
}
-void DomainMapperTableManager::setIsUnfloatTable(bool bIsUnfloatTable)
+void DomainMapperTableManager::setIsInShape(bool bIsInShape)
{
- m_bIsUnfloatTable = bIsUnfloatTable;
+ m_bIsInShape = bIsInShape;
}
void DomainMapperTableManager::startLevel( )
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
index 2ba021812b83..1020d67fc8ad 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
@@ -46,8 +46,8 @@ class DomainMapperTableManager : public TableManager
sal_uInt32 m_nGridAfter; ///< number of grid columns in the parent table's table grid which shall be left after the last cell in the table row
sal_Int32 m_nHeaderRepeat; //counter of repeated headers - if == -1 then the repeating stops
sal_Int32 m_nTableWidth; //might be set directly or has to be calculated from the column positions
- /// Unfloat tables in a shape/table-only header (text append stack is not empty)
- bool m_bIsUnfloatTable;
+ /// Are we in a shape (text append stack is not empty) or in the body document?
+ bool m_bIsInShape;
OUString m_sTableStyleName;
/// Grab-bag of table look attributes for preserving.
comphelper::SequenceAsHashMap m_aTableLook;
@@ -130,7 +130,7 @@ public:
using TableManager::isInCell;
- void setIsUnfloatTable(bool bIsUnfloatTable);
+ void setIsInShape(bool bIsInShape);
};
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 54e76f987ed8..cac4cdceb49b 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1881,11 +1881,6 @@ void DomainMapper_Impl::appendTextPortion( const OUString& rString, const Proper
if (m_aTextAppendStack.empty())
return;
-
- // not a table-only header, don't avoid of floating tables
- if (m_eInHeaderFooterImport == HeaderFooterImportState::header && !IsInShape() && hasTableManager() && !getTableManager().isInCell())
- getTableManager().setIsUnfloatTable(false);
-
// Before placing call to processDeferredCharacterProperties(), TopContextType should be CONTEXT_CHARACTER
// processDeferredCharacterProperties() invokes only if character inserted
if( pPropertyMap == m_pTopContext && !deferredCharacterProperties.empty() && (GetTopContextType() == CONTEXT_CHARACTER) )
@@ -2233,10 +2228,6 @@ void DomainMapper_Impl::PushPageHeaderFooter(bool bHeader, SectionPropertyMap::P
m_eInHeaderFooterImport
= bHeader ? HeaderFooterImportState::header : HeaderFooterImportState::footer;
- // ignore <w:tblpPr> in table-only header, that table is imported as non-floating one
- if (bHeader && hasTableManager())
- getTableManager().setIsUnfloatTable(true);
-
//get the section context
PropertyMapPtr pContext = DomainMapper_Impl::GetTopContextOfType(CONTEXT_SECTION);
//ask for the header/footer name of the given type
@@ -2856,7 +2847,7 @@ void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape
uno::makeAny( true ) );
}
m_bParaChanged = true;
- getTableManager().setIsUnfloatTable(true);
+ getTableManager().setIsInShape(true);
}
catch ( const uno::Exception& )
{
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 4174dab5ef0a..69cc86a73153 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1320,7 +1320,17 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl )
{
rInfo.m_nBreakType = m_nBreakType;
if ( FloatingTableConversion( rDM_Impl, rInfo ) )
- xBodyText->convertToTextFrame( rInfo.m_xStart, rInfo.m_xEnd, rInfo.m_aFrameProperties );
+ {
+ try
+ {
+ xBodyText->convertToTextFrame(rInfo.m_xStart, rInfo.m_xEnd,
+ rInfo.m_aFrameProperties);
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("writerfilter", "convertToTextFrame() failed");
+ }
+ }
}
rPendingFloatingTables.clear();