soc.2009.vulture: 04019011: Allow user to set status using the edit-...

gdick at soc.pidgin.im gdick at soc.pidgin.im
Tue Jun 23 16:00:27 EDT 2009


-----------------------------------------------------------------
Revision: 04019011553560bda0ce5c2d7639fdb281615920
Ancestor: 02e3ec90d8d47fe8e4f88c1e1a12c5bb4333f24b
Author: gdick at soc.pidgin.im
Date: 2009-06-23T11:23:41
Branch: im.pidgin.soc.2009.vulture
URL: http://d.pidgin.im/viewmtn/revision/info/04019011553560bda0ce5c2d7639fdb281615920

Modified files:
        vulture/purplequeue.c vulture/purplequeue.h
        vulture/purplestatus.c vulture/vulture-res.rc
        vulture/vultureblist.c

ChangeLog: 

Allow user to set status using the edit-box.

-------------- next part --------------
============================================================
--- vulture/purplequeue.c	d94443796cc2b8814de8dfdad1ab4ddf40a701e5
+++ vulture/purplequeue.c	892fd73e86b64eb6d22dc4b36d959a6fb04455d6
@@ -197,6 +197,16 @@ static void DispatchPurpleCall(PURPLE_CA
 		VultureFreeConvSend((VULTURE_CONV_SEND*)lppurplecall->lpvParam);
 		break;
 
+	case PC_GETSTATUSMSG:
+		{
+			/* Caller should g_free returned buffer if non-NULL. */
+			PurpleSavedStatus *lppss = purple_savedstatus_get_current();
+			const char *szMessage = purple_savedstatus_get_message(lppss);
+			*((LPTSTR*)lppurplecall->lpvParam) = szMessage ? VultureUTF8ToTCHAR(szMessage) : NULL;
+		}
+
+		break;
+
 	case PC_QUIT:
 		purple_core_quit();
 		g_main_loop_quit(g_lpgmainloop);
============================================================
--- vulture/purplequeue.h	f6087cbcaf4678c2e64889beee6e3ae7d05d57b8
+++ vulture/purplequeue.h	b587a91f6135f57a5b453d7e8aff4f5ae4659184
@@ -56,6 +56,9 @@ enum PURPLE_CALL_ID
 
 	/* (VULTURE_CONV_SEND*) Conversation send-message details. */
 	PC_CONVSEND,
+
+	/* (LPTSTR*) Used to return address of buffer. */
+	PC_GETSTATUSMSG,
 };
 
 
============================================================
--- vulture/purplestatus.c	aa7787cb976a7d529d7c7c6138b5d48ad834f177
+++ vulture/purplestatus.c	c886ba29816ca7ea8c46504f22d6d0d614044826
@@ -128,7 +128,8 @@ void PurpleSetStatus(VULTURE_SAVED_STATU
  */
 void PurpleSetStatus(VULTURE_SAVED_STATUS *lpvss)
 {
-	char *szMessage = NULL;
+	char *szNewMessage = NULL;
+	const char *szMessage = NULL;
 	PurpleSavedStatus *lppss;
 
 	switch(lpvss->vsstype)
@@ -142,10 +143,11 @@ void PurpleSetStatus(VULTURE_SAVED_STATU
 
 	case VSSTYPE_TRANSIENT:
 		if(lpvss->szMessage)
-			szMessage = VultureTCHARToUTF8(lpvss->szMessage);
+			szMessage = szNewMessage = VultureTCHARToUTF8(lpvss->szMessage);
 		break;
 
-	default:
+	case VSSTYPE_PRIMITIVE:
+		szMessage = purple_savedstatus_get_message(purple_savedstatus_get_current());
 		break;
 	}
 
@@ -159,8 +161,8 @@ void PurpleSetStatus(VULTURE_SAVED_STATU
 
 	purple_savedstatus_activate(lppss);
 
-	if(szMessage)
-		g_free(szMessage);
+	if(szNewMessage)
+		g_free(szNewMessage);
 }
 
 
============================================================
--- vulture/vulture-res.rc	1c6366b107a31f81966e33f72127c6eae6a1ed62
+++ vulture/vulture-res.rc	5f10333ff32a684cf4253efa092c20382a7d9dde
@@ -101,7 +101,7 @@ FONT 8, "Ms Shell Dlg"
 {
     CONTROL         "", IDC_BUDDY_ICON, WC_STATIC, WS_TABSTOP | SS_BLACKFRAME | SS_NOTIFY | SS_SUNKEN, 5, 5, 30, 30
     CONTROL         "1", IDC_CBEX_STATUS, "ComboBoxEx32", 0x50000003, 40, 5, 115, 90
-    EDITTEXT        IDC_EDIT_STATUSMSG, 40, 20, 115, 15, ES_AUTOHSCROLL | ES_WANTRETURN
+    EDITTEXT        IDC_EDIT_STATUSMSG, 40, 20, 115, 15, ES_AUTOHSCROLL
 }
 
 
============================================================
--- vulture/vultureblist.c	1a209e5fe5db116d3b66ba2a90137e53b4d10397
+++ vulture/vultureblist.c	c9868c572845ad5edd0816c93142eb8ee8b3df3f
@@ -23,6 +23,8 @@
 #include <windows.h>
 #include <commctrl.h>
 #include <glib.h>
+#include <tchar.h>
+#include <string.h>
 
 #include "vulture.h"
 #include "resource.h"
@@ -38,12 +40,20 @@
 #include "purpleconv.h"
 
 
+typedef struct _STATUSDLGDATA
+{
+	WNDPROC	wndprocStatusMsgOrig;
+} STATUSDLGDATA;
+
+
 static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
 static INT_PTR CALLBACK StatusDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
 static INT_PTR CALLBACK BuddyListDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
 static void ManageAccounts(HWND hwndParent);
 static void PopulateStatusList(HWND hwndComboStatus);
 static void UpdateStatusUI(VULTURE_SAVED_STATUS *lpvss, HWND hwndStatusDlg);
+static LRESULT CALLBACK StatusMsgBoxSubclassProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam);
+static void SetStatusMsg(HWND hwndStatusDlg);
 
 
 #define BLIST_MARGIN 6
@@ -53,6 +63,7 @@ static GList *g_lpglistStatuses = NULL;
 GList *g_lpglistConvContainers = NULL;
 
 static GList *g_lpglistStatuses = NULL;
+static HWND g_hwndStatusDlg = NULL, g_hwndBListDlg = NULL;
 
 
 
@@ -124,7 +135,6 @@ static LRESULT CALLBACK MainWndProc(HWND
  */
 static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
 {
-	static HWND s_hwndStatusDlg = NULL, s_hwndBListDlg = NULL;
 	static HCURSOR s_hCursor;
 
 	switch(uiMsg)
@@ -134,11 +144,11 @@ static LRESULT CALLBACK MainWndProc(HWND
 			int i, iCount;
 			HMENU hmenu = GetMenu(hwnd);
 
-			s_hwndStatusDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_STATUS), hwnd, StatusDlgProc);
-			s_hwndBListDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_BLIST), hwnd, BuddyListDlgProc);
+			g_hwndStatusDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_STATUS), hwnd, StatusDlgProc);
+			g_hwndBListDlg = CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_BLIST), hwnd, BuddyListDlgProc);
 
-			EnableWindow(s_hwndStatusDlg, FALSE);
-			EnableWindow(s_hwndBListDlg, FALSE);
+			EnableWindow(g_hwndStatusDlg, FALSE);
+			EnableWindow(g_hwndBListDlg, FALSE);
 
 			s_hCursor = LoadCursor(NULL, IDC_WAIT);
 
@@ -170,12 +180,12 @@ static LRESULT CALLBACK MainWndProc(HWND
 			RECT rcClient, rcStatus;
 
 			GetClientRect(hwnd, &rcClient);
-			GetWindowRect(s_hwndStatusDlg, &rcStatus);
+			GetWindowRect(g_hwndStatusDlg, &rcStatus);
 
 			hdwp = BeginDeferWindowPos(2);
-			hdwp = DeferWindowPos(hdwp, s_hwndStatusDlg, NULL, 0, 0, rcClient.right, rcStatus.bottom - rcStatus.top, SWP_NOACTIVATE | SWP_NOZORDER);
+			hdwp = DeferWindowPos(hdwp, g_hwndStatusDlg, NULL, 0, 0, rcClient.right, rcStatus.bottom - rcStatus.top, SWP_NOACTIVATE | SWP_NOZORDER);
 			rcClient.top = rcStatus.bottom - rcStatus.top;
-			hdwp = DeferWindowPos(hdwp, s_hwndBListDlg, NULL, 0, rcClient.top, rcClient.right, rcClient.bottom - rcClient.top, SWP_NOACTIVATE | SWP_NOZORDER);
+			hdwp = DeferWindowPos(hdwp, g_hwndBListDlg, NULL, 0, rcClient.top, rcClient.right, rcClient.bottom - rcClient.top, SWP_NOACTIVATE | SWP_NOZORDER);
 			EndDeferWindowPos(hdwp);
 		}
 
@@ -207,10 +217,10 @@ static LRESULT CALLBACK MainWndProc(HWND
 					int i, iCount;
 					HMENU hmenu = GetMenu(hwnd);
 
-					PopulateStatusList(GetDlgItem(s_hwndStatusDlg, IDC_CBEX_STATUS));
+					PopulateStatusList(GetDlgItem(g_hwndStatusDlg, IDC_CBEX_STATUS));
 
-					EnableWindow(s_hwndStatusDlg, TRUE);
-					EnableWindow(s_hwndBListDlg, TRUE);
+					EnableWindow(g_hwndStatusDlg, TRUE);
+					EnableWindow(g_hwndBListDlg, TRUE);
 
 					iCount = GetMenuItemCount(hmenu);
 					for(i = 0; i < iCount; i++)
@@ -224,7 +234,7 @@ static LRESULT CALLBACK MainWndProc(HWND
 
 			case VUIMSG_UPDATEBLISTNODE:
 				{
-					HWND hwndBlistTree = GetDlgItem(s_hwndBListDlg, IDC_TREE_BLIST);
+					HWND hwndBlistTree = GetDlgItem(g_hwndBListDlg, IDC_TREE_BLIST);
 					VULTURE_BLIST_NODE *lpvbn = (VULTURE_BLIST_NODE*)lParam;
 
 					EnterCriticalSection(&lpvbn->cs);
@@ -299,7 +309,7 @@ static LRESULT CALLBACK MainWndProc(HWND
 				break;
 
 			case VUIMSG_STATUSCHANGED:
-				UpdateStatusUI((VULTURE_SAVED_STATUS*)lParam, s_hwndStatusDlg);
+				UpdateStatusUI((VULTURE_SAVED_STATUS*)lParam, g_hwndStatusDlg);
 				VultureFreeStatus((VULTURE_SAVED_STATUS*)lParam);
 				break;
 
@@ -337,8 +347,8 @@ static LRESULT CALLBACK MainWndProc(HWND
 
 	case WM_DESTROY:
 		
-		DestroyWindow(s_hwndBListDlg);
-		DestroyWindow(s_hwndStatusDlg);
+		DestroyWindow(g_hwndBListDlg);
+		DestroyWindow(g_hwndStatusDlg);
 
 		if(g_lpglistConvContainers)
 			g_list_free(g_lpglistConvContainers);
@@ -371,6 +381,8 @@ static INT_PTR CALLBACK StatusDlgProc(HW
 		{
 			RECT rcIcon;
 			POINT ptIcon;
+			HWND hwndStatusMsg = GetDlgItem(hwndDlg, IDC_EDIT_STATUSMSG);
+			STATUSDLGDATA *lpsdd;
 
 			GetWindowRect(GetDlgItem(hwndDlg, IDC_BUDDY_ICON), &rcIcon);
 			ptIcon.x = rcIcon.left;
@@ -381,6 +393,12 @@ static INT_PTR CALLBACK StatusDlgProc(HW
 			 * height.
 			 */
 			SetWindowPos(GetDlgItem(hwndDlg, IDC_BUDDY_ICON), NULL, BLIST_MARGIN, ptIcon.y, rcIcon.bottom - rcIcon.top, rcIcon.bottom - rcIcon.top, SWP_NOACTIVATE | SWP_NOZORDER);
+
+			/* Subclass status message box. */
+			lpsdd = ProcHeapAlloc(sizeof(STATUSDLGDATA));
+			lpsdd->wndprocStatusMsgOrig = (WNDPROC)GetWindowLongPtr(hwndStatusMsg, GWLP_WNDPROC);
+			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG)lpsdd);
+			SetWindowLongPtr(hwndStatusMsg, GWLP_WNDPROC, (LONG)StatusMsgBoxSubclassProc);
 		}
 
 		/* Let the system set the focus. */
@@ -425,20 +443,25 @@ static INT_PTR CALLBACK StatusDlgProc(HW
 		case IDC_CBEX_STATUS:
 			if(HIWORD(wParam) == CBN_SELCHANGE)
 			{
-				/* Inform libpurple of the change in status,
-				 * and update message edit box.
-				 */
+				/* Inform libpurple of the change in status. */
 
 				int iSel = SendDlgItemMessage(hwndDlg, IDC_CBEX_STATUS, CB_GETCURSEL, 0, 0);
 
 				if(iSel >= 0)
 				{
-					VULTURE_SAVED_STATUS *lpvss = (VULTURE_SAVED_STATUS*)SendDlgItemMessage(hwndDlg, IDC_CBEX_STATUS, CB_GETITEMDATA, iSel, 0);
-					VultureSingleSyncPurpleCall(PC_SETSAVEDSTATUS, lpvss);
+					VULTURE_SAVED_STATUS *lpvssList = (VULTURE_SAVED_STATUS*)SendDlgItemMessage(hwndDlg, IDC_CBEX_STATUS, CB_GETITEMDATA, iSel, 0);
+					VultureSingleSyncPurpleCall(PC_SETSAVEDSTATUS, lpvssList);
+				}
 
-					SetDlgItemText(hwndDlg, IDC_EDIT_STATUSMSG, lpvss->szMessage ? lpvss->szMessage : TEXT(""));
-				}
+				return TRUE;
+			}
 
+			break;
+
+		case IDC_EDIT_STATUSMSG:
+			if(HIWORD(wParam) == EN_KILLFOCUS)
+			{
+				SetStatusMsg(hwndDlg);
 				return TRUE;
 			}
 
@@ -448,11 +471,19 @@ static INT_PTR CALLBACK StatusDlgProc(HW
 		break;
 
 
+	case WM_INPUTENTER:
+		SetStatusMsg(hwndDlg);
+		SendMessage(g_hwndBListDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(g_hwndBListDlg, IDC_TREE_BLIST), MAKELPARAM(TRUE, 0));
+		return TRUE;
+
+
 	case WM_DESTROY:
 
 		if(g_lpglistStatuses)
 			VulturePurpleFreeStatusList(g_lpglistStatuses);
 
+		ProcHeapFree((STATUSDLGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
+
 		return TRUE;
 	}
 
@@ -601,3 +632,79 @@ static void UpdateStatusUI(VULTURE_SAVED
 		SetDlgItemText(hwndStatusDlg, IDC_EDIT_STATUSMSG, lpvss->szMessage);
 	}
 }
+
+
+/**
+ * Subclassing window procedure for status message edit control.
+ *
+ * @param	hwnd		Input box window handle.
+ * @param	uiMsg		Message ID.
+ * @param	wParam		Message-specific.
+ * @param	lParam		Message-specific.
+ *
+ * @return Message-specific.
+ */
+static LRESULT CALLBACK StatusMsgBoxSubclassProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
+{
+	STATUSDLGDATA *lpsdd;
+	HWND hwndParent = GetParent(hwnd);
+
+	/* Intercept the Enter key. */
+	if(uiMsg == WM_KEYDOWN && wParam == VK_RETURN)
+	{
+		SendMessage(hwndParent, WM_INPUTENTER, 0, (LPARAM)hwnd);
+		return 0;
+	}
+	/* Don't beep. */
+	else if(uiMsg == WM_CHAR && wParam == VK_RETURN)
+		return 0;
+
+	lpsdd = (STATUSDLGDATA*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
+	return CallWindowProc(lpsdd->wndprocStatusMsgOrig, hwnd, uiMsg, wParam, lParam);
+}
+
+
+/**
+ * Sets the current status message using the values of the UI controls.
+ *
+ * @param	hwndStatusDlg	Status dialogue window handle.
+ */
+static void SetStatusMsg(HWND hwndStatusDlg)
+{
+	HWND hwndEdit = GetDlgItem(hwndStatusDlg, IDC_EDIT_STATUSMSG);
+	VULTURE_SAVED_STATUS vss;
+	LPTSTR szOldMessage;
+
+	int cchStatus = GetWindowTextLength(hwndEdit) + 1;
+
+	if(cchStatus > 1)
+	{
+		vss.szMessage = ProcHeapAlloc(cchStatus * sizeof(TCHAR));
+		GetWindowText(hwndEdit, vss.szMessage, cchStatus);
+	}
+	else vss.szMessage =  NULL;
+
+	VultureSingleSyncPurpleCall(PC_GETSTATUSMSG, &szOldMessage);
+
+	/* Only do anything if the message has actually changed. */
+	if((vss.szMessage && !szOldMessage) ||
+		(!vss.szMessage && szOldMessage) ||
+		(vss.szMessage && szOldMessage && _tcscmp(vss.szMessage, szOldMessage) != 0))
+	{
+		int iSel = SendDlgItemMessage(hwndStatusDlg, IDC_CBEX_STATUS, CB_GETCURSEL, 0, 0);
+
+		if(iSel >= 0)
+		{
+			VULTURE_SAVED_STATUS *lpvssList = (VULTURE_SAVED_STATUS*)SendDlgItemMessage(hwndStatusDlg, IDC_CBEX_STATUS, CB_GETITEMDATA, iSel, 0);
+
+			vss.psprim = lpvssList->psprim;
+			vss.szTitle = lpvssList->szTitle;
+			vss.vsstype = VSSTYPE_TRANSIENT;
+
+			VultureSingleSyncPurpleCall(PC_SETSAVEDSTATUS, &vss);
+		}
+	}
+
+	if(szOldMessage) g_free(szOldMessage);
+	if(vss.szMessage) ProcHeapFree(vss.szMessage);
+}


More information about the Commits mailing list