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();