1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
26 #include <osl/process.h> //osl_getProcessLocale
27 #include <rtl/bootstrap.hxx>
28 #include <sal/log.hxx> //SAL_WARN
29 #include <vcl/settings.hxx> //GetSettings
30 #include <vcl/svapp.hxx> //Application::
31 #include <vcl/virdev.hxx> //VirtualDevice
32 #include <vcl/weld.hxx>
33 #include <unotools/resmgr.hxx> //Translate
35 #include <config_buildid.h> //EXTRA_BUILDID
36 #include <config_features.h>
37 #include <dialmgr.hxx> //CuiResId
38 #include <i18nlangtag/languagetag.hxx>
39 #include <sfx2/app.hxx> //SfxApplication::loadBrandSvg
40 #include <strings.hrc>
41 #include <svtools/langhelp.hxx>
42 #include <unotools/bootstrap.hxx> //utl::Bootstrap::getBuildIdData
43 #include <unotools/configmgr.hxx> //ConfigManager::
45 #include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
46 #include <vcl/unohelp2.hxx>
48 #include <config_feature_opencl.h>
49 #if HAVE_FEATURE_OPENCL
50 #include <opencl/openclwrapper.hxx>
52 #include <officecfg/Office/Calc.hxx>
53 #include <officecfg/Office/Common.hxx>
55 using namespace ::com::sun::star::uno
;
57 AboutDialog::AboutDialog(weld::Window
*pParent
)
58 : GenericDialogController(pParent
, "cui/ui/aboutdialog.ui", "AboutDialog"),
59 m_pCreditsButton(m_xBuilder
->weld_link_button("btnCredits")),
60 m_pWebsiteButton(m_xBuilder
->weld_link_button("btnWebsite")),
61 m_pReleaseNotesButton(m_xBuilder
->weld_link_button("btnReleaseNotes")),
62 m_pCloseButton(m_xBuilder
->weld_button("btnClose")),
63 m_pCopyButton(m_xBuilder
->weld_button("btnCopyVersion")),
64 m_pBrandImage(m_xBuilder
->weld_image("imBrand")),
65 m_pAboutImage(m_xBuilder
->weld_image("imAbout")),
66 m_pVersionLabel(m_xBuilder
->weld_label("lbVersionString")),
67 m_pBuildCaption(m_xBuilder
->weld_label("lbBuild")),
68 m_pBuildLabel(m_xBuilder
->weld_link_button("lbBuildString")),
69 m_pEnvLabel(m_xBuilder
->weld_label("lbEnvString")),
70 m_pUILabel(m_xBuilder
->weld_label("lbUIString")),
71 m_pLocaleLabel(m_xBuilder
->weld_label("lbLocaleString")),
72 m_pMiscLabel(m_xBuilder
->weld_label("lbMiscString")),
73 m_pCopyrightLabel(m_xBuilder
->weld_label("lbCopyright")) {
76 m_pVersionLabel
->set_label(GetVersionString());
78 OUString sbuildId
= GetBuildString();
79 if (IsStringValidGitHash(sbuildId
)) {
80 const tools::Long nMaxChar
= 25;
81 m_pBuildLabel
->set_uri("https://gerrit.libreoffice.org/gitweb?p=core.git;a=log;h="
83 m_pBuildLabel
->set_label(sbuildId
.getLength() > nMaxChar
? sbuildId
.replaceAt(
84 nMaxChar
, sbuildId
.getLength() - nMaxChar
, u
"...")
87 m_pBuildCaption
->hide();
88 m_pBuildLabel
->hide();
91 m_pEnvLabel
->set_label(Application::GetHWOSConfInfo(1));
92 m_pUILabel
->set_label(Application::GetHWOSConfInfo(2));
93 m_pLocaleLabel
->set_label(GetLocaleString());
94 m_pMiscLabel
->set_label(GetMiscString());
95 m_pCopyrightLabel
->set_label(GetCopyrightString());
98 const tools::Long
nWidth(m_pCopyrightLabel
->get_preferred_size().getWidth());
99 BitmapEx aBackgroundBitmap
;
101 if (SfxApplication::loadBrandSvg(Application::GetSettings()
105 ? "shell/logo_inverted"
107 aBackgroundBitmap
, nWidth
* 0.8)) {
108 ScopedVclPtr
<VirtualDevice
> m_pVirDev
=
109 m_pBrandImage
->create_virtual_device();
110 m_pVirDev
->SetOutputSizePixel(aBackgroundBitmap
.GetSizePixel());
111 m_pVirDev
->DrawBitmapEx(Point(0, 0), aBackgroundBitmap
);
112 m_pBrandImage
->set_image(m_pVirDev
.get());
113 m_pVirDev
.disposeAndClear();
115 if (SfxApplication::loadBrandSvg("shell/about", aBackgroundBitmap
, nWidth
* 0.9)) {
116 ScopedVclPtr
<VirtualDevice
> m_pVirDev
=
117 m_pAboutImage
->create_virtual_device();
118 m_pVirDev
->SetOutputSizePixel(aBackgroundBitmap
.GetSizePixel());
119 m_pVirDev
->DrawBitmapEx(Point(0, 0), aBackgroundBitmap
);
120 m_pAboutImage
->set_image(m_pVirDev
.get());
121 m_pVirDev
.disposeAndClear();
125 m_pCreditsButton
->set_uri(officecfg::Office::Common::Menus::CreditsURL::get());
127 OUString
sURL(officecfg::Office::Common::Help::StartCenter::InfoURL::get());
128 localizeWebserviceURI(sURL
);
129 m_pWebsiteButton
->set_uri(sURL
);
131 // See also SID_WHATSNEW in sfx2/source/appl/appserv.cxx
132 sURL
= officecfg::Office::Common::Menus::ReleaseNotesURL::get() +
133 "?LOvers=" + utl::ConfigManager::getProductVersion() + "&LOlocale=" +
134 LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
135 m_pReleaseNotesButton
->set_uri(sURL
);
138 m_pCopyButton
->connect_clicked(LINK(this, AboutDialog
, HandleClick
));
139 m_pCloseButton
->grab_focus();
142 AboutDialog::~AboutDialog() {}
144 bool AboutDialog::IsStringValidGitHash(std::u16string_view hash
) {
145 return std::all_of(hash
.begin(), hash
.end(),
146 [](auto &rSymbol
) { return std::isxdigit(rSymbol
); });
149 OUString
AboutDialog::GetVersionString() {
151 auto const ok
= rtl::Bootstrap::get("_ARCH", arch
);
152 assert(ok
); (void) ok
;
153 OUString sVersion
= CuiResId(TranslateId(nullptr, "%ABOUTBOXPRODUCTVERSION%ABOUTBOXPRODUCTVERSIONSUFFIX")) + " (" + arch
+ ")";
155 #if HAVE_FEATURE_COMMUNITY_FLAVOR
156 sVersion
+= " / LibreOffice Community";
162 OUString
AboutDialog::GetBuildString()
164 OUString
sBuildId(utl::Bootstrap::getBuildIdData(""));
165 SAL_WARN_IF(sBuildId
.isEmpty(), "cui.dialogs", "No BUILDID in bootstrap file");
170 OUString
AboutDialog::GetLocaleString(const bool bLocalized
) {
175 osl_getProcessLocale(&pLocale
);
176 if (pLocale
&& pLocale
->Language
) {
177 if (pLocale
->Country
&& rtl_uString_getLength(pLocale
->Country
) > 0)
178 sLocaleStr
= OUString::unacquired(&pLocale
->Language
) + "_" +
179 OUString::unacquired(&pLocale
->Country
);
181 sLocaleStr
= OUString(pLocale
->Language
);
182 if (pLocale
->Variant
&& rtl_uString_getLength(pLocale
->Variant
) > 0)
183 sLocaleStr
+= OUString(pLocale
->Variant
);
186 sLocaleStr
= Application::GetSettings().GetLanguageTag().getBcp47() + " (" +
189 OUString aUILocaleStr
=
190 Application::GetSettings().GetUILanguageTag().getBcp47();
191 OUString sUILocaleStr
;
193 sUILocaleStr
= CuiResId(RID_CUISTR_ABOUT_UILOCALE
);
195 sUILocaleStr
= Translate::get(RID_CUISTR_ABOUT_UILOCALE
, Translate::Create("cui", LanguageTag("en-US")));
197 if (sUILocaleStr
.indexOf("$LOCALE") == -1) {
198 SAL_WARN("cui.dialogs", "translated uilocale string in translations "
199 "doesn't contain $LOCALE placeholder");
200 sUILocaleStr
+= " $LOCALE";
202 sUILocaleStr
= sUILocaleStr
.replaceAll("$LOCALE", aUILocaleStr
);
204 return sLocaleStr
+ "; " + sUILocaleStr
;
207 OUString
AboutDialog::GetMiscString() {
211 bool const extra
= EXTRA_BUILDID
[0] != '\0';
212 // extracted from the 'if' to avoid Clang -Wunreachable-code
214 sMisc
= EXTRA_BUILDID
"\n";
217 OUString aCalcMode
; // Calc calculation mode
219 #if HAVE_FEATURE_OPENCL
220 if (openclwrapper::GPUEnv::isOpenCLEnabled())
224 static const bool bThreadingProhibited
=
225 std::getenv("SC_NO_THREADED_CALCULATION");
226 bool bThreadedCalc
= officecfg::Office::Calc::Formula::Calculation::
227 UseThreadedCalculationForFormulaGroups::get();
229 if (!bThreadingProhibited
&& bThreadedCalc
) {
230 aCalcMode
+= " threaded";
233 if (officecfg::Office::Calc::Defaults::Sheet::JumboSheets::get())
235 aCalcMode
+= " Jumbo";
238 if (aCalcMode
.isEmpty())
239 aCalcMode
= " default";
240 sMisc
+= "Calc:" + aCalcMode
;
245 OUString
AboutDialog::GetCopyrightString() {
246 OUString
sVendorTextStr(CuiResId(RID_CUISTR_ABOUT_VENDOR
));
247 OUString aCopyrightString
=
248 sVendorTextStr
+ "\n" + CuiResId(RID_CUISTR_ABOUT_COPYRIGHT
) + "\n";
250 if (utl::ConfigManager::getProductName() == "LibreOffice")
251 aCopyrightString
+= CuiResId(RID_CUISTR_ABOUT_BASED_ON
);
253 aCopyrightString
+= CuiResId(RID_CUISTR_ABOUT_DERIVED
);
255 return aCopyrightString
;
258 // special labels to comply with previous version info
259 // untranslated English for QA
260 IMPL_LINK_NOARG(AboutDialog
, HandleClick
, weld::Button
&, void) {
261 css::uno::Reference
<css::datatransfer::clipboard::XClipboard
> xClipboard
=
262 css::datatransfer::clipboard::SystemClipboard::create(
263 comphelper::getProcessComponentContext());
265 OUString sInfo
= "Version: " + m_pVersionLabel
->get_label() + "\n" // version
266 "Build ID: " + GetBuildString() + "\n" + // build id
267 Application::GetHWOSConfInfo(0,false) + "\n" // env+UI
268 "Locale: " + GetLocaleString(false) + "\n" + // locale
269 GetMiscString(); // misc
271 vcl::unohelper::TextDataObject::CopyStringTo(sInfo
, xClipboard
);
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */