# HG changeset patch
# Node ID dffea3eb379f
# Parent  bf4beafd15a3
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -1197,6 +1197,7 @@
 		* pidgin_status_editor_show, use pidgin_status_editor_new instead.
 		* pidgin_status_get_handle
 		* pidgin_status_init
+		* pidgin_status_menu
 		* pidgin_status_uninit
 		* pidgin_status_window_hide
 		* pidgin_status_window_show, use pidgin_status_manager_new instead.
diff --git a/libpurple/data/im.pidgin.Purple.gschema.xml b/libpurple/data/im.pidgin.Purple.gschema.xml
--- a/libpurple/data/im.pidgin.Purple.gschema.xml
+++ b/libpurple/data/im.pidgin.Purple.gschema.xml
@@ -27,13 +27,13 @@
   </schema>
 
   <enum id="im.pidgin.Purple.Idle.Method">
-    <value nick="Never" value="0"/>
-    <value nick="Purple" value="1"/>
-    <value nick="System" value="2"/>
+    <value nick="none" value="0"/>
+    <value nick="purple" value="1"/>
+    <value nick="system" value="2"/>
   </enum>
   <schema path="/purple/idle/" id="im.pidgin.Purple.Idle">
     <key name="method" enum="im.pidgin.Purple.Idle.Method">
-      <default>"System"</default>
+      <default>"system"</default>
       <summary>Idle reporting method</summary>
       <description>
         The method to use to report idle time.
@@ -49,19 +49,38 @@
       </description>
     </key>
 
-    <key name="change-status" type="b">
+    <key name="change-presence" type="b">
       <default>false</default>
-      <summary>Change status when idle</summary>
+      <summary>Change presence when idle</summary>
       <description>
-        When going idle switch statuses.
+        When going idle switch presences.
       </description>
     </key>
 
-    <key name="status" type="s">
+    <key name="saved-presence" type="s">
       <default>""</default>
-      <summary>The status to use when idle</summary>
+      <summary>The saved presence to use when idle</summary>
       <description>
-        The ID of the status to use when the user has gone idle.
+        The name of the saved presence to use when the user has gone idle.
+      </description>
+    </key>
+  </schema>
+
+  <schema path="/purple/startup/" id="im.pidgin.Purple.Startup">
+    <key name="use-previous-presence" type="b">
+      <default>true</default>
+      <summary>Use the saved presence from last exit</summary>
+      <description>
+        Use the saved presence that was in use the last time the application
+        was exited.
+      </description>
+    </key>
+
+    <key name="saved-presence" type="s">
+      <default>""</default>
+      <summary>The saved presence to use at startup</summary>
+      <description>
+        The name of the saved presence to use at startup.
       </description>
     </key>
   </schema>
diff --git a/pidgin/gtksavedstatuses.h b/pidgin/gtksavedstatuses.h
deleted file mode 100644
--- a/pidgin/gtksavedstatuses.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* pidgin
- *
- * Pidgin 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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
-# error "only <pidgin.h> may be included directly"
-#endif
-
-#ifndef _PIDGINSAVEDSTATUSES_H_
-#define _PIDGINSAVEDSTATUSES_H_
-
-#include <purple.h>
-
-#include "pidginversion.h"
-
-G_BEGIN_DECLS
-
-/**
- * pidgin_status_menu:
- * @status:   The default saved_status to show as 'selected'
- * @callback: (scope call): The callback to call when the selection changes
- *
- * Creates a dropdown menu of saved statuses and calls a callback
- * when one is selected
- *
- * Returns: (transfer full): The menu widget
- *
- * Since: 2.0.0
- */
-PIDGIN_AVAILABLE_IN_ALL
-GtkWidget *pidgin_status_menu(PurpleSavedStatus *status, GCallback callback);
-
-G_END_DECLS
-
-#endif /* _PIDGINSAVEDSTATUSES_H_ */
diff --git a/pidgin/gtksavedstatuses.c b/pidgin/gtksavedstatuses.c
deleted file mode 100644
--- a/pidgin/gtksavedstatuses.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/* pidgin
- *
- * Pidgin 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., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
- */
-
-#include <glib/gi18n-lib.h>
-
-#include <gtk/gtk.h>
-
-#include <purple.h>
-
-#include "gtksavedstatuses.h"
-#include "pidginiconname.h"
-
-enum {
-	SS_MENU_ENTRY_TYPE_PRIMITIVE,
-	SS_MENU_ENTRY_TYPE_SAVEDSTATUS
-};
-
-enum {
-	/* _SSMenuEntryType */
-	SS_MENU_TYPE_COLUMN,
-
-	/*
-	 * This is a GdkPixbuf (the other columns are strings).
-	 * This column is visible.
-	 */
-	SS_MENU_ICON_COLUMN,
-
-	/* The text displayed on the status box.  This column is visible. */
-	SS_MENU_TEXT_COLUMN,
-
-	/*
-	 * This value depends on SS_MENU_TYPE_COLUMN.  For _SAVEDSTATUS types,
-	 * this is the creation time.  For _PRIMITIVE types,
-	 * this is the PurpleStatusPrimitive.
-	 */
-	SS_MENU_DATA_COLUMN,
-
-	/*
-	 * This is the emblem to use for this status
-	 */
-	SS_MENU_EMBLEM_COLUMN,
-
-	/*
-	 * And whether or not that emblem is visible
-	 */
-	SS_MENU_EMBLEM_VISIBLE_COLUMN,
-
-	SS_MENU_NUM_COLUMNS
-};
-
-static void
-status_menu_cb(GtkComboBox *widget, void(*callback)(PurpleSavedStatus*))
-{
-	GtkTreeIter iter;
-	int type;
-	gpointer data;
-	PurpleSavedStatus *status = NULL;
-
-	if (!gtk_combo_box_get_active_iter(widget, &iter))
-		return;
-
-	gtk_tree_model_get(gtk_combo_box_get_model(widget), &iter,
-			   SS_MENU_TYPE_COLUMN, &type,
-			   SS_MENU_DATA_COLUMN, &data,
-			   -1);
-
-	if (type == SS_MENU_ENTRY_TYPE_PRIMITIVE)
-	{
-		PurpleStatusPrimitive primitive = GPOINTER_TO_INT(data);
-		status = purple_savedstatus_find_transient_by_type_and_message(primitive, NULL);
-		if (status == NULL)
-			status = purple_savedstatus_new(NULL, primitive);
-	}
-	else if (type == SS_MENU_ENTRY_TYPE_SAVEDSTATUS)
-		status = purple_savedstatus_find_by_creation_time(GPOINTER_TO_INT(data));
-
-	callback(status);
-}
-
-static gint
-saved_status_sort_alphabetically_func(gconstpointer a, gconstpointer b)
-{
-	const PurpleSavedStatus *saved_status_a = a;
-	const PurpleSavedStatus *saved_status_b = b;
-	return g_utf8_collate(purple_savedstatus_get_title(saved_status_a),
-				  purple_savedstatus_get_title(saved_status_b));
-}
-
-static gboolean
-pidgin_status_menu_add_primitive(GtkListStore *model,
-                                 G_GNUC_UNUSED GtkWidget *w,
-                                 PurpleStatusPrimitive primitive,
-                                 PurpleSavedStatus *current_status)
-{
-	GtkTreeIter iter;
-	gboolean currently_selected = FALSE;
-
-	gtk_list_store_append(model, &iter);
-	gtk_list_store_set(model, &iter,
-			   SS_MENU_TYPE_COLUMN, SS_MENU_ENTRY_TYPE_PRIMITIVE,
-			   SS_MENU_ICON_COLUMN, pidgin_icon_name_from_status_primitive(primitive, NULL),
-			   SS_MENU_TEXT_COLUMN, purple_primitive_get_name_from_type(primitive),
-			   SS_MENU_DATA_COLUMN, GINT_TO_POINTER(primitive),
-			   SS_MENU_EMBLEM_VISIBLE_COLUMN, FALSE,
-			   -1);
-
-	if (purple_savedstatus_is_transient(current_status)
-			&& !purple_savedstatus_has_substatuses(current_status)
-			&& purple_savedstatus_get_primitive_type(current_status) == primitive)
-		currently_selected = TRUE;
-
-	return currently_selected;
-}
-
-static void
-pidgin_status_menu_update_iter(GtkWidget *combobox, GtkListStore *store, GtkTreeIter *iter,
-		PurpleSavedStatus *status)
-{
-	PurpleStatusPrimitive primitive;
-
-	if (store == NULL)
-		store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combobox)));
-
-	primitive = purple_savedstatus_get_primitive_type(status);
-	gtk_list_store_set(store, iter,
-			SS_MENU_TYPE_COLUMN, SS_MENU_ENTRY_TYPE_SAVEDSTATUS,
-			SS_MENU_ICON_COLUMN, pidgin_icon_name_from_status_primitive(primitive, NULL),
-			SS_MENU_TEXT_COLUMN, purple_savedstatus_get_title(status),
-			SS_MENU_DATA_COLUMN, GINT_TO_POINTER(purple_savedstatus_get_creation_time(status)),
-			SS_MENU_EMBLEM_COLUMN, "document-save",
-			SS_MENU_EMBLEM_VISIBLE_COLUMN, TRUE,
-			-1);
-}
-
-static gboolean
-pidgin_status_menu_find_iter(GtkListStore *store, GtkTreeIter *iter, PurpleSavedStatus *find)
-{
-	int type;
-	gpointer data;
-	time_t creation_time = purple_savedstatus_get_creation_time(find);
-	GtkTreeModel *model = GTK_TREE_MODEL(store);
-
-	if (!gtk_tree_model_get_iter_first(model, iter))
-		return FALSE;
-
-	do {
-		gtk_tree_model_get(model, iter,
-				SS_MENU_TYPE_COLUMN, &type,
-				SS_MENU_DATA_COLUMN, &data,
-				-1);
-		if (type == SS_MENU_ENTRY_TYPE_PRIMITIVE)
-			continue;
-		if (GPOINTER_TO_INT(data) == creation_time)
-			return TRUE;
-	} while (gtk_tree_model_iter_next(model, iter));
-
-	return FALSE;
-}
-
-static void
-savedstatus_added_cb(PurpleSavedStatus *status, GtkWidget *combobox)
-{
-	GtkListStore *store;
-	GtkTreeIter iter;
-
-	if (purple_savedstatus_is_transient(status))
-		return;
-
-	store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combobox)));
-	gtk_list_store_append(store, &iter);
-	pidgin_status_menu_update_iter(combobox, store, &iter, status);
-}
-
-static void
-savedstatus_deleted_cb(PurpleSavedStatus *status, GtkWidget *combobox)
-{
-	GtkListStore *store;
-	GtkTreeIter iter;
-
-	if (purple_savedstatus_is_transient(status))
-		return;
-
-	store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combobox)));
-	if (pidgin_status_menu_find_iter(store, &iter, status))
-		gtk_list_store_remove(store, &iter);
-}
-
-static void
-savedstatus_modified_cb(PurpleSavedStatus *status, GtkWidget *combobox)
-{
-	GtkListStore *store;
-	GtkTreeIter iter;
-
-	if (purple_savedstatus_is_transient(status))
-		return;
-
-	store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combobox)));
-	if (pidgin_status_menu_find_iter(store, &iter, status))
-		pidgin_status_menu_update_iter(combobox, store, &iter, status);
-}
-
-GtkWidget *pidgin_status_menu(PurpleSavedStatus *current_status, GCallback callback)
-{
-	GtkWidget *combobox;
-	GtkListStore *model;
-	GList *sorted, *cur;
-	int i = 0;
-	int index = -1;
-	GtkTreeIter iter;
-	GtkCellRenderer *text_rend;
-	GtkCellRenderer *icon_rend;
-	GtkCellRenderer *emblem_rend;
-
-	model = gtk_list_store_new(SS_MENU_NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING,
-				   G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN);
-
-	combobox = gtk_combo_box_new();
-
-	if (pidgin_status_menu_add_primitive(model, combobox, PURPLE_STATUS_AVAILABLE, current_status))
-		index = i;
-	i++;
-
-	if (pidgin_status_menu_add_primitive(model, combobox, PURPLE_STATUS_AWAY, current_status))
-		index = i;
-	i++;
-
-	if (pidgin_status_menu_add_primitive(model, combobox, PURPLE_STATUS_INVISIBLE, current_status))
-		index = i;
-	i++;
-
-	if (pidgin_status_menu_add_primitive(model, combobox, PURPLE_STATUS_OFFLINE, current_status))
-		index = i;
-	i++;
-
-	sorted = g_list_copy((GList *)purple_savedstatuses_get_all());
-	sorted = g_list_sort(sorted, saved_status_sort_alphabetically_func);
-	for (cur = sorted; cur; cur = cur->next)
-	{
-		PurpleSavedStatus *status = (PurpleSavedStatus *) cur->data;
-		if (!purple_savedstatus_is_transient(status))
-		{
-			gtk_list_store_append(model, &iter);
-
-			pidgin_status_menu_update_iter(combobox, model, &iter, status);
-
-			if (status == current_status)
-				index = i;
-			i++;
-		}
-	}
-	g_list_free(sorted);
-
-	gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), GTK_TREE_MODEL(model));
-
-	text_rend = gtk_cell_renderer_text_new();
-	icon_rend = gtk_cell_renderer_pixbuf_new();
-	emblem_rend = gtk_cell_renderer_pixbuf_new();
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), icon_rend, FALSE);
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), text_rend, TRUE);
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), emblem_rend, FALSE);
-	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), icon_rend, "icon-name", SS_MENU_ICON_COLUMN, NULL);
-	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), text_rend, "markup", SS_MENU_TEXT_COLUMN, NULL);
-	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), emblem_rend,
-					"icon-name", SS_MENU_EMBLEM_COLUMN, "visible", SS_MENU_EMBLEM_VISIBLE_COLUMN, NULL);
-	g_object_set(text_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-
-	gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), index);
-	g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(status_menu_cb), callback);
-
-	/* Make sure the list is updated dynamically when a substatus is changed/deleted
-	 * or a new one is added. */
-	purple_signal_connect(purple_savedstatuses_get_handle(), "savedstatus-added",
-			combobox, G_CALLBACK(savedstatus_added_cb), combobox);
-	purple_signal_connect(purple_savedstatuses_get_handle(), "savedstatus-deleted",
-			combobox, G_CALLBACK(savedstatus_deleted_cb), combobox);
-	purple_signal_connect(purple_savedstatuses_get_handle(), "savedstatus-modified",
-			combobox, G_CALLBACK(savedstatus_modified_cb), combobox);
-	g_signal_connect(G_OBJECT(combobox), "destroy",
-			G_CALLBACK(purple_signals_disconnect_by_handle), NULL);
-
-	return combobox;
-}
diff --git a/pidgin/meson.build b/pidgin/meson.build
--- a/pidgin/meson.build
+++ b/pidgin/meson.build
@@ -11,7 +11,6 @@
 	'gtknotify.c',
 	'gtkrequest.c',
 	'gtkroomlist.c',
-	'gtksavedstatuses.c',
 	'gtkutils.c',
 	'gtkwhiteboard.c',
 	'gtkxfer.c',
@@ -81,7 +80,6 @@
 	'gtknotify.h',
 	'gtkrequest.h',
 	'gtkroomlist.h',
-	'gtksavedstatuses.h',
 	'gtkutils.h',
 	'gtkwhiteboard.h',
 	'gtkxfer.h',
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -36,7 +36,6 @@
 #include "gtkblist.h"
 #include "gtkdialogs.h"
 #include "gtkroomlist.h"
-#include "gtksavedstatuses.h"
 #include "gtkxfer.h"
 #include "pidginabout.h"
 #include "pidginaccounteditor.h"
diff --git a/pidgin/prefs/pidginawayprefs.c b/pidgin/prefs/pidginawayprefs.c
--- a/pidgin/prefs/pidginawayprefs.c
+++ b/pidgin/prefs/pidginawayprefs.c
@@ -27,8 +27,8 @@
 #include <adwaita.h>
 
 #include "pidginawayprefs.h"
-#include "gtksavedstatuses.h"
 #include "gtkutils.h"
+#include "pidginiconname.h"
 #include "pidginprefsinternal.h"
 
 struct _PidginAwayPrefs {
@@ -48,8 +48,7 @@
  * Helpers
  *****************************************************************************/
 static gchar *
-idle_reporting_expression_cb(GObject *self, G_GNUC_UNUSED gpointer data)
-{
+idle_reporting_expression_cb(GObject *self, G_GNUC_UNUSED gpointer data) {
 	const gchar *text = "";
 	const gchar *value = NULL;
 
@@ -65,18 +64,136 @@
 	return g_strdup(text);
 }
 
-static void
-set_idle_away(PurpleSavedStatus *status)
+static char *
+idle_presence_icon_name_from_primitive(G_GNUC_UNUSED GObject *self,
+                                       PurplePresencePrimitive primitive,
+                                       G_GNUC_UNUSED gpointer data)
+{
+	const char *icon_name = NULL;
+
+	icon_name = pidgin_icon_name_from_presence_primitive(primitive,
+	                                                     "icon-missing");
+
+	return g_strdup(icon_name);
+}
+
+static gboolean
+idle_get_reporting_mapping(GValue *value, GVariant *variant,
+                           G_GNUC_UNUSED gpointer data)
 {
-	purple_prefs_set_int("/purple/savedstatus/idleaway",
-	                     purple_savedstatus_get_creation_time(status));
+	const char *id = NULL;
+
+	id = g_variant_get_string(variant, NULL);
+	if(purple_strequal(id, "none")) {
+		g_value_set_uint(value, 0);
+	} else if(purple_strequal(id, "purple")) {
+		g_value_set_uint(value, 1);
+	} else if(purple_strequal(id, "system")) {
+		g_value_set_uint(value, 2);
+	} else {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static GVariant *
+idle_set_reporting_mapping(const GValue *value, const GVariantType *expected,
+                           G_GNUC_UNUSED gpointer data)
+{
+	const char *id = NULL;
+
+	if(!g_variant_type_equal(expected, G_VARIANT_TYPE_STRING)) {
+		return NULL;
+	}
+
+	switch(g_value_get_uint(value)) {
+	case 0:
+		id = "none";
+		break;
+	case 1:
+		id = "purple";
+		break;
+	case 2:
+		id = "system";
+		break;
+	}
+
+	if(id != NULL) {
+		return g_variant_new_string(id);
+	}
+
+	return NULL;
 }
 
-static void
-set_startupstatus(PurpleSavedStatus *status)
+static gboolean
+idle_get_saved_presence_mapping(GValue *value, GVariant *variant,
+                                G_GNUC_UNUSED gpointer data)
 {
-	purple_prefs_set_int("/purple/savedstatus/startup",
-	                     purple_savedstatus_get_creation_time(status));
+	GListModel *model = NULL;
+	const char *name = NULL;
+	guint n_items = 0;
+
+	model = purple_presence_manager_get_default_as_model();
+
+	name = g_variant_get_string(variant, NULL);
+
+	n_items = g_list_model_get_n_items(model);
+	for(guint i = 0; i < n_items; i++) {
+		PurpleSavedPresence *presence = NULL;
+
+		presence = g_list_model_get_item(model, i);
+		if(PURPLE_IS_SAVED_PRESENCE(presence)) {
+			const char *presence_name = NULL;
+
+			presence_name = purple_saved_presence_get_name(presence);
+			if(purple_strequal(presence_name, name)) {
+				g_value_set_uint(value, i);
+
+				g_clear_object(&presence);
+
+				return TRUE;
+			}
+		}
+
+		g_clear_object(&presence);
+	}
+
+	g_value_set_uint(value, 0);
+
+	return TRUE;
+}
+
+static GVariant *
+idle_set_saved_presence_mapping(const GValue *value,
+                                const GVariantType *expected,
+                                G_GNUC_UNUSED gpointer data)
+{
+	PurpleSavedPresence *presence = NULL;
+	GListModel *model = NULL;
+	guint position = 0;
+
+	if(!g_variant_type_equal(expected, G_VARIANT_TYPE_STRING)) {
+		return NULL;
+	}
+
+	model = purple_presence_manager_get_default_as_model();
+	position = g_value_get_uint(value);
+	presence = g_list_model_get_item(model, position);
+
+	if(PURPLE_IS_SAVED_PRESENCE(presence)) {
+		GVariant *ret = NULL;
+		const char *name = NULL;
+
+		name = purple_saved_presence_get_name(presence);
+		ret = g_variant_new_string(name);
+
+		g_clear_object(&presence);
+
+		return ret;
+	}
+
+	return NULL;
 }
 
 /******************************************************************************
@@ -106,47 +223,64 @@
 	                                     startup_current_status);
 	gtk_widget_class_bind_template_child(widget_class, PidginAwayPrefs,
 	                                     startup_row);
+
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        idle_presence_icon_name_from_primitive);
 }
 
 static void
 pidgin_away_prefs_init(PidginAwayPrefs *prefs)
 {
-	GtkWidget *menu;
+	GListModel *model = NULL;
+	GSettings *settings = NULL;
+	gpointer backend = NULL;
 
 	gtk_widget_init_template(GTK_WIDGET(prefs));
 
-	pidgin_prefs_bind_combo_row("/purple/away/idle_reporting",
-	                            prefs->idle_reporting);
+	backend = purple_core_get_settings_backend();
+	model = purple_presence_manager_get_default_as_model();
 
-	pidgin_prefs_bind_spin_button("/purple/away/mins_before_away",
-			prefs->mins_before_away);
+	/* Finish setting up our idle preferences. */
+	adw_combo_row_set_model(ADW_COMBO_ROW(prefs->idle_row), model);
 
-	pidgin_prefs_bind_switch("/purple/away/away_when_idle",
-	                         prefs->away_when_idle);
+	settings = g_settings_new_with_backend("im.pidgin.Purple.Idle", backend);
 
-	/* TODO: Show something useful if we don't have any saved statuses. */
-	menu = pidgin_status_menu(purple_savedstatus_get_idleaway(),
-	                          G_CALLBACK(set_idle_away));
-	gtk_widget_set_valign(menu, GTK_ALIGN_CENTER);
-	adw_action_row_add_suffix(ADW_ACTION_ROW(prefs->idle_row), menu);
-	adw_action_row_set_activatable_widget(ADW_ACTION_ROW(prefs->idle_row),
-	                                      menu);
-
-	g_object_bind_property(prefs->away_when_idle, "active",
-			menu, "sensitive",
-			G_BINDING_SYNC_CREATE);
+	g_settings_bind_with_mapping(settings, "method",
+	                             prefs->idle_reporting, "selected",
+	                             G_SETTINGS_BIND_DEFAULT,
+	                             idle_get_reporting_mapping,
+	                             idle_set_reporting_mapping,
+	                             NULL, NULL);
+	g_settings_bind(settings, "duration", prefs->mins_before_away,
+	                "value", G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "change-presence", prefs->away_when_idle,
+	                "active", G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind_with_mapping(settings, "saved-presence",
+	                             prefs->idle_row, "selected",
+	                             G_SETTINGS_BIND_DEFAULT,
+	                             idle_get_saved_presence_mapping,
+	                             idle_set_saved_presence_mapping,
+	                             NULL, NULL);
 
-	/* Signon status stuff */
-	pidgin_prefs_bind_switch("/purple/savedstatus/startup_current_status",
-	                         prefs->startup_current_status);
+	g_clear_object(&settings);
+
+	/* Finish setting up the startup presence preferences. */
+	adw_combo_row_set_model(ADW_COMBO_ROW(prefs->startup_row), model);
+
+	settings = g_settings_new_with_backend("im.pidgin.Purple.Startup",
+	                                       backend);
 
-	/* TODO: Show something useful if we don't have any saved statuses. */
-	menu = pidgin_status_menu(purple_savedstatus_get_startup(),
-	                          G_CALLBACK(set_startupstatus));
-	gtk_widget_set_valign(menu, GTK_ALIGN_CENTER);
-	adw_action_row_add_suffix(ADW_ACTION_ROW(prefs->startup_row), menu);
-	adw_action_row_set_activatable_widget(ADW_ACTION_ROW(prefs->startup_row),
-	                                      menu);
+	g_settings_bind(settings, "use-previous-presence",
+	                prefs->startup_current_status, "active",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind_with_mapping(settings, "saved-presence",
+	                             prefs->startup_row, "selected",
+	                             G_SETTINGS_BIND_DEFAULT,
+	                             idle_get_saved_presence_mapping,
+	                             idle_set_saved_presence_mapping,
+	                             NULL, NULL);
+
+	g_clear_object(&settings);
 }
 
 /******************************************************************************
@@ -154,5 +288,5 @@
  *****************************************************************************/
 GtkWidget *
 pidgin_away_prefs_new(void) {
-	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_AWAY_PREFS, NULL));
+	return g_object_new(PIDGIN_TYPE_AWAY_PREFS, NULL);
 }
diff --git a/pidgin/resources/Prefs/away.ui b/pidgin/resources/Prefs/away.ui
--- a/pidgin/resources/Prefs/away.ui
+++ b/pidgin/resources/Prefs/away.ui
@@ -23,6 +23,44 @@
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+  <object class="GtkBuilderListItemFactory" id="saved_presence_factory">
+    <property name="bytes">
+<![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <property name="child">
+      <object class="GtkBox">
+        <property name="orientation">horizontal</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkImage">
+            <binding name="icon-name">
+              <closure type="gchararray" function="idle_presence_icon_name_from_primitive">
+                <lookup name="primitive" type="PurpleSavedPresence">
+                  <lookup name="item">GtkListItem</lookup>
+                </lookup>
+              </closure>
+            </binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <binding name="label">
+              <lookup name="name" type="PurpleSavedPresence">
+                <lookup name="item">GtkListItem</lookup>
+              </lookup>
+            </binding>
+          </object>
+        </child>
+      </object>
+    </property>
+  </template>
+</interface>
+]]>
+    </property>
+  </object>
+
   <template class="PidginAwayPrefs" parent="AdwPreferencesPage">
     <child>
       <object class="AdwPreferencesGroup">
@@ -70,10 +108,11 @@
           </object>
         </child>
         <child>
-          <object class="AdwActionRow" id="idle_row">
+          <object class="AdwComboRow" id="idle_row">
             <property name="activatable-widget">away_when_idle</property>
             <property name="title" translatable="1">Change to this status when _idle</property>
             <property name="use-underline">1</property>
+            <property name="factory">saved_presence_factory</property>
             <child type="prefix">
               <object class="GtkSwitch" id="away_when_idle">
                 <property name="focusable">1</property>
@@ -101,10 +140,11 @@
           </object>
         </child>
         <child>
-          <object class="AdwActionRow" id="startup_row">
+          <object class="AdwComboRow" id="startup_row">
             <property name="title" translatable="1">Status to a_pply at startup</property>
             <property name="use-underline">1</property>
             <property name="sensitive" bind-source="startup_current_status" bind-property="active" bind-flags="sync-create|invert-boolean">0</property>
+            <property name="factory">saved_presence_factory</property>
           </object>
         </child>
       </object>
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -241,7 +241,6 @@
 pidgin/gtknotify.c
 pidgin/gtkrequest.c
 pidgin/gtkroomlist.c
-pidgin/gtksavedstatuses.c
 pidgin/gtkutils.c
 pidgin/gtkwhiteboard.c
 pidgin/gtkxfer.c
