# HG changeset patch # User Sean Egan # Date 1164271027 0 # Node ID ca46f41aa433ae0178fe55839b8c3b5833f60934 # Parent ea6186360b68d753dc3549f12a057ded5e079b45 [gaim-migrate @ 17815] buddy-list alerts. I've made the two existing account ui_ops ('so-and-so has added you' and 'would you like to add so-and-so') use this. I'll follow up with a new 'so-and-so needs you to authorize him' ui_op, and replace the gaim_request_action() calls in the appropriate prpls committer: Tailor Script diff -r ea6186360b68 -r ca46f41aa433 gtk/Makefile.am --- a/gtk/Makefile.am Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/Makefile.am Thu Nov 23 08:37:07 2006 +0000 @@ -97,6 +97,7 @@ gtkrequest.c \ gtkroomlist.c \ gtksavedstatuses.c \ + gtkscrollbook.c \ gtksession.c \ gtksound.c \ gtksourceiter.c \ @@ -143,6 +144,7 @@ gtkrequest.h \ gtkroomlist.h \ gtksavedstatuses.h \ + gtkscrollbook.h \ gtksession.h \ gtksound.h \ gtksourceiter.h \ diff -r ea6186360b68 -r ca46f41aa433 gtk/Makefile.mingw --- a/gtk/Makefile.mingw Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/Makefile.mingw Thu Nov 23 08:37:07 2006 +0000 @@ -82,6 +82,7 @@ gtkrequest.c \ gtkroomlist.c \ gtksavedstatuses.c \ + gtkscrollbook.c \ gtksound.c \ gtksourceiter.c \ gtkstatusbox.c \ diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkaccount.c --- a/gtk/gtkaccount.c Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/gtkaccount.c Thu Nov 23 08:37:07 2006 +0000 @@ -2176,6 +2176,7 @@ GtkWidget *button; int width, height; + if (accounts_window != NULL) { gtk_window_present(GTK_WINDOW(accounts_window->window)); return; @@ -2315,7 +2316,7 @@ : (gaim_connection_get_display_name(gc) != NULL ? gaim_connection_get_display_name(gc) : gaim_account_get_username(account))), - (msg != NULL ? ": " : "."), + (msg != NULL ? ":\n" : "."), (msg != NULL ? msg : "")); } @@ -2326,12 +2327,14 @@ { char *buffer; GaimConnection *gc; + GtkWidget *alert; gc = gaim_account_get_connection(account); buffer = make_info(account, gc, remote_user, id, alias, msg); - - gaim_notify_info(NULL, NULL, buffer, NULL); + alert = gaim_gtk_make_mini_dialog(gc, GAIM_STOCK_DIALOG_INFO, buffer, + NULL, NULL, _("Close"), NULL, NULL); + gaim_gtk_blist_add_alert(alert); g_free(buffer); } @@ -2344,6 +2347,7 @@ char *buffer; GaimConnection *gc; GaimGtkAccountAddUserData *data; + GtkWidget *alert; gc = gaim_account_get_connection(account); @@ -2351,14 +2355,14 @@ data->account = account; data->username = g_strdup(remote_user); data->alias = g_strdup(alias); - + buffer = make_info(account, gc, remote_user, id, alias, msg); - - gaim_request_action(NULL, NULL, _("Add buddy to your list?"), - buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, - _("Add"), G_CALLBACK(add_user_cb), - _("Cancel"), G_CALLBACK(free_add_user_data)); - + alert = gaim_gtk_make_mini_dialog(gc, GAIM_STOCK_DIALOG_INFO, + _("Add buddy to your list?"), buffer, data, + _("Cancel"), G_CALLBACK(free_add_user_data), + _("Add"), G_CALLBACK(add_user_cb), NULL); + gaim_gtk_blist_add_alert(alert); + g_free(buffer); } diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkblist.c --- a/gtk/gtkblist.c Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/gtkblist.c Thu Nov 23 08:37:07 2006 +0000 @@ -54,6 +54,7 @@ #include "gtkprivacy.h" #include "gtkroomlist.h" #include "gtkstatusbox.h" +#include "gtkscrollbook.h" #include "gtkutils.h" #include @@ -4030,7 +4031,7 @@ gtkblist->vbox = gtk_vbox_new(FALSE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(gtkblist->notebook), gtkblist->vbox, NULL); gtk_widget_show_all(gtkblist->notebook); - if (accounts = gaim_accounts_get_all_active()) { + if ((accounts = gaim_accounts_get_all_active())) { g_list_free(accounts); gtk_notebook_set_current_page(GTK_NOTEBOOK(gtkblist->notebook), 1); } @@ -4178,6 +4179,9 @@ sep = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(gtkblist->vbox), sep, FALSE, FALSE, 0); + + gtkblist->scrollbook = gtk_gaim_scroll_book_new(); + gtk_box_pack_start(GTK_BOX(gtkblist->vbox), gtkblist->scrollbook, FALSE, FALSE, 0); /* Create an empty vbox used for showing connection errors */ gtkblist->error_buttons = gtk_vbox_new(FALSE, 0); @@ -4278,6 +4282,8 @@ gtkblist, GAIM_CALLBACK(conversation_deleting_cb), gtkblist); + gtk_widget_hide(gtkblist->scrollbook); + /* emit our created signal */ gaim_signal_emit(handle, "gtkblist-created", list); } @@ -5497,6 +5503,11 @@ gaim_debug_info("gtkblist", "removed visibility manager: %d\n", visibility_manager_count); } +void gaim_gtk_blist_add_alert(GtkWidget *widget) +{ + gtk_container_add(GTK_CONTAINER(gtkblist->scrollbook), widget); +} + static GaimBlistUiOps blist_ui_ops = { diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkblist.h --- a/gtk/gtkblist.h Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/gtkblist.h Thu Nov 23 08:37:07 2006 +0000 @@ -95,6 +95,9 @@ GList *tooltipdata; /**< The data for each "chunk" of the tooltip */ GaimBlistNode *selected_node; /**< The currently selected node */ + + GtkWidget *scrollbook; /**< Scrollbook for alerts */ + GtkWidget *error_buttons; /**< Box containing the connection error buttons */ GtkWidget *statusbox; /**< The status selector dropdown */ }; @@ -202,6 +205,13 @@ */ void gaim_gtk_blist_visibility_manager_remove(void); +/** + * Adds a mini-alert to the blist scrollbook + * + * @param widget The widget to add + */ +void gaim_gtk_blist_add_alert(GtkWidget *widget); + /************************************************************************** * @name GTK+ Buddy List sorting functions diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkscrollbook.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gtk/gtkscrollbook.c Thu Nov 23 08:37:07 2006 +0000 @@ -0,0 +1,198 @@ +/* + * @file gtkscrollbook.c GTK+ Status Selection Widget + * @ingroup gtkui + * + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "gtkscrollbook.h" + + +static void gtk_gaim_scroll_book_init (GtkGaimScrollBook *scroll_book); +static void gtk_gaim_scroll_book_class_init (GtkGaimScrollBookClass *klass); + +GType +gtk_gaim_scroll_book_get_type (void) +{ + static GType scroll_book_type = 0; + + if (!scroll_book_type) + { + static const GTypeInfo scroll_book_info = + { + sizeof (GtkGaimScrollBookClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gtk_gaim_scroll_book_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GtkGaimScrollBook), + 0, + (GInstanceInitFunc) gtk_gaim_scroll_book_init, + NULL /* value_table */ + }; + + scroll_book_type = g_type_register_static(GTK_TYPE_VBOX, + "GtkGaimScrollBook", + &scroll_book_info, + 0); + } + + return scroll_book_type; +} + +static void +scroll_left_cb(GtkGaimScrollBook *scroll_book) +{ + int index; + index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)); + + if (index > 0) + gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book->notebook), index - 1); +} + +static void +scroll_right_cb(GtkGaimScrollBook *scroll_book) +{ + int index, count; + index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)); +#if GTK_CHECK_VERSION(2,2,0) + count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook)); +#else + count = g_list_length(GTK_NOTEBOOK(scroll_book->notebook)->children); +#endif + + if (index + 1 < count) + gtk_notebook_set_current_page(GTK_NOTEBOOK(scroll_book->notebook), index + 1); +} + +static void +refresh_scroll_box(GtkGaimScrollBook *scroll_book, int index, int count) +{ + char *label; + + gtk_widget_show_all(scroll_book); + if (count <= 1) + gtk_widget_hide(GTK_WIDGET(scroll_book->hbox)); + else + gtk_widget_show_all(GTK_WIDGET(scroll_book->hbox)); + + + label = g_strdup_printf("(%d/%d)", index+1, count); + gtk_label_set_markup(GTK_LABEL(scroll_book->label), label); + g_free(label); + + if (index == 0) + gtk_widget_set_sensitive(scroll_book->left_arrow, FALSE); + else + gtk_widget_set_sensitive(scroll_book->left_arrow, TRUE); + + + if (index +1== count) + gtk_widget_set_sensitive(scroll_book->right_arrow, FALSE); + else + gtk_widget_set_sensitive(scroll_book->right_arrow, TRUE); +} + + +static void +page_count_change_cb(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, GtkGaimScrollBook *scroll_book) +{ + int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(scroll_book->notebook)); +#if GTK_CHECK_VERSION(2,2,0) + int count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook)); +#else + count = g_list_length(GTK_NOTEBOOK(scroll_book->notebook)->children); +#endif + refresh_scroll_box(scroll_book, index, count); + +} + +static void +switch_page_cb(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, GtkGaimScrollBook *scroll_book) +{ +#if GTK_CHECK_VERSION(2,2,0) + int count = gtk_notebook_get_n_pages(GTK_NOTEBOOK(scroll_book->notebook)); +#else + count = g_list_length(GTK_NOTEBOOK(scroll_book->notebook)->children); +#endif + refresh_scroll_box(scroll_book, page_num, count); +} + +static void +gtk_gaim_scroll_book_add(GtkContainer *container, GtkWidget *widget) +{ + gtk_widget_show(widget); + gtk_notebook_append_page(GTK_NOTEBOOK(GTK_GAIM_SCROLL_BOOK(container)->notebook), widget, NULL); +} + +static void +gtk_gaim_scroll_book_class_init (GtkGaimScrollBookClass *klass) +{ + GtkContainerClass *container_class = (GtkContainerClass*)klass; + + container_class->add = gtk_gaim_scroll_book_add; + +} + +static void +gtk_gaim_scroll_book_init (GtkGaimScrollBook *scroll_book) +{ + GtkWidget *eb; + + scroll_book->hbox = gtk_hbox_new(FALSE, 0); + + eb = gtk_event_box_new(); + gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0); + scroll_book->right_arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE); + gtk_container_add(GTK_CONTAINER(eb), scroll_book->right_arrow); + g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_right_cb), scroll_book); + + scroll_book->label = gtk_label_new(NULL); + gtk_box_pack_end(GTK_BOX(scroll_book->hbox), scroll_book->label, FALSE, FALSE, 0); + + eb = gtk_event_box_new(); + gtk_box_pack_end(GTK_BOX(scroll_book->hbox), eb, FALSE, FALSE, 0); + scroll_book->left_arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE); + gtk_container_add(GTK_CONTAINER(eb), scroll_book->left_arrow); + g_signal_connect_swapped(G_OBJECT(eb), "button-press-event", G_CALLBACK(scroll_left_cb), scroll_book); + + gtk_box_pack_start(GTK_BOX(scroll_book), scroll_book->hbox, FALSE, FALSE, 0); + + scroll_book->notebook = gtk_notebook_new(); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(scroll_book->notebook), FALSE); + gtk_notebook_set_show_border(GTK_NOTEBOOK(scroll_book->notebook), FALSE); + + gtk_box_pack_start(GTK_BOX(scroll_book), scroll_book->notebook, TRUE, TRUE, 0); + + g_signal_connect(G_OBJECT(scroll_book->notebook), "page-added", G_CALLBACK(page_count_change_cb), scroll_book); + g_signal_connect(G_OBJECT(scroll_book->notebook), "page-removed", G_CALLBACK(page_count_change_cb), scroll_book); + g_signal_connect(G_OBJECT(scroll_book->notebook), "switch-page", G_CALLBACK(switch_page_cb), scroll_book); + gtk_widget_hide(scroll_book->hbox); +} + + + +GtkWidget * +gtk_gaim_scroll_book_new() +{ + return g_object_new(GTK_GAIM_TYPE_SCROLL_BOOK, NULL); +} diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkscrollbook.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gtk/gtkscrollbook.h Thu Nov 23 08:37:07 2006 +0000 @@ -0,0 +1,80 @@ +/* + * @file gtkscrollbook GTK+ Scrolling notebook Widget + * @ingroup gtkui + * + * gaim + * + * Gaim is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __GTK_GAIM_SCROLL_BOOK_H__ +#define __GTK_GAIM_SCROLL_BOOK_H__ + +#include + + +G_BEGIN_DECLS + +#define GTK_GAIM_TYPE_SCROLL_BOOK (gtk_gaim_scroll_book_get_type ()) +#define GTK_GAIM_SCROLL_BOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_GAIM_TYPE_SCROLL_BOOK, GtkGaimScrollBook)) +#define GTK_GAIM_SCROLL_BOOK_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_GAIM_TYPE_SCROLL_BOOK, GtkGaimScrollBookClass)) +#define GTK_GAIM_IS_SCROLL_BOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_GAIM_TYPE_SCROLL_BOOK)) +#define GTK_GAIM_IS_SCROLL_BOOK_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_GAIM_TYPE_SCROLL_BOOK)) +#define GTK_GAIM_SCROLL_BOOK_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), GTK_GAIM_TYPE_SCROLL_BOOK, GtkGaimScrollBookClass)) + +typedef struct _GtkGaimScrollBook GtkGaimScrollBook; +typedef struct _GtkGaimScrollBookClass GtkGaimScrollBookClass; + +struct _GtkGaimScrollBook +{ + GtkVBox parent_instance; + + GtkWidget *notebook; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *left_arrow; + GtkWidget *right_arrow; + + /* Padding for future expansion */ + void (*_gtk_reserved0) (void); + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + +}; + + +struct _GtkGaimScrollBookClass +{ + GtkComboBoxClass parent_class; + + /* Padding for future expansion */ + void (*_gtk_reserved0) (void); + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); +}; + + +GType gtk_gaim_scroll_book_get_type (void) G_GNUC_CONST; +GtkWidget *gtk_gaim_scroll_book_new (void); + +G_END_DECLS + +#endif /* __GTK_GAIM_SCROLL_BOOK_H__ */ diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkutils.c --- a/gtk/gtkutils.c Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/gtkutils.c Thu Nov 23 08:37:07 2006 +0000 @@ -2851,3 +2851,114 @@ return ret; } + +GSList *minidialogs = NULL; + +static void * +gaim_gtk_utils_get_handle() +{ + static int handle; + + return &handle; +} + +static void connection_signed_off_cb(GaimConnection *gc) +{ + GSList *list; + for (list = minidialogs; list; list = list->next) { + if (g_object_get_data(G_OBJECT(list->data), "gc") == gc) { + gtk_widget_destroy(GTK_WIDGET(list->data)); + } + } +} + +static void alert_killed_cb(GtkWidget *widget) +{ + minidialogs = g_slist_remove(minidialogs, widget); +} + +void *gaim_gtk_make_mini_dialog(GaimConnection *gc, const char *icon_name, + const char *primary, const char *secondary, + void *user_data, ...) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *bbox; + GtkWidget *label; + GtkWidget *button; + GtkWidget *img = NULL; + char label_text[2048]; + const char *button_text; + GCallback callback; + char *primary_esc, *secondary_esc; + va_list args; + static gboolean first_call = TRUE; + + img = gtk_image_new_from_stock(icon_name, GTK_ICON_SIZE_BUTTON); + gtk_misc_set_alignment(GTK_MISC(img), 0, 0); + + vbox = gtk_vbox_new(FALSE,0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 6); + + g_object_set_data(G_OBJECT(vbox), "gc" ,gc); + minidialogs = g_slist_prepend(minidialogs, vbox); + g_signal_connect(G_OBJECT(vbox), "destroy", G_CALLBACK(alert_killed_cb), NULL); + + if (first_call) { + first_call = FALSE; + gaim_signal_connect(gaim_connections_get_handle(), "signed-off", + gaim_gtk_utils_get_handle(), + GAIM_CALLBACK(connection_signed_off_cb), NULL); + } + + hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + + if (img != NULL) + gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); + + primary_esc = g_markup_escape_text(primary, -1); + + if (secondary) + secondary_esc = g_markup_escape_text(secondary, -1); + g_snprintf(label_text, sizeof(label_text), + "%s%s%s", + primary_esc, secondary ? "\n" : "", secondary?secondary_esc:""); + g_free(primary_esc); + label = gtk_label_new(NULL); + gtk_widget_modify_text(vbox, GTK_STATE_NORMAL, &(label->style->white)); + gtk_label_set_markup(GTK_LABEL(label), label_text); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); +#if GTK_CHECK_VERSION(2,6,0) + g_object_set(label, "ellipsize", PANGO_ELLIPSIZE_END, NULL); +#endif + + bbox = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 6); + + va_start(args, user_data); + while ((button_text = va_arg(args, char*))) { + callback = va_arg(args, GCallback); + button = gtk_button_new(); + gtk_container_set_border_width(GTK_CONTAINER(button), 0); + if (callback) + g_signal_connect_swapped(G_OBJECT(button), "clicked", callback, user_data); + g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_destroy), vbox); + hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(button), hbox); + g_snprintf(label_text, sizeof(label_text), + "%s", button_text); + label = gtk_label_new(NULL); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), label_text); + gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(bbox), button); + } + va_end(args); + + return vbox; +} diff -r ea6186360b68 -r ca46f41aa433 gtk/gtkutils.h --- a/gtk/gtkutils.h Wed Nov 22 21:33:51 2006 +0000 +++ b/gtk/gtkutils.h Thu Nov 23 08:37:07 2006 +0000 @@ -510,3 +510,16 @@ * @return A newly allocated string with unicode arrow characters */ char *gaim_gtk_make_pretty_arrows(const char *str); + +/** + * Creates a "mini-dialog" suitable for embedding in the buddy list scrollbook + * + * @param handle A handle + * @param primary The primary text + * @param secondary The secondary text + * @param user_data Data to pass to the callbacks + * @param ... a NULL-terminated list of button labels and callbacks + */ +void *gaim_gtk_make_mini_dialog(GaimConnection *handle, const char* stock_id, + const char *primary, const char *secondary, + void *user_data, ...);