sw/qa/extras/uiwriter/data/tdf151993.docx         |binary
 sw/qa/extras/uiwriter/uiwriter6.cxx               |   30 +++++++++++++++++++++-
 writerfilter/source/dmapper/DomainMapper.cxx      |   10 +++++++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |    7 +++--
 writerfilter/source/dmapper/DomainMapper_Impl.hxx |    3 ++
 5 files changed, 47 insertions(+), 3 deletions(-)

New commits:
commit 42baf73137d1776618af5d7c7406bac86ebeb63c
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Mon Nov 14 10:01:36 2022 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Mon Nov 14 13:33:26 2022 +0100

    tdf#151993 DOCX import: convert decimal comma only if needed
    
    E.g. convert en_US document with decimal comma, but not
    de_DE document with decimal comma.
    
    Regression from commit 94bf4908a6661101c270ef647e33dde09f16ac08
    "tdf#148799 DOCX import: fix invalid formulas with comma".
    
    DOCX allows to set decimal symbol independently from the locale
    of the document, so if the DOCX document uses comma, but
    its locale ("language") has got a default decimal point in Writer,
    Writer formulas must contain decimal points instead of commas,
    otherwise automatic update of the formulas, e.g. moving text
    cursor in the table, results ** Expression is faulty ** instead
    of the recalculated value. The only way to get standard
    Writer formulas is to replace the commas with points in numbers
    in writerfilter, if document language has a default
    decimal point in Writer.
    
    Note: not only document language, but area setting of
    LibreOffice installation modifies formula handling. I.e.
    plain numbers recognized with comma only if area setting
    is modified to a language, which uses decimal comma
    (but formulas still need decimal points, if the language
    of the document is a locale with default decimal point).
    E.g. an en_US DOCX document with decimal comma, or a
    de_DE document with decimal comma loaded correctly now,
    but recognizing cell content with a single number with comma
    needs to set also the correct area setting.
    
    Conflicts:
            sw/qa/extras/uiwriter/uiwriter6.cxx
            writerfilter/source/dmapper/DomainMapper_Impl.cxx
    
    (cherry-picked from commit c6688def010fcb6854c6d896efe7186ff6c63475)
    
    Change-Id: Ib13584f83bf36cbd68105da252f7d4955296ec80
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142670
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/sw/qa/extras/uiwriter/data/tdf151993.docx 
b/sw/qa/extras/uiwriter/data/tdf151993.docx
new file mode 100644
index 000000000000..462feb0a61e4
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf151993.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 5b98871bed91..e66fae378115 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -2173,7 +2173,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testCaptionShape)
 
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf148799)
 {
-    // load a document with table formulas with comman delimiter
+    // load a document with table formulas with comma delimiter,
+    // but with a document language with default point delimiter
     SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf148799.docx");
     SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
     // check formula update
@@ -2194,6 +2195,33 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf148799)
     CPPUNIT_ASSERT_EQUAL(OUString("23684.5"), xCellA4->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf151993)
+{
+    // load a document with table formulas with comma delimiter
+    // (with a document language with default comma delimiter)
+    SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "tdf151993.docx");
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+    // check formula update
+
+    // put cursor in the first table row
+    pWrtShell->Down(/*bSelect=*/false, /*nCount=*/1);
+
+    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> 
xTables(xTextTablesSupplier->getTextTables(),
+                                                    uno::UNO_QUERY);
+
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
+
+    uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), 
uno::UNO_QUERY);
+
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTextTable->getRows()->getCount());
+
+    // This was 0
+    uno::Reference<text::XTextRange> xCellA1(xTextTable->getCellByName("A2"), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("30"), xCellA1->getString());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf151462)
 {
     createSwDoc(DATA_DIRECTORY, "tdf151462.odt");
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx 
b/writerfilter/source/dmapper/DomainMapper.cxx
index bfe9769e6293..219c62cef04d 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -75,6 +75,7 @@
 #include <editeng/escapementitem.hxx>
 #include <filter/msfilter/util.hxx>
 #include <sfx2/DocumentMetadataAccess.hxx>
+#include <unotools/localedatawrapper.hxx>
 #include <unotools/mediadescriptor.hxx>
 
 #include "TextEffectsHandler.hxx"
@@ -658,6 +659,15 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         case NS_ooxml::LN_CT_Language_eastAsia: //90315
         case NS_ooxml::LN_CT_Language_bidi: //90316
         {
+            // store decimal symbol associated to the language of the document
+            if ( m_pImpl->IsDocDefaultsImport() && ( nName == 
NS_ooxml::LN_CT_Language_val ) )
+            {
+                LanguageTag aLanguageTag( sStringValue );
+                LocaleDataWrapper aLocaleWrapper( std::move(aLanguageTag) );
+                if ( aLocaleWrapper.getNumDecimalSep() == "," )
+                    m_pImpl->SetIsDecimalComma();
+
+            }
             if (nName == NS_ooxml::LN_CT_Language_eastAsia)
                 m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, 
"eastAsia", sStringValue);
             else if (nName == NS_ooxml::LN_CT_Language_val)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index ca0803c53931..03ac1467426e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -323,6 +323,7 @@ DomainMapper_Impl::DomainMapper_Impl(
         m_xTextFactory( xModel, uno::UNO_QUERY ),
         m_xComponentContext( xContext ),
         m_bForceGenericFields(!utl::ConfigManager::IsFuzzing() && 
officecfg::Office::Common::Filter::Microsoft::Import::ForceImportWWFieldsAsGenericFields::get()),
+        m_bIsDecimalComma( false ),
         m_bSetUserFieldContent( false ),
         m_bSetCitation( false ),
         m_bSetDateValue( false ),
@@ -5498,8 +5499,10 @@ OUString DomainMapper_Impl::convertFieldFormula(const 
OUString& input) {
     icu::RegexMatcher rmatch6("\\b(ABOVE|BELOW|LEFT|RIGHT)\\b", usInput, 
rMatcherFlags, status);
     usInput = rmatch6.replaceAll(icu::UnicodeString(" $1 "), status);
 
-    /* fix decimal separator */
-    if ( m_pSettingsTable->GetDecimalSymbol() == "," )
+    /* DOCX allows to set decimal symbol independently from the locale of the 
document, so if
+     * needed, convert decimal comma to get working formula in a document 
language (locale),
+     * which doesn't use decimal comma */
+    if ( m_pSettingsTable->GetDecimalSymbol() == "," && !m_bIsDecimalComma )
     {
         icu::RegexMatcher rmatch7("\\b([0-9]+),([0-9]+([eE][-]?[0-9]+)?)\\b", 
usInput, rMatcherFlags, status);
         usInput = rmatch7.replaceAll(icu::UnicodeString("$1.$2"), status);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index f6b88fec09b3..1707e171b379 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -475,6 +475,8 @@ private:
     std::stack<std::pair<TextAppendContext, bool>>                             
     m_aHeaderFooterTextAppendStack;
     std::deque<FieldContextPtr> m_aFieldStack;
     bool m_bForceGenericFields;
+    /// Type of decimal symbol associated to the document language in Writer 
locale definition
+    bool                                                                       
     m_bIsDecimalComma;
     bool                                                                       
     m_bSetUserFieldContent;
     bool                                                                       
     m_bSetCitation;
     bool                                                                       
     m_bSetDateValue;
@@ -686,6 +688,7 @@ public:
     void RemoveDummyParaForTableInSection();
     void AddDummyParaForTableInSection();
     void RemoveLastParagraph( );
+    void SetIsDecimalComma() { m_bIsDecimalComma = true; };
     void SetIsLastParagraphInSection( bool bIsLast );
     bool GetIsLastParagraphInSection() const { return m_bIsLastParaInSection;}
     void SetRubySprmId( sal_uInt32 nSprmId) { m_aRubyInfo.nSprmId = nSprmId ; }

Reply via email to