Mercurial > pidgin.yaz
comparison pidgin/gtkblist.c @ 21410:4ccc4ad0a8b0
Use PidginMiniDialog to display signed in elsewhere errors in the blist.
author | Will Thompson <will.thompson@collabora.co.uk> |
---|---|
date | Mon, 05 Nov 2007 01:19:51 +0000 |
parents | c1c7e28223f8 |
children | b089fd1ad059 |
comparison
equal
deleted
inserted
replaced
21409:62a116ddc6e5 | 21410:4ccc4ad0a8b0 |
---|---|
56 #include "gtkprivacy.h" | 56 #include "gtkprivacy.h" |
57 #include "gtkroomlist.h" | 57 #include "gtkroomlist.h" |
58 #include "gtkstatusbox.h" | 58 #include "gtkstatusbox.h" |
59 #include "gtkscrollbook.h" | 59 #include "gtkscrollbook.h" |
60 #include "gtkutils.h" | 60 #include "gtkutils.h" |
61 #include "pidgin/minidialog.h" | |
61 | 62 |
62 #include <gdk/gdkkeysyms.h> | 63 #include <gdk/gdkkeysyms.h> |
63 #include <gtk/gtk.h> | 64 #include <gtk/gtk.h> |
64 #include <gdk/gdk.h> | 65 #include <gdk/gdk.h> |
65 | 66 |
112 /** PidginScrollBook used to hold error minidialogs. Gets packed | 113 /** PidginScrollBook used to hold error minidialogs. Gets packed |
113 * inside PidginBuddyList.error_buttons | 114 * inside PidginBuddyList.error_buttons |
114 */ | 115 */ |
115 GtkWidget *error_scrollbook; | 116 GtkWidget *error_scrollbook; |
116 | 117 |
117 /** List of #PurpleAccount that were disconnected with | |
118 * #PURPLE_CONNECTION_ERROR_NAME_IN_USE that have not been dealt with | |
119 * by the user. | |
120 */ | |
121 GList *accounts_signed_on_elsewhere; | |
122 /** Pointer to the mini-dialog about having signed on elsewhere, if one | 118 /** Pointer to the mini-dialog about having signed on elsewhere, if one |
123 * is showing; @c NULL otherwise. | 119 * is showing; @c NULL otherwise. |
124 */ | 120 */ |
125 GtkWidget *signed_on_elsewhere_minidialog; | 121 PidginMiniDialog *signed_on_elsewhere; |
126 GtkLabel *signed_on_elsewhere_minidialog_title; | |
127 GtkVBox *signed_on_elsewhere_minidialog_accounts; | |
128 } PidginBuddyListPrivate; | 122 } PidginBuddyListPrivate; |
129 | 123 |
130 #define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \ | 124 #define PIDGIN_BUDDY_LIST_GET_PRIVATE(list) \ |
131 ((PidginBuddyListPrivate *)((list)->priv)) | 125 ((PidginBuddyListPrivate *)((list)->priv)) |
132 | 126 |
4365 | 4359 |
4366 if (!GTK_WIDGET_HAS_FOCUS(gtkblist->window)) | 4360 if (!GTK_WIDGET_HAS_FOCUS(gtkblist->window)) |
4367 pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE); | 4361 pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE); |
4368 } | 4362 } |
4369 | 4363 |
4364 static GtkWidget * | |
4365 find_child_widget_by_account(GtkContainer *container, | |
4366 PurpleAccount *account) | |
4367 { | |
4368 GList *l = NULL; | |
4369 GList *children = gtk_container_get_children(container); | |
4370 GtkWidget *ret = NULL; | |
4371 l = g_list_find_custom(children, account, (GCompareFunc) find_account_widget); | |
4372 if (l) | |
4373 ret = GTK_WIDGET(l->data); | |
4374 g_list_free(children); | |
4375 return ret; | |
4376 } | |
4377 | |
4370 static void | 4378 static void |
4371 remove_child_widget_by_account(GtkContainer *container, | 4379 remove_child_widget_by_account(GtkContainer *container, |
4372 PurpleAccount *account) | 4380 PurpleAccount *account) |
4373 { | 4381 { |
4374 GList *l = NULL; | 4382 GtkWidget *widget = find_child_widget_by_account(container, account); |
4375 GList *children = gtk_container_get_children(container); | 4383 if(widget) |
4376 l = g_list_find_custom(children, account, (GCompareFunc) find_account_widget); | 4384 gtk_widget_destroy(widget); |
4377 if (l) { /* it may have already been removed by being acted on */ | |
4378 gtk_widget_destroy(GTK_WIDGET(l->data)); | |
4379 } | |
4380 g_list_free(children); | |
4381 } | 4385 } |
4382 | 4386 |
4383 /* Generic error buttons */ | 4387 /* Generic error buttons */ |
4384 | 4388 |
4385 static void | 4389 static void |
4451 | 4455 |
4452 /* Notifications about accounts which were disconnected with | 4456 /* Notifications about accounts which were disconnected with |
4453 * PURPLE_CONNECTION_ERROR_NAME_IN_USE | 4457 * PURPLE_CONNECTION_ERROR_NAME_IN_USE |
4454 */ | 4458 */ |
4455 | 4459 |
4460 typedef void (*AccountFunction)(PurpleAccount *); | |
4461 | |
4456 static void | 4462 static void |
4457 destroy_signed_on_elsewhere_minidialog(PidginBuddyListPrivate *priv) | 4463 elsewhere_foreach_account(PidginMiniDialog *mini_dialog, |
4458 { | 4464 AccountFunction f) |
4459 if(priv->signed_on_elsewhere_minidialog == NULL) | 4465 { |
4466 PurpleAccount *account; | |
4467 GList *labels = gtk_container_get_children( | |
4468 GTK_CONTAINER(mini_dialog->contents)); | |
4469 GList *l; | |
4470 | |
4471 for (l = labels; l; l = l->next) { | |
4472 account = g_object_get_data(G_OBJECT(l->data), OBJECT_DATA_KEY_ACCOUNT); | |
4473 if (account) | |
4474 f(account); | |
4475 else | |
4476 purple_debug_warning("gtkblist", "mini_dialog's child " | |
4477 "didn't have an account stored in it!"); | |
4478 } | |
4479 g_list_free(labels); | |
4480 } | |
4481 | |
4482 static void | |
4483 enable_account(PurpleAccount *account) | |
4484 { | |
4485 purple_account_set_enabled(account, purple_core_get_ui(), TRUE); | |
4486 } | |
4487 | |
4488 static void | |
4489 reconnect_elsewhere_accounts(PidginMiniDialog *mini_dialog, | |
4490 GtkButton *button, | |
4491 gpointer unused) | |
4492 { | |
4493 elsewhere_foreach_account(mini_dialog, enable_account); | |
4494 } | |
4495 | |
4496 static void | |
4497 ignore_elsewhere_accounts(PidginMiniDialog *mini_dialog, | |
4498 GtkButton *button, | |
4499 gpointer unused) | |
4500 { | |
4501 elsewhere_foreach_account(mini_dialog, purple_account_clear_current_error); | |
4502 } | |
4503 | |
4504 static void | |
4505 ensure_signed_on_elsewhere_minidialog(PidginBuddyList *gtkblist) | |
4506 { | |
4507 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | |
4508 PidginMiniDialog *mini_dialog; | |
4509 | |
4510 if(priv->signed_on_elsewhere) | |
4460 return; | 4511 return; |
4461 | 4512 |
4462 gtk_widget_destroy(priv->signed_on_elsewhere_minidialog); | 4513 mini_dialog = priv->signed_on_elsewhere = |
4463 priv->signed_on_elsewhere_minidialog = NULL; | 4514 pidgin_mini_dialog_new(NULL, NULL, PIDGIN_STOCK_DISCONNECT); |
4464 priv->signed_on_elsewhere_minidialog_accounts = NULL; | 4515 |
4465 priv->signed_on_elsewhere_minidialog_title = NULL; | 4516 pidgin_mini_dialog_add_button(mini_dialog, _("Re-enable"), |
4466 } | 4517 reconnect_elsewhere_accounts, NULL); |
4467 | 4518 |
4468 static void | 4519 pidgin_mini_dialog_add_button(mini_dialog, _("Ignore"), |
4469 reconnect_elsewhere_accounts(PidginBuddyList *gtkblist) | 4520 ignore_elsewhere_accounts, NULL); |
4470 { | 4521 |
4471 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | 4522 add_error_dialog(gtkblist, GTK_WIDGET(mini_dialog)); |
4472 GList *l; | 4523 |
4473 PurpleAccount *account; | 4524 /* Set priv->signed_on_elsewhere to NULL when it is destroyed */ |
4474 for (l = priv->accounts_signed_on_elsewhere; l; l = l->next) { | 4525 g_signal_connect(G_OBJECT(mini_dialog), "destroy", |
4475 account = l->data; | 4526 (GCallback) gtk_widget_destroyed, &(priv->signed_on_elsewhere)); |
4476 purple_account_set_enabled(account, purple_core_get_ui(), TRUE); | |
4477 } | |
4478 g_list_free(priv->accounts_signed_on_elsewhere); | |
4479 priv->accounts_signed_on_elsewhere = NULL; | |
4480 | |
4481 destroy_signed_on_elsewhere_minidialog(priv); | |
4482 } | |
4483 | |
4484 static void | |
4485 ignore_elsewhere_accounts(PidginBuddyList *gtkblist) | |
4486 { | |
4487 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | |
4488 GList *accounts_elsewhere, *l; | |
4489 | |
4490 /* priv->accounts_signed_on_elsewhere gets changed in | |
4491 * update_account_error_state, which is called when | |
4492 * purple_account_clear_current_error emits account-error-changed. So | |
4493 * let's take a copy. | |
4494 * | |
4495 * (Or maybe we could just use while(priv->accounts_elsewhere) and rely | |
4496 * on it being ultimately reduced to NULL? But that sounds fragile.) | |
4497 */ | |
4498 accounts_elsewhere = g_list_copy(priv->accounts_signed_on_elsewhere); | |
4499 | |
4500 for (l = accounts_elsewhere; l != NULL; l = l->next) | |
4501 { | |
4502 PurpleAccount *account = l->data; | |
4503 purple_account_clear_current_error(account); | |
4504 } | |
4505 | |
4506 g_list_free(accounts_elsewhere); | |
4507 | |
4508 destroy_signed_on_elsewhere_minidialog(priv); | |
4509 } | |
4510 | |
4511 static GtkWidget * | |
4512 make_elsewhere_minidialog_button(const char *text, | |
4513 GCallback callback) | |
4514 { | |
4515 GtkWidget *button = gtk_button_new(); | |
4516 GtkWidget *hbox = gtk_hbox_new(FALSE, 0); | |
4517 GtkWidget *label = gtk_label_new(NULL); | |
4518 char *button_text = | |
4519 g_strdup_printf("<span size=\"smaller\">%s</span>", text); | |
4520 | |
4521 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0); | |
4522 | |
4523 g_signal_connect_swapped(G_OBJECT(button), "clicked", callback, | |
4524 gtkblist); | |
4525 gtk_container_add(GTK_CONTAINER(button), hbox); | |
4526 | |
4527 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), button_text); | |
4528 g_free(button_text); | |
4529 | |
4530 gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); | |
4531 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); | |
4532 | |
4533 return button; | |
4534 } | |
4535 | |
4536 static void | |
4537 create_signed_on_elsewhere_minidialog(PidginBuddyList *gtkblist) | |
4538 { | |
4539 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | |
4540 GtkWidget *dialog, *vbox, *hbox, *label, *img, *button; | |
4541 | |
4542 if(priv->signed_on_elsewhere_minidialog) | |
4543 return; | |
4544 | |
4545 dialog = gtk_vbox_new(FALSE, 0); | |
4546 gtk_container_set_border_width(GTK_CONTAINER(dialog), PIDGIN_HIG_BOX_SPACE); | |
4547 priv->signed_on_elsewhere_minidialog = dialog; | |
4548 | |
4549 /* HBox to hold error icon and title */ | |
4550 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | |
4551 | |
4552 img = gtk_image_new_from_stock(PIDGIN_STOCK_DISCONNECT, | |
4553 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); | |
4554 gtk_misc_set_alignment(GTK_MISC(img), 0, 0); | |
4555 if (img) | |
4556 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); | |
4557 | |
4558 label = gtk_label_new(NULL); | |
4559 priv->signed_on_elsewhere_minidialog_title = GTK_LABEL(label); | |
4560 gtk_widget_set_size_request(label, | |
4561 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/width")-25, -1); | |
4562 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
4563 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
4564 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); | |
4565 gtk_box_pack_start(GTK_BOX(dialog), hbox, FALSE, FALSE, 0); | |
4566 | |
4567 /* VBox to hold "[prplicon] account@server.com" widgets */ | |
4568 vbox = gtk_vbox_new(FALSE, 0); | |
4569 priv->signed_on_elsewhere_minidialog_accounts = GTK_VBOX(vbox); | |
4570 gtk_box_pack_start(GTK_BOX(dialog), vbox, FALSE, FALSE, 0); | |
4571 | |
4572 /* HBox to hold buttons */ | |
4573 hbox = gtk_hbox_new(FALSE, 0); | |
4574 | |
4575 button = make_elsewhere_minidialog_button(_("Re-enable"), | |
4576 (GCallback) reconnect_elsewhere_accounts); | |
4577 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
4578 | |
4579 button = make_elsewhere_minidialog_button(_("Ignore"), | |
4580 (GCallback) ignore_elsewhere_accounts); | |
4581 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
4582 | |
4583 gtk_box_pack_start(GTK_BOX(dialog), hbox, FALSE, FALSE, 0); | |
4584 add_error_dialog(gtkblist, dialog); | |
4585 } | 4527 } |
4586 | 4528 |
4587 static void | 4529 static void |
4588 update_signed_on_elsewhere_minidialog_title(void) | 4530 update_signed_on_elsewhere_minidialog_title(void) |
4589 { | 4531 { |
4590 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | 4532 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); |
4591 guint length; | 4533 PidginMiniDialog *mini_dialog = priv->signed_on_elsewhere; |
4592 char *title, *title_markup; | 4534 guint accounts; |
4593 | 4535 char *title; |
4594 length = g_list_length(priv->accounts_signed_on_elsewhere); | 4536 |
4595 if (length == 0) | 4537 if (mini_dialog == NULL) |
4596 { | |
4597 destroy_signed_on_elsewhere_minidialog(priv); | |
4598 return; | 4538 return; |
4599 } | 4539 |
4600 | 4540 accounts = pidgin_mini_dialog_get_num_children(mini_dialog); |
4601 create_signed_on_elsewhere_minidialog(gtkblist); | |
4602 | 4541 |
4603 title = g_strdup_printf( | 4542 title = g_strdup_printf( |
4604 ngettext("%d account was disabled because you signed on from another location.", | 4543 ngettext("%d account was disabled because you signed on from another location.", |
4605 "%d accounts were disabled because you signed on from another location.", | 4544 "%d accounts were disabled because you signed on from another location.", |
4606 length), | 4545 accounts), |
4607 length); | 4546 accounts); |
4608 title_markup = g_strdup_printf("<span weight=\"bold\" size=\"smaller\">%s</span>", title); | 4547 pidgin_mini_dialog_set_title(mini_dialog, title); |
4609 | |
4610 gtk_label_set_markup(priv->signed_on_elsewhere_minidialog_title, title_markup); | |
4611 | |
4612 g_free(title_markup); | |
4613 g_free(title); | 4548 g_free(title); |
4614 | |
4615 gtk_widget_show_all(priv->signed_on_elsewhere_minidialog); | |
4616 } | 4549 } |
4617 | 4550 |
4618 static GtkWidget * | 4551 static GtkWidget * |
4619 create_account_label(PurpleAccount *account) | 4552 create_account_label(PurpleAccount *account) |
4620 { | 4553 { |
4650 | 4583 |
4651 static void | 4584 static void |
4652 add_to_signed_on_elsewhere(PurpleAccount *account) | 4585 add_to_signed_on_elsewhere(PurpleAccount *account) |
4653 { | 4586 { |
4654 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | 4587 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); |
4588 PidginMiniDialog *mini_dialog; | |
4655 GtkWidget *account_label; | 4589 GtkWidget *account_label; |
4656 if(g_list_find(priv->accounts_signed_on_elsewhere, account) != NULL) | 4590 |
4591 ensure_signed_on_elsewhere_minidialog(gtkblist); | |
4592 mini_dialog = priv->signed_on_elsewhere; | |
4593 | |
4594 if(find_child_widget_by_account(GTK_CONTAINER(mini_dialog->contents), account)) | |
4657 return; | 4595 return; |
4658 | 4596 |
4659 priv->accounts_signed_on_elsewhere = | 4597 account_label = create_account_label(account); |
4660 g_list_prepend(priv->accounts_signed_on_elsewhere, account); | 4598 gtk_box_pack_start(mini_dialog->contents, account_label, FALSE, FALSE, 0); |
4599 gtk_widget_show_all(account_label); | |
4661 | 4600 |
4662 update_signed_on_elsewhere_minidialog_title(); | 4601 update_signed_on_elsewhere_minidialog_title(); |
4663 | |
4664 account_label = create_account_label(account); | |
4665 gtk_box_pack_start(GTK_BOX(priv->signed_on_elsewhere_minidialog_accounts), | |
4666 account_label, FALSE, FALSE, 0); | |
4667 gtk_widget_show_all(account_label); | |
4668 | 4602 |
4669 if (!GTK_WIDGET_HAS_FOCUS(gtkblist->window)) | 4603 if (!GTK_WIDGET_HAS_FOCUS(gtkblist->window)) |
4670 pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE); | 4604 pidgin_set_urgent(GTK_WINDOW(gtkblist->window), TRUE); |
4671 } | 4605 } |
4672 | 4606 |
4673 static void | 4607 static void |
4674 remove_from_signed_on_elsewhere(PurpleAccount *account) | 4608 remove_from_signed_on_elsewhere(PurpleAccount *account) |
4675 { | 4609 { |
4676 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); | 4610 PidginBuddyListPrivate *priv = PIDGIN_BUDDY_LIST_GET_PRIVATE(gtkblist); |
4677 if(g_list_find(priv->accounts_signed_on_elsewhere, account) == NULL) | 4611 PidginMiniDialog *mini_dialog = priv->signed_on_elsewhere; |
4612 if(mini_dialog == NULL) | |
4678 return; | 4613 return; |
4679 | 4614 |
4680 priv->accounts_signed_on_elsewhere = | 4615 remove_child_widget_by_account(GTK_CONTAINER(mini_dialog->contents), account); |
4681 g_list_remove(priv->accounts_signed_on_elsewhere, account); | |
4682 | |
4683 if(priv->signed_on_elsewhere_minidialog_accounts) | |
4684 remove_child_widget_by_account(GTK_CONTAINER( | |
4685 priv->signed_on_elsewhere_minidialog_accounts), | |
4686 account); | |
4687 | 4616 |
4688 update_signed_on_elsewhere_minidialog_title(); | 4617 update_signed_on_elsewhere_minidialog_title(); |
4689 } | 4618 } |
4690 | 4619 |
4691 | 4620 |