include/vcl/toolkit/fmtfield.hxx      |    3 +-
 include/vcl/weld.hxx                  |    2 +
 svtools/source/brwbox/ebbcontrols.cxx |   12 +-------
 vcl/source/app/weldutils.cxx          |    4 ++
 vcl/source/control/fmtfield.cxx       |   39 ++++++++++++++++-----------
 vcl/unx/gtk3/gtk3gtkinst.cxx          |   49 ++++++++++++++++++++--------------
 6 files changed, 64 insertions(+), 45 deletions(-)

New commits:
commit 288b9f7edd26458e3a71aad9f96279ec9ef00931
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Tue Jul 14 20:11:39 2020 +0100
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Wed Jul 15 14:59:31 2020 +0200

    need to set the formatter as early as possible
    
    easiest thing is to distinguish between an external one and a
    built-in one and have callers own the external one
    
    Change-Id: Ia14dea81614f7bc7958c5fa11cce928a9a59976a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98790
    Tested-by: Caolán McNamara <caol...@redhat.com>
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/include/vcl/toolkit/fmtfield.hxx b/include/vcl/toolkit/fmtfield.hxx
index af2be6bd741f..4ba668bc7994 100644
--- a/include/vcl/toolkit/fmtfield.hxx
+++ b/include/vcl/toolkit/fmtfield.hxx
@@ -56,7 +56,8 @@ public:
     void SetFormatter(Formatter* pFormatter);
 
 protected:
-    std::unique_ptr<Formatter> m_xFormatter;
+    std::unique_ptr<Formatter> m_xOwnFormatter;
+    Formatter* m_pFormatter;
 
     virtual bool EventNotify(NotifyEvent& rNEvt) override;
     virtual void Modify() override;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index e0f274b50c04..0d8b702e5f20 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -1619,6 +1619,8 @@ protected:
 
 public:
     virtual Formatter& GetFormatter() = 0;
+    // does not take ownership, and so must be deregistered if pFormatter
+    // is destroyed
     virtual void SetFormatter(weld::EntryFormatter* pFormatter) = 0;
 
     void connect_value_changed(const Link<FormattedSpinButton&, void>& rLink)
diff --git a/svtools/source/brwbox/ebbcontrols.cxx 
b/svtools/source/brwbox/ebbcontrols.cxx
index 7372d4fe67d6..400f0fb581fe 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -406,8 +406,6 @@ namespace svt
 
     void FormattedControlBase::InitFormattedControlBase()
     {
-        if (m_bSpinVariant)
-            m_xSpinButton->SetFormatter(m_xEntryFormatter.release());
         InitEditControlBase(m_bSpinVariant ? m_xSpinButton.get() : 
m_xEntry.get());
     }
 
@@ -418,18 +416,12 @@ namespace svt
 
     weld::EntryFormatter& FormattedControlBase::get_formatter()
     {
-        if (m_bSpinVariant)
-            return 
static_cast<weld::EntryFormatter&>(m_xSpinButton->GetFormatter());
-        else
-            return *m_xEntryFormatter;
+        return *m_xEntryFormatter;
     }
 
     void FormattedControlBase::dispose()
     {
-        if (m_bSpinVariant)
-            m_xSpinButton->SetFormatter(nullptr);
-        else
-            m_xEntryFormatter.reset();
+        m_xEntryFormatter.reset();
         m_xSpinButton.reset();
         m_xEntry.reset();
         EditControlBase::dispose();
diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx
index 3c11b8e4afbb..acf1ba3473b5 100644
--- a/vcl/source/app/weldutils.cxx
+++ b/vcl/source/app/weldutils.cxx
@@ -147,12 +147,16 @@ EntryFormatter::~EntryFormatter()
 {
     m_rEntry.connect_changed(Link<weld::Entry&, void>());
     m_rEntry.connect_focus_out(Link<weld::Widget&, void>());
+    if (m_pSpinButton)
+        m_pSpinButton->SetFormatter(nullptr);
 }
 
 void EntryFormatter::Init()
 {
     m_rEntry.connect_changed(LINK(this, EntryFormatter, ModifyHdl));
     m_rEntry.connect_focus_out(LINK(this, EntryFormatter, FocusOutHdl));
+    if (m_pSpinButton)
+        m_pSpinButton->SetFormatter(this);
 }
 
 Selection EntryFormatter::GetEntrySelection() const
diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx
index 52f959056dda..48a82370b325 100644
--- a/vcl/source/control/fmtfield.cxx
+++ b/vcl/source/control/fmtfield.cxx
@@ -1010,7 +1010,8 @@ namespace
 DoubleNumericField::DoubleNumericField(vcl::Window* pParent, WinBits nStyle)
     : FormattedField(pParent, nStyle)
 {
-    m_xFormatter.reset(new DoubleNumericFormatter(*this));
+    m_xOwnFormatter.reset(new DoubleNumericFormatter(*this));
+    m_pFormatter = m_xOwnFormatter.get();
     ResetConformanceTester();
 }
 
@@ -1044,7 +1045,9 @@ void DoubleNumericField::ResetConformanceTester()
 DoubleCurrencyField::DoubleCurrencyField(vcl::Window* pParent, WinBits nStyle)
     :FormattedField(pParent, nStyle)
 {
-    m_xFormatter.reset(new DoubleCurrencyFormatter(*this));
+    m_xOwnFormatter.reset(new DoubleCurrencyFormatter(*this));
+    m_pFormatter = m_xOwnFormatter.get();
+
     m_bPrependCurrSym = false;
 
     // initialize with a system currency format
@@ -1059,7 +1062,7 @@ void DoubleCurrencyField::setCurrencySymbol(const 
OUString& rSymbol)
 
     m_sCurrencySymbol = rSymbol;
     UpdateCurrencyFormat();
-    m_xFormatter->FormatChanged(FORMAT_CHANGE_TYPE::CURRENCY_SYMBOL);
+    m_pFormatter->FormatChanged(FORMAT_CHANGE_TYPE::CURRENCY_SYMBOL);
 }
 
 void DoubleCurrencyField::setPrependCurrSym(bool _bPrepend)
@@ -1069,16 +1072,16 @@ void DoubleCurrencyField::setPrependCurrSym(bool 
_bPrepend)
 
     m_bPrependCurrSym = _bPrepend;
     UpdateCurrencyFormat();
-    m_xFormatter->FormatChanged(FORMAT_CHANGE_TYPE::CURRSYM_POSITION);
+    m_pFormatter->FormatChanged(FORMAT_CHANGE_TYPE::CURRSYM_POSITION);
 }
 
 void DoubleCurrencyField::UpdateCurrencyFormat()
 {
     // the old settings
     LanguageType eLanguage;
-    m_xFormatter->GetFormat(eLanguage);
-    bool bThSep = m_xFormatter->GetThousandsSep();
-    sal_uInt16 nDigits = m_xFormatter->GetDecimalDigits();
+    m_pFormatter->GetFormat(eLanguage);
+    bool bThSep = m_pFormatter->GetThousandsSep();
+    sal_uInt16 nDigits = m_pFormatter->GetDecimalDigits();
 
     // build a new format string with the base class' and my own settings
 
@@ -1142,17 +1145,19 @@ void DoubleCurrencyField::UpdateCurrencyFormat()
     }
 
     // set this new basic format
-    
static_cast<DoubleCurrencyFormatter*>(m_xFormatter.get())->GuardSetFormat(sNewFormat.makeStringAndClear(),
 eLanguage);
+    
static_cast<DoubleCurrencyFormatter*>(m_pFormatter)->GuardSetFormat(sNewFormat.makeStringAndClear(),
 eLanguage);
 }
 
 FormattedField::FormattedField(vcl::Window* pParent, WinBits nStyle)
     : SpinField(pParent, nStyle, WindowType::FORMATTEDFIELD)
+    , m_pFormatter(nullptr)
 {
 }
 
 void FormattedField::dispose()
 {
-    m_xFormatter.reset();
+    m_pFormatter = nullptr;
+    m_xOwnFormatter.reset();
     SpinField::dispose();
 }
 
@@ -1300,22 +1305,26 @@ bool FormattedField::EventNotify(NotifyEvent& rNEvt)
         }
     }
 
-    if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS && m_xFormatter)
-        m_xFormatter->EntryLostFocus();
+    if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS && m_pFormatter)
+        m_pFormatter->EntryLostFocus();
 
     return SpinField::EventNotify( rNEvt );
 }
 
 Formatter& FormattedField::GetFormatter()
 {
-    if (!m_xFormatter)
-        m_xFormatter.reset(new FieldFormatter(*this));
-    return *m_xFormatter;
+    if (!m_pFormatter)
+    {
+        m_xOwnFormatter.reset(new FieldFormatter(*this));
+        m_pFormatter = m_xOwnFormatter.get();
+    }
+    return *m_pFormatter;
 }
 
 void FormattedField::SetFormatter(Formatter* pFormatter)
 {
-    m_xFormatter.reset(pFormatter);
+    m_xOwnFormatter.reset();
+    m_pFormatter = pFormatter;
 }
 
 // currently used by online
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 375526d595a5..29199170b5f9 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -12192,7 +12192,8 @@ class GtkInstanceFormattedSpinButton : public 
GtkInstanceEntry, public virtual w
 {
 private:
     GtkSpinButton* m_pButton;
-    std::unique_ptr<weld::EntryFormatter> m_xFormatter;
+    std::unique_ptr<weld::EntryFormatter> m_xOwnFormatter;
+    weld::EntryFormatter* m_pFormatter;
     gulong m_nValueChangedSignalId;
     gulong m_nOutputSignalId;
     gulong m_nInputSignalId;
@@ -12252,6 +12253,7 @@ public:
     GtkInstanceFormattedSpinButton(GtkSpinButton* pButton, GtkInstanceBuilder* 
pBuilder, bool bTakeOwnership)
         : GtkInstanceEntry(GTK_ENTRY(pButton), pBuilder, bTakeOwnership)
         , m_pButton(pButton)
+        , m_pFormatter(nullptr)
         , m_nValueChangedSignalId(g_signal_connect(pButton, "value-changed", 
G_CALLBACK(signalValueChanged), this))
         , m_nOutputSignalId(g_signal_connect(pButton, "output", 
G_CALLBACK(signalOutput), this))
         , m_nInputSignalId(g_signal_connect(pButton, "input", 
G_CALLBACK(signalInput), this))
@@ -12271,27 +12273,28 @@ public:
 
     virtual void connect_changed(const Link<weld::Entry&, void>& rLink) 
override
     {
-        if (!m_xFormatter) // once a formatter is set, it takes over "changed"
+        if (!m_pFormatter) // once a formatter is set, it takes over "changed"
         {
             GtkInstanceEntry::connect_changed(rLink);
             return;
         }
-        m_xFormatter->connect_changed(rLink);
+        m_pFormatter->connect_changed(rLink);
     }
 
     virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) 
override
     {
-        if (!m_xFormatter) // once a formatter is set, it takes over 
"focus-out"
+        if (!m_pFormatter) // once a formatter is set, it takes over 
"focus-out"
         {
             GtkInstanceEntry::connect_focus_out(rLink);
             return;
         }
-        m_xFormatter->connect_focus_out(rLink);
+        m_pFormatter->connect_focus_out(rLink);
     }
 
     virtual void SetFormatter(weld::EntryFormatter* pFormatter) override
     {
-        m_xFormatter.reset(pFormatter);
+        m_xOwnFormatter.reset();
+        m_pFormatter = pFormatter;
         sync_range_from_formatter();
         sync_value_from_formatter();
         sync_increments_from_formatter();
@@ -12299,7 +12302,7 @@ public:
 
     virtual weld::EntryFormatter& GetFormatter() override
     {
-        if (!m_xFormatter)
+        if (!m_pFormatter)
         {
             auto aFocusOutHdl = m_aFocusOutHdl;
             m_aFocusOutHdl = Link<weld::Widget&, void>();
@@ -12311,38 +12314,46 @@ public:
             gtk_spin_button_get_range(m_pButton, &fMin, &fMax);
             double fStep;
             gtk_spin_button_get_increments(m_pButton, &fStep, nullptr);
-            m_xFormatter.reset(new weld::EntryFormatter(*this));
-            m_xFormatter->SetMinValue(fMin);
-            m_xFormatter->SetMaxValue(fMax);
-            m_xFormatter->SetSpinSize(fStep);
-            m_xFormatter->SetValue(fValue);
+            m_xOwnFormatter.reset(new weld::EntryFormatter(*this));
+            m_xOwnFormatter->SetMinValue(fMin);
+            m_xOwnFormatter->SetMaxValue(fMax);
+            m_xOwnFormatter->SetSpinSize(fStep);
+            m_xOwnFormatter->SetValue(fValue);
 
-            m_xFormatter->connect_focus_out(aFocusOutHdl);
-            m_xFormatter->connect_changed(aChangeHdl);
+            m_xOwnFormatter->connect_focus_out(aFocusOutHdl);
+            m_xOwnFormatter->connect_changed(aChangeHdl);
+
+            m_pFormatter = m_xOwnFormatter.get();
         }
-        return *m_xFormatter;
+        return *m_pFormatter;
     }
 
     virtual void sync_value_from_formatter() override
     {
+        if (!m_pFormatter)
+            return;
         disable_notify_events();
-        gtk_spin_button_set_value(m_pButton, m_xFormatter->GetValue());
+        gtk_spin_button_set_value(m_pButton, m_pFormatter->GetValue());
         enable_notify_events();
     }
 
     virtual void sync_range_from_formatter() override
     {
+        if (!m_pFormatter)
+            return;
         disable_notify_events();
-        double fMin = m_xFormatter->HasMinValue() ? 
m_xFormatter->GetMinValue() : std::numeric_limits<double>::lowest();
-        double fMax = m_xFormatter->HasMaxValue() ? 
m_xFormatter->GetMaxValue() : std::numeric_limits<double>::max();
+        double fMin = m_pFormatter->HasMinValue() ? 
m_pFormatter->GetMinValue() : std::numeric_limits<double>::lowest();
+        double fMax = m_pFormatter->HasMaxValue() ? 
m_pFormatter->GetMaxValue() : std::numeric_limits<double>::max();
         gtk_spin_button_set_range(m_pButton, fMin, fMax);
         enable_notify_events();
     }
 
     virtual void sync_increments_from_formatter() override
     {
+        if (!m_pFormatter)
+            return;
         disable_notify_events();
-        double fSpinSize = m_xFormatter->GetSpinSize();
+        double fSpinSize = m_pFormatter->GetSpinSize();
         gtk_spin_button_set_increments(m_pButton, fSpinSize, fSpinSize * 10);
         enable_notify_events();
     }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to