LibreOffice Module svtools (master) 1
langhelp.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
10#include <sal/config.h>
11
12#include <string_view>
13
17#include <officecfg/Office/Common.hxx>
18#include <officecfg/System.hxx>
19#include <o3tl/string_view.hxx>
20#include <org/freedesktop/PackageKit/SyncDbusSessionHelper.hpp>
21#include <rtl/ustring.hxx>
22#include <svtools/langhelp.hxx>
24#include <vcl/idle.hxx>
25#include <vcl/svapp.hxx>
26#include <vcl/settings.hxx>
27#include <config_langs.h>
28#include <config_vendor.h>
29
30void localizeWebserviceURI( OUString& rURI )
31{
33 if ( aLang.equalsIgnoreAsciiCase("pt")
34 && Application::GetSettings().GetUILanguageTag().getCountry().equalsIgnoreAsciiCase("br") )
35 {
36 aLang = "pt-br";
37 }
38 if ( aLang.equalsIgnoreAsciiCase("zh") )
39 {
40 if ( Application::GetSettings().GetUILanguageTag().getCountry().equalsIgnoreAsciiCase("cn") )
41 aLang = "zh-cn";
42 if ( Application::GetSettings().GetUILanguageTag().getCountry().equalsIgnoreAsciiCase("tw") )
43 aLang = "zh-tw";
44 }
45
46 rURI += aLang;
47}
48
49OUString getInstalledLocaleForLanguage(css::uno::Sequence<OUString> const & installed, OUString const & locale)
50{
51 if (locale.isEmpty())
52 return OUString(); // do not attempt to resolve anything
53
54 if (comphelper::findValue(installed, locale) != -1)
55 return locale;
56
57 std::vector<OUString> fallbacks(LanguageTag(locale).getFallbackStrings(false));
58 auto pf = std::find_if(fallbacks.begin(), fallbacks.end(),
59 [&installed](const OUString& rf) { return comphelper::findValue(installed, rf) != -1; });
60 if (pf != fallbacks.end())
61 return *pf;
62 return OUString();
63}
64
65static std::unique_ptr<Idle> xLangpackInstaller;
66
67namespace {
68
69class InstallLangpack : public Idle
70{
71 std::vector<OUString> m_aPackages;
72public:
73 explicit InstallLangpack(std::vector<OUString>&& rPackages)
74 : Idle("install langpack")
75 , m_aPackages(std::move(rPackages))
76 {
77 SetPriority(TaskPriority::LOWEST);
78 }
79
80 virtual void Invoke() override
81 {
83 if (!pTopWindow)
85 if (!pTopWindow)
86 {
87 Start();
88 return;
89 }
90 try
91 {
92 using namespace org::freedesktop::PackageKit;
93 css::uno::Reference<XSyncDbusSessionHelper> xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext()));
94 xSyncDbusSessionHelper->InstallPackageNames(comphelper::containerToSequence(m_aPackages), OUString());
95 }
96 catch (const css::uno::Exception&)
97 {
98 TOOLS_INFO_EXCEPTION("svl", "trying to install a LibreOffice langpack");
99 }
100 xLangpackInstaller.reset();
101 }
102};
103
104}
105
106OUString getInstalledLocaleForSystemUILanguage(const css::uno::Sequence<OUString>& rLocaleElementNames, bool bRequestInstallIfMissing, const OUString& rPreferredLocale)
107{
108 OUString wantedLocale(rPreferredLocale);
109 if (wantedLocale.isEmpty())
110 wantedLocale = officecfg::System::L10N::UILocale::get();
111
112 OUString locale = getInstalledLocaleForLanguage(rLocaleElementNames, wantedLocale);
113 if (bRequestInstallIfMissing && locale.isEmpty() && !wantedLocale.isEmpty() && !Application::IsHeadlessModeEnabled() &&
114 officecfg::Office::Common::PackageKit::EnableLangpackInstallation::get())
115 {
116 LanguageTag aWantedTag(wantedLocale);
117 if (aWantedTag.getLanguage() != "en")
118 {
119 // Get the list of langpacks that this build was configured to include
120 std::vector<OUString> aPackages;
121 static constexpr std::u16string_view sAvailableLocales(u"" WITH_LANG);
122 std::vector<OUString> aAvailable;
123 sal_Int32 nIndex = 0;
124 do
125 {
126 aAvailable.emplace_back(o3tl::getToken(sAvailableLocales, 0, ' ', nIndex));
127 }
128 while (nIndex >= 0);
129 // See which one matches the desired ui locale
130 OUString install = getInstalledLocaleForLanguage(comphelper::containerToSequence(aAvailable), wantedLocale);
131 if (!install.isEmpty() && install != "en-US")
132 {
133 std::string_view sVendor(OOO_VENDOR);
134 if (sVendor == "Red Hat, Inc." || sVendor == "The Fedora Project")
135 {
136 // langpack is the typical Fedora/RHEL naming convention
137 LanguageType eType = aWantedTag.getLanguageType();
139 aPackages.emplace_back("libreoffice-langpack-zh-Hans");
141 aPackages.emplace_back("libreoffice-langpack-zh-Hant");
142 else if (install == "pt")
143 aPackages.emplace_back("libreoffice-langpack-pt-PT");
144 else
145 aPackages.emplace_back("libreoffice-langpack-" + install);
146 }
147 else if (sVendor == "The Document Foundation/Debian" || sVendor == "The Document Foundation, Debian and Ubuntu")
148 {
149 // l10n is the typical Debian/Ubuntu naming convention
150 aPackages.emplace_back("libreoffice-l10n-" + install);
151 }
152 }
153 if (!aPackages.empty())
154 {
155 xLangpackInstaller.reset(new InstallLangpack(std::move(aPackages)));
156 xLangpackInstaller->Start();
157 }
158 }
159 }
160 if (locale.isEmpty())
161 locale = getInstalledLocaleForLanguage(rLocaleElementNames, "en-US");
162 if (locale.isEmpty() && rLocaleElementNames.hasElements())
163 locale = rLocaleElementNames[0];
164 return locale;
165}
166
167/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const LanguageTag & GetUILanguageTag() const
static const AllSettings & GetSettings()
static vcl::Window * GetActiveTopWindow()
static bool IsHeadlessModeEnabled()
static vcl::Window * GetFirstTopLevelWindow()
virtual void Start(bool bStartTimer=true) override
Idle(const char *pDebugName)
LanguageType getLanguageType(bool bResolveSystem=true) const
OUString getLanguage() const
OUString getCountry() const
static bool isTraditionalChinese(LanguageType nLang)
static bool isSimplifiedChinese(LanguageType nLang)
void SetPriority(TaskPriority ePriority)
virtual void Invoke() override
#define TOOLS_INFO_EXCEPTION(area, stream)
float u
DocumentType eType
sal_Int32 nIndex
OUString getInstalledLocaleForSystemUILanguage(const css::uno::Sequence< OUString > &rLocaleElementNames, bool bRequestInstallIfMissing, const OUString &rPreferredLocale)
Definition: langhelp.cxx:106
OUString getInstalledLocaleForLanguage(css::uno::Sequence< OUString > const &installed, OUString const &locale)
Definition: langhelp.cxx:49
static std::unique_ptr< Idle > xLangpackInstaller
Definition: langhelp.cxx:65
void localizeWebserviceURI(OUString &rURI)
Localize a URI to one of the foundation's webservices.
Definition: langhelp.cxx:30
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Reference< XComponentContext > getProcessComponentContext()
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)