From de85a936fc0f59da8932c3660e57b12aa9663d61 Mon Sep 17 00:00:00 2001 From: "tao%netscape.com" Date: Sun, 31 Mar 2002 07:33:57 +0000 Subject: [PATCH] 44070: match browser and OS locale. r=alecf,sr=hyatt,a=asa. Match browser UI locale and system locale when intl.locale.matchOS == true; Runtime only behavior; won't write to disk. Fallback to default chrome locale when matching langpacks are not installed. --- chrome/public/nsIChromeRegistry.idl | 2 + chrome/src/nsChromeRegistry.cpp | 18 ++++++- chrome/src/nsChromeRegistry.h | 1 + modules/libpref/src/init/all.js | 1 + rdf/chrome/public/nsIChromeRegistry.idl | 2 + rdf/chrome/src/nsChromeRegistry.cpp | 18 ++++++- rdf/chrome/src/nsChromeRegistry.h | 1 + xpfe/bootstrap/Makefile.in | 1 + xpfe/bootstrap/makefile.win | 1 + xpfe/bootstrap/nsAppRunner.cpp | 68 +++++++++++++++++++++++++ 10 files changed, 111 insertions(+), 2 deletions(-) diff --git a/chrome/public/nsIChromeRegistry.idl b/chrome/public/nsIChromeRegistry.idl index f5cce2e0e132..525eb1678863 100644 --- a/chrome/public/nsIChromeRegistry.idl +++ b/chrome/public/nsIChromeRegistry.idl @@ -92,6 +92,8 @@ interface nsIChromeRegistry : nsISupports // Special additional APIs for locales only. void selectLocaleForProfile(in wstring localeName, in wstring profilePath); wstring getSelectedLocale(in wstring packageName); + /* runtimeProvider == true: don't assert the runtime change */ + void setRuntimeProvider(in boolean runtimeProvider); /* Installation APIs */ void installSkin(in string baseURL, in boolean useProfile, in boolean allowScripts); diff --git a/chrome/src/nsChromeRegistry.cpp b/chrome/src/nsChromeRegistry.cpp index 4d7d35cfa3ad..3c9fef95255b 100644 --- a/chrome/src/nsChromeRegistry.cpp +++ b/chrome/src/nsChromeRegistry.cpp @@ -249,6 +249,7 @@ nsChromeRegistry::nsChromeRegistry() mUseXBLForms = PR_FALSE; mBatchInstallFlushes = PR_FALSE; + mRuntimeProvider = PR_FALSE; nsCOMPtr prefService(do_GetService(kPrefServiceCID)); if (prefService) @@ -1521,6 +1522,15 @@ NS_IMETHODIMP nsChromeRegistry::SelectLocaleForProfile(const PRUnichar *aLocale, return SetProvider(nsCAutoString("locale"), mSelectedLocale, aLocale, PR_TRUE, NS_ConvertUCS2toUTF8(aProfilePath).get(), PR_TRUE); } +/* void setRuntimeProvider (in boolean runtimeProvider); */ +// should we inline this one? +NS_IMETHODIMP nsChromeRegistry::SetRuntimeProvider(PRBool runtimeProvider) +{ + mRuntimeProvider = runtimeProvider; + return NS_OK; +} + + /* wstring getSelectedLocale (); */ NS_IMETHODIMP nsChromeRegistry::GetSelectedLocale(const PRUnichar *aPackageName, PRUnichar **_retval) @@ -1721,8 +1731,14 @@ nsChromeRegistry::SetProviderForPackage(const nsCString& aProvider, nsCOMPtr remote = do_QueryInterface(dataSource, &rv); if (NS_FAILED(rv)) return rv; - if (!mBatchInstallFlushes) + // add one more check: + // assert the data source only when we are not setting runtime-only provider + if (!mBatchInstallFlushes && !mRuntimeProvider) rv = remote->Flush(); + + // always reset the flag + mRuntimeProvider = PR_FALSE; + return rv; } diff --git a/chrome/src/nsChromeRegistry.h b/chrome/src/nsChromeRegistry.h index 4b3d35ab221a..5d4109a779a7 100644 --- a/chrome/src/nsChromeRegistry.h +++ b/chrome/src/nsChromeRegistry.h @@ -188,6 +188,7 @@ protected: PRBool mProfileInitialized; PRBool mUseXBLForms; + PRBool mRuntimeProvider; nsCString mProfileRoot; nsCString mInstallRoot; diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 5e7d056bfc2e..23a75b4bdb83 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -547,6 +547,7 @@ pref("intl.charsetmenu.browser.cache.size", 5); pref("intl.charset.detector", "chrome://navigator/locale/navigator.properties"); pref("intl.charset.default", "chrome://navigator-platform/locale/navigator.properties"); pref("intl.content.langcode", "chrome://communicator-region/locale/region.properties"); +pref("intl.locale.matchOS", true); pref("font.language.group", "chrome://navigator/locale/navigator.properties"); // -- folders (Mac: these are binary aliases.) diff --git a/rdf/chrome/public/nsIChromeRegistry.idl b/rdf/chrome/public/nsIChromeRegistry.idl index f5cce2e0e132..525eb1678863 100644 --- a/rdf/chrome/public/nsIChromeRegistry.idl +++ b/rdf/chrome/public/nsIChromeRegistry.idl @@ -92,6 +92,8 @@ interface nsIChromeRegistry : nsISupports // Special additional APIs for locales only. void selectLocaleForProfile(in wstring localeName, in wstring profilePath); wstring getSelectedLocale(in wstring packageName); + /* runtimeProvider == true: don't assert the runtime change */ + void setRuntimeProvider(in boolean runtimeProvider); /* Installation APIs */ void installSkin(in string baseURL, in boolean useProfile, in boolean allowScripts); diff --git a/rdf/chrome/src/nsChromeRegistry.cpp b/rdf/chrome/src/nsChromeRegistry.cpp index 4d7d35cfa3ad..3c9fef95255b 100644 --- a/rdf/chrome/src/nsChromeRegistry.cpp +++ b/rdf/chrome/src/nsChromeRegistry.cpp @@ -249,6 +249,7 @@ nsChromeRegistry::nsChromeRegistry() mUseXBLForms = PR_FALSE; mBatchInstallFlushes = PR_FALSE; + mRuntimeProvider = PR_FALSE; nsCOMPtr prefService(do_GetService(kPrefServiceCID)); if (prefService) @@ -1521,6 +1522,15 @@ NS_IMETHODIMP nsChromeRegistry::SelectLocaleForProfile(const PRUnichar *aLocale, return SetProvider(nsCAutoString("locale"), mSelectedLocale, aLocale, PR_TRUE, NS_ConvertUCS2toUTF8(aProfilePath).get(), PR_TRUE); } +/* void setRuntimeProvider (in boolean runtimeProvider); */ +// should we inline this one? +NS_IMETHODIMP nsChromeRegistry::SetRuntimeProvider(PRBool runtimeProvider) +{ + mRuntimeProvider = runtimeProvider; + return NS_OK; +} + + /* wstring getSelectedLocale (); */ NS_IMETHODIMP nsChromeRegistry::GetSelectedLocale(const PRUnichar *aPackageName, PRUnichar **_retval) @@ -1721,8 +1731,14 @@ nsChromeRegistry::SetProviderForPackage(const nsCString& aProvider, nsCOMPtr remote = do_QueryInterface(dataSource, &rv); if (NS_FAILED(rv)) return rv; - if (!mBatchInstallFlushes) + // add one more check: + // assert the data source only when we are not setting runtime-only provider + if (!mBatchInstallFlushes && !mRuntimeProvider) rv = remote->Flush(); + + // always reset the flag + mRuntimeProvider = PR_FALSE; + return rv; } diff --git a/rdf/chrome/src/nsChromeRegistry.h b/rdf/chrome/src/nsChromeRegistry.h index 4b3d35ab221a..5d4109a779a7 100644 --- a/rdf/chrome/src/nsChromeRegistry.h +++ b/rdf/chrome/src/nsChromeRegistry.h @@ -188,6 +188,7 @@ protected: PRBool mProfileInitialized; PRBool mUseXBLForms; + PRBool mRuntimeProvider; nsCString mProfileRoot; nsCString mInstallRoot; diff --git a/xpfe/bootstrap/Makefile.in b/xpfe/bootstrap/Makefile.in index f8de31c3c261..c2f4fb2296ff 100644 --- a/xpfe/bootstrap/Makefile.in +++ b/xpfe/bootstrap/Makefile.in @@ -50,6 +50,7 @@ REQUIRES = xpcom \ browser \ docshell \ uconv \ + locale \ xremoteservice \ $(NULL) # for jprof diff --git a/xpfe/bootstrap/makefile.win b/xpfe/bootstrap/makefile.win index 53f2cf228477..c485d4358002 100644 --- a/xpfe/bootstrap/makefile.win +++ b/xpfe/bootstrap/makefile.win @@ -43,6 +43,7 @@ REQUIRES = xpcom \ gfx \ intl \ uconv \ + locale \ profile \ xpconnect \ $(NULL) diff --git a/xpfe/bootstrap/nsAppRunner.cpp b/xpfe/bootstrap/nsAppRunner.cpp index 0a6d8e9ff2cb..82557da73ee2 100644 --- a/xpfe/bootstrap/nsAppRunner.cpp +++ b/xpfe/bootstrap/nsAppRunner.cpp @@ -43,6 +43,7 @@ #include "nsIURI.h" #include "nsNetUtil.h" #include "nsIPref.h" +#include "nsILocaleService.h" #include "plevent.h" #include "prmem.h" #include "prnetdb.h" @@ -234,6 +235,7 @@ static nsresult InitializeProfileService(nsICmdLineService *cmdLineArgs); // Install global locale if possible static nsresult InstallGlobalLocale(nsICmdLineService *cmdLineArgs); +static nsresult getUILangCountry(nsAString& aUILang, nsAString& aCountry); class stTSMCloser { @@ -959,11 +961,59 @@ static nsresult Ensure1Window( nsICmdLineService* cmdLineArgs) return rv; } +// match OS locale +static char kMatchOSLocalePref[] = "intl.locale.matchOS"; + +nsresult +getCountry(const nsAString& lc_name, nsAString& aCountry) +{ + + nsresult result = NS_OK; + + PRInt32 dash = lc_name.FindChar('-'); + if (dash > 0) + aCountry = Substring(lc_name, dash+1, lc_name.Length()-dash); + else + result = NS_ERROR_FAILURE; + + return result; +} + +static nsresult +getUILangCountry(nsAString& aUILang, nsAString& aCountry) +{ + nsresult result; + // get a locale service + nsCOMPtr localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &result); + NS_ASSERTION(NS_SUCCEEDED(result),"getUILangCountry: get locale service failed"); + + nsXPIDLString uiLang; + result = localeService->GetLocaleComponentForUserAgent(getter_Copies(uiLang)); + aUILang = uiLang; + result = getCountry(aUILang, aCountry); + return result; +} + // update global locale if possible (in case when user-*.rdf can be updated) // so that any apps after this can be invoked in the UILocale and contentLocale static nsresult InstallGlobalLocale(nsICmdLineService *cmdLineArgs) { nsresult rv = NS_OK; + + // check the pref first + nsCOMPtr prefService(do_GetService("@mozilla.org/preferences;1")); + PRBool matchOS = PR_FALSE; + if (prefService) + prefService->GetBoolPref(kMatchOSLocalePref, &matchOS); + + // match os locale + nsAutoString uiLang; + nsAutoString country; + if (matchOS) { + // compute lang and region code only when needed! + rv = getUILangCountry(uiLang, country); + } + nsXPIDLCString cmdUI; rv = cmdLineArgs->GetCmdLineValue(UILOCALE_CMD_LINE_ARG, getter_Copies(cmdUI)); if (NS_SUCCEEDED(rv)){ @@ -975,6 +1025,15 @@ static nsresult InstallGlobalLocale(nsICmdLineService *cmdLineArgs) rv = chromeRegistry->SelectLocale(UILocaleName.get(), PR_FALSE); } } + // match OS when no cmdline override + if (!cmdUI && matchOS) { + nsCOMPtr chromeRegistry = do_GetService(kChromeRegistryCID, &rv); + if (chromeRegistry) { + chromeRegistry->SetRuntimeProvider(PR_TRUE); + rv = chromeRegistry->SelectLocale(uiLang.get(), PR_FALSE); + } + } + nsXPIDLCString cmdContent; rv = cmdLineArgs->GetCmdLineValue(CONTENTLOCALE_CMD_LINE_ARG, getter_Copies(cmdContent)); if (NS_SUCCEEDED(rv)){ @@ -986,6 +1045,15 @@ static nsresult InstallGlobalLocale(nsICmdLineService *cmdLineArgs) rv = chromeRegistry->SelectLocale(ContentLocaleName.get(), PR_FALSE); } } + // match OS when no cmdline override + if (!cmdContent && matchOS) { + nsCOMPtr chromeRegistry = do_GetService(kChromeRegistryCID, &rv); + if (chromeRegistry) { + chromeRegistry->SetRuntimeProvider(PR_TRUE); + rv = chromeRegistry->SelectLocale(country.get(), PR_FALSE); + } + } + return NS_OK; }