From 97c496705a49c6cb8fc228b0397d9c7793ad6fb7 Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 19 May 2012 14:01:09 +0000 Subject: added LangMan git-svn-id: http://svn.miranda-ng.org/main/trunk@74 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/LangMan/options.c | 681 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 681 insertions(+) create mode 100644 plugins/LangMan/options.c (limited to 'plugins/LangMan/options.c') diff --git a/plugins/LangMan/options.c b/plugins/LangMan/options.c new file mode 100644 index 0000000000..f8676a6b0f --- /dev/null +++ b/plugins/LangMan/options.c @@ -0,0 +1,681 @@ +/* + +'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" +#include +#include + +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=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=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; + PLUGININFO *pluginInfo; + PLUGININFO *(__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'); +#if defined(_UNICODE) + { char cFileNameA[MAX_PATH]; + cFileNameA[0]='\0'; + WideCharToMultiByte(CP_ACP,0,szSearch,-1,cFileNameA,sizeof(cFileNameA),NULL,NULL); + if(IsPluginIncluded(pack,cFileNameA)) continue; + } +#else + if(IsPluginIncluded(pack,szSearch)) continue; +#endif + /* 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,"MirandaPluginInfo"); + if(MirandaPluginInfo==NULL) /* v0.8 support */ + *(PROC*)&MirandaPluginInfo=GetProcAddress(hModule,"MirandaPluginInfoEx"); + if(MirandaPluginInfo!=NULL) { /* both structs have the same header */ + pluginInfo=MirandaPluginInfo(mirandaVersion); + if(pluginInfo!=NULL && pluginInfo->cbSize>=sizeof(PLUGININFO) && 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 BOOL 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; +#if defined(_UNICODE) + case WM_NOTIFYFORMAT: + SetWindowLong(hwndDlg,DWL_MSGRESULT,NFR_UNICODE); + return TRUE; +#endif + 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; + UNREFERENCED_PARAMETER(lParam); + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize=sizeof(odp); + odp.hInstance=hInst; + odp.flags=ODPF_BOLDGROUPS|ODPF_TCHAR; + odp.position=1200000090; /* plugin opts=1300000000 */ +// odp.ptszGroup=_T("Appearance"); /* autotranslated */ + odp.ptszTitle=_T("Appearance"); /* autotranslated */ +// odp.ptszTab=_T("Language"); /* autotranslated, can be made a tab */ + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_LANG); + odp.pfnDlgProc=LangOptDlgProc; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&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