summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-07-15 12:10:32 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-07-21 10:25:42 +0200
commit6e7e19d9c300dbdd279789b09f94781e946fad52 (patch)
tree09155fadd224d8907d0dff7378e5041d3fe6cb1e
parent299638cab15831d31e7906d557d4f95239be4df9 (diff)
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 <caolanm@redhat.com>
-rw-r--r--include/svtools/editbrowsebox.hxx21
-rw-r--r--include/vcl/field.hxx107
-rw-r--r--include/vcl/toolkit/calendar.hxx (renamed from include/vcl/calendar.hxx)6
-rw-r--r--include/vcl/toolkit/field.hxx111
-rw-r--r--include/vcl/weldutils.hxx32
-rw-r--r--solenv/clang-format/excludelist2
-rw-r--r--svtools/source/brwbox/ebbcontrols.cxx69
-rw-r--r--svtools/uiconfig/ui/datewindow.ui54
-rw-r--r--svtools/uiconfig/ui/thineditcontrol.ui83
-rw-r--r--svx/source/fmcomp/gridcell.cxx105
-rw-r--r--svx/source/inc/gridcell.hxx1
-rw-r--r--toolkit/source/awt/vclxtoolkit.cxx2
-rw-r--r--vcl/source/app/weldutils.cxx24
-rw-r--r--vcl/source/control/calendar.cxx2
-rw-r--r--vcl/source/control/field2.cxx291
15 files changed, 630 insertions, 280 deletions
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
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()