Commit cc2c8276 authored by Jiří Klimeš's avatar Jiří Klimeš

editor: allow changes on one page modify other pages

Changes in properties on a page may require changes on other pages. Let's add
an infrastructure for that.
When a change should influence other page(s), the information is set using
nm_connection_editor_inter_page_set_value(). And then that can be retrieved by
nm_connection_editor_inter_page_get_value() in another page in method
inter_page_change().
parent 4cf81f62
......@@ -151,6 +151,24 @@ ce_page_last_update (CEPage *self, NMConnection *connection, GError **error)
return TRUE;
}
gboolean
ce_page_inter_page_change (CEPage *self)
{
gboolean ret = FALSE;
g_return_val_if_fail (CE_IS_PAGE (self), FALSE);
if (self->inter_page_change_running)
return FALSE;
self->inter_page_change_running = TRUE;
if (CE_PAGE_GET_CLASS (self)->inter_page_change)
ret = CE_PAGE_GET_CLASS (self)->inter_page_change (self);
self->inter_page_change_running = FALSE;
return ret;
}
static void
_set_active_combo_item (GtkComboBox *combo, const char *item,
const char *combo_item, int combo_idx)
......@@ -766,6 +784,7 @@ ce_page_new_connection (const char *format,
CEPage *
ce_page_new (GType page_type,
NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
......@@ -786,6 +805,7 @@ ce_page_new (GType page_type,
NULL));
self->title = g_strdup (title);
self->client = client;
self->editor = editor;
if (ui_file) {
if (!gtk_builder_add_from_file (self->builder, ui_file, &error)) {
......
......@@ -30,6 +30,7 @@
#include <NetworkManager.h>
#include "nm-connection-editor.h"
#include "utils.h"
/* for ARPHRD_ETHER / ARPHRD_INFINIBAND for MAC utilies */
......@@ -63,12 +64,14 @@ typedef struct {
GObject parent;
gboolean initialized;
gboolean inter_page_change_running;
GtkBuilder *builder;
GtkWidget *page;
char *title;
gulong secrets_done_validate;
NMConnectionEditor *editor;
NMConnection *connection;
GtkWindow *parent_window;
NMClient *client;
......@@ -80,6 +83,7 @@ typedef struct {
/* Virtual functions */
gboolean (*ce_page_validate_v) (CEPage *self, NMConnection *connection, GError **error);
gboolean (*last_update) (CEPage *self, NMConnection *connection, GError **error);
gboolean (*inter_page_change) (CEPage *self);
/* Signals */
void (*changed) (CEPage *self);
......@@ -87,7 +91,8 @@ typedef struct {
} CEPageClass;
typedef CEPage* (*CEPageNewFunc)(NMConnection *connection,
typedef CEPage* (*CEPageNewFunc)(NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -102,6 +107,7 @@ const char * ce_page_get_title (CEPage *self);
gboolean ce_page_validate (CEPage *self, NMConnection *connection, GError **error);
gboolean ce_page_last_update (CEPage *self, NMConnection *connection, GError **error);
gboolean ce_page_inter_page_change (CEPage *self);
void ce_page_setup_mac_combo (CEPage *self, GtkComboBox *combo,
const char *mac, char **mac_list);
......@@ -146,6 +152,7 @@ NMConnection *ce_page_new_connection (const char *format,
gpointer user_data);
CEPage *ce_page_new (GType page_type,
NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
......@@ -153,5 +160,6 @@ CEPage *ce_page_new (GType page_type,
const char *widget_name,
const char *title);
#endif /* __CE_PAGE_H__ */
......@@ -257,6 +257,12 @@ permissions_changed_cb (NMClient *client,
connection_editor_validate (editor);
}
static void
destroy_inter_page_item (gpointer data)
{
return;
}
static void
nm_connection_editor_init (NMConnectionEditor *editor)
{
......@@ -290,6 +296,8 @@ nm_connection_editor_init (NMConnectionEditor *editor)
editor->cancel_button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "cancel_button"));
editor->export_button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "export_button"));
editor->inter_page_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) destroy_inter_page_item);
}
static void
......@@ -361,6 +369,8 @@ dispose (GObject *object)
g_clear_pointer (&editor->last_validation_error, g_free);
g_hash_table_destroy (editor->inter_page_hash);
out:
G_OBJECT_CLASS (nm_connection_editor_parent_class)->dispose (object);
}
......@@ -507,6 +517,14 @@ static void
page_changed (CEPage *page, gpointer user_data)
{
NMConnectionEditor *editor = NM_CONNECTION_EDITOR (user_data);
GSList *iter;
/* Do page interdependent changes */
for (iter = editor->pages; iter; iter = g_slist_next (iter))
ce_page_inter_page_change (CE_PAGE (iter->data));
if (editor_is_initialized (editor))
nm_connection_editor_inter_page_clear_data (editor);
connection_editor_validate (editor);
}
......@@ -695,7 +713,7 @@ add_page (NMConnectionEditor *editor,
g_return_val_if_fail (func != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
page = (*func) (connection, GTK_WINDOW (editor->window), editor->client,
page = (*func) (editor, connection, GTK_WINDOW (editor->window), editor->client,
&secrets_setting_name, error);
if (page) {
g_object_set_data_full (G_OBJECT (page),
......@@ -1119,3 +1137,21 @@ nm_connection_editor_warning (GtkWindow *parent, const char *heading, const char
va_end (args);
}
void
nm_connection_editor_inter_page_set_value (NMConnectionEditor *editor, InterPageChangeType type, gpointer value)
{
g_hash_table_insert (editor->inter_page_hash, GUINT_TO_POINTER (type), value);
}
gboolean
nm_connection_editor_inter_page_get_value (NMConnectionEditor *editor, InterPageChangeType type, gpointer *value)
{
return g_hash_table_lookup_extended (editor->inter_page_hash, GUINT_TO_POINTER (type), NULL, value);
}
void
nm_connection_editor_inter_page_clear_data (NMConnectionEditor *editor)
{
g_hash_table_remove_all (editor->inter_page_hash);
}
......@@ -66,6 +66,8 @@ typedef struct {
guint validate_id;
char *last_validation_error;
GHashTable *inter_page_hash;
} NMConnectionEditor;
typedef struct {
......@@ -75,6 +77,11 @@ typedef struct {
void (*done) (NMConnectionEditor *editor, gint result, GError *error);
} NMConnectionEditorClass;
typedef enum {
/* Add item for inter-page changes here */
DUMMY,
} InterPageChangeType;
GType nm_connection_editor_get_type (void);
NMConnectionEditor *nm_connection_editor_new (GtkWindow *parent_window,
NMConnection *connection,
......@@ -98,4 +105,12 @@ void nm_connection_editor_warning (GtkWindow *parent,
const char *format,
...);
void nm_connection_editor_inter_page_set_value (NMConnectionEditor *editor,
InterPageChangeType type,
gpointer value);
gboolean nm_connection_editor_inter_page_get_value (NMConnectionEditor *editor,
InterPageChangeType type,
gpointer *value);
void nm_connection_editor_inter_page_clear_data (NMConnectionEditor *editor);
#endif
......@@ -91,7 +91,8 @@ finish_setup (CEPage8021xSecurity *self, gpointer unused, GError *error, gpointe
}
CEPage *
ce_page_8021x_security_new (NMConnection *connection,
ce_page_8021x_security_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -102,6 +103,7 @@ ce_page_8021x_security_new (NMConnection *connection,
CEPage *parent;
self = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_8021x_security_get_type (void);
CEPage *ce_page_8021x_security_new (NMConnection *connection,
CEPage *ce_page_8021x_security_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -90,7 +90,8 @@ finish_setup (CEPageBluetooth *self, gpointer unused, GError *error, gpointer us
}
CEPage *
ce_page_bluetooth_new (NMConnection *connection,
ce_page_bluetooth_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -100,6 +101,7 @@ ce_page_bluetooth_new (NMConnection *connection,
CEPageBluetoothPrivate *priv;
self = CE_PAGE_BLUETOOTH (ce_page_new (CE_TYPE_PAGE_BLUETOOTH,
editor,
connection,
parent_window,
client,
......
......@@ -47,7 +47,8 @@ typedef struct {
GType ce_page_bluetooth_get_type (void);
CEPage *ce_page_bluetooth_new (NMConnection *connection,
CEPage *ce_page_bluetooth_new (NMConnectionEditor *edit,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -426,16 +426,18 @@ finish_setup (CEPageBond *self, gpointer unused, GError *error, gpointer user_da
}
CEPage *
ce_page_bond_new (NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
GError **error)
ce_page_bond_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
GError **error)
{
CEPageBond *self;
CEPageBondPrivate *priv;
self = CE_PAGE_BOND (ce_page_new (CE_TYPE_PAGE_BOND,
editor,
connection,
parent_window,
client,
......
......@@ -43,7 +43,8 @@ typedef struct {
GType ce_page_bond_get_type (void);
CEPage *ce_page_bond_new (NMConnection *connection,
CEPage *ce_page_bond_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -88,7 +88,8 @@ finish_setup (CEPageBridgePort *self, gpointer unused, GError *error, gpointer u
}
CEPage *
ce_page_bridge_port_new (NMConnection *connection,
ce_page_bridge_port_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -98,6 +99,7 @@ ce_page_bridge_port_new (NMConnection *connection,
CEPageBridgePortPrivate *priv;
self = CE_PAGE_BRIDGE_PORT (ce_page_new (CE_TYPE_PAGE_BRIDGE_PORT,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_bridge_port_get_type (void);
CEPage *ce_page_bridge_port_new (NMConnection *connection,
CEPage *ce_page_bridge_port_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -192,7 +192,8 @@ finish_setup (CEPageBridge *self, gpointer unused, GError *error, gpointer user_
}
CEPage *
ce_page_bridge_new (NMConnection *connection,
ce_page_bridge_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -202,6 +203,7 @@ ce_page_bridge_new (NMConnection *connection,
CEPageBridgePrivate *priv;
self = CE_PAGE_BRIDGE (ce_page_new (CE_TYPE_PAGE_BRIDGE,
editor,
connection,
parent_window,
client,
......
......@@ -43,7 +43,8 @@ typedef struct {
GType ce_page_bridge_get_type (void);
CEPage *ce_page_bridge_new (NMConnection *connection,
CEPage *ce_page_bridge_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -584,7 +584,8 @@ finish_setup (CEPageDcb *self, gpointer unused, GError *error, gpointer user_dat
}
CEPage *
ce_page_dcb_new (NMConnection *connection,
ce_page_dcb_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -596,6 +597,7 @@ ce_page_dcb_new (NMConnection *connection,
NMSettingDcb *s_dcb;
self = CE_PAGE_DCB (ce_page_new (CE_TYPE_PAGE_DCB,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_dcb_get_type (void);
CEPage *ce_page_dcb_new (NMConnection *connection,
CEPage *ce_page_dcb_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -110,7 +110,8 @@ finish_setup (CEPageDsl *self, gpointer unused, GError *error, gpointer user_dat
}
CEPage *
ce_page_dsl_new (NMConnection *connection,
ce_page_dsl_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -120,6 +121,7 @@ ce_page_dsl_new (NMConnection *connection,
CEPageDslPrivate *priv;
self = CE_PAGE_DSL (ce_page_new (CE_TYPE_PAGE_DSL,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_dsl_get_type (void);
CEPage *ce_page_dsl_new (NMConnection *connection,
CEPage *ce_page_dsl_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -298,7 +298,8 @@ finish_setup (CEPageEthernet *self, gpointer unused, GError *error, gpointer use
}
CEPage *
ce_page_ethernet_new (NMConnection *connection,
ce_page_ethernet_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -308,6 +309,7 @@ ce_page_ethernet_new (NMConnection *connection,
CEPageEthernetPrivate *priv;
self = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_ethernet_get_type (void);
CEPage *ce_page_ethernet_new (NMConnection *connection,
CEPage *ce_page_ethernet_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -331,7 +331,8 @@ finish_setup (CEPageGeneral *self, gpointer unused, GError *error, gpointer user
}
CEPage *
ce_page_general_new (NMConnection *connection,
ce_page_general_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -341,6 +342,7 @@ ce_page_general_new (NMConnection *connection,
CEPageGeneralPrivate *priv;
self = CE_PAGE_GENERAL (ce_page_new (CE_TYPE_PAGE_GENERAL,
editor,
connection,
parent_window,
client,
......
......@@ -43,7 +43,8 @@ typedef struct {
GType ce_page_general_get_type (void);
CEPage *ce_page_general_new (NMConnection *connection,
CEPage *ce_page_general_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -133,7 +133,8 @@ finish_setup (CEPageInfiniband *self, gpointer unused, GError *error, gpointer u
}
CEPage *
ce_page_infiniband_new (NMConnection *connection,
ce_page_infiniband_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -143,6 +144,7 @@ ce_page_infiniband_new (NMConnection *connection,
CEPageInfinibandPrivate *priv;
self = CE_PAGE_INFINIBAND (ce_page_new (CE_TYPE_PAGE_INFINIBAND,
editor,
connection,
parent_window,
client,
......
......@@ -43,7 +43,8 @@ typedef struct {
GType ce_page_infiniband_get_type (void);
CEPage *ce_page_infiniband_new (NMConnection *connection,
CEPage *ce_page_infiniband_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -1128,7 +1128,8 @@ finish_setup (CEPageIP4 *self, gpointer unused, GError *error, gpointer user_dat
}
CEPage *
ce_page_ip4_new (NMConnection *connection,
ce_page_ip4_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -1139,6 +1140,7 @@ ce_page_ip4_new (NMConnection *connection,
NMSettingConnection *s_con;
self = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_ip4_get_type (void);
CEPage *ce_page_ip4_new (NMConnection *connection,
CEPage *ce_page_ip4_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -1136,7 +1136,8 @@ finish_setup (CEPageIP6 *self, gpointer unused, GError *error, gpointer user_dat
}
CEPage *
ce_page_ip6_new (NMConnection *connection,
ce_page_ip6_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -1147,6 +1148,7 @@ ce_page_ip6_new (NMConnection *connection,
NMSettingConnection *s_con;
self = CE_PAGE_IP6 (ce_page_new (CE_TYPE_PAGE_IP6,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_ip6_get_type (void);
CEPage *ce_page_ip6_new (NMConnection *connection,
CEPage *ce_page_ip6_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -291,7 +291,8 @@ finish_setup (CEPageMobile *self, gpointer unused, GError *error, gpointer user_
}
CEPage *
ce_page_mobile_new (NMConnection *connection,
ce_page_mobile_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -301,6 +302,7 @@ ce_page_mobile_new (NMConnection *connection,
CEPageMobilePrivate *priv;
self = CE_PAGE_MOBILE (ce_page_new (CE_TYPE_PAGE_MOBILE,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_mobile_get_type (void);
CEPage *ce_page_mobile_new (NMConnection *connection,
CEPage *ce_page_mobile_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......
......@@ -262,7 +262,8 @@ finish_setup (CEPagePpp *self, gpointer unused, GError *error, gpointer user_dat
}
CEPage *
ce_page_ppp_new (NMConnection *connection,
ce_page_ppp_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent_window,
NMClient *client,
const char **out_secrets_setting_name,
......@@ -273,6 +274,7 @@ ce_page_ppp_new (NMConnection *connection,
NMSettingConnection *s_con;
self = CE_PAGE_PPP (ce_page_new (CE_TYPE_PAGE_PPP,
editor,
connection,
parent_window,
client,
......
......@@ -45,7 +45,8 @@ typedef struct {
GType ce_page_ppp_get_type (void);
CEPage *ce_page_ppp_new (NMConnection *connection,
CEPage *ce_page_ppp_new (NMConnectionEditor *editor,
NMConnection *connection,
GtkWindow *parent,
NMClient *client,
const char **out_secrets_setting_name,
......