[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.3-desktop' - 7 commits - configure.ac sc/inc sc/qa sc/source sw/qa sw/source writerfilter/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Sep 21 08:00:08 UTC 2018


 configure.ac                                          |    2 
 sc/inc/dbdata.hxx                                     |    3 -
 sc/qa/unit/data/xlsx/tdf41425.xlsx                    |binary
 sc/qa/unit/subsequent_export-test.cxx                 |   15 +++++
 sc/source/core/data/dptabres.cxx                      |    8 ++-
 sc/source/core/tool/dbdata.cxx                        |    6 +-
 sc/source/filter/excel/xetable.cxx                    |    3 +
 sw/qa/extras/ooxmlexport/data/tdf119143.docx          |binary
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx             |   42 ++++++++++++++++
 sw/source/core/unocore/unochart.cxx                   |   47 ++++++------------
 sw/source/filter/ww8/ww8par3.cxx                      |    2 
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |   18 ++++++
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx |    5 +
 writerfilter/source/ooxml/model.xml                   |   24 +++++++++
 14 files changed, 137 insertions(+), 38 deletions(-)

New commits:
commit 2a9e5f2f24aa9f44eaeb4c06ca7439b87cbd3b89
Author:     Andras Timar <andras.timar at collabora.com>
AuthorDate: Fri Sep 21 01:00:29 2018 -0700
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 01:00:29 2018 -0700

    Bump version to 5.3-57
    
    Change-Id: I7502da6d7242d0d2041cdfd2458dd800bb63e801

diff --git a/configure.ac b/configure.ac
index ab6184ee0d9b..0df4964221eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,7 +9,7 @@ dnl in order to create a configure script.
 # several non-alphanumeric characters, those are split off and used only for the
 # ABOUTBOXPRODUCTVERSIONSUFFIX in openoffice.lst. Why that is necessary, no idea.
 
-AC_INIT([Collabora Office],[5.3.10.54],[],[],[https://collaboraoffice.com/])
+AC_INIT([Collabora Office],[5.3.10.57],[],[],[https://collaboraoffice.com/])
 
 AC_PREREQ([2.59])
 
commit c7b0292184c0942ca00633b88e76367092f3ea91
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Aug 15 14:13:02 2018 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 00:56:46 2018 -0700

    outer loop unrelated to inner loop
    
    since original checkin of...
    
    commit 9cddf9da7fb256418e1bc3b4719abb55e3b0604c
    Date:   Tue May 22 15:33:44 2007 +0000
    
        INTEGRATION: CWS chart2mst3 (1.1.2); FILE ADDED
    ...
        2006/12/13 12:31:03 tl 1.1.2.38: #i71244# update charts in writer
    
    where I think this LockUnlockAllCharts chart2 loop was modelled on
    the previous chart[1] styles loop of e.g. DoUpdateAllCharts which
    loop over tables.
    
    chart2 objects are unrelated to these tables, so remove the outer
    loop, which then means the ofz#9689 ofz#9856 ofz9874 crashes that
    made me look at it will get fixed
    
    Change-Id: I7d7ba0a2aa257b5aa399f20d902f01306fbaecff
    Reviewed-on: https://gerrit.libreoffice.org/59112
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>
    (cherry picked from commit eadf6f4551416430b58efc42a5756556df0a237d)
    (cherry picked from commit 74de907344923a9f9575927fca8d43260f86f4c9)

diff --git a/sw/source/core/unocore/unochart.cxx b/sw/source/core/unocore/unochart.cxx
index 7d71e852fb85..2ef1118bf09a 100644
--- a/sw/source/core/unocore/unochart.cxx
+++ b/sw/source/core/unocore/unochart.cxx
@@ -118,43 +118,30 @@ void SwChartLockController_Helper::LockUnlockAllCharts( bool bLock )
     if (!pDoc)
         return;
 
-    const SwFrameFormats& rTableFormats = *pDoc->GetTableFrameFormats();
-    for( size_t n = 0; n < rTableFormats.size(); ++n )
+    uno::Reference< frame::XModel > xRes;
+    SwOLENode *pONd;
+    SwStartNode *pStNd;
+    SwNodeIndex aIdx( *pDoc->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
+    while( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) )
     {
-        SwTable* pTmpTable;
-        const SwTableNode* pTableNd;
-        const SwFrameFormat* pFormat = rTableFormats[ n ];
-
-        if( nullptr != ( pTmpTable = SwTable::FindTable( pFormat ) ) &&
-            nullptr != ( pTableNd = pTmpTable->GetTableNode() ) &&
-            pTableNd->GetNodes().IsDocNodes() )
+        ++aIdx;
+        if (nullptr != ( pONd = aIdx.GetNode().GetOLENode() ) &&
+            !pONd->GetChartTableName().isEmpty() /* is chart object? */)
         {
-            uno::Reference< frame::XModel > xRes;
-            SwOLENode *pONd;
-            SwStartNode *pStNd;
-            SwNodeIndex aIdx( *pDoc->GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 );
-            while( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) )
+            uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
+            if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
             {
-                ++aIdx;
-                if (nullptr != ( pONd = aIdx.GetNode().GetOLENode() ) &&
-                    !pONd->GetChartTableName().isEmpty() /* is chart object? */)
+                xRes.set( xIP->getComponent(), uno::UNO_QUERY );
+                if (xRes.is())
                 {
-                    uno::Reference < embed::XEmbeddedObject > xIP = pONd->GetOLEObj().GetOleRef();
-                    if ( svt::EmbeddedObjectRef::TryRunningState( xIP ) )
-                    {
-                        xRes.set( xIP->getComponent(), uno::UNO_QUERY );
-                        if (xRes.is())
-                        {
-                            if (bLock)
-                                xRes->lockControllers();
-                            else
-                                xRes->unlockControllers();
-                        }
-                    }
+                    if (bLock)
+                        xRes->lockControllers();
+                    else
+                        xRes->unlockControllers();
                 }
-                aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
             }
         }
+        aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 );
     }
 
     bIsLocked = bLock;
commit 3298d3c68fa17b350ef7bec8271fcfc673b5e1a7
Author:     Eike Rathke <erack at redhat.com>
AuthorDate: Thu Sep 20 18:12:03 2018 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 00:47:19 2018 -0700

    Resolves: tdf#119954 do not copy the old parent, init with new parent instead
    
    The parent is always the ScDBCollection that contains the
    ScDBCollection::NamedDBs container, not the one the
    ScDBCollection::NamedDBs was copy-constructed from.
    
    Change-Id: Ia409347f3aeb9ad7a5e68da7af727adfac98d6a2
    Reviewed-on: https://gerrit.libreoffice.org/60833
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Jenkins
    (cherry picked from commit 7ea5d339dc4d8412f436f3affa589bfbd0b1ef68)

diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx
index df6b88d4dbb9..27a7cb77b4ac 100644
--- a/sc/inc/dbdata.hxx
+++ b/sc/inc/dbdata.hxx
@@ -241,7 +241,8 @@ public:
         DBsType m_DBs;
         ScDBCollection& mrParent;
         NamedDBs(ScDBCollection& rParent, ScDocument& rDoc);
-        NamedDBs(const NamedDBs& r);
+        NamedDBs(const NamedDBs& r, ScDBCollection& rParent);
+        NamedDBs(const NamedDBs&) = delete;
         virtual ~NamedDBs() override;
         NamedDBs & operator=(NamedDBs const&) = delete;
         void initInserted( ScDBData* p );
diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx
index 1d62a479981b..31c1977ca064 100644
--- a/sc/source/core/tool/dbdata.cxx
+++ b/sc/source/core/tool/dbdata.cxx
@@ -1071,9 +1071,9 @@ ScRangeList& ScDBDataContainerBase::GetDirtyTableColumnNames()
 ScDBCollection::NamedDBs::NamedDBs(ScDBCollection& rParent, ScDocument& rDoc) :
     ScDBDataContainerBase(rDoc), mrParent(rParent) {}
 
-ScDBCollection::NamedDBs::NamedDBs(const NamedDBs& r)
+ScDBCollection::NamedDBs::NamedDBs(const NamedDBs& r, ScDBCollection& rParent)
     : ScDBDataContainerBase(r.mrDoc)
-    , mrParent(r.mrParent)
+    , mrParent(rParent)
 {
     for (auto const& it : r.m_DBs)
     {
@@ -1288,7 +1288,7 @@ ScDBCollection::ScDBCollection(ScDocument* pDocument) :
     pDoc(pDocument), nEntryIndex(1), maNamedDBs(*this, *pDocument) {}
 
 ScDBCollection::ScDBCollection(const ScDBCollection& r) :
-    pDoc(r.pDoc), nEntryIndex(r.nEntryIndex), maNamedDBs(r.maNamedDBs), maAnonDBs(r.maAnonDBs) {}
+    pDoc(r.pDoc), nEntryIndex(r.nEntryIndex), maNamedDBs(r.maNamedDBs, *this), maAnonDBs(r.maAnonDBs) {}
 
 const ScDBData* ScDBCollection::GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const
 {
commit 108eca19c9043895f26c889c90b3f4081113a3fb
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Sep 20 16:03:24 2018 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 00:46:44 2018 -0700

    ofz#10523 guard aginst 0 pF->nLCode
    
    Change-Id: I8ef476e06f54ddd57be907488a8a65314abda3ee

diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index 5f334ad3361e..e1031167416a 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -102,7 +102,7 @@ eF_ResT SwWW8ImplReader::Read_F_FormTextBox( WW8FieldDesc* pF, OUString& rStr )
 {
     WW8FormulaEditBox aFormula(*this);
 
-    if (rStr[pF->nLCode-1]==0x01) {
+    if (pF->nLCode && rStr[pF->nLCode-1]==0x01) {
         ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_EDIT);
     }
 
commit adc040bbff6a4bac6b96f857c9a24b1a1beba1b2
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Fri Aug 3 16:11:16 2018 +0200
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 00:26:09 2018 -0700

    tdf#41425 XLS/XLSX export: workaround for style and validation loss
    
    of cells of blank rows.
    
    This workaround is probably a fix for problems of most users, but for
    a full solution it needs to extend the workaround for all rows with not
    default settings, also avoiding of the possible performance problems.
    
    Note: the number 1000 of the extra rows came from a similar workaround used in
    XLSX export of Google Spreadsheets, but instead of listing extra empty 1000
    rows in OOXML, this fix writes only the cells with not default settings from
    the extra 1000 blank rows.
    
    Reviewed-on: https://gerrit.libreoffice.org/58575
    Tested-by: Jenkins
    Reviewed-by: László Németh <nemeth at numbertext.org>
    (cherry picked from commit 99b9ea63bfc9a5fe63a0cd7b30b66ce2c1bde08e)
    Reviewed-on: https://gerrit.libreoffice.org/58812
    Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice at googlemail.com>
    (cherry picked from commit d7cbaac61b8f3575184c675a760907c3b4bb225e)
    
    Change-Id: Icac9441b7eb1520dcd20fc04337e070d070591c7
    (cherry picked from commit f9df3478ace3fb3ea25d24c7bc8b6b72cd7f1729)

diff --git a/sc/qa/unit/data/xlsx/tdf41425.xlsx b/sc/qa/unit/data/xlsx/tdf41425.xlsx
new file mode 100644
index 000000000000..f7d3ec9ed6ec
Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf41425.xlsx differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 4b6370ba64c8..1a42cb84828a 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -217,6 +217,7 @@ public:
     void testPivotTableOutlineModeXLSX();
     void testPivotTableDuplicatedMemberFilterXLSX();
     void testPivotTableTabularModeXLSX();
+    void testKeepSettingsOfBlankRows();
 
     CPPUNIT_TEST_SUITE(ScExportTest);
     CPPUNIT_TEST(test);
@@ -334,6 +335,7 @@ public:
     CPPUNIT_TEST(testPivotTableOutlineModeXLSX);
     CPPUNIT_TEST(testPivotTableDuplicatedMemberFilterXLSX);
     CPPUNIT_TEST(testPivotTableTabularModeXLSX);
+    CPPUNIT_TEST(testKeepSettingsOfBlankRows);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -5211,6 +5213,19 @@ void ScExportTest::testPivotTableTabularModeXLSX()
     assertXPath(pTable, "/x:pivotTableDefinition/x:pivotFields/x:pivotField[1]", "outline", "0");
 }
 
+void ScExportTest::testKeepSettingsOfBlankRows()
+{
+    ScDocShellRef xDocSh = loadDoc("tdf41425.", FORMAT_XLSX);
+    CPPUNIT_ASSERT(xDocSh.Is());
+
+    std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
+    xmlDocPtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
+    CPPUNIT_ASSERT(pSheet);
+
+    // saved blank row with not default setting in A2
+    assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row", 2);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index 29257f2df5ed..12e5afc0b5a7 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -2463,6 +2463,9 @@ XclExpCellTable::XclExpCellTable( const XclExpRoot& rRoot ) :
     if(nLastUsedScCol > nMaxScCol)
         nLastUsedScCol = nMaxScCol;
 
+    // check extra blank rows to avoid of losing their not default settings (workaround for tdf#41425)
+    nLastUsedScRow += 1000;
+
     if(nLastUsedScRow > nMaxScRow)
         nLastUsedScRow = nMaxScRow;
 
commit f0d27ad961d7b0e8dbc9f41e645b620fc3978017
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Sun Sep 2 21:20:40 2018 +0100
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 00:25:03 2018 -0700

    ofz#10189 check container size
    
    Change-Id: Ie99e3b082795989290799d057a99b1bcff94b161
    Reviewed-on: https://gerrit.libreoffice.org/59913
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <Michael.Stahl at cib.de>
    (cherry picked from commit 6ee76d210846b84e93420a321c7908721ffe9e43)
    (cherry picked from commit 59e68800029dd91aced2daf1bae41d6ee3e4b6b8)

diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index c20c2a94160d..f992e7aef126 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -2871,10 +2871,14 @@ void ScDPResultDimension::LateInitFrom(
 {
     if ( rParams.IsEnd( nPos ) )
         return;
-    OSL_ENSURE( nPos <= pItemData.size(), OString::number(pItemData.size()).getStr() );
+    if (nPos >= pItemData.size())
+    {
+        SAL_WARN("sc.core", "pos " << nPos << ", but vector size is " << pItemData.size());
+        return;
+    }
+    SCROW rThisData = pItemData[nPos];
     ScDPDimension* pThisDim = rParams.GetDim( nPos );
     ScDPLevel* pThisLevel = rParams.GetLevel( nPos );
-    SCROW rThisData = pItemData[nPos];
 
     if (!pThisDim || !pThisLevel)
         return;
commit 6a03a91c4ee7fb875aa7818b026ff0fa6d72c83c
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Mon Aug 27 12:34:12 2018 +0300
Commit:     Andras Timar <andras.timar at collabora.com>
CommitDate: Fri Sep 21 00:24:37 2018 -0700

    tdf#119143: introduce tentative directional embedding import support
    
    ECMA-376-1:2016 states that w:dir is functionally equivalent to LRE/RLE+PDF
    pair around the enclosed runs. So this patch does just that.
    
    Change-Id: Ibf9775338cc38a3bbc38a42a33fc64ae787b478f
    Reviewed-on: https://gerrit.libreoffice.org/59643
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/59672
    Reviewed-by: Aron Budea <aron.budea at collabora.com>
    Tested-by: Aron Budea <aron.budea at collabora.com>
    (cherry picked from commit 348a1e11045ca8d9dbceab43a68d44dbde3f922c)

diff --git a/sw/qa/extras/ooxmlexport/data/tdf119143.docx b/sw/qa/extras/ooxmlexport/data/tdf119143.docx
new file mode 100644
index 000000000000..be0bc03f71c1
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf119143.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 079fadcca914..7e6b07bde3ec 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -733,6 +733,48 @@ DECLARE_OOXMLEXPORT_TEST(testTdf116976, "tdf116976.docx")
                          getProperty<sal_Int16>(getShape(1), "RelativeWidth"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf119143, "tdf119143.docx")
+{
+    const char sParaTextExpected[] =
+        "\xD8\xB9\xD9\x86\xD8\xAF\xD9\x85\xD8\xA7 \xD9\x8A\xD8\xB1\xD9\x8A\xD8\xAF \xD8\xA7\xD9\x84"
+        "\xD8\xB9\xD8\xA7\xD9\x84\xD9\x85 \xD8\xA3\xD9\x86 \xD9\x8A\xD8\xAA\xD9\x83\xD9\x84\xD9\x91"
+        "\xD9\x85 \xE2\x80\xAC \xD8\x8C \xD9\x81\xD9\x87\xD9\x88 \xD9\x8A\xD8\xAA\xD8\xAD\xD8\xAF"
+        "\xD9\x91\xD8\xAB \xD8\xA8\xD9\x84\xD8\xBA\xD8\xA9 \xD9\x8A\xD9\x88\xD9\x86\xD9\x8A\xD9\x83"
+        "\xD9\x88\xD8\xAF. \xD8\xAA\xD8\xB3\xD8\xAC\xD9\x91\xD9\x84 \xD8\xA7\xD9\x84\xD8\xA2\xD9"
+        "\x86 \xD9\x84\xD8\xAD\xD8\xB6\xD9\x88\xD8\xB1 \xD8\xA7\xD9\x84\xD9\x85\xD8\xA4\xD8\xAA\xD9"
+        "\x85\xD8\xB1 \xD8\xA7\xD9\x84\xD8\xAF\xD9\x88\xD9\x84\xD9\x8A \xD8\xA7\xD9\x84\xD8\xB9\xD8"
+        "\xA7\xD8\xB4\xD8\xB1 \xD9\x84\xD9\x8A\xD9\x88\xD9\x86\xD9\x8A\xD9\x83\xD9\x88\xD8\xAF (Uni"
+        "code Conference)\xD8\x8C \xD8\xA7\xD9\x84\xD8\xB0\xD9\x8A \xD8\xB3\xD9\x8A\xD8\xB9\xD9\x82"
+        "\xD8\xAF \xD9\x81\xD9\x8A 10-12 \xD8\xA2\xD8\xB0\xD8\xA7\xD8\xB1 1997 \xD8\xA8\xD9\x85\xD8"
+        "\xAF\xD9\x8A\xD9\x86\xD8\xA9 \xD9\x85\xD9\x8E\xD8\xA7\xD9\x8A\xD9\x90\xD9\x86\xD9\x92\xD8"
+        "\xAA\xD9\x92\xD8\xB3\xD8\x8C \xD8\xA3\xD9\x84\xD9\x85\xD8\xA7\xD9\x86\xD9\x8A\xD8\xA7. "
+        "\xD9\x88 \xD8\xB3\xD9\x8A\xD8\xAC\xD9\x85\xD8\xB9 \xD8\xA7\xD9\x84\xD9\x85\xD8\xA4\xD8\xAA"
+        "\xD9\x85\xD8\xB1 \xD8\xA8\xD9\x8A\xD9\x86 \xD8\xAE\xD8\xA8\xD8\xB1\xD8\xA7\xD8\xA1 \xD9"
+        "\x85\xD9\x86 \xD9\x83\xD8\xA7\xD9\x81\xD8\xA9 \xD9\x82\xD8\xB7\xD8\xA7\xD8\xB9\xD8\xA7\xD8"
+        "\xAA \xD8\xA7\xD9\x84\xD8\xB5\xD9\x86\xD8\xA7\xD8\xB9\xD8\xA9 \xD8\xB9\xD9\x84\xD9\x89 "
+        "\xD8\xA7\xD9\x84\xD8\xB4\xD8\xA8\xD9\x83\xD8\xA9 \xD8\xA7\xD9\x84\xD8\xB9\xD8\xA7\xD9\x84"
+        "\xD9\x85\xD9\x8A\xD8\xA9 \xD8\xA7\xD9\x86\xD8\xAA\xD8\xB1\xD9\x86\xD9\x8A\xD8\xAA \xD9\x88"
+        "\xD9\x8A\xD9\x88\xD9\x86\xD9\x8A\xD9\x83\xD9\x88\xD8\xAF\xD8\x8C \xD8\xAD\xD9\x8A\xD8\xAB "
+        "\xD8\xB3\xD8\xAA\xD8\xAA\xD9\x85\xD8\x8C \xD8\xB9\xD9\x84\xD9\x89 \xD8\xA7\xD9\x84\xD8\xB5"
+        "\xD8\xB9\xD9\x8A\xD8\xAF\xD9\x8A\xD9\x86 \xD8\xA7\xD9\x84\xD8\xAF\xD9\x88\xD9\x84\xD9\x8A "
+        "\xD9\x88\xD8\xA7\xD9\x84\xD9\x85\xD8\xAD\xD9\x84\xD9\x8A \xD8\xB9\xD9\x84\xD9\x89 \xD8\xAD"
+        "\xD8\xAF \xD8\xB3\xD9\x88\xD8\xA7\xD8\xA1 \xD9\x85\xD9\x86\xD8\xA7\xD9\x82\xD8\xB4\xD8\xA9"
+        " \xD8\xB3\xD8\xA8\xD9\x84 \xD8\xA7\xD8\xB3\xD8\xAA\xD8\xAE\xD8\xAF\xD8\xA7\xD9\x85 \xD9"
+        "\x8A\xD9\x88\xD9\x86\xD9\x83\xD9\x88\xD8\xAF \xD9\x81\xD9\x8A \xD8\xA7\xD9\x84\xD9\x86\xD8"
+        "\xB8\xD9\x85 \xD8\xA7\xD9\x84\xD9\x82\xD8\xA7\xD8\xA6\xD9\x85\xD8\xA9 \xD9\x88\xD9\x81\xD9"
+        "\x8A\xD9\x85\xD8\xA7 \xD9\x8A\xD8\xAE\xD8\xB5 \xD8\xA7\xD9\x84\xD8\xAA\xD8\xB7\xD8\xA8\xD9"
+        "\x8A\xD9\x82\xD8\xA7\xD8\xAA \xD8\xA7\xD9\x84\xD8\xAD\xD8\xA7\xD8\xB3\xD9\x88\xD8\xA8\xD9"
+        "\x8A\xD8\xA9\xD8\x8C \xD8\xA7\xD9\x84\xD8\xAE\xD8\xB7\xD9\x88\xD8\xB7\xD8\x8C \xD8\xAA\xD8"
+        "\xB5\xD9\x85\xD9\x8A\xD9\x85 \xD8\xA7\xD9\x84\xD9\x86\xD8\xB5\xD9\x88\xD8\xB5 \xD9\x88\xD8"
+        "\xA7\xD9\x84\xD8\xAD\xD9\x88\xD8\xB3\xD8\xA8\xD8\xA9 \xD9\x85\xD8\xAA\xD8\xB9\xD8\xAF\xD8"
+        "\xAF\xD8\xA9 \xD8\xA7\xD9\x84\xD9\x84\xD8\xBA\xD8\xA7\xD8\xAA.";
+    // The runs inside <w:dir> were ignored
+    const OUString sParaText = getParagraph(1)->getString();
+    CPPUNIT_ASSERT_EQUAL(
+        OUString::fromUtf8(sParaTextExpected),
+        sParaText);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
index 388f02603f85..6958d15aaae2 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx
@@ -387,6 +387,10 @@ void OOXMLFastContextHandler::endCharacterGroup()
     }
 }
 
+void OOXMLFastContextHandler::pushBiDiEmbedLevel() {}
+
+void OOXMLFastContextHandler::popBiDiEmbedLevel() {}
+
 void OOXMLFastContextHandler::startParagraphGroup()
 {
     if (isForwardEvents())
@@ -1276,6 +1280,20 @@ void OOXMLFastContextHandlerValue::setDefaultStringValue()
         setValue(pValue);
     }
 }
+
+// ECMA-376-1:2016 17.3.2.8; https://www.unicode.org/reports/tr9/#Explicit_Directional_Embeddings
+void OOXMLFastContextHandlerValue::pushBiDiEmbedLevel()
+{
+    const bool bRtl
+        = mpValue.get() && mpValue.get()->getInt() == NS_ooxml::LN_Value_ST_Direction_rtl;
+    OOXMLFactory::characters(this, OUString(sal_Unicode(bRtl ? 0x202B : 0x202A))); // RLE / LRE
+}
+
+void OOXMLFastContextHandlerValue::popBiDiEmbedLevel()
+{
+    OOXMLFactory::characters(this, OUString(sal_Unicode(0x202C))); // PDF (POP DIRECTIONAL FORMATTING)
+}
+
 /*
   class OOXMLFastContextHandlerTable
 */
diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
index 62a4e00822df..e21132210d1b 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -144,6 +144,8 @@ public:
     void endParagraphGroup();
     void startCharacterGroup();
     void endCharacterGroup();
+    virtual void pushBiDiEmbedLevel();
+    virtual void popBiDiEmbedLevel();
     void startSdt();
     void endSdt();
 
@@ -341,6 +343,9 @@ public:
     virtual void setDefaultHexValue() override;
     virtual void setDefaultStringValue() override;
 
+    virtual void pushBiDiEmbedLevel() override;
+    virtual void popBiDiEmbedLevel() override;
+
 protected:
     OOXMLValue::Pointer_t mpValue;
 };
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index 76d718450e50..884c559fc2fe 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -13939,12 +13939,27 @@
           <element name="sdt">
             <ref name="CT_SdtRun"/>
           </element>
+          <element name="dir">
+            <ref name="CT_DirContentRun"/>
+          </element>
           <element name="r">
             <ref name="CT_R"/>
           </element>
           <ref name="EG_RunLevelElts"/>
         </choice>
       </define>
+      <define name="CT_DirContentRun">
+        <ref name="EG_PContent"/>
+        <attribute name="val">
+          <ref name="ST_Direction"/>
+        </attribute>
+      </define>
+      <define name="ST_Direction">
+        <choice>
+          <value>ltr</value>
+          <value>rtl</value>
+        </choice>
+      </define>
       <define name="CT_SdtContentRun">
         <ref name="EG_PContent"/>
       </define>
@@ -18128,6 +18143,15 @@
     <resource name="CT_SdtEndPr" resource="Properties">
       <element name="rPr" tokenid="ooxml:CT_SdtEndPr_rPr"/>
     </resource>
+    <resource name="CT_DirContentRun" resource="Value">
+      <attribute name="val" tokenid="ooxml:CT_DirContentRun_val" action="setValue"/>
+      <action name="start" action="pushBiDiEmbedLevel"/>
+      <action name="end" action="popBiDiEmbedLevel"/>
+    </resource>
+    <resource name="ST_Direction" resource="List">
+      <value tokenid="ooxml:Value_ST_Direction_ltr">ltr</value>
+      <value tokenid="ooxml:Value_ST_Direction_rtl">rtl</value>
+    </resource>
     <resource name="CT_SdtContentRun" resource="Stream"/>
     <resource name="CT_SdtContentBlock" resource="Stream"/>
     <resource name="CT_SdtContentRow" resource="Stream"/>


More information about the Libreoffice-commits mailing list