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(TranslateId(nullptr, "%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
