Resolves: tdf#73063 preserve and roundtrip LCID from/to Excel number formats

Change-Id: I8e3e5ef5873af108596b387e8900d038e3942981
Reviewed-on: https://gerrit.libreoffice.org/59441
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
diff --git a/include/svl/zformat.hxx b/include/svl/zformat.hxx
index b1f9416..88b015f 100644
--- a/include/svl/zformat.hxx
+++ b/include/svl/zformat.hxx
@@ -153,6 +153,7 @@ class SVL_DLLPUBLIC SvNumberformat
        };

        LanguageType meLanguage;
        LanguageType meLanguageWithoutLocaleData;
        Substitute meSubstitute;
        sal_uInt8 mnNumeralShape;
        sal_uInt8 mnCalendarType;
@@ -225,7 +226,8 @@ public:
    // Build a format string of application defined keywords
    OUString GetMappedFormatstring( const NfKeywordTable& rKeywords,
                                    const LocaleDataWrapper& rLoc,
                                    LanguageType nOriginalLang = LANGUAGE_DONTKNOW ) const;
                                    LanguageType nOriginalLang = LANGUAGE_DONTKNOW,
                                    bool bSystemLanguage = false ) const;

    void SetStarFormatSupport( bool b )         { bStarFlag = b; }

diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx
index f0c4b5e..0488449 100644
--- a/sc/source/filter/excel/xestyle.cxx
+++ b/sc/source/filter/excel/xestyle.cxx
@@ -44,6 +44,7 @@
#include <editeng/eeitem.hxx>
#include <editeng/escapementitem.hxx>
#include <editeng/justifyitem.hxx>
#include <editeng/langitem.hxx>
#include <document.hxx>
#include <stlpool.hxx>
#include <stlsheet.hxx>
@@ -2135,10 +2136,21 @@ void XclExpXF::Init( const SfxItemSet& rItemSet, sal_Int16 nScript,
    }

    // number format
    mnScNumFmt = (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) ?
        rItemSet.Get( ATTR_VALUE_FORMAT ).GetValue() : nForceScNumFmt;
    if (nForceScNumFmt != NUMBERFORMAT_ENTRY_NOT_FOUND)
        mnXclNumFmt = nForceScNumFmt;
    else
    {
        // Built-in formats of dedicated languages may be attributed using the
        // system language (or even other?) format with a language attribute,
        // obtain the "real" format key.
        mnScNumFmt = rItemSet.Get( ATTR_VALUE_FORMAT ).GetValue();
        LanguageType nLang = rItemSet.Get( ATTR_LANGUAGE_FORMAT).GetLanguage();
        if (mnScNumFmt >= SV_COUNTRY_LANGUAGE_OFFSET || nLang != LANGUAGE_SYSTEM)
            mnScNumFmt = GetFormatter().GetFormatForLanguageIfBuiltIn( mnScNumFmt, nLang);
    }
    mnXclNumFmt = GetNumFmtBuffer().Insert( mnScNumFmt );
    mbFmtUsed = ScfTools::CheckItem( rItemSet, ATTR_VALUE_FORMAT, IsStyleXF() );

    // alignment
    mbAlignUsed = maAlignment.FillFromItemSet( rItemSet, bForceLineBreak, GetBiff(), IsStyleXF() );

diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 9d4a630..023bc37 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -811,9 +811,13 @@ OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKe
        }
        else
        {
            bool bSystemLanguage = false;
            LanguageType nLang = pEntry->GetLanguage();
            if (nLang == LANGUAGE_SYSTEM)
            {
                bSystemLanguage = true;
                nLang = SvtSysLocale().GetLanguageTag().getLanguageType();
            }
            if (nLang != LANGUAGE_ENGLISH_US)
            {
                sal_Int32 nCheckPos;
@@ -833,7 +837,8 @@ OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKe
                // before (which doesn't do anything if it was the same locale
                // already).
                rTempFormatter.ChangeIntl( LANGUAGE_ENGLISH_US);
                aFormatStr = pEntry->GetMappedFormatstring( rKeywords, *rTempFormatter.GetLocaleData(), nLang );
                aFormatStr = pEntry->GetMappedFormatstring( rKeywords, *rTempFormatter.GetLocaleData(), nLang,
                        bSystemLanguage);
            }
        }
    }
diff --git a/svl/source/numbers/zformat.cxx b/svl/source/numbers/zformat.cxx
index 1d591f6..3d7e1c4 100644
--- a/svl/source/numbers/zformat.cxx
+++ b/svl/source/numbers/zformat.cxx
@@ -1042,6 +1042,10 @@ SvNumberformat::SvNumberformat(OUString& rString,
                            }
                            else
                            {
                                if (nIndex == 0)
                                    // Locale data not available, remember.
                                    maLocale.meLanguageWithoutLocaleData = aTmpLocale.meLanguage;

                                sStr = "$-" + aTmpLocale.generateCode();
                            }
                            NumFor[nIndex].SetNatNumLang( MsLangId::getRealLanguage( aTmpLocale.meLanguage));
@@ -1497,7 +1501,9 @@ OUString SvNumberformat::LocaleType::generateCode() const
    }
#endif

    sal_uInt16 n16 = static_cast<sal_uInt16>(meLanguage);
    sal_uInt16 n16 = static_cast<sal_uInt16>(
            (meLanguageWithoutLocaleData == LANGUAGE_DONTKNOW) ? meLanguage :
            meLanguageWithoutLocaleData);
    if (meLanguage == LANGUAGE_SYSTEM)
    {
        switch (meSubstitute)
@@ -1529,6 +1535,7 @@ OUString SvNumberformat::LocaleType::generateCode() const

SvNumberformat::LocaleType::LocaleType()
    : meLanguage(LANGUAGE_DONTKNOW)
    , meLanguageWithoutLocaleData(LANGUAGE_DONTKNOW)
    , meSubstitute(Substitute::NONE)
    , mnNumeralShape(0)
    , mnCalendarType(0)
@@ -1537,6 +1544,7 @@ SvNumberformat::LocaleType::LocaleType()

SvNumberformat::LocaleType::LocaleType(sal_uInt32 nRawNum)
    : meLanguage(LANGUAGE_DONTKNOW)
    , meLanguageWithoutLocaleData(LANGUAGE_DONTKNOW)
    , meSubstitute(Substitute::NONE)
    , mnNumeralShape(0)
    , mnCalendarType(0)
@@ -5068,7 +5076,8 @@ void lcl_incrementAlphabetWithNatNum ( sal_uInt32& nAlphabetID, sal_uInt32 nNatN

OUString SvNumberformat::GetMappedFormatstring( const NfKeywordTable& rKeywords,
                                                const LocaleDataWrapper& rLocWrp,
                                                LanguageType nOriginalLang /* =LANGUAGE_DONTKNOW */ ) const
                                                LanguageType nOriginalLang /* =LANGUAGE_DONTKNOW */,
                                                bool bSystemLanguage /* =false */ ) const
{
    OUStringBuffer aStr;
    if (maLocale.meSubstitute != LocaleType::Substitute::NONE)
@@ -5385,6 +5394,20 @@ OUString SvNumberformat::GetMappedFormatstring( const NfKeywordTable& rKeywords,
            if ( aNatNum.GetDBNum() > 0 && nLanguageID == LANGUAGE_SYSTEM )
                nLanguageID = MsLangId::getRealLanguage( aNatNum.GetLang());
        }
        else if (!bSystemLanguage && nOriginalLang != LANGUAGE_DONTKNOW)
        {
            // Explicit locale, write only to the first subformat.
            if (n == 0)
                nLanguageID = MsLangId::getRealLanguage( nOriginalLang);
        }
        else if (bSystemLanguage && maLocale.meLanguageWithoutLocaleData != LANGUAGE_DONTKNOW)
        {
            // Explicit locale but no locale data thus assigned to system
            // locale, preserve for roundtrip, write only to the first
            // subformat.
            if (n == 0)
                nLanguageID = maLocale.meLanguageWithoutLocaleData;
        }
        if ( nCalendarID > 0 )
        {   // Add alphabet and language to calendar
            if ( nAlphabetID == 0 )