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