From 76820dab277f48b9d252304a424d9d4c2e69b53f Mon Sep 17 00:00:00 2001 From: "cata%netscape.com" Date: Thu, 13 Jan 2000 23:52:50 +0000 Subject: [PATCH] Charset menu code. Bugs #15867, #15034. r=ftang --- intl/uconv/src/nsCharsetConverterManager.cpp | 97 +++++++++---- intl/uconv/src/nsCharsetMenu.cpp | 138 ++++++++++++++----- intl/uconv/src/nsUConvDll.h | 3 + intl/uconv/src/nsUConvModule.cpp | 2 + 4 files changed, 179 insertions(+), 61 deletions(-) diff --git a/intl/uconv/src/nsCharsetConverterManager.cpp b/intl/uconv/src/nsCharsetConverterManager.cpp index 3da575f6587..ac78a558f38 100644 --- a/intl/uconv/src/nsCharsetConverterManager.cpp +++ b/intl/uconv/src/nsCharsetConverterManager.cpp @@ -33,6 +33,7 @@ #include "nsIUnicodeEncodeHelper.h" static NS_DEFINE_IID(kRegistryNodeIID, NS_IREGISTRYNODE_IID); +static NS_DEFINE_CID(kRegistryCID, NS_REGISTRY_CID); //---------------------------------------------------------------------------- // Class nsObject [declaration] @@ -114,13 +115,17 @@ private: nsresult GetConverterList(nsObjectArray * aArray, nsString *** aResult, PRInt32 * aCount); - static nsresult RegisterConverterPresenceData(char * aRegistryPath, - PRBool aPresence); + static nsresult RegisterConverterTitles(nsIRegistry * aRegistry, + char * aRegistryPath); + + static nsresult RegisterConverterData(nsIRegistry * aRegistry, + char * aRegistryPath); public: nsCharsetConverterManager(); virtual ~nsCharsetConverterManager(); + static nsresult RegisterConverterManagerData(); //-------------------------------------------------------------------------- @@ -163,6 +168,11 @@ NS_IMETHODIMP NS_NewCharsetConverterManager(nsISupports* aOuter, return res; } +NS_IMETHODIMP NS_RegisterConverterManagerData() +{ + return nsCharsetConverterManager::RegisterConverterManagerData(); +} + //---------------------------------------------------------------------------- // Class nsObject [implementation] @@ -274,49 +284,65 @@ nsCharsetConverterManager::~nsCharsetConverterManager() nsresult nsCharsetConverterManager::RegisterConverterManagerData() { + nsresult res = NS_OK; + + NS_WITH_SERVICE(nsIRegistry, registry, kRegistryCID, &res); + if (NS_FAILED(res)) return res; + + // open registry if necessary + PRBool regOpen = PR_FALSE; + registry->IsOpen(®Open); + if (!regOpen) { + res = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry); + if (NS_FAILED(res)) return res; + } + // XXX take these konstants out of here // XXX change "xuconv" to "uconv" when the new enc&dec trees are in place - RegisterConverterPresenceData("software/netscape/intl/xuconv/not-for-browser", PR_FALSE); + RegisterConverterTitles(registry, "software/netscape/intl/xuconv/titles/"); + RegisterConverterData(registry, "software/netscape/intl/xuconv/data/"); return NS_OK; } -nsresult nsCharsetConverterManager::RegisterConverterPresenceData( - char * aRegistryPath, - PRBool aPresence) +nsresult nsCharsetConverterManager::RegisterConverterTitles( + nsIRegistry * aRegistry, + char * aRegistryPath) { nsresult res; - nsIRegistry * registry = NULL; nsRegistryKey key; - // get the registry - res = nsServiceManager::GetService(NS_REGISTRY_PROGID, - nsIRegistry::GetIID(), (nsISupports**)®istry); - if (NS_FAILED(res)) goto done; + nsAutoString str(aRegistryPath); + str.Append("defaultFile"); - // open the registry - res = registry->OpenWellKnownRegistry( - nsIRegistry::ApplicationComponentRegistry); - if (NS_FAILED(res)) goto done; + char * p = str.ToNewCString(); + res = aRegistry->AddSubtree(nsIRegistry::Common, p, &key); + nsAllocator::Free(p); + if (NS_FAILED(res)) return res; + res = aRegistry->SetString(key, "name", "resource:/res/charsetTitles.properties"); + if (NS_FAILED(res)) return res; - res = registry -> AddSubtree(nsIRegistry::Common, aRegistryPath, &key); - if (NS_FAILED(res)) goto done; + return NS_OK; +} - // XXX instead of these hardcoded values, I should read from a property file - res = registry -> SetInt(key, "x-fake-1999", 1); - if (NS_FAILED(res)) goto done; - res = registry -> SetInt(key, "x-fake-2000", 1); - if (NS_FAILED(res)) goto done; - res = registry -> SetInt(key, "x-euc-tw", 1); - if (NS_FAILED(res)) goto done; +nsresult nsCharsetConverterManager::RegisterConverterData( + nsIRegistry * aRegistry, + char * aRegistryPath) +{ + nsresult res; + nsRegistryKey key; -done: - if (registry != NULL) { - registry -> Close(); - nsServiceManager::ReleaseService(NS_REGISTRY_PROGID, registry); - } + nsAutoString str(aRegistryPath); + str.Append("defaultFile"); - return res; + char * p = str.ToNewCString(); + res = aRegistry->AddSubtree(nsIRegistry::Common, p, &key); + nsAllocator::Free(p); + if (NS_FAILED(res)) return res; + res = aRegistry->SetString(key, "name", "resource:/res/charsetData.properties"); + if (NS_FAILED(res)) return res; + + return NS_OK; } // XXX rethink the registry structure(tree) for these converters @@ -330,12 +356,20 @@ void nsCharsetConverterManager::FillInfoArrays() nsIEnumerator * components = NULL; nsIRegistry * registry = NULL; nsRegistryKey uconvKey, key; + PRBool regOpen = PR_FALSE; // get the registry res = nsServiceManager::GetService(NS_REGISTRY_PROGID, nsIRegistry::GetIID(), (nsISupports**)®istry); if (NS_FAILED(res)) goto done; + // open registry if necessary + registry->IsOpen(®Open); + if (!regOpen) { + res = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry); + if (NS_FAILED(res)) goto done; + } + // get subtree res = registry->GetSubtree(nsIRegistry::Common, "software/netscape/intl/uconv", &uconvKey); @@ -377,11 +411,14 @@ void nsCharsetConverterManager::FillInfoArrays() res = registry->GetString(key, "destination", &dest); if (NS_FAILED(res)) goto done1; + // XXX do an alias resolution here instead if (!strcmp(src, "Unicode")) { ci->mName = new nsString(dest); + ci->mName->ToLowerCase(); mEncoderArray.AddObject(ci); } else if (!strcmp(dest, "Unicode")) { ci->mName = new nsString(src); + ci->mName->ToLowerCase(); mDecoderArray.AddObject(ci); } else goto done1; diff --git a/intl/uconv/src/nsCharsetMenu.cpp b/intl/uconv/src/nsCharsetMenu.cpp index 41d6591c45f..7c564c7058a 100644 --- a/intl/uconv/src/nsCharsetMenu.cpp +++ b/intl/uconv/src/nsCharsetMenu.cpp @@ -31,6 +31,9 @@ #include "nsUConvDll.h" #include "nsCharsetMenu.h" #include "nsICharsetConverterManager.h" +#include "nsIStringBundle.h" +#include "nsILocaleFactory.h" +#include "nsLocaleCID.h" static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); @@ -41,6 +44,8 @@ static NS_DEFINE_CID(kRDFContainerUtilsCID, NS_RDFCONTAINERUTILS_CID); static NS_DEFINE_CID(kRDFContainerCID, NS_RDFCONTAINER_CID); static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); static NS_DEFINE_IID(kICharsetConverterManagerIID, NS_ICHARSETCONVERTERMANAGER_IID); +static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID); +static NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID); static const char * kURINC_BSCharsetMenuRoot = "NC:BSCharsetMenuRoot"; static const char * kURINC_BDCharsetMenuRoot = "NC:BDCharsetMenuRoot"; @@ -71,14 +76,20 @@ private: nsresult Init(); nsresult Done(); nsresult CreateBrowserMenu(); - nsresult CreateBrowserMoreMenu(); - nsresult CreateBrowserStaticMenu(); - nsresult FillRDFContainer(nsIRDFResource * aResource, nsString ** aList, - PRInt32 aCount); + nsresult CreateBrowserMoreMenu(nsIRDFService * aRDFServ, + nsIStringBundle * aTitles, nsIStringBundle * aData); + nsresult CreateBrowserStaticMenu(nsIRDFService * aRDFServ, + nsIStringBundle * aTitles, nsIStringBundle * aData); + nsresult FillRDFContainer(nsIRDFService * aRDFServ, nsIRDFResource * aResource, + nsIStringBundle * aTitles, nsString ** aList, PRInt32 aCount); + nsresult RemoveFlaggedCharsets(nsString ** aList, PRInt32 aCount, + nsIStringBundle * aData, char * aProp, PRBool value); nsresult NewRDFContainer(nsIRDFDataSource * aDataSource, nsIRDFResource * aResource, nsIRDFContainer ** aResult); + nsresult GetAppLocale(nsILocale ** aLocale); + public: nsCharsetMenu(); virtual ~nsCharsetMenu(); @@ -256,36 +267,40 @@ done: return res; } -nsresult nsCharsetMenu::FillRDFContainer(nsIRDFResource * aResource, +nsresult nsCharsetMenu::FillRDFContainer(nsIRDFService * aRDFServ, + nsIRDFResource * aResource, + nsIStringBundle * aTitles, nsString ** aList, PRInt32 aCount) { nsresult res = NS_OK; - nsIRDFService * rdfServ = NULL; nsCOMPtr node; nsCOMPtr container; PRInt32 i; - res = nsServiceManager::GetService(kRDFServiceCID, kIRDFServiceIID, - (nsISupports **)&rdfServ); - if (NS_FAILED(res)) goto done; - res = NewRDFContainer(mInner, aResource, getter_AddRefs(container)); - if (NS_FAILED(res)) goto done; + if (NS_FAILED(res)) return res; for (i = 0; i < aCount; i++) { - nsString * str = aList[i]; - if (str == NULL) continue; + nsString * cs = aList[i]; + if (cs == NULL) continue; // Make up a unique ID and create the RDF NODE - char cID[256]; - str->ToCString(cID, 256); - res = rdfServ->GetResource(cID, getter_AddRefs(node)); + char csID[256]; + cs->ToCString(csID, 256); + res = aRDFServ->GetResource(csID, getter_AddRefs(node)); if (NS_FAILED(res)) continue; - // Get the RDF literal and add it to our node - // XXX here get and use the human readable name for this charset + nsAutoString csKey(cs->GetUnicode()); + csKey.Append(".title"); + + PRUnichar * title = NULL; + if (aTitles != NULL) + aTitles->GetStringFromName(csKey.GetUnicode(), &title); + if (title == NULL) + title = (PRUnichar *)cs->GetUnicode(); + nsCOMPtr titleLiteral; - res = rdfServ->GetLiteral(str->GetUnicode(), getter_AddRefs(titleLiteral)); + res = aRDFServ->GetLiteral(title, getter_AddRefs(titleLiteral)); if (NS_FAILED(res)) continue; res = Assert(node, kNC_Name, titleLiteral, PR_TRUE); if (NS_FAILED(res)) continue; @@ -295,21 +310,65 @@ nsresult nsCharsetMenu::FillRDFContainer(nsIRDFResource * aResource, if (NS_FAILED(res)) continue; } -done: - if (rdfServ != NULL) nsServiceManager::ReleaseService(kRDFServiceCID, rdfServ); + return res; +} + +nsresult nsCharsetMenu::RemoveFlaggedCharsets(nsString ** aList, PRInt32 aCount, + nsIStringBundle * aData, + char * aProp, PRBool value) +{ + nsresult res = NS_OK; + + for (PRInt32 i = 0; i < aCount; i++) { + nsString * cs = aList[i]; + if (cs == NULL) continue; + + nsAutoString csKey(cs->GetUnicode()); + csKey.Append(aProp); + + PRUnichar * data = NULL; + if (aData != NULL) + aData->GetStringFromName(csKey.GetUnicode(), &data); + if (data == NULL) continue; + + aList[i] = NULL; + } return res; } +// XXX change "xuconv" to "uconv" when the new enc&dec trees are in place nsresult nsCharsetMenu::CreateBrowserMenu() { - CreateBrowserMoreMenu(); - CreateBrowserStaticMenu(); + nsresult res = NS_OK; + nsCOMPtr titles = nsnull; + nsCOMPtr data = nsnull; + nsCOMPtr locale = nsnull; + + NS_WITH_SERVICE(nsIRDFService, rdfServ, kRDFServiceCID, &res); + if (NS_FAILED(res)) return res; + + NS_WITH_SERVICE(nsIStringBundleService, sbServ, kStringBundleServiceCID, &res); + if (NS_FAILED(res)) return res; + + res = GetAppLocale(getter_AddRefs(locale)); + if (NS_FAILED(res)) return res; + + res = sbServ->CreateExtensibleBundle("software/netscape/intl/xuconv/titles/", locale, getter_AddRefs(titles)); + if (NS_FAILED(res)) return res; + + res = sbServ->CreateExtensibleBundle("software/netscape/intl/xuconv/data/", locale, getter_AddRefs(data)); + if (NS_FAILED(res)) return res; + + CreateBrowserMoreMenu(rdfServ, titles, data); + CreateBrowserStaticMenu(rdfServ, titles, data); return NS_OK; } -nsresult nsCharsetMenu::CreateBrowserMoreMenu() +nsresult nsCharsetMenu::CreateBrowserMoreMenu(nsIRDFService * aRDFServ, + nsIStringBundle * aTitles, + nsIStringBundle * aData) { nsresult res = NS_OK; nsICharsetConverterManager * ccMan = NULL; @@ -323,9 +382,10 @@ nsresult nsCharsetMenu::CreateBrowserMoreMenu() res = ccMan->GetDecoderList(&decs, &count); if (NS_FAILED(res)) goto done; - // XXX put the flagged charsets on null + // put the flagged charsets on null + RemoveFlaggedCharsets(decs, count, aData, ".notForBrowser", PR_TRUE); - res = FillRDFContainer(kNC_BMCharsetMenuRoot, decs, count); + res = FillRDFContainer(aRDFServ, kNC_BMCharsetMenuRoot, aTitles, decs, count); if (NS_FAILED(res)) goto done; done: @@ -336,17 +396,19 @@ done: return res; } -nsresult nsCharsetMenu::CreateBrowserStaticMenu() +nsresult nsCharsetMenu::CreateBrowserStaticMenu(nsIRDFService * aRDFServ, + nsIStringBundle * aTitles, + nsIStringBundle * aData) { nsresult res = NS_OK; PRInt32 count = 2; nsString ** decs = new nsString * [count]; - decs[0] = new nsString("UTF-8"); - decs[1] = new nsString("Shift-JIS"); + decs[0] = new nsString("utf-8"); + decs[1] = new nsString("shift_jis"); - // XXX put the flagged charsets on null + // note that we allow ALL the charsets to be placed here! - res = FillRDFContainer(kNC_BSCharsetMenuRoot, decs, count); + res = FillRDFContainer(aRDFServ, kNC_BSCharsetMenuRoot, aTitles, decs, count); if (NS_FAILED(res)) goto done; done: @@ -376,6 +438,20 @@ nsresult nsCharsetMenu::NewRDFContainer(nsIRDFDataSource * aDataSource, return res; } +nsresult nsCharsetMenu::GetAppLocale(nsILocale ** aLocale) +{ + nsresult res = NS_OK; + nsILocaleFactory * localeFactory; + + res = nsComponentManager::FindFactory(kLocaleFactoryCID, + (nsIFactory**)&localeFactory); + if (NS_FAILED(res)) return res; + + res = localeFactory->GetApplicationLocale(aLocale); + NS_RELEASE(localeFactory); + return res; +} + //---------------------------------------------------------------------------- // Interface nsIRDFDataSource [implementation] diff --git a/intl/uconv/src/nsUConvDll.h b/intl/uconv/src/nsUConvDll.h index c744488c5c9..ded115065b1 100644 --- a/intl/uconv/src/nsUConvDll.h +++ b/intl/uconv/src/nsUConvDll.h @@ -58,4 +58,7 @@ NS_IMETHODIMP NS_NewTextToSubURI(nsISupports* aOuter, const nsIID& aIID, void** aResult); +NS_IMETHODIMP +NS_RegisterConverterManagerData(); + #endif /* nsUConvDll_h___ */ diff --git a/intl/uconv/src/nsUConvModule.cpp b/intl/uconv/src/nsUConvModule.cpp index 7ba2822060e..30b425bc287 100644 --- a/intl/uconv/src/nsUConvModule.cpp +++ b/intl/uconv/src/nsUConvModule.cpp @@ -201,6 +201,8 @@ nsUConvModule::RegisterSelf(nsIComponentManager *aCompMgr, cp++; } + rv = NS_RegisterConverterManagerData(); + return rv; }