include/svx/tbcontrl.hxx         |   29 ++++++
 svx/source/tbxctrls/tbcontrl.cxx |  168 +++++++++++++++++++++++++++++----------
 2 files changed, 155 insertions(+), 42 deletions(-)

New commits:
commit dc6b93011cc5435f367666e43e354c6ab97bbc90
Author:     DrGigioSan <luigi.iu...@hotmail.it>
AuthorDate: Tue Mar 14 21:19:08 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Mar 17 12:58:37 2023 +0000

    store last five most recently used currencies in the currency toolbar 
drop-down
    
    Refactory
     Cause
       Currency must be added in the MRU list in  
SvxCurrencyToolBoxControl::execute
       method.
       Unfortunately in this point the only information available is the number 
format.
       It is not possibile to infer currency from number format  (e.g: both  
USD and
       AUD use symbol $).
     Encapsulating currency data
       In order to solve the problem currency data is enacpsulated in a 
SvxCurrencyData
       struct. Added a vector of SvxCurrencyData to SvxCurrencyToolBoxControl.
     Static and non static call
       Former static SvxCurrencyToolBoxControl::GetCurrencySymbols has been
       preserved, as it is called by SvxNumberFormatShell.
       A new GetCurrencySymbols is used by the control.
       To avoid code duplication, both functions call a static private function
       inner_GetCurrencySymbols.
    MRU Currencies
       MRU currencies are stored in another member vector m_mru_curencies:
       During currencies vector population (inner_GetCurrencySymbols) a space 
is reserved
       on top of vector for mru currencies.
       A new method addMruCurrency updates m_currencies. This method is called 
in
       SvxCurrencyToolBoxControl::execute
    
    Change-Id: I6f86179efd1839e31b089e0086b6ddbdda358f31
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148896
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/svx/tbcontrl.hxx b/include/svx/tbcontrl.hxx
index 72acf5845a4a..e40c06f3eb44 100644
--- a/include/svx/tbcontrl.hxx
+++ b/include/svx/tbcontrl.hxx
@@ -249,15 +249,44 @@ public:
 
 class UNLESS_MERGELIBS(SVXCORE_DLLPUBLIC) SvxCurrencyToolBoxControl final : 
public svt::PopupWindowController
 {
+public:
+    // struct containing currency data
+    struct SvxCurrencyData {
+        sal_uInt16 m_currencyIdx;
+        bool m_onlyIsoCode;
+        OUString m_label;
+
+        static const sal_uInt16 InvalidCurrency;
+
+        SvxCurrencyData(
+            sal_uInt16 currencyIdx = InvalidCurrency,
+            bool onlyIsoCode = false
+        );
+
+        bool operator == (const SvxCurrencyData& other) const;
+    };
+
+    typedef std::vector<SvxCurrencyData> SvxCurrencyVect_t;
+
 private:
     OUString     m_aFormatString;
     LanguageType m_eLanguage;
     sal_uInt32   m_nFormatKey;
+    SvxCurrencyVect_t  m_currencies;
+    SvxCurrencyVect_t  m_mru_currencies;
+
+    void addMruCurrency(sal_Int16 currencyPosition);
+
+    // inner static method for backward compatibility
+    static void inner_GetCurrencySymbols( bool bFlag, SvxCurrencyVect_t 
&p_mru_currencies,
+                                    SvxCurrencyVect_t &pCurrencies);
 
 public:
     static void GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
                                     std::vector<sal_uInt16>& rCurrencyList );
 
+    const SvxCurrencyVect_t& GetCurrencySymbols();
+
     explicit SvxCurrencyToolBoxControl( const 
css::uno::Reference<css::uno::XComponentContext>& rContext );
     virtual ~SvxCurrencyToolBoxControl() override;
 
diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 6303bbcd7d4c..b3a5229e6c10 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -110,6 +110,10 @@
 
 #define COMBO_WIDTH_IN_CHARS        18
 
+#define MAX_MRU_CURRENCIES          5
+
+#define INVALID_CURRENCY            sal_uInt16(-2)
+
 // namespaces
 using namespace ::editeng;
 using namespace ::com::sun::star;
@@ -3894,15 +3898,13 @@ namespace
             , m_rSelectedFormat(rSelectedFormat)
             , m_eSelectedLanguage(eSelectedLanguage)
         {
-            std::vector< OUString > aList;
-            std::vector< sal_uInt16 > aCurrencyList;
             const NfCurrencyTable& rCurrencyTable = 
SvNumberFormatter::GetTheCurrencyTable();
             sal_uInt16 nLen = rCurrencyTable.size();
 
             SvNumberFormatter aFormatter( m_xControl->getContext(), 
LANGUAGE_SYSTEM );
             m_eFormatLanguage = aFormatter.GetLanguage();
 
-            SvxCurrencyToolBoxControl::GetCurrencySymbols( aList, true, 
aCurrencyList );
+            const SvxCurrencyToolBoxControl::SvxCurrencyVect_t &rCurrencies = 
pControl->GetCurrencySymbols( );
 
             sal_uInt16 nPos = 0, nCount = 0;
             sal_Int32 nSelectedPos = -1;
@@ -3912,9 +3914,11 @@ namespace
             OUString sLongestString;
 
             m_xCurrencyLb->freeze();
-            for( const auto& rItem : aList )
+            for( const SvxCurrencyToolBoxControl::SvxCurrencyData& curr : 
rCurrencies )
             {
-                sal_uInt16& rCurrencyIndex = aCurrencyList[ nCount ];
+                const OUString& rItem = curr.m_label;
+                sal_uInt16 rCurrencyIndex = rCurrencies[ nCount 
].m_currencyIdx;
+
                 if ( rCurrencyIndex < nLen )
                 {
                     m_xCurrencyLb->append_text(rItem);
@@ -3991,6 +3995,8 @@ namespace
 
         m_xControl->execute(nSelected + 1);
 
+        m_xCurrencyLb->scroll_to_row(0);
+
         m_xControl->EndPopupMode();
 
         return true;
@@ -4014,6 +4020,26 @@ void SvxCurrencyToolBoxControl::initialize( const 
css::uno::Sequence< css::uno::
         pToolBox->SetItemBits(nId, ToolBoxItemBits::DROPDOWN | 
pToolBox->GetItemBits(nId));
 }
 
+const SvxCurrencyToolBoxControl::SvxCurrencyVect_t  
&SvxCurrencyToolBoxControl::GetCurrencySymbols( ) {
+    inner_GetCurrencySymbols( true, m_currencies, m_mru_currencies );
+    return m_currencies;
+}
+
+void SvxCurrencyToolBoxControl::addMruCurrency(sal_Int16 currencyPosition) {
+    if (currencyPosition == 1)
+        return;
+
+    const SvxCurrencyData& curr = m_currencies[currencyPosition];
+    auto currencyIter = std::find( m_mru_currencies.begin(), 
m_mru_currencies.end(), curr );
+
+    if ( currencyIter != m_mru_currencies.end() )
+        m_mru_currencies.erase( currencyIter );
+
+    m_mru_currencies.insert( m_mru_currencies.begin(), curr );
+    if (m_mru_currencies.size() > MAX_MRU_CURRENCIES)
+        m_mru_currencies.resize( MAX_MRU_CURRENCIES );
+}
+
 std::unique_ptr<WeldToolbarPopup> SvxCurrencyToolBoxControl::weldPopupWindow()
 {
     return std::make_unique<SvxCurrencyList_Impl>(this, m_pToolbar, 
m_aFormatString, m_eLanguage);
@@ -4046,11 +4072,12 @@ void SvxCurrencyToolBoxControl::execute( sal_Int16 
nSelectModifier )
                 nFormatKey = rxNumberFormats->queryKey( m_aFormatString, 
aLocale, false );
                 if ( nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND )
                     nFormatKey = rxNumberFormats->addNew( m_aFormatString, 
aLocale );
-                }
-                catch( const uno::Exception& )
-                {
-                    nFormatKey = m_nFormatKey;
-                }
+                addMruCurrency(nSelectModifier);
+            }
+            catch( const uno::Exception& )
+            {
+                nFormatKey = m_nFormatKey;
+            }
         }
         else
             nFormatKey = m_nFormatKey;
@@ -4091,78 +4118,135 @@ Reference< css::accessibility::XAccessible > 
SvxFontNameBox_Impl::CreateAccessib
     return InterimItemWindow::CreateAccessible();
 }
 
+//static
+sal_uInt16 const SvxCurrencyToolBoxControl::SvxCurrencyData::InvalidCurrency = 
INVALID_CURRENCY;
+
+SvxCurrencyToolBoxControl::SvxCurrencyData::SvxCurrencyData(
+        sal_uInt16 currencyIdx,
+        bool onlyIsoCode
+) :
+    m_currencyIdx(currencyIdx),
+    m_onlyIsoCode(onlyIsoCode)
+{}
+
+bool SvxCurrencyToolBoxControl::SvxCurrencyData::operator == (const 
SvxCurrencyData& other) const
+{
+    return
+        (m_currencyIdx == other.m_currencyIdx) &&
+        (m_onlyIsoCode == other.m_onlyIsoCode);
+}
+
 //static
 void SvxCurrencyToolBoxControl::GetCurrencySymbols( std::vector<OUString>& 
rList, bool bFlag,
                                                     std::vector<sal_uInt16>& 
rCurrencyList )
 {
-    rCurrencyList.clear();
+    SvxCurrencyVect_t currencies, mru_currencies;
+
+    inner_GetCurrencySymbols(bFlag, currencies, mru_currencies);
+
+    rList.resize(currencies.size());
+    rCurrencyList.resize(currencies.size());
+
+    for (size_t j = 0; j < currencies.size(); j++) {
+        rList[j] = std::move(currencies[j].m_label);
+        rCurrencyList[j] = currencies[j].m_currencyIdx;
+    }
+}
 
+//static
+void SvxCurrencyToolBoxControl::inner_GetCurrencySymbols(
+        bool bFlag,
+        SvxCurrencyVect_t &pCurrencies,
+        SvxCurrencyVect_t &p_mru_currencies)
+{
     const NfCurrencyTable& rCurrencyTable = 
SvNumberFormatter::GetTheCurrencyTable();
     sal_uInt16 nCount = rCurrencyTable.size();
 
-    sal_uInt16 nStart = 1;
+    // reserving space for mru currencies on top of vector after -1 element
+    pCurrencies.resize( p_mru_currencies.size() + 1);
+    std::fill( pCurrencies.begin() + 1, pCurrencies.end(), SvxCurrencyData() );
 
-    OUString aString( ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) 
+ " " );
-    aString += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
-                                       rCurrencyTable[0].GetLanguage() ) );
+    // lambda for vector insertion: mru currencies are on top
+    auto addCurrency = [&pCurrencies, &p_mru_currencies]
+                (SvxCurrencyData& curr,    size_t position = SIZE_MAX)
+    {
+        auto mruIter = std::find(p_mru_currencies.begin(), 
p_mru_currencies.end(), curr);
+
+        if (mruIter == p_mru_currencies.end()) {
+            if (position == SIZE_MAX)
+                pCurrencies.push_back( std::move(curr) );
+            else
+                pCurrencies.insert( pCurrencies.begin() + position, 
std::move(curr) );
+        }
+        else {
+            size_t index = mruIter - p_mru_currencies.begin();
+            pCurrencies[index] = std::move(curr);
+        }
+    };
 
-    rList.push_back( aString );
-    rCurrencyList.push_back( sal_uInt16(-1) ); // nAuto
+    SvxCurrencyData aCurr( sal_uInt16(-1) );
+    aCurr.m_label = ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) + 
" ";
+    aCurr.m_label  += ApplyLreOrRleEmbedding( 
SvtLanguageTable::GetLanguageString(
+                                       rCurrencyTable[0].GetLanguage() ) );
 
-    if( bFlag )
-    {
-        rList.push_back( aString );
-        rCurrencyList.push_back( 0 );
-        ++nStart;
+    pCurrencies[0] = aCurr;
+    if( bFlag ) {
+        aCurr.m_currencyIdx = 0;
+        addCurrency( aCurr );
     }
 
+    sal_uInt16 nStart = pCurrencies.size();
+
     CollatorWrapper aCollator( ::comphelper::getProcessComponentContext() );
     aCollator.loadDefaultCollator( 
Application::GetSettings().GetLanguageTag().getLocale(), 0 );
 
     static const OUStringLiteral aTwoSpace(u"  ");
 
+    // appending "long symbol" list
     for( sal_uInt16 i = 1; i < nCount; ++i )
     {
-        OUString aStr( ApplyLreOrRleEmbedding( 
rCurrencyTable[i].GetBankSymbol() ) );
-        aStr += aTwoSpace;
-        aStr += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() );
-        aStr += aTwoSpace;
-        aStr += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
+        SvxCurrencyData curr( i );
+        curr.m_label = ApplyLreOrRleEmbedding( 
rCurrencyTable[i].GetBankSymbol() );
+        curr.m_label += aTwoSpace;
+        curr.m_label += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() 
);
+        curr.m_label += aTwoSpace;
+        curr.m_label += ApplyLreOrRleEmbedding( 
SvtLanguageTable::GetLanguageString(
                                         rCurrencyTable[i].GetLanguage() ) );
 
-        std::vector<OUString>::size_type j = nStart;
-        for( ; j < rList.size(); ++j )
-            if ( aCollator.compareString( aStr, rList[j] ) < 0 )
+        SvxCurrencyVect_t::size_type j = nStart;
+        for( ; j < pCurrencies.size(); ++j )
+            if ( aCollator.compareString( curr.m_label, pCurrencies[j].m_label 
) < 0 )
                 break;  // insert before first greater than
 
-        rList.insert( rList.begin() + j, aStr );
-        rCurrencyList.insert( rCurrencyList.begin() + j, i );
+        addCurrency( curr, j );
     }
 
     // Append ISO codes to symbol list.
     // XXX If this is to be changed, various other places would had to be
     // adapted that assume this order!
-    std::vector<OUString>::size_type nCont = rList.size();
+    size_t nCont = pCurrencies.size();
 
     for ( sal_uInt16 i = 1; i < nCount; ++i )
     {
         bool bInsert = true;
-        OUString aStr( ApplyLreOrRleEmbedding( 
rCurrencyTable[i].GetBankSymbol() ) );
+        SvxCurrencyData curr( i, true );
+        curr.m_label = 
ApplyLreOrRleEmbedding(rCurrencyTable[i].GetBankSymbol());
 
-        std::vector<OUString>::size_type j = nCont;
-        for ( ; j < rList.size() && bInsert; ++j )
+        size_t j = nCont;
+        for ( ; j < pCurrencies.size() && bInsert; ++j )
         {
-            if( rList[j] == aStr )
+            if( pCurrencies[j].m_label == curr.m_label )
                 bInsert = false;
-            else if ( aCollator.compareString( aStr, rList[j] ) < 0 )
+            else if ( aCollator.compareString( curr.m_label, 
pCurrencies[j].m_label ) < 0 )
                 break;  // insert before first greater than
         }
         if ( bInsert )
-        {
-            rList.insert( rList.begin() + j, aStr );
-            rCurrencyList.insert( rCurrencyList.begin() + j, i );
-        }
+            addCurrency( curr, j );
     }
+
+    for ( int j = p_mru_currencies.size() - 1; j > 0; j-- )
+        if ( pCurrencies[j].m_currencyIdx == SvxCurrencyData::InvalidCurrency )
+            pCurrencies.erase( pCurrencies.begin() + j );
 }
 
 ListBoxColorWrapper::ListBoxColorWrapper(ColorListBox* pControl)

Reply via email to