comparison pidgin/gtkdisco.c @ 26336:c619bef09bec

Make the prpl be in charge of creating the PurpleDiscoList; UI data is allocated via ops->create. When the prpl sets protocol data, it also passed in a close_cb which is called when destroying the struct to clean up the protocol data. This still works, but I've introduced some bugs with cancelling the disco or closing the GtkDisco dialog
author Paul Aurich <paul@darkrain42.org>
date Tue, 31 Mar 2009 05:18:09 +0000
parents 535c866b433c
children d6b2944f04b3
comparison
equal deleted inserted replaced
26335:290ea90869c0 26336:c619bef09bec
36 GtkWidget *window; 36 GtkWidget *window;
37 GtkWidget *account_widget; 37 GtkWidget *account_widget;
38 38
39 GtkWidget *sw; 39 GtkWidget *sw;
40 GtkWidget *progress; 40 GtkWidget *progress;
41 GtkTreeStore *model;
42 GtkWidget *tree;
43 GHashTable *cats; /** Meow. */
44 41
45 GtkWidget *stop_button; 42 GtkWidget *stop_button;
46 GtkWidget *list_button; 43 GtkWidget *list_button;
47 GtkWidget *register_button; 44 GtkWidget *register_button;
48 GtkWidget *add_button; 45 GtkWidget *add_button;
49 GtkWidget *close_button; 46 GtkWidget *close_button;
50 47
51 PurpleAccount *account; 48 PurpleAccount *account;
52 PurpleDiscoList *discolist; 49 PurpleDiscoList *discolist;
53 } PidginDiscoDialog; 50 } PidginDiscoDialog;
51
52 typedef struct _PidginDiscoList {
53 PidginDiscoDialog *dialog;
54 GtkTreeStore *model;
55 GtkWidget *tree;
56 GHashTable *cats; /** Meow. */
57 } PidginDiscoList;
54 58
55 struct _menu_cb_info { 59 struct _menu_cb_info {
56 PurpleDiscoList *list; 60 PurpleDiscoList *list;
57 PurpleDiscoService *service; 61 PurpleDiscoService *service;
58 }; 62 };
63 DESCRIPTION_COLUMN, 67 DESCRIPTION_COLUMN,
64 SERVICE_COLUMN, 68 SERVICE_COLUMN,
65 NUM_OF_COLUMNS 69 NUM_OF_COLUMNS
66 }; 70 };
67 71
72 static void pidgin_disco_create_tree(PidginDiscoList *pdl);
73
68 static void dialog_select_account_cb(GObject *w, PurpleAccount *account, 74 static void dialog_select_account_cb(GObject *w, PurpleAccount *account,
69 PidginDiscoDialog *dialog) 75 PidginDiscoDialog *dialog)
70 { 76 {
71 dialog->account = account; 77 dialog->account = account;
72 } 78 }
84 } 90 }
85 91
86 static void list_button_cb(GtkButton *button, PidginDiscoDialog *dialog) 92 static void list_button_cb(GtkButton *button, PidginDiscoDialog *dialog)
87 { 93 {
88 PurpleConnection *gc; 94 PurpleConnection *gc;
95 PidginDiscoList *pdl;
89 96
90 gc = purple_account_get_connection(dialog->account); 97 gc = purple_account_get_connection(dialog->account);
91 if (!gc) 98 if (!gc)
92 return; 99 return;
93 100
94 if (dialog->discolist != NULL) 101 if (dialog->discolist != NULL) {
102 pdl = purple_disco_list_get_ui_data(dialog->discolist);
103 gtk_widget_destroy(pdl->tree);
95 purple_disco_list_unref(dialog->discolist); 104 purple_disco_list_unref(dialog->discolist);
96 105 }
97 dialog->discolist = purple_disco_list_new(dialog->account, (void*) dialog); 106
98 107 dialog->discolist = purple_disco_get_list(gc);
99 purple_disco_get_list(dialog->discolist); 108 if (!dialog->discolist)
109 return;
110 /* We keep a copy... */
111 purple_disco_list_ref(dialog->discolist);
112
113 pdl = purple_disco_list_get_ui_data(dialog->discolist);
114 pdl->dialog = dialog;
115
116 pidgin_disco_create_tree(pdl);
117
118 if (dialog->account_widget)
119 gtk_widget_set_sensitive(dialog->account_widget, FALSE);
100 } 120 }
101 121
102 static void add_room_to_blist_cb(GtkButton *button, PidginDiscoDialog *dialog) 122 static void add_room_to_blist_cb(GtkButton *button, PidginDiscoDialog *dialog)
103 { 123 {
104 struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "disco-info"); 124 struct _menu_cb_info *info = g_object_get_data(G_OBJECT(button), "disco-info");
115 else 135 else
116 purple_blist_request_add_buddy(account, name, NULL, NULL); 136 purple_blist_request_add_buddy(account, name, NULL, NULL);
117 } 137 }
118 138
119 static void 139 static void
120 selection_changed_cb(GtkTreeSelection *selection, PidginDiscoDialog *dialog) 140 selection_changed_cb(GtkTreeSelection *selection, PidginDiscoList *pdl)
121 { 141 {
122 PurpleDiscoService *service; 142 PurpleDiscoService *service;
123 PurpleDiscoServiceFlags flags; 143 PurpleDiscoServiceFlags flags;
124 GtkTreeIter iter; 144 GtkTreeIter iter;
125 GValue val; 145 GValue val;
126 static struct _menu_cb_info *info; 146 static struct _menu_cb_info *info;
147 PidginDiscoDialog *dialog = pdl->dialog;
127 148
128 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) { 149 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
129 val.g_type = 0; 150 val.g_type = 0;
130 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog-> model), &iter, SERVICE_COLUMN, &val); 151 gtk_tree_model_get_value(GTK_TREE_MODEL(pdl->model), &iter, SERVICE_COLUMN, &val);
131 service = g_value_get_pointer(&val); 152 service = g_value_get_pointer(&val);
132 if (!service) { 153 if (!service) {
133 gtk_widget_set_sensitive(dialog->add_button, FALSE); 154 gtk_widget_set_sensitive(dialog->add_button, FALSE);
134 gtk_widget_set_sensitive(dialog->register_button, FALSE); 155 gtk_widget_set_sensitive(dialog->register_button, FALSE);
135 return; 156 return;
155 static gint 176 static gint
156 delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d) 177 delete_win_cb(GtkWidget *w, GdkEventAny *e, gpointer d)
157 { 178 {
158 PidginDiscoDialog *dialog = d; 179 PidginDiscoDialog *dialog = d;
159 180
160 if (dialog->discolist) 181 if (dialog->discolist && purple_disco_list_get_in_progress(dialog->discolist))
182 purple_disco_cancel_get_list(dialog->discolist);
183
184 if (dialog->discolist) {
185 PidginDiscoList *pdl = purple_disco_list_get_ui_data(dialog->discolist);
186
187 if (pdl)
188 pdl->dialog = NULL;
161 purple_disco_list_unref(dialog->discolist); 189 purple_disco_list_unref(dialog->discolist);
190 }
162 191
163 g_free(dialog); 192 g_free(dialog);
164 193
165 return FALSE; 194 return FALSE;
166 } 195 }
210 } 239 }
211 240
212 return FALSE; 241 return FALSE;
213 } 242 }
214 243
215 static void pidgin_disco_create_tree(PidginDiscoDialog *dialog) 244 static void pidgin_disco_create_tree(PidginDiscoList *pdl)
216 { 245 {
217 GtkCellRenderer *text_renderer, *pixbuf_renderer; 246 GtkCellRenderer *text_renderer, *pixbuf_renderer;
218 GtkTreeViewColumn *column; 247 GtkTreeViewColumn *column;
219 GtkTreeSelection *selection; 248 GtkTreeSelection *selection;
220 249
221 dialog->model = gtk_tree_store_new(NUM_OF_COLUMNS, 250 pdl->model = gtk_tree_store_new(NUM_OF_COLUMNS,
222 GDK_TYPE_PIXBUF, /* PIXBUF_COLUMN */ 251 GDK_TYPE_PIXBUF, /* PIXBUF_COLUMN */
223 G_TYPE_STRING, /* NAME_COLUMN */ 252 G_TYPE_STRING, /* NAME_COLUMN */
224 G_TYPE_STRING, /* DESCRIPTION_COLUMN */ 253 G_TYPE_STRING, /* DESCRIPTION_COLUMN */
225 G_TYPE_POINTER /* SERVICE_COLUMN */ 254 G_TYPE_POINTER /* SERVICE_COLUMN */
226 ); 255 );
227 256
228 dialog->tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); 257 pdl->tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(pdl->model));
229 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->tree), TRUE); 258 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(pdl->tree), TRUE);
230 259
231 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->tree)); 260 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pdl->tree));
232 g_signal_connect(G_OBJECT(selection), "changed", 261 g_signal_connect(G_OBJECT(selection), "changed",
233 G_CALLBACK(selection_changed_cb), dialog); 262 G_CALLBACK(selection_changed_cb), pdl);
234 263
235 g_object_unref(dialog->model); 264 g_object_unref(pdl->model);
236 265
237 gtk_container_add(GTK_CONTAINER(dialog->sw), dialog->tree); 266 gtk_container_add(GTK_CONTAINER(pdl->dialog->sw), pdl->tree);
238 gtk_widget_show(dialog->tree); 267 gtk_widget_show(pdl->tree);
239 268
240 text_renderer = gtk_cell_renderer_text_new(); 269 text_renderer = gtk_cell_renderer_text_new();
241 pixbuf_renderer = gtk_cell_renderer_pixbuf_new(); 270 pixbuf_renderer = gtk_cell_renderer_pixbuf_new();
242 271
243 column = gtk_tree_view_column_new(); 272 column = gtk_tree_view_column_new();
254 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column), 283 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
255 GTK_TREE_VIEW_COLUMN_GROW_ONLY); 284 GTK_TREE_VIEW_COLUMN_GROW_ONLY);
256 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); 285 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
257 gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), NAME_COLUMN); 286 gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), NAME_COLUMN);
258 gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE); 287 gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
259 gtk_tree_view_append_column(GTK_TREE_VIEW(dialog->tree), column); 288 gtk_tree_view_append_column(GTK_TREE_VIEW(pdl->tree), column);
260 289
261 column = gtk_tree_view_column_new_with_attributes(_("Description"), text_renderer, 290 column = gtk_tree_view_column_new_with_attributes(_("Description"), text_renderer,
262 "text", DESCRIPTION_COLUMN, NULL); 291 "text", DESCRIPTION_COLUMN, NULL);
263 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column), 292 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
264 GTK_TREE_VIEW_COLUMN_GROW_ONLY); 293 GTK_TREE_VIEW_COLUMN_GROW_ONLY);
265 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE); 294 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), TRUE);
266 gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), DESCRIPTION_COLUMN); 295 gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column), DESCRIPTION_COLUMN);
267 gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE); 296 gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
268 gtk_tree_view_append_column(GTK_TREE_VIEW(dialog->tree), column); 297 gtk_tree_view_append_column(GTK_TREE_VIEW(pdl->tree), column);
269 } 298 }
270 299
271 static PidginDiscoDialog* 300 static PidginDiscoDialog*
272 pidgin_disco_dialog_new_with_account(PurpleAccount *account) 301 pidgin_disco_dialog_new_with_account(PurpleAccount *account)
273 { 302 {
349 378
350 /* close button */ 379 /* close button */
351 dialog->close_button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_CLOSE, 380 dialog->close_button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_CLOSE,
352 G_CALLBACK(close_button_cb), dialog); 381 G_CALLBACK(close_button_cb), dialog);
353 382
354 pidgin_disco_create_tree(dialog);
355
356 /* show the dialog window and return the dialog */ 383 /* show the dialog window and return the dialog */
357 gtk_widget_show(dialog->window); 384 gtk_widget_show(dialog->window);
358 385
359 return dialog; 386 return dialog;
360 } 387 }
377 } 404 }
378 405
379 static void 406 static void
380 pidgin_disco_create(PurpleDiscoList *list) 407 pidgin_disco_create(PurpleDiscoList *list)
381 { 408 {
382 PidginDiscoDialog *dialog; 409 PidginDiscoList *pdl = g_new0(PidginDiscoList, 1);
383 410
384 dialog = purple_disco_list_get_ui_data(list); 411 purple_disco_list_set_ui_data(list, pdl);
385 412
386 dialog->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free); 413 pdl->cats = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)gtk_tree_row_reference_free);
387 } 414 }
388 415
389 416
390 static void 417 static void
391 pidgin_disco_destroy(PurpleDiscoList *list) 418 pidgin_disco_destroy(PurpleDiscoList *list)
392 { 419 {
420 PidginDiscoList *pdl;
421
422 pdl = purple_disco_list_get_ui_data(list);
423
424 g_hash_table_destroy(pdl->cats);
425 g_free(pdl);
426
427 purple_disco_list_set_ui_data(list, NULL);
428 }
429
430 static void pidgin_disco_in_progress(PurpleDiscoList *list, gboolean in_progress)
431 {
432 PidginDiscoList *pdl;
393 PidginDiscoDialog *dialog; 433 PidginDiscoDialog *dialog;
394 434
395 dialog = purple_disco_list_get_ui_data(list); 435 pdl = purple_disco_list_get_ui_data(list);
396 436 if (!pdl)
397 g_hash_table_destroy(dialog->cats); 437 return;
398 } 438
399 439 dialog = pdl->dialog;
400 static void pidgin_disco_in_progress(PurpleDiscoList *list, gboolean in_progress)
401 {
402 PidginDiscoDialog *dialog;
403
404 dialog = purple_disco_list_get_ui_data(list);
405
406 if (!dialog) 440 if (!dialog)
407 return; 441 return;
408 442
409 if (in_progress) { 443 if (in_progress) {
410 gtk_tree_store_clear(dialog->model); 444 gtk_tree_store_clear(pdl->model);
411 if (dialog->account_widget) 445 if (dialog->account_widget)
412 gtk_widget_set_sensitive(dialog->account_widget, FALSE); 446 gtk_widget_set_sensitive(dialog->account_widget, FALSE);
413 gtk_widget_set_sensitive(dialog->stop_button, TRUE); 447 gtk_widget_set_sensitive(dialog->stop_button, TRUE);
414 gtk_widget_set_sensitive(dialog->list_button, FALSE); 448 gtk_widget_set_sensitive(dialog->list_button, FALSE);
415 } else { 449 } else {
421 } 455 }
422 } 456 }
423 457
424 static void pidgin_disco_add_service(PurpleDiscoList *list, PurpleDiscoService *service, PurpleDiscoService *parent) 458 static void pidgin_disco_add_service(PurpleDiscoList *list, PurpleDiscoService *service, PurpleDiscoService *parent)
425 { 459 {
460 PidginDiscoList *pdl;
426 PidginDiscoDialog *dialog; 461 PidginDiscoDialog *dialog;
427 PurpleDiscoServiceCategory category; 462 PurpleDiscoServiceCategory category;
428 PurpleDiscoServiceType type; 463 PurpleDiscoServiceType type;
429 GtkTreeIter iter, parent_iter; 464 GtkTreeIter iter, parent_iter;
430 GtkTreeRowReference *rr; 465 GtkTreeRowReference *rr;
431 GtkTreePath *path; 466 GtkTreePath *path;
432 char *filename = NULL; 467 char *filename = NULL;
433 GdkPixbuf *pixbuf = NULL; 468 GdkPixbuf *pixbuf = NULL;
434 469
435 dialog = purple_disco_list_get_ui_data(list); 470 pdl = purple_disco_list_get_ui_data(list);
471 dialog = pdl->dialog;
436 472
437 purple_debug_info("disco", "Add_service \"%s\"\n", purple_disco_service_get_name(service)); 473 purple_debug_info("disco", "Add_service \"%s\"\n", purple_disco_service_get_name(service));
438 474
439 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(dialog->progress)); 475 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(dialog->progress));
440 476
441 if (parent) { 477 if (parent) {
442 rr = g_hash_table_lookup(dialog->cats, parent); 478 rr = g_hash_table_lookup(pdl->cats, parent);
443 path = gtk_tree_row_reference_get_path(rr); 479 path = gtk_tree_row_reference_get_path(rr);
444 if (path) { 480 if (path) {
445 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &parent_iter, path); 481 gtk_tree_model_get_iter(GTK_TREE_MODEL(pdl->model), &parent_iter, path);
446 gtk_tree_path_free(path); 482 gtk_tree_path_free(path);
447 } 483 }
448 } 484 }
449 485
450 gtk_tree_store_append(dialog->model, &iter, (parent ? &parent_iter : NULL)); 486 gtk_tree_store_append(pdl->model, &iter, (parent ? &parent_iter : NULL));
451 487
452 category = purple_disco_service_get_category(service); 488 category = purple_disco_service_get_category(service);
453 type = purple_disco_service_get_type(service); 489 type = purple_disco_service_get_type(service);
454 490
455 if (type == PURPLE_DISCO_SERVICE_TYPE_XMPP) 491 if (type == PURPLE_DISCO_SERVICE_TYPE_XMPP)
478 if (filename) { 514 if (filename) {
479 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); 515 pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
480 g_free(filename); 516 g_free(filename);
481 } 517 }
482 518
483 gtk_tree_store_set(dialog->model, &iter, 519 gtk_tree_store_set(pdl->model, &iter,
484 PIXBUF_COLUMN, pixbuf, 520 PIXBUF_COLUMN, pixbuf,
485 NAME_COLUMN, purple_disco_service_get_name(service), 521 NAME_COLUMN, purple_disco_service_get_name(service),
486 DESCRIPTION_COLUMN, purple_disco_service_get_description(service), 522 DESCRIPTION_COLUMN, purple_disco_service_get_description(service),
487 SERVICE_COLUMN, service, 523 SERVICE_COLUMN, service,
488 -1); 524 -1);
489 525
490 path = gtk_tree_model_get_path(GTK_TREE_MODEL(dialog->model), &iter); 526 path = gtk_tree_model_get_path(GTK_TREE_MODEL(pdl->model), &iter);
491 527
492 rr = gtk_tree_row_reference_new(GTK_TREE_MODEL(dialog->model), path); 528 rr = gtk_tree_row_reference_new(GTK_TREE_MODEL(pdl->model), path);
493 g_hash_table_insert(dialog->cats, service, rr); 529 g_hash_table_insert(pdl->cats, service, rr);
494 530
495 gtk_tree_path_free(path); 531 gtk_tree_path_free(path);
496 532
497 if (pixbuf) 533 if (pixbuf)
498 g_object_unref(pixbuf); 534 g_object_unref(pixbuf);