From 7f032b2f16fad56beea1df826eb59c6f85c71268 Mon Sep 17 00:00:00 2001 From: Matt K Date: Sat, 3 Apr 2021 01:24:30 -0500 Subject: tdf#127533 Make Tip-of-the-Day dialog non-modal and allow multiple tips to open The Tip-of-the-Day dialog is made non-modal and stays on-top of the main window while allowing the user to interact with the rest of application. Change-Id: I51e1a3488ab74d8371b71a8585d1512ce051f637 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113782 Reviewed-by: Matt K Reviewed-by: Heiko Tietze Tested-by: Jenkins --- cui/source/dialogs/tipofthedaydlg.cxx | 31 +++++++++++++++++++++++++++++++ cui/source/factory/dlgfact.cxx | 14 ++++++++++++-- cui/source/factory/dlgfact.hxx | 13 +++++++++++++ cui/source/inc/tipofthedaydlg.hxx | 5 +++++ cui/uiconfig/ui/tipofthedaydialog.ui | 4 ++-- sfx2/source/appl/appserv.cxx | 2 +- 6 files changed, 64 insertions(+), 5 deletions(-) diff --git a/cui/source/dialogs/tipofthedaydlg.cxx b/cui/source/dialogs/tipofthedaydlg.cxx index 9d43fd21f4ba..8356f6f0e36f 100644 --- a/cui/source/dialogs/tipofthedaydlg.cxx +++ b/cui/source/dialogs/tipofthedaydlg.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +49,7 @@ const Size ThumbSize(150, 150); TipOfTheDayDialog::TipOfTheDayDialog(weld::Window* pParent) : GenericDialogController(pParent, "cui/ui/tipofthedaydialog.ui", "TipOfTheDayDialog") + , m_pParent(pParent) , m_pText(m_xBuilder->weld_label("lbText")) , m_pShowTip(m_xBuilder->weld_check_button("cbShowTip")) , m_pNext(m_xBuilder->weld_button("btnNext")) @@ -58,6 +61,17 @@ TipOfTheDayDialog::TipOfTheDayDialog(weld::Window* pParent) m_nCurrentTip = officecfg::Office::Common::Misc::LastTipOfTheDayID::get(); m_pPreview->set_size_request(ThumbSize.Width(), ThumbSize.Height()); + if (pParent != nullptr) + { + css::uno::Reference xWindow = pParent->GetXWindow(); + if (xWindow.is()) + { + VclPtr xVclWin(VCLUnoHelper::GetWindow(xWindow)); + if (xVclWin != nullptr) + xVclWin->AddEventListener(LINK(this, TipOfTheDayDialog, Terminated)); + } + } + const auto t0 = std::chrono::system_clock::now().time_since_epoch(); m_nDay = std::chrono::duration_cast(t0).count() / 24; if (m_nDay > officecfg::Office::Common::Misc::LastTipOfTheDayShown::get()) @@ -66,6 +80,12 @@ TipOfTheDayDialog::TipOfTheDayDialog(weld::Window* pParent) UpdateTip(); } +IMPL_LINK(TipOfTheDayDialog, Terminated, VclWindowEvent&, rEvent, void) +{ + if (rEvent.GetId() == VclEventId::ObjectDying) + TipOfTheDayDialog::response(RET_OK); +} + TipOfTheDayDialog::~TipOfTheDayDialog() { std::shared_ptr xChanges( @@ -74,6 +94,17 @@ TipOfTheDayDialog::~TipOfTheDayDialog() officecfg::Office::Common::Misc::LastTipOfTheDayID::set(m_nCurrentTip, xChanges); officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_pShowTip->get_active(), xChanges); xChanges->commit(); + + if (m_pParent != nullptr) + { + css::uno::Reference xWindow = m_pParent->GetXWindow(); + if (xWindow.is()) + { + VclPtr xVclWin(VCLUnoHelper::GetWindow(xWindow)); + if (xVclWin != nullptr) + xVclWin->RemoveEventListener(LINK(this, TipOfTheDayDialog, Terminated)); + } + } } static bool file_exists(const OUString& fileName) diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx index 6d0a44086d47..6d0e9e31f77f 100644 --- a/cui/source/factory/dlgfact.cxx +++ b/cui/source/factory/dlgfact.cxx @@ -106,6 +106,16 @@ short CuiAbstractController_Impl::Execute() return m_xDlg->run(); } +short CuiAbstractTipController_Impl::Execute() +{ + return m_xDlg->run(); +} + +bool CuiAbstractTipController_Impl::StartExecuteAsync(AsyncContext& rCtx) +{ + return weld::DialogController::runAsync(m_xDlg, rCtx.maEndDialogFn); +} + short CuiAbstractSingleTabController_Impl::Execute() { return m_xDlg->run(); @@ -1682,8 +1692,8 @@ AbstractDialogFactory_Impl::CreateAboutDialog(weld::Window* pParent) VclPtr AbstractDialogFactory_Impl::CreateTipOfTheDayDialog(weld::Window* pParent) { - return VclPtr::Create( - std::make_unique(pParent)); + return VclPtr::Create( + std::make_shared(pParent)); } VclPtr diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx index 1abf42683c95..1678d3c6349b 100644 --- a/cui/source/factory/dlgfact.hxx +++ b/cui/source/factory/dlgfact.hxx @@ -121,6 +121,19 @@ public: virtual short Execute() override; }; +class CuiAbstractTipController_Impl : public VclAbstractDialog +{ + std::shared_ptr m_xDlg; + +public: + explicit CuiAbstractTipController_Impl(std::shared_ptr p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + virtual bool StartExecuteAsync(AsyncContext& rCtx) override; +}; + class CuiAbstractSingleTabController_Impl : public SfxAbstractDialog { std::unique_ptr m_xDlg; diff --git a/cui/source/inc/tipofthedaydlg.hxx b/cui/source/inc/tipofthedaydlg.hxx index 44ea0134fe01..f5f0ef999420 100644 --- a/cui/source/inc/tipofthedaydlg.hxx +++ b/cui/source/inc/tipofthedaydlg.hxx @@ -21,10 +21,13 @@ #include #include "cuigrfflt.hxx" +class VclWindowEvent; + class TipOfTheDayDialog : public weld::GenericDialogController { private: CuiGraphicPreviewWindow m_aPreview; + weld::Window* m_pParent; std::unique_ptr m_pText; std::unique_ptr m_pShowTip; @@ -41,6 +44,8 @@ private: public: TipOfTheDayDialog(weld::Window* pWindow); virtual ~TipOfTheDayDialog() override; + + DECL_LINK(Terminated, VclWindowEvent&, void); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/uiconfig/ui/tipofthedaydialog.ui b/cui/uiconfig/ui/tipofthedaydialog.ui index e05738d8466a..ebf0515c6b1e 100644 --- a/cui/uiconfig/ui/tipofthedaydialog.ui +++ b/cui/uiconfig/ui/tipofthedaydialog.ui @@ -7,7 +7,7 @@ 6 Tip of the day False - True + False center-on-parent dialog @@ -26,7 +26,7 @@ True True False - Enable the dialog again at Tools > Options > General + Enable the dialog again at Tools > Options > General, or Help > Show Tip of the Day True True True diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx index 91edc7d0ef15..6138bd936082 100644 --- a/sfx2/source/appl/appserv.cxx +++ b/sfx2/source/appl/appserv.cxx @@ -610,7 +610,7 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq ) { SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); ScopedVclPtr pDlg(pFact->CreateTipOfTheDayDialog(rReq.GetFrameWeld())); - pDlg->Execute(); + pDlg->StartExecuteAsync(nullptr); bDone = true; break; } -- cgit