From d80195880f3a04b4a826816f6c2a3468f121ed55 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sun, 20 May 2012 19:23:15 +0000 Subject: AddContactPlus and SimpleStatusMsg added git-svn-id: http://svn.miranda-ng.org/main/trunk@109 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/SimpleStatusMsg/awaymsg.cpp | 535 +++++ plugins/SimpleStatusMsg/commonheaders.h | 65 + .../docs/simplestatusmsg-changelog.txt | 270 +++ .../docs/simplestatusmsg-license.txt | 339 +++ .../docs/simplestatusmsg-readme.txt | 81 + .../docs/simplestatusmsg-translation.txt | 138 ++ plugins/SimpleStatusMsg/m_simpleaway.h | 103 + plugins/SimpleStatusMsg/main.cpp | 2269 ++++++++++++++++++++ plugins/SimpleStatusMsg/msgbox.cpp | 1806 ++++++++++++++++ plugins/SimpleStatusMsg/options.cpp | 1752 +++++++++++++++ plugins/SimpleStatusMsg/res/cbook.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/copy.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/cross.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/csmsg.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/gotourl.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/history.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/msg.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/res/plus.ico | Bin 0 -> 2550 bytes plugins/SimpleStatusMsg/resource.h | 126 ++ plugins/SimpleStatusMsg/resource.rc | 437 ++++ plugins/SimpleStatusMsg/simplestatusmsg.h | 105 + plugins/SimpleStatusMsg/simplestatusmsg_10.sln | 26 + plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj | 309 +++ .../simplestatusmsg_10.vcxproj.filters | 82 + plugins/SimpleStatusMsg/utils.cpp | 226 ++ 25 files changed, 8669 insertions(+) create mode 100644 plugins/SimpleStatusMsg/awaymsg.cpp create mode 100644 plugins/SimpleStatusMsg/commonheaders.h create mode 100644 plugins/SimpleStatusMsg/docs/simplestatusmsg-changelog.txt create mode 100644 plugins/SimpleStatusMsg/docs/simplestatusmsg-license.txt create mode 100644 plugins/SimpleStatusMsg/docs/simplestatusmsg-readme.txt create mode 100644 plugins/SimpleStatusMsg/docs/simplestatusmsg-translation.txt create mode 100644 plugins/SimpleStatusMsg/m_simpleaway.h create mode 100644 plugins/SimpleStatusMsg/main.cpp create mode 100644 plugins/SimpleStatusMsg/msgbox.cpp create mode 100644 plugins/SimpleStatusMsg/options.cpp create mode 100644 plugins/SimpleStatusMsg/res/cbook.ico create mode 100644 plugins/SimpleStatusMsg/res/copy.ico create mode 100644 plugins/SimpleStatusMsg/res/cross.ico create mode 100644 plugins/SimpleStatusMsg/res/csmsg.ico create mode 100644 plugins/SimpleStatusMsg/res/gotourl.ico create mode 100644 plugins/SimpleStatusMsg/res/history.ico create mode 100644 plugins/SimpleStatusMsg/res/msg.ico create mode 100644 plugins/SimpleStatusMsg/res/plus.ico create mode 100644 plugins/SimpleStatusMsg/resource.h create mode 100644 plugins/SimpleStatusMsg/resource.rc create mode 100644 plugins/SimpleStatusMsg/simplestatusmsg.h create mode 100644 plugins/SimpleStatusMsg/simplestatusmsg_10.sln create mode 100644 plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj create mode 100644 plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj.filters create mode 100644 plugins/SimpleStatusMsg/utils.cpp (limited to 'plugins/SimpleStatusMsg') diff --git a/plugins/SimpleStatusMsg/awaymsg.cpp b/plugins/SimpleStatusMsg/awaymsg.cpp new file mode 100644 index 0000000000..062b702254 --- /dev/null +++ b/plugins/SimpleStatusMsg/awaymsg.cpp @@ -0,0 +1,535 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2010 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +Portions of this code modified for Simple Status Message plugin +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "commonheaders.h" +#include "simplestatusmsg.h" + +static HANDLE hAwayMsgMenuItem; +static HANDLE hCopyMsgMenuItem; +static HANDLE hGoToURLMenuItem; +static HANDLE hWindowList; +static HANDLE hWindowList2; + +static char *StrNormNewlineA(char *szStr) +{ + if (szStr == NULL) return NULL; + + int nCR = 0; + for (int i = 0; szStr[i]; i++) + if (szStr[i] != 0x0D && szStr[i + 1] == 0x0A) nCR++; + + if (!nCR) return mir_strdup(szStr); + + char *szNewStr = (char*)mir_alloc(lstrlenA(szStr) + nCR + 1), *pszStr = szNewStr; + while (*szStr) + { + if (*szStr == 0x0A) + *pszStr++ = 0x0D; + *pszStr++ = *szStr++; + } + *pszStr++ = 0; + + return szNewStr; +} + +#ifdef _UNICODE +static TCHAR *StrNormNewline(TCHAR *tszStr) +{ + if (tszStr == NULL) return NULL; + + int nCR = 0; + for (int i = 0; tszStr[i]; i++) + if (tszStr[i] != 0x0D && tszStr[i + 1] == 0x0A) nCR++; + + if (!nCR) return mir_tstrdup(tszStr); + + TCHAR *tszNewStr = (TCHAR*)mir_alloc((lstrlen(tszStr) + nCR + 1) * sizeof(TCHAR)), *ptszStr = tszNewStr; + while (*tszStr) + { + if (*tszStr == 0x0A) + *ptszStr++ = 0x0D; + *ptszStr++ = *tszStr++; + } + *ptszStr++ = 0; + + return tszNewStr; +} +#endif + +struct AwayMsgDlgData +{ + HANDLE hContact; + HANDLE hSeq; + HANDLE hAwayMsgEvent; +}; + +#define HM_AWAYMSG (WM_USER + 10) + +static INT_PTR CALLBACK ReadAwayMsgDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + AwayMsgDlgData *dat = (AwayMsgDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (message) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + dat = (AwayMsgDlgData*)mir_alloc(sizeof(AwayMsgDlgData)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); + + dat->hContact = (HANDLE)lParam; + dat->hSeq = (HANDLE)CallContactService(dat->hContact, PSS_GETAWAYMSG, 0, 0); + dat->hAwayMsgEvent = dat->hSeq ? HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_AWAYMSG) : NULL; + WindowList_Add(hWindowList, hwndDlg, dat->hContact); + { + TCHAR str[256], format[128]; + TCHAR *contactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)dat->hContact, GCDNF_TCHAR); + char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)dat->hContact, 0); + WORD dwStatus = DBGetContactSettingWord(dat->hContact, szProto, "Status", ID_STATUS_OFFLINE); + TCHAR *status = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, dwStatus, GSMDF_TCHAR); + + GetWindowText(hwndDlg, format, SIZEOF(format)); + mir_sntprintf(str, SIZEOF(str), format, status, contactName); + SetWindowText(hwndDlg, str); + if (dat->hSeq) + { + GetDlgItemText(hwndDlg, IDC_RETRIEVING, format, SIZEOF(format)); + mir_sntprintf(str, SIZEOF(str), format, status); + } + else + { + mir_sntprintf(str, SIZEOF(str), TranslateT("Failed to retrieve %s message."), status); + SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); + } + SetDlgItemText(hwndDlg, IDC_RETRIEVING, str); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedProtoIcon(szProto, dwStatus)); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedProtoIcon(szProto, dwStatus)); + EnableWindow(GetDlgItem(hwndDlg, IDC_COPY), FALSE); + } + Utils_RestoreWindowPosition(hwndDlg, (HANDLE)lParam, "SRAway", "AwayMsgDlg"); + return TRUE; + + case HM_AWAYMSG: + { + ACKDATA *ack = (ACKDATA*)lParam; + if (ack->hContact != dat->hContact || ack->type != ACKTYPE_AWAYMSG) break; + if (ack->result != ACKRESULT_SUCCESS) break; + if (dat->hAwayMsgEvent && ack->hProcess == dat->hSeq) { UnhookEvent(dat->hAwayMsgEvent); dat->hAwayMsgEvent = NULL; } + +#ifdef _UNICODE + DBVARIANT dbv; + bool unicode = !DBGetContactSetting(dat->hContact, "CList", "StatusMsg", &dbv) && + (dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR); + DBFreeVariant(&dbv); + if (unicode) + { + DBGetContactSettingWString(dat->hContact, "CList", "StatusMsg", &dbv); + TCHAR *tszMsg = StrNormNewline(dbv.pwszVal); + SetDlgItemText(hwndDlg, IDC_MSG, tszMsg); + mir_free(tszMsg); + DBFreeVariant(&dbv); + } + else +#endif + { + char *szMsg = StrNormNewlineA((char *)ack->lParam); + SetDlgItemTextA(hwndDlg, IDC_MSG, szMsg); + mir_free(szMsg); + } + + if (ack->lParam && *((char*)ack->lParam) != '\0') EnableWindow(GetDlgItem(hwndDlg, IDC_COPY), TRUE); + ShowWindow(GetDlgItem(hwndDlg, IDC_RETRIEVING), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, IDC_MSG), SW_SHOW); + SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close")); + break; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + case IDOK: + DestroyWindow(hwndDlg); + break; + + case IDC_COPY: + if (!OpenClipboard(hwndDlg)) break; + if (EmptyClipboard()) + { + TCHAR msg[1024]; + int len = GetDlgItemText(hwndDlg, IDC_MSG, msg, SIZEOF(msg)); + if (len) + { + LPTSTR lptstrCopy; + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(TCHAR)); + if (hglbCopy == NULL) + { + CloseClipboard(); + break; + } + lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); + memcpy(lptstrCopy, msg, len * sizeof(TCHAR)); + lptstrCopy[len] = (TCHAR)0; + GlobalUnlock(hglbCopy); +#ifdef _UNICODE + SetClipboardData(CF_UNICODETEXT, hglbCopy); +#else + SetClipboardData(CF_TEXT, hglbCopy); +#endif + } + } + CloseClipboard(); + break; + } + break; + + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + + case WM_DESTROY: + if (dat->hAwayMsgEvent) UnhookEvent(dat->hAwayMsgEvent); + Utils_SaveWindowPosition(hwndDlg, dat->hContact, "SRAway", "AwayMsgDlg"); + WindowList_Remove(hWindowList, hwndDlg); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0); + mir_free(dat); + break; + } + return FALSE; +} + +static INT_PTR GetMessageCommand(WPARAM wParam, LPARAM) +{ + if (HWND hwnd = WindowList_Find(hWindowList, (HANDLE)wParam)) + { + SetForegroundWindow(hwnd); + SetFocus(hwnd); + } + else CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_READAWAYMSG), NULL, ReadAwayMsgDlgProc, wParam); + return 0; +} + +static INT_PTR CALLBACK CopyAwayMsgDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + AwayMsgDlgData *dat = (AwayMsgDlgData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (message) + { + case WM_INITDIALOG: + { + TCHAR str[256], format[128]; + TCHAR *contactName; + + TranslateDialogDefault(hwndDlg); + dat = (AwayMsgDlgData*)mir_alloc(sizeof(AwayMsgDlgData)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)dat); + + dat->hContact = (HANDLE)lParam; + dat->hSeq = (HANDLE)CallContactService(dat->hContact, PSS_GETAWAYMSG, 0, 0); + dat->hAwayMsgEvent = dat->hSeq ? HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_AWAYMSG) : NULL; + WindowList_Add(hWindowList2, hwndDlg, dat->hContact); + contactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)dat->hContact, GCDNF_TCHAR); + GetWindowText(hwndDlg, format, SIZEOF(format)); + mir_sntprintf(str, SIZEOF(str), format, contactName); + SetWindowText(hwndDlg, str); + if (!dat->hSeq) DestroyWindow(hwndDlg); + return TRUE; + } + + case HM_AWAYMSG: + { + ACKDATA *ack = (ACKDATA*)lParam; + if (ack->hContact != dat->hContact || ack->type != ACKTYPE_AWAYMSG) { DestroyWindow(hwndDlg); break; } + if (ack->result != ACKRESULT_SUCCESS) { DestroyWindow(hwndDlg); break; } + if (dat->hAwayMsgEvent && ack->hProcess == dat->hSeq) { UnhookEvent(dat->hAwayMsgEvent); dat->hAwayMsgEvent = NULL; } + + if (!OpenClipboard(hwndDlg)) { DestroyWindow(hwndDlg); break; } + if (EmptyClipboard()) + { + TCHAR msg[1024]; + int len; +#ifdef _UNICODE + DBVARIANT dbv; + bool unicode = !DBGetContactSetting(dat->hContact, "CList", "StatusMsg", &dbv) && + (dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR); + DBFreeVariant(&dbv); + if (unicode) + { + DBGetContactSettingWString(dat->hContact, "CList", "StatusMsg", &dbv); + TCHAR *tszMsg = StrNormNewline(dbv.pwszVal); + mir_sntprintf(msg, SIZEOF(msg), _T("%s"), tszMsg); + mir_free(tszMsg); + DBFreeVariant(&dbv); + } + else +#endif + { + char *szMsg = StrNormNewlineA((char *)ack->lParam); + mir_sntprintf(msg, SIZEOF(msg), _T("%hs"), szMsg); + mir_free(szMsg); + } + len = lstrlen(msg); + + if (len) + { + LPTSTR lptstrCopy; + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(TCHAR)); + if (hglbCopy == NULL) + { + CloseClipboard(); + DestroyWindow(hwndDlg); + break; + } + lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); + memcpy(lptstrCopy, msg, len * sizeof(TCHAR)); + lptstrCopy[len] = (TCHAR)0; + GlobalUnlock(hglbCopy); +#ifdef _UNICODE + SetClipboardData(CF_UNICODETEXT, hglbCopy); +#else + SetClipboardData(CF_TEXT, hglbCopy); +#endif + } + } + CloseClipboard(); + DestroyWindow(hwndDlg); + break; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: + case IDOK: + DestroyWindow(hwndDlg); + break; + } + break; + + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + + case WM_DESTROY: + if (dat->hAwayMsgEvent) UnhookEvent(dat->hAwayMsgEvent); + WindowList_Remove(hWindowList2, hwndDlg); + mir_free(dat); + break; + } + return FALSE; +} + +static INT_PTR CopyAwayMsgCommand(WPARAM wParam, LPARAM) +{ + if (HWND hwnd = WindowList_Find(hWindowList2, (HANDLE)wParam)) + { + SetForegroundWindow(hwnd); + SetFocus(hwnd); + } + else CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_COPY), NULL, CopyAwayMsgDlgProc, wParam); + return 0; +} + +static char *StrFindURL(char *pszStr) +{ + char *pszURL = NULL; + + if (pszStr != NULL && *pszStr != '\0') + { + pszURL = strstr(pszStr, "www."); + if (pszURL == NULL) + pszURL = strstr(pszStr, "http://"); + if (pszURL == NULL) + pszURL = strstr(pszStr, "https://"); + if (pszURL == NULL) + pszURL = strstr(pszStr, "ftp://"); + } + + return pszURL; +} + +static INT_PTR GoToURLMsgCommand(WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + char *szMsg; + +#ifdef _UNICODE + int unicode = !DBGetContactSetting((HANDLE)wParam, "CList", "StatusMsg", &dbv) && (dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR); + DBFreeVariant(&dbv); + if (unicode) + { + DBGetContactSettingWString((HANDLE)wParam, "CList", "StatusMsg", &dbv); + szMsg = mir_u2a(dbv.pwszVal); + } + else +#endif + { + DBGetContactSettingString((HANDLE)wParam, "CList", "StatusMsg", &dbv); + szMsg = mir_strdup(dbv.pszVal); + } + DBFreeVariant(&dbv); + + char *szURL = StrFindURL(szMsg); + if (szURL != NULL) + { + int i; + for (i = 0; szURL[i] != ' ' && szURL[i] != '\n' && szURL[i] != '\r' && + szURL[i] != '\t' && szURL[i] != '\0'; i++); + + char *szMsgURL = (char *)mir_alloc(i + 1); + if (szMsgURL) + { + lstrcpynA(szMsgURL, szURL, i + 1); + CallService(MS_UTILS_OPENURL, (WPARAM)1, (LPARAM)szMsgURL); + mir_free(szMsgURL); + } + } + mir_free(szMsg); + + return 0; +} + +static int AwayMsgPreBuildMenu(WPARAM wParam, LPARAM lParam) +{ + CLISTMENUITEM clmi = {0}; + TCHAR str[128]; + char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + int iHidden = szProto ? DBGetContactSettingByte((HANDLE)wParam, szProto, "ChatRoom", 0) : 0; + char *szMsg; + int iStatus; + + clmi.cbSize = sizeof(clmi); + clmi.flags = CMIM_FLAGS | CMIF_HIDDEN | CMIF_TCHAR; + + if (!iHidden) + { + iHidden = 1; + iStatus = DBGetContactSettingWord((HANDLE)wParam, szProto, "Status", ID_STATUS_OFFLINE); + if (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1,0) & PF1_MODEMSGRECV) + { + if (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3,0) & Proto_Status2Flag(iStatus == ID_STATUS_OFFLINE ? ID_STATUS_INVISIBLE : iStatus)) + { + iHidden = 0; + clmi.flags = CMIM_FLAGS | CMIM_NAME | CMIM_ICON | CMIF_TCHAR; + clmi.hIcon = LoadSkinnedProtoIcon(szProto, iStatus); + mir_sntprintf(str, SIZEOF(str), TranslateT("Re&ad %s Message"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, GSMDF_TCHAR)); + clmi.ptszName = str; + } + } + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hAwayMsgMenuItem, (LPARAM)&clmi); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)clmi.hIcon, (LPARAM)0); + clmi.flags = CMIM_FLAGS | CMIF_HIDDEN | CMIF_TCHAR; + + if (!iHidden) + { + DBVARIANT dbv; +#ifdef _UNICODE + int unicode = !DBGetContactSetting((HANDLE)wParam, "CList", "StatusMsg", &dbv) && (dbv.type == DBVT_UTF8 || dbv.type == DBVT_WCHAR); + DBFreeVariant(&dbv); + if (unicode) + { + DBGetContactSettingWString((HANDLE)wParam, "CList", "StatusMsg", &dbv); + szMsg = mir_u2a(dbv.pwszVal); + } + else +#endif + { + DBGetContactSettingString((HANDLE)wParam, "CList", "StatusMsg", &dbv); + szMsg = mir_strdup(dbv.pszVal); + } + DBFreeVariant(&dbv); + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ShowCopy", 1) && szMsg && *szMsg != '\0') + { + clmi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_TCHAR; + mir_sntprintf(str, SIZEOF(str), TranslateT("Copy %s Message"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, GSMDF_TCHAR)); + clmi.ptszName = str; + } + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hCopyMsgMenuItem, (LPARAM)&clmi); + clmi.flags = CMIM_FLAGS | CMIF_HIDDEN | CMIF_TCHAR; + + if (!iHidden) + { + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ShowGoToURL", 1) && StrFindURL(szMsg) != NULL) + { + clmi.flags = CMIM_FLAGS | CMIM_NAME | CMIF_TCHAR; + mir_sntprintf(str, SIZEOF(str), TranslateT("&Go to URL in %s Message"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, GSMDF_TCHAR)); + clmi.ptszName = str; + } + mir_free(szMsg); + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hGoToURLMenuItem, (LPARAM)&clmi); + + return 0; +} + +int AwayMsgPreShutdown(void) +{ + if (hWindowList) WindowList_BroadcastAsync(hWindowList, WM_CLOSE, 0, 0); + if (hWindowList2) WindowList_BroadcastAsync(hWindowList2, WM_CLOSE, 0, 0); + + return 0; +} + +int LoadAwayMsgModule(void) +{ + CLISTMENUITEM mi = {0}; + + hWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + hWindowList2 = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_TCHAR; + + CreateServiceFunctionEx(MS_AWAYMSG_SHOWAWAYMSG, GetMessageCommand); + mi.position = -2000005000; + mi.ptszName = LPGENT("Re&ad Away Message"); + mi.pszService = MS_AWAYMSG_SHOWAWAYMSG; + hAwayMsgMenuItem = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + mi.flags |= CMIF_ICONFROMICOLIB; + CreateServiceFunctionEx(MS_SIMPLESTATUSMSG_COPYMSG, CopyAwayMsgCommand); + mi.position = -2000006000; + mi.icolibItem = GetIconHandle(IDI_COPY); + mi.ptszName = LPGENT("Copy Away Message"); + mi.pszService = MS_SIMPLESTATUSMSG_COPYMSG; + hCopyMsgMenuItem = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + CreateServiceFunctionEx(MS_SIMPLESTATUSMSG_GOTOURLMSG, GoToURLMsgCommand); + mi.position = -2000007000; + mi.icolibItem = GetIconHandle(IDI_GOTOURL); + mi.ptszName = LPGENT("&Go to URL in Away Message"); + mi.pszService = MS_SIMPLESTATUSMSG_GOTOURLMSG; + hGoToURLMenuItem = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + HookEventEx(ME_CLIST_PREBUILDCONTACTMENU, AwayMsgPreBuildMenu); + + // Deprecated SimpleAway services + CreateServiceFunctionEx(MS_SA_COPYAWAYMSG, CopyAwayMsgCommand); + CreateServiceFunctionEx(MS_SA_GOTOURLMSG, GoToURLMsgCommand); + + return 0; +} diff --git a/plugins/SimpleStatusMsg/commonheaders.h b/plugins/SimpleStatusMsg/commonheaders.h new file mode 100644 index 0000000000..c509588ec4 --- /dev/null +++ b/plugins/SimpleStatusMsg/commonheaders.h @@ -0,0 +1,65 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +// to enable all 0.9.0 core functions +#define MIRANDA_VER 0x0A00 +// to enable custom langpacks +#define MIRANDA_CUSTOM_LP + +#define _WIN32_IE 0x0501 + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../protocols/IcqOscarJ/icq_constants.h" +#include "m_fortunemsg.h" +#include "m_statusplugins.h" +#include "m_toolbar.h" +#include "m_toptoolbar.h" +#include "m_updater.h" +#include "m_variables.h" +#include "m_simpleaway.h" +#include "m_simplestatusmsg.h" + +#include "resource.h" diff --git a/plugins/SimpleStatusMsg/docs/simplestatusmsg-changelog.txt b/plugins/SimpleStatusMsg/docs/simplestatusmsg-changelog.txt new file mode 100644 index 0000000000..ac9e29474b --- /dev/null +++ b/plugins/SimpleStatusMsg/docs/simplestatusmsg-changelog.txt @@ -0,0 +1,270 @@ +Simple Status Message plugin for Miranda IM Changelog +----------------------------------------------------- + ++ : new feature +* : changed +! : bugfix + + +============================ +v 1.9.0.4 (2011/11/22): +============================ ++ Added support for custom langpacks ++ Added option to do not update variables during idle ++ Added option to do not update variables on ICQ status message requests ++ Added option to disable status messages parsing by Variables plugin ++ Added option to exclude %date% token from parsing by Variables plugin (built-in parser will be used instead) +* Moved variables-related options to a new Variables tab +* Minor Status Message dialog and Options dialog improvements +* The default behavior for every account is now to not change status message on status change +* URL recognition improved a bit +! Fixed %time% variable for idle types independent of idle time +! Fixed memory leaks + +============================ +v 1.9.0.3 (2010/11/14): +============================ +* Restored periodic status message updating on ICQ protocol +* Simplified the status message dialog title +! Fixed showing and copying multiline status messages without carriage return (CR) characters +! Fixed showing status menu item when there is only one account enabled +! Fixed updating variables on idle +! Fixed memory leak + +============================ +v 1.9.0.2 (2010/10/10): +============================ ++ Added ability to set per-contact status messages (using contact-related variables) for ICQ protocol ++ Added error message when failed to retrieve status message +* Disabled periodic status message updating on ICQ protocol +* Removed redundant 'Change Status Message' menu item from the main menu +! Fixed startup status message issue +! Fixed MS_AWAYMSG_GETSTATUSMSG service +! Fixed setting the same status twice +! Fixed possible crash on opening the contact menu + +============================ +v 1.9.0.1 (2010/08/29): +============================ ++ Updater plugin support ++ Added hotkey for the status message dialog (Ctrl + `) +* The keyboard focus is now set to the status message field in the status message dialog when opened manually +! Fixed showing 'Copy Away Message' and 'Go to URL in Away Message' menu items +! Fixed crash on opening the status message dialog when showing 'Status Message...' item in the status bar is disabled +! Fixed retrieving the Winamp song title by %winampsong& variable + +============================ +v 1.9.0.0 (2010/08/25): +============================ +Plugin name change from SimpleAway to Simple Status Message. +Service names has been changed also. See m_simplestatusmsg.h for details. +Services from m_simpleaway.h are deprecated. Please do not use them anymore. +From now on, Miranda IM 0.9 or later is required. ++ Unicode status messages support ++ Support for Account Manager ++ MS_SIMPLESTATUSMSG_SETSTATUS service now supports variables and Unicode +* x64 portability +* Now "Copy Away Message" is unavailable when a buddy doesn't have status message +* Status message dialog won't appear anymore when screen saver is running +* Selecting status in the status message dialog no longer changes status message +* Updated icons +* Code cleaning and optimization +! Fixed handling of status changes requested by another plugin +! Fixed setting "Update variables in status messages" +! Fixed memory leaks +! Fixed a lot of minor bugs + +======================= +v 1.7.5.9 (2009/02/06): +======================= ++ Unicode version ++ New contact menu item: "Go to URL in Away Message" ++ Automatic status message update if it contains any dynamic variable(s) +* Improved retrieving the Winamp song title by %winampsong& variable +! Fixed parsing built-in %winampsong% variable when using Variables plugin + +======================= +v 1.7.5.4 (2008/12/14): +======================= ++ New feature: do not change status message(s) when changing status +* Improved MS_AWAYMSG_GETSTATUSMSG: now can also return the current status message for the specified protocol (see m_simpleaway.h for details) ++ Added Modern Contact List toolbar button +! Hiding "Status Message..." status menu item when "Always set the same message" or "Do not set status message" is set +! Away %time% doesn't take into account Idle setting [Miranda Built-in Away System bug #135] +* Away message from "Always set the same message" won't disappear anymore when changing this option to another ++ Ctrl-Backspace hotkey in SA window +! Rare bug: in some cases, status list in SA dialog box (global status changes) was incomplete +! Some other bugfixes + +======================= +v 1.7.5.2 (2008/09/06): +======================= +! Stability fixes + +======================= +v 1.7.5.1 (2008/04/20): +======================= ++ Pop up dialog asking for status message at startup ++ Feature: leave last played track's title in %winampsong% after exiting the player +! Global status changes to Offline won't affect locked protocols anymore +! Fixes in service funtions +* Code optimization/clean-up + +============================ +v 1.7.5.0 RC 2 (2007/11/27): +============================ +! Fixed showing SA window at startup + +========================== +v 1.7.5.0 RC (2007/11/26): +========================== ++ Per protocol status delay setting at startup ++ Implemented MS_SA_SHOWSTATUSMSGDIALOG service (see m_simpleaway.h for details) +! Fixed setting status profiles via SimpleAway window +! Fixed updating of %winampsong% when the audio player is closed +! Fixed message manipulation buttons activity in some cases +! Some less important fixes + +============================== +v 1.7.0.0 beta 2 (2007/05/21): +============================== ++ New plugin interface support +! Stability fixes + +============================ +v 1.7.0.0 beta (2007/05/14): +============================ +* From now on, Miranda 0.6 or newer is required ++ Added ability to set protocol-dependent status messages ++ Added ability to set startup status. Per protocol configurable ++ SimpleAway notices when other plugin changes status mode +* Reworked options - tabs, better functionality, new options etc. ++ Compatibility with Status Plugins by UnregistereD +! Track title is retrieved correctly when "Scroll title in the Windows taskbar" is enabled in Winamp +* Updated/improved Variables plugin support ++ New services which forces a change to specified global status mode (see m_simpleaway.h for details) ++ Potential PF1_INDIVMODEMSG support +! Fixed duplication of predefined messages +! A lot of minor fixes and improvements + +============================ +v 1.6.5.6 beta (2006/10/13): +============================ +! Some bugfixes + +======================= +v 1.6.5.5 (2006/10/08): +======================= +! Fixed "Status Message..." item adding for disabled or without status message support protocols +! Fixed "Status Message..." item disappearing problem ++ Added ability to disable "Status Message..." menu items by setting BYTE variable SimpleAway/ShowStatusMenuItem to "0". Restart is needed ++ Status profiles from StartupStatus can be showed in status list combo box (disabled by default) - BYTE variable SimpleAway/AddStatusProfiles must be set to "1" +! Status changes is now compatible with protocols that don't support status messages (e.g. MSN <7) +! Fixed setting empty status message for some protocols (e.g. SKYPE) ++ Prepared and included m_simpleaway.h which contains a list of services that can be used by other plugins +! Some less important changes/fixes (including implementation of some patches by TioDuke) + +======================= +v 1.6.5.0 (2006/09/25): +======================= ++ Added "Status Message..." item to global status menu and for each protocol that allow to set status message (clist_modern or clist_nicer only) +! Compatibility of status with StartupStatus ++ Added new variables: %randmsg% and %randdefmsg% - sets random status message from whole history or from predefined messages only ++ Added possibility to automatic random status message change (disabled by default) - you must set/add a new BYTE variable SimpleAway/RandMsgChange and specify change interval in minutes as vaule. Any change needs restart ++ Added Ctrl-A and Ctrl-W hotkeys +* Without automatic SimpleAway window closing when selected by "Status Message Change" or "Status Message..." item +! Fixed MS_AWAYMSG_GETSTATUSMSG service (patch by pescuma) +* No need to restart Miranda after enabling/disabling check for winamp song (patch by TioDuke) +! Lots of small fixes/changes + +======================= +v 1.6.4.0 (2006/09/15): +======================= +! Fixed bug that causes Miranda to stay in the process list after exiting (0.5 and newer) ++ Added ability to change status message without changing status (global by using "Change Status Message" and for each proto by selecting the same status as actual) ++ Added "Change Status Message" option to the main menu (for whose who don't use TopToolbar) ++ Added locking from global status changes feature support (clist_modern or clist_nicer only) ++ Added possibility to remember window position (disabled by default) - you must set/add a new BYTE variable SimpleAway/WinCentered with "0" value in database by DBEditor ++ Added confirm dialog for clearing status message history +* Refreshed icons and now TopToolbar button can be set as flat also +! Some small, not so important changes in code + +======================= +v 1.6.1.1 (2005/04/13): +======================= +! Compatibility with BossKey and GamerStatus +! Fixes in options dialog ++ Added new option to "Buttons" combo box (flat buttons) +* Variables from context menu are placed at current cursor position +! Fixed updating of %winampsong% when song changes + +======================= +v 1.6.0.0 (2005/04/11): +======================= ++ IcoLib support optimization ++ Added variables for FortuneAwayMsg plugin ++ Some new options +* Tiny layout reorganization ++ All available variables placed in contex menu +! Fixed character counter +! Fixes in TopToolBar button functions +! Many other bug fixes and improvements + +======================= +v 1.5.0.0 (2005/03/15): +======================= ++ Added an option to enable/disable sending of Carriage Return characters ++ Added 4px space between message manipulation buttons +* Message manipulation buttons are enabled by default ++ Added TopToolBar button ++ Added IcoLib plugin support ++ New item in contact menu ("Copy Away Message") which copies contact status message to Clipboard ++ Added new variable %rand(x,y)% + +======================= +v 0.0.0.4 (2005/03/10): +======================= ++ Added status message manipulation buttons next to the status message list +* Changed size of the edit control +! Fixed displaying of 32 bit icons with alpha channel on Windows XP ++ Added new variable %winampsong% ++ Added automatic status message update if it contains %winampsong% variable ++ Added ability to use all variables supported by the "variables" plugin (the plugin must be installed in your Miranda-IM) +* Carriage Return characters are ignored while setting status messages +! Few more little fixes + +======================= +v 0.0.0.3 (2005/03/06): +======================= +* Ctrl+Enter works like OK button ++ User can define and delete status messages ++ Added "Clear History" option +* Changed status message combo box list width to 250 px +* All status messages now fit into status combo box list without hscroolbar +* Icons in the status list are displayed with 32 bit color palette and 16x16 size +! Fixed message list ++ Added options dialog ++ SimpleAway is now compatible with StartupStatus ++ Current status message is stored separately for each protocol + +======================= +v 0.0.0.2 (2005/03/03): +======================= +* Enter key inserts new line ++ Added status list combo box +* Removed status buttons +! Dialog window doesn't pop up when switching to global offline status +! Dialog window doesn't pop up when StartupStatus disconnects protocols during Miranda shutdown ++ KeepStatus is disabled when user sets offline status within SimpleAway dialog window +* Edit control appears empty if the last status message was empty +* SimpleAway stores user status messages in the same place where SRAway did ++ Added %time% and %date% variables ++ Dialog window is automatically closed after 5 seconds ++ SimpleAway checks which status message is set when user goes offline (only works for Tlen and GG protocols now) + +======================= +v 0.0.0.1 (2005/03/01): +======================= +Initial release. ++ Added status message combo box and character counter ++ Added status icons and buttons next to the edit control diff --git a/plugins/SimpleStatusMsg/docs/simplestatusmsg-license.txt b/plugins/SimpleStatusMsg/docs/simplestatusmsg-license.txt new file mode 100644 index 0000000000..89e08fb002 --- /dev/null +++ b/plugins/SimpleStatusMsg/docs/simplestatusmsg-license.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/plugins/SimpleStatusMsg/docs/simplestatusmsg-readme.txt b/plugins/SimpleStatusMsg/docs/simplestatusmsg-readme.txt new file mode 100644 index 0000000000..e79cca8db9 --- /dev/null +++ b/plugins/SimpleStatusMsg/docs/simplestatusmsg-readme.txt @@ -0,0 +1,81 @@ + -===========================================- + Simple Status Message plugin for Miranda IM + -===========================================- + + +Description +----------- +Simple Status Message provides a simple way to set status and away messages in Miranda IM. +The plugin was previously named SimpleAway, but has been renamed to better reflect its purpose. +The SimpleAway plugin was originally created by Harven. + +Main features: +- Global and per-protocol status messages. +- Startup status and status message (per-protocol configurable). +- Per-contact status messages using contact-related variables for ICQ protocol (supported by older IM clients only). +- Unicode status messages support. +- Predefined status messages. +- Can remember up to 25 recent status messages which you can choose in the status message dialog. +- The status message dialog can be accessed through a hotkey, the status bar menu, Modern Contact List Toolbar, + TopToolbar plugin frame or could pop up on status change. +- Built-in variables (see below) and support for Variables plugin. +- Can update variables in status messages every specified time. + +Built-in variables list: + %winampsong% - title of the song currently playing in Winamp (or another player with Winamp API Emulator). + %date% - current date. + %time% - current time or the time of becoming idle. + %rand(x,y)% - random number in a specified range. y must be greater than x and both arguments must be integers. + %randmsg% - random status message from the history. + %randdefmsg% - random predefined status message. + %fortunemsg% - BSD Fortune message (requires FortuneAwayMsg plugin). + %protofortunemsg% - BSD Fortune message for a protocol (requires FortuneAwayMsg plugin). + %statusfortunemsg% - BSD Fortune status message for a status (requires FortuneAwayMsg plugin). + +Miranda IM 0.9 or later is required. + +Latest development version, source code and older releases can be found here: +http://code.google.com/p/dezeath + + +Installation +------------ +Copy simplestatusmsg.dll to your Miranda IM plugins directory. +If you are updating from SimpleAway, make sure you removed simpleaway.dll. + + +Changelog +--------- +See simplestatusmsg-changelog.txt. + + +======================== +Base Address: 0x3ab00000 +======================== + + +Copyright and License +--------------------- + +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek +mailto: dezred(at)gmail(dot)com +http://code.google.com/p/dezeath + +Copyright (C) 2005 Mateusz 'Harven' Kwaśniewski +mailto: harven(at)users(dot)berlios(dot)de +http://developer.berlios.de/projects/mgoodies/ + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + diff --git a/plugins/SimpleStatusMsg/docs/simplestatusmsg-translation.txt b/plugins/SimpleStatusMsg/docs/simplestatusmsg-translation.txt new file mode 100644 index 0000000000..82fa9a2fdc --- /dev/null +++ b/plugins/SimpleStatusMsg/docs/simplestatusmsg-translation.txt @@ -0,0 +1,138 @@ +; This is a template for translation of Simple Status Message plugin +; Last updated for version 1.9.0.4 + +;[OK] +;[OK (%d)] +;[Closing in %d] +;[&Cancel] +;[&Close] +;[] +;[] +;[Global] +;[%s Message (%s)] +;[%s Message for %s] +;[Retrieving %s message...] +;[Co&py to Clipboard] +;[Retrieving status message for %s...] +;[Re&ad %s Message] +;[Re&ad Away Message] +;[Copy %s Message] +;[Copy Away Message] +;[&Go to URL in %s Message] +;[&Go to URL in Away Message] +;[Delete Selected] +;[Recent Message] +;[Predefined Message] +;[Add to Predefined] +;[Clear History] +;[Change Status Message] +;[Status Message...] + +; Popup Menu +;[Cut] +;[Copy] +;[Paste] +;[Delete] +;[Select All] +;[Variables] +;[More variables...] +;[?cinfo(contact,property)] +;[?contact(string,property)] +;[?mstatus(protocol)] +;[?lsdate(contact,format)] +;[?lsstatus(contact)] +;[?lstime(contact,format)] +;[?dbsetting(contact,module,setting)] +;[?txtfile(file,line)] +;[?if(condition,true,false)] +;[?strcmp(string1,string2)] +;[?stricmp(string1,string2)] +;[?replace(sub,string1,string2)] +;[?lower(string)] +;[?upper(string)] +;[?scroll(string,numchars,numchars)] + +; Status Options +;[Status] +;[Status on Startup] +;[Set status after] +;[miliseconds] +;[Protocol:] +;[Status:] +;[] +;[Independent setting for each protocol] +;[Pop up dialog asking for status message] + +; Status Messages | General Options +;[Status Messages] +;[General] +;[Behaviour on status change] +;[Global status change] +;[Apply to all] +;[Max length:] +;[Pop up dialog box] +;[Do not set status message] +;[Always set the same message] +;[Do not change status message] +;[Pop up dialog asking for new message] +;[Set an empty message] +;[Use default message] +;[Use last message] +;[Use last message set for this status] +;[Set the following message:] +;[Put default message in message list] +;[Open String Formatting Help] + +; Status Messages | Variables Options +;[Variables] +;[Update variables in status messages every] +;[seconds] +;[Do not update variables during idle] +;[Do not update variables on ICQ status message requests] +;[Leave last played track's title after exiting the player] +;[Enable status messages parsing by Variables plugin] +;[Exclude %date% token from parsing (restart required)] + +; Status Messages | Advanced Options +;[Advanced] +;[Layout] +;[Show status list] +;[Show status profiles in status list] +;[Show icons in status list] +;[Show icons in message list] +;[Buttons:] +;[Hide] +;[Show next to cancel button] +;[Flat, next to cancel button] +;[Show in message list] +;[Other] +;[Store up to] +;[recent messages (0 = disable)] +;[Automatically close dialog window after] +;[Remember last dialog window position] +;[Remove Carriage Return (CR = '\\r' = #0D) chars from status messages] +;[Show 'Copy Away Message' item in contact menu] +;[Show 'Go to URL in Away Message' item in contact menu] +;[Show 'Status Message...' item in status menu] +;[Clear History] +;[Clear Predefined] +;[Are you sure you want to clear status message history?] +;[Confirm clearing history] +;[Are you sure you want to clear predefined status messages?] +;[Confirm clearing predefined] +;[* This feature is available only when using StartupStatus plugin.] + +; Obsolete since v1.7.5.9 +;[Check for winamp song change every] +;[Set random status message every] +;[minutes] + +; Obsolete since v1.9.0.0 +;[* Your contact list plugin doesn't support this feature. Try another one.] +;[* This feature is only available when using StartupStatus.] + +; Obsolete since v1.9.0.3 +;[%s Status Message: %s] + +; Obsolete since v1.9.0.4 +;[Protocols] \ No newline at end of file diff --git a/plugins/SimpleStatusMsg/m_simpleaway.h b/plugins/SimpleStatusMsg/m_simpleaway.h new file mode 100644 index 0000000000..e70dcbf4ac --- /dev/null +++ b/plugins/SimpleStatusMsg/m_simpleaway.h @@ -0,0 +1,103 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2010 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef M_SIMPLEAWAY_H__ +#define M_SIMPLEAWAY_H__ 1 + +// +// NOTE: These services are deprecated. Please do not use them anymore. +// Take a look at m_simplestatusmsg.h instead. +// + +// Represents status that a protocol(s) is/are currently in +#define ID_STATUS_CURRENT 40082 + +// Force a change of global status mode/message +// wParam = (int)new status (from statusmodes.h), 0 or ID_STATUS_CURRENT for current +// lParam = (TCHAR *)status message +#define MS_SA_SETSTATUSMODE "SimpleAway/SetStatusMode" +#define MS_AWAYSYS_SETSTATUSMODE MS_SA_SETSTATUSMODE // for compatibility with some plugins + +// Brings up the status message dialog +// wParam = 0 +// lParam = (LPARAM)(char *)protocol name, NULL if for all protocols +#define MS_SA_SHOWSTATUSMSGDIALOG "SimpleAway/ShowStatusMessageDialog" + +// Similar to the service above, for internal use only +#define MS_SA_TTCHANGESTATUSMSG "SimpleAway/TTChangeStatusMessage" + +// Force a change of status mode/message. The status message dialog will appear, +// depending on the configuration of the user +// wParam = (int)new status +// lParam = (LPARAM)(char *)protocol name, NULL if for all protocols +// Returns 1 when changed without showing the status message dialog +#define MS_SA_CHANGESTATUSMSG "SimpleAway/ChangeStatusMessage" + +// For checking if SimpleAway is running +// wParam = lParam = 0 +// Always returns 1 +#define MS_SA_ISSARUNNING "SimpleAway/IsSARunning" + +// Copy the away/na/etc message of a contact +// wParam = (WPARAM)(HANDLE)hContact +// lParam = 0 +// Returns 0 on success or nonzero on failure +// Returns immediately, without waiting for the message to retrieve +#define MS_SA_COPYAWAYMSG "SimpleAway/CopyAwayMsg" + +// Go to URL in away/na/etc message of a contact +// wParam = (WPARAM)(HANDLE)hContact +// lParam = 0 +#define MS_SA_GOTOURLMSG "SimpleAway/GoToURLMsg" + +// Returns the default status message for a status in specified protocol module +// or the current status message for the specified protocol if 0 or ID_STATUS_CURRENT is used +// wParam = (int)status, 0 or ID_STATUS_CURRENT for current +// lParam = (LPARAM)(char *)protocol name, NULL if for all protocols +// Returns status msg. Remember to free the return value +#ifndef MS_AWAYMSG_GETSTATUSMSG + #define MS_AWAYMSG_GETSTATUSMSG "SRAway/GetStatusMessage" +#endif +#ifndef MS_AWAYMSG_GETSTATUSMSGW + #define MS_AWAYMSG_GETSTATUSMSGW "SRAway/GetStatusMessageW" +#endif + +#ifndef MS_AWAYMSG_GETSTATUSMSGT + #ifdef _UNICODE + #define MS_AWAYMSG_GETSTATUSMSGT MS_AWAYMSG_GETSTATUSMSGW + #else + #define MS_AWAYMSG_GETSTATUSMSGT MS_AWAYMSG_GETSTATUSMSG + #endif +#endif + +// Force a change to specified global status mode/message +// (calls MS_SA_CHANGESTATUSMSG with proper parameters) +// wParam = lParam = 0 +#define MS_SA_SETOFFLINESTATUS "SimpleAway/SetOfflineStatus" +#define MS_SA_SETONLINESTATUS "SimpleAway/SetOnlineStatus" +#define MS_SA_SETAWAYSTATUS "SimpleAway/SetAwayStatus" +#define MS_SA_SETDNDSTATUS "SimpleAway/SetDNDStatus" +#define MS_SA_SETNASTATUS "SimpleAway/SetNAStatus" +#define MS_SA_SETOCCUPIEDSTATUS "SimpleAway/SetOccupiedStatus" +#define MS_SA_SETFREECHATSTATUS "SimpleAway/SetFreeChatStatus" +#define MS_SA_SETINVISIBLESTATUS "SimpleAway/SetInvisibleStatus" +#define MS_SA_SETONTHEPHONESTATUS "SimpleAway/SetOnThePhoneStatus" +#define MS_SA_SETOUTTOLUNCHSTATUS "SimpleAway/SetOutToLunchStatus" + +#endif // M_SIMPLEAWAY_H__ diff --git a/plugins/SimpleStatusMsg/main.cpp b/plugins/SimpleStatusMsg/main.cpp new file mode 100644 index 0000000000..63a9aebcfc --- /dev/null +++ b/plugins/SimpleStatusMsg/main.cpp @@ -0,0 +1,2269 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "commonheaders.h" +#include "simplestatusmsg.h" +#include + +HINSTANCE g_hInst; +PLUGINLINK *pluginLink; +int hLangpack; +struct MM_INTERFACE mmi; +PROTOACCOUNTS *accounts; + +static int g_iIdleTime = -1; +UINT_PTR g_uUpdateMsgTimer = 0, *g_uSetStatusTimer; +static TCHAR *g_ptszWinampSong; +HANDLE hTTBButton = 0, h_statusmodechange; +HWND hwndSAMsgDialog; +static HANDLE *hProtoStatusMenuItem; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), +#if defined(_WIN64) + "Simple Status Message (x64)", +#elif defined(_UNICODE) + "Simple Status Message (Unicode)", +#else + "Simple Status Message (ANSI)", +#endif + PLUGIN_MAKE_VERSION(1, 9, 0, 4), + "Provides a simple way to set status and away messages", + "Bartosz 'Dezeath' Białek, Harven", + "dezred"/*antispam*/"@"/*antispam*/"gmail"/*antispam*/"."/*antispam*/"com", + "© 2006-2011 Bartosz Białek, © 2005 Harven", + "http://code.google.com/p/dezeath", + UNICODE_AWARE, + DEFMOD_SRAWAY, +#ifdef _UNICODE + // {768CE156-34AC-45a3-B53B-0083C47615C4} + { 0x768ce156, 0x34ac, 0x45a3, { 0xb5, 0x3b, 0x0, 0x83, 0xc4, 0x76, 0x15, 0xc4 } } +#else + // {7D548A69-05E7-4d00-89BC-ACCE781022C1} + { 0x7d548a69, 0x5e7, 0x4d00, { 0x89, 0xbc, 0xac, 0xce, 0x78, 0x10, 0x22, 0xc1 } } +#endif +}; + +static const MUUID interfaces[] = {MIID_SRAWAY, MIID_LAST}; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + g_hInst = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 9, 0, 0)) + { + MessageBox(NULL, _T("The Simple Status Message plugin cannot be loaded. It requires Miranda IM 0.9.0 or later."), _T("Simple Status Message Plugin"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); + return NULL; + } + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +#ifdef _DEBUG +void log2file(const char *fmt, ...) +{ + DWORD dwBytesWritten; + va_list va; + char szText[1024]; + HANDLE hFile = CreateFileA("simplestatusmsg.log", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + SetFilePointer(hFile, 0, 0, FILE_END); + + strncpy(szText, "[\0", SIZEOF(szText)); + WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL); + + GetTimeFormatA(LOCALE_USER_DEFAULT, 0, NULL, NULL, szText, SIZEOF(szText)); + WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL); + + strncpy(szText, "] \0", SIZEOF(szText)); + + va_start(va, fmt); + mir_vsnprintf(szText + strlen(szText), SIZEOF(szText) - strlen(szText), fmt, va); + va_end(va); + + WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL); + + strncpy(szText, "\n\0", SIZEOF(szText)); + WriteFile(hFile, szText, (DWORD)strlen(szText), &dwBytesWritten, NULL); + + CloseHandle(hFile); +} +#endif + +static TCHAR *GetWinampSong(void) +{ + TCHAR *szTitle, *pstr, *res = NULL; + HWND hwndWinamp = FindWindow(_T("STUDIO"), NULL); + int iTitleLen; + + if (hwndWinamp == NULL) + hwndWinamp = FindWindow(_T("Winamp v1.x"), NULL); + + if (hwndWinamp == NULL) + return NULL; + + iTitleLen = GetWindowTextLength(hwndWinamp); + szTitle = (TCHAR *)mir_alloc((iTitleLen + 1) * sizeof(TCHAR)); + if (szTitle == NULL) + return NULL; + + if (GetWindowText(hwndWinamp, szTitle, iTitleLen + 1) == 0) + { + mir_free(szTitle); + return NULL; + } + + pstr = _tcsstr(szTitle, _T(" - Winamp")); + if (pstr == NULL) + { + mir_free(szTitle); + return NULL; + } + + if (pstr < szTitle + (iTitleLen / 2)) + { + MoveMemory(szTitle, pstr + 9, _tcslen(pstr + 9) * sizeof(TCHAR)); + pstr = _tcsstr(pstr + 1, _T(" - Winamp")); + if (pstr == NULL) + { + mir_free(szTitle); + return NULL; + } + } + *pstr = 0; + + pstr = _tcschr(szTitle, _T('.')); + if (pstr == NULL) + { + mir_free(szTitle); + return NULL; + } + + pstr += 2; + res = mir_tstrdup(pstr); + mir_free(szTitle); + + return res; +} + +TCHAR *InsertBuiltinVarsIntoMsg(TCHAR *in, const char *szProto, int status) +{ + int i, count = 0, len; + TCHAR substituteStr[1024], *msg = mir_tstrdup(in); + + for (i = 0; msg[i]; i++) + { + if (msg[i] == 0x0D && DBGetContactSettingByte(NULL, "SimpleStatusMsg", "RemoveCR", 0)) + { + TCHAR *p = msg + i; + if (i + 1 <= 1024 && msg[i + 1]) + { + if (msg[i + 1] == 0x0A) + { + if (i + 2 <= 1024 && msg[i + 2]) + { + count++; + MoveMemory(p, p + 1, (lstrlen(p) - 1) * sizeof(TCHAR)); + } + else + { + msg[i + 1] = 0; + msg[i] = 0x0A; + } + } + } + } + + if (msg[i] != '%') + continue; + + if (!_tcsnicmp(msg+i, _T("%winampsong%"), 12)) + { + TCHAR *ptszWinampTitle = GetWinampSong(); + + if (ptszWinampTitle != NULL) + { + mir_free(g_ptszWinampSong); + g_ptszWinampSong = mir_tstrdup(ptszWinampTitle); + } + else if (g_ptszWinampSong && lstrcmp(g_ptszWinampSong, _T("SimpleStatusMsg")) + && DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AmpLeaveTitle", 1)) + { + ptszWinampTitle = mir_tstrdup(g_ptszWinampSong); + } + else + continue; + + if (lstrlen(ptszWinampTitle) > 12) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(ptszWinampTitle) - 12) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(ptszWinampTitle), msg + i + 12, (lstrlen(msg) - i - 11) * sizeof(TCHAR)); + CopyMemory(msg + i, ptszWinampTitle, lstrlen(ptszWinampTitle) * sizeof(TCHAR)); + + mir_free(ptszWinampTitle); + } + else if (!_tcsnicmp(msg+i, _T("%fortunemsg%"), 12)) + { + TCHAR *FortuneMsg; +#ifdef _UNICODE + char *FortuneMsgA; +#endif + + if (!ServiceExists(MS_FORTUNEMSG_GETMESSAGE)) + continue; + +#ifdef _UNICODE + FortuneMsgA = (char*)CallService(MS_FORTUNEMSG_GETMESSAGE, 0, 0); + FortuneMsg = mir_a2u(FortuneMsgA); +#else + FortuneMsg = (char*)CallService(MS_FORTUNEMSG_GETMESSAGE, 0, 0); +#endif + + if (lstrlen(FortuneMsg) > 12) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(FortuneMsg) - 12) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(FortuneMsg), msg + i + 12, (lstrlen(msg) - i - 11) * sizeof(TCHAR)); + CopyMemory(msg + i, FortuneMsg, lstrlen(FortuneMsg) * sizeof(TCHAR)); + +#ifdef _UNICODE + mir_free(FortuneMsg); + CallService(MS_FORTUNEMSG_FREEMEMORY, 0, (LPARAM)FortuneMsgA); +#else + CallService(MS_FORTUNEMSG_FREEMEMORY, 0, (LPARAM)FortuneMsg); +#endif + } + else if (!_tcsnicmp(msg+i, _T("%protofortunemsg%"), 17)) + { + TCHAR *FortuneMsg; +#ifdef _UNICODE + char *FortuneMsgA; +#endif + + if (!ServiceExists(MS_FORTUNEMSG_GETPROTOMSG)) + continue; + +#ifdef _UNICODE + FortuneMsgA = (char*)CallService(MS_FORTUNEMSG_GETPROTOMSG, (WPARAM)szProto, 0); + FortuneMsg = mir_a2u(FortuneMsgA); +#else + FortuneMsg = (char*)CallService(MS_FORTUNEMSG_GETPROTOMSG, (WPARAM)szProto, 0); +#endif + + if (lstrlen(FortuneMsg) > 17) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(FortuneMsg) - 17) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(FortuneMsg), msg + i + 17, (lstrlen(msg) - i - 16) * sizeof(TCHAR)); + CopyMemory(msg + i, FortuneMsg, lstrlen(FortuneMsg) * sizeof(TCHAR)); + +#ifdef _UNICODE + mir_free(FortuneMsg); + CallService(MS_FORTUNEMSG_FREEMEMORY, 0, (LPARAM)FortuneMsgA); +#else + CallService(MS_FORTUNEMSG_FREEMEMORY, 0, (LPARAM)FortuneMsg); +#endif + } + else if (!_tcsnicmp(msg+i, _T("%statusfortunemsg%"), 18)) + { + TCHAR *FortuneMsg; +#ifdef _UNICODE + char *FortuneMsgA; +#endif + + if (!ServiceExists(MS_FORTUNEMSG_GETSTATUSMSG)) + continue; + +#ifdef _UNICODE + FortuneMsgA = (char*)CallService(MS_FORTUNEMSG_GETSTATUSMSG, (WPARAM)status, 0); + FortuneMsg = mir_a2u(FortuneMsgA); +#else + FortuneMsg = (char*)CallService(MS_FORTUNEMSG_GETSTATUSMSG, (WPARAM)status, 0); +#endif + + if (lstrlen(FortuneMsg) > 18) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(FortuneMsg) - 18) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(FortuneMsg), msg + i + 18, (lstrlen(msg) - i - 17) * sizeof(TCHAR)); + CopyMemory(msg + i, FortuneMsg, lstrlen(FortuneMsg) * sizeof(TCHAR)); + +#ifdef _UNICODE + mir_free(FortuneMsg); + CallService(MS_FORTUNEMSG_FREEMEMORY, 0, (LPARAM)FortuneMsgA); +#else + CallService(MS_FORTUNEMSG_FREEMEMORY, 0, (LPARAM)FortuneMsg); +#endif + } + else if (!_tcsnicmp(msg + i, _T("%time%"), 6)) + { + MIRANDA_IDLE_INFO mii = {0}; + mii.cbSize = sizeof(mii); + CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii); + + if (mii.idleType) + { + int mm; + SYSTEMTIME t; + GetLocalTime(&t); + if ((mm = g_iIdleTime) == -1) + { + mm = t.wMinute + t.wHour * 60; + if (mii.idleType == 1) + { + mm -= mii.idleTime; + if (mm < 0) mm += 60 * 24; + } + g_iIdleTime = mm; + } + t.wMinute = mm % 60; + t.wHour = mm / 60; + GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &t, NULL, substituteStr, SIZEOF(substituteStr)); + } + else GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL, NULL, substituteStr, SIZEOF(substituteStr)); + + if (lstrlen(substituteStr) > 6) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(substituteStr) - 6) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(substituteStr), msg + i + 6, (lstrlen(msg) - i - 5) * sizeof(TCHAR)); + CopyMemory(msg + i, substituteStr, lstrlen(substituteStr) * sizeof(TCHAR)); + } + else if (!_tcsnicmp(msg + i, _T("%date%"), 6)) + { + GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, substituteStr, SIZEOF(substituteStr)); + + if (lstrlen(substituteStr) > 6) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(substituteStr) - 6) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(substituteStr), msg + i + 6, (lstrlen(msg) - i - 5) * sizeof(TCHAR)); + CopyMemory(msg + i, substituteStr, lstrlen(substituteStr) * sizeof(TCHAR)); + } + else if (!_tcsnicmp(msg+i, _T("%rand("), 6)) + { + TCHAR *temp, *token; + int ran_from, ran_to, k; + + temp = mir_tstrdup(msg + i + 6); + token = _tcstok(temp, _T(",)")); + ran_from = _ttoi(token); + token = _tcstok(NULL, _T(",)%%")); + ran_to = _ttoi(token); + + if (ran_to > ran_from) + { + mir_sntprintf(substituteStr, SIZEOF(substituteStr), _T("%d"), GetRandom(ran_from, ran_to)); + for (k = i + 1; msg[k]; k++) if (msg[k] == '%') { k++; break; } + + if (lstrlen(substituteStr) > k - i) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(substituteStr) - (k - i)) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(substituteStr), msg + i + (k - i), (lstrlen(msg) - i - (k - i - 1)) * sizeof(TCHAR)); + CopyMemory(msg + i, substituteStr, lstrlen(substituteStr) * sizeof(TCHAR)); + } + mir_free(temp); + } + else if (!_tcsnicmp(msg+i, _T("%randmsg%"), 9)) + { + char buff[16]; + int k, maxk, k2 = 0; + DBVARIANT dbv; + BOOL rmark[25]; + + for (k = 0; k < 26; k++) rmark[k] = FALSE; + maxk = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "MaxHist", 10); + if (maxk == 0) rmark[0] = TRUE; + + while (!rmark[0]) + { + k = GetRandom(1, maxk); + if (rmark[k]) continue; + rmark[k] = TRUE; + k2++; + if (k2 == maxk || k2 > maxk) rmark[0] = TRUE; + + mir_snprintf(buff, SIZEOF(buff), "SMsg%d", k); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", buff, &dbv)) + { + if (dbv.ptszVal == NULL) + { + DBFreeVariant(&dbv); + continue; + } + lstrcpy(substituteStr, dbv.ptszVal); + DBFreeVariant(&dbv); + } + else continue; + + if (!lstrlen(substituteStr)) continue; + if (_tcsstr(substituteStr, _T("%randmsg%")) != NULL || _tcsstr(substituteStr, _T("%randdefmsg%")) != NULL) + { + if (k == maxk) maxk--; + } + else rmark[0] = TRUE; + } + + if (k2 == maxk || k2 > maxk) lstrcpy(substituteStr, _T("")); + + if (lstrlen(substituteStr) > 9) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg) + 1 + lstrlen(substituteStr) - 9) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(substituteStr), msg + i + 9, (lstrlen(msg) - i - 8) * sizeof(TCHAR)); + CopyMemory(msg + i, substituteStr, lstrlen(substituteStr) * sizeof(TCHAR)); + } + else if (!_tcsnicmp(msg+i, _T("%randdefmsg%"), 12)) + { + char buff[16]; + int k, maxk, k2 = 0; + DBVARIANT dbv; + BOOL rmark[25]; + + for (k = 0; k < 26; k++) rmark[k] = FALSE; + maxk = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "DefMsgCount", 0); + if (maxk == 0) rmark[0] = TRUE; + + while (!rmark[0]) + { + k = GetRandom(1, maxk); + if (rmark[k]) continue; + rmark[k] = TRUE; + k2++; + if (k2 == maxk || k2 > maxk) rmark[0] = TRUE; + + mir_snprintf(buff, SIZEOF(buff), "DefMsg%d", k); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", buff, &dbv)) + { + if (dbv.ptszVal == NULL) + { + DBFreeVariant(&dbv); + continue; + } + lstrcpy(substituteStr, dbv.ptszVal); + DBFreeVariant(&dbv); + } + else continue; + + if (!lstrlen(substituteStr)) continue; + if (_tcsstr(substituteStr, _T("%randmsg%")) != NULL || _tcsstr(substituteStr, _T("%randdefmsg%")) != NULL) + { + if (k == maxk) maxk--; + } + else rmark[0] = TRUE; + } + + if (k2 == maxk || k2 > maxk) lstrcpy(substituteStr, _T("")); + + if (lstrlen(substituteStr) > 12) + msg = (TCHAR *)mir_realloc(msg, (lstrlen(msg)+1+lstrlen(substituteStr)-12) * sizeof(TCHAR)); + + MoveMemory(msg + i + lstrlen(substituteStr), msg + i + 12, (lstrlen(msg) - i - 11) * sizeof(TCHAR)); + CopyMemory(msg + i, substituteStr, lstrlen(substituteStr) * sizeof(TCHAR)); + } + } + + if (count) msg[lstrlen(msg) - count] = 0; + + if (szProto) + { + char szSetting[80]; + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sMaxLen", szProto); + len = DBGetContactSettingWord(NULL, "SimpleStatusMsg", szSetting, 1024); + if (len < lstrlen(msg)) + { + msg = (TCHAR *)mir_realloc(msg, len * sizeof(TCHAR)); + msg[len] = 0; + } + } + + return msg; +} + +TCHAR *InsertVarsIntoMsg(TCHAR *tszMsg, const char *szProto, int iStatus, HANDLE hContact) +{ + if (ServiceExists(MS_VARS_FORMATSTRING) && DBGetContactSettingByte(NULL, "SimpleStatusMsg", "EnableVariables", 1)) + { + FORMATINFO fInfo = {0}; + fInfo.cbSize = sizeof(fInfo); + fInfo.flags = FIF_TCHAR; + fInfo.tszFormat = tszMsg; + fInfo.hContact = hContact; + TCHAR *tszVarsMsg = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fInfo, 0); + if (tszVarsMsg != NULL) + { + TCHAR *format = InsertBuiltinVarsIntoMsg(tszVarsMsg, szProto, iStatus); + CallService(MS_VARS_FREEMEMORY, (WPARAM)tszVarsMsg, 0); + return format; + } + } + + return InsertBuiltinVarsIntoMsg(tszMsg, szProto, iStatus); +} + +static TCHAR *GetAwayMessageFormat(int iStatus, const char *szProto) +{ + DBVARIANT dbv, dbv2; + int flags; + char szSetting[80]; + TCHAR *format; + + mir_snprintf(szSetting, SIZEOF(szSetting), "%sFlags", szProto ? szProto : ""); + flags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", (char *)StatusModeToDbSetting(iStatus, szSetting), STATUS_DEFAULT); + + if (flags & STATUS_EMPTY_MSG) + return mir_tstrdup(_T("")); + + if (flags & STATUS_LAST_STATUS_MSG) + { + if (szProto) + mir_snprintf(szSetting, SIZEOF(szSetting), "%sMsg", szProto); + else + mir_snprintf(szSetting, SIZEOF(szSetting), "Msg"); + + if (DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, szSetting), &dbv)) + return NULL; //mir_tstrdup(_T("")); + + format = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + else if (flags & STATUS_LAST_MSG) + { + if (szProto) + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sMsg", szProto); + else + mir_snprintf(szSetting, SIZEOF(szSetting), "LastMsg"); + + if (DBGetContactSetting(NULL, "SimpleStatusMsg", szSetting, &dbv2)) + return NULL; //mir_tstrdup(_T("")); + + if (DBGetContactSettingTString(NULL, "SimpleStatusMsg", dbv2.pszVal, &dbv)) + { + DBFreeVariant(&dbv2); + return NULL; //mir_tstrdup(_T("")); + } + + format = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + DBFreeVariant(&dbv2); + } + else if (flags & STATUS_THIS_MSG) + { + if (szProto) + mir_snprintf(szSetting, SIZEOF(szSetting), "%sDefault", szProto); + else + mir_snprintf(szSetting, SIZEOF(szSetting), "Default"); + + if (DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, szSetting), &dbv)) + return mir_tstrdup(_T("")); + + format = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + format = mir_tstrdup(GetDefaultMessage(iStatus)); + + return format; +} + +void DBWriteMessage(char *szSetting, TCHAR *tszMsg) +{ + if (tszMsg && lstrlen(tszMsg)) + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", szSetting, tszMsg); + else + DBDeleteContactSetting(NULL, "SimpleStatusMsg", szSetting); +} + +void SaveMessageToDB(const char *szProto, TCHAR *tszMsg, BOOL bIsFormat) +{ + char szSetting[80]; + + if (!szProto) + { + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), bIsFormat ? "FCur%sMsg" : "Cur%sMsg", accounts->pa[i]->szModuleName); + DBWriteMessage(szSetting, tszMsg); +#ifdef _DEBUG + if (bIsFormat) + log2file("SaveMessageToDB(): Set \"" TCHAR_STR_PARAM "\" status message (without inserted vars) for %s.", tszMsg, accounts->pa[i]->szModuleName); + else + log2file("SaveMessageToDB(): Set \"" TCHAR_STR_PARAM "\" status message for %s.", tszMsg, accounts->pa[i]->szModuleName); +#endif + } + } + else + { + if (!(CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + return; + + mir_snprintf(szSetting, SIZEOF(szSetting), bIsFormat ? "FCur%sMsg" : "Cur%sMsg", szProto); + DBWriteMessage(szSetting, tszMsg); +#ifdef _DEBUG + if (bIsFormat) + log2file("SaveMessageToDB(): Set \"" TCHAR_STR_PARAM "\" status message (without inserted vars) for %s.", tszMsg, szProto); + else + log2file("SaveMessageToDB(): Set \"" TCHAR_STR_PARAM "\" status message for %s.", tszMsg, szProto); +#endif + } +} + +void SaveStatusAsCurrent(const char *szProto, int iStatus) +{ + char szSetting[80]; + mir_snprintf(szSetting, SIZEOF(szSetting), "Cur%sStatus", szProto); + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", szSetting, (WORD)iStatus); +} + +static TCHAR *GetAwayMessage(int iStatus, const char *szProto, BOOL bInsertVars, HANDLE hContact) +{ + TCHAR *format = NULL; + char szSetting[80]; + + if ((!iStatus || iStatus == ID_STATUS_CURRENT) && szProto) + { + DBVARIANT dbv; + mir_snprintf(szSetting, SIZEOF(szSetting), "FCur%sMsg", szProto); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + format = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + //else + // format = mir_tstrdup(_T("")); + } + else + { + int flags; + + if (!iStatus || iStatus == ID_STATUS_CURRENT) + iStatus = GetCurrentStatus(szProto); + + if (szProto && !(CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iStatus))) + return NULL; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sFlags", szProto ? szProto : ""); + flags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", szSetting, PROTO_DEFAULT); + + //if (flags & PROTO_NO_MSG) + //{ + // format = mir_tstrdup(_T("")); + //} + //else + if (flags & PROTO_THIS_MSG) + { + DBVARIANT dbv; + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sDefault", szProto); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + format = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + format = mir_tstrdup(_T("")); + } + else if (flags & PROTO_NOCHANGE && szProto) + { + DBVARIANT dbv; + mir_snprintf(szSetting, SIZEOF(szSetting), "FCur%sMsg", szProto); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + format = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + //else + // format = mir_tstrdup(_T("")); + } + else if (flags & PROTO_POPUPDLG) + format = GetAwayMessageFormat(iStatus, szProto); + } +#ifdef _DEBUG + log2file("GetAwayMessage(): %s has %s status and \"" TCHAR_STR_PARAM "\" status message.", szProto, StatusModeToDbSetting(iStatus, ""), format); +#endif + + if (bInsertVars && format != NULL) + { + TCHAR *tszVarsMsg = InsertVarsIntoMsg(format, szProto, iStatus, hContact); // TODO random values not the same! + mir_free(format); + return tszVarsMsg; + } + + return format; +} + +int CheckProtoSettings(const char *szProto, int iInitialStatus) +{ + int iSetting = DBGetContactSettingWord(NULL, szProto, "LeaveStatus", -1); //GG settings + if (iSetting != -1) + return iSetting ? iSetting : iInitialStatus; + iSetting = DBGetContactSettingWord(NULL, szProto, "OfflineMessageOption", -1); //TLEN settings + if (iSetting != -1) + { + switch (iSetting) + { + case 1: return ID_STATUS_ONLINE; + case 2: return ID_STATUS_AWAY; + case 3: return ID_STATUS_NA; + case 4: return ID_STATUS_DND; + case 5: return ID_STATUS_FREECHAT; + case 6: return ID_STATUS_INVISIBLE; + default: return iInitialStatus; + } + } + return iInitialStatus; +} + +static void Proto_SetAwayMsgT(const char *szProto, int iStatus, TCHAR *tszMsg) +{ + if (!(CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_INDIVMODEMSG)) + { +#ifdef _UNICODE + if (CallProtoService(szProto, PS_SETAWAYMSGW, (WPARAM)iStatus, (LPARAM)tszMsg) == CALLSERVICE_NOTFOUND) + { + char *szMsg = mir_u2a(tszMsg); + CallProtoService(szProto, PS_SETAWAYMSG, (WPARAM)iStatus, (LPARAM)szMsg); + mir_free(szMsg); + } +#else + CallProtoService(szProto, PS_SETAWAYMSG, (WPARAM)iStatus, (LPARAM)tszMsg); +#endif + } +} + +static void Proto_SetStatus(const char *szProto, int iInitialStatus, int iStatus, TCHAR *tszMsg) +{ + if (iStatus == ID_STATUS_OFFLINE && iStatus != iInitialStatus) + { + // ugly hack to set offline status message + if (!(CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_INDIVMODEMSG)) + { + int iMsgStatus = CheckProtoSettings(szProto, iInitialStatus); +#ifdef _UNICODE + if (CallProtoService(szProto, PS_SETAWAYMSGW, (WPARAM)iMsgStatus, (LPARAM)tszMsg) == CALLSERVICE_NOTFOUND) + { + char *szMsg = mir_u2a(tszMsg); + CallProtoService(szProto, PS_SETAWAYMSG, (WPARAM)iMsgStatus, (LPARAM)szMsg); + mir_free(szMsg); + } +#else + CallProtoService(szProto, PS_SETAWAYMSG, (WPARAM)iMsgStatus, (LPARAM)tszMsg); +#endif + CallProtoService(szProto, PS_SETSTATUS, (WPARAM)iMsgStatus, 0); + } + if (ServiceExists(MS_KS_ANNOUNCESTATUSCHANGE)) + announce_status_change((char*)szProto, ID_STATUS_OFFLINE, NULL); + CallProtoService(szProto, PS_SETSTATUS, ID_STATUS_OFFLINE, 0); + return; + } + + Proto_SetAwayMsgT(szProto, iStatus, tszMsg /* ? tszMsg : _T("")*/); + if (iStatus != iInitialStatus) + CallProtoService(szProto, PS_SETSTATUS, iStatus, 0); +} + +int HasProtoStaticStatusMsg(const char *szProto, int iInitialStatus, int iStatus) +{ + char szSetting[80]; + int flags; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sFlags", szProto); + flags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", szSetting, PROTO_DEFAULT); + + if (flags & PROTO_NO_MSG) + { + Proto_SetStatus(szProto, iInitialStatus, iStatus, NULL); + SaveMessageToDB(szProto, NULL, TRUE); + SaveMessageToDB(szProto, NULL, FALSE); + return 1; + } + else if (flags & PROTO_THIS_MSG) + { + DBVARIANT dbv; + TCHAR *msg; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sDefault", szProto); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + SaveMessageToDB(szProto, dbv.ptszVal, TRUE); + msg = InsertVarsIntoMsg(dbv.ptszVal, szProto, iStatus, NULL); + DBFreeVariant(&dbv); + Proto_SetStatus(szProto, iInitialStatus, iStatus, msg); + SaveMessageToDB(szProto, msg, FALSE); + mir_free(msg); + } + else + { + Proto_SetStatus(szProto, iInitialStatus, iStatus, _T("")); + SaveMessageToDB(szProto, _T(""), TRUE); + SaveMessageToDB(szProto, _T(""), FALSE); + } + return 1; + } + return 0; +} + +INT_PTR SetStatusModeFromExtern(WPARAM wParam, LPARAM lParam) +{ + if ((wParam < ID_STATUS_OFFLINE && wParam != 0) || (wParam > ID_STATUS_OUTTOLUNCH && wParam != ID_STATUS_CURRENT)) + return 0; + + int newStatus = (int)wParam; + + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) &~ CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + if (DBGetContactSettingByte(NULL, accounts->pa[i]->szModuleName, "LockMainStatus", 0)) + continue; + + if (wParam == ID_STATUS_CURRENT || wParam == 0) + newStatus = GetCurrentStatus(accounts->pa[i]->szModuleName); + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + { + CallProtoService(accounts->pa[i]->szModuleName, PS_SETSTATUS, newStatus, 0); + continue; + } + + int status_modes_msg = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + + if ((Proto_Status2Flag(newStatus) & status_modes_msg) || (newStatus == ID_STATUS_OFFLINE && (Proto_Status2Flag(ID_STATUS_INVISIBLE) & status_modes_msg))) + { + TCHAR *msg = NULL; + + if (HasProtoStaticStatusMsg(accounts->pa[i]->szModuleName, GetCurrentStatus(accounts->pa[i]->szModuleName), newStatus)) + continue; + + if (lParam) + msg = InsertVarsIntoMsg((TCHAR *)lParam, accounts->pa[i]->szModuleName, newStatus, NULL); + + SaveMessageToDB(accounts->pa[i]->szModuleName, (TCHAR *)lParam, TRUE); + SaveMessageToDB(accounts->pa[i]->szModuleName, msg, FALSE); + Proto_SetStatus(accounts->pa[i]->szModuleName, GetCurrentStatus(accounts->pa[i]->szModuleName), newStatus, msg /*? msg : _T("")*/); + mir_free(msg); + } + else + CallProtoService(accounts->pa[i]->szModuleName, PS_SETSTATUS, newStatus, 0); + } + + return 0; +} + +int ChangeStatusMessage(WPARAM wParam, LPARAM lParam); + +void SetStatusMessage(const char *szProto, int iInitialStatus, int iStatus, TCHAR *message, BOOL bOnStartup) +{ + TCHAR *msg = NULL; +#ifdef _DEBUG + log2file("SetStatusMessage(\"%s\", %d, %d, \"" TCHAR_STR_PARAM "\", %d)", szProto, iInitialStatus, iStatus, message, bOnStartup); +#endif + if (szProto) + { + if (bOnStartup && accounts->statusCount > 1) // TODO not only at startup? + { + int status; + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + status = iStatus == ID_STATUS_CURRENT ? GetStartupStatus(accounts->pa[i]->szModuleName) : iStatus; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) || + !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + { + if (!(bOnStartup && status == ID_STATUS_OFFLINE) && GetCurrentStatus(accounts->pa[i]->szModuleName) != status) + CallProtoService(accounts->pa[i]->szModuleName, PS_SETSTATUS, (WPARAM)status, 0); + } + } + } + + if (message) + msg = InsertVarsIntoMsg(message, szProto, iStatus, NULL); + + SaveMessageToDB(szProto, message, TRUE); + SaveMessageToDB(szProto, msg, FALSE); + + if (iInitialStatus == ID_STATUS_CURRENT) + iInitialStatus = bOnStartup ? ID_STATUS_OFFLINE : GetCurrentStatus(szProto); + + Proto_SetStatus(szProto, iInitialStatus, iStatus, msg); + mir_free(msg); + } + else + { + int iProfileStatus = iStatus > ID_STATUS_CURRENT ? iStatus : 0; + BOOL bIsStatusCurrent = iStatus == ID_STATUS_CURRENT; + BOOL bIsInitialStatusCurrent = iInitialStatus == ID_STATUS_CURRENT; + + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + if (!bOnStartup && DBGetContactSettingByte(NULL, accounts->pa[i]->szModuleName, "LockMainStatus", 0)) + continue; + + if (iProfileStatus) + { + int iProfileNumber = iStatus - 40083; + char szSetting[128]; + mir_snprintf(szSetting, SIZEOF(szSetting), "%d_%s", iProfileNumber, accounts->pa[i]->szModuleName); + iStatus = DBGetContactSettingWord(NULL, "StartupStatus", szSetting, ID_STATUS_OFFLINE); + if (iStatus == ID_STATUS_IDLE) // the same as ID_STATUS_LAST in StartupStatus + { + mir_snprintf(szSetting, SIZEOF(szSetting), "last_%s", accounts->pa[i]->szModuleName); + iStatus = DBGetContactSettingWord(NULL, "StartupStatus", szSetting, ID_STATUS_OFFLINE); + } + else if (iStatus == ID_STATUS_CURRENT) + iStatus = GetCurrentStatus(accounts->pa[i]->szModuleName); + } + + if (bIsStatusCurrent) + iStatus = bOnStartup ? GetStartupStatus(accounts->pa[i]->szModuleName) : GetCurrentStatus(accounts->pa[i]->szModuleName); + + if (bIsInitialStatusCurrent) + iInitialStatus = bOnStartup ? ID_STATUS_OFFLINE : GetCurrentStatus(accounts->pa[i]->szModuleName); + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iStatus)) || + !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + { + if (!(bOnStartup && iStatus == ID_STATUS_OFFLINE) && GetCurrentStatus(accounts->pa[i]->szModuleName) != iStatus && iStatus != iInitialStatus) + { + CallProtoService(accounts->pa[i]->szModuleName, PS_SETSTATUS, (WPARAM)iStatus, 0); +#ifdef _DEBUG + log2file("SetStatusMessage(): Set %s status for %s.", StatusModeToDbSetting(iStatus, ""), accounts->pa[i]->szModuleName); +#endif + } + continue; + } + + if (HasProtoStaticStatusMsg(accounts->pa[i]->szModuleName, iInitialStatus, iStatus)) + continue; + + if (message) + msg = InsertVarsIntoMsg(message, accounts->pa[i]->szModuleName, iStatus, NULL); + + SaveMessageToDB(accounts->pa[i]->szModuleName, message, TRUE); + SaveMessageToDB(accounts->pa[i]->szModuleName, msg, FALSE); + + Proto_SetStatus(accounts->pa[i]->szModuleName, iInitialStatus, iStatus, msg); + mir_free(msg); + } + + if (GetCurrentStatus(NULL) != iStatus && !bIsStatusCurrent && !iProfileStatus) + { + // not so nice... + UnhookEvent(h_statusmodechange); + CallService(MS_CLIST_SETSTATUSMODE, (WPARAM)iStatus, 0); + h_statusmodechange = HookEvent(ME_CLIST_STATUSMODECHANGE, ChangeStatusMessage); + } + } +} + +INT_PTR ShowStatusMessageDialogInternal(WPARAM wParam, LPARAM lParam) +{ + struct MsgBoxInitData *box_data; + BOOL idvstatusmsg = FALSE; + + if (Miranda_Terminated()) return 0; + + if (hTTBButton) + { + CallService(MS_TTB_SETBUTTONSTATE, (WPARAM)hTTBButton, (LPARAM)TTBST_RELEASED); + CallService(MS_TTB_SETBUTTONOPTIONS, MAKEWPARAM((WORD)TTBO_TIPNAME, (WORD)hTTBButton), (LPARAM)Translate("Change Status Message")); + } + + box_data = (struct MsgBoxInitData *)mir_alloc(sizeof(struct MsgBoxInitData)); + + if (accounts->statusMsgCount == 1) + { + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + box_data->m_szProto = accounts->pa[i]->szModuleName; + box_data->m_iStatusModes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0); + box_data->m_iStatusMsgModes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + break; + } + } + else + { + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + if (!accounts->pa[i]->bIsVisible) + continue; + + if (hProtoStatusMenuItem[i] == (HANDLE)lParam) + { + box_data->m_szProto = accounts->pa[i]->szModuleName; + box_data->m_iStatusModes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0); + box_data->m_iStatusMsgModes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + + idvstatusmsg = TRUE; + break; + } + } + if (!idvstatusmsg) + { + box_data->m_szProto = NULL; + box_data->m_iStatusModes = accounts->statusFlags; + box_data->m_iStatusMsgModes = accounts->statusMsgFlags; + } + } + box_data->m_iStatus = ID_STATUS_CURRENT; + box_data->m_bOnEvent = FALSE; + box_data->m_bOnStartup = FALSE; + + if (hwndSAMsgDialog) + DestroyWindow(hwndSAMsgDialog); + hwndSAMsgDialog = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_AWAYMSGBOX), NULL, AwayMsgBoxDlgProc, (LPARAM)box_data); + return 0; +} + +INT_PTR ShowStatusMessageDialog(WPARAM wParam, LPARAM lParam) +{ + struct MsgBoxInitData *box_data; + BOOL idvstatusmsg = FALSE; + + if (Miranda_Terminated()) return 0; + + box_data = (struct MsgBoxInitData *)mir_alloc(sizeof(struct MsgBoxInitData)); + + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + if (!accounts->pa[i]->bIsVisible) + continue; + + if (!strcmp(accounts->pa[i]->szModuleName, (char *)lParam)) + { + box_data->m_szProto = accounts->pa[i]->szModuleName; + box_data->m_iStatusModes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0); + box_data->m_iStatusMsgModes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + + idvstatusmsg = TRUE; + break; + } + } + if (!idvstatusmsg) + { + box_data->m_szProto = NULL; + box_data->m_iStatusModes = accounts->statusFlags; + box_data->m_iStatusMsgModes = accounts->statusMsgFlags; + } + box_data->m_iStatus = ID_STATUS_CURRENT; + box_data->m_bOnEvent = FALSE; + box_data->m_bOnStartup = FALSE; + + if (hwndSAMsgDialog) + DestroyWindow(hwndSAMsgDialog); + hwndSAMsgDialog = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_AWAYMSGBOX), NULL, AwayMsgBoxDlgProc, (LPARAM)box_data); + + return 0; +} + +static int ChangeStatusMessage(WPARAM wParam, LPARAM lParam) +{ + int iStatus = (int)wParam; + char *szProto = (char*)lParam; + int iDlgFlags; + BOOL bShowDlg, bOnStartup = FALSE, bGlobalStartupStatus = TRUE, bScreenSaverRunning = FALSE; + char szSetting[80]; + + if (Miranda_Terminated()) return 0; + + // TODO this could be done better + if (szProto && !strcmp(szProto, "SimpleStatusMsgGlobalStartupStatus")) + { + szProto = NULL; + bOnStartup = TRUE; + } + + if (accounts->statusMsgCount == 1 && !szProto) + { + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + szProto = accounts->pa[i]->szModuleName; + if (bOnStartup && iStatus == ID_STATUS_CURRENT) + { + iStatus = GetStartupStatus(accounts->pa[i]->szModuleName); + bGlobalStartupStatus = FALSE; + } + break; + } + } + + mir_snprintf(szSetting, SIZEOF(szSetting), "%sFlags", szProto ? szProto : ""); + iDlgFlags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", (char *)StatusModeToDbSetting(iStatus, szSetting), STATUS_DEFAULT); + bShowDlg = iDlgFlags & STATUS_SHOW_DLG || bOnStartup; + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &bScreenSaverRunning, 0); + + if (szProto) + { + struct MsgBoxInitData *box_data; + int status_modes = 0, status_modes_msg = 0, iProtoFlags; + + status_modes = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_5, 0); + if (!(Proto_Status2Flag(iStatus) & status_modes) && iStatus != ID_STATUS_OFFLINE) + return 0; + + status_modes_msg = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_3, 0); + if (!(Proto_Status2Flag(iStatus) & status_modes_msg) || !(CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + { + if (bOnStartup && GetCurrentStatus(szProto) != iStatus) + { + CallProtoService(szProto, PS_SETSTATUS, iStatus, 0); +#ifdef _DEBUG + log2file("ChangeStatusMessage(): Set %s status for %s.", StatusModeToDbSetting(iStatus, ""), szProto); +#endif + } + return 0; + } + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sFlags", szProto); + iProtoFlags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", szSetting, PROTO_DEFAULT); + if (iProtoFlags & PROTO_NO_MSG || iProtoFlags & PROTO_THIS_MSG) + { + if (HasProtoStaticStatusMsg(szProto, iStatus, iStatus)) + return 1; + } + else if (iProtoFlags & PROTO_NOCHANGE && !bOnStartup) + { + DBVARIANT dbv; + TCHAR *msg = NULL; + + mir_snprintf(szSetting, SIZEOF(szSetting), "FCur%sMsg", szProto); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + msg = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + //else + // msg = mir_tstrdup(_T("")); +#ifdef _DEBUG + log2file("ChangeStatusMessage(): Set %s status and \"" TCHAR_STR_PARAM "\" status message for %s.", StatusModeToDbSetting(iStatus, ""), msg, szProto); +#endif + SetStatusMessage(szProto, iStatus, iStatus, msg, FALSE); + if (msg) mir_free(msg); + return 1; + } + + if (!bShowDlg || bScreenSaverRunning) + { + TCHAR *msg = GetAwayMessageFormat(iStatus, szProto); +#ifdef _DEBUG + log2file("ChangeStatusMessage(): Set %s status and \"" TCHAR_STR_PARAM "\" status message for %s.", StatusModeToDbSetting(iStatus, ""), msg, szProto); +#endif + SetStatusMessage(szProto, iStatus, iStatus, msg, FALSE); + if (msg) mir_free(msg); + return 1; + } + + box_data = (struct MsgBoxInitData *) mir_alloc(sizeof(struct MsgBoxInitData)); + box_data->m_szProto = szProto; + + if (!bOnStartup) + SaveStatusAsCurrent(szProto, iStatus); + + if (GetCurrentStatus(szProto) == iStatus || (bOnStartup && !bGlobalStartupStatus)) + box_data->m_iStatus = ID_STATUS_CURRENT; + else + box_data->m_iStatus = iStatus; + + box_data->m_iStatusModes = status_modes; + box_data->m_iStatusMsgModes = status_modes_msg; + box_data->m_bOnEvent = TRUE; + box_data->m_bOnStartup = bOnStartup; + + if (hwndSAMsgDialog) + DestroyWindow(hwndSAMsgDialog); + hwndSAMsgDialog = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_AWAYMSGBOX), NULL, AwayMsgBoxDlgProc, (LPARAM)box_data); + } + else + { + struct MsgBoxInitData *box_data; + int iProtoFlags; + + // iStatus == ID_STATUS_CURRENT only when bOnStartup == TRUE + if (iStatus == ID_STATUS_OFFLINE || (!(accounts->statusMsgFlags & Proto_Status2Flag(iStatus)) && iStatus != ID_STATUS_CURRENT)) + return 0; + + iProtoFlags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ProtoFlags", PROTO_DEFAULT); + if (!bShowDlg || bScreenSaverRunning || (iProtoFlags & PROTO_NOCHANGE && !bOnStartup)) + { + TCHAR *msg = NULL; + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + if (DBGetContactSettingByte(NULL, accounts->pa[i]->szModuleName, "LockMainStatus", 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(iStatus)) || + !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + if (iProtoFlags & PROTO_NOCHANGE) + { + DBVARIANT dbv; + mir_snprintf(szSetting, SIZEOF(szSetting), "FCur%sMsg", accounts->pa[i]->szModuleName); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + msg = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + //else + // msg = mir_tstrdup(_T("")); + } + else + msg = GetAwayMessageFormat(iStatus, NULL); +#ifdef _DEBUG + log2file("ChangeStatusMessage(): Set %s status and \"" TCHAR_STR_PARAM "\" status message for %s.", StatusModeToDbSetting(iStatus, ""), msg, accounts->pa[i]->szModuleName); +#endif + SetStatusMessage(accounts->pa[i]->szModuleName, iStatus, iStatus, msg, FALSE); + if (msg) { mir_free(msg); msg = NULL; } + } + return 1; + } + + box_data = (struct MsgBoxInitData *)mir_alloc(sizeof(struct MsgBoxInitData)); + box_data->m_szProto = NULL; + box_data->m_iStatus = iStatus; + box_data->m_iStatusModes = accounts->statusFlags; + box_data->m_iStatusMsgModes = accounts->statusMsgFlags; + box_data->m_bOnEvent = TRUE; + box_data->m_bOnStartup = bOnStartup; + + if (hwndSAMsgDialog) + DestroyWindow(hwndSAMsgDialog); + hwndSAMsgDialog = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_AWAYMSGBOX), NULL, AwayMsgBoxDlgProc, (LPARAM)box_data); + } + return 0; +} + +static INT_PTR ChangeStatusMsg(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage(wParam, lParam); + return 0; +} + +static INT_PTR SetOfflineStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_OFFLINE, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetOnlineStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_ONLINE, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetAwayStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_AWAY, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetDNDStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_DND, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetNAStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_NA, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetOccupiedStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_OCCUPIED, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetFreeChatStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_FREECHAT, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetInvisibleStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_INVISIBLE, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetOnThePhoneStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_ONTHEPHONE, (LPARAM)NULL); + return 0; +} + +static INT_PTR SetOutToLunchStatus(WPARAM wParam, LPARAM lParam) +{ + ChangeStatusMessage((WPARAM)ID_STATUS_OUTTOLUNCH, (LPARAM)NULL); + return 0; +} + +static int ProcessProtoAck(WPARAM wParam,LPARAM lParam) +{ + ACKDATA *ack = (ACKDATA *)lParam; + + if (!ack || !ack->szModule) + return 0; + + if (ack->type == ACKTYPE_AWAYMSG && ack->result == ACKRESULT_SENTREQUEST && !ack->lParam) + { + TCHAR *tszMsg = GetAwayMessage(CallProtoService((char *)ack->szModule, PS_GETSTATUS, 0, 0), (char *)ack->szModule, TRUE, NULL); +#ifdef _UNICODE + { + char *szMsg = mir_u2a(tszMsg); + CallContactService(ack->hContact, PSS_AWAYMSG, (WPARAM)(HANDLE)ack->hProcess, (LPARAM)szMsg); + if (szMsg) mir_free(szMsg); + } +#else + CallContactService(ack->hContact, PSS_AWAYMSG, (WPARAM)(HANDLE)ack->hProcess, (LPARAM)tszMsg); +#endif +#ifdef _DEBUG + log2file("ProcessProtoAck(): Send away message \"" TCHAR_STR_PARAM "\" reply.", tszMsg); +#endif + if (tszMsg) mir_free(tszMsg); + return 0; + } + + if (ack->type != ACKTYPE_STATUS || ack->result != ACKRESULT_SUCCESS || ack->hContact != NULL) + return 0; + + if (ack->lParam >= ID_STATUS_CONNECTING && ack->lParam < ID_STATUS_CONNECTING + MAX_CONNECT_RETRIES) + ack->lParam = ID_STATUS_OFFLINE; + + SaveStatusAsCurrent(ack->szModule, (int)ack->lParam); +#ifdef _DEBUG + log2file("ProcessProtoAck(): Set %s (%d) status for %s.", StatusModeToDbSetting((int)ack->lParam, ""), (int)ack->lParam, (char *)ack->szModule); +#endif + + return 0; +} + +int SetStartupStatus(int i) +{ + int flags; + char szSetting[80]; + TCHAR *fmsg = NULL, *msg = NULL; + int iStatus = GetStartupStatus(accounts->pa[i]->szModuleName); + + if (iStatus == ID_STATUS_OFFLINE) + return -1; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) || + !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + { + CallProtoService(accounts->pa[i]->szModuleName, PS_SETSTATUS, (WPARAM)iStatus, 0); + return -1; + } + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sFlags", accounts->pa[i]->szModuleName); + flags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", szSetting, PROTO_DEFAULT); + if (flags & PROTO_NO_MSG || flags & PROTO_THIS_MSG) + { + if (HasProtoStaticStatusMsg(accounts->pa[i]->szModuleName, ID_STATUS_OFFLINE, iStatus)) + return 0; + } + else if (flags & PROTO_NOCHANGE) + { + DBVARIANT dbv; + mir_snprintf(szSetting, SIZEOF(szSetting), "FCur%sMsg", accounts->pa[i]->szModuleName); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + fmsg = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + //else + // fmsg = mir_tstrdup(_T("")); + } + else + fmsg = GetAwayMessageFormat(iStatus, accounts->pa[i]->szModuleName); + +#ifdef _DEBUG + log2file("SetStartupStatus(): Set %s status and \"" TCHAR_STR_PARAM "\" status message for %s.", StatusModeToDbSetting(iStatus, ""), fmsg, accounts->pa[i]->szModuleName); +#endif + + if (fmsg) + msg = InsertVarsIntoMsg(fmsg, accounts->pa[i]->szModuleName, iStatus, NULL); + + SaveMessageToDB(accounts->pa[i]->szModuleName, fmsg, TRUE); + SaveMessageToDB(accounts->pa[i]->szModuleName, msg, FALSE); + + if (fmsg) + mir_free(fmsg); + + Proto_SetStatus(accounts->pa[i]->szModuleName, ID_STATUS_OFFLINE, iStatus, msg /*? msg : _T("")*/); + mir_free(msg); + + return 0; +} + +VOID CALLBACK SetStartupStatusGlobal(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + int prev_status_mode = -1, status_mode, temp_status_mode = ID_STATUS_OFFLINE, i; + BOOL globalstatus = TRUE; + + KillTimer(hwnd, idEvent); + + // is global status mode going to be set? + for (i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + status_mode = GetStartupStatus(accounts->pa[i]->szModuleName); + + if (status_mode != ID_STATUS_OFFLINE) + temp_status_mode = status_mode; + + if (status_mode != prev_status_mode && prev_status_mode != -1) + { + globalstatus = FALSE; + break; + } + + prev_status_mode = status_mode; + } + + // popup status msg dialog at startup? + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "StartupPopupDlg", 1) && accounts->statusMsgFlags) + { + if (globalstatus) + { + ChangeStatusMessage((WPARAM)status_mode, (LPARAM)"SimpleStatusMsgGlobalStartupStatus"); + } + else + { + // pseudo-currentDesiredStatusMode ;-) + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "StartupStatus", (WORD)temp_status_mode); + ChangeStatusMessage((WPARAM)ID_STATUS_CURRENT, (LPARAM)"SimpleStatusMsgGlobalStartupStatus"); + } + return; + } + + for (i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + +// if (DBGetContactSettingByte(NULL, accounts->pa[i]->szModuleName, "LockMainStatus", 0)) +// continue; + + SetStartupStatus(i); + } +} + +VOID CALLBACK SetStartupStatusProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + BOOL found = FALSE; + int i; + + for (i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + if (g_uSetStatusTimer[i] == idEvent) + { + KillTimer(NULL, g_uSetStatusTimer[i]); + found = TRUE; + break; + } + } + + if (!found) + { + KillTimer(hwnd, idEvent); + return; + } + + SetStartupStatus(i); +} + +VOID CALLBACK UpdateMsgTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + MIRANDA_IDLE_INFO mii = {0}; + mii.cbSize = sizeof(mii); + CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii); + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "NoUpdateOnIdle", 1) && mii.idleType) + return; + + if (!hwndSAMsgDialog) + { + char szBuffer[64]; + DBVARIANT dbv; + TCHAR *tszMsg; + int iCurrentStatus; + + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + iCurrentStatus = CallProtoService(accounts->pa[i]->szModuleName, PS_GETSTATUS, 0, 0); + if (iCurrentStatus < ID_STATUS_ONLINE) + continue; + + mir_snprintf(szBuffer, SIZEOF(szBuffer), "FCur%sMsg", accounts->pa[i]->szModuleName); + if (DBGetContactSettingTString(NULL, "SimpleStatusMsg", szBuffer, &dbv)) + continue; + + tszMsg = InsertVarsIntoMsg(dbv.ptszVal, accounts->pa[i]->szModuleName, iCurrentStatus, NULL); + DBFreeVariant(&dbv); + + mir_snprintf(szBuffer, SIZEOF(szBuffer), "Cur%sMsg", accounts->pa[i]->szModuleName); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szBuffer, &dbv)) + { + if (tszMsg && dbv.ptszVal && !lstrcmp(tszMsg, dbv.ptszVal) || !tszMsg && !dbv.ptszVal) + { + DBFreeVariant(&dbv); + mir_free(tszMsg); + continue; + } + DBFreeVariant(&dbv); + } + + if (tszMsg && lstrlen(tszMsg)) + { +#ifdef _DEBUG + log2file("UpdateMsgTimerProc(): Set %s status and \"" TCHAR_STR_PARAM "\" status message for %s.", StatusModeToDbSetting(iCurrentStatus, ""), tszMsg, accounts->pa[i]->szModuleName); +#endif + Proto_SetStatus(accounts->pa[i]->szModuleName, iCurrentStatus, iCurrentStatus, tszMsg); + SaveMessageToDB(accounts->pa[i]->szModuleName, tszMsg, FALSE); + } + mir_free(tszMsg); + } + } +} + +static int AddTopToolbarButton(WPARAM wParam, LPARAM lParam) +{ + TTBButtonV2 ttbb = {0}; + + ttbb.cbSize = sizeof(ttbb); + ttbb.hIconUp = ttbb.hIconDn = LoadIconEx("csmsg"); + ttbb.pszServiceUp = ttbb.pszServiceDown = MS_SIMPLESTATUSMSG_SHOWDIALOGINT; + ttbb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; + ttbb.name = Translate("Change Status Message"); + hTTBButton = (HANDLE)CallService(MS_TTB_ADDBUTTON, (WPARAM)&ttbb, 0); + + if (hTTBButton != (HANDLE)-1) + CallService(MS_TTB_SETBUTTONOPTIONS, MAKEWPARAM((WORD)TTBO_TIPNAME, (WORD)hTTBButton), (LPARAM)Translate("Change Status Message")); + ReleaseIconEx("csmsg"); + + return 0; +} + +void AddToolbarButton(void) +{ + TBButton tbb = {0}; + + tbb.cbSize = sizeof(tbb); + tbb.tbbFlags = TBBF_VISIBLE | TBBF_SHOWTOOLTIP; + tbb.pszButtonID = "sachmsg_btn"; + tbb.pszButtonName = Translate("Change Status Message"); + tbb.pszServiceName = MS_SIMPLESTATUSMSG_SHOWDIALOGINT; + tbb.pszTooltipUp = Translate("Change Status Message"); + tbb.hPrimaryIconHandle = GetIconHandle(IDI_CSMSG); + tbb.defPos = 11000; + CallService(MS_TB_ADDBUTTON, 0, (LPARAM)&tbb); +} + +void RegisterHotkey(void) +{ + HOTKEYDESC hkd = {0}; + + hkd.cbSize = sizeof(hkd); + hkd.dwFlags = HKD_TCHAR; + hkd.pszName = "SimpleStatusMsg_OpenDialog"; + hkd.ptszDescription = _T("Open Status Message Dialog"); + hkd.ptszSection = _T("Status Message"); + hkd.pszService = MS_SIMPLESTATUSMSG_SHOWDIALOGINT; + hkd.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, VK_OEM_3); + CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd); +} + +static int OnIconsChanged(WPARAM wParam, LPARAM lParam) +{ + if (hTTBButton) + { + CallService(MS_TTB_REMOVEBUTTON, (WPARAM)hTTBButton, (LPARAM)0); + AddTopToolbarButton(0, 0); + } + return 0; +} + +static int ChangeStatusMsgPrebuild(WPARAM wParam, LPARAM lParam) +{ +#ifdef _DEBUG + log2file("ChangeStatusMsgPrebuild()"); +#endif + PROTOACCOUNT **pa; + int iStatusMenuItemCount = 0, count, i; + DWORD iStatusMsgFlags = 0; + + ProtoEnumAccounts(&count, &pa); + hProtoStatusMenuItem = (HANDLE *)mir_realloc(hProtoStatusMenuItem, sizeof(HANDLE) * count); + for (i = 0; i < count; ++i) + { + if (!IsAccountEnabled(pa[i])) + continue; + + if (CallProtoService(pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) + iStatusMsgFlags |= CallProtoService(pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3,0); + + if (!pa[i]->bIsVisible) + continue; + + iStatusMenuItemCount++; + } + + if (!iStatusMsgFlags || !iStatusMenuItemCount) + return 0; + + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIF_ICONFROMICOLIB | CMIF_TCHAR; + if (!DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ShowStatusMenuItem", 1)) + mi.flags |= CMIF_HIDDEN; + mi.icolibItem = GetIconHandle(IDI_CSMSG); + mi.pszService = MS_SIMPLESTATUSMSG_SHOWDIALOGINT; + mi.ptszName = LPGENT("Status Message..."); + mi.position = 2000200000; + CallService(MS_CLIST_ADDSTATUSMENUITEM, 0, (LPARAM)&mi); + + mi.popupPosition = 500084000; + mi.position = 2000040000; + + for (i = 0; i < count; ++i) + { + char szSetting[80]; + TCHAR szBuffer[256]; + int iProtoFlags; + + if (!IsAccountEnabled(pa[i])) + continue; + + if (!CallProtoService(pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + if (!pa[i]->bIsVisible) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sFlags", pa[i]->szModuleName); + iProtoFlags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", szSetting, PROTO_DEFAULT); + if (iProtoFlags & PROTO_NO_MSG || iProtoFlags & PROTO_THIS_MSG) + continue; + + if (DBGetContactSettingByte(NULL, pa[i]->szModuleName, "LockMainStatus", 0) && + CallService(MS_SYSTEM_GETVERSION, 0, 0) >= PLUGIN_MAKE_VERSION(0, 9, 0, 10)) + { + mir_sntprintf(szBuffer, SIZEOF(szBuffer), TranslateT("%s (locked)"), pa[i]->tszAccountName); + mi.ptszPopupName = szBuffer; + } + else mi.ptszPopupName = pa[i]->tszAccountName; + hProtoStatusMenuItem[i] = (HANDLE)CallService(MS_CLIST_ADDSTATUSMENUITEM, 0, (LPARAM)&mi); + } + + return 0; +} + +static int OnIdleChanged(WPARAM, LPARAM lParam) +{ +#ifdef _DEBUG + log2file("OnIdleChanged()"); +#endif + if (!(lParam & IDF_ISIDLE)) + g_iIdleTime = -1; + + MIRANDA_IDLE_INFO mii = {0}; + mii.cbSize = sizeof(mii); + CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii); + if (mii.aaStatus == 0) + { +#ifdef _DEBUG + log2file("OnIdleChanged(): AutoAway disabled"); +#endif + return 0; + } + + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (DBGetContactSettingByte(NULL, accounts->pa[i]->szModuleName, "LockMainStatus", 0)) + continue; + + int iStatusBits = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + int iStatus = mii.aaStatus; + if (!(iStatusBits & Proto_Status2Flag(iStatus))) + { + if (iStatusBits & Proto_Status2Flag(ID_STATUS_AWAY)) + iStatus = ID_STATUS_AWAY; + else + continue; + } + + int iCurrentStatus = CallProtoService(accounts->pa[i]->szModuleName, PS_GETSTATUS, 0, 0); + if (iCurrentStatus < ID_STATUS_ONLINE || iCurrentStatus == ID_STATUS_INVISIBLE) + continue; + + if ((lParam & IDF_ISIDLE && (DBGetContactSettingByte(NULL, "AutoAway", accounts->pa[i]->szModuleName, 0) || + iCurrentStatus == ID_STATUS_ONLINE || iCurrentStatus == ID_STATUS_FREECHAT)) || + (!(lParam & IDF_ISIDLE) && !mii.aaLock)) + { + if (!(lParam & IDF_ISIDLE)) + iStatus = ID_STATUS_ONLINE; + TCHAR *tszMsg = GetAwayMessage(iStatus, accounts->pa[i]->szModuleName, FALSE, NULL); + TCHAR *tszVarsMsg = InsertVarsIntoMsg(tszMsg, accounts->pa[i]->szModuleName, iStatus, NULL); + SaveMessageToDB(accounts->pa[i]->szModuleName, tszMsg, TRUE); + SaveMessageToDB(accounts->pa[i]->szModuleName, tszVarsMsg, FALSE); + mir_free(tszMsg); + mir_free(tszVarsMsg); + } + } + + return 0; +} + +static int CSStatusChange(WPARAM wParam, LPARAM lParam) +{ + PROTOCOLSETTINGEX** ps = *(PROTOCOLSETTINGEX***)wParam; + int status_mode, CSProtoCount; + char szSetting[80]; + TCHAR *msg = NULL; + + if (ps == NULL) return -1; + + CSProtoCount = CallService(MS_CS_GETPROTOCOUNT, 0, 0); + for (int i = 0; i < CSProtoCount; ++i) + { + if (ps[i]->szName == NULL || !*ps[i]->szName) continue; + if (ps[i]->status == ID_STATUS_IDLE) + status_mode = ps[i]->lastStatus; + else if (ps[i]->status == ID_STATUS_CURRENT) + status_mode = CallProtoService(ps[i]->szName, PS_GETSTATUS, 0, 0); + else + status_mode = ps[i]->status; + + SaveStatusAsCurrent(ps[i]->szName, status_mode); +#ifdef _DEBUG + log2file("CSStatusChange(): Set %s status for %s.", StatusModeToDbSetting(status_mode, ""), ps[i]->szName); +#endif + + // TODO SaveMessageToDB also when NULL? + if (ps[i]->szMsg) + { + int max_hist_msgs, j; + DBVARIANT dbv; + char buff[80]; + BOOL found = FALSE; +#ifdef _UNICODE + wchar_t *szMsgW = mir_a2u(ps[i]->szMsg); +#endif + +#ifdef _DEBUG + log2file("CSStatusChange(): Set \"%s\" status message for %s.", ps[i]->szMsg, ps[i]->szName); +#endif + max_hist_msgs = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "MaxHist", 10); + for (j = 1; j <= max_hist_msgs; j++) + { + mir_snprintf(buff, SIZEOF(buff), "SMsg%d", j); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", buff, &dbv)) + { +#ifdef _UNICODE + if (!lstrcmp(dbv.ptszVal, szMsgW)) +#else + if (!lstrcmp(dbv.ptszVal, ps[i]->szMsg)) +#endif + { + found = TRUE; + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sMsg", ps[i]->szName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", szSetting, buff); + DBFreeVariant(&dbv); + break; + } + } + } + + if (!found) + { + mir_snprintf(buff, SIZEOF(buff), "FCur%sMsg", ps[i]->szName); + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sMsg", ps[i]->szName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", szSetting, buff); + } + + mir_snprintf(szSetting, SIZEOF(szSetting), "%sMsg", ps[i]->szName); +#ifdef _UNICODE + DBWriteContactSettingWString(NULL, "SRAway", StatusModeToDbSetting(status_mode, szSetting), szMsgW); + msg = InsertVarsIntoMsg(szMsgW, ps[i]->szName, status_mode, NULL); + SaveMessageToDB(ps[i]->szName, szMsgW, TRUE); + mir_free(szMsgW); +#else + DBWriteContactSettingString(NULL, "SRAway", StatusModeToDbSetting(status_mode, szSetting), ps[i]->szMsg); + msg = InsertVarsIntoMsg(ps[i]->szMsg, ps[i]->szName, status_mode, NULL); + SaveMessageToDB(ps[i]->szName, ps[i]->szMsg, TRUE); +#endif + SaveMessageToDB(ps[i]->szName, msg, FALSE); + mir_free(msg); + } + } + + return 0; +} + +static TCHAR *ParseWinampSong(ARGUMENTSINFO *ai) +{ + TCHAR *ptszWinampTitle; + + if (ai->argc != 1) + return NULL; + + ai->flags |= AIF_DONTPARSE; + ptszWinampTitle = GetWinampSong(); + + if (ptszWinampTitle != NULL) + { + mir_free(g_ptszWinampSong); + g_ptszWinampSong = mir_tstrdup(ptszWinampTitle); + } + else if (g_ptszWinampSong && lstrcmp(g_ptszWinampSong, _T("SimpleStatusMsg")) && DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AmpLeaveTitle", 1)) + ptszWinampTitle = mir_tstrdup(g_ptszWinampSong); + + return ptszWinampTitle; +} + +static TCHAR *ParseDate(ARGUMENTSINFO *ai) +{ + TCHAR szStr[128] = {0}; + + if (ai->argc != 1) + return NULL; + + ai->flags |= AIF_DONTPARSE; + GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, szStr, SIZEOF(szStr)); + + return mir_tstrdup(szStr); +} + +int ICQMsgTypeToStatus(int iMsgType) +{ + switch (iMsgType) + { + case MTYPE_AUTOONLINE: return ID_STATUS_ONLINE; + case MTYPE_AUTOAWAY: return ID_STATUS_AWAY; + case MTYPE_AUTOBUSY: return ID_STATUS_OCCUPIED; + case MTYPE_AUTONA: return ID_STATUS_NA; + case MTYPE_AUTODND: return ID_STATUS_DND; + case MTYPE_AUTOFFC: return ID_STATUS_FREECHAT; + default: return ID_STATUS_OFFLINE; + } +} + +static int OnICQStatusMsgRequest(WPARAM wParam, LPARAM lParam, LPARAM lMirParam) +{ +#ifdef _DEBUG + log2file("OnICQStatusMsgRequest(): UIN: %d on %s", (int)lParam, (char *)lMirParam); +#endif + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "NoUpdateOnICQReq", 1)) + return 0; + + HANDLE hContact; + char *szProto; + BOOL bContactFound = FALSE; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact) + { + szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (szProto != NULL && !strcmp(szProto, (char *)lMirParam) && DBGetContactSettingDword(hContact, szProto, "UIN", 0) == (DWORD)lParam) + { + bContactFound = TRUE; + break; + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + if (!bContactFound) + return 0; + + int iStatus = ICQMsgTypeToStatus(wParam); + TCHAR *tszMsg = GetAwayMessage(iStatus, szProto, TRUE, hContact); + Proto_SetAwayMsgT(szProto, iStatus, tszMsg); + mir_free(tszMsg); + + return 0; +} + +static int OnAccListChanged(WPARAM wParam, LPARAM lParam) +{ +#ifdef _DEBUG + log2file("OnAccListChanged()"); +#endif + accounts->statusFlags = 0; + accounts->statusCount = 0; + accounts->statusMsgFlags = 0; + accounts->statusMsgCount = 0; + UnhookProtoEvents(); + + ProtoEnumAccounts(&accounts->count, &accounts->pa); + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!strcmp(accounts->pa[i]->szProtoName, "ICQ")) + HookProtoEvent(accounts->pa[i]->szModuleName, ME_ICQ_STATUSMSGREQ, OnICQStatusMsgRequest); + + accounts->statusFlags |= (CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) &~ CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0)); + + if (CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) &~ CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0)) + accounts->statusCount++; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + accounts->statusMsgFlags |= CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3,0); + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + accounts->statusMsgCount++; + } + + return 0; +} + +static int OnModulesLoaded(WPARAM wParam, LPARAM lParam) +{ +#ifdef _DEBUG + log2file("### Session started ###"); +#endif + // known modules list + if (ServiceExists("DBEditorpp/RegisterSingleModule")) + CallService("DBEditorpp/RegisterSingleModule", (WPARAM)"SimpleStatusMsg", 0); + + if (ServiceExists(MS_UPDATE_REGISTERFL)) +#if defined(_WIN64) + CallService(MS_UPDATE_REGISTERFL, 4322, (LPARAM)&pluginInfo); +#elif defined(_UNICODE) + CallService(MS_UPDATE_REGISTERFL, 4321, (LPARAM)&pluginInfo); +#else + CallService(MS_UPDATE_REGISTERFL, 4320, (LPARAM)&pluginInfo); +#endif + + IconsInit(); + HookEventEx(ME_SKIN2_ICONSCHANGED, OnIconsChanged); + OnAccListChanged(0, 0); + + LoadAwayMsgModule(); + + HookEventEx(ME_TTB_MODULELOADED, AddTopToolbarButton); + if (ServiceExists(MS_TB_ADDBUTTON)) + AddToolbarButton(); + + RegisterHotkey(); + + HookEventEx(ME_OPT_INITIALISE, InitOptions); + h_statusmodechange = HookEvent(ME_CLIST_STATUSMODECHANGE, ChangeStatusMessage); + HookEventEx(ME_PROTO_ACK, ProcessProtoAck); + HookEventEx(ME_IDLE_CHANGED, OnIdleChanged); + + HookEventEx(ME_CLIST_PREBUILDSTATUSMENU, ChangeStatusMsgPrebuild); + ChangeStatusMsgPrebuild(0, 0); + + if (ServiceExists(MS_VARS_REGISTERTOKEN)) + { + TOKENREGISTER tr = {0}; + tr.cbSize = sizeof(TOKENREGISTER); + tr.memType = TR_MEM_MIRANDA; + tr.flags = TRF_FREEMEM | TRF_FIELD | TRF_TCHAR | TRF_PARSEFUNC; + tr.tszTokenString = _T("winampsong"); + tr.parseFunctionT = ParseWinampSong; + tr.szHelpText = LPGEN("External Applications\tretrieves song name of the song currently playing in Winamp (Simple Status Message compatible)"); + CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM)&tr); + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ExclDateToken", 0) != 0) + { + tr.tszTokenString = _T("date"); + tr.parseFunctionT = ParseDate; + tr.szHelpText = LPGEN("Miranda Related\tget the date (Simple Status Message compatible)"); + CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM)&tr); + } + } + +/* if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AmpLeaveTitle", 1))*/ { + DBVARIANT dbv; + + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", "AmpLastTitle", &dbv)) + { + g_ptszWinampSong = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + g_ptszWinampSong = mir_tstrdup(_T("SimpleStatusMsg")); + } +/* else + g_ptszWinampSong = mir_tstrdup(_T("SimpleStatusMsg"));*/ + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "UpdateMsgOn", 1)) + g_uUpdateMsgTimer = SetTimer(NULL, 0, DBGetContactSettingWord(NULL, "SimpleStatusMsg", "UpdateMsgInt", 10) * 1000, (TIMERPROC)UpdateMsgTimerProc); + + if (ServiceExists(MS_CS_SETSTATUSEX)) + HookEventEx(ME_CS_STATUSCHANGEEX, CSStatusChange); + + if (accounts->statusCount == 0) + return 0; + + if (!ServiceExists(MS_SS_GETPROFILECOUNT)) + { + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "GlobalStatusDelay", 1)) + { + SetTimer(NULL, 0, DBGetContactSettingWord(NULL, "SimpleStatusMsg", "SetStatusDelay", 300), (TIMERPROC)SetStartupStatusGlobal); + } + else + { + char szSetting[80]; + + g_uSetStatusTimer = (UINT_PTR*)mir_alloc(sizeof(UINT_PTR) * accounts->count); + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) &~ CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Set%sStatusDelay", accounts->pa[i]->szModuleName); + g_uSetStatusTimer[i] = SetTimer(NULL, 0, DBGetContactSettingWord(NULL, "SimpleStatusMsg", szSetting, 300), (TIMERPROC)SetStartupStatusProc); + } + } + } + + return 0; +} + +static int OnOkToExit(WPARAM wParam, LPARAM lParam) +{ + if (accounts->statusCount) + { + char szSetting[80]; + + for (int i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) &~ CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sStatus", accounts->pa[i]->szModuleName); + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", szSetting, (WORD)CallProtoService(accounts->pa[i]->szModuleName, PS_GETSTATUS, 0, 0)); + } + + if (g_ptszWinampSong && lstrcmp(g_ptszWinampSong, _T("SimpleStatusMsg")) /*&& DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AmpLeaveTitle", 1)*/) + DBWriteMessage("AmpLastTitle", g_ptszWinampSong); + } + + return 0; +} + +static int OnPreShutdown(WPARAM wParam, LPARAM lParam) +{ + if (!accounts->statusMsgFlags) + return 0; + + AwayMsgPreShutdown(); + if (hwndSAMsgDialog) DestroyWindow(hwndSAMsgDialog); + if (hProtoStatusMenuItem) mir_free(hProtoStatusMenuItem); + if (g_uSetStatusTimer) mir_free(g_uSetStatusTimer); + if (g_ptszWinampSong) mir_free(g_ptszWinampSong); + if (g_uUpdateMsgTimer) KillTimer(NULL, g_uUpdateMsgTimer); + + return 0; +} + +static INT_PTR IsSARunning(WPARAM wParam, LPARAM lParam) +{ + return 1; +} + +//remember to mir_free() the return value +static INT_PTR sttGetAwayMessageT(WPARAM wParam, LPARAM lParam) +{ + return (INT_PTR)GetAwayMessage((int)wParam, (char*)lParam, TRUE, NULL); +} + +#ifdef UNICODE +static INT_PTR sttGetAwayMessage(WPARAM wParam, LPARAM lParam) +{ + TCHAR* msg = GetAwayMessage((int)wParam, (char*)lParam, TRUE, NULL); + char* res = mir_t2a(msg); + mir_free(msg); + return (INT_PTR)res; +} +#endif + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + + mir_getMMI(&mmi); + mir_getLP(&pluginInfo); + hwndSAMsgDialog = NULL; + accounts = (PROTOACCOUNTS *)mir_alloc(sizeof(PROTOACCOUNTS)); + + DBWriteContactSettingWord(NULL, "CList", "Status", (WORD)ID_STATUS_OFFLINE); + HookEventEx(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + HookEventEx(ME_PROTO_ACCLISTCHANGED, OnAccListChanged); + +#ifdef UNICODE + CreateServiceFunctionEx(MS_AWAYMSG_GETSTATUSMSG, sttGetAwayMessage); + CreateServiceFunctionEx(MS_AWAYMSG_GETSTATUSMSGW, sttGetAwayMessageT); +#else + CreateServiceFunctionEx(MS_AWAYMSG_GETSTATUSMSG, sttGetAwayMessageT); +#endif + CreateServiceFunctionEx(MS_SIMPLESTATUSMSG_SETSTATUS, SetStatusModeFromExtern); + CreateServiceFunctionEx(MS_SIMPLESTATUSMSG_SHOWDIALOG, ShowStatusMessageDialog); + CreateServiceFunctionEx(MS_SIMPLESTATUSMSG_CHANGESTATUSMSG, ChangeStatusMsg); + CreateServiceFunctionEx(MS_SIMPLESTATUSMSG_SHOWDIALOGINT, ShowStatusMessageDialogInternal); // internal use ONLY + + // Deprecated SimpleAway services + CreateServiceFunctionEx(MS_SA_ISSARUNNING, IsSARunning); + CreateServiceFunctionEx(MS_SA_CHANGESTATUSMSG, ChangeStatusMsg); + CreateServiceFunctionEx(MS_SA_TTCHANGESTATUSMSG, ShowStatusMessageDialogInternal); + CreateServiceFunctionEx(MS_SA_SHOWSTATUSMSGDIALOG, ShowStatusMessageDialog); + CreateServiceFunctionEx(MS_SA_SETSTATUSMODE, SetStatusModeFromExtern); + + CreateServiceFunctionEx(MS_SA_SETOFFLINESTATUS, SetOfflineStatus); + CreateServiceFunctionEx(MS_SA_SETONLINESTATUS, SetOnlineStatus); + CreateServiceFunctionEx(MS_SA_SETAWAYSTATUS, SetAwayStatus); + CreateServiceFunctionEx(MS_SA_SETDNDSTATUS, SetDNDStatus); + CreateServiceFunctionEx(MS_SA_SETNASTATUS, SetNAStatus); + CreateServiceFunctionEx(MS_SA_SETOCCUPIEDSTATUS, SetOccupiedStatus); + CreateServiceFunctionEx(MS_SA_SETFREECHATSTATUS, SetFreeChatStatus); + CreateServiceFunctionEx(MS_SA_SETINVISIBLESTATUS, SetInvisibleStatus); + CreateServiceFunctionEx(MS_SA_SETONTHEPHONESTATUS, SetOnThePhoneStatus); + CreateServiceFunctionEx(MS_SA_SETOUTTOLUNCHSTATUS, SetOutToLunchStatus); + + HookEventEx(ME_SYSTEM_OKTOEXIT, OnOkToExit); + HookEventEx(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + UnhookEvents(); + UnhookEvent(h_statusmodechange); + UnhookProtoEvents(); + DestroyServiceFunctionsEx(); + mir_free(accounts); + +#ifdef _DEBUG + log2file("### Session ended ###"); +#endif + + return 0; +} diff --git a/plugins/SimpleStatusMsg/msgbox.cpp b/plugins/SimpleStatusMsg/msgbox.cpp new file mode 100644 index 0000000000..b984c03338 --- /dev/null +++ b/plugins/SimpleStatusMsg/msgbox.cpp @@ -0,0 +1,1806 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "commonheaders.h" +#include "simplestatusmsg.h" + +#define I_ICON_DEL 0 +#define I_ICON_HIST 1 +#define I_ICON_MSG 2 +#define I_ICON_ADD 3 +#define I_ICON_CLEAR 4 + +struct MsgBoxData +{ + char *m_szProto; + int m_iStatus; + int m_iInitialStatus; + int m_iStatusModes; + int m_iStatusMsgModes; + HWND status_cbex; + HWND recent_cbex; + HICON icon[5]; + HIMAGELIST status_icons; + HIMAGELIST other_icons; + int m_iCountdown; + int curr_sel_msg; + int m_iDlgFlags; + int max_hist_msgs; + int num_def_msgs; + BOOL m_bPredefChanged; + BOOL m_bIsMsgHistory; + BOOL m_bOnStartup; +}; + +typedef struct +{ + clock_t ctLastDblClk; + UINT uClocksPerDblClk; +} +MsgEditCtrl; + +HIMAGELIST AddOtherIconsToImageList(struct MsgBoxData *data) +{ + HIMAGELIST himlIcons = ImageList_Create(16, 16, (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, 4, 0); + + for (int i = 0; i < 5; ++i) + ImageList_AddIcon(himlIcons, data->icon[i]); + + return himlIcons; +} + +int statusicon_nr[9]; + +HIMAGELIST AddStatusIconsToImageList(const char *szProto, int status_flags) +{ + int num_icons = 1; + int i; + + for (i = 0; i < 9; ++i) + if (Proto_Status2Flag(ID_STATUS_ONLINE + i) & status_flags) num_icons++; + + HIMAGELIST himlIcons = ImageList_Create(16, 16, (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, num_icons, 0); + HICON hicon = LoadSkinnedProtoIcon(szProto, ID_STATUS_OFFLINE); + ImageList_AddIcon(himlIcons, hicon); + CallService(MS_SKIN2_RELEASEICON, (LPARAM)hicon, (WPARAM)0); + statusicon_nr[0] = 0; + + int j = 1; + for (i = 0; i < 9; ++i) + { + if (Proto_Status2Flag(ID_STATUS_ONLINE + i) & status_flags) + { + hicon = LoadSkinnedProtoIcon(szProto, ID_STATUS_ONLINE + i); + ImageList_AddIcon(himlIcons, hicon); + CallService(MS_SKIN2_RELEASEICON, (LPARAM)hicon, (WPARAM)0); + statusicon_nr[i + 1] = j; + j++; + } + else + statusicon_nr[i + 1] = 0; + } + + return himlIcons; +} + +HWND WINAPI CreateStatusComboBoxEx(HWND hwndDlg, struct MsgBoxData *data) +{ + int j = 0, cur_sel = 0; + TCHAR *status_desc; + + if (!(data->m_iDlgFlags & DLG_SHOW_STATUS)) + return NULL; + + HWND handle = CreateWindowEx(0, WC_COMBOBOXEX, NULL, + WS_TABSTOP | CBS_NOINTEGRALHEIGHT | WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST, + 0, 0, 0, 240, hwndDlg, NULL, g_hInst, NULL); + + COMBOBOXEXITEM cbei = {0}; + if (!(data->m_iDlgFlags & DLG_SHOW_STATUS_ICONS)) + cbei.mask = CBEIF_LPARAM | CBEIF_TEXT; + else + cbei.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; + + if (data->m_bOnStartup) + status_desc = (TCHAR*)TranslateT(""); + else + status_desc = (TCHAR*)TranslateT(""); + cbei.iItem = j; + cbei.pszText = (LPTSTR)status_desc; + cbei.cchTextMax = sizeof(status_desc); + + if (data->m_szProto || data->m_iStatus == ID_STATUS_CURRENT) + { + if (data->m_bOnStartup) + j = GetStartupStatus(data->m_szProto) - ID_STATUS_OFFLINE; + else + j = GetCurrentStatus(data->m_szProto) - ID_STATUS_OFFLINE; + } + else + j = data->m_iStatus - ID_STATUS_OFFLINE; + + if (j < 0 || j > 9) j = 0; // valid status modes only + + if (data->m_iDlgFlags & DLG_SHOW_STATUS_ICONS) + { + cbei.iImage = statusicon_nr[j]; + cbei.iSelectedImage = statusicon_nr[j]; + } + j = 0; + cbei.lParam = (LPARAM)ID_STATUS_CURRENT; + + if (ID_STATUS_CURRENT == data->m_iInitialStatus) + cur_sel = j; + + SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei); + j++; + + for (int i = 0; i < 10; ++i) + { + if ((Proto_Status2Flag(ID_STATUS_OFFLINE + i) & data->m_iStatusModes) || i == 0) + { + status_desc = (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, ID_STATUS_OFFLINE + i, GSMDF_TCHAR); + cbei.iItem = j; + cbei.pszText = (LPTSTR)status_desc; + cbei.cchTextMax = sizeof(status_desc); + if (data->m_iDlgFlags & DLG_SHOW_STATUS_ICONS) + { + cbei.iImage = j - 1; + cbei.iSelectedImage = j - 1; + } + cbei.lParam = (LPARAM)ID_STATUS_OFFLINE + i; + + if (ID_STATUS_OFFLINE + i == data->m_iInitialStatus) + cur_sel = j; + + if (SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei) == -1) + break; + j++; + } + } + + if (!data->m_szProto && (data->m_iDlgFlags & DLG_SHOW_STATUS_PROFILES) && ServiceExists(MS_SS_GETPROFILECOUNT)) + { + int defaultProfile; + int profileCount = (int)CallService(MS_SS_GETPROFILECOUNT, (WPARAM)&defaultProfile, 0); + char buff1[128]; + + for (int i = 0; i < profileCount; ++i) + { + CallService(MS_SS_GETPROFILENAME, (WPARAM)i, (LPARAM)buff1); +#ifdef _UNICODE + status_desc = mir_a2u(buff1); +#else + status_desc = (char*)buff1; +#endif + cbei.iItem = j; + cbei.pszText = (LPTSTR)status_desc; + cbei.cchTextMax = sizeof(status_desc); + if (data->m_iDlgFlags & DLG_SHOW_STATUS_ICONS) + { + int k = GetCurrentStatus(NULL) - ID_STATUS_OFFLINE; + if (k < 0 || k > 9) k = 0; // valid status modes only + cbei.iImage = statusicon_nr[k]; + cbei.iSelectedImage = statusicon_nr[k]; + } + cbei.lParam = (LPARAM)40083+i; +#ifdef _UNICODE + mir_free(status_desc); +#endif + if (SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei) == -1) + break; + j++; + } + } + + if (!(data->m_iDlgFlags & DLG_SHOW_STATUS_ICONS)) + SendMessage(handle, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)16); + else + { + SendMessage(handle, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)18); + SendMessage(handle, CBEM_SETIMAGELIST, 0, (LPARAM)data->status_icons); + } + SetWindowPos(handle, NULL, 11, 11, 112, 20, SWP_NOACTIVATE); + SendMessage(handle, CB_SETCURSEL, (WPARAM)cur_sel, 0); + SendMessage(handle, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)16); + + return handle; +} + +#define HISTORY_MSG 1 +#define CLEAR_HISTORY 2 +#define PREDEFINED_MSG 3 +#define ADD_MSG 4 +#define DELETE_SELECTED 5 +#define DEFAULT_MSG 6 + +HWND WINAPI CreateRecentComboBoxEx(HWND hwndDlg, struct MsgBoxData *data) +{ + int i, j; + char buff[16]; + BOOL found = FALSE; + DBVARIANT dbv; + TCHAR text[128]; + + HWND handle = CreateWindowEx(0, WC_COMBOBOXEX, NULL, + WS_TABSTOP | CBS_NOINTEGRALHEIGHT | WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST, + 0, 0, 0, 300, hwndDlg, NULL, g_hInst, NULL); + + COMBOBOXEXITEM cbei = {0}; + if (!(data->m_iDlgFlags & DLG_SHOW_LIST_ICONS)) + cbei.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_INDENT; + else + cbei.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; + + j = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "LMMsg", 1); + + for (i = 1; i <= data->max_hist_msgs; ++i) + { + // history messages + if (j < 1) j = data->max_hist_msgs; + mir_snprintf(buff, SIZEOF(buff), "SMsg%d", j); + j--; + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", buff, &dbv)) + { + if (dbv.ptszVal != NULL && dbv.ptszVal != '\0') + { + found = TRUE; + cbei.iItem = -1; + cbei.pszText = (LPTSTR)dbv.ptszVal; + cbei.cchTextMax = sizeof(dbv.ptszVal); + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + cbei.iImage = I_ICON_HIST; + cbei.iSelectedImage = I_ICON_HIST; + } + else + cbei.iIndent = 0; + cbei.lParam = MAKELPARAM(HISTORY_MSG, j + 1); + + if (SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei) == -1) + { + DBFreeVariant(&dbv); + break; + } + } + DBFreeVariant(&dbv); + } + } + + data->m_bIsMsgHistory = found; + + if ((data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + if (found) + { + if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BCLEAR))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), TRUE); + } + else if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BCLEAR))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), FALSE); + } + else if (data->m_iDlgFlags & DLG_SHOW_BUTTONS_INLIST) + { + if (found) + { + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + mir_sntprintf(text, SIZEOF(text), TranslateT("Clear History")); + cbei.iImage = I_ICON_CLEAR; + cbei.iSelectedImage = I_ICON_CLEAR; + } + else + { + mir_sntprintf(text, SIZEOF(text), _T("## %s ##"), TranslateT("Clear History")); + cbei.iIndent = 1; + } + cbei.iItem = -1; + cbei.pszText = (LPTSTR)text; + cbei.cchTextMax = SIZEOF(text); + cbei.lParam = MAKELPARAM(CLEAR_HISTORY, 0); + SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei); + } + + cbei.iItem = -1; + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + mir_sntprintf(text, SIZEOF(text), TranslateT("Add to Predefined")); + cbei.iImage = I_ICON_ADD; + cbei.iSelectedImage = I_ICON_ADD; + } + else + { + mir_sntprintf(text, SIZEOF(text), _T("## %s ##"), TranslateT("Add to Predefined")); + cbei.iIndent = 1; + } + cbei.pszText = (LPTSTR)text; + cbei.cchTextMax = SIZEOF(text); + cbei.lParam = MAKELPARAM(ADD_MSG, 0); + SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei); + + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + mir_sntprintf(text, SIZEOF(text), TranslateT("Delete Selected")); + cbei.iImage = I_ICON_DEL; + cbei.iSelectedImage = I_ICON_DEL; + } + else + { + cbei.iIndent = 1; + mir_sntprintf(text, SIZEOF(text), _T("## %s ##"), TranslateT("Delete Selected")); + } + cbei.iItem = -1; + cbei.pszText = (LPTSTR)text; + cbei.cchTextMax = SIZEOF(text); + cbei.lParam = MAKELPARAM(DELETE_SELECTED, 0); + SendMessage(handle, CBEM_INSERTITEM, 0, (LPARAM)&cbei); + } + + if ((data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + if (data->num_def_msgs || found) + { + if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), TRUE); + } + else if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + } + + for (i = 1; i <= data->num_def_msgs; ++i) + { + // predefined messages + mir_snprintf(buff, SIZEOF(buff), "DefMsg%d", i); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", buff, &dbv)) + { + if (dbv.ptszVal) + { + if (!lstrlen(dbv.ptszVal)) + { + DBFreeVariant(&dbv); + continue; + } + + cbei.iItem = -1; + cbei.pszText = (LPTSTR)dbv.ptszVal; + cbei.cchTextMax = sizeof(dbv.ptszVal); + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + cbei.iImage = I_ICON_MSG; + cbei.iSelectedImage = I_ICON_MSG; + } + else + cbei.iIndent = 0; + cbei.lParam = MAKELPARAM(PREDEFINED_MSG, i); + + if (SendMessage(handle,CBEM_INSERTITEM,0,(LPARAM)&cbei) == -1) + break; + } + DBFreeVariant(&dbv); + } + } + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "PutDefInList", 0)) + { + cbei.iItem = -1; + cbei.pszText = (LPTSTR)GetDefaultMessage(data->m_iStatus); + cbei.cchTextMax = sizeof(GetDefaultMessage(data->m_iStatus)); + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + cbei.iImage = I_ICON_MSG; + cbei.iSelectedImage = I_ICON_MSG; + } + else + cbei.iIndent = 0; + cbei.lParam = MAKELPARAM(DEFAULT_MSG, 0); + + SendMessage(handle,CBEM_INSERTITEM,0,(LPARAM)&cbei); + } + + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + SendMessage(handle, CBEM_SETIMAGELIST, 0, (LPARAM)data->other_icons); + if (!(data->m_iDlgFlags & DLG_SHOW_STATUS)) + { + SetWindowPos(handle, NULL, 11, 11, 290, 20, SWP_NOACTIVATE); + SendMessage(handle, CB_SETDROPPEDWIDTH, (WPARAM)290, 0); + } + else + { + SetWindowPos(handle, NULL, 127, 11, 174, 20, SWP_NOACTIVATE); + SendMessage(handle, CB_SETDROPPEDWIDTH, (WPARAM)250, 0); + } + SendMessage(handle, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)16); + SendMessage(handle, CB_SETITEMHEIGHT, (WPARAM)0, (LPARAM)16); + + if (((data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) && !found && !data->num_def_msgs) + EnableWindow(handle, FALSE); + + if (((!(data->m_iDlgFlags & DLG_SHOW_BUTTONS)) && (!(data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) && (!(data->m_iDlgFlags & DLG_SHOW_BUTTONS_INLIST))) && !found && !data->num_def_msgs) + EnableWindow(handle, FALSE); + + return handle; +} + +VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, HWND edit_control) +{ + HMENU hmenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_EDITMENU)); + if (hmenu == NULL) + return; + + HMENU hmenuTrackPopup = GetSubMenu(hmenu, 0); + + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hmenuTrackPopup, 0); + + ClientToScreen(hwnd, (LPPOINT) &pt); + + LPDWORD sel_s = NULL, sel_e = NULL; + SendMessage(edit_control, EM_GETSEL, (WPARAM)&sel_s, (LPARAM)&sel_e); + if (sel_s == sel_e) + { + EnableMenuItem(hmenuTrackPopup, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(hmenuTrackPopup, IDM_CUT, MF_BYCOMMAND | MF_GRAYED); + } + if (SendMessage(edit_control, WM_GETTEXTLENGTH, 0, 0) == 0) + EnableMenuItem(hmenuTrackPopup, IDM_DELETE, MF_BYCOMMAND | MF_GRAYED); + + if (ServiceExists(MS_VARS_FORMATSTRING)) + DeleteMenu(hmenuTrackPopup, ID__VARIABLES, MF_BYCOMMAND); + else + DeleteMenu(hmenuTrackPopup, 8, MF_BYPOSITION); + + if (ServiceExists(MS_FORTUNEMSG_GETSTATUSMSG)) + DeleteMenu(hmenuTrackPopup, ID__FORTUNEAWAYMSG, MF_BYCOMMAND); + else + DeleteMenu(hmenuTrackPopup, 7, MF_BYPOSITION); + + int m_selection = TrackPopupMenu(hmenuTrackPopup, TPM_LEFTALIGN | TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL); + switch (m_selection) + { + case IDM_COPY: + SendMessage(edit_control, WM_COPY, 0, 0); + break; + + case IDM_CUT: + SendMessage(edit_control, WM_CUT, 0, 0); + break; + + case IDM_PASTE: + SendMessage(edit_control, WM_PASTE, 0, 0); + break; + + case IDM_SELECTALL: + SendMessage(edit_control, EM_SETSEL, 0, -1); + break; + + case IDM_DELETE: + SendMessage(edit_control, WM_SETTEXT, 0, (LPARAM)""); + SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(IDC_EDIT1, EN_CHANGE), (LPARAM)edit_control); + break; + + case ID__FORTUNEAWAYMSG: + CallService(MS_UTILS_OPENURL,1,(LPARAM)"http://addons.miranda-im.org/details.php?action=viewfile&id=1933"); + break; + + case ID__VARIABLES: +#ifdef _UNICODE + CallService(MS_UTILS_OPENURL,1,(LPARAM)"http://addons.miranda-im.org/details.php?action=viewfile&id=3815"); +#else + CallService(MS_UTILS_OPENURL,1,(LPARAM)"http://addons.miranda-im.org/details.php?action=viewfile&id=3814"); +#endif + break; + + case ID__VARIABLES_MOREVARIABLES: + { + VARHELPINFO vhi = {0}; + vhi.cbSize = sizeof(vhi); + vhi.flags = VHF_FULLDLG | VHF_SETLASTSUBJECT; + vhi.hwndCtrl = edit_control; + vhi.szSubjectDesc = NULL; + vhi.szExtraTextDesc = NULL; + CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwnd, (LPARAM)&vhi); + break; + } + + default: + if (!OpenClipboard(GetParent(hwnd))) break; + if (EmptyClipboard()) + { + TCHAR item_string[128]; + int len; + + GetMenuString(hmenu, m_selection, (LPTSTR)&item_string, 128, MF_BYCOMMAND); + len = lstrlen(item_string); + if (len) + { + LPTSTR lptstrCopy; + HGLOBAL hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(TCHAR)); + if (hglbCopy == NULL) + { + CloseClipboard(); + break; + } + lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); + memcpy(lptstrCopy, item_string, len * sizeof(TCHAR)); + lptstrCopy[len] = (TCHAR)0; + GlobalUnlock(hglbCopy); +#ifdef _UNICODE + SetClipboardData(CF_UNICODETEXT, hglbCopy); +#else + SetClipboardData(CF_TEXT, hglbCopy); +#endif + } + } + CloseClipboard(); + SendMessage(edit_control, WM_PASTE, 0, 0); + break; + } + DestroyMenu(hmenu); +} + +static WNDPROC MainDlgProc; + +static LRESULT CALLBACK EditBoxSubProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_CONTEXTMENU: + { + POINT pt = {(LONG)LOWORD(lParam), (LONG)HIWORD(lParam)}; + RECT rc; + GetClientRect(hwndDlg, &rc); + + if (pt.x == -1 && pt.y == -1) + { + GetCursorPos(&pt); + if (!PtInRect(&rc, pt)) + { + pt.x = rc.left + (rc.right - rc.left) / 2; + pt.y = rc.top + (rc.bottom - rc.top) / 2; + } + } + else + ScreenToClient(hwndDlg, &pt); + + if (PtInRect(&rc, pt)) + HandlePopupMenu(hwndDlg, pt, GetDlgItem(GetParent(hwndDlg), IDC_EDIT1)); + + return 0; + } + + case WM_CHAR: + if (wParam=='\n' && GetKeyState(VK_CONTROL) & 0x8000) + { + PostMessage(GetParent(hwndDlg), WM_COMMAND, IDC_OK, 0); + return 0; + } + if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) // Ctrl + A + { + SendMessage(hwndDlg, EM_SETSEL, 0, -1); + return 0; + } + if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) // Ctrl + W + { + SendMessage(GetParent(hwndDlg), WM_COMMAND, IDC_CANCEL, 0); + return 0; + } + if (wParam == 127 && GetKeyState(VK_CONTROL) & 0x8000) // Ctrl + Backspace + { + DWORD start, end; + TCHAR *text; + int textLen; + SendMessage(hwndDlg, EM_GETSEL, (WPARAM)&end, (LPARAM)(PDWORD)NULL); + SendMessage(hwndDlg, WM_KEYDOWN, VK_LEFT, 0); + SendMessage(hwndDlg, EM_GETSEL, (WPARAM)&start, (LPARAM)(PDWORD)NULL); + textLen = GetWindowTextLength(hwndDlg); + text = (TCHAR *)mir_alloc(sizeof(TCHAR) * (textLen + 1)); + GetWindowText(hwndDlg, text, textLen + 1); + MoveMemory(text + start, text + end, sizeof(TCHAR) * (textLen + 1 - end)); + SetWindowText(hwndDlg, text); + mir_free(text); + SendMessage(hwndDlg, EM_SETSEL, start, start); + SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwndDlg), EN_CHANGE), (LPARAM)hwndDlg); + return 0; + } + break; + + case WM_LBUTTONDBLCLK: + { + MsgEditCtrl* mec = (MsgEditCtrl*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (mec != NULL) + { + mec->ctLastDblClk = clock(); + mec->uClocksPerDblClk = GetDoubleClickTime() * CLOCKS_PER_SEC / 1000; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)mec); + } + break; + } + + case WM_LBUTTONDOWN: + { + MsgEditCtrl* mec = (MsgEditCtrl*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (mec != NULL && UINT(clock() - mec->ctLastDblClk) < mec->uClocksPerDblClk) + { + SendMessage(hwndDlg, EM_SETSEL, 0, -1); + return 0; + } + break; + } + + case WM_SETFOCUS: + { + MsgEditCtrl* mec = (MsgEditCtrl*)mir_calloc(sizeof(MsgEditCtrl)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)mec); + break; + } + + case WM_KILLFOCUS: + { + MsgEditCtrl* mec = (MsgEditCtrl*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + mir_free(mec); + mec = NULL; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)mec); + break; + } + } + + return CallWindowProc(MainDlgProc, hwndDlg, uMsg, wParam, lParam); +} + +int AddToPredefined(HWND hwndDlg, struct MsgBoxData *data) +{ + COMBOBOXEXITEM newitem = {0}; + int len = 0, num_items; + TCHAR msg[1024], text[1024]; + + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + len = GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg)); + + if (!len) + return -1; + + num_items = SendMessage(data->recent_cbex, CB_GETCOUNT, 0, 0) - 1; + for (int i = 1; i <= data->num_def_msgs; i++, num_items--) + { + newitem.mask = CBEIF_LPARAM | CBEIF_TEXT; + newitem.iItem = num_items; + newitem.cchTextMax = SIZEOF(text); + newitem.pszText = text; + + SendMessage(data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&newitem); + if (LOWORD(newitem.lParam) == PREDEFINED_MSG && !lstrcmp(text, msg)) + return num_items; + } + + data->num_def_msgs++; + data->m_bPredefChanged = TRUE; + + newitem.iItem = -1; + newitem.pszText = (LPTSTR)msg; + newitem.cchTextMax = SIZEOF(msg); + if (data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + newitem.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; + newitem.iImage = I_ICON_MSG; + newitem.iSelectedImage = I_ICON_MSG; + } + else + { + newitem.mask = CBEIF_LPARAM | CBEIF_TEXT | CBEIF_INDENT; + newitem.iIndent = 0; + } + newitem.lParam = MAKELPARAM(PREDEFINED_MSG, 0); + return SendMessage(data->recent_cbex, CBEM_INSERTITEM, 0, (LPARAM)&newitem); +} + +void ClearHistory(struct MsgBoxData *data, int cur_sel) +{ + COMBOBOXEXITEM histitem = {0}; + int i, num_items; + char text[16], buff2[80]; + + for (i = 1; i <= data->max_hist_msgs; i++) + { + mir_snprintf(text, SIZEOF(text), "SMsg%d", i); + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", text, _T("")); + } + DBWriteContactSettingString(NULL, "SimpleStatusMsg", "LastMsg", ""); + for (i = 0; i < accounts->count; i++) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(buff2, SIZEOF(buff2), "Last%sMsg", accounts->pa[i]->szModuleName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", buff2, ""); + } + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "LMMsg", (WORD)data->max_hist_msgs); + SendMessage(data->recent_cbex, CB_SETCURSEL, -1, 0); + num_items = SendMessage(data->recent_cbex, CB_GETCOUNT, 0, 0); + if (num_items == CB_ERR) + return; + + if ((!(data->m_iDlgFlags & DLG_SHOW_BUTTONS)) && (!(data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT))) + SendMessage(data->recent_cbex, CBEM_DELETEITEM, (WPARAM)cur_sel, 0); + + for (i = num_items; i >= 0; i--) + { + histitem.mask = CBEIF_LPARAM; + histitem.iItem = i; + SendMessage(data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&histitem); + if (LOWORD(histitem.lParam) == HISTORY_MSG) + SendMessage(data->recent_cbex, CBEM_DELETEITEM, (WPARAM)i, 0); + } +} + +void DisplayCharsCount(struct MsgBoxData *dlg_data, HWND hwndDlg) +{ + TCHAR msg[1024]; + TCHAR status_text[128]; + int len, lines = 1; + + if (dlg_data->m_iCountdown != -2) + return; + + len = GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg)); + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "RemoveCR", 0)) + { + int index, num_lines = SendMessage(GetDlgItem(hwndDlg, IDC_EDIT1), EM_GETLINECOUNT, 0, 0); + for (int i = 1; i < num_lines; ++i) + { + index = SendMessage(GetDlgItem(hwndDlg, IDC_EDIT1), EM_LINEINDEX, (WPARAM)i, 0); + if (msg[index - 1] == '\n') lines++; + } + } + mir_sntprintf(status_text, SIZEOF(status_text), TranslateT("OK (%d)"), len - (lines - 1)); + SendMessage(GetDlgItem(hwndDlg, IDC_OK), WM_SETTEXT, 0, (LPARAM)status_text); +} + +void SetEditControlText(struct MsgBoxData *data, HWND hwndDlg, int iStatus) +{ + int flags, fcursel = CB_ERR, num_start; + DBVARIANT dbv, dbv2; + char setting[80]; + + num_start = SendMessage(data->recent_cbex, CB_GETCOUNT, 0, 0); + num_start -= data->num_def_msgs + 1; + + mir_snprintf(setting, SIZEOF(setting), "%sFlags", data->m_szProto ? data->m_szProto : ""); + flags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", (char *)StatusModeToDbSetting(iStatus, setting), STATUS_DEFAULT); + + if (flags & STATUS_LAST_MSG) + { + if (data->m_szProto) + mir_snprintf(setting, SIZEOF(setting), "Last%sMsg", data->m_szProto); + else + mir_snprintf(setting, SIZEOF(setting), "LastMsg"); + + if (!DBGetContactSetting(NULL, "SimpleStatusMsg", setting, &dbv)) + { + if (dbv.pszVal) + { + if (strlen(dbv.pszVal) && !DBGetContactSettingTString(NULL, "SimpleStatusMsg", dbv.pszVal, &dbv2)) + { + if (dbv2.ptszVal && lstrlen(dbv2.ptszVal)) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, dbv2.ptszVal); + fcursel = SendMessage(data->recent_cbex, CB_FINDSTRINGEXACT, num_start, (LPARAM)dbv2.ptszVal); + if (fcursel != CB_ERR) + SendMessage(data->recent_cbex, CB_SETCURSEL, (WPARAM)fcursel, 0); + } + DBFreeVariant(&dbv2); + } + } + DBFreeVariant(&dbv); + } + } + else if (flags & STATUS_DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, GetDefaultMessage(iStatus)); + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "PutDefInList", 0)) + { + fcursel = SendMessage(data->recent_cbex, CB_FINDSTRINGEXACT, num_start, (LPARAM)GetDefaultMessage(iStatus)); + if (fcursel != CB_ERR) + SendMessage(data->recent_cbex, CB_SETCURSEL, (WPARAM)fcursel, 0); + } + } + else if (flags & STATUS_THIS_MSG) + { + if (data->m_szProto) + mir_snprintf(setting, SIZEOF(setting), "%sDefault", data->m_szProto); + else + mir_snprintf(setting, SIZEOF(setting), "Default"); + + if (!DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, setting), &dbv)) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, dbv.ptszVal); + fcursel = SendMessage(data->recent_cbex, CB_FINDSTRINGEXACT, num_start, (LPARAM)dbv.ptszVal); + if (fcursel != CB_ERR) + SendMessage(data->recent_cbex, CB_SETCURSEL, (WPARAM)fcursel, 0); + DBFreeVariant(&dbv); + } + } + else if (flags & STATUS_LAST_STATUS_MSG) + { + if (data->m_szProto) + mir_snprintf(setting, SIZEOF(setting), "%sMsg", data->m_szProto); + else + mir_snprintf(setting, SIZEOF(setting), "Msg"); + + if (!DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, setting), &dbv)) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, dbv.ptszVal); + fcursel = SendMessage(data->recent_cbex, CB_FINDSTRINGEXACT, num_start, (LPARAM)dbv.ptszVal); + if (fcursel != CB_ERR) + SendMessage(data->recent_cbex, CB_SETCURSEL, (WPARAM)fcursel, 0); + DBFreeVariant(&dbv); + } + } + + if (fcursel != CB_ERR) + data->curr_sel_msg = fcursel; +} + +void ChangeDlgStatus(HWND hwndDlg, struct MsgBoxData *msgbox_data, int iStatus) +{ + TCHAR szTitle[256], szProtoName[128]; + BOOL bDisabled = msgbox_data->m_szProto && !(CallProtoService(msgbox_data->m_szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND); + + mir_sntprintf(szProtoName, SIZEOF(szProtoName), msgbox_data->m_szProto ? ProtoGetAccount(msgbox_data->m_szProto)->tszAccountName : TranslateT("Global")); + if (iStatus == ID_STATUS_CURRENT) + { + if (msgbox_data->m_bOnStartup) + mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("%s Message (%s)"), TranslateT(""), szProtoName); + else + mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("%s Message (%s)"), TranslateT(""), szProtoName); + } + else if (iStatus > ID_STATUS_CURRENT) + { + TCHAR buff[128]; +#ifdef _UNICODE + char buff1[128]; + CallService(MS_SS_GETPROFILENAME, iStatus - 40083, (LPARAM)buff1); + MultiByteToWideChar(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0), 0, buff1, -1, buff, 128); +#else + CallService(MS_SS_GETPROFILENAME, iStatus - 40083, (LPARAM)buff); +#endif + mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("%s Message (%s)"), (TCHAR*)buff, szProtoName); + } + else + mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("%s Message (%s)"), (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, iStatus, GSMDF_TCHAR), szProtoName); + SetWindowText(hwndDlg, szTitle); + + if (iStatus == ID_STATUS_CURRENT) + iStatus = msgbox_data->m_bOnStartup ? GetStartupStatus(msgbox_data->m_szProto) : GetCurrentStatus(msgbox_data->m_szProto); + else if (iStatus > ID_STATUS_CURRENT) + iStatus = GetCurrentStatus(NULL); + + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedProtoIcon(msgbox_data->m_szProto, iStatus)), 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedProtoIcon(msgbox_data->m_szProto, iStatus)) , 0); + + if (!bDisabled && ((Proto_Status2Flag(iStatus) & msgbox_data->m_iStatusMsgModes) + || (iStatus == ID_STATUS_OFFLINE && (Proto_Status2Flag(ID_STATUS_INVISIBLE) & msgbox_data->m_iStatusMsgModes)))) + { + int num_items = SendMessage(msgbox_data->recent_cbex, CB_GETCOUNT, 0, 0); + int fcursel = CB_ERR, num_start = num_items - msgbox_data->num_def_msgs - 1; + TCHAR msg[1024]; + + if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), TRUE); + + if (!IsWindowEnabled(msgbox_data->recent_cbex) && num_items) + EnableWindow(msgbox_data->recent_cbex, TRUE); + + // TODO what if num_start <= 0 ? + if (GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg))) + fcursel = SendMessage(msgbox_data->recent_cbex, CB_FINDSTRINGEXACT, num_start, (LPARAM)msg); + if (fcursel != CB_ERR) + { + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, fcursel, 0); + msgbox_data->curr_sel_msg = fcursel; + } + + if ((msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + if (!GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg))) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + } + else if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + if (num_items) + { + if (msgbox_data->curr_sel_msg == -1) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + } + else + { + COMBOBOXEXITEM cbitem = {0}; + cbitem.mask = CBEIF_LPARAM | CBEIF_TEXT; + cbitem.iItem = msgbox_data->curr_sel_msg; + cbitem.cchTextMax = SIZEOF(msg); + cbitem.pszText = msg; + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&cbitem); + if (LOWORD(cbitem.lParam) == PREDEFINED_MSG) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + } + else if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + + if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), TRUE); + } + + if (msgbox_data->m_bIsMsgHistory && !IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BCLEAR))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), TRUE); + } + } + } + else + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), FALSE); + if (IsWindowEnabled(msgbox_data->recent_cbex)) + EnableWindow(msgbox_data->recent_cbex, FALSE); + + if ((msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BCLEAR))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), FALSE); + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + } + } +} + +#define DM_SIMPAWAY_SHUTDOWN (WM_USER + 10) +#define DM_SIMPAWAY_CHANGEICONS (WM_USER + 11) + +INT_PTR CALLBACK AwayMsgBoxDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + struct MsgBoxData *msgbox_data = (struct MsgBoxData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + TCHAR szTitle[256], szFormat[256], szProtoName[128]; + struct MsgBoxInitData *init_data; + struct MsgBoxData *copy_init_data; + INITCOMMONCONTROLSEX icex = {0}; + BOOL bCurrentStatus = FALSE, bDisabled = FALSE; + + InitCommonControls(); + icex.dwSize = sizeof(INITCOMMONCONTROLSEX); + icex.dwICC = ICC_USEREX_CLASSES; + InitCommonControlsEx(&icex); + + TranslateDialogDefault(hwndDlg); + init_data = (struct MsgBoxInitData*)lParam; + GetWindowText(hwndDlg, szFormat, SIZEOF(szFormat)); + mir_sntprintf(szProtoName, SIZEOF(szProtoName), init_data->m_szProto ? ProtoGetAccount(init_data->m_szProto)->tszAccountName : TranslateT("Global")); + + if (init_data->m_iStatus == ID_STATUS_CURRENT) + { + if (init_data->m_bOnStartup) + mir_sntprintf(szTitle, SIZEOF(szTitle), szFormat, TranslateT(""), szProtoName); + else + mir_sntprintf(szTitle, SIZEOF(szTitle), szFormat, TranslateT(""), szProtoName); + } + else + mir_sntprintf(szTitle, SIZEOF(szTitle), szFormat, (TCHAR*)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, init_data->m_iStatus, GSMDF_TCHAR), szProtoName); + SetWindowText(hwndDlg, szTitle); + + int icoStatus = ID_STATUS_OFFLINE; + if (init_data->m_iStatus == ID_STATUS_CURRENT) + icoStatus = init_data->m_bOnStartup ? GetStartupStatus(init_data->m_szProto) : GetCurrentStatus(init_data->m_szProto); + else + icoStatus = init_data->m_iStatus; + if (icoStatus < ID_STATUS_OFFLINE) + icoStatus = ID_STATUS_OFFLINE; + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadSkinnedProtoIcon(init_data->m_szProto, icoStatus)); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadSkinnedProtoIcon(init_data->m_szProto, icoStatus)); + + copy_init_data = (struct MsgBoxData *)mir_alloc(sizeof(struct MsgBoxData)); + + SendDlgItemMessage(hwndDlg, IDC_EDIT1, EM_LIMITTEXT, 1024, 0); + + HookEventMessage(ME_SYSTEM_PRESHUTDOWN, hwndDlg, DM_SIMPAWAY_SHUTDOWN); + HookEventMessage(ME_SKIN2_ICONSCHANGED, hwndDlg, DM_SIMPAWAY_CHANGEICONS); + + copy_init_data->num_def_msgs = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "DefMsgCount", 0); + copy_init_data->max_hist_msgs = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "MaxHist", 10); + copy_init_data->m_iDlgFlags = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "DlgFlags", DLG_SHOW_DEFAULT); + copy_init_data->m_szProto = init_data->m_szProto; + copy_init_data->m_iStatus = init_data->m_iStatus; + copy_init_data->m_iStatusModes = init_data->m_iStatusModes; + copy_init_data->m_iStatusMsgModes = init_data->m_iStatusMsgModes; + copy_init_data->m_iInitialStatus = init_data->m_iStatus; + copy_init_data->m_bOnStartup = init_data->m_bOnStartup; + + //Load Icons + copy_init_data->icon[I_ICON_DEL] = LoadIconEx("cross"); + copy_init_data->icon[I_ICON_HIST] = LoadIconEx("recent"); + copy_init_data->icon[I_ICON_MSG] = LoadIconEx("predef"); + copy_init_data->icon[I_ICON_ADD] = LoadIconEx("add"); + copy_init_data->icon[I_ICON_CLEAR] = LoadIconEx("clear"); + if (copy_init_data->m_iDlgFlags & DLG_SHOW_STATUS_ICONS) + copy_init_data->status_icons = AddStatusIconsToImageList(init_data->m_szProto, copy_init_data->m_iStatusModes); + if (copy_init_data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + copy_init_data->other_icons = AddOtherIconsToImageList(copy_init_data); + + if ((copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + SendMessage(GetDlgItem(hwndDlg, IDC_BADD), BUTTONADDTOOLTIP, (WPARAM)Translate("Add to Predefined"), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_BADD), BM_SETIMAGE, IMAGE_ICON, (LPARAM)copy_init_data->icon[I_ICON_ADD]); + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + ShowWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + + SendMessage(GetDlgItem(hwndDlg, IDC_BDEL), BUTTONADDTOOLTIP, (WPARAM)Translate("Delete Selected"), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_BDEL), BM_SETIMAGE, IMAGE_ICON, (LPARAM)copy_init_data->icon[I_ICON_DEL]); + ShowWindow(GetDlgItem(hwndDlg, IDC_BDEL), TRUE); + + SendMessage(GetDlgItem(hwndDlg, IDC_BCLEAR), BUTTONADDTOOLTIP, (WPARAM)Translate("Clear History"), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_BCLEAR), BM_SETIMAGE, IMAGE_ICON, (LPARAM)copy_init_data->icon[I_ICON_CLEAR]); + ShowWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), TRUE); + + if (copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT) + { + SendMessage(GetDlgItem(hwndDlg, IDC_BADD), BUTTONSETASFLATBTN, 0, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_BDEL), BUTTONSETASFLATBTN, 0, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_BCLEAR), BUTTONSETASFLATBTN, 0, 0); + } + } + else + { + SetWindowPos(GetDlgItem(hwndDlg, IDC_OK), NULL, 52, 115, 0, 0, SWP_NOSIZE|SWP_NOZORDER); + SetWindowPos(GetDlgItem(hwndDlg, IDC_CANCEL), NULL, 160, 115, 0, 0, SWP_NOSIZE|SWP_NOZORDER); + ShowWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + ShowWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + ShowWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), FALSE); + } + copy_init_data->status_cbex = CreateStatusComboBoxEx(hwndDlg, copy_init_data); + + if (copy_init_data->m_iStatus == ID_STATUS_CURRENT) + { + if (copy_init_data->m_bOnStartup) + copy_init_data->m_iStatus = GetStartupStatus(copy_init_data->m_szProto); + else + copy_init_data->m_iStatus = GetCurrentStatus(copy_init_data->m_szProto); + if (copy_init_data->m_szProto == NULL) + bCurrentStatus = TRUE; + } + + copy_init_data->recent_cbex = CreateRecentComboBoxEx(hwndDlg, copy_init_data); + copy_init_data->curr_sel_msg = -1; + copy_init_data->m_bPredefChanged = FALSE; + + SetEditControlText(copy_init_data, hwndDlg, copy_init_data->m_iStatus); + if ((copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + TCHAR msg[1024]; + + if (!GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + + if (copy_init_data->curr_sel_msg == -1) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + } + else + { + COMBOBOXEXITEM cbitem = {0}; + cbitem.mask = CBEIF_LPARAM|CBEIF_TEXT; + cbitem.iItem = copy_init_data->curr_sel_msg; + cbitem.cchTextMax = SIZEOF(msg); + cbitem.pszText = msg; + + SendMessage(copy_init_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&cbitem); + if (LOWORD(cbitem.lParam) == PREDEFINED_MSG) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + } + else if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + } + } + + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)copy_init_data); + + if (copy_init_data->m_szProto && !(CallProtoService(copy_init_data->m_szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + bDisabled = TRUE; + + if (!(((Proto_Status2Flag(copy_init_data->m_iStatus) & copy_init_data->m_iStatusMsgModes) || + (copy_init_data->m_iStatus == ID_STATUS_OFFLINE && (Proto_Status2Flag(ID_STATUS_INVISIBLE) & copy_init_data->m_iStatusMsgModes))) && !bDisabled)) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT1), FALSE); + if (IsWindowEnabled(copy_init_data->recent_cbex)) + EnableWindow(copy_init_data->recent_cbex, FALSE); + + if ((copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (copy_init_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BCLEAR))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), FALSE); + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + } + } + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AutoClose", 1) && init_data->m_bOnEvent) + { + copy_init_data->m_iCountdown = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "DlgTime", 5); + SendMessage(hwndDlg, WM_TIMER, 0, 0); + SetTimer(hwndDlg, 1, 1000, 0); + } + else + { + copy_init_data->m_iCountdown = -2; + DisplayCharsCount(copy_init_data, hwndDlg); + } + + if (bCurrentStatus) + copy_init_data->m_iStatus = ID_STATUS_CURRENT; + + mir_free(init_data); + + MainDlgProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT1), GWLP_WNDPROC, (LONG_PTR)EditBoxSubProc); + if (!init_data->m_bOnEvent && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + { + SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1)); + SendMessage(GetDlgItem(hwndDlg, IDC_EDIT1), EM_SETSEL, 0, -1); + } + else + SetFocus(GetDlgItem(hwndDlg, IDC_OK)); + + if (!DBGetContactSettingByte(NULL, "SimpleStatusMsg", "WinCentered", 1)) + { + WINDOWPLACEMENT wp; + int x, y; + + wp.length = sizeof(wp); + GetWindowPlacement(hwndDlg, &wp); + + x = (int)DBGetContactSettingDword(NULL, "SimpleStatusMsg", "Winx", -1); + y = (int)DBGetContactSettingDword(NULL, "SimpleStatusMsg", "Winy", -1); + + if (x !=- 1) + { + OffsetRect(&wp.rcNormalPosition, x - wp.rcNormalPosition.left, y - wp.rcNormalPosition.top); + wp.flags = 0; + SetWindowPlacement(hwndDlg, &wp); + } + } + return FALSE; + } + + case WM_TIMER: + if (msgbox_data->m_iCountdown == -1) + { + SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_OK, 0); + msgbox_data->m_iCountdown = -2; + DisplayCharsCount(msgbox_data, hwndDlg); + break; + } + else + { + TCHAR str[64]; + mir_sntprintf(str, SIZEOF(str), TranslateT("Closing in %d"), msgbox_data->m_iCountdown); + SetDlgItemText(hwndDlg, IDC_OK, str); + } + msgbox_data->m_iCountdown--; + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_OK: + { + TCHAR tszMsg[1024]; + int iStatus, iMsgLen = 0, iProfileStatus = 0; + BOOL bCurrentStatus = FALSE; + + if (msgbox_data->m_iStatus == ID_STATUS_CURRENT) + { + msgbox_data->m_iStatus = msgbox_data->m_bOnStartup ? GetStartupStatus(msgbox_data->m_szProto) : GetCurrentStatus(msgbox_data->m_szProto); + if (msgbox_data->m_szProto == NULL) + bCurrentStatus = TRUE; + } + else if (msgbox_data->m_iStatus >= ID_STATUS_CURRENT) + { + iProfileStatus = msgbox_data->m_iStatus; + msgbox_data->m_iStatus = GetCurrentStatus(NULL); + } + + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + iMsgLen = GetDlgItemText(hwndDlg, IDC_EDIT1, tszMsg, SIZEOF(tszMsg)); + + if (iMsgLen == 0) + { + char szSetting[80]; + if (msgbox_data->m_szProto) + { + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sMsg", msgbox_data->m_szProto); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", szSetting, ""); + + mir_snprintf(szSetting, SIZEOF(szSetting), "%sMsg", msgbox_data->m_szProto); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(msgbox_data->m_iStatus, szSetting), _T("")); + } + else + { + DBWriteContactSettingString(NULL, "SimpleStatusMsg", "LastMsg", ""); + for (int j = 0; j < accounts->count; j++) + { + if (!IsAccountEnabled(accounts->pa[j])) + continue; + + if (!CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (DBGetContactSettingByte(NULL, accounts->pa[j]->szModuleName, "LockMainStatus", 0)) + continue; + + if (!(CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sMsg", accounts->pa[j]->szModuleName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", szSetting, ""); + + mir_snprintf(szSetting, SIZEOF(szSetting), "%sMsg", accounts->pa[j]->szModuleName); + iStatus = msgbox_data->m_bOnStartup ? GetStartupStatus(accounts->pa[j]->szModuleName) : GetCurrentStatus(accounts->pa[j]->szModuleName); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, szSetting), _T("")); + } + + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(msgbox_data->m_iStatus, "Msg"), _T("")); // for compatibility with some plugins + } + + if (bCurrentStatus) + SetStatusMessage(msgbox_data->m_szProto, msgbox_data->m_iInitialStatus, ID_STATUS_CURRENT, 0, msgbox_data->m_bOnStartup); + else if (iProfileStatus != 0) + SetStatusMessage(msgbox_data->m_szProto, msgbox_data->m_iInitialStatus, iProfileStatus, 0, FALSE); + else + SetStatusMessage(msgbox_data->m_szProto, msgbox_data->m_iInitialStatus, msgbox_data->m_iStatus, 0, msgbox_data->m_bOnStartup); + } + else + { + char buff[64], buff2[80]; + DBVARIANT dbv; + BOOL found = FALSE; + + for (int i = 1; i <= msgbox_data->max_hist_msgs; i++) + { + mir_snprintf(buff, SIZEOF(buff), "SMsg%d", i); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", buff, &dbv)) + { + if (!lstrcmp(dbv.ptszVal, tszMsg)) + { + found = TRUE; + if (msgbox_data->m_szProto) + { + mir_snprintf(buff2, SIZEOF(buff2), "Last%sMsg", msgbox_data->m_szProto); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", buff2, buff); + + mir_snprintf(buff2, SIZEOF(buff2), "%sMsg", msgbox_data->m_szProto); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(msgbox_data->m_iStatus, buff2), tszMsg); + } + else + { + DBWriteContactSettingString(NULL, "SimpleStatusMsg", "LastMsg", buff); + for (int j = 0; j < accounts->count; j++) + { + if (!IsAccountEnabled(accounts->pa[j])) + continue; + + if (!CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (DBGetContactSettingByte(NULL, accounts->pa[j]->szModuleName, "LockMainStatus", 0)) + continue; + + if (!(CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(buff2, SIZEOF(buff2), "Last%sMsg", accounts->pa[j]->szModuleName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", buff2, buff); + + mir_snprintf(buff2, SIZEOF(buff2), "%sMsg", accounts->pa[j]->szModuleName); + iStatus = msgbox_data->m_bOnStartup ? GetStartupStatus(accounts->pa[j]->szModuleName) : GetCurrentStatus(accounts->pa[j]->szModuleName); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, buff2), tszMsg); + } + } + DBFreeVariant(&dbv); + break; + } + } + } + + if (!found) + { + int last_modified_msg = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "LMMsg", msgbox_data->max_hist_msgs); + + if (last_modified_msg == msgbox_data->max_hist_msgs) + last_modified_msg = 1; + else + last_modified_msg++; + + mir_snprintf(buff, SIZEOF(buff), "SMsg%d", last_modified_msg); + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", buff, tszMsg); + + if (msgbox_data->m_szProto) + { + mir_snprintf(buff2, SIZEOF(buff2), "Last%sMsg", msgbox_data->m_szProto); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", buff2, buff); + + mir_snprintf(buff2, SIZEOF(buff2), "%sMsg", msgbox_data->m_szProto); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(msgbox_data->m_iStatus, buff2), tszMsg); + } + else + { + DBWriteContactSettingString(NULL, "SimpleStatusMsg", "LastMsg", buff); + for (int j = 0; j < accounts->count; j++) + { + if (!IsAccountEnabled(accounts->pa[j])) + continue; + + if (!CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (DBGetContactSettingByte(NULL, accounts->pa[j]->szModuleName, "LockMainStatus", 0)) + continue; + + if (!(CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(buff2, SIZEOF(buff2), "Last%sMsg", accounts->pa[j]->szModuleName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", buff2, buff); + + mir_snprintf(buff2, SIZEOF(buff2), "%sMsg", accounts->pa[j]->szModuleName); + iStatus = msgbox_data->m_bOnStartup ? GetStartupStatus(accounts->pa[j]->szModuleName) : GetCurrentStatus(accounts->pa[j]->szModuleName); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(iStatus, buff2), tszMsg); + } + } + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "LMMsg", (WORD)last_modified_msg); + } + + if (!msgbox_data->m_szProto) + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(msgbox_data->m_iStatus, "Msg"), tszMsg); // for compatibility with some plugins + + if (bCurrentStatus) + SetStatusMessage(msgbox_data->m_szProto, msgbox_data->m_iInitialStatus, ID_STATUS_CURRENT, tszMsg, msgbox_data->m_bOnStartup); + else if (iProfileStatus != 0) + SetStatusMessage(msgbox_data->m_szProto, msgbox_data->m_iInitialStatus, iProfileStatus, tszMsg, FALSE); + else + SetStatusMessage(msgbox_data->m_szProto, msgbox_data->m_iInitialStatus, msgbox_data->m_iStatus, tszMsg, msgbox_data->m_bOnStartup); + } + } + + case IDCANCEL: + case IDC_CANCEL: + DestroyWindow(hwndDlg); + return TRUE; + + case IDC_EDIT1: // Notification from the edit control + if (msgbox_data->m_iCountdown > -2) + { + KillTimer(hwndDlg, 1); + msgbox_data->m_iCountdown = -2; + DisplayCharsCount(msgbox_data, hwndDlg); + } + switch (HIWORD(wParam)) + { + case EN_CHANGE: + DisplayCharsCount(msgbox_data, hwndDlg); + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, -1, 0); + if ((msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + TCHAR msg[1024]; + + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + + if (!GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg))) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + } + else if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + } + break; + } + break; + } + + if ((HWND)lParam == msgbox_data->status_cbex) + { + if (msgbox_data->m_iCountdown > -2) + { + KillTimer(hwndDlg, 1); + msgbox_data->m_iCountdown = -2; + DisplayCharsCount(msgbox_data, hwndDlg); + } + switch (HIWORD(wParam)) + { + case CBN_SELENDOK: + case CBN_SELCHANGE: + { + COMBOBOXEXITEM cbitem = {0}; + + cbitem.mask = CBEIF_LPARAM; + cbitem.iItem = SendMessage(msgbox_data->status_cbex, CB_GETCURSEL, 0, 0); + SendMessage(msgbox_data->status_cbex, CBEM_GETITEM, 0, (LPARAM)&cbitem); + + msgbox_data->m_iStatus = cbitem.lParam; + ChangeDlgStatus(hwndDlg, msgbox_data, (int)cbitem.lParam); + + if (HIWORD(wParam) == CBN_SELENDOK && IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1)); + break; + } + } + } + + if ((HWND)lParam == msgbox_data->recent_cbex) + { + if (msgbox_data->m_iCountdown > -2) + { + KillTimer(hwndDlg, 1); + msgbox_data->m_iCountdown = -2; + DisplayCharsCount(msgbox_data, hwndDlg); + } + switch (HIWORD(wParam)) + { + case CBN_SELENDOK: + { + TCHAR text[1024]; + int cur_sel = SendMessage(msgbox_data->recent_cbex, CB_GETCURSEL, 0, 0); + COMBOBOXEXITEM cbitem = {0}; + + cbitem.mask = CBEIF_LPARAM | CBEIF_TEXT; + cbitem.iItem = cur_sel; + cbitem.cchTextMax = SIZEOF(text); + cbitem.pszText = text; + + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&cbitem); + if (LOWORD(cbitem.lParam) == HISTORY_MSG || LOWORD(cbitem.lParam) == PREDEFINED_MSG || LOWORD(cbitem.lParam) == DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, text); + DisplayCharsCount(msgbox_data, hwndDlg); + if ((msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), TRUE); + if (LOWORD(cbitem.lParam) == PREDEFINED_MSG) + { + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + } + else if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), TRUE); + } + } + else if (LOWORD(cbitem.lParam) == CLEAR_HISTORY) + { + if (MessageBox(NULL, TranslateT("Are you sure you want to clear status message history?"), TranslateT("Confirm clearing history"), MB_ICONQUESTION | MB_YESNO) == IDYES) + { + ClearHistory(msgbox_data, cur_sel); + } + else if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + { + TCHAR msg[1024]; + int fcursel = CB_ERR, num_start; + num_start = SendMessage(msgbox_data->recent_cbex, CB_GETCOUNT, 0, 0); + num_start -= msgbox_data->num_def_msgs + 1; + GetDlgItemText(hwndDlg, IDC_EDIT1, msg, SIZEOF(msg)); + fcursel = SendMessage(msgbox_data->recent_cbex, CB_FINDSTRINGEXACT, num_start, (LPARAM)msg); + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, fcursel, 0); + } + } + else if (LOWORD(cbitem.lParam) == DELETE_SELECTED) + { + COMBOBOXEXITEM histitem = {0}; + BOOL scursel = FALSE; + + histitem.mask = CBEIF_LPARAM; + histitem.iItem = msgbox_data->curr_sel_msg; + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&histitem); + + if (LOWORD(histitem.lParam) == HISTORY_MSG) + { + char szSetting[16]; + mir_snprintf(szSetting, SIZEOF(szSetting), "SMsg%d", (int)HIWORD(histitem.lParam)); + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", szSetting, _T("")); + SendMessage(msgbox_data->recent_cbex, CBEM_DELETEITEM, (WPARAM)msgbox_data->curr_sel_msg, 0); + } + if (LOWORD(histitem.lParam) == PREDEFINED_MSG) + { + msgbox_data->m_bPredefChanged = TRUE; + SendMessage(msgbox_data->recent_cbex, CBEM_DELETEITEM, (WPARAM)msgbox_data->curr_sel_msg, 0); + } + + cur_sel = msgbox_data->curr_sel_msg; + while (!scursel) + { + if (cur_sel - 1 >= 0) + cur_sel--; + else + { + scursel = TRUE; + break; + } + histitem.mask = CBEIF_LPARAM; + histitem.iItem = cur_sel; + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&histitem); + + if ((LOWORD(histitem.lParam) != CLEAR_HISTORY) && (LOWORD(histitem.lParam) != DELETE_SELECTED) && (LOWORD(histitem.lParam) != ADD_MSG)) + scursel = TRUE; + } + msgbox_data->curr_sel_msg = cur_sel; + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, (WPARAM)cur_sel, 0); + + histitem.mask = CBEIF_LPARAM | CBEIF_TEXT; + histitem.iItem = cur_sel; + histitem.cchTextMax = SIZEOF(text); + histitem.pszText = text; + + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&histitem); + if (LOWORD(histitem.lParam) == HISTORY_MSG || LOWORD(histitem.lParam) == PREDEFINED_MSG || LOWORD(histitem.lParam) == DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, text); + DisplayCharsCount(msgbox_data, hwndDlg); + } + } + else if (LOWORD(cbitem.lParam) == ADD_MSG) + { + int sel = AddToPredefined(hwndDlg, msgbox_data); + if (sel != -1) + { + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, (WPARAM)sel, 0); + msgbox_data->curr_sel_msg = sel; + } + else + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, (WPARAM)msgbox_data->curr_sel_msg, 0); + break; + } + msgbox_data->curr_sel_msg = cur_sel; + + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_EDIT1))) + { + SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1)); + SendMessage(GetDlgItem(hwndDlg, IDC_EDIT1), EM_SETSEL, 0, -1); + } + break; + } + } + } + + if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_BADD)) + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + int sel = AddToPredefined(hwndDlg, msgbox_data); + if (sel != -1) + { + if (!IsWindowEnabled(msgbox_data->recent_cbex)) + EnableWindow(msgbox_data->recent_cbex, TRUE); + if (!IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BDEL))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), TRUE); + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BADD))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), FALSE); + + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, (WPARAM)sel, 0); + msgbox_data->curr_sel_msg = sel; + } + break; + } + } + } + + if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_BCLEAR)) + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + if (MessageBox(NULL, TranslateT("Are you sure you want to clear status message history?"), TranslateT("Confirm clearing history"), MB_ICONQUESTION | MB_YESNO) == IDYES) + { + ClearHistory(msgbox_data, 0); + + int num_items = SendMessage(msgbox_data->recent_cbex, CB_GETCOUNT, 0, 0); + if (!num_items) + { + if (IsWindowEnabled(msgbox_data->recent_cbex)) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + EnableWindow(msgbox_data->recent_cbex, FALSE); + } + } + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), FALSE); + } + break; + } + } + + if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_BDEL)) + { + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + int cur_sel; + char buff[16]; + int left_items = 0; + COMBOBOXEXITEM histitem = {0}; + + cur_sel = SendMessage(msgbox_data->recent_cbex, CB_GETCURSEL, 0, 0); + + histitem.mask = CBEIF_LPARAM; + histitem.iItem = msgbox_data->curr_sel_msg; + + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&histitem); + + if (LOWORD(histitem.lParam) == HISTORY_MSG) + { + mir_snprintf(buff, SIZEOF(buff), "SMsg%d", (int)HIWORD(histitem.lParam)); + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", buff, _T("")); + } + else if (LOWORD(histitem.lParam) == PREDEFINED_MSG) + { + msgbox_data->m_bPredefChanged = TRUE; + } + left_items = SendMessage(msgbox_data->recent_cbex, CBEM_DELETEITEM, (WPARAM)msgbox_data->curr_sel_msg, 0); + + if (!left_items) + { + if (IsWindowEnabled(msgbox_data->recent_cbex)) + EnableWindow(msgbox_data->recent_cbex, FALSE); + if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_BCLEAR))) + EnableWindow(GetDlgItem(hwndDlg, IDC_BCLEAR), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BDEL), FALSE); + } + else + { + TCHAR text[1024]; + + if (cur_sel - 1 >= 0) + cur_sel--; + msgbox_data->curr_sel_msg = cur_sel; + SendMessage(msgbox_data->recent_cbex, CB_SETCURSEL, (WPARAM)cur_sel, 0); + + histitem.mask = CBEIF_LPARAM | CBEIF_TEXT; + histitem.iItem = cur_sel; + histitem.cchTextMax = SIZEOF(text); + histitem.pszText = text; + + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&histitem); + if (LOWORD(histitem.lParam) == HISTORY_MSG || LOWORD(histitem.lParam) == PREDEFINED_MSG || LOWORD(histitem.lParam) == DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_EDIT1, text); + DisplayCharsCount(msgbox_data, hwndDlg); + EnableWindow(GetDlgItem(hwndDlg, IDC_BADD), LOWORD(histitem.lParam) == PREDEFINED_MSG ? FALSE : TRUE); + } + } + break; + } + } + } + break; + + case DM_SIMPAWAY_SHUTDOWN: + DestroyWindow(hwndDlg); + break; + + case DM_SIMPAWAY_CHANGEICONS: + ReleaseIconEx("cross"); + ReleaseIconEx("recent"); + ReleaseIconEx("predef"); + ReleaseIconEx("add"); + ReleaseIconEx("clear"); + msgbox_data->icon[I_ICON_DEL] = LoadIconEx("cross"); + msgbox_data->icon[I_ICON_HIST] = LoadIconEx("recent"); + msgbox_data->icon[I_ICON_MSG] = LoadIconEx("predef"); + msgbox_data->icon[I_ICON_ADD] = LoadIconEx("add"); + msgbox_data->icon[I_ICON_CLEAR] = LoadIconEx("clear"); + if (msgbox_data->m_iDlgFlags & DLG_SHOW_LIST_ICONS) + { + for (int i = 0; i < 5; ++i) + ImageList_ReplaceIcon(msgbox_data->other_icons, i, msgbox_data->icon[i]); + } + if ((msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS) || (msgbox_data->m_iDlgFlags & DLG_SHOW_BUTTONS_FLAT)) + { + SendMessage(GetDlgItem(hwndDlg, IDC_BADD), BM_SETIMAGE, IMAGE_ICON, (LPARAM)msgbox_data->icon[I_ICON_ADD]); + SendMessage(GetDlgItem(hwndDlg, IDC_BCLEAR), BM_SETIMAGE, IMAGE_ICON, (LPARAM)msgbox_data->icon[I_ICON_CLEAR]); + SendMessage(GetDlgItem(hwndDlg, IDC_BDEL), BM_SETIMAGE, IMAGE_ICON, (LPARAM)msgbox_data->icon[I_ICON_DEL]); + } + break; + + case WM_DESTROY: + { + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + GetWindowPlacement(hwndDlg, &wp); + DBWriteContactSettingDword(NULL, "SimpleStatusMsg", "Winx", wp.rcNormalPosition.left); + DBWriteContactSettingDword(NULL, "SimpleStatusMsg", "Winy", wp.rcNormalPosition.top); + + if (msgbox_data->m_bPredefChanged) + { + int i, num_items, new_num_def_msgs = 0; + COMBOBOXEXITEM cbitem = {0}; + TCHAR text[1024]; + char buff[64]; + + num_items = SendMessage(msgbox_data->recent_cbex, CB_GETCOUNT, 0, 0); + num_items--; + for (i = 1; i <= msgbox_data->num_def_msgs; i++) + { + cbitem.mask = CBEIF_LPARAM|CBEIF_TEXT; + cbitem.iItem = num_items; + cbitem.cchTextMax = SIZEOF(text); + cbitem.pszText = text; + + SendMessage(msgbox_data->recent_cbex, CBEM_GETITEM, 0, (LPARAM)&cbitem); + mir_snprintf(buff, SIZEOF(buff), "DefMsg%d", i); + if (LOWORD(cbitem.lParam) == PREDEFINED_MSG) + { + new_num_def_msgs++; + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", buff, text); + } + else + DBDeleteContactSetting(NULL, "SimpleStatusMsg", buff); + num_items--; + } + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "DefMsgCount", (WORD)new_num_def_msgs); + } + + ImageList_Destroy(msgbox_data->status_icons); + ImageList_Destroy(msgbox_data->other_icons); + ReleaseIconEx("cross"); + ReleaseIconEx("recent"); + ReleaseIconEx("predef"); + ReleaseIconEx("add"); + ReleaseIconEx("clear"); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0); + + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_EDIT1), GWLP_WNDPROC, (LONG_PTR)MainDlgProc); + if (msgbox_data) + mir_free(msgbox_data); + hwndSAMsgDialog = NULL; + break; + } + } + return FALSE; +} diff --git a/plugins/SimpleStatusMsg/options.cpp b/plugins/SimpleStatusMsg/options.cpp new file mode 100644 index 0000000000..b67583776b --- /dev/null +++ b/plugins/SimpleStatusMsg/options.cpp @@ -0,0 +1,1752 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "commonheaders.h" +#include "simplestatusmsg.h" + +extern UINT_PTR g_uUpdateMsgTimer; +extern VOID CALLBACK UpdateMsgTimerProc(HWND, UINT, UINT_PTR, DWORD); +extern VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, HWND edit_control); + +static WNDPROC OldDlgProc; + +static void RebuildStatusMenu(void) +{ + CLIST_INTERFACE* pcli = (CLIST_INTERFACE*)CallService(MS_CLIST_RETRIEVE_INTERFACE, 0, 0); + if (pcli && pcli->version > 4) + pcli->pfnReloadProtoMenus(); +} + +static LRESULT CALLBACK OptEditBoxSubProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_CONTEXTMENU: + { + POINT pt = {(LONG)LOWORD(lParam), (LONG)HIWORD(lParam)}; + RECT rc; + GetClientRect(hwndDlg, &rc); + + if (pt.x == -1 && pt.y == -1) + { + GetCursorPos(&pt); + if (!PtInRect(&rc, pt)) + { + pt.x = rc.left + (rc.right - rc.left) / 2; + pt.y = rc.top + (rc.bottom - rc.top) / 2; + } + } + else + ScreenToClient(hwndDlg, &pt); + + if (PtInRect(&rc, pt)) + HandlePopupMenu(hwndDlg, pt, GetDlgItem(GetParent(hwndDlg), IDC_OPTEDIT1)); + + return 0; + } + + case WM_CHAR: + if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) // Ctrl + A + { + SendMessage(hwndDlg, EM_SETSEL, 0, -1); + return 0; + } + if (wParam == 127 && GetKeyState(VK_CONTROL) & 0x8000) // Ctrl + Backspace + { + DWORD start, end; + TCHAR *text; + int textLen; + SendMessage(hwndDlg, EM_GETSEL, (WPARAM)&end, (LPARAM)(PDWORD)NULL); + SendMessage(hwndDlg, WM_KEYDOWN, VK_LEFT, 0); + SendMessage(hwndDlg, EM_GETSEL, (WPARAM)&start, (LPARAM)(PDWORD)NULL); + textLen = GetWindowTextLength(hwndDlg); + text = (TCHAR *)mir_alloc(sizeof(TCHAR) * (textLen + 1)); + GetWindowText(hwndDlg, text, textLen + 1); + MoveMemory(text + start, text + end, sizeof(TCHAR) * (textLen + 1 - end)); + SetWindowText(hwndDlg, text); + mir_free(text); + SendMessage(hwndDlg, EM_SETSEL, start, start); + SendMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwndDlg), EN_CHANGE), (LPARAM)hwndDlg); + return 0; + } + break; + } + + return CallWindowProc(OldDlgProc, hwndDlg, uMsg, wParam, lParam); +} + +struct SingleProtoMsg +{ + int flags; + TCHAR *msg; + int max_length; +}; + +struct SingleStatusMsg +{ + int flags[9]; + TCHAR msg[9][1024]; +}; + +struct OptDlgData +{ + BOOL proto_ok; + struct SingleProtoMsg *proto_msg; + struct SingleStatusMsg *status_msg; +}; + +static INT_PTR CALLBACK DlgOptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + struct OptDlgData *data = (struct OptDlgData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + int val, i, index; + DBVARIANT dbv; + + TranslateDialogDefault(hwndDlg); + + data = (struct OptDlgData *)mir_alloc(sizeof(struct OptDlgData)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data); + + SendDlgItemMessage(hwndDlg, IDC_OPTEDIT1, EM_LIMITTEXT, 1024, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_SMAXLENGTH), UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_EMAXLENGTH), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_SMAXLENGTH), UDM_SETRANGE32, 1, 1024); + SendMessage(GetDlgItem(hwndDlg, IDC_EMAXLENGTH), EM_LIMITTEXT, 4, 0); + + data->status_msg = (struct SingleStatusMsg *)mir_alloc(sizeof(struct SingleStatusMsg)*(accounts->count + 1)); + + for (i = ID_STATUS_ONLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + { + if (accounts->statusMsgFlags & Proto_Status2Flag(i)) + { + index = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_INSERTSTRING, -1, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, i, GSMDF_TCHAR)); + if (index != CB_ERR && index != CB_ERRSPACE) + { + int j; + char setting[80]; + + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETITEMDATA, (WPARAM)index, (LPARAM)i - ID_STATUS_ONLINE); + + val = DBGetContactSettingByte(NULL, "SimpleStatusMsg", (char *)StatusModeToDbSetting(i, "Flags"), STATUS_DEFAULT); + data->status_msg[0].flags[i - ID_STATUS_ONLINE] = val; + if (DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(i, "Default"), &dbv)) + dbv.ptszVal = mir_tstrdup(GetDefaultMessage(i)); + lstrcpy(data->status_msg[0].msg[i - ID_STATUS_ONLINE], dbv.ptszVal); + mir_free(dbv.ptszVal); + DBFreeVariant(&dbv); + + for (j = 0; j < accounts->count; j++) + { + if (!IsAccountEnabled(accounts->pa[j]) || !CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) || !(CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(setting, SIZEOF(setting), "%sFlags", accounts->pa[j]->szModuleName); + val = DBGetContactSettingByte(NULL, "SimpleStatusMsg", (char *)StatusModeToDbSetting(i, setting), STATUS_DEFAULT); + data->status_msg[j+1].flags[i-ID_STATUS_ONLINE] = val; + mir_snprintf(setting, SIZEOF(setting), "%sDefault", accounts->pa[j]->szModuleName); + if (DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(i, setting), &dbv)) + dbv.ptszVal = mir_tstrdup(GetDefaultMessage(i)); + lstrcpy(data->status_msg[j + 1].msg[i - ID_STATUS_ONLINE], dbv.ptszVal); + mir_free(dbv.ptszVal); + DBFreeVariant(&dbv); + } + } + } + } + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETCURSEL, 0, 0); + + data->proto_msg = (struct SingleProtoMsg *)mir_alloc(sizeof(struct SingleProtoMsg)*(accounts->count + 1)); + if (!data->proto_msg) + { + // TODO not really needed? + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTPROTO), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO2), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO3), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO4), FALSE); + data->proto_ok = FALSE; + } + else + { + char setting[64]; + + data->proto_ok = TRUE; + + index = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_ADDSTRING, 0, (LPARAM)TranslateT("Global status change")); +// SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETITEMDATA, index, 0); + if (index != CB_ERR && index != CB_ERRSPACE) + { + data->proto_msg[0].msg = NULL; + + val = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ProtoFlags", PROTO_DEFAULT); + data->proto_msg[0].flags = val; + data->proto_msg[0].max_length = 0; + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETITEMDATA, (WPARAM)index, 0); + } + + for (i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i]) + || !CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) + || !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + { + data->proto_msg[i+1].msg = NULL; + continue; + } + + index = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_ADDSTRING, 0, (LPARAM)accounts->pa[i]->tszAccountName); +// SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETITEMDATA, index, (LPARAM)i + 1); + if (index != CB_ERR && index != CB_ERRSPACE) + { + mir_snprintf(setting, SIZEOF(setting), "Proto%sDefault", accounts->pa[i]->szModuleName); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", setting, &dbv)) + { + data->proto_msg[i+1].msg = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + data->proto_msg[i+1].msg = NULL; + + mir_snprintf(setting, SIZEOF(setting), "Proto%sFlags", accounts->pa[i]->szModuleName); + val = DBGetContactSettingByte(NULL, "SimpleStatusMsg", setting, PROTO_DEFAULT); + data->proto_msg[i+1].flags = val; + mir_snprintf(setting, SIZEOF(setting), "Proto%sMaxLen", accounts->pa[i]->szModuleName); + val = DBGetContactSettingWord(NULL, "SimpleStatusMsg", setting, 1024); + data->proto_msg[i+1].max_length = val; + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETITEMDATA, (WPARAM)index, (LPARAM)i + 1); + } + } + + if (accounts->statusMsgCount == 1) + { +// ShowWindow(GetDlgItem(hwndDlg, IDC_BOPTPROTO), SW_HIDE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTPROTO), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), FALSE); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETCURSEL, 1, 0); + } + else + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_SETCURSEL, 0, 0); + + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_CBOPTPROTO, CBN_SELCHANGE), (LPARAM)GetDlgItem(hwndDlg, IDC_CBOPTPROTO)); + } + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "PutDefInList", 0)) + CheckDlgButton(hwndDlg, IDC_COPTMSG2, BST_CHECKED); + + if (ServiceExists(MS_VARS_FORMATSTRING)) + { + HICON hIcon=NULL; + char *szTipInfo=NULL; + + if (ServiceExists(MS_VARS_GETSKINITEM)) + { + hIcon = (HICON)CallService(MS_VARS_GETSKINITEM, 0, VSI_HELPICON); + szTipInfo = (char *)CallService(MS_VARS_GETSKINITEM, 0, VSI_HELPTIPTEXT); + } + + if (hIcon != NULL) + SendMessage(GetDlgItem(hwndDlg, IDC_VARSHELP), BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + else + SetDlgItemText(hwndDlg, IDC_VARSHELP, _T("V")); + + if (szTipInfo == NULL) + SendMessage(GetDlgItem(hwndDlg, IDC_VARSHELP), BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open String Formatting Help"), 0); + else + SendMessage(GetDlgItem(hwndDlg, IDC_VARSHELP), BUTTONADDTOOLTIP, (WPARAM)szTipInfo, 0); + + SendDlgItemMessage(hwndDlg, IDC_VARSHELP, BUTTONSETASFLATBTN, 0, 0); + } + ShowWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), ServiceExists(MS_VARS_FORMATSTRING)); + + OldDlgProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_OPTEDIT1), GWLP_WNDPROC, (LONG_PTR)OptEditBoxSubProc); + + return TRUE; + } + + case WM_COMMAND: + if ( ( (HIWORD(wParam) == BN_CLICKED) || /*(HIWORD(wParam) == EN_KILLFOCUS) ||*/ (HIWORD(wParam) == EN_CHANGE) + || ( (HIWORD(wParam) == CBN_SELCHANGE) && (LOWORD(wParam) != IDC_CBOPTPROTO) && (LOWORD(wParam) != IDC_CBOPTSTATUS) ) + ) && (HWND)lParam == GetFocus() ) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + switch (LOWORD(wParam)) + { + case IDC_EMAXLENGTH: + switch (HIWORD(wParam)) + { + case EN_KILLFOCUS: + { + BOOL translated; + int val, i; + + val = GetDlgItemInt(hwndDlg, IDC_EMAXLENGTH, &translated, FALSE); + if (translated && val > 1024) + SetDlgItemInt(hwndDlg, IDC_EMAXLENGTH, 1024, FALSE); + if (translated && val < 1) + SetDlgItemInt(hwndDlg, IDC_EMAXLENGTH, 1, FALSE); + val = GetDlgItemInt(hwndDlg, IDC_EMAXLENGTH, &translated, FALSE); + + i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + data->proto_msg[i].max_length = val; + break; + } + } + break; + + case IDC_CBOPTPROTO: + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE: + case CBN_SELENDOK: + { + int i, j, l, k, status_modes = 0, newindex = 0; + + i = SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); + + if (i == 0) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_MAXLENGTH), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EMAXLENGTH), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SMAXLENGTH), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO3), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO4), FALSE); + SetDlgItemInt(hwndDlg, IDC_EMAXLENGTH, 1024, FALSE); + + if (data->proto_msg[i].flags & PROTO_POPUPDLG) + CheckRadioButton(hwndDlg, IDC_ROPTPROTO1, IDC_ROPTPROTO4, IDC_ROPTPROTO1); + else if (data->proto_msg[i].flags & PROTO_NOCHANGE) + CheckRadioButton(hwndDlg, IDC_ROPTPROTO1, IDC_ROPTPROTO4, IDC_ROPTPROTO2); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_MAXLENGTH), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_EMAXLENGTH), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_SMAXLENGTH), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO3), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTPROTO4), TRUE); + SetDlgItemInt(hwndDlg, IDC_EMAXLENGTH, data->proto_msg[i].max_length, FALSE); + + if (data->proto_msg[i].flags & PROTO_POPUPDLG) + CheckRadioButton(hwndDlg, IDC_ROPTPROTO1, IDC_ROPTPROTO4, IDC_ROPTPROTO1); + else if (data->proto_msg[i].flags & PROTO_NOCHANGE) + CheckRadioButton(hwndDlg, IDC_ROPTPROTO1, IDC_ROPTPROTO4, IDC_ROPTPROTO2); + else if (data->proto_msg[i].flags & PROTO_THIS_MSG) + CheckRadioButton(hwndDlg, IDC_ROPTPROTO1, IDC_ROPTPROTO4, IDC_ROPTPROTO3); + else if (data->proto_msg[i].flags & PROTO_NO_MSG) + CheckRadioButton(hwndDlg, IDC_ROPTPROTO1, IDC_ROPTPROTO4, IDC_ROPTPROTO4); + } + + if (data->proto_msg[i].flags & PROTO_NO_MSG || data->proto_msg[i].flags & PROTO_THIS_MSG + || data->proto_msg[i].flags & PROTO_NOCHANGE) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTSTATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG1), FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG2), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG3), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG5), FALSE); + + if (data->proto_msg[i].flags & PROTO_NO_MSG || data->proto_msg[i].flags & PROTO_NOCHANGE) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG4), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG4), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), TRUE); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG2), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTSTATUS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG1), TRUE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG2), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG3), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG4), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG5), TRUE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG2), TRUE); + } + + if (i) + { + k = i - 1; + status_modes = CallProtoService(accounts->pa[k]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + } + else + status_modes = accounts->statusMsgFlags; + + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_RESETCONTENT, 0, 0); + + for (l=ID_STATUS_ONLINE; l<=ID_STATUS_OUTTOLUNCH; l++) + { + int index; + if (status_modes & Proto_Status2Flag(l)) + { + index = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_INSERTSTRING, -1, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, l, GSMDF_TCHAR)); + + if (index != CB_ERR && index != CB_ERRSPACE) + { + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETITEMDATA, (WPARAM)index, (LPARAM)l - ID_STATUS_ONLINE); + if (j == l-ID_STATUS_ONLINE) + newindex=index; + } + } + } + + if (!newindex) + { + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETCURSEL, 0, 0); + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + } + else + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_SETCURSEL, (WPARAM)newindex, 0); + + if (data->status_msg[i].flags[j] & STATUS_SHOW_DLG) + CheckDlgButton(hwndDlg, IDC_COPTMSG1, BST_CHECKED); + else + CheckDlgButton(hwndDlg, IDC_COPTMSG1, BST_UNCHECKED); + + if (data->proto_msg[i].flags & PROTO_THIS_MSG) + { + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG4); + if (data->proto_msg[i].msg) + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, data->proto_msg[i].msg); + else + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + } + else + { + if (data->status_msg[i].flags[j] & STATUS_EMPTY_MSG) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG1); + } + else if (data->status_msg[i].flags[j] & STATUS_DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, GetDefaultMessage(j+ID_STATUS_ONLINE)); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG2); + } + else if (data->status_msg[i].flags[j] & STATUS_LAST_MSG) + { + char setting[80]; + DBVARIANT dbv, dbv2; + + if (i) + mir_snprintf(setting, SIZEOF(setting), "Last%sMsg", accounts->pa[k]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "LastMsg"); + + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + if (!DBGetContactSetting(NULL, "SimpleStatusMsg", setting, &dbv)) + { + if (dbv.pszVal) + { + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", dbv.pszVal, &dbv2) && strlen(dbv.pszVal)) + { + if ((dbv2.ptszVal) && (lstrlen(dbv2.ptszVal))) + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv2.ptszVal); + + DBFreeVariant(&dbv2); + } + } + DBFreeVariant(&dbv); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG3); + } + else if (data->status_msg[i].flags[j] & STATUS_THIS_MSG) + { + if (data->proto_msg[i].flags & PROTO_NO_MSG || data->proto_msg[i].flags & PROTO_NOCHANGE) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), TRUE); + } + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG4); + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, data->status_msg[i].msg[j]); + } + else if (data->status_msg[i].flags[j] & STATUS_LAST_STATUS_MSG) + { + char setting[80]; + DBVARIANT dbv; + + if (i) + mir_snprintf(setting, SIZEOF(setting), "%sMsg", accounts->pa[k]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "Msg"); + + if (!DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(j + ID_STATUS_ONLINE, setting), &dbv)) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG5); + } + } + break; + } + } + break; + + case IDC_ROPTPROTO1: + case IDC_ROPTPROTO2: + case IDC_ROPTPROTO3: + case IDC_ROPTPROTO4: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + int i, j; + + i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + + data->proto_msg[i].flags = 0; + + if ((LOWORD(wParam) == IDC_ROPTPROTO2) || (LOWORD(wParam) == IDC_ROPTPROTO4)) + { + data->proto_msg[i].flags |= (LOWORD(wParam) == IDC_ROPTPROTO4) ? PROTO_NO_MSG : PROTO_NOCHANGE; + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTSTATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG1), FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG2), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG3), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG4), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG5), FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG2), FALSE); + } + else if (LOWORD(wParam) == IDC_ROPTPROTO3) + { + data->proto_msg[i].flags |= PROTO_THIS_MSG; + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), TRUE); + if (data->proto_msg[i].msg) + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, data->proto_msg[i].msg); + else + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTSTATUS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG1), FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG2), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG3), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG4), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG5), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG4); + + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG2), FALSE); + } + else if (LOWORD(wParam) == IDC_ROPTPROTO1) + { + data->proto_msg[i].flags |= PROTO_POPUPDLG; + EnableWindow(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTSTATUS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG1), TRUE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG2), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG3), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG4), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_ROPTMSG5), TRUE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_COPTMSG2), TRUE); + } + + if (LOWORD(wParam) != IDC_ROPTPROTO3) + { + if (data->status_msg[i].flags[j] & STATUS_EMPTY_MSG) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG1); + } + else if (data->status_msg[i].flags[j] & STATUS_DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, GetDefaultMessage(j+ID_STATUS_ONLINE)); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG2); + } + else if (data->status_msg[i].flags[j] & STATUS_LAST_MSG) + { + char setting[80]; + DBVARIANT dbv, dbv2; + + if (i) + mir_snprintf(setting, SIZEOF(setting), "Last%sMsg", accounts->pa[i-1]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "LastMsg"); + + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + if (!DBGetContactSetting(NULL, "SimpleStatusMsg", setting, &dbv)) + { + if (dbv.pszVal) + { + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", dbv.pszVal, &dbv2) && strlen(dbv.pszVal)) + { + if (dbv2.ptszVal && lstrlen(dbv2.ptszVal)) + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv2.ptszVal); + DBFreeVariant(&dbv2); + } + } + DBFreeVariant(&dbv); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG3); + } + else if (data->status_msg[i].flags[j] & STATUS_THIS_MSG) + { + if ((LOWORD(wParam) == IDC_ROPTPROTO2) || (LOWORD(wParam) == IDC_ROPTPROTO4)) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), TRUE); + } + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG4); + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, data->status_msg[i].msg[j]); + } + else if (data->status_msg[i].flags[j] & STATUS_LAST_STATUS_MSG) + { + char setting[80]; + DBVARIANT dbv; + + if (i) + mir_snprintf(setting, SIZEOF(setting), "%sMsg", accounts->pa[i-1]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "Msg"); + + if (!DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(j + ID_STATUS_ONLINE, setting), &dbv)) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG5); + } + } + break; + } + } + break; + + case IDC_CBOPTSTATUS: + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE: + case CBN_SELENDOK: + { + int i, j; + + i = SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + if (data->status_msg[j].flags[i] & STATUS_SHOW_DLG) + CheckDlgButton(hwndDlg, IDC_COPTMSG1, BST_CHECKED); + else + CheckDlgButton(hwndDlg, IDC_COPTMSG1, BST_UNCHECKED); + + if (data->status_msg[j].flags[i] & STATUS_EMPTY_MSG) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG1); + } + else if (data->status_msg[j].flags[i] & STATUS_DEFAULT_MSG) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, GetDefaultMessage(i+ID_STATUS_ONLINE)); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG2); + } + else if (data->status_msg[j].flags[i] & STATUS_LAST_MSG) + { + char setting[80]; + DBVARIANT dbv,dbv2; + + if (j) + mir_snprintf(setting, SIZEOF(setting), "Last%sMsg", accounts->pa[j-1]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "LastMsg"); + + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + if (!DBGetContactSetting(NULL, "SimpleStatusMsg", setting, &dbv)) + { + if (dbv.pszVal) + { + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", dbv.pszVal, &dbv2) && strlen(dbv.pszVal)) + { + if (dbv2.ptszVal && lstrlen(dbv2.ptszVal)) + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv2.ptszVal); + DBFreeVariant(&dbv2); + } + } + DBFreeVariant(&dbv); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG3); + } + else if (data->status_msg[j].flags[i] & STATUS_THIS_MSG) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), TRUE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG4); + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, data->status_msg[j].msg[i]); + } + else if (data->status_msg[j].flags[i] & STATUS_LAST_STATUS_MSG) + { + char setting[80]; + DBVARIANT dbv; + + if (j) + mir_snprintf(setting, SIZEOF(setting), "%sMsg", accounts->pa[j-1]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "Msg"); + + if (!DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(i + ID_STATUS_ONLINE, setting), &dbv)) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + CheckRadioButton(hwndDlg, IDC_ROPTMSG1, IDC_ROPTMSG5, IDC_ROPTMSG5); + } + break; + } + } + break; + + case IDC_COPTMSG1: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + int i, j; + + i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + if (IsDlgButtonChecked(hwndDlg, IDC_COPTMSG1) == BST_CHECKED) + data->status_msg[j].flags[i] |= STATUS_SHOW_DLG; + else + data->status_msg[j].flags[i] &= ~STATUS_SHOW_DLG; + break; + } + } + break; + + case IDC_ROPTMSG1: + case IDC_ROPTMSG2: + case IDC_ROPTMSG3: + case IDC_ROPTMSG4: + case IDC_ROPTMSG5: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + { + int i, j; + + i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + if (LOWORD(wParam) == IDC_ROPTMSG4 && data->proto_msg[j].flags & PROTO_THIS_MSG) + break; + + data->status_msg[j].flags[i] = 0; + + if (IsDlgButtonChecked(hwndDlg, IDC_COPTMSG1) == BST_CHECKED) + data->status_msg[j].flags[i] |= STATUS_SHOW_DLG; + + if (LOWORD(wParam) == IDC_ROPTMSG1) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + data->status_msg[j].flags[i] |= STATUS_EMPTY_MSG; + } + else if (LOWORD(wParam) == IDC_ROPTMSG2) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, GetDefaultMessage(i+ID_STATUS_ONLINE)); + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + data->status_msg[j].flags[i] |= STATUS_DEFAULT_MSG; + } + else if (LOWORD(wParam) == IDC_ROPTMSG3) + { + char setting[80]; + DBVARIANT dbv, dbv2; + + if (j) + mir_snprintf(setting, SIZEOF(setting), "Last%sMsg", accounts->pa[j-1]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "LastMsg"); + + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + if (!DBGetContactSetting(NULL, "SimpleStatusMsg", setting, &dbv)) + { + if (dbv.pszVal) + { + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", dbv.pszVal, &dbv2) && strlen(dbv.pszVal)) + { + if (dbv2.ptszVal && lstrlen(dbv2.ptszVal)) + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv2.ptszVal); + DBFreeVariant(&dbv2); + } + } + DBFreeVariant(&dbv); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + data->status_msg[j].flags[i] |= STATUS_LAST_MSG; + } + else if (LOWORD(wParam) == IDC_ROPTMSG4) + { + data->status_msg[j].flags[i] |= STATUS_THIS_MSG; + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), TRUE); + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, data->status_msg[j].msg[i]); + } + else if (LOWORD(wParam) == IDC_ROPTMSG5) + { + char setting[80]; + DBVARIANT dbv; + + if (j) + mir_snprintf(setting, SIZEOF(setting), "%sMsg", accounts->pa[j-1]->szModuleName); + else + mir_snprintf(setting, SIZEOF(setting), "Msg"); + + if (!DBGetContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(i+ID_STATUS_ONLINE, setting), &dbv)) + { + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, dbv.ptszVal); + DBFreeVariant(&dbv); + } + else + SetDlgItemText(hwndDlg, IDC_OPTEDIT1, _T("")); + + EnableWindow(GetDlgItem(hwndDlg, IDC_OPTEDIT1), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_VARSHELP), FALSE); + data->status_msg[j].flags[i] |= STATUS_LAST_STATUS_MSG; + } + break; + } + } + break; + + case IDC_OPTEDIT1: + { + int i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + int j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + if (HIWORD(wParam) == EN_KILLFOCUS) + { + TCHAR msg[1024]; + + if (data->proto_msg[j].flags & PROTO_THIS_MSG) + { + int len = GetDlgItemText(hwndDlg, IDC_OPTEDIT1, msg, SIZEOF(msg)); + if (len > 0) + { + if (data->proto_msg[j].msg == NULL) + data->proto_msg[j].msg = mir_tstrdup(msg); + else + { + mir_free(data->proto_msg[j].msg); + data->proto_msg[j].msg = mir_tstrdup(msg); + } + } + else + { + if (data->proto_msg[j].msg != NULL) + { + mir_free(data->proto_msg[j].msg); + data->proto_msg[j].msg = NULL; + } + } + } + else + { + GetDlgItemText(hwndDlg, IDC_OPTEDIT1, msg, SIZEOF(msg)); + lstrcpy(data->status_msg[j].msg[i], msg); + } + } + break; + } + + case IDC_VARSHELP: + variables_showhelp(hwndDlg, IDC_OPTEDIT1, VHF_FULLDLG|VHF_SETLASTSUBJECT, NULL, NULL); + break; + + case IDC_BOPTPROTO: + { + int i, j, k; + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + if (j) + { + for (i = ID_STATUS_ONLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + { + if (accounts->statusMsgFlags & Proto_Status2Flag(i)) + { + data->status_msg[0].flags[i-ID_STATUS_ONLINE] = data->status_msg[j].flags[i-ID_STATUS_ONLINE]; + if (data->status_msg[j].flags[i-ID_STATUS_ONLINE] & STATUS_THIS_MSG) + lstrcpy(data->status_msg[0].msg[i-ID_STATUS_ONLINE], data->status_msg[j].msg[i-ID_STATUS_ONLINE]); + } + } + } + + for (k = 0; k < accounts->count; k++) + { + if (!IsAccountEnabled(accounts->pa[k]) || !CallProtoService(accounts->pa[k]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) || !(CallProtoService(accounts->pa[k]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + if (k != j - 1) + { + data->proto_msg[k+1].flags = data->proto_msg[j].flags; + if (j) + data->proto_msg[k+1].max_length = data->proto_msg[j].max_length; + + if (data->proto_msg[j].flags & PROTO_THIS_MSG) + { + int len = lstrlen(data->proto_msg[j].msg); + if (len > 0) + { + if (data->proto_msg[k+1].msg == NULL) + data->proto_msg[k+1].msg = mir_tstrdup(data->proto_msg[j].msg); + else + { + mir_free(data->proto_msg[k+1].msg); + data->proto_msg[k+1].msg = mir_tstrdup(data->proto_msg[j].msg); + } + } + else + { + if (data->proto_msg[k+1].msg != NULL) + { + mir_free(data->proto_msg[k+1].msg); + data->proto_msg[k+1].msg = NULL; + } + } + } + else if (data->proto_msg[j].flags & PROTO_POPUPDLG) + { + for (i = ID_STATUS_ONLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + { + if (CallProtoService(accounts->pa[k]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(i)) + { + data->status_msg[k + 1].flags[i - ID_STATUS_ONLINE] = data->status_msg[j].flags[i - ID_STATUS_ONLINE]; + if (data->status_msg[j].flags[i - ID_STATUS_ONLINE] & STATUS_THIS_MSG) + lstrcpy(data->status_msg[k + 1].msg[i - ID_STATUS_ONLINE], data->status_msg[j].msg[i - ID_STATUS_ONLINE]); + } + } + } + } + } + break; + } // case IDC_BOPTPROTO + + case IDC_BOPTSTATUS: + { + int status_modes, i, j, k; + + i = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTSTATUS), CB_GETCURSEL, 0, 0), 0); + j = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTPROTO), CB_GETCURSEL, 0, 0), 0); + + if (j) + status_modes = CallProtoService(accounts->pa[j-1]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0); + else + status_modes = accounts->statusMsgFlags; + + for (k = ID_STATUS_ONLINE; k <= ID_STATUS_OUTTOLUNCH; k++) + { + if (k - ID_STATUS_ONLINE != i && status_modes & Proto_Status2Flag(k)) + { + data->status_msg[j].flags[k - ID_STATUS_ONLINE] = data->status_msg[j].flags[i]; + if (data->status_msg[j].flags[i] & STATUS_THIS_MSG) + lstrcpy(data->status_msg[j].msg[k - ID_STATUS_ONLINE], data->status_msg[j].msg[i]); + } + } + break; + } //case IDC_BOPTSTATUS + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) + { + char szSetting[80]; + int i; + + for (i = ID_STATUS_ONLINE; i <= ID_STATUS_OUTTOLUNCH; i++) + { + if (accounts->statusMsgFlags & Proto_Status2Flag(i)) + { + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(i, "Default"), data->status_msg[0].msg[i - ID_STATUS_ONLINE]); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", StatusModeToDbSetting(i, "Flags"), (BYTE)data->status_msg[0].flags[i - ID_STATUS_ONLINE]); + + for (int j = 0; j < accounts->count; j++) + { + if (!IsAccountEnabled(accounts->pa[j])) + continue; + + if (!(CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + if (CallProtoService(accounts->pa[j]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0) & Proto_Status2Flag(i)) + { + mir_snprintf(szSetting, SIZEOF(szSetting), "%sDefault", accounts->pa[j]->szModuleName); + DBWriteContactSettingTString(NULL, "SRAway", StatusModeToDbSetting(i, szSetting), data->status_msg[j + 1].msg[i - ID_STATUS_ONLINE]); + + mir_snprintf(szSetting, SIZEOF(szSetting), "%sFlags", accounts->pa[j]->szModuleName); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", StatusModeToDbSetting(i, szSetting), (BYTE)data->status_msg[j + 1].flags[i - ID_STATUS_ONLINE]); + } + } + } + } + + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "PutDefInList", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_COPTMSG2) == BST_CHECKED)); + + if (data->proto_ok) + { + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "ProtoFlags", (BYTE)data->proto_msg[0].flags); + + for (i = 0; i < accounts->count; i++) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sDefault", accounts->pa[i]->szModuleName); + if (data->proto_msg[i+1].msg && (data->proto_msg[i+1].flags & PROTO_THIS_MSG)) + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", szSetting, data->proto_msg[i+1].msg); +// else +// DBDeleteContactSetting(NULL, "SimpleStatusMsg", szSetting); + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sMaxLen", accounts->pa[i]->szModuleName); + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", szSetting, (WORD)data->proto_msg[i+1].max_length); + + mir_snprintf(szSetting, SIZEOF(szSetting), "Proto%sFlags", accounts->pa[i]->szModuleName); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", szSetting, (BYTE)data->proto_msg[i+1].flags); + } + } + RebuildStatusMenu(); + return TRUE; + } + break; + + case WM_DESTROY: + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_OPTEDIT1), GWLP_WNDPROC, (LONG_PTR)OldDlgProc); + if (data->proto_ok) + { + for (int i = 0; i < accounts->count + 1; ++i) + { + if (data->proto_msg[i].msg) // they want to be free, do they? + mir_free(data->proto_msg[i].msg); + } + mir_free(data->proto_msg); + } + mir_free(data->status_msg); + mir_free(data); + break; + } + return FALSE; +} + +static INT_PTR CALLBACK DlgVariablesOptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_SSECUPDTMSG, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_ESECUPDTMSG), 0); + SendDlgItemMessage(hwndDlg, IDC_SSECUPDTMSG, UDM_SETRANGE32, 1, 999); + SendDlgItemMessage(hwndDlg, IDC_SSECUPDTMSG, UDM_SETPOS, 0, MAKELONG((short)DBGetContactSettingWord(NULL, "SimpleStatusMsg", "UpdateMsgInt", 10), 0)); + SendDlgItemMessage(hwndDlg, IDC_ESECUPDTMSG, EM_LIMITTEXT, 3, 0); + + CheckDlgButton(hwndDlg, IDC_CUPDATEMSG, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "UpdateMsgOn", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CNOIDLE, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "NoUpdateOnIdle", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CNOICQREQ, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "NoUpdateOnICQReq", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CLEAVEWINAMP, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AmpLeaveTitle", 1) ? BST_CHECKED : BST_UNCHECKED); + if (ServiceExists(MS_VARS_FORMATSTRING)) + { + CheckDlgButton(hwndDlg, IDC_CVARIABLES, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "EnableVariables", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CDATEPARSING, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ExclDateToken", 0) ? BST_CHECKED : BST_UNCHECKED); + } + else + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CVARIABLES), FALSE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_CDATEPARSING), IsDlgButtonChecked(hwndDlg, IDC_CVARIABLES) == BST_CHECKED); + + SendMessage(hwndDlg, WM_USER + 2, 0, 0); + return TRUE; + } + + case WM_USER + 2: + { + BOOL bChecked = IsDlgButtonChecked(hwndDlg, IDC_CUPDATEMSG) == BST_CHECKED; + EnableWindow(GetDlgItem(hwndDlg, IDC_ESECUPDTMSG), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_SSECUPDTMSG), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_CNOIDLE), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_CNOICQREQ), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLEAVEWINAMP), bChecked); + break; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_ESECUPDTMSG: + { + if ((HWND)lParam != GetFocus() || HIWORD(wParam) != EN_CHANGE) return 0; + int val = GetDlgItemInt(hwndDlg, IDC_ESECUPDTMSG, NULL, FALSE); + if (val == 0 && GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ESECUPDTMSG))) + SendDlgItemMessage(hwndDlg, IDC_SSECUPDTMSG, UDM_SETPOS, 0, MAKELONG((short)1, 0)); + break; + } + + case IDC_CUPDATEMSG: + SendMessage(hwndDlg, WM_USER + 2, 0, 0); + break; + + case IDC_CVARIABLES: + EnableWindow(GetDlgItem(hwndDlg, IDC_CDATEPARSING), IsDlgButtonChecked(hwndDlg, IDC_CVARIABLES) == BST_CHECKED); + break; + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) + { + if (g_uUpdateMsgTimer) + KillTimer(NULL, g_uUpdateMsgTimer); + + int val = SendDlgItemMessage(hwndDlg, IDC_SSECUPDTMSG, UDM_GETPOS, 0, 0); + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "UpdateMsgInt", (WORD)val); + + if (IsDlgButtonChecked(hwndDlg, IDC_CUPDATEMSG) == BST_CHECKED && val) + { + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "UpdateMsgOn", (BYTE)1); + g_uUpdateMsgTimer = SetTimer(NULL, 0, val * 1000, (TIMERPROC)UpdateMsgTimerProc); + } + else + { + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "UpdateMsgOn", (BYTE)0); + } + + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "NoUpdateOnIdle", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CNOIDLE) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "NoUpdateOnICQReq", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CNOICQREQ) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "AmpLeaveTitle", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CLEAVEWINAMP) == BST_CHECKED)); + if (ServiceExists(MS_VARS_FORMATSTRING)) + { + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "EnableVariables", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CVARIABLES) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "ExclDateToken", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CDATEPARSING) == BST_CHECKED)); + } + return TRUE; + } + break; + } + return FALSE; +} + +static BOOL IsHistoryMsgsFound(HWND hwndDlg, int histMax) +{ + char szSetting[16]; + DBVARIANT dbv; + int j = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "LMMsg", 1); + for (int i = 1; i <= histMax; ++i, --j) + { + if (j < 1) j = histMax; + mir_snprintf(szSetting, SIZEOF(szSetting), "SMsg%d", j); + if (!DBGetContactSettingTString(NULL, "SimpleStatusMsg", szSetting, &dbv)) + { + if (dbv.ptszVal != NULL && *dbv.ptszVal != '\0') + { + DBFreeVariant(&dbv); + return TRUE; + } + DBFreeVariant(&dbv); + } + } + return FALSE; +} + +static INT_PTR CALLBACK DlgAdvancedOptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + int settingValue; + + TranslateDialogDefault(hwndDlg); + + // Layout + int i_btnhide = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_ADDSTRING, 0, (LPARAM)TranslateT("Hide")); + int i_btndown = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_ADDSTRING, 0, (LPARAM)TranslateT("Show next to cancel button")); + int i_btndownflat = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_ADDSTRING, 0, (LPARAM)TranslateT("Flat, next to cancel button")); + int i_btnlist = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_ADDSTRING, 0, (LPARAM)TranslateT("Show in message list")); + + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETITEMDATA, (WPARAM)i_btnhide, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETITEMDATA, (WPARAM)i_btndown, DLG_SHOW_BUTTONS); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETITEMDATA, (WPARAM)i_btndownflat, DLG_SHOW_BUTTONS_FLAT); + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETITEMDATA, (WPARAM)i_btnlist, DLG_SHOW_BUTTONS_INLIST); + + settingValue = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "DlgFlags", DLG_SHOW_DEFAULT); + CheckDlgButton(hwndDlg, IDC_CSTATUSLIST, settingValue & DLG_SHOW_STATUS ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CPROFILES, settingValue & DLG_SHOW_STATUS_PROFILES ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CICONS1, settingValue & DLG_SHOW_STATUS_ICONS ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CICONS2, settingValue & DLG_SHOW_LIST_ICONS ? BST_CHECKED : BST_UNCHECKED); + + if (!(settingValue & DLG_SHOW_STATUS)) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_CPROFILES), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_CICONS1), FALSE); + } + + if (settingValue & DLG_SHOW_BUTTONS) + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETCURSEL, (WPARAM)i_btndown, 0); + else if (settingValue & DLG_SHOW_BUTTONS_FLAT) + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETCURSEL, (WPARAM)i_btndownflat, 0); + else if (settingValue & DLG_SHOW_BUTTONS_INLIST) + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETCURSEL, (WPARAM)i_btnlist, 0); + else + SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_SETCURSEL, (WPARAM)i_btnhide, 0); + + if (!ServiceExists(MS_SS_GETPROFILECOUNT)) + { + TCHAR szText[100]; + mir_sntprintf(szText, SIZEOF(szText), _T("%s *"), TranslateT("Show status profiles in status list")); + SetDlgItemText(hwndDlg, IDC_CPROFILES, szText); + EnableWindow(GetDlgItem(hwndDlg, IDC_CPROFILES), FALSE); + ShowWindow(GetDlgItem(hwndDlg, IDC_NOTE1), SW_SHOW); + } + + // Misc. + settingValue = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "MaxHist", 10); + + SendDlgItemMessage(hwndDlg, IDC_SMAXHIST, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_EMAXHIST), 0); + SendDlgItemMessage(hwndDlg, IDC_SMAXHIST, UDM_SETRANGE32, 0, 25); + SendDlgItemMessage(hwndDlg, IDC_SMAXHIST, UDM_SETPOS, 0, MAKELONG((short)settingValue, 0)); + SendDlgItemMessage(hwndDlg, IDC_EMAXHIST, EM_LIMITTEXT, 2, 0); + + if (settingValue == 0) + EnableWindow(GetDlgItem(hwndDlg, IDC_CICONS2), FALSE); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTHIST), IsHistoryMsgsFound(hwndDlg, settingValue)); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTDEF), DBGetContactSettingWord(NULL, "SimpleStatusMsg", "DefMsgCount", 0) != 0); + + SendDlgItemMessage(hwndDlg, IDC_STIMEOUT, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_ETIMEOUT), 0); + SendDlgItemMessage(hwndDlg, IDC_STIMEOUT, UDM_SETRANGE32, 1, 60); + SendDlgItemMessage(hwndDlg, IDC_STIMEOUT, UDM_SETPOS, 0, MAKELONG((short)DBGetContactSettingByte(NULL, "SimpleStatusMsg", "DlgTime", 5), 0)); + SendDlgItemMessage(hwndDlg, IDC_ETIMEOUT, EM_LIMITTEXT, 2, 0); + + CheckDlgButton(hwndDlg, IDC_CCLOSEWND, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "AutoClose", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CRPOSWND, !DBGetContactSettingByte(NULL, "SimpleStatusMsg", "WinCentered", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CREMOVECR, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "RemoveCR", 0) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CSHOWCOPY, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ShowCopy", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CSHOWGURL, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ShowGoToURL", 1) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CSHOWSMSG, DBGetContactSettingByte(NULL, "SimpleStatusMsg", "ShowStatusMenuItem", 1) ? BST_CHECKED : BST_UNCHECKED); + + SendMessage(hwndDlg, WM_USER + 2, 0, 0); + return TRUE; + } + + case WM_USER + 2: + { + BOOL bChecked = IsDlgButtonChecked(hwndDlg, IDC_CCLOSEWND) == BST_CHECKED; + EnableWindow(GetDlgItem(hwndDlg, IDC_ETIMEOUT), bChecked); + EnableWindow(GetDlgItem(hwndDlg, IDC_STIMEOUT), bChecked); + break; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CSTATUSLIST: + { + BOOL bChecked = IsDlgButtonChecked(hwndDlg, IDC_CSTATUSLIST) == BST_CHECKED; + EnableWindow(GetDlgItem(hwndDlg, IDC_CPROFILES), bChecked && ServiceExists(MS_SS_GETPROFILECOUNT)); + EnableWindow(GetDlgItem(hwndDlg, IDC_CICONS1), bChecked); + break; + } + + case IDC_CBOPTBUTTONS: + if ((HWND)lParam != GetFocus() || HIWORD(wParam) != CBN_SELCHANGE) return 0; + break; + + case IDC_EMAXHIST: + { + if ((HWND)lParam != GetFocus() || HIWORD(wParam) != EN_CHANGE) return 0; + int val = GetDlgItemInt(hwndDlg, IDC_EMAXHIST, NULL, FALSE); + if (val > 25) + SendDlgItemMessage(hwndDlg, IDC_SMAXHIST, UDM_SETPOS, 0, MAKELONG((short)25, 0)); + EnableWindow(GetDlgItem(hwndDlg, IDC_CICONS2), val != 0); + break; + } + + case IDC_CCLOSEWND: + SendMessage(hwndDlg, WM_USER + 2, 0, 0); + break; + + case IDC_ETIMEOUT: + { + if ((HWND)lParam != GetFocus() || HIWORD(wParam) != EN_CHANGE) return 0; + int val = GetDlgItemInt(hwndDlg, IDC_ETIMEOUT, NULL, FALSE); + if (val == 0 && GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ETIMEOUT))) + SendDlgItemMessage(hwndDlg, IDC_STIMEOUT, UDM_SETPOS, 0, MAKELONG((short)1, 0)); + else if (val > 60) + SendDlgItemMessage(hwndDlg, IDC_STIMEOUT, UDM_SETPOS, 0, MAKELONG((short)60, 0)); + break; + } + + case IDC_BOPTHIST: + if (MessageBox(NULL, TranslateT("Are you sure you want to clear status message history?"), TranslateT("Confirm clearing history"), MB_ICONQUESTION | MB_YESNO) == IDYES) + { + int i, max_hist_msgs; + char text[8], setting[80]; + + if (hwndSAMsgDialog) DestroyWindow(hwndSAMsgDialog); + + max_hist_msgs = DBGetContactSettingByte(NULL, "SimpleStatusMsg", "MaxHist", 10); + for (i = 1; i <= max_hist_msgs; i++) + { + mir_snprintf(text, SIZEOF(text), "SMsg%d", i); + DBWriteContactSettingTString(NULL, "SimpleStatusMsg", text, _T("")); + } + DBWriteContactSettingString(NULL, "SimpleStatusMsg", "LastMsg", ""); + for (i = 0; i < accounts->count; i++) + { + if (!IsAccountEnabled(accounts->pa[i])) + continue; + + if (!CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_3, 0)) + continue; + + if (!(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND)) + continue; + + mir_snprintf(setting, SIZEOF(setting), "Last%sMsg", accounts->pa[i]->szModuleName); + DBWriteContactSettingString(NULL, "SimpleStatusMsg", setting, ""); + } + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "LMMsg", (WORD)max_hist_msgs); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTHIST), FALSE); + } + return 0; + + case IDC_BOPTDEF: + if (MessageBox(NULL, TranslateT("Are you sure you want to clear predefined status messages?"), TranslateT("Confirm clearing predefined"), MB_ICONQUESTION | MB_YESNO) == IDYES) + { + char szSetting[16]; + int nDefMSgCount; + + if (hwndSAMsgDialog) DestroyWindow(hwndSAMsgDialog); + + nDefMSgCount = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "DefMsgCount", 0); + for (int i = 1; i <= nDefMSgCount; i++) + { + mir_snprintf(szSetting, SIZEOF(szSetting), "DefMsg%d", i); + DBDeleteContactSetting(NULL, "SimpleStatusMsg", szSetting); + } + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "DefMsgCount", 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_BOPTDEF), FALSE); + } + return 0; + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) + { + // Layout + int flags = 0, curSel; + + if (IsDlgButtonChecked(hwndDlg, IDC_CSTATUSLIST) == BST_CHECKED) flags |= DLG_SHOW_STATUS; + if (IsDlgButtonChecked(hwndDlg, IDC_CICONS1) == BST_CHECKED) flags |= DLG_SHOW_STATUS_ICONS; + if (IsDlgButtonChecked(hwndDlg, IDC_CICONS2) == BST_CHECKED) flags |= DLG_SHOW_LIST_ICONS; + if (IsDlgButtonChecked(hwndDlg, IDC_CPROFILES) == BST_CHECKED) flags |= DLG_SHOW_STATUS_PROFILES; + + curSel = SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_GETCURSEL, 0, 0); + if (curSel != CB_ERR) + flags |= SendMessage(GetDlgItem(hwndDlg, IDC_CBOPTBUTTONS), CB_GETITEMDATA, (WPARAM)curSel, 0); + + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "DlgFlags", (BYTE)flags); + + // Misc. + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "MaxHist", (BYTE)GetDlgItemInt(hwndDlg, IDC_EMAXHIST, NULL, FALSE)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "AutoClose", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CCLOSEWND) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "DlgTime", (BYTE)GetDlgItemInt(hwndDlg, IDC_ETIMEOUT, NULL, FALSE)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "WinCentered", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CRPOSWND) != BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "RemoveCR", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CREMOVECR) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "ShowCopy", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CSHOWCOPY) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "ShowGoToURL", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CSHOWGURL) == BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "ShowStatusMenuItem", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CSHOWSMSG) == BST_CHECKED)); + RebuildStatusMenu(); + + return TRUE; + } + break; + } + return FALSE; +} + +struct StatusOptDlgData +{ + int *status; + int *setdelay; + int setglobaldelay; +}; + +static INT_PTR CALLBACK DlgStatusOptionsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + struct StatusOptDlgData *data = (struct StatusOptDlgData *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + { + int index, i; + + TranslateDialogDefault(hwndDlg); + + data = (struct StatusOptDlgData *)mir_alloc(sizeof(struct StatusOptDlgData)); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)data); + + data->status = (int *)mir_alloc(sizeof(int) * accounts->count); + data->setdelay = (int *)mir_alloc(sizeof(int) * accounts->count); + for (i = 0; i < accounts->count; ++i) + { + if (!IsAccountEnabled(accounts->pa[i]) || !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) &~ CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + index = SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_ADDSTRING, 0, (LPARAM)accounts->pa[i]->tszAccountName); + if (index != LB_ERR && index != LB_ERRSPACE) + { + char setting[80]; + mir_snprintf(setting, SIZEOF(setting), "Startup%sStatus", accounts->pa[i]->szModuleName); + data->status[i] = DBGetContactSettingWord(NULL, "SimpleStatusMsg", setting, ID_STATUS_OFFLINE); + mir_snprintf(setting, SIZEOF(setting), "Set%sStatusDelay", accounts->pa[i]->szModuleName); + data->setdelay[i] = DBGetContactSettingWord(NULL, "SimpleStatusMsg", setting, 300); + SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + } + SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_SETCURSEL, 0, 0); + SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_LISTPROTO, LBN_SELCHANGE), (LPARAM)GetDlgItem(hwndDlg, IDC_LISTPROTO)); + + data->setglobaldelay = DBGetContactSettingWord(NULL, "SimpleStatusMsg", "SetStatusDelay", 300); + + SendMessage(GetDlgItem(hwndDlg, IDC_SSETSTATUS), UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_ESETSTATUS), 0); + SendMessage(GetDlgItem(hwndDlg, IDC_SSETSTATUS), UDM_SETRANGE32, 0, 9000); + SendMessage(GetDlgItem(hwndDlg, IDC_ESETSTATUS), EM_LIMITTEXT, 4, 0); + + if (!DBGetContactSettingByte(NULL, "SimpleStatusMsg", "GlobalStatusDelay", 1)) + { + CheckDlgButton(hwndDlg, IDC_SPECSET, BST_CHECKED); + i = SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETCURSEL, 0, 0), 0); + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setdelay[i], FALSE); + } + else + { + CheckDlgButton(hwndDlg, IDC_SPECSET, BST_UNCHECKED); + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setglobaldelay, FALSE); + } + + if (DBGetContactSettingByte(NULL, "SimpleStatusMsg", "StartupPopupDlg", 1)) + { + CheckDlgButton(hwndDlg, IDC_POPUPDLG, BST_CHECKED); + if (IsDlgButtonChecked(hwndDlg, IDC_SPECSET) == BST_CHECKED) + { + CheckDlgButton(hwndDlg, IDC_SPECSET, BST_UNCHECKED); + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setglobaldelay, FALSE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_SPECSET), FALSE); + } + else + CheckDlgButton(hwndDlg, IDC_POPUPDLG, BST_UNCHECKED); + + if (accounts->statusCount == 1 && accounts->statusMsgCount == 1) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_SPECSET), FALSE); + CheckDlgButton(hwndDlg, IDC_SPECSET, BST_UNCHECKED); //should work like when checked, but should not be checked + i = SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETCURSEL, 0, 0), 0); + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setdelay[i], FALSE); + } + + return TRUE; + } + + case WM_COMMAND: + if ( ( (HIWORD(wParam) == BN_CLICKED) || /*(HIWORD(wParam) == EN_KILLFOCUS) ||*/ (HIWORD(wParam) == EN_CHANGE) + || ( (HIWORD(wParam) == LBN_SELCHANGE) && (LOWORD(wParam) != IDC_LISTPROTO) ) + ) && (HWND)lParam == GetFocus() ) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + switch (LOWORD(wParam)) + { + case IDC_ESETSTATUS: + switch (HIWORD(wParam)) + { + case EN_KILLFOCUS: + { + BOOL translated; + int val = GetDlgItemInt(hwndDlg, IDC_ESETSTATUS, &translated, FALSE); + if (translated && val > 9000) + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, 9000, FALSE); + if (translated && val < 0) + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, 0, FALSE); + val = GetDlgItemInt(hwndDlg, IDC_ESETSTATUS, &translated, FALSE); + + if (IsDlgButtonChecked(hwndDlg, IDC_SPECSET) == BST_CHECKED || (accounts->statusCount == 1 && accounts->statusMsgCount == 1)) + { + int i = SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETCURSEL, 0, 0), 0); + data->setdelay[i] = val; + } + else + data->setglobaldelay = val; + break; + } + } + break; + + case IDC_SPECSET: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + if (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED || (accounts->statusCount == 1 && accounts->statusMsgCount == 1)) + { + int i = SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETCURSEL, 0, 0), 0); + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setdelay[i], FALSE); + } + else + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setglobaldelay, FALSE); + break; + } + break; + + case IDC_POPUPDLG: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + if (accounts->statusCount == 1 && accounts->statusMsgCount == 1) + break; + + if (SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED) + { + if (IsDlgButtonChecked(hwndDlg, IDC_SPECSET) == BST_CHECKED) + { + CheckDlgButton(hwndDlg, IDC_SPECSET, BST_UNCHECKED); + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setglobaldelay, FALSE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_SPECSET), FALSE); + } + else + EnableWindow(GetDlgItem(hwndDlg, IDC_SPECSET), TRUE); + break; + } + break; + + case IDC_LISTPROTO: + switch (HIWORD(wParam)) + { + case LBN_SELCHANGE: + { + int status_modes, i, l, index, newindex = 0; + + i = SendMessage((HWND)lParam, LB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0), 0); + status_modes = CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0) & ~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0); + + SendMessage(GetDlgItem(hwndDlg, IDC_LISTSTATUS), LB_RESETCONTENT, 0, 0); + for (l = ID_STATUS_OFFLINE; l <= ID_STATUS_OUTTOLUNCH; l++) + { + if (status_modes & Proto_Status2Flag(l) || l == ID_STATUS_OFFLINE) + { + index = SendMessage(GetDlgItem(hwndDlg, IDC_LISTSTATUS), LB_INSERTSTRING, -1, (LPARAM)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, l, GSMDF_TCHAR)); + if (index != LB_ERR && index != LB_ERRSPACE) + { + SendMessage(GetDlgItem(hwndDlg, IDC_LISTSTATUS), LB_SETITEMDATA, (WPARAM)index, (LPARAM)l - ID_STATUS_OFFLINE); + if (data->status[i] == l) + newindex = index; + } + } + } + + index = SendMessage(GetDlgItem(hwndDlg, IDC_LISTSTATUS), LB_INSERTSTRING, -1, (LPARAM)TranslateT("")); + if (index != LB_ERR && index != LB_ERRSPACE) + { + SendMessage(GetDlgItem(hwndDlg, IDC_LISTSTATUS), LB_SETITEMDATA, (WPARAM)index, (LPARAM)ID_STATUS_CURRENT-ID_STATUS_OFFLINE); + if (data->status[i] == ID_STATUS_CURRENT) + newindex = index; + } + + SendMessage(GetDlgItem(hwndDlg, IDC_LISTSTATUS), LB_SETCURSEL, (WPARAM)newindex, 0); + + if (IsDlgButtonChecked(hwndDlg, IDC_SPECSET) == BST_CHECKED || (accounts->statusCount == 1 && accounts->statusMsgCount == 1)) + SetDlgItemInt(hwndDlg, IDC_ESETSTATUS, data->setdelay[i], FALSE); + break; + } + } + break; + + case IDC_LISTSTATUS: + switch (HIWORD(wParam)) + { + case LBN_SELCHANGE: + { + int i = SendMessage((HWND)lParam, LB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0), 0); + int j = SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETITEMDATA, (WPARAM)SendMessage(GetDlgItem(hwndDlg, IDC_LISTPROTO), LB_GETCURSEL, 0, 0), 0); + data->status[j] = i + ID_STATUS_OFFLINE; + break; + } + } + break; + } + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == 0 && ((LPNMHDR)lParam)->code == PSN_APPLY) + { + char szSetting[80]; + for (int i = 0; i < accounts->count; i++) + { + if (!IsAccountEnabled(accounts->pa[i]) || !(CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_2, 0)&~CallProtoService(accounts->pa[i]->szModuleName, PS_GETCAPS, PFLAGNUM_5, 0))) + continue; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Startup%sStatus", accounts->pa[i]->szModuleName); + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", szSetting, (WORD)data->status[i]); + + mir_snprintf(szSetting, SIZEOF(szSetting), "Set%sStatusDelay", accounts->pa[i]->szModuleName); + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", szSetting, (WORD)data->setdelay[i]); + } + DBWriteContactSettingWord(NULL, "SimpleStatusMsg", "SetStatusDelay", (WORD)data->setglobaldelay); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "GlobalStatusDelay", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SPECSET) != BST_CHECKED)); + DBWriteContactSettingByte(NULL, "SimpleStatusMsg", "StartupPopupDlg", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_POPUPDLG) == BST_CHECKED)); + return TRUE; + } + break; + + case WM_DESTROY: + mir_free(data->status); + mir_free(data->setdelay); + mir_free(data); + break; + } + return FALSE; +} + +int InitOptions(WPARAM wParam, LPARAM lParam) +{ + if (accounts->statusCount == 0) + return 0; + + OPTIONSDIALOGPAGE odp = {0}; + odp.cbSize = sizeof(odp); + odp.hInstance = g_hInst; + + if (!ServiceExists(MS_SS_GETPROFILECOUNT)) + { + odp.ptszTitle = LPGENT("Status"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_STATUS); + odp.pfnDlgProc = DlgStatusOptionsProc; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + } + + if (accounts->statusMsgCount == 0) + return 0; + + odp.position = 870000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GENERAL); + odp.ptszTitle = LPGENT("Status Messages"); + odp.ptszGroup = LPGENT("Status"); + odp.ptszTab = LPGENT("General"); + odp.pfnDlgProc = DlgOptionsProc; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + odp.ptszTab = LPGENT("Variables"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_VARIABLES); + odp.pfnDlgProc = DlgVariablesOptionsProc; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + odp.ptszTab = LPGENT("Advanced"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ADVANCED); + odp.pfnDlgProc = DlgAdvancedOptionsProc; + odp.flags |= ODPF_EXPERTONLY; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + return 0; +} diff --git a/plugins/SimpleStatusMsg/res/cbook.ico b/plugins/SimpleStatusMsg/res/cbook.ico new file mode 100644 index 0000000000..db2b37e299 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/cbook.ico differ diff --git a/plugins/SimpleStatusMsg/res/copy.ico b/plugins/SimpleStatusMsg/res/copy.ico new file mode 100644 index 0000000000..1bb44affef Binary files /dev/null and b/plugins/SimpleStatusMsg/res/copy.ico differ diff --git a/plugins/SimpleStatusMsg/res/cross.ico b/plugins/SimpleStatusMsg/res/cross.ico new file mode 100644 index 0000000000..c5417931c7 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/cross.ico differ diff --git a/plugins/SimpleStatusMsg/res/csmsg.ico b/plugins/SimpleStatusMsg/res/csmsg.ico new file mode 100644 index 0000000000..9e1dcd2572 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/csmsg.ico differ diff --git a/plugins/SimpleStatusMsg/res/gotourl.ico b/plugins/SimpleStatusMsg/res/gotourl.ico new file mode 100644 index 0000000000..bd50d80679 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/gotourl.ico differ diff --git a/plugins/SimpleStatusMsg/res/history.ico b/plugins/SimpleStatusMsg/res/history.ico new file mode 100644 index 0000000000..2dd478cbc5 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/history.ico differ diff --git a/plugins/SimpleStatusMsg/res/msg.ico b/plugins/SimpleStatusMsg/res/msg.ico new file mode 100644 index 0000000000..13b3d7aac3 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/msg.ico differ diff --git a/plugins/SimpleStatusMsg/res/plus.ico b/plugins/SimpleStatusMsg/res/plus.ico new file mode 100644 index 0000000000..2efc4dc1a2 Binary files /dev/null and b/plugins/SimpleStatusMsg/res/plus.ico differ diff --git a/plugins/SimpleStatusMsg/resource.h b/plugins/SimpleStatusMsg/resource.h new file mode 100644 index 0000000000..137327acac --- /dev/null +++ b/plugins/SimpleStatusMsg/resource.h @@ -0,0 +1,126 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDD_COPY 101 +#define IDD_AWAYMSGBOX 102 +#define IDD_OPT_GENERAL 103 +#define IDD_READAWAYMSG 104 +#define IDI_CROSS 105 +#define IDI_HISTORY 106 +#define IDI_MESSAGE 107 +#define IDI_PLUS 108 +#define IDI_CHIST 109 +#define IDI_COPY 110 +#define IDI_CSMSG 111 +#define IDR_EDITMENU 112 +#define IDD_OPT_ADVANCED 113 +#define IDD_OPT_STATUS 114 +#define IDI_GOTOURL 115 +#define IDD_OPT_VARIABLES 116 +#define IDC_BOPTDEF 1000 +#define IDC_BOPTHIST 1001 +#define IDC_OK 1002 +#define IDC_EDIT1 1003 +#define IDC_CANCEL 1004 +#define IDC_ROPTMSG1 1005 +#define IDC_ROPTMSG2 1006 +#define IDC_ROPTMSG3 1007 +#define IDC_ROPTMSG4 1008 +#define IDC_ROPTMSG5 1009 +#define IDC_SPECSET 1010 +#define IDC_MSG 1011 +#define IDC_RETRIEVING 1012 +#define IDC_CLEAVEWINAMP 1013 +#define IDC_COPY 1014 +#define IDC_CSTATUSLIST 1015 +#define IDC_CICONS2 1016 +#define IDC_CICONS1 1017 +#define IDC_CPROFILES 1018 +#define IDC_EMAXHIST 1019 +#define IDC_ETIMEOUT 1020 +#define IDC_CSHOWGURL 1021 +#define IDC_SMAXHIST 1022 +#define IDC_CCLOSEWND 1023 +#define IDC_STIMEOUT 1024 +#define IDC_CBOPTSTATUS 1025 +#define IDC_COPTMSG1 1026 +#define IDC_OPTEDIT1 1027 +#define IDC_CBOPTPROTO 1028 +#define IDC_ROPTPROTO1 1029 +#define IDC_ROPTPROTO2 1030 +#define IDC_ROPTPROTO3 1031 +#define IDC_CREMOVECR 1032 +#define IDC_CSHOWCOPY 1033 +#define IDC_EMAXLENGTH 1034 +#define IDC_SMAXLENGTH 1035 +#define IDC_COPTMSG2 1036 +#define IDC_VARSHELP 1037 +#define IDC_CBOPTBUTTONS 1038 +#define IDC_CSHOWSMSG 1039 +#define IDC_CRPOSWND 1040 +#define IDC_ESECUPDTMSG 1041 +#define IDC_CUPDATEMSG 1042 +#define IDC_SSECUPDTMSG 1043 +#define IDC_BOPTPROTO 1044 +#define IDC_BOPTSTATUS 1045 +#define IDC_LISTPROTO 1046 +#define IDC_LISTSTATUS 1047 +#define IDC_ESETSTATUS 1048 +#define IDC_SSETSTATUS 1049 +#define IDC_NOTE1 1050 +#define IDC_POPUPDLG 1051 +#define IDC_ROPTPROTO4 1052 +#define IDC_BADD 1053 +#define IDC_BDEL 1054 +#define IDC_BCLEAR 1055 +#define IDC_CNOIDLE 1056 +#define IDC_CNOICQREQ 1057 +#define IDC_CVARIABLES 1058 +#define IDC_CDATEPARSING 1059 +#define IDC_MAXLENGTH 1060 +#define IDM_VDATE 40002 +#define IDM_VWINAMPSONG 40003 +#define IDM_VRANDXY 40004 +#define IDM_VTIME 40006 +#define IDM_CUT 40007 +#define IDM_COPY 40008 +#define IDM_PASTE 40009 +#define IDM_DELETE 40010 +#define IDM_SELECTALL 40011 +#define ID__FORTUNE 40012 +#define ID__FORTUNEAWAYMSG_PROTOFORTUNEMSG 40013 +#define ID__FORTUNEAWAYMSG_STATUSFORTUNEMSG 40014 +#define ID__VARIABLES_LSSTATUSCONTACT 40015 +#define ID__VARIABLES_LSDATECONTACTFORMAT 40016 +#define ID__VARIABLES_CINFOCONTACTPROPERTY 40017 +#define ID__VARIABLES_MSTATUSPROTOCOL 40018 +#define ID__VARIABLES_LSTIMECONTACTFORMAT 40019 +#define ID__VARIABLES_DBSETTINGCONTACTMODULESETTING 40020 +#define ID__VARIABLES_TXTFILEFILELINE 40021 +#define ID__VARIABLES_IFCONDITIONTRUEFALSE 40022 +#define ID__VARIABLES_STRCMPSTRING1STRING2 40023 +#define ID__VARIABLES_STRICMPSTRING1STRING2 40024 +#define ID__VARIABLES_CDATEFORMAT 40025 +#define ID__VARIABLES_CTIMEFORMAT 40026 +#define ID__VARIABLES_REPLACESUBSTRING1STRING2 40027 +#define ID__VARIABLES_LOWERSTRING 40028 +#define ID__VARIABLES_UPPERSTRING 40029 +#define ID__VARIABLES_CONTACTSTRINGPROPERTY 40030 +#define ID__VARIABLES_SCROLLSTRINGNUMCHARSNUMCHARS 40031 +#define ID__VARIABLES_MOREVARIABLES 40032 +#define ID__VARIABLES 40033 +#define ID__FORTUNEAWAYMSG 40034 +#define IDM_VRANDMSG 40035 +#define IDM_VRANDDEFMSG 40036 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 117 +#define _APS_NEXT_COMMAND_VALUE 40037 +#define _APS_NEXT_CONTROL_VALUE 1061 +#define _APS_NEXT_SYMED_VALUE 100 +#endif +#endif diff --git a/plugins/SimpleStatusMsg/resource.rc b/plugins/SimpleStatusMsg/resource.rc new file mode 100644 index 0000000000..4a81378d39 --- /dev/null +++ b/plugins/SimpleStatusMsg/resource.rc @@ -0,0 +1,437 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,9,0,4 + PRODUCTVERSION 1,9,0,4 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Licensed under the terms of the GNU General Public License" + VALUE "CompanyName", "Bartosz 'Dezeath' Białek, Harven" + VALUE "FileDescription", "Simple Status Message plugin for Miranda IM" + VALUE "FileVersion", "1.9.0.4" + VALUE "InternalName", "simplestatusmsg" + VALUE "LegalCopyright", "Copyright © 2006-2011 Bartosz Białek, © 2005 Harven" + VALUE "OriginalFilename", "simplestatusmsg.dll" + VALUE "ProductName", "Simple Status Message" + VALUE "ProductVersion", "1.9.0.4" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Polish resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK) +#ifdef _WIN32 +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_READAWAYMSG DIALOGEX 0, 0, 187, 72 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "%s Message for %s" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "&Cancel",IDOK,32,53,50,14 + CTEXT "Retrieving %s message...",IDC_RETRIEVING,5,21,177,8,SS_NOPREFIX + EDITTEXT IDC_MSG,5,5,177,43,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_VISIBLE | WS_VSCROLL + PUSHBUTTON "Co&py to Clipboard",IDC_COPY,92,53,63,14,BS_CENTER | BS_VCENTER +END + +IDD_AWAYMSGBOX DIALOG 0, 0, 208, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "%s Message (%s)" +FONT 8, "MS Shell Dlg" +BEGIN + EDITTEXT IDC_EDIT1,7,23,193,44,ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL | ES_WANTRETURN | WS_VSCROLL + DEFPUSHBUTTON "OK",IDC_OK,7,71,66,14,BS_CENTER | BS_VCENTER + PUSHBUTTON "&Cancel",IDC_CANCEL,78,71,66,14,BS_CENTER | BS_VCENTER + CONTROL "",IDC_BADD,"MButtonClass",WS_TABSTOP,149,71,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "",IDC_BDEL,"MButtonClass",WS_TABSTOP,167,71,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "",IDC_BCLEAR,"MButtonClass",WS_TABSTOP,185,71,16,14,WS_EX_NOACTIVATE | 0x10000000L +END + +IDD_COPY DIALOGEX 0, 0, 159, 25 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Retrieving status message for %s..." +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "&Cancel",IDCANCEL,55,6,50,14,BS_CENTER | BS_VCENTER +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_READAWAYMSG, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 182 + TOPMARGIN, 5 + BOTTOMMARGIN, 67 + END + + IDD_AWAYMSGBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 201 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END + + IDD_COPY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 152 + TOPMARGIN, 7 + BOTTOMMARGIN, 18 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_CROSS ICON "res\\cross.ico" +IDI_HISTORY ICON "res\\history.ico" +IDI_MESSAGE ICON "res\\msg.ico" +IDI_PLUS ICON "res\\plus.ico" +IDI_CHIST ICON "res\\cbook.ico" +IDI_COPY ICON "res\\copy.ico" +IDI_CSMSG ICON "res\\csmsg.ico" +IDI_GOTOURL ICON "res\\gotourl.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_EDITMENU MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "%time%", IDM_VTIME + MENUITEM "%date%", IDM_VDATE + MENUITEM "%winampsong%", IDM_VWINAMPSONG + MENUITEM "%rand(x,y)%", IDM_VRANDXY + MENUITEM "%randmsg%", IDM_VRANDMSG + MENUITEM "%randdefmsg%", IDM_VRANDDEFMSG + MENUITEM SEPARATOR + POPUP "Fortune" + BEGIN + MENUITEM "%fortunemsg%", ID__FORTUNE + MENUITEM "%protofortunemsg%", ID__FORTUNEAWAYMSG_PROTOFORTUNEMSG + MENUITEM "%statusfortunemsg%", ID__FORTUNEAWAYMSG_STATUSFORTUNEMSG + END + POPUP "Variables" + BEGIN + MENUITEM "?cinfo(contact,property)", ID__VARIABLES_CINFOCONTACTPROPERTY + MENUITEM "?contact(string,property)", ID__VARIABLES_CONTACTSTRINGPROPERTY + MENUITEM "?mstatus(protocol)", ID__VARIABLES_MSTATUSPROTOCOL + MENUITEM "?lsdate(contact,format)", ID__VARIABLES_LSDATECONTACTFORMAT + MENUITEM "?lsstatus(contact)", ID__VARIABLES_LSSTATUSCONTACT + MENUITEM "?lstime(contact,format)", ID__VARIABLES_LSTIMECONTACTFORMAT + MENUITEM "?dbsetting(contact,module,setting)", ID__VARIABLES_DBSETTINGCONTACTMODULESETTING + MENUITEM "?txtfile(file,line)", ID__VARIABLES_TXTFILEFILELINE + MENUITEM "?if(condition,true,false)", ID__VARIABLES_IFCONDITIONTRUEFALSE + MENUITEM "?strcmp(string1,string2)", ID__VARIABLES_STRCMPSTRING1STRING2 + MENUITEM "?stricmp(string1,string2)", ID__VARIABLES_STRICMPSTRING1STRING2 + MENUITEM "?cdate(format)", ID__VARIABLES_CDATEFORMAT + MENUITEM "?ctime(format)", ID__VARIABLES_CTIMEFORMAT + MENUITEM "?replace(sub,string1,string2)", ID__VARIABLES_REPLACESUBSTRING1STRING2 + MENUITEM "?lower(string)", ID__VARIABLES_LOWERSTRING + MENUITEM "?upper(string)", ID__VARIABLES_UPPERSTRING + MENUITEM "?scroll(string,numchars,numchars)", ID__VARIABLES_SCROLLSTRINGNUMCHARSNUMCHARS + MENUITEM SEPARATOR + MENUITEM "More variables...", ID__VARIABLES_MOREVARIABLES + END + MENUITEM "Fortune", ID__FORTUNEAWAYMSG + MENUITEM "Variables", ID__VARIABLES + MENUITEM SEPARATOR + MENUITEM "Cut", IDM_CUT + MENUITEM "Copy", IDM_COPY + MENUITEM "Paste", IDM_PASTE + MENUITEM "Delete", IDM_DELETE + MENUITEM SEPARATOR + MENUITEM "Select All", IDM_SELECTALL + END +END + +#endif // Polish resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_GENERAL DIALOGEX 0, 0, 307, 216 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Behaviour on status change",IDC_STATIC,4,2,300,58,WS_GROUP + COMBOBOX IDC_CBOPTPROTO,13,15,106,97,CBS_DROPDOWNLIST | WS_TABSTOP + PUSHBUTTON "Apply to all",IDC_BOPTPROTO,123,15,60,13 + LTEXT "Max length:",IDC_MAXLENGTH,198,17,63,8 + EDITTEXT IDC_EMAXLENGTH,262,15,36,12,ES_NUMBER | NOT WS_BORDER,WS_EX_CLIENTEDGE + CONTROL "Spin2",IDC_SMAXLENGTH,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,288,15,10,14 + CONTROL "Pop up dialog box",IDC_ROPTPROTO1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,26,31,128,8 + CONTROL "Do not change status message",IDC_ROPTPROTO2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,26,43,128,8 + CONTROL "Always set the same message",IDC_ROPTPROTO3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,155,31,144,8 + CONTROL "Do not set status message",IDC_ROPTPROTO4,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,155,43,144,8 + GROUPBOX "Status Messages",IDC_STATIC,4,62,300,148,WS_GROUP + COMBOBOX IDC_CBOPTSTATUS,35,73,240,97,CBS_DROPDOWNLIST | WS_TABSTOP + PUSHBUTTON "Apply to all",IDC_BOPTSTATUS,215,90,60,13 + CONTROL "Pop up dialog asking for new message",IDC_COPTMSG1, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,89,166,8 + CONTROL "Set an empty message",IDC_ROPTMSG1,"Button",BS_AUTORADIOBUTTON | BS_VCENTER | WS_TABSTOP,48,100,166,8 + CONTROL "Use default message",IDC_ROPTMSG2,"Button",BS_AUTORADIOBUTTON | BS_VCENTER | WS_TABSTOP,48,111,166,8 + CONTROL "Use last message",IDC_ROPTMSG3,"Button",BS_AUTORADIOBUTTON | BS_VCENTER | WS_TABSTOP,48,122,166,8 + CONTROL "Use last message set for this status",IDC_ROPTMSG5, + "Button",BS_AUTORADIOBUTTON | BS_VCENTER | WS_TABSTOP,48,133,166,8 + CONTROL "Set the following message:",IDC_ROPTMSG4,"Button",BS_AUTORADIOBUTTON | BS_VCENTER | WS_TABSTOP,48,144,166,8 + EDITTEXT IDC_OPTEDIT1,58,155,219,38,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + CONTROL "",IDC_VARSHELP,"MButtonClass",WS_TABSTOP,261,141,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "Put default message in message list",IDC_COPTMSG2, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,35,196,179,8 +END + +IDD_OPT_VARIABLES DIALOGEX 0, 0, 307, 226 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Variables",IDC_STATIC,4,2,300,100,WS_GROUP + CONTROL "Update variables in status messages every",IDC_CUPDATEMSG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,16,150,8 + EDITTEXT IDC_ESECUPDTMSG,166,14,32,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Spin2",IDC_SSECUPDTMSG,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,188,14,11,14 + LTEXT "seconds",IDC_STATIC,202,16,32,8 + CONTROL "Do not update variables during idle",IDC_CNOIDLE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,30,274,8 + CONTROL "Do not update variables on ICQ status message requests",IDC_CNOICQREQ, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,44,274,8 + CONTROL "Leave last played track's title after exiting the player",IDC_CLEAVEWINAMP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,58,274,8 + CONTROL "Enable status messages parsing by Variables plugin",IDC_CVARIABLES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,287,8 + CONTROL "Exclude %date% token from parsing (restart required)",IDC_CDATEPARSING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,86,274,8 +END + +IDD_OPT_ADVANCED DIALOGEX 0, 0, 307, 226 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Layout",IDC_STATIC,4,2,300,58,WS_GROUP + CONTROL "Show status list",IDC_CSTATUSLIST,"Button",BS_AUTOCHECKBOX | BS_LEFT | BS_VCENTER | WS_TABSTOP,12,16,137,10 + CONTROL "Show status profiles in status list",IDC_CPROFILES, + "Button",BS_AUTOCHECKBOX | BS_LEFT | BS_VCENTER | WS_TABSTOP,12,30,140,10 + CONTROL "Show icons in status list",IDC_CICONS1,"Button",BS_AUTOCHECKBOX | BS_LEFT | BS_VCENTER | WS_TABSTOP,12,44,138,10 + LTEXT "Buttons:",IDC_STATIC,154,16,58,8 + COMBOBOX IDC_CBOPTBUTTONS,154,28,144,100,CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "Show icons in message list",IDC_CICONS2,"Button",BS_AUTOCHECKBOX | BS_LEFT | BS_VCENTER | WS_TABSTOP,154,44,140,10 + GROUPBOX "Other",IDC_STATIC,4,62,300,112,WS_GROUP + CONTROL "Store up to",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP,12,76,45,8 + EDITTEXT IDC_EMAXHIST,58,74,28,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Spin2",IDC_SMAXHIST,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,76,73,11,14 + LTEXT "recent messages (0 = disable)",IDC_STATIC,90,76,143,8 + CONTROL "Automatically close dialog window after",IDC_CCLOSEWND, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,90,150,8 + EDITTEXT IDC_ETIMEOUT,166,88,28,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Spin2",IDC_STIMEOUT,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,184,87,11,14 + LTEXT "seconds",IDC_STATIC,198,90,36,8 + CONTROL "Remember last dialog window position",IDC_CRPOSWND, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,104,222,8 + CONTROL "Remove Carriage Return (CR = '\\r' = #0D) chars from status messages",IDC_CREMOVECR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,118,287,8 + CONTROL "Show 'Copy Away Message' item in contact menu",IDC_CSHOWCOPY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,132,287,8 + CONTROL "Show 'Go to URL in Away Message' item in contact menu",IDC_CSHOWGURL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,146,287,8 + CONTROL "Show 'Status Message...' item in status menu",IDC_CSHOWSMSG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,160,287,8 + CONTROL "Clear History",IDC_BOPTHIST,"MButtonClass",WS_TABSTOP,236,73,61,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "Clear Predefined",IDC_BOPTDEF,"MButtonClass",WS_TABSTOP,236,90,61,14,WS_EX_NOACTIVATE | 0x10000000L + LTEXT "* This feature is available only when using StartupStatus plugin.",IDC_NOTE1,11,177,287,8,NOT WS_VISIBLE +END + +IDD_OPT_STATUS DIALOGEX 0, 0, 241, 162 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Status on Startup",IDC_STATIC,5,2,230,154,WS_GROUP + LTEXT "Set status after",IDC_STATIC,15,18,80,8 + EDITTEXT IDC_ESETSTATUS,96,16,36,12,ES_NUMBER | NOT WS_BORDER,WS_EX_CLIENTEDGE + CONTROL "Spin2",IDC_SSETSTATUS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,122,16,11,14 + LTEXT "miliseconds",IDC_STATIC,136,18,90,8 + LTEXT "Protocol:",IDC_STATIC,16,34,63,8 + LISTBOX IDC_LISTPROTO,15,45,100,75,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LTEXT "Status:",IDC_STATIC,126,34,63,8 + LISTBOX IDC_LISTSTATUS,125,45,100,75,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + CONTROL "Independent setting for each protocol",IDC_SPECSET, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,126,210,8 + CONTROL "Pop up dialog asking for status message",IDC_POPUPDLG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,138,210,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT_GENERAL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 300 + TOPMARGIN, 7 + BOTTOMMARGIN, 209 + END + + IDD_OPT_VARIABLES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 300 + TOPMARGIN, 7 + BOTTOMMARGIN, 219 + END + + IDD_OPT_ADVANCED, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 300 + TOPMARGIN, 7 + BOTTOMMARGIN, 219 + END + + IDD_OPT_STATUS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 234 + TOPMARGIN, 7 + BOTTOMMARGIN, 155 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/SimpleStatusMsg/simplestatusmsg.h b/plugins/SimpleStatusMsg/simplestatusmsg.h new file mode 100644 index 0000000000..d66aba197c --- /dev/null +++ b/plugins/SimpleStatusMsg/simplestatusmsg.h @@ -0,0 +1,105 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef SIMPLESTATUSMSG_H__ +#define SIMPLESTATUSMSG_H__ 1 + +typedef struct tagACCOUNTS +{ + PROTOACCOUNT **pa; + int count; + int statusCount; + DWORD statusFlags; + int statusMsgCount; + DWORD statusMsgFlags; +} +PROTOACCOUNTS; + +extern PROTOACCOUNTS *accounts; + +#define DLG_SHOW_STATUS 1 +#define DLG_SHOW_STATUS_ICONS 2 +#define DLG_SHOW_LIST_ICONS 4 +#define DLG_SHOW_BUTTONS 8 +#define DLG_SHOW_BUTTONS_INLIST 16 +#define DLG_SHOW_BUTTONS_FLAT 32 +#define DLG_SHOW_STATUS_PROFILES 64 +//NOTE: MAX 128 +#define DLG_SHOW_DEFAULT DLG_SHOW_STATUS | DLG_SHOW_STATUS_ICONS | DLG_SHOW_LIST_ICONS | DLG_SHOW_BUTTONS + +#define STATUS_SHOW_DLG 1 +#define STATUS_EMPTY_MSG 2 +#define STATUS_DEFAULT_MSG 4 +#define STATUS_LAST_MSG 8 +#define STATUS_THIS_MSG 16 +#define STATUS_LAST_STATUS_MSG 32 +#define STATUS_DEFAULT STATUS_SHOW_DLG | STATUS_LAST_MSG + +#define PROTO_NO_MSG 1 +#define PROTO_THIS_MSG 2 +#define PROTO_POPUPDLG 4 +#define PROTO_NOCHANGE 8 +#define PROTO_DEFAULT PROTO_NOCHANGE + +struct MsgBoxInitData +{ + char *m_szProto; + int m_iStatus; + int m_iStatusModes; + int m_iStatusMsgModes; + BOOL m_bOnEvent; + BOOL m_bOnStartup; +}; + +extern HINSTANCE g_hInst; +extern HWND hwndSAMsgDialog; + +#define MS_SIMPLESTATUSMSG_SHOWDIALOGINT "SimpleStatusMsg/ShowDialogInternal" // internal use ONLY + +/* awaymsg.cpp */ +int LoadAwayMsgModule(void); +int AwayMsgPreShutdown(void); + +/* main.cpp */ +void SetStatusMessage(const char *szProto, int initial_status_mode, int status_mode, TCHAR *message, BOOL on_startup); + +/* msgbox.cpp */ +INT_PTR CALLBACK AwayMsgBoxDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +/* options.cpp */ +int InitOptions(WPARAM wParam, LPARAM lParam); + +/* utils.cpp */ +void IconsInit(void); +HICON LoadIconEx(const char* name); +HANDLE GetIconHandle(int iconId); +void ReleaseIconEx(const char* name); +HANDLE HookEventEx(const char *szEvent, MIRANDAHOOK hookProc); +void UnhookEvents(void); +HANDLE HookProtoEvent(const char *szModule, const char *szEvent, MIRANDAHOOKPARAM hookProc); +void UnhookProtoEvents(void); +HANDLE CreateServiceFunctionEx(const char *name, MIRANDASERVICE serviceProc); +void DestroyServiceFunctionsEx(void); +int GetRandom(int from, int to); +const TCHAR *GetDefaultMessage(int status); +const char *StatusModeToDbSetting(int status, const char *suffix); +int GetCurrentStatus(const char *szProto); +int GetStartupStatus(const char *szProto); + +#endif // SIMPLESTATUSMSG_H__ diff --git a/plugins/SimpleStatusMsg/simplestatusmsg_10.sln b/plugins/SimpleStatusMsg/simplestatusmsg_10.sln new file mode 100644 index 0000000000..cc9e1ba186 --- /dev/null +++ b/plugins/SimpleStatusMsg/simplestatusmsg_10.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simplestatusmsg", "simplestatusmsg_10.vcxproj", "{D3D80E27-D099-41EC-AFB2-A891A33F1608}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Debug|Win32.ActiveCfg = Debug|Win32 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Debug|Win32.Build.0 = Debug|Win32 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Debug|x64.ActiveCfg = Debug|x64 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Debug|x64.Build.0 = Debug|x64 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Release|Win32.ActiveCfg = Release|Win32 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Release|Win32.Build.0 = Release|Win32 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Release|x64.ActiveCfg = Release|x64 + {D3D80E27-D099-41EC-AFB2-A891A33F1608}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj b/plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj new file mode 100644 index 0000000000..c0ebd36847 --- /dev/null +++ b/plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj @@ -0,0 +1,309 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + SimpleStatusMsg + {D3D80E27-D099-41EC-AFB2-A891A33F1608} + simplestatusmsg + + + + DynamicLibrary + false + Unicode + true + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + true + + + DynamicLibrary + false + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + $(SolutionDir)$(Configuration)64/Plugins\ + $(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\ + true + $(SolutionDir)$(Configuration)/Plugins\ + $(SolutionDir)$(Configuration)/Obj/$(ProjectName)\ + true + $(SolutionDir)$(Configuration)64/Plugins\ + $(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\ + true + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/simplestatusmsg.tlb + + + + + Disabled + ../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions) + false + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + true + EditAndContinue + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + comctl32.lib;%(AdditionalDependencies) + true + true + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/simplestatusmsg.tlb + + + + + Disabled + ../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions) + false + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0415 + + + comctl32.lib;%(AdditionalDependencies) + true + true + false + + + $(IntDir)$(TargetName).lib + MachineX64 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/simplestatusmsg.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + Fast + false + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + comctl32.lib;%(AdditionalDependencies) + true + true + false + + + true + true + UseLinkTimeCodeGeneration + 0x3ab00000 + false + + + $(IntDir)$(TargetName).lib + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/simplestatusmsg.tlb + + + + + Full + OnlyExplicitInline + Size + true + ../../include;../ExternalAPI;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions) + true + + + MultiThreadedDLL + false + true + Fast + false + + + Level3 + true + ProgramDatabase + Default + 4996;%(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0415 + + + comctl32.lib;%(AdditionalDependencies) + true + true + false + + + true + true + UseLinkTimeCodeGeneration + 0x3ab00000 + false + + + $(IntDir)$(TargetName).lib + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + %(PreprocessorDefinitions) + + + + + + \ No newline at end of file diff --git a/plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj.filters b/plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj.filters new file mode 100644 index 0000000000..ed6adb665f --- /dev/null +++ b/plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj.filters @@ -0,0 +1,82 @@ + + + + + {f92a9951-1818-4755-9280-646f9e75ed9e} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {eb57c612-24d9-49f3-bc59-ddcb10eea749} + h;hpp;hxx;hm;inl + + + {0dbf023c-69ee-4bc3-b830-47b713155501} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/SimpleStatusMsg/utils.cpp b/plugins/SimpleStatusMsg/utils.cpp new file mode 100644 index 0000000000..da2584cd22 --- /dev/null +++ b/plugins/SimpleStatusMsg/utils.cpp @@ -0,0 +1,226 @@ +/* + +Simple Status Message plugin for Miranda IM +Copyright (C) 2006-2011 Bartosz 'Dezeath' Białek, (C) 2005 Harven + +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., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "commonheaders.h" +#include "simplestatusmsg.h" + +static HANDLE *hHookList = NULL; +static HANDLE *hProtoHookList = NULL; +static HANDLE *hServiceList = NULL; +static int HookCount = 0; +static int ProtoHookCount = 0; +static int ServiceCount = 0; + +struct tagiconList +{ + const TCHAR *szDescr; + const char *szName; + int defIconID; +} +static const iconList[] = +{ + { LPGENT("Delete Selected"), "cross", IDI_CROSS }, + { LPGENT("Recent Message"), "recent", IDI_HISTORY }, + { LPGENT("Predefined Message"), "predef", IDI_MESSAGE }, + { LPGENT("Add to Predefined"), "add", IDI_PLUS }, + { LPGENT("Clear History"), "clear", IDI_CHIST }, + { LPGENT("Copy Away Message"), "copy", IDI_COPY }, + { LPGENT("Change Status Message"), "csmsg", IDI_CSMSG, }, + { LPGENT("Go to URL in Away Message"), "gotourl", IDI_GOTOURL } +}; + +HANDLE hIconLibItem[SIZEOF(iconList)]; + +void IconsInit(void) +{ + SKINICONDESC sid = {0}; + char szFile[MAX_PATH]; + char szSettingName[100]; + + GetModuleFileNameA(g_hInst, szFile, MAX_PATH); + sid.cbSize = sizeof(SKINICONDESC); + sid.flags = SIDF_TCHAR; + sid.pszDefaultFile = szFile; + sid.ptszSection = _T("Simple Status Message"); + for (int i = 0; i < SIZEOF(iconList); i++) + { + mir_snprintf(szSettingName, SIZEOF(szSettingName), "SimpleStatusMsg_%s", iconList[i].szName); + sid.pszName = szSettingName; + sid.ptszDescription = (TCHAR*)iconList[i].szDescr; + sid.iDefaultIndex = -iconList[i].defIconID; + hIconLibItem[i] = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } +} + +HICON LoadIconEx(const char* name) +{ + char szSettingName[100]; + mir_snprintf(szSettingName, sizeof(szSettingName), "SimpleStatusMsg_%s", name); + return (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)szSettingName); +} + +HANDLE GetIconHandle(int iconId) +{ + for(int i = 0; i < SIZEOF(iconList); i++) + if (iconList[i].defIconID == iconId) return hIconLibItem[i]; + return NULL; +} + +void ReleaseIconEx(const char* name) +{ + char szSettingName[100]; + mir_snprintf(szSettingName, sizeof(szSettingName), "SimpleStatusMsg_%s", name); + CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)szSettingName); +} + +HANDLE HookEventEx(const char *szEvent, MIRANDAHOOK hookProc) +{ + HookCount++; + hHookList = (HANDLE *)mir_realloc(hHookList, sizeof(HANDLE) * HookCount); + return hHookList[HookCount - 1] = HookEvent(szEvent, hookProc); +} + +void UnhookEvents(void) +{ + if (hHookList == NULL) return; + for (int i = 0; i < HookCount; ++i) + if (hHookList[i] != NULL) UnhookEvent(hHookList[i]); + mir_free(hHookList); + hHookList = NULL; + HookCount = 0; +} + +HANDLE HookProtoEvent(const char *szModule, const char *szEvent, MIRANDAHOOKPARAM hookProc) +{ + char szProtoEvent[MAXMODULELABELLENGTH]; + mir_snprintf(szProtoEvent, sizeof(szProtoEvent), "%s%s", szModule, szEvent); + ProtoHookCount++; + hProtoHookList = (HANDLE *)mir_realloc(hProtoHookList, sizeof(HANDLE) * ProtoHookCount); + return hProtoHookList[ProtoHookCount - 1] = HookEventParam(szProtoEvent, hookProc, (LPARAM)szModule); +} + +void UnhookProtoEvents(void) +{ + if (hProtoHookList == NULL) return; + for (int i = 0; i < ProtoHookCount; ++i) + if (hProtoHookList[i] != NULL) UnhookEvent(hProtoHookList[i]); + mir_free(hProtoHookList); + hProtoHookList = NULL; + ProtoHookCount = 0; +} + +HANDLE CreateServiceFunctionEx(const char *name, MIRANDASERVICE serviceProc) +{ + ServiceCount++; + hServiceList = (HANDLE *)mir_realloc(hServiceList, sizeof(HANDLE) * ServiceCount); + return hServiceList[ServiceCount - 1] = CreateServiceFunction(name, serviceProc); +} + +void DestroyServiceFunctionsEx(void) +{ + for (int i = 0; i < ServiceCount; ++i) + if (hServiceList[i] != NULL) DestroyServiceFunction(hServiceList[i]); + mir_free(hServiceList); + ServiceCount = 0; +} + +// Generate random number in a specified range +int GetRandom(int from, int to) +{ + if ((to - from) < 1) return from; + unsigned randnum; + CallService(MS_UTILS_GETRANDOM, sizeof(randnum), (LPARAM)&randnum); + return ((randnum % (to - from + 1)) + from); +} + +// From SRAway module +const TCHAR *GetDefaultMessage(int status) +{ + switch (status) + { + case ID_STATUS_AWAY: return TranslateT("I've been away since %time%."); + case ID_STATUS_NA: return TranslateT("Give it up, I'm not in!"); + case ID_STATUS_OCCUPIED: return TranslateT("Not right now."); + case ID_STATUS_DND: return TranslateT("Give a guy some peace, would ya?"); + case ID_STATUS_FREECHAT: return TranslateT("I'm a chatbot!"); + case ID_STATUS_ONLINE: return TranslateT("Yep, I'm here."); + case ID_STATUS_OFFLINE: return TranslateT("Nope, not here."); + case ID_STATUS_INVISIBLE: return TranslateT("I'm hiding from the mafia."); + case ID_STATUS_ONTHEPHONE: return TranslateT("That'll be the phone."); + case ID_STATUS_OUTTOLUNCH: return TranslateT("Mmm...food."); + case ID_STATUS_IDLE: return TranslateT("idleeeeeeee"); + } + return NULL; +} + +const char *StatusModeToDbSetting(int status, const char *suffix) +{ + const char *prefix; + static char str[64]; + + switch (status) + { + case ID_STATUS_AWAY: prefix = "Away"; break; + case ID_STATUS_NA: prefix = "Na"; break; + case ID_STATUS_DND: prefix = "Dnd"; break; + case ID_STATUS_OCCUPIED: prefix = "Occupied"; break; + case ID_STATUS_FREECHAT: prefix = "FreeChat"; break; + case ID_STATUS_ONLINE: prefix = "On"; break; + case ID_STATUS_OFFLINE: prefix = "Off"; break; + case ID_STATUS_INVISIBLE: prefix = "Inv"; break; + case ID_STATUS_ONTHEPHONE: prefix = "Otp"; break; + case ID_STATUS_OUTTOLUNCH: prefix = "Otl"; break; + case ID_STATUS_IDLE: prefix = "Idl"; break; + default: return NULL; + } + mir_snprintf(str, SIZEOF(str), "%s%s", prefix, suffix); + return str; +} + +int GetCurrentStatus(const char *szProto) +{ + if (szProto) + { + char szSetting[80]; + mir_snprintf(szSetting, SIZEOF(szSetting), "Cur%sStatus", szProto); + return (int)DBGetContactSettingWord(NULL, "SimpleStatusMsg", szSetting, ID_STATUS_OFFLINE); + + } + return CallService(MS_CLIST_GETSTATUSMODE, 0, 0); +} + +int GetStartupStatus(const char *szProto) +{ + if (szProto) + { + int status_mode; + char szSetting[80]; + + mir_snprintf(szSetting, SIZEOF(szSetting), "Startup%sStatus", szProto); + status_mode = DBGetContactSettingWord(NULL, "SimpleStatusMsg", szSetting, ID_STATUS_OFFLINE); + if (status_mode == ID_STATUS_CURRENT) + { + // load status used for this proto last time + mir_snprintf(szSetting, SIZEOF(szSetting), "Last%sStatus", szProto); + status_mode = DBGetContactSettingWord(NULL, "SimpleStatusMsg", szSetting, ID_STATUS_OFFLINE); + } + return status_mode; + } + return (int)DBGetContactSettingWord(NULL, "SimpleStatusMsg", "StartupStatus", ID_STATUS_OFFLINE); +} -- cgit v1.2.3