summaryrefslogtreecommitdiff
path: root/plugins/SimpleStatusMsg
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-20 19:23:15 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-20 19:23:15 +0000
commitd80195880f3a04b4a826816f6c2a3468f121ed55 (patch)
treee24aa22b07ebacac370584e441647996d46ec4eb /plugins/SimpleStatusMsg
parent12274c83beaefd2815190ac84d404510eed0394f (diff)
AddContactPlus and SimpleStatusMsg added
git-svn-id: http://svn.miranda-ng.org/main/trunk@109 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/SimpleStatusMsg')
-rw-r--r--plugins/SimpleStatusMsg/awaymsg.cpp535
-rw-r--r--plugins/SimpleStatusMsg/commonheaders.h65
-rw-r--r--plugins/SimpleStatusMsg/docs/simplestatusmsg-changelog.txt270
-rw-r--r--plugins/SimpleStatusMsg/docs/simplestatusmsg-license.txt339
-rw-r--r--plugins/SimpleStatusMsg/docs/simplestatusmsg-readme.txt81
-rw-r--r--plugins/SimpleStatusMsg/docs/simplestatusmsg-translation.txt138
-rw-r--r--plugins/SimpleStatusMsg/m_simpleaway.h103
-rw-r--r--plugins/SimpleStatusMsg/main.cpp2269
-rw-r--r--plugins/SimpleStatusMsg/msgbox.cpp1806
-rw-r--r--plugins/SimpleStatusMsg/options.cpp1752
-rw-r--r--plugins/SimpleStatusMsg/res/cbook.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/copy.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/cross.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/csmsg.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/gotourl.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/history.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/msg.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/res/plus.icobin0 -> 2550 bytes
-rw-r--r--plugins/SimpleStatusMsg/resource.h126
-rw-r--r--plugins/SimpleStatusMsg/resource.rc437
-rw-r--r--plugins/SimpleStatusMsg/simplestatusmsg.h105
-rw-r--r--plugins/SimpleStatusMsg/simplestatusmsg_10.sln26
-rw-r--r--plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj309
-rw-r--r--plugins/SimpleStatusMsg/simplestatusmsg_10.vcxproj.filters82
-rw-r--r--plugins/SimpleStatusMsg/utils.cpp226
25 files changed, 8669 insertions, 0 deletions
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 <m_stdhdr.h>
+
+#include <windows.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <newpluginapi.h>
+#include <m_button.h>
+#include <m_clist.h>
+#include <m_clistint.h>
+#include <m_skin.h>
+#include <m_system.h>
+#include <m_options.h>
+#include <m_langpack.h>
+#include <m_protosvc.h>
+#include <m_utils.h>
+#include <m_database.h>
+#include <m_awaymsg.h>
+#include <m_idle.h>
+#include <m_icolib.h>
+#include <m_protoint.h>
+#include <m_hotkeys.h>
+#include <m_icq.h>
+#include <win2k.h>
+
+#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 <current> 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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]
+;[<current>]
+;[<startup>]
+;[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:]
+;[<Last 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 <io.h>
+
+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("<startup>");
+ else
+ status_desc = (TCHAR*)TranslateT("<current>");
+ 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("<startup>"), szProtoName);
+ else
+ mir_sntprintf(szTitle, SIZEOF(szTitle), TranslateT("%s Message (%s)"), TranslateT("<current>"), 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("<startup>"), szProtoName);
+ else
+ mir_sntprintf(szTitle, SIZEOF(szTitle), szFormat, TranslateT("<current>"), 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("<Last status>"));
+ 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
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/cbook.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/copy.ico b/plugins/SimpleStatusMsg/res/copy.ico
new file mode 100644
index 0000000000..1bb44affef
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/copy.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/cross.ico b/plugins/SimpleStatusMsg/res/cross.ico
new file mode 100644
index 0000000000..c5417931c7
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/cross.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/csmsg.ico b/plugins/SimpleStatusMsg/res/csmsg.ico
new file mode 100644
index 0000000000..9e1dcd2572
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/csmsg.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/gotourl.ico b/plugins/SimpleStatusMsg/res/gotourl.ico
new file mode 100644
index 0000000000..bd50d80679
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/gotourl.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/history.ico b/plugins/SimpleStatusMsg/res/history.ico
new file mode 100644
index 0000000000..2dd478cbc5
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/history.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/msg.ico b/plugins/SimpleStatusMsg/res/msg.ico
new file mode 100644
index 0000000000..13b3d7aac3
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/msg.ico
Binary files differ
diff --git a/plugins/SimpleStatusMsg/res/plus.ico b/plugins/SimpleStatusMsg/res/plus.ico
new file mode 100644
index 0000000000..2efc4dc1a2
--- /dev/null
+++ b/plugins/SimpleStatusMsg/res/plus.ico
Binary files 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>SimpleStatusMsg</ProjectName>
+ <ProjectGuid>{D3D80E27-D099-41EC-AFB2-A891A33F1608}</ProjectGuid>
+ <RootNamespace>simplestatusmsg</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IgnoreImportLibrary>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64/Obj/$(ProjectName)\</IntDir>
+ <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/simplestatusmsg.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>false</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>.\Debug/simplestatusmsg.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>false</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/simplestatusmsg.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapFileName>
+ </MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x3ab00000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>.\Release/simplestatusmsg.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;SIMPLESTATUSMSG_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapFileName>
+ </MapFileName>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <BaseAddress>0x3ab00000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="awaymsg.cpp" />
+ <ClCompile Include="main.cpp" />
+ <ClCompile Include="msgbox.cpp" />
+ <ClCompile Include="options.cpp" />
+ <ClCompile Include="utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="commonheaders.h" />
+ <ClInclude Include="m_simpleaway.h" />
+ <ClInclude Include="m_simplestatusmsg.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="simplestatusmsg.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="res\cbook.ico" />
+ <None Include="res\copy.ico" />
+ <None Include="res\cross.ico" />
+ <None Include="res\csmsg.ico" />
+ <None Include="res\gotourl.ico" />
+ <None Include="res\history.ico" />
+ <None Include="res\msg.ico" />
+ <None Include="res\plus.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ 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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{f92a9951-1818-4755-9280-646f9e75ed9e}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{eb57c612-24d9-49f3-bc59-ddcb10eea749}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{0dbf023c-69ee-4bc3-b830-47b713155501}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="awaymsg.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="msgbox.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="commonheaders.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_simpleaway.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_simplestatusmsg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="simplestatusmsg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="res\cbook.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\copy.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\cross.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\csmsg.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\gotourl.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\history.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\msg.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\plus.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ 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);
+}