GUIPrefs::SetLang wraps new Languages::SetLang ...

... the former uses Prefs, wxApp, and AudacityMessageBox, the latter has no
dependency on them.

Also move some other functions from GUIPrefs into namespace Languages.
This commit is contained in:
Paul Licameli 2021-05-22 20:07:25 -04:00
parent 91e4eeadb8
commit 564235f9c9
6 changed files with 117 additions and 95 deletions

View File

@ -1556,7 +1556,7 @@ bool AudacityApp::InitPart2()
Bind(wxEVT_MENU_CLOSE, [=](wxMenuEvent &event)
{
wxSetlocale(LC_NUMERIC, GUIPrefs::GetLocaleName());
wxSetlocale(LC_NUMERIC, Languages::GetLocaleName());
event.Skip();
});
#endif

View File

@ -24,6 +24,7 @@
#include "AudioIOBase.h"
#include "FileNames.h"
#include "Internat.h"
#include "Languages.h"
#include "Project.h"
#include "ProjectFileIO.h"
#include "prefs/GUIPrefs.h"
@ -59,7 +60,7 @@ void Generate(wxDebugReport::Context ctx)
if (ctx == wxDebugReport::Context_Current)
{
auto saveLang = GUIPrefs::GetLangShort();
auto saveLang = Languages::GetLangShort();
GUIPrefs::SetLang( wxT("en") );
auto cleanup = finally( [&]{ GUIPrefs::SetLang( saveLang ); } );

View File

@ -43,6 +43,7 @@
#include <wx/intl.h>
#include <wx/textfile.h>
#include <clocale>
#include <unordered_map>
using LangHash = std::unordered_map<wxString, TranslatableString>;
@ -314,4 +315,93 @@ void GetLanguages( FilePaths pathList,
}
}
static std::unique_ptr<wxLocale> sLocale;
static wxString sLocaleName;
wxString SetLang( const FilePaths &pathList, const wxString & lang )
{
wxString result = lang;
sLocale.reset();
#if defined(__WXMAC__)
// This should be reviewed again during the wx3 conversion.
// On OSX, if the LANG environment variable isn't set when
// using a language like Japanese, an assertion will trigger
// because conversion to Japanese from "?" doesn't return a
// valid length, so make OSX happy by defining/overriding
// the LANG environment variable with U.S. English for now.
wxSetEnv(wxT("LANG"), wxT("en_US.UTF-8"));
#endif
const wxLanguageInfo *info = NULL;
if (!lang.empty() && lang != wxT("System")) {
// Try to find the given language
info = wxLocale::FindLanguageInfo(lang);
}
if (!info)
{
// Not given a language or can't find it; substitute the system language
result = Languages::GetSystemLanguageCode(pathList);
info = wxLocale::FindLanguageInfo(result);
if (!info)
// Return the substituted system language, but we can't complete setup
// Should we try to do something better?
return result;
}
sLocale = std::make_unique<wxLocale>(info->Language);
for( const auto &path : pathList )
sLocale->AddCatalogLookupPathPrefix( path );
// LL: Must add the wxWidgets catalog manually since the search
// paths were not set up when mLocale was created. The
// catalogs are search in LIFO order, so add wxstd first.
sLocale->AddCatalog(wxT("wxstd"));
// Must match TranslationExists() in Languages.cpp
sLocale->AddCatalog("audacity");
// Initialize internationalisation (number formats etc.)
//
// This must go _after_ creating the wxLocale instance because
// creating the wxLocale instance sets the application-wide locale.
Internat::Init();
using future1 = decltype(
// The file of unused strings is part of the source tree scanned by
// xgettext when compiling the catalog template audacity.pot.
// Including it here doesn't change that but does make the C++ compiler
// check for correct syntax, but also generate no object code for them.
#include "UnusedStrings.h"
0
);
sLocaleName = wxSetlocale(LC_ALL, NULL);
return result;
}
wxString GetLocaleName()
{
return sLocaleName;
}
wxString GetLang()
{
if (sLocale)
return sLocale->GetSysName();
else
return {};
}
wxString GetLangShort()
{
if (sLocale)
return sLocale->GetName();
else
return {};
}
}

View File

@ -35,6 +35,25 @@ void GetLanguages( FilePaths pathList,
AUDACITY_DLL_API
wxString GetSystemLanguageCode(const FilePaths &pathList);
/*!
@param audacityPathList paths to search for .mo files, grouped into subdirectories for the different languages
@param lang a language code; or if empty or "System", then default to system language.
@return the language code actually used which is not lang if lang cannot be found. */
AUDACITY_DLL_API
wxString SetLang( const FilePaths &audacityPathList, const wxString & lang );
/*! @return the last language code that was set */
AUDACITY_DLL_API
wxString GetLang();
/*! @return the last language code that was set (minus country code) */
AUDACITY_DLL_API
wxString GetLangShort();
/*! @return a string as from setlocale() */
AUDACITY_DLL_API
wxString GetLocaleName();
}
#endif // __AUDACITY_LANGUAGES__

View File

@ -22,7 +22,6 @@
#include <wx/app.h>
#include <wx/defs.h>
#include <locale>
#include "../FileNames.h"
#include "../Languages.h"
@ -241,7 +240,7 @@ bool GUIPrefs::Commit()
wxString lang = gPrefs->Read(wxT("/Locale/Language"), wxT(""));
wxString usedLang = SetLang(lang);
// Bug 1523: Previously didn't check no-language (=System Language)
if (!(lang.empty()) && (lang != usedLang)) {
if (!(lang.empty() || lang == L"System") && (lang != usedLang)) {
// lang was not usable and is not system language. We got overridden.
gPrefs->Write(wxT("/Locale/Language"), usedLang);
gPrefs->Flush();
@ -254,59 +253,12 @@ bool GUIPrefs::Commit()
return true;
}
static std::unique_ptr<wxLocale> sLocale;
static wxString sLocaleName;
wxString GUIPrefs::SetLang( const wxString & lang )
{
wxString result = lang;
sLocale.reset();
#if defined(__WXMAC__)
// This should be reviewed again during the wx3 conversion.
// On OSX, if the LANG environment variable isn't set when
// using a language like Japanese, an assertion will trigger
// because conversion to Japanese from "?" doesn't return a
// valid length, so make OSX happy by defining/overriding
// the LANG environment variable with U.S. English for now.
wxSetEnv(wxT("LANG"), wxT("en_US.UTF-8"));
#endif
const wxLanguageInfo *info = NULL;
if (!lang.empty() && lang != wxT("System")) {
info = wxLocale::FindLanguageInfo(lang);
if (!info)
::AudacityMessageBox(
XO("Language \"%s\" is unknown").Format( lang ) );
}
if (!info)
{
result = Languages::GetSystemLanguageCode(FileNames::AudacityPathList());
info = wxLocale::FindLanguageInfo(result);
if (!info)
return result;
}
sLocale = std::make_unique<wxLocale>(info->Language);
for( const auto &path : FileNames::AudacityPathList() )
sLocale->AddCatalogLookupPathPrefix( path );
// LL: Must add the wxWidgets catalog manually since the search
// paths were not set up when mLocale was created. The
// catalogs are search in LIFO order, so add wxstd first.
sLocale->AddCatalog(wxT("wxstd"));
// Must match TranslationExists() in Languages.cpp
sLocale->AddCatalog("audacity");
// Initialize internationalisation (number formats etc.)
//
// This must go _after_ creating the wxLocale instance because
// creating the wxLocale instance sets the application-wide locale.
Internat::Init();
auto result = Languages::SetLang(FileNames::AudacityPathList(), lang);
if (!(lang.empty() || lang == L"System") && result != lang)
::AudacityMessageBox(
XO("Language \"%s\" is unknown").Format( lang ) );
#ifdef EXPERIMENTAL_CEE_NUMBERS_OPTION
bool forceCeeNumbers;
@ -315,45 +267,13 @@ wxString GUIPrefs::SetLang( const wxString & lang )
Internat::SetCeeNumberFormat();
#endif
using future1 = decltype(
// The file of unused strings is part of the source tree scanned by
// xgettext when compiling the catalog template audacity.pot.
// Including it here doesn't change that but does make the C++ compiler
// check for correct syntax, but also generate no object code for them.
#include "UnusedStrings.h"
0
);
#ifdef __WXMAC__
wxApp::s_macHelpMenuTitleName = _("&Help");
#endif
sLocaleName = wxSetlocale(LC_ALL, NULL);
return result;
}
wxString GUIPrefs::GetLocaleName()
{
return sLocaleName;
}
wxString GUIPrefs::GetLang()
{
if (sLocale)
return sLocale->GetSysName();
else
return {};
}
wxString GUIPrefs::GetLangShort()
{
if (sLocale)
return sLocale->GetName();
else
return {};
}
int ShowClippingPrefsID()
{
static int value = wxNewId();

View File

@ -44,14 +44,6 @@ class AUDACITY_DLL_API GUIPrefs final : public PrefsPanel
// Returns the language actually used which is not lang if lang cannot be found.
static wxString SetLang( const wxString & lang );
// Returns the last language code that was set
static wxString GetLang();
// Returns the last language code that was set
// Unlike GetLang, gives en rather than en_GB or en_US for result.
static wxString GetLangShort();
static wxString GetLocaleName();
private:
void Populate();