Audacity 3.2.0
TranslatableString.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file TranslatableString.cpp
6
7 Paul Licameli split from Internat.cpp
8
9 **********************************************************************/
10
11#include "TranslatableString.h"
12#include "Identifier.h"
13#include <wx/translation.h>
14
15const wxChar *const TranslatableString::NullContextName = wxT("*");
16
18{
19 return Identifier{ mMsgid };
20}
21
24 [](const wxString & str, TranslatableString::Request request) -> wxString {
25 switch ( request ) {
26 case Request::Context:
27 return NullContextName;
28 case Request::Format:
29 case Request::DebugFormat:
30 default:
31 return str;
32 }
33 }
34};
35
37{
39}
40
42{
43 auto prevFormatter = mFormatter;
44 mFormatter = [prevFormatter, codes]
45 ( const wxString & str, TranslatableString::Request request ) -> wxString {
46 switch ( request ) {
47 case Request::Context:
48 return TranslatableString::DoGetContext( prevFormatter );
49 case Request::Format:
50 case Request::DebugFormat:
51 default: {
52 bool debug = request == Request::DebugFormat;
53 auto result =
55 prevFormatter,
56 str, TranslatableString::DoGetContext( prevFormatter ),
57 debug );
58 if ( codes & MenuCodes ) {
59 // Don't use this, it's in wxCore
60 // result = wxStripMenuCodes( result );
61 decltype( result ) temp;
62 temp.swap(result);
63 for ( auto iter = temp.begin(), end = temp.end();
64 iter != end; ++iter ) {
65 // Stop at trailing hot key name
66 if ( *iter == '\t' )
67 break;
68 // Strip & (unless escaped by another preceding &)
69 if ( *iter == '&' && ++iter == end )
70 break;
71 result.append( 1, *iter );
72 }
73 }
74 if ( codes & Ellipses ) {
75 if (result.EndsWith(wxT("...")))
76 result = result.Left( result.length() - 3 );
77 // Also check for the single-character Unicode ellipsis
78 else if (result.EndsWith(wxT("\u2026")))
79 result = result.Left( result.length() - 1 );
80 }
81 return result;
82 }
83 }
84 };
85
86 return *this;
87}
88
89wxString TranslatableString::DoGetContext( const Formatter &formatter )
90{
91 return formatter ? formatter( {}, Request::Context ) : wxString{};
92}
93
95 const wxString &format, const wxString &context, bool debug )
96{
97 return formatter
98 ? formatter( format, debug ? Request::DebugFormat : Request::Format )
99 : // come here for most translatable strings, which have no formatting
100 ( debug ? format : wxGetTranslation( format, wxString{}, context ) );
101}
102
104 const Formatter &formatter,
105 const wxString &singular, const wxString &plural, unsigned nn, bool debug )
106{
107 // come here for translatable strings that choose among forms by number;
108 // if not debugging, then two keys are passed to an overload of
109 // wxGetTranslation, and also a number.
110 // Some languages might choose among more or fewer than two forms
111 // (e.g. Arabic has duals and Russian has complicated declension rules)
112 wxString context;
113 return ( debug || NullContextName == (context = DoGetContext(formatter)) )
114 ? ( nn == 1 ? singular : plural )
115 : wxGetTranslation(
116 singular, plural, nn
118 , wxString{} // domain
119 , context
120#endif
121 );
122}
123
125 const TranslatableString arg, const wxString &separator ) &
126{
127 auto prevFormatter = mFormatter;
128 mFormatter =
129 [prevFormatter,
130 arg /* = std::move( arg ) */,
131 separator](const wxString &str, Request request)
132 -> wxString {
133 switch ( request ) {
134 case Request::Context:
135 return TranslatableString::DoGetContext( prevFormatter );
136 case Request::Format:
137 case Request::DebugFormat:
138 default: {
139 bool debug = request == Request::DebugFormat;
140 return
142 str, TranslatableString::DoGetContext( prevFormatter ),
143 debug )
144 + separator
145 + arg.DoFormat( debug );
146 }
147 }
148 };
149 return *this;
150}
151
#define str(a)
int format
Definition: ExportPCM.cpp:56
#define HAS_I18N_CONTEXTS
Definition: Internat.h:165
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
Class to construct the HTTP request.
Holds a msgid for the translation catalog; may also bind format arguments.
static wxString DoChooseFormat(const Formatter &formatter, const wxString &singular, const wxString &plural, unsigned nn, bool debug)
Identifier MSGID() const
MSGID is the English lookup key in the catalog, not necessarily for user's eyes if locale is some oth...
static const wxChar *const NullContextName
@ Format
Given the msgid, format the string for end users.
@ DebugFormat
Given the msgid, format the string for developers.
@ Context
return a disambiguating context string
std::function< wxString(const wxString &, Request) > Formatter
A multi-purpose function, depending on the enum argument.
static const TranslatableString Inaudible
A special string value that will have no screen reader pronunciation.
static wxString DoGetContext(const Formatter &formatter)
bool IsVerbatim() const
Returns true if context is NullContextFormatter.
TranslatableString & Strip(unsigned options=MenuCodes) &
static wxString DoSubstitute(const Formatter &formatter, const wxString &format, const wxString &context, bool debug)
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
static const Formatter NullContextFormatter
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for, if Traits<Type>::iterated_type is defined.
Definition: PackedArray.h:126