editeng/source/misc/svxacorr.cxx         |   42 ++++++++++++++++++++++++++++---
 sw/qa/extras/uiwriter/data/tdf44293.fodt |   14 ++++++++++
 sw/qa/extras/uiwriter/uiwriter8.cxx      |   16 +++++++++++
 3 files changed, 68 insertions(+), 4 deletions(-)

New commits:
commit 7cc712eaa6757a461ac68532d77add2a49bd9181
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed May 15 01:15:16 2024 +0200
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Wed May 15 10:32:03 2024 +0200

    tdf#44293 sw AutoCorrect: fix Portuguese ordinal indicators
    
    Add missing dot, support plural and alternative forms with 'r':
    
    – add missing dot: 1a -> 1.ª, 1o -> 1.º
    
    – support plural forms: 43as -> 43.ªˢ, 43os -> 43ºˢ
    
    - support alternative forms:
    
      1ra -> 1.ª, 1ro -> 1.º, 43ras -> 43.ªˢ, 43ros -> 43.ºˢ
    
    Change-Id: Ibaeae958ca209edffb13f611ee8a71c80bf15a26
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167649
    Tested-by: Jenkins
    Reviewed-by: László Németh <nem...@numbertext.org>

diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 12c63fc5f272..1597e523a766 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -44,6 +44,7 @@
 #include <unotools/localedatawrapper.hxx>
 #include <unotools/transliterationwrapper.hxx>
 #include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
 #include <comphelper/storagehelper.hxx>
 #include <o3tl/string_view.hxx>
 #include <editeng/editids.hrc>
@@ -507,28 +508,61 @@ bool SvxAutoCorrect::FnChgOrdinalNumber(
 
         if (bFoundEnd && isValidNumber) {
             sal_Int32 nNum = o3tl::toInt32(rTxt.subView(nSttPos, nNumEnd - 
nSttPos + 1));
+            std::u16string_view sEnd = rTxt.subView(nNumEnd + 1, nEndPos - 
nNumEnd - 1);
 
             // Check if the characters after that number correspond to the 
ordinal suffix
             uno::Reference< i18n::XOrdinalSuffix > xOrdSuffix
                 = 
i18n::OrdinalSuffix::create(comphelper::getProcessComponentContext());
 
-            const uno::Sequence< OUString > aSuffixes = 
xOrdSuffix->getOrdinalSuffix(nNum, rCC.getLanguageTag().getLocale());
-            for (OUString const & sSuffix : aSuffixes)
+            uno::Sequence< OUString > aSuffixes = 
xOrdSuffix->getOrdinalSuffix(nNum, rCC.getLanguageTag().getLocale());
+
+            // add extra suffixes for languages not handled by i18npool/ICU
+            if ( primary(eLang) == primary(LANGUAGE_PORTUGUESE) &&
+                            ( nEndPos == nNumEnd + 3 || nEndPos == nNumEnd + 4 
) &&
+                            ( sEnd[0] == 'a' || sEnd[0] == 'o' || sEnd[0] == 
'r' ) )
             {
-                std::u16string_view sEnd = rTxt.subView(nNumEnd + 1, nEndPos - 
nNumEnd - 1);
+               auto aExtendedSuffixes = comphelper::sequenceToContainer< 
std::vector<OUString> >(aSuffixes);
+               aExtendedSuffixes.push_back("as"); // plural form of 'a'
+               aExtendedSuffixes.push_back("os"); // plural form of 'o'
+               aExtendedSuffixes.push_back("ra"); // alternative form of 'a'
+               aExtendedSuffixes.push_back("ro"); // alternative form of 'o'
+               aExtendedSuffixes.push_back("ras"); // alternative form of "as"
+               aExtendedSuffixes.push_back("ros"); // alternative form of "os"
+               aSuffixes = comphelper::containerToSequence(aExtendedSuffixes);
+            }
 
+            for (OUString const & sSuffix : aSuffixes)
+            {
                 if (sSuffix == sEnd)
                 {
                     // Check if the ordinal suffix has to be set as super 
script
                     if (rCC.isLetter(sSuffix))
                     {
+                        sal_Int32 nNumberChanged = 0;
+                        sal_Int32 nSuffixChanged = 0;
+                        // exceptions for Portuguese
+                        // add missing dot: 1a -> 1.ª
+                        // and remove optional 'r': 1ro -> 1.º
+                        if ( primary(eLang) == primary(LANGUAGE_PORTUGUESE) )
+                        {
+                            if ( sSuffix.startsWith("r") )
+                            {
+                                rDoc.Delete( nNumEnd + 1, nNumEnd + 2 );
+                                nSuffixChanged = -1;
+                            }
+                            rDoc.Insert( nNumEnd + 1, "." );
+                            nNumberChanged = 1;
+                        }
+
                         // Do the change
                         SvxEscapementItem 
aSvxEscapementItem(DFLT_ESC_AUTO_SUPER,
                             DFLT_ESC_PROP, SID_ATTR_CHAR_ESCAPEMENT);
-                        rDoc.SetAttr(nNumEnd + 1, nEndPos,
+                        rDoc.SetAttr(nNumEnd + 1 + nNumberChanged,
+                            nEndPos + nNumberChanged + nSuffixChanged,
                             SID_ATTR_CHAR_ESCAPEMENT,
                             aSvxEscapementItem);
                         bChg = true;
+                        break;
                     }
                 }
             }
diff --git a/sw/qa/extras/uiwriter/data/tdf44293.fodt 
b/sw/qa/extras/uiwriter/data/tdf44293.fodt
new file mode 100644
index 000000000000..3b6f5e48248b
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf44293.fodt
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph">
+   <style:text-properties fo:language="pt" fo:country="BR"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="P1"></text:p>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index 73e66f746f06..2264c86c460e 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -2974,6 +2974,22 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf158703)
     CPPUNIT_ASSERT_EQUAL(u"Foo\u00A0:"_ustr, getParagraph(1)->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf44293)
+{
+    // Given a document with Portuguese text
+    createSwDoc("tdf44293.fodt");
+    SwXTextDocument* pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    CPPUNIT_ASSERT(pTextDoc);
+
+    emulateTyping(*pTextDoc, u"1a 1o ");
+    CPPUNIT_ASSERT_EQUAL(u"1.a 1.o "_ustr, getParagraph(1)->getString());
+    emulateTyping(*pTextDoc, u"1ra 1ro ");
+    CPPUNIT_ASSERT_EQUAL(u"1.a 1.o 1.a 1.o "_ustr, 
getParagraph(1)->getString());
+    emulateTyping(*pTextDoc, u"43as 43os 43ras 43ros ");
+    CPPUNIT_ASSERT_EQUAL(u"1.a 1.o 1.a 1.o 43.as 43.os 43.as 43.os "_ustr,
+                         getParagraph(1)->getString());
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 

Reply via email to