[gimp/metadata-browser] app: set tags for all subdirectories a data file lives in



commit 11dba625626f0aa5f60f5c1499a265679573fbf6
Author: Michael Natterer <mitch gimp org>
Date:   Thu Feb 9 10:02:49 2012 +0100

    app: set tags for all subdirectories a data file lives in
    
    GimpData: add gimp_data_set_folder_tags() and remove the tag logic
    from gimp_data_set_filename(). The function gets the toplevel data
    directory passed so it knows where to stop assigning tags.
    
    GimpDataFactory: when loading data, keep track of the currently
    processed data hierachy's toplevel directory, and pass it to above new
    function. Also make sure obsolete files don't get folder-tagged.

 app/core/gimpdata.c        |  123 +++++++++++++++++++++++++++++++------------
 app/core/gimpdata.h        |    3 +
 app/core/gimpdatafactory.c |   34 +++++++++++--
 3 files changed, 121 insertions(+), 39 deletions(-)
---
diff --git a/app/core/gimpdata.c b/app/core/gimpdata.c
index e9e1ed0..6beefe7 100644
--- a/app/core/gimpdata.c
+++ b/app/core/gimpdata.c
@@ -746,41 +746,6 @@ gimp_data_set_filename (GimpData    *data,
       if (! GIMP_DATA_GET_CLASS (data)->save)
         private->writable = FALSE;
     }
-
-  if (private->filename)
-    {
-      const gchar *tag_blacklist[] = { "brushes",
-                                       "dynamics",
-                                       "patterns",
-                                       "palettes",
-                                       "gradients",
-                                       "tool-presets" };
-
-      gchar   *file_path   = g_path_get_dirname (private->filename);
-      gchar   *tag_text    = g_path_get_basename (file_path);
-      gint     i           = 0;
-      gboolean blacklisted = FALSE;
-
-      for (i = 0; i <  G_N_ELEMENTS (tag_blacklist); i++)
-        {
-          if (! g_strcmp0 (tag_text, tag_blacklist[i]))
-            {
-              blacklisted = TRUE;
-            }
-        }
-
-      if (! blacklisted)
-        {
-          GimpTag *tag = gimp_tag_new (tag_text);
-
-          gimp_tag_set_internal (tag, TRUE);
-          gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
-          g_object_unref (tag);
-        }
-
-      g_free (file_path);
-      g_free (tag_text);
-    }
 }
 
 /**
@@ -874,6 +839,94 @@ gimp_data_get_filename (GimpData *data)
   return private->filename;
 }
 
+static const gchar *tag_blacklist[] = { "brushes",
+                                        "dynamics",
+                                        "patterns",
+                                        "palettes",
+                                        "gradients",
+                                        "tool-presets" };
+
+/**
+ * gimp_data_set_folder_tags:
+ * @data:          a #Gimpdata object.
+ * @top_directory: the top directory of the currently processed data
+ *                 hierarchy, or %NULL if that top directory is
+ *                 currently processed itself
+ *
+ * Sets tags based on all folder names below top_directory. So if the
+ * data's filename is /home/foo/.gimp/brushes/Flowers/Roses/rose.gbr,
+ * it will add "Flowers" and "Roses" tags.
+ *
+ * if the top directory (as passed, or as derived from the data's
+ * filename) does not end with one of the default data directory names
+ * (brushes, patterns etc), its name will be added as tag too.
+ **/
+void
+gimp_data_set_folder_tags (GimpData    *data,
+                           const gchar *top_directory)
+{
+  GimpDataPrivate *private;
+  gchar           *dirname;
+
+  g_return_if_fail (GIMP_IS_DATA (data));
+
+  private = GIMP_DATA_GET_PRIVATE (data);
+
+  if (private->internal)
+    return;
+
+  g_return_if_fail (private->filename != NULL);
+
+  dirname = g_path_get_dirname (private->filename);
+
+  /*  if this data is in a subfolder, walk up the hierarchy and
+   *  set each folder on the way as tag, except the top_directory
+   */
+  if (top_directory)
+    {
+      do
+        {
+          gchar   *basename = g_path_get_basename (dirname);
+          GimpTag *tag      = gimp_tag_new (basename);
+          gchar   *tmp;
+
+          gimp_tag_set_internal (tag, TRUE);
+          gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
+          g_object_unref (tag);
+          g_free (basename);
+
+          tmp = g_path_get_dirname (dirname);
+          g_free (dirname);
+          dirname = tmp;
+        }
+      while (strcmp (dirname, top_directory));
+    }
+
+  if (dirname)
+    {
+      gchar *basename = g_path_get_basename (dirname);
+      gint   i;
+
+      for (i = 0; i <  G_N_ELEMENTS (tag_blacklist); i++)
+        {
+          if (! strcmp (basename, tag_blacklist[i]))
+            break;
+        }
+
+      if (i == G_N_ELEMENTS (tag_blacklist))
+        {
+          GimpTag *tag = gimp_tag_new (basename);
+
+          gimp_tag_set_internal (tag, TRUE);
+          gimp_tagged_add_tag (GIMP_TAGGED (data), tag);
+          g_object_unref (tag);
+        }
+
+      g_free (basename);
+      g_free (dirname);
+    }
+}
+
 const gchar *
 gimp_data_get_mime_type (GimpData *data)
 {
diff --git a/app/core/gimpdata.h b/app/core/gimpdata.h
index 9b808ae..e8c87cd 100644
--- a/app/core/gimpdata.h
+++ b/app/core/gimpdata.h
@@ -91,6 +91,9 @@ void          gimp_data_create_filename  (GimpData     *data,
                                           const gchar  *dest_dir);
 const gchar * gimp_data_get_filename     (GimpData     *data);
 
+void          gimp_data_set_folder_tags  (GimpData     *data,
+                                          const gchar  *top_directory);
+
 const gchar * gimp_data_get_mime_type    (GimpData     *data);
 
 gboolean      gimp_data_is_writable      (GimpData     *data);
diff --git a/app/core/gimpdatafactory.c b/app/core/gimpdatafactory.c
index ae1668a..4f8e1e5 100644
--- a/app/core/gimpdatafactory.c
+++ b/app/core/gimpdatafactory.c
@@ -309,6 +309,7 @@ typedef struct
   GimpDataFactory *factory;
   GimpContext     *context;
   GHashTable      *cache;
+  const gchar     *top_directory;
 } GimpDataLoadContext;
 
 static void
@@ -798,6 +799,19 @@ gimp_data_factory_load_data_recursive (const GimpDatafileData *file_data,
                                        gpointer                data)
 {
   GimpDataLoadContext *context = data;
+  gboolean             top_set = FALSE;
+
+  /*  When processing subdirectories, set the top_directory if it's
+   *  unset. This way me make sure gimp_data_set_folder_tags()'
+   *  calling convention is honored: pass NULL when processing the
+   *  toplevel directory itself, and pass the toplevel directory when
+   *  processing any folder inside.
+   */
+  if (! context->top_directory)
+    {
+      context->top_directory = file_data->dirname;
+      top_set = TRUE;
+    }
 
   gimp_datafiles_read_directories (file_data->filename, G_FILE_TEST_IS_REGULAR,
                                    gimp_data_factory_load_data, context);
@@ -805,6 +819,12 @@ gimp_data_factory_load_data_recursive (const GimpDatafileData *file_data,
   gimp_datafiles_read_directories (file_data->filename, G_FILE_TEST_IS_DIR,
                                    gimp_data_factory_load_data_recursive,
                                    context);
+
+  /*  Unset, the string is only valid within this function, and will
+   *  be set again for the next subdirectory.
+   */
+  if (top_set)
+    context->top_directory = NULL;
 }
 
 static void
@@ -893,11 +913,17 @@ gimp_data_factory_load_data (const GimpDatafileData *file_data,
           gimp_data_clean (data);
 
           if (obsolete)
-            gimp_container_add (factory->priv->container_obsolete,
-                                GIMP_OBJECT (data));
+            {
+              gimp_container_add (factory->priv->container_obsolete,
+                                  GIMP_OBJECT (data));
+            }
           else
-            gimp_container_add (factory->priv->container,
-                                GIMP_OBJECT (data));
+            {
+              gimp_data_set_folder_tags (data, context->top_directory);
+
+              gimp_container_add (factory->priv->container,
+                                  GIMP_OBJECT (data));
+            }
 
           g_object_unref (data);
         }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]