summaryrefslogtreecommitdiff
path: root/protocols/MSN/src/msn_lists.cpp
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2014-11-02 12:12:42 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2014-11-02 12:12:42 +0000
commit24c0dd3e35ae97183a994cc6f25fc78d08da1311 (patch)
treee51c33212cba11597b2909d8284d979d7fb96507 /protocols/MSN/src/msn_lists.cpp
parent05de21be73940c2f058633e5e7866e6c5f3b3e2e (diff)
reverted MSN removal (too early)
git-svn-id: http://svn.miranda-ng.org/main/trunk@10901 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/MSN/src/msn_lists.cpp')
-rw-r--r--protocols/MSN/src/msn_lists.cpp623
1 files changed, 623 insertions, 0 deletions
diff --git a/protocols/MSN/src/msn_lists.cpp b/protocols/MSN/src/msn_lists.cpp
new file mode 100644
index 0000000000..57a227a22f
--- /dev/null
+++ b/protocols/MSN/src/msn_lists.cpp
@@ -0,0 +1,623 @@
+/*
+Plugin of Miranda IM for communicating with users of the MSN Messenger protocol.
+
+Copyright (c) 2012-2014 Miranda NG Team
+Copyright (c) 2006-2012 Boris Krasnovskiy.
+Copyright (c) 2003-2005 George Hazan.
+Copyright (c) 2002-2003 Richard Hughes (original version).
+
+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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "msn_global.h"
+#include "msn_proto.h"
+#include "m_smileyadd.h"
+
+void CMsnProto::Lists_Uninit(void)
+{
+ Lists_Wipe();
+}
+
+void CMsnProto::Lists_Wipe(void)
+{
+ mir_cslock lck(csLists);
+ contList.destroy();
+}
+
+bool CMsnProto::Lists_IsInList(int list, const char* email)
+{
+ mir_cslock lck(csLists);
+
+ MsnContact* p = contList.find((MsnContact*)&email);
+ bool res = p != NULL;
+ if (res && list != -1)
+ res &= ((p->list & list) == list);
+ return res;
+}
+
+MsnContact* CMsnProto::Lists_Get(const char* email)
+{
+ mir_cslock lck(csLists);
+ return contList.find((MsnContact*)&email);
+}
+
+MsnContact* CMsnProto::Lists_Get(MCONTACT hContact)
+{
+ mir_cslock lck(csLists);
+
+ for (int i = 0; i < contList.getCount(); ++i)
+ if (contList[i].hContact == hContact)
+ return &contList[i];
+
+ return NULL;
+}
+
+MsnPlace* CMsnProto::Lists_GetPlace(const char* wlid)
+{
+ mir_cslock lck(csLists);
+
+ char *szEmail, *szInst;
+ parseWLID(NEWSTR_ALLOCA(wlid), NULL, &szEmail, &szInst);
+
+ if (szInst == NULL)
+ szInst = (char*)sttVoidUid;
+
+ MsnPlace* pl = NULL;
+ MsnContact* p = contList.find((MsnContact*)&szEmail);
+ if (p)
+ pl = p->places.find((MsnPlace*)&szInst);
+
+ return pl;
+}
+
+MsnPlace* CMsnProto::Lists_AddPlace(const char* email, const char* id, unsigned cap1, unsigned cap2)
+{
+ mir_cslock lck(csLists);
+
+ MsnPlace* pl = NULL;
+ MsnContact* p = contList.find((MsnContact*)&email);
+ if (p) {
+ pl = p->places.find((MsnPlace*)&id);
+ if (!pl) {
+ pl = new MsnPlace;
+
+ pl->id = mir_strdup(id);
+ pl->cap1 = cap1;
+ pl->cap2 = cap2;
+ pl->p2pMsgId = 0;
+ pl->p2pPktNum = 0;
+ p->places.insert(pl);
+ }
+ }
+
+ return pl;
+}
+
+MsnContact* CMsnProto::Lists_GetNext(int& i)
+{
+ MsnContact* p = NULL;
+
+ mir_cslock lck(csLists);
+
+ while (p == NULL && ++i < contList.getCount())
+ if (contList[i].hContact)
+ p = &contList[i];
+
+ return p;
+}
+
+int CMsnProto::Lists_GetMask(const char* email)
+{
+ mir_cslock lck(csLists);
+
+ MsnContact* p = contList.find((MsnContact*)&email);
+ return p ? p->list : 0;
+}
+
+int CMsnProto::Lists_GetNetId(const char* email)
+{
+ if (email[0] == 0) return NETID_UNKNOWN;
+
+ mir_cslock lck(csLists);
+
+ MsnContact* p = contList.find((MsnContact*)&email);
+ return p ? p->netId : NETID_UNKNOWN;
+}
+
+unsigned CMsnProto::p2p_getMsgId(const char* wlid, int inc)
+{
+ mir_cslock lck(csLists);
+ MsnPlace* p = Lists_GetPlace(wlid);
+
+ unsigned res = p && p->p2pMsgId ? p->p2pMsgId : MSN_GenRandom();
+ if (p)
+ p->p2pMsgId = res + inc;
+
+ return res;
+}
+
+unsigned CMsnProto::p2p_getPktNum(const char* wlid)
+{
+ mir_cslock lck(csLists);
+
+ MsnPlace* p = Lists_GetPlace(wlid);
+ return p ? p->p2pPktNum++ : 0;
+}
+
+int CMsnProto::Lists_Add(int list, int netId, const char* email, MCONTACT hContact, const char* nick, const char* invite)
+{
+ mir_cslock lck(csLists);
+
+ MsnContact* p = contList.find((MsnContact*)&email);
+ if (p == NULL) {
+ p = new MsnContact;
+ p->list = list;
+ p->netId = netId;
+ p->email = _strlwr(mir_strdup(email));
+ p->invite = mir_strdup(invite);
+ p->nick = mir_strdup(nick);
+ p->hContact = hContact;
+ p->p2pMsgId = 0;
+ contList.insert(p);
+ }
+ else {
+ p->list |= list;
+ if (invite) replaceStr(p->invite, invite);
+ if (hContact) p->hContact = hContact;
+ if (list & LIST_FL) p->netId = netId;
+ if (p->netId == NETID_UNKNOWN && netId != NETID_UNKNOWN)
+ p->netId = netId;
+ }
+ return p->list;
+}
+
+void CMsnProto::Lists_Remove(int list, const char* email)
+{
+ mir_cslock lck(csLists);
+
+ int i = contList.getIndex((MsnContact*)&email);
+ if (i != -1) {
+ MsnContact &p = contList[i];
+ p.list &= ~list;
+ if (list & LIST_PL) { mir_free(p.invite); p.invite = NULL; }
+ if (p.list == 0 && p.hContact == NULL)
+ contList.remove(i);
+ }
+}
+
+
+void CMsnProto::Lists_Populate(void)
+{
+ MCONTACT hContact = db_find_first(m_szModuleName);
+ while (hContact) {
+ MCONTACT hNext = db_find_next(hContact, m_szModuleName);
+ char szEmail[MSN_MAX_EMAIL_LEN] = "";
+ if (db_get_static(hContact, m_szModuleName, "wlid", szEmail, sizeof(szEmail)))
+ db_get_static(hContact, m_szModuleName, "e-mail", szEmail, sizeof(szEmail));
+ if (szEmail[0]) {
+ bool localList = getByte(hContact, "LocalList", 0) != 0;
+ if (localList)
+ Lists_Add(LIST_LL, NETID_MSN, szEmail, hContact);
+ else
+ Lists_Add(0, NETID_UNKNOWN, szEmail, hContact);
+ }
+ else CallService(MS_DB_CONTACT_DELETE, hContact, 0);
+ hContact = hNext;
+ }
+}
+
+void CMsnProto::MSN_CleanupLists(void)
+{
+ for (int i = contList.getCount(); i--;) {
+ MsnContact& p = contList[i];
+ if (p.list & LIST_FL)
+ MSN_SetContactDb(p.hContact, p.email);
+
+ if (p.list & LIST_PL) {
+ if (p.list & (LIST_AL | LIST_BL))
+ MSN_AddUser(NULL, p.email, p.netId, LIST_PL + LIST_REMOVE);
+ else
+ MSN_AddAuthRequest(p.email, p.nick, p.invite);
+ }
+
+ if (p.hContact && !(p.list & (LIST_LL | LIST_FL | LIST_PL)) && p.list != LIST_RL) {
+ int count = db_event_count(p.hContact);
+ if (count) {
+ TCHAR text[256];
+ TCHAR *sze = mir_a2t(p.email);
+ mir_sntprintf(text, SIZEOF(text), TranslateT("Contact %s has been removed from the server.\nWould you like to keep it as \"Local Only\" contact to preserve history?"), sze);
+ mir_free(sze);
+
+ TCHAR title[128];
+ mir_sntprintf(title, SIZEOF(title), TranslateT("%s protocol"), m_tszUserName);
+
+ if (MessageBox(NULL, text, title, MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND) == IDYES) {
+ MSN_AddUser(p.hContact, p.email, 0, LIST_LL);
+ setByte(p.hContact, "LocalList", 1);
+ continue;
+ }
+ }
+
+ if (!(p.list & (LIST_LL | LIST_FL))) {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)p.hContact, 0);
+ p.hContact = NULL;
+ }
+ }
+
+ if (p.list & (LIST_LL | LIST_FL) && p.hContact) {
+ TCHAR path[MAX_PATH];
+ MSN_GetCustomSmileyFileName(p.hContact, path, SIZEOF(path), "", 0);
+ if (path[0]) {
+ SMADD_CONT cont;
+ cont.cbSize = sizeof(SMADD_CONT);
+ cont.hContact = p.hContact;
+ cont.type = 0;
+ cont.path = path;
+
+ CallService(MS_SMILEYADD_LOADCONTACTSMILEYS, 0, (LPARAM)&cont);
+ }
+ }
+ }
+}
+
+void CMsnProto::MSN_CreateContList(void)
+{
+ bool *used = (bool*)mir_calloc(contList.getCount()*sizeof(bool));
+
+ char cxml[8192];
+
+ size_t sz = mir_snprintf(cxml, sizeof(cxml), "<ml l=\"1\">");
+ {
+ mir_cslock lck(csLists);
+
+ for (int i = 0; i < contList.getCount(); i++) {
+ if (used[i]) continue;
+
+ const char* lastds = strchr(contList[i].email, '@');
+ bool newdom = true;
+
+ for (int j = 0; j < contList.getCount(); j++) {
+ if (used[j]) continue;
+
+ const MsnContact& C = contList[j];
+ if (C.list == LIST_RL || C.list == LIST_PL || C.list == LIST_LL) {
+ used[j] = true;
+ continue;
+ }
+
+ const char *dom = strchr(C.email, '@');
+ if (dom == NULL && lastds == NULL) {
+ if (sz == 0) sz = mir_snprintf(cxml + sz, sizeof(cxml), "<ml l=\"1\">");
+ if (newdom) {
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, "<t>");
+ newdom = false;
+ }
+
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, "<c n=\"%s\" l=\"%d\"/>", C.email, C.list & ~(LIST_RL | LIST_LL));
+ used[j] = true;
+ }
+ else if (dom != NULL && lastds != NULL && _stricmp(lastds, dom) == 0) {
+ if (sz == 0) sz = mir_snprintf(cxml, sizeof(cxml), "<ml l=\"1\">");
+ if (newdom) {
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, "<d n=\"%s\">", lastds + 1);
+ newdom = false;
+ }
+
+ *(char*)dom = 0;
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, "<c n=\"%s\" l=\"%d\" t=\"%d\"/>", C.email, C.list & ~(LIST_RL | LIST_LL), C.netId);
+ *(char*)dom = '@';
+ used[j] = true;
+ }
+
+ if (used[j] && sz > 7400) {
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, "</%c></ml>", lastds ? 'd' : 't');
+ msnNsThread->sendPacket("ADL", "%d\r\n%s", sz, cxml);
+ sz = 0;
+ newdom = true;
+ }
+ }
+ if (!newdom)
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, lastds ? "</d>" : "</t>");
+ }
+ }
+
+ if (sz) {
+ sz += mir_snprintf(cxml + sz, sizeof(cxml) - sz, "</ml>");
+ msnNsThread->sendPacket("ADL", "%d\r\n%s", sz, cxml);
+ }
+
+ mir_free(used);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// MSN Server List Manager dialog procedure
+
+static void AddPrivacyListEntries(HWND hwndList, CMsnProto *proto)
+{
+ CLCINFOITEM cii = { 0 };
+ cii.cbSize = sizeof(cii);
+ cii.flags = CLCIIF_BELOWCONTACTS;
+
+ // Delete old info
+ HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0);
+ while (hItem) {
+ HANDLE hItemNext = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hItem);
+
+ if (IsHContactInfo(hItem))
+ SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+
+ hItem = hItemNext;
+ }
+
+ // Add new info
+ for (int i = 0; i < proto->contList.getCount(); ++i) {
+ MsnContact &cont = proto->contList[i];
+ if (!(cont.list & (LIST_FL | LIST_LL))) {
+ cii.pszText = (TCHAR*)cont.email;
+ HANDLE hItem = (HANDLE)SendMessage(hwndList, CLM_ADDINFOITEMA, 0, (LPARAM)&cii);
+
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(0, (cont.list & LIST_LL) ? 1 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(1, (cont.list & LIST_FL) ? 2 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(2, (cont.list & LIST_AL) ? 3 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(3, (cont.list & LIST_BL) ? 4 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(4, (cont.list & LIST_RL) ? 5 : 0));
+ }
+ }
+}
+
+static void SetContactIcons(MCONTACT hItem, HWND hwndList, CMsnProto* proto)
+{
+ if (!proto->MSN_IsMyContact(hItem)) {
+ SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+ return;
+ }
+
+ char szEmail[MSN_MAX_EMAIL_LEN];
+ if (db_get_static(hItem, proto->m_szModuleName, "e-mail", szEmail, sizeof(szEmail))) {
+ SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+ return;
+ }
+
+ DWORD dwMask = proto->Lists_GetMask(szEmail);
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(0, (dwMask & LIST_LL) ? 1 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(1, (dwMask & LIST_FL) ? 2 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(2, (dwMask & LIST_AL) ? 3 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(3, (dwMask & LIST_BL) ? 4 : 0));
+ SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(4, (dwMask & LIST_RL) ? 5 : 0));
+}
+
+static void SetAllContactIcons(MCONTACT hItem, HWND hwndList, CMsnProto* proto)
+{
+ if (hItem == NULL)
+ hItem = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0);
+
+ while (hItem) {
+ MCONTACT hItemN = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hItem);
+
+ if (IsHContactGroup(hItem)) {
+ MCONTACT hItemT = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem);
+ if (hItemT)
+ SetAllContactIcons(hItemT, hwndList, proto);
+ }
+ else if (IsHContactContact(hItem))
+ SetContactIcons(hItem, hwndList, proto);
+
+ hItem = hItemN;
+ }
+}
+
+static void SaveListItem(MCONTACT hContact, const char* szEmail, int list, int iPrevValue, int iNewValue, CMsnProto* proto)
+{
+ if (iPrevValue == iNewValue)
+ return;
+
+ if (iNewValue == 0) {
+ if (list & LIST_FL) {
+ DeleteParam param = { proto, hContact };
+ DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DELETECONTACT), NULL, DlgDeleteContactUI, (LPARAM)&param);
+ return;
+ }
+
+ list |= LIST_REMOVE;
+ }
+
+ proto->MSN_AddUser(hContact, szEmail, proto->Lists_GetNetId(szEmail), list);
+}
+
+static void SaveSettings(MCONTACT hItem, HWND hwndList, CMsnProto* proto)
+{
+ if (hItem == NULL)
+ hItem = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0);
+
+ while (hItem) {
+ if (IsHContactGroup(hItem)) {
+ MCONTACT hItemT = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem);
+ if (hItemT)
+ SaveSettings(hItemT, hwndList, proto);
+ }
+ else {
+ char szEmail[MSN_MAX_EMAIL_LEN];
+
+ if (IsHContactContact(hItem)) {
+ if (db_get_static(hItem, proto->m_szModuleName, "e-mail", szEmail, sizeof(szEmail)))
+ continue;
+ }
+ else if (IsHContactInfo(hItem)) {
+ TCHAR buf[MSN_MAX_EMAIL_LEN];
+ SendMessage(hwndList, CLM_GETITEMTEXT, (WPARAM)hItem, (LPARAM)buf);
+ WideCharToMultiByte(CP_ACP, 0, buf, -1, szEmail, sizeof(szEmail), 0, 0);
+
+ }
+
+ int dwMask = proto->Lists_GetMask(szEmail);
+ SaveListItem(hItem, szEmail, LIST_LL, (dwMask & LIST_LL) ? 1 : 0, SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(0, 0)), proto);
+ SaveListItem(hItem, szEmail, LIST_FL, (dwMask & LIST_FL) ? 2 : 0, SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(1, 0)), proto);
+ SaveListItem(hItem, szEmail, LIST_AL, (dwMask & LIST_AL) ? 3 : 0, SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(2, 0)), proto);
+ SaveListItem(hItem, szEmail, LIST_BL, (dwMask & LIST_BL) ? 4 : 0, SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(3, 0)), proto);
+
+ int newMask = proto->Lists_GetMask(szEmail);
+ int xorMask = newMask ^ dwMask;
+
+ if (xorMask && newMask & (LIST_FL | LIST_LL)) {
+ MCONTACT hContact = IsHContactInfo(hItem) ? proto->MSN_HContactFromEmail(szEmail, szEmail, true, false) : hItem;
+ proto->MSN_SetContactDb(hContact, szEmail);
+ }
+
+ if (xorMask & (LIST_FL | LIST_LL) && !(newMask & (LIST_FL | LIST_LL))) {
+ if (!IsHContactInfo(hItem)) {
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)hItem, 0);
+ MsnContact* msc = proto->Lists_Get(szEmail);
+ if (msc) msc->hContact = NULL;
+ }
+ }
+ }
+ hItem = (MCONTACT)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXT, (LPARAM)hItem);
+ }
+}
+
+INT_PTR CALLBACK DlgProcMsnServLists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ CMsnProto *proto = (CMsnProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ {
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
+
+ HIMAGELIST hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 5, 5);
+
+ HICON hIcon = LoadSkinnedIcon(SKINICON_OTHER_SMALLDOT);
+ ImageList_AddIcon(hIml, hIcon);
+ Skin_ReleaseIcon(hIcon);
+
+ hIcon = LoadIconEx("list_lc");
+ ImageList_AddIcon(hIml, hIcon);
+ SendDlgItemMessage(hwndDlg, IDC_ICON_LC, STM_SETICON, (WPARAM)hIcon, 0);
+
+ hIcon = LoadIconEx("list_fl");
+ ImageList_AddIcon(hIml, hIcon);
+ SendDlgItemMessage(hwndDlg, IDC_ICON_FL, STM_SETICON, (WPARAM)hIcon, 0);
+
+ hIcon = LoadIconEx("list_al");
+ ImageList_AddIcon(hIml, hIcon);
+ SendDlgItemMessage(hwndDlg, IDC_ICON_AL, STM_SETICON, (WPARAM)hIcon, 0);
+
+ hIcon = LoadIconEx("list_bl");
+ ImageList_AddIcon(hIml, hIcon);
+ SendDlgItemMessage(hwndDlg, IDC_ICON_BL, STM_SETICON, (WPARAM)hIcon, 0);
+
+ hIcon = LoadIconEx("list_rl");
+ ImageList_AddIcon(hIml, hIcon);
+ SendDlgItemMessage(hwndDlg, IDC_ICON_RL, STM_SETICON, (WPARAM)hIcon, 0);
+
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST);
+
+ SendMessage(hwndList, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml);
+ SendMessage(hwndList, CLM_SETEXTRACOLUMNS, 5, 0);
+
+ EnableWindow(hwndList, ((CMsnProto*)lParam)->msnLoggedIn);
+ }
+ return TRUE;
+
+// case WM_SETFOCUS:
+// SetFocus(GetDlgItem(hwndDlg ,IDC_LIST));
+// break;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDC_LISTREFRESH)
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST);
+ SendMessage(hwndList, CLM_AUTOREBUILD, 0, 0);
+
+ CMsnProto* proto = (CMsnProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ EnableWindow(hwndList, proto->msnLoggedIn);
+ }
+ break;
+
+ case WM_NOTIFY:
+ {
+ CMsnProto* proto = (CMsnProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ NMCLISTCONTROL* nmc = (NMCLISTCONTROL*)lParam;
+ if (nmc->hdr.idFrom == 0 && nmc->hdr.code == (unsigned)PSN_APPLY)
+ {
+ HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST);
+ SaveSettings(NULL, hwndList, proto);
+ SendMessage(hwndList, CLM_AUTOREBUILD, 0, 0);
+ EnableWindow(hwndList, proto->msnLoggedIn);
+ }
+ else if (nmc->hdr.idFrom == IDC_LIST)
+ {
+ switch (nmc->hdr.code)
+ {
+ case CLN_NEWCONTACT:
+ if ((nmc->flags & (CLNF_ISGROUP | CLNF_ISINFO)) == 0)
+ SetContactIcons((MCONTACT)nmc->hItem, nmc->hdr.hwndFrom, proto);
+ break;
+
+ case CLN_LISTREBUILT:
+ AddPrivacyListEntries(nmc->hdr.hwndFrom, proto);
+ SetAllContactIcons(NULL, nmc->hdr.hwndFrom, proto);
+ break;
+
+ case NM_CLICK:
+ HANDLE hItem;
+ DWORD hitFlags;
+ int iImage;
+
+ // Make sure we have an extra column, also we can't change RL list
+ if (nmc->iColumn == -1 || nmc->iColumn == 4)
+ break;
+
+ // Find clicked item
+ hItem = (HANDLE)SendMessage(nmc->hdr.hwndFrom, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nmc->pt.x,nmc->pt.y));
+
+ // Nothing was clicked
+ if (hItem == NULL || !(IsHContactContact(hItem) || IsHContactInfo(hItem)))
+ break;
+
+ // It was not our extended icon
+ if (!(hitFlags & CLCHT_ONITEMEXTRA))
+ break;
+
+ // Get image in clicked column (0=none, 1=LL, 2=FL, 3=AL, 4=BL, 5=RL)
+ iImage = SendMessage(nmc->hdr.hwndFrom, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nmc->iColumn, 0));
+ iImage = iImage ? 0 : nmc->iColumn + 1;
+
+ SendMessage(nmc->hdr.hwndFrom, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nmc->iColumn, iImage));
+ if (iImage && SendMessage(nmc->hdr.hwndFrom, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nmc->iColumn ^ 1, 0)) != EMPTY_EXTRA_ICON)
+ if (nmc->iColumn == 2 || nmc->iColumn == 3)
+ SendMessage(nmc->hdr.hwndFrom, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nmc->iColumn ^ 1, 0));
+
+ // Activate Apply button
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+ }
+ }
+ break;
+
+ case WM_DESTROY:
+ HIMAGELIST hIml=(HIMAGELIST)SendDlgItemMessage(hwndDlg,IDC_LIST,CLM_GETEXTRAIMAGELIST,0,0);
+ ImageList_Destroy(hIml);
+ ReleaseIconEx("list_fl");
+ ReleaseIconEx("list_al");
+ ReleaseIconEx("list_bl");
+ ReleaseIconEx("list_rl");
+ break;
+ }
+
+ return FALSE;
+}