mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 15:19:44 +02:00
wxWidgets 3.0 doesn't support context in wxGetTranslation yet, so don't use the context, similar to existing DoChooseFormat handling. This will lead to some untranslated strings or wrong context translations (if we have equal strings that one specifies the context, but the other doesn't), which isn't great, but better than not being able to compile the application at all against a stable wxWidgets library version. Signed-off-by: Mart Raudsepp <leio@gentoo.org>
158 lines
5.0 KiB
C++
158 lines
5.0 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
@file TranslatableString.cpp
|
|
|
|
Paul Licameli split from Internat.cpp
|
|
|
|
**********************************************************************/
|
|
|
|
#include "TranslatableString.h"
|
|
#include "Identifier.h"
|
|
#include <wx/translation.h>
|
|
|
|
const wxChar *const TranslatableString::NullContextName = wxT("*");
|
|
|
|
Identifier TranslatableString::MSGID() const
|
|
{
|
|
return Identifier{ mMsgid };
|
|
}
|
|
|
|
const TranslatableString::Formatter
|
|
TranslatableString::NullContextFormatter {
|
|
[](const wxString & str, TranslatableString::Request request) -> wxString {
|
|
switch ( request ) {
|
|
case Request::Context:
|
|
return NullContextName;
|
|
case Request::Format:
|
|
case Request::DebugFormat:
|
|
default:
|
|
return str;
|
|
}
|
|
}
|
|
};
|
|
|
|
bool TranslatableString::IsVerbatim() const
|
|
{
|
|
return DoGetContext( mFormatter ) == NullContextName;
|
|
}
|
|
|
|
TranslatableString &TranslatableString::Strip( unsigned codes ) &
|
|
{
|
|
auto prevFormatter = mFormatter;
|
|
mFormatter = [prevFormatter, codes]
|
|
( const wxString & str, TranslatableString::Request request ) -> wxString {
|
|
switch ( request ) {
|
|
case Request::Context:
|
|
return TranslatableString::DoGetContext( prevFormatter );
|
|
case Request::Format:
|
|
case Request::DebugFormat:
|
|
default: {
|
|
bool debug = request == Request::DebugFormat;
|
|
auto result =
|
|
TranslatableString::DoSubstitute(
|
|
prevFormatter,
|
|
str, TranslatableString::DoGetContext( prevFormatter ),
|
|
debug );
|
|
if ( codes & MenuCodes ) {
|
|
// Don't use this, it's in wxCore
|
|
// result = wxStripMenuCodes( result );
|
|
decltype( result ) temp;
|
|
temp.swap(result);
|
|
for ( auto iter = temp.begin(), end = temp.end();
|
|
iter != end; ++iter ) {
|
|
// Stop at trailing hot key name
|
|
if ( *iter == '\t' )
|
|
break;
|
|
// Strip & (unless escaped by another preceding &)
|
|
if ( *iter == '&' && ++iter == end )
|
|
break;
|
|
result.append( 1, *iter );
|
|
}
|
|
}
|
|
if ( codes & Ellipses ) {
|
|
if (result.EndsWith(wxT("...")))
|
|
result = result.Left( result.length() - 3 );
|
|
// Also check for the single-character Unicode ellipsis
|
|
else if (result.EndsWith(wxT("\u2026")))
|
|
result = result.Left( result.length() - 1 );
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
};
|
|
|
|
return *this;
|
|
}
|
|
|
|
wxString TranslatableString::DoGetContext( const Formatter &formatter )
|
|
{
|
|
return formatter ? formatter( {}, Request::Context ) : wxString{};
|
|
}
|
|
|
|
wxString TranslatableString::DoSubstitute( const Formatter &formatter,
|
|
const wxString &format, const wxString &context, bool debug )
|
|
{
|
|
return formatter
|
|
? formatter( format, debug ? Request::DebugFormat : Request::Format )
|
|
: // come here for most translatable strings, which have no formatting
|
|
( debug ? format : wxGetTranslation(
|
|
format
|
|
#if HAS_I18N_CONTEXTS
|
|
, wxString{}, context
|
|
#endif
|
|
) );
|
|
}
|
|
|
|
wxString TranslatableString::DoChooseFormat(
|
|
const Formatter &formatter,
|
|
const wxString &singular, const wxString &plural, unsigned nn, bool debug )
|
|
{
|
|
// come here for translatable strings that choose among forms by number;
|
|
// if not debugging, then two keys are passed to an overload of
|
|
// wxGetTranslation, and also a number.
|
|
// Some languages might choose among more or fewer than two forms
|
|
// (e.g. Arabic has duals and Russian has complicated declension rules)
|
|
wxString context;
|
|
return ( debug || NullContextName == (context = DoGetContext(formatter)) )
|
|
? ( nn == 1 ? singular : plural )
|
|
: wxGetTranslation(
|
|
singular, plural, nn
|
|
#if HAS_I18N_CONTEXTS
|
|
, wxString{} // domain
|
|
, context
|
|
#endif
|
|
);
|
|
}
|
|
|
|
TranslatableString &TranslatableString::Join(
|
|
const TranslatableString arg, const wxString &separator ) &
|
|
{
|
|
auto prevFormatter = mFormatter;
|
|
mFormatter =
|
|
[prevFormatter,
|
|
arg /* = std::move( arg ) */,
|
|
separator](const wxString &str, Request request)
|
|
-> wxString {
|
|
switch ( request ) {
|
|
case Request::Context:
|
|
return TranslatableString::DoGetContext( prevFormatter );
|
|
case Request::Format:
|
|
case Request::DebugFormat:
|
|
default: {
|
|
bool debug = request == Request::DebugFormat;
|
|
return
|
|
TranslatableString::DoSubstitute( prevFormatter,
|
|
str, TranslatableString::DoGetContext( prevFormatter ),
|
|
debug )
|
|
+ separator
|
|
+ arg.DoFormat( debug );
|
|
}
|
|
}
|
|
};
|
|
return *this;
|
|
}
|
|
|
|
const TranslatableString TranslatableString::Inaudible{ wxT("\a") };
|