From 1ce002432b3a5c0bb0a4c9f9eb8d399d649fe283 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 6 Jul 2012 08:31:38 +0000 Subject: - mir_core.dll moved to the core :) - plugins now obtain the fake langpack id if langpack is absent git-svn-id: http://svn.miranda-ng.org/main/trunk@787 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Mir_core/langpack.cpp | 640 ------------------------------------------ 1 file changed, 640 deletions(-) delete mode 100644 plugins/Mir_core/langpack.cpp (limited to 'plugins/Mir_core/langpack.cpp') diff --git a/plugins/Mir_core/langpack.cpp b/plugins/Mir_core/langpack.cpp deleted file mode 100644 index 90c11a4a65..0000000000 --- a/plugins/Mir_core/langpack.cpp +++ /dev/null @@ -1,640 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2009 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include "commonheaders.h" - -#define LANGPACK_BUF_SIZE 4000 - -static int CompareMuuids(const MUUID* p1, const MUUID* p2) -{ - return memcmp(p1, p2, sizeof(MUUID)); -} - -static LIST lMuuids(10, CompareMuuids); -static MUUID* pCurrentMuuid = NULL; - -static BOOL bModuleInitialized = FALSE; - -struct LangPackEntry { - DWORD englishHash; - char *local; - wchar_t *wlocal; - MUUID* pMuuid; - LangPackEntry* pNext; // for langpack items with the same hash value -}; - -struct LangPackStruct { - TCHAR filename[MAX_PATH]; - TCHAR filePath[MAX_PATH]; - char language[64]; - char lastModifiedUsing[64]; - char authors[256]; - char authorEmail[128]; - LangPackEntry *entry; - int entryCount, entriesAlloced; - LCID localeID; - UINT defaultANSICp; -} static langPack; - -static int IsEmpty(char *str) -{ - int i = 0; - - while (str[i]) - { - if (str[i] != ' ' && str[i] != '\r' && str[i] != '\n') - return 0; - i++; - } - return 1; -} - -static void ConvertBackslashes(char *str, UINT fileCp) -{ - char *pstr; - for (pstr = str; *pstr; pstr = CharNextExA(fileCp, pstr, 0)) { - if (*pstr == '\\') { - switch(pstr[1]) { - case 'n': *pstr = '\n'; break; - case 't': *pstr = '\t'; break; - case 'r': *pstr = '\r'; break; - default: *pstr = pstr[1]; break; - } - memmove(pstr+1, pstr+2, strlen(pstr+2) + 1); -} } } - -#ifdef _DEBUG -//#pragma optimize("gt", on) -#endif - -// MurmurHash2 -MIR_CORE_DLL(unsigned int) mir_hash(const void * key, unsigned int len) -{ - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. - const unsigned int m = 0x5bd1e995; - const int r = 24; - - // Initialize the hash to a 'random' value - unsigned int h = len; - - // Mix 4 bytes at a time into the hash - const unsigned char * data = (const unsigned char *)key; - - while (len >= 4) - { - unsigned int k = *(unsigned int *)data; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - // Handle the last few bytes of the input array - switch(len) - { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; - h *= m; - }; - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; -} - -static unsigned int __fastcall hashstrW(const char * key) -{ - if (key == NULL) return 0; - const unsigned int len = (unsigned int)wcslen((const wchar_t*)key); - char* buf = (char*)alloca(len + 1); - for (unsigned i = 0; i <= len ; ++i) - buf[i] = key[i << 1]; - return mir_hash(buf, len); -} - -static int SortLangPackHashesProc(LangPackEntry *arg1, LangPackEntry *arg2) -{ - if (arg1->englishHash < arg2->englishHash) return -1; - if (arg1->englishHash > arg2->englishHash) return 1; - - return (arg1->pMuuid < arg2->pMuuid) ? -1 : 1; -} - -static void swapBytes(void* p, size_t iSize) -{ - char *head = (char *)p; // here - char *tail = head + iSize - 1; - - for (; tail > head; --tail, ++head) { - char temp = *head; - *head = *tail; - *tail = temp; - } -} - -static bool EnterMuuid(const char* p, MUUID& result) -{ - if (*p++ != '{') - return false; - - BYTE* d = (BYTE*)&result; - - for (int nBytes = 0; *p && nBytes < 24; p++) { - if (*p == '-') - continue; - - if (*p == '}') - break; - - if ( !isxdigit(*p)) - return false; - - if ( !isxdigit(p[1])) - return false; - - int c = 0; - if (sscanf(p, "%2x", &c) != 1) - return false; - - *d++ = (BYTE)c; - nBytes++; - p++; - } - - if (*p != '}') - return false; - - swapBytes(&result.a, sizeof(result.a)); - swapBytes(&result.b, sizeof(result.b)); - swapBytes(&result.c, sizeof(result.c)); - return true; -} - -static void LoadLangPackFile(FILE* fp, char* line, UINT fileCp) -{ - while ( !feof(fp)) { - if (fgets(line, LANGPACK_BUF_SIZE, fp) == NULL) - break; - - if (IsEmpty(line) || line[0] == ';' || line[0] == 0) - continue; - - rtrim(line); - - if (line[0] == '#') { - strlwr(line); - - if ( !memcmp(line+1, "include", 7)) { - TCHAR tszFileName[ MAX_PATH ]; - TCHAR* fileName = mir_a2t(ltrim(line+9)); - mir_sntprintf(tszFileName, SIZEOF(tszFileName), _T("%s%s"), langPack.filePath, fileName); - mir_free(fileName); - - FILE* p = _tfopen(tszFileName, _T("r")); - if (p) { - line[0] = 0; - fgets(line, SIZEOF(line), p); - - UINT fileCp = CP_ACP; - if (strlen(line) >= 3 && line[0] == '\xef' && line[1] == '\xbb' && line[2] == '\xbf') { - fileCp = CP_UTF8; - fseek(p, 3, SEEK_SET); - } - else { - fileCp = langPack.defaultANSICp; - fseek(p, 0, SEEK_SET); - } - - LoadLangPackFile(p, line, fileCp); - fclose(p); - } - } - else if ( !memcmp(line+1, "muuid", 5)) { - MUUID t; - if ( !EnterMuuid(line+7, t)) - continue; - - MUUID* pNew = (MUUID*)mir_alloc(sizeof(MUUID)); - memcpy(pNew, &t, sizeof(t)); - lMuuids.insert(pNew); - pCurrentMuuid = pNew; - } - - continue; - } - - ConvertBackslashes(line, fileCp); - - if (line[0] == '[' && line[ lstrlenA(line)-1 ] == ']') { - if (langPack.entryCount && langPack.entry[ langPack.entryCount-1].local == NULL) - langPack.entryCount--; - - char* pszLine = line+1; - line[ lstrlenA(line)-1 ] = '\0'; - if (++langPack.entryCount > langPack.entriesAlloced) { - langPack.entriesAlloced += 128; - langPack.entry = (LangPackEntry*)mir_realloc(langPack.entry, sizeof(LangPackEntry)*langPack.entriesAlloced); - } - - LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; - E->englishHash = mir_hashstr(pszLine); - E->local = NULL; - E->wlocal = NULL; - E->pMuuid = pCurrentMuuid; - E->pNext = NULL; - continue; - } - - if ( !langPack.entryCount) - continue; - - LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; - if (E->local == NULL) { - E->local = mir_strdup(line); - if (fileCp == CP_UTF8) - Utf8DecodeCP(E->local, langPack.defaultANSICp, NULL); - - int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); - E->wlocal = (wchar_t *)mir_alloc((iNeeded+1) * sizeof(wchar_t)); - MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal, iNeeded); - } - else { - size_t iOldLenA = strlen(E->local); - E->local = (char*)mir_realloc(E->local, iOldLenA + strlen(line) + 2); - strcat(E->local, "\n"); - strcat(E->local, line); - - if (fileCp == CP_UTF8) - Utf8DecodeCP(E->local + iOldLenA + 1, langPack.defaultANSICp, NULL); - - int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); - size_t iOldLen = wcslen(E->wlocal); - E->wlocal = (wchar_t*)mir_realloc(E->wlocal, (sizeof(wchar_t) * (iOldLen + iNeeded + 2))); - wcscat(E->wlocal, L"\n"); - MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal + iOldLen + 1, iNeeded); - } - } -} - -MIR_CORE_DLL(int) LoadLangPack(const TCHAR *szLangPack) -{ - int startOfLine=0; - USHORT langID; - - lstrcpy(langPack.filename, szLangPack); - lstrcpy(langPack.filePath, szLangPack); - TCHAR* p = _tcsrchr(langPack.filePath, '\\'); - if (p) - p[1] = 0; - - FILE *fp = _tfopen(szLangPack, _T("rt")); - if (fp == NULL) - return 1; - - char line[ LANGPACK_BUF_SIZE ] = ""; - fgets(line, SIZEOF(line), fp); - - UINT fileCp = CP_ACP; - size_t lineLen = strlen(line); - if (lineLen >= 3 && line[0] == '\xef' && line[1] == '\xbb' && line[2] == '\xbf') - { - fileCp = CP_UTF8; - memmove(line, line + 3, lineLen - 2); - } - - lrtrim(line); - if (lstrcmpA(line, "Miranda Language Pack Version 1")) { - fclose(fp); - return 2; - } - - //headers - while ( !feof(fp)) { - startOfLine = ftell(fp); - if (fgets(line, SIZEOF(line), fp) == NULL) - break; - - lrtrim(line); - if (IsEmpty(line) || line[0] == ';' || line[0] == 0) - continue; - - if (line[0] == '[' || line[0] == '#') - break; - - char* pszColon = strchr(line, ':'); - if (pszColon == NULL) { - fclose(fp); - return 3; - } - - *pszColon++ = 0; - if ( !lstrcmpA(line, "Language")) {mir_snprintf(langPack.language, sizeof(langPack.language), "%s", pszColon); lrtrim(langPack.language);} - else if ( !lstrcmpA(line, "Last-Modified-Using")) {mir_snprintf(langPack.lastModifiedUsing, sizeof(langPack.lastModifiedUsing), "%s", pszColon); lrtrim(langPack.lastModifiedUsing);} - else if ( !lstrcmpA(line, "Authors")) {mir_snprintf(langPack.authors, sizeof(langPack.authors), "%s", pszColon); lrtrim(langPack.authors);} - else if ( !lstrcmpA(line, "Author-email")) {mir_snprintf(langPack.authorEmail, sizeof(langPack.authorEmail), "%s", pszColon); lrtrim(langPack.authorEmail);} - else if ( !lstrcmpA(line, "Locale")) { - char szBuf[20], *stopped; - - lrtrim(pszColon + 1); - langID = (USHORT)strtol(pszColon, &stopped, 16); - langPack.localeID = MAKELCID(langID, 0); - GetLocaleInfoA(langPack.localeID, LOCALE_IDEFAULTANSICODEPAGE, szBuf, 10); - szBuf[5] = 0; // codepages have max. 5 digits - langPack.defaultANSICp = atoi(szBuf); - if (fileCp == CP_ACP) - fileCp = langPack.defaultANSICp; - } - } - - //body - fseek(fp, startOfLine, SEEK_SET); - langPack.entriesAlloced = 0; - - LoadLangPackFile(fp, line, fileCp); - fclose(fp); - pCurrentMuuid = NULL; - - qsort(langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int SortLangPackHashesProc2(LangPackEntry *arg1, LangPackEntry *arg2) -{ - if (arg1->englishHash < arg2->englishHash) return -1; - if (arg1->englishHash > arg2->englishHash) return 1; - return 0; -} - -static char *LangPackTranslateString(MUUID* pUuid, const char *szEnglish, const int W) -{ - if (langPack.entryCount == 0 || szEnglish == NULL) - return (char*)szEnglish; - - LangPackEntry key, *entry; - key.englishHash = W ? hashstrW(szEnglish) : mir_hashstr(szEnglish); - entry = (LangPackEntry*)bsearch(&key, langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc2); - if (entry == NULL) - return (char*)szEnglish; - - // try to find the exact match, otherwise the first entry will be returned - if (pUuid) { - for (LangPackEntry* p = entry->pNext; p != NULL; p = p->pNext) { - if (p->pMuuid == pUuid) { - entry = p; - break; - } } } - - return W ? (char *)entry->wlocal : entry->local; -} - -MIR_CORE_DLL(int) Langpack_GetDefaultCodePage() -{ - return langPack.defaultANSICp; -} - -MIR_CORE_DLL(int) Langpack_GetDefaultLocale() -{ - return (langPack.localeID == 0) ? LOCALE_USER_DEFAULT : langPack.localeID; -} - -MIR_CORE_DLL(TCHAR*) Langpack_PcharToTchar(const char* pszStr) -{ - if (pszStr == NULL) - return NULL; - - int len = (int)strlen(pszStr); - TCHAR* result = (TCHAR*)alloca((len+1)*sizeof(TCHAR)); - MultiByteToWideChar(Langpack_GetDefaultCodePage(), 0, pszStr, -1, result, len); - result[len] = 0; - return mir_wstrdup(TranslateW(result)); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(char*) TranslateA_LP(const char* str, int hLangpack) -{ - return (char*)LangPackTranslateString(Langpack_LookupUuid(hLangpack), str, FALSE); -} - -MIR_CORE_DLL(WCHAR*) TranslateW_LP(const WCHAR* str, int hLangpack) -{ - return (WCHAR*)LangPackTranslateString(Langpack_LookupUuid(hLangpack), (LPCSTR)str, TRUE); -} - -MIR_CORE_DLL(void) TranslateMenu_LP(HMENU hMenu, int hLangpack) -{ - MUUID* uuid = Langpack_LookupUuid(hLangpack); - - MENUITEMINFO mii; - mii.cbSize = MENUITEMINFO_V4_SIZE; - for (int i = GetMenuItemCount(hMenu)-1; i >= 0; i--) { - TCHAR str[256]; - mii.fMask = MIIM_TYPE|MIIM_SUBMENU; - mii.dwTypeData = (TCHAR*)str; - mii.cch = SIZEOF(str); - GetMenuItemInfo(hMenu, i, TRUE, &mii); - - if (mii.cch && mii.dwTypeData) { - TCHAR* result = (TCHAR*)LangPackTranslateString(uuid, (const char*)mii.dwTypeData, TRUE); - if (result != mii.dwTypeData) { - mii.dwTypeData = result; - mii.fMask = MIIM_TYPE; - SetMenuItemInfo(hMenu, i, TRUE, &mii); - } } - - if (mii.hSubMenu != NULL) TranslateMenu_LP(mii.hSubMenu, hLangpack); - } -} - -static void TranslateWindow(MUUID* pUuid, HWND hwnd) -{ - TCHAR title[2048]; - GetWindowText(hwnd, title, SIZEOF(title)); - - TCHAR* result = (TCHAR*)LangPackTranslateString(pUuid, (const char*)title, TRUE); - if (result != title) - SetWindowText(hwnd, result); -} - -struct LANGPACKTRANSLATEDIALOG -{ - HWND hwndDlg; - int hLangpack; -}; - -static BOOL CALLBACK TranslateDialogEnumProc(HWND hwnd, LPARAM lParam) -{ - int hLangpack = (int)lParam; - TCHAR szClass[32]; - int id = GetDlgCtrlID(hwnd); - - MUUID* uuid = Langpack_LookupUuid(hLangpack); - - GetClassName(hwnd, szClass, SIZEOF(szClass)); - if ( !lstrcmpi(szClass, _T("static")) || !lstrcmpi(szClass, _T("hyperlink")) || !lstrcmpi(szClass, _T("button")) || !lstrcmpi(szClass, _T("MButtonClass")) || !lstrcmpi(szClass, _T("MHeaderbarCtrl"))) - TranslateWindow(uuid, hwnd); - else if ( !lstrcmpi(szClass, _T("edit"))) { - if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_READONLY) - TranslateWindow(uuid, hwnd); - } - return TRUE; -} - -MIR_CORE_DLL(void) TranslateDialog_LP(HWND hDlg, int hLangpack) -{ - TranslateWindow( Langpack_LookupUuid(hLangpack), hDlg); - EnumChildWindows(hDlg, TranslateDialogEnumProc, hLangpack); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(MUUID*) Langpack_LookupUuid(WPARAM wParam) -{ - int idx = (wParam >> 16) & 0xFFFF; - return (idx > 0 && idx <= lMuuids.getCount()) ? lMuuids[ idx-1 ] : NULL; -} - -MIR_CORE_DLL(int) Langpack_GetPluginHandle(PLUGININFOEX* pInfo) -{ - int idx = lMuuids.getIndex(&pInfo->uuid); - if (idx == -1) - return 0; - - return (idx+1) << 16; -} - -MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo) -{ - int idx = lMuuids.getIndex(&pInfo->uuid); - if (idx == -1) - return 0; - - return (idx+1) << 16; -} - -MIR_CORE_DLL(void) Langpack_SortDuplicates(void) -{ - if (langPack.entryCount == 0) - return; - - LangPackEntry *s = langPack.entry+1, *d = s, *pLast = langPack.entry; - DWORD dwSavedHash = langPack.entry->englishHash; - bool bSortNeeded = false; - - for (int i=1; i < langPack.entryCount; i++, s++) { - if (s->englishHash != dwSavedHash) { - pLast = d; - if (s != d) - *d++ = *s; - else - d++; - dwSavedHash = s->englishHash; - } - else { - bSortNeeded = true; - LangPackEntry* p = (LangPackEntry*)mir_alloc(sizeof(LangPackEntry)); - *p = *s; - pLast->pNext = p; pLast = p; - } - } - - if (bSortNeeded) { - langPack.entryCount = (int)(d - langPack.entry); - qsort(langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(int) LoadLangPackModule(void) -{ - bModuleInitialized = TRUE; - - ZeroMemory(&langPack, sizeof(langPack)); - - TCHAR szSearch[MAX_PATH]; - PathToAbsoluteT(_T("langpack_*.txt"), szSearch, NULL); - - WIN32_FIND_DATA fd; - HANDLE hFind = FindFirstFile(szSearch, &fd); - if (hFind != INVALID_HANDLE_VALUE) { - PathToAbsoluteT(fd.cFileName, szSearch, NULL); - FindClose(hFind); - LoadLangPack(szSearch); - } - return 0; -} - -void UnloadLangPackModule() -{ - if ( !bModuleInitialized) return; - - int i; - for (i=0; i < lMuuids.getCount(); i++) - mir_free(lMuuids[i]); - lMuuids.destroy(); - - LangPackEntry* p = langPack.entry; - for (i=0; i < langPack.entryCount; i++, p++) { - if (p->pNext != NULL) { - for (LangPackEntry* p1 = p->pNext; p1 != NULL;) { - LangPackEntry* p2 = p1; p1 = p1->pNext; - mir_free(p2->local); - mir_free(p2->wlocal); - mir_free(p2); - } } - - mir_free(p->local); - mir_free(p->wlocal); - } - - if (langPack.entryCount) { - mir_free(langPack.entry); - langPack.entry=0; - langPack.entryCount=0; -} } - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(void) ReloadLangpack(TCHAR *pszStr) -{ - if (pszStr == NULL) - pszStr = langPack.filename; - - UnloadLangPackModule(); - LoadLangPack(pszStr); - Langpack_SortDuplicates(); -} -- cgit v1.2.3