# HG changeset patch
# Node ID 58859eada745
# Parent  00fbef19d730
diff --git a/pidgin/meson.build b/pidgin/meson.build
--- a/pidgin/meson.build
+++ b/pidgin/meson.build
@@ -63,6 +63,7 @@ libpidgin_SOURCES = [
 	'prefs/pidginawaypage.c',
 	'prefs/pidgincredentialproviderrow.c',
 	'prefs/pidgincredentialspage.c',
+	'prefs/pidginnetworkpage.c',
 ]
 
 libpidgin_headers = [
@@ -132,6 +133,7 @@ libpidgin_prefs_headers = [
 	'prefs/pidginawaypage.h',
 	'prefs/pidgincredentialproviderrow.h',
 	'prefs/pidgincredentialspage.h',
+	'prefs/pidginnetworkpage.h',
 ]
 
 libpidgin_enum_headers = [
diff --git a/pidgin/prefs/pidginnetworkpage.h b/pidgin/prefs/pidginnetworkpage.h
new file mode 100644
--- /dev/null
+++ b/pidgin/prefs/pidginnetworkpage.h
@@ -0,0 +1,62 @@
+/*
+ * 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_NETWORK_PAGE_H
+#define PIDGIN_NETWORK_PAGE_H
+
+#include <glib.h>
+
+#include <gtk/gtk.h>
+#include <handy.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PidginNetworkPage:
+ *
+ * #PidginNetworkPage is a widget for the preferences window to let users
+ * choose and configure their network settings.
+ *
+ * Since: 3.0.0
+ */
+#define PIDGIN_TYPE_NETWORK_PAGE (pidgin_network_page_get_type())
+G_DECLARE_FINAL_TYPE(PidginNetworkPage, pidgin_network_page,
+                     PIDGIN, NETWORK_PAGE, HdyPreferencesPage)
+
+/**
+ * pidgin_network_page_new:
+ *
+ * Creates a new #PidginNetworkPage instance.
+ *
+ * Returns: (transfer full): The new #PidginNetworkPage instance.
+ *
+ * Since: 3.0.0
+ */
+GtkWidget *pidgin_network_page_new(void);
+
+G_END_DECLS
+
+#endif /* PIDGIN_NETWORK_PAGE_H */
diff --git a/pidgin/prefs/pidginnetworkpage.c b/pidgin/prefs/pidginnetworkpage.c
new file mode 100644
--- /dev/null
+++ b/pidgin/prefs/pidginnetworkpage.c
@@ -0,0 +1,262 @@
+/*
+ * 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 <glib/gi18n-lib.h>
+
+#include <purple.h>
+
+#include <handy.h>
+#include <nice.h>
+
+#include "pidginnetworkpage.h"
+#include "pidginprefsinternal.h"
+
+struct _PidginNetworkPage {
+	HdyPreferencesPage parent;
+
+	GtkWidget *stun_server;
+	GtkWidget *auto_ip;
+	GtkWidget *public_ip;
+	GtkWidget *public_ip_hbox;
+	GtkWidget *map_ports;
+	GtkWidget *ports_range_use;
+	GtkWidget *ports_range_hbox;
+	GtkWidget *ports_range_start;
+	GtkWidget *ports_range_end;
+	GtkWidget *turn_server;
+	GtkWidget *turn_port_udp;
+	GtkWidget *turn_port_tcp;
+	GtkWidget *turn_username;
+	GtkWidget *turn_password;
+};
+
+G_DEFINE_TYPE(PidginNetworkPage, pidgin_network_page, HDY_TYPE_PREFERENCES_PAGE)
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+network_ip_changed(GtkEntry *entry, gpointer data)
+{
+	const gchar *text = gtk_entry_get_text(entry);
+	GtkStyleContext *context = gtk_widget_get_style_context(GTK_WIDGET(entry));
+
+	if (text && *text) {
+		if (g_hostname_is_ip_address(text)) {
+			purple_network_set_public_ip(text);
+			gtk_style_context_add_class(context, "good-ip");
+			gtk_style_context_remove_class(context, "bad-ip");
+		} else {
+			gtk_style_context_add_class(context, "bad-ip");
+			gtk_style_context_remove_class(context, "good-ip");
+		}
+
+	} else {
+		purple_network_set_public_ip("");
+		gtk_style_context_remove_class(context, "bad-ip");
+		gtk_style_context_remove_class(context, "good-ip");
+	}
+}
+
+static gboolean
+network_stun_server_changed_cb(GtkWidget *widget,
+                               GdkEventFocus *event, gpointer data)
+{
+	GtkEntry *entry = GTK_ENTRY(widget);
+	purple_prefs_set_string("/purple/network/stun_server",
+		gtk_entry_get_text(entry));
+	purple_network_set_stun_server(gtk_entry_get_text(entry));
+
+	return FALSE;
+}
+
+static gboolean
+network_turn_server_changed_cb(GtkWidget *widget,
+                               GdkEventFocus *event, gpointer data)
+{
+	GtkEntry *entry = GTK_ENTRY(widget);
+	purple_prefs_set_string("/purple/network/turn_server",
+		gtk_entry_get_text(entry));
+	purple_network_set_turn_server(gtk_entry_get_text(entry));
+
+	return FALSE;
+}
+
+static void
+auto_ip_button_clicked_cb(GtkWidget *button, gpointer null)
+{
+	const char *ip;
+	PurpleStunNatDiscovery *stun;
+	char *auto_ip_text;
+	GList *list = NULL;
+
+	/* Make a lookup for the auto-detected IP ourselves. */
+	if (purple_prefs_get_bool("/purple/network/auto_ip")) {
+		/* Check if STUN discovery was already done */
+		stun = purple_stun_discover(NULL);
+		if ((stun != NULL) && (stun->status == PURPLE_STUN_STATUS_DISCOVERED)) {
+			ip = stun->publicip;
+		} else {
+			/* Attempt to get the IP from a NAT device using UPnP */
+			ip = purple_upnp_get_public_ip();
+			if (ip == NULL) {
+				/* Attempt to get the IP from a NAT device using NAT-PMP */
+				ip = purple_pmp_get_public_ip();
+				if (ip == NULL) {
+					/* Just fetch the first IP of the local system */
+					list = nice_interfaces_get_local_ips(FALSE);
+					if (list) {
+						ip = list->data;
+					} else {
+						ip = "0.0.0.0";
+					}
+				}
+			}
+		}
+	} else {
+		ip = _("Disabled");
+	}
+
+	auto_ip_text = g_strdup_printf(_("Use _automatically detected IP address: %s"), ip);
+	gtk_button_set_label(GTK_BUTTON(button), auto_ip_text);
+	g_free(auto_ip_text);
+	g_list_free_full(list, g_free);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+static void
+pidgin_network_page_class_init(PidginNetworkPageClass *klass)
+{
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
+	gtk_widget_class_set_template_from_resource(
+		widget_class,
+		"/im/pidgin/Pidgin3/Prefs/network.ui"
+	);
+
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, stun_server);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, auto_ip);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, public_ip);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, public_ip_hbox);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, map_ports);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, ports_range_use);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, ports_range_hbox);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, ports_range_start);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, ports_range_end);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, turn_server);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, turn_port_udp);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, turn_port_tcp);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, turn_username);
+	gtk_widget_class_bind_template_child(
+			widget_class, PidginNetworkPage, turn_password);
+	gtk_widget_class_bind_template_callback(widget_class,
+			network_stun_server_changed_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                 auto_ip_button_clicked_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+			network_ip_changed);
+	gtk_widget_class_bind_template_callback(widget_class,
+			network_turn_server_changed_cb);
+}
+
+static void
+pidgin_network_page_init(PidginNetworkPage *page)
+{
+	GtkStyleContext *context;
+	GtkCssProvider *ip_css;
+
+	gtk_widget_init_template(GTK_WIDGET(page));
+
+	gtk_entry_set_text(GTK_ENTRY(page->stun_server),
+			purple_prefs_get_string("/purple/network/stun_server"));
+
+	pidgin_prefs_bind_checkbox("/purple/network/auto_ip", page->auto_ip);
+	auto_ip_button_clicked_cb(page->auto_ip, NULL); /* Update label */
+
+	gtk_entry_set_text(GTK_ENTRY(page->public_ip),
+			purple_network_get_public_ip());
+
+	ip_css = gtk_css_provider_new();
+	gtk_css_provider_load_from_resource(ip_css,
+	                                    "/im/pidgin/Pidgin3/Prefs/ip.css");
+
+	context = gtk_widget_get_style_context(page->public_ip);
+	gtk_style_context_add_provider(context,
+	                               GTK_STYLE_PROVIDER(ip_css),
+	                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+	g_object_bind_property(page->auto_ip, "active",
+			page->public_ip_hbox, "sensitive",
+			G_BINDING_SYNC_CREATE|G_BINDING_INVERT_BOOLEAN);
+
+	pidgin_prefs_bind_checkbox("/purple/network/map_ports",
+			page->map_ports);
+
+	pidgin_prefs_bind_checkbox("/purple/network/ports_range_use",
+			page->ports_range_use);
+	g_object_bind_property(page->ports_range_use, "active",
+			page->ports_range_hbox, "sensitive",
+			G_BINDING_SYNC_CREATE);
+
+	pidgin_prefs_bind_spin_button("/purple/network/ports_range_start",
+			page->ports_range_start);
+	pidgin_prefs_bind_spin_button("/purple/network/ports_range_end",
+			page->ports_range_end);
+
+	/* TURN server */
+	gtk_entry_set_text(GTK_ENTRY(page->turn_server),
+			purple_prefs_get_string("/purple/network/turn_server"));
+
+	pidgin_prefs_bind_spin_button("/purple/network/turn_port",
+			page->turn_port_udp);
+
+	pidgin_prefs_bind_spin_button("/purple/network/turn_port_tcp",
+			page->turn_port_tcp);
+
+	pidgin_prefs_bind_entry("/purple/network/turn_username",
+			page->turn_username);
+	pidgin_prefs_bind_entry("/purple/network/turn_password",
+			page->turn_password);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GtkWidget *
+pidgin_network_page_new(void) {
+	return GTK_WIDGET(g_object_new(PIDGIN_TYPE_NETWORK_PAGE, NULL));
+}
diff --git a/pidgin/prefs/pidginprefs.c b/pidgin/prefs/pidginprefs.c
--- a/pidgin/prefs/pidginprefs.c
+++ b/pidgin/prefs/pidginprefs.c
@@ -70,24 +70,6 @@ struct _PidginPrefsWindow {
 		GtkWidget *format_view;
 	} conversations;
 
-	/* Network page */
-	struct {
-		GtkWidget *stun_server;
-		GtkWidget *auto_ip;
-		GtkWidget *public_ip;
-		GtkWidget *public_ip_hbox;
-		GtkWidget *map_ports;
-		GtkWidget *ports_range_use;
-		GtkWidget *ports_range_hbox;
-		GtkWidget *ports_range_start;
-		GtkWidget *ports_range_end;
-		GtkWidget *turn_server;
-		GtkWidget *turn_port_udp;
-		GtkWidget *turn_port_tcp;
-		GtkWidget *turn_username;
-		GtkWidget *turn_password;
-	} network;
-
 	/* Proxy page */
 	struct {
 		GtkWidget *stack;
@@ -771,53 +753,6 @@ bind_conv_page(PidginPrefsWindow *win)
 }
 
 static void
-network_ip_changed(GtkEntry *entry, gpointer data)
-{
-	const gchar *text = gtk_entry_get_text(entry);
-	GtkStyleContext *context = gtk_widget_get_style_context(GTK_WIDGET(entry));
-
-	if (text && *text) {
-		if (g_hostname_is_ip_address(text)) {
-			purple_network_set_public_ip(text);
-			gtk_style_context_add_class(context, "good-ip");
-			gtk_style_context_remove_class(context, "bad-ip");
-		} else {
-			gtk_style_context_add_class(context, "bad-ip");
-			gtk_style_context_remove_class(context, "good-ip");
-		}
-
-	} else {
-		purple_network_set_public_ip("");
-		gtk_style_context_remove_class(context, "bad-ip");
-		gtk_style_context_remove_class(context, "good-ip");
-	}
-}
-
-static gboolean
-network_stun_server_changed_cb(GtkWidget *widget,
-                               GdkEventFocus *event, gpointer data)
-{
-	GtkEntry *entry = GTK_ENTRY(widget);
-	purple_prefs_set_string("/purple/network/stun_server",
-		gtk_entry_get_text(entry));
-	purple_network_set_stun_server(gtk_entry_get_text(entry));
-
-	return FALSE;
-}
-
-static gboolean
-network_turn_server_changed_cb(GtkWidget *widget,
-                               GdkEventFocus *event, gpointer data)
-{
-	GtkEntry *entry = GTK_ENTRY(widget);
-	purple_prefs_set_string("/purple/network/turn_server",
-		gtk_entry_get_text(entry));
-	purple_network_set_turn_server(gtk_entry_get_text(entry));
-
-	return FALSE;
-}
-
-static void
 proxy_changed_cb(const char *name, PurplePrefType type,
 				 gconstpointer value, gpointer data)
 {
@@ -862,106 +797,6 @@ proxy_button_clicked_cb(GtkWidget *butto
 }
 
 static void
-auto_ip_button_clicked_cb(GtkWidget *button, gpointer null)
-{
-	const char *ip;
-	PurpleStunNatDiscovery *stun;
-	char *auto_ip_text;
-	GList *list = NULL;
-
-	/* Make a lookup for the auto-detected IP ourselves. */
-	if (purple_prefs_get_bool("/purple/network/auto_ip")) {
-		/* Check if STUN discovery was already done */
-		stun = purple_stun_discover(NULL);
-		if ((stun != NULL) && (stun->status == PURPLE_STUN_STATUS_DISCOVERED)) {
-			ip = stun->publicip;
-		} else {
-			/* Attempt to get the IP from a NAT device using UPnP */
-			ip = purple_upnp_get_public_ip();
-			if (ip == NULL) {
-				/* Attempt to get the IP from a NAT device using NAT-PMP */
-				ip = purple_pmp_get_public_ip();
-				if (ip == NULL) {
-					/* Just fetch the first IP of the local system */
-					list = nice_interfaces_get_local_ips(FALSE);
-					if (list) {
-						ip = list->data;
-					} else {
-						ip = "0.0.0.0";
-					}
-				}
-			}
-		}
-	} else{
-		ip = _("Disabled");
-	}
-
-	auto_ip_text = g_strdup_printf(_("Use _automatically detected IP address: %s"), ip);
-	gtk_button_set_label(GTK_BUTTON(button), auto_ip_text);
-	g_free(auto_ip_text);
-	g_list_free_full(list, g_free);
-}
-
-static void
-bind_network_page(PidginPrefsWindow *win)
-{
-	GtkStyleContext *context;
-	GtkCssProvider *ip_css;
-	const gchar *res = "/im/pidgin/Pidgin3/Prefs/ip.css";
-
-	gtk_entry_set_text(GTK_ENTRY(win->network.stun_server),
-			purple_prefs_get_string("/purple/network/stun_server"));
-
-	pidgin_prefs_bind_checkbox("/purple/network/auto_ip",
-			win->network.auto_ip);
-	auto_ip_button_clicked_cb(win->network.auto_ip, NULL); /* Update label */
-
-	gtk_entry_set_text(GTK_ENTRY(win->network.public_ip),
-			purple_network_get_public_ip());
-
-	ip_css = gtk_css_provider_new();
-	gtk_css_provider_load_from_resource(ip_css, res);
-
-	context = gtk_widget_get_style_context(win->network.public_ip);
-	gtk_style_context_add_provider(context,
-	                               GTK_STYLE_PROVIDER(ip_css),
-	                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
-	g_object_bind_property(win->network.auto_ip, "active",
-			win->network.public_ip_hbox, "sensitive",
-			G_BINDING_SYNC_CREATE|G_BINDING_INVERT_BOOLEAN);
-
-	pidgin_prefs_bind_checkbox("/purple/network/map_ports",
-			win->network.map_ports);
-
-	pidgin_prefs_bind_checkbox("/purple/network/ports_range_use",
-			win->network.ports_range_use);
-	g_object_bind_property(win->network.ports_range_use, "active",
-			win->network.ports_range_hbox, "sensitive",
-			G_BINDING_SYNC_CREATE);
-
-	pidgin_prefs_bind_spin_button("/purple/network/ports_range_start",
-			win->network.ports_range_start);
-	pidgin_prefs_bind_spin_button("/purple/network/ports_range_end",
-			win->network.ports_range_end);
-
-	/* TURN server */
-	gtk_entry_set_text(GTK_ENTRY(win->network.turn_server),
-			purple_prefs_get_string("/purple/network/turn_server"));
-
-	pidgin_prefs_bind_spin_button("/purple/network/turn_port",
-			win->network.turn_port_udp);
-
-	pidgin_prefs_bind_spin_button("/purple/network/turn_port_tcp",
-			win->network.turn_port_tcp);
-
-	pidgin_prefs_bind_entry("/purple/network/turn_username",
-			win->network.turn_username);
-	pidgin_prefs_bind_entry("/purple/network/turn_password",
-			win->network.turn_password);
-}
-
-static void
 bind_proxy_page(PidginPrefsWindow *win)
 {
 	PurpleProxyInfo *proxy_info;
@@ -1551,7 +1386,6 @@ prefs_stack_init(PidginPrefsWindow *win)
 #endif
 
 	bind_conv_page(win);
-	bind_network_page(win);
 	bind_proxy_page(win);
 #ifdef USE_VV
 	vv = vv_page(win);
@@ -1600,53 +1434,6 @@ pidgin_prefs_window_class_init(PidginPre
 			widget_class, PidginPrefsWindow,
 			conversations.format_view);
 
-	/* Network page */
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, network.stun_server);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, network.auto_ip);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, network.public_ip);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.public_ip_hbox);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, network.map_ports);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.ports_range_use);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.ports_range_hbox);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.ports_range_start);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.ports_range_end);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, network.turn_server);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.turn_port_udp);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.turn_port_tcp);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.turn_username);
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow,
-			network.turn_password);
-	gtk_widget_class_bind_template_callback(widget_class,
-			network_stun_server_changed_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
-	                 auto_ip_button_clicked_cb);
-	gtk_widget_class_bind_template_callback(widget_class,
-			network_ip_changed);
-	gtk_widget_class_bind_template_callback(widget_class,
-			network_turn_server_changed_cb);
-
 	/* Proxy page */
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginPrefsWindow, proxy.stack);
diff --git a/pidgin/resources/Prefs/network.ui b/pidgin/resources/Prefs/network.ui
new file mode 100644
--- /dev/null
+++ b/pidgin/resources/Prefs/network.ui
@@ -0,0 +1,503 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 
+
+Pidgin - Internet Messenger
+Copyright (C) Pidgin Developers <devel@pidgin.im>
+
+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/>.
+
+-->
+<interface>
+  <requires lib="gtk+" version="3.22"/>
+  <!-- interface-license-type gplv2 -->
+  <!-- interface-name Pidgin -->
+  <!-- interface-description Internet Messenger -->
+  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+  <object class="GtkAdjustment" id="ports_range_end.adjustment">
+    <property name="upper">65535</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="ports_range_start.adjustment">
+    <property name="upper">65535</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="turn_port_tcp.adjustment">
+    <property name="upper">65535</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="turn_port_udp.adjustment">
+    <property name="upper">65535</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
+  <template class="PidginNetworkPage" parent="HdyPreferencesPage">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <child>
+      <object class="HdyPreferencesGroup">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="title" translatable="yes">IP Address</property>
+        <child>
+          <object class="GtkAlignment">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="left-padding">12</property>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label8">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">ST_UN server:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">stun_server</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="stun_server">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="placeholder-text" translatable="yes">Example: stunserver.org</property>
+                        <property name="input-purpose">url</property>
+                        <signal name="focus-out-event" handler="network_stun_server_changed_cb" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="auto_ip">
+                    <property name="label" translatable="yes">Use _automatically detected IP address</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="use-underline">True</property>
+                    <property name="draw-indicator">True</property>
+                    <signal name="toggled" handler="auto_ip_button_clicked_cb" after="yes" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="public_ip_hbox">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label9">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">Public _IP:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">public_ip</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="public_ip">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <signal name="changed" handler="network_ip_changed" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="HdyPreferencesGroup">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="title" translatable="yes">Ports</property>
+        <child>
+          <object class="GtkAlignment">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="left-padding">12</property>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkCheckButton" id="map_ports">
+                    <property name="label" translatable="yes">_Enable automatic router port forwarding</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="use-underline">True</property>
+                    <property name="draw-indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkCheckButton" id="ports_range_use">
+                        <property name="label" translatable="yes">_Manually specify range of ports to listen on:</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">False</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkBox" id="ports_range_hbox">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">True</property>
+                            <property name="can-focus">False</property>
+                            <property name="label" translatable="yes">_Start:</property>
+                            <property name="use-underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSpinButton" id="ports_range_start">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="text" translatable="yes">0</property>
+                            <property name="adjustment">ports_range_start.adjustment</property>
+                            <property name="numeric">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel">
+                            <property name="visible">True</property>
+                            <property name="can-focus">False</property>
+                            <property name="label" translatable="yes">_End:</property>
+                            <property name="use-underline">True</property>
+                            <property name="mnemonic-widget">ports_range_end</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkSpinButton" id="ports_range_end">
+                            <property name="visible">True</property>
+                            <property name="can-focus">True</property>
+                            <property name="text" translatable="yes">0</property>
+                            <property name="adjustment">ports_range_end.adjustment</property>
+                            <property name="numeric">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="HdyPreferencesGroup">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="title" translatable="yes">Relay Server (TURN)</property>
+        <child>
+          <object class="GtkAlignment">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="left-padding">12</property>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label10">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">_TURN server:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">turn_server</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="turn_server">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <signal name="focus-out-event" handler="network_turn_server_changed_cb" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">_UDP Port:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">turn_port_udp</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="turn_port_udp">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="adjustment">turn_port_udp.adjustment</property>
+                        <property name="numeric">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">T_CP Port:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">turn_port_tcp</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="turn_port_tcp">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="adjustment">turn_port_tcp.adjustment</property>
+                        <property name="numeric">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">5</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label11">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">Use_rname:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">turn_username</property>
+                        <property name="xalign">0</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="turn_username">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can-focus">False</property>
+                        <property name="label" translatable="yes">Pass_word:</property>
+                        <property name="use-underline">True</property>
+                        <property name="mnemonic-widget">turn_password</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="turn_password">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="visibility">False</property>
+                        <property name="invisible-char">●</property>
+                        <property name="input-purpose">password</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+  </template>
+  <object class="GtkSizeGroup" id="sg">
+    <widgets>
+      <widget name="label8"/>
+      <widget name="label9"/>
+      <widget name="label10"/>
+      <widget name="label11"/>
+    </widgets>
+  </object>
+</interface>
diff --git a/pidgin/resources/Prefs/prefs.ui b/pidgin/resources/Prefs/prefs.ui
--- a/pidgin/resources/Prefs/prefs.ui
+++ b/pidgin/resources/Prefs/prefs.ui
@@ -41,26 +41,6 @@ Foundation, Inc., 51 Franklin Street, Fi
     <property name="page-increment">1</property>
   </object>
   <object class="GtkSizeGroup" id="iface.sg"/>
-  <object class="GtkAdjustment" id="network.ports_range_end.adjustment">
-    <property name="upper">65535</property>
-    <property name="step-increment">1</property>
-    <property name="page-increment">10</property>
-  </object>
-  <object class="GtkAdjustment" id="network.ports_range_start.adjustment">
-    <property name="upper">65535</property>
-    <property name="step-increment">1</property>
-    <property name="page-increment">10</property>
-  </object>
-  <object class="GtkAdjustment" id="network.turn_port_tcp.adjustment">
-    <property name="upper">65535</property>
-    <property name="step-increment">1</property>
-    <property name="page-increment">10</property>
-  </object>
-  <object class="GtkAdjustment" id="network.turn_port_udp.adjustment">
-    <property name="upper">65535</property>
-    <property name="step-increment">1</property>
-    <property name="page-increment">10</property>
-  </object>
   <object class="GtkAdjustment" id="proxy.port.adjustment">
     <property name="upper">65535</property>
     <property name="step-increment">1</property>
@@ -393,489 +373,9 @@ Foundation, Inc., 51 Franklin Street, Fi
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkBox" id="network.page">
+                  <object class="PidginNetworkPage">
                     <property name="visible">True</property>
                     <property name="can-focus">False</property>
-                    <property name="border-width">12</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">18</property>
-                    <child>
-                      <object class="GtkFrame">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label-xalign">0</property>
-                        <property name="shadow-type">none</property>
-                        <child>
-                          <object class="GtkAlignment">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="left-padding">12</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">True</property>
-                                <property name="can-focus">False</property>
-                                <property name="orientation">vertical</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkBox">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="spacing">6</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label8">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">ST_UN server:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.stun_server</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkEntry" id="network.stun_server">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <property name="placeholder-text" translatable="yes">Example: stunserver.org</property>
-                                        <property name="input-purpose">url</property>
-                                        <signal name="focus-out-event" handler="network_stun_server_changed_cb" swapped="no"/>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">True</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkCheckButton" id="network.auto_ip">
-                                    <property name="label" translatable="yes">Use _automatically detected IP address</property>
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">True</property>
-                                    <property name="receives-default">False</property>
-                                    <property name="use-underline">True</property>
-                                    <property name="draw-indicator">True</property>
-                                    <signal name="toggled" handler="auto_ip_button_clicked_cb" after="yes" swapped="no"/>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkBox" id="network.public_ip_hbox">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="spacing">6</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label9">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">Public _IP:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.public_ip</property>
-                                        <property name="xalign">0</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkEntry" id="network.public_ip">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <signal name="changed" handler="network_ip_changed" swapped="no"/>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="label" translatable="yes">IP Address</property>
-                            <attributes>
-                              <attribute name="weight" value="bold"/>
-                            </attributes>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkFrame">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label-xalign">0</property>
-                        <property name="shadow-type">none</property>
-                        <child>
-                          <object class="GtkAlignment">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="left-padding">12</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">True</property>
-                                <property name="can-focus">False</property>
-                                <property name="orientation">vertical</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkCheckButton" id="network.map_ports">
-                                    <property name="label" translatable="yes">_Enable automatic router port forwarding</property>
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">True</property>
-                                    <property name="receives-default">False</property>
-                                    <property name="use-underline">True</property>
-                                    <property name="draw-indicator">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkBox">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="spacing">6</property>
-                                    <child>
-                                      <object class="GtkCheckButton" id="network.ports_range_use">
-                                        <property name="label" translatable="yes">_Manually specify range of ports to listen on:</property>
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <property name="receives-default">False</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="draw-indicator">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkBox" id="network.ports_range_hbox">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="spacing">6</property>
-                                        <child>
-                                          <object class="GtkLabel">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">False</property>
-                                            <property name="label" translatable="yes">_Start:</property>
-                                            <property name="use-underline">True</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">0</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkSpinButton" id="network.ports_range_start">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">True</property>
-                                            <property name="text" translatable="yes">0</property>
-                                            <property name="adjustment">network.ports_range_start.adjustment</property>
-                                            <property name="numeric">True</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">1</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkLabel">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">False</property>
-                                            <property name="label" translatable="yes">_End:</property>
-                                            <property name="use-underline">True</property>
-                                            <property name="mnemonic-widget">network.ports_range_end</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">2</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkSpinButton" id="network.ports_range_end">
-                                            <property name="visible">True</property>
-                                            <property name="can-focus">True</property>
-                                            <property name="text" translatable="yes">0</property>
-                                            <property name="adjustment">network.ports_range_end.adjustment</property>
-                                            <property name="numeric">True</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">3</property>
-                                          </packing>
-                                        </child>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="label" translatable="yes">Ports</property>
-                            <attributes>
-                              <attribute name="weight" value="bold"/>
-                            </attributes>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkFrame">
-                        <property name="visible">True</property>
-                        <property name="can-focus">False</property>
-                        <property name="label-xalign">0</property>
-                        <property name="shadow-type">none</property>
-                        <child>
-                          <object class="GtkAlignment">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="left-padding">12</property>
-                            <child>
-                              <object class="GtkBox">
-                                <property name="visible">True</property>
-                                <property name="can-focus">False</property>
-                                <property name="orientation">vertical</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkBox">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="spacing">6</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label10">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">_TURN server:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.turn_server</property>
-                                        <property name="xalign">0</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkEntry" id="network.turn_server">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <signal name="focus-out-event" handler="network_turn_server_changed_cb" swapped="no"/>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkLabel">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">_UDP Port:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.turn_port_udp</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">2</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkSpinButton" id="network.turn_port_udp">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <property name="adjustment">network.turn_port_udp.adjustment</property>
-                                        <property name="numeric">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">3</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkLabel">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">T_CP Port:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.turn_port_tcp</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">4</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkSpinButton" id="network.turn_port_tcp">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <property name="adjustment">network.turn_port_tcp.adjustment</property>
-                                        <property name="numeric">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">5</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkBox">
-                                    <property name="visible">True</property>
-                                    <property name="can-focus">False</property>
-                                    <property name="spacing">6</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label11">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">Use_rname:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.turn_username</property>
-                                        <property name="xalign">0</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkEntry" id="network.turn_username">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkLabel">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">False</property>
-                                        <property name="label" translatable="yes">Pass_word:</property>
-                                        <property name="use-underline">True</property>
-                                        <property name="mnemonic-widget">network.turn_password</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">2</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkEntry" id="network.turn_password">
-                                        <property name="visible">True</property>
-                                        <property name="can-focus">True</property>
-                                        <property name="visibility">False</property>
-                                        <property name="invisible-char">●</property>
-                                        <property name="input-purpose">password</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">True</property>
-                                        <property name="position">3</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <child type="label">
-                          <object class="GtkLabel">
-                            <property name="visible">True</property>
-                            <property name="can-focus">False</property>
-                            <property name="label" translatable="yes">Relay Server (TURN)</property>
-                            <attributes>
-                              <attribute name="weight" value="bold"/>
-                            </attributes>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
                   </object>
                   <packing>
                     <property name="name">network</property>
@@ -1254,12 +754,4 @@ Foundation, Inc., 51 Franklin Street, Fi
       </object>
     </child>
   </template>
-  <object class="GtkSizeGroup" id="network.sg">
-    <widgets>
-      <widget name="label8"/>
-      <widget name="label9"/>
-      <widget name="label10"/>
-      <widget name="label11"/>
-    </widgets>
-  </object>
 </interface>
diff --git a/pidgin/resources/pidgin.gresource.xml b/pidgin/resources/pidgin.gresource.xml
--- a/pidgin/resources/pidgin.gresource.xml
+++ b/pidgin/resources/pidgin.gresource.xml
@@ -27,6 +27,7 @@
     <file compressed="true">Prefs/credentials.ui</file>
     <file compressed="true">Prefs/credentialprovider.ui</file>
     <file compressed="true">Prefs/ip.css</file>
+    <file compressed="true">Prefs/network.ui</file>
     <file compressed="true">Prefs/prefs.ui</file>
     <file compressed="true">Prefs/vv.ui</file>
     <file compressed="true">Privacy/dialog.ui</file>
diff --git a/po/POTFILES.in b/po/POTFILES.in
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -391,6 +391,7 @@ pidgin/plugins/xmppconsole/xmppconsole.c
 pidgin/prefs/pidginawaypage.c
 pidgin/prefs/pidgincredentialproviderrow.c
 pidgin/prefs/pidgincredentialspage.c
+pidgin/prefs/pidginnetworkpage.c
 pidgin/prefs/pidginprefs.c
 pidgin/resources/About/about.ui
 pidgin/resources/Accounts/actionsmenu.ui
@@ -412,6 +413,7 @@ pidgin/resources/Plugins/menu.ui
 pidgin/resources/Prefs/away.ui
 pidgin/resources/Prefs/credentialprovider.ui
 pidgin/resources/Prefs/credentials.ui
+pidgin/resources/Prefs/network.ui
 pidgin/resources/Prefs/prefs.ui
 pidgin/resources/Prefs/vv.ui
 pidgin/resources/Privacy/dialog.ui
