Audacity  3.0.3
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 
15 const 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 
89 wxString TranslatableString::DoGetContext( const Formatter &formatter )
90 {
91  return formatter ? formatter( {}, Request::Context ) : wxString{};
92 }
93 
94 wxString TranslatableString::DoSubstitute( const Formatter &formatter,
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
141  TranslatableString::DoSubstitute( prevFormatter,
142  str, TranslatableString::DoGetContext( prevFormatter ),
143  debug )
144  + separator
145  + arg.DoFormat( debug );
146  }
147  }
148  };
149  return *this;
150 }
151 
TranslatableString::Request::Format
@ Format
Given the msgid, format the string for end users.
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
TranslatableString::DoGetContext
static wxString DoGetContext(const Formatter &formatter)
Definition: TranslatableString.cpp:89
TranslatableString::IsVerbatim
bool IsVerbatim() const
Returns true if context is NullContextFormatter.
Definition: TranslatableString.cpp:36
str
#define str(a)
Definition: DBConnection.cpp:30
TranslatableString::Request
Request
Definition: TranslatableString.h:215
TranslatableString::Inaudible
static const TranslatableString Inaudible
A special string value that will have no screen reader pronunciation.
Definition: TranslatableString.h:34
TranslatableString::NullContextFormatter
static const Formatter NullContextFormatter
Definition: TranslatableString.h:204
TranslatableString.h
TranslatableString::DoChooseFormat
static wxString DoChooseFormat(const Formatter &formatter, const wxString &singular, const wxString &plural, unsigned nn, bool debug)
Definition: TranslatableString.cpp:103
TranslatableString::Request::Context
@ Context
return a disambiguating context string
Identifier
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
TranslatableString::Strip
TranslatableString & Strip(unsigned options=MenuCodes) &
Definition: TranslatableString.cpp:41
TranslatableString::mFormatter
Formatter mFormatter
Definition: TranslatableString.h:286
TranslatableString::DoSubstitute
static wxString DoSubstitute(const Formatter &formatter, const wxString &format, const wxString &context, bool debug)
Definition: TranslatableString.cpp:94
Identifier.h
format
int format
Definition: ExportPCM.cpp:56
HAS_I18N_CONTEXTS
#define HAS_I18N_CONTEXTS
Definition: Internat.h:165
TranslatableString::Request::DebugFormat
@ DebugFormat
Given the msgid, format the string for developers.
TranslatableString::mMsgid
wxString mMsgid
Definition: TranslatableString.h:285
TranslatableString::MSGID
Identifier MSGID() const
MSGID is the English lookup key in the catalog, not necessarily for user's eyes if locale is some oth...
Definition: TranslatableString.cpp:17
TranslatableString::Join
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
Definition: TranslatableString.cpp:124
TranslatableString::Formatter
std::function< wxString(const wxString &, Request) > Formatter
A multi-purpose function, depending on the enum argument.
Definition: TranslatableString.h:45
Request
Class to construct the HTTP request.
TranslatableString::NullContextName
static const wxChar *const NullContextName
Definition: TranslatableString.h:221