From 73956f28f94e6137684150bf5d311826dae7f35a Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Thu, 27 Dec 2012 02:52:33 +0100 Subject: [PATCH] Open new chat windows when activating a roster row --- src/core/main.m | 9 +++--- src/gui/gtk/JubGtkRosterUI.h | 8 ++++- src/gui/gtk/JubGtkRosterUI.m | 63 +++++++++++++++++++++++++++++++----- src/gui/gtk/JubGtkUI.h | 3 ++ src/gui/gtk/JubGtkUI.m | 5 +-- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/core/main.m b/src/core/main.m index 62393b2..c01a5cc 100644 --- a/src/core/main.m +++ b/src/core/main.m @@ -17,9 +17,7 @@ OF_APPLICATION_DELEGATE(AppDelegate) @implementation AppDelegate - (void)applicationDidFinishLaunching { - ui = [[JubGtkUI alloc] init]; - id rosterDelegate = - [ui rosterDelegate]; + id rosterDelegate; connection = [[XMPPConnection alloc] init]; [connection addDelegate: self]; @@ -28,7 +26,8 @@ OF_APPLICATION_DELEGATE(AppDelegate) connection.username = @"alice"; connection.password = @"test"; - [connection asyncConnectAndHandle]; + ui = [[JubGtkUI alloc] initWithConnection: connection]; + rosterDelegate = [ui rosterDelegate]; [connection addDelegate: rosterDelegate]; @@ -36,6 +35,8 @@ OF_APPLICATION_DELEGATE(AppDelegate) [roster addDelegate: rosterDelegate]; [roster addDelegate: self]; + [connection asyncConnectAndHandle]; + [ui startUIThread]; } diff --git a/src/gui/gtk/JubGtkRosterUI.h b/src/gui/gtk/JubGtkRosterUI.h index 9bb0878..1fd0394 100644 --- a/src/gui/gtk/JubGtkRosterUI.h +++ b/src/gui/gtk/JubGtkRosterUI.h @@ -2,6 +2,8 @@ #import #include +@class JubGtkChatUI; + @interface JubGtkRosterUI: OFObject { GtkTreeStore *roster_model; @@ -10,7 +12,11 @@ OFMutableDictionary *contactMap; OFMutableDictionary *chatMap; OFCountedSet *presences; + XMPPConnection *connection; GtkBuilder *builder; } -- initWithBuilder: (GtkBuilder*)builder; + +- initWithBuilder: (GtkBuilder*)builder + connection: (XMPPConnection*)connection; +- (JubGtkChatUI*)chatForJID: (XMPPJID*)jid; @end diff --git a/src/gui/gtk/JubGtkRosterUI.m b/src/gui/gtk/JubGtkRosterUI.m index 6fb8af0..7c81f95 100644 --- a/src/gui/gtk/JubGtkRosterUI.m +++ b/src/gui/gtk/JubGtkRosterUI.m @@ -3,6 +3,34 @@ #import "JubGtkChatUI.h" #import "JubGtkHelper.h" +static gboolean roster_row_activated(GtkTreeView *tree_view, GtkTreePath *path, + GtkTreeViewColumn *column, gpointer data) +{ + JubGtkRosterUI *roster = data; + GtkTreeIter row_iter; + GtkTreeModel *tree_model; + gchar *jid_s; + XMPPJID *jid; + OFAutoreleasePool *pool; + + tree_model = gtk_tree_view_get_model(tree_view); + gtk_tree_model_get_iter(tree_model, &row_iter, path); + gtk_tree_model_get(tree_model, &row_iter, 1, &jid_s, -1); + + // This was a group row + if (!jid_s) return TRUE; + + pool = [OFAutoreleasePool new]; + jid = [XMPPJID JIDWithString: [OFString stringWithUTF8String: jid_s]]; + + [roster performSelectorOnMainThread: @selector(chatForJID:) + withObject: jid + waitUntilDone: NO]; + [pool release]; + + return TRUE; +} + static gboolean filter_roster_by_presence(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { @@ -32,16 +60,20 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, @implementation JubGtkRosterUI - initWithBuilder: (GtkBuilder*)builder_ + connection: (XMPPConnection*)connection_ { self = [super init]; @try { + GtkTreeView *roster_view; + groupMap = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions valueFunctions: rowRefFunctions]; contactMap = [[OFMutableDictionary alloc] init]; chatMap = [[OFMutableDictionary alloc] init]; presences = [[OFCountedSet alloc] init]; + connection = [connection_ retain]; builder = g_object_ref(builder_); @@ -53,6 +85,12 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, gtk_tree_model_filter_set_visible_func(roster_filter, filter_roster_by_presence, presences, NULL); + + roster_view = GTK_TREE_VIEW(gtk_builder_get_object(builder, + "RosterTreeView")); + + g_signal_connect(roster_view, "row_activated", + G_CALLBACK(roster_row_activated), self); } @catch (id e) { [self release]; @throw e; @@ -66,6 +104,7 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, [groupMap release]; [contactMap release]; [presences release]; + [connection release]; if (roster_model) g_object_unref(roster_model); @@ -93,34 +132,42 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, } // FIXME: This needs to move somewhere else -- (void)connection: (XMPPConnection*)connection - didReceiveMessage: (XMPPMessage*)message +- (JubGtkChatUI*)chatForJID: (XMPPJID*)jid { + OFAutoreleasePool *pool = [OFAutoreleasePool new]; JubGtkChatUI *chat = - [chatMap objectForKey: [message.from bareJID]]; + [chatMap objectForKey: [jid bareJID]]; if (chat == nil) { OFString * title = [@"Chat with " stringByAppendingString: - [message.from bareJID]]; + [jid bareJID]]; chat = [[[JubGtkChatUI alloc] initWithTitle: title closeBlock: ^{ - [chatMap removeObjectForKey: - [message.from bareJID]]; + [chatMap removeObjectForKey: [jid bareJID]]; } sendBlock: ^(OFString *text) { XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"]; - msg.to = message.from; + msg.to = jid; msg.body = text; [connection sendStanza: msg]; } ] autorelease]; [chatMap setObject: chat - forKey: [message.from bareJID]]; + forKey: [jid bareJID]]; } + [pool release]; + + return chat; +} + +- (void)connection: (XMPPConnection*)connection + didReceiveMessage: (XMPPMessage*)message +{ + JubGtkChatUI *chat = [self chatForJID: message.from]; [chat addMessage: message.body sender: [message.from bareJID]]; } diff --git a/src/gui/gtk/JubGtkUI.h b/src/gui/gtk/JubGtkUI.h index a739e1a..add8d76 100644 --- a/src/gui/gtk/JubGtkUI.h +++ b/src/gui/gtk/JubGtkUI.h @@ -4,10 +4,13 @@ #import "JubUI.h" @class JubGtkRosterUI; +@class XMPPConnection; @interface JubGtkUI: OFObject { JubGtkRosterUI *rosterUI; GtkBuilder *builder; } + +- initWithConnection: (XMPPConnection*)connection; @end diff --git a/src/gui/gtk/JubGtkUI.m b/src/gui/gtk/JubGtkUI.m index 000b483..26c2cbb 100644 --- a/src/gui/gtk/JubGtkUI.m +++ b/src/gui/gtk/JubGtkUI.m @@ -10,7 +10,7 @@ void on_roster_window_destroy(GObject *object, gpointer user_data) } @implementation JubGtkUI -- init +- initWithConnection: (XMPPConnection*)connection { self = [super init]; @@ -26,7 +26,8 @@ void on_roster_window_destroy(GObject *object, gpointer user_data) builder = gtk_builder_new(); gtk_builder_add_from_file(builder, "data/gtk/roster.ui", NULL); - rosterUI = [[JubGtkRosterUI alloc] initWithBuilder: builder]; + rosterUI = [[JubGtkRosterUI alloc] initWithBuilder: builder + connection: connection]; } @catch (id e) { [self release]; @throw e; -- 2.39.2