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

Reply via email to