summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2016-07-04 14:15:44 +0200
committerLubomir Rintel <lkundrak@v3.sk>2016-07-25 14:02:08 +0200
commit65c662d08b34d486d4d567424ccf623cda72389e (patch)
tree87ffb85a7e467360a961962d9f63d614a15ecac4
parentca7cc39ddb22f250dc375ca7b5af7bc815dd0f32 (diff)
downloadnetwork-manager-applet-65c662d08b34d486d4d567424ccf623cda72389e.tar.gz
editor/team: add UI controls for team master configuration
Editing raw JSON is still supported and kept in sync.
-rw-r--r--configure.ac12
-rw-r--r--src/connection-editor/Makefile.am2
-rw-r--r--src/connection-editor/ce-page-team.ui1419
-rw-r--r--src/connection-editor/nm-connection-list.c7
-rw-r--r--src/connection-editor/page-team.c831
5 files changed, 2164 insertions, 107 deletions
diff --git a/configure.ac b/configure.ac
index 3f0693f0..ad795c8a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,6 +125,18 @@ AM_CONDITIONAL(WITH_WWAN, test "${with_wwan}" != "no")
dnl Check for gudev
PKG_CHECK_MODULES(GUDEV, gudev-1.0 >= 147)
+dnl Jansson for team configuration editing
+AC_ARG_WITH(team, AS_HELP_STRING([--with-team], [Enable team configuration editor in libnm (default: yes)]))
+if (test "${with_team}" == "no"); then
+ AC_DEFINE(WITH_JANSSON, 0, [Define if Jansson is available])
+else
+ PKG_CHECK_MODULES(JANSSON,
+ [jansson >= 2.3],,
+ AC_MSG_ERROR([jansson is needed for team configuration editor. Use --without-team to build without it.]))
+ AC_DEFINE(WITH_JANSSON, 1, [Define if Jansson is available])
+fi
+AM_CONDITIONAL(WITH_JANSSON, test "${with_team}" != "no")
+
dnl Check for gobject introspection
GOBJECT_INTROSPECTION_CHECK([0.9.6])
diff --git a/src/connection-editor/Makefile.am b/src/connection-editor/Makefile.am
index 36df551c..f4f2176f 100644
--- a/src/connection-editor/Makefile.am
+++ b/src/connection-editor/Makefile.am
@@ -3,6 +3,7 @@ bin_PROGRAMS = nm-connection-editor
nm_connection_editor_CPPFLAGS = \
$(GTK_CFLAGS) \
$(LIBNM_CFLAGS) \
+ $(JANSSON_CFLAGS) \
-DLIBNM_BUILD \
-DNM_VERSION_MIN_REQUIRED=NM_VERSION_1_4 \
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_1_4 \
@@ -87,6 +88,7 @@ nm_connection_editor_LDADD = \
${top_builddir}/src/libnma/libnma.la \
$(GTK_LIBS) \
$(LIBNM_LIBS) \
+ $(JANSSON_LIBS) \
-lm
uidir = $(datadir)/nm-applet
diff --git a/src/connection-editor/ce-page-team.ui b/src/connection-editor/ce-page-team.ui
index a65a09df..8b444483 100644
--- a/src/connection-editor/ce-page-team.ui
+++ b/src/connection-editor/ce-page-team.ui
@@ -1,6 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.4"/>
+ <object class="GtkListStore" id="agg_select_policy_model">
+ <columns>
+ <!-- column-name type -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">lacp_prio</col>
+ <col id="1" translatable="yes">Highest priority</col>
+ </row>
+ <row>
+ <col id="0">lacp_prio_stable</col>
+ <col id="1" translatable="yes">Highest priority (stable)</col>
+ </row>
+ <row>
+ <col id="0">bandwidth</col>
+ <col id="1" translatable="yes">Bandwidth</col>
+ </row>
+ <row>
+ <col id="0">count</col>
+ <col id="1" translatable="yes">Highest number of ports</col>
+ </row>
+ <row>
+ <col id="0">port_options</col>
+ <col id="1" translatable="yes">Port priority</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkAdjustment" id="delay_down_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="delay_up_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkListStore" id="hwaddr_policy_model">
+ <columns>
+ <!-- column-name type -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">same_all</col>
+ <col id="1" translatable="yes">From the team device</col>
+ </row>
+ <row>
+ <col id="0">by_active</col>
+ <col id="1" translatable="yes">From the active port</col>
+ </row>
+ <row>
+ <col id="0">only_active</col>
+ <col id="1" translatable="yes">From active to team device</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkAdjustment" id="init_wait_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkListStore" id="link_watch_model">
+ <columns>
+ <!-- column-name type -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">ethtool</col>
+ <col id="1" translatable="yes">Ethernet port state</col>
+ </row>
+ <row>
+ <col id="0">arp_ping</col>
+ <col id="1" translatable="yes">ARP (IPv4)</col>
+ </row>
+ <row>
+ <col id="0">nsna_ping</col>
+ <col id="1" translatable="yes">NDP (IPv6)</col>
+ </row>
+ </data>
+ </object>
<object class="GtkListStore" id="master_connections_model">
<columns>
<!-- column-name connection -->
@@ -9,6 +102,54 @@
<column type="gchararray"/>
</columns>
</object>
+ <object class="GtkAdjustment" id="mcast_rejoin_count_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="mcast_rejoin_interval_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="minimum_ports_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="missed_max_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="notify_peeers_interval_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="notify_peers_count_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="send_interval_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="system_priority_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
<object class="GtkAdjustment" id="team_mtu_adjustment">
<property name="upper">10000</property>
<property name="step_increment">1</property>
@@ -18,14 +159,15 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
+ <property name="vexpand">True</property>
<property name="border_width">12</property>
- <property name="column_spacing">12</property>
<property name="row_spacing">8</property>
+ <property name="column_spacing">12</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="halign">start</property>
<property name="label" translatable="yes">_Teamed connections:</property>
<property name="use_underline">True</property>
</object>
@@ -33,59 +175,6 @@
<property name="left_attach">0</property>
<property name="top_attach">2</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">4</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">5</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">Im_port 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">6</property>
- <property name="width">2</property>
- <property name="height">1</property>
</packing>
</child>
<child>
@@ -194,10 +283,9 @@
<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="halign">start</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>
@@ -220,7 +308,7 @@
<object class="GtkLabel" id="team_mtu_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
+ <property name="halign">start</property>
<property name="label" translatable="yes">_MTU:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">team_mtu</property>
@@ -228,19 +316,19 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="team_mtu_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="hexpand">True</property>
<property name="spacing">4</property>
<child>
<object class="GtkSpinButton" id="team_mtu">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="hexpand">True</property>
<property name="adjustment">team_mtu_adjustment</property>
<property name="climb_rate">1</property>
</object>
@@ -254,8 +342,9 @@
<object class="GtkLabel" id="label29">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="xalign">0</property>
+ <property name="halign">start</property>
<property name="label" translatable="yes">bytes</property>
+ <property name="xalign">0</property>
</object>
<packing>
<property name="expand">True</property>
@@ -267,9 +356,1213 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkButton" id="advanced_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="valign">end</property>
+ <property name="vexpand">True</property>
+ <property name="use_underline">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-preferences</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Ad_vanced...</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>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkListStore" id="team_runner_model">
+ <columns>
+ <!-- column-name type -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">broadcast</col>
+ <col id="1" translatable="yes">Broadcast</col>
+ </row>
+ <row>
+ <col id="0">roundrobin</col>
+ <col id="1" translatable="yes">Round-robin</col>
+ </row>
+ <row>
+ <col id="0">activebackup</col>
+ <col id="1" translatable="yes">Active backup</col>
+ </row>
+ <row>
+ <col id="0">loadbalance</col>
+ <col id="1" translatable="yes">Load balance</col>
+ </row>
+ <row>
+ <col id="0">lacp</col>
+ <col id="1" translatable="yes">LACP</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="tx_balancer_model">
+ <columns>
+ <!-- column-name type -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">none</col>
+ <col id="1" translatable="yes">None</col>
+ </row>
+ <row>
+ <col id="0">basic</col>
+ <col id="1" translatable="yes">Basic</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkAdjustment" id="tx_balancing_interval_adjustment">
+ <property name="lower">-1</property>
+ <property name="upper">100</property>
+ <property name="value">50</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkListStore" id="tx_hash_model">
+ <columns>
+ <!-- column-name type -->
+ <column type="gchararray"/>
+ <!-- column-name name -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">eth</col>
+ <col id="1" translatable="yes">Ethernet</col>
+ </row>
+ <row>
+ <col id="0">vlan</col>
+ <col id="1" translatable="yes">VLAN</col>
+ </row>
+ <row>
+ <col id="0">ipv4</col>
+ <col id="1" translatable="yes">IPv4</col>
+ </row>
+ <row>
+ <col id="0">ipv6</col>
+ <col id="1" translatable="yes">IPv6</col>
+ </row>
+ <row>
+ <col id="0">ip</col>
+ <col id="1" translatable="yes">IP</col>
+ </row>
+ <row>
+ <col id="0">l3</col>
+ <col id="1" translatable="yes">Any L3 protocol</col>
+ </row>
+ <row>
+ <col id="0">tcp</col>
+ <col id="1" translatable="yes">TCP</col>
+ </row>
+ <row>
+ <col id="0">udp</col>
+ <col id="1" translatable="yes">UDP</col>
+ </row>
+ <row>
+ <col id="0">sctp</col>
+ <col id="1" translatable="yes">SCTP</col>
+ </row>
+ <row>
+ <col id="0">l4</col>
+ <col id="1" translatable="yes">Any L4 protocol</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkDialog" id="advanced_dialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Team Advanced Options</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="advanced_dialog_box">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="advanced_buttons">
+ <property name="can_focus">False</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="advanced_cancel">
+ <property name="label">gtk-cancel</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">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="advanced_ok">
+ <property name="label">gtk-ok</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">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="advanced_notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">6</property>
+ <child>
+ <object class="GtkGrid" id="general_grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="border_width">12</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="notify_peers_count_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Peer notification count:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">notify_peers_count</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="notify_peers_interval_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Peer _notification interval:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">notify_peers_interval</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="mcast_rejoin_count_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Multicast rejoin count:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">mcast_rejoin_count</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="mcast_rejoin_interval_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Multicast _rejoin interval:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">mcast_rejoin_interval</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="notify_peers_count">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Number of bursts of unsolicited NAs and gratuitous ARP packets sent after port is enabled or disabled.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">notify_peers_count_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="mcast_rejoin_count">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Number of bursts of multicast group rejoin requests sent after port is enabled or disabled.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">mcast_rejoin_count_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">ms</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">ms</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="notify_peers_interval">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Value is positive number in milliseconds. Specifies an interval between bursts of notify-peer packets.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">notify_peeers_interval_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="mcast_rejoin_interval">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Value is positive number in milliseconds. Specifies an interval between bursts of multicast group rejoin requests.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">mcast_rejoin_interval_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="hwaddr_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Hardware Address:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="hwaddr">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Desired hardware address of new team device. Usual MAC address format is accepted.</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="general_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">General</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="runner_grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">12</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <property name="column_homogeneous">True</property>
+ <child>
+ <object class="GtkLabel" id="team_runner_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Runner:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">team_runner</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="hwaddr_policy_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Hardware address policy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">hwaddr_policy</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="team_runner">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Name of runner to be used.</property>
+ <property name="model">team_runner_model</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="team_runner_renderer"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="hwaddr_policy">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">This defines the policy of how hardware addresses of team device and port devices should be set during the team lifetime.</property>
+ <property name="model">hwaddr_policy_model</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="hwaddr_policy_renderer"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="active">
+ <property name="label" translatable="yes">Send LACPDU frames _periodically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">If checked, LACPDU frames are sent along the configured links periodically. If not, it acts as "speak when spoken to".</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">8</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="fast_rate">
+ <property name="label" translatable="yes">Send a LACPDU frame _every second</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">Option specifies the rate at which our link partner is asked to transmit LACPDU packets. If checked, packets will be sent once per second. Otherwise they will be sent every 30 seconds.</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="system_priority_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_System priority:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">system_priority</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="minimum_ports_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Minimum ports:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">minimum_ports</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="agg_selection_policy_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Aggregator selection policy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">agg_selection_policy</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="system_priority">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">System priority, value can be 0 – 65535.</property>
+ <property name="adjustment">system_priority_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="minimum_ports">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Specifies the minimum number of ports that must be active before asserting carrier in the master interface, value can be 1 – 255.</property>
+ <property name="adjustment">minimum_ports_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="agg_selection_policy">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">This selects the policy of how the aggregators will be selected.</property>
+ <property name="model">agg_select_policy_model</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="tx_hash_frame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">6</property>
+ <property name="margin_bottom">5</property>
+ <property name="vexpand">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="height_request">128</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="tx_hash">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">List of fragment types (strings) which should be used for packet Tx hash computation.</property>
+ <property name="margin_bottom">9</property>
+ <property name="model">tx_hash_model</property>
+ <property name="headers_visible">False</property>
+ <property name="enable_search">False</property>
+ <property name="show_expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection">
+ <property name="mode">multiple</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="tx_hash_column">
+ <child>
+ <object class="GtkCellRendererText" id="tx_hash_renderer"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="tx_hash_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">_Fields for tramsmission hash</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">tx_hash</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="tx_balancing_interval">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">In tenths of a second. Periodic interval between rebalancing.</property>
+ <property name="adjustment">tx_balancing_interval_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="tx_balancer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Name of active Tx balancer. Active Tx balancing is disabled by default.</property>
+ <property name="hexpand">True</property>
+ <property name="model">tx_balancer_model</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="tx_balancing_interval_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Transmission _balancing interval:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">tx_balancing_interval</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="tx_balancer_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Transmission balancer:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">tx_balancer</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="runner_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Runner</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="link_watch_grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="border_width">12</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="link_watcher_name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Link watcher:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">link_watcher_name</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="delay_up_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Up delay:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">delay_up</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="delay_down_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Down delay:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">delay_down</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="send_interval_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Send _interval:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">send_interval</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="init_wait_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Delay _before first send:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">init_wait</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="missed_max_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Maximum missed replies:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">missed_max</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="source_host_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">_Source host:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">source_host</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="target_host_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="hexpand">False</property>
+ <property name="label" translatable="yes">_Target host:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">target_host</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="missed_max">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Maximum number of missed replies. If this number is exceeded, link is reported as down.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">missed_max_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="source_host">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Hostname to be converted to IP address which will be filled into ARP request as source address.</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="target_host">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">Hostname to be converted to IP address which will be filled into request as destination address.</property>
+ <property name="hexpand">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="validate_active">
+ <property name="label" translatable="yes">Ignore invalid packets from _active ports</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">Validate received ARP packets on active ports. If this is not checked, all incoming ARP packets will be considered as a good reply.</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">8</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="validate_inactive">
+ <property name="label" translatable="yes">Ignore invalid packets from i_nactive ports</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">Validate received ARP packets on inactive ports. If this is not checked, all incoming ARP packets will be considered as a good reply.</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="send_all">
+ <property name="label" translatable="yes">S_end on inactive ports</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">By default, ARP requests are sent on active ports only. This option allows sending even on inactive ports.</property>
+ <property name="halign">start</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">10</property>
+ <property name="width">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="delay_up_ms">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">ms</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="delay_down_ms">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">ms</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="send_interval_ms">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">ms</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="init_wait_ms">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label">ms</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="delay_up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">The delay between the link coming up and the runner being notified about it.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">delay_up_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="delay_down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">The delay between the link going down and the runner being notified about it.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">delay_down_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="send_interval">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">The interval between requests being sent.</property>
+ <property name="hexpand">True</property>
+ <property name="adjustment">send_interval_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="init_wait">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip_text" translatable="yes">The delay between link watch initialization and the first request being sent.</property>
+ <property name="hexpand">False</property>
+ <property name="adjustment">init_wait_adjustment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="link_watcher_name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">The link watcher to be used.</property>
+ <property name="hexpand">True</property>
+ <property name="model">link_watch_model</property>
+ <property name="active">0</property>
+ <property name="id_column">0</property>
+ <child>
+ <object class="GtkCellRendererText" id="link_watch_renderer"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="link_watch_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Link Watcher</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="json_grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="vexpand">True</property>
+ <property name="border_width">12</property>
+ <property name="row_spacing">8</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkButton" id="import_config_button">
+ <property name="label" translatable="yes">Im_port team configuration from a file...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</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>
+ <property name="vexpand">True</property>
+ <property name="monospace">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">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="label" translatable="yes">Edit _JSON configuration:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">team_json_config</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="json_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Raw Configuration</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">advanced_cancel</action-widget>
+ <action-widget response="-5">advanced_ok</action-widget>
+ </action-widgets>
</object>
</interface>
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 5c092dcf..9f5a75ee 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -857,9 +857,12 @@ nm_connection_list_new (void)
gtk_window_set_default_icon_name ("preferences-system-network");
- list->client = nm_client_new (NULL, NULL);
- if (!list->client)
+ list->client = nm_client_new (NULL, &error);
+ if (!list->client) {
+ g_warning ("Couldn't construct the client instance: %s", error->message);
+ g_error_free (error);
goto error;
+ }
g_signal_connect (list->client,
NM_CLIENT_CONNECTION_ADDED,
G_CALLBACK (connection_added),
diff --git a/src/connection-editor/page-team.c b/src/connection-editor/page-team.c
index b4900a96..1c530f6f 100644
--- a/src/connection-editor/page-team.c
+++ b/src/connection-editor/page-team.c
@@ -23,6 +23,9 @@
#include "nm-default.h"
#include <stdlib.h>
+#if WITH_JANSSON
+#include <jansson.h>
+#endif
#include "page-team.h"
#include "page-infiniband.h"
@@ -39,24 +42,198 @@ typedef struct {
int slave_arptype;
- GtkWindow *toplevel;
-
GtkTextView *json_config_widget;
GtkWidget *import_config_button;
+
GtkSpinButton *mtu;
+ GtkButton *advanced_button;
+ GtkDialog *advanced_dialog;
+ GtkNotebook *advanced_notebook;
+
+ /* General */
+ GtkSpinButton *notify_peers_count;
+ GtkSpinButton *notify_peers_interval;
+ GtkSpinButton *mcast_rejoin_count;
+ GtkSpinButton *mcast_rejoin_interval;
+ GtkEntry *hwaddr;
+
+ /* Runner */
+ GtkComboBox *runner_name;
+ GtkComboBox *hwaddr_policy;
+ GtkLabel *hwaddr_policy_label;
+ GtkFrame *tx_hash_frame;
+ GtkTreeView *tx_hash;
+ GtkComboBox *tx_balancer;
+ GtkLabel *tx_balancer_label;
+ GtkSpinButton *tx_balancing_interval;
+ GtkLabel *tx_balancing_interval_label;
+ GtkToggleButton *active;
+ GtkToggleButton *fast_rate;
+ GtkSpinButton *system_priority;
+ GtkLabel *system_priority_label;
+ GtkSpinButton *minimum_ports;
+ GtkLabel *minimum_ports_label;
+ GtkComboBox *agg_selection_policy;
+ GtkLabel *agg_selection_policy_label;
+
+ /* Link Watch */
+ GtkComboBox *link_watcher_name;
+ GtkSpinButton *delay_up;
+ GtkLabel *delay_up_label;
+ GtkLabel *delay_up_ms;
+ GtkSpinButton *delay_down;
+ GtkLabel *delay_down_label;
+ GtkLabel *delay_down_ms;
+ GtkSpinButton *send_interval;
+ GtkLabel *send_interval_label;
+ GtkLabel *send_interval_ms;
+ GtkSpinButton *init_wait;
+ GtkLabel *init_wait_label;
+ GtkLabel *init_wait_ms;
+ GtkSpinButton *missed_max;
+ GtkLabel *missed_max_label;
+ GtkEntry *source_host;
+ GtkLabel *source_host_label;
+ GtkEntry *target_host;
+ GtkLabel *target_host_label;
+ GtkToggleButton *validate_active;
+ GtkToggleButton *validate_inactive;
+ GtkToggleButton *send_all;
} CEPageTeamPrivate;
-static void
-widget_realized_cb (GtkWidget *widget, gpointer user_data)
+/* Get string "type" from a combo box with a ["type", "name"] model. */
+static gchar *
+get_combo_box (GtkComboBox *combo)
{
- CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (user_data);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *name;
+
+ if (!gtk_combo_box_get_active_iter (combo, &iter))
+ g_return_val_if_reached (NULL);
+
+ model = gtk_combo_box_get_model (combo);
+ gtk_tree_model_get (model, &iter, 0, &name, -1);
- priv->toplevel = GTK_WINDOW (gtk_widget_get_toplevel (widget));
- if (!gtk_widget_is_toplevel (GTK_WIDGET (priv->toplevel)))
- priv->toplevel = NULL;
- g_signal_handlers_disconnect_by_func (widget, widget_realized_cb, user_data);
+ return name;
}
+#if WITH_JANSSON
+
+/* Set active item to "type" in a combo box with a ["type", "name"] model. */
+static gboolean
+set_combo_box (GtkComboBox *combo, const gchar *value, GError **error)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+ const gchar *name;
+ int i = 0;
+
+ if (!value || !*value) {
+ gtk_combo_box_set_active (combo, 0);
+ return TRUE;
+ }
+
+ model = gtk_combo_box_get_model (combo);
+ for (valid = gtk_tree_model_get_iter_first (model, &iter);
+ valid;
+ valid = gtk_tree_model_iter_next (model, &iter)) {
+ gtk_tree_model_get (model, &iter, 0, &name, -1);
+ if (strcmp (name, value) == 0) {
+ gtk_combo_box_set_active (combo, i);
+ return TRUE;
+ }
+ i++;
+ }
+
+ g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
+ "Value of \"%s\" is not known", value);
+
+ return FALSE;
+}
+
+/* Set active items to values of "type" in a tree view with a ["type", "name"]
+ * model (for setting the tx_hash). */
+static gboolean
+select_in_tree (GtkTreeView *tree, json_t *arr, GError **error)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+ const gchar *name;
+ GtkTreeSelection *selection;
+ size_t i;
+ json_t *val;
+
+ model = gtk_tree_view_get_model (tree);
+ selection = gtk_tree_view_get_selection (tree);
+
+ gtk_tree_selection_unselect_all (selection);
+
+ if (!arr)
+ return TRUE;
+
+ json_array_foreach (arr, i, val) {
+ const char *str;
+
+ if (!json_is_string (val)) {
+ g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC,
+ "Expected a string.");
+ return FALSE;
+ }
+
+ str = json_string_value (val);
+
+ for (valid = gtk_tree_model_get_iter_first (model, &iter);
+ valid;
+ valid = gtk_tree_model_iter_next (model, &iter)) {
+ gtk_tree_model_get (model, &iter, 0, &name, -1);
+ if (strcmp (name, str) == 0) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ break;
+ }
+ }
+
+ if (!valid) {
+ g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC,
+ "Unrecognized value \"%s\".", str);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Set active items to values of "type" in a tree view with a ["type", "name"]
+ * model (for setting the tx_hash). */
+static json_t *
+selected_in_tree (GtkTreeView *tree)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+ const gchar *name;
+ GtkTreeSelection *selection;
+ json_t *arr = json_array ();
+
+ model = gtk_tree_view_get_model (tree);
+ selection = gtk_tree_view_get_selection (tree);
+
+ for (valid = gtk_tree_model_get_iter_first (model, &iter);
+ valid;
+ valid = gtk_tree_model_iter_next (model, &iter)) {
+ gtk_tree_model_get (model, &iter, 0, &name, -1);
+ if (!gtk_tree_selection_iter_is_selected (selection, &iter))
+ continue;
+ json_array_append_new (arr, json_string (name));
+ }
+
+ return arr;
+}
+
+#endif
+
static void
team_private_init (CEPageTeam *self)
{
@@ -67,10 +244,77 @@ team_private_init (CEPageTeam *self)
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->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "team_mtu"));
- /* Wait for widget to be realized to get toplevel window */
- g_signal_connect (priv->json_config_widget, "realize", G_CALLBACK (widget_realized_cb), self);
+ priv->advanced_button = GTK_BUTTON (gtk_builder_get_object (builder, "advanced_button"));
+ priv->advanced_dialog = GTK_DIALOG (gtk_builder_get_object (builder, "advanced_dialog"));
+ gtk_window_set_modal (GTK_WINDOW (priv->advanced_dialog), TRUE);
+ priv->advanced_notebook = GTK_NOTEBOOK (gtk_builder_get_object (builder, "advanced_notebook"));
+
+ /* General */
+ priv->notify_peers_count = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "notify_peers_count"));
+ priv->notify_peers_interval = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "notify_peers_interval"));
+ priv->mcast_rejoin_count = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "mcast_rejoin_count"));
+ priv->mcast_rejoin_interval = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "mcast_rejoin_interval"));
+ priv->hwaddr = GTK_ENTRY (gtk_builder_get_object (builder, "hwaddr"));
+
+ /* Runner */
+ priv->runner_name = GTK_COMBO_BOX (gtk_builder_get_object (builder, "team_runner"));
+ priv->active = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "active"));
+ priv->fast_rate = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "fast_rate"));
+ priv->system_priority = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "system_priority"));
+ priv->system_priority_label = GTK_LABEL (gtk_builder_get_object (builder, "system_priority_label"));
+ priv->minimum_ports = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "minimum_ports"));
+ priv->minimum_ports_label = GTK_LABEL (gtk_builder_get_object (builder, "minimum_ports_label"));
+ priv->agg_selection_policy = GTK_COMBO_BOX (gtk_builder_get_object (builder, "agg_selection_policy"));
+ priv->agg_selection_policy_label = GTK_LABEL (gtk_builder_get_object (builder, "agg_selection_policy_label"));
+ priv->hwaddr_policy = GTK_COMBO_BOX (gtk_builder_get_object (builder, "hwaddr_policy"));
+ priv->hwaddr_policy_label = GTK_LABEL (gtk_builder_get_object (builder, "hwaddr_policy_label"));
+ priv->tx_hash_frame = GTK_FRAME (gtk_builder_get_object (builder, "tx_hash_frame"));
+ priv->tx_hash = GTK_TREE_VIEW (gtk_builder_get_object (builder, "tx_hash"));
+ priv->tx_balancer = GTK_COMBO_BOX (gtk_builder_get_object (builder, "tx_balancer"));
+ priv->tx_balancer_label = GTK_LABEL (gtk_builder_get_object (builder, "tx_balancer_label"));
+ priv->tx_balancing_interval = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "tx_balancing_interval"));
+ priv->tx_balancing_interval_label = GTK_LABEL (gtk_builder_get_object (builder, "tx_balancing_interval_label"));
+
+ /* Link Watcher */
+ priv->link_watcher_name = GTK_COMBO_BOX (gtk_builder_get_object (builder, "link_watcher_name"));
+ priv->send_interval = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "send_interval"));
+ priv->send_interval_label = GTK_LABEL (gtk_builder_get_object (builder, "send_interval_label"));
+ priv->send_interval_ms = GTK_LABEL (gtk_builder_get_object (builder, "send_interval_ms"));
+ priv->init_wait = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "init_wait"));
+ priv->init_wait_label = GTK_LABEL (gtk_builder_get_object (builder, "init_wait_label"));
+ priv->init_wait_ms = GTK_LABEL (gtk_builder_get_object (builder, "init_wait_ms"));
+ priv->missed_max = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "missed_max"));
+ priv->missed_max_label = GTK_LABEL (gtk_builder_get_object (builder, "missed_max_label"));
+ priv->source_host = GTK_ENTRY (gtk_builder_get_object (builder, "source_host"));
+ priv->source_host_label = GTK_LABEL (gtk_builder_get_object (builder, "source_host_label"));
+ priv->target_host = GTK_ENTRY (gtk_builder_get_object (builder, "target_host"));
+ priv->target_host_label = GTK_LABEL (gtk_builder_get_object (builder, "target_host_label"));
+ priv->validate_active = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "validate_active"));
+ priv->validate_inactive = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "validate_inactive"));
+ priv->send_all = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "send_all"));
+ priv->delay_up = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "delay_up"));
+ priv->delay_up_label = GTK_LABEL (gtk_builder_get_object (builder, "delay_up_label"));
+ priv->delay_up_ms = GTK_LABEL (gtk_builder_get_object (builder, "delay_up_ms"));
+ priv->delay_down = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "delay_down"));
+ priv->delay_down_label = GTK_LABEL (gtk_builder_get_object (builder, "delay_down_label"));
+ priv->delay_down_ms = GTK_LABEL (gtk_builder_get_object (builder, "delay_down_ms"));
+
+ ce_spin_default_val (priv->notify_peers_count, -1);
+ ce_spin_default_val (priv->notify_peers_interval, -1);
+ ce_spin_default_val (priv->notify_peers_interval, -1);
+ ce_spin_default_val (priv->mcast_rejoin_count, -1);
+ ce_spin_default_val (priv->mcast_rejoin_interval, -1);
+ ce_spin_default_val (priv->tx_balancing_interval, -1);
+ ce_spin_default_val (priv->system_priority, -1);
+ ce_spin_default_val (priv->minimum_ports, -1);
+ ce_spin_default_val (priv->delay_up, -1);
+ ce_spin_default_val (priv->delay_down, -1);
+ ce_spin_default_val (priv->send_interval, -1);
+ ce_spin_default_val (priv->init_wait, -1);
+ ce_spin_default_val (priv->missed_max, -1);
}
static void
@@ -80,12 +324,6 @@ stuff_changed (GtkWidget *w, gpointer user_data)
}
static void
-json_config_changed (GObject *object, CEPageTeam *self)
-{
- ce_page_changed (CE_PAGE (self));
-}
-
-static void
import_button_clicked_cb (GtkWidget *widget, CEPageTeam *self)
{
CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
@@ -94,9 +332,14 @@ import_button_clicked_cb (GtkWidget *widget, CEPageTeam *self)
char *filename;
char *buf = NULL;
gsize buf_len;
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (CE_PAGE (self)->page);
+ g_return_if_fail (toplevel);
+ g_return_if_fail (gtk_widget_is_toplevel (toplevel));
dialog = gtk_file_chooser_dialog_new (_("Select file to import"),
- priv->toplevel,
+ GTK_WINDOW (toplevel),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
@@ -130,20 +373,528 @@ out:
}
static void
-populate_ui (CEPageTeam *self)
+runner_changed (GtkComboBox *combo, gpointer user_data)
+{
+ CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (user_data);
+ gchar *name;
+
+ /* First hide everything and then show just what we need. */
+ gtk_widget_hide (GTK_WIDGET (priv->hwaddr_policy));
+ gtk_widget_hide (GTK_WIDGET (priv->hwaddr_policy_label));
+ gtk_widget_hide (GTK_WIDGET (priv->tx_hash_frame));
+ gtk_widget_hide (GTK_WIDGET (priv->tx_hash));
+ gtk_widget_hide (GTK_WIDGET (priv->tx_balancer));
+ gtk_widget_hide (GTK_WIDGET (priv->tx_balancer_label));
+ gtk_widget_hide (GTK_WIDGET (priv->tx_balancing_interval));
+ gtk_widget_hide (GTK_WIDGET (priv->tx_balancing_interval_label));
+ gtk_widget_hide (GTK_WIDGET (priv->active));
+ gtk_widget_hide (GTK_WIDGET (priv->fast_rate));
+ gtk_widget_hide (GTK_WIDGET (priv->system_priority));
+ gtk_widget_hide (GTK_WIDGET (priv->system_priority_label));
+ gtk_widget_hide (GTK_WIDGET (priv->minimum_ports));
+ gtk_widget_hide (GTK_WIDGET (priv->minimum_ports_label));
+ gtk_widget_hide (GTK_WIDGET (priv->agg_selection_policy));
+ gtk_widget_hide (GTK_WIDGET (priv->agg_selection_policy_label));
+
+ name = get_combo_box (combo);
+ if (g_strcmp0 (name, "broadcast") == 0 || g_strcmp0 (name, "roundrobin") == 0) {
+ /* No options for these. */
+ } else if (g_strcmp0 (name, "activebackup") == 0) {
+ gtk_widget_show (GTK_WIDGET (priv->hwaddr_policy));
+ gtk_widget_show (GTK_WIDGET (priv->hwaddr_policy_label));
+ } else if (g_strcmp0 (name, "loadbalance") == 0 || g_strcmp0 (name, "lacp") == 0) {
+ gtk_widget_show (GTK_WIDGET (priv->tx_hash_frame));
+ gtk_widget_show (GTK_WIDGET (priv->tx_hash));
+ gtk_widget_show (GTK_WIDGET (priv->tx_balancer));
+ gtk_widget_show (GTK_WIDGET (priv->tx_balancer_label));
+ gtk_widget_show (GTK_WIDGET (priv->tx_balancing_interval));
+ gtk_widget_show (GTK_WIDGET (priv->tx_balancing_interval_label));
+
+ if (g_strcmp0 (name, "lacp") == 0) {
+ gtk_widget_show (GTK_WIDGET (priv->active));
+ gtk_widget_show (GTK_WIDGET (priv->fast_rate));
+ gtk_widget_show (GTK_WIDGET (priv->system_priority));
+ gtk_widget_show (GTK_WIDGET (priv->system_priority_label));
+ gtk_widget_show (GTK_WIDGET (priv->minimum_ports));
+ gtk_widget_show (GTK_WIDGET (priv->minimum_ports_label));
+ gtk_widget_show (GTK_WIDGET (priv->agg_selection_policy));
+ gtk_widget_show (GTK_WIDGET (priv->agg_selection_policy_label));
+ }
+ } else {
+ g_return_if_reached ();
+ }
+ g_free (name);
+}
+
+static void
+link_watcher_changed (GtkComboBox *combo, gpointer user_data)
+{
+ CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (user_data);
+ gchar *name;
+
+ /* First hide everything and then show just what we need. */
+ gtk_widget_hide (GTK_WIDGET (priv->delay_up));
+ gtk_widget_hide (GTK_WIDGET (priv->delay_up_label));
+ gtk_widget_hide (GTK_WIDGET (priv->delay_up_ms));
+ gtk_widget_hide (GTK_WIDGET (priv->delay_down));
+ gtk_widget_hide (GTK_WIDGET (priv->delay_down_label));
+ gtk_widget_hide (GTK_WIDGET (priv->delay_down_ms));
+ gtk_widget_hide (GTK_WIDGET (priv->send_interval));
+ gtk_widget_hide (GTK_WIDGET (priv->send_interval_label));
+ gtk_widget_hide (GTK_WIDGET (priv->send_interval_ms));
+ gtk_widget_hide (GTK_WIDGET (priv->init_wait));
+ gtk_widget_hide (GTK_WIDGET (priv->init_wait_label));
+ gtk_widget_hide (GTK_WIDGET (priv->init_wait_ms));
+ gtk_widget_hide (GTK_WIDGET (priv->missed_max));
+ gtk_widget_hide (GTK_WIDGET (priv->missed_max_label));
+ gtk_widget_hide (GTK_WIDGET (priv->source_host));
+ gtk_widget_hide (GTK_WIDGET (priv->source_host_label));
+ gtk_widget_hide (GTK_WIDGET (priv->target_host));
+ gtk_widget_hide (GTK_WIDGET (priv->target_host_label));
+ gtk_widget_hide (GTK_WIDGET (priv->validate_active));
+ gtk_widget_hide (GTK_WIDGET (priv->validate_inactive));
+ gtk_widget_hide (GTK_WIDGET (priv->send_all));
+
+ name = get_combo_box (combo);
+ if (g_strcmp0 (name, "ethtool") == 0) {
+ gtk_widget_show (GTK_WIDGET (priv->delay_up));
+ gtk_widget_show (GTK_WIDGET (priv->delay_up_label));
+ gtk_widget_show (GTK_WIDGET (priv->delay_up_ms));
+ gtk_widget_show (GTK_WIDGET (priv->delay_down));
+ gtk_widget_show (GTK_WIDGET (priv->delay_down_label));
+ gtk_widget_show (GTK_WIDGET (priv->delay_down_ms));
+ } else if (g_strcmp0 (name, "arp_ping") == 0) {
+ gtk_widget_show (GTK_WIDGET (priv->send_interval));
+ gtk_widget_show (GTK_WIDGET (priv->send_interval_label));
+ gtk_widget_show (GTK_WIDGET (priv->send_interval_ms));
+ gtk_widget_show (GTK_WIDGET (priv->init_wait));
+ gtk_widget_show (GTK_WIDGET (priv->init_wait_label));
+ gtk_widget_show (GTK_WIDGET (priv->init_wait_ms));
+ gtk_widget_show (GTK_WIDGET (priv->missed_max));
+ gtk_widget_show (GTK_WIDGET (priv->missed_max_label));
+ gtk_widget_show (GTK_WIDGET (priv->source_host));
+ gtk_widget_show (GTK_WIDGET (priv->source_host_label));
+ gtk_widget_show (GTK_WIDGET (priv->target_host));
+ gtk_widget_show (GTK_WIDGET (priv->target_host_label));
+ gtk_widget_show (GTK_WIDGET (priv->validate_active));
+ gtk_widget_show (GTK_WIDGET (priv->validate_inactive));
+ gtk_widget_show (GTK_WIDGET (priv->send_all));
+ } else if (g_strcmp0 (name, "nsna_ping") == 0) {
+ gtk_widget_show (GTK_WIDGET (priv->send_interval));
+ gtk_widget_show (GTK_WIDGET (priv->send_interval_label));
+ gtk_widget_show (GTK_WIDGET (priv->send_interval_ms));
+ gtk_widget_show (GTK_WIDGET (priv->init_wait));
+ gtk_widget_show (GTK_WIDGET (priv->init_wait_label));
+ gtk_widget_show (GTK_WIDGET (priv->init_wait_ms));
+ gtk_widget_show (GTK_WIDGET (priv->missed_max));
+ gtk_widget_show (GTK_WIDGET (priv->missed_max_label));
+ gtk_widget_show (GTK_WIDGET (priv->target_host));
+ gtk_widget_show (GTK_WIDGET (priv->target_host_label));
+ } else {
+ g_return_if_reached ();
+ }
+ g_free (name);
+}
+
+#if WITH_JANSSON
+
+static gboolean
+json_to_dialog (CEPageTeam *self)
+{
+ CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
+ char *json_config;
+ json_t *json;
+ json_error_t json_error;
+ int ret;
+ gboolean success = TRUE;
+ GtkTextIter start, end;
+ GtkTextBuffer *buffer;
+ GError *error = NULL;
+ /* General */
+ int notify_peers_count = -1;
+ int notify_peers_interval = -1;
+ int mcast_rejoin_count = -1;
+ int mcast_rejoin_interval = -1;
+ const char *hwaddr = "";
+ /* Runner */
+ const char *runner_name = "";
+ const char *runner_hwaddr_policy = "";
+ json_t *runner_tx_hash = NULL;
+ const char *runner_tx_balancer_name = "";
+ int runner_tx_balancer_balancing_interval = -1;
+ int runner_active = TRUE;
+ int runner_fast_rate = FALSE;
+ int runner_sys_prio = -1;
+ int runner_min_ports = -1;
+ const char *runner_agg_select_policy = "";
+ /* Link Watch */
+ const char *link_watch_name = "";
+ int link_watch_delay_up = -1;
+ int link_watch_delay_down = -1;
+ int link_watch_interval = -1;
+ int link_watch_init_wait = -1;
+ int link_watch_missed_max = -1;
+ const char *link_watch_source_host = "";
+ const char *link_watch_target_host = "";
+ int link_watch_validate_active = FALSE;
+ int link_watch_validate_inactive = FALSE;
+ int link_watch_send_always = FALSE;
+
+ 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 (strcmp (json_config, "") == 0) {
+ /* Initial empty configuration */
+ json = json_object ();
+ } else {
+ json = json_loads (json_config, 0, &json_error);
+ }
+
+ if (!json) {
+ g_message ("Failed to parse JSON: %s on line %d", json_error.text, json_error.line);
+ success = FALSE;
+ }
+
+ /* For simplicity, we proceed with json==NULL. The attempt to
+ * unpack will produce an error which we'll ignore. */
+ g_free (json_config);
+ ret = json_unpack_ex (json, &json_error, 0,
+ "{"
+ " s?:s,"
+ " s?:{s?:i, s?:i !},"
+ " s?:{s?:i, s?:i !},"
+ " s?:{s?:s, s?:s, s?:o, s?:{s?:s, s?:i !}, s?:b, s?:b, s?:i, s?:i, s?:s !},"
+ " s?:{s?:s, s?:i, s?:i, s?:i, s?:i, s?:i, s?:s, s?:s, s?:b, s?:b, s?:b !}"
+ "!}",
+ "hwaddr", &hwaddr,
+ "notify_peers",
+ "interval", &notify_peers_interval,
+ "count", &notify_peers_count,
+ "mcast_rejoin",
+ "count", &mcast_rejoin_count,
+ "interval", &mcast_rejoin_interval,
+ "runner",
+ "name", &runner_name,
+ "hwaddr_policy", &runner_hwaddr_policy,
+ "tx_hash", &runner_tx_hash,
+ "tx_balancer",
+ "name", &runner_tx_balancer_name,
+ "balancing_interval", &runner_tx_balancer_balancing_interval,
+ "active", &runner_active,
+ "fast_rate", &runner_fast_rate,
+ "sys_prio", &runner_sys_prio,
+ "min_ports", &runner_min_ports,
+ "agg_select_policy", &runner_agg_select_policy,
+ "link_watch",
+ "name", &link_watch_name,
+ "delay_up", &link_watch_delay_up,
+ "delay_down", &link_watch_delay_down,
+ "interval", &link_watch_interval,
+ "init_wait", &link_watch_init_wait,
+ "missed_max", &link_watch_missed_max,
+ "source_host", &link_watch_source_host,
+ "target_host", &link_watch_target_host,
+ "validate_active", &link_watch_validate_active,
+ "validate_inactive", &link_watch_validate_inactive,
+ "send_always", &link_watch_send_always);
+
+ if (success == TRUE && ret == -1) {
+ g_message ("Failed to parse JSON: %s on line %d", json_error.text, json_error.line);
+ success = FALSE;
+ }
+
+ /* We proceed setting the form fields even in case we couldn't unpack.
+ * That way we'll get at least sensible default values. Editing will
+ * be disabled anyway. */
+ gtk_entry_set_text (priv->hwaddr, hwaddr);
+ gtk_spin_button_set_value (priv->notify_peers_count, notify_peers_count);
+ gtk_spin_button_set_value (priv->notify_peers_interval, notify_peers_interval);
+ gtk_spin_button_set_value (priv->mcast_rejoin_count, mcast_rejoin_count);
+ gtk_spin_button_set_value (priv->mcast_rejoin_interval, mcast_rejoin_interval);
+ if (!set_combo_box (priv->link_watcher_name, link_watch_name, &error)) {
+ g_message ("Cannot read link watcher name: %s", error->message);
+ g_clear_error (&error);
+ success = FALSE;
+ }
+ if (!set_combo_box (priv->runner_name, runner_name, &error)) {
+ g_message ("Cannot read runner name: %s", error->message);
+ g_clear_error (&error);
+ success = FALSE;
+ }
+ if (!set_combo_box (priv->hwaddr_policy, runner_hwaddr_policy, &error)) {
+ g_message ("Cannot read hardware address policy: %s", error->message);
+ g_clear_error (&error);
+ success = FALSE;
+ }
+ if (!select_in_tree (priv->tx_hash, runner_tx_hash, &error)) {
+ g_message ("Cannot read transmission hash: %s", error->message);
+ g_clear_error (&error);
+ success = FALSE;
+ }
+ if (!set_combo_box (priv->tx_balancer, runner_tx_balancer_name, &error)) {
+ g_message ("Cannot read balancer name: %s", error->message);
+ g_clear_error (&error);
+ success = FALSE;
+ }
+ gtk_spin_button_set_value (priv->tx_balancing_interval, runner_tx_balancer_balancing_interval);
+ gtk_toggle_button_set_active (priv->active, runner_active);
+ gtk_toggle_button_set_active (priv->fast_rate, runner_fast_rate);
+ gtk_spin_button_set_value (priv->system_priority, runner_sys_prio);
+ gtk_spin_button_set_value (priv->minimum_ports, runner_min_ports);
+ if (!set_combo_box (priv->agg_selection_policy, runner_agg_select_policy, &error)) {
+ g_message ("Cannot read aggergator select policy: %s", error->message);
+ g_clear_error (&error);
+ success = FALSE;
+ }
+ gtk_spin_button_set_value (priv->delay_up, link_watch_delay_up);
+ gtk_spin_button_set_value (priv->delay_down, link_watch_delay_down);
+ gtk_spin_button_set_value (priv->send_interval, link_watch_interval);
+ gtk_spin_button_set_value (priv->init_wait, link_watch_init_wait);
+ gtk_spin_button_set_value (priv->missed_max, link_watch_missed_max);
+ gtk_entry_set_text (priv->source_host, link_watch_source_host);
+ gtk_entry_set_text (priv->target_host, link_watch_target_host);
+ gtk_toggle_button_set_active (priv->validate_active, link_watch_validate_active);
+ gtk_toggle_button_set_active (priv->validate_inactive, link_watch_validate_inactive);
+ gtk_toggle_button_set_active (priv->send_all, link_watch_send_always);
+
+ if (success) {
+ /* Enable editing. */
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 0), 1);
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 1), 1);
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 2), 1);
+ }
+
+ json_decref (json);
+ return success;
+}
+
+static void
+maybe_set_str (json_t *json, const char *key, const char *str)
+{
+ if (str && *str)
+ json_object_set_new(json, key, json_string (str));
+}
+
+static void
+maybe_set_int (json_t *json, const char *key, int num)
+{
+ if (num != -1)
+ json_object_set_new(json, key, json_integer (num));
+}
+
+static void
+maybe_set_json (json_t *json, const char *key, json_t *val)
+{
+ if ( (json_is_object (val) && json_object_size (val))
+ || (json_is_array (val) && json_array_size (val))) {
+ json_object_set_new (json, key, val);
+ } else {
+ json_decref (val);
+ }
+}
+
+static void
+maybe_set_true (json_t *json, const char *key, int set)
+{
+ if (set)
+ json_object_set_new(json, key, json_true ());
+ else
+ json_object_set_new(json, key, json_false ());
+}
+
+static void
+dialog_to_json (CEPageTeam *self)
+{
+ CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
+ json_t *json;
+ json_t *obj;
+ gchar *tmp;
+ char *json_config;
+ GtkTextBuffer *buffer;
+
+ /* If the JSON is being edited, don't overwrite it. */
+ if (!gtk_widget_get_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 0)))
+ return;
+
+ /* Disable editing via form, until converted back from JSON. */
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 0), 0);
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 1), 0);
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 2), 0);
+
+ json = json_object ();
+ maybe_set_str (json, "hwaddr", gtk_entry_get_text (priv->hwaddr));
+
+ obj = json_object ();
+ maybe_set_int (obj, "count", gtk_spin_button_get_value_as_int (priv->notify_peers_count));
+ maybe_set_int (obj, "interval", gtk_spin_button_get_value_as_int (priv->notify_peers_interval));
+ maybe_set_json (json, "notify_peers", obj);
+
+ obj = json_object ();
+ maybe_set_int (obj, "count", gtk_spin_button_get_value_as_int (priv->mcast_rejoin_count));
+ maybe_set_int (obj, "interval", gtk_spin_button_get_value_as_int (priv->mcast_rejoin_interval));
+ maybe_set_json (json, "mcast_rejoin", obj);
+
+ obj = json_object ();
+ tmp = get_combo_box (priv->runner_name);
+ maybe_set_str (obj, "name", tmp);
+ if (g_strcmp0 (tmp, "roundrobin") == 0) {
+ } else if (g_strcmp0 (tmp, "activebackup") == 0) {
+ maybe_set_str (obj, "hwaddr_policy", get_combo_box (priv->hwaddr_policy));
+ } else if (g_strcmp0 (tmp, "loadbalance") == 0 || g_strcmp0 (tmp, "lacp") == 0) {
+ json_t *obj2;
+ gchar *str;
+
+ obj2 = json_object ();
+
+ /* Glade won't let us have a "" in the model :( */
+ str = get_combo_box (priv->tx_balancer);
+ if (strcmp (str, "none"))
+ maybe_set_str (obj2, "name", str);
+ g_free (str);
+
+ maybe_set_int (obj2, "balancing_interval", gtk_spin_button_get_value_as_int (priv->tx_balancing_interval));
+ maybe_set_json (obj, "tx_balancer", obj2);
+ maybe_set_json (obj, "tx_hash", selected_in_tree (priv->tx_hash));
+
+ if (g_strcmp0 (tmp, "lacp") == 0) {
+ maybe_set_true (obj, "active", gtk_toggle_button_get_active (priv->active));
+ maybe_set_true (obj, "fast_rate", gtk_toggle_button_get_active (priv->fast_rate));
+ maybe_set_int (obj, "sys_prio", gtk_spin_button_get_value (priv->system_priority));
+ maybe_set_int (obj, "min_ports", gtk_spin_button_get_value (priv->minimum_ports));
+ str = get_combo_box (priv->agg_selection_policy);
+ maybe_set_str (obj, "agg_select_policy", str);
+ g_free (str);
+ }
+ }
+ maybe_set_json (json, "runner", obj);
+ g_free (tmp);
+
+ obj = json_object ();
+ tmp = get_combo_box (priv->link_watcher_name);
+ maybe_set_str (obj, "name", tmp);
+ if (g_strcmp0 (tmp, "ethtool") == 0) {
+ maybe_set_int (obj, "delay_up", gtk_spin_button_get_value (priv->delay_up));
+ maybe_set_int (obj, "delay_down", gtk_spin_button_get_value (priv->delay_down));
+ } else if (g_strcmp0 (tmp, "arp_ping") == 0) {
+ maybe_set_int (obj, "interval", gtk_spin_button_get_value (priv->send_interval));
+ maybe_set_int (obj, "init_wait", gtk_spin_button_get_value (priv->init_wait));
+ maybe_set_int (obj, "missed_max", gtk_spin_button_get_value (priv->missed_max));
+ maybe_set_str (obj, "source_host", gtk_entry_get_text (priv->source_host));
+ maybe_set_str (obj, "target_host", gtk_entry_get_text (priv->target_host));
+ maybe_set_true (obj, "validate_active", gtk_toggle_button_get_active (priv->validate_active));
+ maybe_set_true (obj, "validate_inactive", gtk_toggle_button_get_active (priv->validate_inactive));
+ maybe_set_true (obj, "send_always", gtk_toggle_button_get_active (priv->send_all));
+ } else if (g_strcmp0 (tmp, "nsna_ping") == 0) {
+ maybe_set_int (obj, "interval", gtk_spin_button_get_value (priv->send_interval));
+ maybe_set_int (obj, "init_wait", gtk_spin_button_get_value (priv->init_wait));
+ maybe_set_int (obj, "missed_max", gtk_spin_button_get_value (priv->missed_max));
+ maybe_set_str (obj, "target_host", gtk_entry_get_text (priv->target_host));
+ } else {
+ g_return_if_reached ();
+ }
+ maybe_set_json (json, "link_watch", obj);
+ g_free (tmp);
+
+ json_config = json_dumps (json, JSON_INDENT (4));
+ json_decref (json);
+
+ buffer = gtk_text_view_get_buffer (priv->json_config_widget);
+ gtk_text_buffer_set_text (buffer, json_config, -1);
+ free (json_config);
+}
+
+#else /* WITH_JANSSON */
+
+static gboolean
+json_to_dialog (CEPageTeam *self)
+{
+ return FALSE;
+}
+
+static void
+dialog_to_json (CEPageTeam *self)
+{
+}
+
+#endif /* WITH_JANSSON */
+
+static void
+advanced_button_clicked_cb (GtkWidget *button, gpointer user_data)
{
+ CEPageTeam *self = CE_PAGE_TEAM (user_data);
CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
NMSettingTeam *s_team = priv->setting;
+ GtkWidget *toplevel;
GtkTextBuffer *buffer;
- const char *json_config;
- guint32 mtu_def, mtu_val;
+ GtkTextIter start, end;
+ char *json_config = NULL;
+
+ toplevel = gtk_widget_get_toplevel (CE_PAGE (self)->page);
+ g_return_if_fail (toplevel);
+ gtk_window_set_transient_for (GTK_WINDOW (priv->advanced_dialog), GTK_WINDOW (toplevel));
+ g_return_if_fail (gtk_widget_is_toplevel (toplevel));
+ /* Load in the JSON from settings to dialog. */
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);
+ gtk_text_buffer_set_text (buffer, nm_setting_team_get_config (s_team) ?: "", -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);
+ /* Fill in the form fields. */
+ if (json_to_dialog (self)) {
+ gtk_notebook_set_current_page (priv->advanced_notebook, 0);
+ } else {
+ /* First disable the pages, so that potentially
+ * inconsistent changes are not propageated to JSON. */
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 0), 0);
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 1), 0);
+ gtk_widget_set_sensitive (gtk_notebook_get_nth_page (priv->advanced_notebook, 2), 0);
+ gtk_notebook_set_current_page (priv->advanced_notebook, 3);
+ }
+
+ runner_changed (priv->runner_name, self);
+ link_watcher_changed (priv->link_watcher_name, self);
+
+ if (gtk_dialog_run (priv->advanced_dialog) == GTK_RESPONSE_OK) {
+ dialog_to_json (self);
+
+ /* Set the JSON from the dialog to setting. */
+ 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);
+
+ g_object_set (priv->setting,
+ NM_SETTING_TEAM_CONFIG,
+ g_strcmp0 (json_config, "") == 0 ? NULL : json_config,
+ NULL);
+ g_free (json_config);
+ ce_page_changed (CE_PAGE (self));
+ }
+ gtk_widget_hide (GTK_WIDGET (priv->advanced_dialog));
+}
+
+static gboolean
+switch_page (GtkNotebook *notebook,
+ GtkWidget *page,
+ guint page_num,
+ gpointer user_data)
+{
+ CEPageTeam *self = CE_PAGE_TEAM (user_data);
+
+ /* Keep the JSON and the form in sync if possible. */
+ if (gtk_notebook_get_current_page (notebook) == 3)
+ json_to_dialog (self);
+ else if (page_num == 3)
+ dialog_to_json (self);
+
+ return TRUE;
+}
+
+static void
+populate_ui (CEPageTeam *self)
+{
+ CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
+ guint32 mtu_def, mtu_val;
/* MTU */
if (priv->wired) {
@@ -154,6 +905,12 @@ populate_ui (CEPageTeam *self)
}
ce_spin_automatic_val (priv->mtu, mtu_def);
gtk_spin_button_set_value (priv->mtu, (gdouble) mtu_val);
+
+ g_signal_connect (priv->import_config_button, "clicked", G_CALLBACK (import_button_clicked_cb), self);
+ g_signal_connect (priv->runner_name, "changed", G_CALLBACK (runner_changed), self);
+ g_signal_connect (priv->link_watcher_name, "changed", G_CALLBACK (link_watcher_changed), self);
+ g_signal_connect (priv->advanced_button, "clicked", G_CALLBACK (advanced_button_clicked_cb), self);
+ g_signal_connect (priv->advanced_notebook, "switch-page", G_CALLBACK (switch_page), self);
}
static void
@@ -214,9 +971,14 @@ add_slave (CEPageMaster *master, NewConnectionResultFunc result_func)
{
CEPageTeam *self = CE_PAGE_TEAM (master);
CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (CE_PAGE (self)->page);
+ g_return_if_fail (toplevel);
+ g_return_if_fail (gtk_widget_is_toplevel (toplevel));
if (priv->slave_arptype == ARPHRD_INFINIBAND) {
- new_connection_of_type (priv->toplevel,
+ new_connection_of_type (GTK_WINDOW (toplevel),
NULL,
NULL,
CE_PAGE (self)->client,
@@ -224,7 +986,7 @@ add_slave (CEPageMaster *master, NewConnectionResultFunc result_func)
result_func,
master);
} else {
- new_connection_dialog (priv->toplevel,
+ new_connection_dialog (GTK_WINDOW (toplevel),
CE_PAGE (self)->client,
connection_type_filter,
result_func,
@@ -290,23 +1052,8 @@ ui_to_setting (CEPageTeam *self)
{
CEPageTeamPrivate *priv = CE_PAGE_TEAM_GET_PRIVATE (self);
NMConnection *connection = CE_PAGE (self)->connection;
- GtkTextBuffer *buffer;
- GtkTextIter start, end;
- char *json_config;
guint32 mtu;
- 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);
-
mtu = gtk_spin_button_get_value_as_int (priv->mtu);
if (mtu && !priv->wired) {
priv->wired = NM_SETTING_WIRED (nm_setting_wired_new ());