summaryrefslogtreecommitdiff
path: root/plugins
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
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')
-rw-r--r--plugins/AddContactPlus/addcontact.cpp433
-rw-r--r--plugins/AddContactPlus/addcontactplus.h53
-rw-r--r--plugins/AddContactPlus/addcontactplus_10.sln26
-rw-r--r--plugins/AddContactPlus/addcontactplus_10.vcxproj316
-rw-r--r--plugins/AddContactPlus/addcontactplus_10.vcxproj.filters43
-rw-r--r--plugins/AddContactPlus/contact_add.icobin0 -> 6830 bytes
-rw-r--r--plugins/AddContactPlus/docs/addcontactplus-license.txt339
-rw-r--r--plugins/AddContactPlus/docs/addcontactplus-readme.txt89
-rw-r--r--plugins/AddContactPlus/docs/addcontactplus-translation.txt12
-rw-r--r--plugins/AddContactPlus/main.cpp225
-rw-r--r--plugins/AddContactPlus/resource.h28
-rw-r--r--plugins/AddContactPlus/resource.rc176
-rw-r--r--plugins/ExternalAPI/m_addcontactplus.h33
-rw-r--r--plugins/ExternalAPI/m_simplestatusmsg.h50
-rw-r--r--plugins/NewAwaySysMod/NewAwaySys.sln12
-rw-r--r--plugins/SecureIM/secureim_icons_10.vcxproj2
-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
-rw-r--r--plugins/UserInfoEx/IconPacks/default/icons_default_10.vcxproj2
-rw-r--r--plugins/UserInfoEx/IconPacks/default/icons_default_10_z2.vcxproj2
-rw-r--r--plugins/UserInfoEx/IconPacks/ice/icons_ice_10.vcxproj2
-rw-r--r--plugins/UserInfoEx/IconPacks/ice/icons_ice_10_z2.vcxproj2
45 files changed, 10503 insertions, 11 deletions
diff --git a/plugins/AddContactPlus/addcontact.cpp b/plugins/AddContactPlus/addcontact.cpp
new file mode 100644
index 0000000000..a2feb5c449
--- /dev/null
+++ b/plugins/AddContactPlus/addcontact.cpp
@@ -0,0 +1,433 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2011 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+Portions of this code modified for AddContact+ plugin
+Copyright (C) 2007-2011 Bartosz 'Dezeath' Bia³ek
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "addcontactplus.h"
+#include <limits.h>
+
+// Function from miranda\src\modules\utils\utils.cpp
+TCHAR* __fastcall rtrim(TCHAR* str)
+{
+ if (str == NULL) return NULL;
+ TCHAR* p = _tcschr(str, 0);
+ while (--p >= str)
+ {
+ switch (*p)
+ {
+ case ' ': case '\t': case '\n': case '\r':
+ *p = 0; break;
+ default:
+ return str;
+ }
+ }
+ return str;
+}
+
+typedef struct // mNetSend protocol
+{
+ PROTOSEARCHRESULT hdr;
+ DWORD dwIP;
+} NETSENDSEARCHRESULT;
+
+typedef struct // Myspace protocol
+{
+ PROTOSEARCHRESULT psr;
+ int uid;
+} MYPROTOSEARCHRESULT;
+
+typedef struct // Tlen protocol
+{
+ PROTOSEARCHRESULT hdr;
+ char jid[256];
+} TLEN_SEARCH_RESULT;
+
+void AddContactDlgOpts(HWND hdlg, const char* szProto, BOOL bAuthOptsOnly = FALSE)
+{
+ DWORD flags = (szProto) ? CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0) : 0;
+ if (IsDlgButtonChecked(hdlg, IDC_ADDTEMP))
+ {
+ EnableWindow(GetDlgItem(hdlg, IDC_ADDED), FALSE);
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTH), FALSE);
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), FALSE);
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hdlg, IDC_ADDED), !(flags & PF4_FORCEADDED));
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTH), !(flags & PF4_FORCEAUTH));
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), (flags & PF4_NOCUSTOMAUTH) ? FALSE : IsDlgButtonChecked(hdlg, IDC_AUTH));
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), (flags & PF4_NOCUSTOMAUTH) ? FALSE : IsDlgButtonChecked(hdlg, IDC_AUTH));
+ }
+
+ if (bAuthOptsOnly)
+ return;
+
+ SetDlgItemText(hdlg, IDC_AUTHREQ, (flags & PF4_NOCUSTOMAUTH) ? _T("") : TranslateT("Please authorize my request and add me to your contact list."));
+
+ char* szUniqueId = (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0);
+ if (szUniqueId)
+ {
+ size_t cbLen = strlen(szUniqueId) + 2;
+ TCHAR* pszUniqueId = (TCHAR*)mir_alloc(cbLen * sizeof(TCHAR));
+ mir_sntprintf(pszUniqueId, cbLen, _T(TCHAR_STR_PARAM) _T(":"), szUniqueId);
+ SetDlgItemText(hdlg, IDC_IDLABEL, pszUniqueId);
+ mir_free(pszUniqueId);
+ }
+ else
+ SetDlgItemText(hdlg, IDC_IDLABEL, TranslateT("Contact ID:"));
+
+ flags = (szProto) ? CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) : 0;
+ if (flags & PF1_NUMERICUSERID)
+ {
+ char buffer[65];
+ SetWindowLongPtr(GetDlgItem(hdlg, IDC_USERID), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hdlg, IDC_USERID), GWL_STYLE) | ES_NUMBER);
+ if (strstr(szProto, "GG") || strstr(szProto, "MYSPACE"))
+ _ultoa(INT_MAX, buffer, 10);
+ else
+ _ultoa(ULONG_MAX, buffer, 10);
+ SendDlgItemMessage(hdlg, IDC_USERID, EM_LIMITTEXT, (WPARAM)strlen(buffer), 0);
+ }
+ else
+ {
+ SetWindowLongPtr(GetDlgItem(hdlg, IDC_USERID), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hdlg, IDC_USERID), GWL_STYLE) &~ES_NUMBER);
+ SendDlgItemMessage(hdlg, IDC_USERID, EM_LIMITTEXT, 255, 0);
+ }
+}
+
+void AddContactDlgAccounts(HWND hdlg, ADDCONTACTSTRUCT* acs)
+{
+ PROTOACCOUNT** pAccounts;
+ int iRealAccCount, iAccCount = 0, i;
+ DWORD dwCaps;
+
+ ProtoEnumAccounts(&iRealAccCount, &pAccounts);
+ for (i = 0; i < iRealAccCount; i++)
+ {
+ if (!IsAccountEnabled(pAccounts[i])) continue;
+ dwCaps = (DWORD)CallProtoService(pAccounts[i]->szModuleName, PS_GETCAPS,PFLAGNUM_1, 0);
+ if (dwCaps & PF1_BASICSEARCH || dwCaps & PF1_EXTSEARCH || dwCaps & PF1_SEARCHBYEMAIL || dwCaps & PF1_SEARCHBYNAME)
+ iAccCount++;
+ }
+
+ if (iAccCount == 0)
+ {
+ if (GetParent(hdlg) == NULL)
+ DestroyWindow(hdlg);
+ else
+ EndDialog(hdlg, 0);
+ return;
+ }
+
+ HICON hIcon;
+ SIZE textSize;
+ RECT rc;
+ int iIndex = 0, cbWidth = 0;
+
+ HIMAGELIST hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (IsWinVerXPPlus() ? ILC_COLOR32 : ILC_COLOR16) | ILC_MASK, iAccCount, 0);
+ ImageList_Destroy((HIMAGELIST)SendDlgItemMessage(hdlg, IDC_PROTO, CBEM_SETIMAGELIST, 0, (LPARAM)hIml));
+ SendDlgItemMessage(hdlg, IDC_PROTO, CB_RESETCONTENT, 0, 0);
+
+ COMBOBOXEXITEM cbei = {0};
+ cbei.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
+ HDC hdc = GetDC(hdlg);
+ SelectObject(hdc, (HFONT)SendDlgItemMessage(hdlg, IDC_PROTO, WM_GETFONT, 0, 0));
+ for (i = 0; i < iRealAccCount; i++)
+ {
+ if (!IsAccountEnabled(pAccounts[i])) continue;
+ dwCaps = (DWORD)CallProtoService(pAccounts[i]->szModuleName, PS_GETCAPS,PFLAGNUM_1, 0);
+ if (!(dwCaps & PF1_BASICSEARCH) && !(dwCaps & PF1_EXTSEARCH) && !(dwCaps & PF1_SEARCHBYEMAIL) && !(dwCaps & PF1_SEARCHBYNAME))
+ continue;
+
+ cbei.pszText = pAccounts[i]->tszAccountName;
+ GetTextExtentPoint32(hdc, cbei.pszText, lstrlen(cbei.pszText), &textSize);
+ if (textSize.cx > cbWidth) cbWidth = textSize.cx;
+ hIcon = (HICON)CallProtoService(pAccounts[i]->szModuleName, PS_LOADICON, PLI_PROTOCOL | PLIF_SMALL, 0);
+ cbei.iImage = cbei.iSelectedImage = ImageList_AddIcon(hIml, hIcon);
+ DestroyIcon(hIcon);
+ cbei.lParam = (LPARAM)pAccounts[i]->szModuleName;
+ SendDlgItemMessage(hdlg, IDC_PROTO, CBEM_INSERTITEM, 0, (LPARAM)&cbei);
+ if (acs->szProto && cbei.lParam && !strcmp(acs->szProto, pAccounts[i]->szModuleName))
+ iIndex = cbei.iItem;
+ cbei.iItem++;
+ }
+ cbWidth += 32;
+ SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
+ if ((rc.right - rc.left) < cbWidth)
+ SendDlgItemMessage(hdlg, IDC_PROTO, CB_SETDROPPEDWIDTH, cbWidth, 0);
+ SendDlgItemMessage(hdlg, IDC_PROTO, CB_SETCURSEL, iIndex, 0);
+ SendMessage(hdlg, WM_COMMAND, MAKEWPARAM(IDC_PROTO, CBN_SELCHANGE), (LPARAM)GetDlgItem(hdlg, IDC_PROTO));
+ if (iAccCount == 1)
+ SetFocus(GetDlgItem(hdlg, IDC_USERID));
+}
+
+#define DM_ADDCONTACT_CHANGEICONS WM_USER + 11
+#define DM_ADDCONTACT_CHANGEACCLIST WM_USER + 12
+
+INT_PTR CALLBACK AddContactDlgProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ ADDCONTACTSTRUCT* acs;
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ acs = (ADDCONTACTSTRUCT*)mir_calloc(sizeof(ADDCONTACTSTRUCT));
+ acs->handleType = HANDLE_SEARCHRESULT;
+ SetWindowLongPtr(hdlg, GWLP_USERDATA, (LONG_PTR)acs);
+
+ Utils_RestoreWindowPositionNoSize(hdlg, NULL, "AddContact", "");
+ TranslateDialogDefault(hdlg);
+ SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)CallService(MS_SKIN2_GETICON, 1, (LPARAM)ICON_ADD));
+ SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)CallService(MS_SKIN2_GETICON, 0, (LPARAM)ICON_ADD));
+ HookEventMessage(ME_SKIN2_ICONSCHANGED, hdlg, DM_ADDCONTACT_CHANGEICONS);
+ HookEventMessage(ME_PROTO_ACCLISTCHANGED, hdlg, DM_ADDCONTACT_CHANGEACCLIST);
+
+ {
+ for (int groupId = 0; groupId < 999; groupId++)
+ {
+ DBVARIANT dbv;
+ char idstr[4];
+ int id;
+ _itoa(groupId, idstr, 10);
+ if (DBGetContactSettingTString(NULL, "CListGroups", idstr, &dbv)) break;
+ id = SendDlgItemMessage(hdlg, IDC_GROUP, CB_ADDSTRING, 0, (LPARAM)(dbv.ptszVal + 1));
+ SendDlgItemMessage(hdlg, IDC_GROUP, CB_SETITEMDATA, (WPARAM)id, (LPARAM)groupId + 1);
+ DBFreeVariant(&dbv);
+ }
+ }
+ SendDlgItemMessage(hdlg, IDC_GROUP, CB_INSERTSTRING, 0, (LPARAM)TranslateT("None"));
+ SendDlgItemMessage(hdlg, IDC_GROUP, CB_SETCURSEL, 0, 0);
+
+ AddContactDlgAccounts(hdlg, acs);
+ // By default check these checkboxes
+ CheckDlgButton(hdlg, IDC_ADDED, BST_CHECKED);
+ CheckDlgButton(hdlg, IDC_AUTH, BST_CHECKED);
+ AddContactDlgOpts(hdlg, acs->szProto);
+ EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);
+ break;
+
+ case WM_COMMAND:
+ acs = (ADDCONTACTSTRUCT*)GetWindowLongPtr(hdlg, GWLP_USERDATA);
+ switch (LOWORD(wparam))
+ {
+ case IDC_USERID:
+ if (HIWORD(wparam) == EN_CHANGE)
+ {
+ TCHAR szUserId[256];
+ if (GetDlgItemText(hdlg, IDC_USERID, szUserId, SIZEOF(szUserId)))
+ {
+ if (!IsWindowEnabled(GetDlgItem(hdlg, IDOK)))
+ EnableWindow(GetDlgItem(hdlg, IDOK), TRUE);
+ }
+ else if (IsWindowEnabled(GetDlgItem(hdlg, IDOK)))
+ EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);
+ }
+ break;
+
+ case IDC_PROTO:
+ if (HIWORD(wparam) == CBN_SELCHANGE || HIWORD(wparam) == CBN_SELENDOK)
+ {
+ acs->szProto = (char*)SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hdlg, IDC_PROTO, CB_GETCURSEL, 0, 0), 0);
+ // TODO remember last setting for each proto?
+ AddContactDlgOpts(hdlg, acs->szProto);
+ }
+ if (HIWORD(wparam) == CBN_CLOSEUP)
+ SetFocus(GetDlgItem(hdlg, IDC_USERID));
+ break;
+
+ case IDC_ADDTEMP:
+ AddContactDlgOpts(hdlg, acs->szProto, TRUE);
+ break;
+
+ case IDC_AUTH:
+ {
+ DWORD flags = CallProtoService(acs->szProto, PS_GETCAPS, PFLAGNUM_4,0);
+ if (flags & PF4_NOCUSTOMAUTH)
+ {
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), FALSE);
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), FALSE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHREQ), IsDlgButtonChecked(hdlg, IDC_AUTH));
+ EnableWindow(GetDlgItem(hdlg, IDC_AUTHGB), IsDlgButtonChecked(hdlg, IDC_AUTH));
+ }
+ break;
+ }
+
+ case IDOK:
+ {
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+ PROTOSEARCHRESULT* psr;
+
+ TCHAR szUserId[256];
+ GetDlgItemText(hdlg, IDC_USERID, szUserId, SIZEOF(szUserId));
+
+ if (*rtrim(szUserId) == 0 ||
+ (strstr(acs->szProto, "GG") && _tcstoul(szUserId, NULL, 10) > INT_MAX) || // Gadu-Gadu protocol
+ ((CallProtoService(acs->szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_NUMERICUSERID) && !_tcstoul(szUserId, NULL, 10)))
+ {
+ MessageBox(NULL,
+ TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."),
+ TranslateT("Add Contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+ break;
+ }
+
+ if (strstr(acs->szProto, "MNETSEND")) // mNetSend protocol
+ {
+ psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(NETSENDSEARCHRESULT));
+ psr->cbSize = sizeof(NETSENDSEARCHRESULT);
+ }
+ else if (strstr(acs->szProto, "MYSPACE")) // Myspace protocol
+ {
+ if (_tcstoul(szUserId, NULL, 10) > INT_MAX)
+ {
+ MessageBox(NULL,
+ TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."),
+ TranslateT("Add Contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+ break;
+ }
+ psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(MYPROTOSEARCHRESULT));
+ psr->cbSize = sizeof(MYPROTOSEARCHRESULT);
+ ((MYPROTOSEARCHRESULT*)psr)->uid = _tcstoul(szUserId, NULL, 10);
+ }
+ else if (strstr(acs->szProto, "TLEN")) // Tlen protocol
+ {
+ if (_tcschr(szUserId, '@') == NULL)
+ {
+ MessageBox(NULL,
+ TranslateT("The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly."),
+ TranslateT("Add Contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+ break;
+ }
+ psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(TLEN_SEARCH_RESULT));
+ psr->cbSize = sizeof(TLEN_SEARCH_RESULT);
+ mir_snprintf(((TLEN_SEARCH_RESULT*)psr)->jid, SIZEOF(((TLEN_SEARCH_RESULT*)psr)->jid), TCHAR_STR_PARAM, szUserId);
+ }
+ else
+ {
+ psr = (PROTOSEARCHRESULT*)mir_calloc(sizeof(PROTOSEARCHRESULT));
+ psr->cbSize = sizeof(PROTOSEARCHRESULT);
+ }
+
+ psr->flags = PSR_TCHAR;
+ psr->id = mir_tstrdup(szUserId);
+ acs->psr = psr;
+
+ hContact = (HANDLE)CallProtoService(acs->szProto, PS_ADDTOLIST, IsDlgButtonChecked(hdlg, IDC_ADDTEMP) ? PALF_TEMPORARY : 0, (LPARAM)acs->psr);
+
+ if (hContact == NULL)
+ {
+ MessageBox(NULL,
+ TranslateT("The contact cannot be added to your contact list. If you are not logged into the selected account, please try to do so. Also, make sure the contact ID is entered correctly."),
+ TranslateT("Add Contact"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+ break;
+ }
+
+ TCHAR szHandle[256];
+ if (GetDlgItemText(hdlg, IDC_MYHANDLE, szHandle, SIZEOF(szHandle)))
+ DBWriteContactSettingTString(hContact, "CList", "MyHandle", szHandle);
+
+ int item = SendDlgItemMessage(hdlg, IDC_GROUP, CB_GETCURSEL, 0, 0);
+ if (item > 0)
+ {
+ item = SendDlgItemMessage(hdlg, IDC_GROUP, CB_GETITEMDATA, item, 0);
+ CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, item);
+ }
+
+ if (!IsDlgButtonChecked(hdlg, IDC_ADDTEMP))
+ {
+ DBDeleteContactSetting(hContact, "CList", "NotOnList");
+
+ if (IsDlgButtonChecked(hdlg, IDC_ADDED))
+ CallContactService(hContact, PSS_ADDED, 0, 0);
+
+ if (IsDlgButtonChecked(hdlg, IDC_AUTH))
+ {
+ DWORD flags = CallProtoService(acs->szProto, PS_GETCAPS, PFLAGNUM_4, 0);
+ if (flags & PF4_NOCUSTOMAUTH)
+ CallContactService(hContact, PSS_AUTHREQUESTT, 0, 0);
+ else
+ {
+ TCHAR szReason[512];
+ GetDlgItemText(hdlg, IDC_AUTHREQ, szReason, SIZEOF(szReason));
+ CallContactService(hContact, PSS_AUTHREQUESTT, 0, (LPARAM)szReason);
+ }
+ }
+ }
+
+ if (GetAsyncKeyState(VK_CONTROL))
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, (LPARAM)(const char*)NULL);
+ }
+ // fall through
+ case IDCANCEL:
+ if (GetParent(hdlg) == NULL)
+ DestroyWindow(hdlg);
+ else
+ EndDialog(hdlg, 0);
+ break;
+ }
+ break;
+
+ case WM_CLOSE:
+ /* if there is no parent for the dialog, its a modeless dialog and can't be killed using EndDialog() */
+ if (GetParent(hdlg) == NULL)
+ DestroyWindow(hdlg);
+ else
+ EndDialog(hdlg, 0);
+ break;
+
+ case DM_ADDCONTACT_CHANGEICONS:
+ CallService(MS_SKIN2_RELEASEICONBIG, (WPARAM)SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)CallService(MS_SKIN2_GETICON, 1, (LPARAM)ICON_ADD)), 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)CallService(MS_SKIN2_GETICON, 0, (LPARAM)ICON_ADD)), 0);
+ break;
+
+ case DM_ADDCONTACT_CHANGEACCLIST:
+ {
+ acs = (ADDCONTACTSTRUCT*)GetWindowLongPtr(hdlg, GWLP_USERDATA);
+ AddContactDlgAccounts(hdlg, acs);
+ break;
+ }
+
+ case WM_DESTROY:
+ CallService(MS_SKIN2_RELEASEICONBIG, (WPARAM)SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)NULL), 0);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM)SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM)NULL), 0);
+ ImageList_Destroy((HIMAGELIST)SendDlgItemMessage(hdlg, IDC_PROTO, CBEM_GETIMAGELIST, 0, 0));
+ acs = (ADDCONTACTSTRUCT*)GetWindowLongPtr(hdlg, GWLP_USERDATA);
+ if (acs)
+ {
+ if (acs->psr)
+ {
+ mir_free(acs->psr->nick);
+ mir_free(acs->psr->firstName);
+ mir_free(acs->psr->lastName);
+ mir_free(acs->psr->email);
+ mir_free(acs->psr);
+ }
+ mir_free(acs);
+ }
+ Utils_SaveWindowPosition(hdlg, NULL, "AddContact", "");
+ break;
+ }
+
+ return FALSE;
+}
diff --git a/plugins/AddContactPlus/addcontactplus.h b/plugins/AddContactPlus/addcontactplus.h
new file mode 100644
index 0000000000..3ff4114560
--- /dev/null
+++ b/plugins/AddContactPlus/addcontactplus.h
@@ -0,0 +1,53 @@
+/*
+
+AddContact+ plugin for Miranda IM
+
+Copyright (C) 2007-2011 Bartosz 'Dezeath' Bia³ek
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+// to enable all 0.9 core functions
+#define MIRANDA_VER 0x0A00
+
+#include <m_stdhdr.h>
+
+#include <windows.h>
+#include <commctrl.h>
+#include <win2k.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_clist.h>
+#include <m_database.h>
+#include <m_genmenu.h>
+#include <m_hotkeys.h>
+#include <m_icolib.h>
+#include <m_langpack.h>
+#include <m_message.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_skin.h>
+#include <m_utils.h>
+#include <m_addcontact.h>
+
+#include "m_toolbar.h"
+#include "m_updater.h"
+#include "m_addcontactplus.h"
+#include "resource.h"
+
+#define ICON_ADD "AddContactPlus_Icon"
+
+INT_PTR CALLBACK AddContactDlgProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam);
+extern HINSTANCE hInst;
diff --git a/plugins/AddContactPlus/addcontactplus_10.sln b/plugins/AddContactPlus/addcontactplus_10.sln
new file mode 100644
index 0000000000..edc024d749
--- /dev/null
+++ b/plugins/AddContactPlus/addcontactplus_10.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "addcontactplus", "addcontactplus_10.vcxproj", "{253ADD1D-F7C9-4643-A957-51BFCD61A5D2}"
+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
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Debug|Win32.Build.0 = Debug|Win32
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Debug|x64.ActiveCfg = Debug|x64
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Debug|x64.Build.0 = Debug|x64
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Release|Win32.ActiveCfg = Release|Win32
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Release|Win32.Build.0 = Release|Win32
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Release|x64.ActiveCfg = Release|x64
+ {253ADD1D-F7C9-4643-A957-51BFCD61A5D2}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/AddContactPlus/addcontactplus_10.vcxproj b/plugins/AddContactPlus/addcontactplus_10.vcxproj
new file mode 100644
index 0000000000..1f0ae8e0b7
--- /dev/null
+++ b/plugins/AddContactPlus/addcontactplus_10.vcxproj
@@ -0,0 +1,316 @@
+<?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>AddContactPlus</ProjectName>
+ <ProjectGuid>{253ADD1D-F7C9-4643-A957-51BFCD61A5D2}</ProjectGuid>
+ <RootNamespace>addcontactplus</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <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|x64'" 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>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </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|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|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)'=='Release|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)'=='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)'=='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)'=='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>
+ <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>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(Configuration)/addcontactplus.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;ADDCONTACTPLUS_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>0x3ae00000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(Configuration)/addcontactplus.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;ADDCONTACTPLUS_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>
+ <BaseAddress>0x3ae00000</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>$(Configuration)/addcontactplus.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;ADDCONTACTPLUS_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>0x3ae00000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(Configuration)/addcontactplus.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;ADDCONTACTPLUS_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>
+ <BaseAddress>0x3ae00000</BaseAddress>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="addcontact.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="addcontactplus.h" />
+ <ClInclude Include="m_addcontactplus.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="contact_add.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/AddContactPlus/addcontactplus_10.vcxproj.filters b/plugins/AddContactPlus/addcontactplus_10.vcxproj.filters
new file mode 100644
index 0000000000..5de02f395a
--- /dev/null
+++ b/plugins/AddContactPlus/addcontactplus_10.vcxproj.filters
@@ -0,0 +1,43 @@
+<?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>{5c074c9e-6c66-4233-bbd3-a50170fccf47}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{e30af2c4-42d4-4342-8eb9-2dbca157c6bb}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{9208a050-ffae-47fa-bc98-4ca4f79d37d7}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="addcontact.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="addcontactplus.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_addcontactplus.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="contact_add.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/AddContactPlus/contact_add.ico b/plugins/AddContactPlus/contact_add.ico
new file mode 100644
index 0000000000..53788e9990
--- /dev/null
+++ b/plugins/AddContactPlus/contact_add.ico
Binary files differ
diff --git a/plugins/AddContactPlus/docs/addcontactplus-license.txt b/plugins/AddContactPlus/docs/addcontactplus-license.txt
new file mode 100644
index 0000000000..89e08fb002
--- /dev/null
+++ b/plugins/AddContactPlus/docs/addcontactplus-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/AddContactPlus/docs/addcontactplus-readme.txt b/plugins/AddContactPlus/docs/addcontactplus-readme.txt
new file mode 100644
index 0000000000..e9b114ecfd
--- /dev/null
+++ b/plugins/AddContactPlus/docs/addcontactplus-readme.txt
@@ -0,0 +1,89 @@
+ -=================================-
+ AddContact+ plugin for Miranda IM
+ -=================================-
+
+
+Description
+-----------
+Provides the ability to quickly add new contacts (without searching for them).
+All Miranda IM 0.9 compatible protocols are supported. Please remember that on
+some protocols you can add a contact only when connected.
+
+Hold down the CTRL key while adding a contact to open the message window immediately.
+
+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 addcontactplus.dll to your Miranda IM plugins directory.
+
+
+Change Log
+----------
+v 0.9.9.0 (09/04/2011):
++ Added a hotkey for opening Add Contact dialog
++ Added ability to add a contact temporarily
++ Added ability to quickly open the message window by holding CTRL when adding a contact
++ Miranda 0.9 compatibility (Unicode auth requests and contact search, core ability to add contacts without searching)
++ Updater plugin support
+* Slightly redesigned Add Contact dialog
+* x64 portability
+! Rewritten contact adding - fixed crashes and some other problems
+! Some general fixes and improvements
+
+v 0.9.8.6 (10/04/2010):
+! Prevent adding contacts with improper (too large) UINs
+! Fixed removing toolbar button when no accounts are available
+! Some other minor fixes
+
+v 0.9.8.5 (05/03/2009):
++ Added Modern Contact List toolbar button
+! Fixed occasional crash when adding a contact
+! Fixed adding a contact when some accounts are disabled
+! Minor code cleaning
+
+v 0.9.8.0 (17/09/2008):
+From now on, Miranda IM 0.8 or later is required
++ Support for Account Manager
+* Some small improvements
+* Separate Unicode and ANSI versions
+
+v 0.9.5.0 (25/12/2007):
++ Added a check on numeric user IDs
++ Included m_addcontactplus.h and translation template
+! Some fixes in Unicode version
+
+v 0.9.0.0 (15/12/2007):
+Initial release
+
+
+========================
+Base Address: 0x3ae00000
+========================
+
+
+Copyright and License
+---------------------
+
+Copyright (C) 2007-2011 Bartosz 'Dezeath' Bia³ek
+mailto: dezred(at)gmail(dot)com
+http://code.google.com/p/dezeath
+
+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/AddContactPlus/docs/addcontactplus-translation.txt b/plugins/AddContactPlus/docs/addcontactplus-translation.txt
new file mode 100644
index 0000000000..ce4925b969
--- /dev/null
+++ b/plugins/AddContactPlus/docs/addcontactplus-translation.txt
@@ -0,0 +1,12 @@
+; This is a template for translation of AddContact+ plugin
+
+;[Add Contact]
+;[&Add Contact...]
+;[Provides the ability to quickly add new contacts]
+;[Open Add Contact Dialog]
+;[Add Contact\nAdd a contact to your contact list]
+;[Contact ID:]
+;[Account:]
+;[Add temporarily]
+;[The contact cannot be added to your contact list. Please make sure the contact ID is entered correctly.]
+;[The contact cannot be added to your contact list. If you are not logged into the selected account, please try to do so. Also, make sure the contact ID is entered correctly.]
diff --git a/plugins/AddContactPlus/main.cpp b/plugins/AddContactPlus/main.cpp
new file mode 100644
index 0000000000..fb772537dc
--- /dev/null
+++ b/plugins/AddContactPlus/main.cpp
@@ -0,0 +1,225 @@
+/*
+
+AddContact+ plugin for Miranda IM
+
+Copyright (C) 2007-2011 Bartosz 'Dezeath' Bia³ek
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include "addcontactplus.h"
+
+HINSTANCE hInst;
+PLUGINLINK* pluginLink;
+int hLangpack;
+static HANDLE hModulesLoaded = 0, hChangedIcons = 0, hAccListChanged = 0,
+ hMainMenuItem = 0, hToolBarItem = 0, hService = 0;
+HANDLE hIconLibItem;
+struct MM_INTERFACE mmi;
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+#if defined(_WIN64)
+ "AddContact+ (x64)",
+#elif defined(_UNICODE)
+ "AddContact+ (Unicode)",
+#else
+ "AddContact+ (ANSI)",
+#endif
+ PLUGIN_MAKE_VERSION(0, 9, 9, 0),
+ "Provides the ability to quickly add new contacts",
+ "Bartosz 'Dezeath' Bia³ek",
+ "dezred"/*antispam*/"@"/*antispam*/"gmail"/*antispam*/"."/*antispam*/"com",
+ "© 2007-2011 Bartosz 'Dezeath' Bia³ek",
+ "http://code.google.com/p/dezeath",
+ UNICODE_AWARE,
+ 0,
+#ifdef _UNICODE
+ // {6471D451-2FE0-4ee2-850E-9F84F3C0D187}
+ { 0x6471d451, 0x2fe0, 0x4ee2, { 0x85, 0xe, 0x9f, 0x84, 0xf3, 0xc0, 0xd1, 0x87 } }
+#else
+ // {64B41F85-A2D1-4cac-AA35-658DF950FE05}
+ { 0x64b41f85, 0xa2d1, 0x4cac, { 0xaa, 0x35, 0x65, 0x8d, 0xf9, 0x50, 0xfe, 0x5 } }
+#endif
+};
+
+static const MUUID interfaces[] = {MIID_ADDCONTACTPLUS, MIID_LAST};
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ 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 AddContact+ plugin cannot be loaded. It requires Miranda IM 0.9 or later."), _T("AddContact+ Plugin"), MB_OK | MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+ return NULL;
+ }
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+INT_PTR AddContactPlusDialog(WPARAM, LPARAM)
+{
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_ADDCONTACT), (HWND)NULL, AddContactDlgProc, 0);
+ return 0;
+}
+
+static int OnIconsChanged(WPARAM, LPARAM)
+{
+ CLISTMENUITEM mi = {0};
+
+ if (!hMainMenuItem)
+ return 0;
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON | CMIF_ICONFROMICOLIB;
+ mi.icolibItem = hIconLibItem;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMainMenuItem, (LPARAM)&mi);
+
+ return 0;
+}
+
+static int OnAccListChanged(WPARAM, LPARAM)
+{
+ PROTOACCOUNT** pAccounts;
+ int iRealAccCount, iAccCount = 0;
+ DWORD dwCaps;
+
+ ProtoEnumAccounts(&iRealAccCount, &pAccounts);
+ for (int i = 0; i < iRealAccCount; i++)
+ {
+ if (!IsAccountEnabled(pAccounts[i])) continue;
+ dwCaps = (DWORD)CallProtoService(pAccounts[i]->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0);
+ if (dwCaps & PF1_BASICSEARCH || dwCaps & PF1_EXTSEARCH || dwCaps & PF1_SEARCHBYEMAIL || dwCaps & PF1_SEARCHBYNAME)
+ iAccCount++;
+ }
+
+ if (iAccCount)
+ {
+ CLISTMENUITEM mi = {0};
+
+ if (hMainMenuItem)
+ return 0;
+
+ mi.cbSize = sizeof(mi);
+ mi.position = 500020001;
+ mi.flags = CMIF_ICONFROMICOLIB;
+ mi.icolibItem = hIconLibItem;
+ mi.pszName = LPGEN("&Add Contact...");
+ mi.pszService = MS_ADDCONTACTPLUS_SHOW;
+ hMainMenuItem = (HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi);
+
+ if (ServiceExists(MS_TB_ADDBUTTON))
+ {
+ TBButton tbb = {0};
+
+ tbb.cbSize = sizeof(TBButton);
+ tbb.tbbFlags = TBBF_VISIBLE | TBBF_SHOWTOOLTIP;
+ tbb.pszButtonID = "acplus_btn";
+ tbb.pszButtonName = Translate("Add Contact");
+ tbb.pszServiceName = MS_ADDCONTACTPLUS_SHOW;
+ tbb.pszTooltipUp = Translate("Add Contact");
+ tbb.hPrimaryIconHandle = hIconLibItem;
+ tbb.defPos = 10100;
+ hToolBarItem = (HANDLE)CallService(MS_TB_ADDBUTTON, 0, (LPARAM)&tbb);
+ }
+ }
+ else
+ {
+ if (!hMainMenuItem)
+ return 0;
+
+ CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)hMainMenuItem, 0);
+ CallService(MS_TB_REMOVEBUTTON, (WPARAM)hToolBarItem, 0);
+
+ hMainMenuItem = 0;
+ }
+
+ return 0;
+}
+
+static int OnModulesLoaded(WPARAM, LPARAM)
+{
+ if (ServiceExists(MS_UPDATE_REGISTERFL))
+#if defined(_WIN64)
+ CallService(MS_UPDATE_REGISTERFL, 4414, (LPARAM)&pluginInfo);
+#elif defined(_UNICODE)
+ CallService(MS_UPDATE_REGISTERFL, 3842, (LPARAM)&pluginInfo);
+#else
+ CallService(MS_UPDATE_REGISTERFL, 3843, (LPARAM)&pluginInfo);
+#endif
+
+ SKINICONDESC sid = {0};
+ char szFile[MAX_PATH];
+ GetModuleFileNameA(hInst, szFile, MAX_PATH);
+ sid.cbSize = sizeof(SKINICONDESC);
+ sid.flags = SIDF_TCHAR;
+ sid.pszDefaultFile = szFile;
+ sid.ptszSection = _T("AddContact+");
+ sid.iDefaultIndex = -IDI_ADDCONTACT;
+ sid.ptszDescription = LPGENT("Add Contact");
+ sid.pszName = ICON_ADD;
+ hIconLibItem = (HANDLE)CallService(MS_SKIN2_ADDICON, (WPARAM)0, (LPARAM)&sid);
+ hChangedIcons = HookEvent(ME_SKIN2_ICONSCHANGED, OnIconsChanged);
+
+ HOTKEYDESC hkd = {0};
+ hkd.cbSize = sizeof(hkd);
+ hkd.dwFlags = HKD_TCHAR;
+ hkd.pszName = "AddContactPlus_OpenDialog";
+ hkd.ptszDescription = LPGENT("Open Add Contact Dialog");
+ hkd.ptszSection = LPGENT("Main");
+ hkd.pszService = MS_ADDCONTACTPLUS_SHOW;
+ hkd.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL | HOTKEYF_SHIFT, 'C') | HKF_MIRANDA_LOCAL;
+ CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hkd);
+
+ OnAccListChanged(0, 0);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK* link)
+{
+ pluginLink = link;
+ mir_getMMI(&mmi);
+ mir_getLP(&pluginInfo);
+
+ INITCOMMONCONTROLSEX icex = {0};
+ icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+ icex.dwICC = ICC_USEREX_CLASSES;
+ InitCommonControlsEx(&icex);
+
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+ hAccListChanged = HookEvent(ME_PROTO_ACCLISTCHANGED, OnAccListChanged);
+ hService = CreateServiceFunction(MS_ADDCONTACTPLUS_SHOW, AddContactPlusDialog);
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ UnhookEvent(hModulesLoaded);
+ UnhookEvent(hChangedIcons);
+ UnhookEvent(hAccListChanged);
+ DestroyServiceFunction(hService);
+
+ return 0;
+}
diff --git a/plugins/AddContactPlus/resource.h b/plugins/AddContactPlus/resource.h
new file mode 100644
index 0000000000..b796c401d0
--- /dev/null
+++ b/plugins/AddContactPlus/resource.h
@@ -0,0 +1,28 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_ADDCONTACT 101
+#define IDI_ADDCONTACT 102
+#define IDC_MYHANDLE 1000
+#define IDC_GROUP 1001
+#define IDC_ADDED 1002
+#define IDC_AUTH 1003
+#define IDC_AUTHGB 1004
+#define IDC_AUTHREQ 1005
+#define IDC_USERID 1006
+#define IDC_PROTO 1007
+#define IDC_IDLABEL 1008
+#define IDC_HEADERBAR 1009
+#define IDC_ADDTEMP 1010
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1011
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/AddContactPlus/resource.rc b/plugins/AddContactPlus/resource.rc
new file mode 100644
index 0000000000..3447bb0551
--- /dev/null
+++ b/plugins/AddContactPlus/resource.rc
@@ -0,0 +1,176 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 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 DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,9,9,0
+ PRODUCTVERSION 0,9,9,0
+ 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\0"
+ VALUE "FileDescription", "AddContact+ plugin for Miranda IM\0"
+ VALUE "FileVersion", "0.9.9.0\0"
+ VALUE "InternalName", "addcontactplus\0"
+ VALUE "LegalCopyright", "© 2007-2011 Bartosz 'Dezeath' Bia³ek\0"
+ VALUE "OriginalFilename", "addcontactplus.dll\0"
+ VALUE "ProductName", "AddContact+\0"
+ VALUE "ProductVersion", "0.9.9.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ADDCONTACT ICON DISCARDABLE "contact_add.ico"
+#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_ADDCONTACT DIALOGEX 0, 0, 230, 219
+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 "Add Contact"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Add Contact\nAdd a contact to your contact list",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,230,25
+ LTEXT "Account:",IDC_STATIC,6,29,89,10
+ CONTROL "",IDC_PROTO,"ComboBoxEx32",CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP,6,41,90,80
+ LTEXT "Contact ID:",IDC_IDLABEL,112,29,108,10
+ EDITTEXT IDC_USERID,112,41,110,12,ES_AUTOHSCROLL
+ LTEXT "Custom name:",IDC_STATIC,6,58,89,10
+ EDITTEXT IDC_MYHANDLE,6,70,90,12,ES_AUTOHSCROLL
+ LTEXT "Group:",IDC_STATIC,112,58,108,10
+ COMBOBOX IDC_GROUP,112,70,110,60,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Options",IDC_STATIC,7,87,216,57
+ CONTROL "Add temporarily",IDC_ADDTEMP,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,11,100,204,10
+ CONTROL "Send ""You were added""",IDC_ADDED,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,11,114,204,10
+ CONTROL "Send authorization request",IDC_AUTH,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,11,128,204,10
+ GROUPBOX "Authorization Request",IDC_AUTHGB,7,147,216,45
+ EDITTEXT IDC_AUTHREQ,13,157,204,29,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ DEFPUSHBUTTON "&Add",IDOK,20,198,72,14
+ PUSHBUTTON "&Cancel",IDCANCEL,139,198,71,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_ADDCONTACT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 223
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 144
+ 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/ExternalAPI/m_addcontactplus.h b/plugins/ExternalAPI/m_addcontactplus.h
new file mode 100644
index 0000000000..5aa02bba2e
--- /dev/null
+++ b/plugins/ExternalAPI/m_addcontactplus.h
@@ -0,0 +1,33 @@
+/*
+
+AddContact+ plugin for Miranda IM
+
+Copyright (C) 2007-2011 Bartosz 'Dezeath' Bia³ek
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef M_ADDCONTACTPLUS_H__
+#define M_ADDCONTACTPLUS_H__ 1
+
+#ifndef MIID_ADDCONTACTPLUS
+#define MIID_ADDCONTACTPLUS {0xf60714d1, 0xa44d, 0x4655, {0xb0, 0x85, 0x53, 0x1c, 0xfd, 0xf8, 0x4e, 0x67}}
+#endif
+
+// Brings up the add contact dialog
+// wParam = lParam = 0
+#define MS_ADDCONTACTPLUS_SHOW "AddContactPlus/Show"
+
+#endif // M_ADDCONTACTPLUS_H__
diff --git a/plugins/ExternalAPI/m_simplestatusmsg.h b/plugins/ExternalAPI/m_simplestatusmsg.h
new file mode 100644
index 0000000000..bf31dab2d1
--- /dev/null
+++ b/plugins/ExternalAPI/m_simplestatusmsg.h
@@ -0,0 +1,50 @@
+/*
+
+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 M_SIMPLESTATUSMSG_H__
+#define M_SIMPLESTATUSMSG_H__
+
+// Change global status mode/message
+// wParam = (int)new status, 0 if for current
+// lParam = (LPARAM)(TCHAR *)status message
+#define MS_SIMPLESTATUSMSG_SETSTATUS "SimpleStatusMsg/SetStatus"
+
+// Bring up the status message dialog
+// wParam = 0
+// lParam = (LPARAM)(char *)protocol name, NULL if for all protocols
+#define MS_SIMPLESTATUSMSG_SHOWDIALOG "SimpleStatusMsg/ShowDialog"
+
+// Force a change of status mode/message. The status message dialog will
+// appear depending on settings
+// 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_SIMPLESTATUSMSG_CHANGESTATUSMSG "SimpleStatusMsg/ChangeStatusMessage"
+
+// Copy the status message of a contact to clipboard
+// wParam = (WPARAM)(HANDLE)hContact
+// lParam = 0
+#define MS_SIMPLESTATUSMSG_COPYMSG "SimpleStatusMsg/CopyMsg"
+
+// Go to URL in status message of a contact
+// wParam = (WPARAM)(HANDLE)hContact
+// lParam = 0
+#define MS_SIMPLESTATUSMSG_GOTOURLMSG "SimpleStatusMsg/GoToURLMsg"
+
+#endif // M_SIMPLESTATUSMSG_H__
diff --git a/plugins/NewAwaySysMod/NewAwaySys.sln b/plugins/NewAwaySysMod/NewAwaySys.sln
index 98fcf97f57..c54a180cbf 100644
--- a/plugins/NewAwaySysMod/NewAwaySys.sln
+++ b/plugins/NewAwaySysMod/NewAwaySys.sln
@@ -1,6 +1,7 @@
+
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NewAwaySys", "NewAwaySys.vcxproj", "{076543A3-41D6-6CD5-E1AE-14CAF9819D48}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NewAwaySys", "NewAwaySys.vcxproj", "{6A516E27-AC50-5374-756B-A1558DB2EFA9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -8,13 +9,12 @@ Global
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {076543A3-41D6-6CD5-E1AE-14CAF9819D48}.Debug|Win32.ActiveCfg = Release|Win32
- {076543A3-41D6-6CD5-E1AE-14CAF9819D48}.Release|Win32.ActiveCfg = Release|Win32
+ {6A516E27-AC50-5374-756B-A1558DB2EFA9}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6A516E27-AC50-5374-756B-A1558DB2EFA9}.Debug|Win32.Build.0 = Debug|Win32
+ {6A516E27-AC50-5374-756B-A1558DB2EFA9}.Release|Win32.ActiveCfg = Release|Win32
+ {6A516E27-AC50-5374-756B-A1558DB2EFA9}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(DPCodeReviewSolutionGUID) = preSolution
- DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
- EndGlobalSection
EndGlobal
diff --git a/plugins/SecureIM/secureim_icons_10.vcxproj b/plugins/SecureIM/secureim_icons_10.vcxproj
index 947230eb4d..adef503cc6 100644
--- a/plugins/SecureIM/secureim_icons_10.vcxproj
+++ b/plugins/SecureIM/secureim_icons_10.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectName>secureim_icons</ProjectName>
+ <ProjectName>SecureIM_icons</ProjectName>
<ProjectGuid>{3FAB6AC7-6B7F-4779-B519-34E8035074A4}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
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);
+}
diff --git a/plugins/UserInfoEx/IconPacks/default/icons_default_10.vcxproj b/plugins/UserInfoEx/IconPacks/default/icons_default_10.vcxproj
index aa61e2678c..dba97d8c60 100644
--- a/plugins/UserInfoEx/IconPacks/default/icons_default_10.vcxproj
+++ b/plugins/UserInfoEx/IconPacks/default/icons_default_10.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectName>uinfoex_icons_default_Z1</ProjectName>
+ <ProjectName>UinfoEx_icons_default_Z1</ProjectName>
<ProjectGuid>{AA542F66-FF66-498A-ADBE-0BB9103ECD0A}</ProjectGuid>
<RootNamespace>UinfoEx_Icons</RootNamespace>
<Keyword>Win32Proj</Keyword>
diff --git a/plugins/UserInfoEx/IconPacks/default/icons_default_10_z2.vcxproj b/plugins/UserInfoEx/IconPacks/default/icons_default_10_z2.vcxproj
index 093bcdd04b..b6d2b8e67f 100644
--- a/plugins/UserInfoEx/IconPacks/default/icons_default_10_z2.vcxproj
+++ b/plugins/UserInfoEx/IconPacks/default/icons_default_10_z2.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectName>uinfoex_icons_default_Z2</ProjectName>
+ <ProjectName>UinfoEx_icons_default_Z2</ProjectName>
<ProjectGuid>{D90DD62F-6A75-4469-ABB5-A3E88BCA6A3C}</ProjectGuid>
<RootNamespace>UinfoEx_Icons</RootNamespace>
<Keyword>Win32Proj</Keyword>
diff --git a/plugins/UserInfoEx/IconPacks/ice/icons_ice_10.vcxproj b/plugins/UserInfoEx/IconPacks/ice/icons_ice_10.vcxproj
index 854729e5d0..b5751e282e 100644
--- a/plugins/UserInfoEx/IconPacks/ice/icons_ice_10.vcxproj
+++ b/plugins/UserInfoEx/IconPacks/ice/icons_ice_10.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectName>uinfoex_icons_ice_Z1</ProjectName>
+ <ProjectName>UinfoEx_icons_ice_Z1</ProjectName>
<ProjectGuid>{E04B8ECA-A066-41BA-AE8C-DB172424DD82}</ProjectGuid>
<RootNamespace>UinfoEx_Icons</RootNamespace>
<Keyword>Win32Proj</Keyword>
diff --git a/plugins/UserInfoEx/IconPacks/ice/icons_ice_10_z2.vcxproj b/plugins/UserInfoEx/IconPacks/ice/icons_ice_10_z2.vcxproj
index c468d79e28..a2459a9b96 100644
--- a/plugins/UserInfoEx/IconPacks/ice/icons_ice_10_z2.vcxproj
+++ b/plugins/UserInfoEx/IconPacks/ice/icons_ice_10_z2.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectName>uinfoex_icons_ice_Z2</ProjectName>
+ <ProjectName>uinfoEx_icons_ice_Z2</ProjectName>
<ProjectGuid>{E787B42A-6489-4078-90CD-B78B751A1284}</ProjectGuid>
<RootNamespace>UinfoEx_Icons</RootNamespace>
<Keyword>Win32Proj</Keyword>