diff -r 1edf059a4a26 -r 5af898e91ec2 pidgin/gtkstatusbox.c --- a/pidgin/gtkstatusbox.c Sat May 26 13:48:41 2007 +0000 +++ b/pidgin/gtkstatusbox.c Sun Jul 01 00:55:03 2007 +0000 @@ -41,12 +41,14 @@ #include +#include "internal.h" + #include "account.h" #include "buddyicon.h" #include "core.h" -#include "internal.h" #include "imgstore.h" #include "network.h" +#include "request.h" #include "savedstatuses.h" #include "status.h" #include "debug.h" @@ -191,7 +193,7 @@ static void update_to_reflect_account_status(PidginStatusBox *status_box, PurpleAccount *account, PurpleStatus *newstatus) { - const GList *l; + GList *l; int status_no = -1; const PurpleStatusType *statustype = NULL; const char *message; @@ -732,7 +734,7 @@ static PurpleStatusType * find_status_type_by_index(const PurpleAccount *account, gint active) { - const GList *l = purple_account_get_status_types(account); + GList *l = purple_account_get_status_types(account); gint i; for (i = 0; l; l = l->next) { @@ -941,7 +943,7 @@ { PurpleAccount *acct = NULL, *acct2; GList *tmp, *tmp2, *active_accts = purple_accounts_get_all_active(); - const GList *s, *s1, *s2; + GList *s, *s1, *s2; for (tmp = active_accts; tmp; tmp = tmp->next) { acct = tmp->data; @@ -989,7 +991,7 @@ add_account_statuses(PidginStatusBox *status_box, PurpleAccount *account) { /* Per-account */ - const GList *l; + GList *l; GdkPixbuf *pixbuf; for (l = purple_account_get_status_types(account); l != NULL; l = l->next) @@ -1014,10 +1016,10 @@ } } -static void -pidgin_status_box_regenerate(PidginStatusBox *status_box) +static gboolean +pidgin_status_box_regenerate_real(PidginStatusBox *status_box) { - GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4; + GdkPixbuf *pixbuf, *pixbuf2, *pixbuf3, *pixbuf4, *pixbuf5; GtkIconSize icon_size; icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL); @@ -1047,15 +1049,19 @@ icon_size, "PidginStatusBox"); pixbuf4 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), PIDGIN_STOCK_STATUS_INVISIBLE, icon_size, "PidginStatusBox"); + pixbuf5 = gtk_widget_render_icon (GTK_WIDGET(status_box->vbox), PIDGIN_STOCK_STATUS_BUSY, + icon_size, "PidginStatusBox"); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf, _("Available"), NULL, GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE)); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf2, _("Away"), NULL, GINT_TO_POINTER(PURPLE_STATUS_AWAY)); + pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf5, _("Do not disturb"), NULL, GINT_TO_POINTER(PURPLE_STATUS_UNAVAILABLE)); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf4, _("Invisible"), NULL, GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE)); pidgin_status_box_add(PIDGIN_STATUS_BOX(status_box), PIDGIN_STATUS_BOX_TYPE_PRIMITIVE, pixbuf3, _("Offline"), NULL, GINT_TO_POINTER(PURPLE_STATUS_OFFLINE)); if (pixbuf2) g_object_unref(G_OBJECT(pixbuf2)); if (pixbuf3) g_object_unref(G_OBJECT(pixbuf3)); if (pixbuf4) g_object_unref(G_OBJECT(pixbuf4)); + if (pixbuf5) g_object_unref(G_OBJECT(pixbuf5)); } add_popular_statuses(status_box); @@ -1075,11 +1081,21 @@ } gtk_tree_view_set_model(GTK_TREE_VIEW(status_box->tree_view), GTK_TREE_MODEL(status_box->dropdown_store)); gtk_tree_view_set_search_column(GTK_TREE_VIEW(status_box->tree_view), TEXT_COLUMN); + + return FALSE; +} + +static void +pidgin_status_box_regenerate(PidginStatusBox *status_box) +{ + /* we have to do this in a timeout, so we avoid recursing + * to infinity (and beyond) */ + purple_timeout_add(0, (GSourceFunc)pidgin_status_box_regenerate_real, status_box); } static gboolean combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml) { - pidgin_status_box_popup(PIDGIN_STATUS_BOX(w)); + pidgin_status_box_popup(PIDGIN_STATUS_BOX(w)); return TRUE; } @@ -1223,6 +1239,12 @@ } static void +saved_status_updated_cb(PurpleSavedStatus *status, PidginStatusBox *status_box) +{ + pidgin_status_box_regenerate(status_box); +} + +static void spellcheck_prefs_cb(const char *name, PurplePrefType type, gconstpointer value, gpointer data) { @@ -1514,6 +1536,56 @@ pidgin_status_box_changed(status_box); } +static void tree_view_delete_current_selection_cb(gpointer data) +{ + PurpleSavedStatus *saved; + + saved = purple_savedstatus_find_by_creation_time(GPOINTER_TO_INT(data)); + g_return_if_fail(saved != NULL); + + if (purple_savedstatus_get_current() != saved) + purple_savedstatus_delete_by_status(saved); +} + +static void +tree_view_delete_current_selection(PidginStatusBox *status_box, GtkTreePath *path) +{ + GtkTreeIter iter; + gpointer data; + PurpleSavedStatus *saved; + gchar *msg; + + if (status_box->active_row) { + /* don't delete active status */ + if (gtk_tree_path_compare(path, gtk_tree_row_reference_get_path(status_box->active_row)) == 0) + return; + } + + if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(status_box->dropdown_store), &iter, path)) + return; + + gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, + DATA_COLUMN, &data, + -1); + + saved = purple_savedstatus_find_by_creation_time(GPOINTER_TO_INT(data)); + g_return_if_fail(saved != NULL); + if (saved == purple_savedstatus_get_current()) + return; + + msg = g_strdup_printf(_("Are you sure you want to delete %s?"), purple_savedstatus_get_title(saved)); + + purple_request_action(saved, NULL, msg, NULL, 0, + NULL, NULL, NULL, + data, 2, + _("Delete"), tree_view_delete_current_selection_cb, + _("Cancel"), NULL); + + g_free(msg); + + pidgin_status_box_popdown(status_box); +} + static gboolean treeview_button_release_cb(GtkWidget *widget, GdkEventButton *event, PidginStatusBox *status_box) { @@ -1561,18 +1633,25 @@ if (event->keyval == GDK_Escape) { pidgin_status_box_popdown(box); return TRUE; - } else if (event->keyval == GDK_Return) { + } else { GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(box->tree_view)); GtkTreeIter iter; GtkTreePath *path; if (gtk_tree_selection_get_selected(sel, NULL, &iter)) { + gboolean ret = TRUE; path = gtk_tree_model_get_path(GTK_TREE_MODEL(box->dropdown_store), &iter); - treeview_activate_current_selection(box, path); + if (event->keyval == GDK_Return) { + treeview_activate_current_selection(box, path); + } else if (event->keyval == GDK_Delete) { + tree_view_delete_current_selection(box, path); + } else + ret = FALSE; + gtk_tree_path_free (path); - return TRUE; + return ret; } - } + } } return FALSE; } @@ -1742,6 +1821,15 @@ status_box, PURPLE_CALLBACK(current_savedstatus_changed_cb), status_box); + purple_signal_connect(purple_savedstatuses_get_handle(), + "savedstatus-added", status_box, + PURPLE_CALLBACK(saved_status_updated_cb), status_box); + purple_signal_connect(purple_savedstatuses_get_handle(), + "savedstatus-deleted", status_box, + PURPLE_CALLBACK(saved_status_updated_cb), status_box); + purple_signal_connect(purple_savedstatuses_get_handle(), + "savedstatus-modified", status_box, + PURPLE_CALLBACK(saved_status_updated_cb), status_box); purple_signal_connect(purple_accounts_get_handle(), "account-enabled", status_box, PURPLE_CALLBACK(account_enabled_cb), status_box); @@ -2029,6 +2117,10 @@ int w, h; GtkIconSize icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MEDIUM); gtk_icon_size_lookup(icon_size, &w, &h); + if (height > width) + w = width * h / height; + else if (width > height) + h = height * w / width; gdk_pixbuf_loader_set_size(loader, w, h); #endif } @@ -2219,7 +2311,7 @@ { /* Manually find the appropriate transient acct */ if (status_box->token_status_account) { - const GList *iter = purple_savedstatuses_get_all(); + GList *iter = purple_savedstatuses_get_all(); GList *tmp, *active_accts = purple_accounts_get_all_active(); for (; iter != NULL; iter = iter->next) {