[Libreoffice-commits] .: sw/qa writerfilter/inc writerfilter/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Nov 19 03:42:32 PST 2012


 sw/qa/extras/ooxmlimport/data/n780645.docx               |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                 |   13 ++
 writerfilter/inc/resourcemodel/TableManager.hxx          |    5 +
 writerfilter/source/dmapper/DomainMapperTableManager.cxx |   68 ++++++++++++++-
 writerfilter/source/dmapper/DomainMapperTableManager.hxx |    5 +
 5 files changed, 90 insertions(+), 1 deletion(-)

New commits:
commit ad913681c0e0cdaaa706329f518f59ee54b86d43
Author: Miklos Vajna <vmiklos at suse.cz>
Date:   Mon Nov 19 12:41:39 2012 +0100

    n#780645 DOCX import: add support for fixed column width
    
    In general, DOCX tables provide a grid for the table, then use spans in
    case different number of cells are used in different rows. In this case,
    the cell width is ignored, as the wished width can be counted from the
    grid and span values.
    
    However, it's also valid to simply provide more cells then the amount
    defined by the grid, and in this case the cell width should decide the
    final width of the cells. This commit adds support for this later case.
    
    Change-Id: I0dd6c1f0c06f81c2afa00489b7ad1f33ff300a7c

diff --git a/sw/qa/extras/ooxmlimport/data/n780645.docx b/sw/qa/extras/ooxmlimport/data/n780645.docx
new file mode 100755
index 0000000..12ffa38
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/n780645.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 2c98832..36fdba3 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -107,6 +107,7 @@ public:
     void testFdo52208();
     void testN785767();
     void testN773061();
+    void testN780645();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -167,6 +168,7 @@ void Test::run()
         {"fdo52208.docx", &Test::testFdo52208},
         {"n785767.docx", &Test::testN785767},
         {"n773061.docx", &Test::testN773061},
+        {"n780645.docx", &Test::testN780645},
     };
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
     {
@@ -1030,6 +1032,17 @@ void Test::testN773061()
     CPPUNIT_ASSERT_EQUAL( getProperty< sal_Int32 >( xFrame, "BottomBorderDistance" ), sal_Int32( 0 ));
 }
 
+void Test::testN780645()
+{
+    // The problem was that when the number of cells didn't match the grid, we
+    // didn't take care of direct cell widths.
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
+    uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
+    uno::Reference<table::XTableRows> xTableRows(xTextTable->getRows(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(2135), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(1), "TableColumnSeparators")[0].Position); // was 1999
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/inc/resourcemodel/TableManager.hxx b/writerfilter/inc/resourcemodel/TableManager.hxx
index 71d9a81..b6555cc 100644
--- a/writerfilter/inc/resourcemodel/TableManager.hxx
+++ b/writerfilter/inc/resourcemodel/TableManager.hxx
@@ -467,6 +467,11 @@ protected:
     sal_uInt32 getTableDepthNew() { return mnTableDepthNew; }
 
     /**
+       Return the current table difference, i.e. 1 if we are in the first cell of a new table, etc.
+     */
+    sal_uInt32 getTableDepthDifference() { return mnTableDepthNew - mnTableDepth; }
+
+    /**
        Action to be carried out at the end of the last paragraph of a
        cell.
      */
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index 0853700..afe9d6c 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -16,6 +16,7 @@
  *   except in compliance with the License. You may obtain a copy of
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
+#include <boost/optional.hpp>
 #include <DomainMapperTableManager.hxx>
 #include <resourcemodel/WW8ResourceModel.hxx>
 #include <BorderHandler.hxx>
@@ -51,6 +52,7 @@ DomainMapperTableManager::DomainMapperTableManager(bool bOOXML, bool bImplicitMe
     m_nTableWidth(0),
     m_bOOXML( bOOXML ),
     m_bImplicitMerges(bImplicitMerges),
+    m_bPushCurrentWidth(false),
     m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) )
 {
     m_pTablePropsHandler->SetTableManager( this );
@@ -282,7 +284,21 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm)
                 break;
             }
             case NS_ooxml::LN_CT_TcPrBase_tcW:
-                break; //fixed column width is not supported
+                {
+                    // Contains unit and value, but unit is not interesting for
+                    // us, later we'll just distribute these values in a
+                    // 0..10000 scale.
+                    writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
+                    if( pProperties.get())
+                    {
+                        MeasureHandlerPtr pMeasureHandler(new MeasureHandler());
+                        pProperties->resolve(*pMeasureHandler);
+                        getCurrentCellWidths()->push_back(pMeasureHandler->getMeasureValue());
+                        if (getTableDepthDifference() > 0)
+                            m_bPushCurrentWidth = true;
+                    }
+                }
+                break;
             case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
                 {
                     TablePropertyMapPtr pProps( new TablePropertyMap );
@@ -338,6 +354,11 @@ boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentSpa
     return m_aGridSpans.back( );
 }
 
+boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentCellWidths( )
+{
+    return m_aCellWidths.back( );
+}
+
 const OUString& DomainMapperTableManager::getTableVertAnchor() const
 {
     return m_sTableVertAnchor;
@@ -347,18 +368,33 @@ void DomainMapperTableManager::startLevel( )
 {
     DomainMapperTableManager_Base_t::startLevel( );
 
+    // If requested, 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.back()->pop_back();
+    }
+
     IntVectorPtr pNewGrid( new vector<sal_Int32> );
     IntVectorPtr pNewSpans( new vector<sal_Int32> );
+    IntVectorPtr pNewCellWidths( new vector<sal_Int32> );
     m_aTableGrid.push_back( pNewGrid );
     m_aGridSpans.push_back( pNewSpans );
+    m_aCellWidths.push_back( pNewCellWidths );
     m_nCell.push_back( 0 );
     m_nTableWidth = 0;
+
+    // And push it back to the right level.
+    if (oCurrentWidth)
+        m_aCellWidths.back()->push_back(*oCurrentWidth);
 }
 
 void DomainMapperTableManager::endLevel( )
 {
     m_aTableGrid.pop_back( );
     m_aGridSpans.pop_back( );
+    m_aCellWidths.pop_back( );
     m_nCell.pop_back( );
     m_nTableWidth = 0;
 
@@ -394,6 +430,7 @@ void DomainMapperTableManager::endOfRowAction()
 #endif
 
     IntVectorPtr pTableGrid = getCurrentGrid( );
+    IntVectorPtr pCellWidths = getCurrentCellWidths( );
     if(!m_nTableWidth && pTableGrid->size())
     {
         ::std::vector<sal_Int32>::const_iterator aCellIter = pTableGrid->begin();
@@ -523,11 +560,40 @@ void DomainMapperTableManager::endOfRowAction()
 #endif
         insertRowProps(pPropMap);
     }
+    else if (pCellWidths->size() > 0)
+    {
+        // If we're here, then the number of cells does not equal to the amount
+        // defined by the grid, even after taking care of
+        // gridSpan/gridBefore/gridAfter. Handle this by ignoring the grid and
+        // providing the separators based on the provided cell widths.
+        uno::Sequence< text::TableColumnSeparator > aSeparators(pCellWidths->size() - 1);
+        text::TableColumnSeparator* pSeparators = aSeparators.getArray();
+        sal_Int16 nSum = 0;
+        sal_uInt32 nPos = 0;
+
+        for (sal_uInt32 i = 0; i < pCellWidths->size() - 1; ++i)
+        {
+            nSum += (*pCellWidths.get())[i];
+            pSeparators[nPos].Position = nSum * nFullWidthRelative / nFullWidth;
+            pSeparators[nPos].IsVisible = sal_True;
+            nPos++;
+        }
+
+        TablePropertyMapPtr pPropMap( new TablePropertyMap );
+        pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) );
+#ifdef DEBUG_DOMAINMAPPER
+        dmapper_logger->startElement("rowProperties");
+        pPropMap->dumpXml( dmapper_logger );
+        dmapper_logger->endElement();
+#endif
+        insertRowProps(pPropMap);
+    }
 
     ++m_nRow;
     m_nCell.back( ) = 0;
     m_nCellBorderIndex = 0;
     pCurrentSpans->clear();
+    pCellWidths->clear();
 
     m_nGridBefore = m_nGridAfter = 0;
 
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
index 7f3215c..e7965bd 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx
@@ -50,6 +50,10 @@ class DomainMapperTableManager : public DomainMapperTableManager_Base_t
 
     ::std::vector< IntVectorPtr >  m_aTableGrid;
     ::std::vector< IntVectorPtr >  m_aGridSpans;
+    /// If this is true, then we pushed a width before the next level started, and that should be carried over when starting the next level.
+    bool            m_bPushCurrentWidth;
+    /// Individual table cell width values, used only in case the number of cells doesn't match the table grid.
+    ::std::vector< IntVectorPtr >  m_aCellWidths;
 
     TablePropertiesHandler   *m_pTablePropsHandler;
     PropertyMapPtr            m_pStyleProps;
@@ -75,6 +79,7 @@ public:
 
     IntVectorPtr getCurrentGrid( );
     IntVectorPtr getCurrentSpans( );
+    IntVectorPtr getCurrentCellWidths( );
 
     const OUString& getTableStyleName() const { return m_sTableStyleName; }
     const OUString& getTableVertAnchor() const;


More information about the Libreoffice-commits mailing list