extensions/source/propctrlr/propcontroller.cxx | 4 - extensions/source/propctrlr/standardcontrol.cxx | 57 ++++++++++++++++++++---- extensions/source/propctrlr/standardcontrol.hxx | 23 ++++++++- extensions/uiconfig/spropctrlr/ui/datefield.ui | 43 ++++++++++++++---- include/svtools/ctrlbox.hxx | 4 + solenv/sanitizers/ui/modules/spropctrlr.suppr | 2 svtools/source/control/ctrlbox.cxx | 7 ++ 7 files changed, 115 insertions(+), 25 deletions(-)
New commits: commit 03dc85552e74b7a28c9baea53c17797b1d85a543 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Fri Jul 16 17:26:23 2021 +0100 Commit: Adolfo Jayme Barrientos <fit...@ubuntu.com> CommitDate: Tue Aug 17 15:09:52 2021 +0200 tdf#143357 use a DateFormatter and a separate Calendar menubutton similar to what we ended up with in DateControl in svtools/source/brwbox/ebbcontrols.cxx Change-Id: I37c843ff7e1e8e39b318db80fe590ce5f796f46a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120454 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/extensions/source/propctrlr/propcontroller.cxx b/extensions/source/propctrlr/propcontroller.cxx index 4f3365e6b099..0f0409d861e0 100644 --- a/extensions/source/propctrlr/propcontroller.cxx +++ b/extensions/source/propctrlr/propcontroller.cxx @@ -755,8 +755,8 @@ namespace pcr case PropertyControlType::DateField: { std::unique_ptr<weld::Builder> xBuilder(PropertyHandlerHelper::makeBuilder("modules/spropctrlr/ui/datefield.ui", m_xContext)); - auto pMenuButton = xBuilder->weld_menu_button("datefield"); - auto pControl = new ODateControl(std::make_unique<SvtCalendarBox>(std::move(pMenuButton)), std::move(xBuilder), bCreateReadOnly); + auto pContainer = xBuilder->weld_container("datefield"); + auto pControl = new ODateControl(std::move(pContainer), std::move(xBuilder), bCreateReadOnly); pControl->SetModifyHandler(); xControl = pControl; break; diff --git a/extensions/source/propctrlr/standardcontrol.cxx b/extensions/source/propctrlr/standardcontrol.cxx index ef2645a635a1..76fb572fe386 100644 --- a/extensions/source/propctrlr/standardcontrol.cxx +++ b/extensions/source/propctrlr/standardcontrol.cxx @@ -90,34 +90,75 @@ namespace pcr } //= ODateControl - ODateControl::ODateControl(std::unique_ptr<SvtCalendarBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly) + ODateControl::ODateControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly) : ODateControl_Base(PropertyControlType::DateField, std::move(xBuilder), std::move(xWidget), bReadOnly) + , m_xEntry(m_xBuilder->weld_entry("entry")) + , m_xCalendarBox(std::make_unique<SvtCalendarBox>(m_xBuilder->weld_menu_button("button"), false)) { + m_xEntryFormatter.reset(new weld::DateFormatter(*m_xEntry)); + + m_xEntryFormatter->SetStrictFormat(true); + m_xEntryFormatter->SetMin(::Date(1, 1, 1600)); + m_xEntryFormatter->SetMax(::Date(1, 1, 9999)); + + m_xEntryFormatter->SetExtDateFormat(ExtDateFieldFormat::SystemShortYYYY); + m_xEntryFormatter->EnableEmptyField(true); + + m_xCalendarBox->connect_activated(LINK(this, ODateControl, ActivateHdl)); + + m_xCalendarBox->get_button().connect_toggled(LINK(this, ODateControl, ToggleHdl)); } - void SAL_CALL ODateControl::setValue( const Any& _rValue ) + void SAL_CALL ODateControl::disposing() { - SvtCalendarBox* pCalendarBox = getTypedControlWindow(); + m_xEntryFormatter.reset(); + m_xEntry.reset(); + m_xCalendarBox.reset(); + ODateControl_Base::disposing(); + } + void SAL_CALL ODateControl::setValue( const Any& _rValue ) + { util::Date aUNODate; if ( !( _rValue >>= aUNODate ) ) { - pCalendarBox->set_date(::Date(::Date::SYSTEM)); - pCalendarBox->set_label(""); + m_xEntry->set_text(OUString()); } else { ::Date aDate( aUNODate.Day, aUNODate.Month, aUNODate.Year ); - pCalendarBox->set_date(aDate); + m_xEntryFormatter->SetDate(aDate); } } + IMPL_LINK_NOARG(ODateControl, ActivateHdl, SvtCalendarBox&, void) + { + m_xEntryFormatter->SetDate(m_xCalendarBox->get_date()); + setModified(); + m_xEntry->grab_focus(); + } + + IMPL_LINK(ODateControl, ToggleHdl, weld::ToggleButton&, rToggle, void) + { + if (!rToggle.get_active()) + return; + ::Date aDate = m_xEntryFormatter->GetDate(); + if (aDate.IsEmpty()) + { + // with an empty date preselect today in the calendar + aDate = ::Date(::Date::SYSTEM); + } + m_xCalendarBox->set_date(aDate); + } + Any SAL_CALL ODateControl::getValue() { Any aPropValue; - ::Date aDate(getTypedControlWindow()->get_date()); - if (!aDate.IsEmpty()) + if (!m_xEntry->get_text().isEmpty()) + { + ::Date aDate(m_xEntryFormatter->GetDate()); aPropValue <<= aDate.GetUNODate(); + } return aPropValue; } diff --git a/extensions/source/propctrlr/standardcontrol.hxx b/extensions/source/propctrlr/standardcontrol.hxx index 0ed0fc635093..9c41b4362807 100644 --- a/extensions/source/propctrlr/standardcontrol.hxx +++ b/extensions/source/propctrlr/standardcontrol.hxx @@ -61,11 +61,18 @@ namespace pcr }; //= ODateControl - typedef CommonBehaviourControl<css::inspection::XPropertyControl, SvtCalendarBox> ODateControl_Base; + typedef CommonBehaviourControl<css::inspection::XPropertyControl, weld::Container> ODateControl_Base; class ODateControl : public ODateControl_Base { + std::unique_ptr<weld::Entry> m_xEntry; + std::unique_ptr<SvtCalendarBox> m_xCalendarBox; + std::unique_ptr<weld::DateFormatter> m_xEntryFormatter; + + DECL_LINK(ActivateHdl, SvtCalendarBox&, void); + DECL_LINK(ToggleHdl, weld::ToggleButton&, void); + public: - ODateControl(std::unique_ptr<SvtCalendarBox> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly); + ODateControl(std::unique_ptr<weld::Container> xWidget, std::unique_ptr<weld::Builder> xBuilder, bool bReadOnly); // XPropertyControl virtual css::uno::Any SAL_CALL getValue() override; @@ -75,10 +82,18 @@ namespace pcr virtual void SetModifyHandler() override { ODateControl_Base::SetModifyHandler(); - getTypedControlWindow()->connect_selected( LINK( this, CommonBehaviourControlHelper, DateModifiedHdl ) ); + + m_xEntry->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) ); + m_xEntryFormatter->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) ); + m_xCalendarBox->connect_focus_in( LINK( this, CommonBehaviourControlHelper, GetFocusHdl ) ); + m_xCalendarBox->connect_focus_out( LINK( this, CommonBehaviourControlHelper, LoseFocusHdl ) ); + + m_xEntryFormatter->connect_changed(LINK(this, CommonBehaviourControlHelper, EditModifiedHdl)); } - virtual weld::Widget* getWidget() override { return &getTypedControlWindow()->get_button(); } + virtual void SAL_CALL disposing() override; + + virtual weld::Widget* getWidget() override { return getTypedControlWindow(); } }; //= OEditControl diff --git a/extensions/uiconfig/spropctrlr/ui/datefield.ui b/extensions/uiconfig/spropctrlr/ui/datefield.ui index e064f618bfd5..7b6b6ab17f59 100644 --- a/extensions/uiconfig/spropctrlr/ui/datefield.ui +++ b/extensions/uiconfig/spropctrlr/ui/datefield.ui @@ -1,17 +1,44 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.22.1 --> +<!-- Generated with glade 3.38.2 --> <interface domain="pcr"> <requires lib="gtk+" version="3.20"/> - <object class="GtkMenuButton" id="datefield"> + <object class="GtkImage" id="image7"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="focus-on-click">True</property> - <property name="receives_default">False</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="datefield"> + <property name="visible">True</property> + <property name="can-focus">False</property> <property name="hexpand">True</property> - <property name="draw_indicator">True</property> - <property name="label" translatable="no"></property> + <property name="spacing">6</property> + <child> + <object class="GtkEntry" id="entry"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> <child> - <placeholder/> + <object class="GtkMenuButton" id="button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="image">image7</property> + <property name="margin-start">1</property> + <property name="always_show_image">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> </object> </interface> diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx index 43347a14ce40..9cea6647f461 100644 --- a/include/svtools/ctrlbox.hxx +++ b/include/svtools/ctrlbox.hxx @@ -289,7 +289,7 @@ private: class SVT_DLLPUBLIC SvtCalendarBox { public: - SvtCalendarBox(std::unique_ptr<weld::MenuButton> pControl); + SvtCalendarBox(std::unique_ptr<weld::MenuButton> pControl, bool bUseLabel = true); ~SvtCalendarBox(); weld::MenuButton& get_button() { return *m_xControl; } @@ -315,6 +315,8 @@ private: DECL_LINK(SelectHdl, weld::Calendar&, void); DECL_LINK(ActivateHdl, weld::Calendar&, void); + bool m_bUseLabel; + std::unique_ptr<weld::MenuButton> m_xControl; std::unique_ptr<weld::Builder> m_xBuilder; std::unique_ptr<weld::Widget> m_xTopLevel; diff --git a/solenv/sanitizers/ui/modules/spropctrlr.suppr b/solenv/sanitizers/ui/modules/spropctrlr.suppr index 466a32974a5d..5a7ccb3e54a8 100644 --- a/solenv/sanitizers/ui/modules/spropctrlr.suppr +++ b/solenv/sanitizers/ui/modules/spropctrlr.suppr @@ -1,4 +1,6 @@ extensions/uiconfig/spropctrlr/ui/browserline.ui://GtkLabel[@id='label'] orphan-label +extensions/uiconfig/spropctrlr/ui/datefield.ui://GtkEntry[@id='entry'] no-labelled-by +extensions/uiconfig/spropctrlr/ui/datefield.ui://GtkMenuButton[@id='button'] button-no-label extensions/uiconfig/spropctrlr/ui/datetimefield.ui://GtkSpinButton[@id='timefield'] no-labelled-by extensions/uiconfig/spropctrlr/ui/formattedcontrol.ui://GtkSpinButton[@id='formattedcontrol'] no-labelled-by extensions/uiconfig/spropctrlr/ui/formattedsample.ui://GtkEntry[@id='entry'] no-labelled-by diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx index 7c7f61cb61f8..a70d6d6c4120 100644 --- a/svtools/source/control/ctrlbox.cxx +++ b/svtools/source/control/ctrlbox.cxx @@ -1643,8 +1643,9 @@ void SvtLineListBox::UpdatePreview() } } -SvtCalendarBox::SvtCalendarBox(std::unique_ptr<weld::MenuButton> pControl) - : m_xControl(std::move(pControl)) +SvtCalendarBox::SvtCalendarBox(std::unique_ptr<weld::MenuButton> pControl, bool bUseLabel) + : m_bUseLabel(bUseLabel) + , m_xControl(std::move(pControl)) , m_xBuilder(Application::CreateBuilder(m_xControl.get(), "svt/ui/datewindow.ui")) , m_xTopLevel(m_xBuilder->weld_widget("date_popup_window")) , m_xCalendar(m_xBuilder->weld_calendar("date")) @@ -1662,6 +1663,8 @@ void SvtCalendarBox::set_date(const Date& rDate) void SvtCalendarBox::set_label_from_date() { + if (!m_bUseLabel) + return; const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper(); m_xControl->set_label(rLocaleData.getDate(m_xCalendar->get_date())); }