include/svtools/ctrlbox.hxx        |   12 ++++++++++--
 svtools/source/control/ctrlbox.cxx |   35 ++++++++++++++++++++++++++++-------
 2 files changed, 38 insertions(+), 9 deletions(-)

New commits:
commit 1acda4fc1b906eb0f6b5cff1e7b171adbabba310
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Mon Sep 9 11:01:37 2024 +0100
Commit:     Adolfo Jayme Barrientos <fit...@ubuntu.com>
CommitDate: Tue Sep 10 18:40:47 2024 +0200

    Resolves: tdf#162113 prefer restoring explicit font style selection
    
    so when scrolling through fonts that might not have the original or
    explicitly picked style, then on moving to the next font that does have
    that style, then the original bold/italic/etc gets picked again.
    
    Change-Id: If818a116ed4ab248cb67f60845acad2cd4eeb8ed
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173071
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 22cb250074606a9e637787245f8e18a11ac5c252)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173087
    Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com>

diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index ddd8eabc8f32..1ea54f44308d 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -396,14 +396,20 @@ private:
 class SVT_DLLPUBLIC FontStyleBox
 {
     std::unique_ptr<weld::ComboBox> m_xComboBox;
+    OUString m_aLastStyle;
+    Link<weld::ComboBox&, void> m_aChangedLink;
 public:
     FontStyleBox(std::unique_ptr<weld::ComboBox> p);
 
     void Fill(std::u16string_view rName, const FontList* pList);
 
-    void connect_changed(const Link<weld::ComboBox&, void>& rLink) { 
m_xComboBox->connect_changed(rLink); }
+    void connect_changed(const Link<weld::ComboBox&, void>& rLink) { 
m_aChangedLink = rLink; }
     OUString get_active_text() const { return m_xComboBox->get_active_text(); }
-    void set_active_text(const OUString& rText) { 
m_xComboBox->set_active_text(rText); }
+    void set_active_text(const OUString& rText)
+    {
+        m_aLastStyle = rText;
+        m_xComboBox->set_active_text(rText);
+    }
     void set_size_request(int nWidth, int nHeight) {  
m_xComboBox->set_size_request(nWidth, nHeight); }
 
     void append_text(const OUString& rStr) { m_xComboBox->append_text(rStr); }
@@ -415,6 +421,8 @@ public:
 private:
     FontStyleBox(const FontStyleBox& ) = delete;
     FontStyleBox& operator=(const FontStyleBox&) = delete;
+
+    DECL_LINK(ChangeHdl, weld::ComboBox&, void);
 };
 
 class SVT_DLLPUBLIC FontSizeBox
diff --git a/svtools/source/control/ctrlbox.cxx 
b/svtools/source/control/ctrlbox.cxx
index a4b293b7629e..f18c0801c62d 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -900,6 +900,7 @@ void FontNameBox::set_active_or_entry_text(const OUString& 
rText)
 
 FontStyleBox::FontStyleBox(std::unique_ptr<weld::ComboBox> p)
     : m_xComboBox(std::move(p))
+    , m_aLastStyle(m_xComboBox->get_active_text())
 {
     //Use the standard texts to get an optimal size and stick to that size.
     //That should stop the character dialog dancing around.
@@ -912,12 +913,19 @@ 
FontStyleBox::FontStyleBox(std::unique_ptr<weld::ComboBox> p)
     nMaxLen = std::max(nMaxLen, 
m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_BLACK)).Width());
     nMaxLen = std::max(nMaxLen, 
m_xComboBox->get_pixel_size(SvtResId(STR_SVT_STYLE_BLACK_ITALIC)).Width());
     m_xComboBox->set_entry_width_chars(std::ceil(nMaxLen / 
m_xComboBox->get_approximate_digit_width()));
+    m_xComboBox->connect_changed(LINK(this, FontStyleBox, ChangeHdl));
+}
+
+IMPL_LINK(FontStyleBox, ChangeHdl, weld::ComboBox&, rComboBox, void)
+{
+    // update m_aLastStyle to whatever is explicitly selected by the user
+    m_aLastStyle = rComboBox.get_active_text();
+    m_aChangedLink.Call(rComboBox);
 }
 
 void FontStyleBox::Fill( std::u16string_view rName, const FontList* pList )
 {
     OUString aOldText = m_xComboBox->get_active_text();
-    int nPos = m_xComboBox->get_active();
 
     m_xComboBox->freeze();
     m_xComboBox->clear();
@@ -1034,19 +1042,32 @@ void FontStyleBox::Fill( std::u16string_view rName, 
const FontList* pList )
 
     m_xComboBox->thaw();
 
+    // tdf#162113 prefer restoring the last explicitly set
+    // style if that is possible
+    if (!m_aLastStyle.isEmpty())
+    {
+        int nFound = m_xComboBox->find_text(m_aLastStyle);
+        if (nFound != -1)
+        {
+            m_xComboBox->set_active(nFound);
+            return;
+        }
+    }
+
+    // otherwise, restore the style that was last selected
+    // if that is possible
     if (!aOldText.isEmpty())
     {
         int nFound = m_xComboBox->find_text(aOldText);
         if (nFound != -1)
-            m_xComboBox->set_active(nFound);
-        else
         {
-            if (nPos >= m_xComboBox->get_count())
-                m_xComboBox->set_active(0);
-            else
-                m_xComboBox->set_active(nPos);
+            m_xComboBox->set_active(nFound);
+            return;
         }
     }
+
+    // otherwise, just pick something
+    m_xComboBox->set_active(0);
 }
 
 FontSizeBox::FontSizeBox(std::unique_ptr<weld::ComboBox> p)

Reply via email to