+
+wxArrayString wxFileTranslationsLoader::GetAvailableTranslations(const wxString& domain) const
+{
+ wxArrayString langs;
+ const wxArrayString prefixes = GetSearchPrefixes();
+
+ wxLogTrace(TRACE_I18N,
+ "looking for available translations of \"%s\" in search path \"%s\"",
+ domain, wxJoin(prefixes, wxPATH_SEP[0]));
+
+ for ( wxArrayString::const_iterator i = prefixes.begin();
+ i != prefixes.end();
+ ++i )
+ {
+ if ( i->empty() )
+ continue;
+ wxDir dir;
+ if ( !dir.Open(*i) )
+ continue;
+
+ wxString lang;
+ for ( bool ok = dir.GetFirst(&lang, "", wxDIR_DIRS);
+ ok;
+ ok = dir.GetNext(&lang) )
+ {
+ const wxString langdir = *i + wxFILE_SEP_PATH + lang;
+ if ( HasMsgCatalogInDir(langdir, domain) )
+ {
+#ifdef __WXOSX__
+ wxString rest;
+ if ( lang.EndsWith(".lproj", &rest) )
+ lang = rest;
+#endif // __WXOSX__
+
+ wxLogTrace(TRACE_I18N,
+ "found %s translation of \"%s\"", lang, domain);
+ langs.push_back(lang);
+ }
+ }
+ }
+
+ return langs;
+}
+
+
+// ----------------------------------------------------------------------------
+// wxResourceTranslationsLoader
+// ----------------------------------------------------------------------------
+
+#ifdef __WINDOWS__
+
+wxMsgCatalog *wxResourceTranslationsLoader::LoadCatalog(const wxString& domain,
+ const wxString& lang)
+{
+ const void *mo_data = NULL;
+ size_t mo_size = 0;
+
+ const wxString resname = wxString::Format("%s_%s", domain, lang);
+
+ if ( !wxLoadUserResource(&mo_data, &mo_size,
+ resname,
+ GetResourceType(),
+ GetModule()) )
+ return NULL;
+
+ wxLogTrace(TRACE_I18N,
+ "Using catalog from Windows resource \"%s\".", resname);
+
+ wxMsgCatalog *cat = wxMsgCatalog::CreateFromData(
+ wxCharBuffer::CreateNonOwned(static_cast<const char*>(mo_data), mo_size),
+ domain);
+
+ if ( !cat )
+ {
+ wxLogWarning(_("Resource '%s' is not a valid message catalog."), resname);
+ }
+
+ return cat;
+}
+
+namespace
+{
+
+struct EnumCallbackData
+{
+ wxString prefix;
+ wxArrayString langs;
+};
+
+BOOL CALLBACK EnumTranslations(HMODULE WXUNUSED(hModule),
+ LPCTSTR WXUNUSED(lpszType),
+ LPTSTR lpszName,
+ LONG_PTR lParam)
+{
+ wxString name(lpszName);
+ name.MakeLower(); // resource names are case insensitive
+
+ EnumCallbackData *data = reinterpret_cast<EnumCallbackData*>(lParam);
+
+ wxString lang;
+ if ( name.StartsWith(data->prefix, &lang) && !lang.empty() )
+ data->langs.push_back(lang);
+
+ return TRUE; // continue enumeration
+}
+
+} // anonymous namespace
+
+
+wxArrayString wxResourceTranslationsLoader::GetAvailableTranslations(const wxString& domain) const
+{
+ EnumCallbackData data;
+ data.prefix = domain + "_";
+ data.prefix.MakeLower(); // resource names are case insensitive
+
+ if ( !EnumResourceNames(GetModule(),
+ GetResourceType().t_str(),
+ EnumTranslations,
+ reinterpret_cast<LONG_PTR>(&data)) )
+ {
+ const DWORD err = GetLastError();
+ if ( err != NO_ERROR && err != ERROR_RESOURCE_TYPE_NOT_FOUND )
+ {
+ wxLogSysError(_("Couldn't enumerate translations"));
+ }
+ }
+
+ return data.langs;
+}
+
+#endif // __WINDOWS__
+
+