diff options
Diffstat (limited to 'editeng/source/misc')
-rw-r--r-- | editeng/source/misc/SvXMLAutoCorrectExport.cxx | 4 | ||||
-rw-r--r-- | editeng/source/misc/SvXMLAutoCorrectImport.cxx | 10 | ||||
-rw-r--r-- | editeng/source/misc/SvXMLAutoCorrectImport.hxx | 2 | ||||
-rw-r--r-- | editeng/source/misc/SvXMLAutoCorrectTokenHandler.hxx | 6 | ||||
-rw-r--r-- | editeng/source/misc/acorrcfg.cxx | 247 | ||||
-rw-r--r-- | editeng/source/misc/forbiddencharacterstable.cxx | 5 | ||||
-rw-r--r-- | editeng/source/misc/hangulhanja.cxx | 2 | ||||
-rw-r--r-- | editeng/source/misc/splwrap.cxx | 15 | ||||
-rw-r--r-- | editeng/source/misc/svxacorr.cxx | 666 | ||||
-rw-r--r-- | editeng/source/misc/swafopt.cxx | 6 | ||||
-rw-r--r-- | editeng/source/misc/txtrange.cxx | 7 | ||||
-rw-r--r-- | editeng/source/misc/unolingu.cxx | 18 | ||||
-rw-r--r-- | editeng/source/misc/urlfieldhelper.cxx | 10 |
13 files changed, 615 insertions, 383 deletions
diff --git a/editeng/source/misc/SvXMLAutoCorrectExport.cxx b/editeng/source/misc/SvXMLAutoCorrectExport.cxx index 8faf4341163a..f3da7e11c215 100644 --- a/editeng/source/misc/SvXMLAutoCorrectExport.cxx +++ b/editeng/source/misc/SvXMLAutoCorrectExport.cxx @@ -34,7 +34,7 @@ SvXMLAutoCorrectExport::SvXMLAutoCorrectExport( const SvxAutocorrWordList * pNewAutocorr_List, const OUString &rFileName, css::uno::Reference< css::xml::sax::XDocumentHandler> const &rHandler) -: SvXMLExport( xContext, "", rFileName, util::MeasureUnit::CM, rHandler ), +: SvXMLExport( xContext, u""_ustr, rFileName, util::MeasureUnit::CM, rHandler ), pAutocorr_List( pNewAutocorr_List ) { GetNamespaceMap_().Add( GetXMLToken ( XML_NP_BLOCK_LIST), @@ -75,7 +75,7 @@ SvXMLExceptionListExport::SvXMLExceptionListExport( const SvStringsISortDtor &rNewList, const OUString &rFileName, css::uno::Reference< css::xml::sax::XDocumentHandler> const &rHandler) -: SvXMLExport( xContext, "", rFileName, util::MeasureUnit::CM, rHandler ), +: SvXMLExport( xContext, u""_ustr, rFileName, util::MeasureUnit::CM, rHandler ), rList( rNewList ) { GetNamespaceMap_().Add( GetXMLToken ( XML_NP_BLOCK_LIST ), diff --git a/editeng/source/misc/SvXMLAutoCorrectImport.cxx b/editeng/source/misc/SvXMLAutoCorrectImport.cxx index 957cb708562c..1822f002967d 100644 --- a/editeng/source/misc/SvXMLAutoCorrectImport.cxx +++ b/editeng/source/misc/SvXMLAutoCorrectImport.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <utility> + #include "SvXMLAutoCorrectImport.hxx" #include "SvXMLAutoCorrectTokenHandler.hxx" @@ -27,11 +29,11 @@ SvXMLAutoCorrectImport::SvXMLAutoCorrectImport( const uno::Reference< uno::XComponentContext > & xContext, SvxAutocorrWordList *pNewAutocorr_List, SvxAutoCorrect &rNewAutoCorrect, - const css::uno::Reference < css::embed::XStorage >& rNewStorage) -: SvXMLImport( xContext, "" ), + css::uno::Reference < css::embed::XStorage > xNewStorage) +: SvXMLImport( xContext, u""_ustr ), pAutocorr_List (pNewAutocorr_List), rAutoCorrect ( rNewAutoCorrect ), - xStorage ( rNewStorage ) + xStorage (std::move( xNewStorage )) { } @@ -103,7 +105,7 @@ SvXMLWordContext::~SvXMLWordContext() SvXMLExceptionListImport::SvXMLExceptionListImport( const uno::Reference< uno::XComponentContext > & xContext, SvStringsISortDtor & rNewList ) -: SvXMLImport( xContext, "" ), +: SvXMLImport( xContext, u""_ustr ), rList (rNewList) { } diff --git a/editeng/source/misc/SvXMLAutoCorrectImport.hxx b/editeng/source/misc/SvXMLAutoCorrectImport.hxx index 4b4b819c0711..961e6963d7df 100644 --- a/editeng/source/misc/SvXMLAutoCorrectImport.hxx +++ b/editeng/source/misc/SvXMLAutoCorrectImport.hxx @@ -41,7 +41,7 @@ public: const css::uno::Reference< css::uno::XComponentContext > & xContext, SvxAutocorrWordList *pNewAutocorr_List, SvxAutoCorrect &rNewAutoCorrect, - const css::uno::Reference < css::embed::XStorage >& rNewStorage); + css::uno::Reference < css::embed::XStorage > xNewStorage); virtual ~SvXMLAutoCorrectImport() noexcept override; }; diff --git a/editeng/source/misc/SvXMLAutoCorrectTokenHandler.hxx b/editeng/source/misc/SvXMLAutoCorrectTokenHandler.hxx index 352f77385a67..df913dbe6b01 100644 --- a/editeng/source/misc/SvXMLAutoCorrectTokenHandler.hxx +++ b/editeng/source/misc/SvXMLAutoCorrectTokenHandler.hxx @@ -7,8 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef EDITENG_SOURCE_MISC_SVXMLAUTOCORRECTTOKENHANDLER_HXX -#define EDITENG_SOURCE_MISC_SVXMLAUTOCORRECTTOKENHANDLER_HXX +#pragma once #include <sal/types.h> #include <xmloff/xmltoken.hxx> @@ -43,7 +42,4 @@ public: virtual sal_Int32 getTokenDirect( const char *pToken, sal_Int32 nLength ) const override; }; -#endif // EDITENG_SOURCE_MISC_SVXMLAUTOCORRECTTOKENHANDLER_HXX - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ - diff --git a/editeng/source/misc/acorrcfg.cxx b/editeng/source/misc/acorrcfg.cxx index 4508a1f6e7a9..f1f1825c523a 100644 --- a/editeng/source/misc/acorrcfg.cxx +++ b/editeng/source/misc/acorrcfg.cxx @@ -22,9 +22,13 @@ #include <o3tl/any.hxx> #include <tools/debug.hxx> #include <tools/urlobj.hxx> +#include <comphelper/diagnose_ex.hxx> #include <ucbhelper/content.hxx> #include <unotools/pathoptions.hxx> #include <unotools/ucbhelper.hxx> +#include <svtools/langtab.hxx> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> #include <editeng/svxacorr.hxx> #include <com/sun/star/uno/Sequence.hxx> @@ -34,6 +38,76 @@ using namespace com::sun::star; using namespace com::sun::star::uno; +/** An autocorrection file dropped into such directory may create a language + list entry if one didn't exist already. + */ +static void scanAutoCorrectDirForLanguageTags( const OUString& rURL ) +{ + // Silently ignore all errors. + try + { + ::ucbhelper::Content aContent( rURL, + uno::Reference<ucb::XCommandEnvironment>(), comphelper::getProcessComponentContext()); + if (aContent.isFolder()) + { + // Title is file name here. + uno::Reference<sdbc::XResultSet> xResultSet = aContent.createCursor( + {u"Title"_ustr}, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY); + uno::Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY); + if (xResultSet.is() && xRow.is()) + { + while (xResultSet->next()) + { + try + { + const OUString aTitle( xRow->getString(1)); + if (aTitle.getLength() <= 9 || !(aTitle.startsWith("acor_") && aTitle.endsWith(".dat"))) + continue; + + const OUString aBcp47( aTitle.copy( 5, aTitle.getLength() - 9)); + // Ignore invalid langtags and canonicalize for good, + // allow private-use tags. + const LanguageTag aLanguageTag (aBcp47, true); + if (!aLanguageTag.isValidBcp47()) + continue; + + if (SvtLanguageTable::HasLanguageType( aLanguageTag.getLanguageType())) + continue; + + // Insert language(-script)-only tags only if there is + // no known matching fallback locale, otherwise we'd + // end up with unwanted entries where a language + // autocorrection file covers several locales. We do + // know a few art-x-... though so exclude those and any + // other private-use tag (which should not fallback, + // but avoid). + if (aLanguageTag.getCountry().isEmpty() + && LanguageTag::isValidBcp47( aLanguageTag.getBcp47(), nullptr, + LanguageTag::PrivateUse::DISALLOW)) + { + LanguageTag aFallback( aLanguageTag); + aFallback.makeFallback(); + if (aFallback.getLanguageAndScript() == aLanguageTag.getLanguageAndScript()) + continue; + } + + // Finally add this one. + SvtLanguageTable::AddLanguageTag( aLanguageTag); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("editeng", "Unable to get a directory entry from '" << rURL << "'"); + } + } + } + } + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("editeng", "Unable to iterate directory '" << rURL << "'"); + } +} + SvxAutoCorrCfg::SvxAutoCorrCfg() : aBaseConfig(*this), aSwConfig(*this), @@ -60,6 +134,7 @@ SvxAutoCorrCfg::SvxAutoCorrCfg() : for( OUString* pS : { &sSharePath, &sUserPath } ) { INetURLObject aPath( *pS ); + scanAutoCorrectDirForLanguageTags( aPath.GetMainURL(INetURLObject::DecodeMechanism::ToIUri)); aPath.insertName(u"acor"); *pS = aPath.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); } @@ -88,34 +163,35 @@ void SvxAutoCorrCfg::SetAutoCorrect(SvxAutoCorrect *const pNew) Sequence<OUString> SvxBaseAutoCorrCfg::GetPropertyNames() { - static const char* aPropNames[] = + static constexpr OUString aPropNames[] { - "Exceptions/TwoCapitalsAtStart", // 0 - "Exceptions/CapitalAtStartSentence", // 1 - "UseReplacementTable", // 2 - "TwoCapitalsAtStart", // 3 - "CapitalAtStartSentence", // 4 - "ChangeUnderlineWeight", // 5 - "SetInetAttribute", // 6 - "ChangeOrdinalNumber", // 7 - "AddNonBreakingSpace", // 8 - "ChangeDash", // 9 - "RemoveDoubleSpaces", // 10 - "ReplaceSingleQuote", // 11 - "SingleQuoteAtStart", // 12 - "SingleQuoteAtEnd", // 13 - "ReplaceDoubleQuote", // 14 - "DoubleQuoteAtStart", // 15 - "DoubleQuoteAtEnd", // 16 - "CorrectAccidentalCapsLock", // 17 - "TransliterateRTL", // 18 - "ChangeAngleQuotes" // 19 + u"Exceptions/TwoCapitalsAtStart"_ustr, // 0 + u"Exceptions/CapitalAtStartSentence"_ustr, // 1 + u"UseReplacementTable"_ustr, // 2 + u"TwoCapitalsAtStart"_ustr, // 3 + u"CapitalAtStartSentence"_ustr, // 4 + u"ChangeUnderlineWeight"_ustr, // 5 + u"SetInetAttribute"_ustr, // 6 + u"ChangeOrdinalNumber"_ustr, // 7 + u"AddNonBreakingSpace"_ustr, // 8 + u"ChangeDash"_ustr, // 9 + u"RemoveDoubleSpaces"_ustr, // 10 + u"ReplaceSingleQuote"_ustr, // 11 + u"SingleQuoteAtStart"_ustr, // 12 + u"SingleQuoteAtEnd"_ustr, // 13 + u"ReplaceDoubleQuote"_ustr, // 14 + u"DoubleQuoteAtStart"_ustr, // 15 + u"DoubleQuoteAtEnd"_ustr, // 16 + u"CorrectAccidentalCapsLock"_ustr, // 17 + u"TransliterateRTL"_ustr, // 18 + u"ChangeAngleQuotes"_ustr, // 19 + u"SetDOIAttribute"_ustr, // 20 }; - const int nCount = 20; + const int nCount = 21; Sequence<OUString> aNames(nCount); OUString* pNames = aNames.getArray(); for(int i = 0; i < nCount; i++) - pNames[i] = OUString::createFromAscii(aPropNames[i]); + pNames[i] = aPropNames[i]; return aNames; } @@ -222,6 +298,10 @@ void SvxBaseAutoCorrCfg::Load(bool bInit) if(*o3tl::doAccess<bool>(pValues[nProp])) nFlags |= ACFlags::ChgAngleQuotes; break;//"ChangeAngleQuotes" + case 20: + if(*o3tl::doAccess<bool>(pValues[nProp])) + nFlags |= ACFlags::SetDOIAttr; + break;//"SetDOIAttr", } } } @@ -231,7 +311,7 @@ void SvxBaseAutoCorrCfg::Load(bool bInit) } SvxBaseAutoCorrCfg::SvxBaseAutoCorrCfg(SvxAutoCorrCfg& rPar) : - utl::ConfigItem("Office.Common/AutoCorrect"), + utl::ConfigItem(u"Office.Common/AutoCorrect"_ustr), rParent(rPar) { } @@ -277,9 +357,10 @@ void SvxBaseAutoCorrCfg::ImplCommit() // "CorrectAccidentalCapsLock" css::uno::Any(bool(nFlags & ACFlags::TransliterateRTL)), // "TransliterateRTL" - css::uno::Any(bool(nFlags & ACFlags::ChgAngleQuotes))}); + css::uno::Any(bool(nFlags & ACFlags::ChgAngleQuotes)), // "ChangeAngleQuotes" - + css::uno::Any(bool(nFlags & ACFlags::SetDOIAttr)), // "SetDOIAttribute" + }); } void SvxBaseAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */) @@ -289,61 +370,63 @@ void SvxBaseAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */) Sequence<OUString> SvxSwAutoCorrCfg::GetPropertyNames() { - static const char* aPropNames[] = + static constexpr OUString aPropNames[] { - "Text/FileLinks", // 0 - "Text/InternetLinks", // 1 - "Text/ShowPreview", // 2 - "Text/ShowToolTip", // 3 - "Text/SearchInAllCategories", // 4 - "Format/Option/UseReplacementTable", // 5 - "Format/Option/TwoCapitalsAtStart", // 6 - "Format/Option/CapitalAtStartSentence", // 7 - "Format/Option/ChangeUnderlineWeight", // 8 - "Format/Option/SetInetAttribute", // 9 - "Format/Option/ChangeOrdinalNumber", //10 - "Format/Option/AddNonBreakingSpace", //11 - "Format/Option/ChangeDash", //12 - "Format/Option/DelEmptyParagraphs", //13 - "Format/Option/ReplaceUserStyle", //14 - "Format/Option/ChangeToBullets/Enable", //15 - "Format/Option/ChangeToBullets/SpecialCharacter/Char", //16 - "Format/Option/ChangeToBullets/SpecialCharacter/Font", //17 - "Format/Option/ChangeToBullets/SpecialCharacter/FontFamily", //18 - "Format/Option/ChangeToBullets/SpecialCharacter/FontCharset", //19 - "Format/Option/ChangeToBullets/SpecialCharacter/FontPitch", //20 - "Format/Option/CombineParagraphs", //21 - "Format/Option/CombineValue", //22 - "Format/Option/DelSpacesAtStartEnd", //23 - "Format/Option/DelSpacesBetween", //24 - "Format/ByInput/Enable", //25 - "Format/ByInput/ChangeDash", //26 - "Format/ByInput/ApplyNumbering/Enable", //27 - "Format/ByInput/ChangeToBorders", //28 - "Format/ByInput/ChangeToTable", //29 - "Format/ByInput/ReplaceStyle", //30 - "Format/ByInput/DelSpacesAtStartEnd", //31 - "Format/ByInput/DelSpacesBetween", //32 - "Completion/Enable", //33 - "Completion/MinWordLen", //34 - "Completion/MaxListLen", //35 - "Completion/CollectWords", //36 - "Completion/EndlessList", //37 - "Completion/AppendBlank", //38 - "Completion/ShowAsTip", //39 - "Completion/AcceptKey", //40 - "Completion/KeepList", //41 - "Format/ByInput/ApplyNumbering/SpecialCharacter/Char", //42 - "Format/ByInput/ApplyNumbering/SpecialCharacter/Font", //43 - "Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily", //44 - "Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset", //45 - "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch", //46 + u"Text/FileLinks"_ustr, // 0 + u"Text/InternetLinks"_ustr, // 1 + u"Text/ShowPreview"_ustr, // 2 + u"Text/ShowToolTip"_ustr, // 3 + u"Text/SearchInAllCategories"_ustr, // 4 + u"Format/Option/UseReplacementTable"_ustr, // 5 + u"Format/Option/TwoCapitalsAtStart"_ustr, // 6 + u"Format/Option/CapitalAtStartSentence"_ustr, // 7 + u"Format/Option/ChangeUnderlineWeight"_ustr, // 8 + u"Format/Option/SetInetAttribute"_ustr, // 9 + u"Format/Option/ChangeOrdinalNumber"_ustr, //10 + u"Format/Option/AddNonBreakingSpace"_ustr, //11 + u"Format/Option/ChangeDash"_ustr, //12 + u"Format/Option/DelEmptyParagraphs"_ustr, //13 + u"Format/Option/ReplaceUserStyle"_ustr, //14 + u"Format/Option/ChangeToBullets/Enable"_ustr, //15 + u"Format/Option/ChangeToBullets/SpecialCharacter/Char"_ustr, //16 + u"Format/Option/ChangeToBullets/SpecialCharacter/Font"_ustr, //17 + u"Format/Option/ChangeToBullets/SpecialCharacter/FontFamily"_ustr, //18 + u"Format/Option/ChangeToBullets/SpecialCharacter/FontCharset"_ustr, //19 + u"Format/Option/ChangeToBullets/SpecialCharacter/FontPitch"_ustr, //20 + u"Format/Option/CombineParagraphs"_ustr, //21 + u"Format/Option/CombineValue"_ustr, //22 + u"Format/Option/DelSpacesAtStartEnd"_ustr, //23 + u"Format/Option/DelSpacesBetween"_ustr, //24 + u"Format/ByInput/Enable"_ustr, //25 + u"Format/ByInput/ChangeDash"_ustr, //26 + u"Format/ByInput/ApplyNumbering/Enable"_ustr, //27 + u"Format/ByInput/ChangeToBorders"_ustr, //28 + u"Format/ByInput/ChangeToTable"_ustr, //29 + u"Format/ByInput/ReplaceStyle"_ustr, //30 + u"Format/ByInput/DelSpacesAtStartEnd"_ustr, //31 + u"Format/ByInput/DelSpacesBetween"_ustr, //32 + u"Completion/Enable"_ustr, //33 + u"Completion/MinWordLen"_ustr, //34 + u"Completion/MaxListLen"_ustr, //35 + u"Completion/CollectWords"_ustr, //36 + u"Completion/EndlessList"_ustr, //37 + u"Completion/AppendBlank"_ustr, //38 + u"Completion/ShowAsTip"_ustr, //39 + u"Completion/AcceptKey"_ustr, //40 + u"Completion/KeepList"_ustr, //41 + u"Format/ByInput/ApplyNumbering/SpecialCharacter/Char"_ustr, //42 + u"Format/ByInput/ApplyNumbering/SpecialCharacter/Font"_ustr, //43 + u"Format/ByInput/ApplyNumbering/SpecialCharacter/FontFamily"_ustr, //44 + u"Format/ByInput/ApplyNumbering/SpecialCharacter/FontCharset"_ustr, //45 + u"Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch"_ustr, //46 + u"Format/Option/SetDOIAttribute"_ustr, //47 + u"Format/ByInput/ApplyBulletsAfterSpace"_ustr, //48 }; - const int nCount = 47; + const int nCount = 49; Sequence<OUString> aNames(nCount); OUString* pNames = aNames.getArray(); for(int i = 0; i < nCount; i++) - pNames[i] = OUString::createFromAscii(aPropNames[i]); + pNames[i] = aPropNames[i]; return aNames; } @@ -443,7 +526,7 @@ void SvxSwAutoCorrCfg::Load(bool bInit) { sal_Int32 nVal = 0; pValues[nProp] >>= nVal; rSwFlags.nAutoCmpltListLen = - sal::static_int_cast< sal_uInt16 >(nVal); + sal::static_int_cast< sal_uInt32 >(nVal); } break; // "Completion/MaxListLen", case 36: rSwFlags.bAutoCmpltCollectWords = *o3tl::doAccess<bool>(pValues[nProp]); break; // "Completion/CollectWords", @@ -489,13 +572,15 @@ void SvxSwAutoCorrCfg::Load(bool bInit) rSwFlags.aByInputBulletFont.SetPitch(FontPitch(nVal)); } break;// "Format/ByInput/ApplyNumbering/SpecialCharacter/FontPitch", + case 47: rSwFlags.bSetDOIAttr = *o3tl::doAccess<bool>(pValues[nProp]); break; // "Format/Option/SetDOIAttribute", + case 48 : rSwFlags.bSetNumRuleAfterSpace = *o3tl::doAccess<bool>(pValues[nProp]); break; // "Format/ByInput/ApplyNumberingAfterSpace", } } } } SvxSwAutoCorrCfg::SvxSwAutoCorrCfg(SvxAutoCorrCfg& rPar) : - utl::ConfigItem("Office.Writer/AutoFunction"), + utl::ConfigItem(u"Office.Writer/AutoFunction"_ustr), rParent(rPar) { } @@ -590,8 +675,12 @@ 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.bSetDOIAttr), + css::uno::Any(rSwFlags.bSetNumRuleAfterSpace), // "Format/ByInput/ApplyNumberingAfterSpace" + }); + // "Format/Option/SetDOIAttribute" } void SvxSwAutoCorrCfg::Notify( const Sequence<OUString>& /* aPropertyNames */ ) diff --git a/editeng/source/misc/forbiddencharacterstable.cxx b/editeng/source/misc/forbiddencharacterstable.cxx index 942af2f04527..7276da584bd9 100644 --- a/editeng/source/misc/forbiddencharacterstable.cxx +++ b/editeng/source/misc/forbiddencharacterstable.cxx @@ -20,10 +20,11 @@ #include <editeng/forbiddencharacterstable.hxx> #include <unotools/localedatawrapper.hxx> +#include <utility> SvxForbiddenCharactersTable::SvxForbiddenCharactersTable( - const css::uno::Reference<css::uno::XComponentContext>& rxContext) - : m_xContext(rxContext) + css::uno::Reference<css::uno::XComponentContext> xContext) + : m_xContext(std::move(xContext)) { } diff --git a/editeng/source/misc/hangulhanja.cxx b/editeng/source/misc/hangulhanja.cxx index 186a7ccb2298..5a9a8c1034fe 100644 --- a/editeng/source/misc/hangulhanja.cxx +++ b/editeng/source/misc/hangulhanja.cxx @@ -36,7 +36,7 @@ #include <sal/log.hxx> #include <osl/diagnose.h> #include <tools/debug.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <editeng/edtdlg.hxx> diff --git a/editeng/source/misc/splwrap.cxx b/editeng/source/misc/splwrap.cxx index 669546a8e5cb..67c3dc28e64a 100644 --- a/editeng/source/misc/splwrap.cxx +++ b/editeng/source/misc/splwrap.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <config_wasm_strip.h> + #include <rtl/ustring.hxx> #include <i18nlangtag/languagetag.hxx> #include <vcl/svapp.hxx> @@ -44,13 +46,12 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::uno; -using namespace ::com::sun::star::beans; using namespace ::com::sun::star::linguistic2; // misc functions --------------------------------------------- -void SvxPrepareAutoCorrect( OUString &rOldText, const OUString &rNewText ) +void SvxPrepareAutoCorrect( OUString &rOldText, std::u16string_view rNewText ) { // This function should be used to strip (or add) trailing '.' from // the strings before passing them on to the autocorrect function in @@ -62,7 +63,7 @@ void SvxPrepareAutoCorrect( OUString &rOldText, const OUString &rNewText ) // rNewText: replacement text sal_Int32 nOldLen = rOldText.getLength(); - sal_Int32 nNewLen = rNewText.getLength(); + sal_Int32 nNewLen = rNewText.size(); if (nOldLen && nNewLen) { bool bOldHasDot = '.' == rOldText[ nOldLen - 1 ], @@ -102,14 +103,14 @@ void SvxSpellWrapper::ShowLanguageErrors() { OUString aErr( SvtLanguageTable::GetLanguageString( nLang ) ); ErrorHandler::HandleError( - *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) ); + ErrCodeMsg( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) ); nTmpSpell = SVX_LANG_MISSING; } if (SVX_LANG_MISSING_DO_WARN == nTmpHyph) { OUString aErr( SvtLanguageTable::GetLanguageString( nLang ) ); ErrorHandler::HandleError( - *new StringErrorInfo( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) ); + ErrCodeMsg( ERRCODE_SVX_LINGU_LANGUAGENOTEXISTS, aErr ) ); nTmpHyph = SVX_LANG_MISSING; } @@ -249,6 +250,9 @@ void SvxSpellWrapper::InsertHyphen( const sal_Int32 ) // Testing of the document areas in the order specified by the flags void SvxSpellWrapper::SpellDocument( ) { +#if ENABLE_WASM_STRIP_HUNSPELL + return; +#else if ( bOtherCntnt ) { bReverse = false; @@ -275,6 +279,7 @@ void SvxSpellWrapper::SpellDocument( ) xHyph, this )); pDlg->Execute(); } +#endif } diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx index 32ae3477a9d2..4cc64f90a766 100644 --- a/editeng/source/misc/svxacorr.cxx +++ b/editeng/source/misc/svxacorr.cxx @@ -18,6 +18,8 @@ */ #include <memory> +#include <utility> +#include <algorithm> #include <string_view> #include <sal/config.h> @@ -42,8 +44,9 @@ #include <unotools/localedatawrapper.hxx> #include <unotools/transliterationwrapper.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> #include <comphelper/storagehelper.hxx> -#include <comphelper/string.hxx> +#include <o3tl/string_view.hxx> #include <editeng/editids.hrc> #include <sot/storage.hxx> #include <editeng/udlnitem.hxx> @@ -67,7 +70,7 @@ #include <com/sun/star/ucb/XCommandEnvironment.hpp> #include <com/sun/star/ucb/TransferInfo.hpp> #include <com/sun/star/ucb/NameClash.hpp> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <xmloff/xmltoken.hxx> #include <unordered_map> #include <rtl/character.hxx> @@ -95,17 +98,19 @@ namespace o3tl { } const sal_Unicode cNonBreakingSpace = 0xA0; // UNICODE code for no break space -constexpr OUStringLiteral pXMLImplWordStart_ExcptLstStr = u"WordExceptList.xml"; -constexpr OUStringLiteral pXMLImplCplStt_ExcptLstStr = u"SentenceExceptList.xml"; -constexpr OUStringLiteral pXMLImplAutocorr_ListStr = u"DocumentList.xml"; +constexpr OUString pXMLImplWordStart_ExcptLstStr = u"WordExceptList.xml"_ustr; +constexpr OUString pXMLImplCplStt_ExcptLstStr = u"SentenceExceptList.xml"_ustr; +constexpr OUString pXMLImplAutocorr_ListStr = u"DocumentList.xml"_ustr; -const char +// tdf#54409 check also typographical quotation marks in the case of skipped ASCII quotation marks +// Curious, why these \u0083\u0084\u0089\u0091\u0092\u0093\u0094 are handled as "begin characters"? +constexpr std::u16string_view /* also at these beginnings - Brackets and all kinds of begin characters */ - sImplSttSkipChars[] = "\"\'([{\x83\x84\x89\x91\x92\x93\x94", + sImplSttSkipChars = u"\"'([{\u2018\u2019\u201a\u201b\u201c\u201d\u201e\u201f\u0083\u0084\u0089\u0091\u0092\u0093\u0094", /* also at these ends - Brackets and all kinds of begin characters */ - sImplEndSkipChars[] = "\"\')]}\x83\x84\x89\x91\x92\x93\x94"; + sImplEndSkipChars = u"\"')]}\u2018\u2019\u201a\u201b\u201c\u201d\u201e\u201f\u0083\u0084\u0089\u0091\u0092\u0093\u0094"; -static OUString EncryptBlockName_Imp(const OUString& rName); +static OUString EncryptBlockName_Imp(std::u16string_view rName); static bool NonFieldWordDelim( const sal_Unicode c ) { @@ -170,20 +175,9 @@ static bool lcl_IsSymbolChar( CharClass const & rCC, const OUString& rTxt, return false; } -static bool lcl_IsInAsciiArr( const char* pArr, const sal_Unicode c ) +static bool lcl_IsInArr(std::u16string_view arr, const sal_uInt32 c) { - // tdf#54409 check also typographical quotation marks in the case of skipped ASCII quotation marks - if ( 0x2018 <= c && c <= 0x201F && (pArr == sImplSttSkipChars || pArr == sImplEndSkipChars) ) - return true; - - bool bRet = false; - for( ; *pArr; ++pArr ) - if( *pArr == c ) - { - bRet = true; - break; - } - return bRet; + return std::any_of(arr.begin(), arr.end(), [c](const auto c1) { return c1 == c; }); } SvxAutoCorrDoc::~SvxAutoCorrDoc() @@ -224,7 +218,7 @@ static LocaleDataWrapper& GetLocaleDataWrapper( LanguageType nLang ) static std::unique_ptr<LocaleDataWrapper> xLclDtWrp; LanguageTag aLcl( nLang ); if (!xLclDtWrp || xLclDtWrp->getLoadedLanguageTag() != aLcl) - xLclDtWrp.reset(new LocaleDataWrapper(aLcl)); + xLclDtWrp.reset(new LocaleDataWrapper(std::move(aLcl))); return *xLclDtWrp; } static TransliterationWrapper& GetIgnoreTranslWrapper() @@ -288,6 +282,7 @@ ACFlags SvxAutoCorrect::GetDefaultFlags() | ACFlags::ChgAngleQuotes | ACFlags::ChgWeightUnderl | ACFlags::SetINetAttr + | ACFlags::SetDOIAttr | ACFlags::ChgQuotes | ACFlags::SaveWordCplSttLst | ACFlags::SaveWordWordStartLst @@ -310,6 +305,8 @@ ACFlags SvxAutoCorrect::GetDefaultFlags() constexpr sal_Unicode cEmDash = 0x2014; constexpr sal_Unicode cEnDash = 0x2013; +constexpr OUString sEmDash(u"\u2014"_ustr); +constexpr OUString sEnDash(u"\u2013"_ustr); constexpr sal_Unicode cApostrophe = 0x2019; constexpr sal_Unicode cLeftDoubleAngleQuote = 0xAB; constexpr sal_Unicode cRightDoubleAngleQuote = 0xBB; @@ -324,10 +321,10 @@ const sal_Unicode aStopDoubleAngleQuoteEndRo[] = { cLeftDoubleAngleQuote, cRight const sal_Unicode aStopSingleQuoteEnd[] = { 0x201A, 0x2018, 0x201C, 0x201E, 0 }; const sal_Unicode aStopSingleQuoteEndRuUa[] = { 0x201E, 0x201C, cRightDoubleAngleQuote, cLeftDoubleAngleQuote, 0 }; -SvxAutoCorrect::SvxAutoCorrect( const OUString& rShareAutocorrFile, - const OUString& rUserAutocorrFile ) - : sShareAutoCorrFile( rShareAutocorrFile ) - , sUserAutoCorrFile( rUserAutocorrFile ) +SvxAutoCorrect::SvxAutoCorrect( OUString aShareAutocorrFile, + OUString aUserAutocorrFile ) + : sShareAutoCorrFile(std::move( aShareAutocorrFile )) + , sUserAutoCorrFile(std::move( aUserAutocorrFile )) , eCharClassLang( LANGUAGE_DONTKNOW ) , nFlags(SvxAutoCorrect::GetDefaultFlags()) , cStartDQuote( 0 ) @@ -357,7 +354,7 @@ SvxAutoCorrect::~SvxAutoCorrect() void SvxAutoCorrect::GetCharClass_( LanguageType eLang ) { - pCharClass.reset( new CharClass( LanguageTag( eLang)) ); + moCharClass.emplace( LanguageTag( eLang) ); eCharClassLang = eLang; } @@ -477,16 +474,18 @@ bool SvxAutoCorrect::FnChgOrdinalNumber( // In some languages ordinal suffixes should never be // changed to superscript. Let's break for those languages. if (!eLang.anyOf( + LANGUAGE_CATALAN, // tdf#156792 + LANGUAGE_CATALAN_VALENCIAN, LANGUAGE_SWEDISH, LANGUAGE_SWEDISH_FINLAND)) { CharClass& rCC = GetCharClass(eLang); for (; nSttPos < nEndPos; ++nSttPos) - if (!lcl_IsInAsciiArr(sImplSttSkipChars, rTxt[nSttPos])) + if (!lcl_IsInArr(sImplSttSkipChars, rTxt[nSttPos])) break; for (; nSttPos < nEndPos; --nEndPos) - if (!lcl_IsInAsciiArr(sImplEndSkipChars, rTxt[nEndPos - 1])) + if (!lcl_IsInArr(sImplEndSkipChars, rTxt[nEndPos - 1])) break; @@ -510,29 +509,62 @@ bool SvxAutoCorrect::FnChgOrdinalNumber( } if (bFoundEnd && isValidNumber) { - sal_Int32 nNum = rTxt.copy(nSttPos, nNumEnd - nSttPos + 1).toInt32(); + 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' ) ) { - OUString sEnd = rTxt.copy(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; } } } @@ -553,6 +585,11 @@ bool SvxAutoCorrect::FnChgToEnEmDash( eLang = GetAppLang().getLanguageType(); bool bAlwaysUseEmDash = (eLang == LANGUAGE_RUSSIAN || eLang == LANGUAGE_UKRAINIAN); + // rTxt may refer to the frame text that will change in the calls to rDoc.Delete / rDoc.Insert; + // keep a local copy for later use + OUString aOrigTxt = rTxt; + sal_Int32 nFirstReplacementTextLengthChange = 0; + // replace " - " or " --" with "enDash" if( 1 < nSttPos && 1 <= nEndPos - nSttPos ) { @@ -564,7 +601,7 @@ bool SvxAutoCorrect::FnChgToEnEmDash( '-' == rTxt[ nSttPos+1 ]) { sal_Int32 n; - for( n = nSttPos+2; n < nEndPos && lcl_IsInAsciiArr( + for( n = nSttPos+2; n < nEndPos && lcl_IsInArr( sImplSttSkipChars,(cCh = rTxt[ n ])); ++n ) ; @@ -572,7 +609,7 @@ bool SvxAutoCorrect::FnChgToEnEmDash( // found: " --[<AnySttChars>][A-z0-9] if( rCC.isLetterNumeric( OUString(cCh) ) ) { - for( n = nSttPos-1; n && lcl_IsInAsciiArr( + for( n = nSttPos-1; n && lcl_IsInArr( sImplEndSkipChars,(cCh = rTxt[ --n ])); ) ; @@ -580,7 +617,8 @@ bool SvxAutoCorrect::FnChgToEnEmDash( if( rCC.isLetterNumeric( OUString(cCh) )) { rDoc.Delete( nSttPos, nSttPos + 2 ); - rDoc.Insert( nSttPos, bAlwaysUseEmDash ? OUString(cEmDash) : OUString(cEnDash) ); + rDoc.Insert( nSttPos, bAlwaysUseEmDash ? sEmDash : sEnDash ); + nFirstReplacementTextLengthChange = -1; // 2 ch -> 1 ch bRet = true; } } @@ -599,7 +637,7 @@ bool SvxAutoCorrect::FnChgToEnEmDash( } if( ' ' == cCh ) { - for( n = nSttPos; n < nEndPos && lcl_IsInAsciiArr( + for( n = nSttPos; n < nEndPos && lcl_IsInArr( sImplSttSkipChars,(cCh = rTxt[ n ])); ++n ) ; @@ -608,14 +646,15 @@ bool SvxAutoCorrect::FnChgToEnEmDash( if( rCC.isLetterNumeric( OUString(cCh) ) ) { cCh = ' '; - for( n = nTmpPos-1; n && lcl_IsInAsciiArr( + for( n = nTmpPos-1; n && lcl_IsInArr( sImplEndSkipChars,(cCh = rTxt[ --n ])); ) ; // found: "[A-z0-9][<AnyEndChars>] - [<AnySttChars>][A-z0-9] - if( rCC.isLetterNumeric( OUString(cCh) )) + if (rCC.isLetterNumeric(OUString(cCh)) || lcl_IsInArr(u".!?", cCh)) { rDoc.Delete( nTmpPos, nTmpPos + nLen ); - rDoc.Insert( nTmpPos, bAlwaysUseEmDash ? OUString(cEmDash) : OUString(cEnDash) ); + rDoc.Insert( nTmpPos, bAlwaysUseEmDash ? sEmDash : sEnDash ); + nFirstReplacementTextLengthChange = 1 - nLen; // nLen ch -> 1 ch bRet = true; } } @@ -629,39 +668,54 @@ bool SvxAutoCorrect::FnChgToEnEmDash( bool bEnDash = (eLang == LANGUAGE_HUNGARIAN || eLang == LANGUAGE_FINNISH); if( 4 <= nEndPos - nSttPos ) { - OUString sTmp( rTxt.copy( nSttPos, nEndPos - nSttPos ) ); - sal_Int32 nFndPos = sTmp.indexOf("--"); - if( nFndPos != -1 && nFndPos && - nFndPos + 2 < sTmp.getLength() && - ( rCC.isLetterNumeric( sTmp, nFndPos - 1 ) || - lcl_IsInAsciiArr( sImplEndSkipChars, rTxt[ nFndPos - 1 ] )) && - ( rCC.isLetterNumeric( sTmp, nFndPos + 2 ) || - lcl_IsInAsciiArr( sImplSttSkipChars, rTxt[ nFndPos + 2 ] ))) + std::u16string_view sTmpView( aOrigTxt.subView( nSttPos, nEndPos - nSttPos ) ); + size_t nFndPos = sTmpView.find(u"--"); + if (nFndPos > 0 && nFndPos < sTmpView.size() - 2) { - nSttPos = nSttPos + nFndPos; - rDoc.Delete( nSttPos, nSttPos + 2 ); - rDoc.Insert( nSttPos, (bEnDash || (rCC.isDigit( sTmp, nFndPos - 1 ) && - rCC.isDigit( sTmp, nFndPos + 2 )) ? OUString(cEnDash) : OUString(cEmDash)) ); - bRet = true; + // Use proper codepoints. Currently, CharClass::isLetterNumeric is broken, it + // uses the index *both* as code unit index (when checking it as ASCII), *and* + // as code point index (when passes to css::i18n::XCharacterClassification). + // Oh well... Anyway, single-codepoint strings will workaround it. + sal_Int32 nStart = nSttPos + nFndPos; + sal_uInt32 chStart = aOrigTxt.iterateCodePoints(&nStart, -1); + OUString sStart(&chStart, 1); + // No idea why sImplEndSkipChars is checked at start + if (rCC.isLetterNumeric(sStart, 0) || lcl_IsInArr(sImplEndSkipChars, chStart)) + { + sal_Int32 nEnd = nSttPos + nFndPos + 2; + sal_uInt32 chEnd = aOrigTxt.iterateCodePoints(&nEnd, 1); + OUString sEnd(&chEnd, 1); + // No idea why sImplSttSkipChars is checked at end + if (rCC.isLetterNumeric(sEnd, 0) || lcl_IsInArr(sImplSttSkipChars, chEnd)) + { + nSttPos = nSttPos + nFndPos + nFirstReplacementTextLengthChange; + rDoc.Delete(nSttPos, nSttPos + 2); + rDoc.Insert(nSttPos, + (bEnDash || (rCC.isDigit(sStart, 0) && rCC.isDigit(sEnd, 0)) + ? sEnDash + : sEmDash)); + bRet = true; + } + } } } return bRet; } // Add non-breaking space before specific punctuation marks in French text -bool SvxAutoCorrect::FnAddNonBrkSpace( - SvxAutoCorrDoc& rDoc, const OUString& rTxt, +sal_Int32 SvxAutoCorrect::FnAddNonBrkSpace( + SvxAutoCorrDoc& rDoc, std::u16string_view rTxt, sal_Int32 nEndPos, LanguageType eLang, bool& io_bNbspRunNext ) { - bool bRet = false; + sal_Int32 nRet = -1; CharClass& rCC = GetCharClass( eLang ); if ( rCC.getLanguageTag().getLanguage() == "fr" ) { bool bFrCA = (rCC.getLanguageTag().getCountry() == "CA"); - OUString allChars = ":;?!%"; + OUString allChars = u":;?!%"_ustr; OUString chars( allChars ); if ( bFrCA ) chars = ":"; @@ -683,17 +737,17 @@ bool SvxAutoCorrect::FnAddNonBrkSpace( //See if the text is the start of a protocol string, e.g. have text of //"http" see if it is the start of "http:" and if so leave it alone - sal_Int32 nIndex = nSttWdPos + (bWasWordDelim ? 1 : 0); - sal_Int32 nProtocolLen = nEndPos - nSttWdPos + 1; - if (nIndex + nProtocolLen <= rTxt.getLength()) + size_t nIndex = nSttWdPos + (bWasWordDelim ? 1 : 0); + size_t nProtocolLen = nEndPos - nSttWdPos + 1; + if (nIndex + nProtocolLen <= rTxt.size()) { - if (INetURLObject::CompareProtocolScheme(rTxt.copy(nIndex, nProtocolLen)) != INetProtocol::NotValid) - return false; + if (INetURLObject::CompareProtocolScheme(rTxt.substr(nIndex, nProtocolLen)) != INetProtocol::NotValid) + return -1; } // Check the presence of "://" in the word - sal_Int32 nStrPos = rTxt.indexOf( "://", nSttWdPos + 1 ); - if ( nStrPos == -1 && nEndPos > 0 ) + size_t nStrPos = rTxt.find( u"://", nSttWdPos + 1 ); + if ( nStrPos == std::u16string_view::npos && nEndPos > 0 ) { // Check the previous char sal_Unicode cPrevChar = rTxt[ nEndPos - 1 ]; @@ -716,13 +770,13 @@ bool SvxAutoCorrect::FnAddNonBrkSpace( if ( bHasSpace ) rDoc.Insert( nPos, OUString(cNonBreakingSpace) ); io_bNbspRunNext = true; - bRet = true; + nRet = nPos; } else if ( chars.indexOf( cPrevChar ) != -1 ) io_bNbspRunNext = true; } } - else if ( cChar == '/' && nEndPos > 1 && rTxt.getLength() > (nEndPos - 1) ) + else if ( cChar == '/' && nEndPos > 1 && static_cast<sal_Int32>(rTxt.size()) > (nEndPos - 1) ) { // Remove the hardspace right before to avoid formatting URLs sal_Unicode cPrevChar = rTxt[ nEndPos - 1 ]; @@ -730,12 +784,12 @@ bool SvxAutoCorrect::FnAddNonBrkSpace( if ( cPrevChar == ':' && cMaybeSpaceChar == cNonBreakingSpace ) { rDoc.Delete( nEndPos - 2, nEndPos - 1 ); - bRet = true; + nRet = nEndPos - 1; } } } - return bRet; + return nRet; } // URL recognition @@ -751,6 +805,18 @@ bool SvxAutoCorrect::FnSetINetAttr( SvxAutoCorrDoc& rDoc, const OUString& rTxt, return bRet; } +// DOI citation recognition +bool SvxAutoCorrect::FnSetDOIAttr( SvxAutoCorrDoc& rDoc, std::u16string_view rTxt, + sal_Int32 nSttPos, sal_Int32 nEndPos, + LanguageType eLang ) +{ + OUString sURL( URIHelper::FindFirstDOIInText( rTxt, nSttPos, nEndPos, GetCharClass( eLang ) )); + bool bRet = !sURL.isEmpty(); + if( bRet ) // so, set attribute: + rDoc.SetINetAttr( nSttPos, nEndPos, sURL ); + return bRet; +} + // Automatic *bold*, /italic/, -strikeout- and _underline_ bool SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc& rDoc, const OUString& rTxt, sal_Int32 nEndPos ) @@ -803,37 +869,38 @@ bool SvxAutoCorrect::FnChgWeightUnderl( SvxAutoCorrDoc& rDoc, const OUString& rT // of an empty hint in SetAttr which would be removed by Delete // (fdo#62536, AUTOFMT in Writer) rDoc.Delete( nEndPos, nEndPos + 1 ); - rDoc.Delete( nFndPos, nFndPos + 1 ); + // Span the Attribute over the area // the end. if( '*' == cInsChar ) // Bold { SvxWeightItem aSvxWeightItem( WEIGHT_BOLD, SID_ATTR_CHAR_WEIGHT ); - rDoc.SetAttr( nFndPos, nEndPos - 1, + rDoc.SetAttr( nFndPos + 1, nEndPos, SID_ATTR_CHAR_WEIGHT, aSvxWeightItem); } else if( '/' == cInsChar ) // Italic { SvxPostureItem aSvxPostureItem( ITALIC_NORMAL, SID_ATTR_CHAR_POSTURE ); - rDoc.SetAttr( nFndPos, nEndPos - 1, + rDoc.SetAttr( nFndPos + 1, nEndPos, SID_ATTR_CHAR_POSTURE, aSvxPostureItem); } else if( '-' == cInsChar ) // Strikeout { SvxCrossedOutItem aSvxCrossedOutItem( STRIKEOUT_SINGLE, SID_ATTR_CHAR_STRIKEOUT ); - rDoc.SetAttr( nFndPos, nEndPos - 1, + rDoc.SetAttr( nFndPos + 1, nEndPos, SID_ATTR_CHAR_STRIKEOUT, aSvxCrossedOutItem); } else // Underline { SvxUnderlineItem aSvxUnderlineItem( LINESTYLE_SINGLE, SID_ATTR_CHAR_UNDERLINE ); - rDoc.SetAttr( nFndPos, nEndPos - 1, + rDoc.SetAttr( nFndPos + 1, nEndPos, SID_ATTR_CHAR_UNDERLINE, aSvxUnderlineItem); } + rDoc.Delete( nFndPos, nFndPos + 1 ); } return -1 != nFndPos; @@ -867,7 +934,7 @@ void SvxAutoCorrect::FnCapitalStartSentence( SvxAutoCorrDoc& rDoc, } else if (pWordStt && !rCC.isDigit(aText, pStr - pStart)) { - if( (lcl_IsInAsciiArr( "-'", *pStr ) || *pStr == cApostrophe) && // These characters are allowed in words + if( (lcl_IsInArr( u"-'", *pStr ) || *pStr == cApostrophe) && // These characters are allowed in words pWordStt - 1 == pStr && // Installation at beginning of paragraph. Replaced < by <= (#i38971#) (pStart + 1) <= pStr && @@ -895,7 +962,7 @@ void SvxAutoCorrect::FnCapitalStartSentence( SvxAutoCorrDoc& rDoc, sal_Int32 nProtocolLen = pDelim - pWordStt + 1; if (nIndex + nProtocolLen <= rTxt.getLength()) { - if (INetURLObject::CompareProtocolScheme(rTxt.copy(nIndex, nProtocolLen)) != INetProtocol::NotValid) + if (INetURLObject::CompareProtocolScheme(rTxt.subView(nIndex, nProtocolLen)) != INetProtocol::NotValid) return; // already ok } @@ -904,7 +971,7 @@ void SvxAutoCorrect::FnCapitalStartSentence( SvxAutoCorrDoc& rDoc, // Only capitalize, if string before specified characters is long enough if( *pDelim && 2 >= pDelim - pWordStt && - lcl_IsInAsciiArr( ".-)>", *pDelim ) ) + lcl_IsInArr( u".-)>", *pDelim ) ) return; // tdf#59666 don't capitalize single Greek letters (except in Greek texts) @@ -1253,7 +1320,7 @@ void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos, // i' -> I' in English (last step for the Undo) if( eType == ACQuotes::CapitalizeIAm ) - rDoc.Replace( nInsPos-1, "I" ); + rDoc.Replace( nInsPos-1, u"I"_ustr ); } OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc const & rDoc, sal_Int32 nInsPos, @@ -1279,7 +1346,7 @@ OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc const & rDoc, sal_Int32 nInsPo // search preceding opening quote in the paragraph before the insert position static bool lcl_HasPrecedingChar( std::u16string_view rTxt, sal_Int32 nPos, - const sal_Unicode sPrecedingChar, const sal_Unicode* aStopChars ) + const sal_Unicode sPrecedingChar, const sal_Unicode sStopChar, const sal_Unicode* aStopChars ) { sal_Unicode cTmpChar; @@ -1288,6 +1355,9 @@ static bool lcl_HasPrecedingChar( std::u16string_view rTxt, sal_Int32 nPos, if ( cTmpChar == sPrecedingChar ) return true; + if ( cTmpChar == sStopChar ) + return false; + for ( const sal_Unicode* pCh = aStopChars; *pCh; ++pCh ) if ( cTmpChar == *pCh ) return false; @@ -1329,7 +1399,7 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, { sal_Unicode cPrev = rTxt[ nInsPos-1 ]; bSttQuote = NonFieldWordDelim(cPrev) || - lcl_IsInAsciiArr( "([{", cPrev ) || + lcl_IsInArr( u"([{", cPrev ) || ( cEmDash == cPrev ) || ( cEnDash == cPrev ); // tdf#38394 use opening quotation mark << in French l'<<word>> @@ -1337,7 +1407,7 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, primary(eLang) == primary(LANGUAGE_FRENCH) && ( ( ( nInsPos == 2 || ( nInsPos > 2 && IsWordDelim( rTxt[ nInsPos-3 ] ) ) ) && // abbreviated form of ce, de, je, la, le, ne, me, te, se or si - OUString("cdjlnmtsCDJLNMTS").indexOf( rTxt[ nInsPos-2 ] ) > -1 ) || + u"cdjlnmtsCDJLNMTS"_ustr.indexOf( rTxt[ nInsPos-2 ] ) > -1 ) || ( ( nInsPos == 3 || (nInsPos > 3 && IsWordDelim( rTxt[ nInsPos-4 ] ) ) ) && // abbreviated form of que ( rTxt[ nInsPos-2 ] == 'u' || rTxt[ nInsPos-2 ] == 'U' ) && @@ -1357,13 +1427,15 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, ( ( eLang == LANGUAGE_HUNGARIAN && lcl_HasPrecedingChar( rTxt, nInsPos, bSttQuote ? aStopDoubleAngleQuoteStart[0] : aStopDoubleAngleQuoteEnd[0], - bSttQuote ? aStopDoubleAngleQuoteStart + 1 : aStopDoubleAngleQuoteEnd + 1 ) ) || + bSttQuote ? aStopDoubleAngleQuoteStart[1] : aStopDoubleAngleQuoteEnd[1], + bSttQuote ? aStopDoubleAngleQuoteStart + 1 : aStopDoubleAngleQuoteEnd + 2 ) ) || ( eLang.anyOf( LANGUAGE_ROMANIAN, LANGUAGE_ROMANIAN_MOLDOVA ) && lcl_HasPrecedingChar( rTxt, nInsPos, bSttQuote ? aStopDoubleAngleQuoteStart[0] : aStopDoubleAngleQuoteEndRo[0], - bSttQuote ? aStopDoubleAngleQuoteStart + 1 : aStopDoubleAngleQuoteEndRo + 1 ) ) ) ) + bSttQuote ? aStopDoubleAngleQuoteStart[1] : aStopDoubleAngleQuoteEndRo[1], + bSttQuote ? aStopDoubleAngleQuoteStart + 1 : aStopDoubleAngleQuoteEndRo + 2 ) ) ) ) { LocaleDataWrapper& rLcl = GetLocaleDataWrapper( eLang ); // only if the opening double quotation mark is the default one @@ -1374,7 +1446,7 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, // tdf#128860 use apostrophe outside of second level quotation in Czech, German, Icelandic, // Slovak and Slovenian instead of the – in this case, bad – closing quotation mark U+2018. // tdf#123786 the same for Russian and Ukrainian - ( ( eLang.anyOf ( + ( eLang.anyOf ( LANGUAGE_CZECH, LANGUAGE_GERMAN, LANGUAGE_GERMAN_SWISS, @@ -1383,17 +1455,33 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, LANGUAGE_GERMAN_LIECHTENSTEIN, LANGUAGE_ICELANDIC, LANGUAGE_SLOVAK, - LANGUAGE_SLOVENIAN ) && - !lcl_HasPrecedingChar( rTxt, nInsPos, aStopSingleQuoteEnd[0], aStopSingleQuoteEnd + 1 ) ) || + LANGUAGE_SLOVENIAN ) ) ) + { + sal_Unicode sStartChar = GetStartSingleQuote(); + sal_Unicode sEndChar = GetEndSingleQuote(); + if ( !sStartChar || !sEndChar ) { + LocaleDataWrapper& rLcl = GetLocaleDataWrapper( eLang ); + if ( !sStartChar ) sStartChar = rLcl.getQuotationMarkStart()[0]; + if ( !sEndChar ) sEndChar = rLcl.getQuotationMarkStart()[0]; + } + if ( !lcl_HasPrecedingChar( rTxt, nInsPos, sStartChar, sEndChar, aStopSingleQuoteEnd + 1 ) ) + { + CharClass& rCC = GetCharClass( eLang ); + if ( rCC.isLetter(rTxt, nInsPos-1) ) + { + eType = ACQuotes::UseApostrophe; + } + } + } + else if ( bSingle && nInsPos && !bSttQuote && ( eLang.anyOf ( LANGUAGE_RUSSIAN, LANGUAGE_UKRAINIAN ) && - !lcl_HasPrecedingChar( rTxt, nInsPos, aStopSingleQuoteEndRuUa[0], aStopSingleQuoteEndRuUa + 1 ) ) ) ) + !lcl_HasPrecedingChar( rTxt, nInsPos, aStopSingleQuoteEndRuUa[0], aStopSingleQuoteEndRuUa[1], aStopSingleQuoteEndRuUa + 2 ) ) ) { LocaleDataWrapper& rLcl = GetLocaleDataWrapper( eLang ); CharClass& rCC = GetCharClass( eLang ); - if ( ( rLcl.getQuotationMarkStart() == OUStringChar(aStopSingleQuoteEnd[0]) || - rLcl.getQuotationMarkStart() == OUStringChar(aStopSingleQuoteEndRuUa[0]) ) && + if ( rLcl.getQuotationMarkStart() == OUStringChar(aStopSingleQuoteEndRuUa[0]) && // use apostrophe only after letters, not after digits or punctuation rCC.isLetter(rTxt, nInsPos-1) ) { @@ -1449,10 +1537,14 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, // Hardspaces autocorrection if ( IsAutoCorrFlag( ACFlags::AddNonBrkSpace ) ) { - if ( NeedsHardspaceAutocorr( cChar ) && - FnAddNonBrkSpace( rDoc, rTxt, nInsPos, GetDocLanguage( rDoc, nInsPos ), io_bNbspRunNext ) ) + // WARNING ATTENTION: rTxt is an alias of the text node's OUString + // and its length may change (even become shorter) if FnAddNonBrkSpace succeeds! + sal_Int32 nUpdatedPos = -1; + if (NeedsHardspaceAutocorr(cChar)) + nUpdatedPos = FnAddNonBrkSpace( rDoc, rTxt, nInsPos, GetDocLanguage( rDoc, nInsPos ), io_bNbspRunNext ); + if (nUpdatedPos >= 0) { - ; + nInsPos = nUpdatedPos; } else if ( bIsNextRun && !IsAutoCorrectChar( cChar ) ) { @@ -1531,11 +1623,11 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, { sal_Int32 nCapLttrPos1 = nCapLttrPos, nInsPos1 = nInsPos; while( nCapLttrPos1 < nInsPos && - lcl_IsInAsciiArr( sImplSttSkipChars, rTxt[ nCapLttrPos1 ] ) + lcl_IsInArr( sImplSttSkipChars, rTxt[ nCapLttrPos1 ] ) ) ++nCapLttrPos1; while( nCapLttrPos1 < nInsPos1 && nInsPos1 && - lcl_IsInAsciiArr( sImplEndSkipChars, rTxt[ nInsPos1-1 ] ) + lcl_IsInArr( sImplEndSkipChars, rTxt[ nInsPos1-1 ] ) ) --nInsPos1; @@ -1587,7 +1679,10 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, FnChgOrdinalNumber( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) || ( IsAutoCorrFlag( ACFlags::SetINetAttr ) && ( ' ' == cChar || '\t' == cChar || 0x0a == cChar || !cChar ) && - FnSetINetAttr( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) ) + FnSetINetAttr( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) || + ( IsAutoCorrFlag( ACFlags::SetDOIAttr ) && + ( ' ' == cChar || '\t' == cChar || 0x0a == cChar || !cChar ) && + FnSetDOIAttr( rDoc, rTxt, nCapLttrPos, nInsPos, eLang ) ) ) ; else { @@ -1632,14 +1727,16 @@ SvxAutoCorrectLanguageLists& SvxAutoCorrect::GetLanguageList_( LanguageTag aLanguageTag( eLang); if (m_aLangTable.find(aLanguageTag) == m_aLangTable.end()) (void)CreateLanguageFile(aLanguageTag); - return *(m_aLangTable.find(aLanguageTag)->second); + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end()); + return iter->second; } void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang ) { auto const iter = m_aLangTable.find(LanguageTag(eLang)); - if (iter != m_aLangTable.end() && iter->second) - iter->second->SaveCplSttExceptList(); + if (iter != m_aLangTable.end()) + iter->second.SaveCplSttExceptList(); else { SAL_WARN("editeng", "Save an empty list? "); @@ -1649,8 +1746,8 @@ void SvxAutoCorrect::SaveCplSttExceptList( LanguageType eLang ) void SvxAutoCorrect::SaveWordStartExceptList(LanguageType eLang) { auto const iter = m_aLangTable.find(LanguageTag(eLang)); - if (iter != m_aLangTable.end() && iter->second) - iter->second->SaveWordStartExceptList(); + if (iter != m_aLangTable.end()) + iter->second.SaveWordStartExceptList(); else { SAL_WARN("editeng", "Save an empty list? "); @@ -1665,15 +1762,19 @@ bool SvxAutoCorrect::AddCplSttException( const OUString& rNew, // either the right language is present or it will be this in the general list auto iter = m_aLangTable.find(LanguageTag(eLang)); if (iter != m_aLangTable.end()) - pLists = iter->second.get(); + pLists = &iter->second; else { LanguageTag aLangTagUndetermined( LANGUAGE_UNDETERMINED); iter = m_aLangTable.find(aLangTagUndetermined); if (iter != m_aLangTable.end()) - pLists = iter->second.get(); + pLists = &iter->second; else if(CreateLanguageFile(aLangTagUndetermined)) - pLists = m_aLangTable.find(aLangTagUndetermined)->second.get(); + { + iter = m_aLangTable.find(aLangTagUndetermined); + assert(iter != m_aLangTable.end()); + pLists = &iter->second; + } } OSL_ENSURE(pLists, "No auto correction data"); return pLists && pLists->AddToCplSttExceptList(rNew); @@ -1687,15 +1788,19 @@ bool SvxAutoCorrect::AddWordStartException( const OUString& rNew, //either the right language is present or it is set in the general list auto iter = m_aLangTable.find(LanguageTag(eLang)); if (iter != m_aLangTable.end()) - pLists = iter->second.get(); + pLists = &iter->second; else { LanguageTag aLangTagUndetermined( LANGUAGE_UNDETERMINED); iter = m_aLangTable.find(aLangTagUndetermined); if (iter != m_aLangTable.end()) - pLists = iter->second.get(); + pLists = &iter->second; else if(CreateLanguageFile(aLangTagUndetermined)) - pLists = m_aLangTable.find(aLangTagUndetermined)->second.get(); + { + iter = m_aLangTable.find(aLangTagUndetermined); + assert(iter != m_aLangTable.end()); + pLists = &iter->second; + } } OSL_ENSURE(pLists, "No auto correction file!"); return pLists && pLists->AddToWordStartExceptList(rNew); @@ -1725,7 +1830,7 @@ OUString SvxAutoCorrect::GetPrevAutoCorrWord(SvxAutoCorrDoc const& rDoc, const O if( !nPos && !IsWordDelim( rTxt[ 0 ])) --nCapLttrPos; // Beginning of paragraph and no Blank! - while( lcl_IsInAsciiArr( sImplSttSkipChars, rTxt[ nCapLttrPos ]) ) + while( lcl_IsInArr( sImplSttSkipChars, rTxt[ nCapLttrPos ]) ) if( ++nCapLttrPos >= nEnd ) return sRet; @@ -1744,7 +1849,7 @@ OUString SvxAutoCorrect::GetPrevAutoCorrWord(SvxAutoCorrDoc const& rDoc, const O } // static -std::vector<OUString> SvxAutoCorrect::GetChunkForAutoText(const OUString& rTxt, +std::vector<OUString> SvxAutoCorrect::GetChunkForAutoText(std::u16string_view rTxt, const sal_Int32 nPos) { constexpr sal_Int32 nMinLen = 3; @@ -1761,7 +1866,7 @@ std::vector<OUString> SvxAutoCorrect::GetChunkForAutoText(const OUString& rTxt, } if (nBegin + nMinLen <= nPos) { - OUString sRes = rTxt.copy(nBegin, nPos - nBegin); + OUString sRes( rTxt.substr(nBegin, nPos - nBegin) ); aRes.push_back(sRes); bool bLastStartedWithDelim = IsWordDelim(sRes[0]); for (sal_Int32 i = 1; i <= sRes.getLength() - nMinLen; ++i) @@ -1798,9 +1903,10 @@ bool SvxAutoCorrect::CreateLanguageFile( const LanguageTag& rLanguageTag, bool b if( bNewFile ) { sShareDirFile = sUserDirFile; - pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile, sUserDirFile ); - LanguageTag aTmp(rLanguageTag); // this insert() needs a non-const reference - m_aLangTable.insert(std::make_pair(aTmp, std::unique_ptr<SvxAutoCorrectLanguageLists>(pLists))); + auto itBool = m_aLangTable.emplace(std::piecewise_construct, + std::forward_as_tuple(rLanguageTag), + std::forward_as_tuple(*this, sShareDirFile, sUserDirFile)); + pLists = &itBool.first->second; aLastFileTable.erase(nFndPos); } } @@ -1814,9 +1920,10 @@ bool SvxAutoCorrect::CreateLanguageFile( const LanguageTag& rLanguageTag, bool b ( sShareDirFile = sUserDirFile, bNewFile ) ) { - pLists = new SvxAutoCorrectLanguageLists( *this, sShareDirFile, sUserDirFile ); - LanguageTag aTmp(rLanguageTag); // this insert() needs a non-const reference - m_aLangTable.insert(std::make_pair(aTmp, std::unique_ptr<SvxAutoCorrectLanguageLists>(pLists))); + auto itBool = m_aLangTable.emplace(std::piecewise_construct, + std::forward_as_tuple(rLanguageTag), + std::forward_as_tuple(*this, sShareDirFile, sUserDirFile)); + pLists = &itBool.first->second; if (nFndPos != aLastFileTable.end()) aLastFileTable.erase(nFndPos); } @@ -1831,11 +1938,14 @@ bool SvxAutoCorrect::PutText( const OUString& rShort, const OUString& rLong, LanguageType eLang ) { LanguageTag aLanguageTag( eLang); - auto const iter = m_aLangTable.find(aLanguageTag); - if (iter != m_aLangTable.end()) - return iter->second->PutText(rShort, rLong); - if(CreateLanguageFile(aLanguageTag)) - return m_aLangTable.find(aLanguageTag)->second->PutText(rShort, rLong); + if (auto const iter = m_aLangTable.find(aLanguageTag); iter != m_aLangTable.end()) + return iter->second.PutText(rShort, rLong); + if (CreateLanguageFile(aLanguageTag)) + { + auto const iter = m_aLangTable.find(aLanguageTag); + assert (iter != m_aLangTable.end()); + return iter->second.PutText(rShort, rLong); + } return false; } @@ -1844,14 +1954,16 @@ void SvxAutoCorrect::MakeCombinedChanges( std::vector<SvxAutocorrWord>& aNewEntr LanguageType eLang ) { LanguageTag aLanguageTag( eLang); - auto const iter = m_aLangTable.find(aLanguageTag); + auto iter = m_aLangTable.find(aLanguageTag); if (iter != m_aLangTable.end()) { - iter->second->MakeCombinedChanges( aNewEntries, aDeleteEntries ); + iter->second.MakeCombinedChanges( aNewEntries, aDeleteEntries ); } else if(CreateLanguageFile( aLanguageTag )) { - m_aLangTable.find( aLanguageTag )->second->MakeCombinedChanges( aNewEntries, aDeleteEntries ); + iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end()); + iter->second.MakeCombinedChanges( aNewEntries, aDeleteEntries ); } } @@ -1873,13 +1985,13 @@ bool SvxAutoCorrect::PutText( const css::uno::Reference < css::embed::XStorage > return false; } -OUString EncryptBlockName_Imp(const OUString& rName) +OUString EncryptBlockName_Imp(std::u16string_view rName) { OUStringBuffer aName; aName.append('#').append(rName); - for (sal_Int32 nLen = rName.getLength(), nPos = 1; nPos < nLen; ++nPos) + for (size_t nLen = rName.size(), nPos = 1; nPos < nLen; ++nPos) { - if (lcl_IsInAsciiArr( "!/:.\\", aName[nPos])) + if (lcl_IsInArr( u"!/:.\\", aName[nPos])) aName[nPos] &= 0x0f; } return aName.makeStringAndClear(); @@ -1900,6 +2012,8 @@ static void GeneratePackageName ( std::u16string_view rShort, OUString& rPackage case ':': case '.': case '\\': + // tdf#156769 - escape the question mark in the storage name + case '?': aBuf[nPos] = '_'; break; default: @@ -1911,7 +2025,7 @@ static void GeneratePackageName ( std::u16string_view rShort, OUString& rPackage } static const SvxAutocorrWord* lcl_SearchWordsInList( - SvxAutoCorrectLanguageLists* pList, const OUString& rTxt, + SvxAutoCorrectLanguageLists* pList, std::u16string_view rTxt, sal_Int32& rStt, sal_Int32 nEndPos) { const SvxAutocorrWordList* pAutoCorrWordList = pList->GetAutocorrWordList(); @@ -1920,7 +2034,7 @@ static const SvxAutocorrWord* lcl_SearchWordsInList( // the search for the words in the substitution table const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList( - const OUString& rTxt, sal_Int32& rStt, sal_Int32 nEndPos, + std::u16string_view rTxt, sal_Int32& rStt, sal_Int32 nEndPos, SvxAutoCorrDoc&, LanguageTag& rLang ) { const SvxAutocorrWord* pRet = nullptr; @@ -1936,8 +2050,10 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList( if (m_aLangTable.find(aLanguageTag) != m_aLangTable.end() || CreateLanguageFile(aLanguageTag, false)) { //the language is available - so bring it on - std::unique_ptr<SvxAutoCorrectLanguageLists> const& pList = m_aLangTable.find(aLanguageTag)->second; - pRet = lcl_SearchWordsInList( pList.get(), rTxt, rStt, nEndPos ); + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end()); + SvxAutoCorrectLanguageLists & rList = iter->second; + pRet = lcl_SearchWordsInList( &rList, rTxt, rStt, nEndPos ); if( pRet ) { rLang = aLanguageTag; @@ -1957,8 +2073,8 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList( CreateLanguageFile(aLanguageTag, false))) { //the language is available - so bring it on - std::unique_ptr<SvxAutoCorrectLanguageLists> const& pList = m_aLangTable.find(aLanguageTag)->second; - pRet = lcl_SearchWordsInList( pList.get(), rTxt, rStt, nEndPos ); + SvxAutoCorrectLanguageLists& rList = m_aLangTable.find(aLanguageTag)->second; + pRet = lcl_SearchWordsInList( &rList, rTxt, rStt, nEndPos ); if( pRet ) { rLang = aLanguageTag; @@ -1970,8 +2086,10 @@ const SvxAutocorrWord* SvxAutoCorrect::SearchWordsInList( CreateLanguageFile(aLanguageTag, false)) { //the language is available - so bring it on - std::unique_ptr<SvxAutoCorrectLanguageLists> const& pList = m_aLangTable.find(aLanguageTag)->second; - pRet = lcl_SearchWordsInList( pList.get(), rTxt, rStt, nEndPos ); + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end()); + SvxAutoCorrectLanguageLists& rList = iter->second; + pRet = lcl_SearchWordsInList( &rList, rTxt, rStt, nEndPos ); if( pRet ) { rLang = aLanguageTag; @@ -1994,8 +2112,10 @@ bool SvxAutoCorrect::FindInWordStartExceptList( LanguageType eLang, if (m_aLangTable.find(aLanguageTag) != m_aLangTable.end() || CreateLanguageFile(aLanguageTag, false)) { //the language is available - so bring it on - auto const& pList = m_aLangTable.find(aLanguageTag)->second; - if(pList->GetWordStartExceptList()->find(sWord) != pList->GetWordStartExceptList()->end() ) + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end() && "CreateLanguageFile can't fail"); + auto& rList = iter->second; + if(rList.GetWordStartExceptList()->find(sWord) != rList.GetWordStartExceptList()->end() ) return true; } @@ -2008,8 +2128,10 @@ bool SvxAutoCorrect::FindInWordStartExceptList( LanguageType eLang, CreateLanguageFile(aLanguageTag, false))) { //the language is available - so bring it on - auto const& pList = m_aLangTable.find(aLanguageTag)->second; - if(pList->GetWordStartExceptList()->find(sWord) != pList->GetWordStartExceptList()->end() ) + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end() && "CreateLanguageFile can't fail"); + auto& rList = iter->second; + if(rList.GetWordStartExceptList()->find(sWord) != rList.GetWordStartExceptList()->end() ) return true; } @@ -2017,8 +2139,10 @@ bool SvxAutoCorrect::FindInWordStartExceptList( LanguageType eLang, CreateLanguageFile(aLanguageTag, false)) { //the language is available - so bring it on - auto const& pList = m_aLangTable.find(aLanguageTag)->second; - if(pList->GetWordStartExceptList()->find(sWord) != pList->GetWordStartExceptList()->end() ) + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end()); + auto& rList = iter->second; + if(rList.GetWordStartExceptList()->find(sWord) != rList.GetWordStartExceptList()->end() ) return true; } return false; @@ -2026,7 +2150,7 @@ bool SvxAutoCorrect::FindInWordStartExceptList( LanguageType eLang, static bool lcl_FindAbbreviation(const SvStringsISortDtor* pList, const OUString& sWord) { - SvStringsISortDtor::const_iterator it = pList->find( "~" ); + SvStringsISortDtor::const_iterator it = pList->find(u"~"_ustr); SvStringsISortDtor::size_type nPos = it - pList->begin(); if( nPos < pList->size() ) { @@ -2070,7 +2194,9 @@ bool SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang, if (m_aLangTable.find(aLanguageTag) != m_aLangTable.end() || CreateLanguageFile(aLanguageTag, false)) { //the language is available - so bring it on - const SvStringsISortDtor* pList = m_aLangTable.find(aLanguageTag)->second->GetCplSttExceptList(); + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end() && "CreateLanguageFile can't fail"); + const SvStringsISortDtor* pList = iter->second.GetCplSttExceptList(); if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(sWord) != pList->end() ) return true; } @@ -2084,7 +2210,9 @@ bool SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang, CreateLanguageFile(aLanguageTag, false))) { //the language is available - so bring it on - const SvStringsISortDtor* pList = m_aLangTable.find(aLanguageTag)->second->GetCplSttExceptList(); + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end() && "CreateLanguageFile can't fail"); + const SvStringsISortDtor* pList = iter->second.GetCplSttExceptList(); if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(sWord) != pList->end() ) return true; } @@ -2093,7 +2221,9 @@ bool SvxAutoCorrect::FindInCplSttExceptList(LanguageType eLang, CreateLanguageFile(aLanguageTag, false)) { //the language is available - so bring it on - const SvStringsISortDtor* pList = m_aLangTable.find(aLanguageTag)->second->GetCplSttExceptList(); + const auto iter = m_aLangTable.find(aLanguageTag); + assert(iter != m_aLangTable.end() && "CreateLanguageFile can't fail"); + const SvStringsISortDtor* pList = iter->second.GetCplSttExceptList(); if(bAbbreviation ? lcl_FindAbbreviation(pList, sWord) : pList->find(sWord) != pList->end() ) return true; } @@ -2129,10 +2259,10 @@ OUString SvxAutoCorrect::GetAutoCorrFileName( const LanguageTag& rLanguageTag, SvxAutoCorrectLanguageLists::SvxAutoCorrectLanguageLists( SvxAutoCorrect& rParent, - const OUString& rShareAutoCorrectFile, - const OUString& rUserAutoCorrectFile) -: sShareAutoCorrFile( rShareAutoCorrectFile ), - sUserAutoCorrFile( rUserAutoCorrectFile ), + OUString aShareAutoCorrectFile, + OUString aUserAutoCorrectFile) +: sShareAutoCorrFile(std::move( aShareAutoCorrectFile )), + sUserAutoCorrFile(std::move( aUserAutoCorrectFile )), aModifiedDate( Date::EMPTY ), aModifiedTime( tools::Time::EMPTY ), aLastCheckTime( tools::Time::EMPTY ), @@ -2186,7 +2316,7 @@ bool SvxAutoCorrectLanguageLists::IsFileChanged_Imp() void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp( std::unique_ptr<SvStringsISortDtor>& rpLst, const OUString& sStrmName, - tools::SvRef<SotStorage>& rStg) + rtl::Reference<SotStorage>& rStg) { if( rpLst ) rpLst->clear(); @@ -2196,7 +2326,7 @@ void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp( { if( rStg.is() && rStg->IsStream( sStrmName ) ) { - tools::SvRef<SotStorageStream> xStrm = rStg->OpenSotStream( sStrmName, + rtl::Reference<SotStorageStream> xStrm = rStg->OpenSotStream( sStrmName, ( StreamMode::READ | StreamMode::SHARE_DENYWRITE | StreamMode::NOCREATE ) ); if( ERRCODE_NONE != xStrm->GetError()) { @@ -2223,7 +2353,7 @@ void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp( uno::Reference< xml::sax::XFastParser > xParser = xml::sax::FastParser::create( xContext ); uno::Reference<xml::sax::XFastTokenHandler> xTokenHandler = new SvXMLAutoCorrectTokenHandler; xParser->setFastDocumentHandler( xFilter ); - xParser->registerNamespace( "http://openoffice.org/2001/block-list", SvXMLAutoCorrectToken::NAMESPACE ); + xParser->registerNamespace( u"http://openoffice.org/2001/block-list"_ustr, SvXMLAutoCorrectToken::NAMESPACE ); xParser->setTokenHandler( xTokenHandler ); // parse @@ -2257,7 +2387,7 @@ void SvxAutoCorrectLanguageLists::LoadXMLExceptList_Imp( void SvxAutoCorrectLanguageLists::SaveExceptList_Imp( const SvStringsISortDtor& rLst, const OUString& sStrmName, - tools::SvRef<SotStorage> const &rStg, + rtl::Reference<SotStorage> const &rStg, bool bConvert ) { if( !rStg.is() ) @@ -2270,13 +2400,13 @@ void SvxAutoCorrectLanguageLists::SaveExceptList_Imp( } else { - tools::SvRef<SotStorageStream> xStrm = rStg->OpenSotStream( sStrmName, + rtl::Reference<SotStorageStream> xStrm = rStg->OpenSotStream( sStrmName, ( StreamMode::READ | StreamMode::WRITE | StreamMode::SHARE_DENYWRITE ) ); if( xStrm.is() ) { xStrm->SetSize( 0 ); xStrm->SetBufferSize( 8192 ); - xStrm->SetProperty( "MediaType", Any(OUString( "text/xml" )) ); + xStrm->SetProperty( u"MediaType"_ustr, Any(u"text/xml"_ustr) ); uno::Reference< uno::XComponentContext > xContext = @@ -2334,7 +2464,7 @@ SvxAutocorrWordList* SvxAutoCorrectLanguageLists::LoadAutocorrWordList() // connect parser and filter xParser->setFastDocumentHandler( xFilter ); - xParser->registerNamespace( "http://openoffice.org/2001/block-list", SvXMLAutoCorrectToken::NAMESPACE ); + xParser->registerNamespace( u"http://openoffice.org/2001/block-list"_ustr, SvXMLAutoCorrectToken::NAMESPACE ); xParser->setTokenHandler(xTokenHandler); // parse @@ -2389,7 +2519,7 @@ bool SvxAutoCorrectLanguageLists::AddToCplSttExceptList(const OUString& rNew) if( !rNew.isEmpty() && GetCplSttExceptList()->insert( rNew ).second ) { MakeUserStorage_Impl(); - tools::SvRef<SotStorage> xStg = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStg = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg ); @@ -2409,7 +2539,7 @@ bool SvxAutoCorrectLanguageLists::AddToWordStartExceptList(const OUString& rNew) if( !rNew.isEmpty() && GetWordStartExceptList()->insert( rNew ).second ) { MakeUserStorage_Impl(); - tools::SvRef<SotStorage> xStg = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStg = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); SaveExceptList_Imp( *pWordStart_ExcptLst, pXMLImplWordStart_ExcptLstStr, xStg ); @@ -2427,7 +2557,7 @@ SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadCplSttExceptList() { try { - tools::SvRef<SotStorage> xStg = new SotStorage( sShareAutoCorrFile, StreamMode::READ | StreamMode::SHARE_DENYNONE ); + rtl::Reference<SotStorage> xStg = new SotStorage( sShareAutoCorrFile, StreamMode::READ | StreamMode::SHARE_DENYNONE ); if( xStg.is() && xStg->IsContained( pXMLImplCplStt_ExcptLstStr ) ) LoadXMLExceptList_Imp( pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg ); } @@ -2440,7 +2570,7 @@ SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadCplSttExceptList() void SvxAutoCorrectLanguageLists::SaveCplSttExceptList() { MakeUserStorage_Impl(); - tools::SvRef<SotStorage> xStg = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStg = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); SaveExceptList_Imp( *pCplStt_ExcptLst, pXMLImplCplStt_ExcptLstStr, xStg ); @@ -2456,7 +2586,7 @@ SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadWordStartExceptList() { try { - tools::SvRef<SotStorage> xStg = new SotStorage( sShareAutoCorrFile, StreamMode::READ | StreamMode::SHARE_DENYNONE ); + rtl::Reference<SotStorage> xStg = new SotStorage( sShareAutoCorrFile, StreamMode::READ | StreamMode::SHARE_DENYNONE ); if( xStg.is() && xStg->IsContained( pXMLImplWordStart_ExcptLstStr ) ) LoadXMLExceptList_Imp( pWordStart_ExcptLst, pXMLImplWordStart_ExcptLstStr, xStg ); } @@ -2470,7 +2600,7 @@ SvStringsISortDtor* SvxAutoCorrectLanguageLists::LoadWordStartExceptList() void SvxAutoCorrectLanguageLists::SaveWordStartExceptList() { MakeUserStorage_Impl(); - tools::SvRef<SotStorage> xStg = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStg = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); SaveExceptList_Imp( *pWordStart_ExcptLst, pXMLImplWordStart_ExcptLstStr, xStg ); @@ -2500,7 +2630,7 @@ void SvxAutoCorrectLanguageLists::RemoveStream_Imp( const OUString& rName ) { if( sShareAutoCorrFile != sUserAutoCorrFile ) { - tools::SvRef<SotStorage> xStg = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStg = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); if( xStg.is() && ERRCODE_NONE == xStg->GetError() && xStg->IsStream( rName ) ) { @@ -2553,7 +2683,7 @@ void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl() aInfo.NewTitle = aDest.GetLastName(); aInfo.SourceURL = aSource.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); aInfo.MoveData = false; - aNewContent.executeCommand( "transfer", Any(aInfo)); + aNewContent.executeCommand( u"transfer"_ustr, Any(aInfo)); } catch (...) { @@ -2562,8 +2692,8 @@ void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl() } if (bConvert && !bError) { - tools::SvRef<SotStorage> xSrcStg = new SotStorage( aDest.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ), StreamMode::READ ); - tools::SvRef<SotStorage> xDstStg = new SotStorage( sUserAutoCorrFile, StreamMode::WRITE ); + rtl::Reference<SotStorage> xSrcStg = new SotStorage( aDest.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ), StreamMode::READ ); + rtl::Reference<SotStorage> xDstStg = new SotStorage(sUserAutoCorrFile, StreamMode::WRITE); if( xSrcStg.is() && xDstStg.is() ) { @@ -2595,7 +2725,7 @@ void SvxAutoCorrectLanguageLists::MakeUserStorage_Impl() try { ::ucbhelper::Content aContent ( aDest.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ), uno::Reference < XCommandEnvironment >(), comphelper::getProcessComponentContext() ); - aContent.executeCommand ( "delete", makeAny ( true ) ); + aContent.executeCommand ( u"delete"_ustr, Any ( true ) ); } catch (...) { @@ -2611,13 +2741,13 @@ bool SvxAutoCorrectLanguageLists::MakeBlocklist_Imp( SotStorage& rStg ) bool bRet = true, bRemove = !pAutocorr_List || pAutocorr_List->empty(); if( !bRemove ) { - tools::SvRef<SotStorageStream> refList = rStg.OpenSotStream( pXMLImplAutocorr_ListStr, + rtl::Reference<SotStorageStream> refList = rStg.OpenSotStream( pXMLImplAutocorr_ListStr, ( StreamMode::READ | StreamMode::WRITE | StreamMode::SHARE_DENYWRITE ) ); if( refList.is() ) { refList->SetSize( 0 ); refList->SetBufferSize( 8192 ); - refList->SetProperty( "MediaType", Any(OUString( "text/xml" )) ); + refList->SetProperty( u"MediaType"_ustr, Any(u"text/xml"_ustr) ); uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); @@ -2662,7 +2792,7 @@ bool SvxAutoCorrectLanguageLists::MakeCombinedChanges( std::vector<SvxAutocorrWo GetAutocorrWordList(); MakeUserStorage_Impl(); - tools::SvRef<SotStorage> xStorage = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStorage = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); bool bRet = xStorage.is() && ERRCODE_NONE == xStorage->GetError(); @@ -2731,7 +2861,7 @@ bool SvxAutoCorrectLanguageLists::PutText( const OUString& rShort, const OUStrin GetAutocorrWordList(); MakeUserStorage_Impl(); - tools::SvRef<SotStorage> xStg = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStg = new SotStorage(sUserAutoCorrFile, StreamMode::READWRITE); bool bRet = xStg.is() && ERRCODE_NONE == xStg->GetError(); @@ -2789,7 +2919,7 @@ void SvxAutoCorrectLanguageLists::PutText( const OUString& rShort, { if( pAutocorr_List->Insert( SvxAutocorrWord(rShort, sLong, false) ) ) { - tools::SvRef<SotStorage> xStor = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); + rtl::Reference<SotStorage> xStor = new SotStorage( sUserAutoCorrFile, StreamMode::READWRITE ); MakeBlocklist_Imp( *xStor ); } } @@ -2929,7 +3059,7 @@ const SvxAutocorrWordList::AutocorrWordSetType& SvxAutocorrWordList::getSortedCo } const SvxAutocorrWord* SvxAutocorrWordList::WordMatches(const SvxAutocorrWord *pFnd, - const OUString &rTxt, + std::u16string_view rTxt, sal_Int32 &rStt, sal_Int32 nEndPos) const { @@ -2937,119 +3067,119 @@ const SvxAutocorrWord* SvxAutocorrWordList::WordMatches(const SvxAutocorrWord *p sal_Int32 left_wildcard = rChk.startsWith( ".*" ) ? 2 : 0; // ".*word" pattern? sal_Int32 right_wildcard = rChk.endsWith( ".*" ) ? 2 : 0; // "word.*" pattern? - sal_Int32 nSttWdPos = nEndPos; + assert(nEndPos >= 0); + size_t nSttWdPos = nEndPos; // direct replacement of keywords surrounded by colons (for example, ":name:") - bool bColonNameColon = rTxt.getLength() > nEndPos && + bool bColonNameColon = static_cast<sal_Int32>(rTxt.size()) > nEndPos && rTxt[nEndPos] == ':' && rChk[0] == ':' && rChk.endsWith(":"); - if ( nEndPos + (bColonNameColon ? 1 : 0) >= rChk.getLength() - left_wildcard - right_wildcard ) - { + if ( nEndPos + (bColonNameColon ? 1 : 0) < rChk.getLength() - left_wildcard - right_wildcard ) + return nullptr; - bool bWasWordDelim = false; - sal_Int32 nCalcStt = nEndPos - rChk.getLength() + left_wildcard; - if (bColonNameColon) - nCalcStt++; - if( !right_wildcard && ( !nCalcStt || nCalcStt == rStt || left_wildcard || bColonNameColon || - ( nCalcStt < rStt && - IsWordDelim( rTxt[ nCalcStt - 1 ] ))) ) + bool bWasWordDelim = false; + sal_Int32 nCalcStt = nEndPos - rChk.getLength() + left_wildcard; + if (bColonNameColon) + nCalcStt++; + if( !right_wildcard && ( !nCalcStt || nCalcStt == rStt || left_wildcard || bColonNameColon || + ( nCalcStt < rStt && + IsWordDelim( rTxt[ nCalcStt - 1 ] ))) ) + { + TransliterationWrapper& rCmp = GetIgnoreTranslWrapper(); + OUString sWord( rTxt.substr(nCalcStt, rChk.getLength() - left_wildcard) ); + if( (!left_wildcard && rCmp.isEqual( rChk, sWord )) || (left_wildcard && rCmp.isEqual( rChk.copy(left_wildcard), sWord) )) { - TransliterationWrapper& rCmp = GetIgnoreTranslWrapper(); - OUString sWord = rTxt.copy(nCalcStt, rChk.getLength() - left_wildcard); - if( (!left_wildcard && rCmp.isEqual( rChk, sWord )) || (left_wildcard && rCmp.isEqual( rChk.copy(left_wildcard), sWord) )) + rStt = nCalcStt; + if (!left_wildcard) { - rStt = nCalcStt; - if (!left_wildcard) - { - // fdo#33899 avoid "1/2", "1/3".. to be replaced by fractions in dates, eg. 1/2/14 - if (rTxt.getLength() > nEndPos && rTxt[nEndPos] == '/' && rChk.indexOf('/') != -1) - return nullptr; - return pFnd; - } - // get the first word delimiter position before the matching ".*word" pattern - while( rStt && !(bWasWordDelim = IsWordDelim( rTxt[ --rStt ]))) - ; - if (bWasWordDelim) rStt++; - OUString left_pattern = rTxt.copy(rStt, nEndPos - rStt - rChk.getLength() + left_wildcard); - // avoid double spaces before simple "word" replacement - left_pattern += (left_pattern.getLength() == 0 && pFnd->GetLong()[0] == 0x20) ? pFnd->GetLong().copy(1) : pFnd->GetLong(); - if( const SvxAutocorrWord* pNew = Insert( SvxAutocorrWord(rTxt.copy(rStt, nEndPos - rStt), left_pattern) ) ) - return pNew; + // fdo#33899 avoid "1/2", "1/3".. to be replaced by fractions in dates, eg. 1/2/14 + if (static_cast<sal_Int32>(rTxt.size()) > nEndPos && rTxt[nEndPos] == '/' && rChk.indexOf('/') != -1) + return nullptr; + return pFnd; } - } else - // match "word.*" or ".*word.*" patterns, eg. "i18n.*", ".*---.*", TODO: add transliteration support - if ( right_wildcard ) - { + // get the first word delimiter position before the matching ".*word" pattern + while( rStt && !(bWasWordDelim = IsWordDelim( rTxt[ --rStt ]))) + ; + if (bWasWordDelim) rStt++; + OUString left_pattern( rTxt.substr(rStt, nEndPos - rStt - rChk.getLength() + left_wildcard) ); + // avoid double spaces before simple "word" replacement + left_pattern += (left_pattern.getLength() == 0 && pFnd->GetLong()[0] == 0x20) ? pFnd->GetLong().subView(1) : pFnd->GetLong(); + if( const SvxAutocorrWord* pNew = Insert( SvxAutocorrWord(OUString(rTxt.substr(rStt, nEndPos - rStt)), left_pattern) ) ) + return pNew; + } + } else + // match "word.*" or ".*word.*" patterns, eg. "i18n.*", ".*---.*", TODO: add transliteration support + if ( right_wildcard ) + { - OUString sTmp( rChk.copy( left_wildcard, rChk.getLength() - left_wildcard - right_wildcard ) ); - // Get the last word delimiter position - bool not_suffix; + OUString sTmp( rChk.copy( left_wildcard, rChk.getLength() - left_wildcard - right_wildcard ) ); + // Get the last word delimiter position + bool not_suffix; - while( nSttWdPos && !(bWasWordDelim = IsWordDelim( rTxt[ --nSttWdPos ]))) - ; - // search the first occurrence (with a left word delimitation, if needed) - sal_Int32 nFndPos = -1; - do { - nFndPos = rTxt.indexOf( sTmp, nFndPos + 1); - if (nFndPos == -1) - break; - not_suffix = bWasWordDelim && (nSttWdPos >= (nFndPos + sTmp.getLength())); - } while ( (!left_wildcard && nFndPos && !IsWordDelim( rTxt[ nFndPos - 1 ])) || not_suffix ); + while( nSttWdPos && !(bWasWordDelim = IsWordDelim( rTxt[ --nSttWdPos ]))) + ; + // search the first occurrence (with a left word delimitation, if needed) + size_t nFndPos = std::u16string_view::npos; + do { + nFndPos = rTxt.find( sTmp, nFndPos + 1); + if (nFndPos == std::u16string_view::npos) + break; + not_suffix = bWasWordDelim && (nSttWdPos >= (nFndPos + sTmp.getLength())); + } while ( (!left_wildcard && nFndPos && !IsWordDelim( rTxt[ nFndPos - 1 ])) || not_suffix ); - if ( nFndPos != -1 ) - { - sal_Int32 extra_repl = nFndPos + sTmp.getLength() > nEndPos ? 1: 0; // for patterns with terminating characters, eg. "a:" + if ( nFndPos != std::u16string_view::npos ) + { + sal_Int32 extra_repl = static_cast<sal_Int32>(nFndPos) + sTmp.getLength() > nEndPos ? 1: 0; // for patterns with terminating characters, eg. "a:" - if ( left_wildcard ) - { - // get the first word delimiter position before the matching ".*word.*" pattern - while( nFndPos && !(bWasWordDelim = IsWordDelim( rTxt[ --nFndPos ]))) - ; - if (bWasWordDelim) nFndPos++; - } - if (nEndPos + extra_repl <= nFndPos) - { - return nullptr; - } - // store matching pattern and its replacement as a new list item, eg. "i18ns" -> "internationalizations" - OUString aShort = rTxt.copy(nFndPos, nEndPos - nFndPos + extra_repl); + if ( left_wildcard ) + { + // get the first word delimiter position before the matching ".*word.*" pattern + while( nFndPos && !(bWasWordDelim = IsWordDelim( rTxt[ --nFndPos ]))) + ; + if (bWasWordDelim) nFndPos++; + } + if (nEndPos + extra_repl <= static_cast<sal_Int32>(nFndPos)) + { + return nullptr; + } + // store matching pattern and its replacement as a new list item, eg. "i18ns" -> "internationalizations" + OUString aShort( rTxt.substr(nFndPos, nEndPos - nFndPos + extra_repl) ); - OUString aLong; - rStt = nFndPos; - if ( !left_wildcard ) - { - sal_Int32 siz = nEndPos - nFndPos - sTmp.getLength(); - aLong = pFnd->GetLong() + (siz > 0 ? rTxt.copy(nFndPos + sTmp.getLength(), siz) : ""); - } else { - OUStringBuffer buf; - do { - nSttWdPos = rTxt.indexOf( sTmp, nFndPos); - if (nSttWdPos != -1) - { - sal_Int32 nTmp(nFndPos); - while (nTmp < nSttWdPos && !IsWordDelim(rTxt[nTmp])) - nTmp++; - if (nTmp < nSttWdPos) - break; // word delimiter found - buf.append(rTxt.subView(nFndPos, nSttWdPos - nFndPos)).append(pFnd->GetLong()); - nFndPos = nSttWdPos + sTmp.getLength(); - } - } while (nSttWdPos != -1); - if (nEndPos - nFndPos > extra_repl) - buf.append(rTxt.subView(nFndPos, nEndPos - nFndPos)); - aLong = buf.makeStringAndClear(); - } - if ( const SvxAutocorrWord* pNew = Insert( SvxAutocorrWord(aShort, aLong) ) ) - { - if ( (rTxt.getLength() > nEndPos && IsWordDelim(rTxt[nEndPos])) || rTxt.getLength() == nEndPos ) - return pNew; - } + OUString aLong; + rStt = nFndPos; + if ( !left_wildcard ) + { + sal_Int32 siz = nEndPos - nFndPos - sTmp.getLength(); + aLong = pFnd->GetLong() + (siz > 0 ? rTxt.substr(nFndPos + sTmp.getLength(), siz) : u""); + } else { + OUStringBuffer buf; + do { + nSttWdPos = rTxt.find( sTmp, nFndPos); + if (nSttWdPos != std::u16string_view::npos) + { + sal_Int32 nTmp(nFndPos); + while (nTmp < static_cast<sal_Int32>(nSttWdPos) && !IsWordDelim(rTxt[nTmp])) + nTmp++; + if (nTmp < static_cast<sal_Int32>(nSttWdPos)) + break; // word delimiter found + buf.append(rTxt.substr(nFndPos, nSttWdPos - nFndPos)).append(pFnd->GetLong()); + nFndPos = nSttWdPos + sTmp.getLength(); + } + } while (nSttWdPos != std::u16string_view::npos); + if (static_cast<sal_Int32>(nEndPos - nFndPos) > extra_repl) + buf.append(rTxt.substr(nFndPos, nEndPos - nFndPos)); + aLong = buf.makeStringAndClear(); + } + if ( const SvxAutocorrWord* pNew = Insert( SvxAutocorrWord(aShort, aLong) ) ) + { + if ( (static_cast<sal_Int32>(rTxt.size()) > nEndPos && IsWordDelim(rTxt[nEndPos])) || static_cast<sal_Int32>(rTxt.size()) == nEndPos ) + return pNew; } } } return nullptr; } -const SvxAutocorrWord* SvxAutocorrWordList::SearchWordsInList(const OUString& rTxt, sal_Int32& rStt, +const SvxAutocorrWord* SvxAutocorrWordList::SearchWordsInList(std::u16string_view rTxt, sal_Int32& rStt, sal_Int32 nEndPos) const { for (auto const& elem : mpImpl->maHash) diff --git a/editeng/source/misc/swafopt.cxx b/editeng/source/misc/swafopt.cxx index 126a54bb1f90..f37af302d144 100644 --- a/editeng/source/misc/swafopt.cxx +++ b/editeng/source/misc/swafopt.cxx @@ -22,12 +22,11 @@ #include <vcl/keycodes.hxx> SvxSwAutoFormatFlags::SvxSwAutoFormatFlags() - : aBulletFont( "StarSymbol", Size( 0, 14 ) ) + : aBulletFont( u"OpenSymbol"_ustr, Size( 0, 14 ) ) { bAutoCorrect = bCapitalStartSentence = bCapitalStartWord = - bChgUserColl = bChgEnumNum = bAddNonBrkSpace = bChgOrdinalNumber = @@ -36,15 +35,18 @@ SvxSwAutoFormatFlags::SvxSwAutoFormatFlags() bChgToEnEmDash = bChgWeightUnderl = bSetINetAttr = + bSetDOIAttr = bAFormatDelSpacesAtSttEnd = bAFormatDelSpacesBetweenLines = bAFormatByInpDelSpacesAtSttEnd = bAFormatByInpDelSpacesBetweenLines = true; + bChgUserColl = bReplaceStyles = bDelEmptyNode = bWithRedlining = bAutoCmpltEndless = + bSetNumRuleAfterSpace = bAutoCmpltAppendBlank = false; bAutoCmpltShowAsTip = diff --git a/editeng/source/misc/txtrange.cxx b/editeng/source/misc/txtrange.cxx index 6374747be3c9..2f02a1150f91 100644 --- a/editeng/source/misc/txtrange.cxx +++ b/editeng/source/misc/txtrange.cxx @@ -192,11 +192,12 @@ tools::Long SvxBoundArgs::CalcMax( const Point& rPt1, const Point& rPt2, } else nB = nStart; - nB *= nB; - nB += nDa * nDa; - nB = sqrt( nB ); + + nB = std::hypot(nB, nDa); + if (nB == 0) // avoid div / 0 return 0; + nB = nRange + nDa * ( nFarRange - nRange ) / nB; bool bNote; diff --git a/editeng/source/misc/unolingu.cxx b/editeng/source/misc/unolingu.cxx index c5f37e74cbb4..4cf67b9e2f20 100644 --- a/editeng/source/misc/unolingu.cxx +++ b/editeng/source/misc/unolingu.cxx @@ -29,10 +29,12 @@ #include <com/sun/star/linguistic2/LinguProperties.hpp> #include <com/sun/star/linguistic2/XSpellChecker1.hpp> +#include <comphelper/lok.hxx> #include <comphelper/processfactory.hxx> #include <cppuhelper/implbase.hxx> #include <i18nlangtag/languagetag.hxx> #include <unotools/lingucfg.hxx> +#include <utility> #include <vcl/svapp.hxx> #include <vcl/weld.hxx> #include <linguistic/misc.hxx> @@ -46,7 +48,6 @@ using namespace ::comphelper; using namespace ::linguistic; using namespace ::com::sun::star; -using namespace ::com::sun::star::util; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; @@ -101,7 +102,7 @@ void ThesDummy_Impl::GetCfgLocales() return; SvtLinguConfig aCfg; - Sequence < OUString > aNodeNames( aCfg.GetNodeNames( "ServiceManager/ThesaurusList" ) ); + Sequence < OUString > aNodeNames( aCfg.GetNodeNames( u"ServiceManager/ThesaurusList"_ustr ) ); const OUString *pNodeNames = aNodeNames.getConstArray(); sal_Int32 nLen = aNodeNames.getLength(); pLocaleSeq.reset( new Sequence< lang::Locale >( nLen ) ); @@ -594,7 +595,10 @@ uno::Reference< XDictionary > LinguMgr::GetIgnoreAll() uno::Reference< XSearchableDictionaryList > xTmpDicList( GetDictionaryList() ); if (xTmpDicList.is()) { - std::locale loc(Translate::Create("svt")); + const LanguageTag tag = comphelper::LibreOfficeKit::isActive() + ? LanguageTag(u"en-US"_ustr) + : SvtSysLocale().GetUILanguageTag(); + std::locale loc(Translate::Create("svt", tag)); xIgnoreAll = xTmpDicList->getDictionaryByName( Translate::get(STR_DESCRIPTION_IGNOREALLLIST, loc) ); } @@ -613,7 +617,7 @@ uno::Reference< XDictionary > LinguMgr::GetChangeAll() if (_xDicList.is()) { xChangeAll = _xDicList->createDictionary( - "ChangeAllList", + u"ChangeAllList"_ustr, LanguageTag::convertToLocale( LANGUAGE_NONE ), DictionaryType_NEGATIVE, OUString() ); } @@ -632,7 +636,7 @@ uno::Reference< XDictionary > LinguMgr::GetStandard() if (!xTmpDicList.is()) return nullptr; - static const OUStringLiteral aDicName( u"standard.dic" ); + static constexpr OUString aDicName( u"standard.dic"_ustr ); uno::Reference< XDictionary > xDic = xTmpDicList->getDictionaryByName( aDicName ); if (!xDic.is()) { @@ -709,8 +713,8 @@ SvxAlternativeSpelling SvxGetAltSpelling( } -SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XSearchableDictionaryList > const &rxDicList ) : - xDicList ( rxDicList ) +SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XSearchableDictionaryList > _xDicList ) : + xDicList (std::move( _xDicList )) { if (xDicList.is()) { diff --git a/editeng/source/misc/urlfieldhelper.cxx b/editeng/source/misc/urlfieldhelper.cxx index 564bc54e781e..16303c064d50 100644 --- a/editeng/source/misc/urlfieldhelper.cxx +++ b/editeng/source/misc/urlfieldhelper.cxx @@ -16,16 +16,17 @@ void URLFieldHelper::RemoveURLField(EditView& pEditView) { pEditView.SelectFieldAtCursor(); - const SvxFieldData* pField = pEditView.GetFieldAtCursor(); + const SvxFieldItem* pFieldItem = pEditView.GetFieldAtSelection(); + const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr; if (auto pUrlField = dynamic_cast<const SvxURLField*>(pField)) { ESelection aSel = pEditView.GetSelection(); - pEditView.GetEditEngine()->QuickInsertText(pUrlField->GetRepresentation(), aSel); + pEditView.getEditEngine().QuickInsertText(pUrlField->GetRepresentation(), aSel); pEditView.Invalidate(); } } -bool URLFieldHelper::IsCursorAtURLField(const EditView& pEditView) +bool URLFieldHelper::IsCursorAtURLField(const EditView& pEditView, bool bAlsoCheckBeforeCursor) { // tdf#128666 Make sure only URL field (or nothing) is selected ESelection aSel = pEditView.GetSelection(); @@ -37,7 +38,8 @@ bool URLFieldHelper::IsCursorAtURLField(const EditView& pEditView) if (!bIsValidSelection) return false; - const SvxFieldData* pField = pEditView.GetFieldAtCursor(); + const SvxFieldData* pField + = pEditView.GetFieldUnderMouseOrInSelectionOrAtCursor(bAlsoCheckBeforeCursor); if (dynamic_cast<const SvxURLField*>(pField)) return true; |