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 <[email protected]> AuthorDate: Thu Feb 14 21:26:27 2019 +0000 Commit: Caolán McNamara <[email protected]> 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 <[email protected]> Tested-by: Caolán McNamara <[email protected]> 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())); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
