soc.2009.vulture: 08b97007: Started context menu for chats.

gdick at soc.pidgin.im gdick at soc.pidgin.im
Mon Jul 20 15:33:10 EDT 2009


-----------------------------------------------------------------
Revision: 08b970071624b594694fd7b2cc7dee518839cb28
Ancestor: 12d681863654d6a9dd40dd152d6da084d9dea973
Author: gdick at soc.pidgin.im
Date: 2009-07-20T18:35:07
Branch: im.pidgin.soc.2009.vulture
URL: http://d.pidgin.im/viewmtn/revision/info/08b970071624b594694fd7b2cc7dee518839cb28

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

ChangeLog: 

Started context menu for chats.

-------------- next part --------------
============================================================
--- vulture/purpleblist.c	76df5b0d2887446c22274cc6f176776b487f618b
+++ vulture/purpleblist.c	d15055009825c90a518715d6d1807f944dd4da76
@@ -34,6 +34,7 @@ static BOOL ShouldShowNode(PurpleBlistNo
 
 
 static BOOL ShouldShowNode(PurpleBlistNode *lpblistnode);
+static void AddCommonMenuItems(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA, PurpleConnection *lpconnection, int iProtoIndex, int iExtendedIndex);
 
 
 
@@ -319,33 +320,89 @@ void PurpleMakeBuddyMenu(HMENU hmenu, Pu
  */
 void PurpleMakeBuddyMenu(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA)
 {
-	GList *lpglistPMA;
-	PurplePluginProtocolInfo *lpprplinfo;
-	PurpleConnection *lpconnection;
-	UINT uiNextID = IDM_DYNAMIC_FIRST;
-
 	*lplpglistVMA = NULL;
 
 	if(!lpblistnode)
 		return;
 
-	lpconnection = ((PurpleBuddy*)lpblistnode)->account->gc;
+	AddCommonMenuItems(
+		hmenu,
+		lpblistnode,
+		lplpglistVMA,
+		((PurpleBuddy*)lpblistnode)->account->gc,
+		VultureGetMenuPosFromID(hmenu, IDM_BLIST_CONTEXT_VIEWLOG) + 1,
+		VultureGetMenuPosFromID(hmenu, IDM_BLIST_CONTEXT_BLOCK));
 
+	/* Enable/disable/check stuff as appropriate. */
+	CheckMenuItem(hmenu, IDM_BLIST_CONTEXT_SHOWOFFLINE, purple_blist_node_get_bool(lpblistnode, "show_offline") ? MF_CHECKED : MF_UNCHECKED);
+}
+
+
+/**
+ * Adds dynamic menu items common to various sorts of buddy-list node.
+ *
+ * @param[in,out]	hmenu		Menu to add to.
+ * @param		lpblistnode	List node.
+ * @param[in,out]	lplpglistVMA	VMA pointers will be appended to this
+ *					list as necessary. Free them later.
+ * @param		lpconnect	Connection for node.
+ * @param		iProtoIndex	Menu index at which to insert prpl-
+ *					specific menu items.
+ * @param		iExtendedIndex	Menu index at which to insert extended
+ *					menu items.
+ */
+static void AddCommonMenuItems(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA, PurpleConnection *lpconnection, int iProtoIndex, int iExtendedIndex)
+{
+	GList *lpglistPMA;
+	PurplePluginProtocolInfo *lpprplinfo;
+	UINT uiNextID = IDM_DYNAMIC_FIRST;
+
 	if(lpconnection &&
 		(lpprplinfo = PURPLE_PLUGIN_PROTOCOL_INFO(lpconnection->prpl)) &&
 		lpprplinfo->blist_node_menu)
 	{
 		/* Insert at the bottom of the first section. */
 		lpglistPMA = lpprplinfo->blist_node_menu(lpblistnode);
-		PurpleInsertDynamicMenu(hmenu, VultureGetMenuPosFromID(hmenu, IDM_BLIST_CONTEXT_VIEWLOG) + 1, &uiNextID, lpglistPMA, lplpglistVMA, lpblistnode);
+		PurpleInsertDynamicMenu(hmenu, iProtoIndex, &uiNextID, lpglistPMA, lplpglistVMA, lpblistnode);
 		g_list_free(lpglistPMA);
 	}
 
 	/* Insert at the top of the second section. */
 	lpglistPMA = purple_blist_node_get_extended_menu(lpblistnode);
-	PurpleInsertDynamicMenu(hmenu, VultureGetMenuPosFromID(hmenu, IDM_BLIST_CONTEXT_BLOCK), &uiNextID, lpglistPMA, lplpglistVMA, lpblistnode);
+	PurpleInsertDynamicMenu(hmenu, iExtendedIndex, &uiNextID, lpglistPMA, lplpglistVMA, lpblistnode);
 	g_list_free(lpglistPMA);
+}
 
-	/* Enable/disable/check stuff as appropriate. */
-	CheckMenuItem(hmenu, IDM_BLIST_CONTEXT_SHOWOFFLINE, purple_blist_node_get_bool(lpblistnode, "show_offline") ? MF_CHECKED : MF_UNCHECKED);
+
+/**
+ * Builds the context menu for a chat node.
+ *
+ * @param[in,out]	hmenu		Basic menu loaded from the resources,
+ *					which will be augmented.
+ * @param		lpblistnode	Buddy-list node for a buddy (not
+ *					contact).
+ * @param[out]		lplpglistVMA	Used to return a list populated with
+ *					pointers to item-data for the menu
+ *					items that we add, which the caller
+ *					should g_free (and then g_list_free)
+ *					once it's done with the menu, but which
+ *					otherwise it probably doesn't care
+ *					about.
+ */
+void PurpleMakeChatMenu(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA)
+{
+	int iIndex = VultureGetMenuPosFromID(hmenu, IDM_BLIST_CONTEXT_VIEWLOG) + 1;
+
+	*lplpglistVMA = NULL;
+
+	if(!lpblistnode)
+		return;
+
+	AddCommonMenuItems(
+		hmenu,
+		lpblistnode,
+		lplpglistVMA,
+		((PurpleChat*)lpblistnode)->account->gc,
+		iIndex,
+		iIndex);
 }
============================================================
--- vulture/purpleblist.h	ed5a2b70215e322cb6fc30a9b2323d2bce6f83d7
+++ vulture/purpleblist.h	e62085f3fac63d5e202ec71fbf8f008bcd4af38d
@@ -51,6 +51,7 @@ void PurpleMakeBuddyMenu(HMENU hmenu, Pu
 LPTSTR PurpleBuddyGetStatusText(PurpleBuddy *lpbuddy);
 void PurpleBuddyStatusChanged(PurpleBuddy *lpbuddy, PurpleStatus *lpstatusOld, PurpleStatus *lpstatusNew);
 void PurpleMakeBuddyMenu(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA);
+void PurpleMakeChatMenu(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA);
 
 
 static INLINE void VultureBListNodeAddRef(VULTURE_BLIST_NODE *lpvblnode) { InterlockedIncrement(&lpvblnode->lRefCount); }
============================================================
--- vulture/purplequeue.c	8ac28ebf299e397b7fe61b714bc1e6cd4b8563b7
+++ vulture/purplequeue.c	d29d9b59ecc40a63acbd526bd71c5dc1d5701d62
@@ -273,11 +273,17 @@ static void DispatchPurpleCall(PURPLE_CA
 		
 		break;
 
-	case PC_MAKEBUDDYMENU:
+	case PC_MAKECONTEXTMENU:
 		{
 			VULTURE_MAKE_CONTEXT_MENU *lpvmcm = lppurplecall->lpvParam;
 			
-			PurpleMakeBuddyMenu(lpvmcm->hmenu, EFFECTIVE_BUDDY(lpvmcm->lpvblistnode->lpblistnode), lpvmcm->lplpglistVMA);
+			if(lpvmcm->lpvblistnode->lpblistnode)
+			{
+				if(PURPLE_BLIST_NODE_IS_BUDDY(lpvmcm->lpvblistnode->lpblistnode) || PURPLE_BLIST_NODE_IS_CONTACT(lpvmcm->lpvblistnode->lpblistnode))
+					PurpleMakeBuddyMenu(lpvmcm->hmenu, EFFECTIVE_BUDDY(lpvmcm->lpvblistnode->lpblistnode), lpvmcm->lplpglistVMA);
+				else if(PURPLE_BLIST_NODE_IS_CHAT(lpvmcm->lpvblistnode->lpblistnode))
+					PurpleMakeChatMenu(lpvmcm->hmenu, lpvmcm->lpvblistnode->lpblistnode, lpvmcm->lplpglistVMA);
+			}
 		}
 
 		break;
============================================================
--- vulture/purplequeue.h	611ad85182c54db2595a9d9aface8d9e6e44d6fa
+++ vulture/purplequeue.h	c3fbf1f5d643071908c606423ea7d8355410db07
@@ -84,7 +84,7 @@ enum PURPLE_CALL_ID
 	PC_GETIMBUDDYICON,
 
 	/* (VULTURE_MAKE_CONTEXT_MENU*) */
-	PC_MAKEBUDDYMENU,
+	PC_MAKECONTEXTMENU,
 
 	/* (VULTURE_MENU_ACTION*) */
 	PC_PERFORMMENUACTION,
============================================================
--- vulture/resource.h	58b1a0d28e14faa19ad81b0d256dbf921527dfff
+++ vulture/resource.h	4f4f051631c8f2066662972e132da591c11e4354
@@ -37,7 +37,7 @@
 #define IDM_BLIST_BUDDIES_JOINCHAT              40002
 
 #define IDM_BLIST_CONTEXT                       1002
-#define IDM_BLIST_CONTEXT_IM                    40201
+#define IDM_BLIST_CONTEXT_ACTIVATE              40201
 #define IDM_BLIST_CONTEXT_GETINFO               40202
 #define IDM_BLIST_CONTEXT_SENDFILE              40203
 #define IDM_BLIST_CONTEXT_ADDPOUNCE     	40204
@@ -49,6 +49,8 @@
 #define IDM_BLIST_CONTEXT_CUSTOMICON            40210
 #define IDM_BLIST_CONTEXT_REMOVEICON            40211
 #define IDM_BLIST_CONTEXT_SHOWBUDDIES           40212
+#define IDM_BLIST_CONTEXT_AUTOJOIN              40213
+#define IDM_BLIST_CONTEXT_PROPERTIES            40214
 
 #define IDM_CONV                                1003
 #define IDM_CONV_CONV_CLOSE                     40401
============================================================
--- vulture/vulture-res.rc	f37b20b28b6f682e20099ac92e6183869f404eef
+++ vulture/vulture-res.rc	d4adffc130389c8a069f39aaf8bbfc805433d283
@@ -36,19 +36,19 @@ IDM_CONV MENU
     }
 }
 
-#define BUDDY_CONTACT_VIEWLOG \
+#define CONTEXT_VIEWLOG \
 	MENUITEM "View &log", IDM_BLIST_CONTEXT_VIEWLOG, MFT_STRING, MFS_GRAYED
 
-#define BUDDY_CONTACT_ALIAS_REMOVE \
+#define CONTEXT_ALIAS_REMOVE \
 	MENUITEM "Set &alias...", IDM_BLIST_CONTEXT_ALIAS, MFT_STRING, MFS_GRAYED \
 	MENUITEM "&Remove from buddy list", IDM_BLIST_CONTEXT_REMOVE, MFT_STRING, MFS_GRAYED
 
 #define BUDDY_CONTACT_COMMON \
-	MENUITEM "Start &conversation", IDM_BLIST_CONTEXT_IM, MFT_STRING, MFS_DEFAULT \
+	MENUITEM "Start &conversation", IDM_BLIST_CONTEXT_ACTIVATE, MFT_STRING, MFS_DEFAULT \
 	MENUITEM "Get &info", IDM_BLIST_CONTEXT_GETINFO, MFT_STRING, MFS_GRAYED \
 	MENUITEM "Send &file...", IDM_BLIST_CONTEXT_SENDFILE, MFT_STRING, MFS_GRAYED \
 	MENUITEM "Add &pounce...", IDM_BLIST_CONTEXT_ADDPOUNCE, MFT_STRING, MFS_GRAYED \
-	BUDDY_CONTACT_VIEWLOG \
+	CONTEXT_VIEWLOG \
 	\
 	MENUITEM "", 0, MFT_SEPARATOR \
 	\
@@ -59,7 +59,7 @@ IDM_CONV MENU
 	MENUITEM "", 0, MFT_SEPARATOR \
 	MENUITEM "Set custom &icon...", IDM_BLIST_CONTEXT_CUSTOMICON, MFT_STRING, MFS_GRAYED \
 	MENUITEM "Remo&ve custom icon", IDM_BLIST_CONTEXT_REMOVEICON, MFT_STRING, MFS_GRAYED \
-	BUDDY_CONTACT_ALIAS_REMOVE \
+	CONTEXT_ALIAS_REMOVE \
 	MENUITEM "", 0, MFT_SEPARATOR \
 	MENUITEM "Sho&w individual buddies", IDM_BLIST_CONTEXT_SHOWBUDDIES, MFT_STRING, MFS_GRAYED
 
@@ -69,7 +69,7 @@ IDM_BLIST_CONTEXT MENUEX
 	POPUP "Buddy"
 	{
 		BUDDY_CONTACT_COMMON
-		BUDDY_CONTACT_ALIAS_REMOVE
+		CONTEXT_ALIAS_REMOVE
 	}
 
 	POPUP "Contact (Composite)"
@@ -80,9 +80,19 @@ IDM_BLIST_CONTEXT MENUEX
 
 	POPUP "Contact (Basic)"
 	{
-		BUDDY_CONTACT_VIEWLOG
+		CONTEXT_VIEWLOG
 		CONTACT_TAIL
 	}
+
+	POPUP "Chat"
+	{
+		MENUITEM "&Join chat", IDM_BLIST_CONTEXT_ACTIVATE, MFT_STRING, MFS_DEFAULT
+		MENUITEM "Join &automatically at login", IDM_BLIST_CONTEXT_AUTOJOIN, MFT_STRING, MFS_GRAYED
+		CONTEXT_VIEWLOG
+		MENUITEM "", 0, MFT_SEPARATOR
+		CONTEXT_ALIAS_REMOVE
+		MENUITEM "&Properties", IDM_BLIST_CONTEXT_PROPERTIES, MFT_STRING, MFS_GRAYED
+	}
 }
 
 
============================================================
--- vulture/vultureblist.c	83ff5e22679d56dda403501c5136289a9c24a733
+++ vulture/vultureblist.c	d12bd7013e4b82382784ffae982da52175b55429
@@ -57,6 +57,8 @@ static void RunBuddyMenuCmd(VULTURE_BLIS
 static void SetStatusMsg(HWND hwndStatusDlg);
 static void RemoveBListNode(HWND hwndBlistTree, VULTURE_BLIST_NODE *lpvbn);
 static void RunBuddyMenuCmd(VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd);
+static BOOL RunCommonMenuCmd(VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd);
+static void RunChatMenuCmd(VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd);
 
 
 #define BLIST_MARGIN 6
@@ -66,6 +68,7 @@ enum CONTEXT_MENU_INDICES
 	CMI_BUDDY = 0,
 	CMI_CONTACT_COMPOSITE,
 	CMI_CONTACT_BASIC,
+	CMI_CHAT,
 };
 
 
@@ -602,6 +605,7 @@ static INT_PTR CALLBACK BuddyListDlgProc
 							HMENU hmenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDM_BLIST_CONTEXT));
 							HMENU hmenuSubmenu = NULL;
 							GList *lpglistVMA = NULL;
+							BOOL bExtraItems;
 
 							/* Really select this node. */
 							TreeView_SelectItem(lpnmhdr->hwndFrom, tvitem.hItem);
@@ -611,46 +615,49 @@ static INT_PTR CALLBACK BuddyListDlgProc
 
 							lpvblistnode = (VULTURE_BLIST_NODE*)tvitem.lParam;
 
+							/* Assume we need to ask the core for extra items. */
+							bExtraItems = TRUE;
+
 							/* Reading lpvblistnode->nodetype is atomic and so
 							 * we don't need our critical section.
 							 */
 							switch(lpvblistnode->nodetype)
 							{
 							case PURPLE_BLIST_BUDDY_NODE:
-								{
-									VULTURE_MAKE_CONTEXT_MENU vmcm;
-
-									vmcm.hmenu = hmenuSubmenu = GetSubMenu(hmenu, CMI_BUDDY);
-									vmcm.lpvblistnode = lpvblistnode;
-									vmcm.lplpglistVMA = &lpglistVMA;
-
-									VultureSingleSyncPurpleCall(PC_MAKEBUDDYMENU, &vmcm);
-								}
-								
+								hmenuSubmenu = GetSubMenu(hmenu, CMI_BUDDY);
 								break;
 
 							case PURPLE_BLIST_CONTACT_NODE:
 								if(TreeView_GetChild(lpnmhdr->hwndFrom, tvitem.hItem))
 								{
 									hmenuSubmenu = GetSubMenu(hmenu, CMI_CONTACT_BASIC);
+									bExtraItems = FALSE;
 								}
 								else
-								{
-									VULTURE_MAKE_CONTEXT_MENU vmcm;
+									hmenuSubmenu = GetSubMenu(hmenu, CMI_CONTACT_COMPOSITE);
 
-									vmcm.hmenu = hmenuSubmenu = GetSubMenu(hmenu, CMI_CONTACT_COMPOSITE);
-									vmcm.lpvblistnode = lpvblistnode;
-									vmcm.lplpglistVMA = &lpglistVMA;
+								break;
 
-									VultureSingleSyncPurpleCall(PC_MAKEBUDDYMENU, &vmcm);
-								}
-
+							case PURPLE_BLIST_CHAT_NODE:
+								hmenuSubmenu = GetSubMenu(hmenu, CMI_CHAT);
 								break;
 
 							default:
+								bExtraItems = FALSE;
 								break;
 							}
 
+							if(bExtraItems)
+							{
+								VULTURE_MAKE_CONTEXT_MENU vmcm;
+
+								vmcm.hmenu = hmenuSubmenu;
+								vmcm.lpvblistnode = lpvblistnode;
+								vmcm.lplpglistVMA = &lpglistVMA;
+
+								VultureSingleSyncPurpleCall(PC_MAKECONTEXTMENU, &vmcm);
+							}
+
 							if(hmenuSubmenu)
 							{
 								POINT ptMouse;
@@ -667,6 +674,9 @@ static INT_PTR CALLBACK BuddyListDlgProc
 									case PURPLE_BLIST_CONTACT_NODE:
 										RunBuddyMenuCmd(lpvblistnode, hmenuSubmenu, iCmd);
 										break;
+									case PURPLE_BLIST_CHAT_NODE:
+										RunChatMenuCmd(lpvblistnode, hmenuSubmenu, iCmd);
+										break;
 									default:
 										break;
 									}
@@ -917,18 +927,38 @@ static void RunBuddyMenuCmd(VULTURE_BLIS
  */
 static void RunBuddyMenuCmd(VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd)
 {
-	UNREFERENCED_PARAMETER(hmenu);
+	if(RunCommonMenuCmd(lpvblistnode, hmenu, iCmd))
+		return;
 
 	switch(iCmd)
 	{
-	case IDM_BLIST_CONTEXT_IM:
-		VultureEnqueueAsyncPurpleCall(PC_BLISTNODEACTIVATED, lpvblistnode);
-		break;
-
 	case IDM_BLIST_CONTEXT_SHOWOFFLINE:
 		VultureEnqueueAsyncPurpleCall(PC_TOGGLESHOWOFFLINE, lpvblistnode);
 		break;
+	}
+}
 
+
+/**
+ * Determines whether a menu command is one of those common to various sorts of
+ * context menu, and if so, executes it.
+ *
+ * @param	lpvblistnode	List node to which the context menu relates.
+ * @param	hmenu		Context menu.
+ * @param	iCmd		Command ID.
+ *
+ * @return TRUE iff we processed the command.
+ */
+static BOOL RunCommonMenuCmd(VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd)
+{
+	UNREFERENCED_PARAMETER(hmenu);
+
+	switch(iCmd)
+	{
+	case IDM_BLIST_CONTEXT_ACTIVATE:
+		VultureEnqueueAsyncPurpleCall(PC_BLISTNODEACTIVATED, lpvblistnode);
+		return TRUE;
+
 	default:
 		/* Not a static command that we recongise; might be a dynamic
 		 * command.
@@ -942,8 +972,27 @@ static void RunBuddyMenuCmd(VULTURE_BLIS
 			GetMenuItemInfo(hmenu, iCmd, FALSE, &mii);
 
 			VultureSingleSyncPurpleCall(PC_PERFORMMENUACTION, (VULTURE_MENU_ACTION*)mii.dwItemData);
+
+			return TRUE;
 		}
 
 		break;
 	}
+
+	return FALSE;
 }
+
+
+/**
+ * Executes a menu command from the context menu for a chat node in the buddy
+ * list.
+ *
+ * @param	lpvblistnode	List node to which the context menu relates.
+ * @param	hmenu		Context menu.
+ * @param	iCmd		Command ID.
+ */
+static void RunChatMenuCmd(VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd)
+{
+	if(RunCommonMenuCmd(lpvblistnode, hmenu, iCmd))
+		return;
+}


More information about the Commits mailing list