1 #import <ObjXMPP/ObjXMPP.h>
5 #import "JubGObjectMap.h"
7 void on_roster_window_destroy(GObject *object, gpointer user_data)
12 @implementation JubGtkUI
18 groupMap = [[OFMapTable alloc]
19 initWithKeyFunctions: keyFunctions
20 valueFunctions: rowRefFunctions];
21 contactMap = [[OFMutableDictionary alloc] init];
37 g_object_unref(roster_model);
48 GtkWidget *roster_window;
50 [[OFApplication sharedApplication] getArgumentCount: &argc
51 andArgumentValues: &argv];
55 builder = gtk_builder_new();
56 gtk_builder_add_from_file(builder, "data/gtk/roster.ui", NULL);
59 GTK_WIDGET(gtk_builder_get_object(builder, "RosterWindow"));
62 GTK_TREE_STORE(gtk_builder_get_object(builder, "RosterTreeStore"));
64 gtk_builder_connect_signals(builder, NULL);
65 g_object_unref(G_OBJECT(builder));
67 gtk_widget_show(roster_window);
69 [[OFThread threadWithBlock: ^(void){
71 [OFApplication terminate];
78 - (id<XMPPRosterDelegate>)rosterDelegate
83 /* Roster Delegate methods */
84 struct add_roster_item_param {
89 OFMapTable *contactRows;
90 GtkTreeStore *roster_model;
93 static gboolean add_roster_item(gpointer user_data)
95 struct add_roster_item_param *params = user_data;
96 GtkTreeIter group_iter, contact_iter;
97 GtkTreeRowReference *group_ref, *contact_ref;
98 GtkTreePath *group_path, *contact_path;
100 group_ref = [params->groupMap valueForKey: params->group];
103 // Create new group row
104 gtk_tree_store_append(params->roster_model, &group_iter, NULL);
105 gtk_tree_store_set(params->roster_model, &group_iter,
106 0, [params->group UTF8String], -1);
108 group_path = gtk_tree_model_get_path(GTK_TREE_MODEL(
109 params->roster_model), &group_iter);
111 group_ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(
112 params->roster_model), group_path);
114 [params->groupMap setValue: group_ref
115 forKey: params->group];
117 // Get iter for existing group row
118 group_path = gtk_tree_row_reference_get_path(group_ref);
120 gtk_tree_model_get_iter(GTK_TREE_MODEL(params->roster_model),
121 &group_iter, group_path);
123 gtk_tree_path_free(group_path);
125 // Create new contact row
126 gtk_tree_store_append(params->roster_model, &contact_iter, &group_iter);
127 gtk_tree_store_set(params->roster_model, &contact_iter,
128 0, [params->name UTF8String], 1, [params->jid UTF8String], -1);
130 contact_path = gtk_tree_model_get_path(GTK_TREE_MODEL(
131 params->roster_model), &contact_iter);
133 contact_ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(
134 params->roster_model), contact_path);
136 gtk_tree_path_free(contact_path);
138 [params->contactRows setValue: contact_ref
139 forKey: params->group];
141 [params->group release];
142 [params->name release];
143 [params->jid release];
144 [params->groupMap release];
145 [params->contactRows release];
146 g_object_unref(params->roster_model);
152 - (void)rosterWasReceived: (XMPPRoster*)roster_
154 [[roster_ rosterItems] enumerateKeysAndObjectsUsingBlock:
155 ^(OFString *bareJID, XMPPRosterItem *item, BOOL *stop) {
157 OFMapTable *contactRows = [OFMapTable
158 mapTableWithKeyFunctions: keyFunctions
159 valueFunctions: rowRefFunctions];
161 [contactMap setObject: contactRows
164 if (item.groups != nil)
165 groups = item.groups;
167 groups = @[@"General"];
169 for (OFString *group in groups) {
170 struct add_roster_item_param *params =
171 malloc(sizeof(*params));
172 params->group = [group retain];
173 params->name = [item.name retain];
174 params->jid = [bareJID retain];
175 params->groupMap = [groupMap retain];
176 params->contactRows = [contactRows retain];
177 params->roster_model = g_object_ref(roster_model);
178 g_idle_add(add_roster_item, params);
183 struct remove_roster_item_param {
185 OFMapTable *groupMap;
186 OFMapTable *contactRows;
187 GtkTreeStore *roster_model;
190 static gboolean remove_roster_item(gpointer user_data)
192 struct remove_roster_item_param *params = user_data;
193 GtkTreeIter contact_iter, group_iter;
194 GtkTreePath *contact_path, *group_path;
195 GtkTreeRowReference *contact_ref, *group_ref;
197 contact_ref = [params->contactRows valueForKey: params->group];
198 contact_path = gtk_tree_row_reference_get_path(contact_ref);
199 gtk_tree_model_get_iter(GTK_TREE_MODEL(params->roster_model),
200 &contact_iter, contact_path);
202 gtk_tree_store_remove(params->roster_model, &contact_iter);
204 group_ref = [params->groupMap valueForKey: params->group];
205 group_path = gtk_tree_row_reference_get_path(group_ref);
206 gtk_tree_model_get_iter(GTK_TREE_MODEL(params->roster_model),
207 &group_iter, group_path);
209 if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(params->roster_model),
211 gtk_tree_store_remove(params->roster_model, &group_iter);
212 [params->groupMap removeValueForKey: params->group];
215 gtk_tree_path_free(group_path);
217 [params->group release];
218 [params->groupMap release];
219 [params->contactRows release];
220 g_object_unref(params->roster_model);
226 - (void)roster: (XMPPRoster*)roster_
227 didReceiveRosterItem: (XMPPRosterItem*)item
230 XMPPRosterItem *oldItem =
231 [roster_.rosterItems objectForKey: [item.JID bareJID]];
234 if (oldItem.groups != nil)
235 groups = oldItem.groups;
237 groups = @[@"General"];
239 for (OFString *group in groups) {
240 struct remove_roster_item_param *params =
241 malloc(sizeof(*params));
242 params->group = [group retain];
243 params->contactRows = [[contactMap objectForKey:
244 [oldItem.JID bareJID]] retain];
245 params->groupMap = [groupMap retain];
246 params->roster_model = g_object_ref(roster_model);
247 g_idle_add(remove_roster_item, params);
250 [contactMap removeObjectForKey: [item.JID bareJID]];
253 if (![item.subscription isEqual: @"remove"]) {
254 OFMapTable *contactRows = [OFMapTable
255 mapTableWithKeyFunctions: keyFunctions
256 valueFunctions: rowRefFunctions];
258 [contactMap setObject: contactRows
259 forKey: [item.JID bareJID]];
261 if (item.groups != nil)
262 groups = item.groups;
264 groups = @[@"General"];
266 for (OFString *group in groups) {
267 struct add_roster_item_param *params =
268 malloc(sizeof(*params));
269 params->group = [group retain];
270 params->name = [item.name retain];
271 params->jid = [[item.JID bareJID] retain];
272 params->groupMap = [groupMap retain];
273 params->contactRows = [contactRows retain];
274 params->roster_model = g_object_ref(roster_model);
275 g_idle_add(add_roster_item, params);