summaryrefslogtreecommitdiff
path: root/panels/network/net-device-ethernet.c
diff options
context:
space:
mode:
Diffstat (limited to 'panels/network/net-device-ethernet.c')
-rw-r--r--panels/network/net-device-ethernet.c451
1 files changed, 450 insertions, 1 deletions
diff --git a/panels/network/net-device-ethernet.c b/panels/network/net-device-ethernet.c
index 3ac6faa35..01100b8c3 100644
--- a/panels/network/net-device-ethernet.c
+++ b/panels/network/net-device-ethernet.c
@@ -28,9 +28,14 @@
#include <nm-device.h>
#include <nm-device-ethernet.h>
#include <nm-remote-connection.h>
+#include <nm-utils.h>
#include "panel-common.h"
+#include "egg-list-box/egg-list-box.h"
+#include "connection-editor/net-connection-editor.h"
+#include "connection-editor/ce-page.h"
+
#include "net-device-ethernet.h"
G_DEFINE_TYPE (NetDeviceEthernet, net_device_ethernet, NET_TYPE_DEVICE_SIMPLE)
@@ -51,15 +56,459 @@ device_ethernet_get_speed (NetDeviceSimple *device_simple)
return NULL;
}
+static GSList *
+valid_connections_for_device (NMRemoteSettings *remote_settings,
+ NetDevice *device)
+{
+ GSList *all, *filtered, *iterator, *valid;
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+
+ all = nm_remote_settings_list_connections (remote_settings);
+ filtered = nm_device_filter_connections (net_device_get_nm_device (device), all);
+ g_slist_free (all);
+
+ valid = NULL;
+ for (iterator = filtered; iterator; iterator = iterator->next) {
+ connection = iterator->data;
+ s_con = nm_connection_get_setting_connection (connection);
+ if (!s_con)
+ continue;
+
+ if (nm_setting_connection_get_master (s_con))
+ continue;
+
+ valid = g_slist_prepend (valid, connection);
+ }
+ g_slist_free (filtered);
+
+ return g_slist_reverse (valid);
+}
+
+static GtkWidget *
+device_ethernet_add_to_notebook (NetObject *object,
+ GtkNotebook *notebook,
+ GtkSizeGroup *heading_size_group)
+{
+ NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+ GtkWidget *vbox;
+
+ vbox = GTK_WIDGET (gtk_builder_get_object (device->builder, "vbox6"));
+ g_object_ref (vbox);
+ gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (vbox)), vbox);
+ gtk_notebook_append_page (notebook, vbox, NULL);
+ g_object_unref (vbox);
+ return vbox;
+}
+
+static void
+add_details_row (GtkWidget *details, gint top, const gchar *heading, const gchar *value)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new (heading);
+ gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
+ gtk_widget_set_halign (label, GTK_ALIGN_END);
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
+
+ gtk_grid_attach (GTK_GRID (details), label, 0, top, 1, 1);
+
+ label = gtk_label_new (value);
+ gtk_widget_set_halign (label, GTK_ALIGN_START);
+ gtk_widget_set_hexpand (label, TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ gtk_grid_attach (GTK_GRID (details), label, 1, top, 1, 1);
+}
+
+static gchar *
+get_last_used_string (NMConnection *connection)
+{
+ gchar *last_used = NULL;
+ GDateTime *now = NULL;
+ GDateTime *then = NULL;
+ gint days;
+ GTimeSpan diff;
+ guint64 timestamp;
+ NMSettingConnection *s_con;
+
+ s_con = nm_connection_get_setting_connection (connection);
+ if (s_con == NULL)
+ goto out;
+ timestamp = nm_setting_connection_get_timestamp (s_con);
+ if (timestamp == 0) {
+ last_used = g_strdup (_("never"));
+ goto out;
+ }
+
+ /* calculate the amount of time that has elapsed */
+ now = g_date_time_new_now_utc ();
+ then = g_date_time_new_from_unix_utc (timestamp);
+ diff = g_date_time_difference (now, then);
+ days = diff / G_TIME_SPAN_DAY;
+ if (days == 0)
+ last_used = g_strdup (_("today"));
+ else if (days == 1)
+ last_used = g_strdup (_("yesterday"));
+ else
+ last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days);
+out:
+ if (now != NULL)
+ g_date_time_unref (now);
+ if (then != NULL)
+ g_date_time_unref (then);
+
+ return last_used;
+}
+
+static void
+add_details (GtkWidget *details, NMDevice *device, NMConnection *connection)
+{
+ NMIP4Config *ip4_config = NULL;
+ NMIP6Config *ip6_config = NULL;
+ gchar *ip4_address = NULL;
+ gchar *ip4_route = NULL;
+ gchar *ip4_dns = NULL;
+ gchar *ip6_address = NULL;
+ gint i = 0;
+
+ ip4_config = nm_device_get_ip4_config (device);
+ if (ip4_config) {
+ ip4_address = panel_get_ip4_address_as_string (ip4_config, "address");
+ ip4_route = panel_get_ip4_address_as_string (ip4_config, "gateway");
+ ip4_dns = panel_get_ip4_dns_as_string (ip4_config);
+ }
+ ip6_config = nm_device_get_ip6_config (device);
+ if (ip6_config) {
+ ip6_address = panel_get_ip6_address_as_string (ip6_config);
+ }
+
+ if (ip4_address && ip6_address) {
+ add_details_row (details, i++, _("IP4 Address"), ip4_address);
+ add_details_row (details, i++, _("IP6 Address"), ip6_address);
+ } else if (ip4_address) {
+ add_details_row (details, i++, _("IP Address"), ip4_address);
+ } else if (ip6_address) {
+ add_details_row (details, i++, _("IP Address"), ip6_address);
+ }
+
+ add_details_row (details, i++, _("Hardware Address"),
+ nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)));
+
+ if (ip4_route)
+ add_details_row (details, i++, _("Default Route"), ip4_route);
+ if (ip4_dns)
+ add_details_row (details, i++, _("DNS"), ip4_dns);
+
+ if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) {
+ gchar *last_used;
+ last_used = get_last_used_string (connection);
+ add_details_row (details, i++, _("Last used"), last_used);
+ g_free (last_used);
+ }
+
+ g_free (ip4_address);
+ g_free (ip4_route);
+ g_free (ip4_dns);
+ g_free (ip6_address);
+}
+
+static void populate_ui (NetDeviceEthernet *device);
+
+static void
+editor_done (NetConnectionEditor *editor,
+ gboolean success,
+ NetDeviceEthernet *device)
+{
+ g_object_unref (editor);
+ populate_ui (device);
+}
+
+static void
+show_details_for_row (GtkButton *button, NetDeviceEthernet *device)
+{
+ GtkWidget *row;
+ NMConnection *connection;
+ GtkWidget *window;
+ NetConnectionEditor *editor;
+ NMClient *client;
+ NMRemoteSettings *settings;
+ NMDevice *nmdev;
+
+ window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row"));
+ connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection"));
+
+ nmdev = net_device_get_nm_device (NET_DEVICE (device));
+ client = net_object_get_client (NET_OBJECT (device));
+ settings = net_object_get_remote_settings (NET_OBJECT (device));
+ editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings);
+ g_signal_connect (editor, "done", G_CALLBACK (editor_done), device);
+ net_connection_editor_run (editor);
+}
+
+static void
+add_row (NetDeviceEthernet *device, NMConnection *connection)
+{
+ GtkWidget *row;
+ GtkWidget *widget;
+ GtkWidget *box;
+ GtkWidget *details;
+ NMDevice *nmdev;
+ NMActiveConnection *aconn;
+ gboolean active;
+ GtkWidget *image;
+
+ active = FALSE;
+
+ nmdev = net_device_get_nm_device (NET_DEVICE (device));
+ aconn = nm_device_get_active_connection (nmdev);
+ if (aconn) {
+ const gchar *path1, *path2;
+ path1 = nm_active_connection_get_connection (aconn);
+ path2 = nm_connection_get_path (connection);
+ active = g_strcmp0 (path1, path2) == 0;
+ }
+
+ row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (row), box, FALSE, TRUE, 0);
+ widget = gtk_label_new (nm_connection_get_id (connection));
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_widget_set_margin_right (widget, 12);
+ gtk_widget_set_margin_top (widget, 12);
+ gtk_widget_set_margin_bottom (widget, 12);
+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
+
+ if (active) {
+ widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
+
+ details = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (details), 10);
+ gtk_grid_set_column_spacing (GTK_GRID (details), 10);
+
+ gtk_box_pack_start (GTK_BOX (row), details, FALSE, TRUE, 0);
+
+ add_details (details, nmdev, connection);
+ }
+
+ /* filler */
+ widget = gtk_label_new ("");
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
+
+ image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image);
+ widget = gtk_button_new ();
+ gtk_widget_set_margin_left (widget, 12);
+ gtk_widget_set_margin_right (widget, 12);
+ gtk_widget_set_margin_top (widget, 12);
+ gtk_widget_set_margin_bottom (widget, 12);
+ gtk_widget_show (widget);
+ gtk_container_add (GTK_CONTAINER (widget), image);
+ gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
+ gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
+ g_object_set_data (G_OBJECT (row), "edit", widget);
+ g_object_set_data (G_OBJECT (widget), "row", row);
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (show_details_for_row), device);
+
+ gtk_widget_show_all (row);
+
+ g_object_set_data (G_OBJECT (row), "connection", connection);
+
+ gtk_container_add (GTK_CONTAINER (device->list), row);
+}
+
+static void
+populate_ui (NetDeviceEthernet *device)
+{
+ NMRemoteSettings *settings;
+ GList *children, *c;
+ GSList *connections, *l;
+ NMConnection *connection;
+ gint n_connections;
+
+ children = gtk_container_get_children (GTK_CONTAINER (device->list));
+ for (c = children; c; c = c->next) {
+ gtk_container_remove (GTK_CONTAINER (device->list), c->data);
+ }
+ g_list_free (children);
+
+ children = gtk_container_get_children (GTK_CONTAINER (device->details));
+ for (c = children; c; c = c->next) {
+ gtk_container_remove (GTK_CONTAINER (device->details), c->data);
+ }
+ g_list_free (children);
+
+ settings = net_object_get_remote_settings (NET_OBJECT (device));
+ connections = valid_connections_for_device (settings, NET_DEVICE (device));
+
+ n_connections = g_slist_length (connections);
+ if (n_connections > 1) {
+ gtk_widget_hide (device->details);
+ gtk_widget_hide (device->details_button);
+ for (l = connections; l; l = l->next) {
+ NMConnection *connection = l->data;
+ add_row (device, connection);
+ }
+ gtk_widget_show (device->scrolled_window);
+ } else if (n_connections == 1) {
+ connection = connections->data;
+ gtk_widget_hide (device->scrolled_window);
+ add_details (device->details, net_device_get_nm_device (NET_DEVICE (device)), connection);
+ gtk_widget_show_all (device->details);
+ gtk_widget_show (device->details_button);
+ g_object_set_data (G_OBJECT (device->details_button), "row", device->details_button);
+ g_object_set_data (G_OBJECT (device->details_button), "connection", connection);
+
+ } else {
+ gtk_widget_hide (device->scrolled_window);
+ gtk_widget_hide (device->details);
+ gtk_widget_hide (device->details_button);
+ }
+}
+
+static void
+remote_settings_read_cb (NMRemoteSettings *settings,
+ NetDeviceEthernet *device)
+{
+ populate_ui (device);
+}
+
+static void
+update_separator (GtkWidget **separator,
+ GtkWidget *child,
+ GtkWidget *before,
+ gpointer user_data)
+{
+ if (before == NULL)
+ return;
+
+ if (*separator == NULL)
+ {
+ *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_widget_show (*separator);
+ g_object_ref_sink (*separator);
+ }
+}
+
+static void
+add_profile (GtkButton *button, NetDeviceEthernet *device)
+{
+ NMRemoteSettings *settings;
+ NMConnection *connection;
+ NMSettingConnection *sc;
+ gchar *uuid, *id;
+ NetConnectionEditor *editor;
+ GtkWidget *window;
+ NMClient *client;
+ NMDevice *nmdev;
+ GSList *connections;
+
+ connection = nm_connection_new ();
+ sc = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ nm_connection_add_setting (connection, NM_SETTING (sc));
+
+ uuid = nm_utils_uuid_generate ();
+
+ settings = net_object_get_remote_settings (NET_OBJECT (device));
+ connections = nm_remote_settings_list_connections (settings);
+ id = ce_page_get_next_available_name (connections, _("Profile %d"));
+ g_slist_free (connections);
+
+ g_object_set (sc,
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_ID, id,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NULL);
+
+ nm_connection_add_setting (connection, nm_setting_wired_new ());
+
+ g_free (uuid);
+ g_free (id);
+
+ window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+
+ nmdev = net_device_get_nm_device (NET_DEVICE (device));
+ client = net_object_get_client (NET_OBJECT (device));
+ editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings);
+ g_signal_connect (editor, "done", G_CALLBACK (editor_done), device);
+ net_connection_editor_run (editor);
+}
+
+static void
+device_ethernet_constructed (GObject *object)
+{
+ NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+ NMRemoteSettings *settings;
+ GtkWidget *list;
+ GtkWidget *swin;
+
+ device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "list"));
+ device->list = list = GTK_WIDGET (egg_list_box_new ());
+ egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
+ egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
+ egg_list_box_add_to_scrolled (EGG_LIST_BOX (list), GTK_SCROLLED_WINDOW (swin));
+ gtk_widget_show (list);
+
+ device->details = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details"));
+
+ device->details_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details_button"));
+ g_signal_connect (device->details_button, "clicked",
+ G_CALLBACK (show_details_for_row), device);
+
+ device->add_profile_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "add_profile_button"));
+ g_signal_connect (device->add_profile_button, "clicked",
+ G_CALLBACK (add_profile), device);
+
+ settings = net_object_get_remote_settings (NET_OBJECT (object));
+ g_signal_connect (settings, "connections-read",
+ G_CALLBACK (remote_settings_read_cb), object);
+}
+
+static void
+device_ethernet_finalize (GObject *object)
+{
+ NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
+
+ g_object_unref (device->builder);
+
+ G_OBJECT_CLASS (net_device_ethernet_parent_class)->finalize (object);
+}
+
static void
net_device_ethernet_class_init (NetDeviceEthernetClass *klass)
{
NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass);
+ NetObjectClass *obj_class = NET_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
simple_class->get_speed = device_ethernet_get_speed;
+ obj_class->add_to_notebook = device_ethernet_add_to_notebook;
+ object_class->constructed = device_ethernet_constructed;
+ object_class->finalize = device_ethernet_finalize;
}
static void
-net_device_ethernet_init (NetDeviceEthernet *device_ethernet)
+net_device_ethernet_init (NetDeviceEthernet *device)
{
+ GError *error = NULL;
+
+ device->builder = gtk_builder_new ();
+ gtk_builder_add_from_resource (device->builder,
+ "/org/gnome/control-center/network/network-ethernet.ui",
+ &error);
+ if (error != NULL) {
+ g_warning ("Could not load interface file: %s", error->message);
+ g_error_free (error);
+ return;
+ }
}