[Libreoffice-commits] core.git: include/svtools include/vcl sc/inc sc/source sc/uiconfig solenv/sanitizers svtools/source svtools/uiconfig svtools/UIConfig_svt.mk vcl/source vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Feb 15 14:12:24 UTC 2019


 include/svtools/ctrlbox.hxx              |   24 ++
 include/vcl/calendar.hxx                 |    3 
 include/vcl/weld.hxx                     |   20 ++
 sc/inc/scabstdlg.hxx                     |    8 
 sc/source/ui/attrdlg/scdlgfact.cxx       |   14 -
 sc/source/ui/attrdlg/scdlgfact.hxx       |   17 +
 sc/source/ui/dbgui/dpgroupdlg.cxx        |  268 ++++++++++++-------------------
 sc/source/ui/inc/dpgroupdlg.hxx          |  103 ++++-------
 sc/source/ui/inc/editfield.hxx           |    2 
 sc/source/ui/view/cellsh1.cxx            |    2 
 sc/uiconfig/scalc/ui/groupbydate.ui      |  108 +++++++++++-
 solenv/sanitizers/ui/modules/scalc.suppr |    5 
 svtools/UIConfig_svt.mk                  |    1 
 svtools/source/control/ctrlbox.cxx       |   33 +++
 svtools/uiconfig/ui/datewindow.ui        |   32 +++
 vcl/source/app/salvtables.cxx            |   55 ++++++
 vcl/source/control/calendar.cxx          |   18 ++
 vcl/unx/gtk3/gtk3gtkinst.cxx             |   90 ++++++++++
 18 files changed, 546 insertions(+), 257 deletions(-)

New commits:
commit 03b4d8f486d9ecdfe21a05d6bf65c396a35772f6
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Feb 14 21:26:27 2019 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Fri Feb 15 15:11:58 2019 +0100

    weld ScDPDateGroupDlg
    
    adding a weld::Calendar and a pretty menubutton to access it, sidestepping the
    difficulty of abusing a spinbutton to select a date. The prettiness is wasted
    on this hard to find obscure dialog
    
    Change-Id: I51d461fe0220f947c106d96965e6422b4b26575b
    Reviewed-on: https://gerrit.libreoffice.org/67863
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/include/svtools/ctrlbox.hxx b/include/svtools/ctrlbox.hxx
index eea2e0a51023..c8ea9320c504 100644
--- a/include/svtools/ctrlbox.hxx
+++ b/include/svtools/ctrlbox.hxx
@@ -308,6 +308,30 @@ private:
     Link<SvtLineListBox&,void> maSelectHdl;
 };
 
+class SVT_DLLPUBLIC SvtCalendarBox
+{
+public:
+    SvtCalendarBox(std::unique_ptr<weld::MenuButton> pControl);
+    ~SvtCalendarBox();
+
+    weld::MenuButton& get_button() { return *m_xControl; }
+
+    void set_date(const Date& rDate);
+    Date get_date() const { return m_xCalendar->get_date(); }
+
+    void set_sensitive(bool bSensitive) { m_xControl->set_sensitive(bSensitive); }
+    bool get_sensitive() const { return m_xControl->get_sensitive(); }
+    void grab_focus() { m_xControl->grab_focus(); }
+private:
+    DECL_LINK(SelectHdl, weld::Calendar&, void);
+    DECL_LINK(ActivateHdl, weld::Calendar&, void);
+
+    std::unique_ptr<weld::MenuButton> m_xControl;
+    std::unique_ptr<weld::Builder> m_xBuilder;
+    std::unique_ptr<weld::Widget> m_xTopLevel;
+    std::unique_ptr<weld::Calendar> m_xCalendar;
+};
+
 class SVT_DLLPUBLIC FontNameBox : public ComboBox
 {
 private:
diff --git a/include/vcl/calendar.hxx b/include/vcl/calendar.hxx
index 575af0101c9e..fe4f7ea7c0eb 100644
--- a/include/vcl/calendar.hxx
+++ b/include/vcl/calendar.hxx
@@ -165,6 +165,7 @@ class VCL_DLLPUBLIC Calendar final : public Control
                     mbTravelSelect:1,
                     mbAllSel:1;
     Link<Calendar*,void>   maSelectHdl;
+    Link<Calendar*,void>   maActivateHdl;
 
     using Control::ImplInitSettings;
     using Window::ImplInit;
@@ -193,6 +194,7 @@ class VCL_DLLPUBLIC Calendar final : public Control
     VCL_DLLPRIVATE void         ImplEndTracking( bool bCancel );
     VCL_DLLPRIVATE DayOfWeek    ImplGetWeekStart() const;
 
+    virtual Size GetOptimalSize() const override;
 public:
                     Calendar( vcl::Window* pParent, WinBits nWinStyle );
     virtual         ~Calendar() override;
@@ -235,6 +237,7 @@ public:
     Size            CalcWindowSizePixel() const;
 
     void            SetSelectHdl( const Link<Calendar*,void>& rLink ) { maSelectHdl = rLink; }
+    void            SetActivateHdl( const Link<Calendar*,void>& rLink ) { maActivateHdl = rLink; }
 };
 
 #endif // INCLUDED_VCL_CALENDAR_HXX
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 7a88c60189bf..868a444dcf87 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -12,6 +12,7 @@
 
 #include <rtl/ustring.hxx>
 #include <tools/color.hxx>
+#include <tools/date.hxx>
 #include <tools/fldunit.hxx>
 #include <tools/gen.hxx>
 #include <tools/link.hxx>
@@ -942,6 +943,23 @@ public:
     virtual void set_from_icon_name(const OUString& rIconName) = 0;
 };
 
+class VCL_DLLPUBLIC Calendar : virtual public Widget
+{
+protected:
+    Link<Calendar&, void> m_aSelectedHdl;
+    Link<Calendar&, void> m_aActivatedHdl;
+
+    void signal_selected() { m_aSelectedHdl.Call(*this); }
+    void signal_activated() { m_aActivatedHdl.Call(*this); }
+
+public:
+    void connect_selected(const Link<Calendar&, void>& rLink) { m_aSelectedHdl = rLink; }
+    void connect_activated(const Link<Calendar&, void>& rLink) { m_aActivatedHdl = rLink; }
+
+    virtual void set_date(const Date& rDate) = 0;
+    virtual Date get_date() const = 0;
+};
+
 // an entry + treeview pair, where the entry autocompletes from the
 // treeview list, and selecting something in the list sets the
 // entry to that text, i.e. a visually exploded ComboBox
@@ -1472,6 +1490,8 @@ public:
                                                            bool bTakeOwnership = false)
         = 0;
     virtual std::unique_ptr<Image> weld_image(const OString& id, bool bTakeOwnership = false) = 0;
+    virtual std::unique_ptr<Calendar> weld_calendar(const OString& id, bool bTakeOwnership = false)
+        = 0;
     virtual std::unique_ptr<DrawingArea>
     weld_drawing_area(const OString& id, const a11yref& rA11yImpl = nullptr,
                       FactoryFunction pUITestFactoryFunction = nullptr, void* pUserData = nullptr,
diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx
index f4e48b1e063b..495d8061751b 100644
--- a/sc/inc/scabstdlg.hxx
+++ b/sc/inc/scabstdlg.hxx
@@ -485,10 +485,10 @@ public:
     virtual VclPtr<AbstractScDPNumGroupDlg> CreateScDPNumGroupDlg(weld::Window* pParent,
                                                                   const ScDPNumGroupInfo& rInfo) = 0;
 
-    virtual VclPtr<AbstractScDPDateGroupDlg> CreateScDPDateGroupDlg( vcl::Window* pParent,
-                                                                const ScDPNumGroupInfo& rInfo,
-                                                                sal_Int32 nDatePart,
-                                                                const Date& rNullDate ) = 0;
+    virtual VclPtr<AbstractScDPDateGroupDlg> CreateScDPDateGroupDlg(weld::Window* pParent,
+                                                                    const ScDPNumGroupInfo& rInfo,
+                                                                    sal_Int32 nDatePart,
+                                                                    const Date& rNullDate ) = 0;
 
     virtual VclPtr<AbstractScDPShowDetailDlg> CreateScDPShowDetailDlg(weld::Window* pParent,
                                                                 ScDPObject& rDPObj,
diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx
index 3f24dc09439a..14d40c76febf 100644
--- a/sc/source/ui/attrdlg/scdlgfact.cxx
+++ b/sc/source/ui/attrdlg/scdlgfact.cxx
@@ -174,7 +174,10 @@ short AbstractScDPNumGroupDlg_Impl::Execute()
     return m_xDlg->run();
 }
 
-IMPL_ABSTDLG_BASE(AbstractScDPDateGroupDlg_Impl);
+short AbstractScDPDateGroupDlg_Impl::Execute()
+{
+    return m_xDlg->run();
+}
 
 short AbstractScDPShowDetailDlg_Impl::Execute()
 {
@@ -624,12 +627,12 @@ ScDPNumGroupInfo AbstractScDPNumGroupDlg_Impl::GetGroupInfo() const
 
 ScDPNumGroupInfo AbstractScDPDateGroupDlg_Impl::GetGroupInfo() const
 {
-    return pDlg->GetGroupInfo();
+    return m_xDlg->GetGroupInfo();
 }
 
 sal_Int32 AbstractScDPDateGroupDlg_Impl::GetDatePart() const
 {
-    return pDlg->GetDatePart();
+    return m_xDlg->GetDatePart();
 }
 
 OUString AbstractScDPShowDetailDlg_Impl::GetDimensionName() const
@@ -925,10 +928,9 @@ VclPtr<AbstractScDPNumGroupDlg> ScAbstractDialogFactory_Impl::CreateScDPNumGroup
 }
 
 VclPtr<AbstractScDPDateGroupDlg> ScAbstractDialogFactory_Impl::CreateScDPDateGroupDlg(
-        vcl::Window* pParent,
-        const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate )
+        weld::Window* pParent, const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate)
 {
-    return VclPtr<AbstractScDPDateGroupDlg_Impl>::Create( VclPtr<ScDPDateGroupDlg>::Create( pParent, rInfo, nDatePart, rNullDate ) );
+    return VclPtr<AbstractScDPDateGroupDlg_Impl>::Create(new ScDPDateGroupDlg(pParent, rInfo, nDatePart, rNullDate));
 }
 
 VclPtr<AbstractScDPShowDetailDlg> ScAbstractDialogFactory_Impl::CreateScDPShowDetailDlg (
diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx
index ddee8f8607ea..f134f9a1d294 100644
--- a/sc/source/ui/attrdlg/scdlgfact.hxx
+++ b/sc/source/ui/attrdlg/scdlgfact.hxx
@@ -419,7 +419,14 @@ public:
 
 class AbstractScDPDateGroupDlg_Impl : public AbstractScDPDateGroupDlg
 {
-    DECL_ABSTDLG_BASE( AbstractScDPDateGroupDlg_Impl, ScDPDateGroupDlg )
+protected:
+    std::unique_ptr<ScDPDateGroupDlg> m_xDlg;
+public:
+    explicit AbstractScDPDateGroupDlg_Impl(ScDPDateGroupDlg* p)
+        : m_xDlg(p)
+    {
+    }
+    virtual short Execute() override;
     virtual ScDPNumGroupInfo GetGroupInfo() const override;
     virtual sal_Int32 GetDatePart() const override;
 };
@@ -659,10 +666,10 @@ public:
     virtual VclPtr<AbstractScDPNumGroupDlg> CreateScDPNumGroupDlg(weld::Window* pParent,
                                                                   const ScDPNumGroupInfo& rInfo) override;
 
-    virtual VclPtr<AbstractScDPDateGroupDlg> CreateScDPDateGroupDlg( vcl::Window* pParent,
-                                                                const ScDPNumGroupInfo& rInfo,
-                                                                sal_Int32 nDatePart,
-                                                                const Date& rNullDate ) override;
+    virtual VclPtr<AbstractScDPDateGroupDlg> CreateScDPDateGroupDlg(weld::Window* pParent,
+                                                                    const ScDPNumGroupInfo& rInfo,
+                                                                    sal_Int32 nDatePart,
+                                                                    const Date& rNullDate) override;
 
     virtual VclPtr<AbstractScDPShowDetailDlg> CreateScDPShowDetailDlg(weld::Window* pParent,
                                                                 ScDPObject& rDPObj,
diff --git a/sc/source/ui/dbgui/dpgroupdlg.cxx b/sc/source/ui/dbgui/dpgroupdlg.cxx
index f1e3f3f927ad..a7ba75b12eb7 100644
--- a/sc/source/ui/dbgui/dpgroupdlg.cxx
+++ b/sc/source/ui/dbgui/dpgroupdlg.cxx
@@ -55,18 +55,18 @@ static const char* aDatePartResIds[] =
 
 } // namespace
 
-ScDPGroupEditHelper::ScDPGroupEditHelper( RadioButton* pRbAuto, RadioButton* pRbMan, Edit* pEdValue ) :
-    mpRbAuto( pRbAuto ),
-    mpRbMan( pRbMan ),
-    mpEdValue( pEdValue )
+ScDPGroupEditHelper::ScDPGroupEditHelper(weld::RadioButton& rRbAuto, weld::RadioButton& rRbMan, weld::Widget& rEdValue)
+    : mrRbAuto(rRbAuto)
+    , mrRbMan(rRbMan)
+    , mrEdValue(rEdValue)
 {
-    mpRbAuto->SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
-    mpRbMan->SetClickHdl( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
+    mrRbAuto.connect_clicked( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
+    mrRbMan.connect_clicked( LINK( this, ScDPGroupEditHelper, ClickHdl ) );
 }
 
 bool ScDPGroupEditHelper::IsAuto() const
 {
-    return mpRbAuto->IsChecked();
+    return mrRbAuto.get_active();
 }
 
 double ScDPGroupEditHelper::GetValue() const
@@ -81,112 +81,60 @@ void ScDPGroupEditHelper::SetValue( bool bAuto, double fValue )
 {
     if( bAuto )
     {
-        mpRbAuto->Check();
-        ClickHdl( mpRbAuto );
+        mrRbAuto.set_active(true);
+        ClickHdl(mrRbAuto);
     }
     else
     {
-        mpRbMan->Check();
-        ClickHdl( mpRbMan );
+        mrRbMan.set_active(true);
+        ClickHdl(mrRbMan);
     }
     ImplSetValue( fValue );
 }
 
-IMPL_LINK( ScDPGroupEditHelper, ClickHdl, Button*, pButton, void )
+IMPL_LINK(ScDPGroupEditHelper, ClickHdl, weld::Button&, rButton, void)
 {
-    if( pButton == mpRbAuto )
+    if (&rButton == &mrRbAuto)
     {
         // disable edit field on clicking "automatic" radio button
-        mpEdValue->Disable();
+        mrEdValue.set_sensitive(false);
     }
-    else if( pButton == mpRbMan )
+    else if (&rButton == &mrRbMan)
     {
         // enable and set focus to edit field on clicking "manual" radio button
-        mpEdValue->Enable();
-        mpEdValue->GrabFocus();
+        mrEdValue.set_sensitive(true);
+        mrEdValue.grab_focus();
     }
 }
 
-DPGroupEditHelper::DPGroupEditHelper(weld::RadioButton* pRbAuto, weld::RadioButton* pRbMan, weld::Entry* pEdValue)
-    : mpRbAuto(pRbAuto)
-    , mpRbMan(pRbMan)
-    , mpEdValue(pEdValue)
-{
-    mpRbAuto->connect_clicked( LINK( this, DPGroupEditHelper, ClickHdl ) );
-    mpRbMan->connect_clicked( LINK( this, DPGroupEditHelper, ClickHdl ) );
-}
-
-bool DPGroupEditHelper::IsAuto() const
-{
-    return mpRbAuto->get_active();
-}
-
-double DPGroupEditHelper::GetValue() const
-{
-    double fValue;
-    if( !ImplGetValue( fValue ) )
-        fValue = 0.0;
-    return fValue;
-}
-
-void DPGroupEditHelper::SetValue( bool bAuto, double fValue )
-{
-    if( bAuto )
-    {
-        mpRbAuto->set_active(true);
-        ClickHdl(*mpRbAuto);
-    }
-    else
-    {
-        mpRbMan->set_active(true);
-        ClickHdl(*mpRbMan);
-    }
-    ImplSetValue( fValue );
-}
-
-IMPL_LINK(DPGroupEditHelper, ClickHdl, weld::Button&, rButton, void)
-{
-    if (&rButton == mpRbAuto)
-    {
-        // disable edit field on clicking "automatic" radio button
-        mpEdValue->set_sensitive(false);
-    }
-    else if (&rButton == mpRbMan)
-    {
-        // enable and set focus to edit field on clicking "manual" radio button
-        mpEdValue->set_sensitive(true);
-        mpEdValue->grab_focus();
-    }
-}
-
-ScDPNumGroupEditHelper::ScDPNumGroupEditHelper(weld::RadioButton* pRbAuto,
-    weld::RadioButton* pRbMan, DoubleField* pEdValue)
-    : DPGroupEditHelper(pRbAuto, pRbMan, pEdValue->get_widget())
-    , mpEdValue(pEdValue)
+ScDPNumGroupEditHelper::ScDPNumGroupEditHelper(weld::RadioButton& rRbAuto,
+    weld::RadioButton& rRbMan, DoubleField& rEdValue)
+    : ScDPGroupEditHelper(rRbAuto, rRbMan, rEdValue.get_widget())
+    , mrEdValue(rEdValue)
 {
 }
 
 bool ScDPNumGroupEditHelper::ImplGetValue( double& rfValue ) const
 {
-    return mpEdValue->GetValue( rfValue );
+    return mrEdValue.GetValue(rfValue);
 }
 
 void ScDPNumGroupEditHelper::ImplSetValue( double fValue )
 {
-    mpEdValue->SetValue( fValue );
+    mrEdValue.SetValue(fValue);
 }
 
-ScDPDateGroupEditHelper::ScDPDateGroupEditHelper(
-        RadioButton* pRbAuto, RadioButton* pRbMan, DateField* pEdValue, const Date& rNullDate ) :
-    ScDPGroupEditHelper( pRbAuto, pRbMan, pEdValue ),
-    mpEdValue( pEdValue ),
-    maNullDate( rNullDate )
+ScDPDateGroupEditHelper::ScDPDateGroupEditHelper(weld::RadioButton& rRbAuto, weld::RadioButton& rRbMan,
+                                                 SvtCalendarBox& rEdValue, const Date& rNullDate)
+    : ScDPGroupEditHelper(rRbAuto, rRbMan, rEdValue.get_button())
+    , mrEdValue(rEdValue)
+    , maNullDate(rNullDate)
 {
 }
 
 bool ScDPDateGroupEditHelper::ImplGetValue( double& rfValue ) const
 {
-    rfValue = mpEdValue->GetDate() - maNullDate;
+    rfValue = mrEdValue.get_date() - maNullDate;
     return true;
 }
 
@@ -194,7 +142,7 @@ void ScDPDateGroupEditHelper::ImplSetValue( double fValue )
 {
     Date aDate( maNullDate );
     aDate.AddDays( fValue );
-    mpEdValue->SetDate( aDate );
+    mrEdValue.set_date( aDate );
 }
 
 ScDPNumGroupDlg::ScDPNumGroupDlg(weld::Window* pParent, const ScDPNumGroupInfo& rInfo)
@@ -206,8 +154,8 @@ ScDPNumGroupDlg::ScDPNumGroupDlg(weld::Window* pParent, const ScDPNumGroupInfo&
     , mxRbManEnd(m_xBuilder->weld_radio_button("manual_end"))
     , mxEdEnd(new DoubleField(m_xBuilder->weld_entry("edit_end")))
     , mxEdBy(new DoubleField(m_xBuilder->weld_entry("edit_by")))
-    , maStartHelper(mxRbAutoStart.get(), mxRbManStart.get(), mxEdStart.get())
-    , maEndHelper(mxRbAutoEnd.get(), mxRbManEnd.get(), mxEdEnd.get())
+    , maStartHelper(*mxRbAutoStart, *mxRbManStart, *mxEdStart)
+    , maEndHelper(*mxRbAutoEnd, *mxRbManEnd, *mxEdEnd)
 {
     maStartHelper.SetValue( rInfo.mbAutoStart, rInfo.mfStart );
     maEndHelper.SetValue( rInfo.mbAutoEnd, rInfo.mfEnd );
@@ -247,98 +195,82 @@ ScDPNumGroupInfo ScDPNumGroupDlg::GetGroupInfo() const
     return aInfo;
 }
 
-ScDPDateGroupDlg::ScDPDateGroupDlg( vcl::Window* pParent,
-        const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate ) :
-    ModalDialog( pParent, "PivotTableGroupByDate", "modules/scalc/ui/groupbydate.ui" ),
-    mpRbAutoStart   ( get<RadioButton>("auto_start") ),
-    mpRbManStart    ( get<RadioButton>("manual_start") ),
-    mpEdStart       ( get<DateField>("start_date") ),
-    mpRbAutoEnd     ( get<RadioButton>("auto_end") ),
-    mpRbManEnd      ( get<RadioButton>("manual_end") ),
-    mpEdEnd         ( get<DateField>("end_date") ),
-    mpRbNumDays     ( get<RadioButton>("days") ),
-    mpRbUnits       ( get<RadioButton>("intervals") ),
-    mpEdNumDays     ( get<NumericField>("days_value") ),
-    mpLbUnits       ( get<SvxCheckListBox>("interval_list") ),
-    mpBtnOk         ( get<OKButton>("ok") ),
-    maStartHelper   ( mpRbAutoStart, mpRbManStart, mpEdStart, rNullDate ),
-    maEndHelper     ( mpRbAutoEnd, mpRbManEnd, mpEdEnd, rNullDate )
+ScDPDateGroupDlg::ScDPDateGroupDlg(weld::Window* pParent,
+        const ScDPNumGroupInfo& rInfo, sal_Int32 nDatePart, const Date& rNullDate)
+    : GenericDialogController(pParent, "modules/scalc/ui/groupbydate.ui", "PivotTableGroupByDate")
+    , mxRbAutoStart(m_xBuilder->weld_radio_button("auto_start"))
+    , mxRbManStart(m_xBuilder->weld_radio_button("manual_start"))
+    , mxEdStart(new SvtCalendarBox(m_xBuilder->weld_menu_button("start_date")))
+    , mxRbAutoEnd(m_xBuilder->weld_radio_button("auto_end"))
+    , mxRbManEnd(m_xBuilder->weld_radio_button("manual_end"))
+    , mxEdEnd(new SvtCalendarBox(m_xBuilder->weld_menu_button("end_date")))
+    , mxRbNumDays(m_xBuilder->weld_radio_button("days"))
+    , mxRbUnits(m_xBuilder->weld_radio_button("intervals"))
+    , mxEdNumDays(m_xBuilder->weld_spin_button("days_value"))
+    , mxLbUnits(m_xBuilder->weld_tree_view("interval_list"))
+    , mxBtnOk(m_xBuilder->weld_button("ok"))
+    , maStartHelper(*mxRbAutoStart, *mxRbManStart, *mxEdStart, rNullDate)
+    , maEndHelper(*mxRbAutoEnd, *mxRbManEnd, *mxEdEnd, rNullDate)
 {
-    static const size_t nCount = SAL_N_ELEMENTS(aDatePartResIds);
-    for (const char* pDatePartResId : aDatePartResIds)
-        mpLbUnits->InsertEntry(ScResId(pDatePartResId));
-
-    mpEdStart->SetShowDateCentury( true );
-    mpEdEnd->SetShowDateCentury( true );
-
     maStartHelper.SetValue( rInfo.mbAutoStart, rInfo.mfStart );
     maEndHelper.SetValue( rInfo.mbAutoEnd, rInfo.mfEnd );
 
+    std::vector<int> aWidths;
+    aWidths.push_back(mxLbUnits->get_checkbox_column_width());
+    mxLbUnits->set_column_fixed_widths(aWidths);
+
     if( nDatePart == 0 )
         nDatePart = css::sheet::DataPilotFieldGroupBy::MONTHS;
-    for( size_t nIdx = 0; nIdx < nCount; ++nIdx )
-        mpLbUnits->CheckEntryPos( static_cast< sal_uInt16 >( nIdx ), (nDatePart & spnDateParts[ nIdx ]) != 0 );
+    for (size_t nIdx = 0; nIdx < SAL_N_ELEMENTS(aDatePartResIds); ++nIdx)
+    {
+        mxLbUnits->insert(nullptr, -1, nullptr, nullptr, nullptr, nullptr, nullptr, false);
+        mxLbUnits->set_toggle(nIdx, (nDatePart & spnDateParts[ nIdx ]) != 0, 0);
+        mxLbUnits->set_text(nIdx, ScResId(aDatePartResIds[nIdx]), 1);
+    }
 
     if( rInfo.mbDateValues )
     {
-        mpRbNumDays->Check();
-        ClickHdl( mpRbNumDays );
+        mxRbNumDays->set_active(true);
+        ClickHdl(*mxRbNumDays );
 
         double fNumDays = rInfo.mfStep;
         if( fNumDays < 1.0 )
             fNumDays = 1.0;
         else if( fNumDays > 32767.0 )
             fNumDays = 32767.0;
-        mpEdNumDays->SetValue( static_cast< long >( fNumDays ) );
+        mxEdNumDays->set_value(fNumDays);
     }
     else
     {
-        mpRbUnits->Check();
-        ClickHdl( mpRbUnits );
+        mxRbUnits->set_active(true);
+        ClickHdl(*mxRbUnits);
     }
 
     /*  Set the initial focus, currently it is somewhere after calling all the radio
         button click handlers. Now the first enabled editable control is focused. */
-    if( mpEdStart->IsEnabled() )
-        mpEdStart->GrabFocus();
-    else if( mpEdEnd->IsEnabled() )
-        mpEdEnd->GrabFocus();
-    else if( mpEdNumDays->IsEnabled() )
-        mpEdNumDays->GrabFocus();
-    else if( mpLbUnits->IsEnabled() )
-        mpLbUnits->GrabFocus();
-
-    mpRbNumDays->SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
-    mpRbUnits->SetClickHdl( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
-    mpLbUnits->SetCheckButtonHdl( LINK( this, ScDPDateGroupDlg, CheckHdl ) );
+    if( mxEdStart->get_sensitive() )
+        mxEdStart->grab_focus();
+    else if( mxEdEnd->get_sensitive() )
+        mxEdEnd->grab_focus();
+    else if( mxEdNumDays->get_sensitive() )
+        mxEdNumDays->grab_focus();
+    else if( mxLbUnits->get_sensitive() )
+        mxLbUnits->grab_focus();
+
+    mxRbNumDays->connect_clicked( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
+    mxRbUnits->connect_clicked( LINK( this, ScDPDateGroupDlg, ClickHdl ) );
+    mxLbUnits->connect_toggled( LINK( this, ScDPDateGroupDlg, CheckHdl ) );
 }
 
 ScDPDateGroupDlg::~ScDPDateGroupDlg()
 {
-    disposeOnce();
-}
-
-void ScDPDateGroupDlg::dispose()
-{
-    mpRbAutoStart.clear();
-    mpRbManStart.clear();
-    mpEdStart.clear();
-    mpRbAutoEnd.clear();
-    mpRbManEnd.clear();
-    mpEdEnd.clear();
-    mpRbNumDays.clear();
-    mpRbUnits.clear();
-    mpEdNumDays.clear();
-    mpLbUnits.clear();
-    mpBtnOk.clear();
-    ModalDialog::dispose();
 }
 
 ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const
 {
     ScDPNumGroupInfo aInfo;
     aInfo.mbEnable = true;
-    aInfo.mbDateValues = mpRbNumDays->IsChecked();
+    aInfo.mbDateValues = mxRbNumDays->get_active();
     aInfo.mbAutoStart = maStartHelper.IsAuto();
     aInfo.mbAutoEnd = maEndHelper.IsAuto();
 
@@ -346,7 +278,7 @@ ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const
     // TODO: error messages in OK event?
     aInfo.mfStart = maStartHelper.GetValue();
     aInfo.mfEnd = maEndHelper.GetValue();
-    sal_Int64 nNumDays = mpEdNumDays->GetValue();
+    sal_Int64 nNumDays = mxEdNumDays->get_value();
     aInfo.mfStep = static_cast<double>( aInfo.mbDateValues ? nNumDays : 0L );
     if( aInfo.mfEnd <= aInfo.mfStart )
         aInfo.mfEnd = aInfo.mfStart + nNumDays;
@@ -357,43 +289,55 @@ ScDPNumGroupInfo ScDPDateGroupDlg::GetGroupInfo() const
 sal_Int32 ScDPDateGroupDlg::GetDatePart() const
 {
     // return DAYS for special "number of days" mode
-    if( mpRbNumDays->IsChecked() )
+    if( mxRbNumDays->get_active() )
         return css::sheet::DataPilotFieldGroupBy::DAYS;
 
     // return listbox contents for "units" mode
     sal_Int32 nDatePart = 0;
-    for( sal_uLong nIdx = 0, nCount = mpLbUnits->GetEntryCount(); nIdx < nCount; ++nIdx )
-        if( mpLbUnits->IsChecked( static_cast< sal_uInt16 >( nIdx ) ) )
+    for (int nIdx = 0, nCount = mxLbUnits->n_children(); nIdx < nCount; ++nIdx )
+        if (mxLbUnits->get_toggle(nIdx, 0))
             nDatePart |= spnDateParts[ nIdx ];
     return nDatePart;
 }
 
-IMPL_LINK( ScDPDateGroupDlg, ClickHdl, Button*, pButton, void )
+IMPL_LINK(ScDPDateGroupDlg, ClickHdl, weld::Button&, rButton, void)
 {
-    if( pButton == mpRbNumDays )
+    if (&rButton == mxRbNumDays.get())
     {
-        mpLbUnits->Disable();
+        mxLbUnits->set_sensitive(false);
         // enable and set focus to edit field on clicking "num of days" radio button
-        mpEdNumDays->Enable();
-        mpEdNumDays->GrabFocus();
-        mpBtnOk->Enable();
+        mxEdNumDays->set_sensitive(true);
+        mxEdNumDays->grab_focus();
+        mxBtnOk->set_sensitive(true);
     }
-    else if( pButton == mpRbUnits )
+    else if (&rButton == mxRbUnits.get())
     {
-        mpEdNumDays->Disable();
+        mxEdNumDays->set_sensitive(false);
         // enable and set focus to listbox on clicking "units" radio button
-        mpLbUnits->Enable();
-        mpLbUnits->GrabFocus();
+        mxLbUnits->set_sensitive(true);
+        mxLbUnits->grab_focus();
         // disable OK button if no date part selected
-        CheckHdl( mpLbUnits );
+        CheckHdl(row_col(0, 0));
+    }
+}
+
+namespace
+{
+    bool HasCheckedEntryCount(const weld::TreeView& rView)
+    {
+        for (int i = 0; i < rView.n_children(); ++i)
+        {
+            if (rView.get_toggle(i, 0))
+                return true;
+        }
+        return false;
     }
 }
 
-IMPL_LINK( ScDPDateGroupDlg, CheckHdl, SvTreeListBox*, pListBox, void )
+IMPL_LINK_NOARG(ScDPDateGroupDlg, CheckHdl, const row_col&, void)
 {
     // enable/disable OK button on modifying check list box
-    if( pListBox == mpLbUnits )
-        mpBtnOk->Enable( mpLbUnits->GetCheckedEntryCount() > 0 );
+    mxBtnOk->set_sensitive(HasCheckedEntryCount(*mxLbUnits));
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/dpgroupdlg.hxx b/sc/source/ui/inc/dpgroupdlg.hxx
index 00d5943dc643..a8e33b36fbe6 100644
--- a/sc/source/ui/inc/dpgroupdlg.hxx
+++ b/sc/source/ui/inc/dpgroupdlg.hxx
@@ -24,16 +24,16 @@
 #include <vcl/button.hxx>
 #include <vcl/field.hxx>
 #include <vcl/weld.hxx>
-#include <svx/checklbx.hxx>
+#include <svtools/ctrlbox.hxx>
 #include "editfield.hxx"
 #include <dpnumgroupinfo.hxx>
 
 class ScDPGroupEditHelper
 {
 public:
-    explicit            ScDPGroupEditHelper(
-                            RadioButton* rRbAuto, RadioButton* rRbMan,
-                            Edit* rEdValue );
+    explicit ScDPGroupEditHelper(weld::RadioButton& rRbAuto,
+                                 weld::RadioButton& rRbMan,
+                                 weld::Widget& rEdValue);
 
     bool                IsAuto() const;
     double              GetValue() const;
@@ -46,47 +46,20 @@ private:
     virtual bool        ImplGetValue( double& rfValue ) const = 0;
     virtual void        ImplSetValue( double fValue ) = 0;
 
-    DECL_LINK( ClickHdl, Button*, void );
-
-private:
-    VclPtr<RadioButton>        mpRbAuto;
-    VclPtr<RadioButton>        mpRbMan;
-    VclPtr<Edit>               mpEdValue;
-};
-
-class DPGroupEditHelper
-{
-public:
-    explicit            DPGroupEditHelper(
-                            weld::RadioButton* rRbAuto, weld::RadioButton* rRbMan,
-                            weld::Entry* rEdValue );
-
-    bool                IsAuto() const;
-    double              GetValue() const;
-    void                SetValue( bool bAuto, double fValue );
-
-protected:
-    ~DPGroupEditHelper() {}
-
-private:
-    virtual bool        ImplGetValue( double& rfValue ) const = 0;
-    virtual void        ImplSetValue( double fValue ) = 0;
-
     DECL_LINK(ClickHdl, weld::Button&, void);
 
 private:
-    weld::RadioButton* mpRbAuto;
-    weld::RadioButton* mpRbMan;
-    weld::Entry*       mpEdValue;
+    weld::RadioButton& mrRbAuto;
+    weld::RadioButton& mrRbMan;
+    weld::Widget&      mrEdValue;
 };
 
-
-class ScDPNumGroupEditHelper : public DPGroupEditHelper
+class ScDPNumGroupEditHelper : public ScDPGroupEditHelper
 {
 public:
-    explicit            ScDPNumGroupEditHelper(
-                            weld::RadioButton* pRbAuto, weld::RadioButton* pRbMan,
-                            DoubleField* pEdValue );
+    explicit ScDPNumGroupEditHelper(weld::RadioButton& rRbAuto,
+                                    weld::RadioButton& rRbMan,
+                                    DoubleField& rEdValue);
 
     virtual             ~ScDPNumGroupEditHelper() {}
 private:
@@ -94,15 +67,16 @@ private:
     virtual void        ImplSetValue( double fValue ) override;
 
 private:
-    DoubleField*        mpEdValue;
+    DoubleField&        mrEdValue;
 };
 
 class ScDPDateGroupEditHelper : public ScDPGroupEditHelper
 {
 public:
-    explicit            ScDPDateGroupEditHelper(
-                            RadioButton* pRbAuto, RadioButton* pRbMan,
-                            DateField* pEdValue, const Date& rNullDate );
+    explicit ScDPDateGroupEditHelper(weld::RadioButton& rRbAuto,
+                                     weld::RadioButton& rRbMan,
+                                     SvtCalendarBox& rEdValue,
+                                     const Date& rNullDate);
 
     virtual ~ScDPDateGroupEditHelper() {}
 
@@ -111,8 +85,8 @@ private:
     virtual void        ImplSetValue( double fValue ) override;
 
 private:
-    VclPtr<DateField>          mpEdValue;
-    Date const                maNullDate;
+    SvtCalendarBox&     mrEdValue;
+    Date const          maNullDate;
 };
 
 class ScDPNumGroupDlg : public weld::GenericDialogController
@@ -134,32 +108,33 @@ private:
     ScDPNumGroupEditHelper maEndHelper;
 };
 
-class ScDPDateGroupDlg : public ModalDialog
+class ScDPDateGroupDlg : public weld::GenericDialogController
 {
 public:
-    explicit            ScDPDateGroupDlg( vcl::Window* pParent, const ScDPNumGroupInfo& rInfo,
-                            sal_Int32 nDatePart, const Date& rNullDate );
-    virtual             ~ScDPDateGroupDlg() override;
-    virtual void        dispose() override;
-    ScDPNumGroupInfo    GetGroupInfo() const;
-    sal_Int32           GetDatePart() const;
+    explicit ScDPDateGroupDlg(weld::Window* pParent, const ScDPNumGroupInfo& rInfo,
+                              sal_Int32 nDatePart, const Date& rNullDate);
+    virtual ~ScDPDateGroupDlg() override;
+    ScDPNumGroupInfo GetGroupInfo() const;
+    sal_Int32 GetDatePart() const;
 
 private:
-    DECL_LINK( ClickHdl, Button*, void );
-    DECL_LINK( CheckHdl, SvTreeListBox*, void );
+    DECL_LINK(ClickHdl, weld::Button&, void);
+
+    typedef std::pair<int, int> row_col;
+    DECL_LINK(CheckHdl, const row_col&, void);
 
 private:
-    VclPtr<RadioButton>         mpRbAutoStart;
-    VclPtr<RadioButton>         mpRbManStart;
-    VclPtr<DateField>           mpEdStart;
-    VclPtr<RadioButton>         mpRbAutoEnd;
-    VclPtr<RadioButton>         mpRbManEnd;
-    VclPtr<DateField>           mpEdEnd;
-    VclPtr<RadioButton>         mpRbNumDays;
-    VclPtr<RadioButton>         mpRbUnits;
-    VclPtr<NumericField>        mpEdNumDays;
-    VclPtr<SvxCheckListBox>     mpLbUnits;
-    VclPtr<OKButton>            mpBtnOk;
+    std::unique_ptr<weld::RadioButton> mxRbAutoStart;
+    std::unique_ptr<weld::RadioButton> mxRbManStart;
+    std::unique_ptr<SvtCalendarBox> mxEdStart;
+    std::unique_ptr<weld::RadioButton> mxRbAutoEnd;
+    std::unique_ptr<weld::RadioButton> mxRbManEnd;
+    std::unique_ptr<SvtCalendarBox> mxEdEnd;
+    std::unique_ptr<weld::RadioButton> mxRbNumDays;
+    std::unique_ptr<weld::RadioButton> mxRbUnits;
+    std::unique_ptr<weld::SpinButton> mxEdNumDays;
+    std::unique_ptr<weld::TreeView> mxLbUnits;
+    std::unique_ptr<weld::Button> mxBtnOk;
     ScDPDateGroupEditHelper maStartHelper;
     ScDPDateGroupEditHelper maEndHelper;
 };
diff --git a/sc/source/ui/inc/editfield.hxx b/sc/source/ui/inc/editfield.hxx
index 4ab170ceacb0..a1edbf6baead 100644
--- a/sc/source/ui/inc/editfield.hxx
+++ b/sc/source/ui/inc/editfield.hxx
@@ -44,7 +44,7 @@ public:
     bool GetValue(double& rfValue) const;
     void SetValue(double fValue, sal_Int32 nDecPlaces = 12);
 
-    weld::Entry* get_widget() { return m_xEntry.get(); }
+    weld::Entry& get_widget() { return *m_xEntry; }
 
     void grab_focus() { m_xEntry->grab_focus(); }
     bool get_sensitive() const { return m_xEntry->get_sensitive(); }
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 88e7b85cb428..42f9c6521f46 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1116,7 +1116,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                         ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
                         const Date& rNullDate( GetViewData()->GetDocument()->GetFormatTable()->GetNullDate() );
                         ScopedVclPtr<AbstractScDPDateGroupDlg> pDlg( pFact->CreateScDPDateGroupDlg(
-                            pTabViewShell->GetDialogParent(),
+                            pTabViewShell->GetFrameWeld(),
                             aNumInfo, nParts, rNullDate ) );
                         if( pDlg->Execute() == RET_OK )
                         {
diff --git a/sc/uiconfig/scalc/ui/groupbydate.ui b/sc/uiconfig/scalc/ui/groupbydate.ui
index 747cf2918e13..59c7e9449c23 100644
--- a/sc/uiconfig/scalc/ui/groupbydate.ui
+++ b/sc/uiconfig/scalc/ui/groupbydate.ui
@@ -1,13 +1,33 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.18.3 -->
+<!-- Generated with glade 3.22.1 -->
 <interface domain="sc">
   <requires lib="gtk+" version="3.18"/>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name check1 -->
+      <column type="gboolean"/>
+      <!-- column-name text -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+      <!-- column-name checkvis1 -->
+      <column type="gboolean"/>
+    </columns>
+  </object>
   <object class="GtkDialog" id="PivotTableGroupByDate">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes" context="groupbydate|PivotTableGroupByDate">Grouping</property>
     <property name="resizable">False</property>
     <property name="type_hint">dialog</property>
+    <child>
+      <placeholder/>
+    </child>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
@@ -22,6 +42,7 @@
                 <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="can_default">True</property>
                 <property name="has_default">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
@@ -37,6 +58,7 @@
                 <property name="label">gtk-cancel</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_stock">True</property>
               </object>
@@ -73,6 +95,8 @@
           <object class="GtkBox" id="box1">
             <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>
             <child>
               <object class="GtkFrame" id="frame1">
@@ -104,7 +128,6 @@
                             <property name="xalign">0</property>
                             <property name="active">True</property>
                             <property name="draw_indicator">True</property>
-                            <property name="group">manual_start</property>
                           </object>
                           <packing>
                             <property name="left_attach">0</property>
@@ -119,7 +142,6 @@
                             <property name="receives_default">False</property>
                             <property name="use_underline">True</property>
                             <property name="xalign">0</property>
-                            <property name="active">True</property>
                             <property name="draw_indicator">True</property>
                             <property name="group">auto_start</property>
                           </object>
@@ -129,9 +151,13 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkSpinButton" id="start_date:yy:mm:dd">
+                          <object class="GtkMenuButton" id="start_date">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <child>
+                              <placeholder/>
+                            </child>
                           </object>
                           <packing>
                             <property name="left_attach">1</property>
@@ -192,7 +218,6 @@
                             <property name="xalign">0</property>
                             <property name="active">True</property>
                             <property name="draw_indicator">True</property>
-                            <property name="group">manual_end</property>
                           </object>
                           <packing>
                             <property name="left_attach">0</property>
@@ -217,9 +242,13 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkSpinButton" id="end_date:yy:mm:dd">
+                          <object class="GtkMenuButton" id="end_date">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <child>
+                              <placeholder/>
+                            </child>
                           </object>
                           <packing>
                             <property name="left_attach">1</property>
@@ -254,12 +283,16 @@
               <object class="GtkFrame" id="frame3">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
                 <property name="label_xalign">0</property>
                 <property name="shadow_type">none</property>
                 <child>
                   <object class="GtkAlignment" id="alignment3">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
                     <property name="top_padding">6</property>
                     <property name="left_padding">12</property>
                     <child>
@@ -280,7 +313,9 @@
                             <property name="xalign">0</property>
                             <property name="active">True</property>
                             <property name="draw_indicator">True</property>
-                            <property name="group">intervals</property>
+                            <accessibility>
+                              <relation type="label-for" target="days_value"/>
+                            </accessibility>
                           </object>
                           <packing>
                             <property name="left_attach">0</property>
@@ -296,9 +331,11 @@
                             <property name="valign">start</property>
                             <property name="use_underline">True</property>
                             <property name="xalign">0</property>
-                            <property name="active">True</property>
                             <property name="draw_indicator">True</property>
                             <property name="group">days</property>
+                            <accessibility>
+                              <relation type="label-for" target="interval_list"/>
+                            </accessibility>
                           </object>
                           <packing>
                             <property name="left_attach">0</property>
@@ -309,6 +346,10 @@
                           <object class="GtkSpinButton" id="days_value">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
+                            <property name="adjustment">adjustment1</property>
+                            <accessibility>
+                              <relation type="labelled-by" target="days"/>
+                            </accessibility>
                           </object>
                           <packing>
                             <property name="left_attach">1</property>
@@ -316,13 +357,58 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="svxcorelo-SvxCheckListBox" id="interval_list">
+                          <object class="GtkScrolledWindow">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="hexpand">True</property>
                             <property name="vexpand">True</property>
-                            <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection1"/>
+                            <property name="hscrollbar_policy">never</property>
+                            <property name="vscrollbar_policy">never</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkTreeView" id="interval_list">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="hexpand">True</property>
+                                <property name="vexpand">True</property>
+                                <property name="model">liststore1</property>
+                                <property name="headers_visible">False</property>
+                                <property name="search_column">0</property>
+                                <property name="show_expanders">False</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="Macro Library List-selection2"/>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+                                    <property name="resizable">True</property>
+                                    <property name="spacing">6</property>
+                                    <property name="alignment">0.5</property>
+                                    <child>
+                                      <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+                                      <attributes>
+                                        <attribute name="visible">3</attribute>
+                                        <attribute name="active">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+                                    <property name="resizable">True</property>
+                                    <property name="spacing">6</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="cellrenderer4"/>
+                                      <attributes>
+                                        <attribute name="text">1</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <accessibility>
+                                  <relation type="labelled-by" target="intervals"/>
+                                </accessibility>
+                              </object>
                             </child>
                           </object>
                           <packing>
diff --git a/solenv/sanitizers/ui/modules/scalc.suppr b/solenv/sanitizers/ui/modules/scalc.suppr
index ffed06f1dca5..91878c065422 100644
--- a/solenv/sanitizers/ui/modules/scalc.suppr
+++ b/solenv/sanitizers/ui/modules/scalc.suppr
@@ -72,9 +72,8 @@ sc/uiconfig/scalc/ui/externaldata.ui://GtkLabel[@id='secondsft'] orphan-label
 sc/uiconfig/scalc/ui/functionpanel.ui://GtkComboBoxText[@id='category'] no-labelled-by
 sc/uiconfig/scalc/ui/functionpanel.ui://GtkTreeView[@id='funclist:border'] no-labelled-by
 sc/uiconfig/scalc/ui/functionpanel.ui://GtkLabel[@id='funcdesc:border'] orphan-label
-sc/uiconfig/scalc/ui/groupbydate.ui://GtkSpinButton[@id='start_date:yy:mm:dd'] no-labelled-by
-sc/uiconfig/scalc/ui/groupbydate.ui://GtkSpinButton[@id='end_date:yy:mm:dd'] no-labelled-by
-sc/uiconfig/scalc/ui/groupbydate.ui://GtkSpinButton[@id='days_value'] no-labelled-by
+sc/uiconfig/scalc/ui/groupbydate.ui://GtkMenuButton[@id='start_date'] button-no-label
+sc/uiconfig/scalc/ui/groupbydate.ui://GtkMenuButton[@id='end_date'] button-no-label
 sc/uiconfig/scalc/ui/groupbynumber.ui://GtkEntry[@id='edit_by'] no-labelled-by
 sc/uiconfig/scalc/ui/headerfootercontent.ui://GtkLabel[@id='labelFT_H_CUSTOM'] orphan-label
 sc/uiconfig/scalc/ui/headerfootercontent.ui://GtkLabel[@id='labelFT_F_CUSTOM'] orphan-label
diff --git a/svtools/UIConfig_svt.mk b/svtools/UIConfig_svt.mk
index 5887d1645165..8ebefde11310 100644
--- a/svtools/UIConfig_svt.mk
+++ b/svtools/UIConfig_svt.mk
@@ -11,6 +11,7 @@ $(eval $(call gb_UIConfig_UIConfig,svt))
 
 $(eval $(call gb_UIConfig_add_uifiles,svt,\
 	svtools/uiconfig/ui/addresstemplatedialog \
+	svtools/uiconfig/ui/datewindow \
 	svtools/uiconfig/ui/fileviewmenu \
 	svtools/uiconfig/ui/graphicexport \
 	svtools/uiconfig/ui/inputbox \
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index 0fba463c4ff6..d45547e22b8b 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -2056,4 +2056,37 @@ void SvtLineListBox::UpdatePreview()
     }
 }
 
+SvtCalendarBox::SvtCalendarBox(std::unique_ptr<weld::MenuButton> pControl)
+    : 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"))
+{
+    m_xControl->set_popover(m_xTopLevel.get());
+    m_xCalendar->connect_selected(LINK(this, SvtCalendarBox, SelectHdl));
+    m_xCalendar->connect_activated(LINK(this, SvtCalendarBox, ActivateHdl));
+}
+
+void SvtCalendarBox::set_date(const Date& rDate)
+{
+    m_xCalendar->set_date(rDate);
+    SelectHdl(*m_xCalendar);
+}
+
+IMPL_LINK(SvtCalendarBox, SelectHdl, weld::Calendar&, rCalendar, void)
+{
+    const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper();
+    m_xControl->set_label(rLocaleData.getDate(rCalendar.get_date()));
+}
+
+IMPL_LINK_NOARG(SvtCalendarBox, ActivateHdl, weld::Calendar&, void)
+{
+    if (m_xControl->get_active())
+        m_xControl->set_active(false);
+}
+
+SvtCalendarBox::~SvtCalendarBox()
+{
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svtools/uiconfig/ui/datewindow.ui b/svtools/uiconfig/ui/datewindow.ui
new file mode 100644
index 000000000000..84d7ebf4931c
--- /dev/null
+++ b/svtools/uiconfig/ui/datewindow.ui
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="svx">
+  <requires lib="gtk+" version="3.18"/>
+  <object class="GtkPopover" id="date_popup_window">
+    <property name="can_focus">False</property>
+    <property name="no_show_all">True</property>
+    <property name="border_width">4</property>
+    <child>
+      <object class="GtkBox" id="box1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkCalendar" id="date">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="year">2019</property>
+            <property name="month">1</property>
+            <property name="day">14</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index d783794ca8d2..c24d6f5ab745 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -36,6 +36,7 @@
 #include <utility>
 #include <tools/helpers.hxx>
 #include <vcl/builder.hxx>
+#include <vcl/calendar.hxx>
 #include <vcl/combobox.hxx>
 #include <vcl/lstbox.hxx>
 #include <vcl/dialog.hxx>
@@ -1788,6 +1789,54 @@ public:
     }
 };
 
+class SalInstanceCalendar : public SalInstanceWidget, public virtual weld::Calendar
+{
+private:
+    VclPtr<::Calendar> m_xCalendar;
+
+    DECL_LINK(SelectHdl, ::Calendar*, void);
+    DECL_LINK(ActivateHdl, ::Calendar*, void);
+
+public:
+    SalInstanceCalendar(::Calendar* pCalendar, bool bTakeOwnership)
+        : SalInstanceWidget(pCalendar, bTakeOwnership)
+        , m_xCalendar(pCalendar)
+    {
+        m_xCalendar->SetSelectHdl(LINK(this, SalInstanceCalendar, SelectHdl));
+        m_xCalendar->SetActivateHdl(LINK(this, SalInstanceCalendar, ActivateHdl));
+    }
+
+    virtual void set_date(const Date& rDate) override
+    {
+        m_xCalendar->SetCurDate(rDate);
+    }
+
+    virtual Date get_date() const override
+    {
+        return m_xCalendar->GetFirstSelectedDate();
+    }
+
+    virtual ~SalInstanceCalendar() override
+    {
+        m_xCalendar->SetSelectHdl(Link<::Calendar*, void>());
+        m_xCalendar->SetActivateHdl(Link<::Calendar*, void>());
+    }
+};
+
+IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
+{
+    if (notify_events_disabled())
+        return;
+    signal_selected();
+}
+
+IMPL_LINK_NOARG(SalInstanceCalendar, ActivateHdl, ::Calendar*, void)
+{
+    if (notify_events_disabled())
+        return;
+    signal_activated();
+}
+
 namespace
 {
     class WeldTextFilter : public TextFilter
@@ -3854,6 +3903,12 @@ public:
         return pImage ? std::make_unique<SalInstanceImage>(pImage, bTakeOwnership) : nullptr;
     }
 
+    virtual std::unique_ptr<weld::Calendar> weld_calendar(const OString &id, bool bTakeOwnership) override
+    {
+        Calendar* pCalendar = m_xBuilder->get<Calendar>(id);
+        return pCalendar ? std::make_unique<SalInstanceCalendar>(pCalendar, bTakeOwnership) : nullptr;
+    }
+
     virtual std::unique_ptr<weld::Entry> weld_entry(const OString &id, bool bTakeOwnership) override
     {
         Edit* pEntry = m_xBuilder->get<Edit>(id);
diff --git a/vcl/source/control/calendar.cxx b/vcl/source/control/calendar.cxx
index d9656d3e60ff..9bd1c17b31e1 100644
--- a/vcl/source/control/calendar.cxx
+++ b/vcl/source/control/calendar.cxx
@@ -1057,6 +1057,8 @@ void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
 
                         ImplMouseSelect( aTempDate, nHitTest, false );
                     }
+                    if (rMEvt.GetClicks() == 2)
+                        maActivateHdl.Call(this);
                 }
             }
         }
@@ -1135,6 +1137,9 @@ void Calendar::KeyInput( const KeyEvent& rKEvt )
             aNewDate.AddDays( aNewDate.GetDaysInMonth() );
             break;
 
+        case KEY_RETURN:
+            break;
+
         default:
             Control::KeyInput( rKEvt );
             break;
@@ -1147,6 +1152,14 @@ void Calendar::KeyInput( const KeyEvent& rKEvt )
         Select();
         mbTravelSelect = false;
     }
+
+    if (rKEvt.GetKeyCode().GetCode() == KEY_RETURN)
+    {
+        if (maActivateHdl.IsSet())
+            maActivateHdl.Call(this);
+        else
+            Control::KeyInput(rKEvt);
+    }
 }
 
 void Calendar::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
@@ -1547,4 +1560,9 @@ Size Calendar::CalcWindowSizePixel() const
     return aSize;
 }
 
+Size Calendar::GetOptimalSize() const
+{
+    return CalcWindowSizePixel();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index d26c9e42d24e..3afb2e260b28 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -4611,6 +4611,87 @@ public:
     }
 };
 
+class GtkInstanceCalendar : public GtkInstanceWidget, public virtual weld::Calendar
+{
+private:
+    GtkCalendar* m_pCalendar;
+    gulong m_nDaySelectedSignalId;
+    gulong m_nDaySelectedDoubleClickSignalId;
+    gulong m_nKeyPressEventSignalId;
+
+    static void signalDaySelected(GtkCalendar*, gpointer widget)
+    {
+        GtkInstanceCalendar* pThis = static_cast<GtkInstanceCalendar*>(widget);
+        pThis->signal_selected();
+    }
+
+    static void signalDaySelectedDoubleClick(GtkCalendar*, gpointer widget)
+    {
+        GtkInstanceCalendar* pThis = static_cast<GtkInstanceCalendar*>(widget);
+        pThis->signal_activated();
+    }
+
+    gboolean signal_key_press(GdkEventKey* pEvent)
+    {
+        if (pEvent->keyval == GDK_KEY_Return)
+        {
+            signal_activated();
+            return true;
+        }
+        return false;
+    }
+
+    static gboolean signalKeyPress(GtkWidget*, GdkEventKey* pEvent, gpointer widget)
+    {
+        GtkInstanceCalendar* pThis = static_cast<GtkInstanceCalendar*>(widget);
+        return pThis->signal_key_press(pEvent);
+    }
+
+public:
+    GtkInstanceCalendar(GtkCalendar* pCalendar, bool bTakeOwnership)
+        : GtkInstanceWidget(GTK_WIDGET(pCalendar), bTakeOwnership)
+        , m_pCalendar(pCalendar)
+        , m_nDaySelectedSignalId(g_signal_connect(pCalendar, "day-selected", G_CALLBACK(signalDaySelected), this))
+        , m_nDaySelectedDoubleClickSignalId(g_signal_connect(pCalendar, "day-selected-double-click", G_CALLBACK(signalDaySelectedDoubleClick), this))
+        , m_nKeyPressEventSignalId(g_signal_connect(pCalendar, "key-press-event", G_CALLBACK(signalKeyPress), this))
+    {
+    }
+
+    virtual void set_date(const Date& rDate) override
+    {
+        gtk_calendar_select_month(m_pCalendar, rDate.GetMonth(), rDate.GetYear());
+        gtk_calendar_select_day(m_pCalendar, rDate.GetDay());
+    }
+
+    virtual Date get_date() const override
+    {
+        guint year, month, day;
+        gtk_calendar_get_date(m_pCalendar, &year, &month, &day);
+        return Date(day, month, year);
+    }
+
+    virtual void disable_notify_events() override
+    {
+        g_signal_handler_block(m_pCalendar, m_nDaySelectedDoubleClickSignalId);
+        g_signal_handler_block(m_pCalendar, m_nDaySelectedSignalId);
+        GtkInstanceWidget::disable_notify_events();
+    }
+
+    virtual void enable_notify_events() override
+    {
+        GtkInstanceWidget::enable_notify_events();
+        g_signal_handler_unblock(m_pCalendar, m_nDaySelectedSignalId);
+        g_signal_handler_unblock(m_pCalendar, m_nDaySelectedDoubleClickSignalId);
+    }
+
+    virtual ~GtkInstanceCalendar() override
+    {
+        g_signal_handler_disconnect(m_pCalendar, m_nKeyPressEventSignalId);
+        g_signal_handler_disconnect(m_pCalendar, m_nDaySelectedDoubleClickSignalId);
+        g_signal_handler_disconnect(m_pCalendar, m_nDaySelectedSignalId);
+    }
+};
+
 class GtkInstanceEntry : public GtkInstanceWidget, public virtual weld::Entry
 {
 private:
@@ -8325,6 +8406,15 @@ public:
         return std::make_unique<GtkInstanceImage>(pImage, bTakeOwnership);
     }
 
+    virtual std::unique_ptr<weld::Calendar> weld_calendar(const OString &id, bool bTakeOwnership) override
+    {
+        GtkCalendar* pCalendar = GTK_CALENDAR(gtk_builder_get_object(m_pBuilder, id.getStr()));
+        if (!pCalendar)
+            return nullptr;
+        auto_add_parentless_widgets_to_container(GTK_WIDGET(pCalendar));
+        return std::make_unique<GtkInstanceCalendar>(pCalendar, bTakeOwnership);
+    }
+
     virtual std::unique_ptr<weld::Entry> weld_entry(const OString &id, bool bTakeOwnership) override
     {
         GtkEntry* pEntry = GTK_ENTRY(gtk_builder_get_object(m_pBuilder, id.getStr()));


More information about the Libreoffice-commits mailing list