[Xfce4-commits] <xfce4-appfinder:master> Add action item editing.

Nick Schermer noreply at xfce.org
Tue Sep 20 21:58:04 CEST 2011


Updating branch refs/heads/master
         to f6290f1c16c175e65ef7837317342feb4efbb732 (commit)
       from dbce37f8979ae6230c13438da1c21a8e53cb6091 (commit)

commit f6290f1c16c175e65ef7837317342feb4efbb732
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Sep 20 21:52:52 2011 +0200

    Add action item editing.

 src/appfinder-actions.c         |  134 +++++++++++++++++++++++++++------
 src/appfinder-actions.h         |   14 ++--
 src/appfinder-preferences.c     |  154 +++++++++++++++++++++++++++++++++------
 src/appfinder-preferences.glade |    1 +
 4 files changed, 248 insertions(+), 55 deletions(-)

diff --git a/src/appfinder-actions.c b/src/appfinder-actions.c
index 01c1feb..3d57f4b 100644
--- a/src/appfinder-actions.c
+++ b/src/appfinder-actions.c
@@ -35,7 +35,8 @@
 
 static void xfce_appfinder_actions_finalize (GObject              *object);
 static void xfce_appfinder_actions_free     (XfceAppfinderAction  *action);
-static void xfce_appfinder_actions_load     (XfceAppfinderActions *actions);
+static void xfce_appfinder_actions_load     (XfceAppfinderActions *actions,
+                                             gboolean              steal);
 static void xfce_appfinder_actions_save     (XfceAppfinderActions *actions,
                                              gboolean              save_actions);
 static void xfce_appfinder_actions_changed  (XfconfChannel        *channel,
@@ -57,6 +58,8 @@ struct _XfceAppfinderActions
   XfconfChannel *channel;
   gulong         property_watch_id;
 
+  guint          reload_idle_id;
+
   GSList        *actions;
 };
 
@@ -100,7 +103,7 @@ xfce_appfinder_actions_init (XfceAppfinderActions *actions)
 {
   actions->channel = xfconf_channel_get ("xfce4-appfinder");
 
-  xfce_appfinder_actions_load (actions);
+  xfce_appfinder_actions_load (actions, FALSE);
 
   actions->property_watch_id =
     g_signal_connect (G_OBJECT (actions->channel), "property-changed",
@@ -114,6 +117,9 @@ xfce_appfinder_actions_finalize (GObject *object)
 {
   XfceAppfinderActions *actions = XFCE_APPFINDER_ACTIONS (object);
 
+  if (actions->reload_idle_id != 0)
+    g_source_remove (actions->reload_idle_id);
+
   g_signal_handler_disconnect (actions->channel, actions->property_watch_id);
 
   g_slist_foreach (actions->actions, (GFunc) xfce_appfinder_actions_free, NULL);
@@ -197,7 +203,8 @@ xfce_appfinder_actions_sort (gconstpointer a,
 
 
 static void
-xfce_appfinder_actions_load (XfceAppfinderActions *actions)
+xfce_appfinder_actions_load (XfceAppfinderActions *actions,
+                             gboolean              steal)
 {
   XfceAppfinderAction *action;
   gchar                prop[32];
@@ -207,6 +214,16 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
   guint                i;
   gint                 unique_id;
   GPtrArray           *array;
+  GSList              *li, *old_actions = NULL;
+
+  appfinder_return_if_fail (XFCE_IS_APPFINDER_ACTIONS (actions));
+  appfinder_return_if_fail (steal || actions->actions == NULL);
+
+  if (steal)
+    {
+      old_actions = actions->actions;
+      actions->actions = NULL;
+    }
 
   if (xfconf_channel_has_property (actions->channel, "/actions"))
     {
@@ -219,8 +236,26 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
               appfinder_assert (value != NULL);
               unique_id = g_value_get_int (value);
 
+              /* look for the id in the old actions */
+              for (li = old_actions; li != NULL; li = li->next)
+                {
+                  action = li->data;
+                  if (action->unique_id == unique_id)
+                    break;
+                }
+
+              if (li != NULL)
+                {
+                  /* use the old action */
+                  old_actions = g_slist_delete_link (old_actions, li);
+                  actions->actions = g_slist_prepend (actions->actions, action);
+
+                  continue;
+                }
+
+              /* no usable actions was found, create a new one */
               g_snprintf (prop, sizeof (prop), "/actions/action-%d/type", unique_id);
-              type = xfconf_channel_get_int (actions->channel, prop, -1);
+              type = xfconf_channel_get_int (actions->channel, prop, XFCE_APPFINDER_ACTION_TYPE_PREFIX);
               if (type < XFCE_APPFINDER_ACTION_TYPE_PREFIX
                   || type > XFCE_APPFINDER_ACTION_TYPE_REGEX)
                 continue;
@@ -231,21 +266,13 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
               g_snprintf (prop, sizeof (prop), "/actions/action-%d/command", unique_id);
               command = xfconf_channel_get_string (actions->channel, prop, NULL);
 
-              if (pattern != NULL && command != NULL)
-                {
-                  action = g_slice_new0 (XfceAppfinderAction);
-                  action->type = type;
-                  action->unique_id = unique_id;
-                  action->pattern = pattern;
-                  action->command = command;
+              action = g_slice_new0 (XfceAppfinderAction);
+              action->type = type;
+              action->unique_id = unique_id;
+              action->pattern = pattern;
+              action->command = command;
 
-                  actions->actions = g_slist_prepend (actions->actions, action);
-                }
-              else
-                {
-                  g_free (pattern);
-                  g_free (command);
-                }
+              actions->actions = g_slist_prepend (actions->actions, action);
             }
 
           xfconf_array_free (array);
@@ -254,10 +281,15 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
   else
     {
       xfce_appfinder_actions_load_defaults (actions);
-
       xfce_appfinder_actions_save (actions, TRUE);
     }
 
+  if (old_actions != NULL)
+    {
+      g_slist_foreach (old_actions, (GFunc) xfce_appfinder_actions_free, NULL);
+      g_slist_free (old_actions);
+    }
+
   actions->actions = g_slist_sort (actions->actions, xfce_appfinder_actions_sort);
 
   APPFINDER_DEBUG ("loaded %d actions", g_slist_length (actions->actions));
@@ -265,6 +297,23 @@ xfce_appfinder_actions_load (XfceAppfinderActions *actions)
 
 
 
+static gboolean
+xfce_appfinder_actions_reload_idle (gpointer data)
+{
+  xfce_appfinder_actions_load (XFCE_APPFINDER_ACTIONS (data), TRUE);
+  return FALSE;
+}
+
+
+
+static void
+xfce_appfinder_actions_reload_idle_destroyed (gpointer data)
+{
+  XFCE_APPFINDER_ACTIONS (data)->reload_idle_id = 0;
+}
+
+
+
 static void
 xfce_appfinder_actions_save (XfceAppfinderActions *actions,
                              gboolean              save_actions)
@@ -275,8 +324,7 @@ xfce_appfinder_actions_save (XfceAppfinderActions *actions,
   GPtrArray           *array;
   gchar                prop[32];
 
-  if (actions->property_watch_id > 0)
-    g_signal_handler_block (actions->channel, actions->property_watch_id);
+  g_signal_handler_block (actions->channel, actions->property_watch_id);
 
   array = g_ptr_array_new ();
 
@@ -306,12 +354,12 @@ xfce_appfinder_actions_save (XfceAppfinderActions *actions,
 
   xfconf_array_free (array);
 
-  if (actions->property_watch_id > 0)
-    g_signal_handler_unblock (actions->channel, actions->property_watch_id);
+  g_signal_handler_unblock (actions->channel, actions->property_watch_id);
 }
 
 
 
+
 static void
 xfce_appfinder_actions_changed (XfconfChannel        *channel,
                                 const gchar          *prop_name,
@@ -328,7 +376,12 @@ xfce_appfinder_actions_changed (XfconfChannel        *channel,
 
   if (strcmp (prop_name, "/actions") == 0)
     {
-
+      if (actions->reload_idle_id == 0)
+        {
+          actions->reload_idle_id = g_idle_add_full (G_PRIORITY_LOW,
+              xfce_appfinder_actions_reload_idle, actions,
+              xfce_appfinder_actions_reload_idle_destroyed);
+        }
     }
   else if (sscanf (prop_name, "/actions/action-%d/%30s",
                    &unique_id, field) == 2)
@@ -431,7 +484,6 @@ xfce_appfinder_actions_get (void)
     {
       actions = g_object_new (XFCE_TYPE_APPFINDER_ACTIONS, NULL);
       g_object_add_weak_pointer (G_OBJECT (actions), (gpointer) &actions);
-      APPFINDER_DEBUG ("allocate actions");
     }
 
   return actions;
@@ -439,6 +491,33 @@ xfce_appfinder_actions_get (void)
 
 
 
+gint
+xfce_appfinder_actions_get_unique_id (XfceAppfinderActions *actions)
+{
+  static gint          unique_id = 1;
+  GSList              *li;
+  XfceAppfinderAction *action;
+
+  appfinder_return_val_if_fail (XFCE_IS_APPFINDER_ACTIONS (actions), -1);
+
+  for (; unique_id < G_MAXINT; unique_id++)
+    {
+      for (li = actions->actions; li != NULL; li = li->next)
+        {
+          action = li->data;
+          if (action->unique_id == unique_id)
+            break;
+        }
+
+      if (li == NULL)
+        return unique_id;
+    }
+
+  return -1;
+}
+
+
+
 XfceAppfinderActionsResult
 xfce_appfinder_actions_execute (XfceAppfinderActions  *actions,
                                 const gchar           *text,
@@ -464,6 +543,11 @@ xfce_appfinder_actions_execute (XfceAppfinderActions  *actions,
     {
       action = li->data;
 
+      /* skip empty actions */
+      if (!IS_STRING (action->pattern)
+          || !IS_STRING (action->command))
+        continue;
+
       switch (action->type)
         {
         case XFCE_APPFINDER_ACTION_TYPE_PREFIX:
diff --git a/src/appfinder-actions.h b/src/appfinder-actions.h
index 97ceb80..8f62003 100644
--- a/src/appfinder-actions.h
+++ b/src/appfinder-actions.h
@@ -43,14 +43,16 @@ typedef enum
 }
 XfceAppfinderActionsResult;
 
-GType                       xfce_appfinder_actions_get_type    (void) G_GNUC_CONST;
+GType                       xfce_appfinder_actions_get_type      (void) G_GNUC_CONST;
 
-XfceAppfinderActions       *xfce_appfinder_actions_get         (void) G_GNUC_MALLOC;
+XfceAppfinderActions       *xfce_appfinder_actions_get           (void) G_GNUC_MALLOC;
 
-XfceAppfinderActionsResult  xfce_appfinder_actions_execute     (XfceAppfinderActions  *actions,
-                                                                const gchar           *text,
-                                                                GdkScreen             *screen,
-                                                                GError               **error);
+gint                        xfce_appfinder_actions_get_unique_id (XfceAppfinderActions  *actions);
+
+XfceAppfinderActionsResult  xfce_appfinder_actions_execute       (XfceAppfinderActions  *actions,
+                                                                  const gchar           *text,
+                                                                  GdkScreen             *screen,
+                                                                  GError               **error);
 
 G_END_DECLS
 
diff --git a/src/appfinder-preferences.c b/src/appfinder-preferences.c
index e48f424..37a4c6b 100644
--- a/src/appfinder-preferences.c
+++ b/src/appfinder-preferences.c
@@ -32,6 +32,7 @@
 #include <src/appfinder-preferences-ui.h>
 #include <src/appfinder-model.h>
 #include <src/appfinder-private.h>
+#include <src/appfinder-actions.h>
 
 
 
@@ -61,12 +62,14 @@ struct _XfceAppfinderPreferences
 {
   GtkBuilder __parent__;
 
-  GObject       *dialog;
+  GObject          *dialog;
 
-  XfconfChannel *channel;
+  XfconfChannel    *channel;
 
-  gulong         bindings[3];
-  gulong         property_watch_id;
+  GtkTreeSelection *selection;
+
+  gulong            bindings[3];
+  gulong            property_watch_id;
 };
 
 enum
@@ -91,9 +94,8 @@ xfce_appfinder_preferences_class_init (XfceAppfinderPreferencesClass *klass)
 static void
 xfce_appfinder_preferences_init (XfceAppfinderPreferences *preferences)
 {
-  GObject          *object;
-  GtkTreeSelection *selection;
-  GtkTreePath      *path;
+  GObject     *object;
+  GtkTreePath *path;
 
   preferences->channel = xfconf_channel_get ("xfce4-appfinder");
 
@@ -126,17 +128,17 @@ xfce_appfinder_preferences_init (XfceAppfinderPreferences *preferences)
   g_signal_connect (G_OBJECT (object), "clicked",
       G_CALLBACK (xfce_appfinder_preferences_action_remove), preferences);
 
-  xfce_appfinder_preferences_action_populate (preferences);
-
   object = gtk_builder_get_object (GTK_BUILDER (preferences), "actions-treeview");
+  preferences->selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
+
+  xfce_appfinder_preferences_action_populate (preferences);
 
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
-  gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-  g_signal_connect (G_OBJECT (selection), "changed",
+  gtk_tree_selection_set_mode (preferences->selection, GTK_SELECTION_BROWSE);
+  g_signal_connect (G_OBJECT (preferences->selection), "changed",
       G_CALLBACK (xfce_appfinder_preferences_selection_changed), preferences);
 
   path = gtk_tree_path_new_first ();
-  gtk_tree_selection_select_path (selection, path);
+  gtk_tree_selection_select_path (preferences->selection, path);
   gtk_tree_path_free (path);
 
   preferences->property_watch_id =
@@ -182,10 +184,79 @@ xfce_appfinder_preferences_clear_history (XfceAppfinderPreferences *preferences)
 
 
 
+static gboolean
+xfce_appfinder_preferences_action_save_foreach (GtkTreeModel *model,
+                                                GtkTreePath  *path,
+                                                GtkTreeIter  *iter,
+                                                gpointer      data)
+{
+  GPtrArray *array = data;
+  gint       id;
+  GValue    *value;
+
+  gtk_tree_model_get (model, iter, COLUMN_UNIQUE_ID, &id, -1);
+
+  value = g_new0 (GValue, 1);
+  g_value_init (value, G_TYPE_INT);
+  g_value_set_int (value, id);
+  g_ptr_array_add (array, value);
+
+  return FALSE;
+}
+
+
+
+static void
+xfce_appfinder_preferences_action_save (XfceAppfinderPreferences *preferences,
+                                        GtkTreeModel             *model)
+{
+  GPtrArray *array;
+
+  appfinder_return_if_fail (GTK_IS_TREE_MODEL (model));
+  appfinder_return_if_fail (XFCE_IS_APPFINDER_PREFERENCES (preferences));
+
+  g_signal_handler_block (preferences->channel, preferences->property_watch_id);
+
+  array = g_ptr_array_new ();
+  gtk_tree_model_foreach (model, xfce_appfinder_preferences_action_save_foreach, array);
+  xfconf_channel_set_arrayv (preferences->channel, "/actions", array);
+  xfconf_array_free (array);
+
+  g_signal_handler_unblock (preferences->channel, preferences->property_watch_id);
+}
+
+
+
 static void
 xfce_appfinder_preferences_action_add (XfceAppfinderPreferences *preferences)
 {
+  XfceAppfinderActions *actions;
+  gint                  id;
+  GObject              *store;
+  GtkTreeIter           iter;
+  gchar                 prop[32];
+
+  appfinder_return_if_fail (XFCE_IS_APPFINDER_PREFERENCES (preferences));
+
+  /* get an unused id */
+  actions = xfce_appfinder_actions_get ();
+  id = xfce_appfinder_actions_get_unique_id (actions);
+  g_object_unref (G_OBJECT (actions));
 
+  /* make sure property does not exist */
+  g_snprintf (prop, sizeof (prop), "/actions/action-%d", id);
+  xfconf_channel_reset_property (preferences->channel, prop, TRUE);
+
+  /* add new item to store */
+  store = gtk_builder_get_object (GTK_BUILDER (preferences), "actions-store");
+  gtk_list_store_append (GTK_LIST_STORE (store), &iter);
+  gtk_list_store_set (GTK_LIST_STORE (store), &iter, COLUMN_UNIQUE_ID, id, -1);
+
+  /* select item */
+  gtk_tree_selection_select_iter (preferences->selection, &iter);
+
+  /* save new id */
+  xfce_appfinder_preferences_action_save (preferences, GTK_TREE_MODEL (store));
 }
 
 
@@ -194,17 +265,40 @@ static void
 xfce_appfinder_preferences_action_remove (GtkWidget                *button,
                                           XfceAppfinderPreferences *preferences)
 {
-  GObject *object;
+  GtkTreeModel     *model;
+  GtkTreeIter       iter;
+  gchar            *pattern;
+  gint              id;
+  gchar             prop[32];
+
+  appfinder_return_if_fail (GTK_IS_WIDGET (button));
+  appfinder_return_if_fail (XFCE_IS_APPFINDER_PREFERENCES (preferences));
+
+  if (!gtk_tree_selection_get_selected (preferences->selection, &model, &iter))
+    return;
+
+  gtk_tree_model_get (model, &iter,
+                      COLUMN_PATTERN, &pattern,
+                      COLUMN_UNIQUE_ID, &id,
+                      -1);
 
-  object = gtk_builder_get_object (GTK_BUILDER (preferences), "pattern");
   if (xfce_dialog_confirm (GTK_WINDOW (gtk_widget_get_toplevel (button)),
                            GTK_STOCK_DELETE, NULL,
                            _("The custom action will be deleted permanently."),
                            _("Are you sure you want to delete pattern \"%s\"?"),
-                           gtk_entry_get_text (GTK_ENTRY (object))))
+                           pattern))
     {
+      gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
 
+      /* remove data from channel */
+      g_snprintf (prop, sizeof (prop), "/actions/action-%d", id);
+      xfconf_channel_reset_property (preferences->channel, prop, TRUE);
+
+      /* save */
+      xfce_appfinder_preferences_action_save (preferences, model);
     }
+
+  g_free (pattern);
 }
 
 
@@ -273,19 +367,25 @@ xfce_appfinder_preferences_action_changed (XfconfChannel            *channel,
 }
 
 
+
 static void
 xfce_appfinder_preferences_action_populate (XfceAppfinderPreferences *preferences)
 {
   GPtrArray    *array;
-  GObject      *store;
+  GtkTreeModel *store;
   const GValue *value;
   gint          unique_id;
   gchar         prop[32];
   gchar        *pattern, *command;
   guint         i;
+  gint          restore_id = -1;
+  GtkTreeIter   iter;
+
+  APPFINDER_DEBUG ("populate tree model");
+
+  if (gtk_tree_selection_get_selected (preferences->selection, &store, &iter))
+    gtk_tree_model_get (store, &iter, COLUMN_UNIQUE_ID, &restore_id, -1);
 
-  store = gtk_builder_get_object (GTK_BUILDER (preferences), "actions-store");
-  appfinder_assert (GTK_IS_LIST_STORE (store));
   gtk_list_store_clear (GTK_LIST_STORE (store));
 
   array = xfconf_channel_get_arrayv (preferences->channel, "/actions");
@@ -303,11 +403,14 @@ xfce_appfinder_preferences_action_populate (XfceAppfinderPreferences *preference
         g_snprintf (prop, sizeof (prop), "/actions/action-%d/command", unique_id);
         command = xfconf_channel_get_string (preferences->channel, prop, NULL);
 
-        gtk_list_store_insert_with_values (GTK_LIST_STORE (store), NULL, i,
+        gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, i,
                                            COLUMN_UNIQUE_ID, unique_id,
                                            COLUMN_PATTERN, pattern,
                                            -1);
 
+        if (restore_id == unique_id)
+          gtk_tree_selection_select_iter (preferences->selection, &iter);
+
         g_free (pattern);
         g_free (command);
       }
@@ -369,6 +472,13 @@ xfce_appfinder_preferences_selection_changed (GtkTreeSelection         *selectio
       object = gtk_builder_get_object (GTK_BUILDER (preferences), objects[i].name);
       appfinder_return_if_fail (GTK_IS_WIDGET (object));
       gtk_widget_set_sensitive (GTK_WIDGET (object), unique_id != -1);
+
+      /* clear contents */
+      if (GTK_IS_ENTRY (object))
+        gtk_entry_set_text (GTK_ENTRY (object), "");
+      else if (GTK_IS_COMBO_BOX (object))
+        gtk_combo_box_set_active (GTK_COMBO_BOX (object), 0);
+
       if (unique_id > -1)
         {
           g_snprintf (prop, sizeof (prop), "/actions/action-%d/%s", unique_id, objects[i].name);
@@ -376,10 +486,6 @@ xfce_appfinder_preferences_selection_changed (GtkTreeSelection         *selectio
                                                              objects[i].prop_type, object,
                                                              objects[i].prop_name);
         }
-      else if (GTK_IS_ENTRY (object))
-        {
-          gtk_entry_set_text (GTK_ENTRY (object), "");
-        }
     }
 
   object = gtk_builder_get_object (GTK_BUILDER (preferences), "button-remove");
diff --git a/src/appfinder-preferences.glade b/src/appfinder-preferences.glade
index 3eb3b02..3ae52e3 100644
--- a/src/appfinder-preferences.glade
+++ b/src/appfinder-preferences.glade
@@ -231,6 +231,7 @@
                             <property name="headers_clickable">False</property>
                             <property name="enable_search">False</property>
                             <property name="search_column">0</property>
+                            <property name="rules_hint">True</property>
                             <child>
                               <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                                 <property name="title" translatable="yes">Pattern</property>


More information about the Xfce4-commits mailing list