chart2/source/controller/dialogs/res_Trendline.cxx | 22 + chart2/source/controller/dialogs/tp_AxisPositions.cxx | 27 +- chart2/source/controller/dialogs/tp_Scale.cxx | 76 ++++-- extensions/source/propctrlr/usercontrol.cxx | 47 ++- extensions/source/propctrlr/usercontrol.hxx | 4 framework/source/uielement/spinfieldtoolbarcontroller.cxx | 62 +---- include/vcl/fmtfield.hxx | 1 include/vcl/formatter.hxx | 12 include/vcl/weld.hxx | 46 +-- include/vcl/weldutils.hxx | 23 + vcl/source/app/salvtables.cxx | 76 ------ vcl/source/app/weldutils.cxx | 76 +++++- vcl/source/control/fmtfield.cxx | 17 - vcl/unx/gtk3/gtk3gtkinst.cxx | 173 ++++---------- 14 files changed, 332 insertions(+), 330 deletions(-)
New commits: commit 95cfa85395f983df3ba044192b29ce0bbc5e6085 Author: Caolán McNamara <[email protected]> AuthorDate: Fri Jul 3 12:08:02 2020 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Sun Jul 5 16:44:09 2020 +0200 adjust FormattedSpinButton to be driven by an EntryFormatter so we can have the same backend driving the FormattedSpinButtons as a FormattedEntry Change-Id: I07a472315a04787eb5fcf992cde8f758af742156 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97860 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/chart2/source/controller/dialogs/res_Trendline.cxx b/chart2/source/controller/dialogs/res_Trendline.cxx index 0eaea7b4e163..11514a19a84a 100644 --- a/chart2/source/controller/dialogs/res_Trendline.cxx +++ b/chart2/source/controller/dialogs/res_Trendline.cxx @@ -24,6 +24,7 @@ #include <svl/intitem.hxx> #include <svl/stritem.hxx> #include <svl/zforlist.hxx> +#include <vcl/formatter.hxx> #include <vcl/weld.hxx> namespace chart @@ -31,8 +32,9 @@ namespace chart static void lcl_setValue(weld::FormattedSpinButton& rFmtField, double fValue ) { - rFmtField.set_value(fValue); -//TODO rFmtField.SetDefaultValue( fValue ); + Formatter& rFieldFormatter = rFmtField.GetFormatter(); + rFieldFormatter.SetValue(fValue); + rFieldFormatter.SetDefaultValue( fValue ); } TrendlineResources::TrendlineResources(weld::Builder& rBuilder, const SfxItemSet& rInAttrs) @@ -66,6 +68,16 @@ TrendlineResources::TrendlineResources(weld::Builder& rBuilder, const SfxItemSet { FillValueSets(); + Formatter& rForwardFormatter = m_xFmtFld_ExtrapolateForward->GetFormatter(); + rForwardFormatter.ClearMinValue(); + rForwardFormatter.ClearMaxValue(); + Formatter& rBackwardFormatter = m_xFmtFld_ExtrapolateBackward->GetFormatter(); + rBackwardFormatter.ClearMinValue(); + rBackwardFormatter.ClearMaxValue(); + Formatter& rInterceptFormatter = m_xFmtFld_InterceptValue->GetFormatter(); + rInterceptFormatter.ClearMinValue(); + rInterceptFormatter.ClearMaxValue(); + Link<weld::ToggleButton&,void> aLink = LINK(this, TrendlineResources, SelectTrendLine); m_xRB_Linear->connect_toggled( aLink ); m_xRB_Logarithmic->connect_toggled( aLink ); @@ -369,9 +381,9 @@ IMPL_LINK_NOARG(TrendlineResources, ChangeFormattedValue, weld::FormattedSpinBut void TrendlineResources::SetNumFormatter( SvNumberFormatter* pFormatter ) { m_pNumFormatter = pFormatter; - m_xFmtFld_ExtrapolateForward->set_formatter( m_pNumFormatter ); - m_xFmtFld_ExtrapolateBackward->set_formatter( m_pNumFormatter ); - m_xFmtFld_InterceptValue->set_formatter( m_pNumFormatter ); + m_xFmtFld_ExtrapolateForward->GetFormatter().SetFormatter(m_pNumFormatter); + m_xFmtFld_ExtrapolateBackward->GetFormatter().SetFormatter(m_pNumFormatter); + m_xFmtFld_InterceptValue->GetFormatter().SetFormatter(m_pNumFormatter); } void TrendlineResources::SetNbPoints( sal_Int32 nNbPoints ) diff --git a/chart2/source/controller/dialogs/tp_AxisPositions.cxx b/chart2/source/controller/dialogs/tp_AxisPositions.cxx index 89b8c3899881..f94f09b98690 100644 --- a/chart2/source/controller/dialogs/tp_AxisPositions.cxx +++ b/chart2/source/controller/dialogs/tp_AxisPositions.cxx @@ -25,6 +25,7 @@ #include <rtl/math.hxx> #include <svx/chrtitem.hxx> #include <svl/intitem.hxx> +#include <vcl/formatter.hxx> using namespace ::com::sun::star; @@ -59,10 +60,12 @@ AxisPositionsTabPage::AxisPositionsTabPage(weld::Container* pPage, weld::DialogC m_xLB_CrossesAt->connect_changed(LINK(this, AxisPositionsTabPage, CrossesAtSelectHdl)); m_xLB_PlaceLabels->connect_changed(LINK(this, AxisPositionsTabPage, PlaceLabelsSelectHdl)); - const double nMin = static_cast<double>(SAL_MIN_INT64); - const double nMax = static_cast<double>(SAL_MAX_INT64); - m_xED_CrossesAt->set_range(nMin, nMax); - m_xED_LabelDistance->set_range(nMin, nMax); + Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter(); + rCrossFormatter.ClearMinValue(); + rCrossFormatter.ClearMaxValue(); + Formatter& rDistanceFormatter = m_xED_CrossesAt->GetFormatter(); + rDistanceFormatter.ClearMinValue(); + rDistanceFormatter.ClearMaxValue(); } AxisPositionsTabPage::~AxisPositionsTabPage() @@ -81,7 +84,8 @@ bool AxisPositionsTabPage::FillItemSet(SfxItemSet* rOutAttrs) rOutAttrs->Put( SfxInt32Item( SCHATTR_AXIS_POSITION, nPos+1 )); if( nPos==2 ) { - double fCrossover = m_xED_CrossesAt->get_value(); + Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter(); + double fCrossover = rCrossFormatter.GetValue(); if( m_bCrossingAxisIsCategoryAxis ) fCrossover = m_xED_CrossesAtCategory->get_active()+1; rOutAttrs->Put(SvxDoubleItem(fCrossover,SCHATTR_AXIS_POSITION_VALUE)); @@ -167,7 +171,10 @@ void AxisPositionsTabPage::Reset(const SfxItemSet* rInAttrs) if( m_bCrossingAxisIsCategoryAxis ) m_xED_CrossesAtCategory->set_active( static_cast<sal_uInt16>(::rtl::math::round(fCrossover-1.0)) ); else - m_xED_CrossesAt->set_value(fCrossover); + { + Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter(); + rCrossFormatter.SetValue(fCrossover); + } } else { @@ -251,13 +258,15 @@ DeactivateRC AxisPositionsTabPage::DeactivatePage(SfxItemSet* pItemSet) void AxisPositionsTabPage::SetNumFormatter( SvNumberFormatter* pFormatter ) { m_pNumFormatter = pFormatter; - m_xED_CrossesAt->set_formatter(m_pNumFormatter); + Formatter& rCrossFormatter = m_xED_CrossesAt->GetFormatter(); + rCrossFormatter.SetFormatter(m_pNumFormatter); + rCrossFormatter.UseInputStringForFormatting(); const SfxPoolItem *pPoolItem = nullptr; if( GetItemSet().GetItemState( SCHATTR_AXIS_CROSSING_MAIN_AXIS_NUMBERFORMAT, true, &pPoolItem ) == SfxItemState::SET ) { sal_uLong nFmt = static_cast<const SfxUInt32Item*>(pPoolItem)->GetValue(); - m_xED_CrossesAt->set_format_key( nFmt ); + rCrossFormatter.SetFormatKey(nFmt); } } @@ -288,7 +297,7 @@ IMPL_LINK_NOARG(AxisPositionsTabPage, CrossesAtSelectHdl, weld::ComboBox&, void) m_xED_CrossesAtCategory->set_visible( (nPos==2) && m_bCrossingAxisIsCategoryAxis ); if (m_xED_CrossesAt->get_text().isEmpty()) - m_xED_CrossesAt->set_value(0.0); + m_xED_CrossesAt->GetFormatter().SetValue(0.0); if (m_xED_CrossesAtCategory->get_active() == -1) m_xED_CrossesAtCategory->set_active(0); diff --git a/chart2/source/controller/dialogs/tp_Scale.cxx b/chart2/source/controller/dialogs/tp_Scale.cxx index 0c626667790c..b9b31019803d 100644 --- a/chart2/source/controller/dialogs/tp_Scale.cxx +++ b/chart2/source/controller/dialogs/tp_Scale.cxx @@ -29,6 +29,7 @@ #include <svx/chrtitem.hxx> #include <svl/eitem.hxx> #include <svl/intitem.hxx> +#include <vcl/formatter.hxx> #include <vcl/weld.hxx> #include <svl/zformat.hxx> #include <vcl/svapp.hxx> @@ -45,7 +46,7 @@ namespace void lcl_setValue(weld::FormattedSpinButton& rFmtField, double fValue) { - rFmtField.set_value(fValue); + rFmtField.GetFormatter().SetValue(fValue); } } @@ -97,12 +98,18 @@ ScaleTabPage::ScaleTabPage(weld::Container* pPage, weld::DialogController* pCont m_xCbxAutoOrigin->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl)); m_xCbx_AutoTimeResolution->connect_toggled(LINK(this, ScaleTabPage, EnableValueHdl)); - const double nMin = static_cast<double>(SAL_MIN_INT64); - const double nMax = static_cast<double>(SAL_MAX_INT64); - m_xFmtFldMin->set_range(nMin, nMax); - m_xFmtFldMax->set_range(nMin, nMax); - m_xFmtFldStepMain->set_range(nMin, nMax); - m_xFmtFldOrigin->set_range(nMin, nMax); + Formatter& rFmtFldMax = m_xFmtFldMax->GetFormatter(); + rFmtFldMax.ClearMinValue(); + rFmtFldMax.ClearMaxValue(); + Formatter& rFmtFldMin = m_xFmtFldMin->GetFormatter(); + rFmtFldMin.ClearMinValue(); + rFmtFldMin.ClearMaxValue(); + Formatter& rFmtFldStepMain = m_xFmtFldStepMain->GetFormatter(); + rFmtFldStepMain.ClearMinValue(); + rFmtFldStepMain.ClearMaxValue(); + Formatter& rFmtFldOrigin = m_xFmtFldOrigin->GetFormatter(); + rFmtFldOrigin.ClearMinValue(); + rFmtFldOrigin.ClearMaxValue(); m_xLB_AxisType->connect_changed(LINK(this, ScaleTabPage, SelectAxisTypeHdl)); @@ -144,7 +151,7 @@ void ScaleTabPage::EnableControls() if( bWasDateAxis ) lcl_setValue( *m_xFmtFldStepMain, m_xMt_MainDateStep->get_value() ); else - m_xMt_MainDateStep->set_value(m_xFmtFldStepMain->get_value()); + m_xMt_MainDateStep->set_value(m_xFmtFldStepMain->GetFormatter().GetValue()); } m_xFmtFldStepMain->set_visible( bValueAxis && !bDateAxis ); @@ -379,11 +386,11 @@ DeactivateRC ScaleTabPage::DeactivatePage(SfxItemSet* pItemSet) bool bDateAxis = m_nAxisType == chart2::AxisType::DATE; - sal_uInt32 nMinMaxOriginFmt = m_xFmtFldMax->get_format_key(); + sal_uInt32 nMinMaxOriginFmt = m_xFmtFldMax->GetFormatter().GetFormatKey(); if (pNumFormatter->GetType(nMinMaxOriginFmt) == SvNumFormatType::TEXT) nMinMaxOriginFmt = 0; // numberformat_text cause numbers to fail being numbers... Shouldn't happen, but can. - sal_uInt32 nStepFmt = m_xFmtFldStepMain->get_format_key(); + sal_uInt32 nStepFmt = m_xFmtFldStepMain->GetFormatter().GetFormatKey(); if (pNumFormatter->GetType(nStepFmt) == SvNumFormatType::TEXT) nStepFmt = 0; @@ -391,10 +398,10 @@ DeactivateRC ScaleTabPage::DeactivatePage(SfxItemSet* pItemSet) const char* pErrStrId = nullptr; double fDummy; - fMax = m_xFmtFldMax->get_value(); - fMin = m_xFmtFldMin->get_value(); - fOrigin = m_xFmtFldOrigin->get_value(); - fStepMain = bDateAxis ? m_xMt_MainDateStep->get_value() : m_xFmtFldStepMain->get_value(); + fMax = m_xFmtFldMax->GetFormatter().GetValue(); + fMin = m_xFmtFldMin->GetFormatter().GetValue(); + fOrigin = m_xFmtFldOrigin->GetFormatter().GetValue(); + fStepMain = bDateAxis ? m_xMt_MainDateStep->get_value() : m_xFmtFldStepMain->GetFormatter().GetValue(); nStepHelp = m_xMtStepHelp->get_value(); m_nTimeResolution = m_xLB_TimeResolution->get_active(); m_nMainTimeUnit = m_xLB_MainTimeUnit->get_active(); @@ -491,10 +498,26 @@ DeactivateRC ScaleTabPage::DeactivatePage(SfxItemSet* pItemSet) void ScaleTabPage::SetNumFormatter( SvNumberFormatter* pFormatter ) { pNumFormatter = pFormatter; - m_xFmtFldMax->set_formatter( pNumFormatter ); - m_xFmtFldMin->set_formatter( pNumFormatter ); - m_xFmtFldStepMain->set_formatter( pNumFormatter ); - m_xFmtFldOrigin->set_formatter( pNumFormatter ); + + Formatter& rFmtFldMax = m_xFmtFldMax->GetFormatter(); + Formatter& rFmtFldMin = m_xFmtFldMin->GetFormatter(); + Formatter& rFmtFldStepMain = m_xFmtFldStepMain->GetFormatter(); + Formatter& rFmtFldOrigin = m_xFmtFldOrigin->GetFormatter(); + + rFmtFldMax.SetFormatter( pNumFormatter ); + rFmtFldMin.SetFormatter( pNumFormatter ); + rFmtFldStepMain.SetFormatter( pNumFormatter ); + rFmtFldOrigin.SetFormatter( pNumFormatter ); + + // #i6278# allow more decimal places than the output format. As + // the numbers shown in the edit fields are used for input, it makes more + // sense to display the values in the input format rather than the output + // format. + rFmtFldMax.UseInputStringForFormatting(); + rFmtFldMin.UseInputStringForFormatting(); + rFmtFldStepMain.UseInputStringForFormatting(); + rFmtFldOrigin.UseInputStringForFormatting(); + SetNumFormat(); } @@ -507,9 +530,12 @@ void ScaleTabPage::SetNumFormat() sal_uLong nFmt = static_cast<const SfxUInt32Item*>(pPoolItem)->GetValue(); - m_xFmtFldMax->set_format_key(nFmt); - m_xFmtFldMin->set_format_key(nFmt); - m_xFmtFldOrigin->set_format_key(nFmt); + Formatter& rFmtFldMax = m_xFmtFldMax->GetFormatter(); + rFmtFldMax.SetFormatKey(nFmt); + Formatter& rFmtFldMin = m_xFmtFldMin->GetFormatter(); + rFmtFldMin.SetFormatKey(nFmt); + Formatter& rFmtFldOrigin = m_xFmtFldOrigin->GetFormatter(); + rFmtFldOrigin.SetFormatKey(nFmt); if( pNumFormatter ) { @@ -541,13 +567,13 @@ void ScaleTabPage::SetNumFormat() else nFmt = pNumFormatter->GetStandardFormat( SvNumFormatType::DATE ); - m_xFmtFldMax->set_format_key(nFmt); - m_xFmtFldMin->set_format_key(nFmt); - m_xFmtFldOrigin->set_format_key(nFmt); + rFmtFldMax.SetFormatKey(nFmt); + rFmtFldMin.SetFormatKey(nFmt); + rFmtFldOrigin.SetFormatKey(nFmt); } } - m_xFmtFldStepMain->set_format_key(nFmt); + m_xFmtFldStepMain->GetFormatter().SetFormatKey(nFmt); } void ScaleTabPage::ShowAxisOrigin( bool bShowOrigin ) diff --git a/extensions/source/propctrlr/usercontrol.cxx b/extensions/source/propctrlr/usercontrol.cxx index cab4402c77d8..4fef3424cc7c 100644 --- a/extensions/source/propctrlr/usercontrol.cxx +++ b/extensions/source/propctrlr/usercontrol.cxx @@ -55,18 +55,19 @@ namespace pcr void OFormatSampleControl::SetFormatSupplier( const SvNumberFormatsSupplierObj* pSupplier ) { + Formatter& rFieldFormatter = m_xSpinButton->GetFormatter(); if (pSupplier) { - m_xSpinButton->treat_as_number(true); + rFieldFormatter.TreatAsNumber(true); SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter(); - m_xSpinButton->set_formatter(pFormatter); - m_xSpinButton->set_value( 1234.56789 ); + rFieldFormatter.SetFormatter(pFormatter); + rFieldFormatter.SetValue( 1234.56789 ); } else { - m_xSpinButton->treat_as_number(false); - m_xSpinButton->set_formatter(nullptr); + rFieldFormatter.TreatAsNumber(false); + rFieldFormatter.SetFormatter(nullptr); m_xSpinButton->set_text( "" ); } @@ -78,7 +79,8 @@ namespace pcr , m_xSpinButton(m_xBuilder->weld_formatted_spin_button("sample")) , m_xEntry(m_xBuilder->weld_entry("entry")) { - m_xSpinButton->treat_as_number(true); + Formatter& rFieldFormatter = m_xSpinButton->GetFormatter(); + rFieldFormatter.TreatAsNumber(true); m_xEntry->connect_key_press(LINK(this, OFormatSampleControl, KeyInputHdl)); } @@ -88,9 +90,10 @@ namespace pcr if ( _rValue >>= nFormatKey ) { // else set the new format key, the text will be reformatted - m_xSpinButton->set_format_key( nFormatKey ); + Formatter& rFieldFormatter = m_xSpinButton->GetFormatter(); + rFieldFormatter.SetFormatKey(nFormatKey); - SvNumberFormatter* pNF = m_xSpinButton->get_formatter(); + SvNumberFormatter* pNF = rFieldFormatter.GetFormatter(); const SvNumberformat* pEntry = pNF->GetEntry( nFormatKey ); OSL_ENSURE( pEntry, "OFormatSampleControl::setValue: invalid format entry!" ); @@ -98,7 +101,7 @@ namespace pcr if ( bIsTextFormat ) m_xSpinButton->set_text( PcrRes( RID_STR_TEXT_FORMAT ) ); else - m_xSpinButton->set_value( pEntry ? getPreviewValue( *pEntry ) : 1234.56789 ); + rFieldFormatter.SetValue( pEntry ? getPreviewValue( *pEntry ) : 1234.56789 ); } else m_xSpinButton->set_text( "" ); @@ -146,7 +149,10 @@ namespace pcr { Any aPropValue; if ( !m_xSpinButton->get_text().isEmpty() ) - aPropValue <<= m_xSpinButton->get_value(); + { + Formatter& rFieldFormatter = m_xSpinButton->GetFormatter(); + aPropValue <<= rFieldFormatter.GetValue(); + } return aPropValue; } @@ -158,7 +164,7 @@ namespace pcr OFormattedNumericControl::OFormattedNumericControl(std::unique_ptr<weld::FormattedSpinButton> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly) : OFormattedNumericControl_Base(PropertyControlType::Unknown, std::move(xBuilder), std::move(xWidget), bReadOnly) { - getTypedControlWindow()->treat_as_number(true); + getTypedControlWindow()->GetFormatter().TreatAsNumber(true); } OFormattedNumericControl::~OFormattedNumericControl() @@ -169,7 +175,7 @@ namespace pcr { double nValue( 0 ); if ( _rValue >>= nValue ) - getTypedControlWindow()->set_value( nValue ); + getTypedControlWindow()->GetFormatter().SetValue(nValue); else getTypedControlWindow()->set_text(""); } @@ -178,7 +184,7 @@ namespace pcr { Any aPropValue; if ( !getTypedControlWindow()->get_text().isEmpty() ) - aPropValue <<= getTypedControlWindow()->get_value(); + aPropValue <<= getTypedControlWindow()->GetFormatter().GetValue(); return aPropValue; } @@ -191,16 +197,17 @@ namespace pcr { bool bFallback = true; + Formatter& rFieldFormatter = getTypedControlWindow()->GetFormatter(); if (rDesc.pSupplier) { - getTypedControlWindow()->treat_as_number(true); + rFieldFormatter.TreatAsNumber(true); SvNumberFormatter* pFormatter = rDesc.pSupplier->GetNumberFormatter(); - if (pFormatter != getTypedControlWindow()->get_formatter()) - getTypedControlWindow()->set_formatter(pFormatter); - getTypedControlWindow()->set_format_key(rDesc.nKey); + if (pFormatter != rFieldFormatter.GetFormatter()) + rFieldFormatter.SetFormatter(pFormatter); + rFieldFormatter.SetFormatKey(rDesc.nKey); - const SvNumberformat* pEntry = getTypedControlWindow()->get_formatter()->GetEntry(getTypedControlWindow()->get_format_key()); + const SvNumberformat* pEntry = rFieldFormatter.GetFormatter()->GetEntry(rFieldFormatter.GetFormatKey()); DBG_ASSERT( pEntry, "OFormattedNumericControl::SetFormatDescription: invalid format key!" ); if ( pEntry ) { @@ -211,8 +218,8 @@ namespace pcr if ( bFallback ) { - getTypedControlWindow()->treat_as_number(false); - getTypedControlWindow()->set_formatter(nullptr); + rFieldFormatter.TreatAsNumber(false); + rFieldFormatter.SetFormatter(nullptr); getTypedControlWindow()->set_text(""); } } diff --git a/extensions/source/propctrlr/usercontrol.hxx b/extensions/source/propctrlr/usercontrol.hxx index 93969d2afb21..002c209ce7b1 100644 --- a/extensions/source/propctrlr/usercontrol.hxx +++ b/extensions/source/propctrlr/usercontrol.hxx @@ -98,8 +98,8 @@ namespace pcr void SetFormatDescription( const FormatDescription& rDesc ); // make some FormattedField methods available - void SetDecimalDigits(sal_uInt16 nPrecision) { getTypedControlWindow()->set_digits(nPrecision); } - void SetDefaultValue(double dDef) { getTypedControlWindow()->set_value(dDef); } + void SetDecimalDigits(sal_uInt16 nPrecision) { getTypedControlWindow()->GetFormatter().SetDecimalDigits(nPrecision); } + void SetDefaultValue(double dDef) { getTypedControlWindow()->GetFormatter().SetDefaultValue(dDef); } virtual void SetModifyHandler() override { diff --git a/framework/source/uielement/spinfieldtoolbarcontroller.cxx b/framework/source/uielement/spinfieldtoolbarcontroller.cxx index 04de7c1a7db5..dfcd5a6c4342 100644 --- a/framework/source/uielement/spinfieldtoolbarcontroller.cxx +++ b/framework/source/uielement/spinfieldtoolbarcontroller.cxx @@ -28,6 +28,7 @@ #include <svtools/toolboxcontroller.hxx> #include <vcl/InterimItemWindow.hxx> #include <vcl/event.hxx> +#include <vcl/formatter.hxx> #include <vcl/svapp.hxx> #include <vcl/toolbox.hxx> #include <o3tl/char16_t2wchar_t.hxx> @@ -59,33 +60,16 @@ public: InterimItemWindow::GetFocus(); } - void set_value(double fValue); - - void set_digits(int nDigits) - { - m_xWidget->set_digits(nDigits); - } - - void set_min(double fMin) - { - m_xWidget->set_min(fMin); - } - - void set_max(double fMax) - { - m_xWidget->set_max(fMax); - } - - void set_step(double fStep) + Formatter& GetFormatter() { - m_xWidget->set_increments(fStep, fStep * 10); + return m_xWidget->GetFormatter(); } OUString get_entry_text() const { return m_xWidget->get_text(); } DECL_LINK(ValueChangedHdl, weld::FormattedSpinButton&, void); - DECL_LINK(FormatOutputHdl, weld::FormattedSpinButton&, void); - DECL_LINK(ParseInputHdl, double*, bool); + DECL_LINK(FormatOutputHdl, LinkParamNone*, bool); + DECL_LINK(ParseInputHdl, sal_Int64*, TriState); DECL_LINK(ModifyHdl, weld::Entry&, void); DECL_LINK(ActivateHdl, weld::Entry&, bool); DECL_LINK(FocusInHdl, weld::Widget&, void); @@ -104,9 +88,10 @@ SpinfieldControl::SpinfieldControl(vcl::Window* pParent, SpinfieldToolbarControl { m_xWidget->connect_focus_in(LINK(this, SpinfieldControl, FocusInHdl)); m_xWidget->connect_focus_out(LINK(this, SpinfieldControl, FocusOutHdl)); + Formatter& rFormatter = m_xWidget->GetFormatter(); + rFormatter.SetOutputHdl(LINK(this, SpinfieldControl, FormatOutputHdl)); + rFormatter.SetInputHdl(LINK(this, SpinfieldControl, ParseInputHdl)); m_xWidget->connect_value_changed(LINK(this, SpinfieldControl, ValueChangedHdl)); - m_xWidget->connect_output(LINK(this, SpinfieldControl, FormatOutputHdl)); - m_xWidget->connect_input(LINK(this, SpinfieldControl, ParseInputHdl)); m_xWidget->connect_changed(LINK(this, SpinfieldControl, ModifyHdl)); m_xWidget->connect_activate(LINK(this, SpinfieldControl, ActivateHdl)); m_xWidget->connect_key_press(LINK(this, SpinfieldControl, KeyInputHdl)); @@ -118,23 +103,15 @@ SpinfieldControl::SpinfieldControl(vcl::Window* pParent, SpinfieldToolbarControl SetSizePixel(get_preferred_size()); } -void SpinfieldControl::set_value(double fValue) -{ - OUString aOutString = m_pSpinfieldToolbarController->FormatOutputString(fValue); - m_xWidget->set_value(fValue); - m_xWidget->set_text(aOutString); - m_pSpinfieldToolbarController->Modify(); -} - IMPL_LINK(SpinfieldControl, KeyInputHdl, const ::KeyEvent&, rKEvt, bool) { return ChildKeyInput(rKEvt); } -IMPL_LINK(SpinfieldControl, ParseInputHdl, double*, result, bool) +IMPL_LINK(SpinfieldControl, ParseInputHdl, sal_Int64*, result, TriState) { - *result = m_xWidget->get_text().toDouble(); - return true; + *result = m_xWidget->get_text().toDouble() * weld::SpinButton::Power10(m_xWidget->GetFormatter().GetDecimalDigits()); + return TRISTATE_TRUE; } SpinfieldControl::~SpinfieldControl() @@ -184,10 +161,11 @@ IMPL_LINK_NOARG(SpinfieldControl, ActivateHdl, weld::Entry&, bool) return bConsumed; } -IMPL_LINK_NOARG(SpinfieldControl, FormatOutputHdl, weld::FormattedSpinButton&, void) +IMPL_LINK_NOARG(SpinfieldControl, FormatOutputHdl, LinkParamNone*, bool) { - OUString aText = m_pSpinfieldToolbarController->FormatOutputString(m_xWidget->get_value()); + OUString aText = m_pSpinfieldToolbarController->FormatOutputString(m_xWidget->GetFormatter().GetValue()); m_xWidget->set_text(aText); + return true; } SpinfieldToolbarController::SpinfieldToolbarController( @@ -387,29 +365,31 @@ void SpinfieldToolbarController::executeControlCommand( const css::frame::Contro } } + Formatter& rFormatter = m_pSpinfieldControl->GetFormatter(); + // Check values and set members if (bFloatValue) - m_pSpinfieldControl->set_digits(2); + rFormatter.SetDecimalDigits(2); if ( !aValue.isEmpty() ) { m_bFloat = bFloatValue; m_nValue = aValue.toDouble(); - m_pSpinfieldControl->set_value(m_nValue); + rFormatter.SetValue(m_nValue); } if ( !aMax.isEmpty() ) { m_nMax = aMax.toDouble(); - m_pSpinfieldControl->set_max(m_nMax); + rFormatter.SetMaxValue(m_nMax); } if ( !aMin.isEmpty() ) { m_nMin = aMin.toDouble(); - m_pSpinfieldControl->set_min(m_nMin); + rFormatter.SetMinValue(m_nMin); } if ( !aStep.isEmpty() ) { m_nStep = aStep.toDouble(); - m_pSpinfieldControl->set_step(m_nStep); + rFormatter.SetSpinSize(m_nStep); } } diff --git a/include/vcl/fmtfield.hxx b/include/vcl/fmtfield.hxx index 26715e687218..1d92a1b957b4 100644 --- a/include/vcl/fmtfield.hxx +++ b/include/vcl/fmtfield.hxx @@ -48,6 +48,7 @@ public: virtual FactoryFunction GetUITestFactory() const override; Formatter* GetFormatter(); + void SetFormatter(Formatter* pFormatter); protected: std::unique_ptr<Formatter> m_xFormatter; diff --git a/include/vcl/formatter.hxx b/include/vcl/formatter.hxx index f54d59ca4600..4f9a016cc6da 100644 --- a/include/vcl/formatter.hxx +++ b/include/vcl/formatter.hxx @@ -156,13 +156,13 @@ public: // Min-/Max-management bool HasMinValue() const { return m_bHasMin; } - void ClearMinValue() { m_bHasMin = false; } - void SetMinValue(double dMin); + virtual void ClearMinValue() { m_bHasMin = false; } + virtual void SetMinValue(double dMin); double GetMinValue() const { return m_dMinValue; } bool HasMaxValue() const { return m_bHasMax; } - void ClearMaxValue() { m_bHasMax = false; } - void SetMaxValue(double dMax); + virtual void ClearMaxValue() { m_bHasMax = false; } + virtual void SetMaxValue(double dMax); double GetMaxValue() const { return m_dMaxValue; } // Current value @@ -219,7 +219,7 @@ public: void SetStrictFormat(bool bEnable) { m_bStrictFormat = bEnable; } // Check format during input - void SetSpinSize(double dStep) { m_dSpinSize = dStep; } + virtual void SetSpinSize(double dStep) { m_dSpinSize = dStep; } double GetSpinSize() const { return m_dSpinSize; } void SetSpinFirst(double dFirst) { m_dSpinFirst = dFirst; } @@ -304,6 +304,8 @@ protected: SvNumberFormatter* CreateFormatter() { SetFormatter(StandardFormatter()); return m_pFormatter; } + virtual void UpdateCurrentValue(double dCurrentValue) { m_dCurrentValue = dCurrentValue; } + void ReFormat(); }; diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index ee110a049888..88dbcf0dad5f 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -62,6 +62,7 @@ typedef css::uno::Reference<css::accessibility::XAccessibleRelationSet> a11yrela enum class PointerStyle; class CommandEvent; class KeyEvent; +class Formatter; class MouseEvent; class SvNumberFormatter; class TransferDataContainer; @@ -1506,7 +1507,7 @@ public: */ virtual void set_font_color(const Color& rColor) = 0; - void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; } + virtual void connect_changed(const Link<Entry&, void>& rLink) { m_aChangeHdl = rLink; } void connect_insert_text(const Link<OUString&, bool>& rLink) { m_aInsertTextHdl = rLink; } // callback returns true to indicated no further processing of activate wanted void connect_activate(const Link<Entry&, bool>& rLink) { m_aActivateHdl = rLink; } @@ -1596,52 +1597,31 @@ public: static unsigned int Power10(unsigned int n); }; +class EntryFormatter; + +// Similar to a SpinButton, but input and output formatting and range/value +// are managed by a more complex Formatter which can support doubles. class VCL_DLLPUBLIC FormattedSpinButton : virtual public Entry { protected: Link<FormattedSpinButton&, void> m_aValueChangedHdl; - Link<FormattedSpinButton&, void> m_aOutputHdl; - Link<double*, bool> m_aInputHdl; void signal_value_changed() { m_aValueChangedHdl.Call(*this); } public: - virtual void set_value(double value) = 0; - virtual double get_value() const = 0; - virtual void set_range(double min, double max) = 0; - virtual void get_range(double& min, double& max) const = 0; - virtual void set_increments(double step, double page) = 0; - - void set_min(double min) - { - double max, dummy; - get_range(dummy, max); - set_range(min, max); - } - - void set_max(double max) - { - double min, dummy; - get_range(min, dummy); - set_range(min, max); - } - - virtual void set_formatter(SvNumberFormatter* pFormatter) = 0; - virtual SvNumberFormatter* get_formatter() = 0; - virtual sal_Int32 get_format_key() const = 0; - virtual void set_format_key(sal_Int32 nFormatKey) = 0; - - virtual void set_digits(unsigned int digits) = 0; - - virtual void treat_as_number(bool bSet) = 0; + virtual Formatter& GetFormatter() = 0; + virtual void SetFormatter(weld::EntryFormatter* pFormatter) = 0; void connect_value_changed(const Link<FormattedSpinButton&, void>& rLink) { m_aValueChangedHdl = rLink; } - void connect_output(const Link<FormattedSpinButton&, void>& rLink) { m_aOutputHdl = rLink; } - void connect_input(const Link<double*, bool>& rLink) { m_aInputHdl = rLink; } +private: + friend class EntryFormatter; + virtual void sync_range_from_formatter() = 0; + virtual void sync_value_from_formatter() = 0; + virtual void sync_increments_from_formatter() = 0; }; class VCL_DLLPUBLIC Image : virtual public Widget diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx index 299d3ee3135b..757303fdcabf 100644 --- a/include/vcl/weldutils.hxx +++ b/include/vcl/weldutils.hxx @@ -158,12 +158,17 @@ class VCL_DLLPUBLIC EntryFormatter : public Formatter { public: EntryFormatter(weld::Entry& rEntry); + EntryFormatter(weld::FormattedSpinButton& rSpinButton); + // EntryFormatter will set listeners to "changed" and "focus-out" of the + // entry so users that want to add their own listeners to those must set + // them through this formatter and not directly on the entry void connect_changed(const Link<weld::Entry&, void>& rLink) { m_aModifyHdl = rLink; } + void connect_focus_out(const Link<weld::Widget&, void>& rLink) { m_aFocusOutHdl = rLink; } weld::Entry& get_widget() { return m_rEntry; } - // Formatter overrides + // public Formatter overrides, drives interactions with the Entry virtual Selection GetEntrySelection() const override; virtual OUString GetEntryText() const override; virtual void SetEntryText(const OUString& rText, const Selection& rSel) override; @@ -171,14 +176,30 @@ public: virtual SelectionOptions GetEntrySelectionOptions() const override; virtual void FieldModified() override; + // public Formatter overrides, drives optional SpinButton settings + virtual void ClearMinValue() override; + virtual void SetMinValue(double dMin) override; + virtual void ClearMaxValue() override; + virtual void SetMaxValue(double dMin) override; + + virtual void SetSpinSize(double dStep) override; + void SetEntrySelectionOptions(SelectionOptions eOptions) { m_eOptions = eOptions; } + virtual ~EntryFormatter() override; + private: weld::Entry& m_rEntry; + weld::FormattedSpinButton* m_pSpinButton; Link<weld::Entry&, void> m_aModifyHdl; + Link<weld::Widget&, void> m_aFocusOutHdl; SelectionOptions m_eOptions; DECL_DLLPRIVATE_LINK(ModifyHdl, weld::Entry&, void); DECL_DLLPRIVATE_LINK(FocusOutHdl, weld::Widget&, void); + void Init(); + + // private Formatter overrides + virtual void UpdateCurrentValue(double dCurrentValue) override; }; // get the row the iterator is on diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 22b8329cb9f5..f646beb64d9a 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -65,6 +65,7 @@ #include <vcl/toolkit/throbber.hxx> #include <vcl/toolkit/unowrap.hxx> #include <vcl/weld.hxx> +#include <vcl/weldutils.hxx> #include <vcl/vclmedit.hxx> #include <vcl/viewdataentry.hxx> #include <vcl/virdev.hxx> @@ -5325,96 +5326,41 @@ class SalInstanceFormattedSpinButton : public SalInstanceEntry, { private: VclPtr<FormattedField> m_xButton; - Formatter* m_pFormatter; - - DECL_LINK(OutputHdl, LinkParamNone*, bool); - DECL_LINK(InputHdl, sal_Int64*, TriState); public: SalInstanceFormattedSpinButton(FormattedField* pButton, SalInstanceBuilder* pBuilder, bool bTakeOwnership) : SalInstanceEntry(pButton, pBuilder, bTakeOwnership) , m_xButton(pButton) - , m_pFormatter(m_xButton->GetFormatter()) - { - m_pFormatter->SetOutputHdl(LINK(this, SalInstanceFormattedSpinButton, OutputHdl)); - m_pFormatter->SetInputHdl(LINK(this, SalInstanceFormattedSpinButton, InputHdl)); - - // #i6278# allow more decimal places than the output format. As - // the numbers shown in the edit fields are used for input, it makes more - // sense to display the values in the input format rather than the output - // format. - m_pFormatter->UseInputStringForFormatting(); - } - - virtual ~SalInstanceFormattedSpinButton() override { - m_pFormatter->SetInputHdl(Link<sal_Int64*, TriState>()); - m_pFormatter->SetOutputHdl(Link<LinkParamNone*, bool>()); } - virtual double get_value() const override { return m_pFormatter->GetValue(); } - - virtual void set_value(double value) override { m_pFormatter->SetValue(value); } - - virtual void set_range(double min, double max) override + virtual void SetFormatter(weld::EntryFormatter* pFormatter) override { - m_pFormatter->SetMinValue(min); - m_pFormatter->SetMaxValue(max); + m_xButton->SetFormatter(pFormatter); } - virtual void get_range(double& min, double& max) const override + virtual void sync_value_from_formatter() override { - min = m_pFormatter->GetMinValue(); - max = m_pFormatter->GetMaxValue(); + // no-op for gen } - virtual void set_increments(double step, double /*page*/) override + virtual void sync_range_from_formatter() override { - m_pFormatter->SetSpinSize(step); + // no-op for gen } - virtual void set_formatter(SvNumberFormatter* pFormatter) override + virtual void sync_increments_from_formatter() override { - m_pFormatter->SetFormatter(pFormatter); + // no-op for gen } - virtual SvNumberFormatter* get_formatter() override { return m_pFormatter->GetFormatter(); } - - virtual sal_Int32 get_format_key() const override { return m_pFormatter->GetFormatKey(); } - - virtual void set_format_key(sal_Int32 nFormatKey) override + virtual Formatter& GetFormatter() override { - m_pFormatter->SetFormatKey(nFormatKey); + return *m_xButton->GetFormatter(); } - - virtual void treat_as_number(bool bSet) override { m_pFormatter->TreatAsNumber(bSet); } - - virtual void set_digits(unsigned int digits) override { m_pFormatter->SetDecimalDigits(digits); } }; -IMPL_LINK_NOARG(SalInstanceFormattedSpinButton, OutputHdl, LinkParamNone*, bool) -{ - // allow an explicit handler - if (!m_aOutputHdl.IsSet()) - return false; - m_aOutputHdl.Call(*this); - return true; -} - -IMPL_LINK(SalInstanceFormattedSpinButton, InputHdl, sal_Int64*, pResult, TriState) -{ - // allow an explicit handler - if (!m_aInputHdl.IsSet()) - return TRISTATE_INDET; - - double value; - TriState eRet = m_aInputHdl.Call(&value) ? TRISTATE_TRUE : TRISTATE_FALSE; - if (eRet == TRISTATE_TRUE) - *pResult = std::round(value * weld::SpinButton::Power10(m_pFormatter->GetDecimalDigits())); - return eRet; -} - } SalInstanceLabel::SalInstanceLabel(Control* pLabel, SalInstanceBuilder* pBuilder, diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx index d9d237cef5c4..f560923e5609 100644 --- a/vcl/source/app/weldutils.cxx +++ b/vcl/source/app/weldutils.cxx @@ -125,9 +125,29 @@ void RemoveParentKeepChildren(weld::TreeView& rTreeView, weld::TreeIter& rParent rTreeView.remove(rParent); } +EntryFormatter::EntryFormatter(weld::FormattedSpinButton& rSpinButton) + : m_rEntry(rSpinButton) + , m_pSpinButton(&rSpinButton) + , m_eOptions(Application::GetSettings().GetStyleSettings().GetSelectionOptions()) +{ + Init(); +} + EntryFormatter::EntryFormatter(weld::Entry& rEntry) : m_rEntry(rEntry) + , m_pSpinButton(nullptr) , m_eOptions(Application::GetSettings().GetStyleSettings().GetSelectionOptions()) +{ + Init(); +} + +EntryFormatter::~EntryFormatter() +{ + m_rEntry.connect_changed(Link<weld::Entry&, void>()); + m_rEntry.connect_focus_out(Link<weld::Widget&, void>()); +} + +void EntryFormatter::Init() { m_rEntry.connect_changed(LINK(this, EntryFormatter, ModifyHdl)); m_rEntry.connect_focus_out(LINK(this, EntryFormatter, FocusOutHdl)); @@ -155,13 +175,65 @@ void EntryFormatter::SetEntryTextColor(const Color* pColor) m_rEntry.set_font_color(pColor ? *pColor : COL_AUTO); } +void EntryFormatter::UpdateCurrentValue(double dCurrentValue) +{ + Formatter::UpdateCurrentValue(dCurrentValue); + if (m_pSpinButton) + m_pSpinButton->sync_value_from_formatter(); +} + +void EntryFormatter::ClearMinValue() +{ + Formatter::ClearMinValue(); + if (m_pSpinButton) + m_pSpinButton->sync_range_from_formatter(); +} + +void EntryFormatter::SetMinValue(double dMin) +{ + Formatter::SetMinValue(dMin); + if (m_pSpinButton) + m_pSpinButton->sync_range_from_formatter(); +} + +void EntryFormatter::ClearMaxValue() +{ + Formatter::ClearMaxValue(); + if (m_pSpinButton) + m_pSpinButton->sync_range_from_formatter(); +} + +void EntryFormatter::SetMaxValue(double dMin) +{ + Formatter::SetMaxValue(dMin); + if (m_pSpinButton) + m_pSpinButton->sync_range_from_formatter(); +} + +void EntryFormatter::SetSpinSize(double dStep) +{ + Formatter::SetSpinSize(dStep); + if (m_pSpinButton) + m_pSpinButton->sync_increments_from_formatter(); +} + SelectionOptions EntryFormatter::GetEntrySelectionOptions() const { return m_eOptions; } void EntryFormatter::FieldModified() { m_aModifyHdl.Call(m_rEntry); } -IMPL_LINK_NOARG(EntryFormatter, ModifyHdl, weld::Entry&, void) { Modify(); } +IMPL_LINK_NOARG(EntryFormatter, ModifyHdl, weld::Entry&, void) +{ + // This leads to FieldModified getting called at the end of Modify() and + // FieldModified then calls any modification callback + Modify(); +} + +IMPL_LINK_NOARG(EntryFormatter, FocusOutHdl, weld::Widget&, void) +{ + EntryLostFocus(); + m_aFocusOutHdl.Call(m_rEntry); +} -IMPL_LINK_NOARG(EntryFormatter, FocusOutHdl, weld::Widget&, void) { EntryLostFocus(); } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/fmtfield.cxx b/vcl/source/control/fmtfield.cxx index d67b0b9ba792..5f1cb134b9d4 100644 --- a/vcl/source/control/fmtfield.cxx +++ b/vcl/source/control/fmtfield.cxx @@ -699,7 +699,6 @@ void Formatter::ReFormat() } } - void Formatter::SetMinValue(double dMin) { DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !"); @@ -754,7 +753,7 @@ void Formatter::ImplSetValue(double dVal, bool bForce) DBG_ASSERT(GetOrCreateFormatter() != nullptr, "FormattedField::ImplSetValue : can't set a value without a formatter !"); m_ValueState = valueDouble; - m_dCurrentValue = dVal; + UpdateCurrentValue(dVal); if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(nullptr)) { @@ -860,13 +859,14 @@ void Formatter::SetValue(double dVal) double Formatter::GetValue() { - if ( !ImplGetValue( m_dCurrentValue ) ) { - if ( m_bEnableNaN ) - ::rtl::math::setNan( &m_dCurrentValue ); + double dValue; + if (m_bEnableNaN) + ::rtl::math::setNan(&dValue); else - m_dCurrentValue = m_dDefaultValue; + dValue = m_dDefaultValue; + UpdateCurrentValue(dValue); } m_ValueState = valueDouble; @@ -1308,6 +1308,11 @@ Formatter* FormattedField::GetFormatter() return m_xFormatter.get(); } +void FormattedField::SetFormatter(Formatter* pFormatter) +{ + m_xFormatter.reset(pFormatter); +} + // currently used by online void FormattedField::SetValueFromString(const OUString& rStr) { diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index a7d8a9cd30a7..bbcb6218aed3 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -12165,39 +12165,14 @@ class GtkInstanceFormattedSpinButton : public GtkInstanceEntry, public virtual w { private: GtkSpinButton* m_pButton; - SvNumberFormatter* m_pFormatter; - Color* m_pLastOutputColor; - sal_uInt32 m_nFormatKey; - bool m_bTreatAsNumber; + std::unique_ptr<weld::EntryFormatter> m_xFormatter; gulong m_nValueChangedSignalId; gulong m_nOutputSignalId; gulong m_nInputSignalId; bool signal_output() { - // allow an explicit handler - if (m_aOutputHdl.IsSet()) - { - m_aOutputHdl.Call(*this); - return true; - } - if (!m_pFormatter) - return false; - double dVal = get_value(); - OUString sNewText; - if (m_pFormatter->IsTextFormat(m_nFormatKey)) - { - // first convert the number as string in standard format - OUString sTemp; - m_pFormatter->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor); - // then encode the string in the corresponding text format - m_pFormatter->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor); - } - else - { - m_pFormatter->GetInputLineString(dVal, m_nFormatKey, sNewText); - } - set_text(sNewText); + GetFormatter().SetValue(gtk_spin_button_get_value(m_pButton)); return true; } @@ -12210,42 +12185,9 @@ private: gint signal_input(double* value) { - // allow an explicit handler - if (m_aInputHdl.IsSet()) - return m_aInputHdl.Call(value) ? 1 : GTK_INPUT_ERROR; - - if (!m_pFormatter) - return 0; - - sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the FormatKey! - - if (m_pFormatter->IsTextFormat(nFormatKey) && m_bTreatAsNumber) - // for detection of values like "1,1" in fields that are formatted as text - nFormatKey = 0; - - OUString sText(get_text()); - - // special treatment for percentage formatting - if (m_pFormatter->GetType(m_nFormatKey) == SvNumFormatType::PERCENT) - { - // the language of our format - LanguageType eLanguage = m_pFormatter->GetEntry(m_nFormatKey)->GetLanguage(); - // the default number format for this language - sal_uLong nStandardNumericFormat = m_pFormatter->GetStandardFormat(SvNumFormatType::NUMBER, eLanguage); - - sal_uInt32 nTempFormat = nStandardNumericFormat; - double dTemp; - if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) && - SvNumFormatType::NUMBER == m_pFormatter->GetType(nTempFormat)) - // the string is equivalent to a number formatted one (has no % sign) -> append it - sText += "%"; - // (with this, an input of '3' becomes '3%', which then by the formatter is translated - // into 0.03. Without this, the formatter would give us the double 3 for an input '3', - // which equals 300 percent. - } - if (!m_pFormatter->IsNumberFormat(sText, nFormatKey, *value)) - return GTK_INPUT_ERROR; - + Formatter& rFormatter = GetFormatter(); + rFormatter.Modify(); + *value = rFormatter.GetValue(); return 1; } @@ -12267,88 +12209,87 @@ public: GtkInstanceFormattedSpinButton(GtkSpinButton* pButton, GtkInstanceBuilder* pBuilder, bool bTakeOwnership) : GtkInstanceEntry(GTK_ENTRY(pButton), pBuilder, bTakeOwnership) , m_pButton(pButton) - , m_pFormatter(nullptr) - , m_pLastOutputColor(nullptr) - , m_nFormatKey(0) - , m_bTreatAsNumber(true) , 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)) { } - virtual double get_value() const override + virtual void connect_changed(const Link<weld::Entry&, void>& rLink) override { - return gtk_spin_button_get_value(m_pButton); - } - - virtual void set_value(double value) override - { - disable_notify_events(); - gtk_spin_button_set_value(m_pButton, value); - enable_notify_events(); - } - - virtual void set_range(double min, double max) override - { - disable_notify_events(); - gtk_spin_button_set_range(m_pButton, min, max); - enable_notify_events(); + if (!m_xFormatter) // once a formatter is set, it takes over "changed" + { + GtkInstanceEntry::connect_changed(rLink); + return; + } + m_xFormatter->connect_changed(rLink); } - virtual void get_range(double& min, double& max) const override + virtual void connect_focus_out(const Link<weld::Widget&, void>& rLink) override { - gtk_spin_button_get_range(m_pButton, &min, &max); + if (!m_xFormatter) // once a formatter is set, it takes over "focus-out" + { + GtkInstanceEntry::connect_focus_out(rLink); + return; + } + m_xFormatter->connect_focus_out(rLink); } - virtual void set_increments(double step, double page) override + virtual void SetFormatter(weld::EntryFormatter* pFormatter) override { - disable_notify_events(); - gtk_spin_button_set_increments(m_pButton, step, page); - enable_notify_events(); + m_xFormatter.reset(pFormatter); + sync_range_from_formatter(); + sync_value_from_formatter(); + sync_increments_from_formatter(); } - virtual void set_formatter(SvNumberFormatter* pFormatter) override + virtual weld::EntryFormatter& GetFormatter() override { - m_pFormatter = pFormatter; - - // calc the default format key from the Office's UI locale - if (m_pFormatter) + if (!m_xFormatter) { - // get the Office's locale and translate - LanguageType eSysLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType( false); - // get the standard numeric format for this language - m_nFormatKey = m_pFormatter->GetStandardFormat( SvNumFormatType::NUMBER, eSysLanguage ); - } - else - m_nFormatKey = 0; - signal_output(); - } + auto aFocusOutHdl = m_aFocusOutHdl; + m_aFocusOutHdl = Link<weld::Widget&, void>(); + auto aChangeHdl = m_aChangeHdl; + m_aChangeHdl = Link<weld::Entry&, void>(); - virtual SvNumberFormatter* get_formatter() override - { - return m_pFormatter; - } + double fValue = gtk_spin_button_get_value(m_pButton); + double fMin, fMax; + 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); - virtual sal_Int32 get_format_key() const override - { - return m_nFormatKey; + m_xFormatter->connect_focus_out(aFocusOutHdl); + m_xFormatter->connect_changed(aChangeHdl); + } + return *m_xFormatter; } - virtual void set_format_key(sal_Int32 nFormatKey) override + virtual void sync_value_from_formatter() override { - m_nFormatKey = nFormatKey; + disable_notify_events(); + gtk_spin_button_set_value(m_pButton, m_xFormatter->GetValue()); + enable_notify_events(); } - virtual void treat_as_number(bool bSet) override + virtual void sync_range_from_formatter() override { - m_bTreatAsNumber = bSet; + disable_notify_events(); + double fMin = m_xFormatter->HasMinValue() ? m_xFormatter->GetMinValue() : DBL_MIN; + double fMax = m_xFormatter->HasMaxValue() ? m_xFormatter->GetMaxValue() : DBL_MAX; + gtk_spin_button_set_range(m_pButton, fMin, fMax); + enable_notify_events(); } - virtual void set_digits(unsigned int digits) override + virtual void sync_increments_from_formatter() override { disable_notify_events(); - gtk_spin_button_set_digits(m_pButton, digits); + double fSpinSize = m_xFormatter->GetSpinSize(); + gtk_spin_button_set_increments(m_pButton, fSpinSize, fSpinSize * 10); enable_notify_events(); } _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
