[Libreoffice-commits] core.git: Branch 'distro/suse/suse-4.0' - 7 commits - sw/qa writerfilter/source

Miklos Vajna vmiklos at suse.cz
Tue Sep 3 08:21:44 PDT 2013


 sw/qa/extras/inc/swmodeltestbase.hxx                     |   12 ++
 sw/qa/extras/ooxmlimport/data/fdo68607.docx              |binary
 sw/qa/extras/ooxmlimport/data/table-auto-nested.docx     |binary
 sw/qa/extras/ooxmlimport/data/table-floating.docx        |binary
 sw/qa/extras/ooxmlimport/data/table-pagebreak.docx       |binary
 sw/qa/extras/ooxmlimport/data/table-style-parprop.docx   |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                 |   64 +++++++++++
 writerfilter/source/dmapper/DomainMapper.cxx             |   19 ++-
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx |   85 +++++++++++++--
 writerfilter/source/dmapper/DomainMapperTableHandler.hxx |    4 
 writerfilter/source/dmapper/DomainMapperTableManager.cxx |   11 +
 writerfilter/source/dmapper/DomainMapper_Impl.cxx        |    9 +
 writerfilter/source/dmapper/DomainMapper_Impl.hxx        |    9 +
 writerfilter/source/dmapper/PropertyMap.cxx              |    5 
 writerfilter/source/dmapper/PropertyMap.hxx              |    3 
 writerfilter/source/dmapper/TablePositionHandler.cxx     |   12 +-
 writerfilter/source/dmapper/TablePositionHandler.hxx     |    2 
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx    |   10 +
 writerfilter/source/ooxml/model.xml                      |    1 
 19 files changed, 227 insertions(+), 19 deletions(-)

New commits:
commit d34ce87ddd17a66a074f47d11d8931e1d8594d64
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Sep 3 11:52:51 2013 +0200

    fdo#68607 bnc#816593 DomainMapperTableHandler: don't always start a frame
    
    This is a port of commit 8fe8bd6c3b5b1a539b7370f8c457fa69c061d2de
    "Related: fdo#61594 SwWW8ImplReader::StartApo: don't always start a
    frame" from the WW8 filter to the DOCX one.
    
    (regression from edc4861a68e0269b83b17e0ec57912a1ce4220ad)
    
    (cherry picked from commit 78d1f1c2835b9fae0f91ed771fc1d594c7817502)
    
    Change-Id: If1bb4a8a3786aacd618585cf859b57ce9be85c51

diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx
index a4e8213..cf37f7f 100644
--- a/sw/qa/extras/inc/swmodeltestbase.hxx
+++ b/sw/qa/extras/inc/swmodeltestbase.hxx
@@ -27,9 +27,11 @@
 
 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/text/XPageCursor.hpp>
 #include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/text/XTextRange.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 #include <com/sun/star/table/XCell.hpp>
 
 #include <test/bootstrapfixture.hxx>
@@ -248,6 +250,16 @@ protected:
         return getProperty<OUString>(getProperty< uno::Reference<beans::XPropertySet> >(xFormula, "Model"), "Formula");
     }
 
+    /// Get page count.
+    int getPages()
+    {
+        uno::Reference<frame::XModel> xModel(mxComponent, 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();
+        return xCursor->getPage();
+    }
+
     uno::Reference<lang::XComponent> mxComponent;
     xmlBufferPtr mpXmlBuffer;
 
diff --git a/sw/qa/extras/ooxmlimport/data/fdo68607.docx b/sw/qa/extras/ooxmlimport/data/fdo68607.docx
new file mode 100644
index 0000000..11f5706
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/fdo68607.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 4da8664..4d6733a 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -134,6 +134,7 @@ public:
     void testTableAutoNested();
     void testTableStyleParprop();
     void testTablePagebreak();
+    void testFdo68607();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -217,6 +218,7 @@ void Test::run()
         {"table-auto-nested.docx", &Test::testTableAutoNested},
         {"table-style-parprop.docx", &Test::testTableStyleParprop},
         {"table-pagebreak.docx", &Test::testTablePagebreak},
+        {"fdo68607.docx", &Test::testFdo68607},
     };
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
     {
@@ -1360,6 +1362,14 @@ void Test::testTablePagebreak()
     CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, getProperty<style::BreakType>(getParagraph(3), "BreakType"));
 }
 
+void Test::testFdo68607()
+{
+    // Bugdoc was 8 pages in Word, 1 in Writer due to pointlessly wrapping the
+    // table in a frame. Exact layout may depend on fonts available, etc. --
+    // but at least make sure that our table spans over multiple pages now.
+    CPPUNIT_ASSERT(getPages() > 1);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 546ff20..571ef77 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -764,7 +764,20 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
     {
         uno::Reference<text::XTextRange> xStart;
         uno::Reference<text::XTextRange> xEnd;
-        bool bFloating = aFrameProperties.hasElements();
+
+        bool bNoFly = false;
+        if (SectionPropertyMap* pSectionContext = m_rDMapper_Impl.GetSectionContext())
+        {
+            sal_Int32 nTextAreaWidth = pSectionContext->GetPageWidth() - pSectionContext->GetLeftMargin() - pSectionContext->GetRightMargin();
+            sal_Int32 nTableWidth = 0;
+            m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth );
+            // If the table is wider than the text area, then don't create a fly
+            // for the table: no wrapping will be performed anyway, but multi-page
+            // tables will be broken.
+            bNoFly = nTableWidth >= nTextAreaWidth;
+        }
+
+        bool bFloating = aFrameProperties.hasElements() && !bNoFly;
         // Additional checks: if we can do this.
         if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
         {
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 1b79667..62c6272 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -1169,6 +1169,11 @@ void SectionPropertyMap::SetFirstPaperBin( sal_Int32 nSet )
 }
 
 
+sal_Int32 SectionPropertyMap::GetPageWidth()
+{
+    return operator[](PropertyDefinition(PROP_WIDTH, false)).get<sal_Int32>();
+}
+
 StyleSheetPropertyMap::StyleSheetPropertyMap() :
     mnCT_Spacing_line( 0 ),
     mnCT_Spacing_lineRule( 0 ),
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx
index 8389859..ce9987f 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -240,11 +240,14 @@ public:
     void SetFirstPaperBin( sal_Int32 nSet );
 
     void SetLeftMargin(    sal_Int32 nSet ) { m_nLeftMargin = nSet; }
+    sal_Int32 GetLeftMargin() { return m_nLeftMargin; }
     void SetRightMargin( sal_Int32 nSet ) { m_nRightMargin = nSet; }
+    sal_Int32 GetRightMargin() { return m_nRightMargin; }
     void SetTopMargin(    sal_Int32 nSet ) { m_nTopMargin = nSet; }
     void SetBottomMargin( sal_Int32 nSet ) { m_nBottomMargin = nSet; }
     void SetHeaderTop(    sal_Int32 nSet ) { m_nHeaderTop = nSet; }
     void SetHeaderBottom( sal_Int32 nSet ) { m_nHeaderBottom = nSet; }
+    sal_Int32 GetPageWidth();
 
     void SetGutterRTL( bool bSet ) { m_bGutterRTL = bSet;}
     void SetDzaGutter( sal_Int32 nSet ) {m_nDzaGutter = nSet; }
commit 5e502cf754e7c08e098ba401610aef76b4244f1f
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Sep 2 10:27:49 2013 +0200

    bnc#816593 DOCX import: ignore page breaks in tables
    
    (cherry picked from commit 7d3778e0ef9f54f3c8988f1b84d58e7002d6c625)
    
    Conflicts:
    	writerfilter/source/dmapper/DomainMapper.cxx
    
    Change-Id: Ibb250148d41d1929fa17dd993bb71c93c0e09dcf
    
    Conflicts:
    	writerfilter/source/dmapper/DomainMapper_Impl.cxx

diff --git a/sw/qa/extras/ooxmlimport/data/table-pagebreak.docx b/sw/qa/extras/ooxmlimport/data/table-pagebreak.docx
new file mode 100755
index 0000000..06ecf95
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-pagebreak.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index e85a228..4da8664 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -133,6 +133,7 @@ public:
     void testTableFloating();
     void testTableAutoNested();
     void testTableStyleParprop();
+    void testTablePagebreak();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -215,6 +216,7 @@ void Test::run()
         {"table-floating.docx", &Test::testTableFloating},
         {"table-auto-nested.docx", &Test::testTableAutoNested},
         {"table-style-parprop.docx", &Test::testTableStyleParprop},
+        {"table-pagebreak.docx", &Test::testTablePagebreak},
     };
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
     {
@@ -1349,6 +1351,15 @@ void Test::testTableStyleParprop()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
 }
 
+void Test::testTablePagebreak()
+{
+    // Page break inside table: should be ignored (was style::BreakType_PAGE_BEFORE before).
+    CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty<style::BreakType>(getParagraphOrTable(2), "BreakType"));
+
+    // This one is outside the table: should not be ignored.
+    CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, getProperty<style::BreakType>(getParagraph(3), "BreakType"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 4d0d721..03d1c85 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3332,6 +3332,12 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
         }
     }
     break;
+    case NS_ooxml::LN_tblStart:
+        m_pImpl->m_nTableDepth++;
+    break;
+    case NS_ooxml::LN_tblEnd:
+        m_pImpl->m_nTableDepth--;
+    break;
     default:
         {
 #ifdef DEBUG_DOMAINMAPPER
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 8f1af5a..07654c6 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -193,7 +193,9 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_bSdt(false),
         m_xInsertTextRange(xInsertTextRange),
         m_bIsNewDoc(bIsNewDoc),
-        m_pSdtHelper(0)
+        m_pSdtHelper(0),
+        m_nTableDepth(0)
+
 {
     appendTableManager( );
     GetBodyText();
@@ -632,6 +634,11 @@ void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
             m_bIsColumnBreakDeferred = true;
         break;
     case PAGE_BREAK:
+            // See SwWW8ImplReader::HandlePageBreakChar(), page break should be
+            // ignored inside tables.
+            if (m_nTableDepth > 0)
+                return;
+
             m_bIsPageBreakDeferred = true;
         break;
     default:
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index e2a43b6..ccca0dc 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -683,6 +683,15 @@ public:
 
     /// Document background color, applied to every page style.
     boost::optional<sal_Int32> m_oBackgroundColor;
+
+    /**
+     * This contains the raw table depth. m_nTableDepth > 0 is the same as
+     * getTableManager().isInTable(), unless we're in the first paragraph of a
+     * table, or first paragraph after a table, as the table manager is only
+     * updated once we ended the paragraph (and know if the para has the
+     * PFInTable SPRM or not).
+     */
+    sal_Int32 m_nTableDepth;
 };
 } //namespace dmapper
 } //namespace writerfilter
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index d406856..4d4ac65 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -1943,6 +1943,16 @@ void OOXMLFastContextHandlerTextTable::lcl_endFastElement
 {
     endAction(Element);
 
+    boost::shared_ptr<OOXMLPropertySet> pProps( new OOXMLPropertySetImpl );
+    {
+        OOXMLValue::Pointer_t pVal
+            (new OOXMLIntegerValue(mnTableDepth));
+        OOXMLProperty::Pointer_t pProp
+            (new OOXMLPropertyImpl(NS_ooxml::LN_tblEnd, pVal, OOXMLPropertyImpl::SPRM));
+        pProps->add(pProp);
+    }
+    mpParserState->setCharacterProperties(pProps);
+
     mnTableDepth--;
     mpParserState->endTable();
 }
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 6f27ef6..ff1d618 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -38,6 +38,7 @@
   <token tokenid="ooxml:trackchange"/>
   <token tokenid="ooxml:object"/>
   <token tokenid="ooxml:tblStart"/>
+  <token tokenid="ooxml:tblEnd"/>
   <token tokenid="ooxml:ffdata"/>
   <token tokenid="ooxml:starmath"/>
   <namespace name="dml-stylesheet" url="http://schemas.openxmlformats.org/drawingml/2006/main" file="dml-stylesheet.rng">
commit fc01e55ded5b517307a28a9ac8c438ce9ea5f967
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Thu Aug 29 14:17:09 2013 +0200

    bnc#816593 DOCX filter: import paragraph spacing from table style
    
    (cherry picked from commit 17e904ed66c3caf87e658b9d3a18d7b13f4a0b52)
    
    Change-Id: I9dce59ecd8a2d2bfadb8c7273cd46c6c0cf17774

diff --git a/sw/qa/extras/ooxmlimport/data/table-style-parprop.docx b/sw/qa/extras/ooxmlimport/data/table-style-parprop.docx
new file mode 100755
index 0000000..1c68c70
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-style-parprop.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index bbdb706..e85a228 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -132,6 +132,7 @@ public:
     void testBnc780044Spacing();
     void testTableFloating();
     void testTableAutoNested();
+    void testTableStyleParprop();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -213,6 +214,7 @@ void Test::run()
         {"bnc780044_spacing.docx", &Test::testBnc780044Spacing},
         {"table-floating.docx", &Test::testTableFloating},
         {"table-auto-nested.docx", &Test::testTableAutoNested},
+        {"table-style-parprop.docx", &Test::testTableStyleParprop},
     };
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
     {
@@ -1338,6 +1340,15 @@ void Test::testTableAutoNested()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(23051), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));
 }
 
+void Test::testTableStyleParprop()
+{
+    // The problem was that w:spacing's w:after=0 (a paragraph property) wasn't imported from table style.
+    uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+    // This was 353, the document default, i.e. paragraph property from table style had no effect.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 6647408..546ff20 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -19,9 +19,12 @@
 #include <DomainMapperTableHandler.hxx>
 #include <DomainMapper_Impl.hxx>
 #include <StyleSheetTable.hxx>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
 #include <com/sun/star/table/TableBorderDistances.hpp>
 #include <com/sun/star/table/TableBorder.hpp>
 #include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/table/XCellRange.hpp>
 #include <com/sun/star/text/HoriOrientation.hpp>
 #include <com/sun/star/text/RelOrientation.hpp>
 #include <com/sun/star/text/SizeType.hpp>
@@ -720,6 +723,22 @@ RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties()
     return aRowProperties;
 }
 
+// Apply paragraph property to each paragraph within a cell.
+static void lcl_ApplyCellParaProps(uno::Reference<table::XCell> xCell, uno::Any aBottomMargin)
+{
+    uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCell, uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
+    while (xEnumeration->hasMoreElements())
+    {
+        uno::Reference<beans::XPropertySet> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
+        uno::Reference<beans::XPropertyState> xPropertyState(xParagraph, uno::UNO_QUERY);
+        // Don't apply in case direct formatting is already present.
+        // TODO: probably paragraph style has priority over table style here.
+        if (xPropertyState.is() && xPropertyState->getPropertyState("ParaBottomMargin") == beans::PropertyState_DEFAULT_VALUE)
+            xParagraph->setPropertyValue("ParaBottomMargin", aBottomMargin);
+    }
+}
+
 void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
 {
 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
@@ -766,6 +785,25 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
 
                 if (xTable.is())
                     m_xTableRange = xTable->getAnchor( );
+
+                // OOXML table style may container paragraph properties, apply these now.
+                for (int i = 0; i < aTableInfo.aTableProperties.getLength(); ++i)
+                {
+                    if (aTableInfo.aTableProperties[i].Name == "ParaBottomMargin")
+                    {
+                        uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY);
+                        uno::Any aBottomMargin = aTableInfo.aTableProperties[i].Value;
+                        sal_Int32 nRows = aCellProperties.getLength();
+                        for (sal_Int32 nRow = 0; nRow < nRows; ++nRow)
+                        {
+                            const uno::Sequence< beans::PropertyValues > aCurrentRow = aCellProperties[nRow];
+                            sal_Int32 nCells = aCurrentRow.getLength();
+                            for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
+                                lcl_ApplyCellParaProps(xCellRange->getCellByPosition(nCell, nRow), aBottomMargin);
+                        }
+                        break;
+                    }
+                }
             }
         }
         catch ( const lang::IllegalArgumentException &e )
commit d74f44882336226990a290eaaf37f7b477c98777
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Tue Sep 3 15:23:46 2013 +0200

    bnc#816593 DOCX import: fix auto table width wrt nested tables
    
    This is a backport of the fix + 3 other commits from master, which were
    needed to make the testcase pass on -4-1 as well.
    
    (cherry picked from commits 74c5ed19f430327988194cdcd6bdff09591a93fa,
    824cc4bf4ae9035d4108e8da8e81eb57284f0b54,
    53d27a30ce5f2c9f7d37a4089286116854c16215 and
    76d1ca523ddcf89cc269fe51c70e66066943ef5a)
    
    Change-Id: I62a1f526cf1d4e4056daa1495d61f1b9f5c0b1b2
    
    Conflicts:
    	sw/qa/extras/ooxmlimport/ooxmlimport.cxx
    	writerfilter/source/dmapper/DomainMapperTableManager.cxx

diff --git a/sw/qa/extras/ooxmlimport/data/table-auto-nested.docx b/sw/qa/extras/ooxmlimport/data/table-auto-nested.docx
new file mode 100755
index 0000000..85f47db
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-auto-nested.docx differ
diff --git a/sw/qa/extras/ooxmlimport/data/table-floating.docx b/sw/qa/extras/ooxmlimport/data/table-floating.docx
new file mode 100755
index 0000000..1e0cb30
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/table-floating.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 3463541..bbdb706 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -130,6 +130,8 @@ public:
     void testTableAutoColumnFixedSize();
     void testFdo66474();
     void testBnc780044Spacing();
+    void testTableFloating();
+    void testTableAutoNested();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -209,6 +211,8 @@ void Test::run()
         {"table-auto-column-fixed-size.docx", &Test::testTableAutoColumnFixedSize},
         {"fdo66474.docx", &Test::testFdo66474},
         {"bnc780044_spacing.docx", &Test::testBnc780044Spacing},
+        {"table-floating.docx", &Test::testTableFloating},
+        {"table-auto-nested.docx", &Test::testTableAutoNested},
     };
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
     {
@@ -1306,6 +1310,34 @@ void Test::testBnc780044Spacing()
     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xCursor->getPage());
 }
 
+void Test::testTableFloating()
+{
+    // Both the size and the position of the table was incorrect.
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+    // Second table was too wide: 16249, i.e. as wide as the first table.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11248), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));
+
+    uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
+    // This was 0, should be the the opposite of (left margin + half of the border width).
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xFrame, "HoriOrientPosition"));
+    // Was 0 as well, should be the right margin.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(191), getProperty<sal_Int32>(xFrame, "RightMargin"));
+}
+
+void Test::testTableAutoNested()
+{
+    // This was 176, when compat option is not enabled, the auto paragraph bottom margin value was incorrect.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(494), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin"));
+
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+    // This was 115596, i.e. the width of the outer table was too large.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(23051), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index d9c5abb..6647408 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -38,8 +38,6 @@ namespace dmapper {
 using namespace ::com::sun::star;
 using namespace ::std;
 
-#define DEF_BORDER_DIST 190  //0,19cm
-
 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
 static void  lcl_printProperties( PropertyMapPtr pProps )
 {
@@ -306,7 +304,7 @@ bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const Prope
 
 }
 
-TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo)
+TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties)
 {
     // will receive the table style if any
     TableStyleSheetEntry* pTableStyle = NULL;
@@ -418,7 +416,25 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
             aTableBorder.IsLeftLineValid = sal_True;
             // Only top level table position depends on border width
             if (rInfo.nNestLevel == 1)
-                rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
+            {
+                if (!rFrameProperties.hasElements())
+                    rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
+                else
+                {
+                    // If this is a floating table, then the position of the frame should be adjusted, instead.
+                    for (sal_Int32 i = 0; i < rFrameProperties.getLength(); ++i)
+                    {
+                        beans::PropertyValue& rPropertyValue = rFrameProperties[i];
+                        if (rPropertyValue.Name == "HoriOrientPosition")
+                        {
+                            sal_Int32 nValue = rPropertyValue.Value.get<sal_Int32>();
+                            nValue -= aLeftBorder.LineWidth * 0.5;
+                            rPropertyValue.Value <<= nValue;
+                            break;
+                        }
+                    }
+                }
+            }
         }
         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine))
         {
@@ -710,9 +726,11 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
     dmapper_logger->startElement("tablehandler.endTable");
 #endif
 
+    // If we want to make this table a floating one.
+    uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition();
     TableInfo aTableInfo;
     aTableInfo.nNestLevel = nestedTableLevel;
-    aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo);
+    aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties);
     //  expands to uno::Sequence< Sequence< beans::PropertyValues > >
 
     CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo);
@@ -727,8 +745,6 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
     {
         uno::Reference<text::XTextRange> xStart;
         uno::Reference<text::XTextRange> xEnd;
-        // If we want to make this table a floating one.
-        uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition();
         bool bFloating = aFrameProperties.hasElements();
         // Additional checks: if we can do this.
         if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
index ea4c421..792b978 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
@@ -45,6 +45,8 @@ typedef ::com::sun::star::uno::Sequence< RowPropertyValuesSeq_t>    CellProperty
 typedef std::vector<PropertyMapPtr>     PropertyMapVector1;
 typedef std::vector<PropertyMapVector1> PropertyMapVector2;
 
+#define DEF_BORDER_DIST 190  //0,19cm
+
 class DomainMapper_Impl;
 class TableStyleSheetEntry;
 struct TableInfo;
@@ -66,7 +68,7 @@ class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public TableDataHandler
     sal_Int32 m_nCellIndex;
     sal_Int32 m_nRowIndex;
 
-    TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo);
+    TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties);
     CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo);
     RowPropertyValuesSeq_t endTableGetRowProperties();
 
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index 6362969..d07d7e8 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -467,6 +467,7 @@ void DomainMapperTableManager::startLevel( )
     m_nCell.push_back( 0 );
     m_nTableWidth = 0;
     m_nLayoutType = 0;
+    m_nMaxFixedWidth = 0;
 
     // And push it back to the right level.
     if (oCurrentWidth)
@@ -477,10 +478,20 @@ void DomainMapperTableManager::endLevel( )
 {
     m_aTableGrid.pop_back( );
     m_aGridSpans.pop_back( );
+
+    // Do the same trick as in startLevel(): pop the value that was pushed too early.
+    boost::optional<sal_Int32> oCurrentWidth;
+    if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty())
+        oCurrentWidth.reset(m_aCellWidths.back()->back());
     m_aCellWidths.pop_back( );
+    // And push it back to the right level.
+    if (oCurrentWidth)
+        m_aCellWidths.back()->push_back(*oCurrentWidth);
+
     m_nCell.pop_back( );
     m_nTableWidth = 0;
     m_nLayoutType = 0;
+    m_nMaxFixedWidth = 0;
 
     m_aTmpPosition.pop_back( );
     m_aTmpTableProperties.pop_back( );
diff --git a/writerfilter/source/dmapper/TablePositionHandler.cxx b/writerfilter/source/dmapper/TablePositionHandler.cxx
index 7ed8bde..30dd2cf 100644
--- a/writerfilter/source/dmapper/TablePositionHandler.cxx
+++ b/writerfilter/source/dmapper/TablePositionHandler.cxx
@@ -7,6 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 #include <TablePositionHandler.hxx>
+#include <DomainMapperTableHandler.hxx>
 #include <PropertyMap.hxx>
 #include <doctok/resourceids.hxx>
 #include <ConversionHelper.hxx>
@@ -28,7 +29,9 @@ TablePositionHandler::TablePositionHandler() :
     m_aHorzAnchor( "text" ),
     m_aXSpec( ),
     m_nY( 0 ),
-    m_nX( 0 )
+    m_nX( 0 ),
+    m_nLeftBorderDistance(DEF_BORDER_DIST),
+    m_nRightBorderDistance(DEF_BORDER_DIST)
 {
 }
 
@@ -75,7 +78,7 @@ void TablePositionHandler::lcl_sprm(Sprm& /*rSprm*/)
 
 uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() const
 {
-    uno::Sequence< beans::PropertyValue > aFrameProperties(18);
+    uno::Sequence< beans::PropertyValue > aFrameProperties(19);
     beans::PropertyValue* pFrameProperties = aFrameProperties.getArray();
 
     pFrameProperties[0].Name = "LeftBorderDistance";
@@ -132,7 +135,7 @@ uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() con
     pFrameProperties[13].Name = "HoriOrientRelation";
     pFrameProperties[13].Value <<= nHoriOrientRelation;
     pFrameProperties[14].Name = "HoriOrientPosition";
-    pFrameProperties[14].Value <<= m_nX;
+    pFrameProperties[14].Value <<= m_nX - m_nLeftBorderDistance;
 
 
     // Vertical positioning
@@ -161,6 +164,9 @@ uno::Sequence<beans::PropertyValue> TablePositionHandler::getTablePosition() con
     pFrameProperties[17].Name = "VertOrientPosition";
     pFrameProperties[17].Value <<= m_nY;
 
+    pFrameProperties[18].Name = "RightMargin";
+    pFrameProperties[18].Value <<= m_nRightBorderDistance;
+
     return aFrameProperties;
 }
 
diff --git a/writerfilter/source/dmapper/TablePositionHandler.hxx b/writerfilter/source/dmapper/TablePositionHandler.hxx
index b6ddd50..43eabbc 100644
--- a/writerfilter/source/dmapper/TablePositionHandler.hxx
+++ b/writerfilter/source/dmapper/TablePositionHandler.hxx
@@ -27,6 +27,8 @@ namespace writerfilter {
             OUString m_aXSpec;
             sal_Int32 m_nY;
             sal_Int32 m_nX;
+            sal_Int32 m_nLeftBorderDistance;
+            sal_Int32 m_nRightBorderDistance;
 
             // Properties
             virtual void lcl_attribute(Id Name, Value & val);
commit 6bf4fac3759a4fb986382b032efbb22aa8c23175
Author: Pierre-Eric Pelloux-Prayer <pierre-eric at lanedo.com>
Date:   Fri Jan 11 17:40:39 2013 +0100

    bnc#816593 docx import: fix incorrect nested table margins
    
    Change-Id: I07f0f47fcbd3d463d7831820cde338d8d59d9b68
    (cherry picked from commit 194ba3a2cacbb5438dfcb8fb35167055e01ca251)

diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 41d2c04..d9c5abb 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -416,7 +416,9 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
         {
             aTableBorder.LeftLine = aLeftBorder;
             aTableBorder.IsLeftLineValid = sal_True;
-            rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
+            // Only top level table position depends on border width
+            if (rInfo.nNestLevel == 1)
+                rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
         }
         if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine))
         {
commit c1bf8f7dbaee8d5633f6bdf06e6a50ea597c821b
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Wed Aug 28 11:43:36 2013 +0200

    bnc#816593 DOCX import: let w:before not overwrite w:beforeAutospacing
    
    And do the same for w:after / w:afterAutospacing. The spec says that if
    w:beforeAutospacing is read, w:before should be ignored, this implies
    that if we already had w:beforeAutospacing, w:before should not
    overwrite the already existing top margin.
    
    (cherry picked from commit de516780bf2d5f74afe643033bfc528c53013902)
    
    Conflicts:
    	writerfilter/source/dmapper/DomainMapper.cxx
    
    Change-Id: I9437cb5c6fc352a360e27aa279d0a789706c5578

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 320cdf2..4d0d721 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -972,13 +972,15 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         break;
         case NS_ooxml::LN_CT_Spacing_before:
             if (m_pImpl->GetTopContext())
-                m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
+                // Don't overwrite NS_ooxml::LN_CT_Spacing_beforeAutospacing.
+                m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
             break;
         case NS_ooxml::LN_CT_Spacing_beforeLines:
             break;
         case NS_ooxml::LN_CT_Spacing_after:
             if (m_pImpl->GetTopContext())
-                m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ));
+                // Don't overwrite NS_ooxml::LN_CT_Spacing_afterAutospacing.
+                m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, true, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
             break;
         case NS_ooxml::LN_CT_Spacing_afterLines:
             break;
commit e72abb9c52570beb560d0fe3589e39a8ddb971b5
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Wed Aug 28 11:24:07 2013 +0200

    bnc#816593 DOCX import: fix auto para spacing without compat option
    
    Paragraph auto spacing (before and after) without the
    w:doNotUseHTMLParagraphAutoSpacing compat option was incorrect.
    
    (cherry picked from commit 279ff2e03371542d014bf281e73282ba8080cf6b)
    
    Conflicts:
    	writerfilter/source/dmapper/DomainMapper.cxx
    
    Change-Id: I56d6153f7c489de7fceaf6fab7325c42ee8f9cae

diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 63f1124..320cdf2 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1157,17 +1157,16 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                              uno::makeAny( aLocale ) );
         }
         break;
-// This is the value when the compat option is not enabled. No idea where it comes from, the spec doesn't mention it.
-#define AUTO_PARA_SPACING sal_Int32(49)
+        // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
         case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
             if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
-                m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, false, uno::makeAny( AUTO_PARA_SPACING ) );
+                m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, false, uno::makeAny( ConversionHelper::convertTwipToMM100(280) ) );
             else
                 m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, false, uno::makeAny( ConversionHelper::convertTwipToMM100(100) ) );
         break;
         case NS_ooxml::LN_CT_Spacing_afterAutospacing:
             if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
-                m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, false, uno::makeAny( AUTO_PARA_SPACING ) );
+                m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, false, uno::makeAny( ConversionHelper::convertTwipToMM100(280) ) );
             else
                 m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, false, uno::makeAny( ConversionHelper::convertTwipToMM100(100) ) );
         break;


More information about the Libreoffice-commits mailing list