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>
diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index b5ffad4..4dc3381 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 1cb4974..36a78606 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 a88105e..a1a1cd9 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 6b994b0..6316c56 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 e1944cc..cc2a49d 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 ac6e1e2..0708c30 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 ba90f7f..3f1c019 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 bce2ff0..0e7729af 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 8fd8f89..d734a8f 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>
<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>
<property name="activates_default">True</property>
<property name="width_chars">1</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">0</property>
</packing>
</child>
<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="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 4c1eb32..8e87c2d 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;
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);
}
VclPtr<CalendarField> pField = VclPtr<CalendarField>::Create( _pParent, _nFieldStyle );
pField->EnableToday();
pField->EnableNone();
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 0a65995..e4203d31 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 267a9fc..e1faaf2 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 9efab32..e245666 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 083bfa6..14fcfe6 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 2388daa..1cbf4fc 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();
}
namespace
{
ExtDateFieldFormat ChangeDateCentury(ExtDateFieldFormat eExtDateFormat, bool bShowDateCentury)
{
// #91913# Remove LongFormat and DateShowCentury - redundant
if (bShowDateCentury)
{
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 (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;
// #91913# Remove LongFormat and DateShowCentury - redundant
if ( bShowDateCentury )
{
switch ( GetExtDateFormat() )
{
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:
;
}
}
else
{
switch ( GetExtDateFormat() )
{
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:
;
}
}
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()