From 1c7d3390022908cfbfd30f55e8c0c3b60a045da7 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Wed, 20 Dec 2017 16:02:18 +0000 Subject: request installation of langpack via packagekit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if ui is set to track the locale automatically and the current locale has no match in installed resources but has a match in the list of languages that libreoffice was compiled to contain so e.g. de_AT locale shouldn't trigger the installation of anything if langpack-de is already installed and yue_HK shouldn't trigger install of anything cause that not supported (at time of writing) for libreoffice put Fedora/RHEL/Ubuntu naming schemes in here. I moved the lang code from svl to svtools so I could use the restart dialog to prompt to restart after the langpack is installed, but packagekit's blocking mode seems to be no longer blocking and control returns immediately which is a change since the last time I played with this stuff, so drop the restart thing for now. The lack of a blocking modal also makes the "run this on idle when there's a toplevel window up and running" a bit futile, but lets keep that for now anyway. caolanm->rene: I know you'd disable this anyway, so Debian is left out, there's also config key Office/Common/PackageKit/EnableLangpackInstallation to disable this too. Change-Id: Ice731be539850338ccdd8af87839e0b4d83f01e7 Reviewed-on: https://gerrit.libreoffice.org/46856 Tested-by: Jenkins Reviewed-by: Caolán McNamara Tested-by: Caolán McNamara --- svtools/source/misc/langhelp.cxx | 131 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) (limited to 'svtools') diff --git a/svtools/source/misc/langhelp.cxx b/svtools/source/misc/langhelp.cxx index 16a3a1d8191c..47cb87e36963 100644 --- a/svtools/source/misc/langhelp.cxx +++ b/svtools/source/misc/langhelp.cxx @@ -7,12 +7,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - +#include +#include +#include +#include +#include +#include #include - +#include #include +#include #include -#include +#include +#include +#include void localizeWebserviceURI( OUString& rURI ) { @@ -33,4 +41,121 @@ void localizeWebserviceURI( OUString& rURI ) rURI += aLang; } +OUString getInstalledLocaleForLanguage(css::uno::Sequence const & installed, OUString const & locale) +{ + if (locale.isEmpty()) + return OUString(); // do not attempt to resolve anything + + for (sal_Int32 i = 0; i != installed.getLength(); ++i) { + if (installed[i] == locale) { + return installed[i]; + } + } + std::vector fallbacks(LanguageTag(locale).getFallbackStrings(false)); + for (OUString & rf : fallbacks) { + for (sal_Int32 i = 0; i != installed.getLength(); ++i) { + if (installed[i] == rf) { + return installed[i]; + } + } + } + return OUString(); +} + +static std::unique_ptr xLangpackInstaller; + +class InstallLangpack : public Idle +{ + std::vector m_aPackages; +public: + explicit InstallLangpack(const std::vector& rPackages) + : Idle("install langpack") + , m_aPackages(rPackages) + { + SetPriority(TaskPriority::LOWEST); + } + + virtual void Invoke() override + { + vcl::Window* pTopWindow = Application::GetActiveTopWindow(); + if (!pTopWindow) + pTopWindow = Application::GetFirstTopLevelWindow(); + if (!pTopWindow) + { + Start(); + return; + } + try + { + using namespace org::freedesktop::PackageKit; + css::uno::Reference xSyncDbusSessionHelper(SyncDbusSessionHelper::create(comphelper::getProcessComponentContext())); + const SystemEnvData* pEnvData = pTopWindow->GetSystemData(); + sal_uInt32 nDbusId = pEnvData ? GetDbusId(*pEnvData) : 0; + xSyncDbusSessionHelper->InstallPackageNames(nDbusId, comphelper::containerToSequence(m_aPackages), OUString()); + } + catch (const css::uno::Exception& e) + { + SAL_INFO("svl", "trying to install a LibreOffice langpack, caught " << e); + } + xLangpackInstaller.reset(); + } +}; + +OUString getInstalledLocaleForSystemUILanguage(const css::uno::Sequence& rLocaleElementNames, bool bRequestInstallIfMissing) +{ + OUString wantedLocale = officecfg::System::L10N::UILocale::get(); + OUString locale = getInstalledLocaleForLanguage(rLocaleElementNames, wantedLocale); + if (bRequestInstallIfMissing && locale.isEmpty() && !wantedLocale.isEmpty() && !Application::IsHeadlessModeEnabled() && + officecfg::Office::Common::PackageKit::EnableLangpackInstallation::get()) + { + LanguageTag aWantedTag(wantedLocale); + if (aWantedTag.getLanguage() != "en") + { + // Get the list of langpacks that this build was configured to include + std::vector aPackages; + OUString sAvailableLocales(WITH_LANG); + std::vector aAvailable; + sal_Int32 nIndex = 0; + do + { + aAvailable.emplace_back(sAvailableLocales.getToken(0, ' ', nIndex)); + } + while (nIndex >= 0); + // See which one matches the desired ui locale + OUString install = getInstalledLocaleForLanguage(comphelper::containerToSequence(aAvailable), wantedLocale); + if (!install.isEmpty() && install != "en-US") + { + OUString sVendor(OOO_VENDOR); + if (sVendor == "Red Hat, Inc." || sVendor == "The Fedora Project") + { + // langpack is the typical Fedora/RHEL naming convention + LanguageType eType = aWantedTag.getLanguageType(); + if (MsLangId::isSimplifiedChinese(eType)) + aPackages.emplace_back("libreoffice-langpack-zh-Hans"); + else if (MsLangId::isTraditionalChinese(eType)) + aPackages.emplace_back("libreoffice-langpack-zh-Hant"); + else + aPackages.emplace_back("libreoffice-langpack-" + install); + } + //Debian would be: "The Document Foundation/Debian" + else if (sVendor == "The Document Foundation, Debian and Ubuntu") + { + // l10n is the typical Debian/Ubuntu naming convention + aPackages.emplace_back("libreoffice-l10n-" + install); + } + } + if (!aPackages.empty()) + { + xLangpackInstaller.reset(new InstallLangpack(aPackages)); + xLangpackInstaller->Start(); + } + } + } + if (locale.isEmpty()) + locale = getInstalledLocaleForLanguage(rLocaleElementNames, "en-US"); + if (locale.isEmpty() && rLocaleElementNames.hasElements()) + locale = rLocaleElementNames[0]; + return locale; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit