diff --git a/headers/private/locale/DefaultCatalog.h b/headers/private/locale/DefaultCatalog.h index 80939f41ee..34d17ebdc8 100644 --- a/headers/private/locale/DefaultCatalog.h +++ b/headers/private/locale/DefaultCatalog.h @@ -61,6 +61,10 @@ class DefaultCatalog : public BHashMapCatalog { mutable BString fPath; }; +extern "C" status_t +default_catalog_get_available_languages(BMessage* availableLanguages, + const char* sigPattern, const char* langPattern = NULL, + int32 fingerprint = 0); } // namespace BPrivate diff --git a/src/add-ons/locale/catalogs/plaintext/Catalog.cpp b/src/add-ons/locale/catalogs/plaintext/Catalog.cpp index da4079a1c4..efc9fbd839 100644 --- a/src/add-ons/locale/catalogs/plaintext/Catalog.cpp +++ b/src/add-ons/locale/catalogs/plaintext/Catalog.cpp @@ -417,9 +417,8 @@ instantiate_catalog(const char *signature, const char *language, } -extern "C" -BCatalogAddOn *create_catalog(const char *signature, - const char *language) +extern "C" BCatalogAddOn * +create_catalog(const char *signature, const char *language) { PlainTextCatalog *catalog = new(std::nothrow) PlainTextCatalog("emptycat", signature, language); @@ -427,5 +426,15 @@ BCatalogAddOn *create_catalog(const char *signature, } +extern "C" status_t +get_available_languages(BMessage* availableLanguages, + const char* sigPattern = NULL, const char* langPattern = NULL, + int32 fingerprint = 0) +{ + // TODO + return B_ERROR; +} + + uint8 gCatalogAddOnPriority = 99; // give low priority to this add on, we don't want it to be actually used diff --git a/src/apps/readonlybootprompt/BootPromptWindow.cpp b/src/apps/readonlybootprompt/BootPromptWindow.cpp index 3cb4d96380..054c016825 100644 --- a/src/apps/readonlybootprompt/BootPromptWindow.cpp +++ b/src/apps/readonlybootprompt/BootPromptWindow.cpp @@ -266,36 +266,33 @@ BootPromptWindow::_PopulateLanguages() firstPreferredLanguage = "en"; } -// TODO: Use this API instead once it's ready. -// BMessage installedCatalogs; -// be_locale_roster->GetInstalledCatalogs(&installedCatalogs); -// installedCatalogs.PrintToStream(); + BMessage installedCatalogs; + be_locale_roster->GetInstalledCatalogs(&installedCatalogs, + "x-vnd.Haiku-ReadOnlyBootPrompt"); // Try to instantiate a BCatalog for each language, it will only work // for translations of this application. So the list of languages will be // limited to catalogs written for this application, which is on purpose! + const char* languageString; for (int32 i = 0; - fInstalledLanguages.FindString("langs", i, &languageString) == B_OK; + installedCatalogs.FindString("langs", i, &languageString) == B_OK; i++) { - BCatalog catalog("x-vnd.Haiku-ReadOnlyBootPrompt", languageString); - if (catalog.InitCheck() == B_OK) { - BLanguage* language; - if (be_locale_roster->GetLanguage(&language, - BString(languageString)) == B_OK) { - BString name; - language->GetName(&name); - LanguageItem* item = new LanguageItem(name.String(), - languageString); - fLanguagesListView->AddItem(item); - // Select this item if it is the first preferred language - if (strcmp(firstPreferredLanguage, languageString) == 0) { - fLanguagesListView->Select( - fLanguagesListView->CountItems() - 1); - } - } else - printf("failed to get BLanguage for %s\n", languageString); - } + BLanguage* language; + if (be_locale_roster->GetLanguage(&language, + BString(languageString)) == B_OK) { + BString name; + language->GetName(&name); + LanguageItem* item = new LanguageItem(name.String(), + languageString); + fLanguagesListView->AddItem(item); + // Select this item if it is the first preferred language + if (strcmp(firstPreferredLanguage, languageString) == 0) { + fLanguagesListView->Select( + fLanguagesListView->CountItems() - 1); + } + } else + printf("failed to get BLanguage for %s\n", languageString); } // Re-enable sending the selection message. diff --git a/src/kits/locale/DefaultCatalog.cpp b/src/kits/locale/DefaultCatalog.cpp index 953164da34..ab415664ba 100644 --- a/src/kits/locale/DefaultCatalog.cpp +++ b/src/kits/locale/DefaultCatalog.cpp @@ -575,3 +575,64 @@ DefaultCatalog::Create(const char *signature, const char *language) } return catalog; } + +extern "C" status_t +default_catalog_get_available_languages(BMessage* availableLanguages, + const char* sigPattern, const char* langPattern = NULL, + int32 fingerprint = 0) +{ + if (availableLanguages == NULL || sigPattern == NULL) + return B_BAD_DATA; + + app_info appInfo; + be_app->GetAppInfo(&appInfo); + node_ref nref; + nref.device = appInfo.ref.device; + nref.node = appInfo.ref.directory; + BDirectory appDir(&nref); + BString catalogName("locale/"); + catalogName << kCatFolder + << "/" << sigPattern ; + BPath catalogPath(&appDir, catalogName.String()); + BEntry file(catalogPath.Path()); + BDirectory dir(&file); + + char fileName[B_FILE_NAME_LENGTH]; + while(dir.GetNextEntry(&file) == B_OK) { + file.GetName(fileName); + BString langName(fileName); + langName.Replace(kCatExtension,"",1); + availableLanguages->AddString("langs",langName); + } + + // search in data folders + + directory_which which[] = { + B_USER_DATA_DIRECTORY, + B_COMMON_DATA_DIRECTORY, + B_SYSTEM_DATA_DIRECTORY + }; + + for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) { + BPath path; + if (find_directory(which[i], &path) == B_OK) { + catalogName = BString("locale/") + << kCatFolder + << "/" << sigPattern; + + BPath catalogPath(path.Path(), catalogName.String()); + BEntry file(catalogPath.Path()); + BDirectory dir(&file); + + char fileName[B_FILE_NAME_LENGTH]; + while(dir.GetNextEntry(&file) == B_OK) { + file.GetName(fileName); + BString langName(fileName); + langName.Replace(kCatExtension,"",1); + availableLanguages->AddString("langs",langName); + } + } + } + + return B_OK; +} diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index e8d6601255..b3969129c8 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -47,6 +47,9 @@ typedef BCatalogAddOn *(*CreateCatalogFunc)(const char *name, typedef BCatalogAddOn *(*InstantiateEmbeddedCatalogFunc)( entry_ref *appOrAddOnRef); + +typedef status_t (*GetAvailableLanguagesFunc)(BMessage*, const char*, + const char*, int32); static BLocaleRoster gLocaleRoster; BLocaleRoster *be_locale_roster = &gLocaleRoster; @@ -62,6 +65,7 @@ struct BCatalogAddOnInfo { InstantiateCatalogFunc fInstantiateFunc; InstantiateEmbeddedCatalogFunc fInstantiateEmbeddedFunc; CreateCatalogFunc fCreateFunc; + GetAvailableLanguagesFunc fLanguagesFunc; uint8 fPriority; BList fLoadedCatalogs; bool fIsEmbedded; @@ -84,6 +88,7 @@ BCatalogAddOnInfo::BCatalogAddOnInfo(const BString& name, const BString& path, fInstantiateFunc(NULL), fInstantiateEmbeddedFunc(NULL), fCreateFunc(NULL), + fLanguagesFunc(NULL), fPriority(priority), fIsEmbedded(path.Length()==0) { @@ -118,6 +123,8 @@ BCatalogAddOnInfo::MakeSureItsLoaded() B_SYMBOL_TYPE_TEXT, (void **)&fInstantiateEmbeddedFunc); get_image_symbol(fAddOnImage, "create_catalog", B_SYMBOL_TYPE_TEXT, (void **)&fCreateFunc); + get_image_symbol(fAddOnImage, "get_available_languages", + B_SYMBOL_TYPE_TEXT, (void **)&fLanguagesFunc); log_team(LOG_DEBUG, "catalog-add-on %s has been loaded", fName.String()); } else { @@ -125,6 +132,9 @@ BCatalogAddOnInfo::MakeSureItsLoaded() fName.String(), strerror(fAddOnImage)); return false; } + } else if (fIsEmbedded) { + // The built-in catalog still has to provide this function + fLanguagesFunc = default_catalog_get_available_languages; } return true; } @@ -139,6 +149,7 @@ BCatalogAddOnInfo::UnloadIfPossible() fInstantiateFunc = NULL; fInstantiateEmbeddedFunc = NULL; fCreateFunc = NULL; + fLanguagesFunc = NULL; log_team(LOG_DEBUG, "catalog-add-on %s has been unloaded", fName.String()); } @@ -533,6 +544,29 @@ BLocaleRoster::GetInstalledLanguages(BMessage *languages) const } +status_t +BLocaleRoster::GetInstalledCatalogs(BMessage * languageList, const char* sigPattern, + const char* langPattern, int32 fingerprint) const +{ + if (languageList == NULL) + return B_BAD_VALUE; + + int32 count = gRosterData.fCatalogAddOnInfos.CountItems(); + for (int32 i = 0; i < count; ++i) { + BCatalogAddOnInfo *info + = (BCatalogAddOnInfo*)gRosterData.fCatalogAddOnInfos.ItemAt(i); + + if (!info->MakeSureItsLoaded() || !info->fInstantiateFunc) + continue; + + info->fLanguagesFunc(languageList, sigPattern, langPattern, + fingerprint); + } + + return B_OK; +} + + /* * creates a new (empty) catalog of the given type (the request is dispatched * to the appropriate add-on).