[Libreoffice-commits] core.git: include/svtools include/vcl svtools/source svx/source vcl/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Wed Jul 15 13:01:12 UTC 2020


 include/svtools/editbrowsebox.hxx     |    6 ++
 include/vcl/field.hxx                 |  102 ----------------------------------
 include/vcl/toolkit/field.hxx         |  102 ++++++++++++++++++++++++++++++++++
 include/vcl/weldutils.hxx             |   35 +++++++++++
 svtools/source/brwbox/ebbcontrols.cxx |   10 +++
 svx/source/fmcomp/gridcell.cxx        |   72 ++++++++++++++----------
 svx/source/inc/gridcell.hxx           |    2 
 vcl/source/app/weldutils.cxx          |   90 ++++++++++++++++++++++++++++++
 vcl/source/control/field2.cxx         |   81 +++++++++++++++++++++++++++
 vcl/source/window/builder.cxx         |   11 +--
 10 files changed, 372 insertions(+), 139 deletions(-)

New commits:
commit 0abbf64dc1ebe9f12523a69ce1cfd25fe189d869
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Mon Jul 13 15:14:21 2020 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Jul 15 15:00:17 2020 +0200

    weld TimeControl
    
    Change-Id: Idb19639eb39bc83fb8bdc7c2181bf63e9c522d18
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98670
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index 6732b9df211e..9ace81d5d3f3 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -746,6 +746,12 @@ namespace svt
         LongCurrencyControl(BrowserDataWin* pParent, bool bSpinVariant);
     };
 
+    class SVT_DLLPUBLIC TimeControl : public FormattedControlBase
+    {
+    public:
+        TimeControl(BrowserDataWin* pParent, bool bSpinVariant);
+    };
+
     //= FormattedFieldCellController
     class SVT_DLLPUBLIC FormattedFieldCellController final : public EditCellController
     {
diff --git a/include/vcl/field.hxx b/include/vcl/field.hxx
index 92cfbbfac65b..1cb4974bfd08 100644
--- a/include/vcl/field.hxx
+++ b/include/vcl/field.hxx
@@ -263,77 +263,6 @@ public:
     bool             IsEnforceValidValue( ) const { return mbEnforceValidValue; }
 };
 
-class UNLESS_MERGELIBS(VCL_DLLPUBLIC) TimeFormatter : public FormatterBase
-{
-private:
-    tools::Time             maLastTime;
-    tools::Time             maMin;
-    tools::Time             maMax;
-    TimeFieldFormat         meFormat;
-    TimeFormat              mnTimeFormat;
-    bool                    mbDuration;
-    bool                    mbEnforceValidValue;
-
-protected:
-    tools::Time             maFieldTime;
-
-                            TimeFormatter(Edit* pEdit);
-
-    SAL_DLLPRIVATE void     ImplTimeReformat( const OUString& rStr, OUString& rOutStr );
-    SAL_DLLPRIVATE void     ImplNewFieldValue( const tools::Time& rTime );
-    SAL_DLLPRIVATE void     ImplSetUserTime( const tools::Time& rNewTime, Selection const * pNewSelection = nullptr );
-    SAL_DLLPRIVATE bool     ImplAllowMalformedInput() const;
-
-public:
-    static OUString         FormatTime(const tools::Time& rNewTime, TimeFieldFormat eFormat, TimeFormat eHourFormat, bool bDuration, const LocaleDataWrapper& rLocaleData);
-    static bool             TextToTime(const OUString& rStr, tools::Time& rTime, TimeFieldFormat eFormat, bool bDuration, const LocaleDataWrapper& rLocaleDataWrapper, bool _bSkipInvalidCharacters = true);
-    static int              GetTimeArea(TimeFieldFormat eFormat, const OUString& rText, int nCursor,
-                                        const LocaleDataWrapper& rLocaleDataWrapper);
-    static tools::Time      SpinTime(bool bUp, const tools::Time& rTime, TimeFieldFormat eFormat,
-                                     bool bDuration, const OUString& rText, int nCursor,
-                                     const LocaleDataWrapper& rLocaleDataWrapper);
-
-    virtual                 ~TimeFormatter() override;
-
-    virtual void            Reformat() override;
-    virtual void            ReformatAll() override;
-
-    void                    SetMin( const tools::Time& rNewMin );
-    const tools::Time&             GetMin() const { return maMin; }
-    void                    SetMax( const tools::Time& rNewMax );
-    const tools::Time&             GetMax() const { return maMax; }
-
-    void                    SetTimeFormat( TimeFormat eNewFormat );
-    TimeFormat              GetTimeFormat() const { return mnTimeFormat;}
-
-    void                    SetFormat( TimeFieldFormat eNewFormat );
-    TimeFieldFormat         GetFormat() const { return meFormat; }
-
-    void                    SetDuration( bool mbDuration );
-    bool                    IsDuration() const { return mbDuration; }
-
-    void                    SetTime( const tools::Time& rNewTime );
-    void                    SetUserTime( const tools::Time& rNewTime );
-    tools::Time             GetTime() const;
-    void                    SetEmptyTime() { FormatterBase::SetEmptyFieldValue(); }
-    bool                    IsEmptyTime() const { return FormatterBase::IsEmptyFieldValue(); }
-
-    /** enables or disables the enforcement of valid values
-
-        If this is set to true (which is the default), then GetTime will always return a valid
-        time, no matter whether the current text can really be interpreted as time. (Note: this
-        is the compatible behavior).
-
-        If this is set to false, the GetTime will return GetInvalidTime, in case the current text
-        cannot be interpreted as time.
-
-        In addition, if this is set to false, the text in the field will <em>not</em> be corrected
-        when the control loses the focus - instead, the invalid input will be preserved.
-    */
-    void                    EnforceValidValue( bool _bEnforce ) { mbEnforceValidValue = _bEnforce; }
-    bool             IsEnforceValidValue( ) const { return mbEnforceValidValue; }
-};
-
 class UNLESS_MERGELIBS(VCL_DLLPUBLIC) PatternField final : public SpinField, public PatternFormatter
 {
 public:
@@ -399,37 +328,6 @@ public:
     virtual void            dispose() override;
 };
 
-class UNLESS_MERGELIBS(VCL_DLLPUBLIC) TimeField final : public SpinField, public TimeFormatter
-{
-private:
-    tools::Time                    maFirst;
-    tools::Time                    maLast;
-
-    SAL_DLLPRIVATE void     ImplTimeSpinArea( bool bUp );
-
-public:
-    explicit                TimeField( vcl::Window* pParent, WinBits nWinStyle );
-
-    virtual bool            PreNotify( NotifyEvent& rNEvt ) override;
-    virtual bool            EventNotify( NotifyEvent& rNEvt ) override;
-    virtual void            DataChanged( const DataChangedEvent& rDCEvt ) override;
-
-    virtual void            Modify() override;
-
-    virtual void            Up() override;
-    virtual void            Down() override;
-    virtual void            First() override;
-    virtual void            Last() override;
-
-    void                    SetFirst( const tools::Time& rNewFirst )   { maFirst = rNewFirst; }
-    const tools::Time&      GetFirst() const                    { return maFirst; }
-    void                    SetLast( const tools::Time& rNewLast )     { maLast = rNewLast; }
-    const tools::Time&      GetLast() const                     { return maLast; }
-
-    void                    SetExtFormat( ExtTimeFieldFormat eFormat );
-    virtual void            dispose() override;
-};
-
 #endif // INCLUDED_VCL_FIELD_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/vcl/toolkit/field.hxx b/include/vcl/toolkit/field.hxx
index f996bd1efcab..6b994b02baea 100644
--- a/include/vcl/toolkit/field.hxx
+++ b/include/vcl/toolkit/field.hxx
@@ -158,6 +158,108 @@ public:
     virtual void            dispose() override;
 };
 
+class UNLESS_MERGELIBS(VCL_DLLPUBLIC) TimeFormatter : public FormatterBase
+{
+private:
+    tools::Time             maLastTime;
+    tools::Time             maMin;
+    tools::Time             maMax;
+    TimeFieldFormat         meFormat;
+    TimeFormat              mnTimeFormat;
+    bool                    mbDuration;
+    bool                    mbEnforceValidValue;
+
+protected:
+    tools::Time             maFieldTime;
+
+                            TimeFormatter(Edit* pEdit);
+
+    SAL_DLLPRIVATE void     ImplTimeReformat( const OUString& rStr, OUString& rOutStr );
+    SAL_DLLPRIVATE void     ImplNewFieldValue( const tools::Time& rTime );
+    SAL_DLLPRIVATE void     ImplSetUserTime( const tools::Time& rNewTime, Selection const * pNewSelection = nullptr );
+    SAL_DLLPRIVATE bool     ImplAllowMalformedInput() const;
+
+public:
+    static OUString         FormatTime(const tools::Time& rNewTime, TimeFieldFormat eFormat, TimeFormat eHourFormat, bool bDuration, const LocaleDataWrapper& rLocaleData);
+    static bool             TextToTime(const OUString& rStr, tools::Time& rTime, TimeFieldFormat eFormat, bool bDuration, const LocaleDataWrapper& rLocaleDataWrapper, bool _bSkipInvalidCharacters = true);
+    static int              GetTimeArea(TimeFieldFormat eFormat, const OUString& rText, int nCursor,
+                                        const LocaleDataWrapper& rLocaleDataWrapper);
+    static tools::Time      SpinTime(bool bUp, const tools::Time& rTime, TimeFieldFormat eFormat,
+                                     bool bDuration, const OUString& rText, int nCursor,
+                                     const LocaleDataWrapper& rLocaleDataWrapper);
+
+    virtual                 ~TimeFormatter() override;
+
+    virtual void            Reformat() override;
+    virtual void            ReformatAll() override;
+
+    void                    SetMin( const tools::Time& rNewMin );
+    const tools::Time&             GetMin() const { return maMin; }
+    void                    SetMax( const tools::Time& rNewMax );
+    const tools::Time&             GetMax() const { return maMax; }
+
+    void                    SetTimeFormat( TimeFormat eNewFormat );
+    TimeFormat              GetTimeFormat() const { return mnTimeFormat;}
+
+    void                    SetFormat( TimeFieldFormat eNewFormat );
+    TimeFieldFormat         GetFormat() const { return meFormat; }
+
+    void                    SetDuration( bool mbDuration );
+    bool                    IsDuration() const { return mbDuration; }
+
+    void                    SetTime( const tools::Time& rNewTime );
+    void                    SetUserTime( const tools::Time& rNewTime );
+    tools::Time             GetTime() const;
+    void                    SetEmptyTime() { FormatterBase::SetEmptyFieldValue(); }
+    bool                    IsEmptyTime() const { return FormatterBase::IsEmptyFieldValue(); }
+
+    /** enables or disables the enforcement of valid values
+
+        If this is set to true (which is the default), then GetTime will always return a valid
+        time, no matter whether the current text can really be interpreted as time. (Note: this
+        is the compatible behavior).
+
+        If this is set to false, the GetTime will return GetInvalidTime, in case the current text
+        cannot be interpreted as time.
+
+        In addition, if this is set to false, the text in the field will <em>not</em> be corrected
+        when the control loses the focus - instead, the invalid input will be preserved.
+    */
+    void                    EnforceValidValue( bool _bEnforce ) { mbEnforceValidValue = _bEnforce; }
+    bool             IsEnforceValidValue( ) const { return mbEnforceValidValue; }
+};
+
+class UNLESS_MERGELIBS(VCL_DLLPUBLIC) TimeField final : public SpinField, public TimeFormatter
+{
+private:
+    tools::Time                    maFirst;
+    tools::Time                    maLast;
+
+    SAL_DLLPRIVATE void     ImplTimeSpinArea( bool bUp );
+
+public:
+    explicit                TimeField( vcl::Window* pParent, WinBits nWinStyle );
+
+    virtual bool            PreNotify( NotifyEvent& rNEvt ) override;
+    virtual bool            EventNotify( NotifyEvent& rNEvt ) override;
+    virtual void            DataChanged( const DataChangedEvent& rDCEvt ) override;
+
+    virtual void            Modify() override;
+
+    virtual void            Up() override;
+    virtual void            Down() override;
+    virtual void            First() override;
+    virtual void            Last() override;
+
+    void                    SetFirst( const tools::Time& rNewFirst )   { maFirst = rNewFirst; }
+    const tools::Time&      GetFirst() const                    { return maFirst; }
+    void                    SetLast( const tools::Time& rNewLast )     { maLast = rNewLast; }
+    const tools::Time&      GetLast() const                     { return maLast; }
+
+    void                    SetExtFormat( ExtTimeFieldFormat eFormat );
+    virtual void            dispose() override;
+};
+
 class UNLESS_MERGELIBS(VCL_DLLPUBLIC) NumericBox : public ComboBox, public NumericFormatter
 {
     SAL_DLLPRIVATE void     ImplNumericReformat( const OUString& rStr, sal_Int64& rValue, OUString& rOutStr );
diff --git a/include/vcl/weldutils.hxx b/include/vcl/weldutils.hxx
index ebb458de9727..e4faeea905a7 100644
--- a/include/vcl/weldutils.hxx
+++ b/include/vcl/weldutils.hxx
@@ -234,10 +234,45 @@ private:
     DECL_LINK(FormatOutputHdl, LinkParamNone*, bool);
     DECL_LINK(ParseInputHdl, sal_Int64*, TriState);
 
+    void Init();
+
     OUString m_aCurrencySymbol;
     bool m_bThousandSep;
 };
 
+class VCL_DLLPUBLIC TimeFormatter final : public EntryFormatter
+{
+public:
+    TimeFormatter(weld::Entry& rEntry);
+    TimeFormatter(weld::FormattedSpinButton& rSpinButton);
+
+    void SetExtFormat(ExtTimeFieldFormat eFormat);
+
+    void SetMin(const tools::Time& rNewMin);
+    void SetMax(const tools::Time& rNewMax);
+
+    void SetTime(const tools::Time& rNewTime);
+    tools::Time GetTime();
+
+    virtual ~TimeFormatter() override;
+
+private:
+    DECL_LINK(FormatOutputHdl, LinkParamNone*, bool);
+    DECL_LINK(ParseInputHdl, sal_Int64*, TriState);
+    DECL_LINK(CursorChangedHdl, weld::Entry&, void);
+
+    void Init();
+
+    static tools::Time ConvertValue(int nValue);
+    static int ConvertValue(const tools::Time& rTime);
+
+    OUString FormatNumber(int nValue) const;
+
+    TimeFieldFormat m_eFormat;
+    TimeFormat m_eTimeFormat;
+    bool m_bDuration;
+};
+
 // get the row the iterator is on
 VCL_DLLPUBLIC size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& rIter);
 
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
index 400f0fb581fe..ba90f7f5a3a2 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -457,6 +457,16 @@ namespace svt
         InitFormattedControlBase();
     }
 
+    TimeControl::TimeControl(BrowserDataWin* pParent, bool bSpinVariant)
+        : FormattedControlBase(pParent, bSpinVariant)
+    {
+        if (bSpinVariant)
+            m_xEntryFormatter.reset(new weld::TimeFormatter(*m_xSpinButton));
+        else
+            m_xEntryFormatter.reset(new weld::TimeFormatter(*m_xEntry));
+        InitFormattedControlBase();
+    }
+
     EditCellController::EditCellController(EditControlBase* pEdit)
         : CellController(pEdit)
         , m_pEditImplementation(new EntryImplementation(*pEdit))
diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index bddf63079c0c..b29fdcbc5f79 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -2272,10 +2272,14 @@ DbTimeField::DbTimeField( DbGridColumn& _rColumn )
     doPropertyListening( FM_PROP_STRICTFORMAT );
 }
 
-VclPtr<Control> DbTimeField::createField(BrowserDataWin* _pParent, bool bSpinButton, const Reference< XPropertySet >& /*_rxModel*/ )
+VclPtr<Control> DbTimeField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& /*rxModel*/ )
 {
-    WinBits _nFieldStyle = bSpinButton ? (WB_REPEAT | WB_SPIN) : 0;
-    return VclPtr<TimeField>::Create( _pParent, _nFieldStyle );
+    return VclPtr<TimeControl>::Create(pParent, bSpinButton);
+}
+
+CellControllerRef DbTimeField::CreateController() const
+{
+    return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
 }
 
 void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
@@ -2292,23 +2296,28 @@ void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >
     OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax );
     bool    bStrict     = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
 
-    static_cast< TimeField* >( m_pWindow.get() )->SetExtFormat( static_cast<ExtTimeFieldFormat>(nFormat) );
-    static_cast< TimeField* >( m_pWindow.get() )->SetMin( aMin );
-    static_cast< TimeField* >( m_pWindow.get() )->SetMax( aMax );
-    static_cast< TimeField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
-    static_cast< TimeField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
+    FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
+    weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
+
+    rControlFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
+    rControlFormatter.SetMin(aMin);
+    rControlFormatter.SetMax(aMax);
+    rControlFormatter.SetStrictFormat(bStrict);
+    rControlFormatter.EnableEmptyField(true);
+
+    FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
+    weld::TimeFormatter& rPainterFormatter = static_cast<weld::TimeFormatter&>(pPainter->get_formatter());
 
-    static_cast< TimeField* >( m_pPainter.get() )->SetExtFormat( static_cast<ExtTimeFieldFormat>(nFormat) );
-    static_cast< TimeField* >( m_pPainter.get() )->SetMin( aMin );
-    static_cast< TimeField* >( m_pPainter.get() )->SetMax( aMax );
-    static_cast< TimeField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
-    static_cast< TimeField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
+    rPainterFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
+    rPainterFormatter.SetMin(aMin);
+    rPainterFormatter.SetMax(aMax);
+    rPainterFormatter.SetStrictFormat(bStrict);
+    rPainterFormatter.EnableEmptyField(true);
 }
 
 namespace
 {
-
-    OUString lcl_setFormattedTime_nothrow( TimeField& _rField, const Reference< XColumn >& _rxField )
+    OUString lcl_setFormattedTime_nothrow(TimeControl& _rField, const Reference<XColumn>& _rxField)
     {
         OUString sTime;
         if ( _rxField.is() )
@@ -2316,12 +2325,10 @@ namespace
             try
             {
                 css::util::Time aValue = _rxField->getTime();
-                if ( _rxField->wasNull() )
-                    _rField.SetText( sTime );
-                else
+                if (!_rxField->wasNull())
                 {
-                    _rField.SetTime( ::tools::Time( aValue ) );
-                    sTime = _rField.GetText();
+                    static_cast<weld::TimeFormatter&>(_rField.get_formatter()).SetTime( ::tools::Time( aValue ) );
+                    sTime = _rField.get_widget().get_text();
                 }
             }
             catch( const Exception& )
@@ -2335,34 +2342,41 @@ namespace
 
 OUString DbTimeField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
 {
-    return lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pPainter.get() ), _rxField );
+    return lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pPainter.get()), _rxField);
 }
 
 void DbTimeField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
 {
-    lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pWindow.get() ), _rxField );
+    lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pWindow.get()), _rxField);
 }
 
 void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
 {
     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
 
+    FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
+    weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
+
     util::Time aTime;
     if ( _rxModel->getPropertyValue( FM_PROP_TIME ) >>= aTime )
-        static_cast< TimeField* >( m_pWindow.get() )->SetTime( ::tools::Time( aTime ) );
+        rControlFormatter.SetTime(::tools::Time(aTime));
     else
-        static_cast< TimeField* >( m_pWindow.get() )->SetText( OUString() );
+        pControl->get_widget().set_text(OUString());
 }
 
 bool DbTimeField::commitControl()
 {
-    OUString aText(m_pWindow->GetText());
+    FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
+    OUString aText(pControl->get_widget().get_text());
     Any aVal;
-    if (!aText.isEmpty())
-        aVal <<= static_cast<TimeField*>(m_pWindow.get())->GetTime().GetUNOTime();
-    else
-        aVal.clear();
 
+    fprintf(stderr, "text is %s\n", aText.toUtf8().getStr());
+
+    if (!aText.isEmpty())   // not empty
+    {
+        weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
+        aVal <<= rControlFormatter.GetTime().GetUNOTime();
+    }
     m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
     return true;
 }
diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx
index 121720b29b1a..6b4a3afc8585 100644
--- a/svx/source/inc/gridcell.hxx
+++ b/svx/source/inc/gridcell.hxx
@@ -576,11 +576,11 @@ protected:
     virtual void    implAdjustGenericFieldSetting( const css::uno::Reference< css::beans::XPropertySet >& _rxModel ) override;
 };
 
-
 class DbTimeField : public DbSpinField
 {
 public:
     DbTimeField(DbGridColumn& _rColumn);
+    virtual ::svt::CellControllerRef CreateController() const override;
     virtual OUString GetFormatText(const css::uno::Reference< css::sdb::XColumn >& _rxField, const css::uno::Reference< css::util::XNumberFormatter >& xFormatter, Color** ppColor = nullptr) override;
     virtual void UpdateFromField(const css::uno::Reference< css::sdb::XColumn >& _rxField, const css::uno::Reference< css::util::XNumberFormatter >& xFormatter) override;
 
diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx
index acf1ba3473b5..21161e396db8 100644
--- a/vcl/source/app/weldutils.cxx
+++ b/vcl/source/app/weldutils.cxx
@@ -294,12 +294,19 @@ void DoubleNumericFormatter::ResetConformanceTester()
 
 LongCurrencyFormatter::LongCurrencyFormatter(weld::Entry& rEntry)
     : EntryFormatter(rEntry)
+    , m_bThousandSep(true)
 {
+    Init();
 }
 
 LongCurrencyFormatter::LongCurrencyFormatter(weld::FormattedSpinButton& rSpinButton)
     : EntryFormatter(rSpinButton)
     , m_bThousandSep(true)
+{
+    Init();
+}
+
+void LongCurrencyFormatter::Init()
 {
     SetOutputHdl(LINK(this, LongCurrencyFormatter, FormatOutputHdl));
     SetInputHdl(LINK(this, LongCurrencyFormatter, ParseInputHdl));
@@ -318,6 +325,89 @@ void LongCurrencyFormatter::SetCurrencySymbol(const OUString& rStr)
 }
 
 LongCurrencyFormatter::~LongCurrencyFormatter() = default;
+
+TimeFormatter::TimeFormatter(weld::Entry& rEntry)
+    : EntryFormatter(rEntry)
+    , m_eFormat(TimeFieldFormat::F_NONE)
+    , m_eTimeFormat(TimeFormat::Hour24)
+    , m_bDuration(false)
+{
+    Init();
+}
+
+TimeFormatter::TimeFormatter(weld::FormattedSpinButton& rSpinButton)
+    : EntryFormatter(rSpinButton)
+    , m_eFormat(TimeFieldFormat::F_NONE)
+    , m_eTimeFormat(TimeFormat::Hour24)
+    , m_bDuration(false)
+{
+    Init();
+}
+
+void TimeFormatter::Init()
+{
+    SetOutputHdl(LINK(this, TimeFormatter, FormatOutputHdl));
+    SetInputHdl(LINK(this, TimeFormatter, ParseInputHdl));
+
+    SetMin(tools::Time(0, 0));
+    SetMax(tools::Time(23, 59, 59, 999999999));
+
+    // so the spin size can depend on which zone the cursor is in
+    get_widget().connect_cursor_position(LINK(this, TimeFormatter, CursorChangedHdl));
+    // and set the initial spin size
+    CursorChangedHdl(get_widget());
+}
+
+void TimeFormatter::SetExtFormat(ExtTimeFieldFormat eFormat)
+{
+    switch (eFormat)
+    {
+        case ExtTimeFieldFormat::Short24H:
+        {
+            m_eTimeFormat = TimeFormat::Hour24;
+            m_bDuration = false;
+            m_eFormat = TimeFieldFormat::F_NONE;
+        }
+        break;
+        case ExtTimeFieldFormat::Long24H:
+        {
+            m_eTimeFormat = TimeFormat::Hour24;
+            m_bDuration = false;
+            m_eFormat = TimeFieldFormat::F_SEC;
+        }
+        break;
+        case ExtTimeFieldFormat::Short12H:
+        {
+            m_eTimeFormat = TimeFormat::Hour12;
+            m_bDuration = false;
+            m_eFormat = TimeFieldFormat::F_NONE;
+        }
+        break;
+        case ExtTimeFieldFormat::Long12H:
+        {
+            m_eTimeFormat = TimeFormat::Hour12;
+            m_bDuration = false;
+            m_eFormat = TimeFieldFormat::F_SEC;
+        }
+        break;
+        case ExtTimeFieldFormat::ShortDuration:
+        {
+            m_bDuration = true;
+            m_eFormat = TimeFieldFormat::F_NONE;
+        }
+        break;
+        case ExtTimeFieldFormat::LongDuration:
+        {
+            m_bDuration = true;
+            m_eFormat = TimeFieldFormat::F_SEC;
+        }
+        break;
+    }
+
+    ReFormat();
+}
+
+TimeFormatter::~TimeFormatter() = default;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx
index 6b69d19c9ff1..2388daa6bfb7 100644
--- a/vcl/source/control/field2.cxx
+++ b/vcl/source/control/field2.cxx
@@ -30,6 +30,7 @@
 #include <vcl/toolkit/field.hxx>
 #include <vcl/unohelp.hxx>
 #include <vcl/settings.hxx>
+#include <vcl/weldutils.hxx>
 
 #include <svdata.hxx>
 
@@ -2705,4 +2706,84 @@ void TimeBox::ReformatAll()
     SetUpdateMode( true );
 }
 
+namespace weld
+{
+    tools::Time TimeFormatter::ConvertValue(int nValue)
+    {
+        tools::Time aTime(0);
+        aTime.MakeTimeFromMS(nValue);
+        return aTime;
+    }
+
+    int TimeFormatter::ConvertValue(const tools::Time& rTime)
+    {
+        return rTime.GetMSFromTime();
+    }
+
+    void TimeFormatter::SetTime(const tools::Time& rTime)
+    {
+        SetValue(ConvertValue(rTime));
+    }
+
+    tools::Time TimeFormatter::GetTime()
+    {
+        return ConvertValue(GetValue());
+    }
+
+    void TimeFormatter::SetMin(const tools::Time& rNewMin)
+    {
+        SetMinValue(ConvertValue(rNewMin));
+    }
+
+    void TimeFormatter::SetMax(const tools::Time& rNewMax)
+    {
+        SetMaxValue(ConvertValue(rNewMax));
+    }
+
+    OUString TimeFormatter::FormatNumber(int nValue) const
+    {
+        const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
+        return ::TimeFormatter::FormatTime(ConvertValue(nValue), m_eFormat, m_eTimeFormat, m_bDuration, rLocaleData);
+    }
+
+    IMPL_LINK_NOARG(TimeFormatter, FormatOutputHdl, LinkParamNone*, bool)
+    {
+        OUString sText = FormatNumber(GetValue());
+        ImplSetTextImpl(sText, nullptr);
+        return true;
+    }
+
+    IMPL_LINK(TimeFormatter, ParseInputHdl, sal_Int64*, result, TriState)
+    {
+        const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper();
+
+        tools::Time aResult(0);
+        bool bRet = ::TimeFormatter::TextToTime(GetEntryText(), aResult, m_eFormat, m_bDuration, rLocaleDataWrapper);
+        if (bRet)
+            *result = ConvertValue(aResult);
+
+        return bRet ? TRISTATE_TRUE : TRISTATE_FALSE;
+    }
+
+    IMPL_LINK(TimeFormatter, CursorChangedHdl, weld::Entry&, rEntry, void)
+    {
+        int nStartPos, nEndPos;
+        rEntry.get_selection_bounds(nStartPos, nEndPos);
+
+        const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
+        const int nTimeArea = ::TimeFormatter::GetTimeArea(m_eFormat, GetEntryText(), nEndPos, rLocaleData);
+
+        int nIncrements = 1;
+
+        if (nTimeArea == 1)
+            nIncrements = 1000 * 60 * 60;
+        else if (nTimeArea == 2)
+            nIncrements = 1000 * 60;
+        else if (nTimeArea == 3)
+            nIncrements = 1000;
+
+        SetSpinSize(nIncrements);
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 5738891c6c7f..368c4292fd06 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -360,8 +360,8 @@ namespace weld
         m_xSpinButton->get_selection_bounds(nStartPos, nEndPos);
 
         const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
-        const int nTimeArea = TimeFormatter::GetTimeArea(m_eFormat, m_xSpinButton->get_text(), nEndPos,
-                                                         rLocaleData);
+        const int nTimeArea = ::TimeFormatter::GetTimeArea(m_eFormat, m_xSpinButton->get_text(), nEndPos,
+                                                           rLocaleData);
 
         int nIncrements = 1;
 
@@ -390,12 +390,9 @@ namespace weld
 
     IMPL_LINK(TimeSpinButton, spin_button_input, int*, result, bool)
     {
-        int nStartPos, nEndPos;
-        m_xSpinButton->get_selection_bounds(nStartPos, nEndPos);
-
         const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
         tools::Time aResult(0);
-        bool bRet = TimeFormatter::TextToTime(m_xSpinButton->get_text(), aResult, m_eFormat, true, rLocaleData);
+        bool bRet = ::TimeFormatter::TextToTime(m_xSpinButton->get_text(), aResult, m_eFormat, true, rLocaleData);
         if (bRet)
             *result = ConvertValue(aResult);
         return bRet;
@@ -426,7 +423,7 @@ namespace weld
     OUString TimeSpinButton::format_number(int nValue) const
     {
         const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
-        return TimeFormatter::FormatTime(ConvertValue(nValue), m_eFormat, TimeFormat::Hour24, true, rLocaleData);
+        return ::TimeFormatter::FormatTime(ConvertValue(nValue), m_eFormat, TimeFormat::Hour24, true, rLocaleData);
     }
 
     EntryTreeView::EntryTreeView(std::unique_ptr<Entry> xEntry, std::unique_ptr<TreeView> xTreeView)


More information about the Libreoffice-commits mailing list