sc/inc/addincol.hxx | 5 ++ sc/source/core/tool/addincol.cxx | 65 +++++++++++++++++++++++++++------- sc/source/core/tool/compiler.cxx | 6 ++- scaddins/source/analysis/analysis.cxx | 2 - scaddins/source/datefunc/datefunc.cxx | 2 - scaddins/source/pricing/pricing.cxx | 6 +-- scaddins/source/pricing/pricing.hxx | 4 +- 7 files changed, 68 insertions(+), 22 deletions(-)
New commits: commit 7231a2362cce8f036586c744c775d9555086de5f Author: Eike Rathke <er...@redhat.com> AuthorDate: Wed Aug 3 00:11:32 2022 +0200 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Sat Aug 13 13:27:35 2022 +0200 Resolves: tdf#150203 Gather AddIn English names and provide for FunctionAccess This is a combination of 4 commits. Use nNumOfLoc instead of sizeof(pLang) ... which is count*sizeof(char*), but luckily this private function was never used with out-of-bounds values. xChange-Id: Ief3b3de614ca0df00c424f7caabf70e029ea7266 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137703 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins (cherry picked from commit dac843c4dc0407430d5a7441fd80940a99a4d8f8) Related: tdf#150203 Pricing, there is only one compatibility name, en-US ... but that was associated with de-DE instead. xChange-Id: I9024666b5d33bbabbdb514075fe0598d072dacd5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137706 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins (cherry picked from commit 8690d8878248320b0b706e9d6f7b8fa89ed903c4) Resolves: tdf#150203 Gather AddIn English names and provide for FunctionAccess This works at least for the bundled AddIns from scaddins/. It may for others if en-US compatibility function names are provided, if not the local name will be continued to be used. xChange-Id: I09e23f731c0f3d9753ef355ab59c2005bc567464 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137708 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins (cherry picked from commit 8dc76b13458fac1a30787f8bbab117a4a9508ab5) Avoid multiple conversions to LanguageTag, specifically in loops xChange-Id: I47a969d7476df32e0c9d525d416467c59358d9ce Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137712 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins (cherry picked from commit 86b2bfd34a4f07c54f03c8c8dfe48e0810834628) Change-Id: I09e23f731c0f3d9753ef355ab59c2005bc567464 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137713 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/sc/inc/addincol.hxx b/sc/inc/addincol.hxx index 9366e31b68ff..14af12006637 100644 --- a/sc/inc/addincol.hxx +++ b/sc/inc/addincol.hxx @@ -42,6 +42,7 @@ namespace com::sun::star::uno { class XInterface; } class SfxObjectShell; class ScUnoAddInFuncData; class ScFuncDesc; +class LanguageTag; typedef std::unordered_map< OUString, const ScUnoAddInFuncData* > ScAddInHashMap; @@ -123,7 +124,8 @@ public: const OString& GetHelpId() const { return sHelpId; } const ::std::vector< LocalizedName >& GetCompNames() const; - bool GetExcelName( LanguageType eDestLang, OUString& rRetExcelName ) const; + bool GetExcelName( const LanguageTag& rDestLang, OUString& rRetExcelName, + bool bFallbackToAny = true ) const; void SetFunction( const css::uno::Reference< css::reflection::XIdlMethod>& rNewFunc, const css::uno::Any& rNewObj ); @@ -140,6 +142,7 @@ private: std::unique_ptr<ScAddInHashMap> pExactHashMap; ///< exact internal name std::unique_ptr<ScAddInHashMap> pNameHashMap; ///< internal name upper std::unique_ptr<ScAddInHashMap> pLocalHashMap; ///< localized name upper + std::unique_ptr<ScAddInHashMap> pEnglishHashMap; ///< English name upper bool bInitialized; void Initialize(); diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx index addb1512806f..ea2184233f62 100644 --- a/sc/source/core/tool/addincol.cxx +++ b/sc/source/core/tool/addincol.cxx @@ -138,13 +138,12 @@ void ScUnoAddInFuncData::SetCompNames( ::std::vector< ScUnoAddInFuncData::Locali bCompInitialized = true; } -bool ScUnoAddInFuncData::GetExcelName( LanguageType eDestLang, OUString& rRetExcelName ) const +bool ScUnoAddInFuncData::GetExcelName( const LanguageTag& rDestLang, OUString& rRetExcelName, bool bFallbackToAny ) const { const ::std::vector<LocalizedName>& rCompNames = GetCompNames(); if ( !rCompNames.empty() ) { - LanguageTag aLanguageTag( eDestLang); - const OUString& aSearch( aLanguageTag.getBcp47()); + const OUString& aSearch( rDestLang.getBcp47()); // First, check exact match without fallback overhead. ::std::vector<LocalizedName>::const_iterator itNames = std::find_if(rCompNames.begin(), rCompNames.end(), @@ -157,7 +156,7 @@ bool ScUnoAddInFuncData::GetExcelName( LanguageType eDestLang, OUString& rRetExc // Second, try match of fallback search with fallback locales, // appending also 'en-US' and 'en' to search if not queried. - ::std::vector< OUString > aFallbackSearch( aLanguageTag.getFallbackStrings( true)); + ::std::vector< OUString > aFallbackSearch( rDestLang.getFallbackStrings( true)); if (aSearch != "en-US") { aFallbackSearch.emplace_back("en-US"); @@ -180,9 +179,12 @@ bool ScUnoAddInFuncData::GetExcelName( LanguageType eDestLang, OUString& rRetExc } } - // Third, last resort, use first (default) entry. - rRetExcelName = rCompNames[0].maName; - return true; + if (bFallbackToAny) + { + // Third, last resort, use first (default) entry. + rRetExcelName = rCompNames[0].maName; + return true; + } } return false; } @@ -226,6 +228,7 @@ void ScUnoAddInCollection::Clear() pExactHashMap.reset(); pNameHashMap.reset(); pLocalHashMap.reset(); + pEnglishHashMap.reset(); ppFuncData.reset(); nFuncCount = 0; @@ -380,6 +383,8 @@ void ScUnoAddInCollection::ReadConfiguration() pNameHashMap.reset( new ScAddInHashMap ); if ( !pLocalHashMap ) pLocalHashMap.reset( new ScAddInHashMap ); + if ( !pEnglishHashMap ) + pEnglishHashMap.reset( new ScAddInHashMap ); //TODO: get the function information in a single call for all functions? @@ -395,6 +400,7 @@ void ScUnoAddInCollection::ReadConfiguration() if ( pExactHashMap->find( aFuncName ) == pExactHashMap->end() ) { + OUString aEnglishName; OUString aLocalName; OUString aDescription; sal_uInt16 nCategory = ID_FUNCTION_GRP_ADDINS; @@ -441,6 +447,11 @@ void ScUnoAddInCollection::ReadConfiguration() OUString aName; rConfig.Value >>= aName; aCompNames.emplace_back( aLocale, aName); + // Accept 'en' and 'en-...' but prefer 'en-US'. + if (aLocale == "en-US") + aEnglishName = aName; + else if (aEnglishName.isEmpty() && (aLocale == "en" || aLocale.startsWith("en-"))) + aEnglishName = aName; } } } @@ -527,6 +538,15 @@ void ScUnoAddInCollection::ReadConfiguration() pLocalHashMap->emplace( pData->GetUpperLocal(), pData ); + + if (aEnglishName.isEmpty()) + SAL_WARN("sc.core", "no English name for " << aLocalName << " " << aFuncName); + else + { + pEnglishHashMap->emplace( + aEnglishName.toAsciiUpperCase(), + pData ); + } } } } @@ -561,7 +581,7 @@ bool ScUnoAddInCollection::GetExcelName( const OUString& rCalcName, { const ScUnoAddInFuncData* pFuncData = GetFuncData( rCalcName ); if ( pFuncData ) - return pFuncData->GetExcelName( eDestLang, rRetExcelName); + return pFuncData->GetExcelName( LanguageTag( eDestLang), rRetExcelName); return false; } @@ -746,7 +766,10 @@ void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& pNameHashMap.reset( new ScAddInHashMap ); if ( !pLocalHashMap ) pLocalHashMap.reset( new ScAddInHashMap ); + if ( !pEnglishHashMap ) + pEnglishHashMap.reset( new ScAddInHashMap ); + const LanguageTag aEnglishLanguageTag(LANGUAGE_ENGLISH_US); const uno::Reference<reflection::XIdlMethod>* pArray = aMethods.getConstArray(); for (tools::Long nFuncPos=0; nFuncPos<nNewCount; nFuncPos++) { @@ -907,6 +930,16 @@ void ScUnoAddInCollection::ReadFromAddIn( const uno::Reference<uno::XInterface>& pLocalHashMap->emplace( pData->GetUpperLocal(), pData ); + + OUString aEnglishName; + if (!pData->GetExcelName( aEnglishLanguageTag, aEnglishName, false /*bFallbackToAny*/)) + SAL_WARN("sc.core", "no English name for " << aLocalName << " " << aFuncName); + else + { + pEnglishHashMap->emplace( + aEnglishName.toAsciiUpperCase(), + pData ); + } } } } @@ -1076,7 +1109,7 @@ OUString ScUnoAddInCollection::FindFunction( const OUString& rUpperName, bool bL if ( bLocalFirst ) { - // first scan all local names (used for entering formulas) + // Only scan local names (used for entering formulas). ScAddInHashMap::const_iterator iLook( pLocalHashMap->find( rUpperName ) ); if ( iLook != pLocalHashMap->end() ) @@ -1084,14 +1117,22 @@ OUString ScUnoAddInCollection::FindFunction( const OUString& rUpperName, bool bL } else { - // first scan international names (used when calling a function) - //TODO: before that, check for exact match??? + // First scan international programmatic names (used when calling a + // function). ScAddInHashMap::const_iterator iLook( pNameHashMap->find( rUpperName ) ); if ( iLook != pNameHashMap->end() ) return iLook->second->GetOriginalName(); - // after that, scan all local names (to allow replacing old AddIns with Uno) + // Then scan English names (as FunctionAccess API could expect). + + iLook = pEnglishHashMap->find( rUpperName ); + if ( iLook != pEnglishHashMap->end() ) + return iLook->second->GetOriginalName(); + + // After that, scan all local names; either to allow replacing old + // AddIns with Uno, or for functions where the AddIn did not provide an + // English name. iLook = pLocalHashMap->find( rUpperName ); if ( iLook != pLocalHashMap->end() ) diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 86499cc209b9..d7b628615d63 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -166,6 +166,7 @@ void ScCompiler::fillFromAddInCollectionUpperName( const NonConstOpCodeMapPtr& x void ScCompiler::fillFromAddInCollectionEnglishName( const NonConstOpCodeMapPtr& xMap ) const { + const LanguageTag aEnglishLanguageTag(LANGUAGE_ENGLISH_US); ScUnoAddInCollection* pColl = ScGlobal::GetAddInCollection(); tools::Long nCount = pColl->GetFuncCount(); for (tools::Long i=0; i < nCount; ++i) @@ -174,7 +175,7 @@ void ScCompiler::fillFromAddInCollectionEnglishName( const NonConstOpCodeMapPtr& if (pFuncData) { OUString aName; - if (pFuncData->GetExcelName( LANGUAGE_ENGLISH_US, aName)) + if (pFuncData->GetExcelName( aEnglishLanguageTag, aName)) xMap->putExternalSoftly( aName, pFuncData->GetOriginalName()); else xMap->putExternalSoftly( pFuncData->GetUpperName(), @@ -5523,6 +5524,7 @@ void ScCompiler::fillAddInToken(::std::vector< css::sheet::FormulaOpCodeMapEntry sheet::FormulaOpCodeMapEntry aEntry; aEntry.Token.OpCode = ocExternal; + const LanguageTag aEnglishLanguageTag(LANGUAGE_ENGLISH_US); ScUnoAddInCollection* pColl = ScGlobal::GetAddInCollection(); const tools::Long nCount = pColl->GetFuncCount(); for (tools::Long i=0; i < nCount; ++i) @@ -5533,7 +5535,7 @@ void ScCompiler::fillAddInToken(::std::vector< css::sheet::FormulaOpCodeMapEntry if ( _bIsEnglish ) { OUString aName; - if (pFuncData->GetExcelName( LANGUAGE_ENGLISH_US, aName)) + if (pFuncData->GetExcelName( aEnglishLanguageTag, aName)) aEntry.Name = aName; else aEntry.Name = pFuncData->GetUpperName(); diff --git a/scaddins/source/analysis/analysis.cxx b/scaddins/source/analysis/analysis.cxx index 9ad63bc15efa..9c9fc9718c59 100644 --- a/scaddins/source/analysis/analysis.cxx +++ b/scaddins/source/analysis/analysis.cxx @@ -298,7 +298,7 @@ inline const lang::Locale& AnalysisAddIn::GetLocale( sal_uInt32 nInd ) if( !pDefLocales ) InitDefLocales(); - if( nInd < sizeof( pLang ) ) + if( nInd < nNumOfLoc ) return pDefLocales[ nInd ]; else return aFuncLoc; diff --git a/scaddins/source/datefunc/datefunc.cxx b/scaddins/source/datefunc/datefunc.cxx index 3ca23c5f0571..92492b29d150 100644 --- a/scaddins/source/datefunc/datefunc.cxx +++ b/scaddins/source/datefunc/datefunc.cxx @@ -120,7 +120,7 @@ const lang::Locale& ScaDateAddIn::GetLocale( sal_uInt32 nIndex ) if( !pDefLocales ) InitDefLocales(); - return (nIndex < sizeof( pLang )) ? pDefLocales[ nIndex ] : aFuncLoc; + return (nIndex < nNumOfLoc) ? pDefLocales[ nIndex ] : aFuncLoc; } void ScaDateAddIn::InitData() diff --git a/scaddins/source/pricing/pricing.cxx b/scaddins/source/pricing/pricing.cxx index 3961603bc04b..f4e9e53f44af 100644 --- a/scaddins/source/pricing/pricing.cxx +++ b/scaddins/source/pricing/pricing.cxx @@ -105,8 +105,8 @@ ScaPricingAddIn::~ScaPricingAddIn() { } -static const char* pLang[] = { "de", "en" }; -static const char* pCoun[] = { "DE", "US" }; +static const char* pLang[] = { "en" }; +static const char* pCoun[] = { "US" }; const sal_uInt32 nNumOfLoc = SAL_N_ELEMENTS( pLang ); void ScaPricingAddIn::InitDefLocales() @@ -125,7 +125,7 @@ const lang::Locale& ScaPricingAddIn::GetLocale( sal_uInt32 nIndex ) if( !pDefLocales ) InitDefLocales(); - return (nIndex < sizeof( pLang )) ? pDefLocales[ nIndex ] : aFuncLoc; + return (nIndex < nNumOfLoc) ? pDefLocales[ nIndex ] : aFuncLoc; } void ScaPricingAddIn::InitData() diff --git a/scaddins/source/pricing/pricing.hxx b/scaddins/source/pricing/pricing.hxx index ee362a3b3df3..6c6ad7d1dedb 100644 --- a/scaddins/source/pricing/pricing.hxx +++ b/scaddins/source/pricing/pricing.hxx @@ -61,8 +61,8 @@ struct ScaFuncDataBase const TranslateId* pDescrID; // resource ID to description, parameter names and ~ description // pCompName was originally meant to be able to load Excel documents that for // some time were stored with localized function names. - // This is not relevant to this add-in, so we only supply the same - // (English) function names again. + // This is not relevant to this add-in, so we only supply the + // English function name. // see also: GetExcelName() or GetCompNames() or getCompatibilityNames() const char* pCompName; sal_uInt16 nParamCount; // number of named / described parameters