diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-05-15 10:38:20 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-05-15 10:38:20 +0000 |
commit | 48540940b6c28bb4378abfeb500ec45a625b37b6 (patch) | |
tree | 2ef294c0763e802f91d868bdef4229b6868527de /protocols/Gadu-Gadu/sessions.c | |
parent | 5c350913f011e119127baeb32a6aedeb4f0d33bc (diff) |
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Gadu-Gadu/sessions.c')
-rw-r--r-- | protocols/Gadu-Gadu/sessions.c | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/protocols/Gadu-Gadu/sessions.c b/protocols/Gadu-Gadu/sessions.c new file mode 100644 index 0000000000..39348fef61 --- /dev/null +++ b/protocols/Gadu-Gadu/sessions.c @@ -0,0 +1,445 @@ +////////////////////////////////////////////////////////////////////////////////
+// Gadu-Gadu Plugin for Miranda IM
+//
+// Copyright (c) 2009-2012 Bartosz Białek
+//
+// 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 "gg.h"
+
+#define GGS_CONCUR_SESS "%s/ConcurSess"
+
+static void gg_clearsessionslist(HWND hwndDlg)
+{
+ HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
+ LV_COLUMN column = {0};
+ RECT rc;
+ int iWidth;
+
+ if (!hList) return;
+
+ ListView_DeleteAllItems(hList);
+ while (ListView_DeleteColumn(hList, 0));
+
+ column.mask = LVCF_TEXT;
+ column.cx = 500;
+ column.pszText = TranslateT("Client Name");
+ ListView_InsertColumn(hList, 1, &column);
+
+ column.pszText=TranslateT("IP Address");
+ ListView_InsertColumn(hList, 2, &column);
+
+ column.pszText = TranslateT("Login Time");
+ ListView_InsertColumn(hList, 3, &column);
+
+ column.pszText = TranslateT("Action");
+ ListView_InsertColumn(hList, 4, &column);
+
+ GetClientRect(hList, &rc);
+ iWidth = rc.right - rc.left;
+ ListView_SetColumnWidth(hList, 0, iWidth * 45 / 100);
+ ListView_SetColumnWidth(hList, 1, iWidth * 20 / 100);
+ ListView_SetColumnWidth(hList, 2, iWidth * 20 / 100);
+ ListView_SetColumnWidth(hList, 3, LVSCW_AUTOSIZE_USEHEADER);
+}
+
+static void ListView_SetItemTextA(HWND hwndLV, int i, int iSubItem, char* pszText)
+{
+ LV_ITEMA _ms_lvi;
+ _ms_lvi.iSubItem = iSubItem;
+ _ms_lvi.pszText = pszText;
+ SendMessageA(hwndLV, LVM_SETITEMTEXTA, i, (LPARAM)&_ms_lvi);
+}
+
+static int gg_insertlistitem(HWND hList, gg_multilogon_id_t* id, const char* clientName, const char* ip, const char* loginTime)
+{
+ LVITEM item = {0};
+ int index;
+
+ item.iItem = ListView_GetItemCount(hList);
+ item.mask = LVIF_PARAM;
+ item.lParam = (LPARAM)id;
+
+ index = ListView_InsertItem(hList, &item);
+ if (index < 0) return index;
+
+ ListView_SetItemTextA(hList, index, 0, (char*)clientName);
+ ListView_SetItemTextA(hList, index, 1, (char*)ip);
+ ListView_SetItemTextA(hList, index, 2, (char*)loginTime);
+ ListView_SetItemText(hList, index, 3, TranslateT("sign out"));
+
+ return index;
+}
+
+static void gg_listsessions(GGPROTO* gg, HWND hwndDlg)
+{
+ HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
+ list_t l;
+
+ if (!hList) return;
+
+ EnterCriticalSection(&gg->sessions_mutex);
+ for (l = gg->sessions; l; l = l->next)
+ {
+ struct gg_multilogon_session* sess = (struct gg_multilogon_session*)l->data;
+ struct in_addr ia;
+ char* ip;
+ char loginTime[20];
+ ia.S_un.S_addr = sess->remote_addr;
+ ip = inet_ntoa(ia);
+ strftime(loginTime, sizeof(loginTime), "%d-%m-%Y %H:%M:%S", localtime(&sess->logon_time));
+ gg_insertlistitem(hList, &sess->id, sess->name, ip, loginTime);
+ }
+ LeaveCriticalSection(&gg->sessions_mutex);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SIGNOUTALL), ListView_GetItemCount(hList) > 0);
+}
+
+static int sttSessionsDlgResizer(HWND hwndDlg, LPARAM lParam, UTILRESIZECONTROL* urc)
+{
+ switch (urc->wId)
+ {
+ case IDC_HEADERBAR:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORX_WIDTH;
+ case IDC_SESSIONS:
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP | RD_ANCHORY_HEIGHT | RD_ANCHORX_WIDTH;
+ case IDC_SIGNOUTALL:
+ return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+ }
+ return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
+}
+
+static BOOL IsOverAction(HWND hwndDlg)
+{
+ HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
+ LVHITTESTINFO hti;
+ RECT rc;
+ HDC hdc;
+ TCHAR szText[256];
+ SIZE textSize;
+ int textPosX;
+
+ GetCursorPos(&hti.pt);
+ ScreenToClient(hList, &hti.pt);
+ GetClientRect(hList, &rc);
+ if (!PtInRect(&rc, hti.pt) || ListView_SubItemHitTest(hList, &hti) == -1
+ || hti.iSubItem != 3 || !(hti.flags & LVHT_ONITEMLABEL))
+ return FALSE;
+
+ ListView_GetSubItemRect(hList, hti.iItem, hti.iSubItem, LVIR_LABEL, &rc);
+ szText[0] = 0;
+ ListView_GetItemText(hList, hti.iItem, hti.iSubItem, szText, SIZEOF(szText));
+ hdc = GetDC(hList);
+ GetTextExtentPoint32(hdc, szText, lstrlen(szText), &textSize);
+ ReleaseDC(hList, hdc);
+ textPosX = rc.left + (((rc.right - rc.left) - textSize.cx) / 2);
+ return (hti.pt.x > textPosX && hti.pt.x < textPosX + textSize.cx);
+}
+
+static HCURSOR hHandCursor = NULL;
+#define WM_MULTILOGONINFO (WM_USER + 10)
+#define HM_PROTOACK (WM_USER + 11)
+
+static INT_PTR CALLBACK gg_sessions_viewdlg(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ GGPROTO* gg = (GGPROTO*)GetWindowLongPtr(hwndDlg, DWLP_USER);
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ GGPROTO* gg = (GGPROTO*)lParam;
+ TCHAR oldTitle[256], newTitle[256];
+ HANDLE hProtoAckEvent;
+
+ SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)lParam);
+ TranslateDialogDefault(hwndDlg);
+ GetDlgItemText(hwndDlg, IDC_HEADERBAR, oldTitle, SIZEOF(oldTitle));
+ mir_snprintf(newTitle, SIZEOF(newTitle), oldTitle, GG_PROTONAME);
+ SetDlgItemText(hwndDlg, IDC_HEADERBAR, newTitle);
+ WindowSetIcon(hwndDlg, "sessions");
+ gg->hwndSessionsDlg = hwndDlg;
+
+ if (hHandCursor == NULL)
+ hHandCursor = LoadCursor(NULL, IDC_HAND);
+ hProtoAckEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_PROTOACK);
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)hProtoAckEvent);
+
+ ListView_SetExtendedListViewStyle(GetDlgItem(hwndDlg, IDC_SESSIONS), LVS_EX_FULLROWSELECT);
+ SendMessage(hwndDlg, WM_MULTILOGONINFO, 0, 0);
+ return TRUE;
+ }
+
+ case HM_PROTOACK:
+ {
+ ACKDATA* ack = (ACKDATA*)lParam;
+ if (!strcmp(ack->szModule, GG_PROTO) && !ack->hContact && ack->type == ACKTYPE_STATUS
+ && ack->result == ACKRESULT_SUCCESS && (ack->lParam == ID_STATUS_OFFLINE
+ || (ack->hProcess == (HANDLE)ID_STATUS_CONNECTING && ack->lParam != ID_STATUS_OFFLINE
+ && !ListView_GetItemCount(GetDlgItem(hwndDlg, IDC_SESSIONS)))))
+ {
+ gg_clearsessionslist(hwndDlg);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_SIGNOUTALL), FALSE);
+ }
+ break;
+ }
+
+ case WM_MULTILOGONINFO:
+ gg_clearsessionslist(hwndDlg);
+ gg_listsessions(gg, hwndDlg);
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wParam))
+ {
+ case IDC_SIGNOUTALL:
+ {
+ HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
+ LVITEM lvi = {0};
+ int iCount = ListView_GetItemCount(hList), i;
+ lvi.mask = LVIF_PARAM;
+ for (i = 0; i < iCount; i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hList, &lvi);
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_multilogon_disconnect(gg->sess, *((gg_multilogon_id_t*)lvi.lParam));
+ LeaveCriticalSection(&gg->sess_mutex);
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->idFrom == IDC_SESSIONS)
+ {
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_CUSTOMDRAW:
+ {
+ LPNMLVCUSTOMDRAW nm = (LPNMLVCUSTOMDRAW)lParam;
+ switch (nm->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ if (ListView_GetItemCount(nm->nmcd.hdr.hwndFrom) == 0)
+ {
+ const LPCTSTR szText = gg_isonline(gg)
+ ? TranslateT("There are no active concurrent sessions for this account.")
+ : TranslateT("You have to be logged in to view concurrent sessions.");
+ RECT rc;
+ HWND hwndHeader = ListView_GetHeader(nm->nmcd.hdr.hwndFrom);
+ SIZE textSize;
+ int textPosX;
+ GetClientRect(nm->nmcd.hdr.hwndFrom, &rc);
+ if (hwndHeader != NULL)
+ {
+ RECT rcHeader;
+ GetClientRect(hwndHeader, &rcHeader);
+ rc.top += rcHeader.bottom;
+ }
+ GetTextExtentPoint32(nm->nmcd.hdc, szText, lstrlen(szText), &textSize);
+ textPosX = rc.left + (((rc.right - rc.left) - textSize.cx) / 2);
+ ExtTextOut(nm->nmcd.hdc, textPosX, rc.top + textSize.cy, ETO_OPAQUE, &rc, szText, lstrlen(szText), NULL);
+ }
+ // FALL THROUGH
+
+ case CDDS_ITEMPREPAINT:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT , CDRF_NOTIFYSUBITEMDRAW);
+ return TRUE;
+
+ case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+ {
+ RECT rc;
+ ListView_GetSubItemRect(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, LVIR_LABEL, &rc);
+ if (nm->nmcd.hdr.idFrom == IDC_SESSIONS && nm->iSubItem == 3)
+ {
+ TCHAR szText[256];
+ szText[0] = 0;
+ ListView_GetItemText(nm->nmcd.hdr.hwndFrom, nm->nmcd.dwItemSpec, nm->iSubItem, szText, SIZEOF(szText));
+ FillRect(nm->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
+ SetTextColor(nm->nmcd.hdc, RGB(0, 0, 255));
+ DrawText(nm->nmcd.hdc, szText, -1, &rc, DT_END_ELLIPSIS | DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_TOP);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT);
+ return TRUE;
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case NM_CLICK:
+ if (IsOverAction(hwndDlg))
+ {
+ LPNMITEMACTIVATE nm = (LPNMITEMACTIVATE)lParam;
+ LVITEM lvi = {0};
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = nm->iItem;
+ ListView_GetItem(nm->hdr.hwndFrom, &lvi);
+ EnterCriticalSection(&gg->sess_mutex);
+ gg_multilogon_disconnect(gg->sess, *((gg_multilogon_id_t*)lvi.lParam));
+ LeaveCriticalSection(&gg->sess_mutex);
+ }
+ break;
+ }
+ }
+ break;
+
+ case WM_CONTEXTMENU:
+ {
+ HWND hList = GetDlgItem(hwndDlg, IDC_SESSIONS);
+ POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}, ptDlg = pt;
+ LVHITTESTINFO lvhti = {0};
+
+ ScreenToClient(hwndDlg, &ptDlg);
+ if (ChildWindowFromPoint(hwndDlg, ptDlg) == hList)
+ {
+ HMENU hMenu;
+ int iSelection;
+
+ lvhti.pt = pt;
+ ScreenToClient(hList, &lvhti.pt);
+ if (ListView_HitTest(hList, &lvhti) == -1) break;
+
+ hMenu = CreatePopupMenu();
+ AppendMenu(hMenu, MFT_STRING, 10001, TranslateT("Copy Text"));
+ AppendMenu(hMenu, MFT_STRING, 10002, TranslateT("Whois"));
+ iSelection = TrackPopupMenu(hMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL);
+ switch (iSelection)
+ {
+ case 10001:
+ {
+ char szText[512], szClientName[256], szIP[64], szLoginTime[64];
+ HGLOBAL hData;
+ if (!OpenClipboard(hwndDlg)) break;
+ EmptyClipboard();
+ szClientName[0] = szIP[0] = szLoginTime[0] = 0;
+ ListView_GetItemText(hList, lvhti.iItem, 0, szClientName, SIZEOF(szClientName));
+ ListView_GetItemText(hList, lvhti.iItem, 1, szIP, SIZEOF(szIP));
+ ListView_GetItemText(hList, lvhti.iItem, 2, szLoginTime, SIZEOF(szLoginTime));
+ mir_snprintf(szText, SIZEOF(szText), "%s\t%s\t%s", szClientName, szIP, szLoginTime);
+ if ((hData = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(szText) + 1)) != NULL)
+ {
+ lstrcpyA((char*)GlobalLock(hData), szText);
+ GlobalUnlock(hData);
+ SetClipboardData(CF_TEXT, hData);
+ }
+ CloseClipboard();
+ break;
+ }
+
+ case 10002:
+ {
+ char szUrl[256], szIP[64];
+ szIP[0] = 0;
+ ListView_GetItemText(hList, lvhti.iItem, 1, szIP, SIZEOF(szIP));
+ mir_snprintf(szUrl, SIZEOF(szUrl), "http://whois.domaintools.com/%s", szIP);
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM)szUrl);
+ break;
+ }
+ }
+ DestroyMenu(hMenu);
+ }
+ break;
+ }
+
+ case WM_GETMINMAXINFO:
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.x = 620;
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.y = 220;
+ return 0;
+
+ case WM_SIZE:
+ {
+ UTILRESIZEDIALOG urd = {0};
+ urd.cbSize = sizeof(urd);
+ urd.hInstance = hInstance;
+ urd.hwndDlg = hwndDlg;
+ urd.lpTemplate = MAKEINTRESOURCEA(IDD_SESSIONS);
+ urd.pfnResizer = sttSessionsDlgResizer;
+ CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
+ return 0;
+ }
+
+ case WM_SETCURSOR:
+ if (LOWORD(lParam) == HTCLIENT && IsOverAction(hwndDlg))
+ {
+ SetCursor(hHandCursor);
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ {
+ HANDLE hProtoAckEvent = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ if (hProtoAckEvent) UnhookEvent(hProtoAckEvent);
+ gg->hwndSessionsDlg = NULL;
+ WindowFreeIcon(hwndDlg);
+ break;
+ }
+ }
+ return FALSE;
+}
+
+INT_PTR gg_sessions_view(GGPROTO* gg, WPARAM wParam, LPARAM lParam)
+{
+ if (gg->hwndSessionsDlg && IsWindow(gg->hwndSessionsDlg))
+ {
+ ShowWindow(gg->hwndSessionsDlg, SW_SHOWNORMAL);
+ SetForegroundWindow(gg->hwndSessionsDlg);
+ SetFocus(gg->hwndSessionsDlg);
+ }
+ else
+ CreateDialogParam(hInstance, MAKEINTRESOURCE(IDD_SESSIONS), NULL, gg_sessions_viewdlg, (LPARAM)gg);
+ return 0;
+}
+
+void gg_sessions_updatedlg(GGPROTO* gg)
+{
+ if (gg->hwndSessionsDlg && IsWindow(gg->hwndSessionsDlg))
+ SendMessage(gg->hwndSessionsDlg, WM_MULTILOGONINFO, 0, 0);
+}
+
+BOOL gg_sessions_closedlg(GGPROTO* gg)
+{
+ if (gg->hwndSessionsDlg && IsWindow(gg->hwndSessionsDlg))
+ return PostMessage(gg->hwndSessionsDlg, WM_CLOSE, 0, 0);
+ return FALSE;
+}
+
+void gg_sessions_menus_init(GGPROTO* gg, HGENMENU hRoot)
+{
+ CLISTMENUITEM mi = {0};
+ char service[64];
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTHANDLE | CMIF_TCHAR;
+ mi.hParentMenu = hRoot;
+
+ mir_snprintf(service, sizeof(service), GGS_CONCUR_SESS, GG_PROTO);
+ CreateProtoServiceFunction(service, gg_sessions_view, gg);
+ if (gg->hMenuRoot)
+ mi.position = 2050000001;
+ else
+ mi.position = 200003;
+ mi.icolibItem = GetIconHandle(IDI_SESSIONS);
+ mi.ptszName = LPGENT("Concurrent &sessions");
+ mi.pszService = service;
+ CallService(MS_CLIST_ADDPROTOMENUITEM, 0, (LPARAM)&mi);
+}
|