Resolves rdm#3867 - Add a donation banner to the start center

Change-Id: I075e94798aaf83b394e713f6ef6139a985e22064
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198539
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
Tested-by: Jenkins
This commit is contained in:
Heiko Tietze
2026-03-20 10:53:22 +01:00
parent 6ca5fd8cbb
commit 2269d92bf9
6 changed files with 84 additions and 2 deletions
+1 -1
View File
@@ -15411,7 +15411,7 @@ dnl ===================================================================
AC_MSG_CHECKING([for alternative branding images directory])
# initialize mapped arrays
BRAND_INTRO_IMAGES="intro.png intro-highres.png"
brand_files="$BRAND_INTRO_IMAGES logo.svg logo_inverted.svg logo-sc.svg logo-sc_inverted.svg about.svg"
brand_files="$BRAND_INTRO_IMAGES logo.svg logo_inverted.svg logo-sc.svg logo-sc_inverted.svg about.svg donatebanner.png"
if test -z "$with_branding" -o "$with_branding" = "no"; then
AC_MSG_RESULT([none])
Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

+5
View File
@@ -390,6 +390,11 @@
#define STR_QUERY_CLR_UNAVAILABLE_DOCS_TITLE NC_("STR_QUERY_CLR_UNAVAILABLE_DOCS_TITLE", "Clear Unavailable Documents")
#define STR_QUERY_CLR_UNAVAILABLE_DOCS_TEXT NC_("STR_QUERY_CLR_UNAVAILABLE_DOCS_TEXT", "This action is irreversible.")
#define STR_QUERY_CLR_UNAVAILABLE_DOCS_QUESTION NC_("STR_QUERY_CLR_UNAVAILABLE_DOCS_QUESTION", "Do you want to clear all unavailable Documents?")
#define STR_DONATIONBANNER NC_("STR_DONATIONBANNER", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere.")
#define DONATIONBANNER_HEIGHT 0.25 // banner height as percentage of the app height
#define DONATIONBANNER_FREQ 1 // frequency of days to show the banner; 1 = every start
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+63 -1
View File
@@ -61,6 +61,12 @@
#include <sfx2/strings.hrc>
#include <sfx2/sfxresid.hxx>
#include <bitmaps.hlst>
#include <rtl/bootstrap.hxx>
#include <vcl/virdev.hxx>
#include <vcl/graph.hxx>
#include <vcl/graphicfilter.hxx>
#include <config_folders.h>
using namespace ::com::sun::star;
using namespace ::com::sun::star::beans;
@@ -174,17 +180,29 @@ BackingWindow::BackingWindow(vcl::Window* i_pParent)
, mxAllButtonsBox(m_xBuilder->weld_container(u"all_buttons_box"_ustr))
, mxButtonsBox(m_xBuilder->weld_container(u"buttons_box"_ustr))
, mxSmallButtonsBox(m_xBuilder->weld_container(u"small_buttons_box"_ustr))
, mxRightBox(m_xBuilder->weld_container(u"box2"_ustr))
, mxAllRecentThumbnails(new sfx2::RecentDocsView(m_xBuilder->weld_scrolled_window(u"scrollrecent"_ustr, true)))
, mxAllRecentThumbnailsWin(new weld::CustomWeld(*m_xBuilder, u"all_recent"_ustr, *mxAllRecentThumbnails))
, mxLocalView(new TemplateDefaultView(m_xBuilder->weld_scrolled_window(u"scrolllocal"_ustr, true),
m_xBuilder->weld_menu(u"localmenu"_ustr)))
, mxLocalViewWin(new weld::CustomWeld(*m_xBuilder, u"local_view"_ustr, *mxLocalView))
, mxDonation(m_xBuilder->weld_image(u"imgDonation"_ustr))
, mbLocalViewInitialized(false)
, mbInitControls(false)
{
// init background, undo InterimItemWindow defaults for this widget
SetPaintTransparent(false);
// draw the donation image/text
const auto t0 = std::chrono::system_clock::now().time_since_epoch();
const sal_Int32 nDay = std::chrono::duration_cast<std::chrono::hours>(t0).count()/24; // days since 1970-01-01
const bool bShowDonationBanner = nDay % DONATIONBANNER_FREQ == 0;
if (bShowDonationBanner)
{
mxDonation->set_visible(true);
mxRightBox->connect_size_allocate(LINK(this,BackingWindow,ResizeHdl));
}
// square action button
auto nHeight = mxFilter->get_preferred_size().getHeight();
mxActions->set_size_request(nHeight, nHeight);
@@ -194,7 +212,7 @@ BackingWindow::BackingWindow(vcl::Window* i_pParent)
mxHelpButton->connect_clicked(LINK(this, BackingWindow, ClickHelpHdl));
// tdf#161796 replace the extension button with a donate button
if (officecfg::Office::Common::Misc::ShowDonation::get())
if (bShowDonationBanner || officecfg::Office::Common::Misc::ShowDonation::get())
{
mxExtensionsButton->hide();
mxDonateButton->show();
@@ -233,6 +251,50 @@ IMPL_LINK(BackingWindow, ClickHelpHdl, weld::Button&, rButton, void)
pHelp->Start(m_xContainer->get_help_id(), &rButton);
}
IMPL_LINK(BackingWindow, ResizeHdl, const Size&, rSize, void)
{
const Size aBannerSize(Size(rSize.getWidth(), rSize.getHeight() * DONATIONBANNER_HEIGHT));
mxDonation->set_size_request(aBannerSize.getWidth(), aBannerSize.getHeight());
ScopedVclPtr<VirtualDevice> m_pVirDev = mxDonation->create_virtual_device();
m_pVirDev->SetOutputSizePixel(aBannerSize);
// image proportionally scaled to banner height and placed at the right side
OUString aURL = "$BRAND_BASE_DIR/" LIBO_ETC_FOLDER + u"/shell/donatebanner.png"_ustr;
rtl::Bootstrap::expandMacros( aURL );
Graphic aGraphic;
Size aGraphicSize;
if (GraphicFilter::LoadGraphic(aURL, OUString(), aGraphic) == ERRCODE_NONE)
{
aGraphicSize = aGraphic.GetBitmap().GetSizePixel();
const float nRel
= static_cast<float>(aBannerSize.getHeight()) / static_cast<float>(aGraphicSize.getHeight());
aGraphicSize = Size(aGraphicSize.getWidth() * nRel, aGraphicSize.getHeight() * nRel);
m_pVirDev->DrawBitmap(Point(aBannerSize.getWidth() - aGraphicSize.getWidth(), 0),
aGraphicSize, aGraphic.GetBitmap());
}
// text
tools::Rectangle aRect(Point(6, 0), Size(aBannerSize.getWidth() - aGraphicSize.getWidth(),
aBannerSize.getHeight()));
vcl::Font aFont = m_pVirDev->GetFont();
aFont.SetFontHeight(48);
m_pVirDev->SetFont(aFont);
DrawTextFlags const nTextStyle = DrawTextFlags::MultiLine | DrawTextFlags::WordBreak;
while (m_pVirDev->GetTextRect(aRect, SfxResId(STR_DONATIONBANNER), nTextStyle).GetHeight()
> aBannerSize.getHeight())
{
aFont.SetFontHeight(aFont.GetFontHeight() - 1);
m_pVirDev->SetFont(aFont);
if (aFont.GetFontHeight() < 12)
break;
}
m_pVirDev->DrawText(aRect, SfxResId(STR_DONATIONBANNER), nTextStyle);
mxDonation->set_image(m_pVirDev.get());
m_pVirDev.disposeAndClear();
}
BackingWindow::~BackingWindow()
{
disposeOnce();
+4
View File
@@ -75,11 +75,14 @@ class BackingWindow : public InterimItemWindow
std::unique_ptr<weld::Container> mxAllButtonsBox;
std::unique_ptr<weld::Container> mxButtonsBox;
std::unique_ptr<weld::Container> mxSmallButtonsBox;
std::unique_ptr<weld::Container> mxRightBox;
std::unique_ptr<sfx2::RecentDocsView> mxAllRecentThumbnails;
std::unique_ptr<weld::CustomWeld> mxAllRecentThumbnailsWin;
std::unique_ptr<TemplateDefaultView> mxLocalView;
std::unique_ptr<weld::CustomWeld> mxLocalViewWin;
std::unique_ptr<weld::Image> mxDonation;
bool mbLocalViewInitialized;
css::uno::Reference<css::datatransfer::dnd::XDropTarget> mxDropTarget;
@@ -102,6 +105,7 @@ class BackingWindow : public InterimItemWindow
DECL_LINK(CreateContextMenuHdl, TemplateViewItem*, void);
DECL_LINK(OpenTemplateHdl, const OUString&, void);
DECL_LINK(EditTemplateHdl, const OUString&, void);
DECL_LINK(ResizeHdl, const Size&, void);
void initControls();
+11
View File
@@ -676,6 +676,17 @@
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkImage" id="imgDonation">
<property name="can-focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>