X-Git-Url: http://cgit.babelmonkeys.de/?p=jubjub.git;a=blobdiff_plain;f=src%2Fgui%2Fgtk%2FJubGtkRosterUI.m;h=b3899e34a1d750edf1e57d0d6961d4a8f4baf326;hp=6fb8af0e86b62feb5ad72cea68c19693c73b4d36;hb=77e1d677232eeab371a8ac2da1e542bc62bbaea6;hpb=62773a7c965b220c3f83acfe2e915f08ddb3f474 diff --git a/src/gui/gtk/JubGtkRosterUI.m b/src/gui/gtk/JubGtkRosterUI.m index 6fb8af0..b3899e3 100644 --- a/src/gui/gtk/JubGtkRosterUI.m +++ b/src/gui/gtk/JubGtkRosterUI.m @@ -3,6 +3,55 @@ #import "JubGtkChatUI.h" #import "JubGtkHelper.h" +#include + +static void 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; + + pool = [OFAutoreleasePool new]; + jid = [XMPPJID JIDWithString: [OFString stringWithUTF8String: jid_s]]; + + [roster performSelectorOnMainThread: @selector(chatForJID:) + withObject: jid + waitUntilDone: NO]; + [pool release]; +} + +static void presence_changed(GtkComboBox *combo_box, gpointer data) +{ + XMPPPresence *pres; + XMPPConnection *connection = data; + OFAutoreleasePool *pool = [OFAutoreleasePool new]; + + const char *status = gtk_combo_box_get_active_id(combo_box); + + if (!strcmp(status, "unavailable")) + pres = [XMPPPresence presenceWithType: @"unavailable"]; + else { + pres = [XMPPPresence presence]; + if (strcmp(status, "available")) + [pres addShow: @(status)]; + } + + [connection sendStanza: pres]; + + [pool release]; +} + static gboolean filter_roster_by_presence(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { @@ -31,19 +80,31 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, } @implementation JubGtkRosterUI -- initWithBuilder: (GtkBuilder*)builder_ +- initWithConnection: (XMPPConnection*)connection_ { self = [super init]; @try { + GtkTreeView *roster_view; + GtkComboBox *presence_combo; + GtkBuilder *builder; + 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_); + builder = gtk_builder_new(); + gtk_builder_add_from_file(builder, "data/gtk/roster.ui", NULL); + gtk_builder_connect_signals(builder, NULL); + + roster_window = + GTK_WIDGET(gtk_builder_get_object(builder, "RosterWindow")); + + gtk_widget_show(roster_window); roster_model = GTK_TREE_STORE(gtk_builder_get_object(builder, "RosterTreeStore")); @@ -53,6 +114,20 @@ 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); + + presence_combo = GTK_COMBO_BOX(gtk_builder_get_object(builder, + "PresenceComboBox")); + + g_signal_connect(presence_combo, "changed", + G_CALLBACK(presence_changed), connection); + + g_object_unref(G_OBJECT(builder)); } @catch (id e) { [self release]; @throw e; @@ -65,15 +140,11 @@ static gboolean filter_roster_by_presence(GtkTreeModel *model, { [groupMap release]; [contactMap release]; + [chatMap release]; [presences release]; + [connection release]; - if (roster_model) - g_object_unref(roster_model); - - if (roster_filter) - g_object_unref(roster_filter); - - g_object_unref(builder); + gtk_widget_destroy(roster_window); [super dealloc]; } @@ -93,34 +164,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]]; }