include/sfx2/IDocumentModelAccessor.hxx    |   42 +++++++++++++++++++
 include/sfx2/objsh.hxx                     |    8 ++-
 include/svx/tbcontrl.hxx                   |    9 +---
 sc/qa/unit/ucalc.cxx                       |   41 ++++++++++++++++++
 sc/source/ui/docshell/docsh.cxx            |    8 +++
 sc/source/ui/inc/DocumentModelAccessor.hxx |   63 +++++++++++++++++++++++++++++
 sc/source/ui/inc/docsh.hxx                 |    1 
 sfx2/source/doc/objcont.cxx                |    6 ++
 svx/source/items/numfmtsh.cxx              |    5 +-
 svx/source/tbxctrls/tbcontrl.cxx           |   59 +++++++++++++++++++++------
 10 files changed, 220 insertions(+), 22 deletions(-)

New commits:
commit 79da840fac78f11c156801c43d8b79d6d4f32869
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Jan 27 00:33:56 2024 +0900
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Jan 30 10:38:00 2024 +0100

    sc: put used currencies on top of the currency pop-up list
    
    The list of currencies is fairly long and there is no easy way
    to search the list, so to make it easier to concurrently fint the
    desired currency, put the currencies that are used in the document
    on top of the list.
    
    This adds a DocumentModelAccessor class, which is used to access
    parts of the document model from other modules throught the
    SfxObjectShell.
    
    Change-Id: I81a180b674ae69b373b0422f363678e8bab37194
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162638
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/sfx2/IDocumentModelAccessor.hxx 
b/include/sfx2/IDocumentModelAccessor.hxx
new file mode 100644
index 000000000000..8bd0f6b68c95
--- /dev/null
+++ b/include/sfx2/IDocumentModelAccessor.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <sfx2/dllapi.h>
+
+namespace sfx
+{
+struct SFX2_DLLPUBLIC CurrencyID
+{
+    OUString aSymbol;
+    OUString aExtension;
+    LanguageType eLanguage;
+};
+
+/** Document model accessor, used to access parts of the document model.
+ *
+ * This is useful when some common parts of the model are needed, but can
+ * only access the model indirecly from other modules that can access
+ * SfxObjectShell, but don't have a direct access to the document model
+ * (and access through UNO would be inconvenient).
+ *
+ * For example - get information about various parts of the document in
+ * generic dialogs (in CUI).
+ */
+class SFX2_DLLPUBLIC IDocumentModelAccessor
+{
+public:
+    virtual std::vector<CurrencyID> getDocumentCurrencies() const { return {}; 
}
+};
+
+} // end sfx namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx
index 0e1ec4d208de..db36fb493452 100644
--- a/include/sfx2/objsh.hxx
+++ b/include/sfx2/objsh.hxx
@@ -88,8 +88,11 @@ namespace sfx2
 {
     class SvLinkSource;
     class StyleManager;
+    class IXmlIdRegistry;
 }
 
+namespace sfx { class IDocumentModelAccessor; }
+
 namespace com::sun::star::awt { class XWindow; }
 namespace com::sun::star::beans { struct PropertyValue; }
 namespace com::sun::star::document { struct CmisVersion; }
@@ -106,8 +109,6 @@ namespace com::sun::star::task { class XInteractionHandler; 
}
 namespace com::sun::star::lang { class XComponent; }
 namespace com::sun::star::text { class XTextRange; }
 
-namespace sfx2 { class IXmlIdRegistry; }
-
 #define SFX_TITLE_TITLE    0
 #define SFX_TITLE_FILENAME 1
 #define SFX_TITLE_FULLNAME 2
@@ -564,7 +565,8 @@ public:
                                 GetDialogContainer();
     StarBASIC*                  GetBasic() const;
 
-    virtual std::set<Color>     GetDocColors();
+    virtual std::shared_ptr<sfx::IDocumentModelAccessor> 
GetDocumentModelAccessor() const;
+    virtual std::set<Color> GetDocColors();
     virtual std::shared_ptr<model::ColorSet> GetThemeColors();
 
     // Accessibility Check
diff --git a/include/svx/tbcontrl.hxx b/include/svx/tbcontrl.hxx
index 8347e3b9df1e..e9984daeab89 100644
--- a/include/svx/tbcontrl.hxx
+++ b/include/svx/tbcontrl.hxx
@@ -147,10 +147,8 @@ class SfxStyleSheetBasePool;
 class SfxTemplateItem;
 class PaletteManager;
 
-namespace svx
-{
-    class ToolboxButtonColorUpdaterBase;
-}
+namespace svx { class ToolboxButtonColorUpdaterBase; }
+namespace sfx { struct CurrencyID; }
 
 class SvxStyleToolBoxControl final : public 
cppu::ImplInheritanceHelper<svt::ToolboxController,
                                                                                
           css::lang::XServiceInfo>
@@ -257,7 +255,8 @@ private:
 
 public:
     static void GetCurrencySymbols( std::vector<OUString>& rList, bool bFlag,
-                                    std::vector<sal_uInt16>& rCurrencyList );
+                                    std::vector<sal_uInt16>& rCurrencyList,
+                                    std::vector<sfx::CurrencyID> const& 
rCurrencyIDs);
 
     explicit SvxCurrencyToolBoxControl( const 
css::uno::Reference<css::uno::XComponentContext>& rContext );
     virtual ~SvxCurrencyToolBoxControl() override;
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index b6761d3d04bf..35f33633b0ef 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -62,6 +62,7 @@
 #include <svl/srchitem.hxx>
 #include <svl/sharedstringpool.hxx>
 #include <unotools/collatorwrapper.hxx>
+#include <sfx2/IDocumentModelAccessor.hxx>
 
 #include <sfx2/sfxsids.hrc>
 
@@ -237,6 +238,7 @@ public:
     void testProtectedSheetEditByColumn();
 
     void testInsertColumnsWithFormulaCells();
+    void testDocumentModelAccessor_getDocumentCurrencies();
 
     CPPUNIT_TEST_SUITE(Test);
     CPPUNIT_TEST(testCollator);
@@ -337,6 +339,7 @@ public:
     CPPUNIT_TEST(testProtectedSheetEditByRow);
     CPPUNIT_TEST(testProtectedSheetEditByColumn);
     CPPUNIT_TEST(testInsertColumnsWithFormulaCells);
+    CPPUNIT_TEST(testDocumentModelAccessor_getDocumentCurrencies);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -7030,6 +7033,44 @@ void Test::testInsertColumnsWithFormulaCells()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testDocumentModelAccessor_getDocumentCurrencies()
+{
+    m_pDoc->InsertTab(0, "Sheet1");
+
+    // Check Document Currencies
+    auto pAccessor = m_xDocShell->GetDocumentModelAccessor();
+    CPPUNIT_ASSERT(pAccessor);
+    CPPUNIT_ASSERT_EQUAL(size_t(0), pAccessor->getDocumentCurrencies().size());
+
+    // Set a currency to a cell
+    {
+        m_pDoc->SetValue(ScAddress(0, 0, 0), 2.0);
+
+        OUString aCode(u"#.##0,00[$€-424]");
+
+        sal_Int32 nCheckPos;
+        SvNumFormatType eType;
+        sal_uInt32 nFormat;
+
+        m_pDoc->GetFormatTable()->PutEntry(aCode, nCheckPos, eType, nFormat, 
LANGUAGE_SLOVENIAN);
+        CPPUNIT_ASSERT_EQUAL(SvNumFormatType::CURRENCY, eType);
+
+        ScPatternAttr aNewAttrs(m_pDoc->GetPool());
+        SfxItemSet& rSet = aNewAttrs.GetItemSet();
+        rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat));
+        m_pDoc->ApplyPattern(0, 0, 0, aNewAttrs); // A1.
+        CPPUNIT_ASSERT_EQUAL(OUString(u"2,00€"), 
m_pDoc->GetString(ScAddress(0, 0, 0)));
+    }
+
+    // Check Document Currencies Again
+    auto aCurrencyIDs = pAccessor->getDocumentCurrencies();
+    CPPUNIT_ASSERT_EQUAL(size_t(1), aCurrencyIDs.size());
+
+    CPPUNIT_ASSERT_EQUAL(LANGUAGE_SLOVENIAN, aCurrencyIDs[0].eLanguage);
+    CPPUNIT_ASSERT_EQUAL(OUString(u"-424"), aCurrencyIDs[0].aExtension);
+    CPPUNIT_ASSERT_EQUAL(OUString(u"€"), aCurrencyIDs[0].aSymbol);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index a0d45efd23a6..6b4b7c839f63 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -142,6 +142,7 @@
 #include <datastream.hxx>
 #include <documentlinkmgr.hxx>
 #include <refupdatecontext.hxx>
+#include <DocumentModelAccessor.hxx>
 
 #include <memory>
 #include <vector>
@@ -219,6 +220,13 @@ std::set<Color> ScDocShell::GetDocColors()
     return m_pDocument->GetDocColors();
 }
 
+std::shared_ptr<sfx::IDocumentModelAccessor> 
ScDocShell::GetDocumentModelAccessor() const
+{
+    std::shared_ptr<sfx::IDocumentModelAccessor> pReturn;
+    pReturn.reset(new sc::DocumentModelAccessor(m_pDocument));
+    return pReturn;
+}
+
 std::shared_ptr<model::ColorSet> ScDocShell::GetThemeColors()
 {
     ScTabViewShell* pShell = GetBestViewShell();
diff --git a/sc/source/ui/inc/DocumentModelAccessor.hxx 
b/sc/source/ui/inc/DocumentModelAccessor.hxx
new file mode 100644
index 000000000000..5a77c1adf041
--- /dev/null
+++ b/sc/source/ui/inc/DocumentModelAccessor.hxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sfx2/IDocumentModelAccessor.hxx>
+#include <document.hxx>
+#include <docpool.hxx>
+#include <svl/intitem.hxx>
+#include <svl/zformat.hxx>
+#include <svl/zforlist.hxx>
+
+namespace sc
+{
+/** DocumentModelAccessor implementation for Calc */
+class DocumentModelAccessor : public sfx::IDocumentModelAccessor
+{
+private:
+    std::shared_ptr<ScDocument> m_pDocument;
+
+public:
+    DocumentModelAccessor(std::shared_ptr<ScDocument> const& pDocument)
+        : m_pDocument(pDocument)
+    {
+    }
+
+    std::vector<sfx::CurrencyID> getDocumentCurrencies() const override
+    {
+        std::vector<sfx::CurrencyID> aCurrencyIDs;
+
+        for (const SfxPoolItem* pItem :
+             m_pDocument->GetPool()->GetItemSurrogates(ATTR_VALUE_FORMAT))
+        {
+            auto* pIntItem = static_cast<const SfxUInt32Item*>(pItem);
+            sal_Int32 nFormat = pIntItem->GetValue();
+            SvNumberFormatter* pFormatter = m_pDocument->GetFormatTable();
+            if (pFormatter)
+            {
+                SvNumberformat const* pEntry = pFormatter->GetEntry(nFormat);
+                if (pEntry && pEntry->GetMaskedType() == 
SvNumFormatType::CURRENCY
+                    && pEntry->HasNewCurrency() && pEntry->GetLanguage() != 
LANGUAGE_SYSTEM)
+                {
+                    OUString aSymbol;
+                    OUString aExtension;
+                    pEntry->GetNewCurrencySymbol(aSymbol, aExtension);
+                    aCurrencyIDs.push_back({ aSymbol, aExtension, 
pEntry->GetLanguage() });
+                }
+            }
+        }
+
+        return aCurrencyIDs;
+    }
+};
+
+} // end sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 2d13df4848b3..b4a016d8fd68 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -182,6 +182,7 @@ public:
                                sal_Int32 nFileFormat,
                                bool bTemplate = false ) const override;
 
+    std::shared_ptr<sfx::IDocumentModelAccessor> GetDocumentModelAccessor() 
const override;
     virtual std::set<Color> GetDocColors() override;
     virtual std::shared_ptr<model::ColorSet> GetThemeColors() override;
 
diff --git a/sfx2/source/doc/objcont.cxx b/sfx2/source/doc/objcont.cxx
index 177451b116b6..013fe9907391 100644
--- a/sfx2/source/doc/objcont.cxx
+++ b/sfx2/source/doc/objcont.cxx
@@ -57,6 +57,7 @@
 #include <sfx2/strings.hrc>
 #include <sfx2/docfile.hxx>
 #include <sfx2/docfilt.hxx>
+#include <sfx2/IDocumentModelAccessor.hxx>
 #include <memory>
 #include <helpids.h>
 
@@ -323,6 +324,11 @@ std::set<Color> SfxObjectShell::GetDocColors()
 
 std::shared_ptr<model::ColorSet> SfxObjectShell::GetThemeColors() { return {}; 
}
 
+std::shared_ptr<sfx::IDocumentModelAccessor> 
SfxObjectShell::GetDocumentModelAccessor() const
+{
+    return {};
+}
+
 sfx::AccessibilityIssueCollection SfxObjectShell::runAccessibilityCheck()
 {
     sfx::AccessibilityIssueCollection aCollection;
diff --git a/svx/source/items/numfmtsh.cxx b/svx/source/items/numfmtsh.cxx
index 1aa58a32340a..70cf03536e7e 100644
--- a/svx/source/items/numfmtsh.cxx
+++ b/svx/source/items/numfmtsh.cxx
@@ -30,6 +30,7 @@
 #include <svx/numfmtsh.hxx>
 #include <svx/flagsdef.hxx>
 #include <svx/tbcontrl.hxx>
+#include <sfx2/IDocumentModelAccessor.hxx>
 
 #include <limits>
 
@@ -1390,7 +1391,9 @@ void 
SvxNumberFormatShell::GetCurrencySymbols(std::vector<OUString>& rList, sal_
 
     bool bFlag = (pTmpCurrencyEntry == nullptr);
 
-    SvxCurrencyToolBoxControl::GetCurrencySymbols(rList, bFlag, 
aCurCurrencyList);
+    std::vector<sfx::CurrencyID> aDocumentCurrencyIDs;
+    SvxCurrencyToolBoxControl::GetCurrencySymbols(rList, bFlag, 
aCurCurrencyList,
+                                                  aDocumentCurrencyIDs);
 
     if (pPos == nullptr)
         return;
diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx
index 835598d23c0e..c359ab24088f 100644
--- a/svx/source/tbxctrls/tbcontrl.cxx
+++ b/svx/source/tbxctrls/tbcontrl.cxx
@@ -92,15 +92,18 @@
 #include <svx/xfillit0.hxx>
 #include <svx/xflclit.hxx>
 #include <svl/currencytable.hxx>
+#include <svl/zformat.hxx>
 #include <svtools/langtab.hxx>
 #include <cppu/unotype.hxx>
 #include <cppuhelper/supportsservice.hxx>
 #include <officecfg/Office/Common.hxx>
+#include <o3tl/temporary.hxx>
 #include <o3tl/safeint.hxx>
 #include <o3tl/typed_flags_set.hxx>
 #include <bitmaps.hlst>
 #include <sal/log.hxx>
 #include <unotools/collatorwrapper.hxx>
+#include <sfx2/IDocumentModelAccessor.hxx>
 
 #include <comphelper/lok.hxx>
 #include <tools/json_writer.hxx>
@@ -3942,7 +3945,13 @@ namespace
             SvNumberFormatter aFormatter( m_xControl->getContext(), 
LANGUAGE_SYSTEM );
             m_eFormatLanguage = aFormatter.GetLanguage();
 
-            SvxCurrencyToolBoxControl::GetCurrencySymbols( aList, true, 
aCurrencyList );
+            std::vector<sfx::CurrencyID> aCurrencyIDs;
+
+            SfxObjectShell* pDocShell = SfxObjectShell::Current();
+            if (auto pModelAccessor = pDocShell->GetDocumentModelAccessor())
+                aCurrencyIDs = pModelAccessor->getDocumentCurrencies();
+
+            SvxCurrencyToolBoxControl::GetCurrencySymbols(aList, true, 
aCurrencyList, aCurrencyIDs);
 
             sal_uInt16 nPos = 0, nCount = 0;
             sal_Int32 nSelectedPos = -1;
@@ -4132,8 +4141,9 @@ Reference< css::accessibility::XAccessible > 
SvxFontNameBox_Impl::CreateAccessib
 }
 
 //static
-void SvxCurrencyToolBoxControl::GetCurrencySymbols( std::vector<OUString>& 
rList, bool bFlag,
-                                                    std::vector<sal_uInt16>& 
rCurrencyList )
+void SvxCurrencyToolBoxControl::GetCurrencySymbols(std::vector<OUString>& 
rList, bool bFlag,
+                                                   std::vector<sal_uInt16>& 
rCurrencyList,
+                                                   
std::vector<sfx::CurrencyID> const& rDocumentCurrencyIDs)
 {
     rCurrencyList.clear();
 
@@ -4143,8 +4153,7 @@ void SvxCurrencyToolBoxControl::GetCurrencySymbols( 
std::vector<OUString>& rList
     sal_uInt16 nStart = 1;
 
     OUString aString( ApplyLreOrRleEmbedding( rCurrencyTable[0].GetSymbol() ) 
+ " " );
-    aString += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
-                                       rCurrencyTable[0].GetLanguage() ) );
+    aString += 
ApplyLreOrRleEmbedding(SvtLanguageTable::GetLanguageString(rCurrencyTable[0].GetLanguage()));
 
     rList.push_back( aString );
     rCurrencyList.push_back( sal_uInt16(-1) ); // nAuto
@@ -4163,17 +4172,40 @@ void SvxCurrencyToolBoxControl::GetCurrencySymbols( 
std::vector<OUString>& rList
 
     for( sal_uInt16 i = 1; i < nCount; ++i )
     {
-        OUString aStr( ApplyLreOrRleEmbedding( 
rCurrencyTable[i].GetBankSymbol() ) );
+        auto& rCurrencyEntry = rCurrencyTable[i];
+
+        OUString aStr( ApplyLreOrRleEmbedding(rCurrencyEntry.GetBankSymbol()));
         aStr += aTwoSpace;
-        aStr += ApplyLreOrRleEmbedding( rCurrencyTable[i].GetSymbol() );
+        aStr += ApplyLreOrRleEmbedding(rCurrencyEntry.GetSymbol());
         aStr += aTwoSpace;
-        aStr += ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString(
-                                        rCurrencyTable[i].GetLanguage() ) );
+        aStr += 
ApplyLreOrRleEmbedding(SvtLanguageTable::GetLanguageString(rCurrencyEntry.GetLanguage()));
 
         std::vector<OUString>::size_type j = nStart;
-        for( ; j < rList.size(); ++j )
-            if ( aCollator.compareString( aStr, rList[j] ) < 0 )
-                break;  // insert before first greater than
+
+        // Search if the currency is present in the document
+        auto iter = std::find_if(rDocumentCurrencyIDs.begin(), 
rDocumentCurrencyIDs.end(), [rCurrencyEntry](sfx::CurrencyID const& rCurrency)
+        {
+            const NfCurrencyEntry* pEntry = 
SvNumberFormatter::GetCurrencyEntry(o3tl::temporary(bool()), rCurrency.aSymbol, 
rCurrency.aExtension, rCurrency.eLanguage);
+
+            if (pEntry)
+                return rCurrencyEntry.GetLanguage() == pEntry->GetLanguage() 
&& rCurrencyEntry.GetSymbol() == pEntry->GetSymbol();
+
+            return false;
+        });
+
+        // If currency is in document, insert it on top
+        if (iter != rDocumentCurrencyIDs.end())
+        {
+            nStart++;
+        }
+        else
+        {
+            for( ; j < rList.size(); ++j )
+            {
+                if ( aCollator.compareString( aStr, rList[j] ) < 0 )
+                    break;  // insert before first greater than
+            }
+        }
 
         rList.insert( rList.begin() + j, aStr );
         rCurrencyList.insert( rCurrencyList.begin() + j, i );
@@ -4187,7 +4219,8 @@ void SvxCurrencyToolBoxControl::GetCurrencySymbols( 
std::vector<OUString>& rList
     for ( sal_uInt16 i = 1; i < nCount; ++i )
     {
         bool bInsert = true;
-        OUString aStr( ApplyLreOrRleEmbedding( 
rCurrencyTable[i].GetBankSymbol() ) );
+        auto& rCurrencyEntry = rCurrencyTable[i];
+        OUString aStr( ApplyLreOrRleEmbedding(rCurrencyEntry.GetBankSymbol()));
 
         std::vector<OUString>::size_type j = nCont;
         for ( ; j < rList.size() && bInsert; ++j )

Reply via email to