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
