From bacf5e0272c566c30e591152084daf2f684aebe8 Mon Sep 17 00:00:00 2001 From: Goraf Date: Fri, 5 Feb 2016 22:40:46 +0000 Subject: ContextHelp: initial commit (adopted) * working * 32/64-bit compilable git-svn-id: http://svn.miranda-ng.org/main/trunk@16225 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ContextHelp/src/options.cpp | 797 ++++++++++++++++++++++++++++++++++++ 1 file changed, 797 insertions(+) create mode 100644 plugins/ContextHelp/src/options.cpp (limited to 'plugins/ContextHelp/src/options.cpp') diff --git a/plugins/ContextHelp/src/options.cpp b/plugins/ContextHelp/src/options.cpp new file mode 100644 index 0000000000..1078bd2e4e --- /dev/null +++ b/plugins/ContextHelp/src/options.cpp @@ -0,0 +1,797 @@ +/* +Miranda IM Help Plugin +Copyright (C) 2002 Richard Hughes, 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 (Help-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "stdafx.h" + +typedef PLUGININFOEX* (__cdecl *pfnMirandaPluginInfo)(DWORD); + +WORD settingAutoTipDelay; /* auto show help after those milliseconds, 0 if disabled */ +extern HINSTANCE hInst; +static HANDLE hHookOptInit; +static HWND hwndLangOpt; + +/**************************** LANGUAGE OPTS ***********************/ + +/* these are only there for a short time to +* debug those radio buttons an Win9x */ +#define BOX(str) BOX2("%s (err:%i)",str,GetLastError()) +#define BOX2(fmt,p1,p2) { char str[256]; mir_snprintf(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) +{ + /* draw bitmap */ + HDC hdcScreen = GetDC(NULL); + if (hdcScreen == NULL) + return NULL; + + HIMAGELIST himl = NULL; + HDC hdc = CreateCompatibleDC(NULL); // compatible to screen + if (hdc != NULL) { + SIZE size = { GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON) }; + RECT rc; + SetRect(&rc, 0, 0, 2 * size.cx, size.cy); + HBITMAP hbm = CreateCompatibleBitmap(hdcScreen, rc.right, rc.bottom); + if (hbm != NULL) { + HBITMAP hbmPrev = (HBITMAP)SelectObject(hdc, hbm); + if (hbmPrev != NULL) { // error on select? + HTHEME hTheme = OpenThemeData(NULL, L"Button"); + SetRect(&rc, 0, 0, size.cx, size.cy); + /* unchecked */ + if (!DrawThemeBackground(hTheme, hdc, BP_RADIOBUTTON, RBS_UNCHECKEDNORMAL, &rc, NULL)) { + /* checked */ + OffsetRect(&rc, size.cx, 0); + if (!DrawThemeBackground(hTheme, hdc, BP_RADIOBUTTON, RBS_CHECKEDNORMAL, &rc, NULL)) + himl = ImageList_Create(size.cx, size.cy, ILC_COLOR32 | ILC_MASK, 3, 0); + } + CloseThemeData(hTheme); + + /* the classic way */ + if (himl == NULL) { + HBRUSH hbrBk = CreateSolidBrush(clrBk); + if (hbrBk != NULL) { + FillRect(hdc, &rc, hbrBk); + DeleteObject(hbrBk); + HDC hdcMono = CreateCompatibleDC(hdc); + if (hdcMono != NULL) { + HBITMAP hbmMono = CreateBitmap(rc.right, rc.bottom, 1, 1, NULL); + if (hbmMono != NULL) { + HBITMAP 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 */ + COLORREF clrPrevText = SetTextColor(hdc, clrText); + COLORREF clrPrevBk = SetBkColor(hdc, clrBk); + /* check mark is slightly smaller than icon size */ + RECT rcRadio; + 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); + if (himl == NULL) + BOX("img list creation failed"); + } + } + 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 (ImageList_AddMasked(himl, hbm, clrBk) == -1) + BOX("addmasked failed"); + } + else + BOX("Win9x: drawing code not reached"); + } + DeleteObject(hbm); + } + DeleteDC(hdc); + } + ReleaseDC(NULL, hdcScreen); + + return himl; +} + +static void CleanupPluginName(char *szShortName) +{ + char *p; + /* strip-off anything in brackets */ + for (p = szShortName; *p != '\0'; ++p) + if (*p == '(' || *p == '[') { + *p = '\0'; + break; + } + /* remove trailing space */ + int len = lstrlenA(szShortName); + while (szShortName[0] != '\0' && szShortName[len - 1] == ' ') + szShortName[--len] = 0; +} + +static void DisplayNotIncludedPlugins(HWND hwndListBox, const HELPPACK_INFO *pack) +{ + /* enum plugins */ + TCHAR szDir[MAX_PATH]; + if (GetModuleFileName(NULL, szDir, sizeof(szDir))) { + TCHAR *p = _tcsrchr(szDir, _T('\\')); + if (p != NULL) + *p = _T('\0'); + TCHAR szSearch[MAX_PATH]; + mir_sntprintf(szSearch, sizeof(szSearch), _T("%s\\Plugins\\*.dll"), szDir); + WIN32_FIND_DATA wfd; + HANDLE hFind = FindFirstFile(szSearch, &wfd); + if (hFind != INVALID_HANDLE_VALUE) { + DWORD mirandaVersion = CallService(MS_SYSTEM_GETVERSION, 0, 0); + SendMessage(hwndListBox, LB_SETLOCALE, Langpack_GetDefaultLocale(), 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 hModule = GetModuleHandle(szSearch); + BOOL fNeedsFree = (hModule == NULL); + if (hModule == NULL) { + hModule = LoadLibrary(szSearch); + if (hModule == NULL) + continue; + } + + /* plugin info */ + pfnMirandaPluginInfo pFunc = (pfnMirandaPluginInfo)GetProcAddress(hModule, "MirandaPluginInfoEx"); + if (pFunc != NULL) { /* both structs have the same header */ + PLUGININFOEX *pluginInfo = pFunc(mirandaVersion); + if (pluginInfo != NULL && pluginInfo->cbSize >= sizeof(PLUGININFOEX) && pluginInfo->shortName != NULL) { + char buf[128]; + lstrcpynA(buf, pluginInfo->shortName, sizeof(buf)); /* buffer safe */ + CleanupPluginName(buf); + + TCHAR buf2[128]; + mir_sntprintf(buf2, sizeof(buf2), _T("%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.")); +} + +// pack is allowed to be NULL +static void DisplayPackInfo(HWND hwndDlg, const HELPPACK_INFO *pack) +{ + /* show/hide controls */ + if (IsWindowVisible(GetDlgItem(hwndDlg, IDC_NOPACK)) == (pack != NULL)) { + const int controls[] = { IDC_LANGNOTINCLUDEDLABEL, IDC_LANGNOTINCLUDED, IDC_LANGDATELABEL, IDC_LANGDATE, + IDC_LANGLOCALELABEL, IDC_LANGLOCALE, IDC_LANGVERSIONLABEL, IDC_LANGVERSION, + IDC_LANGMODUSINGLABEL, IDC_LANGMODUSING, IDC_LANGAUTHORSLABEL, IDC_LANGAUTHORS, + IDC_LANGEMAILLABEL, IDC_LANGEMAIL }; + for (int i = 0; i < sizeof(controls); i++) + ShowWindow(GetDlgItem(hwndDlg, controls[i]), (pack != NULL) ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_NOPACK), (pack != NULL) ? SW_HIDE : SW_SHOW); + SetDlgItemText(hwndDlg, IDC_LANGINFOFRAME, NULL); + } + if (pack == NULL) + return; + /* 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&HPF_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(Langpack_GetDefaultLocale(), 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)); +} + +#define M_RELOADLIST (WM_APP+1) +#define M_SHOWFILECOL (WM_APP+2) + +static void DeletePackFile(HWND hwndDlg, HWND hwndList, int iItem, HELPPACK_INFO *pack) +{ + SHFILEOPSTRUCT sfo = { 0 }; + sfo.hwnd = hwndDlg; + sfo.wFunc = FO_DELETE; + sfo.fFlags = FOF_SIMPLEPROGRESS | FOF_SILENT; /* silent = no progress */ + /* double zero terminated */ + TCHAR szFileName[MAX_PATH]; + if (GetPackPath(szFileName, sizeof(szFileName) - 1, pack->flags&HPF_ENABLED, pack->szFileName)) { + szFileName[lstrlen(szFileName) + 1] = _T('\0'); + sfo.pFrom = szFileName; + /* ask to delete file */ + if (!SHFileOperation(&sfo) && !sfo.fAnyOperationsAborted) { + LVITEM lvi; + 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 */ + int nCount = ListView_GetItemCount(hwndList); + lvi.iItem = (iItem < nCount) ? iItem : iItem - 1; + if (lvi.iItem != -1) { + ListView_SetItemState(hwndList, lvi.iItem, lvi.state, lvi.stateMask); + /* enable pack file */ + lvi.mask = LVIF_PARAM; + lvi.iSubItem = 0; + if (ListView_GetItem(hwndList, &lvi)) + EnablePack((HELPPACK_INFO*)lvi.lParam, _T("helppack_*.txt")); + } + else + DisplayPackInfo(hwndDlg, NULL); + if (nCount == 1) + SendMessage(hwndDlg, M_SHOWFILECOL, 0, FALSE); + } + } + } +} + +static INT_PTR CALLBACK InsertPackItemEnumProc(HELPPACK_INFO *pack, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + + HELPPACK_INFO *pack2 = (HELPPACK_INFO*)mir_alloc(sizeof(HELPPACK_INFO)); + if (pack2 == NULL) + return FALSE; + CopyMemory(pack2, pack, sizeof(HELPPACK_INFO)); + + /* country flag icon */ + LVITEM lvi; + lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; + if ((HIMAGELIST)lParam != NULL) { + HICON hIcon; + if (pack->flags&HPF_DEFAULT) /* not really needed, but to be consistent with LangMan */ + 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&HPF_NOLOCALE)) + if (GetLocaleInfo(pack->Locale, LOCALE_ICOUNTRY, szBuf, sizeof(szBuf))) + countryId = _ttoi(szBuf); + hIcon = (HICON)CallService(MS_FLAGS_LOADFLAGICON, countryId, 0); + } + lvi.iImage = (hIcon == NULL) ? -1 : 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&HPF_ENABLED) ? 2 : 1); + if (pack->flags&HPF_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 = CompareString((LCID)lParamSort, 0, ((HELPPACK_INFO*)lParam1)->szLanguage, -1, ((HELPPACK_INFO*)lParam2)->szLanguage, -1); + if (cmp) + cmp -= 2; + if (!cmp) { + if (((HELPPACK_INFO*)lParam1)->flags&HPF_ENABLED) + cmp = -1; + else if (((HELPPACK_INFO*)lParam2)->flags&HPF_ENABLED) + cmp = 1; + } + + return cmp; +} + +static INT_PTR CALLBACK LangOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndList = GetDlgItem(hwndDlg, IDC_LANGLIST); + LVITEM lvi; + + switch (msg) { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + hwndLangOpt = hwndDlg; + ListView_SetExtendedListViewStyle(hwndList, LVS_EX_FULLROWSELECT | LVS_EX_LABELTIP); + ListView_SetImageList(hwndList, CreateRadioImages(ListView_GetBkColor(hwndList), ListView_GetTextColor(hwndList)), LVSIL_STATE); /* auto-destroyed */ + { + LVCOLUMN lvc; + 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("helppack_*.txt"), _T("helppack_english.txt"), FALSE); + CheckDlgButton(hwndDlg, IDC_ENABLEHELPUPDATES, db_get_b(NULL, "HelpPlugin", "EnableHelpUpdates", SETTING_ENABLEHELPUPDATES_DEFAULT) != 0); + SendMessage(hwndDlg, M_RELOADLIST, 0, 0); + SendMessage(hwndDlg, M_SHOWFILECOL, 0, 1); + return TRUE; + } + case M_RELOADLIST: + { + /* init list */ + ListView_DeleteAllItems(hwndList); + ListView_DeleteColumn(hwndList, 1); /* if present */ + { + HIMAGELIST himl = ListView_GetImageList(hwndList, LVSIL_SMALL); + ImageList_RemoveAll(himl); + /* enum all packs */ + EnumPacks(InsertPackItemEnumProc, _T("helppack_*.txt"), "Miranda Help Pack Version 1", (WPARAM)hwndList, (LPARAM)himl); + /* nothing installed */ + if (!ListView_GetItemCount(hwndList)) + DisplayPackInfo(hwndDlg, NULL); + /* make it use current langpack locale for sort */ + ListView_SortItems(hwndList, CompareListItem, Langpack_GetDefaultLocale()); + CheckDlgButton(hwndDlg, IDC_ENABLEHELPUPDATES, db_get_b(NULL, "HelpPlugin", "EnableHelpUpdates", SETTING_ENABLEHELPUPDATES_DEFAULT) != 0); + /* show selection */ + int iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); + if (iItem != -1) + ListView_EnsureVisible(hwndList, iItem, FALSE); + } + return TRUE; + } + case M_SHOWFILECOL: + if ((BOOL)lParam && ListView_GetItemCount(hwndList)>1) { + /* add column */ + LVCOLUMN lvc; + 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) { + HELPPACK_INFO *pack = (HELPPACK_INFO*)lvi.lParam; + ListView_SetItemText(hwndList, lvi.iItem, 1, pack->szFileName); + } + } + else { + ListView_DeleteColumn(hwndList, 1); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER); + } + return TRUE; + + case WM_THEMECHANGED: + case WM_SETTINGCHANGE: + { + HIMAGELIST 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); // look at !! + return TRUE; + } + + case IDC_MORELANG: + // CallService(MS_UTILS_OPENURL,TRUE,(LPARAM)"http://miranda-ng.org/"); //look at !! + return TRUE; + + case IDC_ENABLEHELPUPDATES: + 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) { + /* get item */ + LVHITTESTINFO hti; + 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; + + RECT rc; + 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; + + /* context menu */ + HELPPACK_INFO *pack = (HELPPACK_INFO*)lvi.lParam; + HMENU 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((HELPPACK_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, (HELPPACK_INFO*)nmlv->lParam); + } + /* disable all other radio items */ + else if (nmlv->uNewState&INDEXTOSTATEIMAGEMASK(2)) { + for (int 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); + } + } + break; + + case LVN_KEYDOWN: + { + int 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: + lvi.iItem = iItem; + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + if (ListView_GetItem(nmhdr->hwndFrom, &lvi)) + DeletePackFile(hwndDlg, nmhdr->hwndFrom, iItem, (HELPPACK_INFO*)lvi.lParam); + 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); + } /* switch nmhdr->code */ + break; + + case 0: + switch (nmhdr->code) { + case PSN_APPLY: + lvi.mask = LVIF_STATE | LVIF_PARAM; + lvi.stateMask = LVIS_STATEIMAGEMASK; + lvi.iSubItem = 0; + for (lvi.iItem = 0; ListView_GetItem(hwndList, &lvi); ++lvi.iItem) { + HELPPACK_INFO *pack = (HELPPACK_INFO*)lvi.lParam; + if (lvi.state&INDEXTOSTATEIMAGEMASK(2)) { + EnablePack(pack, _T("helppack_*.txt")); + pack->flags |= HPF_ENABLED; + } + else + pack->flags &= ~HPF_ENABLED; + } + db_set_b(NULL, "HelpPlugin", "EnableAutoUpdates", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ENABLEHELPUPDATES) != 0)); + return TRUE; + } + } /* switch nmhdr->idFrom */ + break; + } + return FALSE; +} + +void ReloadLangOptList(void) +{ + if (hwndLangOpt != NULL) { + SendMessage(hwndLangOpt, M_RELOADLIST, 0, 0); + SendMessage(hwndLangOpt, M_SHOWFILECOL, 0, 1); + } +} + +/**************************** ADV OPTS ****************************/ + +static INT_PTR CALLBACK AdvOptDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + { + WORD val = settingAutoTipDelay; + if (!val) + val = db_get_w(NULL, "HelpPlugin", "AutoTipDelay", SETTING_AUTOTIPDELAY_DEFAULT); + CheckDlgButton(hwndDlg, IDC_AUTOTIPSENABLED, settingAutoTipDelay != 0); + SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAYSPIN, UDM_SETRANGE, 0, MAKELPARAM(10000, 500)); + SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAY, EM_SETLIMITTEXT, (WPARAM)5, 0); + { + UDACCEL uda = { 0, 500 }; + SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAYSPIN, UDM_SETACCEL, 1, (LPARAM)&uda); + } + SetDlgItemInt(hwndDlg, IDC_AUTOTIPDELAY, val, FALSE); + SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAYSPIN, UDM_SETPOS, 0, MAKELPARAM(val, 0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAYLABEL), settingAutoTipDelay != 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAY), settingAutoTipDelay != 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAYSPIN), settingAutoTipDelay != 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAYMS), settingAutoTipDelay != 0); + } + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_AUTOTIPSENABLED: + { + BOOL checked = IsDlgButtonChecked(hwndDlg, IDC_AUTOTIPSENABLED); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAYLABEL), checked); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAY), checked); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAYSPIN), checked); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTOTIPDELAYMS), checked); + break; + } + case IDC_AUTOTIPDELAY: + if (HIWORD(wParam) == EN_KILLFOCUS) { + WORD minVal = HIWORD(SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAYSPIN, UDM_GETRANGE, 0, 0)); + if (GetDlgItemInt(hwndDlg, IDC_AUTOTIPDELAY, NULL, FALSE)idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + { + WORD minVal; + minVal = HIWORD(SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAYSPIN, UDM_GETRANGE, 0, 0)); + if (GetDlgItemInt(hwndDlg, IDC_AUTOTIPDELAY, NULL, FALSE) < minVal) { + SetDlgItemInt(hwndDlg, IDC_AUTOTIPDELAY, minVal, FALSE); + SendDlgItemMessage(hwndDlg, IDC_AUTOTIPDELAYSPIN, UDM_SETPOS, 0, MAKELPARAM(minVal, 0)); + } + settingAutoTipDelay = (WORD)GetDlgItemInt(hwndDlg, IDC_AUTOTIPDELAY, NULL, FALSE); + db_set_w(NULL, "HelpPlugin", "AutoTipDelay", settingAutoTipDelay); + + if (!IsDlgButtonChecked(hwndDlg, IDC_AUTOTIPSENABLED)) + settingAutoTipDelay = 0; + db_set_b(NULL, "HelpPlugin", "AutoTipsEnabled", (BYTE)(settingAutoTipDelay != 0)); + return TRUE; + } + } + break; + } + break; + } + return FALSE; +} + +/**************************** INIT ********************************/ + +static int HelpOptInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.position = 1200000080; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_LANG); + odp.ptszGroup = LPGENT("Customize"); // autotranslated + odp.ptszTitle = LPGENT("Help"); // autotranslated + + odp.ptszTab = LPGENT("Language"); // autotranslated + odp.flags = ODPF_TCHAR | ODPF_BOLDGROUPS; + odp.pfnDlgProc = LangOptDlgProc; + Options_AddPage(wParam, &odp); + +#ifdef EDITOR + odp.ptszTab = _T("Help Editor"); /* autotranslated */ +#else + odp.ptszTab = _T("Advanced"); /* autotranslated */ +#endif + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ADV); + odp.pfnDlgProc = AdvOptDlgProc; + Options_AddPage(wParam, &odp); + + return 0; +} + +void InitOptions(void) +{ + settingAutoTipDelay = 0; + if (db_get_b(NULL, "HelpPlugin", "AutoTipsEnabled", SETTING_AUTOTIPSENABLED_DEFAULT)) + settingAutoTipDelay = db_get_w(NULL, "HelpPlugin", "AutoTipDelay", SETTING_AUTOTIPDELAY_DEFAULT); + + hwndLangOpt = NULL; + hHookOptInit = HookEvent(ME_OPT_INITIALISE, HelpOptInit); + CorrectPacks(_T("helppack_*.txt"), _T("helppack_english.txt"), FALSE); +} + +void UninitOptions(void) +{ + UnhookEvent(hHookOptInit); +} \ No newline at end of file -- cgit v1.2.3