mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-20 09:31:15 +02:00
TranslatableString can store a context and format arguments...
... Format arguments are substituted into the translation of the msgid, which may not be known at the time the format arguments are captured (because locale may change). This allows TranslatableString with arguments to be constructed at static initialization time. There is also a special "verbatim" or null context which makes no translations of msgids. There is not yet any use of other contexts besides default or null.
This commit is contained in:
@@ -68,12 +68,12 @@ public:
|
||||
|
||||
// Allows implicit construction from an internal string re-used as a msgid
|
||||
ComponentInterfaceSymbol( const wxString &internal )
|
||||
: mInternal{ internal }, mMsgid{ internal }
|
||||
: mInternal{ internal }, mMsgid{ internal, {} }
|
||||
{}
|
||||
|
||||
// Allows implicit construction from an internal string re-used as a msgid
|
||||
ComponentInterfaceSymbol( const wxChar *msgid )
|
||||
: mInternal{ msgid }, mMsgid{ msgid }
|
||||
: mInternal{ msgid }, mMsgid{ msgid, {} }
|
||||
{}
|
||||
|
||||
// Two-argument version distinguishes internal from translatable string
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
|
||||
const wxString &Internal() const { return mInternal; }
|
||||
const TranslatableString &Msgid() const { return mMsgid; }
|
||||
const wxString &Translation() const { return mMsgid.Translation(); }
|
||||
const wxString Translation() const { return mMsgid.Translation(); }
|
||||
|
||||
bool empty() const { return mInternal.empty(); }
|
||||
|
||||
@@ -135,7 +135,7 @@ public:
|
||||
virtual wxString GetDescription() = 0;
|
||||
|
||||
// non-virtual convenience function
|
||||
const wxString& GetTranslatedName();
|
||||
const wxString GetTranslatedName();
|
||||
|
||||
// Parameters, if defined. false means no defined parameters.
|
||||
virtual bool DefineParams( ShuttleParams & WXUNUSED(S) ){ return false;};
|
||||
|
@@ -43,6 +43,7 @@
|
||||
#define __AUDACITY_TYPES_H__
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <wx/debug.h> // for wxASSERT
|
||||
@@ -292,8 +293,8 @@ using CommandID = TaggedIdentifier< CommandIdTag, false >;
|
||||
using CommandIDs = std::vector<CommandID>;
|
||||
|
||||
|
||||
// Holds a msgid for the translation catalog (and in future, might also hold a
|
||||
// second, disambiguating context string)
|
||||
// Holds a msgid for the translation catalog and may also hold a context string
|
||||
// and a formatter closure that captures formatting arguments
|
||||
//
|
||||
// Two different wxString accessors -- one for the msgid itself, another for
|
||||
// the user-visible translation. The msgid should be used only in unusual cases
|
||||
@@ -302,10 +303,28 @@ using CommandIDs = std::vector<CommandID>;
|
||||
// Implicit conversions to and from wxString are intentionally disabled
|
||||
class TranslatableString : private wxString {
|
||||
public:
|
||||
// A dual-purpose function
|
||||
// Given the empty string, return a context string
|
||||
// Given the translation of the msgid into the current locale, substitute
|
||||
// format arguments into it
|
||||
using Formatter = std::function< wxString(const wxString &) >;
|
||||
|
||||
// This special formatter causes msgids to be used verbatim, not looked up
|
||||
// in any catalog
|
||||
static const Formatter NullContextFormatter;
|
||||
|
||||
TranslatableString() {}
|
||||
|
||||
explicit TranslatableString(const wxString &str) : wxString{ str } {}
|
||||
explicit TranslatableString(const wxChar *str) : wxString{ str } {}
|
||||
// Supply {} for the second argument to cause lookup of the msgid with
|
||||
// empty context string
|
||||
explicit TranslatableString(
|
||||
const wxString &str, Formatter formatter = NullContextFormatter)
|
||||
: wxString{ str }, mFormatter{ std::move(formatter) } {}
|
||||
// Supply {} for the second argument to cause lookup of the msgid with
|
||||
// empty context string
|
||||
explicit TranslatableString(
|
||||
const wxChar *str, Formatter formatter = NullContextFormatter)
|
||||
: wxString{ str }, mFormatter{ std::move(formatter) } {}
|
||||
|
||||
using wxString::empty;
|
||||
|
||||
@@ -316,7 +335,7 @@ public:
|
||||
// This is a deliberately ugly-looking function name. Use with caution.
|
||||
Identifier MSGID() const { return Identifier{ *this }; }
|
||||
|
||||
const wxString &Translation() const;
|
||||
wxString Translation() const;
|
||||
|
||||
friend bool operator == (
|
||||
const TranslatableString &x, const TranslatableString &y)
|
||||
@@ -326,8 +345,31 @@ public:
|
||||
const TranslatableString &x, const TranslatableString &y)
|
||||
{ return !(x == y); }
|
||||
|
||||
// Future: may also store a domain and context, as if for dpgettext()
|
||||
// Returns true if context is NullContextFormatter
|
||||
bool IsVerbatim() const;
|
||||
|
||||
// Capture variadic format arguments (by copy). The subsitution is
|
||||
// computed later in a call to Translate() after msgid is looked up in the
|
||||
// translation catalog.
|
||||
template <typename... Args>
|
||||
TranslatableString&& Format( Args&&... args ) &&
|
||||
{
|
||||
wxString context;
|
||||
if ( this->mFormatter )
|
||||
context = this->mFormatter({});
|
||||
this->mFormatter = [context, args...](const wxString &str){
|
||||
if (str.empty())
|
||||
return context;
|
||||
else
|
||||
return wxString::Format( str, args... );
|
||||
};
|
||||
return std::move( *this );
|
||||
}
|
||||
|
||||
friend std::hash< TranslatableString >;
|
||||
private:
|
||||
|
||||
Formatter mFormatter;
|
||||
};
|
||||
|
||||
using TranslatableStrings = std::vector<TranslatableString>;
|
||||
|
Reference in New Issue
Block a user