cui/source/dialogs/welcomedlg.cxx | 31 +++++++++++++++++-- cui/source/dialogs/whatsnewtabpage.cxx | 16 ++++++++-- cui/source/factory/dlgfact.cxx | 4 +- cui/source/factory/dlgfact.hxx | 2 - cui/source/inc/welcomedlg.hxx | 8 ++++- cui/source/inc/whatsnewtabpage.hxx | 5 +++ cui/uiconfig/ui/welcomedialog.ui | 23 +++++++++++++- include/sfx2/sfxdlg.hxx | 2 - include/sfx2/strings.hrc | 4 +- officecfg/registry/schema/org/openoffice/Setup.xcs | 10 +++++- sfx2/source/view/viewfrm.cxx | 33 ++++++++++++++------- 11 files changed, 111 insertions(+), 27 deletions(-)
New commits: commit 9e1470c07d7dc4f43c6bf98226583ee14e83c480 Author: Heiko Tietze <tietze.he...@gmail.com> AuthorDate: Tue May 20 10:24:15 2025 +0200 Commit: Heiko Tietze <heiko.tie...@documentfoundation.org> CommitDate: Tue May 20 21:47:31 2025 +0200 Resolves tdf#166594 - Reuse the Welcome dialog for WhatsNew * some nicer strings, depending on whether run as first-start dialog or after an update * checkbox to not show the dialog again (but the infobar) Change-Id: I6b1fafbf70e06a80a4e92864acce5cd16b85bc8d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185552 Reviewed-by: Heiko Tietze <heiko.tie...@documentfoundation.org> Tested-by: Jenkins diff --git a/cui/source/dialogs/welcomedlg.cxx b/cui/source/dialogs/welcomedlg.cxx index 88eb32d29b5a..c3d402e16e49 100644 --- a/cui/source/dialogs/welcomedlg.cxx +++ b/cui/source/dialogs/welcomedlg.cxx @@ -15,6 +15,7 @@ #include <comphelper/dispatchcommand.hxx> #include <officecfg/Office/UI/ToolbarMode.hxx> +#include <officecfg/Setup.hxx> #include <unotools/confignode.hxx> #include <sfx2/bindings.hxx> @@ -28,13 +29,15 @@ constexpr OUString sNewsTab = u"WhatsNewTabPage"_ustr; constexpr OUString sUITab = u"UITabPage"_ustr; constexpr OUString sAppearanceTab = u"AppearanceTabPage"_ustr; -WelcomeDialog::WelcomeDialog(weld::Window* pParent) +WelcomeDialog::WelcomeDialog(weld::Window* pParent, const bool bIsFirstStart) : SfxTabDialogController(pParent, u"cui/ui/welcomedialog.ui"_ustr, u"WelcomeDialog"_ustr) + , m_bFirstStart(bIsFirstStart) , m_xActionBtn(m_xBuilder->weld_button(u"action"_ustr)) // release notes / apply , m_xNextBtn(m_xBuilder->weld_button(u"next"_ustr)) // next / close , m_xOKBtn(m_xBuilder->weld_button(u"ok"_ustr)) // hidden , m_xResetBtn(m_xBuilder->weld_button(u"reset"_ustr)) // hidden , m_xCancelBtn(m_xBuilder->weld_button(u"cancel"_ustr)) // hidden + , m_xShowAgain(m_xBuilder->weld_check_button(u"cbShowAgain"_ustr)) { m_xDialog->set_title(SfxResId(STR_WELCOME_LINE1)); @@ -50,14 +53,35 @@ WelcomeDialog::WelcomeDialog(weld::Window* pParent) m_xNextBtn->connect_clicked(LINK(this, WelcomeDialog, OnNextClick)); m_xActionBtn->connect_clicked(LINK(this, WelcomeDialog, OnActionClick)); + m_xShowAgain->set_visible(!m_bFirstStart); + m_xTabCtrl->set_current_page(sNewsTab); OnActivatePage(sNewsTab); } +WelcomeDialog::~WelcomeDialog() +{ + if (!m_xShowAgain->get_active()) + { + std::shared_ptr<comphelper::ConfigurationChanges> xChanges( + comphelper::ConfigurationChanges::create()); + officecfg::Setup::Product::WhatsNewDialog::set(false, xChanges); + xChanges->commit(); + } +} + +void WelcomeDialog::PageCreated(const OUString& rId, SfxTabPage& rPage) +{ + if (rId == sNewsTab) + { + rPage.getAdditionalProperties().emplace(u"IsFirstRun"_ustr, css::uno::Any(m_bFirstStart)); + } +} + IMPL_LINK(WelcomeDialog, OnActivatePage, const OUString&, rPage, void) { if (rPage == sNewsTab) - m_xActionBtn->set_label(SfxResId(STR_CREDITS_BUTTON)); + m_xActionBtn->set_label(SfxResId(m_bFirstStart ? STR_CREDITS_BUTTON : STR_WHATSNEW_BUTTON)); else m_xActionBtn->set_label(SfxResId(STR_WELCOME_APPLY)); @@ -88,7 +112,8 @@ IMPL_LINK_NOARG(WelcomeDialog, OnActionClick, weld::Button&, void) { SfxViewFrame* pViewFrame = SfxViewFrame::Current(); if (pViewFrame) - pViewFrame->GetBindings().GetDispatcher()->Execute(SID_CREDITS); + pViewFrame->GetBindings().GetDispatcher()->Execute(m_bFirstStart ? SID_CREDITS + : SID_WHATSNEW); } break; case 1: diff --git a/cui/source/dialogs/whatsnewtabpage.cxx b/cui/source/dialogs/whatsnewtabpage.cxx index 4fcbd128f7dc..6b8345cd3c9c 100644 --- a/cui/source/dialogs/whatsnewtabpage.cxx +++ b/cui/source/dialogs/whatsnewtabpage.cxx @@ -25,8 +25,6 @@ WhatsNewTabPage::WhatsNewTabPage(weld::Container* pPage, weld::DialogController* , m_aBrand() , m_pBrand(new weld::CustomWeld(*m_xBuilder, u"imBrand"_ustr, m_aBrand)) { - const Size aGraphicSize = m_aBrand.GetGraphicSize(); - m_pBrand->set_size_request(aGraphicSize.getWidth(), aGraphicSize.getHeight()); } std::unique_ptr<SfxTabPage> WhatsNewTabPage::Create(weld::Container* pPage, @@ -36,6 +34,18 @@ std::unique_ptr<SfxTabPage> WhatsNewTabPage::Create(weld::Container* pPage, return std::make_unique<WhatsNewTabPage>(pPage, pController, *rAttr); } +void WhatsNewTabPage::Reset(const SfxItemSet* rSet) { ActivatePage(*rSet); } + +void WhatsNewTabPage::ActivatePage(const SfxItemSet& /* rSet */) +{ + const Size aGraphicSize = m_aBrand.GetGraphicSize(); + m_pBrand->set_size_request(aGraphicSize.getWidth(), aGraphicSize.getHeight()); + + auto& aProperties = getAdditionalProperties(); + auto aIterator = aProperties.find(u"IsFirstRun"_ustr); + m_aBrand.SetIsFirstStart(aIterator->second.get<sal_Bool>()); +} + AnimatedBrand::AnimatedBrand() { OUString aURL(u"$BRAND_BASE_DIR/" LIBO_SHARE_SHELL_FOLDER "/animatedbrand.gif"_ustr); @@ -69,7 +79,7 @@ void AnimatedBrand::Paint(vcl::RenderContext& rRenderContext, const tools::Recta aTextRect = rRect; //text - OUString sText(SfxResId(STR_WHATSNEW_FIRST)); + OUString sText(SfxResId(m_bIsFirstStart ? STR_WELCOME_TEXT : STR_WHATSNEW_TEXT)); vcl::Font aFont = rRenderContext.GetFont(); aFont.SetFontSize(Size(0, 24)); diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx index 60c14b21c92d..0ae3c7aad561 100644 --- a/cui/source/factory/dlgfact.cxx +++ b/cui/source/factory/dlgfact.cxx @@ -1404,9 +1404,9 @@ public: }; } -VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateWelcomeDialog(weld::Window* pParent) +VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateWelcomeDialog(weld::Window* pParent, const bool bIsFirstStart) { - return VclPtr<CuiAbstractTabController_Impl<WelcomeDialog>>::Create(pParent); + return VclPtr<CuiAbstractTabController_Impl<WelcomeDialog>>::Create(pParent, bIsFirstStart); } VclPtr<SfxAbstractPasteDialog> AbstractDialogFactory_Impl::CreatePasteDialog(weld::Window* pParent) diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx index b758e5ab90ff..8c13c1005d56 100644 --- a/cui/source/factory/dlgfact.hxx +++ b/cui/source/factory/dlgfact.hxx @@ -181,7 +181,7 @@ public: virtual VclPtr<SfxAbstractTabDialog> CreateSvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet& rAttr, const SdrModel& rModel, bool bStyle) override; - virtual VclPtr<SfxAbstractTabDialog> CreateWelcomeDialog(weld::Window* pParent) override; + virtual VclPtr<SfxAbstractTabDialog> CreateWelcomeDialog(weld::Window* pParent, const bool bIsFirstStart) override; virtual VclPtr<SvxAbstractSplitTableDialog> CreateSvxSplitTableDialog(weld::Window* pParent, bool bIsTableVertical, tools::Long nMaxVertical) override; diff --git a/cui/source/inc/welcomedlg.hxx b/cui/source/inc/welcomedlg.hxx index 0af9fbab053a..fab291fdc14a 100644 --- a/cui/source/inc/welcomedlg.hxx +++ b/cui/source/inc/welcomedlg.hxx @@ -14,18 +14,24 @@ class WelcomeDialog : public SfxTabDialogController { private: + bool m_bFirstStart; + std::unique_ptr<weld::Button> m_xActionBtn; // release notes / apply std::unique_ptr<weld::Button> m_xNextBtn; // next / close std::unique_ptr<weld::Button> m_xOKBtn; // hidden std::unique_ptr<weld::Button> m_xResetBtn; // hidden std::unique_ptr<weld::Button> m_xCancelBtn; // hidden + std::unique_ptr<weld::CheckButton> m_xShowAgain; + + virtual void PageCreated(const OUString& rId, SfxTabPage& rPage) override; DECL_LINK(OnActivatePage, const OUString&, void); DECL_LINK(OnActionClick, weld::Button&, void); DECL_LINK(OnNextClick, weld::Button&, void); public: - WelcomeDialog(weld::Window* pParent); + WelcomeDialog(weld::Window* pParent, const bool bIsFirstStart); + virtual ~WelcomeDialog() override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/cui/source/inc/whatsnewtabpage.hxx b/cui/source/inc/whatsnewtabpage.hxx index 81d274a7c563..7eeeb0337182 100644 --- a/cui/source/inc/whatsnewtabpage.hxx +++ b/cui/source/inc/whatsnewtabpage.hxx @@ -16,6 +16,7 @@ class AnimatedBrand : public weld::CustomWidgetController { private: + bool m_bIsFirstStart; Graphic m_pGraphic; Size m_pGraphicSize; virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override; @@ -23,6 +24,7 @@ private: public: AnimatedBrand(); const Size& GetGraphicSize() const { return m_pGraphicSize; }; + void SetIsFirstStart(const bool bIsFirstStart) { m_bIsFirstStart = bIsFirstStart; }; }; class WhatsNewTabPage : public SfxTabPage @@ -31,6 +33,9 @@ private: AnimatedBrand m_aBrand; std::unique_ptr<weld::CustomWeld> m_pBrand; + virtual void ActivatePage(const SfxItemSet&) override; + virtual void Reset(const SfxItemSet* rSet) override; + public: WhatsNewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet); diff --git a/cui/uiconfig/ui/welcomedialog.ui b/cui/uiconfig/ui/welcomedialog.ui index 3866ee0c4db0..0a3cde4fc96a 100644 --- a/cui/uiconfig/ui/welcomedialog.ui +++ b/cui/uiconfig/ui/welcomedialog.ui @@ -19,6 +19,7 @@ <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> <property name="can-focus">False</property> + <property name="hexpand">True</property> <property name="layout-style">end</property> <child> <object class="GtkButton" id="action"> @@ -91,9 +92,27 @@ <property name="position">4</property> </packing> </child> + <child> + <object class="GtkCheckButton" id="cbShowAgain"> + <property name="label" translatable="yes" context="welcomedialog|showagain">Do Show Again</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="use-underline">True</property> + <property name="active">True</property> + <property name="draw-indicator">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">5</property> + <property name="secondary">True</property> + </packing> + </child> </object> <packing> - <property name="expand">False</property> + <property name="expand">True</property> <property name="fill">True</property> <property name="pack-type">end</property> <property name="position">0</property> @@ -117,7 +136,7 @@ <object class="GtkLabel" id="WhatsNewTabPage"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes" context="welcomedialog|whatsnewtab">What's New</property> + <property name="label" translatable="yes" context="welcomedialog|whatsnewtab">Welcome</property> </object> <packing> <property name="tab-fill">False</property> diff --git a/include/sfx2/sfxdlg.hxx b/include/sfx2/sfxdlg.hxx index 919ac744e212..1f6fcd081e7d 100644 --- a/include/sfx2/sfxdlg.hxx +++ b/include/sfx2/sfxdlg.hxx @@ -168,7 +168,7 @@ public: virtual VclPtr<VclAbstractDialog> CreateWidgetTestDialog(weld::Window* _pParent) = 0; - virtual VclPtr<SfxAbstractTabDialog> CreateWelcomeDialog(weld::Window* pParent) =0; + virtual VclPtr<SfxAbstractTabDialog> CreateWelcomeDialog(weld::Window* pParent, const bool bIsFirstStart) =0; }; #endif diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc index 595e43ca9ee6..207317f04c15 100644 --- a/include/sfx2/strings.hrc +++ b/include/sfx2/strings.hrc @@ -270,8 +270,8 @@ // Translators: text will be abbreviated at >8 characters, eg. "Please D..." #define STR_DONATE_BUTTON NC_("STR_DONATE_BUTTON", "Donate") #define STR_CREDITS_BUTTON NC_("STR_CREDITS_BUTTON", "~Credits") -#define STR_WHATSNEW_TEXT NC_("STR_WHATSNEW", "You are running version %PRODUCTVERSION of %PRODUCTNAME for the first time. Do you want to learn what's new?") -#define STR_WHATSNEW_FIRST NC_("STR_WHATSNEW_FIRST", "You are running %PRODUCTNAME for the first time. Please take a moment to personalize your settings.") +#define STR_WHATSNEW_TEXT NC_("STR_WHATSNEW_TEXT", "You are running version %PRODUCTVERSION of %PRODUCTNAME for the first time. Do you want to learn what's new?") +#define STR_WELCOME_TEXT NC_("STR_WELCOME_TEXT", "You are running %PRODUCTNAME for the first time. Please take a moment to personalize your settings.") #define STR_WHATSNEW_BUTTON NC_("STR_WHATSNEW_BUTTON", "~Release Notes") #define STR_WELCOME_APPLY NC_("STR_WELCOME_APPLY", "~Apply") #define STR_WELCOME_CLOSE NC_("STR_WELCOME_CLOSE", "~Close") diff --git a/officecfg/registry/schema/org/openoffice/Setup.xcs b/officecfg/registry/schema/org/openoffice/Setup.xcs index cabcf9ff7fc2..de6740bdbf2f 100644 --- a/officecfg/registry/schema/org/openoffice/Setup.xcs +++ b/officecfg/registry/schema/org/openoffice/Setup.xcs @@ -303,10 +303,16 @@ </prop> <prop oor:name="WhatsNew" oor:type="xs:boolean" oor:nillable="false"> <info> - <desc>Set to false to not show the WhatsNew dialog on major updates.</desc> + <desc>Set to false to not show the WhatsNew infobar on major updates.</desc> </info> <value>true</value> - </prop> + </prop> + <prop oor:name="WhatsNewDialog" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc>Set to false to not show the WhatsNew dialog but the infobar.</desc> + </info> + <value>true</value> + </prop> </group> <group oor:name="Office"> <!--The default must be written by the setup.--> diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 51bdd0adee7c..0c41e379c806 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -1645,30 +1645,43 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) #if !ENABLE_WASM_STRIP_PINGUSER if (!SfxApplication::IsHeadlessOrUITest()) //uitest.uicheck fails when the dialog is open { + bool bIsWhatsNewShown = false; //suppress tipoftheday if whatsnew was shown + static const bool bRunningUnitTest = o3tl::IsRunningUnitTest() || o3tl::IsRunningUITest(); - if (officecfg::Office::Common::Misc::FirstRun::get() && !IsInModalMode() && !bRunningUnitTest) + static const bool bIsFirstStart = officecfg::Office::Common::Misc::FirstRun::get(); + if (bIsFirstStart && !IsInModalMode() && !bRunningUnitTest) { SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); ScopedVclPtr<SfxAbstractTabDialog> pDlg( - pFact->CreateWelcomeDialog(GetWindow().GetFrameWeld())); + pFact->CreateWelcomeDialog(GetWindow().GetFrameWeld(), true)); pDlg->Execute(); + bIsWhatsNewShown = true; } - bool bIsWhatsNewShown = false; //suppress tipoftheday if whatsnew was shown - //what's new dialog - static bool wantsWhatsNew = utl::isProductVersionUpgraded() && !IsInModalMode(); + static bool wantsWhatsNew = utl::isProductVersionUpgraded() && !IsInModalMode() && !bIsFirstStart; if (wantsWhatsNew) { wantsWhatsNew = false; if (officecfg::Setup::Product::WhatsNew::get()) { - VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar(u"whatsnew"_ustr, u""_ustr, SfxResId(STR_WHATSNEW_TEXT), InfobarType::INFO); - if (pInfoBar) + if (officecfg::Setup::Product::WhatsNewDialog::get()) + { + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + ScopedVclPtr<SfxAbstractTabDialog> pDlg( + pFact->CreateWelcomeDialog(GetWindow().GetFrameWeld(), false)); + pDlg->Execute(); + } + else { - weld::Button& rWhatsNewButton = pInfoBar->addButton(); - rWhatsNewButton.set_label(SfxResId(STR_WHATSNEW_BUTTON)); - rWhatsNewButton.connect_clicked(LINK(this, SfxViewFrame, WhatsNewHandler)); + OUString sText(SfxResId(STR_WHATSNEW_TEXT)); + VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar(u"whatsnew"_ustr, u""_ustr, sText.replaceAll(" ",""), InfobarType::INFO); + if (pInfoBar) + { + weld::Button& rWhatsNewButton = pInfoBar->addButton(); + rWhatsNewButton.set_label(SfxResId(STR_WHATSNEW_BUTTON)); + rWhatsNewButton.connect_clicked(LINK(this, SfxViewFrame, WhatsNewHandler)); + } } bIsInfobarShown = true; bIsWhatsNewShown = true;