summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Tietze <tietze.heiko@gmail.com>2024-02-22 12:56:01 +0100
committerHeiko Tietze <heiko.tietze@documentfoundation.org>2024-03-27 09:41:44 +0100
commitdd889b290304b73f96a9a8e6e0f144d3aa2ba7e1 (patch)
treeb7267890302290529e9305c8730e8e217f907b31
parentCppunitTest_sw_htmlexport: use more CPPUNIT_TEST_FIXTURE() (diff)
downloadcore-dd889b290304b73f96a9a8e6e0f144d3aa2ba7e1.tar.gz
core-dd889b290304b73f96a9a8e6e0f144d3aa2ba7e1.zip
Resolves tdf#159573 and tdf#137931 - WhatsNew or Welcome dialog
To test the new dialog, change org.openoffice.Setup > Product > ooSetupLastVersion to some lesser value for the WhatsNew dialog or clear the entry for the Welcome version. Change-Id: Iec6de50edba0e5430e82f1db85e61d1e4501771d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163739 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
-rw-r--r--Repository.mk1
-rw-r--r--cui/Library_cui.mk1
-rw-r--r--cui/UIConfig_cui.mk1
-rw-r--r--cui/inc/whatsnew.hrc42
-rw-r--r--cui/source/dialogs/whatsnew.cxx172
-rw-r--r--cui/source/factory/dlgfact.cxx13
-rw-r--r--cui/source/factory/dlgfact.hxx2
-rw-r--r--cui/source/inc/whatsnew.hxx75
-rw-r--r--cui/uiconfig/ui/whatsnewdialog.ui131
-rw-r--r--desktop/source/app/app.cxx2
-rw-r--r--extras/source/whatsnew/Community.pngbin0 -> 280336 bytes
-rw-r--r--extras/source/whatsnew/Configurability.pngbin0 -> 186675 bytes
-rw-r--r--extras/source/whatsnew/LibreOffice.gifbin0 -> 112299 bytes
-rw-r--r--extras/source/whatsnew/ODF.pngbin0 -> 77938 bytes
-rw-r--r--extras/source/whatsnew/whatsnew1.pngbin0 -> 31419 bytes
-rw-r--r--include/sfx2/sfxdlg.hxx2
-rw-r--r--include/sfx2/sfxsids.hrc5
-rw-r--r--include/sfx2/strings.hrc2
-rw-r--r--include/sfx2/viewfrm.hxx1
-rw-r--r--include/unotools/VersionConfig.hxx24
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/UI/Infobar.xcs6
-rw-r--r--officecfg/registry/schema/org/openoffice/Setup.xcs8
-rw-r--r--sfx2/sdi/appslots.sdi4
-rw-r--r--sfx2/sdi/sfx.sdi16
-rw-r--r--sfx2/source/appl/appserv.cxx10
-rw-r--r--sfx2/source/dialog/infobar.cxx2
-rw-r--r--sfx2/source/view/viewfrm.cxx43
-rw-r--r--vcl/Module_vcl.mk1
-rw-r--r--vcl/Package_whatsnew.mk20
29 files changed, 533 insertions, 51 deletions
diff --git a/Repository.mk b/Repository.mk
index 5b60bd66cfcc..9317a29975df 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -925,6 +925,7 @@ $(eval $(call gb_Helper_register_packages_for_install,sdk,\
ifneq ($(ENABLE_WASM_STRIP_PINGUSER),TRUE)
$(eval $(call gb_Helper_register_packages_for_install,ooo,\
tipoftheday_images \
+ whatsnew_images \
))
endif
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index e01e33ecb4ec..3ee744e32d0f 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -114,6 +114,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
cui/source/customize/SvxNotebookbarConfigPage \
cui/source/customize/CustomNotebookbarGenerator \
cui/source/dialogs/about \
+ cui/source/dialogs/whatsnew \
$(call gb_Helper_optional,EXTENSIONS, \
cui/source/dialogs/AdditionsDialog) \
cui/source/dialogs/colorpicker \
diff --git a/cui/UIConfig_cui.mk b/cui/UIConfig_cui.mk
index 10acd83c8c39..79ff7696a93a 100644
--- a/cui/UIConfig_cui.mk
+++ b/cui/UIConfig_cui.mk
@@ -18,6 +18,7 @@ endif
ifneq ($(ENABLE_WASM_STRIP_PINGUSER),TRUE)
$(eval $(call gb_UIConfig_add_uifiles,cui,\
cui/uiconfig/ui/tipofthedaydialog \
+ cui/uiconfig/ui/whatsnewdialog \
))
endif
diff --git a/cui/inc/whatsnew.hrc b/cui/inc/whatsnew.hrc
new file mode 100644
index 000000000000..e155a597bcf2
--- /dev/null
+++ b/cui/inc/whatsnew.hrc
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#define NC_(Context, String) TranslateId(Context, u8##String)
+
+#include <rtl/ustring.hxx>
+#include <config_python.h>
+#include <tuple>
+#include <unotools/resmgr.hxx>
+
+/*
+ * std:tuple consists of <text, image>
+ * image:
+ * place new images at extra/source/whatsnew
+ * do not forget to add the files to vcl/Package_whatsnew.mk
+ * images are cut-off at 600x400px
+*/
+
+const std::tuple<TranslateId, OUString> WELCOME_STRINGARRAY[] =
+{
+ { NC_("RID_CUI_WHATSNEW", "%PRODUCTNAME is a powerful and free office suite, used by millions of people around the world."), "LibreOffice.gif"},
+ { NC_("RID_CUI_WHATSNEW", "%PRODUCTNAME uses the reliable and trustworthy standard open document format."), "ODF.png"},
+ { NC_("RID_CUI_WHATSNEW", "%PRODUCTNAME blends into every operation system and provides full customization."), "Configurability.png"},
+ { NC_("RID_CUI_WHATSNEW", "%PRODUCTNAME is open source: Your project, your data, your freedom."), "Community.png"},
+};
+
+const std::tuple<TranslateId, OUString> WHATSNEW_STRINGARRAY[] =
+{
+ { NC_("RID_CUI_WHATSNEW", "Version 24.8 brings a shiny WhatsNew dialog :-)"), "whatsnew1.png"},
+};
+
+#define STR_WELCOME NC_("STR_WELCOME", "Welcome to %PRODUCTNAME!")
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file
diff --git a/cui/source/dialogs/whatsnew.cxx b/cui/source/dialogs/whatsnew.cxx
new file mode 100644
index 000000000000..31ad380d8cf9
--- /dev/null
+++ b/cui/source/dialogs/whatsnew.cxx
@@ -0,0 +1,172 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <whatsnew.hxx>
+#include <whatsnew.hrc>
+
+#include <dialmgr.hxx>
+#include <comphelper/DirectoryHelper.hxx>
+#include <rtl/bootstrap.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/gdimtf.hxx>
+
+constexpr tools::Long TEXT_HEIGHT(120);
+constexpr tools::Long PROGRESS_DOTSIZE(24);
+constexpr tools::Long PROGRESS_DOTSPACING(4);
+
+WhatsNewDialog::WhatsNewDialog(weld::Window* pParent, const bool bWelcome)
+ : GenericDialogController(pParent, "cui/ui/whatsnewdialog.ui", "WhatsNewDialog")
+ , m_bWelcome(bWelcome)
+ , m_aPreview()
+ , m_aProgress()
+ , m_pPrevBtn(m_xBuilder->weld_button("btnPrev"))
+ , m_pNextBtn(m_xBuilder->weld_button("btnNext"))
+ , m_pProgress(new weld::CustomWeld(*m_xBuilder, "imProgress", m_aProgress))
+ , m_pImage(new weld::CustomWeld(*m_xBuilder, "imNews", m_aPreview))
+{
+ if (m_bWelcome)
+ m_xDialog->set_title(CuiResId(STR_WELCOME));
+ m_pPrevBtn->set_sensitive(false);
+
+ m_pPrevBtn->connect_clicked(LINK(this, WhatsNewDialog, OnPrevClick));
+ m_pNextBtn->connect_clicked(LINK(this, WhatsNewDialog, OnNextClick));
+
+ m_nNumberOfNews = m_bWelcome ? std::size(WELCOME_STRINGARRAY) : std::size(WHATSNEW_STRINGARRAY);
+ m_nCurrentNews = 0;
+ m_pNextBtn->set_sensitive(m_nNumberOfNews > 1);
+ m_pProgress->set_size_request(m_nNumberOfNews * (PROGRESS_DOTSIZE + PROGRESS_DOTSPACING),
+ PROGRESS_DOTSIZE + 1);
+
+ LoadImage();
+}
+
+WhatsNewDialog::~WhatsNewDialog() {}
+
+void WhatsNewDialog::LoadImage()
+{
+ if (m_nCurrentNews < m_nNumberOfNews)
+ {
+ auto[sText, sImage] = m_bWelcome ? WELCOME_STRINGARRAY[m_nCurrentNews]
+ : WHATSNEW_STRINGARRAY[m_nCurrentNews];
+ OUString aURL("$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/whatsnew/");
+ rtl::Bootstrap::expandMacros(aURL);
+
+ const bool bFileExists = comphelper::DirectoryHelper::fileExists(aURL + sImage);
+ if (!sImage.isEmpty() && bFileExists)
+ m_aPreview.Update(aURL + sImage, CuiResId(sText));
+
+ m_aProgress.Update(m_nCurrentNews, m_nNumberOfNews);
+ }
+}
+
+IMPL_LINK_NOARG(WhatsNewDialog, OnPrevClick, weld::Button&, void)
+{
+ m_nCurrentNews--;
+ if (m_nCurrentNews == 0)
+ m_pPrevBtn->set_sensitive(false);
+ m_pNextBtn->set_sensitive(true);
+ LoadImage();
+}
+
+IMPL_LINK_NOARG(WhatsNewDialog, OnNextClick, weld::Button&, void)
+{
+ m_nCurrentNews++;
+ if (m_nCurrentNews == m_nNumberOfNews - 1)
+ m_pNextBtn->set_sensitive(false);
+ m_pPrevBtn->set_sensitive(true);
+ LoadImage();
+}
+
+void WhatsNewImg::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ const StyleSettings rSettings(Application::GetSettings().GetStyleSettings());
+
+ //clear
+ rRenderContext.SetBackground(Wallpaper(rSettings.GetDialogColor()));
+ rRenderContext.Erase();
+
+ //background image
+ Graphic aGraphic;
+ GraphicFilter::LoadGraphic(m_sImage, OUString(), aGraphic);
+ const Size aGraphicSize(aGraphic.GetSizePixel());
+
+ if (aGraphic.IsAnimated())
+ aGraphic.StartAnimation(rRenderContext, Point(), aGraphicSize);
+ else
+ aGraphic.Draw(rRenderContext, Point(), aGraphicSize);
+
+ tools::Rectangle aRect(Point(0, aGraphicSize.Height() - TEXT_HEIGHT),
+ Size(aGraphicSize.Width(), TEXT_HEIGHT));
+
+ //transparent text background
+ ScopedVclPtrInstance<VirtualDevice> aVDev;
+ GDIMetaFile aMetafile;
+
+ aMetafile.Record(aVDev.get());
+ aMetafile.SetPrefSize(aRect.GetSize());
+ aVDev->SetOutputSize(aRect.GetSize());
+ aVDev->SetBackground(Color(0x10, 0x68, 0x02));
+ aVDev->Erase();
+ aMetafile.Stop();
+
+ Gradient aVCLGradient;
+ aVCLGradient.SetStyle(css::awt::GradientStyle_LINEAR);
+ aVCLGradient.SetStartColor(COL_GRAY);
+ aVCLGradient.SetEndColor(COL_GRAY);
+ aVCLGradient.SetStartIntensity(33);
+ aVCLGradient.SetEndIntensity(66);
+
+ rRenderContext.DrawTransparent(aMetafile, aRect.TopLeft(), aRect.GetSize(), aVCLGradient);
+
+ //text
+ vcl::Font aFont = rRenderContext.GetFont();
+ const Size aFontSize = aFont.GetFontSize();
+ aFont.SetFontSize(Size(0, 24));
+ aFont.SetColor(COL_WHITE);
+ aFont.SetWeight(WEIGHT_BOLD);
+ rRenderContext.SetFont(aFont);
+
+ DrawTextFlags nDrawTextStyle(DrawTextFlags::MultiLine | DrawTextFlags::WordBreak
+ | DrawTextFlags::EndEllipsis);
+ const bool bIsRTL = rRenderContext.GetTextIsRTL(m_sText, 0, m_sText.getLength());
+ if (bIsRTL)
+ nDrawTextStyle |= DrawTextFlags::Right;
+
+ aRect.shrink(6);
+ aRect.setWidth(rRenderContext.GetOutputSizePixel().Width() - 12);
+ rRenderContext.DrawText(aRect, m_sText, nDrawTextStyle);
+
+ aFont.SetFontSize(aFontSize);
+ aFont.SetWeight(WEIGHT_NORMAL);
+ rRenderContext.SetFont(aFont);
+}
+
+void WhatsNewProgress::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ const StyleSettings rSettings(Application::GetSettings().GetStyleSettings());
+ rRenderContext.SetBackground(rSettings.GetDialogColor());
+ rRenderContext.Erase();
+ rRenderContext.SetAntialiasing(AntialiasingFlags::Enable);
+
+ tools::Rectangle aRect(Point(0, 0), Size(PROGRESS_DOTSIZE, PROGRESS_DOTSIZE));
+ for (sal_Int32 i = 0; i < m_nTotal; i++)
+ {
+ if (i == m_nCurrent)
+ rRenderContext.SetFillColor(rSettings.GetAccentColor());
+ else
+ rRenderContext.SetFillColor(COL_WHITE);
+ rRenderContext.DrawEllipse(aRect);
+
+ aRect.AdjustLeft(PROGRESS_DOTSIZE + PROGRESS_DOTSPACING);
+ aRect.AdjustRight(PROGRESS_DOTSIZE + PROGRESS_DOTSPACING);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ \ No newline at end of file
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
index b25ce9c9359b..2a71808ae59d 100644
--- a/cui/source/factory/dlgfact.cxx
+++ b/cui/source/factory/dlgfact.cxx
@@ -24,6 +24,7 @@
#include "dlgfact.hxx"
#include <about.hxx>
+#include <whatsnew.hxx>
#include <sfx2/app.hxx>
#include <sfx2/basedlgs.hxx>
#include <sfx2/pageids.hxx>
@@ -1532,6 +1533,18 @@ AbstractDialogFactory_Impl::CreateAboutDialog(weld::Window* pParent)
}
VclPtr<VclAbstractDialog>
+AbstractDialogFactory_Impl::CreateWhatsNewDialog(weld::Window* pParent, const bool bWelcome)
+{
+#if !ENABLE_WASM_STRIP_PINGUSER
+ return VclPtr<CuiAbstractControllerAsync_Impl>::Create(
+ std::make_shared<WhatsNewDialog>(pParent, bWelcome));
+#else
+ (void) pParent;
+ return nullptr;
+#endif
+}
+
+VclPtr<VclAbstractDialog>
AbstractDialogFactory_Impl::CreateTipOfTheDayDialog(weld::Window* pParent)
{
#if !ENABLE_WASM_STRIP_PINGUSER
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
index fc83403cb24d..6b4a548fe3fc 100644
--- a/cui/source/factory/dlgfact.hxx
+++ b/cui/source/factory/dlgfact.hxx
@@ -619,6 +619,8 @@ public:
virtual VclPtr<VclAbstractDialog> CreateAboutDialog(weld::Window* pParent) override;
+ virtual VclPtr<VclAbstractDialog> CreateWhatsNewDialog(weld::Window* pParent, const bool bWelcome) override;
+
virtual VclPtr<VclAbstractDialog> CreateTipOfTheDayDialog(weld::Window* pParent) override;
virtual VclPtr<VclAbstractDialog> CreateWidgetTestDialog(weld::Window* pParent) override;
diff --git a/cui/source/inc/whatsnew.hxx b/cui/source/inc/whatsnew.hxx
new file mode 100644
index 000000000000..76a3a2d4d63d
--- /dev/null
+++ b/cui/source/inc/whatsnew.hxx
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+#include "cuigrfflt.hxx"
+
+class WhatsNewImg : public weld::CustomWidgetController
+{
+ OUString m_sImage;
+ OUString m_sText;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+
+public:
+ WhatsNewImg(){};
+ void Update(const OUString& sImage, const OUString& sText)
+ {
+ m_sImage = sImage;
+ m_sText = sText;
+ SetAccessibleName(m_sText);
+ Invalidate();
+ };
+};
+
+class WhatsNewProgress : public weld::CustomWidgetController
+{
+ sal_Int32 m_nTotal;
+ sal_Int32 m_nCurrent;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+
+public:
+ WhatsNewProgress(){};
+ void Update(const sal_Int32 nCurrent, const sal_Int32 nTotal)
+ {
+ m_nTotal = nTotal;
+ m_nCurrent = nCurrent;
+ Invalidate();
+ };
+};
+
+class WhatsNewDialog : public weld::GenericDialogController
+{
+private:
+ const bool m_bWelcome;
+
+ WhatsNewImg m_aPreview;
+ WhatsNewProgress m_aProgress;
+
+ std::unique_ptr<weld::Button> m_pPrevBtn;
+ std::unique_ptr<weld::Button> m_pNextBtn;
+ std::unique_ptr<weld::CustomWeld> m_pProgress;
+ std::unique_ptr<weld::CustomWeld> m_pImage;
+
+ DECL_LINK(OnPrevClick, weld::Button&, void);
+ DECL_LINK(OnNextClick, weld::Button&, void);
+
+ void LoadImage(); // loads WHATSNEW_STRINGARRAY[m_nCurrentNews]
+
+ sal_Int32 m_nNumberOfNews;
+ sal_Int32 m_nCurrentNews;
+
+public:
+ WhatsNewDialog(weld::Window* pParent, const bool bWelcome);
+ virtual ~WhatsNewDialog() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/uiconfig/ui/whatsnewdialog.ui b/cui/uiconfig/ui/whatsnewdialog.ui
new file mode 100644
index 000000000000..0a4949c398bf
--- /dev/null
+++ b/cui/uiconfig/ui/whatsnewdialog.ui
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkDialog" id="WhatsNewDialog">
+ <property name="can-focus">False</property>
+ <property name="border-width">6</property>
+ <property name="title" translatable="yes" context="whatsnewdialog|WhatsNewDialog">What's new in %PRODUCTVERSION</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window-position">center-on-parent</property>
+ <property name="type-hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox">
+ <property name="can-focus">False</property>
+ <property name="margin-top">12</property>
+ <property name="hexpand">True</property>
+ <property name="layout-style">end</property>
+ <child>
+ <object class="GtkButton" id="btnClose">
+ <property name="label" translatable="yes" context="stock">_Close</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack-type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <!-- n-columns=3 n-rows=2 -->
+ <object class="GtkGrid" id="grid">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child>
+ <object class="GtkDrawingArea" id="imNews">
+ <property name="width-request">600</property>
+ <property name="height-request">400</property>
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="imNews-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="whatsnewdialog|extended_tip|news">Picture illustrating what is new</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ <property name="width">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnPrev">
+ <property name="label" translatable="yes" context="whatsnewdialog|prev">Previous</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="btnNext">
+ <property name="label" translatable="yes" context="whatsnewdialog|next">Next</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="halign">start</property>
+ <property name="valign">center</property>
+ <property name="use-underline">True</property>
+ <property name="image-position">right</property>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkDrawingArea" id="imProgress">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="imProgress-atkobject">
+ <property name="AtkObject::accessible-description" translatable="yes" context="whatsnewdialog|extended_tip|progress">Progress of news</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">btnClose</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index d99b7995ed93..d59855e58b03 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -347,7 +347,7 @@ void runGraphicsRenderTests()
if (comphelper::LibreOfficeKit::isActive())
return;
#if !ENABLE_WASM_STRIP_PINGUSER
- if (!utl::isProductVersionUpgraded(false))
+ if (!utl::isProductVersionUpgraded())
{
return;
}
diff --git a/extras/source/whatsnew/Community.png b/extras/source/whatsnew/Community.png
new file mode 100644
index 000000000000..ae3169885705
--- /dev/null
+++ b/extras/source/whatsnew/Community.png
Binary files differ
diff --git a/extras/source/whatsnew/Configurability.png b/extras/source/whatsnew/Configurability.png
new file mode 100644
index 000000000000..2ca9094ebf70
--- /dev/null
+++ b/extras/source/whatsnew/Configurability.png
Binary files differ
diff --git a/extras/source/whatsnew/LibreOffice.gif b/extras/source/whatsnew/LibreOffice.gif
new file mode 100644
index 000000000000..1d5643091a6b
--- /dev/null
+++ b/extras/source/whatsnew/LibreOffice.gif
Binary files differ
diff --git a/extras/source/whatsnew/ODF.png b/extras/source/whatsnew/ODF.png
new file mode 100644
index 000000000000..04e23d7021d6
--- /dev/null
+++ b/extras/source/whatsnew/ODF.png
Binary files differ
diff --git a/extras/source/whatsnew/whatsnew1.png b/extras/source/whatsnew/whatsnew1.png
new file mode 100644
index 000000000000..bce0be6b970c
--- /dev/null
+++ b/extras/source/whatsnew/whatsnew1.png
Binary files differ
diff --git a/include/sfx2/sfxdlg.hxx b/include/sfx2/sfxdlg.hxx
index 31bd0c3108ad..c4db62792f14 100644
--- a/include/sfx2/sfxdlg.hxx
+++ b/include/sfx2/sfxdlg.hxx
@@ -147,6 +147,8 @@ public:
virtual VclPtr<VclAbstractDialog> CreateAboutDialog(weld::Window* _pParent) = 0;
+ virtual VclPtr<VclAbstractDialog> CreateWhatsNewDialog(weld::Window* _pParent, const bool bWelcome) = 0;
+
virtual VclPtr<VclAbstractDialog> CreateTipOfTheDayDialog(weld::Window* _pParent) = 0;
virtual VclPtr<VclAbstractDialog> CreateToolbarmodeDialog(weld::Window* _pParent) = 0;
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index e2fafac7321a..f863d7cb3233 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -117,8 +117,9 @@ class SvxZoomItem;
#define SID_DOCUMENTATION (SID_SFX_START + 423)
#define SID_DONATION (SID_SFX_START + 424)
#define SID_GETINVOLVED (SID_SFX_START + 425)
-#define SID_WHATSNEW (SID_SFX_START + 426)
-#define SID_HYPHENATIONMISSING (SID_SFX_START + 427)
+#define SID_WHATSNEW (SID_SFX_START + 426) // open ReleaseNotesURL
+#define SID_WHATSNEWDLG (SID_SFX_START + 427) // show WhatsNewDlg
+#define SID_HYPHENATIONMISSING (SID_SFX_START + 428)
#define SID_SHOW_LICENSE (SID_SFX_START + 1683)
#define SID_SHOW_CREDITS (SID_SFX_START + 1711)
diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc
index 1c3fafa074c0..a269b5335a36 100644
--- a/include/sfx2/strings.hrc
+++ b/include/sfx2/strings.hrc
@@ -260,8 +260,6 @@
#define STR_GET_INVOLVED_BUTTON NC_("STR_GET_INVOLVED_BUTTON", "Get involved")
#define STR_DONATE_TEXT NC_("STR_DONATE_TEXT", "Your donations support our worldwide community.")
#define STR_DONATE_BUTTON NC_("STR_DONATE_BUTTON", "Donate")
-#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_BUTTON NC_("STR_WHATSNEW_BUTTON", "Release Notes")
#define STR_READONLY_DOCUMENT NC_("STR_READONLY_DOCUMENT", "This document is open in read-only mode.")
#define STR_READONLY_PDF NC_("STR_READONLY_PDF", "This PDF is open in read-only mode to allow signing the existing file.")
#define STR_CLASSIFIED_DOCUMENT NC_("STR_CLASSIFIED_DOCUMENT", "The classification label of this document is %1.")
diff --git a/include/sfx2/viewfrm.hxx b/include/sfx2/viewfrm.hxx
index 7e038e9d6b96..1e3d4e55ab47 100644
--- a/include/sfx2/viewfrm.hxx
+++ b/include/sfx2/viewfrm.hxx
@@ -63,7 +63,6 @@ class SFX2_DLLPUBLIC SfxViewFrame final : public SfxShell, public SfxListener
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
DECL_DLLPRIVATE_LINK(GetInvolvedHandler, weld::Button&, void);
DECL_DLLPRIVATE_LINK(DonationHandler, weld::Button&, void);
- DECL_DLLPRIVATE_LINK(WhatsNewHandler, weld::Button&, void);
DECL_DLLPRIVATE_LINK(MacroButtonHandler, weld::Button&, void);
DECL_DLLPRIVATE_LINK(SecurityButtonHandler, weld::Button&, void);
DECL_DLLPRIVATE_LINK(EventButtonHandler, weld::Button&, void);
diff --git a/include/unotools/VersionConfig.hxx b/include/unotools/VersionConfig.hxx
index 5e40b0af8756..3918dfd2e514 100644
--- a/include/unotools/VersionConfig.hxx
+++ b/include/unotools/VersionConfig.hxx
@@ -25,7 +25,7 @@ namespace utl
@param aUpdateVersion This variable is used to determine if
LibreOffice's previous version should be updated.
*/
-static bool isProductVersionUpgraded(bool aUpdateVersion)
+static bool isProductVersionUpgraded()
{
OUString sSetupVersion = utl::ConfigManager::getProductVersion();
sal_Int32 iCurrent = o3tl::toInt32(o3tl::getToken(sSetupVersion, 0, '.')) * 10
@@ -33,26 +33,6 @@ static bool isProductVersionUpgraded(bool aUpdateVersion)
OUString sLastVersion = officecfg::Setup::Product::ooSetupLastVersion::get().value_or("0.0");
sal_Int32 iLast = o3tl::toInt32(o3tl::getToken(sLastVersion, 0, '.')) * 10
+ o3tl::toInt32(o3tl::getToken(sLastVersion, 1, '.'));
- if (iCurrent > iLast)
- {
- if (aUpdateVersion)
- { //update lastversion
- try
- {
- std::shared_ptr<comphelper::ConfigurationChanges> batch(
- comphelper::ConfigurationChanges::create());
- officecfg::Setup::Product::ooSetupLastVersion::set(sSetupVersion, batch);
- batch->commit();
- }
- catch (css::lang::IllegalArgumentException&)
- { //If the value was readOnly.
- SAL_WARN("desktop.updater", "Updating property ooSetupLastVersion to version "
- << sSetupVersion
- << " failed (read-only property?)");
- }
- }
- return true;
- }
- return false;
+ return (iCurrent > iLast);
}
}
diff --git a/officecfg/registry/schema/org/openoffice/Office/UI/Infobar.xcs b/officecfg/registry/schema/org/openoffice/Office/UI/Infobar.xcs
index 6235c575c5d0..0fc4c38230af 100644
--- a/officecfg/registry/schema/org/openoffice/Office/UI/Infobar.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/UI/Infobar.xcs
@@ -48,12 +48,6 @@
</info>
<value>true</value>
</prop>
- <prop oor:name="WhatsNew" oor:type="xs:boolean" oor:nillable="false">
- <info>
- <desc>Whether an Infobar is shown when the major version number has changed</desc>
- </info>
- <value>true</value>
- </prop>
<prop oor:name="HiddenTrackChanges" oor:type="xs:boolean" oor:nillable="false">
<info>
<desc>Whether an Infobar is shown when hidden Track Changes settings or data are there in a document</desc>
diff --git a/officecfg/registry/schema/org/openoffice/Setup.xcs b/officecfg/registry/schema/org/openoffice/Setup.xcs
index 82e23f0d8d9f..44640c71797a 100644
--- a/officecfg/registry/schema/org/openoffice/Setup.xcs
+++ b/officecfg/registry/schema/org/openoffice/Setup.xcs
@@ -301,7 +301,13 @@
</info>
<value>0</value>
</prop>
- </group>
+ <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>
+ </info>
+ <value>true</value>
+ </prop>
+ </group>
<group oor:name="Office">
<!--The default must be written by the setup.-->
<info>
diff --git a/sfx2/sdi/appslots.sdi b/sfx2/sdi/appslots.sdi
index b8d75480fef5..4b2e0a5357bf 100644
--- a/sfx2/sdi/appslots.sdi
+++ b/sfx2/sdi/appslots.sdi
@@ -147,6 +147,10 @@ interface Application
[
ExecMethod = MiscExec_Impl ;
]
+ SID_WHATSNEWDLG
+ [
+ ExecMethod = MiscExec_Impl ;
+ ]
SID_HYPHENATIONMISSING
[
ExecMethod = MiscExec_Impl ;
diff --git a/sfx2/sdi/sfx.sdi b/sfx2/sdi/sfx.sdi
index 5d26a161c817..21894391ef51 100644
--- a/sfx2/sdi/sfx.sdi
+++ b/sfx2/sdi/sfx.sdi
@@ -5144,6 +5144,22 @@ SfxVoidItem WhatsNew SID_WHATSNEW
MenuConfig = TRUE,
GroupId = SfxGroupId::Application;
]
+SfxVoidItem WhatsNewDlg SID_WHATSNEWDLG
+()
+[
+ AutoUpdate = FALSE,
+ FastCall = FALSE,
+ ReadOnlyDoc = TRUE,
+ Toggle = FALSE,
+ Container = FALSE,
+ RecordAbsolute = FALSE,
+ RecordPerSet;
+
+ AccelConfig = FALSE,
+ MenuConfig = FALSE,
+ ToolBoxConfig = FALSE,
+ GroupId = SfxGroupId::Application;
+]
SfxVoidItem HyphenationMissing SID_HYPHENATIONMISSING
()
[
diff --git a/sfx2/source/appl/appserv.cxx b/sfx2/source/appl/appserv.cxx
index ecd290c4940b..5dd93dc54a25 100644
--- a/sfx2/source/appl/appserv.cxx
+++ b/sfx2/source/appl/appserv.cxx
@@ -105,6 +105,7 @@
#include <comphelper/types.hxx>
#include <officecfg/Office/Common.hxx>
+#include <officecfg/Setup.hxx>
#include <unotools/confignode.hxx>
#include <memory>
@@ -711,6 +712,15 @@ void SfxApplication::MiscExec_Impl( SfxRequest& rReq )
bDone = true;
break;
}
+ case SID_WHATSNEWDLG:
+ {
+ const bool bWelcome = !officecfg::Setup::Product::ooSetupLastVersion::get().has_value();
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateWhatsNewDialog(rReq.GetFrameWeld(), bWelcome));
+ pDlg->StartExecuteAsync(nullptr);
+ bDone = true;
+ break;
+ }
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case SID_WIDGET_TEST_DIALOG:
diff --git a/sfx2/source/dialog/infobar.cxx b/sfx2/source/dialog/infobar.cxx
index 26dfc0af26c0..58beb3892518 100644
--- a/sfx2/source/dialog/infobar.cxx
+++ b/sfx2/source/dialog/infobar.cxx
@@ -436,8 +436,6 @@ bool SfxInfoBarContainerWindow::isInfobarEnabled(std::u16string_view sId)
return officecfg::Office::UI::Infobar::Enabled::GetInvolved::get();
if (sId == u"hyphenationmissing")
return officecfg::Office::UI::Infobar::Enabled::HyphenationMissing::get();
- if (sId == u"whatsnew")
- return officecfg::Office::UI::Infobar::Enabled::WhatsNew::get();
if (sId == u"hiddentrackchanges")
return officecfg::Office::UI::Infobar::Enabled::HiddenTrackChanges::get();
if (sId == u"macro")
diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx
index 20e56a6c4076..222eb0ff96ec 100644
--- a/sfx2/source/view/viewfrm.cxx
+++ b/sfx2/source/view/viewfrm.cxx
@@ -1615,23 +1615,43 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
#if !ENABLE_WASM_STRIP_PINGUSER
bool bIsHeadlessOrUITest = SfxApplication::IsHeadlessOrUITest(); //uitest.uicheck fails when the dialog is open
+ bool bIsWhatsNewShown = false; //suppress tipoftheday if whatsnew is shown
- //what's new infobar
- if (!bIsInfobarShown && utl::isProductVersionUpgraded(true) && !bIsHeadlessOrUITest)
+ //what's new dialog
+ if (utl::isProductVersionUpgraded())
{
- VclPtr<SfxInfoBarWindow> pInfoBar = AppendInfoBar("whatsnew", "", SfxResId(STR_WHATSNEW_TEXT), InfobarType::INFO);
- bIsInfobarShown = true;
- if (pInfoBar)
+ const bool bShowWhatsNew = officecfg::Setup::Product::WhatsNew::get();
+ const bool bIsUnitTestMode = getenv("LO_TESTNAME") != nullptr;
+
+ if (!bIsHeadlessOrUITest && !bIsUnitTestMode && bShowWhatsNew)
+ {
+ const auto xCurrentFrame = GetFrame().GetFrameInterface();
+ SfxUnoFrameItem aDocFrame(SID_FILLFRAME, xCurrentFrame);
+ GetDispatcher()->ExecuteList(SID_WHATSNEWDLG, SfxCallMode::SLOT, {},
+ { &aDocFrame });
+ bIsWhatsNewShown = true;
+ }
+
+ //update lastversion
+ OUString sSetupVersion = utl::ConfigManager::getProductVersion();
+ try
{
- weld::Button& rWhatsNewButton = pInfoBar->addButton();
- rWhatsNewButton.set_label(SfxResId(STR_WHATSNEW_BUTTON));
- rWhatsNewButton.connect_clicked(LINK(this, SfxViewFrame, WhatsNewHandler));
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Setup::Product::ooSetupLastVersion::set(sSetupVersion, batch);
+ batch->commit();
+ }
+ catch (css::lang::IllegalArgumentException&)
+ { //If the value was readOnly.
+ SAL_WARN("desktop.updater", "Updating property ooSetupLastVersion to version "
+ << sSetupVersion
+ << " failed (read-only property?)");
}
}
// show tip-of-the-day dialog if it due, but not if there is the impress modal template dialog
// open where SdModule::ExecuteNewDocument will launch it instead when that dialog is dismissed
- if (SfxApplication::IsTipOfTheDayDue() && !bIsHeadlessOrUITest && !IsInModalMode())
+ if (SfxApplication::IsTipOfTheDayDue() && !bIsHeadlessOrUITest && !IsInModalMode() && !bIsWhatsNewShown)
{
bool bIsBaseFormOpen = false;
@@ -1804,11 +1824,6 @@ void SfxViewFrame::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
}
#if !ENABLE_WASM_STRIP_PINGUSER
-IMPL_LINK_NOARG(SfxViewFrame, WhatsNewHandler, weld::Button&, void)
-{
- GetDispatcher()->Execute(SID_WHATSNEW);
-}
-
IMPL_LINK_NOARG(SfxViewFrame, GetInvolvedHandler, weld::Button&, void)
{
GetDispatcher()->Execute(SID_GETINVOLVED);
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index 35c6427b4ed1..5f627722e78f 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -22,6 +22,7 @@ $(eval $(call gb_Module_Module,vcl))
ifneq ($(ENABLE_WASM_STRIP_PINGUSER),TRUE)
$(eval $(call gb_Module_add_targets,vcl,\
Package_tipoftheday \
+ Package_whatsnew \
))
endif
diff --git a/vcl/Package_whatsnew.mk b/vcl/Package_whatsnew.mk
new file mode 100644
index 000000000000..6e1add206628
--- /dev/null
+++ b/vcl/Package_whatsnew.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Package_Package,whatsnew_images,$(SRCDIR)/extras/source/whatsnew))
+
+$(eval $(call gb_Package_add_files_with_dir,whatsnew_images,$(LIBO_SHARE_FOLDER)/whatsnew,\
+ LibreOffice.gif \
+ ODF.png \
+ Configurability.png \
+ Community.png \
+ whatsnew1.png \
+))
+
+# vim: set noet sw=4 ts=4: \ No newline at end of file