1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_desktop.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include "app.hxx"
28*b1cdbd2cSJim Jagielski #include "langselect.hxx"
29*b1cdbd2cSJim Jagielski #include "cmdlineargs.hxx"
30*b1cdbd2cSJim Jagielski #include <stdio.h>
31*b1cdbd2cSJim Jagielski
32*b1cdbd2cSJim Jagielski #include <rtl/string.hxx>
33*b1cdbd2cSJim Jagielski #include <rtl/bootstrap.hxx>
34*b1cdbd2cSJim Jagielski #include <unotools/pathoptions.hxx>
35*b1cdbd2cSJim Jagielski #include <tools/resid.hxx>
36*b1cdbd2cSJim Jagielski #include <tools/config.hxx>
37*b1cdbd2cSJim Jagielski #include <i18npool/mslangid.hxx>
38*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/container/XNameAccess.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XComponent.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/NamedValue.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XChangesBatch.hpp>
43*b1cdbd2cSJim Jagielski #include <com/sun/star/uno/Any.hxx>
44*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XLocalizable.hpp>
45*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/Locale.hpp>
46*b1cdbd2cSJim Jagielski #include "com/sun/star/util/XFlushable.hpp"
47*b1cdbd2cSJim Jagielski #include <rtl/locale.hxx>
48*b1cdbd2cSJim Jagielski #include <rtl/instance.hxx>
49*b1cdbd2cSJim Jagielski #include <osl/process.h>
50*b1cdbd2cSJim Jagielski #include <osl/file.hxx>
51*b1cdbd2cSJim Jagielski
52*b1cdbd2cSJim Jagielski using namespace rtl;
53*b1cdbd2cSJim Jagielski using namespace com::sun::star::uno;
54*b1cdbd2cSJim Jagielski using namespace com::sun::star::lang;
55*b1cdbd2cSJim Jagielski using namespace com::sun::star::container;
56*b1cdbd2cSJim Jagielski using namespace com::sun::star::beans;
57*b1cdbd2cSJim Jagielski using namespace com::sun::star::util;
58*b1cdbd2cSJim Jagielski
59*b1cdbd2cSJim Jagielski namespace desktop {
60*b1cdbd2cSJim Jagielski
61*b1cdbd2cSJim Jagielski static char const SOFFICE_BOOTSTRAP[] = "Bootstrap";
62*b1cdbd2cSJim Jagielski static char const SOFFICE_STARTLANG[] = "STARTLANG";
63*b1cdbd2cSJim Jagielski
64*b1cdbd2cSJim Jagielski sal_Bool LanguageSelection::bFoundLanguage = sal_False;
65*b1cdbd2cSJim Jagielski OUString LanguageSelection::aFoundLanguage;
66*b1cdbd2cSJim Jagielski LanguageSelection::LanguageSelectionStatus LanguageSelection::m_eStatus = LS_STATUS_OK;
67*b1cdbd2cSJim Jagielski
68*b1cdbd2cSJim Jagielski const OUString LanguageSelection::usFallbackLanguage = OUString::createFromAscii("en-US");
69*b1cdbd2cSJim Jagielski
existsURL(OUString const & sURL)70*b1cdbd2cSJim Jagielski static sal_Bool existsURL( OUString const& sURL )
71*b1cdbd2cSJim Jagielski {
72*b1cdbd2cSJim Jagielski using namespace osl;
73*b1cdbd2cSJim Jagielski DirectoryItem aDirItem;
74*b1cdbd2cSJim Jagielski
75*b1cdbd2cSJim Jagielski if (sURL.getLength() != 0)
76*b1cdbd2cSJim Jagielski return ( DirectoryItem::get( sURL, aDirItem ) == DirectoryItem::E_None );
77*b1cdbd2cSJim Jagielski
78*b1cdbd2cSJim Jagielski return sal_False;
79*b1cdbd2cSJim Jagielski }
80*b1cdbd2cSJim Jagielski
81*b1cdbd2cSJim Jagielski // locate soffice.ini/.rc file
locateSofficeIniFile()82*b1cdbd2cSJim Jagielski static OUString locateSofficeIniFile()
83*b1cdbd2cSJim Jagielski {
84*b1cdbd2cSJim Jagielski OUString aUserDataPath;
85*b1cdbd2cSJim Jagielski OUString aSofficeIniFileURL;
86*b1cdbd2cSJim Jagielski
87*b1cdbd2cSJim Jagielski // Retrieve the default file URL for the soffice.ini/rc
88*b1cdbd2cSJim Jagielski rtl::Bootstrap().getIniName( aSofficeIniFileURL );
89*b1cdbd2cSJim Jagielski
90*b1cdbd2cSJim Jagielski if ( utl::Bootstrap::locateUserData( aUserDataPath ) == utl::Bootstrap::PATH_EXISTS )
91*b1cdbd2cSJim Jagielski {
92*b1cdbd2cSJim Jagielski const char CONFIG_DIR[] = "/config";
93*b1cdbd2cSJim Jagielski
94*b1cdbd2cSJim Jagielski sal_Int32 nIndex = aSofficeIniFileURL.lastIndexOf( '/');
95*b1cdbd2cSJim Jagielski if ( nIndex > 0 )
96*b1cdbd2cSJim Jagielski {
97*b1cdbd2cSJim Jagielski OUString aUserSofficeIniFileURL;
98*b1cdbd2cSJim Jagielski OUStringBuffer aBuffer( aUserDataPath );
99*b1cdbd2cSJim Jagielski aBuffer.appendAscii( CONFIG_DIR );
100*b1cdbd2cSJim Jagielski aBuffer.append( aSofficeIniFileURL.copy( nIndex ));
101*b1cdbd2cSJim Jagielski aUserSofficeIniFileURL = aBuffer.makeStringAndClear();
102*b1cdbd2cSJim Jagielski
103*b1cdbd2cSJim Jagielski if ( existsURL( aUserSofficeIniFileURL ))
104*b1cdbd2cSJim Jagielski return aUserSofficeIniFileURL;
105*b1cdbd2cSJim Jagielski }
106*b1cdbd2cSJim Jagielski }
107*b1cdbd2cSJim Jagielski // Fallback try to use the soffice.ini/rc from program folder
108*b1cdbd2cSJim Jagielski return aSofficeIniFileURL;
109*b1cdbd2cSJim Jagielski }
110*b1cdbd2cSJim Jagielski
IsoStringToLocale(const OUString & str)111*b1cdbd2cSJim Jagielski Locale LanguageSelection::IsoStringToLocale(const OUString& str)
112*b1cdbd2cSJim Jagielski {
113*b1cdbd2cSJim Jagielski Locale l;
114*b1cdbd2cSJim Jagielski sal_Int32 index=0;
115*b1cdbd2cSJim Jagielski l.Language = str.getToken(0, '-', index);
116*b1cdbd2cSJim Jagielski if (index >= 0) l.Country = str.getToken(0, '-', index);
117*b1cdbd2cSJim Jagielski if (index >= 0) l.Variant = str.getToken(0, '-', index);
118*b1cdbd2cSJim Jagielski return l;
119*b1cdbd2cSJim Jagielski }
120*b1cdbd2cSJim Jagielski
prepareLanguage()121*b1cdbd2cSJim Jagielski bool LanguageSelection::prepareLanguage()
122*b1cdbd2cSJim Jagielski {
123*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_OK;
124*b1cdbd2cSJim Jagielski OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
125*b1cdbd2cSJim Jagielski Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
126*b1cdbd2cSJim Jagielski Reference< XLocalizable > theConfigProvider;
127*b1cdbd2cSJim Jagielski try
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski theConfigProvider = Reference< XLocalizable >(theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
130*b1cdbd2cSJim Jagielski }
131*b1cdbd2cSJim Jagielski catch(const Exception&)
132*b1cdbd2cSJim Jagielski {
133*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
134*b1cdbd2cSJim Jagielski }
135*b1cdbd2cSJim Jagielski
136*b1cdbd2cSJim Jagielski if(!theConfigProvider.is())
137*b1cdbd2cSJim Jagielski return false;
138*b1cdbd2cSJim Jagielski
139*b1cdbd2cSJim Jagielski sal_Bool bSuccess = sal_False;
140*b1cdbd2cSJim Jagielski
141*b1cdbd2cSJim Jagielski // #i42730#get the windows 16Bit locale - it should be preferred over the UI language
142*b1cdbd2cSJim Jagielski try
143*b1cdbd2cSJim Jagielski {
144*b1cdbd2cSJim Jagielski Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.System/L10N/", sal_False), UNO_QUERY_THROW);
145*b1cdbd2cSJim Jagielski Any aWin16SysLocale = xProp->getPropertyValue(OUString::createFromAscii("SystemLocale"));
146*b1cdbd2cSJim Jagielski ::rtl::OUString sWin16SysLocale;
147*b1cdbd2cSJim Jagielski aWin16SysLocale >>= sWin16SysLocale;
148*b1cdbd2cSJim Jagielski if( sWin16SysLocale.getLength())
149*b1cdbd2cSJim Jagielski setDefaultLanguage(sWin16SysLocale);
150*b1cdbd2cSJim Jagielski }
151*b1cdbd2cSJim Jagielski catch(const Exception&)
152*b1cdbd2cSJim Jagielski {
153*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
154*b1cdbd2cSJim Jagielski }
155*b1cdbd2cSJim Jagielski
156*b1cdbd2cSJim Jagielski // #i32939# use system locale to set document default locale
157*b1cdbd2cSJim Jagielski try
158*b1cdbd2cSJim Jagielski {
159*b1cdbd2cSJim Jagielski OUString usLocale;
160*b1cdbd2cSJim Jagielski Reference< XPropertySet > xLocaleProp(getConfigAccess(
161*b1cdbd2cSJim Jagielski "org.openoffice.System/L10N", sal_True), UNO_QUERY_THROW);
162*b1cdbd2cSJim Jagielski xLocaleProp->getPropertyValue(OUString::createFromAscii("Locale")) >>= usLocale;
163*b1cdbd2cSJim Jagielski setDefaultLanguage(usLocale);
164*b1cdbd2cSJim Jagielski }
165*b1cdbd2cSJim Jagielski catch (Exception&)
166*b1cdbd2cSJim Jagielski {
167*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
168*b1cdbd2cSJim Jagielski }
169*b1cdbd2cSJim Jagielski
170*b1cdbd2cSJim Jagielski // get the selected UI language as string
171*b1cdbd2cSJim Jagielski bool bCmdLanguage( false );
172*b1cdbd2cSJim Jagielski bool bIniLanguage( false );
173*b1cdbd2cSJim Jagielski OUString aEmpty;
174*b1cdbd2cSJim Jagielski OUString aLocaleString = getUserUILanguage();
175*b1cdbd2cSJim Jagielski
176*b1cdbd2cSJim Jagielski if ( aLocaleString.getLength() == 0 )
177*b1cdbd2cSJim Jagielski {
178*b1cdbd2cSJim Jagielski CommandLineArgs* pCmdLineArgs = Desktop::GetCommandLineArgs();
179*b1cdbd2cSJim Jagielski if ( pCmdLineArgs )
180*b1cdbd2cSJim Jagielski {
181*b1cdbd2cSJim Jagielski pCmdLineArgs->GetLanguage(aLocaleString);
182*b1cdbd2cSJim Jagielski if (isInstalledLanguage(aLocaleString, sal_False))
183*b1cdbd2cSJim Jagielski {
184*b1cdbd2cSJim Jagielski bCmdLanguage = true;
185*b1cdbd2cSJim Jagielski bFoundLanguage = true;
186*b1cdbd2cSJim Jagielski aFoundLanguage = aLocaleString;
187*b1cdbd2cSJim Jagielski }
188*b1cdbd2cSJim Jagielski else
189*b1cdbd2cSJim Jagielski aLocaleString = aEmpty;
190*b1cdbd2cSJim Jagielski }
191*b1cdbd2cSJim Jagielski
192*b1cdbd2cSJim Jagielski if ( !bCmdLanguage )
193*b1cdbd2cSJim Jagielski {
194*b1cdbd2cSJim Jagielski OUString aSOfficeIniURL = locateSofficeIniFile();
195*b1cdbd2cSJim Jagielski Config aConfig(aSOfficeIniURL);
196*b1cdbd2cSJim Jagielski aConfig.SetGroup( SOFFICE_BOOTSTRAP );
197*b1cdbd2cSJim Jagielski OString sLang = aConfig.ReadKey( SOFFICE_STARTLANG );
198*b1cdbd2cSJim Jagielski aLocaleString = OUString( sLang.getStr(), sLang.getLength(), RTL_TEXTENCODING_ASCII_US );
199*b1cdbd2cSJim Jagielski if (isInstalledLanguage(aLocaleString, sal_False))
200*b1cdbd2cSJim Jagielski {
201*b1cdbd2cSJim Jagielski bIniLanguage = true;
202*b1cdbd2cSJim Jagielski bFoundLanguage = true;
203*b1cdbd2cSJim Jagielski aFoundLanguage = aLocaleString;
204*b1cdbd2cSJim Jagielski }
205*b1cdbd2cSJim Jagielski else
206*b1cdbd2cSJim Jagielski aLocaleString = aEmpty;
207*b1cdbd2cSJim Jagielski }
208*b1cdbd2cSJim Jagielski }
209*b1cdbd2cSJim Jagielski
210*b1cdbd2cSJim Jagielski // user further fallbacks for the UI language
211*b1cdbd2cSJim Jagielski if ( aLocaleString.getLength() == 0 )
212*b1cdbd2cSJim Jagielski aLocaleString = getLanguageString();
213*b1cdbd2cSJim Jagielski
214*b1cdbd2cSJim Jagielski if ( aLocaleString.getLength() > 0 )
215*b1cdbd2cSJim Jagielski {
216*b1cdbd2cSJim Jagielski try
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski // prepare default config provider by localizing it to the selected locale
219*b1cdbd2cSJim Jagielski // this will ensure localized configuration settings to be selected accoring to the
220*b1cdbd2cSJim Jagielski // UI language.
221*b1cdbd2cSJim Jagielski Locale loc = LanguageSelection::IsoStringToLocale(aLocaleString);
222*b1cdbd2cSJim Jagielski // flush any data already written to the configuration (which
223*b1cdbd2cSJim Jagielski // currently uses independent caches for different locales and thus
224*b1cdbd2cSJim Jagielski // would ignore data written to another cache):
225*b1cdbd2cSJim Jagielski Reference< XFlushable >(theConfigProvider, UNO_QUERY_THROW)->
226*b1cdbd2cSJim Jagielski flush();
227*b1cdbd2cSJim Jagielski theConfigProvider->setLocale(loc);
228*b1cdbd2cSJim Jagielski
229*b1cdbd2cSJim Jagielski Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Setup/L10N/", sal_True), UNO_QUERY_THROW);
230*b1cdbd2cSJim Jagielski if ( !bCmdLanguage )
231*b1cdbd2cSJim Jagielski {
232*b1cdbd2cSJim Jagielski // Store language only
233*b1cdbd2cSJim Jagielski xProp->setPropertyValue(OUString::createFromAscii("ooLocale"), makeAny(aLocaleString));
234*b1cdbd2cSJim Jagielski Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
235*b1cdbd2cSJim Jagielski }
236*b1cdbd2cSJim Jagielski
237*b1cdbd2cSJim Jagielski if ( bIniLanguage )
238*b1cdbd2cSJim Jagielski {
239*b1cdbd2cSJim Jagielski // Store language only
240*b1cdbd2cSJim Jagielski Reference< XPropertySet > xProp2(getConfigAccess("org.openoffice.Office.Linguistic/General/", sal_True), UNO_QUERY_THROW);
241*b1cdbd2cSJim Jagielski xProp2->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(aLocaleString));
242*b1cdbd2cSJim Jagielski Reference< XChangesBatch >(xProp2, UNO_QUERY_THROW)->commitChanges();
243*b1cdbd2cSJim Jagielski }
244*b1cdbd2cSJim Jagielski
245*b1cdbd2cSJim Jagielski MsLangId::setConfiguredSystemUILanguage( MsLangId::convertLocaleToLanguage(loc) );
246*b1cdbd2cSJim Jagielski
247*b1cdbd2cSJim Jagielski OUString sLocale;
248*b1cdbd2cSJim Jagielski xProp->getPropertyValue(OUString::createFromAscii("ooSetupSystemLocale")) >>= sLocale;
249*b1cdbd2cSJim Jagielski if ( sLocale.getLength() )
250*b1cdbd2cSJim Jagielski {
251*b1cdbd2cSJim Jagielski loc = LanguageSelection::IsoStringToLocale(sLocale);
252*b1cdbd2cSJim Jagielski MsLangId::setConfiguredSystemLanguage( MsLangId::convertLocaleToLanguage(loc) );
253*b1cdbd2cSJim Jagielski }
254*b1cdbd2cSJim Jagielski else
255*b1cdbd2cSJim Jagielski MsLangId::setConfiguredSystemLanguage( MsLangId::getSystemLanguage() );
256*b1cdbd2cSJim Jagielski
257*b1cdbd2cSJim Jagielski bSuccess = sal_True;
258*b1cdbd2cSJim Jagielski }
259*b1cdbd2cSJim Jagielski catch ( PropertyVetoException& )
260*b1cdbd2cSJim Jagielski {
261*b1cdbd2cSJim Jagielski // we are not allowed to change this
262*b1cdbd2cSJim Jagielski }
263*b1cdbd2cSJim Jagielski catch (Exception& e)
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
266*b1cdbd2cSJim Jagielski OSL_ENSURE(sal_False, aMsg.getStr());
267*b1cdbd2cSJim Jagielski
268*b1cdbd2cSJim Jagielski }
269*b1cdbd2cSJim Jagielski }
270*b1cdbd2cSJim Jagielski
271*b1cdbd2cSJim Jagielski // #i32939# setting of default document locale
272*b1cdbd2cSJim Jagielski // #i32939# this should not be based on the UI language
273*b1cdbd2cSJim Jagielski setDefaultLanguage(aLocaleString);
274*b1cdbd2cSJim Jagielski
275*b1cdbd2cSJim Jagielski return bSuccess;
276*b1cdbd2cSJim Jagielski }
277*b1cdbd2cSJim Jagielski
setDefaultLanguage(const OUString & sLocale)278*b1cdbd2cSJim Jagielski void LanguageSelection::setDefaultLanguage(const OUString& sLocale)
279*b1cdbd2cSJim Jagielski {
280*b1cdbd2cSJim Jagielski // #i32939# setting of default document language
281*b1cdbd2cSJim Jagielski //
282*b1cdbd2cSJim Jagielski // See #i42730# for rules for determining source of settings
283*b1cdbd2cSJim Jagielski
284*b1cdbd2cSJim Jagielski // determine script type of locale
285*b1cdbd2cSJim Jagielski LanguageType nLang = MsLangId::convertIsoStringToLanguage(sLocale);
286*b1cdbd2cSJim Jagielski sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage(nLang);
287*b1cdbd2cSJim Jagielski
288*b1cdbd2cSJim Jagielski switch (nScriptType)
289*b1cdbd2cSJim Jagielski {
290*b1cdbd2cSJim Jagielski case SCRIPTTYPE_ASIAN:
291*b1cdbd2cSJim Jagielski MsLangId::setConfiguredAsianFallback( nLang );
292*b1cdbd2cSJim Jagielski break;
293*b1cdbd2cSJim Jagielski case SCRIPTTYPE_COMPLEX:
294*b1cdbd2cSJim Jagielski MsLangId::setConfiguredComplexFallback( nLang );
295*b1cdbd2cSJim Jagielski break;
296*b1cdbd2cSJim Jagielski default:
297*b1cdbd2cSJim Jagielski MsLangId::setConfiguredWesternFallback( nLang );
298*b1cdbd2cSJim Jagielski break;
299*b1cdbd2cSJim Jagielski }
300*b1cdbd2cSJim Jagielski }
301*b1cdbd2cSJim Jagielski
getUserUILanguage()302*b1cdbd2cSJim Jagielski OUString LanguageSelection::getUserUILanguage()
303*b1cdbd2cSJim Jagielski {
304*b1cdbd2cSJim Jagielski // check whether the user has selected a specific language
305*b1cdbd2cSJim Jagielski OUString aUserLanguage = getUserLanguage();
306*b1cdbd2cSJim Jagielski if (aUserLanguage.getLength() > 0 )
307*b1cdbd2cSJim Jagielski {
308*b1cdbd2cSJim Jagielski if (isInstalledLanguage(aUserLanguage))
309*b1cdbd2cSJim Jagielski {
310*b1cdbd2cSJim Jagielski // all is well
311*b1cdbd2cSJim Jagielski bFoundLanguage = sal_True;
312*b1cdbd2cSJim Jagielski aFoundLanguage = aUserLanguage;
313*b1cdbd2cSJim Jagielski return aFoundLanguage;
314*b1cdbd2cSJim Jagielski }
315*b1cdbd2cSJim Jagielski else
316*b1cdbd2cSJim Jagielski {
317*b1cdbd2cSJim Jagielski // selected language is not/no longer installed
318*b1cdbd2cSJim Jagielski resetUserLanguage();
319*b1cdbd2cSJim Jagielski }
320*b1cdbd2cSJim Jagielski }
321*b1cdbd2cSJim Jagielski
322*b1cdbd2cSJim Jagielski return aUserLanguage;
323*b1cdbd2cSJim Jagielski }
324*b1cdbd2cSJim Jagielski
getLanguageString()325*b1cdbd2cSJim Jagielski OUString LanguageSelection::getLanguageString()
326*b1cdbd2cSJim Jagielski {
327*b1cdbd2cSJim Jagielski // did we already find a language?
328*b1cdbd2cSJim Jagielski if (bFoundLanguage)
329*b1cdbd2cSJim Jagielski return aFoundLanguage;
330*b1cdbd2cSJim Jagielski
331*b1cdbd2cSJim Jagielski // check whether the user has selected a specific language
332*b1cdbd2cSJim Jagielski OUString aUserLanguage = getUserUILanguage();
333*b1cdbd2cSJim Jagielski if (aUserLanguage.getLength() > 0 )
334*b1cdbd2cSJim Jagielski return aUserLanguage ;
335*b1cdbd2cSJim Jagielski
336*b1cdbd2cSJim Jagielski // try to use system default
337*b1cdbd2cSJim Jagielski aUserLanguage = getSystemLanguage();
338*b1cdbd2cSJim Jagielski if (aUserLanguage.getLength() > 0 )
339*b1cdbd2cSJim Jagielski {
340*b1cdbd2cSJim Jagielski if (isInstalledLanguage(aUserLanguage, sal_False))
341*b1cdbd2cSJim Jagielski {
342*b1cdbd2cSJim Jagielski // great, system default language is available
343*b1cdbd2cSJim Jagielski bFoundLanguage = sal_True;
344*b1cdbd2cSJim Jagielski aFoundLanguage = aUserLanguage;
345*b1cdbd2cSJim Jagielski return aFoundLanguage;
346*b1cdbd2cSJim Jagielski }
347*b1cdbd2cSJim Jagielski }
348*b1cdbd2cSJim Jagielski // fallback 1: en-US
349*b1cdbd2cSJim Jagielski OUString usFB = usFallbackLanguage;
350*b1cdbd2cSJim Jagielski if (isInstalledLanguage(usFB))
351*b1cdbd2cSJim Jagielski {
352*b1cdbd2cSJim Jagielski bFoundLanguage = sal_True;
353*b1cdbd2cSJim Jagielski aFoundLanguage = usFallbackLanguage;
354*b1cdbd2cSJim Jagielski return aFoundLanguage;
355*b1cdbd2cSJim Jagielski }
356*b1cdbd2cSJim Jagielski
357*b1cdbd2cSJim Jagielski // fallback didn't work use first installed language
358*b1cdbd2cSJim Jagielski aUserLanguage = getFirstInstalledLanguage();
359*b1cdbd2cSJim Jagielski
360*b1cdbd2cSJim Jagielski bFoundLanguage = sal_True;
361*b1cdbd2cSJim Jagielski aFoundLanguage = aUserLanguage;
362*b1cdbd2cSJim Jagielski return aFoundLanguage;
363*b1cdbd2cSJim Jagielski }
364*b1cdbd2cSJim Jagielski
getConfigAccess(const sal_Char * pPath,sal_Bool bUpdate)365*b1cdbd2cSJim Jagielski Reference< XNameAccess > LanguageSelection::getConfigAccess(const sal_Char* pPath, sal_Bool bUpdate)
366*b1cdbd2cSJim Jagielski {
367*b1cdbd2cSJim Jagielski Reference< XNameAccess > xNameAccess;
368*b1cdbd2cSJim Jagielski try{
369*b1cdbd2cSJim Jagielski OUString sConfigSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider");
370*b1cdbd2cSJim Jagielski OUString sAccessSrvc;
371*b1cdbd2cSJim Jagielski if (bUpdate)
372*b1cdbd2cSJim Jagielski sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationUpdateAccess");
373*b1cdbd2cSJim Jagielski else
374*b1cdbd2cSJim Jagielski sAccessSrvc = OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess");
375*b1cdbd2cSJim Jagielski
376*b1cdbd2cSJim Jagielski OUString sConfigURL = OUString::createFromAscii(pPath);
377*b1cdbd2cSJim Jagielski
378*b1cdbd2cSJim Jagielski // get configuration provider
379*b1cdbd2cSJim Jagielski Reference< XMultiServiceFactory > theMSF = comphelper::getProcessServiceFactory();
380*b1cdbd2cSJim Jagielski if (theMSF.is()) {
381*b1cdbd2cSJim Jagielski Reference< XMultiServiceFactory > theConfigProvider = Reference< XMultiServiceFactory > (
382*b1cdbd2cSJim Jagielski theMSF->createInstance( sConfigSrvc ),UNO_QUERY_THROW );
383*b1cdbd2cSJim Jagielski
384*b1cdbd2cSJim Jagielski // access the provider
385*b1cdbd2cSJim Jagielski Sequence< Any > theArgs(1);
386*b1cdbd2cSJim Jagielski theArgs[ 0 ] <<= sConfigURL;
387*b1cdbd2cSJim Jagielski xNameAccess = Reference< XNameAccess > (
388*b1cdbd2cSJim Jagielski theConfigProvider->createInstanceWithArguments(
389*b1cdbd2cSJim Jagielski sAccessSrvc, theArgs ), UNO_QUERY_THROW );
390*b1cdbd2cSJim Jagielski }
391*b1cdbd2cSJim Jagielski } catch (com::sun::star::uno::Exception& e)
392*b1cdbd2cSJim Jagielski {
393*b1cdbd2cSJim Jagielski OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
394*b1cdbd2cSJim Jagielski OSL_ENSURE(sal_False, aMsg.getStr());
395*b1cdbd2cSJim Jagielski }
396*b1cdbd2cSJim Jagielski return xNameAccess;
397*b1cdbd2cSJim Jagielski }
398*b1cdbd2cSJim Jagielski
getInstalledLanguages()399*b1cdbd2cSJim Jagielski Sequence< OUString > LanguageSelection::getInstalledLanguages()
400*b1cdbd2cSJim Jagielski {
401*b1cdbd2cSJim Jagielski Sequence< OUString > seqLanguages;
402*b1cdbd2cSJim Jagielski Reference< XNameAccess > xAccess = getConfigAccess("org.openoffice.Setup/Office/InstalledLocales", sal_False);
403*b1cdbd2cSJim Jagielski if (!xAccess.is()) return seqLanguages;
404*b1cdbd2cSJim Jagielski seqLanguages = xAccess->getElementNames();
405*b1cdbd2cSJim Jagielski return seqLanguages;
406*b1cdbd2cSJim Jagielski }
407*b1cdbd2cSJim Jagielski
408*b1cdbd2cSJim Jagielski // FIXME
409*b1cdbd2cSJim Jagielski // it's not very clever to handle language fallbacks here, but
410*b1cdbd2cSJim Jagielski // right now, there is no place that handles those fallbacks globally
_getFallbackLocales(const OUString & aIsoLang)411*b1cdbd2cSJim Jagielski static Sequence< OUString > _getFallbackLocales(const OUString& aIsoLang)
412*b1cdbd2cSJim Jagielski {
413*b1cdbd2cSJim Jagielski Sequence< OUString > seqFallbacks;
414*b1cdbd2cSJim Jagielski if (aIsoLang.equalsAscii("zh-HK")) {
415*b1cdbd2cSJim Jagielski seqFallbacks = Sequence< OUString >(1);
416*b1cdbd2cSJim Jagielski seqFallbacks[0] = OUString::createFromAscii("zh-TW");
417*b1cdbd2cSJim Jagielski }
418*b1cdbd2cSJim Jagielski return seqFallbacks;
419*b1cdbd2cSJim Jagielski }
420*b1cdbd2cSJim Jagielski
isInstalledLanguage(OUString & usLocale,sal_Bool bExact)421*b1cdbd2cSJim Jagielski sal_Bool LanguageSelection::isInstalledLanguage(OUString& usLocale, sal_Bool bExact)
422*b1cdbd2cSJim Jagielski {
423*b1cdbd2cSJim Jagielski sal_Bool bInstalled = sal_False;
424*b1cdbd2cSJim Jagielski Sequence< OUString > seqLanguages = getInstalledLanguages();
425*b1cdbd2cSJim Jagielski for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
426*b1cdbd2cSJim Jagielski {
427*b1cdbd2cSJim Jagielski if (usLocale.equals(seqLanguages[i]))
428*b1cdbd2cSJim Jagielski {
429*b1cdbd2cSJim Jagielski bInstalled = sal_True;
430*b1cdbd2cSJim Jagielski break;
431*b1cdbd2cSJim Jagielski }
432*b1cdbd2cSJim Jagielski }
433*b1cdbd2cSJim Jagielski
434*b1cdbd2cSJim Jagielski if (!bInstalled && !bExact)
435*b1cdbd2cSJim Jagielski {
436*b1cdbd2cSJim Jagielski // try fallback locales
437*b1cdbd2cSJim Jagielski Sequence< OUString > seqFallbacks = _getFallbackLocales(usLocale);
438*b1cdbd2cSJim Jagielski for (sal_Int32 j=0; j<seqFallbacks.getLength(); j++)
439*b1cdbd2cSJim Jagielski {
440*b1cdbd2cSJim Jagielski for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
441*b1cdbd2cSJim Jagielski {
442*b1cdbd2cSJim Jagielski if (seqFallbacks[j].equals(seqLanguages[i]))
443*b1cdbd2cSJim Jagielski {
444*b1cdbd2cSJim Jagielski bInstalled = sal_True;
445*b1cdbd2cSJim Jagielski usLocale = seqFallbacks[j];
446*b1cdbd2cSJim Jagielski break;
447*b1cdbd2cSJim Jagielski }
448*b1cdbd2cSJim Jagielski }
449*b1cdbd2cSJim Jagielski }
450*b1cdbd2cSJim Jagielski }
451*b1cdbd2cSJim Jagielski
452*b1cdbd2cSJim Jagielski if (!bInstalled && !bExact)
453*b1cdbd2cSJim Jagielski {
454*b1cdbd2cSJim Jagielski // no exact match was found, well try to find a substitute
455*b1cdbd2cSJim Jagielski OUString aInstalledLocale;
456*b1cdbd2cSJim Jagielski for (sal_Int32 i=0; i<seqLanguages.getLength(); i++)
457*b1cdbd2cSJim Jagielski {
458*b1cdbd2cSJim Jagielski if (usLocale.indexOf(seqLanguages[i]) == 0)
459*b1cdbd2cSJim Jagielski {
460*b1cdbd2cSJim Jagielski // requested locale starts with the installed locale
461*b1cdbd2cSJim Jagielski // (i.e. installed locale has index 0 in requested locale)
462*b1cdbd2cSJim Jagielski bInstalled = sal_True;
463*b1cdbd2cSJim Jagielski usLocale = seqLanguages[i];
464*b1cdbd2cSJim Jagielski break;
465*b1cdbd2cSJim Jagielski }
466*b1cdbd2cSJim Jagielski }
467*b1cdbd2cSJim Jagielski }
468*b1cdbd2cSJim Jagielski return bInstalled;
469*b1cdbd2cSJim Jagielski }
470*b1cdbd2cSJim Jagielski
getFirstInstalledLanguage()471*b1cdbd2cSJim Jagielski OUString LanguageSelection::getFirstInstalledLanguage()
472*b1cdbd2cSJim Jagielski {
473*b1cdbd2cSJim Jagielski OUString aLanguage;
474*b1cdbd2cSJim Jagielski Sequence< OUString > seqLanguages = getInstalledLanguages();
475*b1cdbd2cSJim Jagielski if (seqLanguages.getLength() > 0)
476*b1cdbd2cSJim Jagielski aLanguage = seqLanguages[0];
477*b1cdbd2cSJim Jagielski return aLanguage;
478*b1cdbd2cSJim Jagielski }
479*b1cdbd2cSJim Jagielski
getUserLanguage()480*b1cdbd2cSJim Jagielski OUString LanguageSelection::getUserLanguage()
481*b1cdbd2cSJim Jagielski {
482*b1cdbd2cSJim Jagielski OUString aUserLanguage;
483*b1cdbd2cSJim Jagielski Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_False));
484*b1cdbd2cSJim Jagielski if (xAccess.is())
485*b1cdbd2cSJim Jagielski {
486*b1cdbd2cSJim Jagielski try
487*b1cdbd2cSJim Jagielski {
488*b1cdbd2cSJim Jagielski xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
489*b1cdbd2cSJim Jagielski }
490*b1cdbd2cSJim Jagielski catch ( NoSuchElementException const & )
491*b1cdbd2cSJim Jagielski {
492*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
493*b1cdbd2cSJim Jagielski return OUString();
494*b1cdbd2cSJim Jagielski }
495*b1cdbd2cSJim Jagielski catch ( WrappedTargetException const & )
496*b1cdbd2cSJim Jagielski {
497*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
498*b1cdbd2cSJim Jagielski return OUString();
499*b1cdbd2cSJim Jagielski }
500*b1cdbd2cSJim Jagielski }
501*b1cdbd2cSJim Jagielski return aUserLanguage;
502*b1cdbd2cSJim Jagielski }
503*b1cdbd2cSJim Jagielski
getSystemLanguage()504*b1cdbd2cSJim Jagielski OUString LanguageSelection::getSystemLanguage()
505*b1cdbd2cSJim Jagielski {
506*b1cdbd2cSJim Jagielski OUString aUserLanguage;
507*b1cdbd2cSJim Jagielski Reference< XNameAccess > xAccess(getConfigAccess("org.openoffice.System/L10N", sal_False));
508*b1cdbd2cSJim Jagielski if (xAccess.is())
509*b1cdbd2cSJim Jagielski {
510*b1cdbd2cSJim Jagielski try
511*b1cdbd2cSJim Jagielski {
512*b1cdbd2cSJim Jagielski xAccess->getByName(OUString::createFromAscii("UILocale")) >>= aUserLanguage;
513*b1cdbd2cSJim Jagielski }
514*b1cdbd2cSJim Jagielski catch ( NoSuchElementException const & )
515*b1cdbd2cSJim Jagielski {
516*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
517*b1cdbd2cSJim Jagielski return OUString();
518*b1cdbd2cSJim Jagielski }
519*b1cdbd2cSJim Jagielski catch ( WrappedTargetException const & )
520*b1cdbd2cSJim Jagielski {
521*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
522*b1cdbd2cSJim Jagielski return OUString();
523*b1cdbd2cSJim Jagielski }
524*b1cdbd2cSJim Jagielski }
525*b1cdbd2cSJim Jagielski return aUserLanguage;
526*b1cdbd2cSJim Jagielski }
527*b1cdbd2cSJim Jagielski
528*b1cdbd2cSJim Jagielski
resetUserLanguage()529*b1cdbd2cSJim Jagielski void LanguageSelection::resetUserLanguage()
530*b1cdbd2cSJim Jagielski {
531*b1cdbd2cSJim Jagielski try
532*b1cdbd2cSJim Jagielski {
533*b1cdbd2cSJim Jagielski Reference< XPropertySet > xProp(getConfigAccess("org.openoffice.Office.Linguistic/General", sal_True), UNO_QUERY_THROW);
534*b1cdbd2cSJim Jagielski xProp->setPropertyValue(OUString::createFromAscii("UILocale"), makeAny(OUString::createFromAscii("")));
535*b1cdbd2cSJim Jagielski Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
536*b1cdbd2cSJim Jagielski }
537*b1cdbd2cSJim Jagielski catch ( PropertyVetoException& )
538*b1cdbd2cSJim Jagielski {
539*b1cdbd2cSJim Jagielski // we are not allowed to change this
540*b1cdbd2cSJim Jagielski }
541*b1cdbd2cSJim Jagielski catch ( Exception& e)
542*b1cdbd2cSJim Jagielski {
543*b1cdbd2cSJim Jagielski OString aMsg = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
544*b1cdbd2cSJim Jagielski OSL_ENSURE(sal_False, aMsg.getStr());
545*b1cdbd2cSJim Jagielski m_eStatus = LS_STATUS_CONFIGURATIONACCESS_BROKEN;
546*b1cdbd2cSJim Jagielski }
547*b1cdbd2cSJim Jagielski }
548*b1cdbd2cSJim Jagielski
getStatus()549*b1cdbd2cSJim Jagielski LanguageSelection::LanguageSelectionStatus LanguageSelection::getStatus()
550*b1cdbd2cSJim Jagielski {
551*b1cdbd2cSJim Jagielski return m_eStatus;
552*b1cdbd2cSJim Jagielski }
553*b1cdbd2cSJim Jagielski
554*b1cdbd2cSJim Jagielski } // namespace desktop
555