xref: /core/cui/source/dialogs/about.cxx (revision 427deae2)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <about.hxx>
21 
22 #include <osl/process.h>     //osl_getProcessLocale
23 #include <sal/log.hxx>       //SAL_WARN
24 #include <vcl/settings.hxx>  //GetSettings
25 #include <vcl/svapp.hxx>     //Application::
26 #include <vcl/virdev.hxx>    //VirtualDevice
27 #include <vcl/weld.hxx>
28 #include <unotools/resmgr.hxx> //Translate
29 
30 #include <config_buildid.h> //EXTRA_BUILDID
31 #include <config_features.h>
32 #include <dialmgr.hxx>      //CuiResId
33 #include <i18nlangtag/languagetag.hxx>
34 #include <sfx2/app.hxx> //SfxApplication::loadBrandSvg
35 #include <strings.hrc>
36 #include <svtools/langhelp.hxx>
37 #include <unotools/bootstrap.hxx> //utl::Bootstrap::getBuildIdData
38 #include <unotools/configmgr.hxx> //ConfigManager::
39 
40 #include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
41 #include <vcl/unohelp2.hxx>
42 
43 #include <config_feature_opencl.h>
44 #if HAVE_FEATURE_OPENCL
45 #include <opencl/openclwrapper.hxx>
46 #endif
47 #include <officecfg/Office/Calc.hxx>
48 #include <officecfg/Office/Common.hxx>
49 
50 using namespace ::com::sun::star::uno;
51 
52 AboutDialog::AboutDialog(weld::Window *pParent)
53     : GenericDialogController(pParent, "cui/ui/aboutdialog.ui", "AboutDialog"),
54       m_pCreditsButton(m_xBuilder->weld_link_button("btnCredits")),
55       m_pWebsiteButton(m_xBuilder->weld_link_button("btnWebsite")),
56       m_pReleaseNotesButton(m_xBuilder->weld_link_button("btnReleaseNotes")),
57       m_pCloseButton(m_xBuilder->weld_button("btnClose")),
58       m_pCopyButton(m_xBuilder->weld_button("btnCopyVersion")),
59       m_pBrandImage(m_xBuilder->weld_image("imBrand")),
60       m_pAboutImage(m_xBuilder->weld_image("imAbout")),
61       m_pVersionLabel(m_xBuilder->weld_label("lbVersionString")),
62       m_pBuildCaption(m_xBuilder->weld_label("lbBuild")),
63       m_pBuildLabel(m_xBuilder->weld_link_button("lbBuildString")),
64       m_pEnvLabel(m_xBuilder->weld_label("lbEnvString")),
65       m_pUILabel(m_xBuilder->weld_label("lbUIString")),
66       m_pLocaleLabel(m_xBuilder->weld_label("lbLocaleString")),
67       m_pMiscLabel(m_xBuilder->weld_label("lbMiscString")),
68       m_pCopyrightLabel(m_xBuilder->weld_label("lbCopyright")) {
69 
70   // Labels
71   m_pVersionLabel->set_label(GetVersionString());
72 
73   OUString sbuildId = GetBuildString();
74   if (IsStringValidGitHash(sbuildId)) {
75     const tools::Long nMaxChar = 25;
76     m_pBuildLabel->set_uri("https://gerrit.libreoffice.org/gitweb?p=core.git;a=log;h="
77                            + sbuildId);
78     m_pBuildLabel->set_label(sbuildId.getLength() > nMaxChar ? sbuildId.replaceAt(
79                                  nMaxChar, sbuildId.getLength() - nMaxChar, "...")
80                                                              : sbuildId);
81   } else {
82     m_pBuildCaption->hide();
83     m_pBuildLabel->hide();
84   }
85 
86   m_pEnvLabel->set_label(Application::GetHWOSConfInfo(1));
87   m_pUILabel->set_label(Application::GetHWOSConfInfo(2));
88   m_pLocaleLabel->set_label(GetLocaleString());
89   m_pMiscLabel->set_label(GetMiscString());
90   m_pCopyrightLabel->set_label(GetCopyrightString());
91 
92   // Images
93   const tools::Long nWidth(m_pCopyrightLabel->get_preferred_size().getWidth());
94   BitmapEx aBackgroundBitmap;
95 
96   if (SfxApplication::loadBrandSvg(Application::GetSettings()
97                                            .GetStyleSettings()
98                                            .GetDialogColor()
99                                            .IsDark()
100                                        ? "shell/logo_inverted"
101                                        : "shell/logo",
102                                    aBackgroundBitmap, nWidth * 0.8)) {
103     ScopedVclPtr<VirtualDevice> m_pVirDev =
104         m_pBrandImage->create_virtual_device();
105     m_pVirDev->SetOutputSizePixel(aBackgroundBitmap.GetSizePixel());
106     m_pVirDev->DrawBitmapEx(Point(0, 0), aBackgroundBitmap);
107     m_pBrandImage->set_image(m_pVirDev.get());
108     m_pVirDev.disposeAndClear();
109   }
110   if (SfxApplication::loadBrandSvg("shell/about", aBackgroundBitmap, nWidth * 0.9)) {
111     ScopedVclPtr<VirtualDevice> m_pVirDev =
112         m_pAboutImage->create_virtual_device();
113     m_pVirDev->SetOutputSizePixel(aBackgroundBitmap.GetSizePixel());
114     m_pVirDev->DrawBitmapEx(Point(0, 0), aBackgroundBitmap);
115     m_pAboutImage->set_image(m_pVirDev.get());
116     m_pVirDev.disposeAndClear();
117   }
118 
119   // Links
120   m_pCreditsButton->set_uri(CuiResId(RID_SVXSTR_ABOUT_CREDITS_URL));
121 
122   OUString sURL(officecfg::Office::Common::Help::StartCenter::InfoURL::get());
123   localizeWebserviceURI(sURL);
124   m_pWebsiteButton->set_uri(sURL);
125 
126   // See also SID_WHATSNEW in sfx2/source/appl/appserv.cxx
127   sURL = officecfg::Office::Common::Menus::ReleaseNotesURL::get() +
128          "?LOvers=" + utl::ConfigManager::getProductVersion() + "&LOlocale=" +
129          LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
130   m_pReleaseNotesButton->set_uri(sURL);
131 
132   // Handler
133   m_pCopyButton->connect_clicked(LINK(this, AboutDialog, HandleClick));
134   m_pCloseButton->grab_focus();
135 }
136 
137 AboutDialog::~AboutDialog() {}
138 
139 bool AboutDialog::IsStringValidGitHash(const OUString &hash) {
140   for (int i = 0; i < hash.getLength(); i++) {
141     if (!std::isxdigit(hash[i])) {
142       return false;
143     }
144   }
145   return true;
146 }
147 
148 OUString AboutDialog::GetVersionString() {
149   OUString sVersion = CuiResId("%ABOUTBOXPRODUCTVERSION%ABOUTBOXPRODUCTVERSIONSUFFIX");
150 
151 #ifdef _WIN64
152   sVersion += " (x64)";
153 #elif defined(_WIN32)
154   sVersion += " (x86)";
155 #endif
156 
157 #if HAVE_FEATURE_COMMUNITY_FLAVOR
158   sVersion += " / LibreOffice Community";
159 #endif
160 
161   return sVersion;
162 }
163 
164 OUString AboutDialog::GetBuildString()
165 {
166   OUString sBuildId(utl::Bootstrap::getBuildIdData(""));
167   SAL_WARN_IF(sBuildId.isEmpty(), "cui.dialogs", "No BUILDID in bootstrap file");
168 
169   return sBuildId;
170 }
171 
172 OUString AboutDialog::GetLocaleString(const bool bLocalized) {
173 
174   OUString sLocaleStr;
175 
176   rtl_Locale *pLocale;
177   osl_getProcessLocale(&pLocale);
178   if (pLocale && pLocale->Language) {
179     if (pLocale->Country && rtl_uString_getLength(pLocale->Country) > 0)
180       sLocaleStr = OUString::unacquired(&pLocale->Language) + "_" +
181                    OUString::unacquired(&pLocale->Country);
182     else
183       sLocaleStr = OUString(pLocale->Language);
184     if (pLocale->Variant && rtl_uString_getLength(pLocale->Variant) > 0)
185       sLocaleStr += OUString(pLocale->Variant);
186   }
187 
188   sLocaleStr = Application::GetSettings().GetLanguageTag().getBcp47() + " (" +
189                sLocaleStr + ")";
190 
191   OUString aUILocaleStr =
192       Application::GetSettings().GetUILanguageTag().getBcp47();
193   OUString sUILocaleStr;
194   if (bLocalized)
195      sUILocaleStr = CuiResId(RID_SVXSTR_ABOUT_UILOCALE);
196   else
197      sUILocaleStr = Translate::get(RID_SVXSTR_ABOUT_UILOCALE, Translate::Create("cui", LanguageTag("en-US")));
198 
199   if (sUILocaleStr.indexOf("$LOCALE") == -1) {
200     SAL_WARN("cui.dialogs", "translated uilocale string in translations "
201                             "doesn't contain $LOCALE placeholder");
202     sUILocaleStr += " $LOCALE";
203   }
204   sUILocaleStr = sUILocaleStr.replaceAll("$LOCALE", aUILocaleStr);
205 
206   return sLocaleStr + "; " + sUILocaleStr;
207 }
208 
209 OUString AboutDialog::GetMiscString() {
210 
211   OUString sMisc;
212 
213   bool const extra = EXTRA_BUILDID[0] != '\0';
214   // extracted from the 'if' to avoid Clang -Wunreachable-code
215   if (extra) {
216     sMisc = EXTRA_BUILDID "\n";
217   }
218 
219   OUString aCalcMode = "Calc: "; // Calc calculation mode
220 
221 #if HAVE_FEATURE_OPENCL
222   bool bOpenCL = openclwrapper::GPUEnv::isOpenCLEnabled();
223   if (bOpenCL)
224     aCalcMode += "CL";
225 #else
226   const bool bOpenCL = false;
227 #endif
228 
229   static const bool bThreadingProhibited =
230       std::getenv("SC_NO_THREADED_CALCULATION");
231   bool bThreadedCalc = officecfg::Office::Calc::Formula::Calculation::
232       UseThreadedCalculationForFormulaGroups::get();
233 
234   if (!bThreadingProhibited && !bOpenCL && bThreadedCalc) {
235     if (!aCalcMode.endsWith(" "))
236       aCalcMode += " ";
237     aCalcMode += "threaded";
238   }
239 
240   if (officecfg::Office::Calc::Defaults::Sheet::JumboSheets::get())
241   {
242     if (!aCalcMode.endsWith(" "))
243       aCalcMode += " ";
244     aCalcMode += "Jumbo";
245   }
246   sMisc += aCalcMode;
247 
248   return sMisc;
249 }
250 
251 OUString AboutDialog::GetCopyrightString() {
252   OUString sVendorTextStr(CuiResId(RID_SVXSTR_ABOUT_VENDOR));
253   OUString aCopyrightString =
254       sVendorTextStr + "\n" + CuiResId(RID_SVXSTR_ABOUT_COPYRIGHT) + "\n";
255 
256   if (utl::ConfigManager::getProductName() == "LibreOffice")
257     aCopyrightString += CuiResId(RID_SVXSTR_ABOUT_BASED_ON);
258   else
259     aCopyrightString += CuiResId(RID_SVXSTR_ABOUT_DERIVED);
260 
261   return aCopyrightString;
262 }
263 
264 // special labels to comply with previous version info
265 // untranslated English for QA
266 IMPL_LINK_NOARG(AboutDialog, HandleClick, weld::Button &, void) {
267   css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard =
268       css::datatransfer::clipboard::SystemClipboard::create(
269           comphelper::getProcessComponentContext());
270 
271   OUString sInfo = "Version: " + m_pVersionLabel->get_label() + "\n" // version
272                    "Build ID: " + GetBuildString() + "\n" + // build id
273                    Application::GetHWOSConfInfo(0,false) + "\n" // env+UI
274                    "Locale: " + GetLocaleString(false) + "\n" + // locale
275                    GetMiscString(); // misc
276 
277   vcl::unohelper::TextDataObject::CopyStringTo(sInfo, xClipboard);
278 }
279 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
280