Mercurial > pidgin.yaz
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); |