static void
remove_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
	gint idx = find_selected_layout_idx (dialog);

	if (idx != -1) {
		GSList *layouts_list = xkb_layouts_get_selected_list ();
		char *id = NULL;
		GSList *node2Remove = g_slist_nth (layouts_list, idx);

		layouts_list =
		    g_slist_remove_link (layouts_list, node2Remove);

		id = (char *) node2Remove->data;
		g_slist_free_1 (node2Remove);
		g_free (id);

		if (default_group > idx)
			xkb_save_default_group (default_group - 1);
		else if (default_group == idx)
			xkb_save_default_group (-1);

		xkb_layouts_set_selected_list (layouts_list);
		clear_xkb_elements_list (layouts_list);
	}
}
void
xkb_layouts_fill_selected_tree (GtkBuilder * dialog)
{
	GSList *layouts = xkb_layouts_get_selected_list ();
	GSList *cur_layout;
	GtkListStore *list_store =
	    GTK_LIST_STORE (gtk_tree_view_get_model
			    (GTK_TREE_VIEW
			     (WID ("xkb_layouts_selected"))));
	int counter = 0;

	/* temporarily disable the buttons' status update */
	disable_buttons_sensibility_update = TRUE;

	gtk_list_store_clear (list_store);

	for (cur_layout = layouts; cur_layout != NULL;
	     cur_layout = cur_layout->next, counter++) {
		GtkTreeIter iter;
		const char *visible = (char *) cur_layout->data;
		gchar *utf_visible = xkb_layout_description_utf8 (visible);
		gtk_list_store_append (list_store, &iter);
		gtk_list_store_set (list_store, &iter,
				    SEL_LAYOUT_TREE_COL_DESCRIPTION,
				    utf_visible,
				    SEL_LAYOUT_TREE_COL_ID,
				    cur_layout->data,
				    SEL_LAYOUT_TREE_COL_ENABLED,
				    counter < max_selected_layouts, -1);
		g_free (utf_visible);
	}

	clear_xkb_elements_list (layouts);

	/* enable the buttons' status update */
	disable_buttons_sensibility_update = FALSE;

	if (idx2select != -1) {
		GtkTreeSelection *selection =
		    gtk_tree_view_get_selection ((GTK_TREE_VIEW
						  (WID
						   ("xkb_layouts_selected"))));
		GtkTreePath *path =
		    gtk_tree_path_new_from_indices (idx2select, -1);
		gtk_tree_selection_select_path (selection, path);
		gtk_tree_path_free (path);
		idx2select = -1;
	} else {
		/* if there is nothing to select - just enable/disable the buttons,
		   otherwise it would be done by the selection change */
		xkb_layouts_enable_disable_buttons (dialog);
	}
}
/* Return true if optionname describes a string already in the backend's
   list of selected options */
static gboolean
xkb_options_is_selected (gchar * optionname)
{
	gboolean retval = FALSE;
	GSList *options_list = xkb_options_get_selected_list ();
	GSList *option;
	for (option = options_list; option != NULL; option = option->next) {
		if (!strcmp ((gchar *) option->data, optionname))
			retval = TRUE;
	}
	clear_xkb_elements_list (options_list);
	return retval;
}
void
xkl_layout_chooser_add_default_switcher_if_necessary (GSList *
						      layouts_list)
{
	GSList *options_list = xkb_options_get_selected_list ();
	gboolean was_appended;

	options_list =
	    matekbd_keyboard_config_add_default_switch_option_if_necessary
	    (layouts_list, options_list, &was_appended);
	if (was_appended)
		xkb_options_set_selected_list (options_list);
	clear_xkb_elements_list (options_list);
}
static void
show_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
	gint idx = find_selected_layout_idx (dialog);

	if (idx != -1) {
		GSList *layouts_list = xkb_layouts_get_selected_list ();
		const gchar *id = g_slist_nth_data (layouts_list, idx);
		char *descr = xkb_layout_description_utf8 (id);
		GtkWidget *parent = WID ("keyboard_dialog");
		GtkWidget *popup = matekbd_keyboard_drawing_new_dialog (idx, descr);
		gtk_widget_set_parent (popup, parent);
		clear_xkb_elements_list (layouts_list);
		g_free (descr);
	}
}
/* Add optionname from the backend's selection list if it's not
   already in there. */
static void
xkb_options_select (gchar * optionname)
{
	gboolean already_selected = FALSE;
	GSList *options_list = xkb_options_get_selected_list ();
	GSList *option;
	for (option = options_list; option != NULL; option = option->next)
		if (!strcmp ((gchar *) option->data, optionname))
			already_selected = TRUE;

	if (!already_selected)
		options_list =
		    g_slist_append (options_list, g_strdup (optionname));
	xkb_options_set_selected_list (options_list);

	clear_xkb_elements_list (options_list);
}
static void
xkb_layouts_dnd_data_received (GtkWidget * widget, GdkDragContext * dc,
			       gint x, gint y,
			       GtkSelectionData * selection_data,
			       guint info, guint t, GtkBuilder * dialog)
{
	gint sidx = find_selected_layout_idx (dialog);
	GtkWidget *tree_view = WID ("xkb_layouts_selected");
	GtkTreePath *path = NULL;
	GtkTreeViewDropPosition pos;
	gint didx;
	gchar *id;
	GSList *layouts_list;
	GSList *node2Remove;

	if (sidx == -1)
		return;

	layouts_list = xkb_layouts_get_selected_list ();
	node2Remove = g_slist_nth (layouts_list, sidx);

	id = (gchar *) node2Remove->data;
	layouts_list = g_slist_delete_link (layouts_list, node2Remove);

	if (!gtk_tree_view_get_dest_row_at_pos
	    (GTK_TREE_VIEW (tree_view), x, y, &path, &pos)) {
		/* Move to the very end */
		layouts_list =
		    g_slist_append (layouts_list, g_strdup (id));
		xkb_layouts_set_selected_list (layouts_list);
	} else if (path != NULL) {
		gint *indices = gtk_tree_path_get_indices (path);
		didx = indices[0];
		gtk_tree_path_free (path);
		/* Move to the new position */
		if (sidx != didx) {
			layouts_list =
			    g_slist_insert (layouts_list, g_strdup (id),
					    didx);
			xkb_layouts_set_selected_list (layouts_list);
		}
	}
	g_free (id);
	clear_xkb_elements_list (layouts_list);
}
static void
move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
	gint idx = find_selected_layout_idx (dialog);

	if (idx != -1) {
		GSList *layouts_list = xkb_layouts_get_selected_list ();
		GSList *node2Remove = g_slist_nth (layouts_list, idx);

		layouts_list =
		    g_slist_remove_link (layouts_list, node2Remove);
		layouts_list =
		    g_slist_insert (layouts_list, node2Remove->data,
				    idx + 1);
		g_slist_free_1 (node2Remove);

		idx2select = idx + 1;
		xkb_layouts_set_selected_list (layouts_list);
		clear_xkb_elements_list (layouts_list);
	}
}
/* Remove all occurences of optionname from the backend's selection list */
static void
xkb_options_deselect (gchar * optionname)
{
	GSList *options_list = xkb_options_get_selected_list ();
	GSList *nodetmp;
	GSList *option = options_list;
	while (option != NULL) {
		gchar *id = (char *) option->data;
		if (!strcmp (id, optionname)) {
			nodetmp = option->next;
			g_free (id);
			options_list =
			    g_slist_remove_link (options_list, option);
			g_slist_free_1 (option);
			option = nodetmp;
		} else
			option = option->next;
	}
	xkb_options_set_selected_list (options_list);
	clear_xkb_elements_list (options_list);
}
static void
xkb_layout_chooser_response (GtkDialog * dialog,
			     gint response, GtkBuilder * chooser_dialog)
{
	GdkRectangle rect;

	if (response == GTK_RESPONSE_OK) {
		gchar *selected_id = (gchar *)
		    xkb_layout_chooser_get_selected_id (chooser_dialog);

		if (selected_id != NULL) {
			GSList *layouts_list =
			    xkb_layouts_get_selected_list ();

			selected_id = g_strdup (selected_id);

			layouts_list =
			    g_slist_append (layouts_list, selected_id);
			xkb_layouts_set_selected_list (layouts_list);

			xkl_layout_chooser_add_default_switcher_if_necessary
			    (layouts_list);

			clear_xkb_elements_list (layouts_list);
		}
	} else if (response == gtk_dialog_get_response_for_widget
		   (dialog, CWID ("btnPrint"))) {
		xkb_layout_chooser_print (chooser_dialog);
		g_signal_stop_emission_by_name (dialog, "response");
		return;
	}

	gtk_window_get_position (GTK_WINDOW (dialog), &rect.x, &rect.y);
	gtk_window_get_size (GTK_WINDOW (dialog), &rect.width,
			     &rect.height);
	matekbd_preview_save_position (&rect);
}