Index: src/libictranslate/ResourceManager.cpp =================================================================== diff -u -N -rd9527df01ee91b35d9a5fdccb80ded25a9c8265f -r19b135b50b55b75d008526a799344bda9a62dc22 --- src/libictranslate/ResourceManager.cpp (.../ResourceManager.cpp) (revision d9527df01ee91b35d9a5fdccb80ded25a9c8265f) +++ src/libictranslate/ResourceManager.cpp (.../ResourceManager.cpp) (revision 19b135b50b55b75d008526a799344bda9a62dc22) @@ -28,1072 +28,1070 @@ #endif #define TRANSLATION_FORMAT_VERSION _T("2") - -BEGIN_ICTRANSLATE_NAMESPACE - #define EMPTY_STRING _T("") -CResourceManager CResourceManager::S_ResourceManager; - -CFormat::CFormat(const wchar_t* pszFormat) : - m_strText(pszFormat) +namespace ictranslate { -} + CResourceManager CResourceManager::S_ResourceManager; -CFormat::CFormat() -{ -} + CFormat::CFormat(const wchar_t* pszFormat) : + m_strText(pszFormat) + { + } -CFormat::~CFormat() -{ -} + CFormat::CFormat() + { + } -void CFormat::SetFormat(const wchar_t* pszFormat) -{ - m_strText = pszFormat; -} + CFormat::~CFormat() + { + } -CFormat& CFormat::SetParam(PCTSTR pszName, PCTSTR pszText) -{ - assert(pszName); - if(!pszName) - return *this; - - size_t stLen = _tcslen(pszName); - std::wstring::size_type stPos = 0; - while((stPos = m_strText.find(pszName)) != std::wstring::npos) + void CFormat::SetFormat(const wchar_t* pszFormat) { - m_strText.replace(stPos, stLen, pszText); + m_strText = pszFormat; } - return *this; -} + CFormat& CFormat::SetParam(PCTSTR pszName, PCTSTR pszText) + { + assert(pszName); + if(!pszName) + return *this; -CFormat& CFormat::SetParam(PCTSTR pszName, unsigned long long ullData) -{ - wchar_t szBuffer[64]; - _sntprintf(szBuffer, 63, L"%I64u", ullData); - szBuffer[63] = _T('\0'); + size_t stLen = _tcslen(pszName); + std::wstring::size_type stPos = 0; + while((stPos = m_strText.find(pszName)) != std::wstring::npos) + { + m_strText.replace(stPos, stLen, pszText); + } - return SetParam(pszName, szBuffer); -} + return *this; + } -CFormat& CFormat::SetParam(PCTSTR pszName, long long llData) -{ - wchar_t szBuffer[64]; - _sntprintf(szBuffer, 63, L"%I64d", llData); - szBuffer[63] = _T('\0'); + CFormat& CFormat::SetParam(PCTSTR pszName, unsigned long long ullData) + { + wchar_t szBuffer[ 64 ]; + _sntprintf(szBuffer, 63, L"%I64u", ullData); + szBuffer[ 63 ] = _T('\0'); - return SetParam(pszName, szBuffer); -} + return SetParam(pszName, szBuffer); + } -CFormat& CFormat::SetParam(PCTSTR pszName, unsigned long ulData) -{ - wchar_t szBuffer[64]; - _sntprintf(szBuffer, 63, L"%lu", ulData); - szBuffer[63] = _T('\0'); + CFormat& CFormat::SetParam(PCTSTR pszName, long long llData) + { + wchar_t szBuffer[ 64 ]; + _sntprintf(szBuffer, 63, L"%I64d", llData); + szBuffer[ 63 ] = _T('\0'); - return SetParam(pszName, szBuffer); -} + return SetParam(pszName, szBuffer); + } -CFormat& CFormat::SetParam(PCTSTR pszName, unsigned int uiData) -{ - wchar_t szBuffer[64]; - _sntprintf(szBuffer, 63, L"%u", uiData); - szBuffer[63] = _T('\0'); + CFormat& CFormat::SetParam(PCTSTR pszName, unsigned long ulData) + { + wchar_t szBuffer[ 64 ]; + _sntprintf(szBuffer, 63, L"%lu", ulData); + szBuffer[ 63 ] = _T('\0'); - return SetParam(pszName, szBuffer); -} + return SetParam(pszName, szBuffer); + } -CFormat& CFormat::SetParam(PCTSTR pszName, int iData) -{ - wchar_t szBuffer[64]; - _sntprintf(szBuffer, 63, L"%d", iData); - szBuffer[63] = _T('\0'); + CFormat& CFormat::SetParam(PCTSTR pszName, unsigned int uiData) + { + wchar_t szBuffer[ 64 ]; + _sntprintf(szBuffer, 63, L"%u", uiData); + szBuffer[ 63 ] = _T('\0'); - return SetParam(pszName, szBuffer); -} + return SetParam(pszName, szBuffer); + } -CFormat& CFormat::SetParam(PCTSTR pszName, bool bData) -{ - wchar_t szBuffer[64]; - _sntprintf(szBuffer, 63, L"%hu", (unsigned short)bData); - szBuffer[63] = _T('\0'); + CFormat& CFormat::SetParam(PCTSTR pszName, int iData) + { + wchar_t szBuffer[ 64 ]; + _sntprintf(szBuffer, 63, L"%d", iData); + szBuffer[ 63 ] = _T('\0'); - return SetParam(pszName, szBuffer); -} + return SetParam(pszName, szBuffer); + } -CTranslationItem::CTranslationItem() -{ -} - -CTranslationItem::CTranslationItem(const wchar_t* pszText, unsigned int uiChecksum) -{ - if(pszText) + CFormat& CFormat::SetParam(PCTSTR pszName, bool bData) { - m_stTextLength = _tcslen(pszText); - if(m_stTextLength > 0) - { - m_pszText = new wchar_t[m_stTextLength + 1]; - _tcscpy(m_pszText, pszText); + wchar_t szBuffer[ 64 ]; + _sntprintf(szBuffer, 63, L"%hu", (unsigned short)bData); + szBuffer[ 63 ] = _T('\0'); - UnescapeString(); - } + return SetParam(pszName, szBuffer); + } - m_uiChecksum = uiChecksum; + CTranslationItem::CTranslationItem() + { } -} -ictranslate::CTranslationItem::CTranslationItem(const CTranslationItem& rSrc) -{ - if(rSrc.m_pszText) + CTranslationItem::CTranslationItem(const wchar_t* pszText, unsigned int uiChecksum) { - m_stTextLength = _tcslen(rSrc.m_pszText); - if(m_stTextLength > 0) + if(pszText) { - m_pszText = new wchar_t[ m_stTextLength + 1 ]; - _tcscpy(m_pszText, rSrc.m_pszText); + m_stTextLength = _tcslen(pszText); + if(m_stTextLength > 0) + { + m_pszText = new wchar_t[ m_stTextLength + 1 ]; + _tcscpy(m_pszText, pszText); - UnescapeString(); + UnescapeString(); + } + + m_uiChecksum = uiChecksum; } } -} -CTranslationItem::~CTranslationItem() -{ - Clear(); -} - -CTranslationItem& CTranslationItem::operator=(const CTranslationItem& rSrc) -{ - if(this != &rSrc) + ictranslate::CTranslationItem::CTranslationItem(const CTranslationItem& rSrc) { - Clear(); if(rSrc.m_pszText) { - m_stTextLength = rSrc.m_stTextLength; + m_stTextLength = _tcslen(rSrc.m_pszText); if(m_stTextLength > 0) { - m_pszText = new wchar_t[rSrc.m_stTextLength + 1]; + m_pszText = new wchar_t[ m_stTextLength + 1 ]; _tcscpy(m_pszText, rSrc.m_pszText); + + UnescapeString(); } } - m_uiChecksum = rSrc.m_uiChecksum; } - return *this; -} + CTranslationItem::~CTranslationItem() + { + Clear(); + } -void CTranslationItem::Clear() -{ - delete [] m_pszText; - m_pszText = nullptr; - m_stTextLength = 0; - m_uiChecksum = 0; -} - -const wchar_t* CTranslationItem::GetText() const -{ - return m_pszText ? m_pszText : _T(""); -} - -void CTranslationItem::SetText(const wchar_t* pszText, bool bUnescapeString) -{ - delete [] m_pszText; - if(pszText) + CTranslationItem& CTranslationItem::operator=(const CTranslationItem& rSrc) { - m_stTextLength = _tcslen(pszText); - if(m_stTextLength > 0) + if(this != &rSrc) { - m_pszText = new wchar_t[m_stTextLength + 1]; - _tcscpy(m_pszText, pszText); - if(bUnescapeString) - UnescapeString(); - return; + Clear(); + if(rSrc.m_pszText) + { + m_stTextLength = rSrc.m_stTextLength; + if(m_stTextLength > 0) + { + m_pszText = new wchar_t[ rSrc.m_stTextLength + 1 ]; + _tcscpy(m_pszText, rSrc.m_pszText); + } + } + m_uiChecksum = rSrc.m_uiChecksum; } + + return *this; } - m_pszText = nullptr; - m_stTextLength = 0; -} + void CTranslationItem::Clear() + { + delete[] m_pszText; + m_pszText = nullptr; + m_stTextLength = 0; + m_uiChecksum = 0; + } -void CTranslationItem::UnescapeString() -{ - if(!m_pszText) - return; + const wchar_t* CTranslationItem::GetText() const + { + return m_pszText ? m_pszText : _T(""); + } - const wchar_t* pszIn = m_pszText; - wchar_t* pszOut = m_pszText; - while (*pszIn != 0) + void CTranslationItem::SetText(const wchar_t* pszText, bool bUnescapeString) { - if (*pszIn == _T('\\')) + delete[] m_pszText; + if(pszText) { - pszIn++; - switch(*pszIn++) + m_stTextLength = _tcslen(pszText); + if(m_stTextLength > 0) { - case _T('t'): - *pszOut++ = _T('\t'); - break; - case _T('r'): - *pszOut++ = _T('\r'); - break; - case _T('n'): - *pszOut++ = _T('\n'); - break; - default: - *pszOut++ = _T('\\'); + m_pszText = new wchar_t[ m_stTextLength + 1 ]; + _tcscpy(m_pszText, pszText); + if(bUnescapeString) + UnescapeString(); + return; } } - else - *pszOut++ = *pszIn++; + + m_pszText = nullptr; + m_stTextLength = 0; } - *pszOut = _T('\0'); -} -CTranslationItem::ECompareResult CTranslationItem::Compare(const CTranslationItem& rReferenceItem) -{ - if(!m_pszText || !rReferenceItem.m_pszText) - return eResult_Invalid; + void CTranslationItem::UnescapeString() + { + if(!m_pszText) + return; - if(m_uiChecksum != rReferenceItem.m_uiChecksum) - return eResult_Invalid; + const wchar_t* pszIn = m_pszText; + wchar_t* pszOut = m_pszText; + while(*pszIn != 0) + { + if(*pszIn == _T('\\')) + { + pszIn++; + switch(*pszIn++) + { + case _T('t'): + *pszOut++ = _T('\t'); + break; + case _T('r'): + *pszOut++ = _T('\r'); + break; + case _T('n'): + *pszOut++ = _T('\n'); + break; + default: + *pszOut++ = _T('\\'); + } + } + else + *pszOut++ = *pszIn++; + } + *pszOut = _T('\0'); + } - // space check - if(rReferenceItem.m_pszText[0] == _T(' ') && m_pszText[0] != _T(' ')) - return eResult_ContentWarning; - - size_t stReferenceLen = _tcslen(rReferenceItem.m_pszText); - size_t stOwnLen = _tcslen(m_pszText); - if(stReferenceLen > 0 && stOwnLen > 0 && rReferenceItem.m_pszText[stReferenceLen - 1] == _T(' ') && m_pszText[stOwnLen - 1] != _T(' ')) - return eResult_ContentWarning; + CTranslationItem::ECompareResult CTranslationItem::Compare(const CTranslationItem& rReferenceItem) + { + if(!m_pszText || !rReferenceItem.m_pszText) + return eResult_Invalid; - // formatting strings check - std::set setRefFmt; - if(!rReferenceItem.GetFormatStrings(setRefFmt)) - return eResult_ContentWarning; + if(m_uiChecksum != rReferenceItem.m_uiChecksum) + return eResult_Invalid; - std::set setThisFmt; - if(!GetFormatStrings(setThisFmt)) - return eResult_ContentWarning; + // space check + if(rReferenceItem.m_pszText[ 0 ] == _T(' ') && m_pszText[ 0 ] != _T(' ')) + return eResult_ContentWarning; - if(setRefFmt != setThisFmt) - return eResult_ContentWarning; + size_t stReferenceLen = _tcslen(rReferenceItem.m_pszText); + size_t stOwnLen = _tcslen(m_pszText); + if(stReferenceLen > 0 && stOwnLen > 0 && rReferenceItem.m_pszText[ stReferenceLen - 1 ] == _T(' ') && m_pszText[ stOwnLen - 1 ] != _T(' ')) + return eResult_ContentWarning; - return eResult_Valid; -} + // formatting strings check + std::set setRefFmt; + if(!rReferenceItem.GetFormatStrings(setRefFmt)) + return eResult_ContentWarning; -bool CTranslationItem::GetFormatStrings(std::set& setFmtStrings) const -{ - setFmtStrings.clear(); + std::set setThisFmt; + if(!GetFormatStrings(setThisFmt)) + return eResult_ContentWarning; - const wchar_t* pszData = m_pszText; - const size_t stMaxFmt = 256; - wchar_t szFmt[stMaxFmt]; - while((pszData = _tcschr(pszData, _T('%'))) != nullptr) - { - pszData++; // it works assuming the string is null-terminated + if(setRefFmt != setThisFmt) + return eResult_ContentWarning; - // search the end of fmt string - const wchar_t* pszNext = pszData; - while(*pszNext && isalpha(*pszNext)) - pszNext++; + return eResult_Valid; + } - // if we have bigger buffer needs than is available - if(pszNext - pszData >= stMaxFmt) - return false; + bool CTranslationItem::GetFormatStrings(std::set& setFmtStrings) const + { + setFmtStrings.clear(); - // copy data - _tcsncpy(szFmt, pszData, pszNext - pszData); - szFmt[pszNext - pszData] = _T('\0'); + const wchar_t* pszData = m_pszText; + const size_t stMaxFmt = 256; + wchar_t szFmt[ stMaxFmt ]; + while((pszData = _tcschr(pszData, _T('%'))) != nullptr) + { + pszData++; // it works assuming the string is null-terminated - setFmtStrings.insert(std::wstring(szFmt)); - } + // search the end of fmt string + const wchar_t* pszNext = pszData; + while(*pszNext && isalpha(*pszNext)) + pszNext++; - return true; -} + // if we have bigger buffer needs than is available + if(pszNext - pszData >= stMaxFmt) + return false; -CLangData::CLangData() : - m_pszFilename(nullptr), - m_pszLngName(nullptr), - m_pszFontFace(nullptr), - m_wPointSize(0), - m_pszHelpName(nullptr), - m_pszAuthor(nullptr), - m_bRTL(false), - m_uiSectionID(0), - m_bUpdating(false), - m_bModified(false) -{ -} + // copy data + _tcsncpy(szFmt, pszData, pszNext - pszData); + szFmt[ pszNext - pszData ] = _T('\0'); -CLangData::~CLangData() -{ - delete [] m_pszFilename; - delete [] m_pszLngName; - delete [] m_pszFontFace; - delete [] m_pszHelpName; - delete [] m_pszAuthor; -} + setFmtStrings.insert(std::wstring(szFmt)); + } -void CLangData::Clear() -{ - delete [] m_pszFilename; - m_pszFilename = nullptr; - delete [] m_pszLngName; - m_pszLngName = nullptr; - delete [] m_pszFontFace; - m_pszFontFace = nullptr; - delete [] m_pszHelpName; - m_pszHelpName = nullptr; - delete [] m_pszAuthor; - m_pszAuthor = nullptr; - m_bModified = false; - m_bRTL = false; - m_bUpdating = false; - m_uiSectionID = 0; - m_wPointSize = 0; + return true; + } - m_mapTranslation.clear(); -} + CLangData::CLangData() : + m_pszFilename(nullptr), + m_pszLngName(nullptr), + m_pszFontFace(nullptr), + m_wPointSize(0), + m_pszHelpName(nullptr), + m_pszAuthor(nullptr), + m_bRTL(false), + m_uiSectionID(0), + m_bUpdating(false), + m_bModified(false) + { + } -CLangData::CLangData(const CLangData& ld) : - m_pszFilename(nullptr), - m_pszLngName(nullptr), - m_pszFontFace(nullptr), - m_wPointSize(ld.m_wPointSize), - m_pszHelpName(nullptr), - m_pszAuthor(nullptr), - m_bRTL(ld.m_bRTL), - m_uiSectionID(ld.m_uiSectionID), - m_bUpdating(ld.m_bUpdating), - m_bModified(false) -{ - SetFilename(ld.GetFilename(true)); - SetLangName(ld.GetLangName()); - SetFontFace(ld.GetFontFace()); - SetPointSize(ld.GetPointSize()); - SetDirection(ld.GetDirection()); - SetHelpName(ld.GetHelpName()); - SetAuthor(ld.GetAuthor()); + CLangData::~CLangData() + { + delete[] m_pszFilename; + delete[] m_pszLngName; + delete[] m_pszFontFace; + delete[] m_pszHelpName; + delete[] m_pszAuthor; + } - m_mapTranslation.insert(ld.m_mapTranslation.begin(), ld.m_mapTranslation.end()); -} - -CLangData& CLangData::operator=(const CLangData& rSrc) -{ - if(this != &rSrc) + void CLangData::Clear() { - SetFilename(rSrc.GetFilename(true)); - SetLangName(rSrc.GetLangName()); - SetFontFace(rSrc.GetFontFace()); - SetPointSize(rSrc.GetPointSize()); - SetDirection(rSrc.GetDirection()); - SetHelpName(rSrc.GetHelpName()); - SetAuthor(rSrc.GetAuthor()); - m_bRTL = rSrc.m_bRTL; - m_bUpdating = rSrc.m_bUpdating; - m_uiSectionID = rSrc.m_uiSectionID; - m_wPointSize = rSrc.m_wPointSize; + delete[] m_pszFilename; + m_pszFilename = nullptr; + delete[] m_pszLngName; + m_pszLngName = nullptr; + delete[] m_pszFontFace; + m_pszFontFace = nullptr; + delete[] m_pszHelpName; + m_pszHelpName = nullptr; + delete[] m_pszAuthor; + m_pszAuthor = nullptr; m_bModified = false; + m_bRTL = false; + m_bUpdating = false; + m_uiSectionID = 0; + m_wPointSize = 0; - m_mapTranslation.insert(rSrc.m_mapTranslation.begin(), rSrc.m_mapTranslation.end()); + m_mapTranslation.clear(); } - return *this; -} + CLangData::CLangData(const CLangData& ld) : + m_pszFilename(nullptr), + m_pszLngName(nullptr), + m_pszFontFace(nullptr), + m_wPointSize(ld.m_wPointSize), + m_pszHelpName(nullptr), + m_pszAuthor(nullptr), + m_bRTL(ld.m_bRTL), + m_uiSectionID(ld.m_uiSectionID), + m_bUpdating(ld.m_bUpdating), + m_bModified(false) + { + SetFilename(ld.GetFilename(true)); + SetLangName(ld.GetLangName()); + SetFontFace(ld.GetFontFace()); + SetPointSize(ld.GetPointSize()); + SetDirection(ld.GetDirection()); + SetHelpName(ld.GetHelpName()); + SetAuthor(ld.GetAuthor()); -bool CLangData::ReadInfo(PCTSTR pszFile) -{ - try + m_mapTranslation.insert(ld.m_mapTranslation.begin(), ld.m_mapTranslation.end()); + } + + CLangData& CLangData::operator=(const CLangData& rSrc) { - Clear(); + if(this != &rSrc) + { + SetFilename(rSrc.GetFilename(true)); + SetLangName(rSrc.GetLangName()); + SetFontFace(rSrc.GetFontFace()); + SetPointSize(rSrc.GetPointSize()); + SetDirection(rSrc.GetDirection()); + SetHelpName(rSrc.GetHelpName()); + SetAuthor(rSrc.GetAuthor()); + m_bRTL = rSrc.m_bRTL; + m_bUpdating = rSrc.m_bUpdating; + m_uiSectionID = rSrc.m_uiSectionID; + m_wPointSize = rSrc.m_wPointSize; + m_bModified = false; - config cfg(config::eIni); - const unsigned int uiLangName = cfg.register_string(_T("Info/Lang Name"), _T("")); - const unsigned int uiFontFace = cfg.register_string(_T("Info/Font Face"), _T("")); - const unsigned int uiSize = cfg.register_signed_num(_T("Info/Size"), 0, 0, 0xffff); - const unsigned int uiRTL = cfg.register_bool(_T("Info/RTL reading order"), false); - const unsigned int uiHelpName = cfg.register_string(_T("Info/Help name"), _T("")); - const unsigned int uiAuthor = cfg.register_string(_T("Info/Author"), _T("")); - const unsigned int uiVersion = cfg.register_string(_T("Info/Format version"), _T("1")); + m_mapTranslation.insert(rSrc.m_mapTranslation.begin(), rSrc.m_mapTranslation.end()); + } - cfg.read(pszFile); - - // we don't support old language versions - const wchar_t* pszVersion = cfg.get_string(uiVersion); - if(_tcscmp(pszVersion, TRANSLATION_FORMAT_VERSION) != 0) - return false; + return *this; + } - const wchar_t* psz = cfg.get_string(uiLangName); - if(!psz || psz[0] == _T('\0')) - return false; - SetLangName(psz); + bool CLangData::ReadInfo(PCTSTR pszFile) + { + try + { + Clear(); - psz = cfg.get_string(uiFontFace); - if(!psz || psz[0] == _T('\0')) - return false; - SetFontFace(psz); + config cfg(config::eIni); + const unsigned int uiLangName = cfg.register_string(_T("Info/Lang Name"), _T("")); + const unsigned int uiFontFace = cfg.register_string(_T("Info/Font Face"), _T("")); + const unsigned int uiSize = cfg.register_signed_num(_T("Info/Size"), 0, 0, 0xffff); + const unsigned int uiRTL = cfg.register_bool(_T("Info/RTL reading order"), false); + const unsigned int uiHelpName = cfg.register_string(_T("Info/Help name"), _T("")); + const unsigned int uiAuthor = cfg.register_string(_T("Info/Author"), _T("")); + const unsigned int uiVersion = cfg.register_string(_T("Info/Format version"), _T("1")); - long long ll = cfg.get_signed_num(uiSize); - if(ll == 0) - return false; - SetPointSize((WORD)ll); + cfg.read(pszFile); - SetDirection(cfg.get_bool(uiRTL)); + // we don't support old language versions + const wchar_t* pszVersion = cfg.get_string(uiVersion); + if(_tcscmp(pszVersion, TRANSLATION_FORMAT_VERSION) != 0) + return false; - psz = cfg.get_string(uiHelpName); - if(!psz || psz[0] == _T('\0')) - return false; - SetHelpName(psz); + const wchar_t* psz = cfg.get_string(uiLangName); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetLangName(psz); - psz = cfg.get_string(uiAuthor); - if(!psz || psz[0] == _T('\0')) - return false; - SetAuthor(psz); + psz = cfg.get_string(uiFontFace); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetFontFace(psz); - SetFilename(pszFile); + long long ll = cfg.get_signed_num(uiSize); + if(ll == 0) + return false; + SetPointSize((WORD)ll); - m_bModified = false; + SetDirection(cfg.get_bool(uiRTL)); - return true; - } - catch(...) - { - return false; - } -} + psz = cfg.get_string(uiHelpName); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetHelpName(psz); -void CLangData::EnumAttributesCallback(bool bGroup, const wchar_t* pszName, const wchar_t* pszValue, void* pData) -{ - CLangData* pLangData = (CLangData*)pData; - assert(pLangData); - assert(pszName); - if(!pLangData || !pszName) - return; + psz = cfg.get_string(uiAuthor); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetAuthor(psz); - if(bGroup && _tcsicmp(pszName, _T("Info")) == 0) - return; - if(bGroup) - { - // new section - remember in member - pLangData->m_uiSectionID = _ttoi(pszName); + SetFilename(pszFile); + + m_bModified = false; + + return true; + } + catch(...) + { + return false; + } } - else + + void CLangData::EnumAttributesCallback(bool bGroup, const wchar_t* pszName, const wchar_t* pszValue, void* pData) { - unsigned int uiID = 0; - unsigned int uiChecksum = 0; + CLangData* pLangData = (CLangData*)pData; + assert(pLangData); + assert(pszName); + if(!pLangData || !pszName) + return; - // parse the pszName to get both the string id and checksum - const wchar_t* pszChecksum = _tcschr(pszName, _T('[')); - if(pszChecksum == nullptr) + if(bGroup && _tcsicmp(pszName, _T("Info")) == 0) + return; + if(bGroup) { - TRACE(_T("Warning! Old-style translation string %s.\n"), pszName); - - int iCount = _stscanf(pszName, L"%u", &uiID); - if(iCount != 1) - { - TRACE(_T("Warning! Problem retrieving id from string '%s'\n"), pszName); - return; - } + // new section - remember in member + pLangData->m_uiSectionID = _ttoi(pszName); } else { - int iCount = _stscanf(pszName, L"%u[0x%x]", &uiID, &uiChecksum); - if(iCount != 2) + unsigned int uiID = 0; + unsigned int uiChecksum = 0; + + // parse the pszName to get both the string id and checksum + const wchar_t* pszChecksum = _tcschr(pszName, _T('[')); + if(pszChecksum == nullptr) { - TRACE(_T("Warning! Problem retrieving id/checksum from string '%s'\n"), pszName); - return; + TRACE(_T("Warning! Old-style translation string %s.\n"), pszName); + + int iCount = _stscanf(pszName, L"%u", &uiID); + if(iCount != 1) + { + TRACE(_T("Warning! Problem retrieving id from string '%s'\n"), pszName); + return; + } } - } + else + { + int iCount = _stscanf(pszName, L"%u[0x%x]", &uiID, &uiChecksum); + if(iCount != 2) + { + TRACE(_T("Warning! Problem retrieving id/checksum from string '%s'\n"), pszName); + return; + } + } - unsigned int uiKey = pLangData->m_uiSectionID << 16 | uiID; - translation_map::iterator itTranslation = pLangData->m_mapTranslation.end(); - if(pLangData->m_bUpdating) - { - // check if the checksum exists and matches - itTranslation = pLangData->m_mapTranslation.find(uiKey); - if(itTranslation == pLangData->m_mapTranslation.end()) + unsigned int uiKey = pLangData->m_uiSectionID << 16 | uiID; + translation_map::iterator itTranslation = pLangData->m_mapTranslation.end(); + if(pLangData->m_bUpdating) { - TRACE(_T("Warning! Superfluous entry %lu in processed language file\n"), uiKey); - return; // entry not found - probably superfluous entry in the language file + // check if the checksum exists and matches + itTranslation = pLangData->m_mapTranslation.find(uiKey); + if(itTranslation == pLangData->m_mapTranslation.end()) + { + TRACE(_T("Warning! Superfluous entry %lu in processed language file\n"), uiKey); + return; // entry not found - probably superfluous entry in the language file + } + + if((*itTranslation).second.GetChecksum() != uiChecksum) + { + TRACE(_T("Warning! Invalid checksum for string ID %lu in processed language file\n"), uiKey); + return; // entry has invalid checksum (older version of translation) + } } + else + { + std::pair pairTranslation = pLangData->m_mapTranslation.insert(translation_map::value_type(uiKey, CTranslationItem())); + itTranslation = pairTranslation.first; + } - if((*itTranslation).second.GetChecksum() != uiChecksum) + assert(itTranslation != pLangData->m_mapTranslation.end()); + if(itTranslation != pLangData->m_mapTranslation.end()) { - TRACE(_T("Warning! Invalid checksum for string ID %lu in processed language file\n"), uiKey); - return; // entry has invalid checksum (older version of translation) + (*itTranslation).second.SetText(pszValue, true); + if(!pLangData->m_bUpdating) + (*itTranslation).second.SetChecksum(uiChecksum); } } - else - { - std::pair pairTranslation = pLangData->m_mapTranslation.insert(translation_map::value_type(uiKey, CTranslationItem())); - itTranslation = pairTranslation.first; - } + } - assert(itTranslation != pLangData->m_mapTranslation.end()); - if(itTranslation != pLangData->m_mapTranslation.end()) + void CLangData::UnescapeString(wchar_t* pszData) + { + wchar_t* pszOut = pszData; + while(*pszData != 0) { - (*itTranslation).second.SetText(pszValue, true); - if(!pLangData->m_bUpdating) - (*itTranslation).second.SetChecksum(uiChecksum); + if(*pszData == _T('\\')) + { + pszData++; + switch(*pszData++) + { + case _T('t'): + *pszOut++ = _T('\t'); + break; + case _T('r'): + *pszOut++ = _T('\r'); + break; + case _T('n'): + *pszOut++ = _T('\n'); + break; + default: + *pszOut++ = _T('\\'); + } + } + else + *pszOut++ = *pszData++; } + *pszOut = _T('\0'); + } -} -void CLangData::UnescapeString(wchar_t* pszData) -{ - wchar_t* pszOut = pszData; - while (*pszData != 0) + bool CLangData::ReadTranslation(PCTSTR pszFile, bool bUpdateTranslation, bool bIgnoreVersion) { - if (*pszData == _T('\\')) + try { - pszData++; - switch(*pszData++) + if(!bUpdateTranslation) + Clear(); + + // load data from file + config cfg(config::eIni); + const unsigned int uiLangName = cfg.register_string(_T("Info/Lang Name"), _T("")); + const unsigned int uiFontFace = cfg.register_string(_T("Info/Font Face"), _T("")); + const unsigned int uiSize = cfg.register_signed_num(_T("Info/Size"), 0, 0, 0xffff); + const unsigned int uiRTL = cfg.register_bool(_T("Info/RTL reading order"), false); + const unsigned int uiHelpName = cfg.register_string(_T("Info/Help name"), _T("")); + const unsigned int uiAuthor = cfg.register_string(_T("Info/Author"), _T("")); + const unsigned int uiVersion = cfg.register_string(_T("Info/Format version"), _T("1")); + + cfg.read(pszFile); + + // we don't support old language versions unless requested specifically + if(!bIgnoreVersion) { - case _T('t'): - *pszOut++ = _T('\t'); - break; - case _T('r'): - *pszOut++ = _T('\r'); - break; - case _T('n'): - *pszOut++ = _T('\n'); - break; - default: - *pszOut++ = _T('\\'); + const wchar_t* pszVersion = cfg.get_string(uiVersion); + if(_tcscmp(pszVersion, TRANSLATION_FORMAT_VERSION) != 0) + return false; } - } - else - *pszOut++ = *pszData++; - } - *pszOut = _T('\0'); -} + const wchar_t* psz = cfg.get_string(uiLangName); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetLangName(psz); -bool CLangData::ReadTranslation(PCTSTR pszFile, bool bUpdateTranslation, bool bIgnoreVersion) -{ - try - { - if(!bUpdateTranslation) - Clear(); + psz = cfg.get_string(uiFontFace); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetFontFace(psz); - // load data from file - config cfg(config::eIni); - const unsigned int uiLangName = cfg.register_string(_T("Info/Lang Name"), _T("")); - const unsigned int uiFontFace = cfg.register_string(_T("Info/Font Face"), _T("")); - const unsigned int uiSize = cfg.register_signed_num(_T("Info/Size"), 0, 0, 0xffff); - const unsigned int uiRTL = cfg.register_bool(_T("Info/RTL reading order"), false); - const unsigned int uiHelpName = cfg.register_string(_T("Info/Help name"), _T("")); - const unsigned int uiAuthor = cfg.register_string(_T("Info/Author"), _T("")); - const unsigned int uiVersion = cfg.register_string(_T("Info/Format version"), _T("1")); + long long ll = cfg.get_signed_num(uiSize); + if(ll == 0) + return false; + SetPointSize((WORD)ll); - cfg.read(pszFile); + SetDirection(cfg.get_bool(uiRTL)); - // we don't support old language versions unless requested specifically - if(!bIgnoreVersion) - { - const wchar_t* pszVersion = cfg.get_string(uiVersion); - if(_tcscmp(pszVersion, TRANSLATION_FORMAT_VERSION) != 0) + psz = cfg.get_string(uiHelpName); + if(!psz || psz[ 0 ] == _T('\0')) return false; - } + SetHelpName(psz); - const wchar_t* psz = cfg.get_string(uiLangName); - if(!psz || psz[0] == _T('\0')) - return false; - SetLangName(psz); + psz = cfg.get_string(uiAuthor); + if(!psz || psz[ 0 ] == _T('\0')) + return false; + SetAuthor(psz); - psz = cfg.get_string(uiFontFace); - if(!psz || psz[0] == _T('\0')) - return false; - SetFontFace(psz); + m_bUpdating = bUpdateTranslation; + m_uiSectionID = 0; + if(!cfg.enum_properties(_T("*"), EnumAttributesCallback, this)) + { + m_bUpdating = false; + return false; + } + m_bUpdating = false; - long long ll = cfg.get_signed_num(uiSize); - if(ll == 0) - return false; - SetPointSize((WORD)ll); + SetFilename(pszFile); - SetDirection(cfg.get_bool(uiRTL)); + m_bModified = false; - psz = cfg.get_string(uiHelpName); - if(!psz || psz[0] == _T('\0')) + return true; + } + catch(...) + { return false; - SetHelpName(psz); + } + } - psz = cfg.get_string(uiAuthor); - if(!psz || psz[0] == _T('\0')) - return false; - SetAuthor(psz); + void CLangData::WriteTranslation(PCTSTR pszPath) + { + if(!IsValidDescription()) + throw std::runtime_error("Invalid translation information (author, name or point size)"); - m_bUpdating = bUpdateTranslation; - m_uiSectionID = 0; - if(!cfg.enum_properties(_T("*"), EnumAttributesCallback, this)) + // real writing + const int iBufferSize = 256; + wchar_t szTemp[ iBufferSize ]; + + // load data from file + config cfg(config::eIni); + cfg.set_string(_T("Info/Lang Name"), m_pszLngName); + cfg.set_string(_T("Info/Font Face"), m_pszFontFace); + cfg.set_string(_T("Info/Size"), _itot(m_wPointSize, szTemp, 10)); + cfg.set_string(_T("Info/RTL reading order"), m_bRTL ? _T("1") : _T("0")); + cfg.set_string(_T("Info/Help name"), m_pszHelpName); + cfg.set_string(_T("Info/Author"), m_pszAuthor); + cfg.set_string(_T("Info/Format version"), TRANSLATION_FORMAT_VERSION); + + std::wstring strText; + for(translation_map::iterator it = m_mapTranslation.begin(); it != m_mapTranslation.end(); ++it) { - m_bUpdating = false; - return false; + unsigned int uiKey = (*it).first; + _sntprintf(szTemp, iBufferSize - 1, L"%u/%u[0x%x]", (uiKey >> 16), uiKey & 0x0000ffff, (*it).second.GetChecksum()); + + strText = (*it).second.GetText(); + std::wstring::size_type stPos; + while((stPos = strText.find_first_of(_T("\r\n\t"))) != std::wstring::npos) + { + switch(strText[ stPos ]) + { + case _T('\r'): + strText.replace(stPos, 1, _T("\\r")); + break; + case _T('\n'): + strText.replace(stPos, 1, _T("\\n")); + break; + case _T('\t'): + strText.replace(stPos, 1, _T("\\t")); + break; + } + } + + cfg.set_string(szTemp, strText.c_str()); } - m_bUpdating = false; - SetFilename(pszFile); + if(pszPath == nullptr) + pszPath = m_pszFilename; + else + SetFilename(pszPath); + cfg.write(pszPath); m_bModified = false; - - return true; } - catch(...) + + PCTSTR CLangData::GetString(WORD wHiID, WORD wLoID) { - return false; + translation_map::const_iterator it = m_mapTranslation.find((wHiID << 16) | wLoID); + if(it != m_mapTranslation.end()) + return (*it).second.GetText(); + else + return EMPTY_STRING; } -} -void CLangData::WriteTranslation(PCTSTR pszPath) -{ - if(!IsValidDescription()) - throw std::runtime_error("Invalid translation information (author, name or point size)"); - - // real writing - const int iBufferSize = 256; - wchar_t szTemp[iBufferSize]; - - // load data from file - config cfg(config::eIni); - cfg.set_string(_T("Info/Lang Name"), m_pszLngName); - cfg.set_string(_T("Info/Font Face"), m_pszFontFace); - cfg.set_string(_T("Info/Size"), _itot(m_wPointSize, szTemp, 10)); - cfg.set_string(_T("Info/RTL reading order"), m_bRTL ? _T("1") : _T("0")); - cfg.set_string(_T("Info/Help name"), m_pszHelpName); - cfg.set_string(_T("Info/Author"), m_pszAuthor); - cfg.set_string(_T("Info/Format version"), TRANSLATION_FORMAT_VERSION); - - std::wstring strText; - for(translation_map::iterator it = m_mapTranslation.begin(); it != m_mapTranslation.end(); ++it) + void CLangData::EnumStrings(PFNENUMCALLBACK pfnCallback, void* pData) { - unsigned int uiKey = (*it).first; - _sntprintf(szTemp, iBufferSize - 1, L"%u/%u[0x%x]", (uiKey >> 16), uiKey & 0x0000ffff, (*it).second.GetChecksum()); + for(translation_map::const_iterator iterTranslation = m_mapTranslation.begin(); iterTranslation != m_mapTranslation.end(); ++iterTranslation) + { + (*pfnCallback)((*iterTranslation).first, &(*iterTranslation).second, pData); + } + } - strText = (*it).second.GetText(); - std::wstring::size_type stPos; - while((stPos = strText.find_first_of(_T("\r\n\t"))) != std::wstring::npos) + CTranslationItem* CLangData::GetTranslationItem(unsigned int uiTranslationKey, bool bCreate) + { + translation_map::iterator iterTranslation = m_mapTranslation.find(uiTranslationKey); + if(iterTranslation != m_mapTranslation.end()) + return &(*iterTranslation).second; + else { - switch(strText[stPos]) + if(bCreate) { - case _T('\r'): - strText.replace(stPos, 1, _T("\\r")); - break; - case _T('\n'): - strText.replace(stPos, 1, _T("\\n")); - break; - case _T('\t'): - strText.replace(stPos, 1, _T("\\t")); - break; + std::pair pairTranslation = m_mapTranslation.insert(std::make_pair(uiTranslationKey, CTranslationItem())); + if(pairTranslation.second) + { + m_bModified = true; + return &(*pairTranslation.first).second; + } } } - cfg.set_string(szTemp, strText.c_str()); + return nullptr; } - if(pszPath == nullptr) - pszPath = m_pszFilename; - else - SetFilename(pszPath); - cfg.write(pszPath); - - m_bModified = false; -} - -PCTSTR CLangData::GetString(WORD wHiID, WORD wLoID) -{ - translation_map::const_iterator it=m_mapTranslation.find((wHiID << 16) | wLoID); - if (it != m_mapTranslation.end()) - return (*it).second.GetText(); - else - return EMPTY_STRING; -} - -void CLangData::EnumStrings(PFNENUMCALLBACK pfnCallback, void* pData) -{ - for(translation_map::const_iterator iterTranslation = m_mapTranslation.begin(); iterTranslation != m_mapTranslation.end(); ++iterTranslation) + bool CLangData::Exists(unsigned int uiTranslationKey) const { - (*pfnCallback)((*iterTranslation).first, &(*iterTranslation).second, pData); + return m_mapTranslation.find(uiTranslationKey) != m_mapTranslation.end(); } -} -CTranslationItem* CLangData::GetTranslationItem(unsigned int uiTranslationKey, bool bCreate) -{ - translation_map::iterator iterTranslation = m_mapTranslation.find(uiTranslationKey); - if(iterTranslation != m_mapTranslation.end()) - return &(*iterTranslation).second; - else + // removes strings that does not exist in the reference translation + void CLangData::CleanupTranslation(const CLangData& rReferenceTranslation) { - if(bCreate) + translation_map::iterator iterTranslation = m_mapTranslation.begin(); + while(iterTranslation != m_mapTranslation.end()) { - std::pair pairTranslation = m_mapTranslation.insert(std::make_pair(uiTranslationKey, CTranslationItem())); - if(pairTranslation.second) + if(!rReferenceTranslation.Exists((*iterTranslation).first)) { m_bModified = true; - return &(*pairTranslation.first).second; + m_mapTranslation.erase(iterTranslation++); } + else + ++iterTranslation; } } - return nullptr; -} + void CLangData::SetFilename(PCTSTR psz) + { + if(m_pszFilename) + delete[] m_pszFilename; -bool CLangData::Exists(unsigned int uiTranslationKey) const -{ - return m_mapTranslation.find(uiTranslationKey) != m_mapTranslation.end(); -} + // copy + m_pszFilename = new TCHAR[ _tcslen(psz) + 1 ]; + _tcscpy(m_pszFilename, psz); -// removes strings that does not exist in the reference translation -void CLangData::CleanupTranslation(const CLangData& rReferenceTranslation) -{ - translation_map::iterator iterTranslation = m_mapTranslation.begin(); - while(iterTranslation != m_mapTranslation.end()) + m_bModified = true; + } + + PCTSTR CLangData::GetFilename(bool bFullPath) const { - if(!rReferenceTranslation.Exists((*iterTranslation).first)) + if(bFullPath) + return m_pszFilename; + else { - m_bModified = true; - m_mapTranslation.erase(iterTranslation++); + if(m_pszFilename) + { + TCHAR *pszFnd = _tcsrchr(m_pszFilename, _T('\\')); + if(pszFnd) + return pszFnd + 1; + } + + return m_pszFilename; } - else - ++iterTranslation; } -} -void CLangData::SetFilename(PCTSTR psz) -{ - if (m_pszFilename) - delete [] m_pszFilename; + void CLangData::SetLangName(PCTSTR psz) + { + if(m_pszLngName) + delete[] m_pszLngName; + m_pszLngName = new TCHAR[ _tcslen(psz) + 1 ]; + _tcscpy(m_pszLngName, psz); + m_bModified = true; + } - // copy - m_pszFilename=new TCHAR[_tcslen(psz)+1]; - _tcscpy(m_pszFilename, psz); + void CLangData::SetFontFace(PCTSTR psz) + { + if(m_pszFontFace) + delete[] m_pszFontFace; + m_pszFontFace = new TCHAR[ _tcslen(psz) + 1 ]; + _tcscpy(m_pszFontFace, psz); + m_bModified = true; + } - m_bModified = true; -} + void CLangData::SetHelpName(PCTSTR psz) + { + SetFnameData(&m_pszHelpName, psz); + m_bModified = true; + } -PCTSTR CLangData::GetFilename(bool bFullPath) const -{ - if (bFullPath) - return m_pszFilename; - else + void CLangData::SetAuthor(PCTSTR psz) { - if(m_pszFilename) - { - TCHAR *pszFnd=_tcsrchr(m_pszFilename, _T('\\')); - if (pszFnd) - return pszFnd+1; - } + if(m_pszAuthor) + delete[] m_pszAuthor; + m_pszAuthor = new TCHAR[ _tcslen(psz) + 1 ]; + _tcscpy(m_pszAuthor, psz); + m_bModified = true; + } - return m_pszFilename; + bool CLangData::IsValidDescription() const + { + // basic sanity checks + if(!m_pszAuthor || m_pszAuthor[ 0 ] == _T('\0') || + !m_pszLngName || m_pszLngName[ 0 ] == _T('\0') || + !m_pszFontFace || m_pszFontFace[ 0 ] == _T('\0') || + m_wPointSize == 0) + return false; + return true; } -} -void CLangData::SetLangName(PCTSTR psz) -{ - if (m_pszLngName) - delete [] m_pszLngName; - m_pszLngName=new TCHAR[_tcslen(psz)+1]; - _tcscpy(m_pszLngName, psz); - m_bModified = true; -} + void CLangData::SetFnameData(PTSTR *ppszDst, PCTSTR pszSrc) + { + if(*ppszDst) + delete[](*ppszDst); + const TCHAR* pszLast = nullptr; + if((pszLast = _tcsrchr(pszSrc, _T('\\'))) != nullptr) + pszLast++; + else + pszLast = pszSrc; -void CLangData::SetFontFace(PCTSTR psz) -{ - if (m_pszFontFace) - delete [] m_pszFontFace; - m_pszFontFace=new TCHAR[_tcslen(psz)+1]; - _tcscpy(m_pszFontFace, psz); - m_bModified = true; -} + // copy + *ppszDst = new TCHAR[ _tcslen(pszLast) + 1 ]; + _tcscpy(*ppszDst, pszLast); + } -void CLangData::SetHelpName(PCTSTR psz) -{ - SetFnameData(&m_pszHelpName, psz); - m_bModified = true; -} + CResourceManager::CResourceManager() : + m_hRes(nullptr), + m_pfnCallback(nullptr) + { + InitializeCriticalSection(&m_cs); + } -void CLangData::SetAuthor(PCTSTR psz) -{ - if (m_pszAuthor) - delete [] m_pszAuthor; - m_pszAuthor=new TCHAR[_tcslen(psz)+1]; - _tcscpy(m_pszAuthor, psz); - m_bModified = true; -} + CResourceManager::~CResourceManager() + { + DeleteCriticalSection(&m_cs); + } -bool CLangData::IsValidDescription() const -{ - // basic sanity checks - if(!m_pszAuthor || m_pszAuthor[0] == _T('\0') || - !m_pszLngName || m_pszLngName[0] == _T('\0') || - !m_pszFontFace || m_pszFontFace[0] == _T('\0') || - m_wPointSize == 0) - return false; - return true; -} + CResourceManager& CResourceManager::Acquire() + { + return CResourceManager::S_ResourceManager; + } -void CLangData::SetFnameData(PTSTR *ppszDst, PCTSTR pszSrc) -{ - if (*ppszDst) - delete [] (*ppszDst); - const TCHAR* pszLast=nullptr; - if ( (pszLast=_tcsrchr(pszSrc, _T('\\'))) != nullptr) - pszLast++; - else - pszLast=pszSrc; + void CResourceManager::Init(HMODULE hrc) + { + m_hRes = hrc; + } - // copy - *ppszDst=new TCHAR[_tcslen(pszLast)+1]; - _tcscpy(*ppszDst, pszLast); -} + // requires the param with ending '\\' + void CResourceManager::Scan(LPCTSTR pszFolder, std::vector* pvData) + { + assert(pszFolder); + assert(pvData); + if(!pszFolder || !pvData) + return; -CResourceManager::CResourceManager() : - m_hRes(nullptr), - m_pfnCallback(nullptr) -{ - InitializeCriticalSection(&m_cs); -} + CString strPath = pszFolder; + strPath += _T("*.lng"); -CResourceManager::~CResourceManager() -{ - DeleteCriticalSection(&m_cs); -} + WIN32_FIND_DATA wfd; + HANDLE hFind = ::FindFirstFile(strPath, &wfd); + BOOL bFound = TRUE; + CLangData ld; + while(bFound && hFind != INVALID_HANDLE_VALUE) + { + if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + strPath = pszFolder; + strPath += wfd.cFileName; + if(ld.ReadInfo(strPath)) + pvData->push_back(ld); + } -CResourceManager& CResourceManager::Acquire() -{ - return CResourceManager::S_ResourceManager; -} + bFound = ::FindNextFile(hFind, &wfd); + } -void CResourceManager::Init(HMODULE hrc) -{ - m_hRes=hrc; -} + if(hFind != INVALID_HANDLE_VALUE) + ::FindClose(hFind); + } -// requires the param with ending '\\' -void CResourceManager::Scan(LPCTSTR pszFolder, vector* pvData) -{ - assert(pszFolder); - assert(pvData); - if(!pszFolder || !pvData) - return; - - CString strPath = pszFolder; - strPath += _T("*.lng"); - - WIN32_FIND_DATA wfd; - HANDLE hFind=::FindFirstFile(strPath, &wfd); - BOOL bFound=TRUE; - CLangData ld; - while (bFound && hFind != INVALID_HANDLE_VALUE) + bool CResourceManager::SetLanguage(PCTSTR pszPath) { - if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + CString strBasePath; + CString strRealPath = pszPath; + + // parse the path to allow reading the English language first + const CString strEnglishFileName = _T("english.lng"); + + CString strTestPath = pszPath; + strTestPath.MakeLower(); + if(strTestPath.Right(strEnglishFileName.GetLength()) != strEnglishFileName) { - strPath = pszFolder; - strPath += wfd.cFileName; - if (ld.ReadInfo(strPath)) - pvData->push_back(ld); + int iPos = strRealPath.ReverseFind(L'\\'); + if(iPos <= 0) + strBasePath = strEnglishFileName; + else + strBasePath = strRealPath.Left(iPos + 1) + strEnglishFileName; } + else + { + strBasePath = strRealPath; + strRealPath.Empty(); + } - bFound=::FindNextFile(hFind, &wfd); - } + // and load everything + bool bRet = true; - if (hFind != INVALID_HANDLE_VALUE) - ::FindClose(hFind); -} + EnterCriticalSection(&m_cs); + try + { + if(!strBasePath.IsEmpty()) + bRet = m_ld.ReadTranslation(strBasePath); // base language + if(bRet && !strRealPath.IsEmpty()) + bRet = m_ld.ReadTranslation(strRealPath, true); // real language + } + catch(...) + { + LeaveCriticalSection(&m_cs); + return false; + } + LeaveCriticalSection(&m_cs); + if(!bRet) + return false; -bool CResourceManager::SetLanguage(PCTSTR pszPath) -{ - CString strBasePath; - CString strRealPath = pszPath; + // update registered dialog boxes + std::list::iterator it = m_lhDialogs.begin(); + while(it != m_lhDialogs.end()) + { + if(::IsWindow((*it)->m_hWnd)) + (*it)->PostMessage(WM_RMNOTIFY, RMNT_LANGCHANGE, 0); + ++it; + } - // parse the path to allow reading the English language first - const CString strEnglishFileName = _T("english.lng"); + // send the notification stuff to the others + if(m_pfnCallback) + (*m_pfnCallback)(RMNT_LANGCHANGE); - CString strTestPath = pszPath; - strTestPath.MakeLower(); - if(strTestPath.Right(strEnglishFileName.GetLength()) != strEnglishFileName) + return bRet; + } + + HGLOBAL CResourceManager::LoadResource(LPCTSTR pszType, LPCTSTR pszName) { - int iPos = strRealPath.ReverseFind(L'\\'); - if(iPos <= 0) - strBasePath = strEnglishFileName; - else - strBasePath = strRealPath.Left(iPos + 1) + strEnglishFileName; + EnterCriticalSection(&m_cs); + + // find resource + HGLOBAL hRet = nullptr; + HRSRC hr = FindResource(m_hRes, pszName, pszType); + if(hr) + hRet = ::LoadResource(m_hRes, hr); + + LeaveCriticalSection(&m_cs); + return hRet; } - else + + HACCEL CResourceManager::LoadAccelerators(LPCTSTR pszName) { - strBasePath = strRealPath; - strRealPath.Empty(); + return ::LoadAccelerators(m_hRes, pszName); } - // and load everything - bool bRet = true; - - EnterCriticalSection(&m_cs); - try + HBITMAP CResourceManager::LoadBitmap(LPCTSTR pszName) { - if(!strBasePath.IsEmpty()) - bRet = m_ld.ReadTranslation(strBasePath); // base language - if(bRet && !strRealPath.IsEmpty()) - bRet=m_ld.ReadTranslation(strRealPath, true); // real language + return ::LoadBitmap(m_hRes, pszName); } - catch(...) + + HCURSOR CResourceManager::LoadCursor(LPCTSTR pszName) { - LeaveCriticalSection(&m_cs); - return false; + return ::LoadCursor(m_hRes, pszName); } - LeaveCriticalSection(&m_cs); - if (!bRet) - return false; - - // update registered dialog boxes - list::iterator it=m_lhDialogs.begin(); - while (it != m_lhDialogs.end()) + + HICON CResourceManager::LoadIcon(LPCTSTR pszName) { - if (::IsWindow((*it)->m_hWnd)) - (*it)->PostMessage(WM_RMNOTIFY, RMNT_LANGCHANGE, 0); - ++it; + return ::LoadIcon(m_hRes, pszName); } - - // send the notification stuff to the others - if (m_pfnCallback) - (*m_pfnCallback)(RMNT_LANGCHANGE); - return bRet; -} - -HGLOBAL CResourceManager::LoadResource(LPCTSTR pszType, LPCTSTR pszName) -{ - EnterCriticalSection(&m_cs); - - // find resource - HGLOBAL hRet=nullptr; - HRSRC hr=FindResource(m_hRes, pszName, pszType); - if (hr) - hRet=::LoadResource(m_hRes, hr); - - LeaveCriticalSection(&m_cs); - return hRet; -} - -HACCEL CResourceManager::LoadAccelerators(LPCTSTR pszName) -{ - return ::LoadAccelerators(m_hRes, pszName); -} - -HBITMAP CResourceManager::LoadBitmap(LPCTSTR pszName) -{ - return ::LoadBitmap(m_hRes, pszName); -} - -HCURSOR CResourceManager::LoadCursor(LPCTSTR pszName) -{ - return ::LoadCursor(m_hRes, pszName); -} - -HICON CResourceManager::LoadIcon(LPCTSTR pszName) -{ - return ::LoadIcon(m_hRes, pszName); -} - -void CResourceManager::UpdateMenu(HMENU hMenu, WORD wMenuID) -{ - // change the strings inside the menu to the one from txt res file - int iCount=::GetMenuItemCount(hMenu); - MENUITEMINFO mif; - WORD wLoID; - TCHAR szItem[1024]; - memset(szItem, 0, 1024); - for (int i=0;i