diff options
author | Jiří Klimeš <jklimes@redhat.com> | 2013-10-07 18:32:33 +0200 |
---|---|---|
committer | Jiří Klimeš <jklimes@redhat.com> | 2013-10-07 18:35:29 +0200 |
commit | ba7652f19a836862d02d19a61a4b3d8bf284125a (patch) | |
tree | 1cda74293dbd4e9fe221b5dcd15cf296422eb8d1 | |
parent | a42cc9570f07f8b6c692caa4f56cbf4dcbda677b (diff) | |
parent | e98d9756ca6409e05160635377f45f30b67b31a7 (diff) | |
download | network-manager-applet-ba7652f19a836862d02d19a61a4b3d8bf284125a.tar.gz |
team: merge a branch adding support for Team to applet/editor (bgo #708245)
https://bugzilla.gnome.org/show_bug.cgi?id=708245
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/applet-device-team.c | 165 | ||||
-rw-r--r-- | src/applet-device-team.h | 27 | ||||
-rw-r--r-- | src/applet.c | 12 | ||||
-rw-r--r-- | src/applet.h | 1 | ||||
-rw-r--r-- | src/connection-editor/Makefile.am | 6 | ||||
-rw-r--r-- | src/connection-editor/ce-page-team-port.ui | 62 | ||||
-rw-r--r-- | src/connection-editor/ce-page-team.ui | 215 | ||||
-rw-r--r-- | src/connection-editor/new-connection.c | 7 | ||||
-rw-r--r-- | src/connection-editor/nm-connection-editor.c | 12 | ||||
-rw-r--r-- | src/connection-editor/nm-connection-list.c | 3 | ||||
-rw-r--r-- | src/connection-editor/page-team-port.c | 228 | ||||
-rw-r--r-- | src/connection-editor/page-team-port.h | 55 | ||||
-rw-r--r-- | src/connection-editor/page-team.c | 384 | ||||
-rw-r--r-- | src/connection-editor/page-team.h | 61 | ||||
-rw-r--r-- | src/libnm-gtk/nm-ui-utils.c | 5 |
16 files changed, 1243 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index e9fd33b5..44554cf7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,6 +61,8 @@ nm_applet_SOURCES = \ applet-device-vlan.c \ applet-device-bond.h \ applet-device-bond.c \ + applet-device-team.h \ + applet-device-team.c \ applet-device-bridge.h \ applet-device-bridge.c \ applet-device-infiniband.h \ diff --git a/src/applet-device-team.c b/src/applet-device-team.c new file mode 100644 index 00000000..9c037847 --- /dev/null +++ b/src/applet-device-team.c @@ -0,0 +1,165 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include <nm-device.h> +#include <nm-setting-connection.h> +#include <nm-setting-wired.h> +#include <nm-setting-team.h> +#include <nm-device-team.h> +#include <nm-utils.h> + +#include "applet.h" +#include "applet-device-team.h" +#include "utils.h" +#include "nm-ui-utils.h" + +static void +team_add_menu_item (NMDevice *device, + gboolean multiple_devices, + GSList *connections, + NMConnection *active, + GtkWidget *menu, + NMApplet *applet) +{ + char *text; + GtkWidget *item; + + text = nma_utils_get_connection_device_name (connections->data); + item = applet_menu_item_create_device_item_helper (device, applet, text); + g_free (text); + + gtk_widget_set_sensitive (item, FALSE); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + + if (g_slist_length (connections)) + applet_add_connection_items (device, connections, TRUE, active, NMA_ADD_ACTIVE, menu, applet); + + /* Notify user of unmanaged or unavailable device */ + if (device) { + item = nma_menu_device_get_menu_item (device, applet, NULL); + if (item) { + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + } + } + + if (!device || !nma_menu_device_check_unusable (device)) { + if ((!active && g_slist_length (connections)) || (active && g_slist_length (connections) > 1)) + applet_menu_item_add_complex_separator_helper (menu, applet, _("Available"), -1); + + if (g_slist_length (connections)) + applet_add_connection_items (device, connections, TRUE, active, NMA_ADD_INACTIVE, menu, applet); + } +} + +static void +team_notify_connected (NMDevice *device, + const char *msg, + NMApplet *applet) +{ + applet_do_notify_with_pref (applet, + _("Connection Established"), + msg ? msg : _("You are now connected to the teamed network."), + "nm-device-wired", + PREF_DISABLE_CONNECTED_NOTIFICATIONS); +} + +static GdkPixbuf * +team_get_icon (NMDevice *device, + NMDeviceState state, + NMConnection *connection, + char **tip, + NMApplet *applet) +{ + NMSettingConnection *s_con; + GdkPixbuf *pixbuf = NULL; + const char *id; + + id = nm_device_get_iface (NM_DEVICE (device)); + if (connection) { + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + id = nm_setting_connection_get_id (s_con); + } + + switch (state) { + case NM_DEVICE_STATE_PREPARE: + *tip = g_strdup_printf (_("Preparing team connection '%s'..."), id); + break; + case NM_DEVICE_STATE_CONFIG: + *tip = g_strdup_printf (_("Configuring team connection '%s'..."), id); + break; + case NM_DEVICE_STATE_NEED_AUTH: + *tip = g_strdup_printf (_("User authentication required for team connection '%s'..."), id); + break; + case NM_DEVICE_STATE_IP_CONFIG: + *tip = g_strdup_printf (_("Requesting address for '%s'..."), id); + break; + case NM_DEVICE_STATE_ACTIVATED: + pixbuf = nma_icon_check_and_load ("nm-device-wired", &applet->ethernet_icon, applet); + *tip = g_strdup_printf (_("Team connection '%s' active"), id); + break; + default: + break; + } + + return pixbuf ? g_object_ref (pixbuf) : NULL; +} + +static gboolean +team_new_auto_connection (NMDevice *device, + gpointer dclass_data, + AppletNewAutoConnectionCallback callback, + gpointer callback_data) +{ + return FALSE; +} + + +static gboolean +team_get_secrets (SecretsRequest *req, GError **error) +{ + /* No 802.1x or PPPoE possible yet on teams */ + return FALSE; +} + +NMADeviceClass * +applet_device_team_get_class (NMApplet *applet) +{ + NMADeviceClass *dclass; + + dclass = g_slice_new0 (NMADeviceClass); + if (!dclass) + return NULL; + + dclass->new_auto_connection = team_new_auto_connection; + dclass->add_menu_item = team_add_menu_item; + dclass->notify_connected = team_notify_connected; + dclass->get_icon = team_get_icon; + dclass->get_secrets = team_get_secrets; + + return dclass; +} diff --git a/src/applet-device-team.h b/src/applet-device-team.h new file mode 100644 index 00000000..76ef2eb1 --- /dev/null +++ b/src/applet-device-team.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __APPLET_DEVICE_TEAM_H__ +#define __APPLET_DEVICE_TEAM_H__ + +#include "applet.h" + +NMADeviceClass *applet_device_team_get_class (NMApplet *applet); + +#endif /* __APPLET_DEVICE_TEAM_H__ */ diff --git a/src/applet.c b/src/applet.c index 6c3e87bf..106d9bd8 100644 --- a/src/applet.c +++ b/src/applet.c @@ -46,6 +46,7 @@ #include <NetworkManagerVPN.h> #include <nm-device-bond.h> +#include <nm-device-team.h> #include <nm-device-bridge.h> #include <nm-device-bt.h> #include <nm-device-ethernet.h> @@ -72,6 +73,7 @@ #include "applet.h" #include "applet-device-bond.h" +#include "applet-device-team.h" #include "applet-device-bridge.h" #include "applet-device-bt.h" #include "applet-device-cdma.h" @@ -270,6 +272,8 @@ get_device_class (NMDevice *device, NMApplet *applet) return applet->vlan_class; else if (NM_IS_DEVICE_BOND (device)) return applet->bond_class; + else if (NM_IS_DEVICE_TEAM (device)) + return applet->team_class; else if (NM_IS_DEVICE_BRIDGE (device)) return applet->bridge_class; else if (NM_IS_DEVICE_INFINIBAND (device)) @@ -310,6 +314,8 @@ get_device_class_from_connection (NMConnection *connection, NMApplet *applet) return applet->bt_class; else if (!strcmp (ctype, NM_SETTING_BOND_SETTING_NAME)) return applet->bond_class; + else if (!strcmp (ctype, NM_SETTING_TEAM_SETTING_NAME)) + return applet->team_class; else if (!strcmp (ctype, NM_SETTING_BRIDGE_SETTING_NAME)) return applet->bridge_class; else if (!strcmp (ctype, NM_SETTING_VLAN_SETTING_NAME)) @@ -1703,6 +1709,8 @@ nma_menu_add_devices (GtkWidget *menu, NMApplet *applet) all_devices, all_connections, menu, applet); n_items += add_virtual_items (NM_SETTING_BOND_SETTING_NAME, all_devices, all_connections, menu, applet); + n_items += add_virtual_items (NM_SETTING_TEAM_SETTING_NAME, + all_devices, all_connections, menu, applet); n_items += add_device_items (NM_DEVICE_TYPE_ETHERNET, all_devices, all_connections, menu, applet); n_items += add_device_items (NM_DEVICE_TYPE_INFINIBAND, @@ -3723,6 +3731,9 @@ constructor (GType type, applet->bond_class = applet_device_bond_get_class (applet); g_assert (applet->bond_class); + applet->team_class = applet_device_team_get_class (applet); + g_assert (applet->team_class); + applet->bridge_class = applet_device_bridge_get_class (applet); g_assert (applet->bridge_class); @@ -3773,6 +3784,7 @@ static void finalize (GObject *object) g_slice_free (NMADeviceClass, applet->wimax_class); g_slice_free (NMADeviceClass, applet->vlan_class); g_slice_free (NMADeviceClass, applet->bond_class); + g_slice_free (NMADeviceClass, applet->team_class); g_slice_free (NMADeviceClass, applet->bridge_class); g_slice_free (NMADeviceClass, applet->infiniband_class); diff --git a/src/applet.h b/src/applet.h index c567367d..174e42a1 100644 --- a/src/applet.h +++ b/src/applet.h @@ -118,6 +118,7 @@ typedef struct NMADeviceClass *wimax_class; NMADeviceClass *vlan_class; NMADeviceClass *bond_class; + NMADeviceClass *team_class; NMADeviceClass *bridge_class; NMADeviceClass *infiniband_class; diff --git a/src/connection-editor/Makefile.am b/src/connection-editor/Makefile.am index 4cc90053..09d1719c 100644 --- a/src/connection-editor/Makefile.am +++ b/src/connection-editor/Makefile.am @@ -55,6 +55,10 @@ nm_connection_editor_SOURCES = \ page-master.c \ page-bond.h \ page-bond.c \ + page-team.h \ + page-team.c \ + page-team-port.h \ + page-team-port.c \ page-bridge.h \ page-bridge.c \ page-bridge-port.h \ @@ -97,6 +101,8 @@ ui_DATA = \ ce-page-wimax.ui \ ce-page-infiniband.ui \ ce-page-bond.ui \ + ce-page-team.ui \ + ce-page-team-port.ui \ ce-page-bridge.ui \ ce-page-bridge-port.ui \ ce-page-ip4.ui \ diff --git a/src/connection-editor/ce-page-team-port.ui b/src/connection-editor/ce-page-team-port.ui new file mode 100644 index 00000000..10422f4e --- /dev/null +++ b/src/connection-editor/ce-page-team-port.ui @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <object class="GtkGrid" id="TeamPortPage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">12</property> + <property name="column_spacing">12</property> + <property name="row_spacing">6</property> + <property name="column_homogeneous">True</property> + <child> + <object class="GtkLabel" id="team_port_json_config_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_JSON config:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">team_port_json_config</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <property name="min_content_height">100</property> + <child> + <object class="GtkTextView" id="team_port_json_config"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">2</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="import_config_button"> + <property name="label" translatable="yes">_Import team configuration from a file...</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_underline">True</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + <property name="height">1</property> + </packing> + </child> + </object> +</interface> diff --git a/src/connection-editor/ce-page-team.ui b/src/connection-editor/ce-page-team.ui new file mode 100644 index 00000000..a751fdb8 --- /dev/null +++ b/src/connection-editor/ce-page-team.ui @@ -0,0 +1,215 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <!-- interface-requires gtk+ 3.0 --> + <object class="GtkListStore" id="master_connections_model"> + <columns> + <!-- column-name connection --> + <column type="NMConnection"/> + <!-- column-name name --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkGrid" id="TeamPage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="border_width">12</property> + <property name="column_spacing">12</property> + <property name="row_spacing">8</property> + <child> + <object class="GtkLabel" id="master_connections_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Teamed connections:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">2</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="team_json_config_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_JSON config:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">team_json_config</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + <property name="width">2</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <property name="min_content_height">100</property> + <child> + <object class="GtkTextView" id="team_json_config"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + <property name="width">2</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="import_config_button"> + <property name="label" translatable="yes">I_mport team configuration from a file...</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="use_underline">True</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">5</property> + <property name="width">2</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="hexpand">True</property> + <property name="spacing">10</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="master_connections"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="model">master_connections_model</property> + <property name="headers_visible">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> + <child> + <object class="GtkTreeViewColumn" id="master_connection_name"> + <child> + <object class="GtkCellRendererText" id="master_connection_renderer"/> + <attributes> + <attribute name="text">1</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButtonBox" id="buttonbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">10</property> + <property name="layout_style">start</property> + <child> + <object class="GtkButton" id="master_connection_add"> + <property name="label">gtk-add</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="master_connection_edit"> + <property name="label" translatable="yes">_Edit</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="master_connection_delete"> + <property name="label" translatable="yes">_Delete</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="master_interface_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Interface name:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">master_interface</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="master_interface"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="invisible_char">●</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + </object> +</interface> diff --git a/src/connection-editor/new-connection.c b/src/connection-editor/new-connection.c index 5b306cfd..ed3a7424 100644 --- a/src/connection-editor/new-connection.c +++ b/src/connection-editor/new-connection.c @@ -32,6 +32,7 @@ #include "page-dsl.h" #include "page-infiniband.h" #include "page-bond.h" +#include "page-team.h" #include "page-bridge.h" #include "page-vlan.h" #include "page-vpn.h" @@ -140,6 +141,12 @@ get_connection_type_list (void) data.virtual = TRUE; g_array_append_val (array, data); + data.name = _("Team"); + data.new_connection_func = team_connection_new; + data.setting_type = NM_TYPE_SETTING_TEAM; + data.virtual = TRUE; + g_array_append_val (array, data); + data.name = _("Bridge"); data.new_connection_func = bridge_connection_new; data.setting_type = NM_TYPE_SETTING_BRIDGE; diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c index c2f6c524..3024244f 100644 --- a/src/connection-editor/nm-connection-editor.c +++ b/src/connection-editor/nm-connection-editor.c @@ -48,6 +48,7 @@ #include <nm-setting-wimax.h> #include <nm-setting-infiniband.h> #include <nm-setting-bond.h> +#include <nm-setting-team.h> #include <nm-setting-bridge.h> #include <nm-utils.h> @@ -71,6 +72,8 @@ #include "page-wimax.h" #include "page-infiniband.h" #include "page-bond.h" +#include "page-team.h" +#include "page-team-port.h" #include "page-bridge.h" #include "page-bridge-port.h" #include "page-vlan.h" @@ -821,6 +824,9 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor, } else if (!strcmp (connection_type, NM_SETTING_BOND_SETTING_NAME)) { if (!add_page (editor, ce_page_bond_new, editor->connection, error)) goto out; + } else if (!strcmp (connection_type, NM_SETTING_TEAM_SETTING_NAME)) { + if (!add_page (editor, ce_page_team_new, editor->connection, error)) + goto out; } else if (!strcmp (connection_type, NM_SETTING_BRIDGE_SETTING_NAME)) { if (!add_page (editor, ce_page_bridge_new, editor->connection, error)) goto out; @@ -834,7 +840,11 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor, slave_type = nm_setting_connection_get_slave_type (s_con); if (!g_strcmp0 (slave_type, NM_SETTING_BOND_SETTING_NAME)) add_ip4 = add_ip6 = FALSE; - else if (!g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { + else if (!g_strcmp0 (slave_type, NM_SETTING_TEAM_SETTING_NAME)) { + add_ip4 = add_ip6 = FALSE; + if (!add_page (editor, ce_page_team_port_new, editor->connection, error)) + goto out; + } else if (!g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME)) { add_ip4 = add_ip6 = FALSE; if (!add_page (editor, ce_page_bridge_port_new, editor->connection, error)) goto out; diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c index 9ae92eb3..cee5bb5d 100644 --- a/src/connection-editor/nm-connection-list.c +++ b/src/connection-editor/nm-connection-list.c @@ -571,7 +571,7 @@ tree_model_visible_func (GtkTreeModel *model, } /* A connection node is visible unless it is a slave to a known - * bond or bridge. + * bond or team or bridge. */ s_con = nm_connection_get_setting_connection (connection); g_object_unref (connection); @@ -582,6 +582,7 @@ tree_model_visible_func (GtkTreeModel *model, return TRUE; slave_type = nm_setting_connection_get_slave_type (s_con); if ( g_strcmp0 (slave_type, NM_SETTING_BOND_SETTING_NAME) != 0 + && g_strcmp0 (slave_type, NM_SETTING_TEAM_SETTING_NAME) != 0 && g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) != 0) return TRUE; diff --git a/src/connection-editor/page-team-port.c b/src/connection-editor/page-team-port.c new file mode 100644 index 00000000..280cf4ed --- /dev/null +++ b/src/connection-editor/page-team-port.c @@ -0,0 +1,228 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <string.h> + +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include <nm-setting-connection.h> +#include <nm-setting-team-port.h> +#include <nm-utils.h> + +#include "page-team-port.h" + +G_DEFINE_TYPE (CEPageTeamPort, ce_page_team_port, CE_TYPE_PAGE) + +#define CE_PAGE_TEAM_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_TEAM_PORT, CEPageTeamPortPrivate)) + +typedef struct { + NMSettingTeamPort *setting; + + GtkTextView *json_config_widget; + GtkWidget *import_config_button; +} CEPageTeamPortPrivate; + +static void +team_port_private_init (CEPageTeamPort *self) +{ + CEPageTeamPortPrivate *priv = CE_PAGE_TEAM_PORT_GET_PRIVATE (self); + GtkBuilder *builder; + + builder = CE_PAGE (self)->builder; + + priv->json_config_widget = GTK_TEXT_VIEW (gtk_builder_get_object (builder, "team_port_json_config")); + priv->import_config_button = GTK_WIDGET (gtk_builder_get_object (builder, "import_config_button")); +} + +static void +json_config_changed (GObject *object, CEPageTeamPort *self) +{ + ce_page_changed (CE_PAGE (self)); +} + +static void +import_config_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data) +{ + CEPageTeamPortPrivate *priv = CE_PAGE_TEAM_PORT_GET_PRIVATE (user_data); + GtkTextBuffer *buffer; + char *filename; + char *buf = NULL; + gsize buf_len; + + if (response != GTK_RESPONSE_ACCEPT) + goto out; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (!filename) { + g_warning ("%s: didn't get a filename back from the chooser!", __func__); + goto out; + } + + /* Put the file content into JSON config text view. */ + // FIXME: do a cleverer file validity check + g_file_get_contents (filename, &buf, &buf_len, NULL); + if (buf_len > 100000) { + g_free (buf); + buf = g_strdup (_("Error: file doesn't contain a valid JSON configuration")); + } + + buffer = gtk_text_view_get_buffer (priv->json_config_widget); + gtk_text_buffer_set_text (buffer, buf ? buf : "", -1); + + g_free (filename); + g_free (buf); + +out: + gtk_widget_hide (dialog); + gtk_widget_destroy (dialog); +} + +static void +import_button_clicked_cb (GtkWidget *widget, CEPageTeamPort *self) +{ + GtkWidget *dialog; + + dialog = gtk_file_chooser_dialog_new (_("Select file to import"), + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_config_from_file_cb), self); + gtk_widget_show_all (dialog); + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +populate_ui (CEPageTeamPort *self) +{ + CEPageTeamPortPrivate *priv = CE_PAGE_TEAM_PORT_GET_PRIVATE (self); + NMSettingTeamPort *s_port = priv->setting; + GtkTextBuffer *buffer; + const char *json_config; + + buffer = gtk_text_view_get_buffer (priv->json_config_widget); + json_config = nm_setting_team_port_get_config (s_port); + gtk_text_buffer_set_text (buffer, json_config ? json_config : "", -1); + + g_signal_connect (buffer, "changed", G_CALLBACK (json_config_changed), self); + g_signal_connect (priv->import_config_button, "clicked", G_CALLBACK (import_button_clicked_cb), self); +} + +static void +finish_setup (CEPageTeamPort *self, gpointer unused, GError *error, gpointer user_data) +{ + if (error) + return; + + populate_ui (self); +} + +CEPage * +ce_page_team_port_new (NMConnection *connection, + GtkWindow *parent_window, + NMClient *client, + NMRemoteSettings *settings, + const char **out_secrets_setting_name, + GError **error) +{ + CEPageTeamPort *self; + CEPageTeamPortPrivate *priv; + + self = CE_PAGE_TEAM_PORT (ce_page_new (CE_TYPE_PAGE_TEAM_PORT, + connection, + parent_window, + client, + settings, + UIDIR "/ce-page-team-port.ui", + "TeamPortPage", + /* Translators: a "Team Port" is a network + * device that is part of a team. + */ + _("Team Port"))); + if (!self) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load team port user interface.")); + return NULL; + } + + team_port_private_init (self); + priv = CE_PAGE_TEAM_PORT_GET_PRIVATE (self); + + priv->setting = nm_connection_get_setting_team_port (connection); + if (!priv->setting) { + priv->setting = NM_SETTING_TEAM_PORT (nm_setting_team_port_new ()); + nm_connection_add_setting (connection, NM_SETTING (priv->setting)); + } + + g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL); + + return CE_PAGE (self); +} + +static void +ui_to_setting (CEPageTeamPort *self) +{ + CEPageTeamPortPrivate *priv = CE_PAGE_TEAM_PORT_GET_PRIVATE (self); + GtkTextBuffer *buffer; + GtkTextIter start, end; + char *json_config; + + buffer = gtk_text_view_get_buffer (priv->json_config_widget); + gtk_text_buffer_get_iter_at_offset (buffer, &start, 0); + gtk_text_buffer_get_iter_at_offset (buffer, &end, -1); + json_config = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); + + if (g_strcmp0 (json_config, "") == 0) + json_config = NULL; + g_object_set (priv->setting, + NM_SETTING_TEAM_PORT_CONFIG, json_config, + NULL); + g_free (json_config); +} + +static gboolean +validate (CEPage *page, NMConnection *connection, GError **error) +{ + CEPageTeamPort *self = CE_PAGE_TEAM_PORT (page); + CEPageTeamPortPrivate *priv = CE_PAGE_TEAM_PORT_GET_PRIVATE (self); + + ui_to_setting (self); + return nm_setting_verify (NM_SETTING (priv->setting), NULL, error); +} + +static void +ce_page_team_port_init (CEPageTeamPort *self) +{ +} + +static void +ce_page_team_port_class_init (CEPageTeamPortClass *team_port_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (team_port_class); + CEPageClass *parent_class = CE_PAGE_CLASS (team_port_class); + + g_type_class_add_private (object_class, sizeof (CEPageTeamPortPrivate)); + + /* virtual methods */ + parent_class->validate = validate; +} diff --git a/src/connection-editor/page-team-port.h b/src/connection-editor/page-team-port.h new file mode 100644 index 00000000..6eccb15e --- /dev/null +++ b/src/connection-editor/page-team-port.h @@ -0,0 +1,55 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __PAGE_TEAM_PORT_H__ +#define __PAGE_TEAM_PORT_H__ + +#include <nm-connection.h> + +#include <glib.h> +#include <glib-object.h> + +#include "ce-page.h" + +#define CE_TYPE_PAGE_TEAM_PORT (ce_page_team_port_get_type ()) +#define CE_PAGE_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_TEAM_PORT, CEPageTeamPort)) +#define CE_PAGE_TEAM_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_TEAM_PORT, CEPageTeamPortClass)) +#define CE_IS_PAGE_TEAM_PORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_TEAM_PORT)) +#define CE_IS_PAGE_TEAM_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_TEAM_PORT)) +#define CE_PAGE_TEAM_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_TEAM_PORT, CEPageTeamPortClass)) + +typedef struct { + CEPage parent; +} CEPageTeamPort; + +typedef struct { + CEPageClass parent; +} CEPageTeamPortClass; + +GType ce_page_team_port_get_type (void); + +CEPage *ce_page_team_port_new (NMConnection *connection, + GtkWindow *parent, + NMClient *client, + NMRemoteSettings *settings, + const char **out_secrets_setting_name, + GError **error); + +#endif /* __PAGE_TEAM_PORT_H__ */ + diff --git a/src/connection-editor/page-team.c b/src/connection-editor/page-team.c new file mode 100644 index 00000000..a14a4d89 --- /dev/null +++ b/src/connection-editor/page-team.c @@ -0,0 +1,384 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <stdlib.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include <nm-setting-connection.h> +#include <nm-setting-team.h> + +#include "page-team.h" +#include "page-ethernet.h" +#include "page-wifi.h" +#include "page-infiniband.h" +#include "page-vlan.h" +#include "nm-connection-editor.h" +#include "new-connection.h" + +G_DEFINE_TYPE (CEPageTeam, ce_page_team, CE_TYPE_PAGE_MASTER) + +#define CE_PAGE_TEAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_TEAM, CEPageTeamPrivate)) + +typedef struct { + NMSettingTeam *setting; + + GType slave_type; + + GtkWindow *toplevel; + + GtkTextView *json_config_widget; + GtkWidget *import_config_button; +} CEPageTeamPrivate; + +static void +team_private_init (CEPageTeam *self) +{ + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + GtkBuilder *builder; + + builder = CE_PAGE (self)->builder; + + priv->json_config_widget = GTK_TEXT_VIEW (gtk_builder_get_object (builder, "team_json_config")); + priv->import_config_button = GTK_WIDGET (gtk_builder_get_object (builder, "import_config_button")); + + priv->toplevel = GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (priv->json_config_widget), + GTK_TYPE_WINDOW)); +} + +static void +json_config_changed (GObject *object, CEPageTeam *self) +{ + ce_page_changed (CE_PAGE (self)); +} + +static void +import_config_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data) +{ + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (user_data); + GtkTextBuffer *buffer; + char *filename; + char *buf = NULL; + gsize buf_len; + + if (response != GTK_RESPONSE_ACCEPT) + goto out; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (!filename) { + g_warning ("%s: didn't get a filename back from the chooser!", __func__); + goto out; + } + + /* Put the file content into JSON config text view. */ + // FIXME: do a cleverer file validity check + g_file_get_contents (filename, &buf, &buf_len, NULL); + if (buf_len > 100000) { + g_free (buf); + buf = g_strdup (_("Error: file doesn't contain a valid JSON configuration")); + } + + buffer = gtk_text_view_get_buffer (priv->json_config_widget); + gtk_text_buffer_set_text (buffer, buf ? buf : "", -1); + + g_free (filename); + g_free (buf); + +out: + gtk_widget_hide (dialog); + gtk_widget_destroy (dialog); +} + +static void +import_button_clicked_cb (GtkWidget *widget, CEPageTeam *self) +{ + GtkWidget *dialog; + + dialog = gtk_file_chooser_dialog_new (_("Select file to import"), + NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL); + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_config_from_file_cb), self); + gtk_widget_show_all (dialog); + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +populate_ui (CEPageTeam *self) +{ + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + NMSettingTeam *s_team = priv->setting; + GtkTextBuffer *buffer; + const char *json_config; + + buffer = gtk_text_view_get_buffer (priv->json_config_widget); + json_config = nm_setting_team_get_config (s_team); + gtk_text_buffer_set_text (buffer, json_config ? json_config : "", -1); + + g_signal_connect (buffer, "changed", G_CALLBACK (json_config_changed), self); + g_signal_connect (priv->import_config_button, "clicked", G_CALLBACK (import_button_clicked_cb), self); +} + +static void +connection_removed (CEPageMaster *master, NMConnection *connection) +{ + CEPageTeam *self = CE_PAGE_TEAM (master); + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + + if (!ce_page_master_has_slaves (master)) + priv->slave_type = G_TYPE_INVALID; +} + +static void +connection_added (CEPageMaster *master, NMConnection *connection) +{ + CEPageTeam *self = CE_PAGE_TEAM (master); + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + + /* A bit kludgy... */ + if (nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) + priv->slave_type = NM_TYPE_SETTING_INFINIBAND; + else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) + priv->slave_type = NM_TYPE_SETTING_WIRED; + else if (nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) + priv->slave_type = NM_TYPE_SETTING_WIRELESS; + else + priv->slave_type = NM_TYPE_SETTING_VLAN; +} + +static void +create_connection (CEPageMaster *master, NMConnection *connection) +{ + NMSetting *s_port; + + s_port = nm_connection_get_setting (connection, NM_TYPE_SETTING_TEAM_PORT); + if (!s_port) { + s_port = nm_setting_team_port_new (); + nm_connection_add_setting (connection, s_port); + } +} + +static gboolean +connection_type_filter_all (GType type, gpointer user_data) +{ + if (type == NM_TYPE_SETTING_WIRED || + type == NM_TYPE_SETTING_WIRELESS || + type == NM_TYPE_SETTING_VLAN || + type == NM_TYPE_SETTING_INFINIBAND) + return TRUE; + else + return FALSE; +} + +static gboolean +connection_type_filter_eth (GType type, gpointer user_data) +{ + if (type == NM_TYPE_SETTING_WIRED || + type == NM_TYPE_SETTING_WIRELESS || + type == NM_TYPE_SETTING_VLAN) + return TRUE; + else + return FALSE; +} + +static void +add_slave (CEPageMaster *master, NewConnectionResultFunc result_func) +{ + CEPageTeam *self = CE_PAGE_TEAM (master); + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + + if (priv->slave_type == NM_TYPE_SETTING_INFINIBAND) { + new_connection_of_type (priv->toplevel, + NULL, + CE_PAGE (self)->settings, + infiniband_connection_new, + result_func, + master); + } else { + new_connection_dialog (priv->toplevel, + CE_PAGE (self)->settings, + priv->slave_type == G_TYPE_INVALID ? connection_type_filter_all : connection_type_filter_eth, + result_func, + master); + } +} + +static void +finish_setup (CEPageTeam *self, gpointer unused, GError *error, gpointer user_data) +{ + if (error) + return; + + populate_ui (self); +} + +CEPage * +ce_page_team_new (NMConnection *connection, + GtkWindow *parent_window, + NMClient *client, + NMRemoteSettings *settings, + const char **out_secrets_setting_name, + GError **error) +{ + CEPageTeam *self; + CEPageTeamPrivate *priv; + + self = CE_PAGE_TEAM (ce_page_new (CE_TYPE_PAGE_TEAM, + connection, + parent_window, + client, + settings, + UIDIR "/ce-page-team.ui", + "TeamPage", + _("Team"))); + if (!self) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, + _("Could not load team user interface.")); + return NULL; + } + + team_private_init (self); + priv = CE_PAGE_TEAM_GET_PRIVATE (self); + + priv->setting = nm_connection_get_setting_team (connection); + if (!priv->setting) { + priv->setting = NM_SETTING_TEAM (nm_setting_team_new ()); + nm_connection_add_setting (connection, NM_SETTING (priv->setting)); + } + + g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL); + + return CE_PAGE (self); +} + +static void +ui_to_setting (CEPageTeam *self) +{ + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + GtkTextBuffer *buffer; + GtkTextIter start, end; + char *json_config; + + buffer = gtk_text_view_get_buffer (priv->json_config_widget); + gtk_text_buffer_get_iter_at_offset (buffer, &start, 0); + gtk_text_buffer_get_iter_at_offset (buffer, &end, -1); + json_config = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); + + if (g_strcmp0 (json_config, "") == 0) + json_config = NULL; + g_object_set (priv->setting, + NM_SETTING_TEAM_CONFIG, json_config, + NULL); + g_free (json_config); +} + +static gboolean +validate (CEPage *page, NMConnection *connection, GError **error) +{ + CEPageTeam *self = CE_PAGE_TEAM (page); + CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self); + + if (!CE_PAGE_CLASS (ce_page_team_parent_class)->validate (page, connection, error)) + return FALSE; + + ui_to_setting (self); + return nm_setting_verify (NM_SETTING (priv->setting), NULL, error); +} + +static void +ce_page_team_init (CEPageTeam *self) +{ +} + +static void +ce_page_team_class_init (CEPageTeamClass *team_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (team_class); + CEPageClass *parent_class = CE_PAGE_CLASS (team_class); + CEPageMasterClass *master_class = CE_PAGE_MASTER_CLASS (team_class); + + g_type_class_add_private (object_class, sizeof (CEPageTeamPrivate)); + + /* virtual methods */ + parent_class->validate = validate; + master_class->create_connection = create_connection; + master_class->connection_added = connection_added; + master_class->connection_removed = connection_removed; + master_class->add_slave = add_slave; +} + + +void +team_connection_new (GtkWindow *parent, + const char *detail, + NMRemoteSettings *settings, + PageNewConnectionResultFunc result_func, + gpointer user_data) +{ + NMConnection *connection; + int team_num, num; + GSList *connections, *iter; + NMConnection *conn2; + NMSettingTeam *s_team; + const char *iface; + char *my_iface; + + connection = ce_page_new_connection (_("Team connection %d"), + NM_SETTING_TEAM_SETTING_NAME, + TRUE, + settings, + user_data); + nm_connection_add_setting (connection, nm_setting_team_new ()); + + /* Find an available interface name */ + team_num = 0; + connections = nm_remote_settings_list_connections (settings); + for (iter = connections; iter; iter = iter->next) { + conn2 = iter->data; + + if (!nm_connection_is_type (conn2, NM_SETTING_TEAM_SETTING_NAME)) + continue; + s_team = nm_connection_get_setting_team (conn2); + if (!s_team) + continue; + iface = nm_setting_team_get_interface_name (s_team); + if (!iface || strncmp (iface, "team", 4) != 0 || !g_ascii_isdigit (iface[4])) + continue; + + num = atoi (iface + 4); + if (team_num <= num) + team_num = num + 1; + } + g_slist_free (connections); + + my_iface = g_strdup_printf ("team%d", team_num); + s_team = nm_connection_get_setting_team (connection); + g_object_set (G_OBJECT (s_team), + NM_SETTING_TEAM_INTERFACE_NAME, my_iface, + NULL); + g_free (my_iface); + + (*result_func) (connection, FALSE, NULL, user_data); +} + diff --git a/src/connection-editor/page-team.h b/src/connection-editor/page-team.h new file mode 100644 index 00000000..d1936b32 --- /dev/null +++ b/src/connection-editor/page-team.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __PAGE_TEAM_H__ +#define __PAGE_TEAM_H__ + +#include <nm-connection.h> + +#include <glib.h> +#include <glib-object.h> + +#include "page-master.h" + +#define CE_TYPE_PAGE_TEAM (ce_page_team_get_type ()) +#define CE_PAGE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_TEAM, CEPageTeam)) +#define CE_PAGE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_TEAM, CEPageTeamClass)) +#define CE_IS_PAGE_TEAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_TEAM)) +#define CE_IS_PAGE_TEAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_TEAM)) +#define CE_PAGE_TEAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_TEAM, CEPageTeamClass)) + +typedef struct { + CEPageMaster parent; +} CEPageTeam; + +typedef struct { + CEPageMasterClass parent; +} CEPageTeamClass; + +GType ce_page_team_get_type (void); + +CEPage *ce_page_team_new (NMConnection *connection, + GtkWindow *parent, + NMClient *client, + NMRemoteSettings *settings, + const char **out_secrets_setting_name, + GError **error); + +void team_connection_new (GtkWindow *parent, + const char *detail, + NMRemoteSettings *settings, + PageNewConnectionResultFunc result_func, + gpointer user_data); + +#endif /* __PAGE_TEAM_H__ */ + diff --git a/src/libnm-gtk/nm-ui-utils.c b/src/libnm-gtk/nm-ui-utils.c index 4d28bae1..69ede41e 100644 --- a/src/libnm-gtk/nm-ui-utils.c +++ b/src/libnm-gtk/nm-ui-utils.c @@ -335,6 +335,8 @@ nma_utils_get_device_type_name (NMDevice *device) return _("InfiniBand"); case NM_DEVICE_TYPE_BOND: return _("Bond"); + case NM_DEVICE_TYPE_TEAM: + return _("Team"); case NM_DEVICE_TYPE_BRIDGE: return _("Bridge"); case NM_DEVICE_TYPE_VLAN: @@ -353,6 +355,7 @@ get_device_type_name_with_iface (NMDevice *device) switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_BOND: + case NM_DEVICE_TYPE_TEAM: case NM_DEVICE_TYPE_BRIDGE: case NM_DEVICE_TYPE_VLAN: return g_strdup_printf ("%s (%s)", type_name, nm_device_get_iface (device)); @@ -557,6 +560,8 @@ nma_utils_get_connection_device_name (NMConnection *connection) if (!strcmp (type, NM_SETTING_BOND_SETTING_NAME)) display_type = _("Bond"); + else if (!strcmp (type, NM_SETTING_TEAM_SETTING_NAME)) + display_type = _("Team"); else if (!strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME)) display_type = _("Bridge"); else if (!strcmp (type, NM_SETTING_VLAN_SETTING_NAME)) |