pidgin/gtkstatusbox.c

changeset 18545
5af898e91ec2
parent 18318
146d6831fc3d
child 18319
e5f4aef72165
--- 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 <gdk/gdkkeysyms.h>
 
+#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) {

mercurial