/* "Last Seen mod" plugin for Miranda IM Copyright ( C ) 2002-03 micron-x Copyright ( C ) 2005-06 Y.B. 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 "seen.h" static HANDLE hWindowList; char* BuildSetting(int historyLast) { static char setting[15]; static char sztemp[15]; *setting = '\0'; strcat(setting, "History_"); strcat(setting, _itoa(historyLast, sztemp, 10)); return setting; } void HistoryWrite(HANDLE hContact) { int historyMax = db_get_w(NULL, S_MOD, "HistoryMax", 10); if (historyMax < 0) historyMax=0; else if (historyMax > 99) historyMax = 99; if (historyMax == 0) return; int historyFirst = db_get_w(hContact, S_MOD, "HistoryFirst", 0); if (historyFirst >= historyMax) historyFirst = 0; int historyLast = db_get_w(hContact, S_MOD, "HistoryLast", 0); if (historyLast >= historyMax) historyLast = historyMax-1; TCHAR *ptszString; DBVARIANT dbv; if ( !db_get_ts(NULL, S_MOD, "HistoryStamp", &dbv)) { ptszString = ParseString(dbv.ptszVal, hContact, 0); db_free(&dbv); } else ptszString = ParseString(DEFAULT_HISTORYSTAMP, hContact, 0); db_set_ts(hContact, S_MOD, BuildSetting(historyLast), ptszString); historyLast = (historyLast+1) % historyMax; db_set_w(hContact, S_MOD, "HistoryLast", historyLast); if (historyLast == historyFirst) db_set_w(hContact, S_MOD, "HistoryFirst", (historyFirst+1) % historyMax); } void LoadHistoryList(HANDLE hContact, HWND hwnd, int nList) { SendDlgItemMessage(hwnd, nList, LB_RESETCONTENT, 0, 0); int historyMax = db_get_w(NULL,S_MOD,"HistoryMax",10); if (historyMax < 0) historyMax = 0; else if (historyMax > 99) historyMax = 99; if (historyMax == 0) return; int historyFirst = db_get_w(hContact,S_MOD,"HistoryFirst",0); if (historyFirst >= historyMax) historyFirst = 0; int historyLast = db_get_w(hContact,S_MOD,"HistoryLast",0); if (historyLast >= historyMax) historyLast = historyMax-1; for (int i = historyLast; i != historyFirst; ) { i = (i-1+historyMax) % historyMax; DBVARIANT dbv; if ( !db_get_ts(hContact, S_MOD, BuildSetting(i), &dbv)) { SendDlgItemMessage(hwnd, nList, LB_ADDSTRING, 0, (LPARAM)dbv.ptszVal); db_free(&dbv); } else SendDlgItemMessage(hwnd, nList, LB_ADDSTRING, 0, (LPARAM)_T("")); } } HDWP MyResizeWindow (HDWP hDwp, HWND hwndDlg, HWND hwndControl, int nHorizontalOffset, int nVerticalOffset, int nWidthOffset, int nHeightOffset) { POINT pt; RECT rcinit; // get current bounding rectangle GetWindowRect(hwndControl, &rcinit); // get current top left point pt.x = rcinit.left; pt.y = rcinit.top; ScreenToClient(hwndDlg, &pt); // resize control return DeferWindowPos(hDwp, hwndControl, NULL, pt.x + nHorizontalOffset, pt.y + nVerticalOffset, rcinit.right - rcinit.left + nWidthOffset, rcinit.bottom - rcinit.top + nHeightOffset, SWP_NOZORDER); } HDWP MyHorizCenterWindow (HDWP hDwp, HWND hwndDlg, HWND hwndControl, int nClientWidth, int nVerticalOffset, int nHeightOffset) { POINT pt; RECT rcinit; // get current bounding rectangle GetWindowRect(hwndControl, &rcinit); // get current top left point pt.x = rcinit.left; pt.y = rcinit.top; ScreenToClient(hwndDlg, &pt); // resize control return DeferWindowPos(hDwp, hwndControl, NULL, (int) ((nClientWidth - (rcinit.right - rcinit.left))/2), pt.y + nVerticalOffset, rcinit.right - rcinit.left, rcinit.bottom - rcinit.top + nHeightOffset, SWP_NOZORDER); } void MyResizeGetOffset (HWND hwndDlg, HWND hwndControl, int nWidth, int nHeight, int* nDx, int* nDy) { RECT rcinit; // get current bounding rectangle GetWindowRect(hwndControl, &rcinit); // calculate offsets *nDx = nWidth - (rcinit.right - rcinit.left); *nDy = nHeight - (rcinit.bottom - rcinit.top); } INT_PTR CALLBACK HistoryDlgProc(HWND hwndDlg, UINT Message, WPARAM wparam, LPARAM lparam) { HANDLE hContact; TCHAR sztemp[1024]; switch(Message) { case WM_INITDIALOG: TranslateDialogDefault(hwndDlg); hContact = (HANDLE)lparam; SetWindowLongPtr(hwndDlg,GWLP_USERDATA,lparam); mir_sntprintf(sztemp, SIZEOF(sztemp), _T("%s: %s"), CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR), TranslateT("last seen history")); SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)sztemp); SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA)); SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_MIRANDA)); if ( db_get_b(hContact,S_MOD,"OnlineAlert",0)) SendDlgItemMessage(hwndDlg, IDC_STATUSCHANGE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); SendDlgItemMessage(hwndDlg, IDC_DETAILS, BM_SETIMAGE, IMAGE_ICON, (WPARAM)LoadSkinnedIcon(SKINICON_OTHER_USERDETAILS)); SendDlgItemMessage(hwndDlg, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (WPARAM)LoadSkinnedIcon(SKINICON_OTHER_DOWNARROW)); SendDlgItemMessage(hwndDlg, IDC_SENDMSG, BM_SETIMAGE, IMAGE_ICON, (WPARAM)LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); //set-up tooltips SendDlgItemMessage(hwndDlg, IDC_DETAILS, BUTTONADDTOOLTIP, (WPARAM)TranslateT("View User's Details"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_USERMENU, BUTTONADDTOOLTIP, (WPARAM)TranslateT("User Menu"), BATF_TCHAR); SendDlgItemMessage(hwndDlg, IDC_SENDMSG, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Send Instant Message"), BATF_TCHAR); Utils_RestoreWindowPositionNoMove(hwndDlg,NULL,S_MOD,"History_"); ShowWindow(hwndDlg, SW_SHOW); return TRUE; case WM_MEASUREITEM: return CallService(MS_CLIST_MENUMEASUREITEM,wparam,lparam); case WM_DRAWITEM: return CallService(MS_CLIST_MENUDRAWITEM,wparam,lparam); case WM_COMMAND: hContact=(HANDLE)GetWindowLongPtr(hwndDlg,GWLP_USERDATA); if (CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wparam),MPCF_CONTACTMENU),(LPARAM)hContact)) break; switch(LOWORD(wparam)) { case IDCANCEL: SendMessage(hwndDlg, WM_CLOSE, 0, 0); break; case IDOK: if (SendDlgItemMessage(hwndDlg, IDC_STATUSCHANGE, BM_GETCHECK, 0, 0) == BST_CHECKED) db_set_b(hContact,S_MOD,"OnlineAlert",1); else db_set_b(hContact,S_MOD,"OnlineAlert",0); SendMessage(hwndDlg, WM_CLOSE, 0, 0); break; case IDC_USERMENU: { RECT rc; HMENU hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)hContact,0); GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc); TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); DestroyMenu(hMenu); } break; case IDC_DETAILS: CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)hContact,0); break; case IDC_SENDMSG: CallService(MS_MSG_SENDMESSAGE,(WPARAM)hContact,0); break; case IDC_TEST: debug( ParseString( LPGENT("Date: %d.%m.%y(%Y) \n Date desc: %W - %w - %E - %e \n Time: %H:%M:%S (%h-%p) \n user: %n - %u \n Status: %s \n IP: %i - %r"), hContact, 0)); break; } break; case WM_SIZE: { int dx, dy; HDWP hDwp = BeginDeferWindowPos(6); MyResizeGetOffset(hwndDlg, GetDlgItem(hwndDlg, IDC_HISTORYLIST), LOWORD(lparam)-15, HIWORD(lparam)-99, &dx, &dy); hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_USERMENU), dx, 0, 0, 0); hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_DETAILS), dx, 0, 0, 0); hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_SENDMSG), dx, 0, 0, 0); hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_HISTORYLIST), 0, 0, dx, dy); hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_STATUSCHANGE), 0, dy, dx, 0); hDwp = MyHorizCenterWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDOK), LOWORD(lparam), dy, 0); EndDeferWindowPos(hDwp); } break; case WM_GETMINMAXINFO: { MINMAXINFO mmi; CopyMemory (&mmi, (LPMINMAXINFO) lparam, sizeof (MINMAXINFO)); /* The minimum width in points*/ mmi.ptMinTrackSize.x = 200; /* The minimum height in points*/ mmi.ptMinTrackSize.y = 190; CopyMemory ((LPMINMAXINFO) lparam, &mmi, sizeof (MINMAXINFO)); } break; case WM_CLOSE: DestroyWindow(hwndDlg); WindowList_Remove(hWindowList,hwndDlg); break; case WM_DESTROY: Utils_SaveWindowPosition(hwndDlg,NULL,S_MOD,"History_"); DestroyIcon((HICON)SendMessage(hwndDlg, WM_GETICON, ICON_BIG, 0)); DestroyIcon((HICON)SendMessage(hwndDlg, WM_GETICON, ICON_SMALL, 0)); break; } return FALSE; } void ShowHistory(HANDLE hContact, BYTE isAlert) { HWND hHistoryDlg = WindowList_Find(hWindowList,hContact); if (hHistoryDlg == NULL) { hHistoryDlg = CreateDialogParam(hInstance,MAKEINTRESOURCE(IDD_HISTORY),NULL,HistoryDlgProc,(LPARAM)hContact); LoadHistoryList(hContact, hHistoryDlg, IDC_HISTORYLIST); WindowList_Add(hWindowList,hHistoryDlg,hContact); } else { SetForegroundWindow(hHistoryDlg); LoadHistoryList(hContact, hHistoryDlg, IDC_HISTORYLIST); SetFocus(hHistoryDlg); } if (isAlert) SkinPlaySound("LastSeenTrackedStatusChange"); } void InitHistoryDialog(void) { hWindowList = WindowList_Create(); } void UninitHistoryDialog(void) { WindowList_Destroy(hWindowList); }