Merge with develop

This commit is contained in:
kervala 2016-03-18 22:16:28 +01:00
parent 224875c39f
commit 63b2843232
15 changed files with 237 additions and 145 deletions

View file

@ -71,13 +71,13 @@ namespace NLGUI
private: private:
/// Drawing helpers /// Drawing helpers
virtual bool drawResizer(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawResizer(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawRotate(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawRotate(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawScale(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawScale(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawColorPicker(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawColorPicker(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawLink(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawLink(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawBrowse(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawBrowse(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawPan(CCtrlBase* pCB, NLMISC::CRGBA col){ return false; } virtual bool drawPan(CCtrlBase* /* pCB */, NLMISC::CRGBA /* col */) { return false; }
virtual bool drawCustom(CCtrlBase* pCB); virtual bool drawCustom(CCtrlBase* pCB);
protected: protected:

View file

@ -127,6 +127,9 @@ public:
/// Returns the code of the language ("fr", "en", ...) defined on system /// Returns the code of the language ("fr", "en", ...) defined on system
static std::string getSystemLanguageCode (); static std::string getSystemLanguageCode ();
/// Define the code of the language ("fr", "en", ...) defined on system
static bool setSystemLanguageCode (const std::string &languageCode);
/// Find a string in the selected language and return his association. /// Find a string in the selected language and return his association.
static const ucstring &get (const std::string &label); static const ucstring &get (const std::string &label);
@ -230,6 +233,7 @@ private:
static std::vector<std::string> _LanguageCodes; static std::vector<std::string> _LanguageCodes;
static std::vector<ucstring> _LanguageNames; static std::vector<ucstring> _LanguageNames;
static std::string _SystemLanguageCode;
static bool _LanguagesNamesLoaded; static bool _LanguagesNamesLoaded;

View file

@ -236,9 +236,6 @@ private:
// If not NULL, binary mode detected, use this stream in serials // If not NULL, binary mode detected, use this stream in serials
IStream *_BinaryStream; IStream *_BinaryStream;
// System dependant structure for locale
void* _Locale;
}; };

View file

@ -181,9 +181,6 @@ private:
// Error message // Error message
std::string _ErrorString; std::string _ErrorString;
// System dependant structure for locale
void* _Locale;
}; };

View file

@ -19,6 +19,8 @@
#include "nel/misc/dynloadlib.h" #include "nel/misc/dynloadlib.h"
#include "nel/misc/command.h" #include "nel/misc/command.h"
#include <locale.h>
#ifdef DEBUG_NEW #ifdef DEBUG_NEW
#define new DEBUG_NEW #define new DEBUG_NEW
#endif #endif
@ -85,6 +87,9 @@ void INelContext::contextReady()
_NelContext = this; _NelContext = this;
*(_getInstance()) = this; *(_getInstance()) = this;
// set numeric locale to C to avoid the use of decimal separators different of a dot
char *locale = setlocale(LC_NUMERIC, "C");
// register any pending thinks // register any pending thinks
// register local instance counter in the global instance counter manager // register local instance counter in the global instance counter manager

View file

@ -316,6 +316,13 @@ CConfigFile::~CConfigFile ()
void CConfigFile::load (const string &fileName, bool lookupPaths ) void CConfigFile::load (const string &fileName, bool lookupPaths )
{ {
char *locale = setlocale(LC_NUMERIC, NULL);
if (!locale || strcmp(locale, "C"))
{
nlerror("Numeric locale not defined to C, an external library possibly redefined it!");
}
if(fileName.empty()) if(fileName.empty())
{ {
nlwarning ("CF: Can't load a empty file name configfile"); nlwarning ("CF: Can't load a empty file name configfile");
@ -597,8 +604,12 @@ bool CConfigFile::exists (const std::string &varName)
void CConfigFile::save () const void CConfigFile::save () const
{ {
// Avoid any problem, Force Locale to default char *locale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_ALL, "C");
if (!locale || strcmp(locale, "C"))
{
nlerror("Numeric locale not defined to C, an external library possibly redefined it!");
}
FILE *fp = nlfopen (getFilename(), "w"); FILE *fp = nlfopen (getFilename(), "w");
if (fp == NULL) if (fp == NULL)

View file

@ -43,6 +43,7 @@ string CI18N::_SelectedLanguageCode;
CI18N::ILoadProxy *CI18N::_LoadProxy = 0; CI18N::ILoadProxy *CI18N::_LoadProxy = 0;
vector<string> CI18N::_LanguageCodes; vector<string> CI18N::_LanguageCodes;
vector<ucstring> CI18N::_LanguageNames; vector<ucstring> CI18N::_LanguageNames;
std::string CI18N::_SystemLanguageCode;
bool CI18N::noResolution = false; bool CI18N::noResolution = false;
void CI18N::setLoadProxy(ILoadProxy *loadProxy) void CI18N::setLoadProxy(ILoadProxy *loadProxy)
@ -248,10 +249,8 @@ bool CI18N::isLanguageCodeSupported(const std::string &lang)
std::string CI18N::getSystemLanguageCode () std::string CI18N::getSystemLanguageCode ()
{ {
static std::string s_cachedSystemLanguage; if (!_SystemLanguageCode.empty())
return _SystemLanguageCode;
if (!s_cachedSystemLanguage.empty())
return s_cachedSystemLanguage;
#ifdef NL_OS_MAC #ifdef NL_OS_MAC
// under OS X, locale is only defined in console, not in UI // under OS X, locale is only defined in console, not in UI
@ -317,7 +316,7 @@ std::string CI18N::getSystemLanguageCode ()
// only keep language code if supported by NeL // only keep language code if supported by NeL
if (isLanguageCodeSupported(lang)) if (isLanguageCodeSupported(lang))
{ {
s_cachedSystemLanguage = lang; _SystemLanguageCode = lang;
break; break;
} }
} }
@ -328,21 +327,118 @@ std::string CI18N::getSystemLanguageCode ()
} }
#endif #endif
// use system locale (works under Linux and Windows) #ifdef NL_OS_WINDOWS
if (s_cachedSystemLanguage.empty()) // use user locale under Windows (since Vista)
if (_SystemLanguageCode.empty())
{ {
std::string lang = NLMISC::toLower(std::string(setlocale(LC_CTYPE, ""))); // GetUserDefaultLocaleName prototype
typedef int (WINAPI* GetUserDefaultLocaleNamePtr)(LPWSTR lpLocaleName, int cchLocaleName);
// only keep 2 first characters // get pointer on GetUserDefaultLocaleName, kernel32.dll is always in memory so no need to call LoadLibrary
if (lang.size() > 1) GetUserDefaultLocaleNamePtr nlGetUserDefaultLocaleName = (GetUserDefaultLocaleNamePtr)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetUserDefaultLocaleName");
s_cachedSystemLanguage = lang.substr(0, 2);
// only use it if found
if (nlGetUserDefaultLocaleName)
{
// get user locale
wchar_t buffer[LOCALE_NAME_MAX_LENGTH];
sint res = nlGetUserDefaultLocaleName(buffer, LOCALE_NAME_MAX_LENGTH);
// convert wide string to std::string
std::string lang = wideToUtf8(buffer);
// only keep 2 first characters
if (lang.size() > 1)
_SystemLanguageCode = lang.substr(0, 2);
}
}
#endif
// use system locale (works under OS X, Linux and Windows)
if (_SystemLanguageCode.empty())
{
// get default locale
char *locale = setlocale(LC_CTYPE, "");
if (locale)
{
std::string lang(locale);
#ifdef NL_OS_WINDOWS
// be sure supported languages are initialized
initLanguages();
// locales names are different under Windows, for example: French_France.1252
for(uint i = 0; i < _LanguageNames.size(); ++i)
{
std::string name = _LanguageNames[i].toUtf8();
// so we compare the language name with the supported ones
if (lang.compare(0, name.length(), name) == 0)
{
// found, so use its code
_SystemLanguageCode = _LanguageCodes[i];
break;
}
}
#else
std::string lang = NLMISC::toLower(lang);
// only keep 2 first characters
if (lang.size() > 1)
_SystemLanguageCode = lang.substr(0, 2);
#endif
}
} }
// english is default language // english is default language
if (s_cachedSystemLanguage.empty()) if (_SystemLanguageCode.empty())
s_cachedSystemLanguage = "en"; _SystemLanguageCode = "en";
return s_cachedSystemLanguage; return _SystemLanguageCode;
}
bool CI18N::setSystemLanguageCode (const std::string &languageCode)
{
// be sure supported languages are initialized
initLanguages();
std::string lang = NLMISC::toLower(languageCode);
// specified language is really a code (2 characters)
if (lang.length() == 2)
{
// check if language code is supported
for(uint i = 0; i < _LanguageCodes.size(); ++i)
{
std::string code = NLMISC::toLower(_LanguageCodes[i]);
if (lang == code)
{
// found, so use it
_SystemLanguageCode = lang;
return true;
}
}
}
// specified language is something else
else
{
// check if language name is supported
for(uint i = 0; i < _LanguageNames.size(); ++i)
{
std::string name = NLMISC::toLower(_LanguageNames[i].toUtf8());
if (name == lang)
{
// found, so use its code
_SystemLanguageCode = _LanguageCodes[i];
return true;
}
}
}
return false;
} }
void CI18N::removeCComment(ucstring &commentedString) void CI18N::removeCComment(ucstring &commentedString)

View file

@ -24,11 +24,6 @@
// Include from libxml2 // Include from libxml2
#include <libxml/xmlerror.h> #include <libxml/xmlerror.h>
#if defined(NL_OS_WINDOWS) && defined(NL_COMP_VC_VERSION) && NL_COMP_VC_VERSION >= 80
#define USE_LOCALE_ATOF
#include <locale.h>
#endif
using namespace std; using namespace std;
#define NLMISC_READ_BUFFER_SIZE 1024 #define NLMISC_READ_BUFFER_SIZE 1024
@ -46,26 +41,10 @@ const char SEPARATOR = ' ';
// *************************************************************************** // ***************************************************************************
#define readnumber(dest,thetype,digits,convfunc) \ #define readnumber(dest,digits) \
string number_as_string; \ string number_as_string; \
serialSeparatedBufferIn( number_as_string ); \ serialSeparatedBufferIn( number_as_string ); \
dest = (thetype)convfunc( number_as_string.c_str() ); NLMISC::fromString(number_as_string, dest);
#ifdef USE_LOCALE_ATOF
#define readnumberlocale(dest,thetype,digits,convfunc) \
string number_as_string; \
serialSeparatedBufferIn( number_as_string ); \
dest = (thetype)convfunc( number_as_string.c_str(), (_locale_t)_Locale );
#define nl_atof _atof_l
#else
#define readnumberlocale(dest,thetype,digits,convfunc) readnumber(dest,thetype,digits,convfunc)
#define nl_atof atof
#endif
// *************************************************************************** // ***************************************************************************
@ -91,13 +70,6 @@ CIXml::CIXml () : IStream (true /* Input mode */)
_ErrorString = ""; _ErrorString = "";
_TryBinaryMode = false; _TryBinaryMode = false;
_BinaryStream = NULL; _BinaryStream = NULL;
#ifdef USE_LOCALE_ATOF
// create C numeric locale
_Locale = _create_locale(LC_NUMERIC, "C");
#else
_Locale = NULL;
#endif
} }
// *************************************************************************** // ***************************************************************************
@ -113,13 +85,6 @@ CIXml::CIXml (bool tryBinaryMode) : IStream (true /* Input mode */)
_ErrorString = ""; _ErrorString = "";
_TryBinaryMode = tryBinaryMode; _TryBinaryMode = tryBinaryMode;
_BinaryStream = NULL; _BinaryStream = NULL;
#ifdef USE_LOCALE_ATOF
// create C numeric locale
_Locale = _create_locale(LC_NUMERIC, "C");
#else
_Locale = NULL;
#endif
} }
// *************************************************************************** // ***************************************************************************
@ -128,10 +93,6 @@ CIXml::~CIXml ()
{ {
// Release // Release
release (); release ();
#ifdef USE_LOCALE_ATOF
if (_Locale) _free_locale((_locale_t)_Locale);
#endif
} }
// *************************************************************************** // ***************************************************************************
@ -468,7 +429,7 @@ void CIXml::serial(uint8 &b)
else else
{ {
// Read the number // Read the number
readnumber( b, uint8, 3, atoi ); readnumber( b, 3 );
} }
} }
@ -482,7 +443,7 @@ void CIXml::serial(sint8 &b)
} }
else else
{ {
readnumber( b, sint8, 4, atoi ); readnumber( b, 4 );
} }
} }
@ -496,7 +457,7 @@ void CIXml::serial(uint16 &b)
} }
else else
{ {
readnumber( b, uint16, 5, atoi ); readnumber( b, 5 );
} }
} }
@ -510,7 +471,7 @@ void CIXml::serial(sint16 &b)
} }
else else
{ {
readnumber( b, sint16, 6, atoi ); readnumber( b, 6 );
} }
} }
@ -529,7 +490,7 @@ void CIXml::serial(uint32 &b)
} }
else else
{ {
readnumber( b, uint32, 10, atoui ); readnumber( b, 10 );
} }
} }
@ -543,7 +504,7 @@ void CIXml::serial(sint32 &b)
} }
else else
{ {
readnumber( b, sint32, 11, atoi ); readnumber( b, 11 );
} }
} }
@ -557,7 +518,7 @@ void CIXml::serial(uint64 &b)
} }
else else
{ {
readnumber( b, uint64, 20, atoiInt64 ); readnumber( b, 20 );
} }
} }
@ -571,7 +532,7 @@ void CIXml::serial(sint64 &b)
} }
else else
{ {
readnumber( b, sint64, 20, atoiInt64 ); readnumber( b, 20 );
} }
} }
@ -585,7 +546,7 @@ void CIXml::serial(float &b)
} }
else else
{ {
readnumberlocale( b, float, 128, nl_atof ); readnumber( b, 128 );
} }
} }
@ -599,7 +560,7 @@ void CIXml::serial(double &b)
} }
else else
{ {
readnumberlocale( b, double, 128, nl_atof ); readnumber( b, 128 );
} }
} }

View file

@ -43,22 +43,11 @@ const char SEPARATOR = ' ';
// *************************************************************************** // ***************************************************************************
#ifdef USE_LOCALE_SPRINTF
#define writenumber(src,format,digits) \
char number_as_cstring [digits+1]; \
_sprintf_l( number_as_cstring, format, (_locale_t)_Locale, src ); \
serialSeparatedBufferOut( number_as_cstring );
#else
#define writenumber(src,format,digits) \ #define writenumber(src,format,digits) \
char number_as_cstring [digits+1]; \ char number_as_cstring [digits+1]; \
sprintf( number_as_cstring, format, src ); \ sprintf( number_as_cstring, format, src ); \
serialSeparatedBufferOut( number_as_cstring ); serialSeparatedBufferOut( number_as_cstring );
#endif
// *************************************************************************** // ***************************************************************************
// XML callbacks // XML callbacks
// *************************************************************************** // ***************************************************************************
@ -149,13 +138,6 @@ COXml::COXml () : IStream (false /* Output mode */)
// Push begin // Push begin
_PushBegin = false; _PushBegin = false;
#ifdef USE_LOCALE_SPRINTF
// create C numeric locale
_Locale = _create_locale(LC_NUMERIC, "C");
#else
_Locale = NULL;
#endif
} }
// *************************************************************************** // ***************************************************************************
@ -215,10 +197,6 @@ COXml::~COXml ()
{ {
// Flush document to the internal stream // Flush document to the internal stream
flush (); flush ();
#ifdef USE_LOCALE_SPRINTF
if (_Locale) _free_locale((_locale_t)_Locale);
#endif
} }
// *************************************************************************** // ***************************************************************************

View file

@ -195,13 +195,17 @@ uint32 CAudioDecoderVorbis::getNextBytes(uint8 *buffer, uint32 minimum, uint32 m
uint8 CAudioDecoderVorbis::getChannels() uint8 CAudioDecoderVorbis::getChannels()
{ {
vorbis_info *vi = ov_info(&_OggVorbisFile, -1); vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
return (uint8)vi->channels; if (vi) return (uint8)vi->channels;
nlwarning("ov_info returned NULL");
return 0;
} }
uint CAudioDecoderVorbis::getSamplesPerSec() uint CAudioDecoderVorbis::getSamplesPerSec()
{ {
vorbis_info *vi = ov_info(&_OggVorbisFile, -1); vorbis_info *vi = ov_info(&_OggVorbisFile, -1);
return (uint)vi->rate; if (vi) return (uint)vi->rate;
nlwarning("ov_info returned NULL");
return 0;
} }
uint8 CAudioDecoderVorbis::getBitsPerSample() uint8 CAudioDecoderVorbis::getBitsPerSample()

View file

@ -30,13 +30,6 @@
#include <csignal> #include <csignal>
#endif #endif
#ifdef NL_OS_MAC
#include <stdio.h>
#include <sys/resource.h>
#include "nel/misc/dynloadlib.h"
#include "app_bundle_utils.h"
#endif
#include "nel/misc/debug.h" #include "nel/misc/debug.h"
#include "nel/misc/command.h" #include "nel/misc/command.h"
#include "nel/net/tcp_sock.h" #include "nel/net/tcp_sock.h"
@ -230,23 +223,6 @@ int main(int argc, char **argv)
} }
#endif // TEST_CRASH_COUNTER #endif // TEST_CRASH_COUNTER
#ifdef NL_OS_MAC
struct rlimit rlp, rlp2, rlp3;
getrlimit(RLIMIT_NOFILE, &rlp);
rlp2.rlim_cur = 1024;
rlp2.rlim_max = rlp.rlim_max;
setrlimit(RLIMIT_NOFILE, &rlp2);
getrlimit(RLIMIT_NOFILE, &rlp3);
nlinfo("rlimit before %d %d\n", rlp.rlim_cur, rlp.rlim_max);
nlinfo("rlimit after %d %d\n", rlp3.rlim_cur, rlp3.rlim_max);
// add the bundle's plugins path as library search path (for nel drivers)
CLibrary::addLibPath(getAppBundlePath() + "/Contents/PlugIns/nel/");
#endif
#if defined(NL_OS_WINDOWS) #if defined(NL_OS_WINDOWS)
#ifdef TEST_CRASH_COUNTER #ifdef TEST_CRASH_COUNTER
@ -295,6 +271,10 @@ int main(int argc, char **argv)
// TODO for Linux : splashscreen // TODO for Linux : splashscreen
#endif #endif
// initialize log
initLog();
// initialize patch manager and set the ryzom full path, before it's used // initialize patch manager and set the ryzom full path, before it's used
CPatchManager *pPM = CPatchManager::getInstance(); CPatchManager *pPM = CPatchManager::getInstance();
pPM->setRyzomFilename(Args.getProgramPath() + Args.getProgramName()); pPM->setRyzomFilename(Args.getProgramPath() + Args.getProgramName());

View file

@ -86,7 +86,7 @@ namespace NL3D
class CEntitySheet; class CEntitySheet;
class CEntityCL; class CEntityCL;
class CAttackInfo; struct CAttackInfo;
class CItemSheet; class CItemSheet;

View file

@ -105,6 +105,12 @@ extern HINSTANCE HInstance;
extern HWND SlashScreen; extern HWND SlashScreen;
#endif // NL_OS_WINDOWS #endif // NL_OS_WINDOWS
#ifdef NL_OS_MAC
#include <stdio.h>
#include <sys/resource.h>
#include "nel/misc/dynloadlib.h"
#endif
#include "app_bundle_utils.h" #include "app_bundle_utils.h"
#include <new> #include <new>
@ -796,6 +802,65 @@ static bool addRyzomIconBitmap(const std::string &directory, vector<CBitmap> &bi
} }
#endif #endif
//---------------------------------------------------
// initLog :
// Initialize the client.log file
//---------------------------------------------------
void initLog()
{
// Add a displayer for Debug Infos.
createDebug();
// Client.Log displayer
nlassert( !ErrorLog->getDisplayer("CLIENT.LOG") );
CFileDisplayer *ClientLogDisplayer = new CFileDisplayer(getLogDirectory() + "client.log", true, "CLIENT.LOG");
DebugLog->addDisplayer (ClientLogDisplayer);
InfoLog->addDisplayer (ClientLogDisplayer);
WarningLog->addDisplayer (ClientLogDisplayer);
ErrorLog->addDisplayer (ClientLogDisplayer);
AssertLog->addDisplayer (ClientLogDisplayer);
// Display the client version.
nlinfo("RYZOM VERSION : %s", getDebugVersion().c_str());
#ifdef NL_OS_MAC
struct rlimit rlp, rlp2, rlp3;
getrlimit(RLIMIT_NOFILE, &rlp);
rlim_t value = 1024;
rlp2.rlim_cur = std::min(value, rlp.rlim_max);
rlp2.rlim_max = rlp.rlim_max;
if (setrlimit(RLIMIT_NOFILE, &rlp2))
{
if (errno == EINVAL)
{
nlwarning("Unable to set rlimit with error: the specified limit is invalid");
}
else if (errno == EPERM)
{
nlwarning("Unable to set rlimit with error: the limit specified would have raised the maximum limit value and the caller is not the super-user");
}
else
{
nlwarning("Unable to set rlimit with error: unknown error");
}
}
getrlimit(RLIMIT_NOFILE, &rlp3);
nlinfo("rlimit before %llu %llu", (uint64)rlp.rlim_cur, (uint64)rlp.rlim_max);
nlinfo("rlimit after %llu %llu", (uint64)rlp3.rlim_cur, (uint64)rlp3.rlim_max);
// add the bundle's plugins path as library search path (for nel drivers)
if (CFile::isExists(getAppBundlePath() + "/Contents/PlugIns/nel"))
{
CLibrary::addLibPath(getAppBundlePath() + "/Contents/PlugIns/nel/");
}
#endif
}
//--------------------------------------------------- //---------------------------------------------------
// prelogInit : // prelogInit :
// Initialize the application before login // Initialize the application before login
@ -848,21 +913,6 @@ void prelogInit()
// Due to Bug #906, we disable the stl xml allocation // Due to Bug #906, we disable the stl xml allocation
// nlverify (xmlMemSetup (XmlFree4NeL, XmlMalloc4NeL, XmlRealloc4NeL, XmlStrdup4NeL) == 0); // nlverify (xmlMemSetup (XmlFree4NeL, XmlMalloc4NeL, XmlRealloc4NeL, XmlStrdup4NeL) == 0);
// Add a displayer for Debug Infos.
createDebug();
// Client.Log displayer
nlassert( !ErrorLog->getDisplayer("CLIENT.LOG") );
CFileDisplayer *ClientLogDisplayer = new CFileDisplayer(getLogDirectory() + "client.log", true, "CLIENT.LOG");
DebugLog->addDisplayer (ClientLogDisplayer);
InfoLog->addDisplayer (ClientLogDisplayer);
WarningLog->addDisplayer (ClientLogDisplayer);
ErrorLog->addDisplayer (ClientLogDisplayer);
AssertLog->addDisplayer (ClientLogDisplayer);
// Display the client version.
nlinfo("RYZOM VERSION : %s", getDebugVersion().c_str());
// Init the debug memory // Init the debug memory
initDebugMemory(); initDebugMemory();

View file

@ -27,6 +27,9 @@ namespace NLMISC
class IProgressCallback; class IProgressCallback;
} }
// Initialize the log
void initLog();
// Initialize the application before login step // Initialize the application before login step
void prelogInit(); void prelogInit();

View file

@ -2635,7 +2635,13 @@ public:
{ {
ucstring title; ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title); STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
pMenu->addLineAtIndex(5 + insertion_index, title+" @{T8}/"+s, "chat_target_selected", "dyn"+s, "dyn"+s);
// replace dynamic channel name and shortcut
ucstring res = CI18N::get("uiFilterMenuDynamic");
strFindReplace(res, "%channel", title);
strFindReplace(res, "%shortcut", s);
pMenu->addLineAtIndex(5 + insertion_index, res, "chat_target_selected", "dyn"+s, "dyn"+s);
insertion_index++; insertion_index++;
} }
} }