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;

Reply via email to