include/vcl/toolkit/combobox.hxx   |    4 +-
 include/vcl/weld/ComboBox.hxx      |    4 +-
 include/vcl/weld/EntryTreeView.hxx |    6 ++--
 svtools/source/control/ctrlbox.cxx |   33 +++++++++++++++++-----
 vcl/inc/listbox.hxx                |    4 +-
 vcl/inc/qt5/QtInstanceComboBox.hxx |    4 +-
 vcl/inc/salvtables.hxx             |    8 ++---
 vcl/qt5/QtInstanceComboBox.cxx     |   32 +++++++++++++++++----
 vcl/source/app/salvtables.cxx      |   10 +++---
 vcl/source/control/combobox.cxx    |    8 ++---
 vcl/source/control/imp_listbox.cxx |   23 +++++----------
 vcl/unx/gtk3/gtkinst.cxx           |   54 +++++++++++++------------------------
 12 files changed, 102 insertions(+), 88 deletions(-)

New commits:
commit a41fcd306ba9bcf5b1e28576d0eb47b8125cac46
Author:     Michael Weghorn <[email protected]>
AuthorDate: Sat Jan 3 20:04:50 2026 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Sun Jan 4 15:05:17 2026 +0100

    weld: Pass/Return vector in ComboBox::{g,s}et_mru_entries
    
    The MRU entries are logically a list/vector, so
    use a vector of strings for those in the weld::ComboBox
    API instead of a serialized string.
    
    Instead of (de)serializing to/from string in each
    of the weld::ComboBox implementations, let the
    caller take care of that.
    
    Also adjust the underlying vcl widgets used
    by SalInstanceComboBoxWithEdit accordingly.
    
    At this point in time, FontNameBox (use for the
    font combobox in the Writer formatting toolbar)
    is the only user of the API.
    No change in behavior expected or seen in a quick
    test using that combobox. (After selecting entries
    in that combobox, they show up in the MRU list at
    the top as expected and are restored when exiting
    and restarting Writer.)
    
    For GtkInstanceComboBox, GtkInstanceComboBox::get_mru_entries
    was seen returning a vector with an empty entry initially.
    Explicitly filter out empty strings to avoid that.
    (It was not a problem before, because an empty string
    was interpreted as "no entries", while a vector with
    a single entry consisting of an empty string is no more.)
    
    Change-Id: I8422e1abaaabaa500cdffaba1fae97638bd4d5f0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196460
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/include/vcl/toolkit/combobox.hxx b/include/vcl/toolkit/combobox.hxx
index d934d83343f7..60f8de2cefc7 100644
--- a/include/vcl/toolkit/combobox.hxx
+++ b/include/vcl/toolkit/combobox.hxx
@@ -159,8 +159,8 @@ public:
     Size            CalcBlockSize( sal_uInt16 nColumns, sal_uInt16 nLines ) 
const;
     void            GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& 
rnLines ) const;
 
-    SAL_DLLPRIVATE void     SetMRUEntries( std::u16string_view rEntries );
-    SAL_DLLPRIVATE OUString GetMRUEntries() const;
+    SAL_DLLPRIVATE void SetMRUEntries(const std::vector<OUString>& rEntries);
+    SAL_DLLPRIVATE std::vector<OUString> GetMRUEntries() const;
     SAL_DLLPRIVATE void     SetMaxMRUCount( sal_Int32  n );
     SAL_DLLPRIVATE sal_Int32 GetMaxMRUCount() const;
     SAL_DLLPRIVATE void  SetEntryData( sal_Int32  nPos, void* pNewData );
diff --git a/include/vcl/weld/ComboBox.hxx b/include/vcl/weld/ComboBox.hxx
index ca8ffb0b4130..fbdc2b8d205d 100644
--- a/include/vcl/weld/ComboBox.hxx
+++ b/include/vcl/weld/ComboBox.hxx
@@ -216,8 +216,8 @@ public:
     // for mru support
     virtual int get_max_mru_count() const = 0;
     virtual void set_max_mru_count(int nCount) = 0;
-    virtual OUString get_mru_entries() const = 0;
-    virtual void set_mru_entries(const OUString& rEntries) = 0;
+    virtual std::vector<OUString> get_mru_entries() const = 0;
+    virtual void set_mru_entries(const std::vector<OUString>& rEntries) = 0;
 
     // Backwards compatibility, should be avoided to allow
     // UI consistency.
diff --git a/include/vcl/weld/EntryTreeView.hxx 
b/include/vcl/weld/EntryTreeView.hxx
index f99fb1ff4cd4..4383f239da5c 100644
--- a/include/vcl/weld/EntryTreeView.hxx
+++ b/include/vcl/weld/EntryTreeView.hxx
@@ -148,13 +148,13 @@ public:
 
     virtual void set_max_mru_count(int) override final { assert(false && "not 
implemented"); }
 
-    virtual OUString get_mru_entries() const override final
+    virtual std::vector<OUString> get_mru_entries() const override final
     {
         assert(false && "not implemented");
-        return OUString();
+        return {};
     }
 
-    virtual void set_mru_entries(const OUString&) override final
+    virtual void set_mru_entries(const std::vector<OUString>&) override final
     {
         assert(false && "not implemented");
     }
diff --git a/svtools/source/control/ctrlbox.cxx 
b/svtools/source/control/ctrlbox.cxx
index 1123fc96e079..a204bb8986a4 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -432,8 +432,16 @@ FontNameBox::~FontNameBox()
 
 void FontNameBox::SaveMRUEntries(const OUString& aFontMRUEntriesFile) const
 {
-    OString aEntries(OUStringToOString(m_xComboBox->get_mru_entries(),
-        RTL_TEXTENCODING_UTF8));
+    std::vector<OUString> aMRUEntries = m_xComboBox->get_mru_entries();
+
+    const sal_Unicode cSep = ';';
+    OUStringBuffer aEntries;
+    for (size_t i = 0; i < aMRUEntries.size(); i++)
+    {
+        aEntries.append(aMRUEntries.at(i));
+        if (i < aMRUEntries.size() - 1)
+            aEntries.append(cSep);
+    }
 
     if (aEntries.isEmpty() || aFontMRUEntriesFile.isEmpty())
         return;
@@ -447,7 +455,7 @@ void FontNameBox::SaveMRUEntries(const OUString& 
aFontMRUEntriesFile) const
     }
 
     aStream.SetLineDelimiter( LINEEND_LF );
-    aStream.WriteLine( aEntries );
+    aStream.WriteLine(aEntries.makeStringAndClear().toUtf8());
     aStream.WriteLine( "" );
 }
 
@@ -468,9 +476,18 @@ void FontNameBox::LoadMRUEntries( const OUString& 
aFontMRUEntriesFile )
 
     OStringBuffer aLine;
     aStream.ReadLine( aLine );
-    OUString aEntries = OStringToOUString(aLine,
-        RTL_TEXTENCODING_UTF8);
-    m_xComboBox->set_mru_entries(aEntries);
+    const OUString sEntries = OStringToOUString(aLine, RTL_TEXTENCODING_UTF8);
+    std::vector<OUString> aFontEntries;
+    const sal_Unicode cSep = ';';
+    sal_Int32 nIndex = 0;
+    while (nIndex >= 0)
+    {
+        const OUString sEntry = sEntries.getToken(0, cSep, nIndex);
+        if (!sEntry.isEmpty())
+            aFontEntries.push_back(sEntry);
+    }
+
+    m_xComboBox->set_mru_entries(aFontEntries);
 }
 
 void FontNameBox::InitFontMRUEntriesFile()
@@ -496,8 +513,8 @@ void FontNameBox::Fill( const FontList* pList )
 {
     // store old text and clear box
     OUString aOldText = m_xComboBox->get_active_text();
-    OUString rEntries = m_xComboBox->get_mru_entries();
-    bool bLoadFromFile = rEntries.isEmpty();
+    std::vector<OUString> rEntries = m_xComboBox->get_mru_entries();
+    bool bLoadFromFile = rEntries.empty();
     m_xComboBox->freeze();
     m_xComboBox->clear();
 
diff --git a/vcl/inc/listbox.hxx b/vcl/inc/listbox.hxx
index b05cee40fa97..91fab5cc4fa6 100644
--- a/vcl/inc/listbox.hxx
+++ b/vcl/inc/listbox.hxx
@@ -489,8 +489,8 @@ public:
     void            SetHighlightColor(const Color& rColor);
     void            SetHighlightTextColor(const Color& rColor);
 
-    void            SetMRUEntries( std::u16string_view rEntries, sal_Unicode 
cSep );
-    OUString        GetMRUEntries( sal_Unicode cSep ) const;
+    void SetMRUEntries(const std::vector<OUString>& rEntries);
+    std::vector<OUString> GetMRUEntries() const;
     void            SetMaxMRUCount( sal_Int32  n )                  { 
maLBWindow->GetEntryList().SetMaxMRUCount( n ); }
     sal_Int32       GetMaxMRUCount() const                      { return 
maLBWindow->GetEntryList().GetMaxMRUCount(); }
     sal_uInt16      GetDisplayLineCount() const
diff --git a/vcl/inc/qt5/QtInstanceComboBox.hxx 
b/vcl/inc/qt5/QtInstanceComboBox.hxx
index 3a8cdc87736a..8b6ed5bd541d 100644
--- a/vcl/inc/qt5/QtInstanceComboBox.hxx
+++ b/vcl/inc/qt5/QtInstanceComboBox.hxx
@@ -79,8 +79,8 @@ public:
 
     virtual int get_max_mru_count() const override;
     virtual void set_max_mru_count(int nCount) override;
-    virtual OUString get_mru_entries() const override;
-    virtual void set_mru_entries(const OUString& rEntries) override;
+    virtual std::vector<OUString> get_mru_entries() const override;
+    virtual void set_mru_entries(const std::vector<OUString>& rEntries) 
override;
 
     virtual void set_max_drop_down_rows(int nRows) override;
 
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index c3de55bcc50d..bb266b116b2e 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -984,9 +984,9 @@ public:
 
     virtual void set_max_mru_count(int) override;
 
-    virtual OUString get_mru_entries() const override;
+    virtual std::vector<OUString> get_mru_entries() const override;
 
-    virtual void set_mru_entries(const OUString&) override;
+    virtual void set_mru_entries(const std::vector<OUString>& rEntries) 
override;
 
     virtual void HandleEventListener(VclWindowEvent& rEvent) override;
 
@@ -1056,9 +1056,9 @@ public:
 
     virtual void set_max_mru_count(int nCount) override;
 
-    virtual OUString get_mru_entries() const override;
+    virtual std::vector<OUString> get_mru_entries() const override;
 
-    virtual void set_mru_entries(const OUString& rEntries) override;
+    virtual void set_mru_entries(const std::vector<OUString>& rEntries) 
override;
 
     virtual void HandleEventListener(VclWindowEvent& rEvent) override;
 
diff --git a/vcl/qt5/QtInstanceComboBox.cxx b/vcl/qt5/QtInstanceComboBox.cxx
index 2620aaf6eba2..724e757839f5 100644
--- a/vcl/qt5/QtInstanceComboBox.cxx
+++ b/vcl/qt5/QtInstanceComboBox.cxx
@@ -411,13 +411,13 @@ int QtInstanceComboBox::get_max_mru_count() const
 
 void QtInstanceComboBox::set_max_mru_count(int) { assert(false && "Not 
implemented yet"); }
 
-OUString QtInstanceComboBox::get_mru_entries() const
+std::vector<OUString> QtInstanceComboBox::get_mru_entries() const
 {
     assert(false && "Not implemented yet");
-    return OUString();
+    return {};
 }
 
-void QtInstanceComboBox::set_mru_entries(const OUString&)
+void QtInstanceComboBox::set_mru_entries(const std::vector<OUString>&)
 {
     assert(false && "Not implemented yet");
 }
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index b4ad6de38000..21b533c9ec17 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -6156,13 +6156,13 @@ int SalInstanceComboBoxWithoutEdit::get_max_mru_count() 
const
 
 void SalInstanceComboBoxWithoutEdit::set_max_mru_count(int) { assert(false && 
"not implemented"); }
 
-OUString SalInstanceComboBoxWithoutEdit::get_mru_entries() const
+std::vector<OUString> SalInstanceComboBoxWithoutEdit::get_mru_entries() const
 {
     assert(false && "not implemented");
-    return OUString();
+    return {};
 }
 
-void SalInstanceComboBoxWithoutEdit::set_mru_entries(const OUString&)
+void SalInstanceComboBoxWithoutEdit::set_mru_entries(const 
std::vector<OUString>&)
 {
     assert(false && "not implemented");
 }
@@ -6344,12 +6344,12 @@ void SalInstanceComboBoxWithEdit::set_max_mru_count(int 
nCount)
     return m_xComboBox->SetMaxMRUCount(nCount);
 }
 
-OUString SalInstanceComboBoxWithEdit::get_mru_entries() const
+std::vector<OUString> SalInstanceComboBoxWithEdit::get_mru_entries() const
 {
     return m_xComboBox->GetMRUEntries();
 }
 
-void SalInstanceComboBoxWithEdit::set_mru_entries(const OUString& rEntries)
+void SalInstanceComboBoxWithEdit::set_mru_entries(const std::vector<OUString>& 
rEntries)
 {
     m_xComboBox->SetMRUEntries(rEntries);
 }
diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx
index 0e93a19a7a47..8b93f74cc46c 100644
--- a/vcl/source/control/combobox.cxx
+++ b/vcl/source/control/combobox.cxx
@@ -1283,14 +1283,14 @@ void ComboBox::AddSeparator( sal_Int32 n )
     m_pImplLB->AddSeparator( n );
 }
 
-void ComboBox::SetMRUEntries( std::u16string_view rEntries )
+void ComboBox::SetMRUEntries(const std::vector<OUString>& rEntries)
 {
-    m_pImplLB->SetMRUEntries( rEntries, ';' );
+    m_pImplLB->SetMRUEntries(rEntries);
 }
 
-OUString ComboBox::GetMRUEntries() const
+std::vector<OUString> ComboBox::GetMRUEntries() const
 {
-    return m_pImplLB ? m_pImplLB->GetMRUEntries( ';' ) : OUString();
+    return m_pImplLB ? m_pImplLB->GetMRUEntries() : std::vector<OUString>();
 }
 
 void ComboBox::SetMaxMRUCount( sal_Int32 n )
diff --git a/vcl/source/control/imp_listbox.cxx 
b/vcl/source/control/imp_listbox.cxx
index de2f83b2bcaf..4bad0adcaa2e 100644
--- a/vcl/source/control/imp_listbox.cxx
+++ b/vcl/source/control/imp_listbox.cxx
@@ -2436,7 +2436,7 @@ bool ImplListBox::HandleWheelAsCursorTravel(const 
CommandEvent& rCEvt, Control&
     return bDone;
 }
 
-void ImplListBox::SetMRUEntries( std::u16string_view rEntries, sal_Unicode 
cSep )
+void ImplListBox::SetMRUEntries(const std::vector<OUString>& rEntries)
 {
     bool bChanges = GetEntryList().GetMRUCount() != 0;
 
@@ -2445,19 +2445,16 @@ void ImplListBox::SetMRUEntries( std::u16string_view 
rEntries, sal_Unicode cSep
         maLBWindow->RemoveEntry( --n );
 
     sal_Int32 nMRUCount = 0;
-    sal_Int32 nIndex = 0;
-    do
+    for (const OUString& rEntry : rEntries)
     {
-        OUString aEntry( o3tl::getToken(rEntries, 0, cSep, nIndex ) );
         // Accept only existing entries
-        if ( GetEntryList().FindEntry( aEntry ) != LISTBOX_ENTRY_NOTFOUND )
+        if (GetEntryList().FindEntry(rEntry) != LISTBOX_ENTRY_NOTFOUND)
         {
-            ImplEntryType* pNewEntry = new ImplEntryType( aEntry );
+            ImplEntryType* pNewEntry = new ImplEntryType(rEntry);
             maLBWindow->InsertEntry(nMRUCount++, pNewEntry, false);
             bChanges = true;
         }
     }
-    while ( nIndex >= 0 );
 
     if ( bChanges )
     {
@@ -2467,16 +2464,12 @@ void ImplListBox::SetMRUEntries( std::u16string_view 
rEntries, sal_Unicode cSep
     }
 }
 
-OUString ImplListBox::GetMRUEntries( sal_Unicode cSep ) const
+std::vector<OUString> ImplListBox::GetMRUEntries() const
 {
-    OUStringBuffer aEntries;
+    std::vector<OUString> aEntries;
     for ( sal_Int32 n = 0; n < GetEntryList().GetMRUCount(); n++ )
-    {
-        aEntries.append(GetEntryList().GetEntryText( n ));
-        if( n < ( GetEntryList().GetMRUCount() - 1 ) )
-            aEntries.append(cSep);
-    }
-    return aEntries.makeStringAndClear();
+        aEntries.push_back(GetEntryList().GetEntryText(n));
+    return aEntries;
 }
 
 void ImplListBox::SetEdgeBlending(bool bNew)
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index bdca8f4734b4..ed05bc33ffc1 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -20596,43 +20596,36 @@ public:
 #endif
     }
 
-    OUString get_mru_entries() const override
+    std::vector<OUString> get_mru_entries() const override
     {
-        const sal_Unicode cSep = ';';
-
-        OUStringBuffer aEntries;
+        std::vector<OUString> aEntries;
         for (sal_Int32 n = 0; n < m_nMRUCount; n++)
         {
-            aEntries.append(get_text_including_mru(n));
-            if (n < m_nMRUCount - 1)
-                aEntries.append(cSep);
+            const OUString aEntry = get_text_including_mru(n);
+            if (!aEntry.isEmpty())
+                aEntries.push_back(aEntry);
         }
-        return aEntries.makeStringAndClear();
+        return aEntries;
     }
 
-    virtual void set_mru_entries(const OUString& rEntries) override
+    virtual void set_mru_entries(const std::vector<OUString>& rEntries) 
override
     {
-        const sal_Unicode cSep = ';';
-
         // Remove old MRU entries
         for (sal_Int32 n = m_nMRUCount; n;)
             remove_including_mru(--n);
 
         sal_Int32 nMRUCount = 0;
-        sal_Int32 nIndex = 0;
-        do
+        for (const OUString& rEntry : rEntries)
         {
-            OUString aEntry = rEntries.getToken(0, cSep, nIndex);
             // Accept only existing entries
-            int nPos = find_text(aEntry);
+            int nPos = find_text(rEntry);
             if (nPos != -1)
             {
                 OUString sId = get_id(nPos);
-                insert_including_mru(0, aEntry, &sId, nullptr, nullptr);
+                insert_including_mru(0, rEntry, &sId, nullptr, nullptr);
                 ++nMRUCount;
             }
         }
-        while (nIndex >= 0);
 
         if (nMRUCount && !m_nMRUCount)
             insert_separator_including_mru(nMRUCount, "separator");
@@ -22543,43 +22536,36 @@ public:
         m_sMenuButtonRow = rIdent;
     }
 
-    OUString get_mru_entries() const override
+    std::vector<OUString> get_mru_entries() const override
     {
-        const sal_Unicode cSep = ';';
-
-        OUStringBuffer aEntries;
+        std::vector<OUString> aEntries;
         for (sal_Int32 n = 0; n < m_nMRUCount; n++)
         {
-            aEntries.append(get_text_including_mru(n));
-            if (n < m_nMRUCount - 1)
-                aEntries.append(cSep);
+            const OUString aEntry = get_text_including_mru(n);
+            if (!aEntry.isEmpty())
+                aEntries.push_back(aEntry);
         }
-        return aEntries.makeStringAndClear();
+        return aEntries;
     }
 
-    virtual void set_mru_entries(const OUString& rEntries) override
+    virtual void set_mru_entries(const std::vector<OUString>& rEntries) 
override
     {
-        const sal_Unicode cSep = ';';
-
         // Remove old MRU entries
         for (sal_Int32 n = m_nMRUCount; n;)
             remove_including_mru(--n);
 
         sal_Int32 nMRUCount = 0;
-        sal_Int32 nIndex = 0;
-        do
+        for (const OUString& rEntry : rEntries)
         {
-            OUString aEntry = rEntries.getToken(0, cSep, nIndex);
             // Accept only existing entries
-            int nPos = find_text(aEntry);
+            int nPos = find_text(rEntry);
             if (nPos != -1)
             {
                 OUString sId = get_id(nPos);
-                insert_including_mru(0, aEntry, &sId, nullptr, nullptr);
+                insert_including_mru(0, rEntry, &sId, nullptr, nullptr);
                 ++nMRUCount;
             }
         }
-        while (nIndex >= 0);
 
         if (nMRUCount && !m_nMRUCount)
             insert_separator_including_mru(nMRUCount, u"separator"_ustr);
commit e712ef765d358d16b5f675955498ebd91c2ce4e8
Author:     Michael Weghorn <[email protected]>
AuthorDate: Sat Jan 3 18:48:42 2026 +0100
Commit:     Michael Weghorn <[email protected]>
CommitDate: Sun Jan 4 15:05:08 2026 +0100

    tdf#130857 qt weld: Implement QtInstanceComboBox::{g,s}et_entry_font
    
    Implement these QtInstanceComboBox methods by
    by creating a QtInstanceEntry for the combobox's
    entry/QLineEdit and calling the corresponding
    weld::Entry methods.
    
    Change-Id: Ib6ffe878c18a4a90c8ad227aae3957a646ef7479
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196459
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/qt5/QtInstanceComboBox.cxx b/vcl/qt5/QtInstanceComboBox.cxx
index 6da25a687505..2620aaf6eba2 100644
--- a/vcl/qt5/QtInstanceComboBox.cxx
+++ b/vcl/qt5/QtInstanceComboBox.cxx
@@ -355,15 +355,33 @@ void QtInstanceComboBox::paste_entry_clipboard()
 
 void QtInstanceComboBox::set_font(const vcl::Font& rFont) { setFont(rFont); }
 
-void QtInstanceComboBox::set_entry_font(const vcl::Font&)
+void QtInstanceComboBox::set_entry_font(const vcl::Font& rFont)
 {
-    assert(false && "Not implemented yet");
+    SolarMutexGuard g;
+
+    GetQtInstance().RunInMainThread([&] {
+        if (QLineEdit* pEdit = m_pComboBox->lineEdit())
+        {
+            QtInstanceEntry aEntry(pEdit);
+            aEntry.set_font(rFont);
+        }
+    });
 }
 
 vcl::Font QtInstanceComboBox::get_entry_font()
 {
-    assert(false && "Not implemented yet");
-    return vcl::Font();
+    SolarMutexGuard g;
+
+    vcl::Font aFont;
+    GetQtInstance().RunInMainThread([&] {
+        if (QLineEdit* pEdit = m_pComboBox->lineEdit())
+        {
+            QtInstanceEntry aEntry(pEdit);
+            aFont = aEntry.get_font();
+        }
+    });
+
+    return aFont;
 }
 
 bool QtInstanceComboBox::get_popup_shown() const

Reply via email to