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