LibreOffice Module cui (master)  1
about.cxx
Go to the documentation of this file.
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 <config_feature_opencl.h>
21 #include <osl/process.h>
22 #include <sal/log.hxx>
23 #include <osl/diagnose.h>
24 #include <rtl/character.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/stdtext.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/virdev.hxx>
30 #include <vcl/weld.hxx>
31 
32 #include <unotools/configmgr.hxx>
33 #include <unotools/bootstrap.hxx>
34 #include <com/sun/star/uno/Any.h>
35 #include <svtools/langhelp.hxx>
37 
38 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
39 #include <com/sun/star/system/SystemShellExecute.hpp>
42 #include <cppuhelper/exc_hlp.hxx>
44 
45 #include <about.hxx>
46 #include <dialmgr.hxx>
47 #include <strings.hrc>
48 #include <config_buildid.h>
49 #include <sfx2/app.hxx>
50 
51 #if HAVE_FEATURE_OPENCL
52 #include <opencl/openclwrapper.hxx>
53 #endif
54 #include <officecfg/Office/Common.hxx>
55 #include <officecfg/Office/Calc.hxx>
56 
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::beans;
59 using namespace ::com::sun::star;
60 
62  : m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/aboutdialog.ui"))
63  , m_xDialog(m_xBuilder->weld_about_dialog("AboutDialog"))
64  , m_xContentArea(m_xDialog->weld_content_area())
65 {
66  m_xDialog->add_button(GetStandardText(StandardButtonType::Close), RET_CLOSE);
67  m_xDialog->add_button(CuiResId(RID_SVXSTR_ABOUT_CREDITS), 101);
68  m_xDialog->add_button(CuiResId(RID_SVXSTR_ABOUT_WEBSITE), 102);
69  m_xDialog->add_button(CuiResId(RID_SVXSTR_ABOUT_RELEASE_NOTES), 103);
70 
71  m_xCreditsButton.reset(m_xDialog->weld_widget_for_response(101));
72  m_xCreditsButton->set_secondary(true);
73  m_xWebsiteButton.reset(m_xDialog->weld_widget_for_response(102));
74  m_xWebsiteButton->set_secondary(true);
75  m_xReleaseNotesButton.reset(m_xDialog->weld_widget_for_response(103));
76  m_xReleaseNotesButton->set_secondary(true);
77  m_xCloseButton.reset(m_xDialog->weld_widget_for_response(RET_CLOSE));
78 
79  m_buildIdLinkString = m_xDialog->get_website_label();
80 
81  m_xDialog->set_version(GetVersionString());
82  m_xDialog->set_copyright(GetCopyrightString());
83 
85 
86  SetLogo();
87 
88  m_xDialog->connect_size_allocate(LINK(this, AboutDialog, SizeAllocHdl));
89 
90  // Connect all handlers
91  m_xCreditsButton->connect_clicked( LINK( this, AboutDialog, HandleClick ) );
92  m_xWebsiteButton->connect_clicked( LINK( this, AboutDialog, HandleClick ) );
93  m_xReleaseNotesButton->connect_clicked( LINK( this, AboutDialog, HandleClick ) );
94  m_xCloseButton->grab_focus();
95 }
96 
98 {
99 }
100 
101 IMPL_LINK(AboutDialog, HandleClick, weld::Button&, rButton, void)
102 {
103  OUString sURL = "";
104 
105  // Find which button was pressed and from this, get the URL to be opened
106  if (&rButton == m_xCreditsButton.get())
107  sURL = CuiResId(RID_SVXSTR_ABOUT_CREDITS_URL);
108  else if (&rButton == m_xWebsiteButton.get())
109  {
110  sURL = officecfg::Office::Common::Help::StartCenter::InfoURL::get();
111  localizeWebserviceURI(sURL);
112  }
113  else if (&rButton == m_xReleaseNotesButton.get())
114  {
115  sURL = officecfg::Office::Common::Menus::ReleaseNotesURL::get() +
118  }
119 
120  // If the URL is empty, don't do anything
121  if ( sURL.isEmpty() )
122  return;
123  try
124  {
125  Reference< css::system::XSystemShellExecute > xSystemShellExecute(
126  css::system::SystemShellExecute::create(::comphelper::getProcessComponentContext() ) );
127  xSystemShellExecute->execute( sURL, OUString(), css::system::SystemShellExecuteFlags::URIS_ONLY );
128  }
129  catch (const Exception&)
130  {
131  Any exc( ::cppu::getCaughtException() );
132  OUString msg( ::comphelper::anyToString( exc ) );
133  const SolarMutexGuard guard;
134  std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(getDialog(),
135  VclMessageType::Warning, VclButtonsType::Ok, msg));
136  xErrorBox->set_title(m_xDialog->get_title());
137  xErrorBox->run();
138  }
139 }
140 
142 {
143  const OUString buildId = GetBuildId();
144 
145  if (IsStringValidGitHash(buildId))
146  {
147  if (m_buildIdLinkString.indexOf("$GITHASH") == -1)
148  {
149  SAL_WARN( "cui.dialogs", "translated git hash string in translations doesn't contain $GITHASH placeholder" );
150  m_buildIdLinkString += " $GITHASH";
151  }
152 
153  m_xDialog->set_website_label(m_buildIdLinkString.replaceAll("$GITHASH", buildId));
154  m_xDialog->set_website("https://hub.libreoffice.org/git-core/" + buildId);
155  }
156  else
157  {
158  m_xDialog->set_website_label(OUString());
159  m_xDialog->set_website(OUString());
160  }
161 }
162 
164 {
165  auto nWidth = m_xContentArea->get_preferred_size().Width();
166 
167  // fdo#67401 set AntiAliasing for SVG logo
168  SvtOptionsDrawinglayer aDrawOpt;
169  bool bOldAntiAliasSetting = aDrawOpt.IsAntiAliasing();
170  aDrawOpt.SetAntiAliasing(true);
171 
172  // load svg logo, specify desired width, scale height isotropically
173  SfxApplication::loadBrandSvg("flat_logo", aLogoBitmap, nWidth);
174 
175  aDrawOpt.SetAntiAliasing(bOldAntiAliasSetting);
176 
177  if (!aLogoBitmap)
178  m_xDialog->set_logo(nullptr);
179  else
180  {
181  Graphic aGraphic(aLogoBitmap);
182  m_xDialog->set_logo(aGraphic.GetXGraphic());
183  }
184 }
185 
186 IMPL_LINK(AboutDialog, SizeAllocHdl, const Size&, rSize, void)
187 {
188  if (rSize.Width() == aBackgroundBitmap.GetSizePixel().Width())
189  return;
190  // Load background image
191  if (!(Application::GetSettings().GetStyleSettings().GetHighContrastMode()))
192  {
193  SfxApplication::loadBrandSvg("shell/about", aBackgroundBitmap, rSize.Width());
194  Graphic aGraphic(aBackgroundBitmap);
195  m_xDialog->set_background(aGraphic.GetXGraphic());
196  }
197 }
198 
200 {
201  OUString sDefault;
202  OUString sBuildId(utl::Bootstrap::getBuildVersion(sDefault));
203  if (!sBuildId.isEmpty())
204  return sBuildId;
205 
206  sBuildId = utl::Bootstrap::getBuildIdData(sDefault);
207 
208  if (!sBuildId.isEmpty())
209  {
210  return sBuildId.getToken( 0, '-' );
211  }
212 
213  OSL_ENSURE( !sBuildId.isEmpty(), "No BUILDID in bootstrap file" );
214  return sBuildId;
215 }
216 
218 {
219  OUString aLocaleStr;
220  rtl_Locale * pLocale;
221 
222  osl_getProcessLocale( &pLocale );
223 
224  if ( pLocale && pLocale->Language )
225  {
226  if (pLocale->Country && rtl_uString_getLength( pLocale->Country) > 0)
227  aLocaleStr = OUString::unacquired(&pLocale->Language) + "_" + OUString::unacquired(&pLocale->Country);
228  else
229  aLocaleStr = OUString(pLocale->Language);
230  if (pLocale->Variant && rtl_uString_getLength( pLocale->Variant) > 0)
231  aLocaleStr += OUString(pLocale->Variant);
232  }
233 
234  return aLocaleStr;
235 }
236 
237 bool AboutDialog::IsStringValidGitHash(const OUString& hash)
238 {
239  for (int i = 0; i < hash.getLength(); i++)
240  {
241  if (!rtl::isAsciiHexDigit(hash[i]))
242  {
243  return false;
244  }
245  }
246 
247  return true;
248 }
249 
251 {
252  OUString sVersion = CuiResId(RID_SVXSTR_ABOUT_VERSION);
253 
254 #ifdef _WIN64
255  sVersion += " (x64)";
256 #elif defined(_WIN32)
257  sVersion += " (x86)";
258 #endif
259 
260  OUString sBuildId = GetBuildId();
261 
262  OUString aLocaleStr = Application::GetSettings().GetLanguageTag().getBcp47() + " (" + GetLocaleString() + ")";
263  OUString aUILocaleStr = Application::GetSettings().GetUILanguageTag().getBcp47();
264 
265  if (!sBuildId.trim().isEmpty())
266  {
267  sVersion += "\n";
268  OUString sBuildStr = CuiResId(RID_SVXSTR_ABOUT_BUILDID);
269  if (sBuildStr.indexOf("$BUILDID") == -1)
270  {
271  SAL_WARN( "cui.dialogs", "translated Build Id string in translations doesn't contain $BUILDID placeholder" );
272  sBuildStr += " $BUILDID";
273  }
274  sVersion += sBuildStr.replaceAll("$BUILDID", sBuildId);
275  }
276 
277  sVersion += "\n" + Application::GetHWOSConfInfo();
278 
279  bool const extra = EXTRA_BUILDID[0] != '\0';
280  // extracted from the 'if' to avoid Clang -Wunreachable-code
281  if (extra)
282  {
283  sVersion += "\n" EXTRA_BUILDID;
284  }
285 
286  OUString sLocaleStr(CuiResId(RID_SVXSTR_ABOUT_LOCALE));
287  if (sLocaleStr.indexOf("$LOCALE") == -1)
288  {
289  SAL_WARN( "cui.dialogs", "translated locale string in translations doesn't contain $LOCALE placeholder" );
290  sLocaleStr += " $LOCALE";
291  }
292  sVersion += "\n" + sLocaleStr.replaceAll("$LOCALE", aLocaleStr);
293 
294  OUString sUILocaleStr(CuiResId(RID_SVXSTR_ABOUT_UILOCALE));
295  if (sUILocaleStr.indexOf("$LOCALE") == -1)
296  {
297  SAL_WARN( "cui.dialogs", "translated uilocale string in translations doesn't contain $LOCALE placeholder" );
298  sUILocaleStr += " $LOCALE";
299  }
300  sVersion += "; " + sUILocaleStr.replaceAll("$LOCALE", aUILocaleStr);
301 
302  OUString aCalcMode = "Calc: "; // Calc calculation mode
303 
304 #if HAVE_FEATURE_OPENCL
306  if (bOpenCL)
307  aCalcMode += "CL";
308 #else
309  const bool bOpenCL = false;
310 #endif
311 
312  static const bool bThreadingProhibited = std::getenv("SC_NO_THREADED_CALCULATION");
313  bool bThreadedCalc = officecfg::Office::Calc::Formula::Calculation::UseThreadedCalculationForFormulaGroups::get();
314 
315  if (!bThreadingProhibited && !bOpenCL && bThreadedCalc)
316  {
317  if (!aCalcMode.endsWith(" "))
318  aCalcMode += " ";
319  aCalcMode += "threaded";
320  }
321 
322  sVersion += "\n" + aCalcMode;
323 
324  return sVersion;
325 }
326 
328 {
329  OUString sVendorTextStr(CuiResId(RID_SVXSTR_ABOUT_VENDOR));
330  OUString aCopyrightString = sVendorTextStr + "\n"
331  + CuiResId(RID_SVXSTR_ABOUT_COPYRIGHT) + "\n";
332 
333  if (utl::ConfigManager::getProductName() == "LibreOffice")
334  aCopyrightString += CuiResId(RID_SVXSTR_ABOUT_BASED_ON);
335  else
336  aCopyrightString += CuiResId(RID_SVXSTR_ABOUT_DERIVED);
337 
338  return aCopyrightString;
339 }
340 
341 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool isOpenCLEnabled()
AboutDialog(weld::Window *pParent)
Definition: about.cxx:61
const char * pLocale
static OUString GetHWOSConfInfo()
static bool IsStringValidGitHash(const OUString &hash)
Definition: about.cxx:237
const LanguageTag & GetUILanguageTag() const
OUString GetStandardText(StandardButtonType eButton)
static OUString getBuildVersion(OUString const &_sDefault)
static const AllSettings & GetSettings()
const OUString & getBcp47(bool bResolveSystem=true) const
std::unique_ptr< weld::Button > m_xWebsiteButton
Definition: about.hxx:32
std::unique_ptr< weld::Button > m_xCloseButton
Definition: about.hxx:34
void SetLogo()
Definition: about.cxx:163
void localizeWebserviceURI(OUString &rURI)
css::uno::Reference< css::graphic::XGraphic > GetXGraphic() const
BitmapEx aLogoBitmap
Definition: about.hxx:36
std::unique_ptr< weld::Button > m_xReleaseNotesButton
Definition: about.hxx:33
OUString getLanguage() const
Any SAL_CALL getCaughtException()
void SetAntiAliasing(bool bState)
static OUString getProductVersion()
const LanguageTag & GetLanguageTag() const
static OUString getProductName()
int i
static OUString GetCopyrightString()
Definition: about.cxx:327
IMPL_LINK(AboutDialog, HandleClick, weld::Button &, rButton, void)
Definition: about.cxx:101
static OUString getUILocale()
static OUString GetVersionString()
Definition: about.cxx:250
OUString CuiResId(const char *pKey)
Definition: cuiresmgr.cxx:23
static bool loadBrandSvg(const char *pName, BitmapEx &rBitmap, int nWidth)
RET_CLOSE
std::unique_ptr< weld::Button > m_xCreditsButton
Definition: about.hxx:31
void SetBuildIdLink()
Definition: about.cxx:141
static OUString GetLocaleString()
Definition: about.cxx:217
Reference< XComponentContext > getProcessComponentContext()
static OUString GetBuildId()
Definition: about.cxx:199
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage)
bool IsAntiAliasing() const
#define SAL_WARN(area, stream)
OUString m_buildIdLinkString
Definition: about.hxx:39
std::shared_ptr< weld::AboutDialog > m_xDialog
Definition: about.hxx:29
std::unique_ptr< weld::Container > m_xContentArea
Definition: about.hxx:30
static OUString getBuildIdData(OUString const &_sDefault)
virtual ~AboutDialog() override
Definition: about.cxx:97
OUString anyToString(uno::Any const &value)