diff options
Diffstat (limited to 'Plugins/smcnotify/list.c')
-rw-r--r-- | Plugins/smcnotify/list.c | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/Plugins/smcnotify/list.c b/Plugins/smcnotify/list.c new file mode 100644 index 0000000..bc40ecc --- /dev/null +++ b/Plugins/smcnotify/list.c @@ -0,0 +1,445 @@ +/*
+Status Message Change Notify plugin for Miranda IM.
+
+Copyright © 2004-2005 NoName
+Copyright © 2005-2006 Daniel Vijge, Tomasz Słotwiński, Ricardo Pescuma Domenecci
+
+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 "commonheaders.h"
+
+
+typedef struct {
+ int bSortAscending;
+ int iProtoSort;
+ int iLastColumnSortIndex;
+} LVDLGDAT;
+
+typedef struct {
+ HANDLE hContact;
+ int iiProto;
+ int iStatus;
+} LVITEMDAT;
+
+
+static int GetStatusOnlineness(int status) {
+ switch (status) {
+ case ID_STATUS_FREECHAT:
+ return 110;
+ case ID_STATUS_ONLINE:
+ return 100;
+ case ID_STATUS_OCCUPIED:
+ return 60;
+ case ID_STATUS_ONTHEPHONE:
+ return 50;
+ case ID_STATUS_DND:
+ return 40;
+ case ID_STATUS_AWAY:
+ return 30;
+ case ID_STATUS_OUTTOLUNCH:
+ return 20;
+ case ID_STATUS_NA:
+ return 10;
+ case ID_STATUS_INVISIBLE:
+ return 5;
+ }
+ return 0;
+}
+
+static BOOL CheckStatusMessage(HANDLE hContact, TCHAR* str) {
+ if (DBGetContactSettingByte(hContact, "CList", "Hidden", 0)) return 0;
+
+ MyDBGetContactSettingTString_dup(hContact, "CList", "StatusMsg", str);
+
+ if (str != NULL && str[0] != _T('\0')) return 1;
+
+ return 0;
+}
+
+static BOOL ListOpenContact(HWND hList, int item) {
+ if (item != -1)
+ {
+ LVITEM lvi;
+ LVITEMDAT *lvidat;
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_PARAM;
+ lvi.lParam = (LONG)NULL;
+ lvi.iItem = item;
+ lvi.iSubItem = 0;
+ ListView_GetItem(hList, &lvi);
+ lvidat = (LVITEMDAT*)lvi.lParam;
+ if(lvidat->hContact != NULL)
+ {
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)lvidat->hContact, (LONG)NULL);
+ CallService("SRMsg/LaunchMessageWindow", (WPARAM)lvidat->hContact, (LONG)NULL);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static BOOL ListOpenContactMenu(HWND hDlg, HWND hList, int item) {
+ if (item != -1)
+ {
+ LVITEM lvi;
+ LVITEMDAT *lvidat;
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_PARAM;
+ lvi.lParam = (LONG)NULL;
+ lvi.iItem = item;
+ lvi.iSubItem = 0;
+ ListView_GetItem(hList, &lvi);
+ lvidat = (LVITEMDAT*)lvi.lParam;
+ if (lvidat->hContact != NULL)
+ {
+ HMENU hCMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)lvidat->hContact, 0);
+ if (hCMenu != NULL)
+ {
+ POINT p;
+ int ret;
+ GetCursorPos(&p);
+ ret = TrackPopupMenu(hCMenu, TPM_NONOTIFY | TPM_RETURNCMD, p.x, p.y, 0, hDlg, NULL);
+ CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(ret, MPCF_CONTACTMENU), (LPARAM)lvidat->hContact);
+ DestroyMenu(hCMenu);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+static int CALLBACK ListSortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) {
+ LVDLGDAT *dat = (LVDLGDAT*)lParamSort;
+ HWND hList = GetDlgItem(hListDlg, IDC_LIST);
+ int result = 0;
+
+ const int maxSize = 128;
+ TCHAR text1[128];
+ TCHAR text2[128];
+ ListView_GetItemText(hList, (int)lParam1, dat->iLastColumnSortIndex, text1, maxSize);
+ ListView_GetItemText(hList, (int)lParam2, dat->iLastColumnSortIndex, text2, maxSize);
+
+ switch (dat->iLastColumnSortIndex)
+ {
+ case 0:
+ {
+ LVITEM lvi;
+ LVITEMDAT *lvid1, *lvid2;
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_PARAM;
+ lvi.lParam = (LONG)NULL;
+ lvi.iSubItem = 0;
+
+ lvi.iItem = (int)lParam1;
+ ListView_GetItem(hList, &lvi);
+ lvid1 = (LVITEMDAT*)lvi.lParam;
+
+ lvi.iItem = (int)lParam2;
+ ListView_GetItem(hList, &lvi);
+ lvid2 = (LVITEMDAT*)lvi.lParam;
+
+ if ((lvid1 == NULL) || (lvid2 == NULL)) return 0;
+
+ if (dat->iProtoSort == 1)
+ {
+ if (lvid1->iStatus == lvid2->iStatus) break;
+ else
+ {
+ result = (lvid1->iStatus < lvid2->iStatus) ? 1 : -1;
+ }
+ }
+ else if (dat->iProtoSort == 0)
+ {
+ result = lstrcmp(text1, text2);
+ if (result == 0)
+ {
+ if (lvid1->iStatus == lvid2->iStatus) break;
+ else
+ {
+ result = (lvid1->iStatus < lvid2->iStatus) ? 1 : -1;
+ }
+ }
+ }
+ break;
+ }
+ case 1:
+ case 2:
+ result = lstrcmpi(text1, text2);
+ break;
+ }
+
+ return dat->bSortAscending ? result : -result;
+}
+
+static void AddColumns(HWND hList) {
+ HIMAGELIST hImgList;
+ LVCOLUMN lvc;
+
+ ListView_SetExtendedListViewStyle(hList,
+ LVS_EX_FULLROWSELECT
+ | LVS_EX_INFOTIP
+ | LVS_EX_LABELTIP
+ | LVS_EX_BORDERSELECT
+ | LVS_EX_GRIDLINES
+ );
+
+ hImgList = (HIMAGELIST)CallService(MS_CLIST_GETICONSIMAGELIST, 0, 0);
+ if (hImgList != NULL)
+ ListView_SetImageList(hList, hImgList, LVSIL_SMALL);
+
+ ZeroMemory(&lvc, sizeof(lvc));
+ lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
+ lvc.fmt = LVCFMT_IMAGE;
+ lvc.pszText = TranslateT("Protocol");
+ lvc.cx = DBGetContactSettingWord(NULL, MODULE_NAME, "ListColWidth0", 30);
+ ListView_InsertColumn(hList, 0, &lvc);
+ lvc.mask = LVCF_TEXT | LVCF_WIDTH;
+// lvc.fmt = LVCFMT_LEFT;
+ lvc.pszText = TranslateT("Nick");
+ lvc.cx = DBGetContactSettingWord(NULL, MODULE_NAME, "ListColWidth1", 70);
+ ListView_InsertColumn(hList, 1, &lvc);
+ lvc.pszText = TranslateT("Status Message");
+ lvc.cx = DBGetContactSettingWord(NULL, MODULE_NAME, "ListColWidth2", 250);
+ ListView_InsertColumn(hList, 2, &lvc);
+
+ ListView_SetTextColor(hList, opts.colListText);
+ if (opts.bListUseBkImage && lstrcmp(opts.listbkimage, _T("")))
+ {
+ LVBKIMAGE lvbi;
+ ZeroMemory(&lvbi, sizeof(lvbi));
+ lvbi.ulFlags = LVBKIF_SOURCE_URL | LVBKIF_STYLE_TILE;
+ lvbi.pszImage = opts.listbkimage;
+ ListView_SetBkImage(hList, &lvbi);
+ ListView_SetBkColor(hList, GetSysColor(COLOR_HIGHLIGHT));
+ ListView_SetTextBkColor(hList, CLR_NONE);
+ }
+ else
+ {
+ ListView_SetBkColor(hList, opts.colListBack);
+ ListView_SetTextBkColor(hList, opts.colListBack);
+ }
+}
+
+static void LoadContacts(HWND hList) {
+ HANDLE hContact;
+ LVITEM lvi;
+ LVITEMDAT *lvidat;
+ int i = 0;
+ TCHAR *proto = NULL;
+ TCHAR *smsg = NULL;
+
+ ZeroMemory(&lvi, sizeof(lvi));
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+// if (DBGetContactSettingByte(hContact, "CList", "Hidden", 0));
+ smsg = MyDBGetContactSettingTString_dup(hContact, "CList", "StatusMsg", smsg);
+ if (smsg != NULL && smsg[0] != _T('\0'))
+ {
+ lvidat = (LVITEMDAT*)mir_alloc(sizeof(LVITEMDAT));
+ lvidat->iiProto = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0);
+ lvidat->iStatus = GetStatusOnlineness(DBGetContactSettingWord(hContact, (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0), "Status", 0));
+ lvidat->hContact = hContact;
+ lvi.mask = LVIF_PARAM | LVIF_IMAGE | LVIF_TEXT;
+ lvi.iItem = i;
+ lvi.iSubItem = 0;
+ lvi.lParam = (LPARAM)lvidat;
+ lvi.iImage = CallService(MS_CLIST_GETCONTACTICON, (WPARAM)hContact, 0);
+ proto = MyDBGetContactSettingTString_dup(hContact, "Protocol", "p", proto);
+ lvi.pszText = proto;
+ ListView_InsertItem(hList, &lvi);
+ ListView_SetItemText(hList, i, 1, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR));
+ ListView_SetItemText(hList, i, 2, smsg);
+ i++;
+ mir_free(smsg);
+ mir_free(proto);
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+}
+
+static BOOL CALLBACK ListDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ HWND hList = GetDlgItem(hwndDlg, IDC_LIST);
+ LVDLGDAT *lvdat;
+ lvdat = (LVDLGDAT*)GetWindowLong(hwndDlg, GWL_USERDATA);
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ DWORD sort;
+ TranslateDialogDefault(hwndDlg);
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_BIG, CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)ICO_LIST));
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM)ICON_SMALL, CallService(MS_SKIN2_GETICONBYHANDLE, 0, (LPARAM)ICO_LIST));
+ Utils_RestoreWindowPosition(hwndDlg, NULL, MODULE_NAME, "List");
+
+ lvdat = (LVDLGDAT*)mir_alloc(sizeof(LVDLGDAT));
+ sort = DBGetContactSettingDword(NULL, MODULE_NAME, "ListColumnSort", 9);
+ lvdat->iLastColumnSortIndex = sort >> 2;
+ lvdat->bSortAscending = (sort & 1) ? 1 : 0;
+ lvdat->iProtoSort = (sort & 2) ? 1 : 0;
+ SetWindowLong(hwndDlg, GWL_USERDATA, (LONG)lvdat);
+
+ AddColumns(hList);
+
+ LoadContacts(hList);
+
+ ListView_SortItemsEx(hList, ListSortFunc, (LPARAM)lvdat);
+// SendMessage(hwndDlg, WM_SIZE, 0, 0);
+// ShowWindow(hwndDlg, SW_SHOW);
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ if (((LPNMHDR)lParam)->idFrom == IDC_LIST)
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_DBLCLK:
+ {
+ LVHITTESTINFO lvh;
+ POINT p;
+ GetCursorPos(&p);
+ ZeroMemory(&lvh, sizeof(lvh));
+ lvh.pt = p;
+ ScreenToClient(hList, &lvh.pt);
+ ListView_HitTest(hList, &lvh);
+ if ((lvh.flags & (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)) && lvh.iItem != -1)
+ ListOpenContact(hList, lvh.iItem);
+ break;
+ }
+ case NM_RCLICK:
+ {
+ LVHITTESTINFO lvh;
+ POINT p;
+ GetCursorPos(&p);
+ ZeroMemory(&lvh, sizeof(lvh));
+ lvh.pt = p;
+ ScreenToClient(hList, &lvh.pt);
+ ListView_HitTest(hList, &lvh);
+ if ((lvh.flags & (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)) && lvh.iItem != -1)
+ ListOpenContactMenu(hwndDlg, hList, lvh.iItem);
+ break;
+ }
+ case LVN_COLUMNCLICK:
+ {
+ LPNMLISTVIEW nmlv = (LPNMLISTVIEW)lParam;
+// if (nmlv->iSubItem == 2) {
+// SendMessage(hwndDlg, WM_USER + 10, 0, 0);
+// break;
+// }
+ if (nmlv->iSubItem != lvdat->iLastColumnSortIndex)
+ {
+ lvdat->bSortAscending = 1;
+ lvdat->iLastColumnSortIndex = nmlv->iSubItem;
+ lvdat->iProtoSort = 0;
+ }
+ else
+ {
+ lvdat->bSortAscending = !lvdat->bSortAscending;
+ if (lvdat->bSortAscending == 1) lvdat->iProtoSort = !lvdat->iProtoSort;
+ }
+ ListView_SortItemsEx(hList, ListSortFunc, (LPARAM)lvdat);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
+ case WM_DRAWITEM:
+ return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
+ case WM_COMMAND:
+ {
+ switch (wParam)
+ {
+ case IDOK:
+ ListOpenContact(hList, ListView_GetNextItem(hList, -1, LVIS_SELECTED));
+ break;
+ case IDCANCEL:
+ SendMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+ }
+ break;
+ }
+// case WM_USER + 10: // refresh
+// ListView_DeleteAllItems(hList);
+// LoadContactsStatusMsgList(hList);
+// ListView_SortItems(hList, ListSortFunc, (LPARAM)lvdat);
+// return 0;
+ case WM_SIZE:
+ {
+ RECT rc;
+ POINT p;
+ GetWindowRect(hwndDlg, &rc);
+ p.x = rc.right - GetSystemMetrics(SM_CYDLGFRAME);
+ p.y = rc.bottom - GetSystemMetrics(SM_CXDLGFRAME);
+ ScreenToClient(hwndDlg, &p);
+ MoveWindow(hList, 0, 0, p.x, p.y, TRUE);
+ break;
+ }
+ case WM_CLOSE:
+ {
+ DestroyWindow(hwndDlg);
+// KillTimer(hwndDlg, TIMERID_LISTAUTOREFRESH);
+ break;
+ }
+ case WM_DESTROY:
+ {
+ DWORD sort;
+ int i;
+ Utils_SaveWindowPosition(hwndDlg, NULL, MODULE_NAME, "List");
+ DBWriteContactSettingWord(NULL, MODULE_NAME, "ListColWidth0", (WORD)ListView_GetColumnWidth(hList, 0));
+ DBWriteContactSettingWord(NULL, MODULE_NAME, "ListColWidth1", (WORD)ListView_GetColumnWidth(hList, 1));
+ DBWriteContactSettingWord(NULL, MODULE_NAME, "ListColWidth2", (WORD)ListView_GetColumnWidth(hList, 2));
+
+// sort = lvdat->iLastColumnSortIndex<<2;
+ sort = lvdat->iLastColumnSortIndex * 4;
+ sort = lvdat->bSortAscending ? sort | 1 : sort;
+ sort = lvdat->iProtoSort ? sort | 2 : sort;
+ DBWriteContactSettingDword(NULL, MODULE_NAME, "ListColumnSort", sort);
+
+ for (i = 0; i < ListView_GetItemCount(hList); i++)
+ {
+ LVITEM lvi;
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_PARAM;
+ lvi.lParam = (LONG)NULL;
+ lvi.iItem = i;
+ lvi.iSubItem = 0;
+ ListView_GetItem(hList, &lvi);
+ mir_free((LVITEMDAT*)lvi.lParam);
+ }
+ mir_free(lvdat);
+ hListDlg = NULL;
+ break;
+ }
+ }
+ return FALSE;
+}
+
+extern void ShowList() {
+ if (hListDlg == NULL)
+ {
+ hListDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_LIST), NULL, ListDlgProc);
+ //ShowWindow(hListDlg, SW_SHOW);
+ }
+ else
+ {
+ SetForegroundWindow(hListDlg);
+ SetFocus(hListDlg);
+ }
+}
|