Line data Source code
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 <sal/config.h>
21 :
22 : #include <boost/shared_ptr.hpp>
23 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
24 : #include <com/sun/star/container/XNameAccess.hpp>
25 : #include <com/sun/star/lang/XLocalizable.hpp>
26 : #include <com/sun/star/uno/Exception.hpp>
27 : #include <com/sun/star/uno/Reference.hxx>
28 : #include <com/sun/star/uno/Sequence.hxx>
29 : #include <comphelper/configuration.hxx>
30 : #include <comphelper/processfactory.hxx>
31 : #include <i18nlangtag/lang.h>
32 : #include <i18nlangtag/languagetag.hxx>
33 : #include <i18nlangtag/mslangid.hxx>
34 : #include "officecfg/Office/Linguistic.hxx"
35 : #include "officecfg/Setup.hxx"
36 : #include "officecfg/System.hxx"
37 : #include <rtl/ustring.hxx>
38 : #include <sal/log.hxx>
39 : #include <sal/types.h>
40 : #include <svl/languageoptions.hxx>
41 :
42 : #include "app.hxx"
43 :
44 : #include "cmdlineargs.hxx"
45 : #include "langselect.hxx"
46 :
47 : namespace desktop { namespace langselect {
48 :
49 : namespace {
50 :
51 116 : OUString foundLocale;
52 :
53 232 : OUString getInstalledLocale(
54 : css::uno::Sequence<OUString> const & installed, OUString const & locale)
55 : {
56 232 : if (locale.isEmpty())
57 116 : return OUString(); // do not attempt to resolve anything
58 :
59 116 : for (sal_Int32 i = 0; i != installed.getLength(); ++i) {
60 116 : if (installed[i] == locale) {
61 116 : return installed[i];
62 : }
63 : }
64 0 : ::std::vector<OUString> fallbacks( LanguageTag( locale).getFallbackStrings( false));
65 0 : for (size_t f=0; f < fallbacks.size(); ++f) {
66 0 : const OUString& rf = fallbacks[f];
67 0 : for (sal_Int32 i = 0; i != installed.getLength(); ++i) {
68 0 : if (installed[i] == rf) {
69 0 : return installed[i];
70 : }
71 : }
72 : }
73 0 : return OUString();
74 : }
75 :
76 348 : void setMsLangIdFallback(OUString const & locale) {
77 : // #i32939# setting of default document language
78 : // See #i42730# for rules for determining source of settings
79 348 : if (!locale.isEmpty()) {
80 348 : LanguageType type = LanguageTag::convertToLanguageTypeWithFallback(locale);
81 348 : switch (SvtLanguageOptions::GetScriptTypeOfLanguage(type)) {
82 : case SvtScriptType::ASIAN:
83 0 : MsLangId::setConfiguredAsianFallback(type);
84 0 : break;
85 : case SvtScriptType::COMPLEX:
86 0 : MsLangId::setConfiguredComplexFallback(type);
87 0 : break;
88 : default:
89 348 : MsLangId::setConfiguredWesternFallback(type);
90 348 : break;
91 : }
92 : }
93 348 : }
94 :
95 : }
96 :
97 116 : OUString getEmergencyLocale() {
98 116 : if (!foundLocale.isEmpty()) {
99 116 : return foundLocale;
100 : }
101 : try {
102 : css::uno::Sequence<OUString> inst(
103 0 : officecfg::Setup::Office::InstalledLocales::get()->
104 0 : getElementNames());
105 : OUString locale(
106 : getInstalledLocale(
107 : inst,
108 0 : officecfg::Office::Linguistic::General::UILocale::get()));
109 0 : if (!locale.isEmpty()) {
110 0 : return locale;
111 : }
112 0 : locale = getInstalledLocale(
113 0 : inst, officecfg::System::L10N::UILocale::get());
114 0 : if (!locale.isEmpty()) {
115 0 : return locale;
116 : }
117 0 : locale = getInstalledLocale(inst, "en-US");
118 0 : if (!locale.isEmpty()) {
119 0 : return locale;
120 : }
121 0 : if (inst.hasElements()) {
122 0 : return inst[0];
123 0 : }
124 0 : } catch (css::uno::Exception & e) {
125 : SAL_WARN("desktop.app", "ignoring Exception \"" << e.Message << "\"");
126 : }
127 0 : return OUString();
128 : }
129 :
130 116 : bool prepareLocale() {
131 : // #i42730# Get the windows 16Bit locale, it should be preferred over the UI
132 : // locale:
133 116 : setMsLangIdFallback(officecfg::System::L10N::SystemLocale::get());
134 : // #i32939# Use system locale to set document default locale:
135 116 : setMsLangIdFallback(officecfg::System::L10N::Locale::get());
136 : css::uno::Sequence<OUString> inst(
137 116 : officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
138 232 : OUString locale(officecfg::Office::Linguistic::General::UILocale::get());
139 116 : if (!locale.isEmpty()) {
140 0 : locale = getInstalledLocale(inst, locale);
141 0 : if (locale.isEmpty()) {
142 : // Selected language is not/no longer installed:
143 : try {
144 : std::shared_ptr<comphelper::ConfigurationChanges> batch(
145 0 : comphelper::ConfigurationChanges::create());
146 : officecfg::Office::Linguistic::General::UILocale::set(
147 0 : "", batch);
148 0 : batch->commit();
149 0 : } catch (css::uno::Exception & e) {
150 : SAL_WARN(
151 : "desktop.app",
152 : "ignoring Exception \"" << e.Message << "\"");
153 : }
154 : }
155 : }
156 116 : bool cmdLanguage = false;
157 116 : if (locale.isEmpty()) {
158 232 : locale = getInstalledLocale(
159 232 : inst, Desktop::GetCommandLineArgs().GetLanguage());
160 116 : if (!locale.isEmpty()) {
161 0 : cmdLanguage = true;
162 : }
163 : }
164 116 : if (locale.isEmpty()) {
165 232 : locale = getInstalledLocale(
166 116 : inst, officecfg::System::L10N::UILocale::get());
167 : }
168 116 : if (locale.isEmpty()) {
169 0 : locale = getInstalledLocale(inst, "en-US");
170 : }
171 116 : if (locale.isEmpty() && inst.hasElements()) {
172 0 : locale = inst[0];
173 : }
174 116 : if (locale.isEmpty()) {
175 0 : return false;
176 : }
177 232 : LanguageTag tag(locale);
178 : // Prepare default config provider by localizing it to the selected
179 : // locale this will ensure localized configuration settings to be
180 : // selected according to the UI language:
181 : css::uno::Reference<css::lang::XLocalizable>(
182 : com::sun::star::configuration::theDefaultProvider::get(
183 : comphelper::getProcessComponentContext()),
184 116 : css::uno::UNO_QUERY_THROW)->setLocale(tag.getLocale(false));
185 116 : if (!cmdLanguage) {
186 : try {
187 : std::shared_ptr<comphelper::ConfigurationChanges> batch(
188 116 : comphelper::ConfigurationChanges::create());
189 116 : officecfg::Setup::L10N::ooLocale::set(locale, batch);
190 116 : batch->commit();
191 0 : } catch (css::uno::Exception & e) {
192 : SAL_WARN(
193 : "desktop.app", "ignoring Exception \"" << e.Message << "\"");
194 : }
195 : }
196 116 : MsLangId::setConfiguredSystemUILanguage(tag.getLanguageType(false));
197 232 : OUString setupSysLoc(officecfg::Setup::L10N::ooSetupSystemLocale::get());
198 : LanguageTag::setConfiguredSystemLanguage(
199 116 : setupSysLoc.isEmpty()
200 116 : ? MsLangId::getSystemLanguage()
201 232 : : LanguageTag(setupSysLoc).getLanguageType(false));
202 : // #i32939# setting of default document locale
203 : // #i32939# this should not be based on the UI language
204 116 : setMsLangIdFallback(locale);
205 116 : foundLocale = locale;
206 232 : return true;
207 : }
208 :
209 348 : } }
210 :
211 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|