[Xfce4-commits] <thunar:jannis/file-menu-custom-actions> Generate persistent unique IDs and names for custom actions.

Jannis Pohlmann noreply at xfce.org
Tue Nov 8 14:40:01 CET 2011


Updating branch refs/heads/jannis/file-menu-custom-actions
         to d99e85d67d27ece202c0a79a0c916d21558a9e61 (commit)
       from 0edbd00ac4322efcf3d6eb155be8c3961a804707 (commit)

commit d99e85d67d27ece202c0a79a0c916d21558a9e61
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Tue Nov 8 14:34:51 2011 +0100

    Generate persistent unique IDs and names for custom actions.
    
    This adds an optional <unique-id> element to the <action> element in
    uca.xml. When loading the UCA model from uca.xml, we check for this
    element in the parser. If it is not given, we generate a new ID with the
    following signature:
    
      <current_time.tv_sec>.<current_time.tv_usec>-<static counter value>
    
    After parsing we check if we have generated new IDs and, if so,
    immediately save the model back to the uca.xml file. This part is a bit
    of a hack but it will be a no-brainer once we've switched to xfconf, I
    think.
    
    The ThunarUcaEditor is extended so that it generates a unique ID for new
    items with the same signature as above. It does not overwrite IDs of
    existing custom actions.
    
    Together this allows for a persistent association of custom actions with
    keyboard shortcuts.

 plugins/thunar-uca/thunar-uca-editor.c   |   41 ++++++++++
 plugins/thunar-uca/thunar-uca-model.c    |  123 +++++++++++++++++++++++++-----
 plugins/thunar-uca/thunar-uca-model.h    |    5 +
 plugins/thunar-uca/thunar-uca-provider.c |   10 ++-
 plugins/thunar-uca/uca.xml.in            |    4 +-
 5 files changed, 159 insertions(+), 24 deletions(-)

diff --git a/plugins/thunar-uca/thunar-uca-editor.c b/plugins/thunar-uca/thunar-uca-editor.c
index 00add99..fa1c9f9 100644
--- a/plugins/thunar-uca/thunar-uca-editor.c
+++ b/plugins/thunar-uca/thunar-uca-editor.c
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2007 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2011 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -41,6 +42,9 @@ static void           thunar_uca_editor_set_icon_name   (ThunarUcaEditor
 static ThunarUcaTypes thunar_uca_editor_get_types       (const ThunarUcaEditor  *uca_editor);
 static void           thunar_uca_editor_set_types       (ThunarUcaEditor        *uca_editor,
                                                          ThunarUcaTypes          types);
+static const gchar   *thunar_uca_editor_get_unique_id   (const ThunarUcaEditor  *uca_editor);
+static void           thunar_uca_editor_set_unique_id   (ThunarUcaEditor        *uca_editor,
+                                                         const gchar            *unique_id);
 static void           thunar_uca_editor_command_clicked (ThunarUcaEditor        *uca_editor);
 static void           thunar_uca_editor_icon_clicked    (ThunarUcaEditor        *uca_editor);
 
@@ -101,6 +105,7 @@ thunar_uca_editor_init (ThunarUcaEditor *uca_editor)
   GtkWidget      *table;
   GtkWidget      *hbox;
   GtkWidget      *vbox;
+  gchar          *unique_id;
 
   /* configure the dialog properties */
   gtk_dialog_add_button (GTK_DIALOG (uca_editor), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
@@ -454,6 +459,11 @@ thunar_uca_editor_init (ThunarUcaEditor *uca_editor)
   gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.0f);
   gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
   gtk_widget_show (label);
+
+  /* set a unique ID for new items. this will be overridden by existing items */
+  unique_id = thunar_uca_model_get_unique_id ();
+  thunar_uca_editor_set_unique_id (uca_editor, unique_id);
+  g_free (unique_id);
 }
 
 
@@ -751,6 +761,30 @@ thunar_uca_editor_set_types (ThunarUcaEditor *uca_editor,
 
 
 
+static const gchar*
+thunar_uca_editor_get_unique_id (const ThunarUcaEditor *uca_editor)
+{
+  g_return_val_if_fail (THUNAR_UCA_IS_EDITOR (uca_editor), NULL);
+  return g_object_get_data (G_OBJECT (uca_editor->icon_button), "thunar-uca-unique-id");
+}
+
+
+
+static void
+thunar_uca_editor_set_unique_id (ThunarUcaEditor *uca_editor,
+                                 const gchar     *unique_id)
+{
+  g_return_if_fail (THUNAR_UCA_IS_EDITOR (uca_editor));
+
+  /* remember the unique ID for the item */
+  g_object_set_data_full (G_OBJECT (uca_editor->icon_button),
+                          "thunar-uca-unique-id",
+                          g_strdup (unique_id),
+                          g_free);
+}
+
+
+
 /**
  * thunar_uca_editor_load:
  * @uca_editor  : a #ThunarUcaEditor.
@@ -771,6 +805,7 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
   gchar         *command;
   gchar         *icon;
   gchar         *name;
+  gchar         *unique_id;
   gboolean       startup_notify;
 
   g_return_if_fail (THUNAR_UCA_IS_EDITOR (uca_editor));
@@ -785,6 +820,7 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
                       THUNAR_UCA_MODEL_COLUMN_TYPES, &types,
                       THUNAR_UCA_MODEL_COLUMN_ICON, &icon,
                       THUNAR_UCA_MODEL_COLUMN_NAME, &name,
+                      THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID, &unique_id,
                       THUNAR_UCA_MODEL_COLUMN_STARTUP_NOTIFY, &startup_notify,
                       -1);
 
@@ -794,6 +830,9 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
   /* setup the new icon */
   thunar_uca_editor_set_icon_name (uca_editor, icon);
 
+  /* setup the unique ID */
+  thunar_uca_editor_set_unique_id (uca_editor, unique_id);
+
   /* apply the new values */
   gtk_entry_set_text (GTK_ENTRY (uca_editor->description_entry), (description != NULL) ? description : "");
   gtk_entry_set_text (GTK_ENTRY (uca_editor->patterns_entry), (patterns != NULL) ? patterns : "");
@@ -806,6 +845,7 @@ thunar_uca_editor_load (ThunarUcaEditor *uca_editor,
   g_free (patterns);
   g_free (command);
   g_free (icon);
+  g_free (unique_id);
   g_free (name);
 }
 
@@ -831,6 +871,7 @@ thunar_uca_editor_save (ThunarUcaEditor *uca_editor,
 
   thunar_uca_model_update (uca_model, iter,
                            gtk_entry_get_text (GTK_ENTRY (uca_editor->name_entry)),
+                           thunar_uca_editor_get_unique_id (uca_editor),
                            gtk_entry_get_text (GTK_ENTRY (uca_editor->description_entry)),
                            thunar_uca_editor_get_icon_name (uca_editor),
                            gtk_entry_get_text (GTK_ENTRY (uca_editor->command_entry)),
diff --git a/plugins/thunar-uca/thunar-uca-model.c b/plugins/thunar-uca/thunar-uca-model.c
index 1f54bb1..ab91460 100644
--- a/plugins/thunar-uca/thunar-uca-model.c
+++ b/plugins/thunar-uca/thunar-uca-model.c
@@ -1,7 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2011 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -35,6 +35,9 @@
 #ifdef HAVE_PATHS_H
 #include <paths.h>
 #endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
@@ -73,6 +76,7 @@ typedef enum
   PARSER_ACTION,
   PARSER_ICON,
   PARSER_NAME,
+  PARSER_UNIQUE_ID,
   PARSER_COMMAND,
   PARSER_STARTUP_NOTIFY,
   PARSER_PATTERNS,
@@ -120,6 +124,7 @@ static gboolean           thunar_uca_model_iter_parent      (GtkTreeModel
                                                              GtkTreeIter          *child);
 static gboolean           thunar_uca_model_load_from_file   (ThunarUcaModel       *uca_model,
                                                              const gchar          *filename,
+                                                             gboolean             *ids_generated,
                                                              GError              **error);
 static void               thunar_uca_model_item_reset       (ThunarUcaModelItem   *item);
 static void               thunar_uca_model_item_free        (ThunarUcaModelItem   *item);
@@ -159,6 +164,7 @@ struct _ThunarUcaModel
 struct _ThunarUcaModelItem
 {
   gchar         *name;
+  gchar         *unique_id;
   gchar         *description;
   gchar         *icon;
   gchar         *command;
@@ -180,6 +186,7 @@ typedef struct
   GString        *name;
   gboolean        name_use;
   guint           name_match;
+  GString        *unique_id;
   GString        *icon;
   GString        *command;
   GString        *patterns;
@@ -188,6 +195,7 @@ typedef struct
   gboolean        description_use;
   guint           description_match;
   ThunarUcaTypes  types;
+  gboolean        ids_generated;
 } Parser;
 
 
@@ -244,8 +252,9 @@ thunar_uca_model_tree_model_init (GtkTreeModelIface *iface)
 static void
 thunar_uca_model_init (ThunarUcaModel *uca_model)
 {
-  GError *error = NULL;
-  gchar  *filename;
+  gboolean ids_generated = FALSE;
+  GError  *error = NULL;
+  gchar   *filename;
 
   /* allocate a new icon factory for our action icons
    * and add it to the default icon factories
@@ -261,12 +270,16 @@ thunar_uca_model_init (ThunarUcaModel *uca_model)
   if (G_LIKELY (filename != NULL))
     {
       /* try to load the file */
-      if (!thunar_uca_model_load_from_file (uca_model, filename, &error))
+      if (!thunar_uca_model_load_from_file (uca_model, filename, &ids_generated, &error))
         {
           g_warning ("Failed to load `%s': %s", filename, error->message);
           g_error_free (error);
         }
 
+      /* save the model back to the file immediately to make unique IDs persistent */
+      if (ids_generated)
+        thunar_uca_model_save (uca_model, NULL);
+
       /* release the filename */
       g_free (filename);
     }
@@ -317,6 +330,9 @@ thunar_uca_model_get_column_type (GtkTreeModel *tree_model,
     case THUNAR_UCA_MODEL_COLUMN_NAME:
       return G_TYPE_STRING;
 
+    case THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID:
+      return G_TYPE_STRING;
+
     case THUNAR_UCA_MODEL_COLUMN_DESCRIPTION:
       return G_TYPE_STRING;
 
@@ -406,6 +422,10 @@ thunar_uca_model_get_value (GtkTreeModel *tree_model,
       g_value_set_static_string (value, item->name ? item->name : "");
       break;
 
+    case THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID:
+      g_value_set_static_string (value, item->unique_id ? item->unique_id : "");
+      break;
+
     case THUNAR_UCA_MODEL_COLUMN_DESCRIPTION:
       g_value_set_static_string (value, item->description);
       break;
@@ -534,6 +554,7 @@ thunar_uca_model_iter_parent (GtkTreeModel *tree_model,
 static gboolean
 thunar_uca_model_load_from_file (ThunarUcaModel *uca_model,
                                  const gchar    *filename,
+                                 gboolean       *ids_generated,
                                  GError        **error)
 {
   GMarkupParseContext *context;
@@ -543,8 +564,8 @@ thunar_uca_model_load_from_file (ThunarUcaModel *uca_model,
   gsize                content_len;
 
   g_return_val_if_fail (THUNAR_UCA_IS_MODEL (uca_model), FALSE);
-  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
   g_return_val_if_fail (g_path_is_absolute (filename), FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
   /* read the file info memory */
   if (!g_file_get_contents (filename, &content, &content_len, error))
@@ -555,11 +576,13 @@ thunar_uca_model_load_from_file (ThunarUcaModel *uca_model,
   parser.model = uca_model;
   parser.locale = g_strdup (setlocale (LC_MESSAGES, NULL));
   parser.name = g_string_new (NULL);
+  parser.unique_id = g_string_new (NULL);
   parser.icon = g_string_new (NULL);
   parser.command = g_string_new (NULL);
   parser.patterns = g_string_new (NULL);
   parser.description = g_string_new (NULL);
   parser.startup_notify = FALSE;
+  parser.ids_generated = FALSE;
   xfce_stack_push (parser.stack, PARSER_START);
 
   /* parse the file */
@@ -567,12 +590,17 @@ thunar_uca_model_load_from_file (ThunarUcaModel *uca_model,
   succeed = g_markup_parse_context_parse (context, content, content_len, error)
          && g_markup_parse_context_end_parse (context, error);
 
+  /* tell the caller whether or not we generated new IDs */
+  if (ids_generated != NULL)
+    *ids_generated = parser.ids_generated;
+
   /* cleanup */
   g_markup_parse_context_free (context);
   g_string_free (parser.description, TRUE);
   g_string_free (parser.patterns, TRUE);
   g_string_free (parser.command, TRUE);
   g_string_free (parser.icon, TRUE);
+  g_string_free (parser.unique_id, TRUE);
   g_string_free (parser.name, TRUE);
   g_free (parser.locale);
   xfce_stack_free (parser.stack);
@@ -637,6 +665,7 @@ start_element_handler (GMarkupParseContext *context,
           parser->startup_notify = FALSE;
           g_string_truncate (parser->icon, 0);
           g_string_truncate (parser->name, 0);
+          g_string_truncate (parser->unique_id, 0);
           g_string_truncate (parser->command, 0);
           g_string_truncate (parser->patterns, 0);
           g_string_truncate (parser->description, 0);
@@ -676,6 +705,11 @@ start_element_handler (GMarkupParseContext *context,
 
           xfce_stack_push (parser->stack, PARSER_NAME);
         }
+      else if (strcmp (element_name, "unique-id") == 0)
+        {
+          g_string_truncate (parser->unique_id, 0);
+          xfce_stack_push (parser->stack, PARSER_UNIQUE_ID);
+        }
       else if (strcmp (element_name, "icon") == 0)
         {
           g_string_truncate (parser->icon, 0);
@@ -780,6 +814,7 @@ end_element_handler (GMarkupParseContext *context,
 {
   GtkTreeIter iter;
   Parser     *parser = user_data;
+  gchar      *unique_id;
 
   switch (xfce_stack_top (parser->stack))
     {
@@ -796,9 +831,21 @@ end_element_handler (GMarkupParseContext *context,
     case PARSER_ACTION:
       if (strcmp (element_name, "action") == 0)
         {
+          /* generate a unique ID if we have none yet */
+          if (parser->unique_id->len == 0)
+            {
+              unique_id = thunar_uca_model_get_unique_id ();
+              g_string_append (parser->unique_id, unique_id);
+              g_free (unique_id);
+
+              /* remember that we generated at least one new ID */
+              parser->ids_generated = TRUE;
+            }
+
           thunar_uca_model_append (parser->model, &iter);
           thunar_uca_model_update (parser->model, &iter,
                                    parser->name->str,
+                                   parser->unique_id->str,
                                    parser->description->str,
                                    parser->icon->str,
                                    parser->command->str,
@@ -815,6 +862,11 @@ end_element_handler (GMarkupParseContext *context,
         goto unknown_element;
       break;
 
+    case PARSER_UNIQUE_ID:
+      if (strcmp (element_name, "unique-id") != 0)
+        goto unknown_element;
+      break;
+
     case PARSER_ICON:
       if (strcmp (element_name, "icon") != 0)
         goto unknown_element;
@@ -900,6 +952,10 @@ text_handler (GMarkupParseContext *context,
         g_string_append_len (parser->name, text, text_len);
       break;
 
+    case PARSER_UNIQUE_ID:
+      g_string_append_len (parser->unique_id, text, text_len);
+      break;
+
     case PARSER_ICON:
       g_string_append_len (parser->icon, text, text_len);
       break;
@@ -1224,6 +1280,7 @@ thunar_uca_model_remove (ThunarUcaModel *uca_model,
  * @uca_model          : a #ThunarUcaModel.
  * @iter               : the #GtkTreeIter of the item to update.
  * @name               : the name of the item.
+ * @unique_id          : a unique ID for the item.
  * @description        : the description of the item.
  * @icon               : the icon for the item.
  * @command            : the command of the item.
@@ -1236,6 +1293,7 @@ void
 thunar_uca_model_update (ThunarUcaModel *uca_model,
                          GtkTreeIter    *iter,
                          const gchar    *name,
+                         const gchar    *unique_id,
                          const gchar    *description,
                          const gchar    *icon,
                          const gchar    *command,
@@ -1257,6 +1315,8 @@ thunar_uca_model_update (ThunarUcaModel *uca_model,
   /* setup the new item values */
   if (G_LIKELY (name != NULL && *name != '\0'))
     item->name = g_strdup (name);
+  if (G_LIKELY (unique_id != NULL && *unique_id != '\0'))
+    item->unique_id = g_strdup (unique_id);
   if (G_LIKELY (icon != NULL && *icon != '\0'))
     item->icon = g_strdup (icon);
   if (G_LIKELY (command != NULL && *command != '\0'))
@@ -1339,19 +1399,19 @@ thunar_uca_model_save (ThunarUcaModel *uca_model,
   fp = fdopen (fd, "w");
 
   /* write the header */
-  fprintf (fp, "<?xml encoding=\"UTF-8\" version=\"1.0\"?>\n<actions>");
+  fprintf (fp, "<?xml encoding=\"UTF-8\" version=\"1.0\"?>\n<actions>\n");
 
   /* write the model items */
   for (lp = uca_model->items; lp != NULL; lp = lp->next)
     {
       item = (ThunarUcaModelItem *) lp->data;
-      fprintf (fp, "<action>");
+      fprintf (fp, "<action>\n");
       patterns = g_strjoinv (";", item->patterns);
-      escaped = g_markup_printf_escaped ("<icon>%s</icon>"
-                                         "<name>%s</name>"
-                                         "<command>%s</command>"
-                                         "<description>%s</description>"
-                                         "<patterns>%s</patterns>",
+      escaped = g_markup_printf_escaped ("  <icon>%s</icon>\n"
+                                         "  <name>%s</name>\n"
+                                         "  <command>%s</command>\n"
+                                         "  <description>%s</description>\n"
+                                         "  <patterns>%s</patterns>\n",
                                          (item->icon != NULL) ? item->icon : "",
                                          (item->name != NULL) ? item->name : "",
                                          (item->command != NULL) ? item->command : "",
@@ -1360,21 +1420,28 @@ thunar_uca_model_save (ThunarUcaModel *uca_model,
       fprintf (fp, "%s", escaped);
       g_free (patterns);
       g_free (escaped);
+      if (item->unique_id != NULL)
+        {
+          escaped = g_markup_printf_escaped ("  <unique-id>%s</unique-id>\n",
+                                             item->unique_id);
+          fprintf (fp, "%s", escaped);
+          g_free (escaped);
+        }
       if (item->startup_notify)
-        fprintf (fp, "<startup-notify/>");
+        fprintf (fp, "  <startup-notify/>\n");
       if ((item->types & THUNAR_UCA_TYPE_DIRECTORIES) != 0)
-        fprintf (fp, "<directories/>");
+        fprintf (fp, "  <directories/>\n");
       if ((item->types & THUNAR_UCA_TYPE_AUDIO_FILES) != 0)
-        fprintf (fp, "<audio-files/>");
+        fprintf (fp, "  <audio-files/>\n");
       if ((item->types & THUNAR_UCA_TYPE_IMAGE_FILES) != 0)
-        fprintf (fp, "<image-files/>");
+        fprintf (fp, "  <image-files/>\n");
       if ((item->types & THUNAR_UCA_TYPE_OTHER_FILES) != 0)
-        fprintf (fp, "<other-files/>");
+        fprintf (fp, "  <other-files/>\n");
       if ((item->types & THUNAR_UCA_TYPE_TEXT_FILES) != 0)
-        fprintf (fp, "<text-files/>");
+        fprintf (fp, "  <text-files/>\n");
       if ((item->types & THUNAR_UCA_TYPE_VIDEO_FILES) != 0)
-        fprintf (fp, "<video-files/>");
-      fprintf (fp, "</action>");
+        fprintf (fp, "  <video-files/>\n");
+      fprintf (fp, "</action>\n");
     }
 
   /* write the footer and close the tmp file */
@@ -1608,3 +1675,19 @@ error:
 }
 
 
+
+gchar *
+thunar_uca_model_get_unique_id (void)
+{
+  static gint counter = 0;
+  GTimeVal    current_time = { 0, 0 };
+
+  /* get the current timestamp */
+  g_get_current_time (&current_time);
+
+  /* produce a "<timestamp>-<counter>" string */
+  return g_strdup_printf ("%ld.%ld-%d",
+                          current_time.tv_sec,
+                          current_time.tv_usec,
+                          ++counter);
+}
diff --git a/plugins/thunar-uca/thunar-uca-model.h b/plugins/thunar-uca/thunar-uca-model.h
index 9bef6df..b57fdb7 100644
--- a/plugins/thunar-uca/thunar-uca-model.h
+++ b/plugins/thunar-uca/thunar-uca-model.h
@@ -1,6 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2011 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -38,6 +39,7 @@ typedef struct _ThunarUcaModel      ThunarUcaModel;
 typedef enum
 {
   THUNAR_UCA_MODEL_COLUMN_NAME,
+  THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID,
   THUNAR_UCA_MODEL_COLUMN_DESCRIPTION,
   THUNAR_UCA_MODEL_COLUMN_ICON,
   THUNAR_UCA_MODEL_COLUMN_COMMAND,
@@ -88,6 +90,7 @@ void            thunar_uca_model_remove         (ThunarUcaModel         *uca_mod
 void            thunar_uca_model_update         (ThunarUcaModel         *uca_model,
                                                  GtkTreeIter            *iter,
                                                  const gchar            *name,
+                                                 const gchar            *unique_id,
                                                  const gchar            *description,
                                                  const gchar            *icon,
                                                  const gchar            *command,
@@ -105,6 +108,8 @@ gboolean        thunar_uca_model_parse_argv     (ThunarUcaModel         *uca_mod
                                                  gchar                ***argvp,
                                                  GError                **error);
 
+gchar          *thunar_uca_model_get_unique_id  (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
 G_END_DECLS;
 
 #endif /* !__THUNAR_UCA_MODEL_H__ */
diff --git a/plugins/thunar-uca/thunar-uca-provider.c b/plugins/thunar-uca/thunar-uca-provider.c
index 674af2f..edad6b9 100644
--- a/plugins/thunar-uca/thunar-uca-provider.c
+++ b/plugins/thunar-uca/thunar-uca-provider.c
@@ -1,7 +1,7 @@
 /* $Id$ */
 /*-
  * Copyright (c) 2005-2006 Benedikt Meurer <benny at xfce.org>
- * Copyright (c) 2009 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2009-2011 Jannis Pohlmann <jannis at xfce.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,6 +28,8 @@
 #include <libxfce4util/libxfce4util.h>
 #include <libxfce4ui/libxfce4ui.h>
 
+#include <exo/exo.h>
+
 #include <thunar-uca/thunar-uca-chooser.h>
 #include <thunar-uca/thunar-uca-context.h>
 #include <thunar-uca/thunar-uca-model.h>
@@ -201,6 +203,7 @@ thunar_uca_provider_get_file_actions (ThunarxMenuProvider *menu_provider,
   gchar               *tooltip;
   gchar               *label;
   gchar               *name;
+  gchar               *unique_id;
 
   paths = thunar_uca_model_match (uca_provider->model, files);
   for (lp = g_list_last (paths); lp != NULL; lp = lp->prev)
@@ -211,13 +214,13 @@ thunar_uca_provider_get_file_actions (ThunarxMenuProvider *menu_provider,
           /* determine the label, tooltip and stock-id for the item */
           gtk_tree_model_get (GTK_TREE_MODEL (uca_provider->model), &iter,
                               THUNAR_UCA_MODEL_COLUMN_NAME, &label,
+                              THUNAR_UCA_MODEL_COLUMN_UNIQUE_ID, &unique_id,
                               THUNAR_UCA_MODEL_COLUMN_ICON, &icon_name,
                               THUNAR_UCA_MODEL_COLUMN_DESCRIPTION, &tooltip,
                               -1);
 
           /* generate a unique action name */
-          /* FIXME this name is persistent only if actions are not re-ordered in the GUI */
-          name = g_strdup_printf ("ThunarUca::action-%d", ++uca_provider->last_action_id);
+          name = g_strdup_printf ("ThunarUca::action-%s", unique_id);
 
           /* create the new action with the given parameters */
           action = gtk_action_new (name, label, tooltip, NULL);
@@ -251,6 +254,7 @@ thunar_uca_provider_get_file_actions (ThunarxMenuProvider *menu_provider,
           g_free (icon_name);
           g_free (tooltip);
           g_free (label);
+          g_free (unique_id);
           g_free (name);
         }
 
diff --git a/plugins/thunar-uca/uca.xml.in b/plugins/thunar-uca/uca.xml.in
index a851407..fbbd6dd 100644
--- a/plugins/thunar-uca/uca.xml.in
+++ b/plugins/thunar-uca/uca.xml.in
@@ -2,7 +2,7 @@
 <!DOCTYPE actions [
   <!ELEMENT actions (action)+>
 
-  <!ELEMENT action (icon|patterns|name|command|description|directories|audio-files|image-files|other-files|text-files|video-files)*>
+  <!ELEMENT action (icon|patterns|name|unique-id?|command|description|directories|audio-files|image-files|other-files|text-files|video-files)*>
 
   <!ELEMENT icon (#PCDATA)>
   <!ELEMENT command (#PCDATA)>
@@ -11,6 +11,8 @@
   <!ELEMENT name (#PCDATA)>
   <!ATTLIST name xml:lang CDATA #IMPLIED>
 
+  <!ELEMENT unique-id (#PCDATA)>
+
   <!ELEMENT description (#PCDATA)>
   <!ATTLIST description xml:lang CDATA #IMPLIED>
 


More information about the Xfce4-commits mailing list