include/svtools/editbrowsebox.hxx | 21 ++ include/vcl/field.hxx | 107 ------------ include/vcl/toolkit/calendar.hxx | 6 include/vcl/toolkit/field.hxx | 111 ++++++++++++ include/vcl/weldutils.hxx | 32 +++ solenv/clang-format/excludelist | 2 svtools/source/brwbox/ebbcontrols.cxx | 69 +++++++ svtools/uiconfig/ui/datewindow.ui | 54 ++++++ svtools/uiconfig/ui/thineditcontrol.ui | 83 ++++++--- svx/source/fmcomp/gridcell.cxx | 105 +++++------ svx/source/inc/gridcell.hxx | 1 toolkit/source/awt/vclxtoolkit.cxx | 2 vcl/source/app/weldutils.cxx | 24 ++ vcl/source/control/calendar.cxx | 2 vcl/source/control/field2.cxx | 291 +++++++++++++++++++++++---------- 15 files changed, 630 insertions(+), 280 deletions(-)
New commits: commit 6e7e19d9c300dbdd279789b09f94781e946fad52 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Wed Jul 15 12:10:32 2020 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Tue Jul 21 10:25:42 2020 +0200 weld DateControl replace SpinButton when WB_SPINBUTTON is set on a date field to always use a popover with a calendar in it to make it possible to integrate this with native widgets Change-Id: I36a26599a154bddf9aec9b50b6570e13477a1f63 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98858 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx index b5ffad460555..4dc3381d5aaa 100644 --- a/include/svtools/editbrowsebox.hxx +++ b/include/svtools/editbrowsebox.hxx @@ -750,6 +750,27 @@ namespace svt TimeControl(BrowserDataWin* pParent, bool bSpinVariant); }; + class SVT_DLLPUBLIC DateControl : public FormattedControlBase + { + public: + DateControl(BrowserDataWin* pParent, bool bDropDown); + + void SetDate(const Date& rDate); + + virtual void dispose() override; + private: + std::unique_ptr<weld::MenuButton> m_xMenuButton; + std::unique_ptr<weld::Builder> m_xCalendarBuilder; + std::unique_ptr<weld::Widget> m_xTopLevel; + std::unique_ptr<weld::Calendar> m_xCalendar; + std::unique_ptr<weld::Button> m_xTodayBtn; + std::unique_ptr<weld::Button> m_xNoneBtn; + + DECL_LINK(ToggleHdl, weld::ToggleButton&, void); + DECL_LINK(ActivateHdl, weld::Calendar&, void); + DECL_LINK(ImplClickHdl, weld::Button&, void); + }; + //= FormattedFieldCellController class SVT_DLLPUBLIC FormattedFieldCellController final : public EditCellController { diff --git a/include/vcl/field.hxx b/include/vcl/field.hxx index 1cb4974bfd08..36a786061bdb 100644 --- a/include/vcl/field.hxx +++ b/include/vcl/field.hxx @@ -186,83 +186,6 @@ private: }; -class UNLESS_MERGELIBS(VCL_DLLPUBLIC) DateFormatter : public FormatterBase -{ -private: - std::unique_ptr<CalendarWrapper> mxCalendarWrapper; - Date maFieldDate; - Date maLastDate; - Date maMin; - Date maMax; - bool mbLongFormat; - bool mbShowDateCentury; - ExtDateFieldFormat mnExtDateFormat; - bool mbEnforceValidValue; - -protected: - DateFormatter(Edit* pEdit); - - SAL_DLLPRIVATE const Date& ImplGetFieldDate() const { return maFieldDate; } - SAL_DLLPRIVATE void ImplDateReformat( const OUString& rStr, OUString& rOutStr ); - SAL_DLLPRIVATE void ImplSetUserDate( const Date& rNewDate, - Selection const * pNewSelection = nullptr ); - SAL_DLLPRIVATE OUString ImplGetDateAsText( const Date& rDate ) const; - SAL_DLLPRIVATE void ImplNewFieldValue( const Date& rDate ); - CalendarWrapper& GetCalendarWrapper() const; - - SAL_DLLPRIVATE bool ImplAllowMalformedInput() const; - -public: - virtual ~DateFormatter() override; - - virtual void Reformat() override; - virtual void ReformatAll() override; - - void SetExtDateFormat( ExtDateFieldFormat eFormat ); - ExtDateFieldFormat GetExtDateFormat( bool bResolveSystemFormat = false ) const; - - void SetMin( const Date& rNewMin ); - const Date& GetMin() const { return maMin; } - - void SetMax( const Date& rNewMax ); - const Date& GetMax() const { return maMax; } - - - // MT: Remove these methods too, ExtDateFormat should be enough! - // What should happen if using DDMMYYYY, but ShowCentury=false? - - void SetLongFormat( bool bLong ); - bool IsLongFormat() const { return mbLongFormat; } - void SetShowDateCentury( bool bShowCentury ); - bool IsShowDateCentury() const { return mbShowDateCentury; } - - - void SetDate( const Date& rNewDate ); - Date GetDate() const; - void SetEmptyDate(); - bool IsEmptyDate() const; - - void ResetLastDate() { maLastDate = Date( Date::EMPTY ); } - - static void ExpandCentury( Date& rDate ); - static void ExpandCentury( Date& rDate, sal_uInt16 nTwoDigitYearStart ); - - /** enables or disables the enforcement of valid values - - If this is set to true (which is the default), then GetDate will always return a valid - date, no matter whether the current text can really be interpreted as date. (Note: this - is the compatible behavior). - - If this is set to false, the GetDate will return GetInvalidDate, in case the current text - cannot be interpreted as date. - - In addition, if this is set to false, the text in the field will \em not 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: @@ -298,36 +221,6 @@ public: virtual void DumpAsPropertyTree(tools::JsonWriter&) override; }; -class UNLESS_MERGELIBS(VCL_DLLPUBLIC) DateField : public SpinField, public DateFormatter -{ -private: - Date maFirst; - Date maLast; - -protected: - SAL_DLLPRIVATE void ImplDateSpinArea( bool bUp ); - -public: - explicit DateField( 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 Date& rNewFirst ) { maFirst = rNewFirst; } - const Date& GetFirst() const { return maFirst; } - void SetLast( const Date& rNewLast ) { maLast = rNewLast; } - const Date& GetLast() const { return maLast; } - virtual void dispose() override; -}; - #endif // INCLUDED_VCL_FIELD_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/vcl/calendar.hxx b/include/vcl/toolkit/calendar.hxx similarity index 94% rename from include/vcl/calendar.hxx rename to include/vcl/toolkit/calendar.hxx index a88105e29e59..a1a1cd90105a 100644 --- a/include/vcl/calendar.hxx +++ b/include/vcl/toolkit/calendar.hxx @@ -19,10 +19,14 @@ #pragma once +#if !defined(VCL_DLLIMPLEMENTATION) && !defined(TOOLKIT_DLLIMPLEMENTATION) && !defined(VCL_INTERNALS) +#error "don't use this in new code" +#endif + #include <config_options.h> #include <vcl/dllapi.h> -#include <vcl/field.hxx> +#include <vcl/toolkit/field.hxx> #include <vcl/weld.hxx> class FloatingWindow; diff --git a/include/vcl/toolkit/field.hxx b/include/vcl/toolkit/field.hxx index 6b994b02baea..6316c5698933 100644 --- a/include/vcl/toolkit/field.hxx +++ b/include/vcl/toolkit/field.hxx @@ -260,6 +260,117 @@ public: virtual void dispose() override; }; +class UNLESS_MERGELIBS(VCL_DLLPUBLIC) DateFormatter : public FormatterBase +{ +private: + std::unique_ptr<CalendarWrapper> mxCalendarWrapper; + Date maFieldDate; + Date maLastDate; + Date maMin; + Date maMax; + bool mbLongFormat; + bool mbShowDateCentury; + ExtDateFieldFormat mnExtDateFormat; + bool mbEnforceValidValue; + +protected: + DateFormatter(Edit* pEdit); + + SAL_DLLPRIVATE const Date& ImplGetFieldDate() const { return maFieldDate; } + SAL_DLLPRIVATE void ImplDateReformat( const OUString& rStr, OUString& rOutStr ); + SAL_DLLPRIVATE void ImplSetUserDate( const Date& rNewDate, + Selection const * pNewSelection = nullptr ); + SAL_DLLPRIVATE OUString ImplGetDateAsText( const Date& rDate ) const; + SAL_DLLPRIVATE void ImplNewFieldValue( const Date& rDate ); + CalendarWrapper& GetCalendarWrapper() const; + + SAL_DLLPRIVATE bool ImplAllowMalformedInput() const; + +public: + static OUString FormatDate(const Date& rNewDate, ExtDateFieldFormat eFormat, const LocaleDataWrapper& rLocaleData, CalendarWrapper& rCalendarWrapper); + static bool TextToDate(const OUString& rStr, Date& rTime, ExtDateFieldFormat eFormat, const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper); + static int GetDateArea(ExtDateFieldFormat eFormat, const OUString& rText, int nCursor, const LocaleDataWrapper& rLocaleDataWrapper); + + virtual ~DateFormatter() override; + + virtual void Reformat() override; + virtual void ReformatAll() override; + + void SetExtDateFormat( ExtDateFieldFormat eFormat ); + ExtDateFieldFormat GetExtDateFormat( bool bResolveSystemFormat = false ) const; + + void SetMin( const Date& rNewMin ); + const Date& GetMin() const { return maMin; } + + void SetMax( const Date& rNewMax ); + const Date& GetMax() const { return maMax; } + + + // MT: Remove these methods too, ExtDateFormat should be enough! + // What should happen if using DDMMYYYY, but ShowCentury=false? + + void SetLongFormat( bool bLong ); + bool IsLongFormat() const { return mbLongFormat; } + void SetShowDateCentury( bool bShowCentury ); + bool IsShowDateCentury() const { return mbShowDateCentury; } + + + void SetDate( const Date& rNewDate ); + Date GetDate() const; + void SetEmptyDate(); + bool IsEmptyDate() const; + + void ResetLastDate() { maLastDate = Date( Date::EMPTY ); } + + static void ExpandCentury( Date& rDate ); + static void ExpandCentury( Date& rDate, sal_uInt16 nTwoDigitYearStart ); + + /** enables or disables the enforcement of valid values + + If this is set to true (which is the default), then GetDate will always return a valid + date, no matter whether the current text can really be interpreted as date. (Note: this + is the compatible behavior). + + If this is set to false, the GetDate will return GetInvalidDate, in case the current text + cannot be interpreted as date. + + In addition, if this is set to false, the text in the field will \em not 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) DateField : public SpinField, public DateFormatter +{ +private: + Date maFirst; + Date maLast; + +protected: + SAL_DLLPRIVATE void ImplDateSpinArea( bool bUp ); + +public: + explicit DateField( 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 Date& rNewFirst ) { maFirst = rNewFirst; } + const Date& GetFirst() const { return maFirst; } + void SetLast( const Date& rNewLast ) { maLast = rNewLast; } + const Date& GetLast() const { return maLast; } + 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 e1944cc41ee8..cc2a49d4d881 100644 --- a/include/vcl/weldutils.hxx +++ b/include/vcl/weldutils.hxx @@ -19,6 +19,8 @@ #include <vcl/formatter.hxx> #include <vcl/weld.hxx> +class CalendarWrapper; + namespace weld { typedef cppu::WeakComponentImplHelper<css::awt::XWindow> TransportAsXWindow_Base; @@ -280,6 +282,36 @@ private: bool m_bDuration; }; +class VCL_DLLPUBLIC DateFormatter final : public EntryFormatter +{ +public: + DateFormatter(weld::Entry& rEntry); + + void SetMin(const Date& rNewMin); + void SetMax(const Date& rNewMax); + + void SetDate(const Date& rNewDate); + Date GetDate(); + + void SetExtDateFormat(ExtDateFieldFormat eFormat); + void SetShowDateCentury(bool bShowCentury); + + virtual ~DateFormatter() override; + +private: + DECL_LINK(FormatOutputHdl, LinkParamNone*, bool); + DECL_LINK(ParseInputHdl, sal_Int64*, TriState); + DECL_LINK(CursorChangedHdl, weld::Entry&, void); + + void Init(); + CalendarWrapper& GetCalendarWrapper() const; + + OUString FormatNumber(int nValue) const; + + ExtDateFieldFormat m_eFormat; + mutable std::unique_ptr<CalendarWrapper> m_xCalendarWrapper; +}; + // get the row the iterator is on VCL_DLLPUBLIC size_t GetAbsPos(const weld::TreeView& rTreeView, const weld::TreeIter& rIter); diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index ac6e1e28bdee..0708c30817f7 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -7321,7 +7321,6 @@ include/vcl/builder.hxx include/vcl/builderfactory.hxx include/vcl/button.hxx include/vcl/cairo.hxx -include/vcl/calendar.hxx include/vcl/canvastools.hxx include/vcl/checksum.hxx include/vcl/commandevent.hxx @@ -7439,6 +7438,7 @@ include/vcl/threadex.hxx include/vcl/timer.hxx include/vcl/toolbox.hxx include/vcl/toolkit/button.hxx +include/vcl/toolkit/calendar.hxx include/vcl/toolkit/combobox.hxx include/vcl/toolkit/controllayout.hxx include/vcl/toolkit/dialog.hxx diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx index ba90f7f5a3a2..3f1c0196e838 100644 --- a/svtools/source/brwbox/ebbcontrols.cxx +++ b/svtools/source/brwbox/ebbcontrols.cxx @@ -18,6 +18,7 @@ #include <svtools/editbrowsebox.hxx> #include <vcl/spinfld.hxx> +#include <vcl/svapp.hxx> #include <vcl/xtextedt.hxx> #include <vcl/textview.hxx> #include <vcl/virdev.hxx> @@ -467,6 +468,74 @@ namespace svt InitFormattedControlBase(); } + DateControl::DateControl(BrowserDataWin* pParent, bool bDropDown) + : FormattedControlBase(pParent, false) + , m_xMenuButton(m_xBuilder->weld_menu_button("button")) + , m_xCalendarBuilder(Application::CreateBuilder(m_xMenuButton.get(), "svt/ui/datewindow.ui")) + , m_xTopLevel(m_xCalendarBuilder->weld_widget("date_popup_window")) + , m_xCalendar(m_xCalendarBuilder->weld_calendar("date")) + , m_xTodayBtn(m_xCalendarBuilder->weld_button("today")) + , m_xNoneBtn(m_xCalendarBuilder->weld_button("none")) + { + m_xEntryFormatter.reset(new weld::DateFormatter(*m_xEntry)); + InitFormattedControlBase(); + + m_xMenuButton->set_popover(m_xTopLevel.get()); + m_xMenuButton->set_visible(bDropDown); + m_xMenuButton->connect_toggled(LINK(this, DateControl, ToggleHdl)); + + m_xTodayBtn->connect_clicked(LINK(this, DateControl, ImplClickHdl)); + m_xNoneBtn->connect_clicked(LINK(this, DateControl, ImplClickHdl)); + + m_xCalendar->connect_activated(LINK(this, DateControl, ActivateHdl)); + } + + IMPL_LINK(DateControl, ImplClickHdl, weld::Button&, rBtn, void) + { + m_xMenuButton->set_active(false); + get_widget().grab_focus(); + + if (&rBtn == m_xTodayBtn.get()) + { + Date aToday(Date::SYSTEM); + SetDate(aToday); + } + else if (&rBtn == m_xNoneBtn.get()) + { + get_widget().set_text(OUString()); + } + } + + IMPL_LINK(DateControl, ToggleHdl, weld::ToggleButton&, rButton, void) + { + if (rButton.get_active()) + m_xCalendar->set_date(static_cast<weld::DateFormatter&>(get_formatter()).GetDate()); + } + + IMPL_LINK_NOARG(DateControl, ActivateHdl, weld::Calendar&, void) + { + if (m_xMenuButton->get_active()) + m_xMenuButton->set_active(false); + static_cast<weld::DateFormatter&>(get_formatter()).SetDate(m_xCalendar->get_date()); + } + + void DateControl::SetDate(const Date& rDate) + { + static_cast<weld::DateFormatter&>(get_formatter()).SetDate(rDate); + m_xCalendar->set_date(rDate); + } + + void DateControl::dispose() + { + m_xTodayBtn.reset(); + m_xNoneBtn.reset(); + m_xCalendar.reset(); + m_xTopLevel.reset(); + m_xCalendarBuilder.reset(); + m_xMenuButton.reset(); + FormattedControlBase::dispose(); + } + EditCellController::EditCellController(EditControlBase* pEdit) : CellController(pEdit) , m_pEditImplementation(new EntryImplementation(*pEdit)) diff --git a/svtools/uiconfig/ui/datewindow.ui b/svtools/uiconfig/ui/datewindow.ui index bce2ff038a94..0e7729afe74e 100644 --- a/svtools/uiconfig/ui/datewindow.ui +++ b/svtools/uiconfig/ui/datewindow.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> +<!-- Generated with glade 3.36.0 --> <interface domain="svt"> <requires lib="gtk+" version="3.18"/> <object class="GtkPopover" id="date_popup_window"> @@ -26,6 +26,58 @@ <property name="position">0</property> </packing> </child> + <child> + <object class="GtkSeparator"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButtonBox" id="buttonbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <property name="layout_style">spread</property> + <child> + <object class="GtkButton" id="today"> + <property name="label" context="calendar|STR_SVT_CALENDAR_TODAY">Today</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="none"> + <property name="label" context="calendar|STR_SVT_CALENDAR_NONE">None</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> </object> </child> </object> diff --git a/svtools/uiconfig/ui/thineditcontrol.ui b/svtools/uiconfig/ui/thineditcontrol.ui index 8fd8f891d778..d734a8f269b8 100644 --- a/svtools/uiconfig/ui/thineditcontrol.ui +++ b/svtools/uiconfig/ui/thineditcontrol.ui @@ -1,42 +1,79 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.2 --> +<!-- Generated with glade 3.36.0 --> <interface domain="svt"> <requires lib="gtk+" version="3.18"/> + <object class="GtkImage" id="image7"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="icon_name">sc/res/date.png</property> + <property name="icon_size">2</property> + </object> <object class="GtkBox" id="EditControl"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkEntry" id="entry"> - <property name="can_focus">True</property> - <property name="no_show_all">True</property> - <property name="hexpand">True</property> - <property name="vexpand">True</property> - <property name="has_frame">False</property> - <property name="activates_default">True</property> - <property name="width_chars">1</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> <child> - <object class="GtkSpinButton" id="spinbutton"> - <property name="can_focus">True</property> - <property name="no_show_all">True</property> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> - <property name="has_frame">False</property> + <child> + <object class="GtkSpinButton" id="spinbutton"> + <property name="can_focus">True</property> + <property name="no_show_all">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="has_frame">False</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry"> + <property name="can_focus">True</property> + <property name="no_show_all">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="has_frame">False</property> + <property name="activates_default">True</property> + <property name="width_chars">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="button"> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="no_show_all">True</property> + <property name="halign">end</property> + <property name="image">image7</property> + <property name="margin_left">1</property> + <property name="always_show_image">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="button-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes" context="thineditcontrol|button">Pick Date</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx index 4c1eb3211412..8e87c2dabfc6 100644 --- a/svx/source/fmcomp/gridcell.cxx +++ b/svx/source/fmcomp/gridcell.cxx @@ -55,7 +55,6 @@ #include <i18nlangtag/lang.h> #include <rtl/math.hxx> -#include <vcl/calendar.hxx> #include <svl/numuno.hxx> #include <svl/zforlist.hxx> #include <svx/dialmgr.hxx> @@ -417,7 +416,6 @@ OUString DbGridColumn::GetCellText(const DbGridRow* pRow, const Reference< XNumb return aText; } - OUString DbGridColumn::GetCellText(const Reference< css::sdb::XColumn >& xField, const Reference< XNumberFormatter >& xFormatter) const { OUString aText; @@ -432,7 +430,6 @@ OUString DbGridColumn::GetCellText(const Reference< css::sdb::XColumn >& xField, return aText; } - Reference< css::sdb::XColumn > DbGridColumn::GetCurrentFieldValue() const { Reference< css::sdb::XColumn > xField; @@ -1195,7 +1192,6 @@ void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel ) m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) ); } - bool DbTextField::commitControl() { OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) ); @@ -1213,7 +1209,6 @@ bool DbTextField::commitControl() return true; } - void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen ) { if ( m_pEdit ) @@ -1812,7 +1807,6 @@ void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, cons static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) ); } - void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel ) { OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" ); @@ -1824,7 +1818,6 @@ void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel ) static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) ); } - bool DbPatternField::commitControl() { OUString aText(m_pWindow->GetText()); @@ -2143,21 +2136,20 @@ DbDateField::DbDateField( DbGridColumn& _rColumn ) doPropertyListening( FM_PROP_DATE_SHOW_CENTURY ); } -VclPtr<Control> DbDateField::createField(BrowserDataWin* _pParent, bool bSpinButton, const Reference< XPropertySet >& _rxModel ) +VclPtr<Control> DbDateField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& rxModel) { - WinBits _nFieldStyle = bSpinButton ? (WB_REPEAT | WB_SPIN) : 0; // check if there is a DropDown property set to TRUE - bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, _rxModel ) - || getBOOL( _rxModel->getPropertyValue( FM_PROP_DROPDOWN ) ); - if ( bDropDown ) - _nFieldStyle |= WB_DROPDOWN; - - VclPtr<CalendarField> pField = VclPtr<CalendarField>::Create( _pParent, _nFieldStyle ); - - pField->EnableToday(); - pField->EnableNone(); + bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, rxModel ) + || getBOOL( rxModel->getPropertyValue( FM_PROP_DROPDOWN ) ); + // given the apparent inability to set a custom up/down action for a gtk + // spinbutton to have different up/down dates depending on the zone the + // mouse is in, show the dropdown calender for both the spin or dropdown case + return VclPtr<DateControl>::Create(pParent, bSpinButton || bDropDown); +} - return pField; +CellControllerRef DbDateField::CreateController() const +{ + return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get())); } void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel ) @@ -2174,32 +2166,37 @@ void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet > OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax ); bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) ); + FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get()); + weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter()); + + FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get()); + weld::DateFormatter& rPainterFormatter = static_cast<weld::DateFormatter&>(pPainter->get_formatter()); + Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY ); if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID ) { bool bShowDateCentury = getBOOL( aCentury ); - static_cast<DateField*>( m_pWindow.get() )->SetShowDateCentury( bShowDateCentury ); - static_cast<DateField*>( m_pPainter.get() )->SetShowDateCentury( bShowDateCentury ); + rControlFormatter.SetShowDateCentury(bShowDateCentury); + rPainterFormatter.SetShowDateCentury(bShowDateCentury); } - static_cast< DateField* >( m_pWindow.get() )->SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) ); - static_cast< DateField* >( m_pWindow.get() )->SetMin( aMin ); - static_cast< DateField* >( m_pWindow.get() )->SetMax( aMax ); - static_cast< DateField* >( m_pWindow.get() )->SetStrictFormat( bStrict ); - static_cast< DateField* >( m_pWindow.get() )->EnableEmptyFieldValue( true ); + rControlFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) ); + rControlFormatter.SetMin( aMin ); + rControlFormatter.SetMax( aMax ); + rControlFormatter.SetStrictFormat( bStrict ); + rControlFormatter.EnableEmptyField( true ); - static_cast< DateField* >( m_pPainter.get() )->SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) ); - static_cast< DateField* >( m_pPainter.get() )->SetMin( aMin ); - static_cast< DateField* >( m_pPainter.get() )->SetMax( aMax ); - static_cast< DateField* >( m_pPainter.get() )->SetStrictFormat( bStrict ); - static_cast< DateField* >( m_pPainter.get() )->EnableEmptyFieldValue( true ); + rPainterFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) ); + rPainterFormatter.SetMin( aMin ); + rPainterFormatter.SetMax( aMax ); + rPainterFormatter.SetStrictFormat( bStrict ); + rPainterFormatter.EnableEmptyField( true ); } namespace { - - OUString lcl_setFormattedDate_nothrow( DateField& _rField, const Reference< XColumn >& _rxField ) + OUString lcl_setFormattedDate_nothrow(DateControl& _rField, const Reference<XColumn>& _rxField) { OUString sDate; if ( _rxField.is() ) @@ -2207,12 +2204,10 @@ namespace try { css::util::Date aValue = _rxField->getDate(); - if ( _rxField->wasNull() ) - _rField.SetText( sDate ); - else + if (!_rxField->wasNull()) { - _rField.SetDate( ::Date( aValue.Day, aValue.Month, aValue.Year ) ); - sDate = _rField.GetText(); + _rField.SetDate(::Date(aValue.Day, aValue.Month, aValue.Year)); + sDate = _rField.get_widget().get_text(); } } catch( const Exception& ) @@ -2226,33 +2221,38 @@ namespace OUString DbDateField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/) { - return lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pPainter), _rxField); + return lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pPainter.get()), _rxField); } void DbDateField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/) { - lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pWindow), _rxField); + lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pWindow.get()), _rxField); } void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel ) { OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" ); + DateControl* pControl = static_cast<DateControl*>(m_pWindow.get()); + util::Date aDate; if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= aDate ) - static_cast< DateField* >( m_pWindow.get() )->SetDate( ::Date( aDate ) ); + pControl->SetDate(::Date(aDate)); else - static_cast< DateField* >( m_pWindow.get() )->SetText( OUString() ); + pControl->get_widget().set_text(OUString()); } bool DbDateField::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<DateField*>(m_pWindow.get())->GetDate().GetUNODate(); - else - aVal.clear(); + + if (!aText.isEmpty()) // not empty + { + weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter()); + aVal <<= rControlFormatter.GetDate().GetUNODate(); + } m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal); return true; @@ -2365,13 +2365,12 @@ bool DbTimeField::commitControl() OUString aText(pControl->get_widget().get_text()); Any aVal; - 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; } @@ -3618,7 +3617,6 @@ void SAL_CALL FmXEditCell::insertText(const css::awt::Selection& rSel, const OUS } } - OUString SAL_CALL FmXEditCell::getText() { ::osl::MutexGuard aGuard( m_aMutex ); @@ -4212,43 +4210,36 @@ void SAL_CALL FmXFilterCell::removeTextListener(const Reference< css::awt::XText m_aTextListeners.removeInterface( l ); } - void SAL_CALL FmXFilterCell::setText( const OUString& aText ) { ::osl::MutexGuard aGuard( m_aMutex ); static_cast<DbFilterField*>(m_pCellControl.get())->SetText(aText); } - void SAL_CALL FmXFilterCell::insertText( const css::awt::Selection& /*rSel*/, const OUString& /*aText*/ ) { } - OUString SAL_CALL FmXFilterCell::getText() { ::osl::MutexGuard aGuard( m_aMutex ); return static_cast<DbFilterField*>(m_pCellControl.get())->GetText(); } - OUString SAL_CALL FmXFilterCell::getSelectedText() { return getText(); } - void SAL_CALL FmXFilterCell::setSelection( const css::awt::Selection& /*aSelection*/ ) { } - css::awt::Selection SAL_CALL FmXFilterCell::getSelection() { return css::awt::Selection(); } - sal_Bool SAL_CALL FmXFilterCell::isEditable() { return true; diff --git a/svx/source/inc/gridcell.hxx b/svx/source/inc/gridcell.hxx index 0a65995c9435..e4203d31819a 100644 --- a/svx/source/inc/gridcell.hxx +++ b/svx/source/inc/gridcell.hxx @@ -557,6 +557,7 @@ class DbDateField : public DbSpinField { public: DbDateField(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/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx index 267a9fced788..e1faaf2f31ca 100644 --- a/toolkit/source/awt/vclxtoolkit.cxx +++ b/toolkit/source/awt/vclxtoolkit.cxx @@ -81,7 +81,7 @@ #include <controls/filectrl.hxx> #include <controls/treecontrolpeer.hxx> #include <vcl/toolkit/button.hxx> -#include <vcl/calendar.hxx> +#include <vcl/toolkit/calendar.hxx> #include <vcl/toolkit/combobox.hxx> #include <vcl/ctrl.hxx> #include <vcl/toolkit/dialog.hxx> diff --git a/vcl/source/app/weldutils.cxx b/vcl/source/app/weldutils.cxx index 9efab321e91d..e24566675123 100644 --- a/vcl/source/app/weldutils.cxx +++ b/vcl/source/app/weldutils.cxx @@ -422,6 +422,30 @@ void TimeFormatter::SetTimeFormat(TimeFieldFormat eTimeFormat) } TimeFormatter::~TimeFormatter() = default; + +DateFormatter::DateFormatter(weld::Entry& rEntry) + : EntryFormatter(rEntry) + , m_eFormat(ExtDateFieldFormat::SystemShort) +{ + Init(); +} + +void DateFormatter::Init() +{ + SetOutputHdl(LINK(this, DateFormatter, FormatOutputHdl)); + SetInputHdl(LINK(this, DateFormatter, ParseInputHdl)); + + SetMin(Date(1, 1, 1900)); + SetMax(Date(31, 12, 2200)); +} + +void DateFormatter::SetExtDateFormat(ExtDateFieldFormat eFormat) +{ + m_eFormat = eFormat; + ReFormat(); +} + +DateFormatter::~DateFormatter() = default; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/control/calendar.cxx b/vcl/source/control/calendar.cxx index 083bfa6d34d6..14fcfe62f797 100644 --- a/vcl/source/control/calendar.cxx +++ b/vcl/source/control/calendar.cxx @@ -22,7 +22,7 @@ #include <vcl/menu.hxx> #include <vcl/settings.hxx> #include <vcl/event.hxx> -#include <vcl/calendar.hxx> +#include <vcl/toolkit/calendar.hxx> #include <vcl/commandevent.hxx> #include <vcl/dockwin.hxx> #include <unotools/calendarwrapper.hxx> diff --git a/vcl/source/control/field2.cxx b/vcl/source/control/field2.cxx index 2388daa6bfb7..1cbf4fcf9e92 100644 --- a/vcl/source/control/field2.cxx +++ b/vcl/source/control/field2.cxx @@ -1003,8 +1003,8 @@ static bool ImplDateProcessKeyInput( const KeyEvent& rKEvt, ExtDateFieldFormat e (cChar == ImplGetDateSep( rLocaleDataWrapper, eFormat )[0])); } -static bool ImplDateGetValue( const OUString& rStr, Date& rDate, ExtDateFieldFormat eDateOrder, - const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper ) +bool DateFormatter::TextToDate(const OUString& rStr, Date& rDate, ExtDateFieldFormat eDateOrder, + const LocaleDataWrapper& rLocaleDataWrapper, const CalendarWrapper& rCalendarWrapper) { sal_uInt16 nDay = 0; sal_uInt16 nMonth = 0; @@ -1115,7 +1115,7 @@ static bool ImplDateGetValue( const OUString& rStr, Date& rDate, ExtDateFieldFor void DateFormatter::ImplDateReformat( const OUString& rStr, OUString& rOutStr ) { Date aDate( Date::EMPTY ); - if ( !ImplDateGetValue( rStr, aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper() ) ) + if (!TextToDate(rStr, aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper())) return; Date aTempDate = aDate; @@ -1127,10 +1127,34 @@ void DateFormatter::ImplDateReformat( const OUString& rStr, OUString& rOutStr ) rOutStr = ImplGetDateAsText( aTempDate ); } -OUString DateFormatter::ImplGetDateAsText( const Date& rDate ) const +namespace +{ + ExtDateFieldFormat ResolveSystemFormat(ExtDateFieldFormat eDateFormat, const LocaleDataWrapper& rLocaleData) + { + if (eDateFormat <= ExtDateFieldFormat::SystemShortYYYY) + { + bool bShowCentury = (eDateFormat == ExtDateFieldFormat::SystemShortYYYY); + switch (rLocaleData.getDateOrder()) + { + case DateOrder::DMY: + eDateFormat = bShowCentury ? ExtDateFieldFormat::ShortDDMMYYYY : ExtDateFieldFormat::ShortDDMMYY; + break; + case DateOrder::MDY: + eDateFormat = bShowCentury ? ExtDateFieldFormat::ShortMMDDYYYY : ExtDateFieldFormat::ShortMMDDYY; + break; + default: + eDateFormat = bShowCentury ? ExtDateFieldFormat::ShortYYYYMMDD : ExtDateFieldFormat::ShortYYMMDD; + } + } + return eDateFormat; + } +} + +OUString DateFormatter::FormatDate(const Date& rDate, ExtDateFieldFormat eExtFormat, + const LocaleDataWrapper& rLocaleData, CalendarWrapper& rCalendarWrapper) { bool bShowCentury = false; - switch ( GetExtDateFormat() ) + switch (eExtFormat) { case ExtDateFieldFormat::SystemShortYYYY: case ExtDateFieldFormat::SystemLong: @@ -1162,7 +1186,9 @@ OUString DateFormatter::ImplGetDateAsText( const Date& rDate ) const sal_Unicode aBuf[128]; sal_Unicode* pBuf = aBuf; - OUString aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), GetExtDateFormat( true ) ); + eExtFormat = ResolveSystemFormat(eExtFormat, rLocaleData); + + OUString aDateSep = ImplGetDateSep( rLocaleData, eExtFormat ); sal_uInt16 nDay = rDate.GetDay(); sal_uInt16 nMonth = rDate.GetMonth(); sal_Int16 nYear = rDate.GetYear(); @@ -1171,11 +1197,11 @@ OUString DateFormatter::ImplGetDateAsText( const Date& rDate ) const if ( !bShowCentury ) nYear %= 100; - switch ( GetExtDateFormat( true ) ) + switch (eExtFormat) { case ExtDateFieldFormat::SystemLong: { - return ImplGetLocaleDataWrapper().getLongDate( rDate, GetCalendarWrapper(), !bShowCentury ); + return rLocaleData.getLongDate( rDate, rCalendarWrapper, !bShowCentury ); } case ExtDateFieldFormat::ShortDDMMYY: case ExtDateFieldFormat::ShortDDMMYYYY: @@ -1218,6 +1244,11 @@ OUString DateFormatter::ImplGetDateAsText( const Date& rDate ) const return OUString(aBuf, pBuf-aBuf); } +OUString DateFormatter::ImplGetDateAsText( const Date& rDate ) const +{ + return DateFormatter::FormatDate(rDate, GetExtDateFormat(), ImplGetLocaleDataWrapper(), GetCalendarWrapper()); +} + static void ImplDateIncrementDay( Date& rDate, bool bUp ) { DateFormatter::ExpandCentury( rDate ); @@ -1309,6 +1340,36 @@ bool DateFormatter::ImplAllowMalformedInput() const return !IsEnforceValidValue(); } +int DateFormatter::GetDateArea(ExtDateFieldFormat eFormat, const OUString& rText, int nCursor, const LocaleDataWrapper& rLocaleDataWrapper) +{ + sal_Int8 nDateArea = 0; + + if ( eFormat == ExtDateFieldFormat::SystemLong ) + { + eFormat = ImplGetExtFormat(rLocaleDataWrapper.getLongDateOrder()); + nDateArea = 1; + } + else + { + // search area + sal_Int32 nPos = 0; + OUString aDateSep = ImplGetDateSep(rLocaleDataWrapper, eFormat); + for ( sal_Int8 i = 1; i <= 3; i++ ) + { + nPos = rText.indexOf( aDateSep, nPos ); + if (nPos < 0 || nPos >= nCursor) + { + nDateArea = i; + break; + } + else + nPos++; + } + } + + return nDateArea; +} + void DateField::ImplDateSpinArea( bool bUp ) { // increment days if all is selected @@ -1322,31 +1383,8 @@ void DateField::ImplDateSpinArea( bool bUp ) ImplDateIncrementDay( aDate, bUp ); else { - sal_Int8 nDateArea = 0; - ExtDateFieldFormat eFormat = GetExtDateFormat( true ); - if ( eFormat == ExtDateFieldFormat::SystemLong ) - { - eFormat = ImplGetExtFormat( ImplGetLocaleDataWrapper().getLongDateOrder() ); - nDateArea = 1; - } - else - { - // search area - sal_Int32 nPos = 0; - OUString aDateSep = ImplGetDateSep( ImplGetLocaleDataWrapper(), eFormat ); - for ( sal_Int8 i = 1; i <= 3; i++ ) - { - nPos = aText.indexOf( aDateSep, nPos ); - if (nPos < 0 || nPos >= static_cast<sal_Int32>(aSelection.Max())) - { - nDateArea = i; - break; - } - else - nPos++; - } - } + sal_Int8 nDateArea = GetDateArea(eFormat, aText, aSelection.Max(), ImplGetLocaleDataWrapper()); switch( eFormat ) { @@ -1436,21 +1474,8 @@ ExtDateFieldFormat DateFormatter::GetExtDateFormat( bool bResolveSystemFormat ) { ExtDateFieldFormat eDateFormat = mnExtDateFormat; - if ( bResolveSystemFormat && ( eDateFormat <= ExtDateFieldFormat::SystemShortYYYY ) ) - { - bool bShowCentury = (eDateFormat == ExtDateFieldFormat::SystemShortYYYY); - switch ( ImplGetLocaleDataWrapper().getDateOrder() ) - { - case DateOrder::DMY: - eDateFormat = bShowCentury ? ExtDateFieldFormat::ShortDDMMYYYY : ExtDateFieldFormat::ShortDDMMYY; - break; - case DateOrder::MDY: - eDateFormat = bShowCentury ? ExtDateFieldFormat::ShortMMDDYYYY : ExtDateFieldFormat::ShortMMDDYY; - break; - default: - eDateFormat = bShowCentury ? ExtDateFieldFormat::ShortYYYYMMDD : ExtDateFieldFormat::ShortYYMMDD; - } - } + if (bResolveSystemFormat) + eDateFormat = ResolveSystemFormat(eDateFormat, ImplGetLocaleDataWrapper()); return eDateFormat; } @@ -1492,49 +1517,59 @@ void DateFormatter::SetLongFormat( bool bLong ) ReformatAll(); } -void DateFormatter::SetShowDateCentury( bool bShowDateCentury ) +namespace { - mbShowDateCentury = bShowDateCentury; - - // #91913# Remove LongFormat and DateShowCentury - redundant - if ( bShowDateCentury ) + ExtDateFieldFormat ChangeDateCentury(ExtDateFieldFormat eExtDateFormat, bool bShowDateCentury) { - switch ( GetExtDateFormat() ) + // #91913# Remove LongFormat and DateShowCentury - redundant + if (bShowDateCentury) { - case ExtDateFieldFormat::SystemShort: - case ExtDateFieldFormat::SystemShortYY: - SetExtDateFormat( ExtDateFieldFormat::SystemShortYYYY ); break; - case ExtDateFieldFormat::ShortDDMMYY: - SetExtDateFormat( ExtDateFieldFormat::ShortDDMMYYYY ); break; - case ExtDateFieldFormat::ShortMMDDYY: - SetExtDateFormat( ExtDateFieldFormat::ShortMMDDYYYY ); break; - case ExtDateFieldFormat::ShortYYMMDD: - SetExtDateFormat( ExtDateFieldFormat::ShortYYYYMMDD ); break; - case ExtDateFieldFormat::ShortYYMMDD_DIN5008: - SetExtDateFormat( ExtDateFieldFormat::ShortYYYYMMDD_DIN5008 ); break; - default: - ; + switch (eExtDateFormat) + { + case ExtDateFieldFormat::SystemShort: + case ExtDateFieldFormat::SystemShortYY: + eExtDateFormat = ExtDateFieldFormat::SystemShortYYYY; break; + case ExtDateFieldFormat::ShortDDMMYY: + eExtDateFormat = ExtDateFieldFormat::ShortDDMMYYYY; break; + case ExtDateFieldFormat::ShortMMDDYY: + eExtDateFormat = ExtDateFieldFormat::ShortMMDDYYYY; break; + case ExtDateFieldFormat::ShortYYMMDD: + eExtDateFormat = ExtDateFieldFormat::ShortYYYYMMDD; break; + case ExtDateFieldFormat::ShortYYMMDD_DIN5008: + eExtDateFormat = ExtDateFieldFormat::ShortYYYYMMDD_DIN5008; break; + default: + ; + } } - } - else - { - switch ( GetExtDateFormat() ) + else { - case ExtDateFieldFormat::SystemShort: - case ExtDateFieldFormat::SystemShortYYYY: - SetExtDateFormat( ExtDateFieldFormat::SystemShortYY ); break; - case ExtDateFieldFormat::ShortDDMMYYYY: - SetExtDateFormat( ExtDateFieldFormat::ShortDDMMYY ); break; - case ExtDateFieldFormat::ShortMMDDYYYY: - SetExtDateFormat( ExtDateFieldFormat::ShortMMDDYY ); break; - case ExtDateFieldFormat::ShortYYYYMMDD: - SetExtDateFormat( ExtDateFieldFormat::ShortYYMMDD ); break; - case ExtDateFieldFormat::ShortYYYYMMDD_DIN5008: - SetExtDateFormat( ExtDateFieldFormat::ShortYYMMDD_DIN5008 ); break; - default: - ; + switch (eExtDateFormat) + { + case ExtDateFieldFormat::SystemShort: + case ExtDateFieldFormat::SystemShortYYYY: + eExtDateFormat = ExtDateFieldFormat::SystemShortYY; break; + case ExtDateFieldFormat::ShortDDMMYYYY: + eExtDateFormat = ExtDateFieldFormat::ShortDDMMYY; break; + case ExtDateFieldFormat::ShortMMDDYYYY: + eExtDateFormat = ExtDateFieldFormat::ShortMMDDYY; break; + case ExtDateFieldFormat::ShortYYYYMMDD: + eExtDateFormat = ExtDateFieldFormat::ShortYYMMDD; break; + case ExtDateFieldFormat::ShortYYYYMMDD_DIN5008: + eExtDateFormat = ExtDateFieldFormat::ShortYYMMDD_DIN5008; break; + default: + ; + } } + + return eExtDateFormat; } +} + +void DateFormatter::SetShowDateCentury( bool bShowDateCentury ) +{ + mbShowDateCentury = bShowDateCentury; + + SetExtDateFormat(ChangeDateCentury(GetExtDateFormat(), bShowDateCentury)); ReformatAll(); } @@ -1594,7 +1629,7 @@ Date DateFormatter::GetDate() const if ( GetField() ) { - if ( ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper() ) ) + if (TextToDate(GetField()->GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper())) { if ( aDate > maMax ) aDate = maMax; @@ -1639,7 +1674,7 @@ bool DateFormatter::IsEmptyDate() const else if ( !maLastDate.GetDate() ) { Date aDate( Date::EMPTY ); - bEmpty = !ImplDateGetValue( GetField()->GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper() ); + bEmpty = !TextToDate(GetField()->GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper()); } } return bEmpty; @@ -1659,7 +1694,7 @@ void DateFormatter::Reformat() if ( !aStr.isEmpty() ) { ImplSetText( aStr ); - (void)ImplDateGetValue(aStr, maLastDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper()); + (void)TextToDate(aStr, maLastDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper()); } else { @@ -1741,7 +1776,7 @@ bool DateField::EventNotify( NotifyEvent& rNEvt ) else { Date aDate( 0, 0, 0 ); - if ( ImplDateGetValue( GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper() ) ) + if (TextToDate(GetText(), aDate, GetExtDateFormat(true), ImplGetLocaleDataWrapper(), GetCalendarWrapper())) // even with strict text analysis, our text is a valid date -> do a complete // reformat Reformat(); @@ -1881,6 +1916,79 @@ void DateBox::ReformatAll() SetUpdateMode( true ); } +namespace weld +{ + CalendarWrapper& DateFormatter::GetCalendarWrapper() const + { + if (!m_xCalendarWrapper) + { + m_xCalendarWrapper.reset(new CalendarWrapper(comphelper::getProcessComponentContext())); + m_xCalendarWrapper->loadDefaultCalendar(Application::GetSettings().GetLanguageTag().getLocale()); + } + return *m_xCalendarWrapper; + } + + void DateFormatter::SetShowDateCentury(bool bShowDateCentury) + { + m_eFormat = ChangeDateCentury(m_eFormat, bShowDateCentury); + + ReFormat(); + } + + void DateFormatter::SetDate(const Date& rDate) + { + auto nDate = rDate.GetDate(); + bool bForceOutput = GetEntryText().isEmpty() && rDate == GetDate(); + if (bForceOutput) + { + ImplSetValue(nDate, true); + return; + } + SetValue(nDate); + } + + Date DateFormatter::GetDate() + { + return Date(GetValue()); + } + + void DateFormatter::SetMin(const Date& rNewMin) + { + SetMinValue(rNewMin.GetDate()); + } + + void DateFormatter::SetMax(const Date& rNewMax) + { + SetMaxValue(rNewMax.GetDate()); + } + + OUString DateFormatter::FormatNumber(int nValue) const + { + const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper(); + return ::DateFormatter::FormatDate(Date(nValue), m_eFormat, rLocaleData, GetCalendarWrapper()); + } + + IMPL_LINK_NOARG(DateFormatter, FormatOutputHdl, LinkParamNone*, bool) + { + OUString sText = FormatNumber(GetValue()); + ImplSetTextImpl(sText, nullptr); + return true; + } + + IMPL_LINK(DateFormatter, ParseInputHdl, sal_Int64*, result, TriState) + { + const LocaleDataWrapper& rLocaleDataWrapper = Application::GetSettings().GetLocaleDataWrapper(); + + Date aResult(Date::EMPTY); + bool bRet = ::DateFormatter::TextToDate(GetEntryText(), aResult, ResolveSystemFormat(m_eFormat, rLocaleDataWrapper), + rLocaleDataWrapper, GetCalendarWrapper()); + if (bRet) + *result = aResult.GetDate(); + + return bRet ? TRISTATE_TRUE : TRISTATE_FALSE; + } +} + static bool ImplTimeProcessKeyInput( const KeyEvent& rKEvt, bool bStrictFormat, bool bDuration, TimeFieldFormat eFormat, @@ -2722,7 +2830,14 @@ namespace weld void TimeFormatter::SetTime(const tools::Time& rTime) { - SetValue(ConvertValue(rTime)); + auto nTime = ConvertValue(rTime); + bool bForceOutput = GetEntryText().isEmpty() && rTime == GetTime(); + if (bForceOutput) + { + ImplSetValue(nTime, true); + return; + } + SetValue(nTime); } tools::Time TimeFormatter::GetTime() _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits