From 205c3163ad207b7a95d8a80799c4e538851f0ce7 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Tue, 29 Jan 2013 19:25:22 +0100 Subject: [PATCH] Adapt to use XMPPContactManager --- data/gtk/chat.ui | 1 + src/core/JubChatClient.h | 2 + src/core/JubChatClient.m | 6 ++ src/gui/gtk/JubGtkChatUI.m | 12 ++- src/gui/gtk/JubGtkRosterUI.h | 4 +- src/gui/gtk/JubGtkRosterUI.m | 163 ++++++++++++++++++----------------- 6 files changed, 103 insertions(+), 85 deletions(-) diff --git a/data/gtk/chat.ui b/data/gtk/chat.ui index 8c352cd..bc23241 100644 --- a/data/gtk/chat.ui +++ b/data/gtk/chat.ui @@ -193,6 +193,7 @@ True True + True ● diff --git a/src/core/JubChatClient.h b/src/core/JubChatClient.h index a73082d..4f6205b 100644 --- a/src/core/JubChatClient.h +++ b/src/core/JubChatClient.h @@ -9,11 +9,13 @@ XMPPConnection *connection; XMPPRoster *roster; XMPPStreamManagement *streamManagement; + XMPPContactManager *contactManager; XMPPPresence *presence; id ui; } @property (readonly) XMPPConnection *connection; @property (readonly) XMPPRoster *roster; +@property (readonly) XMPPContactManager *contactManager; @property (readonly) XMPPPresence *presence; @property (assign) id ui; diff --git a/src/core/JubChatClient.m b/src/core/JubChatClient.m index 4efa894..b4a1481 100644 --- a/src/core/JubChatClient.m +++ b/src/core/JubChatClient.m @@ -3,6 +3,7 @@ @implementation JubChatClient @synthesize connection; @synthesize roster; +@synthesize contactManager; @synthesize presence; @synthesize ui; @@ -22,6 +23,10 @@ roster = [[XMPPRoster alloc] initWithConnection: connection]; [roster addDelegate: self]; + contactManager = [[XMPPContactManager alloc] + initWithConnection: connection + roster: roster]; + streamManagement = [[XMPPStreamManagement alloc] initWithConnection: connection]; @@ -37,6 +42,7 @@ - (void)dealloc { [roster release]; + [contactManager release]; [streamManagement release]; [connection release]; [presence release]; diff --git a/src/gui/gtk/JubGtkChatUI.m b/src/gui/gtk/JubGtkChatUI.m index 8fc633e..7db4aef 100644 --- a/src/gui/gtk/JubGtkChatUI.m +++ b/src/gui/gtk/JubGtkChatUI.m @@ -15,10 +15,14 @@ static gboolean call_send_block(GtkEntry *entry, GdkEventKey *event, OFString *text = [[OFString alloc] initWithUTF8String: gtk_entry_get_text(entry)]; - gtk_entry_set_text(entry, ""); - params->block(text); - [params->chat addMessage: text - sender: @"You"]; + + if ([text length] > 0) { + gtk_entry_set_text(entry, ""); + params->block(text); + [params->chat addMessage: text + sender: @"You"]; + } + [text release]; return TRUE; diff --git a/src/gui/gtk/JubGtkRosterUI.h b/src/gui/gtk/JubGtkRosterUI.h index ec94383..4b2e50a 100644 --- a/src/gui/gtk/JubGtkRosterUI.h +++ b/src/gui/gtk/JubGtkRosterUI.h @@ -6,7 +6,7 @@ @class JubGtkChatUI; -@interface JubGtkRosterUI: OFObject +@interface JubGtkRosterUI: OFObject { GtkWidget *roster_window; GtkTreeStore *roster_model; @@ -17,7 +17,7 @@ OFMutableDictionary *contactMap; OFMutableDictionary *chatMap; OFCountedSet *presences; - XMPPConnection *connection; + JubChatClient *client; } - initWithClient: (JubChatClient*)client; diff --git a/src/gui/gtk/JubGtkRosterUI.m b/src/gui/gtk/JubGtkRosterUI.m index ad54fd6..5826aa1 100644 --- a/src/gui/gtk/JubGtkRosterUI.m +++ b/src/gui/gtk/JubGtkRosterUI.m @@ -81,7 +81,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, } @implementation JubGtkRosterUI -- initWithClient: (JubChatClient*)client; +- initWithClient: (JubChatClient*)client_ { self = [super init]; @@ -95,10 +95,9 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, contactMap = [[OFMutableDictionary alloc] init]; chatMap = [[OFMutableDictionary alloc] init]; presences = [[OFCountedSet alloc] init]; - connection = [client.connection retain]; + client = [client_ retain]; - [connection addDelegate: self]; - [client.roster addDelegate: self]; + [client.contactManager addDelegate: self]; builder = gtk_builder_new(); gtk_builder_add_from_file(builder, "data/gtk/roster.ui", NULL); @@ -129,7 +128,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, presence_combo_changed_handler_id = g_signal_connect(presence_combo, "changed", - G_CALLBACK(presence_changed), connection); + G_CALLBACK(presence_changed), client.connection); g_object_unref(G_OBJECT(builder)); } @catch (id e) { @@ -142,31 +141,18 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, - (void)dealloc { + [client.contactManager removeDelegate: self]; [groupMap release]; [contactMap release]; [chatMap release]; [presences release]; - [connection release]; + [client release]; gtk_widget_destroy(roster_window); [super dealloc]; } -/* Presence handling */ -- (void)connection: (XMPPConnection*)connection - didReceivePresence: (XMPPPresence*)presence -{ - if ([presence.type isEqual: @"available"]) - [presences addObject: [presence.from bareJID]]; - else if ([presence.type isEqual: @"unavailable"]) - [presences removeObject: [presence.from bareJID]]; - - g_idle_add_block(^{ - gtk_tree_model_filter_refilter(roster_filter); - }); -} - // FIXME: This needs to move somewhere else - (JubGtkChatUI*)chatForJID: (XMPPJID*)jid { @@ -187,7 +173,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, [XMPPMessage messageWithType: @"chat"]; msg.to = jid; msg.body = text; - [connection sendStanza: msg]; + [client.connection sendStanza: msg]; } ] autorelease]; @@ -200,9 +186,12 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, return chat; } -- (void)connection: (XMPPConnection*)connection - didReceiveMessage: (XMPPMessage*)message +- (void)contact: (XMPPContact*)contact + didSendMessage: (XMPPMessage*)message { + if (message.body == nil || ![message.type isEqual: @"chat"]) + return; + JubGtkChatUI *chat = [self chatForJID: message.from]; [chat addMessage: message.body sender: [message.from bareJID]]; @@ -216,8 +205,17 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, GtkTreeIter group_iter, contact_iter; GtkTreeRowReference *group_ref, *contact_ref; GtkTreePath *group_path, *contact_path; - OFMapTable *contactRows = - [contactMap objectForKey: [item.JID bareJID]]; + OFString *bareJID = [item.JID bareJID]; + OFMapTable *contactRows; + + if (!(contactRows = [contactMap objectForKey: bareJID])) { + contactRows = [OFMapTable + mapTableWithKeyFunctions: keyFunctions + valueFunctions: rowRefFunctions]; + + [contactMap setObject: contactRows + forKey: bareJID]; + } group_ref = [groupMap valueForKey: group]; @@ -249,11 +247,11 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, if (item.name) gtk_tree_store_set(roster_model, &contact_iter, 0, [item.name UTF8String], - 1, [[item.JID bareJID] UTF8String], -1); + 1, [bareJID UTF8String], -1); else gtk_tree_store_set(roster_model, &contact_iter, 0, [item.JID.node UTF8String], - 1, [[item.JID bareJID] UTF8String], -1); + 1, [bareJID UTF8String], -1); contact_path = gtk_tree_model_get_path(GTK_TREE_MODEL( roster_model), &contact_iter); @@ -275,8 +273,8 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, GtkTreeIter contact_iter, group_iter; GtkTreePath *contact_path, *group_path; GtkTreeRowReference *contact_ref, *group_ref; - OFMapTable *contactRows = - [contactMap objectForKey: [item.JID bareJID]]; + OFString *bareJID = [item.JID bareJID]; + OFMapTable *contactRows = [contactMap objectForKey: bareJID]; contact_ref = [contactRows valueForKey: group]; contact_path = gtk_tree_row_reference_get_path(contact_ref); @@ -297,73 +295,80 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, } gtk_tree_path_free(group_path); + + [contactRows removeValueForKey: group]; + if([contactRows count] == 0) + [contactMap removeObjectForKey: bareJID]; }); } -- (void)rosterWasReceived: (XMPPRoster*)roster_ +- (void)contactManager: (XMPPContactManager*)manager + didAddContact: (XMPPContact*)contact { - of_log(@"Handling roster"); - [[roster_ rosterItems] enumerateKeysAndObjectsUsingBlock: - ^(OFString *bareJID, XMPPRosterItem *item, BOOL *stop) { - OFArray *groups; - OFMapTable *contactRows = [OFMapTable - mapTableWithKeyFunctions: keyFunctions - valueFunctions: rowRefFunctions]; - - [contactMap setObject: contactRows - forKey: bareJID]; - - if (item.groups != nil) - groups = item.groups; - else - groups = @[@"General"]; + XMPPRosterItem *rosterItem = contact.rosterItem; + OFArray *groups = rosterItem.groups;; + + if (groups == nil) + groups = @[ @"General" ]; - for (OFString *group in groups) - [self Jub_addRosterItem: item - group: group]; - }]; + for (OFString *group in groups) + [self Jub_addRosterItem: rosterItem + group: group]; } -- (void)roster: (XMPPRoster*)roster_ - didReceiveRosterItem: (XMPPRosterItem*)item +- (void)contactManager: (XMPPContactManager*)manager + didRemoveContact: (XMPPContact*)contact { - OFArray *groups; - XMPPRosterItem *oldItem = - [roster_.rosterItems objectForKey: [item.JID bareJID]]; + XMPPRosterItem *rosterItem = contact.rosterItem; + OFArray *groups = rosterItem.groups; - if (oldItem) { - if (oldItem.groups != nil) - groups = oldItem.groups; - else - groups = @[@"General"]; + if (groups == nil) + groups = @[ @"General" ]; - for (OFString *group in groups) - [self Jub_removeRosterItem: oldItem - group: group]; + for (OFString *group in groups) + [self Jub_removeRosterItem: rosterItem + group: group]; +} - [contactMap removeObjectForKey: [item.JID bareJID]]; - } +- (void)contact: (XMPPContact*)contact + willUpdateWithRosterItem: (XMPPRosterItem*)rosterItem; +{ + // Remove contact from old set of groups + XMPPRosterItem *oldItem = contact.rosterItem; + OFArray *groups = oldItem.groups; - if (![item.subscription isEqual: @"remove"]) { - OFMapTable *contactRows = [OFMapTable - mapTableWithKeyFunctions: keyFunctions - valueFunctions: rowRefFunctions]; + if (groups == nil) + groups = @[ @"General" ]; - [contactMap setObject: contactRows - forKey: [item.JID bareJID]]; + for (OFString *group in groups) + [self Jub_removeRosterItem: oldItem + group: group]; - if (item.groups != nil) - groups = item.groups; - else - groups = @[@"General"]; + // Add contact to new set of groups + groups = rosterItem.groups; - for (OFString *group in groups) - [self Jub_addRosterItem: item - group: group]; - } + if (groups == nil) + groups = @[ @"General" ]; + + for (OFString *group in groups) + [self Jub_addRosterItem: rosterItem + group: group]; +} + +- (void)contact: (XMPPContact*)contact + didSendPresence: (XMPPPresence*)presence +{ + if ([presence.type isEqual: @"available"]) + [presences addObject: [presence.from bareJID]]; + else if ([presence.type isEqual: @"unavailable"]) + [presences removeObject: [presence.from bareJID]]; + + g_idle_add_block(^{ + gtk_tree_model_filter_refilter(roster_filter); + }); } -- (void)client: (JubChatClient*)client +- (void)client: (JubChatClient*)client_ didChangePresence: (XMPPPresence*)presence { OFString *tooltip = @""; -- 2.39.2