diff options
author | László Németh <nemeth@numbertext.org> | 2020-06-01 19:31:38 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-06-02 18:40:06 +0200 |
commit | da64ec8c8a91db6a6ec9657898f081d5ee67e739 (patch) | |
tree | 2bd7d3ddf24ce6c5adeb3c29dd46ead2e1215c0a | |
parent | 2d6395b87218cbf3512aa9b54807a859205006f0 (diff) |
tdf#133589 AutoCorrect: transliterate to Old Hungarian
In right-to-left paragraph mode, transliterate
Hungarian text word by word during typing, also
add the associated checkbox to Localized Options
page of AutoCorrect dialog window.
Old Hungarian (ISO 15924: Hung) is a historical
and renewed script which is still in use to
transliterate Hungarian writing.
As a localized AutoCorrect feature, the patch supports
the followings:
– word-by-word transliteration of Hungarian texts only
in right-to-left paragraph mode.
– consonant disambiguation of digraphs and trigraphs
based on hyphenation (now pattern-based Huhyphn
dictionary of libhyphen, planned dictionary based
Hunspell later)
– transliteration by extended hu-Hung module of
Numbertext library.
Note: transliteration of the selected text using
AutoCorrect Apply function has't been implemented, yet.
Change-Id: Iee0f18e2485c974c35acf0a3abc3a49c2cf80196
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95303
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
24 files changed, 260 insertions, 17 deletions
diff --git a/compilerplugins/clang/unusedenumconstants.writeonly.results b/compilerplugins/clang/unusedenumconstants.writeonly.results index 313ef966c1a7..700ea09eae0f 100644 --- a/compilerplugins/clang/unusedenumconstants.writeonly.results +++ b/compilerplugins/clang/unusedenumconstants.writeonly.results @@ -1080,6 +1080,8 @@ cui/source/tabpages/autocdlg.cxx:1521 enum OfaQuoteOptions ADD_NONBRK_SPACE cui/source/tabpages/autocdlg.cxx:1522 enum OfaQuoteOptions REPLACE_1ST +cui/source/tabpages/autocdlg.cxx:1529 + enum OfaQuoteOptions TRANSLITERATE_RTL dbaccess/source/core/dataaccess/databasedocument.hxx:163 enum dbaccess::ODatabaseDocument::InitState NotInitialized dbaccess/source/core/dataaccess/databasedocument.hxx:641 diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc index 32e13138bf10..0039d4d02fdc 100644 --- a/cui/inc/strings.hrc +++ b/cui/inc/strings.hrc @@ -331,6 +331,7 @@ #define RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK NC_("RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK", "Correct accidental use of cAPS LOCK key") #define RID_SVXSTR_NON_BREAK_SPACE NC_("RID_SVXSTR_NON_BREAK_SPACE", "Add non-breaking space before specific punctuation marks in French text") #define RID_SVXSTR_ORDINAL NC_("RID_SVXSTR_ORDINAL", "Format ordinal numbers suffixes (1st -> 1^st)") +#define RID_SVXSTR_OLD_HUNGARIAN NC_("RID_SVXSTR_OLD_HUNGARIAN", "Transliterate to Old Hungarian if the text direction is from right to left") #define RID_SVXSTR_DEL_EMPTY_PARA NC_("RID_SVXSTR_DEL_EMPTY_PARA", "Remove blank paragraphs") #define RID_SVXSTR_USER_STYLE NC_("RID_SVXSTR_USER_STYLE", "Replace Custom Styles") #define RID_SVXSTR_BULLET NC_("RID_SVXSTR_BULLET", "Replace bullets with: %1") diff --git a/cui/source/inc/autocdlg.hxx b/cui/source/inc/autocdlg.hxx index 896a481b711c..b94fd3d80fef 100644 --- a/cui/source/inc/autocdlg.hxx +++ b/cui/source/inc/autocdlg.hxx @@ -268,6 +268,7 @@ class OfaQuoteTabPage : public SfxTabPage private: OUString sNonBrkSpace; OUString sOrdinal; + OUString sTransliterateRTL; sal_UCS4 cSglStartQuote; sal_UCS4 cSglEndQuote; diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx index 5b623de576ef..74e1ef127659 100644 --- a/cui/source/tabpages/autocdlg.cxx +++ b/cui/source/tabpages/autocdlg.cxx @@ -1525,7 +1525,8 @@ namespace { enum OfaQuoteOptions { ADD_NONBRK_SPACE, - REPLACE_1ST + REPLACE_1ST, + TRANSLITERATE_RTL }; } @@ -1545,6 +1546,7 @@ OfaQuoteTabPage::OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* : SfxTabPage(pPage, pController, "cui/ui/applylocalizedpage.ui", "ApplyLocalizedPage", &rSet) , sNonBrkSpace(CuiResId(RID_SVXSTR_NON_BREAK_SPACE)) , sOrdinal(CuiResId(RID_SVXSTR_ORDINAL)) + , sTransliterateRTL(CuiResId(RID_SVXSTR_OLD_HUNGARIAN)) , cSglStartQuote(0) , cSglEndQuote(0) , cStartQuote(0) @@ -1619,6 +1621,7 @@ bool OfaQuoteTabPage::FillItemSet( SfxItemSet* ) int nPos = 0; pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE); pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE); + pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE); } bool bModified = false; @@ -1637,6 +1640,12 @@ bool OfaQuoteTabPage::FillItemSet( SfxItemSet* ) pOpt->bChgOrdinalNumber = bCheck; pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE); + + bCheck = m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_FIRST) == TRISTATE_TRUE; + bModified |= pOpt->bTransliterateRTL != bCheck; + pOpt->bTransliterateRTL = bCheck; + pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, + m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_SECOND) == TRISTATE_TRUE); } pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active()); @@ -1696,11 +1705,14 @@ void OfaQuoteTabPage::Reset( const SfxItemSet* ) CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2); CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2); + CreateEntry(*m_xSwCheckLB, sTransliterateRTL, CBCOL_BOTH, 2); m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); + m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, pOpt->bTransliterateRTL ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); + m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND); m_xSwCheckLB->thaw(); } @@ -1713,10 +1725,12 @@ void OfaQuoteTabPage::Reset( const SfxItemSet* ) CreateEntry(*m_xCheckLB, sNonBrkSpace, CBCOL_FIRST, 1); CreateEntry(*m_xCheckLB, sOrdinal, CBCOL_FIRST, 1); + CreateEntry(*m_xCheckLB, sTransliterateRTL, CBCOL_FIRST, 1); int nPos = 0; m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); + m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST); m_xCheckLB->thaw(); } diff --git a/editeng/inc/edtspell.hxx b/editeng/inc/edtspell.hxx index 43edeadd9213..efd9272f4859 100644 --- a/editeng/inc/edtspell.hxx +++ b/editeng/inc/edtspell.hxx @@ -132,6 +132,8 @@ public: virtual bool ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, SvxAutoCorrect& rACorrect, OUString* pPara ) override; + virtual bool TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos ) override; + virtual LanguageType GetLanguage( sal_Int32 nPos ) const override; diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index a91565bce2a9..b98edae2b967 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -428,6 +428,10 @@ private: return false; } + virtual bool TransliterateRTLWord( sal_Int32& /*rSttPos*/, sal_Int32 /*nEndPos*/ ) override + { + return false; + } }; //https://bugs.libreoffice.org/show_bug.cgi?id=55693 diff --git a/editeng/source/editeng/edtspell.cxx b/editeng/source/editeng/edtspell.cxx index db4fa899f34d..04658edad326 100644 --- a/editeng/source/editeng/edtspell.cxx +++ b/editeng/source/editeng/edtspell.cxx @@ -680,6 +680,17 @@ bool EdtAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, return bRet; } +bool EdtAutoCorrDoc::TransliterateRTLWord( sal_Int32& /*rSttPos*/, + sal_Int32 /*nEndPos*/ ) +{ + // Paragraph-start or a blank found, search for the word + // shortcut in Auto + bool bRet = false; + + return bRet; +} + + LanguageType EdtAutoCorrDoc::GetLanguage( sal_Int32 nPos ) const { return mpEditEngine->GetLanguage( EditPaM( pCurNode, nPos+1 ) ); diff --git a/editeng/source/misc/acorrcfg.cxx b/editeng/source/misc/acorrcfg.cxx index 20648438d16a..d3e9f75b8413 100644 --- a/editeng/source/misc/acorrcfg.cxx +++ b/editeng/source/misc/acorrcfg.cxx @@ -109,9 +109,10 @@ Sequence<OUString> SvxBaseAutoCorrCfg::GetPropertyNames() "ReplaceDoubleQuote", // 14 "DoubleQuoteAtStart", // 15 "DoubleQuoteAtEnd", // 16 - "CorrectAccidentalCapsLock" // 17 + "CorrectAccidentalCapsLock", // 17 + "TransliterateRTL" // 18 }; - const int nCount = 18; + const int nCount = 19; Sequence<OUString> aNames(nCount); OUString* pNames = aNames.getArray(); for(int i = 0; i < nCount; i++) @@ -214,12 +215,16 @@ void SvxBaseAutoCorrCfg::Load(bool bInit) if(*o3tl::doAccess<bool>(pValues[nProp])) nFlags |= ACFlags::CorrectCapsLock; break;//"CorrectAccidentalCapsLock" + case 18: + if(*o3tl::doAccess<bool>(pValues[nProp])) + nFlags |= ACFlags::TransliterateRTL; + break;//"TransliterateRTL" } } } if( nFlags != ACFlags::NONE ) rParent.pAutoCorrect->SetAutoCorrFlag( nFlags ); - rParent.pAutoCorrect->SetAutoCorrFlag( ( static_cast<ACFlags>(0x3fff) & ~nFlags ), false ); + rParent.pAutoCorrect->SetAutoCorrFlag( ( static_cast<ACFlags>(0x7fff) & ~nFlags ), false ); } SvxBaseAutoCorrCfg::SvxBaseAutoCorrCfg(SvxAutoCorrCfg& rPar) : @@ -265,8 +270,10 @@ void SvxBaseAutoCorrCfg::ImplCommit() // "DoubleQuoteAtStart" css::uno::Any(sal_Int32(rParent.pAutoCorrect->GetEndDoubleQuote())), // "DoubleQuoteAtEnd" - css::uno::Any(bool(nFlags & ACFlags::CorrectCapsLock))}); + css::uno::Any(bool(nFlags & ACFlags::CorrectCapsLock)), // "CorrectAccidentalCapsLock" + css::uno::Any(bool(nFlags & ACFlags::TransliterateRTL))}); + // "TransliterateRTL" } void SvxBaseAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */) @@ -324,9 +331,10 @@ Sequence<OUString> SvxSwAutoCorrCfg::GetPropertyNames() "Format/ByInput/ApplyNumbering/SpecialCharacter/Font", //43 "Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily", //44 "Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset", //45 - "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch" //46 + "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch", //46 + "Format/Option/TransliterateRTL" //47 }; - const int nCount = 47; + const int nCount = 48; Sequence<OUString> aNames(nCount); OUString* pNames = aNames.getArray(); for(int i = 0; i < nCount; i++) @@ -476,6 +484,7 @@ void SvxSwAutoCorrCfg::Load(bool bInit) rSwFlags.aByInputBulletFont.SetPitch(FontPitch(nVal)); } break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch", + case 47 : rSwFlags.bTransliterateRTL = *o3tl::doAccess<bool>(pValues[nProp]); break; // "Format/Option/TransliterateRTL", } } } @@ -577,8 +586,11 @@ void SvxSwAutoCorrCfg::ImplCommit() // "Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily" css::uno::Any(sal_Int32(rSwFlags.aByInputBulletFont.GetCharSet())), // "Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset" - css::uno::Any(sal_Int32(rSwFlags.aByInputBulletFont.GetPitch()))}); + css::uno::Any(sal_Int32(rSwFlags.aByInputBulletFont.GetPitch())), // "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch" + css::uno::Any(rSwFlags.bTransliterateRTL)}); + // "Format/Option/TransliterateRTL" + } void SvxSwAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */ ) diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx index b381b1726f45..51fdf5c30746 100644 --- a/editeng/source/misc/svxacorr.cxx +++ b/editeng/source/misc/svxacorr.cxx @@ -285,6 +285,7 @@ ACFlags SvxAutoCorrect::GetDefaultFlags() | ACFlags::ChgOrdinalNumber | ACFlags::ChgToEnEmDash | ACFlags::AddNonBrkSpace + | ACFlags::TransliterateRTL | ACFlags::ChgWeightUnderl | ACFlags::SetINetAttr | ACFlags::ChgQuotes @@ -1525,6 +1526,14 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, } } + if( IsAutoCorrFlag( ACFlags::TransliterateRTL ) && GetDocLanguage( rDoc, nInsPos ) == LANGUAGE_HUNGARIAN ) + { + // WARNING ATTENTION: rTxt is an alias of the text node's OUString + // and becomes INVALID if TransliterateRTLWord returns true! + if ( rDoc.TransliterateRTLWord( nCapLttrPos, nInsPos ) ) + break; + } + if( ( IsAutoCorrFlag( ACFlags::ChgOrdinalNumber ) && (nInsPos >= 2 ) && // fdo#69762 avoid autocorrect for 2e-3 ( '-' != cChar || 'E' != rtl::toAsciiUpperCase(rTxt[nInsPos-1]) || '0' > rTxt[nInsPos-2] || '9' < rTxt[nInsPos-2] ) && diff --git a/editeng/source/misc/swafopt.cxx b/editeng/source/misc/swafopt.cxx index 751b3e575a53..f682c690ae32 100644 --- a/editeng/source/misc/swafopt.cxx +++ b/editeng/source/misc/swafopt.cxx @@ -31,6 +31,7 @@ SvxSwAutoFormatFlags::SvxSwAutoFormatFlags() bChgEnumNum = bAddNonBrkSpace = bChgOrdinalNumber = + bTransliterateRTL = bChgToEnEmDash = bChgWeightUnderl = bSetINetAttr = diff --git a/include/editeng/svxacorr.hxx b/include/editeng/svxacorr.hxx index 697ac614f76d..c9908c633d01 100644 --- a/include/editeng/svxacorr.hxx +++ b/include/editeng/svxacorr.hxx @@ -71,13 +71,14 @@ enum class ACFlags : sal_uInt32 { IgnoreDoubleSpace = 0x00000800, // Ignore 2 Spaces ChgSglQuotes = 0x00001000, // Replace simple quotes CorrectCapsLock = 0x00002000, // Correct accidental use of cAPS LOCK key + TransliterateRTL = 0x00004000, // Transliterate RTL text ChgWordLstLoad = 0x20000000, // Replacement list loaded CplSttLstLoad = 0x40000000, // Exception list for Capital letters Start loaded WrdSttLstLoad = 0x80000000, // Exception list for Word Start loaded }; namespace o3tl { - template<> struct typed_flags<ACFlags> : is_typed_flags<ACFlags, 0xe0003fff> {}; + template<> struct typed_flags<ACFlags> : is_typed_flags<ACFlags, 0xe0007fff> {}; } enum class ACQuotes @@ -119,6 +120,8 @@ public: virtual bool ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, SvxAutoCorrect& rACorrect, OUString* pPara ) = 0; + virtual bool TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos ) = 0; + // Is called after the change of the signs by the functions // - FnCapitalStartWord // - FnCapitalStartSentence diff --git a/include/editeng/swafopt.hxx b/include/editeng/swafopt.hxx index 360954a24ab8..682e85e4d77a 100644 --- a/include/editeng/swafopt.hxx +++ b/include/editeng/swafopt.hxx @@ -103,6 +103,7 @@ struct EDITENG_DLLPUBLIC SvxSwAutoFormatFlags bool bChgOrdinalNumber : 1; bool bChgToEnEmDash : 1; bool bAddNonBrkSpace : 1; + bool bTransliterateRTL : 1; bool bChgWeightUnderl : 1; bool bSetINetAttr : 1; diff --git a/lingucomponent/source/numbertext/numbertext.cxx b/lingucomponent/source/numbertext/numbertext.cxx index 006e99d30aed..bc13530d5250 100644 --- a/lingucomponent/source/numbertext/numbertext.cxx +++ b/lingucomponent/source/numbertext/numbertext.cxx @@ -138,6 +138,9 @@ OUString SAL_CALL NumberText_Impl::getNumberText(const OUString& rText, const Lo LanguageTag aLanguageTag(rLocale); OUString aCode(aLanguageTag.getLanguage()); OUString aCountry(aLanguageTag.getCountry()); + OUString aScript(aLanguageTag.getScript()); + if (!aScript.isEmpty()) + aCode += "-" + aScript; if (!aCountry.isEmpty()) aCode += "-" + aCountry; OString aLangCode(OUStringToOString(aCode, RTL_TEXTENCODING_ASCII_US)); diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 71abd8a438cb..fd466a6899f4 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -1364,6 +1364,14 @@ </info> <value>true</value> </prop> + <prop oor:name="TransliterateRTL" oor:type="xs:boolean" oor:nillable="false"> + <!-- UIHints: Tools AutoCorrect/AutoFormat Options - Transliterate Hungarian to Old Hungarian --> + <info> + <desc>Transliterates RTL Hungarian text to Old Hungarian script.</desc> + <label>Transliterate RTL text to Old Hungarian</label> + </info> + <value>true</value> + </prop> <prop oor:name="RemoveDoubleSpaces" oor:type="xs:boolean" oor:nillable="false"> <!-- OldPath: AutoCorrect/Options/All --> <!-- OldLocation: Soffice.cfg --> diff --git a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs index d049dea5b46e..8b76534d540d 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs @@ -4328,6 +4328,14 @@ </info> <value>true</value> </prop> + <prop oor:name="TransliterateRTL" oor:type="xs:boolean" oor:nillable="false"> + <!-- UIHints: Tools AutoCorrect/AutoFormat Options - Transliterate Hungarian to Old Hungarian --> + <info> + <desc>Transliterates RTL Hungarian text to Old Hungarian script.</desc> + <label>Transliterate RTL text to Old Hungarian</label> + </info> + <value>true</value> + </prop> <prop oor:name="DelEmptyParagraphs" oor:type="xs:boolean" oor:nillable="false"> <!-- OldPath: Writer/AutoFormat/Options --> <!-- OldLocation: Soffice.cfg --> diff --git a/sw/inc/comcore.hxx b/sw/inc/comcore.hxx index 6b6230e87268..2fda83a3cbc4 100644 --- a/sw/inc/comcore.hxx +++ b/sw/inc/comcore.hxx @@ -42,8 +42,9 @@ #define STR_AUTOFMTREDL_SET_NUMBER_BULLET 19 #define STR_AUTOFMTREDL_DEL_MORELINES 20 #define STR_AUTOFMTREDL_NON_BREAK_SPACE 21 +#define STR_AUTOFMTREDL_TRANSLITERATE_RTL 22 // !!!!!!!!!!!!!!!!!!!!!!!!!! always set the correct end !!!!!!!!!!!! -#define STR_AUTOFMTREDL_END 22 +#define STR_AUTOFMTREDL_END 23 #endif diff --git a/sw/qa/extras/uiwriter/data/tdf133589.fodt b/sw/qa/extras/uiwriter/data/tdf133589.fodt new file mode 100644 index 000000000000..68fa94697dc6 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf133589.fodt @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:styles> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:default-style style:family="paragraph"> + <style:text-properties fo:language="hu" fo:country="HU" style:writing-mode="rl-tb"/> + </style:default-style> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:paragraph-properties fo:text-align="end" style:justify-single-word="false" style:writing-mode="rl-tb"/> + </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/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index 1cdc40cc43a6..92c4201bce24 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -46,6 +46,7 @@ #include <AnnotationWin.hxx> #include <com/sun/star/text/XDefaultNumberingProvider.hpp> #include <com/sun/star/awt/FontUnderline.hpp> +#include <config_libnumbertext.h> #include <svx/svdpage.hxx> #include <svx/svdview.hxx> @@ -370,6 +371,9 @@ public: void testTdf59666(); void testTdf133524(); void testTdf128860(); +#if ENABLE_LIBNUMBERTEXT + void testTdf133589(); +#endif void testInconsistentBookmark(); #if HAVE_FEATURE_PDFIUM void testInsertPdf(); @@ -586,6 +590,9 @@ public: CPPUNIT_TEST(testTdf59666); CPPUNIT_TEST(testTdf133524); CPPUNIT_TEST(testTdf128860); +#if ENABLE_LIBNUMBERTEXT + CPPUNIT_TEST(testTdf133589); +#endif #if HAVE_FEATURE_PDFIUM CPPUNIT_TEST(testInsertPdf); #endif @@ -7267,6 +7274,45 @@ void SwUiWriterTest::testTdf128860() CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText()); } +#if ENABLE_LIBNUMBERTEXT +void SwUiWriterTest::testTdf133589() +{ +#if !defined(_WIN32) + // Hungarian test document with right-to-left paragraph setting + SwDoc* pDoc = createDoc("tdf133589.fodt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + // translitere words to Old Hungarian + SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect()); + pWrtShell->Insert(u"székely"); + pWrtShell->AutoCorrect(corr, ' '); + sal_uLong nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + OUString sReplaced(u"𐳥𐳋𐳓𐳉𐳗 "); + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText()); + // disambiguate consonants: asszony -> asz|szony + pWrtShell->Insert(u"asszony"); + pWrtShell->AutoCorrect(corr, ' '); + nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + sReplaced += u"𐳀𐳥𐳥𐳛𐳚 "; + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText()); + // disambiguate consonants: kosszarv -> kos|szarv + // (add explicite ZWSP temporarily for consonant disambiguation, because the requested + // hu_HU hyphenation dictionary isn't installed on all testing platform) + // pWrtShell->Insert(u"kosszarv"); + pWrtShell->Insert(u"kosszarv"); + pWrtShell->AutoCorrect(corr, ' '); + nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + sReplaced += u"𐳓𐳛𐳤𐳥𐳀𐳢𐳮 "; + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText()); + // transliterate numbers to Old Hungarian + pWrtShell->Insert(u"2020"); + pWrtShell->AutoCorrect(corr, ' '); + nIndex = pWrtShell->GetCursor()->GetNode().GetIndex(); + sReplaced += u"𐳺𐳺𐳿𐳼𐳼 "; + CPPUNIT_ASSERT_EQUAL(sReplaced, static_cast<SwTextNode*>(pDoc->GetNodes()[nIndex])->GetText()); +#endif +} +#endif + #if HAVE_FEATURE_PDFIUM void SwUiWriterTest::testInsertPdf() { diff --git a/sw/source/core/edit/acorrect.cxx b/sw/source/core/edit/acorrect.cxx index 6d48f24ae503..f26f23732f40 100644 --- a/sw/source/core/edit/acorrect.cxx +++ b/sw/source/core/edit/acorrect.cxx @@ -31,6 +31,13 @@ #include <shellio.hxx> #include <swundo.hxx> #include <viscrs.hxx> +#include <com/sun/star/i18n/BreakType.hpp> +#include <com/sun/star/i18n/WordType.hpp> +#include <com/sun/star/i18n/XBreakIterator.hpp> +#include <com/sun/star/linguistic2/XHyphenator.hpp> +#include <com/sun/star/linguistic2/XHyphenatedWord.hpp> +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> #include <editeng/acorrcfg.hxx> @@ -490,6 +497,76 @@ bool SwAutoCorrDoc::ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, return bRet; } +bool SwAutoCorrDoc::TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos ) +{ + if( m_bUndoIdInitialized ) + m_bUndoIdInitialized = true; + + SwTextNode* pTextNd = m_rCursor.GetNode().GetTextNode(); + OSL_ENSURE( pTextNd, "where is the TextNode?" ); + + bool bRet = false; + if( nEndPos == rSttPos ) + return bRet; + + LanguageType eLang = GetLanguage(nEndPos); + if(LANGUAGE_SYSTEM == eLang) + eLang = GetAppLanguage(); + LanguageTag aLanguageTag(eLang); + + SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>( + pTextNd->getLayoutFrame(m_rEditSh.GetLayout()))); + assert(pFrame); + + const OUString sFrameText = pFrame->GetText(); + SwDoc* pDoc = m_rEditSh.GetDoc(); + if ( pFrame->IsRightToLeft() ) + { + // transliterate to Old Hungarian using Numbertext via NatNum12 number format modifier + OUString sWord(sFrameText.copy(rSttPos, nEndPos - rSttPos)); + // Consonant disambiguation using hyphenation + uno::Reference< linguistic2::XHyphenator > xHyph; + xHyph = ::GetHyphenator(); + OUStringBuffer sDisambiguatedWord; + + const ::css::uno::Sequence< ::css::beans::PropertyValue > aProperties; + css::uno::Reference< css::linguistic2::XHyphenatedWord > xHyphWord; + for (int i = 0; i+1 < sWord.getLength(); i++ ) + { + xHyphWord = xHyph->hyphenate( sWord, + aLanguageTag.getLocale(), + i, + aProperties ); + // insert ZWSP at a hyphenation point, if it's not an alternative one (i.e. ssz->sz-sz) + if (xHyphWord.is() && xHyphWord->getHyphenationPos()+1 == i && !xHyphWord->isAlternativeSpelling()) + { + sDisambiguatedWord.append(CHAR_ZWSP); + } + sDisambiguatedWord.append(sWord[i]); + } + sDisambiguatedWord.append(sWord[sWord.getLength()-1]); + + SvNumberFormatter* pFormatter = pDoc->GetNumberFormatter(); + OUString sConverted; + if (pFormatter && !sWord.isEmpty()) + { + Color* pColor = nullptr; + Color** ppColor = &pColor; + // Send text as NatNum12 prefix + OUString sPrefix("[NatNum12 " + sDisambiguatedWord.makeStringAndClear() + "]0"); + if (pFormatter->GetPreviewString(sPrefix, 0, sConverted, ppColor, LANGUAGE_USER_HUNGARIAN_ROVAS)) + bRet = true; + } + + SwPaM aPam(pFrame->MapViewToModelPos(TextFrameIndex(rSttPos)), + pFrame->MapViewToModelPos(TextFrameIndex(nEndPos))); + if (bRet && nEndPos <= sFrameText.getLength()) + pDoc->getIDocumentContentOperations().ReplaceRange(aPam, sConverted, false); + } + + return bRet; +} + // Called by the functions: // - FnCapitalStartWord // - FnCapitalStartSentence diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx index 16d817f48df4..ac69ff2aa4f4 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -277,6 +277,7 @@ void SwAutoFormat::SetRedlineText_( sal_uInt16 nActionId ) case STR_AUTOFMTREDL_DASH: case STR_AUTOFMTREDL_ORDINAL: case STR_AUTOFMTREDL_NON_BREAK_SPACE: + case STR_AUTOFMTREDL_TRANSLITERATE_RTL: nSeqNo = ++m_nRedlAutoFormatSeqId; break; } @@ -1912,7 +1913,7 @@ void SwAutoFormat::AutoCorrect(TextFrameIndex nPos) if( m_aFlags.bAFormatByInput || (!m_aFlags.bAutoCorrect && !bReplaceQuote && !bReplaceSglQuote && !m_aFlags.bCapitalStartSentence && !m_aFlags.bCapitalStartWord && - !m_aFlags.bChgOrdinalNumber && + !m_aFlags.bChgOrdinalNumber && !m_aFlags.bTransliterateRTL && !m_aFlags.bChgToEnEmDash && !m_aFlags.bSetINetAttr && !m_aFlags.bChgWeightUnderl && !m_aFlags.bAddNonBrkSpace) ) return; @@ -1921,7 +1922,7 @@ void SwAutoFormat::AutoCorrect(TextFrameIndex nPos) if (TextFrameIndex(pText->getLength()) <= nPos) return; - bool bGetLanguage = m_aFlags.bChgOrdinalNumber || + bool bGetLanguage = m_aFlags.bChgOrdinalNumber || m_aFlags.bTransliterateRTL || m_aFlags.bChgToEnEmDash || m_aFlags.bSetINetAttr || m_aFlags.bCapitalStartWord || m_aFlags.bCapitalStartSentence || m_aFlags.bAddNonBrkSpace; @@ -2153,6 +2154,24 @@ void SwAutoFormat::AutoCorrect(TextFrameIndex nPos) ? m_pCurTextFrame->GetLangOfChar(nSttPos, 0, true) : LANGUAGE_SYSTEM; + if( m_aFlags.bTransliterateRTL && eLang == LANGUAGE_HUNGARIAN && + SetRedlineText( STR_AUTOFMTREDL_TRANSLITERATE_RTL ) && + aACorrDoc.TransliterateRTLWord(reinterpret_cast<sal_Int32&>(nSttPos), sal_Int32(nPos))) + { + nPos = m_pCurTextFrame->MapModelToViewPos(*m_aDelPam.GetPoint()); + if( m_aFlags.bWithRedlining ) + { + m_aNdIdx = m_aDelPam.GetPoint()->nNode; + m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode(); + m_pCurTextFrame = GetFrame( *m_pCurTextNd ); + pText = &m_pCurTextFrame->GetText(); + m_aDelPam.SetMark(); + m_aDelPam.DeleteMark(); + } + + continue; // do not check further + } + if ( m_aFlags.bAddNonBrkSpace ) { SetRedlineText( STR_AUTOFMTREDL_NON_BREAK_SPACE ); @@ -2754,7 +2773,7 @@ void SwEditShell::AutoFormatBySplitNode() &pCursor->GetPoint()->nNode ); SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect(); if( pACorr && !pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | - ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | + ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect )) pACorr = nullptr; diff --git a/sw/source/core/inc/acorrect.hxx b/sw/source/core/inc/acorrect.hxx index 8c4c5a5cb91d..e229ce1f2483 100644 --- a/sw/source/core/inc/acorrect.hxx +++ b/sw/source/core/inc/acorrect.hxx @@ -80,6 +80,7 @@ public: virtual bool ChgAutoCorrWord( sal_Int32& rSttPos, sal_Int32 nEndPos, SvxAutoCorrect& rACorrect, OUString* pPara ) override; + virtual bool TransliterateRTLWord( sal_Int32& rSttPos, sal_Int32 nEndPos ) override; // Will be called after swapping characters by the functions // - FnCapitalStartWord and diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 6345066d36ba..ca797f516b6a 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -2404,7 +2404,7 @@ KEYINPUT_CHECKTABLE_INSDEL: pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | ACFlags::ChgOrdinalNumber | ACFlags::AddNonBrkSpace | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | - ACFlags::Autocorrect ) && + ACFlags::Autocorrect | ACFlags::TransliterateRTL ) && '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh ) { @@ -2436,7 +2436,7 @@ KEYINPUT_CHECKTABLE_INSDEL: { if( pACorr && pACfg->IsAutoFormatByInput() && pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | - ACFlags::ChgOrdinalNumber | + ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect ) && !rSh.HasReadonlySel() ) diff --git a/sw/source/uibase/shells/textsh.cxx b/sw/source/uibase/shells/textsh.cxx index a7cb1c2058a8..f2e3fd0b6cc3 100644 --- a/sw/source/uibase/shells/textsh.cxx +++ b/sw/source/uibase/shells/textsh.cxx @@ -162,7 +162,7 @@ void SwTextShell::ExecInsert(SfxRequest &rReq) if( pACorr && rACfg.IsAutoFormatByInput() && pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | - ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | + ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect ) ) { rSh.AutoCorrect( *pACorr, cIns ); diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx index 89211d49f581..7eb8e17f95bb 100644 --- a/sw/source/uibase/wrtsh/wrtsh1.cxx +++ b/sw/source/uibase/wrtsh/wrtsh1.cxx @@ -134,7 +134,7 @@ static SvxAutoCorrect* lcl_IsAutoCorr() { SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect(); if( pACorr && !pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | - ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | + ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect )) pACorr = nullptr; return pACorr; |