soc.2009.vulture: 126c471f: Remove blist nodes from context menu.
gdick at soc.pidgin.im
gdick at soc.pidgin.im
Fri Jul 24 18:30:54 EDT 2009
-----------------------------------------------------------------
Revision: 126c471fce73c7f92c794e2be3f72073041fb04a
Ancestor: 659a88b2b14098998b4755feac7b15ee2c9654e6
Author: gdick at soc.pidgin.im
Date: 2009-07-22T18:31:59
Branch: im.pidgin.soc.2009.vulture
URL: http://d.pidgin.im/viewmtn/revision/info/126c471fce73c7f92c794e2be3f72073041fb04a
Modified files:
vulture/purpleblist.c vulture/purpleblist.h
vulture/purplequeue.c vulture/purplequeue.h
vulture/resource.h vulture/vulture-res.rc
vulture/vultureblist.c vulture/vultureblist.h
ChangeLog:
Remove blist nodes from context menu.
-------------- next part --------------
============================================================
--- vulture/purpleblist.c 2bc7ea663b751be35961ceb1002894ba9bc5e296
+++ vulture/purpleblist.c b516a5fb34e9b61b21ee2ac59442445af5d1d233
@@ -35,6 +35,7 @@ static void AddCommonMenuItems(HMENU hme
static BOOL ShouldShowNode(PurpleBlistNode *lpblistnode);
static void AddCommonMenuItems(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA, PurpleConnection *lpconnection, int iProtoIndex, int iExtendedIndex);
+static void DeleteBuddyFromAccount(PurpleBuddy *lpbuddy);
@@ -213,12 +214,20 @@ void PurpleBlistRemoveNode(PurpleBuddyLi
lpvbn = lpblistnode->ui_data;
- /* This pointer is about to become invalid. */
- lpvbn->lpblistnode = NULL;
+ EnterCriticalSection(&lpvbn->cs);
+ {
+ /* This pointer is about to become invalid. */
+ lpvbn->lpblistnode = NULL;
- if(lpvbn->hti)
- VulturePostUIMessage(VUIMSG_REMOVEBLISTNODE, lpvbn);
+ if(lpvbn->hti)
+ VulturePostUIMessage(VUIMSG_REMOVEBLISTNODE, lpvbn);
+ /* The parent may need to go, too. */
+ if(lpvbn->lpvbnParent && lpvbn->lpvbnParent->hti)
+ PurpleBlistUpdateNode(lpbuddylist, lpvbn->lpvbnParent->lpblistnode);
+ }
+ LeaveCriticalSection(&lpvbn->cs);
+
VultureBListNodeRelease((VULTURE_BLIST_NODE*)lpblistnode->ui_data);
lpblistnode->ui_data = NULL;
@@ -453,3 +462,100 @@ void PurpleBlistAliasNode(PurpleBlistNod
g_free(szAliasUTF8);
}
+
+
+/**
+ * Removes a buddy-list from libpurple's buddy list.
+ *
+ * @param lpblistnode Buddy-list node.
+ */
+void PurpleDeleteBlistNode(PurpleBlistNode *lpblistnode)
+{
+ if(!lpblistnode)
+ return;
+
+ if(PURPLE_BLIST_NODE_IS_CHAT(lpblistnode))
+ {
+ /* Chats are easy, since they only exist in the buddy list and
+ * have no children.
+ */
+ purple_blist_remove_chat((PurpleChat*)lpblistnode);
+ }
+ else if(PURPLE_BLIST_NODE_IS_BUDDY(lpblistnode))
+ {
+ DeleteBuddyFromAccount((PurpleBuddy*)lpblistnode);
+ purple_blist_remove_buddy((PurpleBuddy*)lpblistnode);
+ }
+ else if(PURPLE_BLIST_NODE_IS_CONTACT(lpblistnode))
+ {
+ PurpleBlistNode *lpblistnodeBuddies;
+
+ /* Remove any buddies from their respective accounts. */
+ for(lpblistnodeBuddies = lpblistnode->child;
+ lpblistnodeBuddies;
+ lpblistnodeBuddies = lpblistnodeBuddies->next)
+ {
+ if(PURPLE_BLIST_NODE_IS_BUDDY(lpblistnodeBuddies))
+ DeleteBuddyFromAccount((PurpleBuddy*)lpblistnodeBuddies);
+ }
+
+ purple_blist_remove_contact((PurpleContact*)lpblistnode);
+ }
+ else if(PURPLE_BLIST_NODE_IS_GROUP(lpblistnode))
+ {
+ PurpleBlistNode *lpblistnodeInGroup = lpblistnode->child;
+
+ /* Traverse tree, deleting everything, and being careful with
+ * the list pointers.
+ */
+ while(lpblistnodeInGroup)
+ {
+ if(PURPLE_BLIST_NODE_IS_CONTACT(lpblistnodeInGroup))
+ {
+ PurpleContact *lpcontact = (PurpleContact*)lpblistnodeInGroup;
+ PurpleBlistNode *lpblistnodeBuddies = lpblistnode->child;
+ lpblistnodeInGroup = lpblistnodeInGroup->next;
+
+ while(lpblistnodeBuddies)
+ {
+ if(PURPLE_BLIST_NODE_IS_BUDDY(lpblistnodeBuddies))
+ {
+ PurpleBuddy *lpbuddy = (PurpleBuddy*)lpblistnodeBuddies;
+ lpblistnodeBuddies = lpblistnodeBuddies->next;
+
+ DeleteBuddyFromAccount(lpbuddy);
+ purple_blist_remove_buddy(lpbuddy);
+ }
+ else
+ lpblistnodeBuddies = lpblistnodeBuddies->next;
+ }
+
+ purple_blist_remove_contact(lpcontact);
+ }
+ else if(PURPLE_BLIST_NODE_IS_CHAT(lpblistnodeInGroup))
+ {
+ PurpleChat *lpchat = (PurpleChat*)lpblistnodeInGroup;
+ lpblistnodeInGroup = lpblistnodeInGroup->next;
+ purple_blist_remove_chat(lpchat);
+ }
+ else
+ lpblistnodeInGroup = lpblistnodeInGroup->next;
+ }
+
+ purple_blist_remove_group((PurpleGroup*)lpblistnode);
+ }
+}
+
+
+/**
+ * Removes a buddy from its account, if that account is connected.
+ *
+ * @param lpbuddy Buddy.
+ */
+static void DeleteBuddyFromAccount(PurpleBuddy *lpbuddy)
+{
+ PurpleAccount *lpaccount = purple_buddy_get_account(lpbuddy);
+
+ if(purple_account_is_connected(lpaccount))
+ purple_account_remove_buddy(lpaccount, lpbuddy, purple_buddy_get_group(lpbuddy));
+}
============================================================
--- vulture/purpleblist.h af9870519752904d7644f52f1da45e3833250386
+++ vulture/purpleblist.h a70828ebc277bb5291ce8a37f144db6f62bf2941
@@ -41,6 +41,7 @@ void PurpleBlistAliasNode(PurpleBlistNod
void PurpleMakeBuddyMenu(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA);
void PurpleMakeChatMenu(HMENU hmenu, PurpleBlistNode *lpblistnode, GList **lplpglistVMA);
void PurpleBlistAliasNode(PurpleBlistNode *lpblistnode, LPCTSTR szAlias);
+void PurpleDeleteBlistNode(PurpleBlistNode *lpblistnode);
static INLINE void VultureBListNodeAddRef(VULTURE_BLIST_NODE *lpvblnode) { InterlockedIncrement(&lpvblnode->lRefCount); }
============================================================
--- vulture/purplequeue.c 7f16e6679fbaf37b6ee5dd1e38c1ef42762b4454
+++ vulture/purplequeue.c f233b9684865dcadab89c0135eb76d10cd5d8e31
@@ -335,6 +335,18 @@ static void DispatchPurpleCall(PURPLE_CA
break;
+ case PC_REMOVEBLISTNODE:
+ PurpleDeleteBlistNode(((VULTURE_BLIST_NODE*)lppurplecall->lpvParam)->lpblistnode);
+ break;
+
+ case PC_BLISTNODEHASCHILDREN:
+ {
+ VULTURE_BLIST_NODE_GET_BOOL *lpvbngetbool = lppurplecall->lpvParam;
+ lpvbngetbool->bReturn = lpvbngetbool->lpvblistnode->lpblistnode && lpvbngetbool->lpvblistnode->lpblistnode->child;
+ }
+
+ break;
+
case PC_QUIT:
purple_core_quit();
g_main_loop_quit(g_lpgmainloop);
============================================================
--- vulture/purplequeue.h 231e847f1a6d7a374a98e035870840358a1af803
+++ vulture/purplequeue.h 1b419a9f8e73dc3f4fd4b4a5cc176df3be224f96
@@ -97,6 +97,12 @@ enum PURPLE_CALL_ID
/* (VULTURE_BLIST_NODE*) Chat node. */
PC_TOGGLEAUTOJOIN,
+
+ /* (VULTURE_BLIST_NODE*) */
+ PC_REMOVEBLISTNODE,
+
+ /* (VULTURE_BLIST_NODE_GET_BOOL*) */
+ PC_BLISTNODEHASCHILDREN,
};
============================================================
--- vulture/resource.h 4f4f051631c8f2066662972e132da591c11e4354
+++ vulture/resource.h 71fba6866b61e5ef3518586cb0f28c4e6ac96f2a
@@ -68,3 +68,5 @@
#define IDS_ACCMGR_PROTOCOL 4
#define IDS_ERROR_CONVCONTCLASS 5
#define IDS_ERROR_RICHEDIT 6
+#define IDS_QUERY_DELGROUP 7
+#define IDS_QUERY_DELCONTACT 8
============================================================
--- vulture/vulture-res.rc 9c4feae7646ef2779d955bccba9eee35028dbba3
+++ vulture/vulture-res.rc c2410c425b80bc856886f306c742534fb14f0f68
@@ -41,7 +41,7 @@ IDM_CONV MENU
#define CONTEXT_ALIAS_REMOVE \
MENUITEM "Set &alias", IDM_BLIST_CONTEXT_ALIAS, MFT_STRING \
- MENUITEM "&Remove from buddy list", IDM_BLIST_CONTEXT_REMOVE, MFT_STRING, MFS_GRAYED
+ MENUITEM "&Remove from buddy list", IDM_BLIST_CONTEXT_REMOVE, MFT_STRING
#define BUDDY_CONTACT_COMMON \
MENUITEM "Start &conversation", IDM_BLIST_CONTEXT_ACTIVATE, MFT_STRING, MFS_DEFAULT \
@@ -210,6 +210,8 @@ STRINGTABLE
IDS_ACCMGR_PROTOCOL "Protocol"
IDS_ERROR_CONVCONTCLASS "Couldn't register conversation container class."
IDS_ERROR_RICHEDIT "Couldn't load RichEdit."
+ IDS_QUERY_DELGROUP "Deleting this group will also delete everything contained in it. Do you wish to continue?"
+ IDS_QUERY_DELCONTACT "Deleting this contact will also delete all buddies associated with it. Do you wish to continue?"
}
============================================================
--- vulture/vultureblist.c 6b652e2f3614508a0df595c2dba5cdfb9f17104d
+++ vulture/vultureblist.c def4faff462d708a6cddf8a610974a4dfbb21809
@@ -59,6 +59,7 @@ static void RunChatMenuCmd(HWND hwndBudd
static void RunBuddyMenuCmd(HWND hwndBuddies, VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd);
static BOOL RunCommonMenuCmd(HWND hwndBuddies, VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd);
static void RunChatMenuCmd(HWND hwndBuddies, VULTURE_BLIST_NODE *lpvblistnode, HMENU hmenu, int iCmd);
+static void RemoveNodeRequest(HWND hwndBuddies, VULTURE_BLIST_NODE *lpvblistnode);
#define BLIST_MARGIN 6
@@ -614,6 +615,7 @@ static INT_PTR CALLBACK BuddyListDlgProc
TreeView_GetItem(lpnmhdr->hwndFrom, &tvitem);
lpvblistnode = (VULTURE_BLIST_NODE*)tvitem.lParam;
+ VultureBListNodeAddRef(lpvblistnode);
/* Assume we need to ask the core for extra items. */
bExtraItems = TRUE;
@@ -683,6 +685,8 @@ static INT_PTR CALLBACK BuddyListDlgProc
}
}
+ VultureBListNodeRelease(lpvblistnode);
+
/* Destroy menu. This will also destroy our modifications. */
DestroyMenu(hmenu);
@@ -991,6 +995,10 @@ static BOOL RunCommonMenuCmd(HWND hwndBu
SendMessage(hwndBuddies, TVM_EDITLABEL, 0, (LPARAM)lpvblistnode->hti);
return TRUE;
+ case IDM_BLIST_CONTEXT_REMOVE:
+ RemoveNodeRequest(hwndBuddies, lpvblistnode);
+ return TRUE;
+
default:
/* Not a static command that we recongise; might be a dynamic
* command.
@@ -1036,3 +1044,33 @@ static void RunChatMenuCmd(HWND hwndBudd
break;
}
}
+
+
+/**
+ * Deletes a buddy-list node, prompting the user first if necessary.
+ *
+ * @param hwndBuddies Buddy-list tree-view.
+ * @param lpvblistnode List node to delete.
+ */
+static void RemoveNodeRequest(HWND hwndBuddies, VULTURE_BLIST_NODE *lpvblistnode)
+{
+ VULTURE_BLIST_NODE_GET_BOOL vblngetbool;
+ BOOL bDelete = TRUE;
+
+ vblngetbool.lpvblistnode = lpvblistnode;
+ VultureSingleSyncPurpleCall(PC_BLISTNODEHASCHILDREN, &vblngetbool);
+
+ /* If we have any children, prompt before deleting. */
+ if(vblngetbool.bReturn)
+ {
+ EnterCriticalSection(&lpvblistnode->cs);
+ if(lpvblistnode->nodetype == PURPLE_BLIST_GROUP_NODE)
+ bDelete = MessageBoxFromStringTable(g_hwndMain, IDS_QUERY_DELGROUP, MB_ICONEXCLAMATION | MB_YESNO);
+ else if(lpvblistnode->nodetype == PURPLE_BLIST_CONTACT_NODE)
+ bDelete = MessageBoxFromStringTable(g_hwndMain, IDS_QUERY_DELCONTACT, MB_ICONEXCLAMATION | MB_YESNO);
+ LeaveCriticalSection(&lpvblistnode->cs);
+ }
+
+ if(bDelete)
+ VultureSingleSyncPurpleCall(PC_REMOVEBLISTNODE, lpvblistnode);
+}
============================================================
--- vulture/vultureblist.h 677720b04ee7247e4f175ab294c5466b8b7be9c9
+++ vulture/vultureblist.h 87f6739800c61a41b79503397408ffe6fa037fac
@@ -43,11 +43,17 @@ typedef struct _VULTURE_ALIAS_NODE
typedef struct _VULTURE_ALIAS_NODE
{
- VULTURE_BLIST_NODE *lpvblistnode;
- LPTSTR szAlias;
+ VULTURE_BLIST_NODE *lpvblistnode;
+ LPTSTR szAlias;
} VULTURE_ALIAS_NODE;
+typedef struct _VULTURE_BLIST_NODE_GET_BOOL
+{
+ VULTURE_BLIST_NODE *lpvblistnode;
+ BOOL bReturn;
+} VULTURE_BLIST_NODE_GET_BOOL;
+
extern HWND g_hwndMain;
GList *g_lpglistConvContainers;
More information about the Commits
mailing list