tdf#114694: Make default value in language settings the first element

For Languages, to make the default value ​​the first element in the
list, I've added 3 parameters to SvxLanguageBox::SetLanguageList().
With this parameters, function adds default value according to its
existence before other values. For sorting User Interface and
Currency, I removed the make_sorted function.  I added std::sort
with lambda expressions for both of them.

Change-Id: Iae37bfe09aaac4d8ecde1caad7a14e11df551eae
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87926
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index fb73341..d99f353 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
@@ -43,6 +43,7 @@
#include <editeng/unolingu.hxx>
#include <editeng/langitem.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <editeng/editids.hrc>
#include <svx/svxids.hrc>
@@ -1335,9 +1336,6 @@ OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogCon
    , m_xCTLSupportCB(m_xBuilder->weld_check_button("ctlsupport"))
    , m_xIgnoreLanguageChangeCB(m_xBuilder->weld_check_button("ignorelanguagechange"))
{
    m_xUserInterfaceLB->make_sorted();
    m_xCurrencyLB->make_sorted();

    // tdf#125483 save original default label
    m_sDecimalSeparatorLabel = m_xDecimalSeparatorCB->get_label();

@@ -1349,7 +1347,7 @@ OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogCon
                       SvtLanguageTable::GetLanguageString(GetInstalledLocaleForSystemUILanguage().getLanguageType());

    m_xUserInterfaceLB->append("0", aUILang);
    m_xUserInterfaceLB->set_active(0);
    m_xUserInterfaceLB->append_separator("");
    try
    {
        Reference< XMultiServiceFactory > theConfigProvider(
@@ -1364,16 +1362,32 @@ OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogCon
            theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs ), UNO_QUERY_THROW );
        seqInstalledLanguages = theNameAccess->getElementNames();
        LanguageType aLang = LANGUAGE_DONTKNOW;
        for (sal_IntPtr i=0; i<seqInstalledLanguages.getLength(); i++)
        std::vector< std::pair<sal_Int32, OUString> > aUILanguages;
        for (sal_Int32 i=0; i<seqInstalledLanguages.getLength(); i++)
        {
            aLang = LanguageTag::convertToLanguageTypeWithFallback(seqInstalledLanguages[i]);
            if (aLang != LANGUAGE_DONTKNOW)
            {
                OUString aLangStr( SvtLanguageTable::GetLanguageString( aLang ) );
                m_xUserInterfaceLB->append(OUString::number(i+1), aLangStr);
                aUILanguages.emplace_back(i+1, aLangStr);
            }
        }

        std::sort(aUILanguages.begin(), aUILanguages.end(), [](const auto& l1, const auto& l2) {
            static const auto aSorter = comphelper::string::NaturalStringSorter(
                comphelper::getProcessComponentContext(),
                Application::GetSettings().GetLanguageTag().getLocale());
            return aSorter.compare(l1.second, l2.second) < 0;
        });

        // tdf#114694: append the sorted list after the default entry and separator.
        for (const auto & [ nGroupID, sGroupName ] : aUILanguages)
        {
            m_xUserInterfaceLB->append(OUString::number(nGroupID), sGroupName);
        }

        m_xUserInterfaceLB->set_active(0);

        // find out whether the user has a specific locale specified
        Sequence< Any > theArgs2(1);
        theArgs2[0] <<= NamedValue("nodepath", Any(OUString(sUserLocalePath)));
@@ -1400,38 +1414,57 @@ OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogCon
        TOOLS_WARN_EXCEPTION("cui.options", "ignoring" );
    }

    m_xWesternLanguageLB->SetLanguageList( SvxLanguageListFlags::WESTERN | SvxLanguageListFlags::ONLY_KNOWN, true, false, true );
    m_xWesternLanguageLB->InsertDefaultLanguage( css::i18n::ScriptType::LATIN );
    m_xAsianLanguageLB->SetLanguageList( SvxLanguageListFlags::CJK     | SvxLanguageListFlags::ONLY_KNOWN, true, false, true );
    m_xAsianLanguageLB->InsertDefaultLanguage( css::i18n::ScriptType::ASIAN );
    m_xComplexLanguageLB->SetLanguageList( SvxLanguageListFlags::CTL     | SvxLanguageListFlags::ONLY_KNOWN, true, false, true );
    m_xComplexLanguageLB->InsertDefaultLanguage( css::i18n::ScriptType::COMPLEX );
    m_xWesternLanguageLB->SetLanguageList(
        SvxLanguageListFlags::WESTERN | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
        LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);

    m_xLocaleSettingLB->SetLanguageList( SvxLanguageListFlags::ALL     | SvxLanguageListFlags::ONLY_KNOWN, false, false, false );
    m_xLocaleSettingLB->InsertLanguage(LANGUAGE_USER_SYSTEM_CONFIG);
    m_xAsianLanguageLB->SetLanguageList(
        SvxLanguageListFlags::CJK | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
        LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);

    m_xComplexLanguageLB->SetLanguageList(
        SvxLanguageListFlags::CTL | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
        LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);

    m_xLocaleSettingLB->SetLanguageList(
        SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false, false, false, true,
        LANGUAGE_USER_SYSTEM_CONFIG, css::i18n::ScriptType::WEAK);

    const NfCurrencyTable& rCurrTab = SvNumberFormatter::GetTheCurrencyTable();
    const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry( LANGUAGE_SYSTEM );
    // insert SYSTEM entry
    OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
    m_xCurrencyLB->append("default", aDefaultCurr);
    m_xCurrencyLB->append_separator("");

    assert(m_xCurrencyLB->find_id("default") != -1);
    // all currencies
    OUString aTwoSpace( "  " );
    sal_uInt16 nCurrCount = rCurrTab.size();
    std::vector< const NfCurrencyEntry* > aCurrencies;
    // first entry is SYSTEM, skip it
    for ( sal_uInt16 j=1; j < nCurrCount; ++j )
    {
        const NfCurrencyEntry* pCurr = &rCurrTab[j];
        OUString aStr_ = pCurr->GetBankSymbol() +
        aCurrencies.push_back(&rCurrTab[j]);
    }
    std::sort(aCurrencies.begin(), aCurrencies.end(),
              [](const NfCurrencyEntry* c1, const NfCurrencyEntry* c2) {
                  return c1->GetBankSymbol().compareTo(c2->GetBankSymbol()) < 0;
              });

    for (auto &v : aCurrencies)
    {
        OUString aStr_ = v->GetBankSymbol() +
                         aTwoSpace +
                         pCurr->GetSymbol();
                         v->GetSymbol();
        aStr_ = ApplyLreOrRleEmbedding( aStr_ ) +
                aTwoSpace +
                ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( pCurr->GetLanguage() ) );
        m_xCurrencyLB->append(OUString::number(reinterpret_cast<sal_Int64>(pCurr)), aStr_);
                ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( v->GetLanguage() ) );
        m_xCurrencyLB->append(OUString::number(reinterpret_cast<sal_Int64>(v)), aStr_);
    }

    m_xCurrencyLB->set_active(0);

    m_xLocaleSettingLB->connect_changed( LINK( this, OfaLanguagesTabPage, LocaleSettingHdl ) );
    m_xDatePatternsED->connect_changed( LINK( this, OfaLanguagesTabPage, DatePatternsHdl ) );

@@ -1930,11 +1963,12 @@ IMPL_LINK_NOARG(OfaLanguagesTabPage, LocaleSettingHdl, weld::ComboBox&, void)

    const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry(
            (eLang == LANGUAGE_USER_SYSTEM_CONFIG) ? MsLangId::getSystemLanguage() : eLang);
    const OUString aDefaultID = "default";
    // Update the "Default ..." currency.
    m_xCurrencyLB->remove_id("default");
    m_xCurrencyLB->remove_id(aDefaultID);
    OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
    m_xCurrencyLB->append("default", aDefaultCurr);
    assert(m_xCurrencyLB->find_id("default") != -1);
    m_xCurrencyLB->insert(0, aDefaultCurr, &aDefaultID, nullptr, nullptr);
    assert(m_xCurrencyLB->find_id(aDefaultID) != -1);
    m_xCurrencyLB->set_active_text(aDefaultCurr);

    // obtain corresponding locale data
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
index f61ddc3..88ccf7d 100644
--- a/cui/source/tabpages/chardlg.cxx
+++ b/cui/source/tabpages/chardlg.cxx
@@ -321,9 +321,12 @@ SvxCharNamePage::SvxCharNamePage(weld::Container* pPage, weld::DialogController*
    m_xEastFrame->set_visible(bShowCJK);
    m_xCTLFrame->set_visible(bShowCTL);

    m_xWestFontLanguageLB->SetLanguageList(SvxLanguageListFlags::WESTERN, true, false, true);
    m_xEastFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CJK, true, false, true);
    m_xCTLFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CTL, true, false, true);
    m_xWestFontLanguageLB->SetLanguageList(SvxLanguageListFlags::WESTERN, true, false, true, true,
                                           LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
    m_xEastFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CJK, true, false, true, true,
                                           LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
    m_xCTLFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CTL, true, false, true, true,
                                          LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);

    Initialize();
}
diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx
index db22b3c..97ba2da 100644
--- a/cui/source/tabpages/numfmt.cxx
+++ b/cui/source/tabpages/numfmt.cxx
@@ -307,8 +307,9 @@ void SvxNumberFormatTabPage::Init_Impl()

    // initialize language ListBox

    m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false);
    m_xLbLanguage->InsertLanguage( LANGUAGE_SYSTEM );
    m_xLbLanguage->SetLanguageList(SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
                                   false, false, false, true, LANGUAGE_SYSTEM,
                                   css::i18n::ScriptType::WEAK);
}

std::unique_ptr<SfxTabPage> SvxNumberFormatTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
diff --git a/include/svx/langbox.hxx b/include/svx/langbox.hxx
index 583de15..188b2b1 100644
--- a/include/svx/langbox.hxx
+++ b/include/svx/langbox.hxx
@@ -77,7 +77,9 @@ public:
    SvxLanguageBox(std::unique_ptr<weld::ComboBox> pControl);
    void            SetLanguageList( SvxLanguageListFlags nLangList,
                            bool bHasLangNone, bool bLangNoneIsLangAll = false,
                            bool bCheckSpellAvail = false );
                            bool bCheckSpellAvail = false, bool bDefaultLangExist = false,
                            LanguageType eDefaultLangType = LANGUAGE_NONE,
                            sal_Int16 nDefaultType = 0 );
    void            InsertLanguage(const LanguageType nLangType);
    void            InsertDefaultLanguage(sal_Int16 nType);

diff --git a/svx/source/dialog/langbox.cxx b/svx/source/dialog/langbox.cxx
index a2aed40..ac837e9 100644
--- a/svx/source/dialog/langbox.cxx
+++ b/svx/source/dialog/langbox.cxx
@@ -34,6 +34,11 @@
#include <svx/strings.hrc>
#include <bitmaps.hlst>

#include <comphelper/string.hxx>
#include <comphelper/processfactory.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>

using namespace ::com::sun::star::util;
using namespace ::com::sun::star::linguistic2;
using namespace ::com::sun::star::uno;
@@ -185,8 +190,10 @@ void SvxLanguageBox::AddLanguages(const std::vector< LanguageType >& rLanguageTy
    }
}

void SvxLanguageBox::SetLanguageList( SvxLanguageListFlags nLangList,
        bool bHasLangNone, bool bLangNoneIsLangAll, bool bCheckSpellAvail )
void SvxLanguageBox::SetLanguageList(SvxLanguageListFlags nLangList, bool bHasLangNone,
                                     bool bLangNoneIsLangAll, bool bCheckSpellAvail,
                                     bool bDefaultLangExist, LanguageType eDefaultLangType,
                                     sal_Int16 nDefaultType)
{
    m_bHasLangNone          = bHasLangNone;
    m_bLangNoneIsLangAll    = bLangNoneIsLangAll;
@@ -278,10 +285,30 @@ void SvxLanguageBox::SetLanguageList( SvxLanguageListFlags nLangList,
        AddLanguages(aThesAvailLang, nLangList, aEntries);
    }

    std::sort(aEntries.begin(), aEntries.end(),
              [](const weld::ComboBoxEntry e1, const weld::ComboBoxEntry e2) {
                  static const auto aSorter = comphelper::string::NaturalStringSorter(
                      ::comphelper::getProcessComponentContext(),
                      Application::GetSettings().GetLanguageTag().getLocale());
                  return aSorter.compare(e1.sString, e2.sString) < 0;
              });

    int nSeparatorPosition = 0;
    if (bDefaultLangExist)
    {
        aEntries.insert(aEntries.begin(), BuildEntry(eDefaultLangType, nDefaultType));
        nSeparatorPosition++;
    }

    if (bHasLangNone)
       aEntries.push_back(BuildEntry(LANGUAGE_NONE));
    {
        aEntries.insert(aEntries.begin(), BuildEntry(LANGUAGE_NONE));
        nSeparatorPosition++;
    }

    m_xControl->insert_vector(aEntries, false);
    if (nSeparatorPosition > 0)
        m_xControl->insert_separator(nSeparatorPosition, "");
}

int SvxLanguageBox::ImplTypeToPos(LanguageType eType) const
@@ -438,7 +465,6 @@ SvxLanguageBox::SvxLanguageBox(std::unique_ptr<weld::ComboBox> pControl)
    , m_bLangNoneIsLangAll(false)
    , m_bWithCheckmark(false)
{
    m_xControl->make_sorted();
    m_xControl->connect_changed(LINK(this, SvxLanguageBox, ChangeHdl));
}