diff options
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 Binary files differnew file mode 100644 index 000000000000..ae3169885705 --- /dev/null +++ b/extras/source/whatsnew/Community.png diff --git a/extras/source/whatsnew/Configurability.png b/extras/source/whatsnew/Configurability.png Binary files differnew file mode 100644 index 000000000000..2ca9094ebf70 --- /dev/null +++ b/extras/source/whatsnew/Configurability.png diff --git a/extras/source/whatsnew/LibreOffice.gif b/extras/source/whatsnew/LibreOffice.gif Binary files differnew file mode 100644 index 000000000000..1d5643091a6b --- /dev/null +++ b/extras/source/whatsnew/LibreOffice.gif diff --git a/extras/source/whatsnew/ODF.png b/extras/source/whatsnew/ODF.png Binary files differnew file mode 100644 index 000000000000..04e23d7021d6 --- /dev/null +++ b/extras/source/whatsnew/ODF.png diff --git a/extras/source/whatsnew/whatsnew1.png b/extras/source/whatsnew/whatsnew1.png Binary files differnew file mode 100644 index 000000000000..bce0be6b970c --- /dev/null +++ b/extras/source/whatsnew/whatsnew1.png 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 |