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 <erack@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 <erack@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 <erack@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 <erack@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 <caolanm@redhat.com>
diff --git a/sc/inc/addincol.hxx b/sc/inc/addincol.hxx
index 9366e31..14af120 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 addb151..ea21842 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 86499cc..d7b6286 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 9ad63bc..9c9fc97 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 3ca23c5..92492b2 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 3961603..f4e9e53 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 ee362a3..6c6ad7d 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