[gnome-control-center] region: Make drag'n'drop work
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] region: Make drag'n'drop work
- Date: Tue, 15 Mar 2011 22:41:18 +0000 (UTC)
commit 211461007c394d607b7c81e8f445bbf5cd07c914
Author: Bastien Nocera <hadess hadess net>
Date: Tue Mar 15 17:43:09 2011 +0000
region: Make drag'n'drop work
By making sure we only store the layouts in the list store, and keep
GSettings in sync with the list store, rather than constantly re-reading
from GSettings.
https://bugzilla.gnome.org/show_bug.cgi?id=644783
panels/region/gnome-region-panel-xkb.h | 7 +-
panels/region/gnome-region-panel-xkblt.c | 282 +++++++++++++++------------
panels/region/gnome-region-panel-xkbltadd.c | 65 ++-----
panels/region/gnome-region-panel-xkbpv.c | 13 --
4 files changed, 179 insertions(+), 188 deletions(-)
---
diff --git a/panels/region/gnome-region-panel-xkb.h b/panels/region/gnome-region-panel-xkb.h
index 11f0be5..dd8bf23 100644
--- a/panels/region/gnome-region-panel-xkb.h
+++ b/panels/region/gnome-region-panel-xkb.h
@@ -60,7 +60,9 @@ extern void enable_disable_restoring (GtkBuilder * dialog);
extern void preview_toggled (GtkBuilder * dialog, GtkWidget * button);
-extern void xkb_layout_choose (GtkBuilder * dialog);
+extern GtkWidget *xkb_layout_choose (GtkBuilder * dialog);
+
+extern void xkb_layout_chooser_response (GtkDialog *dialog, gint response_id);
extern gchar **xkb_layouts_get_selected_list (void);
@@ -84,8 +86,7 @@ extern void xkb_layout_preview_update (GtkBuilder * chooser_dialog);
extern void xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw,
const gchar * id);
-extern gchar *xkb_layout_chooser_get_selected_id (GtkBuilder *
- chooser_dialog);
+extern gchar *xkb_layout_chooser_get_selected_id (GtkDialog *dialog);
extern void xkb_save_default_group (gint group_no);
diff --git a/panels/region/gnome-region-panel-xkblt.c b/panels/region/gnome-region-panel-xkblt.c
index 19468d3..b8b24dd 100644
--- a/panels/region/gnome-region-panel-xkblt.c
+++ b/panels/region/gnome-region-panel-xkblt.c
@@ -34,31 +34,40 @@
enum {
SEL_LAYOUT_TREE_COL_DESCRIPTION,
SEL_LAYOUT_TREE_COL_ID,
- SEL_LAYOUT_TREE_COL_ENABLED
+ SEL_LAYOUT_TREE_COL_ENABLED,
+ SEL_LAYOUT_N_COLS
};
static int idx2select = -1;
static int max_selected_layouts = -1;
-static int default_group = -1;
+static gboolean updating_settings = FALSE;
static GtkCellRenderer *text_renderer;
static gboolean disable_buttons_sensibility_update = FALSE;
+static gboolean
+get_selected_iter (GtkBuilder *dialog,
+ GtkTreeModel **model,
+ GtkTreeIter *iter)
+{
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("xkb_layouts_selected")));
+
+ return gtk_tree_selection_get_selected (selection, model, iter);
+}
+
static gint
-find_selected_layout_idx (GtkBuilder * dialog)
+find_selected_layout_idx (GtkBuilder *dialog)
{
- GtkTreeSelection *selection =
- gtk_tree_view_get_selection (GTK_TREE_VIEW
- (WID ("xkb_layouts_selected")));
GtkTreeIter selected_iter;
GtkTreeModel *model;
GtkTreePath *path;
gint *indices;
gint rv;
- if (!gtk_tree_selection_get_selected
- (selection, &model, &selected_iter))
+ if (!get_selected_iter (dialog, &model, &selected_iter))
return -1;
path = gtk_tree_model_get_path (model, &selected_iter);
@@ -96,10 +105,9 @@ xkb_get_default_group ()
void
xkb_save_default_group (gint default_group)
{
- if (default_group != xkb_get_default_group ())
- g_settings_set_int (xkb_desktop_settings,
- GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP,
- default_group);
+ g_settings_set_int (xkb_desktop_settings,
+ GKBD_DESKTOP_CONFIG_KEY_DEFAULT_GROUP,
+ default_group);
}
static void
@@ -141,79 +149,76 @@ xkb_layouts_enable_disable_buttons (GtkBuilder * dialog)
}
static void
-xkb_layouts_dnd_data_get (GtkWidget * widget, GdkDragContext * dc,
- GtkSelectionData * selection_data, guint info,
- guint t, GtkBuilder * dialog)
+update_layouts_list (GtkTreeModel *model,
+ GtkBuilder *dialog)
{
- /* Storing the value into selection -
- * while it is actually not used
- */
- gint idx = find_selected_layout_idx (dialog);
- gtk_selection_data_set (selection_data,
- GDK_SELECTION_TYPE_INTEGER, 32,
- (guchar *) & idx, sizeof (idx));
+ gboolean cont;
+ GtkTreeIter iter;
+ GPtrArray *array;
+
+ updating_settings = TRUE;
+
+ array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
+ cont = gtk_tree_model_get_iter_first (model, &iter);
+ while (cont) {
+ char *id;
+
+ gtk_tree_model_get (model, &iter,
+ SEL_LAYOUT_TREE_COL_ID, &id,
+ -1);
+ g_ptr_array_add (array, id);
+ cont = gtk_tree_model_iter_next (model, &iter);
+ }
+ g_ptr_array_add (array, NULL);
+ xkb_layouts_set_selected_list (array->pdata);
+ g_ptr_array_free (array, TRUE);
+
+ updating_settings = FALSE;
+
+ xkb_layouts_enable_disable_buttons (dialog);
}
static void
-xkb_layouts_dnd_data_received (GtkWidget * widget, GdkDragContext * dc,
- gint x, gint y,
- GtkSelectionData * selection_data,
- guint info, guint t, GtkBuilder * dialog)
+xkb_layouts_row_inserted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ 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;
- gchar **layouts_list;
+ g_message ("row inserted");
+ update_layouts_list (tree_model, dialog);
+}
- if (sidx == -1)
- return;
+static void
+xkb_layouts_row_deleted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkBuilder *dialog)
+{
+ g_message ("row deleted");
+ update_layouts_list (tree_model, dialog);
+}
- layouts_list = xkb_layouts_get_selected_list ();
- id = g_strdup (layouts_list[sidx]);
-
- /* Remove the element at position sidx */
- gkbd_strv_behead (layouts_list + sidx);
-
- if (!gtk_tree_view_get_dest_row_at_pos
- (GTK_TREE_VIEW (tree_view), x, y, &path, &pos)) {
- /* Move to the very end */
- int old_length = g_strv_length (layouts_list);
- layouts_list[old_length] = id;
- /* NULL was there before deletion, no need to re-assign */
- 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) {
- memmove (layouts_list + didx + 1,
- layouts_list + didx,
- g_strv_length (layouts_list + didx));
- layouts_list[didx] = id;
- xkb_layouts_set_selected_list (layouts_list);
- } else {
- g_free (id);
- }
- }
- g_strfreev (layouts_list);
+static void
+xkb_layouts_row_reordered (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer new_order,
+ GtkBuilder *dialog)
+{
+ g_message ("row reordered");
+ update_layouts_list (tree_model, dialog);
}
void
xkb_layouts_prepare_selected_tree (GtkBuilder * dialog)
{
- GtkListStore *list_store =
- gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_BOOLEAN);
+ GtkListStore *list_store;
GtkWidget *tree_view = WID ("xkb_layouts_selected");
GtkTreeSelection *selection;
- GtkTargetEntry self_drag_target =
- { "xkb_layouts_selected", GTK_TARGET_SAME_WIDGET, 0 };
GtkTreeViewColumn *desc_column;
+ list_store = gtk_list_store_new (SEL_LAYOUT_N_COLS,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
+
text_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ());
desc_column =
@@ -245,17 +250,13 @@ xkb_layouts_prepare_selected_tree (GtkBuilder * dialog)
max_selected_layouts = xkl_engine_get_max_num_groups (engine);
/* Setting up DnD */
- gtk_drag_source_set (tree_view, GDK_BUTTON1_MASK,
- &self_drag_target, 1, GDK_ACTION_MOVE);
- gtk_drag_source_set_icon_name (tree_view, "input-keyboard");
- gtk_drag_dest_set (tree_view, GTK_DEST_DEFAULT_ALL,
- &self_drag_target, 1, GDK_ACTION_MOVE);
-
- g_signal_connect (G_OBJECT (tree_view), "drag_data_get",
- G_CALLBACK (xkb_layouts_dnd_data_get), dialog);
- g_signal_connect (G_OBJECT (tree_view), "drag_data_received",
- G_CALLBACK (xkb_layouts_dnd_data_received),
- dialog);
+ gtk_tree_view_set_reorderable (GTK_TREE_VIEW (tree_view), TRUE);
+ g_signal_connect (G_OBJECT (list_store), "row-inserted",
+ G_CALLBACK (xkb_layouts_row_inserted), dialog);
+ g_signal_connect (G_OBJECT (list_store), "row-deleted",
+ G_CALLBACK (xkb_layouts_row_deleted), dialog);
+ g_signal_connect (G_OBJECT (list_store), "rows-reordered",
+ G_CALLBACK (xkb_layouts_row_reordered), dialog);
}
gchar *
@@ -285,19 +286,17 @@ xkb_layouts_fill_selected_tree (GtkBuilder * dialog)
gtk_list_store_clear (list_store);
for (i = 0; layouts != NULL && layouts[i] != NULL; i++) {
- GtkTreeIter iter;
char *cur_layout = layouts[i];
gchar *utf_visible =
xkb_layout_description_utf8 (cur_layout);
- 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,
- SEL_LAYOUT_TREE_COL_ENABLED,
- i < max_selected_layouts, -1);
+ gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT,
+ SEL_LAYOUT_TREE_COL_DESCRIPTION,
+ utf_visible,
+ SEL_LAYOUT_TREE_COL_ID,
+ cur_layout,
+ SEL_LAYOUT_TREE_COL_ENABLED,
+ i < max_selected_layouts, -1);
g_free (utf_visible);
}
@@ -324,9 +323,35 @@ xkb_layouts_fill_selected_tree (GtkBuilder * dialog)
}
static void
+chooser_response (GtkDialog *chooser,
+ int response_id,
+ GtkBuilder *dialog)
+{
+ if (response_id == GTK_RESPONSE_OK) {
+ char *id, *name;
+ GtkListStore *list_store;
+
+ list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (WID ("xkb_layouts_selected"))));
+ id = xkb_layout_chooser_get_selected_id (chooser);
+ name = xkb_layout_description_utf8 (id);
+ gtk_list_store_insert_with_values (list_store, NULL, G_MAXINT,
+ SEL_LAYOUT_TREE_COL_DESCRIPTION, name,
+ SEL_LAYOUT_TREE_COL_ID, id,
+ SEL_LAYOUT_TREE_COL_ENABLED, TRUE,
+ -1);
+ }
+
+ xkb_layout_chooser_response (chooser, response_id);
+}
+
+static void
add_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
- xkb_layout_choose (dialog);
+ GtkWidget *chooser;
+
+ chooser = xkb_layout_choose (dialog);
+ g_signal_connect (G_OBJECT (chooser), "response",
+ G_CALLBACK (chooser_response), dialog);
}
static void
@@ -351,54 +376,67 @@ show_selected_layout (GtkWidget * button, GtkBuilder * dialog)
static void
remove_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
- gint idx = find_selected_layout_idx (dialog);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
- if (idx != -1) {
- gchar **layouts_list = xkb_layouts_get_selected_list ();
- gkbd_strv_behead (layouts_list + idx);
+ if (get_selected_iter (dialog, &model, &iter) == FALSE)
+ return;
- if (default_group > idx)
- xkb_save_default_group (default_group - 1);
- else if (default_group == idx)
- xkb_save_default_group (-1);
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+}
- xkb_layouts_set_selected_list (layouts_list);
- g_strfreev (layouts_list);
- }
+static gboolean
+_tree_model_iter_previous (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ GtkTreePath *path;
+ gboolean ret;
+
+ path = gtk_tree_model_get_path (tree_model, iter);
+ ret = gtk_tree_path_prev (path);
+ if (ret != FALSE)
+ gtk_tree_model_get_iter (tree_model, iter, path);
+
+ gtk_tree_path_free (path);
+ return ret;
}
static void
move_up_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
- gint idx = find_selected_layout_idx (dialog);
+ GtkTreeModel *model;
+ GtkTreeIter iter, *prev;
- if (idx != -1) {
- gchar **layouts_list = xkb_layouts_get_selected_list ();
- gchar *tmp = layouts_list[idx - 1];
- layouts_list[idx - 1] = layouts_list[idx];
- layouts_list[idx] = tmp;
-
- idx2select = idx - 1;
- xkb_layouts_set_selected_list (layouts_list);
- g_strfreev (layouts_list);
+ if (get_selected_iter (dialog, &model, &iter) == FALSE)
+ return;
+
+ prev = gtk_tree_iter_copy (&iter);
+ if (!_tree_model_iter_previous (model, prev)) {
+ gtk_tree_iter_free (prev);
+ return;
}
+
+ gtk_list_store_swap (GTK_LIST_STORE (model), &iter, prev);
+ gtk_tree_iter_free (prev);
}
static void
move_down_selected_layout (GtkWidget * button, GtkBuilder * dialog)
{
- gint idx = find_selected_layout_idx (dialog);
+ GtkTreeModel *model;
+ GtkTreeIter iter, *next;
- if (idx != -1) {
- gchar **layouts_list = xkb_layouts_get_selected_list ();
- gchar *tmp = layouts_list[idx + 1];
- layouts_list[idx + 1] = layouts_list[idx];
- layouts_list[idx] = tmp;
-
- idx2select = idx + 1;
- xkb_layouts_set_selected_list (layouts_list);
- g_strfreev (layouts_list);
+ if (get_selected_iter (dialog, &model, &iter) == FALSE)
+ return;
+
+ next = gtk_tree_iter_copy (&iter);
+ if (!gtk_tree_model_iter_next (model, next)) {
+ gtk_tree_iter_free (next);
+ return;
}
+
+ gtk_list_store_swap (GTK_LIST_STORE (model), &iter, next);
+ gtk_tree_iter_free (next);
}
void
@@ -423,6 +461,8 @@ xkb_layouts_update_list (GSettings * settings,
gchar * key, GtkBuilder * dialog)
{
if (strcmp (key, GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS) == 0) {
+ if (updating_settings)
+ return;
xkb_layouts_fill_selected_tree (dialog);
enable_disable_restoring (dialog);
}
diff --git a/panels/region/gnome-region-panel-xkbltadd.c b/panels/region/gnome-region-panel-xkbltadd.c
index cddb7d2..2cd588a 100644
--- a/panels/region/gnome-region-panel-xkbltadd.c
+++ b/panels/region/gnome-region-panel-xkbltadd.c
@@ -45,31 +45,16 @@ static GtkWidget *preview_dialog = NULL;
#define RESPONSE_PREVIEW 1
static void
-xkl_layout_chooser_add_default_switcher_if_necessary (gchar **
- layouts_list)
-{
- gchar **options_list = xkb_options_get_selected_list ();
- gboolean was_appended;
-
- options_list =
- gkbd_keyboard_config_add_default_switch_option_if_necessary
- (layouts_list, options_list, &was_appended);
- if (was_appended)
- xkb_options_set_selected_list (options_list);
- g_strfreev (options_list);
-}
-
-static void
xkb_preview_destroy_callback (GtkWidget * widget)
{
preview_dialog = NULL;
}
static gboolean
-xkb_layout_chooser_selection_dupe (GtkBuilder * chooser_dialog)
+xkb_layout_chooser_selection_dupe (GtkDialog *dialog)
{
gchar *selected_id =
- (gchar *) xkb_layout_chooser_get_selected_id (chooser_dialog);
+ (gchar *) xkb_layout_chooser_get_selected_id (dialog);
gchar **layouts_list, **pl;
gboolean rv = FALSE;
if (selected_id == NULL)
@@ -85,38 +70,18 @@ xkb_layout_chooser_selection_dupe (GtkBuilder * chooser_dialog)
return rv;
}
-static void
-xkb_layout_chooser_response (GtkDialog * dialog,
- gint response, GtkBuilder * chooser_dialog)
+void
+xkb_layout_chooser_response (GtkDialog *dialog,
+ gint response)
{
switch (response)
case GTK_RESPONSE_OK:{
- gchar *selected_id = (gchar *)
- xkb_layout_chooser_get_selected_id
- (chooser_dialog);
-
- if (selected_id != NULL) {
- gchar **layouts_list =
- xkb_layouts_get_selected_list ();
-
- layouts_list =
- gkbd_strv_append (layouts_list,
- g_strdup
- (selected_id));
-
- xkb_layouts_set_selected_list
- (layouts_list);
-
- xkl_layout_chooser_add_default_switcher_if_necessary
- (layouts_list);
-
- g_strfreev (layouts_list);
- }
+ /* Handled by the main code */
break;
case RESPONSE_PREVIEW:{
gchar *selected_id = (gchar *)
xkb_layout_chooser_get_selected_id
- (chooser_dialog);
+ (dialog);
if (selected_id != NULL) {
if (preview_dialog == NULL) {
@@ -307,7 +272,7 @@ xkb_layout_chooser_selection_changed (GtkTreeSelection * selection,
GtkWidget *add_button = CWID ("btnOk");
GtkWidget *preview_button = CWID ("btnPreview");
gboolean anything_selected = g_list_length (selected_layouts) == 1;
- gboolean dupe = xkb_layout_chooser_selection_dupe (chooser_dialog);
+ gboolean dupe = xkb_layout_chooser_selection_dupe (GTK_DIALOG (CWID("xkb_layout_chooser")));
gtk_widget_set_sensitive (add_button, anything_selected && !dupe);
gtk_widget_set_sensitive (preview_button, anything_selected);
@@ -359,7 +324,7 @@ xkb_filter_layouts (GtkTreeModel * model,
return rv;
}
-void
+GtkWidget *
xkb_layout_choose (GtkBuilder * dialog)
{
GtkBuilder *chooser_dialog = gtk_builder_new ();
@@ -376,6 +341,7 @@ xkb_layout_choose (GtkBuilder * dialog)
xkb_filtered_layouts_list = CWID ("xkb_filtered_layouts_list");
xkb_layout_filter = CWID ("xkb_layout_filter");
+ g_object_set_data (G_OBJECT (chooser), "xkb_filtered_layouts_list", xkb_filtered_layouts_list);
visible_column =
gtk_tree_view_column_new_with_attributes ("Layout",
gtk_cell_renderer_text_new
@@ -397,11 +363,6 @@ xkb_layout_choose (GtkBuilder * dialog)
(xkb_layout_filter_changed),
chooser_dialog);
- g_signal_connect (G_OBJECT (chooser),
- "response",
- G_CALLBACK (xkb_layout_chooser_response),
- chooser_dialog);
-
selection =
gtk_tree_view_get_selection (GTK_TREE_VIEW
(xkb_filtered_layouts_list));
@@ -438,14 +399,16 @@ xkb_layout_choose (GtkBuilder * dialog)
gtk_widget_grab_focus (xkb_layout_filter);
gtk_widget_show (chooser);
+
+ return chooser;
}
gchar *
-xkb_layout_chooser_get_selected_id (GtkBuilder * chooser_dialog)
+xkb_layout_chooser_get_selected_id (GtkDialog *dialog)
{
GtkTreeModel *filtered_list_model;
GtkWidget *xkb_filtered_layouts_list =
- CWID ("xkb_filtered_layouts_list");
+ g_object_get_data (G_OBJECT (dialog), "xkb_filtered_layouts_list");
GtkTreeIter viter;
gchar *v_id;
GtkTreeSelection *selection =
diff --git a/panels/region/gnome-region-panel-xkbpv.c b/panels/region/gnome-region-panel-xkbpv.c
index 5d4027e..839aadf 100644
--- a/panels/region/gnome-region-panel-xkbpv.c
+++ b/panels/region/gnome-region-panel-xkbpv.c
@@ -62,19 +62,6 @@ xkb_layout_preview_create_widget (GtkBuilder * chooserDialog)
}
void
-xkb_layout_preview_update (GtkBuilder * chooser_dialog)
-{
-#ifdef HAVE_X11_EXTENSIONS_XKB_H
- GtkWidget *chooser = CWID ("xkb_layout_chooser");
- GtkWidget *kbdraw =
- GTK_WIDGET (g_object_get_data (G_OBJECT (chooser), "kbdraw"));
- gchar *id = xkb_layout_chooser_get_selected_id (chooser_dialog);
- xkb_layout_preview_set_drawing_layout (kbdraw, id);
- g_free (id);
-#endif
-}
-
-void
xkb_layout_preview_set_drawing_layout (GtkWidget * kbdraw,
const gchar * id)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]