/* 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 "..\..\core\commonheaders.h" #define IGNOREEVENT_MAX 7 static const DWORD ignoreIdToPf1[IGNOREEVENT_MAX]={PF1_IMRECV,PF1_URLRECV,PF1_FILERECV,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; static const DWORD ignoreIdToPf4[IGNOREEVENT_MAX]={0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,PF4_SUPPORTTYPING}; static DWORD GetMask(HANDLE hContact) { DWORD mask=DBGetContactSettingDword(hContact,"Ignore","Mask1",(DWORD)(-1)); if (mask == (DWORD)(-1)) { if (hContact == NULL) mask=0; else { if (DBGetContactSettingByte(hContact,"CList","Hidden",0) || DBGetContactSettingByte(hContact,"CList","NotOnList",0)) mask=DBGetContactSettingDword(NULL,"Ignore","Mask1",0); else mask=DBGetContactSettingDword(NULL,"Ignore","Default1",0); } } return mask; } static void SetListGroupIcons(HWND hwndList,HANDLE hFirstItem,HANDLE hParentItem,int *groupChildCount) { int typeOfFirst; int iconOn[IGNOREEVENT_MAX]={1,1,1,1,1,1,1}; int childCount[IGNOREEVENT_MAX]={0,0,0,0,0,0,0},i; int iImage; HANDLE hItem,hChildItem; typeOfFirst=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem,0); //check groups if (typeOfFirst == CLCIT_GROUP) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hFirstItem); while (hItem) { hChildItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem); if (hChildItem) SetListGroupIcons(hwndList,hChildItem,hItem,childCount); for (i=0; i < SIZEOF(iconOn); i++) if (iconOn[i] && SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,i) == 0) iconOn[i]=0; hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hItem); } //check contacts if (typeOfFirst == CLCIT_CONTACT) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hFirstItem); while (hItem) { for ( i=0; i < SIZEOF(iconOn); i++ ) { iImage=SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,i); if (iconOn[i] && iImage == 0) iconOn[i]=0; if (iImage != 0xFF) childCount[i]++; } hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem); } //set icons for ( i=0; i < SIZEOF(iconOn); i++ ) { SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hParentItem,MAKELPARAM(i,childCount[i]?(iconOn[i]?i+3:0):0xFF)); if (groupChildCount) groupChildCount[i]+=childCount[i]; } SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hParentItem,MAKELPARAM(IGNOREEVENT_MAX,1)); SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hParentItem,MAKELPARAM(IGNOREEVENT_MAX+1,2)); } static void SetAllChildIcons(HWND hwndList,HANDLE hFirstItem,int iColumn,int iImage) { int typeOfFirst,iOldIcon; HANDLE hItem,hChildItem; typeOfFirst=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem,0); //check groups if (typeOfFirst == CLCIT_GROUP) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hFirstItem); while (hItem) { hChildItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem); if (hChildItem) SetAllChildIcons(hwndList,hChildItem,iColumn,iImage); hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTGROUP,(LPARAM)hItem); } //check contacts if (typeOfFirst == CLCIT_CONTACT) hItem=hFirstItem; else hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hFirstItem); while (hItem) { iOldIcon=SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn); if (iOldIcon != 0xFF && iOldIcon != iImage) SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage)); hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_NEXTCONTACT,(LPARAM)hItem); } } static void ResetListOptions(HWND hwndList) { int i; SendMessage(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); SendMessage(hwndList,CLM_SETBKCOLOR,GetSysColor(COLOR_WINDOW),0); SendMessage(hwndList,CLM_SETGREYOUTFLAGS,0,0); SendMessage(hwndList,CLM_SETLEFTMARGIN,4,0); SendMessage(hwndList,CLM_SETINDENT,10,0); SendMessage(hwndList,CLM_SETHIDEEMPTYGROUPS,1,0); for (i=0;i<=FONTID_MAX;i++) SendMessage(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); } static void SetIconsForColumn(HWND hwndList,HANDLE hItem,HANDLE hItemAll,int iColumn,int iImage) { int itemType; itemType=SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hItem,0); if (itemType == CLCIT_CONTACT) { int oldiImage = SendMessage(hwndList,CLM_GETEXTRAIMAGE,(WPARAM)hItem,iColumn); if (oldiImage != 0xFF&&oldiImage != iImage) SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage)); } else if (itemType == CLCIT_INFO) { if (hItem == hItemAll) SetAllChildIcons(hwndList,hItem,iColumn,iImage); else SendMessage(hwndList,CLM_SETEXTRAIMAGE,(WPARAM)hItem,MAKELPARAM(iColumn,iImage)); //hItemUnknown } else if (itemType == CLCIT_GROUP) { hItem=(HANDLE)SendMessage(hwndList,CLM_GETNEXTITEM,CLGN_CHILD,(LPARAM)hItem); if (hItem) SetAllChildIcons(hwndList,hItem,iColumn,iImage); } } static void InitialiseItem(HWND hwndList,HANDLE hContact,HANDLE hItem,DWORD proto1Caps,DWORD proto4Caps) { DWORD mask; int i; mask=GetMask(hContact); for (i=0;iidFrom) { case IDC_LIST: switch (((LPNMHDR)lParam)->code) { case CLN_NEWCONTACT: case CLN_LISTREBUILT: SetAllContactIcons(GetDlgItem(hwndDlg,IDC_LIST)); //fall through case CLN_CONTACTMOVED: SetListGroupIcons(GetDlgItem(hwndDlg,IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETNEXTITEM,CLGN_ROOT,0),hItemAll,NULL); break; case CLN_OPTIONSCHANGED: ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); break; case CLN_CHECKCHANGED: SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; case NM_CLICK: { HANDLE hItem; NMCLISTCONTROL *nm=(NMCLISTCONTROL*)lParam; DWORD hitFlags; int iImage; if (nm->iColumn == -1) break; hItem=(HANDLE)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_HITTEST,(WPARAM)&hitFlags,MAKELPARAM(nm->pt.x,nm->pt.y)); if (hItem == NULL) break; if (!(hitFlags&CLCHT_ONITEMEXTRA)) break; if (nm->iColumn == IGNOREEVENT_MAX) { //ignore all for (iImage=0;iImageiColumn == IGNOREEVENT_MAX+1) { //ignore none for (iImage=0;iImageiColumn,0)); if (iImage == 0) iImage=nm->iColumn+3; else if (iImage != 0xFF) iImage=0; SetIconsForColumn(GetDlgItem(hwndDlg,IDC_LIST),hItem,hItemAll,nm->iColumn,iImage); } SetListGroupIcons(GetDlgItem(hwndDlg,IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETNEXTITEM,CLGN_ROOT,0),hItemAll,NULL); SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); break; } } break; case 0: switch (((LPNMHDR)lParam)->code) { case PSN_APPLY: { HANDLE hContact,hItem; hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); do { hItem=(HANDLE)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_FINDCONTACT,(WPARAM)hContact,0); if (hItem) SaveItemMask(GetDlgItem(hwndDlg,IDC_LIST),hContact,hItem,"Mask1"); if (SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETCHECKMARK,(WPARAM)hItem,0)) DBDeleteContactSetting(hContact,"CList","Hidden"); else DBWriteContactSettingByte(hContact,"CList","Hidden",1); } while (hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)); SaveItemMask(GetDlgItem(hwndDlg,IDC_LIST),NULL,hItemAll,"Default1"); SaveItemMask(GetDlgItem(hwndDlg,IDC_LIST),NULL,hItemUnknown,"Mask1"); return TRUE; } case PSN_EXPERTCHANGED: SetWindowLongPtr(GetDlgItem(hwndDlg,IDC_LIST),GWL_STYLE,((PSHNOTIFY*)lParam)->lParam?GetWindowLongPtr(GetDlgItem(hwndDlg,IDC_LIST),GWL_STYLE)|CLS_CHECKBOXES|CLS_GROUPCHECKBOXES|CLS_SHOWHIDDEN:GetWindowLongPtr(GetDlgItem(hwndDlg,IDC_LIST),GWL_STYLE)&~(CLS_CHECKBOXES|CLS_GROUPCHECKBOXES|CLS_SHOWHIDDEN)); SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_AUTOREBUILD,0,0); break; } break; } break; case WM_DESTROY: { int i; HIMAGELIST hIml; for ( i=0; i < SIZEOF(hIcons); i++ ) DestroyIcon(hIcons[i]); hIml=(HIMAGELIST)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETEXTRAIMAGELIST,0,0); ImageList_Destroy(hIml); break; } } return FALSE; } static UINT expertOnlyControls[]={IDC_STCHECKMARKS}; static int IgnoreOptInitialise(WPARAM wParam, LPARAM) { OPTIONSDIALOGPAGE odp = { 0 }; odp.cbSize = sizeof(odp); odp.position = 900000000; odp.hInstance = hMirandaInst; odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_IGNORE); odp.pszTitle = LPGEN("Ignore"); odp.pszGroup = LPGEN("Events"); odp.pfnDlgProc = DlgProcIgnoreOpts; odp.flags = ODPF_BOLDGROUPS; odp.expertOnlyControls = expertOnlyControls; odp.nExpertOnlyControls = SIZEOF( expertOnlyControls ); CallService( MS_OPT_ADDPAGE, wParam, ( LPARAM )&odp); return 0; } static INT_PTR IsIgnored(WPARAM wParam,LPARAM lParam) { DWORD mask=GetMask((HANDLE)wParam); if (lParam<1 || lParam>IGNOREEVENT_MAX) return 1; return (mask>>(lParam-1))&1; } static INT_PTR Ignore(WPARAM wParam,LPARAM lParam) { DWORD mask=GetMask((HANDLE)wParam); if ((lParam<1 || lParam>IGNOREEVENT_MAX) && lParam != IGNOREEVENT_ALL) return 1; if (lParam == IGNOREEVENT_ALL) mask=(1<IGNOREEVENT_MAX) && lParam != IGNOREEVENT_ALL) return 1; if (lParam == IGNOREEVENT_ALL) mask=0; else mask&=~(1<<(lParam-1)); DBWriteContactSettingDword((HANDLE)wParam,"Ignore","Mask1",mask); return 0; } static int IgnoreContactAdded(WPARAM wParam, LPARAM) { CallService(MS_PROTO_ADDTOCONTACT,wParam,(LPARAM)"Ignore"); return 0; } static INT_PTR IgnoreRecvMessage(WPARAM wParam,LPARAM lParam) { if (IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact,IGNOREEVENT_MESSAGE)) return 1; return CallService(MS_PROTO_CHAINRECV,wParam,lParam); } static INT_PTR IgnoreRecvUrl(WPARAM wParam,LPARAM lParam) { if (IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact,IGNOREEVENT_URL)) return 1; return CallService(MS_PROTO_CHAINRECV,wParam,lParam); } static INT_PTR IgnoreRecvFile(WPARAM wParam,LPARAM lParam) { if (IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact,IGNOREEVENT_FILE)) return 1; return CallService(MS_PROTO_CHAINRECV,wParam,lParam); } static INT_PTR IgnoreRecvAuth(WPARAM wParam,LPARAM lParam) { if (IsIgnored((WPARAM)((CCSDATA*)lParam)->hContact,IGNOREEVENT_AUTHORIZATION)) return 1; return CallService(MS_PROTO_CHAINRECV,wParam,lParam); } static int IgnoreAddedNotify(WPARAM, LPARAM lParam) { DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; if (dbei && dbei->eventType == EVENTTYPE_ADDED && dbei->pBlob != NULL) { HANDLE hContact; hContact=*((PHANDLE)(dbei->pBlob+sizeof(DWORD))); if (CallService(MS_DB_CONTACT_IS,(WPARAM)hContact,0) && IsIgnored((WPARAM)hContact,IGNOREEVENT_YOUWEREADDED)) return 1; } return 0; } static int IgnoreModernOptInit(WPARAM wParam, LPARAM) { static int iBoldControls[] = { IDC_TXT_TITLE1, IDC_TXT_TITLE2, IDC_TXT_TITLE3, MODERNOPT_CTRL_LAST }; MODERNOPTOBJECT obj = {0}; obj.cbSize = sizeof(obj); obj.hInstance = hMirandaInst; obj.dwFlags = MODEROPT_FLG_TCHAR; obj.iSection = MODERNOPT_PAGE_IGNORE; obj.iType = MODERNOPT_TYPE_SECTIONPAGE; obj.iBoldControls = iBoldControls; obj.lpzTemplate = MAKEINTRESOURCEA(IDD_MODERNOPT_IGNORE); obj.pfnDlgProc = DlgProcIgnoreOpts; // obj.lpzClassicGroup = "Events"; // obj.lpzClassicPage = "Ignore"; CallService(MS_MODERNOPT_ADDOBJECT, wParam, (LPARAM)&obj); return 0; } int LoadIgnoreModule(void) { PROTOCOLDESCRIPTOR pd = { 0 }; pd.cbSize=sizeof(pd); pd.szName="Ignore"; pd.type=PROTOTYPE_IGNORE; CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); while ( hContact != NULL ) { if (!CallService(MS_PROTO_ISPROTOONCONTACT,(WPARAM)hContact,(LPARAM)"Ignore")) CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)hContact,(LPARAM)"Ignore"); hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); } CreateServiceFunction("Ignore"PSR_MESSAGE,IgnoreRecvMessage); CreateServiceFunction("Ignore"PSR_URL,IgnoreRecvUrl); CreateServiceFunction("Ignore"PSR_FILE,IgnoreRecvFile); CreateServiceFunction("Ignore"PSR_AUTH,IgnoreRecvAuth); CreateServiceFunction(MS_IGNORE_ISIGNORED,IsIgnored); CreateServiceFunction(MS_IGNORE_IGNORE,Ignore); CreateServiceFunction(MS_IGNORE_UNIGNORE,Unignore); HookEvent(ME_DB_CONTACT_ADDED,IgnoreContactAdded); HookEvent(ME_DB_EVENT_FILTER_ADD,IgnoreAddedNotify); HookEvent(ME_MODERNOPT_INITIALIZE, IgnoreModernOptInit); HookEvent(ME_OPT_INITIALISE,IgnoreOptInitialise); return 0; }