/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2003 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 #pragma hdrstop static HMENU hMainMenu, hMainStatusMenu; static MWindowList hWindowListIGN = 0; void DestroyTrayMenu(HMENU hMenu) { int i, cnt; cnt = GetMenuItemCount(hMenu); for (i=0; ihwndContactList); PostQuitMessage(0); Sleep(0); } return(0); } static const UINT xImgCtrlIds[] = { IDC_EXTRA_ICON_RES0, IDC_EXTRA_ICON_EMAIL, IDC_EXTRA_ICON_RES1, IDC_EXTRA_ICON_SMS, IDC_EXTRA_ICON_ADV1, IDC_EXTRA_ICON_ADV2, IDC_EXTRA_ICON_WEB, IDC_EXTRA_ICON_CLIENT, IDC_EXTRA_ICON_RES2, IDC_EXTRA_ICON_ADV3, IDC_EXTRA_ICON_ADV4 }; static const UINT xImgCtrlBits[] = { EXTRA_ICON_RES0, EXTRA_ICON_EMAIL, EXTRA_ICON_RES1, EXTRA_ICON_SMS, EXTRA_ICON_ADV1, EXTRA_ICON_ADV2, EXTRA_ICON_WEB, EXTRA_ICON_CLIENT, EXTRA_ICON_RES2, EXTRA_ICON_ADV3, EXTRA_ICON_ADV4 }; static INT_PTR CALLBACK IgnoreDialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { MCONTACT hContact = (MCONTACT)GetWindowLongPtr(hWnd, GWLP_USERDATA); switch(msg) { case WM_INITDIALOG: { DWORD dwMask; struct ClcContact *contact = NULL; int pCaps; HWND hwndAdd; hContact = lParam; SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)hContact); dwMask = cfg::getDword(hContact, "Ignore", "Mask1", 0); SendMessage(hWnd, WM_USER + 100, (WPARAM)hContact, dwMask); SendMessage(hWnd, WM_USER + 120, 0, 0); TranslateDialogDefault(hWnd); hwndAdd = GetDlgItem(hWnd, IDC_IGN_ADDPERMANENTLY); // CreateWindowEx(0, L"CLCButtonClass", L"FOO", WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 200, 276, 106, 24, hWnd, (HMENU)IDC_IGN_ADDPERMANENTLY, g_hInst, NULL); SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1); SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1); SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_LoadIcon(SKINICON_OTHER_ADDCONTACT)); SetWindowText(hwndAdd, TranslateT("Add permanently")); EnableWindow(hwndAdd, cfg::getByte(hContact, "CList", "NotOnList", 0)); hwndAdd = GetDlgItem(hWnd, IDC_DSP_LOADDEFAULT); // CreateWindowEx(0, L"CLCButtonClass", L"FOO", WS_VISIBLE | BS_PUSHBUTTON | WS_CHILD | WS_TABSTOP, 200, 276, 106, 24, hWnd, (HMENU)IDC_IGN_ADDPERMANENTLY, g_hInst, NULL); SendMessage(hwndAdd, BUTTONSETASFLATBTN, 0, 1); SendMessage(hwndAdd, BUTTONSETASFLATBTN + 10, 0, 1); SendMessage(hwndAdd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_LoadIcon(SKINICON_OTHER_DELETE)); SetWindowText(hwndAdd, TranslateT("Revert to default")); EnableWindow(hwndAdd, TRUE); SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Default (global setting)")); SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Show always when available")); SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Hide always")); SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Default (global setting)")); SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Never")); SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Always")); SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When space is available")); SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_INSERTSTRING, -1, (LPARAM)TranslateT("When needed by status message")); if(cfg::clcdat) { CLC::findItem(pcli->hwndContactTree, cfg::clcdat, (HANDLE)hContact, &contact, NULL, NULL); if(contact && contact->type != CLCIT_CONTACT) { DestroyWindow(hWnd); return FALSE; } else { wchar_t szTitle[512]; DWORD dwFlags = cfg::getDword(hContact, "CList", "CLN_Flags", 0); BYTE bSecondLine = cfg::getByte(hContact, "CList", "CLN_2ndline", -1); DWORD dwXMask = cfg::getDword(hContact, "CList", "CLN_xmask", 0); int i = 0; mir_sntprintf(szTitle, 512, TranslateT("Contact list display and ignore options for %s"), contact ? contact->szText : pcli->pfnGetContactDisplayName(hContact, 0)); SetWindowText(hWnd, szTitle); SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)Skin_LoadIcon(SKINICON_OTHER_MIRANDA)); pCaps = CallProtoService(contact ? contact->proto : GetContactProto(hContact), PS_GETCAPS, PFLAGNUM_1, 0); Utils::enableDlgControl(hWnd, IDC_IGN_ALWAYSONLINE, pCaps & PF1_INVISLIST ? TRUE : FALSE); Utils::enableDlgControl(hWnd, IDC_IGN_ALWAYSOFFLINE, pCaps & PF1_VISLIST ? TRUE : FALSE); CheckDlgButton(hWnd, IDC_IGN_PRIORITY, cfg::getByte(hContact, "CList", "Priority", 0) ? 1 : 0); Utils::enableDlgControl(hWnd, IDC_IGN_PRIORITY, TRUE); Utils::enableDlgControl(hWnd, IDC_AVATARDISPMODE, TRUE); Utils::enableDlgControl(hWnd, IDC_SECONDLINEMODE, TRUE); if(dwFlags & ECF_FORCEAVATAR) SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 1, 0); else if(dwFlags & ECF_HIDEAVATAR) SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 2, 0); else SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 0, 0); if(dwFlags & ECF_FORCEOVERLAY) SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_CHECKED, 0); else if(dwFlags & ECF_HIDEOVERLAY) SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_UNCHECKED, 0); else SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_INDETERMINATE, 0); if(dwFlags & ECF_FORCELOCALTIME) SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_SETCHECK, BST_CHECKED, 0); else if(dwFlags & ECF_HIDELOCALTIME) SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_SETCHECK, BST_UNCHECKED, 0); else SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_SETCHECK, BST_INDETERMINATE, 0); if(dwFlags & ECF_FORCEVISIBILITY) SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_CHECKED, 0); else if(dwFlags & ECF_HIDEVISIBILITY) SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_UNCHECKED, 0); else SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_INDETERMINATE, 0); while(xImgCtrlIds[i] != 0) { if(dwXMask & (1 << (2 * xImgCtrlBits[i]))) SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_SETCHECK, BST_CHECKED, 0); else if(dwXMask & (1 << (2 * xImgCtrlBits[i] + 1))) SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_SETCHECK, BST_UNCHECKED, 0); else SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_SETCHECK, BST_INDETERMINATE, 0); i++; } if(bSecondLine == 0xff) SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, 0, 0); else SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, (WPARAM)(bSecondLine + 1), 0); } } WindowList_Add(hWindowListIGN, hWnd, hContact); ShowWindow(hWnd, SW_SHOWNORMAL); return TRUE; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_IGN_PRIORITY: SendMessage(pcli->hwndContactTree, CLM_TOGGLEPRIORITYCONTACT, (WPARAM)hContact, 0); return 0; case IDC_IGN_ALL: SendMessage(hWnd, WM_USER + 100, (WPARAM)hContact, (LPARAM)0xffffffff); return 0; case IDC_IGN_NONE: SendMessage(hWnd, WM_USER + 100, (WPARAM)hContact, (LPARAM)0); return 0; case IDC_IGN_ALWAYSONLINE: if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSONLINE)) CheckDlgButton(hWnd, IDC_IGN_ALWAYSOFFLINE, FALSE); break; case IDC_IGN_ALWAYSOFFLINE: if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSOFFLINE)) CheckDlgButton(hWnd, IDC_IGN_ALWAYSONLINE, FALSE); break; case IDC_HIDECONTACT: cfg::writeByte(hContact, "CList", "Hidden", (BYTE)(IsDlgButtonChecked(hWnd, IDC_HIDECONTACT) ? 1 : 0)); break; case IDC_IGN_ADDPERMANENTLY: { ADDCONTACTSTRUCT acs = {0}; acs.hContact = hContact; acs.handleType = HANDLE_CONTACT; acs.szProto = 0; CallService(MS_ADDCONTACT_SHOW, (WPARAM)hWnd, (LPARAM)&acs); Utils::enableDlgControl(hWnd, IDC_IGN_ADDPERMANENTLY, cfg::getByte(hContact, "CList", "NotOnList", 0)); break; } case IDC_DSP_LOADDEFAULT: { int i = 0; SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_SETCURSEL, 0, 0); SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_SETCURSEL, 0, 0); while(xImgCtrlIds[i] != 0) SendDlgItemMessage(hWnd, xImgCtrlIds[i++], BM_SETCHECK, BST_INDETERMINATE, 0); SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_SETCHECK, BST_INDETERMINATE, 0); SendDlgItemMessage(hWnd, IDC_LOCALTIME, BM_SETCHECK, BST_INDETERMINATE, 0); SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_SETCHECK, BST_INDETERMINATE, 0); break; } case IDOK: { DWORD newMask = 0; struct ClcContact *contact = NULL; SendMessage(hWnd, WM_USER + 110, 0, (LPARAM)&newMask); cfg::writeDword(hContact, "Ignore", "Mask1", newMask); SendMessage(hWnd, WM_USER + 130, 0, 0); if(cfg::clcdat) { LRESULT iSel = SendDlgItemMessage(hWnd, IDC_AVATARDISPMODE, CB_GETCURSEL, 0, 0); DWORD dwFlags = cfg::getDword(hContact, "CList", "CLN_Flags", 0), dwXMask = 0; LRESULT checked = 0; int i = 0; CLC::findItem(pcli->hwndContactTree, cfg::clcdat, (HANDLE)hContact, &contact, NULL, NULL); if(iSel != CB_ERR) { dwFlags &= ~(ECF_FORCEAVATAR | ECF_HIDEAVATAR); if(iSel == 1) dwFlags |= ECF_FORCEAVATAR; else if(iSel == 2) dwFlags |= ECF_HIDEAVATAR; if(contact) LoadAvatarForContact(contact); } dwFlags &= ~(ECF_FORCEOVERLAY | ECF_HIDEOVERLAY | ECF_FORCELOCALTIME | ECF_HIDELOCALTIME | ECF_FORCEVISIBILITY | ECF_HIDEVISIBILITY); checked = SendDlgItemMessage(hWnd, IDC_OVERLAYICON, BM_GETCHECK, 0, 0); if(checked == BST_CHECKED) dwFlags |= ECF_FORCEOVERLAY; else if(checked == BST_UNCHECKED) dwFlags |= ECF_HIDEOVERLAY; checked = SendDlgItemMessage(hWnd, IDC_SHOWLOCALTIME1, BM_GETCHECK, 0, 0); if(checked == BST_CHECKED) dwFlags |= ECF_FORCELOCALTIME; else if(checked == BST_UNCHECKED) dwFlags |= ECF_HIDELOCALTIME; checked = SendDlgItemMessage(hWnd, IDC_SHOWVISIBILITY, BM_GETCHECK, 0, 0); if(checked == BST_CHECKED) dwFlags |= ECF_FORCEVISIBILITY; else if(checked == BST_UNCHECKED) dwFlags |= ECF_HIDEVISIBILITY; cfg::writeDword(hContact, "CList", "CLN_Flags", dwFlags); if((iSel = SendDlgItemMessage(hWnd, IDC_SECONDLINEMODE, CB_GETCURSEL, 0, 0)) != CB_ERR) { if(iSel == 0) { db_unset(hContact, "CList", "CLN_2ndline"); if(contact) contact->bSecondLineLocal = -1; } else { cfg::writeByte(hContact, "CList", "CLN_2ndline", (BYTE)(iSel - 1)); if(contact) contact->bSecondLineLocal = (BYTE)(iSel - 1); } } while(xImgCtrlIds[i] != 0) { checked = SendDlgItemMessage(hWnd, xImgCtrlIds[i], BM_GETCHECK, 0, 0); if(checked == BST_CHECKED) dwXMask |= (1 << (2 * xImgCtrlBits[i])); else if(checked == BST_UNCHECKED) dwXMask |= (1 << (2 * xImgCtrlBits[i] + 1)); i++; } cfg::writeDword(hContact, "CList", "CLN_xmask", dwXMask); if(contact) { if(contact->extraCacheEntry >= 0 && contact->extraCacheEntry <= cfg::nextCacheEntry) { contact->dwDFlags = dwFlags; cfg::eCache[contact->extraCacheEntry].dwXMask = CalcXMask(hContact); } } else { int iIndex = cfg::getCache(hContact, NULL); if(iIndex >= 0 && iIndex <= cfg::nextCacheEntry) cfg::eCache[iIndex].dwXMask = CalcXMask(hContact); } cfg::writeByte(hContact, "CList", "Priority", (BYTE)(IsDlgButtonChecked(hWnd, IDC_IGN_PRIORITY) ? 1 : 0)); pcli->pfnClcBroadcast(CLM_AUTOREBUILD, 0, 0); } } case IDCANCEL: DestroyWindow(hWnd); break; } break; case WM_USER + 100: // fill dialog (wParam = hContact, lParam = mask) { CheckDlgButton(hWnd, IDC_IGN_MSGEVENTS, lParam & (1 << (IGNOREEVENT_MESSAGE - 1)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_IGN_FILEEVENTS, lParam & (1 << (IGNOREEVENT_FILE - 1)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_IGN_URLEVENTS, lParam & (1 << (IGNOREEVENT_URL - 1)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_IGN_AUTH, lParam & (1 << (IGNOREEVENT_AUTHORIZATION - 1)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_IGN_ADD, lParam & (1 << (IGNOREEVENT_YOUWEREADDED - 1)) ? BST_CHECKED : BST_UNCHECKED); CheckDlgButton(hWnd, IDC_IGN_ONLINE, lParam & (1 << (IGNOREEVENT_USERONLINE - 1)) ? BST_CHECKED : BST_UNCHECKED); return 0; } case WM_USER + 110: // retrieve value { DWORD *dwNewMask = (DWORD *)lParam, dwMask = 0; dwMask = (IsDlgButtonChecked(hWnd, IDC_IGN_MSGEVENTS) ? (1 << (IGNOREEVENT_MESSAGE - 1)) : 0) | (IsDlgButtonChecked(hWnd, IDC_IGN_FILEEVENTS) ? (1 << (IGNOREEVENT_FILE - 1)) : 0) | (IsDlgButtonChecked(hWnd, IDC_IGN_URLEVENTS) ? (1 << (IGNOREEVENT_URL - 1)) : 0) | (IsDlgButtonChecked(hWnd, IDC_IGN_AUTH) ? (1 << (IGNOREEVENT_AUTHORIZATION - 1)) : 0) | (IsDlgButtonChecked(hWnd, IDC_IGN_ADD) ? (1 << (IGNOREEVENT_YOUWEREADDED - 1)) : 0) | (IsDlgButtonChecked(hWnd, IDC_IGN_ONLINE) ? (1 << (IGNOREEVENT_USERONLINE - 1)) : 0); if(dwNewMask) *dwNewMask = dwMask; return 0; } case WM_USER + 120: // set visibility status { struct ClcContact *contact = NULL; if(CLC::findItem(pcli->hwndContactTree, cfg::clcdat, (HANDLE)hContact, &contact, NULL, NULL)) { if(contact) { WORD wApparentMode = cfg::getWord(contact->hContact, contact->proto, "ApparentMode", 0); CheckDlgButton(hWnd, IDC_IGN_ALWAYSOFFLINE, wApparentMode == ID_STATUS_OFFLINE ? TRUE : FALSE); CheckDlgButton(hWnd, IDC_IGN_ALWAYSONLINE, wApparentMode == ID_STATUS_ONLINE ? TRUE : FALSE); } } return 0; } case WM_USER + 130: // update apparent mode { struct ClcContact *contact = NULL; if(CLC::findItem(pcli->hwndContactTree, cfg::clcdat, (HANDLE)hContact, &contact, NULL, NULL)) { if(contact) { WORD wApparentMode = 0; if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSONLINE)) wApparentMode = ID_STATUS_ONLINE; else if(IsDlgButtonChecked(hWnd, IDC_IGN_ALWAYSOFFLINE)) wApparentMode = ID_STATUS_OFFLINE; CallContactService(hContact, PSS_SETAPPARENTMODE, (WPARAM)wApparentMode, 0); SendMessage(hWnd, WM_USER + 120, 0, 0); } } return 0; } case WM_DESTROY: SetWindowLongPtr(hWnd, GWLP_USERDATA, 0); WindowList_Remove(hWindowListIGN, hWnd); break; } return FALSE; } /* * service function: Open ignore settings dialog for the contact handle in wParam * (clist_nicer+ specific service) * * Servicename = CList/SetContactIgnore * * ensure that dialog is only opened once (the dialog proc saves the window handle of an open dialog * of this type to the contacts database record). * * if dialog is already open, focus it. */ static INT_PTR SetContactIgnore(WPARAM wParam, LPARAM) { HWND hWnd = 0; if (hWindowListIGN == 0) hWindowListIGN = WindowList_Create(); hWnd = WindowList_Find(hWindowListIGN, wParam); if (wParam) { if (hWnd == 0) CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_QUICKIGNORE), 0, IgnoreDialogProc, (LPARAM)wParam); else if (IsWindow(hWnd)) SetFocus(hWnd); } return 0; } /* * service function: Set a contacts floating status. * (clist_nicer+ specific service) * * Servicename = CList/SetContactFloating * * a floating contact appears as a small independent top level window anywhere on * the desktop. */ static INT_PTR SetContactFloating(WPARAM wParam, LPARAM lParam) { SendMessage(pcli->hwndContactTree, CLM_TOGGLEFLOATINGCONTACT, wParam, lParam); return 0; } int InitCustomMenus(void) { CreateServiceFunction("CloseAction", CloseAction); CreateServiceFunction("CList/SetContactIgnore", SetContactIgnore); CMenuItem mi; mi.position = 200000; mi.pszService = "CList/SetContactIgnore"; mi.hIcolibItem = iconItem[0].hIcolib; mi.name.a = LPGEN("&Contact list settings..."); Menu_AddContactMenuItem(&mi); return 0; } void UninitCustomMenus(void) { WindowList_Destroy(hWindowListIGN); }