From c943899dce2dac80cf54f8c673a009d2a071ddd4 Mon Sep 17 00:00:00 2001
From: Kirill Volinsky <mataes2007@gmail.com>
Date: Fri, 5 Apr 2013 11:00:59 +0000
Subject: added contact menu support

git-svn-id: http://svn.miranda-ng.org/main/trunk@4311 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 plugins/XSoundNotify/res/XSoundNotify.rc | Bin 6416 -> 6494 bytes
 plugins/XSoundNotify/src/xsn_main.cpp    | 224 ++++++++++++++++++++++++++++++-
 2 files changed, 220 insertions(+), 4 deletions(-)

(limited to 'plugins')

diff --git a/plugins/XSoundNotify/res/XSoundNotify.rc b/plugins/XSoundNotify/res/XSoundNotify.rc
index ca35e52332..f64fc3b661 100644
Binary files a/plugins/XSoundNotify/res/XSoundNotify.rc and b/plugins/XSoundNotify/res/XSoundNotify.rc differ
diff --git a/plugins/XSoundNotify/src/xsn_main.cpp b/plugins/XSoundNotify/src/xsn_main.cpp
index a920f298ac..338c95240a 100644
--- a/plugins/XSoundNotify/src/xsn_main.cpp
+++ b/plugins/XSoundNotify/src/xsn_main.cpp
@@ -12,6 +12,7 @@ There is no warranty.
 HINSTANCE hInst;
 int hLangpack;
 LIST<XSN_Data> XSN_Users(10, LIST<XSN_Data>::FTSortFunc(HandleKeySort));
+HANDLE hChangeSound = NULL, hChangeSoundDlgList = NULL;
 
 PLUGININFOEX pluginInfo = {
 	sizeof(PLUGININFOEX),
@@ -72,7 +73,7 @@ bool IsSuitableProto(PROTOACCOUNT* pa)
 	if (pa->bDynDisabled || !pa->bIsEnabled)
 		return false;
 
-	if (CallProtoService(pa->szProtoName, PS_GETCAPS, PFLAGNUM_2, 0) == 0)
+	if (!(CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IMRECV))
 		return false;
 
 	return true;
@@ -281,8 +282,198 @@ INT OptInit(WPARAM wParam, LPARAM lParam)
 	return 0;
 }
 
+INT_PTR CALLBACK DlgProcContactsOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	switch (msg) {
+	case WM_INITDIALOG:
+		{
+			TranslateDialogDefault(hwndDlg);
+			HANDLE hContact = (HANDLE)lParam;
+			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
+			WindowList_Add(hChangeSoundDlgList, hwndDlg, hContact);
+			Utils_RestoreWindowPositionNoSize(hwndDlg, hContact, SETTINGSNAME, "ChangeSoundDlg");
+			char* szProto = GetContactProto(hContact);
+			PROTOACCOUNT *pa = ProtoGetAccount(szProto);
+			char* szUniqueId = (char*)CallProtoService(pa->szModuleName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+			if ((INT_PTR) szUniqueId != CALLSERVICE_NOTFOUND && szUniqueId != NULL) {
+				DBVARIANT dbvuid = {0};
+				if ( !db_get(hContact, pa->szModuleName, szUniqueId, &dbvuid))
+				{
+					TCHAR uid[MAX_PATH];
+					switch(dbvuid.type) {
+					case DBVT_DWORD:
+						_itot(dbvuid.dVal, uid, 10);
+						break;
+
+					case DBVT_ASCIIZ:
+						_tcscpy(uid, _A2T(dbvuid.pszVal));
+						break;
+
+					case DBVT_UTF8:
+						{
+							TCHAR *tmpuid = mir_utf8decodeT(dbvuid.pszVal);
+							_tcscpy(uid, tmpuid);
+							mir_free(tmpuid);
+						}
+						break;
+					}
+
+					TCHAR *nick = (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR);
+					TCHAR *value = (TCHAR *)mir_alloc(sizeof(TCHAR) * (_tcslen(uid) + _tcslen(nick) + 21));
+					mir_sntprintf(value, _tcslen(uid) + _tcslen(nick) + 21, TranslateT("Custom sound for %s (%s)"), nick, uid);
+					SetWindowText(hwndDlg, value);
+					mir_free(value);
+					db_free(&dbvuid);
+				}
+			}
+			EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_CHOOSE_SOUND), TRUE);
+			DBVARIANT dbv = {0};
+			if ( !db_get_ts(hContact, SETTINGSNAME, SETTINGSKEY, &dbv))
+			{
+				EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_TEST_PLAY), TRUE);
+				EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_RESET_SOUND), TRUE);
+				SetDlgItemText(hwndDlg, IDC_LABEL_SOUND, PathFindFileName(dbv.ptszVal));
+				db_free(&dbv);
+			} else {
+				EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_TEST_PLAY), FALSE);
+				EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_RESET_SOUND), FALSE);
+				SetDlgItemText(hwndDlg, IDC_LABEL_SOUND, TranslateT("Not set"));
+			}
+			XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact);
+			if (p == NULL)
+			{
+				DBVARIANT dbv;
+				if ( !db_get_ts(hContact, SETTINGSNAME, SETTINGSKEY, &dbv))
+				{
+					XSN_Users.insert( new XSN_Data(hContact, dbv.ptszVal));
+					db_free(&dbv);
+				}
+			}
+		}
+		return TRUE;
+	
+	case WM_COMMAND:
+		switch (LOWORD(wParam)) {
+		case IDOK:
+			{
+				HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+				XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact);
+				if (p != NULL)
+				{
+					TCHAR shortpath[MAX_PATH];
+					PathToRelativeT(p->path, shortpath);
+					db_set_ts(hContact, SETTINGSNAME, SETTINGSKEY, shortpath);
+				}
+			}
+
+		case IDCANCEL:
+			DestroyWindow(hwndDlg);
+			break;
+
+		case IDC_BUTTON_CHOOSE_SOUND:
+			{
+				TCHAR FileName[MAX_PATH];
+				TCHAR *tszMirDir = Utils_ReplaceVarsT(_T("%miranda_path%"));
+
+				OPENFILENAME ofn = {0};
+				ofn.lStructSize = sizeof(ofn);
+				TCHAR tmp[MAX_PATH];
+				if (GetModuleHandle(_T("bass_interface.dll")))
+					mir_sntprintf(tmp, SIZEOF(tmp), _T("%s (*.wav, *.mp3, *.ogg)%c*.wav;*.mp3;*.ogg%c%c"), TranslateT("Sound files"), 0, 0, 0);
+				else
+					mir_sntprintf(tmp, SIZEOF(tmp), _T("%s (*.wav)%c*.wav%c%c"), TranslateT("WAV files"), 0, 0, 0);
+				ofn.lpstrFilter = tmp;
+				ofn.hwndOwner = 0;
+				ofn.lpstrFile = FileName;
+				ofn.nMaxFile = MAX_PATH;
+				ofn.nMaxFileTitle = MAX_PATH;
+				ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
+				ofn.lpstrInitialDir = tszMirDir;
+				*FileName = '\0';
+				ofn.lpstrDefExt = _T("");
+
+				if (GetOpenFileName(&ofn)) {
+					HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+					SetDlgItemText(hwndDlg, IDC_LABEL_SOUND, PathFindFileName(FileName));
+					XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact);
+					if (p == NULL)
+						XSN_Users.insert( new XSN_Data(hContact, FileName));
+					else
+						_tcsncpy(p->path, FileName, SIZEOF(p->path));
+					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_TEST_PLAY), TRUE);
+					EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_RESET_SOUND), TRUE);
+				}
+				mir_free(tszMirDir);
+			}
+			break;
+
+		case IDC_BUTTON_TEST_PLAY:
+			{
+				HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+				XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact);
+				if (p == NULL)
+				{
+					DBVARIANT dbv;
+					if ( !db_get_ts(hContact, SETTINGSNAME, SETTINGSKEY, &dbv))
+					{
+						TCHAR longpath[MAX_PATH] = {0};
+						PathToAbsoluteT(dbv.ptszVal, longpath);
+						SkinPlaySoundFile(longpath);
+						db_free(&dbv);
+					}
+				}
+				else
+				{
+					TCHAR longpath[MAX_PATH] = {0};
+					PathToAbsoluteT(p->path, longpath);
+					SkinPlaySoundFile(longpath);
+				}
+			}
+			break;
+
+		case IDC_BUTTON_RESET_SOUND:
+			{
+				HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+				EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_TEST_PLAY), FALSE);
+				EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_RESET_SOUND), FALSE);
+				SetDlgItemText(hwndDlg, IDC_LABEL_SOUND, TranslateT("Not set"));
+				XSN_Data *p = XSN_Users.find((XSN_Data *)&hContact);
+				if (p != NULL)
+				{
+					XSN_Users.remove(p);
+					delete p;
+				}
+				db_unset(hContact, SETTINGSNAME, SETTINGSKEY);
+			}
+			break;
+		}
+		break;
+
+	case WM_CLOSE:
+		DestroyWindow(hwndDlg);
+		break;
+
+	case WM_DESTROY:
+		{
+			HANDLE hContact = (HANDLE)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+		Utils_SaveWindowPosition(hwndDlg, hContact, SETTINGSNAME, "ChangeSoundDlg");
+		WindowList_Remove(hChangeSoundDlgList, hwndDlg);
+		}
+	}
+	return FALSE;
+}
+
 INT_PTR ShowDialog(WPARAM wParam, LPARAM lParam)
 {
+	HWND hChangeSoundDlg = WindowList_Find(hChangeSoundDlgList, (HANDLE)wParam);
+	if (!hChangeSoundDlg) {
+		hChangeSoundDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_CONTACTS), 0, DlgProcContactsOptions, (LPARAM)wParam);
+		ShowWindow(hChangeSoundDlg, SW_SHOW);
+	}
+	else {
+		SetForegroundWindow(hChangeSoundDlg);
+		SetFocus(hChangeSoundDlg);
+	}
 	return 0;
 }
 
@@ -295,8 +486,30 @@ int OnLoadInit(WPARAM wParam, LPARAM lParam)
 	mi.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); 
 	mi.ptszName = LPGENT("Custom contact sound"); 
 	mi.pszService = "XSoundNotify/ContactMenuCommand"; 
-	Menu_AddContactMenuItem(&mi); 
+	hChangeSound = Menu_AddContactMenuItem(&mi); 
+
+	return 0;
+}
 
+int PrebuildContactMenu(WPARAM wParam, LPARAM lParam)
+{
+	HANDLE hContact = (HANDLE)wParam;
+	if (hContact) {
+		char* szProto = GetContactProto(hContact);
+		PROTOACCOUNT *pa = ProtoGetAccount(szProto);
+		CLISTMENUITEM mi = { sizeof(mi) };
+		if (IsSuitableProto(pa))
+			mi.flags = CMIF_TCHAR | CMIM_FLAGS;
+		else
+			mi.flags = CMIF_TCHAR | CMIM_FLAGS | CMIF_HIDDEN;
+		CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hChangeSound, (LPARAM)&mi);
+	}
+	return 0;
+}
+
+int OnPreShutdown(WPARAM wParam, LPARAM lParam)
+{
+	WindowList_Broadcast(hChangeSoundDlgList, WM_CLOSE, 0, 0);
 	return 0;
 }
 
@@ -304,12 +517,15 @@ extern "C" int __declspec(dllexport) Load()
 {
 	mir_getLP(&pluginInfo);
 
-	CreateServiceFunction("XSoundNotify/ContactMenuCommand", ShowDialog); 
+	CreateServiceFunction("XSoundNotify/ContactMenuCommand", ShowDialog);
+
+	hChangeSoundDlgList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0);
 
 	HookEvent(ME_OPT_INITIALISE, OptInit);
 	HookEvent(ME_DB_EVENT_ADDED, ProcessEvent);
 	HookEvent(ME_SYSTEM_MODULESLOADED, OnLoadInit);
-
+	HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu);
+	HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreShutdown);
 	return 0;
 }
 
-- 
cgit v1.2.3