summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-06-04 11:34:28 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-06-06 09:57:53 +0200
commita30a5d1b8af18d19526f1980df41857f455cc8ef (patch)
treee8add75abca3c336cbc46936a7d19028ba4251aa /vcl
parent7665246ac8addc002f74e3a9b22d1baeda448af3 (diff)
weld AboutDialog
use a native GtkAboutDialog on that platform and refactor the current cui about dialog body to form the body of a vcl AboutDialog use add_button to add the buttons to whichever is preferred of the headerbar or action-area Change-Id: I67e0b36dcb8d3fa08ec4f0397b0f6185b0778675 Reviewed-on: https://gerrit.libreoffice.org/73439 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/UIConfig_vcl.mk1
-rw-r--r--vcl/source/app/salvtables.cxx79
-rw-r--r--vcl/source/window/aboutdialog.cxx159
-rw-r--r--vcl/source/window/builder.cxx8
-rw-r--r--vcl/uiconfig/ui/aboutbox.ui135
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx173
7 files changed, 551 insertions, 5 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 428e69324782..deb7cf049106 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -117,6 +117,7 @@ endif
$(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/animate/Animation \
vcl/source/animate/AnimationBitmap \
+ vcl/source/window/aboutdialog \
vcl/source/window/errinf \
vcl/source/window/settings \
vcl/source/window/paint \
diff --git a/vcl/UIConfig_vcl.mk b/vcl/UIConfig_vcl.mk
index 8a385dedddd8..3184aaee5293 100644
--- a/vcl/UIConfig_vcl.mk
+++ b/vcl/UIConfig_vcl.mk
@@ -10,6 +10,7 @@
$(eval $(call gb_UIConfig_UIConfig,vcl))
$(eval $(call gb_UIConfig_add_uifiles,vcl,\
+ vcl/uiconfig/ui/aboutbox \
vcl/uiconfig/ui/cupspassworddialog \
vcl/uiconfig/ui/editmenu \
vcl/uiconfig/ui/errornocontentdialog \
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index afca107ef91c..166a5133feb0 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -36,6 +36,7 @@
#include <unotools/accessiblerelationsethelper.hxx>
#include <utility>
#include <tools/helpers.hxx>
+#include <vcl/aboutdialog.hxx>
#include <vcl/builder.hxx>
#include <vcl/calendar.hxx>
#include <vcl/combobox.hxx>
@@ -462,6 +463,11 @@ public:
return m_xWidget->get_vexpand();
}
+ virtual void set_secondary(bool bSecondary) override
+ {
+ m_xWidget->set_secondary(bSecondary);
+ }
+
virtual void set_margin_top(int nMargin) override
{
m_xWidget->set_margin_top(nMargin);
@@ -1301,6 +1307,26 @@ public:
VclPtr<PushButton> xButton(VclPtr<PushButton>::Create(pBox, WB_CLIPCHILDREN|WB_CENTER|WB_VCENTER));
xButton->SetText(rText);
xButton->SetHelpId(rHelpId);
+
+ switch (nResponse)
+ {
+ case RET_OK:
+ xButton->set_id("ok");
+ break;
+ case RET_CLOSE:
+ xButton->set_id("close");
+ break;
+ case RET_CANCEL:
+ xButton->set_id("cancel");
+ break;
+ case RET_YES:
+ xButton->set_id("yes");
+ break;
+ case RET_NO:
+ xButton->set_id("no");
+ break;
+ }
+
xButton->Show();
m_xDialog->add_button(xButton, nResponse, true);
}
@@ -1355,6 +1381,46 @@ public:
}
};
+class SalInstanceAboutDialog : public SalInstanceDialog, public virtual weld::AboutDialog
+{
+private:
+ VclPtr<::AboutDialog> m_xAboutDialog;
+public:
+ SalInstanceAboutDialog(::AboutDialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+ : SalInstanceDialog(pDialog, pBuilder, bTakeOwnership)
+ , m_xAboutDialog(pDialog)
+ {
+ }
+ virtual void set_version(const OUString& rVersion) override
+ {
+ m_xAboutDialog->SetVersion(rVersion);
+ }
+ virtual void set_copyright(const OUString& rCopyright) override
+ {
+ m_xAboutDialog->SetCopyright(rCopyright);
+ }
+ virtual void set_website(const OUString& rURL) override
+ {
+ m_xAboutDialog->SetWebsiteLink(rURL);
+ }
+ virtual void set_website_label(const OUString& rLabel) override
+ {
+ m_xAboutDialog->SetWebsiteLabel(rLabel);
+ }
+ virtual OUString get_website_label() const override
+ {
+ return m_xAboutDialog->GetWebsiteLabel();
+ }
+ virtual void set_logo(VirtualDevice* pDevice) override
+ {
+ m_xAboutDialog->SetLogo(createImage(*pDevice));
+ }
+ virtual void set_background(VirtualDevice* pDevice) override
+ {
+ m_xAboutDialog->SetBackground(createImage(*pDevice));
+ }
+};
+
class SalInstanceFrame : public SalInstanceContainer, public virtual weld::Frame
{
private:
@@ -5014,6 +5080,19 @@ public:
return pRet;
}
+ virtual std::unique_ptr<weld::AboutDialog> weld_about_dialog(const OString &id, bool bTakeOwnership) override
+ {
+ AboutDialog* pAboutDialog = m_xBuilder->get<AboutDialog>(id);
+ std::unique_ptr<weld::AboutDialog> pRet(pAboutDialog ? new SalInstanceAboutDialog(pAboutDialog, this, false) : nullptr);
+ if (bTakeOwnership && pAboutDialog)
+ {
+ assert(!m_aOwnedToplevel && "only one toplevel per .ui allowed");
+ m_aOwnedToplevel.set(pAboutDialog);
+ m_xBuilder->drop_ownership(pAboutDialog);
+ }
+ return pRet;
+ }
+
virtual std::unique_ptr<weld::Dialog> weld_dialog(const OString &id, bool bTakeOwnership) override
{
Dialog* pDialog = m_xBuilder->get<Dialog>(id);
diff --git a/vcl/source/window/aboutdialog.cxx b/vcl/source/window/aboutdialog.cxx
new file mode 100644
index 000000000000..1a563dfd367d
--- /dev/null
+++ b/vcl/source/window/aboutdialog.cxx
@@ -0,0 +1,159 @@
+/* -*- 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 <config_features.h>
+#include <osl/process.h>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <rtl/character.hxx>
+#include <vcl/aboutdialog.hxx>
+#include <vcl/layout.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+
+#include <tools/stream.hxx>
+#include <rtl/bootstrap.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/bootstrap.hxx>
+#include <com/sun/star/uno/Any.h>
+#include <vcl/graph.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <i18nlangtag/languagetag.hxx>
+
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/system/SystemShellExecute.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/anytostring.hxx>
+#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+
+#include <config_buildid.h>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/bitmap.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star;
+
+AboutDialog::AboutDialog(vcl::Window* pParent, WinBits nStyle, Dialog::InitFlag eFlag)
+ : Dialog(pParent, nStyle, eFlag)
+ , m_xBuilder(new VclBuilder(this, getUIRootDir(), "vcl/ui/aboutbox.ui"))
+{
+ m_xBuilder->get(m_xContents, "about");
+ m_xBuilder->get(m_xLogoReplacement, "logoreplacement");
+ m_xBuilder->get(m_xLogoImage, "logo");
+ m_xBuilder->get(m_xVersion, "version");
+ m_xBuilder->get(m_xDescriptionText, "description");
+ m_xBuilder->get(m_xCopyrightText, "copyright");
+ m_xBuilder->get(m_xBuildIdLink, "buildIdLink");
+}
+
+void AboutDialog::set_content_area(VclBox* pBox)
+{
+ Dialog::set_content_area(pBox);
+
+ // move it now that the content area exists
+ m_xContents->SetParent(pBox);
+
+ StyleControls();
+}
+
+AboutDialog::~AboutDialog() { disposeOnce(); }
+
+void AboutDialog::dispose()
+{
+ m_xVersion.clear();
+ m_xDescriptionText.clear();
+ m_xCopyrightText.clear();
+ m_xLogoImage.clear();
+ m_xLogoReplacement.clear();
+ m_xBuildIdLink.clear();
+ m_xContents.clear();
+ m_xBuilder.reset();
+ Dialog::dispose();
+}
+
+void AboutDialog::StyleControls()
+{
+ // Make all the controls have a transparent background
+ m_xLogoImage->SetBackground();
+ m_xLogoReplacement->SetPaintTransparent(true);
+ m_xVersion->SetPaintTransparent(true);
+ m_xDescriptionText->SetPaintTransparent(true);
+ m_xCopyrightText->SetPaintTransparent(true);
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+
+ const vcl::Font& aLabelFont = rStyleSettings.GetLabelFont();
+ vcl::Font aLargeFont = aLabelFont;
+ aLargeFont.SetFontSize(Size(0, aLabelFont.GetFontSize().Height() * 3));
+
+ // Logo Replacement Text
+ m_xLogoReplacement->SetControlFont(aLargeFont);
+
+ // Description Text
+ aLargeFont.SetFontSize(Size(0, aLabelFont.GetFontSize().Height() * 1.3));
+ m_xDescriptionText->SetControlFont(aLargeFont);
+}
+
+void AboutDialog::SetLogo(const Image& rLogoBitmap)
+{
+ if (!rLogoBitmap)
+ {
+ m_xLogoImage->Hide();
+ m_xLogoReplacement->Show();
+ }
+ else
+ {
+ m_xLogoReplacement->Hide();
+ m_xLogoImage->SetImage(rLogoBitmap);
+ m_xLogoImage->Show();
+ }
+}
+
+void AboutDialog::SetBackground(const Image& rBackgroundBitmap)
+{
+ m_aBackgroundBitmap = rBackgroundBitmap.GetBitmapEx();
+ Invalidate();
+}
+
+void AboutDialog::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect)
+{
+ rRenderContext.SetClipRegion(vcl::Region(rRect));
+
+ Size aSize(GetOutputSizePixel());
+ Point aPos(aSize.Width() - m_aBackgroundBitmap.GetSizePixel().Width(),
+ aSize.Height() - m_aBackgroundBitmap.GetSizePixel().Height());
+
+ rRenderContext.DrawBitmapEx(aPos, m_aBackgroundBitmap);
+}
+
+bool AboutDialog::set_property(const OString& rKey, const OUString& rValue)
+{
+ if (rKey == "version")
+ m_xVersion->SetText(rValue);
+ else if (rKey == "copyright")
+ m_xCopyrightText->SetText(rValue);
+ else if (rKey == "comments")
+ m_xDescriptionText->SetText(rValue);
+ else if (rKey == "website")
+ m_xBuildIdLink->SetURL(rValue);
+ else if (rKey == "website_label")
+ m_xBuildIdLink->SetText(rValue);
+ else if (rKey == "program_name")
+ m_xLogoReplacement->SetText(rValue);
+ else
+ return Dialog::set_property(rKey, rValue);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 42c6654c5e64..61df46ffe9b7 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -20,6 +20,7 @@
#include <sal/log.hxx>
#include <unotools/localedatawrapper.hxx>
#include <unotools/resmgr.hxx>
+#include <vcl/aboutdialog.hxx>
#include <vcl/builder.hxx>
#include <vcl/builderfactory.hxx>
#include <vcl/button.hxx>
@@ -1647,12 +1648,15 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString &
extractButtonImage(id, rMap, name == "GtkRadioButton");
VclPtr<vcl::Window> xWindow;
- if (name == "GtkDialog")
+ if (name == "GtkDialog" || name == "GtkAboutDialog")
{
WinBits nBits = WB_MOVEABLE|WB_3DLOOK|WB_CLOSEABLE;
if (extractResizable(rMap))
nBits |= WB_SIZEABLE;
- xWindow = VclPtr<Dialog>::Create(pParent, nBits, !pParent ? Dialog::InitFlag::NoParent : Dialog::InitFlag::Default);
+ if (name == "GtkAboutDialog")
+ xWindow = VclPtr<AboutDialog>::Create(pParent, nBits, !pParent ? Dialog::InitFlag::NoParent : Dialog::InitFlag::Default);
+ else
+ xWindow = VclPtr<Dialog>::Create(pParent, nBits, !pParent ? Dialog::InitFlag::NoParent : Dialog::InitFlag::Default);
#if HAVE_FEATURE_DESKTOP
if (!m_bLegacy && !extractModal(rMap))
xWindow->SetType(WindowType::MODELESSDIALOG);
diff --git a/vcl/uiconfig/ui/aboutbox.ui b/vcl/uiconfig/ui/aboutbox.ui
new file mode 100644
index 000000000000..2686d80e675a
--- /dev/null
+++ b/vcl/uiconfig/ui/aboutbox.ui
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface domain="cui">
+ <requires lib="gtk+" version="3.18"/>
+ <object class="GtkBox" id="about">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkImage" id="logo">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-missing-image</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="box2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="logoreplacement">
+ <property name="can_focus">False</property>
+ <property name="no_show_all">True</property>
+ <property name="justify">center</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkTextView" id="version">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="editable">False</property>
+ <property name="wrap_mode">word</property>
+ <property name="justification">center</property>
+ <property name="cursor_visible">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLinkButton" id="buildIdLink">
+ <property name="label" translatable="yes" context="aboutdialog|buildIdLink">See Log: $GITHASH</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="description">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="justify">center</property>
+ <property name="wrap">True</property>
+ <property name="max_width_chars">62</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="grid2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <child>
+ <object class="GtkLabel" id="copyright">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">12</property>
+ <property name="margin_right">12</property>
+ <property name="hexpand">True</property>
+ <property name="justify">center</property>
+ <property name="wrap">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index bd1f8a6f3abe..c7459a81a1f4 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1817,6 +1817,13 @@ public:
return gtk_widget_get_vexpand(m_pWidget);
}
+ virtual void set_secondary(bool bSecondary) override
+ {
+ GtkWidget* pParent = gtk_widget_get_parent(m_pWidget);
+ if (pParent && GTK_IS_BUTTON_BOX(pParent))
+ gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(pParent), m_pWidget, bSecondary);
+ }
+
virtual void set_margin_top(int nMargin) override
{
gtk_widget_set_margin_top(m_pWidget, nMargin);
@@ -2288,10 +2295,31 @@ namespace
GdkPixbuf* getPixbuf(const VirtualDevice& rDevice)
{
Size aSize(rDevice.GetOutputSizePixel());
- cairo_surface_t* surface = get_underlying_cairo_surface(rDevice);
+ cairo_surface_t* orig_surface = get_underlying_cairo_surface(rDevice);
double m_fXScale, m_fYScale;
- dl_cairo_surface_get_device_scale(surface, &m_fXScale, &m_fYScale);
- return gdk_pixbuf_get_from_surface(surface, 0, 0, aSize.Width() * m_fXScale, aSize.Height() * m_fYScale);
+ dl_cairo_surface_get_device_scale(orig_surface, &m_fXScale, &m_fYScale);
+
+ cairo_surface_t* surface;
+ if (m_fXScale != 1.0 || m_fYScale != -1)
+ {
+ surface = cairo_surface_create_similar_image(orig_surface,
+ CAIRO_FORMAT_ARGB32,
+ aSize.Width(),
+ aSize.Height());
+ cairo_t* cr = cairo_create(surface);
+ cairo_set_source_surface(cr, orig_surface, 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+ }
+ else
+ surface = orig_surface;
+
+ GdkPixbuf* pRet = gdk_pixbuf_get_from_surface(surface, 0, 0, aSize.Width(), aSize.Height());
+
+ if (surface != orig_surface)
+ cairo_surface_destroy(surface);
+
+ return pRet;
}
GtkWidget* image_new_from_virtual_device(const VirtualDevice& rImageSurface)
@@ -3349,6 +3377,118 @@ public:
}
};
+class GtkInstanceAboutDialog : public GtkInstanceDialog, public virtual weld::AboutDialog
+{
+private:
+ GtkAboutDialog* m_pAboutDialog;
+ GtkCssProvider* m_pCssProvider;
+ std::unique_ptr<utl::TempFile> mxBackgroundImage;
+public:
+ GtkInstanceAboutDialog(GtkAboutDialog* pAboutDialog, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
+ : GtkInstanceDialog(GTK_DIALOG(pAboutDialog), pBuilder, bTakeOwnership)
+ , m_pAboutDialog(pAboutDialog)
+ , m_pCssProvider(nullptr)
+ {
+ }
+
+ virtual void set_version(const OUString& rVersion) override
+ {
+ gtk_about_dialog_set_version(m_pAboutDialog, OUStringToOString(rVersion, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual void set_copyright(const OUString& rCopyright) override
+ {
+ gtk_about_dialog_set_copyright(m_pAboutDialog, OUStringToOString(rCopyright, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ virtual void set_website(const OUString& rURL) override
+ {
+ OString sURL(OUStringToOString(rURL, RTL_TEXTENCODING_UTF8));
+ gtk_about_dialog_set_website(m_pAboutDialog, sURL.isEmpty() ? nullptr : sURL.getStr());
+ }
+
+ virtual void set_website_label(const OUString& rLabel) override
+ {
+ OString sLabel(OUStringToOString(rLabel, RTL_TEXTENCODING_UTF8));
+ gtk_about_dialog_set_website_label(m_pAboutDialog, sLabel.isEmpty() ? nullptr : sLabel.getStr());
+ }
+
+ virtual OUString get_website_label() const override
+ {
+ const gchar* pText = gtk_about_dialog_get_website_label(m_pAboutDialog);
+ return OUString(pText, pText ? strlen(pText) : 0, RTL_TEXTENCODING_UTF8);
+ }
+
+ virtual void set_logo(VirtualDevice* pDevice) override
+ {
+ GdkPixbuf* pixbuf = pDevice ? getPixbuf(*pDevice) : nullptr;
+ if (!pixbuf)
+ gtk_about_dialog_set_logo(m_pAboutDialog, nullptr);
+ else
+ {
+ gtk_about_dialog_set_logo(m_pAboutDialog, pixbuf);
+ g_object_unref(pixbuf);
+ }
+ }
+
+ virtual void set_background(VirtualDevice* pDevice) override
+ {
+ GtkStyleContext *pStyleContext = gtk_widget_get_style_context(GTK_WIDGET(m_pAboutDialog));
+ if (m_pCssProvider)
+ {
+ gtk_style_context_remove_provider(pStyleContext, GTK_STYLE_PROVIDER(m_pCssProvider));
+ m_pCssProvider= nullptr;
+ }
+
+ mxBackgroundImage.reset();
+
+ if (pDevice)
+ {
+ mxBackgroundImage.reset(new utl::TempFile());
+ mxBackgroundImage->EnableKillingFile(true);
+
+ OString sOutput = mxBackgroundImage->GetFileName().toUtf8();
+
+ cairo_surface_t* orig_surface = get_underlying_cairo_surface(*pDevice);
+ double m_fXScale, m_fYScale;
+ dl_cairo_surface_get_device_scale(orig_surface, &m_fXScale, &m_fYScale);
+
+ cairo_surface_t* surface;
+ if (m_fXScale != 1.0 || m_fYScale != -1)
+ {
+ Size aSize(pDevice->GetOutputSizePixel());
+ surface = cairo_surface_create_similar_image(orig_surface,
+ CAIRO_FORMAT_ARGB32,
+ aSize.Width(),
+ aSize.Height());
+ cairo_t* cr = cairo_create(surface);
+ cairo_set_source_surface(cr, orig_surface, 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr);
+ }
+ else
+ surface = orig_surface;
+
+ cairo_surface_write_to_png(surface, sOutput.getStr());
+
+ if (surface != orig_surface)
+ cairo_surface_destroy(surface);
+
+ m_pCssProvider = gtk_css_provider_new();
+ OUString aBuffer = "* { background-image: url(\"" + mxBackgroundImage->GetURL() + "\"); }";
+ OString aResult = OUStringToOString(aBuffer, RTL_TEXTENCODING_UTF8);
+ gtk_css_provider_load_from_data(m_pCssProvider, aResult.getStr(), aResult.getLength(), nullptr);
+ gtk_style_context_add_provider(pStyleContext, GTK_STYLE_PROVIDER(m_pCssProvider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+ }
+
+ virtual ~GtkInstanceAboutDialog() override
+ {
+ set_background(nullptr);
+ }
+};
+
class GtkInstanceFrame : public GtkInstanceContainer, public virtual weld::Frame
{
private:
@@ -10057,6 +10197,24 @@ private:
set_primary_text(pMessageDialog, (*m_pStringReplace)(get_primary_text(pMessageDialog)));
set_secondary_text(pMessageDialog, (*m_pStringReplace)(get_secondary_text(pMessageDialog)));
}
+ else if (GTK_IS_ABOUT_DIALOG(pWindow))
+ {
+ GtkAboutDialog* pAboutDialog = GTK_ABOUT_DIALOG(pWindow);
+ const gchar *pComments = gtk_about_dialog_get_comments(pAboutDialog);
+ if (pComments)
+ {
+ OUString sComments(pComments, strlen(pComments), RTL_TEXTENCODING_UTF8);
+ sComments = (*m_pStringReplace)(sComments);
+ gtk_about_dialog_set_comments(pAboutDialog, OUStringToOString(sComments, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ const gchar *pProgramName = gtk_about_dialog_get_program_name(pAboutDialog);
+ if (pProgramName)
+ {
+ OUString sProgramName(pProgramName, strlen(pProgramName), RTL_TEXTENCODING_UTF8);
+ sProgramName = (*m_pStringReplace)(sProgramName);
+ gtk_about_dialog_set_program_name(pAboutDialog, OUStringToOString(sProgramName, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
}
}
}
@@ -10176,6 +10334,15 @@ public:
return std::make_unique<GtkInstanceMessageDialog>(pMessageDialog, this, bTakeOwnership);
}
+ virtual std::unique_ptr<weld::AboutDialog> weld_about_dialog(const OString &id, bool bTakeOwnership) override
+ {
+ GtkAboutDialog* pAboutDialog = GTK_ABOUT_DIALOG(gtk_builder_get_object(m_pBuilder, id.getStr()));
+ if (!pAboutDialog)
+ return nullptr;
+ gtk_window_set_transient_for(GTK_WINDOW(pAboutDialog), GTK_WINDOW(gtk_widget_get_toplevel(m_pParentWidget)));
+ return std::make_unique<GtkInstanceAboutDialog>(pAboutDialog, this, bTakeOwnership);
+ }
+
virtual std::unique_ptr<weld::Dialog> weld_dialog(const OString &id, bool bTakeOwnership) override
{
GtkDialog* pDialog = GTK_DIALOG(gtk_builder_get_object(m_pBuilder, id.getStr()));