Merge pull request #2106 from Flakebi/test
Simplify StringUtils::insertValues
This commit is contained in:
commit
6a26010bc8
@ -417,10 +417,8 @@ void PlayerKartWidget::markAsReady()
|
||||
// 'playerNameString' is already fribidize, so we need to use
|
||||
// 'insertValues' and not _("...", a) so it's not flipped again
|
||||
m_ready_text =
|
||||
GUIEngine::getGUIEnv()->addStaticText(
|
||||
StringUtils::insertValues(_("%s is ready"),
|
||||
playerNameString).c_str(),
|
||||
rect );
|
||||
GUIEngine::getGUIEnv()->addStaticText(_("%s is ready", playerNameString),
|
||||
rect);
|
||||
m_ready_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
|
||||
|
||||
m_children.remove(m_player_ident_spinner);
|
||||
|
@ -452,7 +452,7 @@ public:
|
||||
*/
|
||||
core::stringw getName() const
|
||||
{
|
||||
return core::stringw(translations->w_gettext(m_name.c_str()));
|
||||
return _LTR(m_name.c_str());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -199,9 +199,8 @@ void EasterEggHunt::getKartsDisplayInfo(
|
||||
{
|
||||
RaceGUIBase::KartIconDisplayInfo& rank_info = (*info)[i];
|
||||
//I18n: number of collected eggs / overall number of eggs
|
||||
rank_info.m_text = StringUtils::insertValues(_("Eggs: %d / %d"),
|
||||
m_eggs_collected[i],
|
||||
m_number_of_eggs);
|
||||
rank_info.m_text = _("Eggs: %d / %d", m_eggs_collected[i],
|
||||
m_number_of_eggs);
|
||||
rank_info.m_color = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
} // getKartDisplayInfo
|
||||
|
@ -167,8 +167,8 @@ public:
|
||||
// -------------------------------------------------------------------------
|
||||
enum GPReverseType getReverseType()
|
||||
const { return m_reverse_type; }
|
||||
static const char* getRandomGPID() { return "random"; }
|
||||
static const wchar_t* getRandomGPName() { return _LTR("Random Grand Prix");}
|
||||
static const char* getRandomGPID() { return "random"; }
|
||||
static irr::core::stringw getRandomGPName() { return _LTR("Random Grand Prix"); }
|
||||
}; // GrandPrixData
|
||||
|
||||
#endif
|
||||
|
@ -356,9 +356,8 @@ void AddonsLoading::doInstall()
|
||||
bool error = !addons_manager->install(m_addon);
|
||||
if(error)
|
||||
{
|
||||
core::stringw msg = StringUtils::insertValues(
|
||||
_("Problems installing the addon '%s'."),
|
||||
core::stringw(m_addon.getName().c_str()));
|
||||
const core::stringw &name = m_addon.getName();
|
||||
core::stringw msg = _("Problems installing the addon '%s'.", name);
|
||||
getWidget<BubbleWidget>("description")->setText(msg.c_str());
|
||||
}
|
||||
|
||||
@ -394,8 +393,8 @@ void AddonsLoading::doUninstall()
|
||||
Log::warn("Addons", "Directory '%s' can not be removed.",
|
||||
m_addon.getDataDir().c_str());
|
||||
Log::warn("Addons", "Please remove this directory manually.");
|
||||
core::stringw msg = StringUtils::insertValues(_("Problems removing the addon '%s'."),
|
||||
core::stringw(m_addon.getName().c_str()));
|
||||
const core::stringw &name = m_addon.getName();
|
||||
core::stringw msg = _("Problems removing the addon '%s'.", name);
|
||||
getWidget<BubbleWidget>("description")->setText(msg.c_str());
|
||||
}
|
||||
|
||||
|
@ -98,10 +98,6 @@ RaceGUIBase::RaceGUIBase()
|
||||
m_dist_show_overlap = 2;
|
||||
m_icons_inertia = 2;
|
||||
|
||||
|
||||
//I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
|
||||
m_string_top = _("Top %i");
|
||||
|
||||
m_referee = NULL;
|
||||
} // RaceGUIBase
|
||||
|
||||
@ -812,7 +808,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
||||
static video::SColor color = video::SColor(255, 255, 255, 255);
|
||||
pos_top.LowerRightCorner = pos_top.UpperLeftCorner;
|
||||
|
||||
font->draw(StringUtils::insertValues( m_string_top, position-1 ), pos_top, color);
|
||||
//I18N: When some GlobalPlayerIcons are hidden, write "Top 10" to show it
|
||||
font->draw(_("Top %i", position-1 ), pos_top, color);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -129,9 +129,6 @@ private:
|
||||
/** Translated strings 'ready', 'set', 'go'. */
|
||||
core::stringw m_string_ready, m_string_set, m_string_go, m_string_goal;
|
||||
|
||||
/** Translated string 'Top %d' displayed every frame. */
|
||||
core::stringw m_string_top;
|
||||
|
||||
/** The position of the referee for all karts. */
|
||||
std::vector<Vec3> m_referee_pos;
|
||||
|
||||
|
@ -25,12 +25,13 @@
|
||||
#include "utils/utf8.h"
|
||||
#include "coreutil.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <cwchar>
|
||||
#include <exception>
|
||||
#include <assert.h>
|
||||
|
||||
namespace StringUtils
|
||||
{
|
||||
@ -167,7 +168,7 @@ namespace StringUtils
|
||||
try
|
||||
{
|
||||
std::string::size_type start=0;
|
||||
while(start!=std::string::npos && start<(unsigned int)s.size())
|
||||
while(start < (unsigned int) s.size())
|
||||
{
|
||||
std::string::size_type i=s.find(c, start);
|
||||
if (i!=std::string::npos)
|
||||
@ -185,11 +186,11 @@ namespace StringUtils
|
||||
}
|
||||
else // end of string reached
|
||||
{
|
||||
if (keepSplitChar)
|
||||
if (keepSplitChar && start != 0)
|
||||
result.push_back(std::string(s,start-1));
|
||||
else
|
||||
result.push_back(std::string(s,start));
|
||||
start = i;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -243,14 +244,13 @@ namespace StringUtils
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keepSplitChar)
|
||||
if (keepSplitChar && start != 0)
|
||||
result.push_back( s.subString(start - 1,
|
||||
s.size()-start + 1) );
|
||||
else
|
||||
result.push_back( s.subString(start, s.size()-start) );
|
||||
|
||||
return result;
|
||||
//start = i+1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -136,210 +136,71 @@ namespace StringUtils
|
||||
std::string insertValues(const std::string &s,
|
||||
std::vector<std::string>& all_vals);
|
||||
|
||||
/** This no-op is useful when using variadic arguments, so that we may
|
||||
* support the case with 0 variadic arguments */
|
||||
template <class T1>
|
||||
T1 insertValues(const T1& s) { return s; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Same as above but for wide-strings */
|
||||
irr::core::stringw insertValues(const irr::core::stringw &s,
|
||||
std::vector<irr::core::stringw>& all_vals);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Note: the order in which the templates are specified is important, since
|
||||
// otherwise some compilers will not find the right template to use.
|
||||
|
||||
template <class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4,
|
||||
const T5 &v5,const T6 &v6)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v4; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v5; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v6; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v6)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4,
|
||||
const T5 &v5)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v4; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v5; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v5)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v4; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v4)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Shortcut insert_values taking three values, see above for
|
||||
* full docs.
|
||||
* \param s String in which all %s or %d are replaced.
|
||||
* \param v1,v2, v3 Value(s) to replace all %s or %d with.
|
||||
*/
|
||||
template <class T1, class T2, class T3>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v3; all_vals.push_back(dummy.str());
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, ..., v3)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Note: the order in which the templates are specified is important, since
|
||||
// otherwise some compilers will not find the right template to use.
|
||||
/** Shortcut insert_values taking three values, see above for
|
||||
* full docs.
|
||||
* \param s String in which all %s or %d are replaced.
|
||||
* \param v1,v2 Value(s) to replace all %s or %d with.
|
||||
*/
|
||||
template <class T1, class T2>
|
||||
std::string insertValues(const std::string &s, const T1 &v1,
|
||||
const T2 &v2)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
dummy << v2; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1, v2)
|
||||
// ------------------------------------------------------------------------
|
||||
/** Shortcut insert_values taking three values, see above for
|
||||
* full docs.
|
||||
* \param s String in which all %s, %d are replaced.
|
||||
* \param v1 Value to replace.
|
||||
*/
|
||||
template <class T1>
|
||||
std::string insertValues(const std::string &s, const T1 &v1)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
std::ostringstream dummy;
|
||||
dummy << v1; all_vals.push_back(dummy.str()); dummy.str("");
|
||||
|
||||
return insertValues(s, all_vals);
|
||||
} // insertValues(s, v1)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Intermediate struct to fill a vector using variadic templates */
|
||||
struct __FillStringwVector
|
||||
struct FillStringVector
|
||||
{
|
||||
/** FillS takes a vector as the first argument and a variadic list of
|
||||
* arguments. The arguments are recursively inserted into the vector
|
||||
* which will contain all the arguments converted to strings in the end.
|
||||
*/
|
||||
template<typename T, typename...Args>
|
||||
static void __Fill(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
|
||||
static void FillS(std::vector<std::string> &all_vals, T&& v, Args &&...args)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << v;
|
||||
all_vals.push_back(oss.str());
|
||||
FillS(all_vals, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static void FillS(std::vector<std::string>&) {}
|
||||
|
||||
/** This functions does the same as FillS but for wide strings. */
|
||||
template<typename T, typename...Args>
|
||||
static void FillW(std::vector<irr::core::stringw> &all_vals, T&& v, Args &&...args)
|
||||
{
|
||||
all_vals.push_back(irr::core::stringw(std::forward<T>(v)));
|
||||
__Fill(all_vals, std::forward<Args>(args)...);
|
||||
FillW(all_vals, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static void __Fill(std::vector<irr::core::stringw>&) {}
|
||||
|
||||
static void FillW(std::vector<irr::core::stringw>&) {}
|
||||
};
|
||||
|
||||
template <typename...Args>
|
||||
std::string insertValues(const std::string &s, Args ...args)
|
||||
{
|
||||
std::vector<std::string> all_vals;
|
||||
all_vals.reserve(sizeof...(args));
|
||||
FillStringVector::FillS(all_vals, std::forward<Args>(args)...);
|
||||
return insertValues(s, all_vals);
|
||||
}
|
||||
|
||||
template <typename...Args>
|
||||
std::string insertValues(const char *s, Args ...args)
|
||||
{
|
||||
return insertValues(std::string(s), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <typename...Args>
|
||||
irr::core::stringw insertValues(const irr::core::stringw &s, Args ...args)
|
||||
{
|
||||
std::vector<irr::core::stringw> all_vals;
|
||||
__FillStringwVector::__Fill(all_vals, std::forward<Args>(args)...);
|
||||
all_vals.reserve(sizeof...(args));
|
||||
FillStringVector::FillW(all_vals, std::forward<Args>(args)...);
|
||||
return insertValues(s, all_vals);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1, class T2, class T3, class T4, class T5>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3, const T4 &v4,
|
||||
const T5 &v5)
|
||||
template <typename...Args>
|
||||
irr::core::stringw insertValues(const wchar_t *s, Args ...args)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1, v2, v3, v4, v5);
|
||||
} // insertValues(s, v1, ..., v5)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1, class T2, class T3>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1, v2, v3);
|
||||
} // insertValues(s, v1, ..., v3)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1, class T2>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1,
|
||||
const T2 &v2)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1, v2);
|
||||
} // insertValues(s, v1, v2)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for wide strings */
|
||||
template <class T1>
|
||||
irr::core::stringw insertValues(const wchar_t* chars, const T1 &v1)
|
||||
{
|
||||
irr::core::stringw s(chars);
|
||||
return insertValues(s, v1);
|
||||
} // insertValues(s, v1)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for C strings */
|
||||
template <class T1, class T2, class T3>
|
||||
std::string insertValues(const char* chars, const T1 &v1,
|
||||
const T2 &v2, const T3 &v3)
|
||||
{
|
||||
std::string s(chars);
|
||||
return insertValues(s, v1, v2, v3);
|
||||
} // insertValues(s, v1, ..., v3)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for C strings */
|
||||
template <class T1, class T2>
|
||||
std::string insertValues(const char* chars, const T1 &v1,
|
||||
const T2 &v2)
|
||||
{
|
||||
std::string s(chars);
|
||||
return insertValues(s, v1, v2);
|
||||
} // insertValues(s, v1, v2)
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Like the other ones above but for C strings */
|
||||
template <class T1>
|
||||
std::string insertValues(const char* chars, const T1 &v1)
|
||||
{
|
||||
std::string s(chars);
|
||||
return insertValues(s, v1);
|
||||
} // insertValues(s, v1)
|
||||
return insertValues(irr::core::stringw(s), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
@ -371,5 +232,3 @@ namespace StringUtils
|
||||
} // namespace StringUtils
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
@ -26,12 +26,13 @@
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <clocale>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cwchar>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
@ -359,10 +360,23 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
Translations::~Translations()
|
||||
{
|
||||
} // ~Translations
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
|
||||
{
|
||||
if (isRTLText(in_ptr))
|
||||
{
|
||||
// Test if this string was already fribidized
|
||||
std::map<const irr::core::stringw, const irr::core::stringw>::const_iterator
|
||||
found = m_fribidized_strings.find(in_ptr);
|
||||
if (found != m_fribidized_strings.cend())
|
||||
return found->second.c_str();
|
||||
|
||||
// Use fribidi to fribidize the string
|
||||
// Split text into lines
|
||||
std::vector<core::stringw> input_lines = StringUtils::split(in_ptr, '\n');
|
||||
// Reverse lines for RTL strings, irrlicht will reverse them back
|
||||
@ -371,18 +385,25 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
|
||||
std::reverse(input_lines.begin(), input_lines.end());
|
||||
|
||||
// Fribidize and concat lines
|
||||
core::stringw converted_string;
|
||||
for (std::vector<core::stringw>::iterator it = input_lines.begin();
|
||||
it != input_lines.end(); it++)
|
||||
{
|
||||
if (it == input_lines.begin())
|
||||
m_converted_string = fribidizeLine(*it);
|
||||
converted_string = fribidizeLine(*it);
|
||||
else
|
||||
{
|
||||
m_converted_string += "\n";
|
||||
m_converted_string += fribidizeLine(*it);
|
||||
converted_string += "\n";
|
||||
converted_string += fribidizeLine(*it);
|
||||
}
|
||||
}
|
||||
return m_converted_string.c_str();
|
||||
|
||||
// Save it in the map
|
||||
m_fribidized_strings.insert(std::pair<const irr::core::stringw, const irr::core::stringw>(
|
||||
in_ptr, converted_string));
|
||||
found = m_fribidized_strings.find(in_ptr);
|
||||
|
||||
return found->second.c_str();
|
||||
}
|
||||
else
|
||||
return in_ptr;
|
||||
@ -448,12 +469,13 @@ const wchar_t* Translations::w_gettext(const char* original, const char* context
|
||||
|
||||
if (original_t == original)
|
||||
{
|
||||
m_converted_string = StringUtils::utf8_to_wide(original);
|
||||
static irr::core::stringw converted_string;
|
||||
converted_string = StringUtils::utf8_to_wide(original);
|
||||
|
||||
#if TRANSLATE_VERBOSE
|
||||
std::wcout << L" translation : " << m_converted_string << std::endl;
|
||||
std::wcout << L" translation : " << converted_string << std::endl;
|
||||
#endif
|
||||
return m_converted_string.c_str();
|
||||
return converted_string.c_str();
|
||||
}
|
||||
|
||||
// print
|
||||
@ -572,4 +594,3 @@ core::stringw Translations::fribidizeLine(const core::stringw &str)
|
||||
return core::stringw(str);
|
||||
#endif // ENABLE_BIDI
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,14 @@
|
||||
#define TRANSLATION_HPP
|
||||
|
||||
#include <irrString.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
# include "tinygettext/tinygettext.hpp"
|
||||
#include "tinygettext/tinygettext.hpp"
|
||||
|
||||
# define _(String, ...) (translations->fribidize(StringUtils::insertValues(translations->w_gettext(String), ##__VA_ARGS__)))
|
||||
#undef _C
|
||||
@ -46,13 +49,15 @@ private:
|
||||
tinygettext::DictionaryManager m_dictionary_manager;
|
||||
tinygettext::Dictionary m_dictionary;
|
||||
|
||||
irr::core::stringw m_converted_string;
|
||||
/** A map that saves all fribidized strings: Original string, fribidized string */
|
||||
std::map<const irr::core::stringw, const irr::core::stringw> m_fribidized_strings;
|
||||
bool m_rtl;
|
||||
|
||||
std::string m_current_language_name;
|
||||
|
||||
public:
|
||||
Translations();
|
||||
~Translations();
|
||||
|
||||
const wchar_t *w_gettext(const wchar_t* original, const char* context=NULL);
|
||||
const wchar_t *w_gettext(const char* original, const char* context=NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user