From d0de809a2d4f2ac76025d861bf55aa2c4ba1ac07 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 20 Jul 2012 10:47:53 +0000 Subject: LangMan: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1072 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/LangMan/src/options.cpp | 672 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 plugins/LangMan/src/options.cpp (limited to 'plugins/LangMan/src/options.cpp') diff --git a/plugins/LangMan/src/options.cpp b/plugins/LangMan/src/options.cpp new file mode 100644 index 0000000000..72f78dd597 --- /dev/null +++ b/plugins/LangMan/src/options.cpp @@ -0,0 +1,672 @@ +/* + +'Language Pack Manager'-Plugin for Miranda IM + +Copyright (C) 2005-2007 H. Herkenrath + +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 (LangMan-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +extern HINSTANCE hInst; +static HANDLE hHookOptInit; + +/************************* Utils **************************************/ + +#define BOX(str) BOX2("%s (err:%i)", str, GetLastError()) +#define BOX2(fmt, p1, p2) { char str[256]; wsprintfA(str, fmt, p1, p2); MessageBoxA(NULL, str, "dbg", 0); } + +// ImageList_Destroy() the return value +// refresh on WM_THEMECHANGED +static HIMAGELIST CreateRadioImages(COLORREF clrBk, COLORREF clrText) +{ + register HDC hdc, hdcScreen; + SIZE size; + RECT rc; + HBITMAP hbm, hbmPrev; + HIMAGELIST himl = NULL; + + /* the WinXP+ themed way */ + HMODULE hUxThemeDLL; + HTHEME (WINAPI *pfnOpenThemeData)(HWND, const WCHAR*); + HTHEME (WINAPI *pfnCloseThemeData)(HTHEME); + HRESULT (WINAPI *pfnDrawThemeBackground)(HTHEME, HDC, int, int, const RECT*, const RECT*); + hUxThemeDLL = LoadLibraryA("UXTHEME"); /* all ascii */ + + /* draw bitmap */ + hdcScreen = GetDC(NULL); + if (hdcScreen!=NULL) { + hdc = CreateCompatibleDC(NULL); /* compatible to screen */ + if (hdc!=NULL) { + size.cx = GetSystemMetrics(SM_CXSMICON); + size.cy = GetSystemMetrics(SM_CYSMICON); + SetRect(&rc, 0, 0, 2*size.cx, size.cy); + hbm = CreateCompatibleBitmap(hdcScreen, rc.right, rc.bottom); + if (hbm!=NULL) { + hbmPrev = (HBITMAP)SelectObject(hdc, hbm); + if (hbmPrev!=NULL) { /* error on select? */ + /* the WinXP+ themed way */ + if (hUxThemeDLL!=NULL) { + *(PROC*)&pfnOpenThemeData = GetProcAddress(hUxThemeDLL, "OpenThemeData"); + *(PROC*)&pfnCloseThemeData = GetProcAddress(hUxThemeDLL, "CloseThemeData"); + *(PROC*)&pfnDrawThemeBackground = GetProcAddress(hUxThemeDLL, "DrawThemeBackground"); + if (pfnOpenThemeData!=NULL && pfnCloseThemeData!=NULL && pfnDrawThemeBackground!=NULL) { + HTHEME hTheme; + hTheme = pfnOpenThemeData(NULL, L"Button"); + if (hTheme!=NULL) { + SetRect(&rc, 0, 0, size.cx, size.cy); + /* unchecked */ + if (!pfnDrawThemeBackground(hTheme, hdc, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL, &rc, NULL)) { + /* checked */ + OffsetRect(&rc, size.cx, 0); + if (!pfnDrawThemeBackground(hTheme, hdc, BP_RADIOBUTTON, RBS_CHECKEDNORMAL, &rc, NULL)) + himl = ImageList_Create(size.cx, size.cy, ILC_COLOR32|ILC_MASK, 3, 0); + } + pfnCloseThemeData(hTheme); + } + } + } + /* the classic way */ + if (himl == NULL) { + register HDC hdcMono; + HBITMAP hbmMono, hbmPrevMono; + RECT rcRadio; + COLORREF clrPrevText, clrPrevBk; + HBRUSH hbrBk; + hbrBk = CreateSolidBrush(clrBk); + if (hbrBk!=NULL) { + FillRect(hdc, &rc, hbrBk); + DeleteObject(hbrBk); + hdcMono = CreateCompatibleDC(hdc); + if (hdcMono!=NULL) { + hbmMono = CreateBitmap(rc.right, rc.bottom, 1, 1, NULL); + if (hbmMono!=NULL) { + hbmPrevMono = (HBITMAP)SelectObject(hdcMono, hbmMono); + if (hbmPrevMono!=NULL) { /* error on select? */ + /* draws a black-and-white mask (see docs) + * we need to colorize it using BitBlt with text and background color */ + clrPrevText = SetTextColor(hdc, clrText); + clrPrevBk = SetBkColor(hdc, clrBk); + /* check mark is slightly smaller than icon size */ + SetRect(&rcRadio, 0, 0, GetSystemMetrics(SM_CXMENUCHECK), GetSystemMetrics(SM_CYMENUCHECK)); + if (rcRadio.right>size.cx) rcRadio.right = size.cx; + if (rcRadio.bottom>size.cy) rcRadio.bottom = size.cy; + SetRect(&rc, ((size.cx-rcRadio.right)/2)+1, ((size.cy-rcRadio.bottom)/2)+1, rcRadio.right+1, rcRadio.bottom+1); + /* unchecked */ + if (BitBlt(hdcMono, 0, 0, rcRadio.right, rcRadio.bottom, NULL, 0, 0, WHITENESS)) { /* white back */ + if (DrawFrameControl(hdcMono, &rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO|DFCS_FLAT)) { + if (BitBlt(hdc, rc.left, rc.top, rcRadio.right, rcRadio.bottom, hdcMono, 0, 0, SRCCOPY|NOMIRRORBITMAP)) { + /* checked */ + OffsetRect(&rc, size.cx, 0); + if (BitBlt(hdcMono, 0, 0, rcRadio.right, rcRadio.bottom, NULL, 0, 0, WHITENESS)) {/* white back */ + if (DrawFrameControl(hdcMono, &rcRadio, DFC_BUTTON, DFCS_BUTTONRADIO|DFCS_FLAT|DFCS_CHECKED)) { + if (BitBlt(hdc, rc.left, rc.top, rcRadio.right, rcRadio.bottom, hdcMono, 0, 0, SRCCOPY|NOMIRRORBITMAP)) + himl = ImageList_Create(size.cx, size.cy, ILC_COLOR|ILC_MASK, 3, 0); + } else BOX("second DrawFrameControl() failed"); + } else BOX("second BitBlt() failed"); + } else BOX("intermediate BitBlt() failed"); + } else BOX("DrawFrameControl() failed"); + } else BOX("first BitBlt() failed"); + /* restore */ + SetBkColor(hdc, clrPrevBk); + SetTextColor(hdc, clrPrevText); + SelectObject(hdcMono, hbmPrevMono); + } else BOX("hbmPrevMono == NULL"); + DeleteObject(hbmMono); + } else BOX("hbmMono == NULL"); + DeleteDC(hdcMono); + } else BOX("hdcMono == NULL"); + } + } + SelectObject(hdc, hbmPrev); + /* create imagelist */ + if (himl!=NULL) { + if (himl == NULL) BOX("img list create failed"); + if (himl!=NULL) if (ImageList_AddMasked(himl, hbm, clrBk) == -1) BOX("add failed"); + } else BOX("Win9x: drawing code not reached"); + } + DeleteObject(hbm); + } + DeleteDC(hdc); + } + ReleaseDC(NULL, hdcScreen); + } + + if (hUxThemeDLL!=NULL) FreeLibrary(hUxThemeDLL); + return himl; +} + +static void CleanupPluginName(char *szShortName) +{ + char *p; + int len; + /* strip-off anything in brackets */ + for(p = szShortName;*p!='\0';++p) + if (*p == '(' || *p == '[') { + *p = '\0'; + break; + } + /* remove trailing space */ + len = lstrlenA(szShortName); + while(szShortName[0]!='\0' && szShortName[len-1] == ' ') + szShortName[--len] = 0; +} + +static void DisplayNotIncludedPlugins(HWND hwndListBox, const LANGPACK_INFO *pack) +{ + WIN32_FIND_DATA wfd; + HANDLE hFind; + TCHAR szSearch[MAX_PATH], szDir[MAX_PATH], *p; + HMODULE hModule; + BOOL fNeedsFree; + char buf[128]; + TCHAR buf2[128]; + DWORD mirandaVersion; + PLUGININFOEX *pluginInfo; + PLUGININFOEX *(__cdecl *MirandaPluginInfo)(DWORD); + + /* enum plugins */ + if (!(pack->flags&LPF_DEFAULT) && GetModuleFileName(NULL, szDir, SIZEOF(szDir))) { + p = _tcsrchr(szDir, _T('\\')); + if (p!=NULL) *p = _T('\0'); + mir_sntprintf(szSearch, SIZEOF(szSearch), _T("%s\\Plugins\\*.dll"), szDir); + hFind = FindFirstFile(szSearch, &wfd); + if (hFind!=INVALID_HANDLE_VALUE) { + mirandaVersion = CallService(MS_SYSTEM_GETVERSION, 0, 0); + SendMessage(hwndListBox, LB_SETLOCALE, CallService(MS_LANGPACK_GETLOCALE, 0, 0), 0); /* for sort order */ + SendMessage(hwndListBox, LB_INITSTORAGE, 128, lstrlenA(pack->szPluginsIncluded)); /* speed up */ + do { + if (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue; + if ((lstrlen(wfd.cFileName)<4) || (wfd.cFileName[lstrlen(wfd.cFileName)-4]!=_T('.'))) continue; + /* file name */ + lstrcpy(szSearch, wfd.cFileName); /* buffer safe */ + p = _tcsrchr(szSearch, _T('.')); + if (p!=NULL) *p = _T('\0'); + + { char cFileNameA[MAX_PATH]; + cFileNameA[0] = '\0'; + WideCharToMultiByte(CP_ACP, 0, szSearch, -1, cFileNameA, sizeof(cFileNameA), NULL, NULL); + if (IsPluginIncluded(pack, cFileNameA)) continue; + } + + /* friendly name of the plugin */ + mir_sntprintf(szSearch, SIZEOF(szSearch), _T("%s\\Plugins\\%s"), szDir, wfd.cFileName); + hModule = GetModuleHandle(szSearch); + fNeedsFree = (hModule == NULL); + if (hModule == NULL) { + hModule = LoadLibrary(szSearch); + if (hModule == NULL) continue; + } + /* plugin info */ + *(PROC*)&MirandaPluginInfo = GetProcAddress(hModule, "MirandaPluginInfoEx"); + if (MirandaPluginInfo!=NULL) { /* both structs have the same header */ + pluginInfo = MirandaPluginInfo(mirandaVersion); + if (pluginInfo!=NULL && pluginInfo->cbSize >= sizeof(PLUGININFOEX) && pluginInfo->shortName!=NULL) { + lstrcpynA(buf, pluginInfo->shortName, sizeof(buf)); /* buffer safe */ + CleanupPluginName(buf); + mir_sntprintf(buf2, SIZEOF(buf2), TranslateT("%hs (%s)"), buf, CharLower(wfd.cFileName)); + SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)buf2); + } + } + if (fNeedsFree) FreeLibrary(hModule); + } while(FindNextFile(hFind, &wfd)); + FindClose(hFind); + } + } + /* all are included? */ + if (!SendMessage(hwndListBox, LB_GETCOUNT, 0, 0)) + SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)TranslateT("All installed plugins are included.")); +} + +static void DisplayPackInfo(HWND hwndDlg, const LANGPACK_INFO *pack) +{ + /* compute not-included from included list */ + SendDlgItemMessage(hwndDlg, IDC_LANGNOTINCLUDED, LB_RESETCONTENT, 0, 0); + DisplayNotIncludedPlugins(GetDlgItem(hwndDlg, IDC_LANGNOTINCLUDED), pack); + /* locale string */ + if (!(pack->flags&LPF_NOLOCALE)) { + TCHAR szLocaleName[128]; + szLocaleName[0] = _T('\0'); + /* can't use LOCALE_SNAME as it is not present on pre WinVista */ + if (!GetLocaleInfo(pack->Locale, LOCALE_SISO639LANGNAME, szLocaleName, SIZEOF(szLocaleName))) { /* Win98/NT4+ */ + if (!GetLocaleInfo(pack->Locale, LOCALE_SLANGUAGE, szLocaleName, SIZEOF(szLocaleName))) /* not unique! */ + szLocaleName[0] = _T('\0'); + } else { + if (GetLocaleInfo(pack->Locale, LOCALE_SISO3166CTRYNAME, &szLocaleName[3], SIZEOF(szLocaleName)-3)) /* Win98/NT4+ */ + szLocaleName[2] = _T('-'); + } + /* add some note if its incompatible */ + if (szLocaleName[0]) { + if (!IsValidLocale(pack->Locale, LCID_INSTALLED)) { + TCHAR *pszIncompat; + pszIncompat = TranslateT("(incompatible)"); + szLocaleName[SIZEOF(szLocaleName)-lstrlen(pszIncompat)-1] = 0; + lstrcat(lstrcat(szLocaleName, _T(" ")), pszIncompat); /* buffer safe */ + } + SetDlgItemText(hwndDlg, IDC_LANGLOCALE, szLocaleName); + } + else SetDlgItemText(hwndDlg, IDC_LANGLOCALE, TranslateT("Unknown")); + } + else SetDlgItemText(hwndDlg, IDC_LANGLOCALE, TranslateT("Current")); + /* file date */ + { SYSTEMTIME stFileDate; + TCHAR szDate[128]; + szDate[0] = _T('\0'); + if (FileTimeToSystemTime(&pack->ftFileDate, &stFileDate)) + GetDateFormat((LCID)CallService(MS_LANGPACK_GETLOCALE, 0, 0), DATE_SHORTDATE, &stFileDate, NULL, szDate, SIZEOF(szDate)); + SetDlgItemText(hwndDlg, IDC_LANGDATE, szDate); + } + /* version */ + SetDlgItemTextA(hwndDlg, IDC_LANGVERSION, pack->szVersion); + if (pack->szVersion[0] && pack->szFLName[0]) { + if (!IsWindowVisible(GetDlgItem(hwndDlg, IDC_LANGVERSIONLABEL))) { + ShowWindow(GetDlgItem(hwndDlg, IDC_LANGVERSIONLABEL), SW_SHOW); + ShowWindow(GetDlgItem(hwndDlg, IDC_LANGVERSION), SW_SHOW); + } + } else { + ShowWindow(GetDlgItem(hwndDlg, IDC_LANGVERSIONLABEL), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_LANGVERSION), SW_HIDE); + } + /* general */ + SetDlgItemTextA(hwndDlg, IDC_LANGMODUSING, pack->szLastModifiedUsing); + SetDlgItemTextA(hwndDlg, IDC_LANGAUTHORS, pack->szAuthors); + SetDlgItemTextA(hwndDlg, IDC_LANGEMAIL, pack->szAuthorEmail); + SetDlgItemText(hwndDlg, IDC_LANGINFOFRAME, TranslateTS(pack->szLanguage)); +} + +/************************* Insert/Delete ******************************/ + +#define M_RELOADLIST (WM_APP+1) +#define M_SHOWFILECOL (WM_APP+2) + +static void DeletePackFile(HWND hwndDlg, HWND hwndList, int iItem, LANGPACK_INFO *pack) +{ + SHFILEOPSTRUCT sfo; + TCHAR szFileName[MAX_PATH]; + ZeroMemory(&sfo, sizeof(sfo)); + sfo.hwnd = hwndDlg; + sfo.wFunc = FO_DELETE; + sfo.fFlags = FOF_SIMPLEPROGRESS|FOF_SILENT; /* silent = no progress */ + /* double zero terminated */ + if (GetPackPath(szFileName, SIZEOF(szFileName)-1, pack->flags&LPF_ENABLED, pack->szFileName)) { + szFileName[lstrlen(szFileName)+1] = _T('\0'); + sfo.pFrom = szFileName; + /* ask to delete file */ + if (!SHFileOperation(&sfo) && !sfo.fAnyOperationsAborted) { + LVITEM lvi; + int nCount; + lvi.iItem = iItem; + lvi.iSubItem = 0; + lvi.mask = LVIF_STATE; + lvi.stateMask = LVIS_STATEIMAGEMASK|LVIS_SELECTED|LVIS_FOCUSED; + if (ListView_GetItem(hwndList, &lvi)) { + ListView_DeleteItem(hwndList, iItem); + /* enable/select next item at same position */ + nCount = ListView_GetItemCount(hwndList); + if (iItemflags&LPF_DEFAULT) + hIcon = (HICON)CallService(MS_FLAGS_CREATEMERGEDFLAGICON, CTRY_UNITED_STATES, CTRY_UNITED_KINGDOM); + else { + int countryId = 0xFFFF; /* Unknown */ + TCHAR szBuf[6]; + /* get country id from locale */ + if (!(pack->flags&LPF_NOLOCALE)) + if (GetLocaleInfo(pack->Locale, LOCALE_ICOUNTRY, szBuf, SIZEOF(szBuf))) + countryId = _ttoi(szBuf); + hIcon = (HICON)CallService(MS_FLAGS_LOADFLAGICON, countryId, 0); + } + if (hIcon == NULL) lvi.iImage = -1; + else lvi.iImage = ImageList_AddIcon((HIMAGELIST)lParam, hIcon); + lvi.mask |= LVIF_IMAGE; + } + /* insert */ + lvi.iItem = lvi.iSubItem = 0; + lvi.stateMask = LVIS_STATEIMAGEMASK|LVIS_SELECTED; + lvi.state = INDEXTOSTATEIMAGEMASK((pack->flags&LPF_ENABLED)?2:1); + if (pack->flags & LPF_ENABLED) lvi.state |= LVIS_SELECTED|LVIS_FOCUSED; + lvi.pszText = TranslateTS(pack->szLanguage); + lvi.lParam = (LPARAM)pack2; + ListView_InsertItem((HWND)wParam, &lvi); + + return TRUE; +} + +static int CALLBACK CompareListItem(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + int cmp; + cmp = CompareString((LCID)lParamSort, 0, ((LANGPACK_INFO*)lParam1)->szLanguage, -1, ((LANGPACK_INFO*)lParam2)->szLanguage, -1); + if (cmp!=0) cmp -= 2; + return cmp; +} + +/************************* Options Page *******************************/ + +static HWND hwndLangOpt; + +static INT_PTR CALLBACK LangOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + case WM_INITDIALOG: + { HWND hwndList; + LVCOLUMN lvc; + hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST); + hwndLangOpt = hwndDlg; + TranslateDialogDefault(hwndDlg); + ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT|LVS_EX_LABELTIP); + ListView_SetImageList(hwndList, CreateRadioImages(ListView_GetBkColor(hwndList), ListView_GetTextColor(hwndList)), LVSIL_STATE); /* auto-destroyed */ + + lvc.mask = LVCF_TEXT; + lvc.pszText = TranslateT("Installed Languages"); + ListView_InsertColumn(hwndList, 0, &lvc); + if (ServiceExists(MS_FLAGS_LOADFLAGICON)) + ListView_SetImageList(hwndList, ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR24, 8, 8), LVSIL_SMALL); + CorrectPacks(_T("langpack_*.txt"), FALSE); + CheckDlgButton(hwndDlg, IDC_ENABLEAUTOUPDATES, DBGetContactSettingByte(NULL, "LangMan", "EnableAutoUpdates", SETTING_ENABLEAUTOUPDATES_DEFAULT)!=0); + SendMessage(hwndDlg, M_RELOADLIST, 0, 0); + SendMessage(hwndDlg, M_SHOWFILECOL, 0, SendMessage(GetParent(hwndDlg), PSM_ISEXPERT, 0, 0)); + return TRUE; + } + case M_RELOADLIST: + { HWND hwndList; + HIMAGELIST himl; + int iItem; + /* init list */ + hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST); + ListView_DeleteAllItems(hwndList); + ListView_DeleteColumn(hwndList, 1); /* if present */ + himl = ListView_GetImageList(hwndList, LVSIL_SMALL); + ImageList_RemoveAll(himl); + /* enum all packs */ + EnumPacks(InsertPackItemEnumProc, _T("langpack_*.txt"), "Miranda Language Pack Version 1", TRUE, (WPARAM)hwndList, (LPARAM)himl); + /* make it use current langpack locale for sort */ + ListView_SortItems(hwndList, CompareListItem, CallService(MS_LANGPACK_GETLOCALE, 0, 0)); + CheckDlgButton(hwndDlg, IDC_ENABLEAUTOUPDATES, DBGetContactSettingByte(NULL, "LangMan", "EnableAutoUpdates", SETTING_ENABLEAUTOUPDATES_DEFAULT)!=0); + /* show selection */ + iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); + if (iItem!=-1) ListView_EnsureVisible(hwndList, iItem, FALSE); + return TRUE; + } + case M_SHOWFILECOL: + { HWND hwndList; + hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST); + if ((BOOL)lParam && ListView_GetItemCount(hwndList)>1) { + LVCOLUMN lvc; + LVITEM lvi; + LANGPACK_INFO *pack; + /* add column */ + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER); + lvc.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; + lvc.pszText = TranslateT("File"); + lvc.cx = 160; + ListView_InsertColumn(hwndList, lvc.iSubItem = 1, &lvc); + ListView_SetColumnWidth(hwndList, 0, ListView_GetColumnWidth(hwndList, 0)-lvc.cx); + /* add text */ + lvi.mask = LVIF_PARAM; + lvi.iSubItem = 0; + for(lvi.iItem = 0;ListView_GetItem(hwndList, &lvi);++lvi.iItem) { + pack = (LANGPACK_INFO*)lvi.lParam; + ListView_SetItemText(hwndList, lvi.iItem, 1, (pack->flags&LPF_DEFAULT)?TranslateT("built-in"):pack->szFileName); + } + } + else { + ListView_DeleteColumn(hwndList, 1); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER); + } + return TRUE; + } + case WM_DESTROY: + ListView_DeleteAllItems(GetDlgItem(hwndDlg, IDC_LANGLIST)); + return TRUE; + case WM_THEMECHANGED: + case WM_SETTINGCHANGE: + { HIMAGELIST himl; + HWND hwndList; + hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST); + himl = ListView_SetImageList(hwndList, CreateRadioImages(ListView_GetBkColor(hwndList), ListView_GetTextColor(hwndList)), LVSIL_STATE); /* auto-destroyed */ + if (himl!=NULL) ImageList_Destroy(himl); + break; + } + case WM_CTLCOLORLISTBOX: /* mimic readonly edit */ + return (BOOL)SendMessage(hwndDlg, WM_CTLCOLORSTATIC, wParam, lParam); + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_LANGEMAIL: + { char buf[512]; + lstrcpyA(buf, "mailto:"); + if (GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), &buf[7], sizeof(buf)-7)) + CallService(MS_UTILS_OPENURL, FALSE, (LPARAM)buf); + return TRUE; + } + case IDC_MORELANG: + CallService(MS_UTILS_OPENURL, TRUE, (LPARAM)"http://addons.miranda-im.org/index.php?action = display&id = 23"); + return TRUE; +/* case IDC_ENABLEAUTOUPDATES: + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); /* enable apply */ +/* return TRUE; + case IDC_DOWNLOADLANG: + ServiceShowLangDialog(0, 0); + return TRUE;*/ + } + break; + case WM_CONTEXTMENU: + if (GetDlgCtrlID((HWND)wParam) == IDC_LANGLIST) { + LVHITTESTINFO hti; + HMENU hContextMenu; + RECT rc; + LVITEM lvi; + LANGPACK_INFO *pack; + /* get item */ + POINTSTOPOINT(hti.pt, MAKEPOINTS(lParam)); + if (hti.pt.x == -1 && hti.pt.y == -1) { + /* keyboard invoked */ + hti.iItem = ListView_GetNextItem((HWND)wParam, -1, LVNI_SELECTED); + if (hti.iItem!=-1) + break; + if (!ListView_GetItemRect((HWND)wParam, hti.iItem, &rc, LVIR_SELECTBOUNDS)) + break; + hti.pt.x = rc.left+(rc.right-rc.left)/2; + hti.pt.y = rc.top+(rc.bottom-rc.top)/2; + ClientToScreen((HWND)wParam, &hti.pt); + } else { + ScreenToClient((HWND)wParam, &hti.pt); + if (ListView_HitTest((HWND)wParam, &hti) == -1 || !(hti.flags&LVHT_ONITEM)) + break; + POINTSTOPOINT(hti.pt, MAKEPOINTS(lParam)); + } + /* param */ + lvi.iItem = hti.iItem; + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + if (!ListView_GetItem((HWND)wParam, &lvi)) break; + pack = (LANGPACK_INFO*)lvi.lParam; + /* context menu */ + if (!(pack->flags&LPF_DEFAULT)) { + hContextMenu = CreatePopupMenu(); + if (hContextMenu!=NULL) { + AppendMenu(hContextMenu, MF_STRING, 2, TranslateT("&Remove...")); + if (TrackPopupMenuEx(hContextMenu, TPM_RETURNCMD|TPM_NONOTIFY|TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_HORPOSANIMATION|TPM_VERPOSANIMATION, hti.pt.x, hti.pt.y, (HWND)wParam, NULL)) + DeletePackFile(hwndDlg, (HWND)wParam, hti.iItem, pack); + DestroyMenu(hContextMenu); + } + } + return TRUE; + } + break; + + case WM_NOTIFYFORMAT: + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, NFR_UNICODE); + return TRUE; + + case WM_NOTIFY: + { NMHDR *nmhdr = (NMHDR*)lParam; + switch(nmhdr->idFrom) { + case IDC_LANGLIST: + switch(nmhdr->code) { + case LVN_DELETEITEM: + { LVITEM lvi; + lvi.iItem = ((NMLISTVIEW*)lParam)->iItem; /* nmlv->lParam is invalid */ + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + if (ListView_GetItem(nmhdr->hwndFrom, &lvi)) + mir_free((LANGPACK_INFO*)lvi.lParam); + break; + } + case LVN_ITEMCHANGED: + { NMLISTVIEW *nmlv = (NMLISTVIEW*)lParam; + if (!(nmlv->uChanged&LVIF_STATE)) break; + /* display info and check radio item */ + if (nmlv->uNewState&LVIS_SELECTED && !(nmlv->uOldState&LVIS_SELECTED)) { + ListView_SetItemState(nmhdr->hwndFrom, nmlv->iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); + DisplayPackInfo(hwndDlg, (LANGPACK_INFO*)nmlv->lParam); + } + /* disable all other radio items */ + else if (nmlv->uNewState&INDEXTOSTATEIMAGEMASK(2)) { + int iItem; + for(iItem = ListView_GetItemCount(nmhdr->hwndFrom)-1;iItem!=-1;--iItem) + if (iItem!=nmlv->iItem) + ListView_SetItemState(nmhdr->hwndFrom, iItem, INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK); + /* enable apply */ + if (nmlv->uOldState) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART), SW_SHOW); + } + } + break; + } + case LVN_KEYDOWN: + { int iItem; + iItem = ListView_GetNextItem(nmhdr->hwndFrom, -1, LVNI_SELECTED); + switch(((NMLVKEYDOWN*)lParam)->wVKey) { + case VK_SPACE: + ListView_SetItemState(nmhdr->hwndFrom, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); + break; + case VK_DELETE: + { LVITEM lvi; + LANGPACK_INFO *pack; + lvi.iItem = iItem; + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + if (ListView_GetItem(nmhdr->hwndFrom, &lvi)) { + pack = (LANGPACK_INFO*)lvi.lParam; + if (!(pack->flags&LPF_DEFAULT)) + DeletePackFile(hwndDlg, nmhdr->hwndFrom, iItem, pack); + } + break; + } + } + break; + } + case NM_CLICK: + { LVHITTESTINFO hti; + lParam = GetMessagePos(); + POINTSTOPOINT(hti.pt, MAKEPOINTS(lParam)); + ScreenToClient(nmhdr->hwndFrom, &hti.pt); + if (ListView_HitTest(nmhdr->hwndFrom, &hti)!=-1) + if (hti.flags&(LVHT_ONITEMSTATEICON|LVHT_ONITEMICON)) /* one of them */ + ListView_SetItemState(nmhdr->hwndFrom, hti.iItem, LVIS_SELECTED, LVIS_SELECTED); + break; + } + } /* switch nmhdr->code */ + break; + case 0: + switch(nmhdr->code) { + case PSN_APPLY: + { HWND hwndList; + LVITEM lvi; + LANGPACK_INFO *pack; + hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST); + lvi.mask = LVIF_STATE|LVIF_PARAM; + lvi.stateMask = LVIS_STATEIMAGEMASK; + lvi.iSubItem = 0; + for(lvi.iItem = 0;ListView_GetItem(hwndList, &lvi);++lvi.iItem) { + pack = (LANGPACK_INFO*)lvi.lParam; + if (lvi.state&INDEXTOSTATEIMAGEMASK(2)) { + EnablePack(pack, _T("langpack_*.txt")); + pack->flags |= LPF_ENABLED; + } else pack->flags &= ~LPF_ENABLED; + } + DBWriteContactSettingByte(NULL, "LangMan", "EnableAutoUpdates", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ENABLEAUTOUPDATES)!=0)); + return TRUE; + } + case PSN_EXPERTCHANGED: + SendMessage(hwndDlg, M_SHOWFILECOL, 0, ((PSHNOTIFY*)lParam)->lParam); + return TRUE; + } /* switch nmhdr->code */ + break; + } /* switch nmhdr->idFrom */ + break; + } + } + return FALSE; +} + +void ReloadLangOptList(void) +{ + if (hwndLangOpt!=NULL) { + SendMessage(hwndLangOpt, M_RELOADLIST, 0, 0); + SendMessage(hwndLangOpt, M_SHOWFILECOL, 0, SendMessage(GetParent(hwndLangOpt), PSM_ISEXPERT, 0, 0)); + } +} + +static int LangOptInit(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + UNREFERENCED_PARAMETER(lParam); + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.flags = ODPF_BOLDGROUPS; + odp.position = 1200000090; + odp.pszTitle = LPGEN("Appearance"); /* autotranslated */ + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_LANG); + odp.pfnDlgProc = LangOptDlgProc; + Options_AddPage(wParam, &odp); + return 0; +} + +/************************* Misc ***************************************/ + +void InitOptions(void) +{ + hwndLangOpt = NULL; + hHookOptInit = HookEvent(ME_OPT_INITIALISE, LangOptInit); + CorrectPacks(_T("langpack_*.txt"), FALSE); +} + +void UninitOptions(void) +{ + UnhookEvent(hHookOptInit); +} \ No newline at end of file -- cgit v1.2.3