static gboolean
validate (CEPage        *page,
          NMConnection  *connection,
          GError       **error)
{
        if (!ui_to_setting (CE_PAGE_IP4 (page)))
                return FALSE;

        return nm_setting_verify (NM_SETTING (CE_PAGE_IP4 (page)->setting), NULL, error);
}
static void
change_method_combo (CEPage *page, gboolean is_hotspot)
{
	CEPageIP4 *self = CE_PAGE_IP4 (page);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);

	/* Store previous active method */
	if (get_method_sensitivity (page, IP4_METHOD_AUTO))
		priv->normal_method_idx = gtk_combo_box_get_active (priv->method);
	else
		priv->hotspot_method_idx = gtk_combo_box_get_active (priv->method);

	/* Set active method */
	if (is_hotspot) {
		if (priv->hotspot_method_idx == -1) {
			int method = IP4_METHOD_SHARED;
			if (g_strcmp0 (nm_setting_ip_config_get_method (priv->setting),
			               NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0)
				method = IP4_METHOD_DISABLED;
			gtk_combo_box_set_active (priv->method, method);
		} else
			gtk_combo_box_set_active (priv->method, priv->hotspot_method_idx);
	} else {
		if (priv->normal_method_idx != -1)
			gtk_combo_box_set_active (priv->method, priv->normal_method_idx);
	}

	toggle_method_sensitivity (page, IP4_METHOD_AUTO, !is_hotspot);
	toggle_method_sensitivity (page, IP4_METHOD_AUTO_ADDRESSES, !is_hotspot);
	toggle_method_sensitivity (page, IP4_METHOD_MANUAL, !is_hotspot);
	toggle_method_sensitivity (page, IP4_METHOD_LINK_LOCAL, !is_hotspot);
}
static gboolean
tree_view_button_pressed_cb (GtkWidget *widget,
                             GdkEvent *event,
                             gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);

	/* last_edited can be set e.g. when we get here by clicking an cell while
	 * editing another cell. GTK3 issue neither editing-canceled nor editing-done
	 * for cell renderer. Thus the previous cell value isn't saved. Store it now. */
	if (priv->last_edited && priv->last_path) {
		GtkTreeIter iter;
		GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
		GtkTreePath *last_treepath = gtk_tree_path_new_from_string (priv->last_path);

		gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, last_treepath);
		gtk_list_store_set (store, &iter, priv->last_column, priv->last_edited, -1);
		gtk_tree_path_free (last_treepath);

		g_free (priv->last_edited);
		priv->last_edited = NULL;
		g_free (priv->last_path);
		priv->last_path = NULL;
		priv->last_column = -1;
	}

	/* Ignore double clicks events. (They are issued after the single clicks, see GdkEventButton) */
	if (event->type == GDK_2BUTTON_PRESS)
		return TRUE;

	gtk_widget_grab_focus (GTK_WIDGET (priv->addr_list));
	return FALSE;
}
static void
cell_editing_canceled (GtkCellRenderer *renderer, gpointer user_data)
{
	CEPageIP4 *self;
	CEPageIP4Private *priv;
	GtkTreeModel *model = NULL;
	GtkTreeSelection *selection;
	GtkTreeIter iter;
	guint32 column;

	/* user_data disposed? */
	if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (renderer), "ce-page-not-valid")))
		return;

	self = CE_PAGE_IP4 (user_data);
	priv = CE_PAGE_IP4_GET_PRIVATE (self);

	if (priv->last_edited) {
		selection = gtk_tree_view_get_selection (priv->addr_list);
		if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
			column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (renderer), "column"));
			gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, priv->last_edited, -1);
		}

		g_free (priv->last_edited);
		priv->last_edited = NULL;

		ce_page_changed (CE_PAGE (self));
	}

	g_free (priv->last_path);
	priv->last_path = NULL;
	priv->last_column = -1;
}
Example #5
0
static void
cell_edited (GtkCellRendererText *cell,
             const gchar *path_string,
             const gchar *new_text,
             gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
	GtkTreeIter iter;
	guint32 column;
	GtkTreeViewColumn *next_col;

	column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
	gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
	gtk_list_store_set (store, &iter, column, new_text, -1);

	/* Move focus to the next column */
	column = (column >= COL_LAST) ? 0 : column + 1;
	next_col = gtk_tree_view_get_column (priv->addr_list, column);
	gtk_tree_view_set_cursor_on_cell (priv->addr_list, path, next_col, priv->addr_cells[column], TRUE);
	gtk_widget_grab_focus (GTK_WIDGET (priv->addr_list));

	gtk_tree_path_free (path);
	ce_page_changed (CE_PAGE (self));
}
static gboolean
ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
{
	CEPageIP4 *self = CE_PAGE_IP4 (page);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);

	if (!ui_to_setting (self, error))
		return FALSE;
	return nm_setting_verify (NM_SETTING (priv->setting), NULL, error);
}
static void
routes_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);

	if (response == GTK_RESPONSE_OK)
		ip4_routes_dialog_update_setting (dialog, priv->setting);

	routes_dialog_close_cb (dialog, NULL);
}
static void
toggle_method_sensitivity (CEPage *page, int column, gboolean sensitive)
{
	CEPageIP4 *self = CE_PAGE_IP4 (page);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkTreeModel *model = GTK_TREE_MODEL (priv->method_store);
	GtkTreeIter iter;

	if (get_iter_for_method (model, column, &iter))
		gtk_list_store_set (priv->method_store, &iter, METHOD_COL_ENABLED, sensitive, -1);
}
Example #9
0
CEPage *
ce_page_ip4_new (NMConnection *connection, GtkWindow *parent_window, GError **error)
{
	CEPageIP4 *self;
	CEPageIP4Private *priv;
	CEPage *parent;
	NMSettingConnection *s_con;

	self = CE_PAGE_IP4 (g_object_new (CE_TYPE_PAGE_IP4,
	                                  CE_PAGE_CONNECTION, connection,
	                                  CE_PAGE_PARENT_WINDOW, parent_window,
	                                  NULL));
	parent = CE_PAGE (self);

	parent->xml = glade_xml_new (GLADEDIR "/ce-page-ip4.glade", "IP4Page", NULL);
	if (!parent->xml) {
		g_set_error (error, 0, 0, "%s", _("Could not load IPv4 user interface."));
		g_object_unref (self);
		return NULL;
	}

	parent->page = glade_xml_get_widget (parent->xml, "IP4Page");
	if (!parent->page) {
		g_set_error (error, 0, 0, "%s", _("Could not load IPv4 user interface."));
		g_object_unref (self);
		return NULL;
	}
	g_object_ref_sink (parent->page);

	parent->title = g_strdup (_("IPv4 Settings"));

	ip4_private_init (self, connection);
	priv = CE_PAGE_IP4_GET_PRIVATE (self);

	priv->window_group = gtk_window_group_new ();

	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
	g_assert (s_con);
	priv->connection_id = g_strdup (nm_setting_connection_get_id (s_con));

	priv->setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
	if (!priv->setting) {
		priv->setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
		nm_connection_add_setting (connection, NM_SETTING (priv->setting));
	}

	g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);
	if (!ce_page_initialize (parent, NULL, error)) {
		g_object_unref (self);
		return NULL;
	}

	return CE_PAGE (self);
}
static void
delete_text_cb (GtkEditable *editable,
                    gint start_pos,
                    gint end_pos,
                    gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);

	/* Keep last_edited up-to-date */
	g_free (priv->last_edited);
	priv->last_edited = gtk_editable_get_chars (editable, 0, -1);
}
static gboolean
get_method_sensitivity (CEPage *page, int column)
{
	CEPageIP4 *self = CE_PAGE_IP4 (page);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkTreeModel *model = GTK_TREE_MODEL (priv->method_store);
	GtkTreeIter iter;
	gboolean sensitive = FALSE;

	if (get_iter_for_method (model, column, &iter))
		gtk_tree_model_get (GTK_TREE_MODEL (priv->method_store), &iter, METHOD_COL_ENABLED, &sensitive, -1);
	return sensitive;
}
Example #12
0
static void
dispose (GObject *object)
{
	CEPageIP4 *self = CE_PAGE_IP4 (object);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);

	if (priv->window_group)
		g_object_unref (priv->window_group);

	g_free (priv->connection_id);

	G_OBJECT_CLASS (ce_page_ip4_parent_class)->dispose (object);
}
static void
cell_editing_started (GtkCellRenderer *cell,
                      GtkCellEditable *editable,
                      const gchar     *path,
                      gpointer         user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkTreeModel *model;
	GtkTreeIter iter;
	AddressLineInfo *info;

	if (!GTK_IS_ENTRY (editable)) {
		g_warning ("%s: Unexpected cell editable type.", __func__);
		return;
	}

	/* Initialize last_path and last_column, last_edited is initialized when the cell is edited */
	g_free (priv->last_edited);
	priv->last_edited = NULL;
	g_free (priv->last_path);
	priv->last_path = g_strdup (path);
	priv->last_column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));

	/* Set up the entry filter */
	g_signal_connect (G_OBJECT (editable), "insert-text",
	                  (GCallback) ip_address_filter_cb,
	                  user_data);

	g_signal_connect_after (G_OBJECT (editable), "delete-text",
	                        (GCallback) delete_text_cb,
	                        user_data);

	/* Set up handler for IP verifying and changing cell background */
	model = gtk_tree_view_get_model (priv->addr_list);
	gtk_tree_model_get_iter_from_string (model, &iter, priv->last_path);
	info = g_slice_new0 (AddressLineInfo);
	info->model = model;
	info->iter = iter;
	info->column = priv->last_column;
	g_signal_connect_data (G_OBJECT (editable), "changed",
	                       (GCallback) cell_changed_cb,
	                       info,
	                       (GClosureNotify) address_line_info_destroy, 0);

	/* Set up key pressed handler - need to handle Tab key */
	g_signal_connect (G_OBJECT (editable), "key-press-event",
	                  (GCallback) key_pressed_cb,
	                  cell);
}
static void
dispose (GObject *object)
{
	CEPageIP4 *self = CE_PAGE_IP4 (object);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	int i;

	g_clear_object (&priv->window_group);

	/* Mark CEPageIP4 object as invalid; store this indication to cells to be usable in callbacks */
	for (i = 0; i <= COL_LAST; i++)
		g_object_set_data (G_OBJECT (priv->addr_cells[i]), "ce-page-not-valid", GUINT_TO_POINTER (1));

	g_clear_pointer (&priv->connection_id, g_free);

	G_OBJECT_CLASS (ce_page_ip4_parent_class)->dispose (object);
}
CEPage *
ce_page_ip4_new (NMConnectionEditor *editor,
                 NMConnection *connection,
                 GtkWindow *parent_window,
                 NMClient *client,
                 const char **out_secrets_setting_name,
                 GError **error)
{
	CEPageIP4 *self;
	CEPageIP4Private *priv;
	NMSettingConnection *s_con;

	self = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4,
	                                 editor,
	                                 connection,
	                                 parent_window,
	                                 client,
	                                 UIDIR "/ce-page-ip4.ui",
	                                 "IP4Page",
	                                 _("IPv4 Settings")));
	if (!self) {
		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load IPv4 user interface."));
		return NULL;
	}

	ip4_private_init (self, connection);
	priv = CE_PAGE_IP4_GET_PRIVATE (self);

	priv->window_group = gtk_window_group_new ();

	s_con = nm_connection_get_setting_connection (connection);
	g_assert (s_con);
	priv->connection_id = g_strdup (nm_setting_connection_get_id (s_con));

	priv->setting = nm_connection_get_setting_ip4_config (connection);
	g_assert (priv->setting);

	g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);

	return CE_PAGE (self);
}
static void
ip_address_filter_cb (GtkEditable *editable,
                      gchar *text,
                      gint length,
                      gint *position,
                      gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	gboolean changed;

	changed = utils_filter_editable_on_insert_text (editable,
	                                                text, length, position, user_data,
	                                                utils_char_is_ascii_ip4_address,
	                                                ip_address_filter_cb);

	if (changed) {
		g_free (priv->last_edited);
		priv->last_edited = gtk_editable_get_chars (editable, 0, -1);
	}
}
Example #17
0
static void
routes_button_clicked_cb (GtkWidget *button, gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkWidget *dialog, *toplevel;
	gboolean automatic = FALSE;
	const char *method;
	char *tmp;

	toplevel = gtk_widget_get_toplevel (CE_PAGE (self)->page);
	g_return_if_fail (GTK_WIDGET_TOPLEVEL (toplevel));

	method = nm_setting_ip4_config_get_method (priv->setting);
	if (!method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO))
		automatic = TRUE;

	dialog = ip4_routes_dialog_new (priv->setting, automatic);
	if (!dialog) {
		g_warning ("%s: failed to create the routes dialog!", __func__);
		return;
	}

	gtk_window_group_add_window (priv->window_group, GTK_WINDOW (dialog));
	if (!priv->window_added) {
		gtk_window_group_add_window (priv->window_group, GTK_WINDOW (toplevel));
		priv->window_added = TRUE;
	}

	gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel));
	tmp = g_strdup_printf (_("Editing IPv4 routes for %s"), priv->connection_id);
	gtk_window_set_title (GTK_WINDOW (dialog), tmp);
	g_free (tmp);

	g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (routes_dialog_response_cb), self);
	g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (routes_dialog_close_cb), self);

	gtk_widget_show_all (dialog);
}
static void
cell_edited (GtkCellRendererText *cell,
             const gchar *path_string,
             const gchar *new_text,
             gpointer user_data)
{
	CEPageIP4 *self = CE_PAGE_IP4 (user_data);
	CEPageIP4Private *priv = CE_PAGE_IP4_GET_PRIVATE (self);
	GtkListStore *store = GTK_LIST_STORE (gtk_tree_view_get_model (priv->addr_list));
	GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
	GtkTreeIter iter;
	guint32 column;
	GtkTreeViewColumn *next_col;
	GtkCellRenderer *next_cell;
	gboolean can_cycle;
	int direction, tmp;

	/* Free auxiliary stuff */
	g_free (priv->last_edited);
	priv->last_edited = NULL;
	g_free (priv->last_path);
	priv->last_path = NULL;
	priv->last_column = -1;

	column = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (cell), "column"));
	gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
	gtk_list_store_set (store, &iter, column, new_text, -1);

	/* Try to autodetect the prefix from the given address if we can */
	if (column == COL_ADDRESS && new_text && strlen (new_text)) {
		char *prefix = NULL;
		const char *guess_prefix = NULL;

		gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (store), &iter, path_string);
		gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, COL_PREFIX, &prefix, -1);
		if (!prefix || !strlen (prefix)) {
			if (!strncmp ("10.", new_text, 3))
				guess_prefix = "8";
			else if (!strncmp ("172.16.", new_text, 7))
				guess_prefix = "16";
			else if (!strncmp ("192.168.", new_text, 8))
				guess_prefix = "24";

			if (guess_prefix)
				gtk_list_store_set (store, &iter, COL_PREFIX, guess_prefix, -1);
		}
		g_free (prefix);
	}

	/* Move focus to the next/previous column */
	can_cycle = g_object_get_data (G_OBJECT (cell), DO_NOT_CYCLE_TAG) == NULL;
	direction = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), DIRECTION_TAG));
	g_object_set_data (G_OBJECT (cell), DIRECTION_TAG, NULL);
	g_object_set_data (G_OBJECT (cell), DO_NOT_CYCLE_TAG, NULL);
	if (direction == 0)  /* Move forward by default */
		direction = 1;

	tmp = column + direction;
	if (can_cycle)
		column = tmp < 0 ? COL_LAST : tmp > COL_LAST ? 0 : tmp;
	else
		column = tmp;
	next_col = gtk_tree_view_get_column (priv->addr_list, column);
	next_cell = column <= COL_LAST ? priv->addr_cells[column] : NULL;
	gtk_tree_view_set_cursor_on_cell (priv->addr_list, path, next_col, next_cell, TRUE);

	gtk_tree_path_free (path);
	ce_page_changed (CE_PAGE (self));
}