[Xfce4-commits] <xfce4-panel:master> Various improvements in the launcher dialog.

Nick Schermer noreply at xfce.org
Thu Dec 16 20:54:01 CET 2010


Updating branch refs/heads/master
         to d99751094c58330f5671822f03c2e1a90e569785 (commit)
       from c1a5fbf2d3652cf5bfd0ce015c3886a7a462437d (commit)

commit d99751094c58330f5671822f03c2e1a90e569785
Author: Nick Schermer <nick at xfce.org>
Date:   Thu Dec 16 20:51:33 2010 +0100

    Various improvements in the launcher dialog.
    
    Restore the item dnd we has in 4.6 and reduce the amount
    of reloads and saving item moves triggered.

 plugins/launcher/launcher-dialog.c |  200 ++++++++++++++++++++++++++----------
 1 files changed, 144 insertions(+), 56 deletions(-)

diff --git a/plugins/launcher/launcher-dialog.c b/plugins/launcher/launcher-dialog.c
index f450d18..fb51905 100644
--- a/plugins/launcher/launcher-dialog.c
+++ b/plugins/launcher/launcher-dialog.c
@@ -57,6 +57,13 @@ typedef struct
 }
 LauncherPluginDialog;
 
+typedef struct
+{
+  LauncherPluginDialog *dialog;
+  GarconMenuItem       *item;
+}
+LauncherChangedHandler;
+
 enum
 {
   COL_ICON,
@@ -70,7 +77,8 @@ enum
 
 static void     launcher_dialog_items_set_item         (GtkTreeModel         *model,
                                                         GtkTreeIter          *iter,
-                                                        GarconMenuItem       *item);
+                                                        GarconMenuItem       *item,
+                                                        LauncherPluginDialog *dialog);
 static void     launcher_dialog_tree_save              (LauncherPluginDialog *dialog);
 static void     launcher_dialog_tree_selection_changed (GtkTreeSelection     *selection,
                                                         LauncherPluginDialog *dialog);
@@ -82,9 +90,26 @@ static void     launcher_dialog_items_load             (LauncherPluginDialog *di
 
 
 /* dnd for items in and from the treeviews */
-static const GtkTargetEntry dnd_targets[] =
+enum
 {
-  { "text/uri-list", 0, 0, },
+  DROP_TARGET_URI,
+  DROP_TARGET_ROW
+};
+
+static const GtkTargetEntry add_drag_targets[] =
+{
+  { "text/uri-list", 0, 0 }
+};
+
+static const GtkTargetEntry list_drop_targets[] =
+{
+  { "text/uri-list", 0, DROP_TARGET_URI },
+  { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, DROP_TARGET_ROW }
+};
+
+static const GtkTargetEntry list_drag_targets[] =
+{
+  { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, 0 }
 };
 
 
@@ -165,7 +190,7 @@ launcher_dialog_add_store_insert (gpointer key,
   panel_return_if_fail (GTK_IS_LIST_STORE (model));
 
   gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-  launcher_dialog_items_set_item (model, &iter, item);
+  launcher_dialog_items_set_item (model, &iter, item, NULL);
 
   gfile = garcon_menu_item_get_file (item);
   tooltip = g_file_get_parse_name (gfile);
@@ -373,7 +398,7 @@ launcher_dialog_add_response (GtkWidget            *widget,
           /* insert the item in the item store */
           if (G_LIKELY (item != NULL))
             {
-              launcher_dialog_items_set_item (item_model, &iter, item);
+              launcher_dialog_items_set_item (item_model, &iter, item, dialog);
               g_object_unref (G_OBJECT (item));
 
               /* select the first item */
@@ -452,7 +477,12 @@ launcher_dialog_tree_save (LauncherPluginDialog *dialog)
   gtk_tree_model_foreach (GTK_TREE_MODEL (store),
                           launcher_dialog_tree_save_foreach, array);
 
+  g_signal_handlers_block_by_func (G_OBJECT (dialog->plugin),
+          G_CALLBACK (launcher_dialog_items_load), dialog);
   g_object_set (dialog->plugin, "items", array, NULL);
+    g_signal_handlers_unblock_by_func (G_OBJECT (dialog->plugin),
+          G_CALLBACK (launcher_dialog_items_load), dialog);
+
   xfconf_array_free (array);
 }
 
@@ -480,50 +510,57 @@ launcher_dialog_tree_drag_data_received (GtkWidget            *treeview,
   panel_return_if_fail (GTK_IS_TREE_VIEW (treeview));
   panel_return_if_fail (GTK_IS_BUILDER (dialog->builder));
 
-  uris = gtk_selection_data_get_uris (data);
-  if (G_LIKELY (uris == NULL))
+  if (info == DROP_TARGET_URI)
     {
-      gtk_drag_finish (context, FALSE, FALSE, timestamp);
-      return;
-    }
+      uris = gtk_selection_data_get_uris (data);
+      if (G_LIKELY (uris == NULL))
+        {
+          gtk_drag_finish (context, FALSE, FALSE, timestamp);
+          return;
+        }
 
-  /* get the insert position */
-  model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
-  if (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (treeview),
-                                         x, y, &path, &drop_pos))
-    {
-      position = gtk_tree_path_get_indices (path)[0];
-      gtk_tree_path_free (path);
-      if (drop_pos == GTK_TREE_VIEW_DROP_AFTER
-          || drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
-        position++;
-    }
-  else
-    {
-      /* prepend at the end of the model */
-      position = gtk_tree_model_iter_n_children (model, NULL);
-    }
+      /* get the insert position */
+      model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
+      if (gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (treeview),
+                                             x, y, &path, &drop_pos))
+        {
+          position = gtk_tree_path_get_indices (path)[0];
+          gtk_tree_path_free (path);
+          if (drop_pos == GTK_TREE_VIEW_DROP_AFTER
+              || drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
+            position++;
+        }
+      else
+        {
+          /* prepend at the end of the model */
+          position = gtk_tree_model_iter_n_children (model, NULL);
+        }
 
-  /* insert the uris */
-  for (i = 0; uris[i] != NULL; i++)
-    {
-      if (!g_str_has_suffix (uris[i], ".desktop"))
-        continue;
+      /* insert the uris */
+      for (i = 0; uris[i] != NULL; i++)
+        {
+          if (!g_str_has_suffix (uris[i], ".desktop"))
+            continue;
 
-      item = garcon_menu_item_new_for_uri (uris[i]);
-      if (G_UNLIKELY (item == NULL))
-        continue;
+          item = garcon_menu_item_new_for_uri (uris[i]);
+          if (G_UNLIKELY (item == NULL))
+            continue;
 
-      gtk_list_store_insert (GTK_LIST_STORE (model), &iter, position);
-      launcher_dialog_items_set_item (model, &iter, item);
-      g_object_unref (G_OBJECT (item));
-    }
+          gtk_list_store_insert (GTK_LIST_STORE (model), &iter, position);
+          launcher_dialog_items_set_item (model, &iter, item, dialog);
+          g_object_unref (G_OBJECT (item));
+        }
 
-  g_strfreev (uris);
+      g_strfreev (uris);
 
-  launcher_dialog_tree_save (dialog);
+      launcher_dialog_tree_save (dialog);
 
-  gtk_drag_finish (context, TRUE, FALSE, timestamp);
+      gtk_drag_finish (context, TRUE, FALSE, timestamp);
+    }
+  else if (info == DROP_TARGET_ROW)
+    {
+        /* nothing to do here, just wait for an row-inserted signal */
+    }
 }
 
 
@@ -667,6 +704,7 @@ launcher_dialog_item_button_clicked (GtkWidget            *button,
   gchar            *filename;
   gboolean          can_delete;
   GFile            *item_file;
+  gboolean          save_items = TRUE;
 
   panel_return_if_fail (GTK_IS_BUILDABLE (button));
   panel_return_if_fail (GTK_IS_BUILDER (dialog->builder));
@@ -724,6 +762,10 @@ launcher_dialog_item_button_clicked (GtkWidget            *button,
                   g_object_unref (G_OBJECT (item_file));
                 }
             }
+          else
+            {
+              save_items = FALSE;
+            }
 
           if (G_LIKELY (item != NULL))
             g_object_unref (G_OBJECT (item));
@@ -763,6 +805,8 @@ launcher_dialog_item_button_clicked (GtkWidget            *button,
             }
 
           g_free (command);
+
+          save_items = FALSE;
         }
       else if (strcmp (name, "item-move-up") == 0)
         {
@@ -784,7 +828,8 @@ launcher_dialog_item_button_clicked (GtkWidget            *button,
         }
 
       /* store the new settings */
-      launcher_dialog_tree_save (dialog);
+      if (save_items)
+        launcher_dialog_tree_save (dialog);
 
       /* emit a changed signal to update the button states */
       launcher_dialog_tree_selection_changed (selection, dialog);
@@ -840,17 +885,18 @@ launcher_dialog_item_changed_foreach (GtkTreeModel *model,
                                       GtkTreeIter  *iter,
                                       gpointer      user_data)
 {
-  GarconMenuItem *item;
-  gboolean        found;
+  GarconMenuItem         *item;
+  gboolean                found;
+  LauncherChangedHandler *handler = user_data;
 
-  panel_return_val_if_fail (GARCON_IS_MENU_ITEM (user_data), TRUE);
+  panel_return_val_if_fail (GARCON_IS_MENU_ITEM (handler->item), TRUE);
 
   /* check if this is the item in the model */
   gtk_tree_model_get (model, iter, COL_ITEM, &item, -1);
-  found = item == user_data;
+  found = !!(item == handler->item);
 
   if (G_UNLIKELY (found))
-    launcher_dialog_items_set_item (model, iter, item);
+    launcher_dialog_items_set_item (model, iter, item, handler->dialog);
 
   g_object_unref (G_OBJECT (item));
 
@@ -863,8 +909,9 @@ static void
 launcher_dialog_item_changed (GarconMenuItem       *item,
                               LauncherPluginDialog *dialog)
 {
-  GObject      *treeview;
-  GtkTreeModel *model;
+  GObject                *treeview;
+  GtkTreeModel           *model;
+  LauncherChangedHandler *handler;
 
   panel_return_if_fail (GARCON_IS_MENU_ITEM (item));
 
@@ -872,15 +919,42 @@ launcher_dialog_item_changed (GarconMenuItem       *item,
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
 
   /* find the item in the model and update it */
-  gtk_tree_model_foreach (model, launcher_dialog_item_changed_foreach, item);
+  handler = g_slice_new0 (LauncherChangedHandler);
+  handler->dialog = dialog;
+  handler->item = item;
+  gtk_tree_model_foreach (model, launcher_dialog_item_changed_foreach, handler);
+  g_slice_free (LauncherChangedHandler, handler);
+}
+
+
+
+static void
+launcher_dialog_tree_row_changed (GtkTreeModel         *model,
+                                  GtkTreePath          *path,
+                                  GtkTreeIter          *iter,
+                                  LauncherPluginDialog *dialog)
+{
+  GtkTreeSelection *selection;
+  GObject          *treeview;
+
+  panel_return_if_fail (GTK_IS_BUILDER (dialog->builder));
+
+  /* item moved with dnd, save the tree to update the plugin */
+  g_idle_add ((GSourceFunc) launcher_dialog_tree_save, dialog);
+
+  /* select the moved item to there is no selection change on reload */
+  treeview = gtk_builder_get_object (dialog->builder, "item-treeview");
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+  gtk_tree_selection_select_iter (selection, iter);
 }
 
 
 
 static void
-launcher_dialog_items_set_item (GtkTreeModel   *model,
-                                GtkTreeIter    *iter,
-                                GarconMenuItem *item)
+launcher_dialog_items_set_item (GtkTreeModel         *model,
+                                GtkTreeIter          *iter,
+                                GarconMenuItem       *item,
+                                LauncherPluginDialog *dialog)
 {
   const gchar *name, *comment;
   gchar       *markup;
@@ -896,12 +970,20 @@ launcher_dialog_items_set_item (GtkTreeModel   *model,
   else
     markup = g_markup_printf_escaped ("<b>%s</b>", name);
 
+  if (dialog != NULL)
+    g_signal_handlers_block_by_func (G_OBJECT (model),
+        G_CALLBACK (launcher_dialog_tree_row_changed), dialog);
+
   gtk_list_store_set (GTK_LIST_STORE (model), iter,
                       COL_ICON, garcon_menu_item_get_icon_name (item),
                       COL_NAME, markup,
                       COL_ITEM, item,
                       -1);
 
+  if (dialog != NULL)
+    g_signal_handlers_unblock_by_func (G_OBJECT (model),
+        G_CALLBACK (launcher_dialog_tree_row_changed), dialog);
+
   g_free (markup);
 }
 
@@ -955,7 +1037,7 @@ launcher_dialog_items_load (LauncherPluginDialog *dialog)
   for (li = dialog->items; li != NULL; li = li->next)
     {
       gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-      launcher_dialog_items_set_item (model, &iter, GARCON_MENU_ITEM (li->data));
+      launcher_dialog_items_set_item (model, &iter, GARCON_MENU_ITEM (li->data), dialog);
       g_signal_connect (G_OBJECT (li->data), "changed",
           G_CALLBACK (launcher_dialog_item_changed), dialog);
     }
@@ -1016,11 +1098,17 @@ launcher_dialog_show (LauncherPlugin *plugin)
           G_CALLBACK (launcher_dialog_item_button_clicked), dialog);
     }
 
+  object = gtk_builder_get_object (dialog->builder, "item-store");
+  g_signal_connect (G_OBJECT (object), "row-changed",
+      G_CALLBACK (launcher_dialog_tree_row_changed), dialog);
+
   /* setup treeview selection */
   object = gtk_builder_get_object (builder, "item-treeview");
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
   gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (object),
-      dnd_targets, G_N_ELEMENTS (dnd_targets), GDK_ACTION_COPY);
+      list_drop_targets, G_N_ELEMENTS (list_drop_targets), GDK_ACTION_COPY);
+  gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (object), GDK_BUTTON1_MASK,
+      list_drag_targets, G_N_ELEMENTS (list_drag_targets), GDK_ACTION_MOVE);
   gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
   g_signal_connect (G_OBJECT (object), "drag-data-received",
       G_CALLBACK (launcher_dialog_tree_drag_data_received), dialog);
@@ -1056,7 +1144,7 @@ launcher_dialog_show (LauncherPlugin *plugin)
   /* allow selecting multiple items in the add dialog */
   object = gtk_builder_get_object (builder, "add-treeview");
   gtk_drag_source_set (GTK_WIDGET (object), GDK_BUTTON1_MASK,
-      dnd_targets, G_N_ELEMENTS (dnd_targets), GDK_ACTION_COPY);
+      add_drag_targets, G_N_ELEMENTS (add_drag_targets), GDK_ACTION_COPY);
   g_signal_connect (G_OBJECT (object), "drag-data-get",
       G_CALLBACK (launcher_dialog_add_drag_data_get), dialog);
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));



More information about the Xfce4-commits mailing list