1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/**********************************************************************
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, wxString{}, context ) );
}
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") };
|