# HG changeset patch
# Node ID b777d9a3e429
# Parent  24e5305ebcb6
diff --git a/pidgin/meson.build b/pidgin/meson.build
--- a/pidgin/meson.build
+++ b/pidgin/meson.build
@@ -58,7 +58,6 @@
 	'pidginstatuseditor.c',
 	'pidginstatusmanager.c',
 	'pidginstatusprimitivechooser.c',
-	'pidginstatusprimitivestore.c',
 	'pidgintalkatu.c',
 	'pidginui.c',
 	'prefs/pidginprefs.c',
@@ -126,7 +125,6 @@
 	'pidginstatuseditor.h',
 	'pidginstatusmanager.h',
 	'pidginstatusprimitivechooser.h',
-	'pidginstatusprimitivestore.h',
 	'pidgintalkatu.h',
 	'pidginui.h',
 ]
diff --git a/pidgin/pidginstatusprimitivechooser.h b/pidgin/pidginstatusprimitivechooser.h
--- a/pidgin/pidginstatusprimitivechooser.h
+++ b/pidgin/pidginstatusprimitivechooser.h
@@ -29,6 +29,8 @@
 
 #include <gtk/gtk.h>
 
+#include <adwaita.h>
+
 #include <purple.h>
 
 G_BEGIN_DECLS
@@ -45,7 +47,7 @@
 #define PIDGIN_TYPE_STATUS_PRIMITIVE_CHOOSER (pidgin_status_primitive_chooser_get_type())
 G_DECLARE_FINAL_TYPE(PidginStatusPrimitiveChooser,
                      pidgin_status_primitive_chooser, PIDGIN,
-                     STATUS_PRIMITIVE_CHOOSER, GtkComboBox)
+                     STATUS_PRIMITIVE_CHOOSER, AdwBin)
 
 /**
  * pidgin_status_primitive_chooser_new:
diff --git a/pidgin/pidginstatusprimitivechooser.c b/pidgin/pidginstatusprimitivechooser.c
--- a/pidgin/pidginstatusprimitivechooser.c
+++ b/pidgin/pidginstatusprimitivechooser.c
@@ -22,17 +22,81 @@
 
 #include <pidgin/pidginstatusprimitivechooser.h>
 
+#include <pidgin/pidginiconname.h>
+
 struct _PidginStatusPrimitiveChooser {
-	GtkComboBox parent;
+	AdwBin parent;
+
+	GtkDropDown *chooser;
 };
 
 G_DEFINE_TYPE(PidginStatusPrimitiveChooser, pidgin_status_primitive_chooser,
-              GTK_TYPE_COMBO_BOX)
+              ADW_TYPE_BIN)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static PurpleStatusPrimitive
+pidgin_status_primitive_chooser_primitive_from_string(const char *str) {
+	if(purple_strequal(str, "offline")) {
+		return PURPLE_STATUS_OFFLINE;
+	} else if(purple_strequal(str, "available")) {
+		return PURPLE_STATUS_AVAILABLE;
+	} else if(purple_strequal(str, "unavailable")) {
+		return PURPLE_STATUS_UNAVAILABLE;
+	} else if(purple_strequal(str, "invisible")) {
+		return PURPLE_STATUS_INVISIBLE;
+	} else if(purple_strequal(str, "away")) {
+		return PURPLE_STATUS_AWAY;
+	} else if(purple_strequal(str, "extended-away")) {
+		return PURPLE_STATUS_EXTENDED_AWAY;
+	}
+
+	return PURPLE_STATUS_UNSET;
+}
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static char *
+pidgin_status_primitive_chooser_icon_name_cb(G_GNUC_UNUSED GObject *self,
+                                             GtkStringObject *object,
+                                             G_GNUC_UNUSED gpointer data)
+{
+	PurpleStatusPrimitive primitive = PURPLE_STATUS_UNSET;
+	const char *value = NULL;
+
+	if(!GTK_IS_STRING_OBJECT(object)) {
+		return NULL;
+	}
+
+	value = gtk_string_object_get_string(object);
+	primitive = pidgin_status_primitive_chooser_primitive_from_string(value);
+
+	return g_strdup(pidgin_icon_name_from_status_primitive(primitive, NULL));
+}
+
+static char *
+pidgin_status_primitive_chooser_label_cb(G_GNUC_UNUSED GObject *self,
+                                         GtkStringObject *object,
+                                         G_GNUC_UNUSED gpointer data)
+{
+	PurpleStatusPrimitive primitive = PURPLE_STATUS_UNSET;
+	const char *value = NULL;
+
+	if(!GTK_IS_STRING_OBJECT(object)) {
+		return NULL;
+	}
+
+	value = gtk_string_object_get_string(object);
+	primitive = pidgin_status_primitive_chooser_primitive_from_string(value);
+
+	return g_strdup(purple_primitive_get_name_from_type(primitive));
+}
 
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
-
 static void
 pidgin_status_primitive_chooser_init(PidginStatusPrimitiveChooser *chooser) {
 	gtk_widget_init_template(GTK_WIDGET(chooser));
@@ -45,6 +109,15 @@
 	/* Widget template */
 	gtk_widget_class_set_template_from_resource(
 	        widget_class, "/im/pidgin/Pidgin3/statusprimitivechooser.ui");
+
+	gtk_widget_class_bind_template_child(widget_class,
+	                                     PidginStatusPrimitiveChooser,
+	                                     chooser);
+
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_status_primitive_chooser_icon_name_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        pidgin_status_primitive_chooser_label_cb);
 }
 
 /******************************************************************************
@@ -57,25 +130,40 @@
 
 PurpleStatusPrimitive
 pidgin_status_primitive_chooser_get_selected(PidginStatusPrimitiveChooser *chooser) {
-    const gchar *active_id = NULL;
+	GtkStringObject *selected = NULL;
+	const char *value = NULL;
 
-    g_return_val_if_fail(PIDGIN_IS_STATUS_PRIMITIVE_CHOOSER(chooser),
-                         PURPLE_STATUS_UNSET);
+	g_return_val_if_fail(PIDGIN_IS_STATUS_PRIMITIVE_CHOOSER(chooser),
+	                     PURPLE_STATUS_UNSET);
 
-    active_id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(chooser));
+	selected = gtk_drop_down_get_selected_item(chooser->chooser);
+	value = gtk_string_object_get_string(selected);
 
-    return purple_primitive_get_type_from_id(active_id);
+	return pidgin_status_primitive_chooser_primitive_from_string(value);
 }
 
 void
 pidgin_status_primitive_chooser_set_selected(PidginStatusPrimitiveChooser *chooser,
                                              PurpleStatusPrimitive primitive)
 {
-    const gchar *active_id = NULL;
+	GListModel *model = NULL;
+
+	g_return_if_fail(PIDGIN_IS_STATUS_PRIMITIVE_CHOOSER(chooser));
 
-    g_return_if_fail(PIDGIN_IS_STATUS_PRIMITIVE_CHOOSER(chooser));
+	model = gtk_drop_down_get_model(chooser->chooser);
+	for(guint i = 0; i < g_list_model_get_n_items(model); i++) {
+		PurpleStatusPrimitive candidate = PURPLE_STATUS_UNSET;
+		GtkStringObject *str = NULL;
+		const char *value = NULL;
 
-    active_id = purple_primitive_get_id_from_type(primitive);
+		str = g_list_model_get_item(model, i);
+		value = gtk_string_object_get_string(str);
+
+		candidate = pidgin_status_primitive_chooser_primitive_from_string(value);
+		g_clear_object(&str);
 
-    gtk_combo_box_set_active_id(GTK_COMBO_BOX(chooser), active_id);
+		if(primitive == candidate) {
+			gtk_drop_down_set_selected(chooser->chooser, i);
+		}
+	}
 }
diff --git a/pidgin/pidginstatusprimitivestore.h b/pidgin/pidginstatusprimitivestore.h
deleted file mode 100644
--- a/pidgin/pidginstatusprimitivestore.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Pidgin - Internet Messenger
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * 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, see <https://www.gnu.org/licenses/>.
- */
-
-#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION)
-# error "only <pidgin.h> may be included directly"
-#endif
-
-#ifndef PIDGIN_STATUS_PRIMITIVE_STORE_H
-#define PIDGIN_STATUS_PRIMITIVE_STORE_H
-
-#include <gtk/gtk.h>
-
-#include <purple.h>
-
-G_BEGIN_DECLS
-
-/**
- * PidginStatusPrimitiveStore:
- *
- * A [class@Gtk.ListStore] for use with [class@PidginStatusPrimitiveChooser].
- *
- * Since: 3.0.0
- */
-
-#define PIDGIN_TYPE_STATUS_PRIMITIVE_STORE (pidgin_status_primitive_store_get_type())
-G_DECLARE_FINAL_TYPE(PidginStatusPrimitiveStore, pidgin_status_primitive_store,
-                     PIDGIN, STATUS_PRIMITIVE_STORE, GtkListStore)
-
-/**
- * pidgin_status_primitive_store_new:
- *
- * Creates a new [class@Gtk.ListStore] that contains status primitives in
- * purple.
- *
- * Returns: (transfer full): The new list store.
- *
- * Since: 3.0.0
- */
-GtkListStore *pidgin_status_primitive_store_new(void);
-
-/**
- * pidgin_status_primitive_store_set_account:
- * @store: The status primitive store instance.
- * @account: (nullable): The account to use.
- *
- * Sets the [class@Purple.Account] whose status primitives to show. If %NULL,
- * all status primitives will be displayed.
- *
- * Since: 3.0.0
- */
-void pidgin_status_primitive_store_set_account(PidginStatusPrimitiveStore *store, PurpleAccount *account);
-
-/**
- * pidgin_status_primitive_store_get_account:
- * @store: The store instance.
- *
- * Gets the [class@Purple.Account] that's associated with @store.
- *
- * Returns: (transfer none): The account of %NULL.
- *
- * Since: 3.0.0
- */
-PurpleAccount *pidgin_status_primitive_store_get_account(PidginStatusPrimitiveStore *store);
-
-G_END_DECLS
-
-#endif /* PIDGIN_STATUS_PRIMITIVE_STORE_H */
diff --git a/pidgin/pidginstatusprimitivestore.c b/pidgin/pidginstatusprimitivestore.c
deleted file mode 100644
--- a/pidgin/pidginstatusprimitivestore.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Pidgin - Internet Messenger
- * Copyright (C) Pidgin Developers <devel@pidgin.im>
- *
- * 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, see <https://www.gnu.org/licenses/>.
- */
-
-#include <pidgin/pidginstatusprimitivestore.h>
-
-#include <pidgin/pidginiconname.h>
-
-struct _PidginStatusPrimitiveStore {
-	GtkListStore parent;
-
-	PurpleAccount *account;
-};
-
-enum {
-	PROP_0,
-	PROP_ACCOUNT,
-	N_PROPERTIES,
-};
-static GParamSpec *properties[N_PROPERTIES] = { NULL, };
-
-enum {
-	COL_ID,
-	COL_ICON,
-	COL_TEXT,
-	N_COLUMNS,
-};
-
-G_DEFINE_TYPE(PidginStatusPrimitiveStore, pidgin_status_primitive_store,
-              GTK_TYPE_LIST_STORE)
-
-/******************************************************************************
- * Helpers
- *****************************************************************************/
-static GList *
-pidgin_status_primitive_store_get_primitives_from_account(PidginStatusPrimitiveStore *store)
-{
-	GList *primitives = NULL;
-	GList *list = purple_account_get_status_types(store->account);
-
-	while(list != NULL) {
-		PurpleStatusType *type = (PurpleStatusType *)list->data;
-		PurpleStatusPrimitive primitive;
-		gboolean user_settable = FALSE, independent = FALSE;
-
-		/* iterate to the next item as we already have the data in type. */
-		list = list->next;
-
-		user_settable = purple_status_type_is_user_settable(type);
-		independent = purple_status_type_is_independent(type);
-		if(!user_settable || independent) {
-			continue;
-		}
-
-		primitive = purple_status_type_get_primitive(type);
-
-		primitives = g_list_append(primitives, GINT_TO_POINTER(primitive));
-	}
-
-	return primitives;
-}
-
-static GList *
-pidgin_status_primitive_store_get_primitives(PidginStatusPrimitiveStore *store)
-{
-	GList *primitives = NULL;
-
-	primitives = g_list_append(primitives,
-	                           GINT_TO_POINTER(PURPLE_STATUS_OFFLINE));
-	primitives = g_list_append(primitives,
-	                           GINT_TO_POINTER(PURPLE_STATUS_AVAILABLE));
-	primitives = g_list_append(primitives,
-	                           GINT_TO_POINTER(PURPLE_STATUS_UNAVAILABLE));
-	primitives = g_list_append(primitives,
-	                           GINT_TO_POINTER(PURPLE_STATUS_INVISIBLE));
-	primitives = g_list_append(primitives,
-	                           GINT_TO_POINTER(PURPLE_STATUS_AWAY));
-	primitives = g_list_append(primitives,
-	                           GINT_TO_POINTER(PURPLE_STATUS_EXTENDED_AWAY));
-
-	return primitives;
-}
-
-static void
-pidgin_status_primitive_store_populate(PidginStatusPrimitiveStore *store) {
-	GList *primitives = NULL;
-
-	/* clear out the list */
-	gtk_list_store_clear(GTK_LIST_STORE(store));
-
-	/* Get all the primitives and add them. */
-	if(PURPLE_IS_ACCOUNT(store->account)) {
-		primitives = pidgin_status_primitive_store_get_primitives_from_account(store);
-	} else {
-		primitives = pidgin_status_primitive_store_get_primitives(store);
-	}
-
-	while(primitives != NULL) {
-		PurpleStatusPrimitive primitive = GPOINTER_TO_INT(primitives->data);
-		GtkTreeIter iter;
-
-		gtk_list_store_append(GTK_LIST_STORE(store), &iter);
-		/* clang-format off */
-		gtk_list_store_set(
-			GTK_LIST_STORE(store), &iter,
-			COL_ID, purple_primitive_get_id_from_type(primitive),
-			COL_ICON, pidgin_icon_name_from_status_primitive(primitive, NULL),
-			COL_TEXT, purple_primitive_get_name_from_type(primitive),
-			-1);
-		/* clang-format on */
-
-		primitives = g_list_delete_link(primitives, primitives);
-	}
-}
-
-/******************************************************************************
- * GObject Implementation
- *****************************************************************************/
-
-static void
-pidgin_status_primitive_store_get_property(GObject *obj, guint param_id,
-                                           GValue *value, GParamSpec *pspec)
-{
-	PidginStatusPrimitiveStore *store = PIDGIN_STATUS_PRIMITIVE_STORE(obj);
-
-	switch(param_id) {
-		case PROP_ACCOUNT:
-			g_value_set_object(value,
-			                   pidgin_status_primitive_store_get_account(store));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-static void
-pidgin_status_primitive_store_set_property(GObject *obj, guint param_id,
-                                           const GValue *value,
-                                           GParamSpec *pspec)
-{
-	PidginStatusPrimitiveStore *store = PIDGIN_STATUS_PRIMITIVE_STORE(obj);
-
-	switch(param_id) {
-		case PROP_ACCOUNT:
-			pidgin_status_primitive_store_set_account(store,
-			                                          g_value_get_object(value));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-static void
-pidgin_status_primitive_store_dispose(GObject *obj) {
-	PidginStatusPrimitiveStore *store = PIDGIN_STATUS_PRIMITIVE_STORE(obj);
-
-	g_clear_object(&store->account);
-
-	G_OBJECT_CLASS(pidgin_status_primitive_store_parent_class)->dispose(obj);
-}
-
-static void
-pidgin_status_primitive_store_constructed(GObject *obj) {
-	PidginStatusPrimitiveStore *store = PIDGIN_STATUS_PRIMITIVE_STORE(obj);
-
-	G_OBJECT_CLASS(pidgin_status_primitive_store_parent_class)->constructed(obj);
-
-	/* This exists to populate the store if it was created without a value for
-	 * the account property.
-	 */
-	pidgin_status_primitive_store_populate(store);
-}
-
-static void
-pidgin_status_primitive_store_init(PidginStatusPrimitiveStore *store) {
-	GType types[N_COLUMNS] = { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING };
-
-	gtk_list_store_set_column_types(GTK_LIST_STORE(store), N_COLUMNS, types);
-}
-
-static void
-pidgin_status_primitive_store_class_init(PidginStatusPrimitiveStoreClass *klass) {
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
-	obj_class->get_property = pidgin_status_primitive_store_get_property;
-	obj_class->set_property = pidgin_status_primitive_store_set_property;
-	obj_class->constructed = pidgin_status_primitive_store_constructed;
-	obj_class->dispose = pidgin_status_primitive_store_dispose;
-
-	/**
-	 * PidginStatusPrimitiveStore:account:
-	 *
-	 * The account whose statuses to display.
-	 *
-	 * Since: 3.0.0
-	 */
-	/* clang-format off */
-	properties[PROP_ACCOUNT] = g_param_spec_object(
-		"account", "account",
-		"The account whose statuses to display",
-		PURPLE_TYPE_ACCOUNT,
-		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-	/* clang-format on */
-
-	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
-}
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-GtkListStore *
-pidgin_status_primitive_store_new(void) {
-	return g_object_new(PIDGIN_TYPE_STATUS_PRIMITIVE_STORE, NULL);
-}
-
-void
-pidgin_status_primitive_store_set_account(PidginStatusPrimitiveStore *store,
-                                          PurpleAccount *account)
-{
-	g_return_if_fail(PIDGIN_IS_STATUS_PRIMITIVE_STORE(store));
-
-	if(g_set_object(&store->account, account)) {
-		pidgin_status_primitive_store_populate(store);
-
-		g_object_notify_by_pspec(G_OBJECT(store), properties[PROP_ACCOUNT]);
-	}
-}
-
-PurpleAccount *
-pidgin_status_primitive_store_get_account(PidginStatusPrimitiveStore *store) {
-	g_return_val_if_fail(PIDGIN_IS_STATUS_PRIMITIVE_STORE(store), NULL);
-
-	return store->account;
-}
diff --git a/pidgin/resources/Status/editor.ui b/pidgin/resources/Status/editor.ui
--- a/pidgin/resources/Status/editor.ui
+++ b/pidgin/resources/Status/editor.ui
@@ -72,8 +72,6 @@
                 <child>
                   <object class="PidginStatusPrimitiveChooser" id="primitive">
                     <property name="hexpand">1</property>
-                    <property name="id-column">0</property>
-                    <property name="model">primitive_store</property>
                   </object>
                 </child>
               </object>
@@ -160,5 +158,4 @@
     </widgets>
   </object>
   <object class="TalkatuHtmlBuffer" id="buffer"/>
-  <object class="PidginStatusPrimitiveStore" id="primitive_store"/>
 </interface>
diff --git a/pidgin/resources/statusprimitivechooser.ui b/pidgin/resources/statusprimitivechooser.ui
--- a/pidgin/resources/statusprimitivechooser.ui
+++ b/pidgin/resources/statusprimitivechooser.ui
@@ -24,19 +24,60 @@
   <!-- interface-name Pidgin -->
   <!-- interface-description Internet Messenger -->
   <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
-  <template class="PidginStatusPrimitiveChooser" parent="GtkComboBox">
-    <property name="id-column">0</property>
-    <child>
-      <object class="GtkCellRendererPixbuf"/>
-      <attributes>
-        <attribute name="icon-name">1</attribute>
-      </attributes>
-    </child>
-    <child>
-      <object class="GtkCellRendererText"/>
-      <attributes>
-        <attribute name="markup">2</attribute>
-      </attributes>
-    </child>
+  <template class="PidginStatusPrimitiveChooser" parent="AdwBin">
+    <property name="child">
+      <object class="GtkDropDown" id="chooser">
+        <property name="factory">
+          <object class="GtkBuilderListItemFactory">
+            <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="pidgin_status_primitive_chooser_icon_name_cb">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="xalign">0</property>
+            <binding name="label">
+              <closure type="gchararray" function="pidgin_status_primitive_chooser_label_cb">
+                <lookup name="item">GtkListItem</lookup>
+              </closure>
+            </binding>
+          </object>
+        </child>
+      </object>
+    </property>
   </template>
 </interface>
+]]>
+            </property>
+          </object>
+        </property>
+        <property name="model">
+          <object class="GtkStringList">
+            <items>
+              <item>offline</item>
+              <item>available</item>
+              <item>unavailable</item>
+              <item>invisible</item>
+              <item>away</item>
+              <item>extended-away</item>
+            </items>
+          </object>
+        </property>
+      </object>
+    </property>
+  </template>
+</interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -294,7 +294,6 @@
 pidgin/pidginstatuseditor.c
 pidgin/pidginstatusmanager.c
 pidgin/pidginstatusprimitivechooser.c
-pidgin/pidginstatusprimitivestore.c
 pidgin/pidgintalkatu.c
 pidgin/plugins/disco/gtkdisco.c
 pidgin/plugins/disco/resources/disco.ui
