sw/qa/extras/ooxmlimport/data/fdo65090.docx              |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                 |   12 ++++
 sw/qa/extras/rtfimport/data/fdo65090.rtf                 |    6 ++
 sw/qa/extras/rtfimport/rtfimport.cxx                     |   12 ++++
 sw/source/core/unocore/unotbl.cxx                        |    2 
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx |   43 ++++++++++++++-
 writerfilter/source/dmapper/DomainMapperTableHandler.hxx |   17 +++++
 writerfilter/source/dmapper/DomainMapperTableManager.cxx |    8 ++
 writerfilter/source/dmapper/PropertyIds.cxx              |    1 
 writerfilter/source/dmapper/PropertyIds.hxx              |    1 
 writerfilter/source/rtftok/rtfdocumentimpl.cxx           |   12 ++++
 11 files changed, 110 insertions(+), 4 deletions(-)

New commits:
commit 8b8152b8fbfb39f44fe0441decd3a746684f4382
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Fri Dec 27 20:46:50 2013 +0100

    fdo#65090 RTF filter: import RTF_CLMGF and RTF_CLMRG
    
    These describe an explicit horizontal merge, that is not something Word
    itself creates, but it turns out the Calc RTF export does.
    
    (cherry picked from commits bb562304c1e1c61a882e6db65806cfdf8601bcbf,
    97dcf77841d19d344d58d5bdacdab141cdea4817 and
    6eb02ac8a77f9f89f256b190281029f6cbd60d95)
    
    Conflicts:
        sw/qa/extras/ooxmlimport/ooxmlimport.cxx
        writerfilter/source/dmapper/PropertyIds.cxx
        writerfilter/source/dmapper/PropertyIds.hxx
        writerfilter/source/rtftok/rtfdocumentimpl.cxx
    
    Change-Id: I1b6ec10bb8e8bd40e24791ccc96f2f066dd0d5d5
    Reviewed-on: https://gerrit.libreoffice.org/7220
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    Tested-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/qa/extras/ooxmlimport/data/fdo65090.docx 
b/sw/qa/extras/ooxmlimport/data/fdo65090.docx
new file mode 100644
index 0000000..4d45737
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/fdo65090.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index d1fa650..2c72214 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -136,6 +136,7 @@ public:
     void testGroupshapeSdt();
     void testBnc779620();
     void testRPrChangeClosed();
+    void testFdo65090();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -237,6 +238,7 @@ void Test::run()
         {"groupshape-sdt.docx", &Test::testGroupshapeSdt},
         {"bnc779620.docx", &Test::testBnc779620},
         {"rprchange_closed.docx", &Test::testRPrChangeClosed},
+        {"fdo65090.docx", &Test::testFdo65090},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1661,6 +1663,16 @@ void Test::testRPrChangeClosed()
     CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(getParagraph(2), 1), 
"RedlineType"));
 }
 
+void Test::testFdo65090()
+{
+    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);
+    // The first row had two cells, instead of a single horizontally merged 
one.
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty< 
uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), 
"TableColumnSeparators").getLength());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/rtfimport/data/fdo65090.rtf 
b/sw/qa/extras/rtfimport/data/fdo65090.rtf
new file mode 100644
index 0000000..8a3eabd
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo65090.rtf
@@ -0,0 +1,6 @@
+{\rtf\ansi
+{
+\trowd\trgaph30\trleft-30\trrh242\clmgf\clvertalc\cellx1280\clmrg\clvertalb\cellx2560\clvertalb\cellx3840\pard\plain\intbl
+\qc a\cell\cell\ql b\cell\row
+}
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx 
b/sw/qa/extras/rtfimport/rtfimport.cxx
index 687baac..eca16e3 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -161,6 +161,7 @@ public:
     void testFdo68291();
     void testFdo69384();
     void testFdo70221();
+    void testFdo65090();
 
     CPPUNIT_TEST_SUITE(Test);
 #if !defined(MACOSX) && !defined(WNT)
@@ -306,6 +307,7 @@ void Test::run()
         {"fdo68291.odt", &Test::testFdo68291},
         {"hello.rtf", &Test::testFdo69384},
         {"fdo70221.rtf", &Test::testFdo70221},
+        {"fdo65090.rtf", &Test::testFdo65090},
     };
     header();
     for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i)
@@ -1488,6 +1490,16 @@ void Test::testFdo70221()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDraws->getCount());
 }
 
+void Test::testFdo65090()
+{
+    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);
+    // The first row had 3 cells, instead of a horizontally merged one and a 
normal one (2 -> 1 separator).
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty< 
uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), 
"TableColumnSeparators").getLength());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/unocore/unotbl.cxx 
b/sw/source/core/unocore/unotbl.cxx
index 49fc1a3..3fd2350 100644
--- a/sw/source/core/unocore/unotbl.cxx
+++ b/sw/source/core/unocore/unotbl.cxx
@@ -1709,7 +1709,7 @@ sal_Bool SwXTextTableCursor::mergeRange(void) throw( 
uno::RuntimeException )
             if(bRet)
             {
                 size_t nCount = pTblCrsr->GetSelectedBoxesCount();
-                while (--nCount)
+                while (nCount--)
                 {
                     pTblCrsr->DeleteBox(nCount);
                 }
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index b613c07..28be09c 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -536,7 +536,7 @@ TableStyleSheetEntry * 
DomainMapperTableHandler::endTableGetTableStyle(TableInfo
 #define CNF_LAST_ROW_LAST_COLUMN    0x002
 #define CNF_LAST_ROW_FIRST_COLUMN   0x001
 
-CellPropertyValuesSeq_t 
DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo)
+CellPropertyValuesSeq_t 
DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo, 
std::vector<HorizontallyMergedCell>& rMerges)
 {
 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
     dmapper_logger->startElement("getCellProperties");
@@ -692,6 +692,25 @@ CellPropertyValuesSeq_t 
DomainMapperTableHandler::endTableGetCellProperties(Tabl
                     aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, 
false,
                                                  uno::makeAny((sal_Int32) 
rInfo.nBottomBorderDistance ) );
 
+                // Horizontal merge is not an UNO property, extract that info 
here to rMerges, and then remove it from the map.
+                const PropertyMap::const_iterator aHorizontalMergeIter = 
aCellIterator->get()->find(PropertyDefinition(PROP_HORIZONTAL_MERGE, false));
+                if (aHorizontalMergeIter != aCellIterator->get()->end())
+                {
+                    if (aHorizontalMergeIter->second.get<sal_Bool>())
+                    {
+                        // first cell in a merge
+                        HorizontallyMergedCell aMerge(nRow, nCell);
+                        rMerges.push_back(aMerge);
+                    }
+                    else if (!rMerges.empty())
+                    {
+                        // resuming an earlier merge
+                        HorizontallyMergedCell& rMerge = rMerges.back();
+                        rMerge.m_nLastRow = nRow;
+                        rMerge.m_nLastCol = nCell;
+                    }
+                    
aCellIterator->get()->erase(PropertyDefinition(PROP_HORIZONTAL_MERGE, false));
+                }
                 pSingleCellProperties[nCell] = 
aCellIterator->get()->GetPropertyValues();
 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
                 dmapper_logger->endElement();
@@ -804,7 +823,8 @@ void DomainMapperTableHandler::endTable(unsigned int 
nestedTableLevel)
     aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, 
aFrameProperties);
     //  expands to uno::Sequence< Sequence< beans::PropertyValues > >
 
-    CellPropertyValuesSeq_t aCellProperties = 
endTableGetCellProperties(aTableInfo);
+    std::vector<HorizontallyMergedCell> aMerges;
+    CellPropertyValuesSeq_t aCellProperties = 
endTableGetCellProperties(aTableInfo, aMerges);
 
     RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties();
 
@@ -837,8 +857,27 @@ void DomainMapperTableHandler::endTable(unsigned int 
nestedTableLevel)
                         aTableInfo.aTableProperties);
 
                 if (xTable.is())
+                {
                     m_xTableRange = xTable->getAnchor( );
 
+                    if (!aMerges.empty())
+                    {
+                        // Perform horizontal merges in reverse order, so the 
fact that merging changes the position of cells won't cause a problem for us.
+                        for 
(std::vector<HorizontallyMergedCell>::reverse_iterator it = aMerges.rbegin(); 
it != aMerges.rend(); ++it)
+                        {
+                            uno::Reference<table::XCellRange> 
xCellRange(xTable, uno::UNO_QUERY_THROW);
+                            uno::Reference<beans::XPropertySet> 
xCell(xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), 
uno::UNO_QUERY_THROW);
+                            OUString aFirst = 
xCell->getPropertyValue("CellName").get<OUString>();
+                            
xCell.set(xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), 
uno::UNO_QUERY_THROW);
+                            OUString aLast = 
xCell->getPropertyValue("CellName").get<OUString>();
+
+                            uno::Reference<text::XTextTableCursor> xCursor = 
xTable->createCursorByCellName(aFirst);
+                            xCursor->gotoCellByName(aLast, true);
+                            xCursor->mergeRange();
+                        }
+                    }
+                }
+
                 // OOXML table style may container paragraph properties, apply 
these now.
                 for (int i = 0; i < aTableInfo.aTableProperties.getLength(); 
++i)
                 {
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
index 792b978..6b284f7 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
@@ -50,6 +50,21 @@ typedef std::vector<PropertyMapVector1> PropertyMapVector2;
 class DomainMapper_Impl;
 class TableStyleSheetEntry;
 struct TableInfo;
+
+/// A horizontally merged cell is in fact a range of cells till its merge is 
performed.
+struct HorizontallyMergedCell
+{
+    sal_Int32 m_nFirstRow;
+    sal_Int32 m_nFirstCol;
+    sal_Int32 m_nLastRow;
+    sal_Int32 m_nLastCol;
+    HorizontallyMergedCell(sal_Int32 nFirstRow, sal_Int32 nFirstCol)
+        : m_nFirstRow(nFirstRow),
+        m_nFirstCol(nFirstCol)
+    {
+    }
+};
+
 class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : public 
TableDataHandler<Handle_t , TablePropertyMapPtr >
 {
     TextReference_t         m_xText;
@@ -69,7 +84,7 @@ class WRITERFILTER_DLLPRIVATE DomainMapperTableHandler : 
public TableDataHandler
     sal_Int32 m_nRowIndex;
 
     TableStyleSheetEntry * endTableGetTableStyle(TableInfo & rInfo, 
uno::Sequence<beans::PropertyValue>& rFrameProperties);
-    CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo);
+    CellPropertyValuesSeq_t endTableGetCellProperties(TableInfo & rInfo, 
std::vector<HorizontallyMergedCell>& rMerges);
     RowPropertyValuesSeq_t endTableGetRowProperties();
 
 public:
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx 
b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index c3f4c5b..59afbb3 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -298,6 +298,14 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm)
                 cellProps( pMergeProps);
             }
             break;
+            case NS_ooxml::LN_CT_TcPrBase_hMerge:
+            {
+                // values can be: LN_Value_ST_Merge_restart, 
LN_Value_ST_Merge_continue, in reality the second one is a 0
+                TablePropertyMapPtr pMergeProps(new TablePropertyMap());
+                pMergeProps->Insert(PROP_HORIZONTAL_MERGE, false, 
uno::makeAny(bool(sal::static_int_cast<Id>(nIntValue) == 
NS_ooxml::LN_Value_ST_Merge_restart)));
+                cellProps(pMergeProps);
+            }
+            break;
             case NS_ooxml::LN_CT_TcPrBase_gridSpan: //number of grid positions 
spanned by this cell
             {
 #ifdef DEBUG_DOMAINMAPPER
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx 
b/writerfilter/source/dmapper/PropertyIds.cxx
index 46a316c..f305c03 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -325,6 +325,7 @@ const OUString& PropertyNameSupplier::GetName( PropertyIds 
eId ) const
             case PROP_GRAPHIC_URL: sName = "GraphicURL"; break;
             case PROP_GRAPHIC_BITMAP: sName = "GraphicBitmap"; break;
             case PROP_LABEL_CATEGORY: sName = "LabelCategory"; break;
+            case PROP_HORIZONTAL_MERGE: sName = "HorizontalMerge"; break;
         }
         ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt =
                 m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, 
sName ));
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx 
b/writerfilter/source/dmapper/PropertyIds.hxx
index 92d3928d..194d7c5 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -296,6 +296,7 @@ enum PropertyIds
         ,PROP_IS_WIDTH_RELATIVE
         ,PROP_GRAPHIC_URL
         ,PROP_GRAPHIC_BITMAP
+        ,PROP_HORIZONTAL_MERGE
     };
 struct PropertyNameSupplier_Impl;
 class PropertyNameSupplier
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5e7ea2a..2deb1ef 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -2394,6 +2394,18 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
                 m_aStates.top().nBorderState = BORDER_PARAGRAPH;
             }
             break;
+        case RTF_CLMGF:
+        {
+            RTFValue::Pointer_t pValue(new 
RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
+            
m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
+        }
+        break;
+        case RTF_CLMRG:
+        {
+            RTFValue::Pointer_t pValue(new 
RTFValue(NS_ooxml::LN_Value_ST_Merge_continue));
+            
m_aStates.top().aTableCellSprms.set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue);
+        }
+        break;
         case RTF_CLVMGF:
             {
                 RTFValue::Pointer_t pValue(new 
RTFValue(NS_ooxml::LN_Value_ST_Merge_restart));
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to