# HG changeset patch
# Node ID 5472c3c9d0d0
# Parent  64d7e69bff25
diff --git a/pidgin/prefs/pidginproxyprefs.c b/pidgin/prefs/pidginproxyprefs.c
--- a/pidgin/prefs/pidginproxyprefs.c
+++ b/pidgin/prefs/pidginproxyprefs.c
@@ -78,35 +78,19 @@
 }
 
 static void
-proxy_changed_cb(const gchar *name, PurplePrefType type, gconstpointer value,
-                 gpointer data)
-{
-	PidginProxyPrefs *prefs = data;
-	const char *proxy = value;
-
-	gtk_widget_set_visible(prefs->options,
-	                       !purple_strequal(proxy, "none") &&
-	                       !purple_strequal(proxy, "envvar"));
-}
-
-static void
-proxy_print_option(GtkWidget *entry, gpointer data)
+pidgin_proxy_prefs_type_changed_cb(GSettings *settings, char *key,
+                                   gpointer data)
 {
 	PidginProxyPrefs *prefs = data;
 
-	if (entry == prefs->host) {
-		purple_prefs_set_string("/purple/proxy/host",
-		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
-	} else if (entry == prefs->port) {
-		purple_prefs_set_int("/purple/proxy/port",
-				gtk_spin_button_get_value_as_int(
-					GTK_SPIN_BUTTON(entry)));
-	} else if (entry == prefs->username) {
-		purple_prefs_set_string("/purple/proxy/username",
-		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
-	} else if (entry == prefs->password) {
-		purple_prefs_set_string("/purple/proxy/password",
-		                        gtk_editable_get_text(GTK_EDITABLE(entry)));
+	if(purple_strequal(key, "type")) {
+		char *current = g_settings_get_string(settings, key);
+
+		gtk_widget_set_visible(prefs->options,
+		                       !purple_strequal(current, "No Proxy") &&
+		                       !purple_strequal(current, "Use Environmental Settings"));
+
+		g_free(current);
 	}
 }
 
@@ -124,6 +108,121 @@
 	g_error_free(err);
 }
 
+static gboolean
+pidgin_proxy_prefs_get_type_mapping(GValue *value, GVariant *variant,
+                                    G_GNUC_UNUSED gpointer data)
+{
+	const char *current = g_variant_get_string(variant, NULL);
+	guint position = 0;
+
+	/* The values for position are dependent on the order of the GtkStringList
+	 * in prefs/proxy.ui.
+	 */
+	if(purple_strequal(current, "No Proxy")) {
+		position = 0;
+	} else if(purple_strequal(current, "SOCKS4")) {
+		position = 1;
+	} else if(purple_strequal(current, "SOCKS5")) {
+		position = 2;
+	} else if(purple_strequal(current, "TOR")) {
+		position = 3;
+	} else if(purple_strequal(current, "HTTP")) {
+		position = 4;
+	} else if(purple_strequal(current, "Use Environmental Settings")) {
+		position = 5;
+	} else {
+		return FALSE;
+	}
+
+	g_value_set_uint(value, position);
+
+	return TRUE;
+}
+
+static GVariant *
+pidgin_proxy_prefs_set_type_mapping(const GValue *gvalue,
+                                    G_GNUC_UNUSED const GVariantType *expected_type,
+                                    G_GNUC_UNUSED gpointer data)
+{
+	guint position = g_value_get_uint(gvalue);
+
+	/* The index of these items is dependent on the order of the GtkStringList
+	 * in prefs/proxy.ui.
+	 */
+	const char *map[] = {
+		"No Proxy", "SOCKS4", "SOCKS5", "TOR", "HTTP",
+		"Use Environmental Settings",
+	};
+
+	if(position >= G_N_ELEMENTS(map)) {
+		return NULL;
+	}
+
+	return g_variant_new_string(map[position]);
+}
+
+static void
+pidgin_proxy_prefs_init_gnome(PidginProxyPrefs *prefs) {
+	gchar *path = NULL;
+
+	gtk_widget_set_visible(prefs->gnome, TRUE);
+	gtk_widget_set_visible(prefs->nongnome, FALSE);
+
+	path = g_find_program_in_path("gnome-network-properties");
+	if (path == NULL) {
+		path = g_find_program_in_path("gnome-network-preferences");
+	}
+	if (path == NULL) {
+		path = g_find_program_in_path("gnome-control-center");
+		if (path != NULL) {
+			char *tmp = g_strdup_printf("%s network", path);
+			g_free(path);
+			path = tmp;
+		}
+	}
+
+	prefs->gnome_program_path = path;
+	gtk_widget_set_visible(prefs->gnome_not_found, path == NULL);
+	gtk_widget_set_visible(prefs->gnome_program, path != NULL);
+}
+
+static void
+pidgin_proxy_prefs_init_non_gnome(PidginProxyPrefs *prefs) {
+	GSettings *settings = NULL;
+	gpointer settings_backend = NULL;
+
+	settings_backend = purple_core_get_settings_backend();
+	settings = g_settings_new_with_backend("im.pidgin.Purple.Proxy",
+	                                       settings_backend);
+
+	gtk_widget_set_visible(prefs->gnome, FALSE);
+	gtk_widget_set_visible(prefs->nongnome, TRUE);
+
+	g_settings_bind_with_mapping(settings, "type",
+	                             prefs->type, "selected",
+	                             G_SETTINGS_BIND_DEFAULT,
+	                             pidgin_proxy_prefs_get_type_mapping,
+	                             pidgin_proxy_prefs_set_type_mapping,
+	                             NULL,
+	                             NULL);
+
+	g_settings_bind(settings, "host", prefs->host, "text",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "port", prefs->port, "value",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "username", prefs->username, "text",
+	                G_SETTINGS_BIND_DEFAULT);
+	g_settings_bind(settings, "password", prefs->password, "text",
+	                G_SETTINGS_BIND_DEFAULT);
+
+	g_signal_connect_object(settings, "changed",
+	                        G_CALLBACK(pidgin_proxy_prefs_type_changed_cb),
+	                        prefs, 0);
+
+	/* Manually call the callback to set the initial visibility. */
+	pidgin_proxy_prefs_type_changed_cb(settings, "type", prefs);
+}
+
 /******************************************************************************
  * GObject Implementation
  *****************************************************************************/
@@ -177,79 +276,18 @@
 	                                        proxy_type_expression_cb);
 	gtk_widget_class_bind_template_callback(widget_class,
 	                                        proxy_row_activated_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
-			proxy_print_option);
 }
 
 static void
 pidgin_proxy_prefs_init(PidginProxyPrefs *prefs)
 {
-	PurpleProxyInfo *proxy_info;
 
 	gtk_widget_init_template(GTK_WIDGET(prefs));
 
 	if(purple_running_gnome()) {
-		gchar *path = NULL;
-
-		gtk_widget_set_visible(prefs->gnome, TRUE);
-		gtk_widget_set_visible(prefs->nongnome, FALSE);
-
-		path = g_find_program_in_path("gnome-network-properties");
-		if (path == NULL) {
-			path = g_find_program_in_path("gnome-network-preferences");
-		}
-		if (path == NULL) {
-			path = g_find_program_in_path("gnome-control-center");
-			if (path != NULL) {
-				char *tmp = g_strdup_printf("%s network", path);
-				g_free(path);
-				path = tmp;
-			}
-		}
-
-		prefs->gnome_program_path = path;
-		gtk_widget_set_visible(prefs->gnome_not_found, path == NULL);
-		gtk_widget_set_visible(prefs->gnome_program, path != NULL);
-
+		pidgin_proxy_prefs_init_gnome(prefs);
 	} else {
-		gtk_widget_set_visible(prefs->gnome, FALSE);
-		gtk_widget_set_visible(prefs->nongnome, TRUE);
-
-		pidgin_prefs_bind_combo_row("/purple/proxy/type", prefs->type);
-
-		proxy_info = purple_global_proxy_get_info();
-
-		purple_prefs_connect_callback(prefs, "/purple/proxy/type",
-				proxy_changed_cb, prefs);
-
-		if (proxy_info != NULL) {
-			const gchar *value = NULL;
-
-			value = purple_proxy_info_get_hostname(proxy_info);
-			if(value != NULL) {
-				gtk_editable_set_text(GTK_EDITABLE(prefs->host), value);
-			}
-
-			if (purple_proxy_info_get_port(proxy_info) != 0) {
-				gtk_spin_button_set_value(
-						GTK_SPIN_BUTTON(prefs->port),
-						purple_proxy_info_get_port(proxy_info));
-			}
-
-			value = purple_proxy_info_get_username(proxy_info);
-			if(value != NULL) {
-				gtk_editable_set_text(GTK_EDITABLE(prefs->username), value);
-			}
-
-			value = purple_proxy_info_get_password(proxy_info);
-			if(value != NULL) {
-				gtk_editable_set_text(GTK_EDITABLE(prefs->password), value);
-			}
-		}
-
-		proxy_changed_cb("/purple/proxy/type", PURPLE_PREF_STRING,
-			purple_prefs_get_string("/purple/proxy/type"),
-			prefs);
+		pidgin_proxy_prefs_init_non_gnome(prefs);
 	}
 }
 
@@ -258,5 +296,5 @@
  *****************************************************************************/
 GtkWidget *
 pidgin_proxy_prefs_new(void) {
-	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_PROXY_PREFS, NULL));
+	return g_object_new(PIDGIN_TYPE_PROXY_PREFS, NULL);
 }
diff --git a/pidgin/resources/Prefs/proxy.ui b/pidgin/resources/Prefs/proxy.ui
--- a/pidgin/resources/Prefs/proxy.ui
+++ b/pidgin/resources/Prefs/proxy.ui
@@ -53,14 +53,18 @@
     <child>
       <object class="AdwPreferencesGroup" id="nongnome">
         <property name="title" translatable="1">Proxy Server</property>
+        <property name="focusable">0</property>
         <child>
           <object class="AdwComboRow" id="type">
             <property name="title" translatable="1">Proxy t_ype</property>
             <property name="use-subtitle">1</property>
             <property name="use-underline">1</property>
+            <property name="focusable">1</property>
             <property name="model">
               <object class="GtkStringList">
                 <items>
+                  <!-- the order of this list must be consistent with
+                       prefs/pidginproxyprefs.c at all times. -->
                   <item>none</item>
                   <item>socks4</item>
                   <item>socks5</item>
@@ -77,6 +81,7 @@
         </child>
         <child>
           <object class="AdwPreferencesRow" id="options">
+            <property name="focusable">0</property>
             <child>
               <object class="GtkListBox">
                 <child>
@@ -84,12 +89,12 @@
                     <property name="activatable-widget">host</property>
                     <property name="title" translatable="1">_Host</property>
                     <property name="use-underline">1</property>
+                    <property name="focusable">0</property>
                     <child>
                       <object class="GtkEntry" id="host">
                         <property name="focusable">1</property>
                         <property name="hexpand">1</property>
                         <property name="valign">center</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -99,6 +104,7 @@
                     <property name="activatable-widget">port</property>
                     <property name="title" translatable="1">P_ort</property>
                     <property name="use-underline">1</property>
+                    <property name="focusable">0</property>
                     <child>
                       <object class="GtkSpinButton" id="port">
                         <property name="focusable">1</property>
@@ -113,7 +119,6 @@
                         <property name="numeric">1</property>
                         <property name="hexpand">1</property>
                         <property name="valign">center</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -123,12 +128,12 @@
                     <property name="activatable-widget">username</property>
                     <property name="title" translatable="1">User_name</property>
                     <property name="use-underline">1</property>
+                    <property name="focusable">0</property>
                     <child>
                       <object class="GtkEntry" id="username">
                         <property name="focusable">1</property>
                         <property name="hexpand">1</property>
                         <property name="valign">center</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -138,13 +143,13 @@
                     <property name="activatable-widget">password</property>
                     <property name="title" translatable="1">Pa_ssword</property>
                     <property name="use-underline">1</property>
+                    <property name="focusable">0</property>
                     <child>
                       <object class="GtkPasswordEntry" id="password">
                         <property name="focusable">1</property>
                         <property name="hexpand">1</property>
                         <property name="show-peek-icon">1</property>
                         <property name="valign">center</property>
-                        <signal name="changed" handler="proxy_print_option" object="PidginProxyPrefs" swapped="no"/>
                       </object>
                     </child>
                   </object>
