[gthumb] Bug 581183 – Show categories with images



commit 4e279a2c68c9039b54190bb8ac8cbf23723db897
Author: Marc Pavot <marc pavot gmail com>
Date:   Mon May 4 19:30:29 2009 -0400

    Bug 581183 â?? Show categories with images
---
 data/glade/gthumb_preferences.glade |   19 +++
 data/gthumb.schemas.in              |   13 ++
 libgthumb/comments.c                |   58 +++++++--
 libgthumb/comments.h                |    2 +
 libgthumb/file-data.c               |    7 +
 libgthumb/file-data.h               |    1 +
 libgthumb/gth-file-list.c           |    2 +
 libgthumb/gth-file-view-list.c      |   68 +++++++++-
 libgthumb/gth-file-view-thumbs.c    |   30 ++++-
 libgthumb/gth-file-view.c           |   46 ++++++--
 libgthumb/gth-file-view.h           |   28 +++--
 libgthumb/gth-image-list.c          |  232 ++++++++++++++++++++++++++++-------
 libgthumb/gth-image-list.h          |   16 ++-
 libgthumb/preferences.c             |   21 ++--
 libgthumb/preferences.h             |    3 +-
 libgthumb/typedefs.h                |   14 +--
 src/dlg-photo-importer.c            |    1 +
 src/dlg-preferences.c               |   15 +++
 src/gth-browser.c                   |   24 ++---
 19 files changed, 474 insertions(+), 126 deletions(-)

diff --git a/data/glade/gthumb_preferences.glade b/data/glade/gthumb_preferences.glade
index 35d7e54..69c16e6 100644
--- a/data/glade/gthumb_preferences.glade
+++ b/data/glade/gthumb_preferences.glade
@@ -961,6 +961,25 @@
 			      <property name="fill">False</property>
 			    </packing>
 			  </child>
+
+			  <child>
+			    <widget class="GtkCheckButton" id="toggle_show_categories">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="label" translatable="yes">C_ategories</property>
+			      <property name="use_underline">True</property>
+			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
+			      <property name="active">False</property>
+			      <property name="inconsistent">False</property>
+			      <property name="draw_indicator">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
 			</widget>
 			<packing>
 			  <property name="padding">0</property>
diff --git a/data/gthumb.schemas.in b/data/gthumb.schemas.in
index 11f6838..cf02d24 100644
--- a/data/gthumb.schemas.in
+++ b/data/gthumb.schemas.in
@@ -150,6 +150,19 @@
       </schema>
 
       <schema>
+	<key>/schemas/apps/gthumb/browser/show_categories</key>
+	<applyto>/apps/gthumb/browser/show_categories</applyto>
+	<owner>gthumb</owner>
+	<type>bool</type>
+	<default>true</default>
+	<locale name="C">
+	  <short></short>
+	  <long>
+	  </long>
+	</locale>
+      </schema>
+
+      <schema>
 	<key>/schemas/apps/gthumb/browser/show_thumbnails</key>
 	<applyto>/apps/gthumb/browser/show_thumbnails</applyto>
 	<owner>gthumb</owner>
diff --git a/libgthumb/comments.c b/libgthumb/comments.c
index 302a718..8282824 100644
--- a/libgthumb/comments.c
+++ b/libgthumb/comments.c
@@ -334,12 +334,12 @@ get_keywords (CommentData *data,
 static gboolean
 has_non_whitespace_comment (const char *text_in)
 {
-        gchar *pos;
+        const char *pos;
 
         if (text_in == NULL)
                 return FALSE;
 
-        for (pos = (char *) text_in; *pos != 0; pos = g_utf8_next_char (pos)) {
+        for (pos = text_in; *pos != 0; pos = g_utf8_next_char (pos)) {
                 gunichar ch = g_utf8_get_char (pos);
                 if (!g_unichar_isspace (ch))
                         return TRUE;
@@ -382,12 +382,10 @@ load_comment_from_metadata (const char *uri)
                         keywords_v = g_strsplit (tmp->data, ",", 0);
 
                         for (i = 0; keywords_v[i]; ++i) {
-                                if (has_non_whitespace_comment (keywords_v[i])) {
-                                        data->keywords = g_slist_append (data->keywords, g_strdup (keywords_v[i]));
+                                comment_data_add_keyword (data, keywords_v[i]);
                         }
+                        g_strfreev (keywords_v);
                 }
-		g_strfreev (keywords_v);
-	}
         }
         g_slist_foreach (metadata_list, (GFunc) g_free, NULL);
         g_slist_free (metadata_list);
@@ -777,15 +775,22 @@ comment_data_add_keyword (CommentData *data,
 			  const char  *keyword)
 {
         GSList *found;
+        gchar *formated_keyword;
 
 	if (keyword == NULL)
 		return;
 
-        found = g_slist_find_custom (data->keywords, keyword, (GCompareFunc) g_utf8_collate);
-	if (found)
-			return;
+        if (!has_non_whitespace_comment (keyword))
+                return;
+
+        /* Removes leading and trailing whitespaces */
+        formated_keyword = g_strstrip (g_strdup (keyword));
 
-        data->keywords = g_slist_append (data->keywords, g_strdup (keyword));
+        found = g_slist_find_custom (data->keywords, formated_keyword, (GCompareFunc) g_utf8_collate);
+        if (!found)
+                data->keywords = g_slist_append (data->keywords, g_strdup (formated_keyword));
+
+        g_free (formated_keyword);
 }
 
 
@@ -991,6 +996,32 @@ _get_comment_as_string_common (CommentData *data,
 }
 
 
+/* Note: separators are not escaped */
+static char *
+_get_categories_as_string_common (CommentData *data,
+                                  char        *sep)
+{
+        GString *categories;
+        GSList  *tmp;
+
+	if (data == NULL)
+		return NULL;
+
+        if (data->keywords == NULL)
+                return NULL;
+
+        categories = g_string_new ("");
+
+        for (tmp = data->keywords; tmp; tmp = g_slist_next (tmp)) {
+                g_string_append (categories, tmp->data);
+                if (g_slist_next (tmp))
+                        g_string_append (categories, sep);
+        }
+
+        return g_string_free (categories, FALSE);
+}
+
+
 char *
 comments_get_comment_as_string (CommentData *data,
 				char        *sep1,
@@ -999,3 +1030,10 @@ comments_get_comment_as_string (CommentData *data,
 	return _get_comment_as_string_common (data, sep1, sep2, FALSE);
 }
 
+char *
+comments_get_categories_as_string (CommentData *data,
+                                   char        *sep)
+{
+	return _get_categories_as_string_common (data, sep);
+}
+
diff --git a/libgthumb/comments.h b/libgthumb/comments.h
index ff64cb1..bac07ab 100644
--- a/libgthumb/comments.h
+++ b/libgthumb/comments.h
@@ -73,6 +73,8 @@ void           comments_save_categories            (const char  *uri,
 char *         comments_get_comment_as_string      (CommentData *data,
 						    char        *sep1,
 						    char        *sep2);
+char *         comments_get_categories_as_string   (CommentData *data,
+						    char        *sep);
 char*          _g_escape_text_for_html             (const gchar *text,
 						    gssize       length);
 
diff --git a/libgthumb/file-data.c b/libgthumb/file-data.c
index add752f..08adaab 100644
--- a/libgthumb/file-data.c
+++ b/libgthumb/file-data.c
@@ -125,6 +125,7 @@ file_data_new (const char *path)
 	fd->thumb_loaded = FALSE;
 	fd->thumb_created = FALSE;
 	fd->comment = g_strdup ("");
+	fd->categories = g_strdup ("");
 
 	return fd;
 }
@@ -168,6 +169,7 @@ file_data_dup (FileData *source)
 	fd->thumb_loaded = source->thumb_loaded;
 	fd->thumb_created = source->thumb_created;
 	fd->comment = (source->comment != NULL) ? g_strdup (source->comment) : NULL;
+	fd->categories = (source->categories != NULL) ? g_strdup (source->categories) : NULL;
 	fd->comment_data = comment_data_dup (source->comment_data);
 	
 	return fd;
@@ -188,6 +190,7 @@ file_data_unref (FileData *fd)
 		if (fd->comment_data != NULL)
 			comment_data_free (fd->comment_data);
 		g_free (fd->comment);
+		g_free (fd->categories);
 		fd_free_metadata (fd);
 		g_free (fd);
 	}
@@ -273,6 +276,10 @@ file_data_update_comment (FileData *fd)
 	fd->comment = comments_get_comment_as_string (fd->comment_data, "\n", "\n");
 	if (fd->comment == NULL)
 		fd->comment = g_strdup ("");
+
+	fd->categories = comments_get_categories_as_string (fd->comment_data, ", ");
+	if (fd->categories == NULL)
+		fd->categories = g_strdup ("");
 }
 
 
diff --git a/libgthumb/file-data.h b/libgthumb/file-data.h
index 8bbcdeb..41ecb38 100644
--- a/libgthumb/file-data.h
+++ b/libgthumb/file-data.h
@@ -54,6 +54,7 @@ typedef struct {
 						* created for this image. */
 
 	char               *comment;
+	char               *categories;
 	CommentData        *comment_data;
 	
 	GList              *metadata;
diff --git a/libgthumb/gth-file-list.c b/libgthumb/gth-file-list.c
index bc1a0b5..72c7441 100644
--- a/libgthumb/gth-file-list.c
+++ b/libgthumb/gth-file-list.c
@@ -1114,6 +1114,7 @@ add_list_in_chunks (gpointer callback_data)
 					      		pixbuf,
 							fd->utf8_name,
 							fd->comment,
+							fd->categories,
 							fd);
 			g_object_unref (pixbuf);
 		}
@@ -1723,6 +1724,7 @@ gfl_update_comment (GthFileList *file_list,
 		/* Set the new name. */
 
 		gth_file_view_set_image_comment (file_list->view, pos, fd->comment);
+		gth_file_view_set_image_categories (file_list->view, pos, fd->categories);
 		file_data_unref (fd);
 	}
 }
diff --git a/libgthumb/gth-file-view-list.c b/libgthumb/gth-file-view-list.c
index ed1c847..857caa1 100644
--- a/libgthumb/gth-file-view-list.c
+++ b/libgthumb/gth-file-view-list.c
@@ -47,6 +47,7 @@ enum {
 	COLUMN_TIME,
 	COLUMN_COMMENT,
 	COLUMN_EXIF_DATE,
+	COLUMN_CATEGORIES,
 	NUMBER_OF_COLUMNS
 };
 
@@ -57,7 +58,7 @@ struct _GthFileViewListPrivate {
 	GtkListStore   *list_store;
 	GthSortMethod   sort_method;
 	GtkSortType     sort_type;
-	GthViewMode     view_mode;
+	int             view_mode;
 	GthVisibleFunc  filter_func;
 	gpointer        filter_data;
 	int             max_image_size;
@@ -214,7 +215,8 @@ gfv_insert (GthFileView  *file_view,
 	    int           pos,
 	    GdkPixbuf    *pixbuf,
 	    const char   *text,
-	    const char   *comment)
+	    const char   *comment,
+            const char   *categories)
 {
 	GthFileViewList *gfv_list = (GthFileViewList *) file_view;
 	GtkListStore    *list_store = gfv_list->priv->list_store;
@@ -230,6 +232,7 @@ gfv_insert (GthFileView  *file_view,
 			    COLUMN_ICON, real_pixbuf,
 			    COLUMN_NAME, text,
 			    COLUMN_COMMENT, comment,
+			    COLUMN_CATEGORIES, categories,
 			    -1);
 
 	if (real_pixbuf != NULL)
@@ -241,7 +244,8 @@ static int
 gfv_append (GthFileView  *file_view,
 	    GdkPixbuf    *pixbuf,
 	    const char   *text,
-	    const char   *comment)
+	    const char   *comment,
+            const char   *categories)
 {
 	GthFileViewList *gfv_list = (GthFileViewList *) file_view;
 	GtkListStore    *list_store = gfv_list->priv->list_store;
@@ -259,6 +263,7 @@ gfv_append (GthFileView  *file_view,
 			    COLUMN_ICON, real_pixbuf,
 			    COLUMN_NAME, text,
 			    COLUMN_COMMENT, comment,
+			    COLUMN_CATEGORIES, categories,
 			    -1);
 
 	if (real_pixbuf != NULL)
@@ -277,6 +282,7 @@ gfv_append_with_data (GthFileView  *file_view,
 		      GdkPixbuf    *pixbuf,
 		      const char   *text,
 		      const char   *comment,
+                      const char   *categories,
 		      gpointer      data)
 {
 	GthFileViewList *gfv_list = (GthFileViewList *) file_view;
@@ -295,6 +301,7 @@ gfv_append_with_data (GthFileView  *file_view,
 			    COLUMN_ICON, real_pixbuf,
 			    COLUMN_NAME, text,
 			    COLUMN_COMMENT, comment,
+			    COLUMN_CATEGORIES, categories,
 			    COLUMN_FILE_DATA, data,
 			    -1);
 
@@ -448,6 +455,23 @@ gfv_set_image_comment (GthFileView  *file_view,
 }
 
 
+static void
+gfv_set_image_categories (GthFileView  *file_view,
+                          int           pos,
+                          const char   *categories)
+{
+	GthFileViewList *gfv_list = (GthFileViewList *) file_view;
+	GtkTreeIter      iter;
+
+	if (! get_list_store_iter_from_pos (gfv_list, pos, &iter))
+		return;
+
+	gtk_list_store_set (gfv_list->priv->list_store, &iter,
+			    COLUMN_CATEGORIES, categories,
+			    -1);
+}
+
+
 static const char*
 gfv_get_image_comment (GthFileView  *file_view,
 		       int           pos)
@@ -845,19 +869,25 @@ gfv_enable_thumbs (GthFileView *file_view,
 
 static void
 gfv_set_view_mode (GthFileView *file_view,
-		   GthViewMode  mode)
+		   int          mode)
 {
 	GthFileViewList   *gfv_list = (GthFileViewList *) file_view;
 	GtkTreeViewColumn *column;
 
 	gfv_list->priv->view_mode = mode;
 
+	column = gtk_tree_view_get_column (gfv_list->priv->tree_view, 1);
+	gtk_tree_view_column_set_visible (column, mode & GTH_VIEW_MODE_LABEL);
+
 	column = gtk_tree_view_get_column (gfv_list->priv->tree_view, 2);
-	gtk_tree_view_column_set_visible (column, FALSE /*mode == GTH_VIEW_MODE_ALL*/);
+	gtk_tree_view_column_set_visible (column, mode & GTH_VIEW_MODE_COMMENTS);
+
+	column = gtk_tree_view_get_column (gfv_list->priv->tree_view, 3);
+	gtk_tree_view_column_set_visible (column, mode & GTH_VIEW_MODE_CATEGORIES);
 }
 
 
-static GthViewMode
+static int
 gfv_get_view_mode (GthFileView *file_view)
 {
 	GthFileViewList *gfv_list = (GthFileViewList *) file_view;
@@ -1304,6 +1334,7 @@ gth_file_view_list_class_init (GthFileViewListClass *file_view_list_class)
 	file_view_class->set_image_text       = gfv_set_image_text;
 	file_view_class->get_image_text       = gfv_get_image_text;
 	file_view_class->set_image_comment    = gfv_set_image_comment;
+	file_view_class->set_image_categories    = gfv_set_image_categories;
 	file_view_class->get_image_comment    = gfv_get_image_comment;
 	file_view_class->get_images           = gfv_get_images;
 	file_view_class->get_list             = gfv_get_list;
@@ -1489,6 +1520,30 @@ add_columns (GtkTreeView *treeview)
 	gtk_tree_view_column_set_expand (column, TRUE);
 
 	gtk_tree_view_append_column (treeview, column);
+
+	/* Categories column */
+
+	column = gtk_tree_view_column_new ();
+
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_column_set_attributes (column, renderer,
+					     "text", COLUMN_CATEGORIES,
+					     NULL);
+
+	g_value_init (&value, PANGO_TYPE_ELLIPSIZE_MODE);
+	g_value_set_enum (&value, PANGO_ELLIPSIZE_END);
+	g_object_set_property (G_OBJECT (renderer), "ellipsize", &value);
+	g_value_unset (&value);
+
+	gtk_tree_view_column_set_sort_column_id (column, COLUMN_CATEGORIES);
+	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+	gtk_tree_view_column_set_resizable (column, FALSE);
+	gtk_tree_view_column_set_expand (column, TRUE);
+
+	gtk_tree_view_column_set_visible (column, TRUE);
+	gtk_tree_view_append_column (treeview, column);
+
 }
 
 
@@ -1649,6 +1704,7 @@ gth_file_view_list_new (guint image_width)
 					       G_TYPE_STRING,
 					       G_TYPE_STRING,
 					       G_TYPE_STRING,
+					       G_TYPE_STRING,
 					       G_TYPE_STRING);
 	priv->filter_model =  gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->list_store), NULL);
 	g_object_unref (priv->list_store);
diff --git a/libgthumb/gth-file-view-thumbs.c b/libgthumb/gth-file-view-thumbs.c
index 513f096..d74dec5 100644
--- a/libgthumb/gth-file-view-thumbs.c
+++ b/libgthumb/gth-file-view-thumbs.c
@@ -132,14 +132,15 @@ gfv_insert (GthFileView  *file_view,
 	    int           pos,
 	    GdkPixbuf    *pixbuf,
 	    const char   *text,
-	    const char   *comment)
+	    const char   *comment,
+            const char   *categories)
 {
 	GthFileViewThumbs *gfv_thumbs = (GthFileViewThumbs *) file_view;
 	GthImageList      *ilist = gfv_thumbs->priv->ilist;
 
 	g_return_if_fail (pixbuf != NULL);
 
-	gth_image_list_insert (ilist, pos, pixbuf, text, comment);
+	gth_image_list_insert (ilist, pos, pixbuf, text, comment, categories);
 }
 
 
@@ -147,14 +148,15 @@ static int
 gfv_append (GthFileView  *file_view,
 	    GdkPixbuf    *pixbuf,
 	    const char   *text,
-	    const char   *comment)
+	    const char   *comment,
+            const char   *categories)
 {
 	GthFileViewThumbs *gfv_thumbs = (GthFileViewThumbs *) file_view;
 	GthImageList      *ilist = gfv_thumbs->priv->ilist;
 
 	g_return_val_if_fail (pixbuf != NULL, -1);
 
-	return 	gth_image_list_append (ilist, pixbuf, text, comment);
+	return 	gth_image_list_append (ilist, pixbuf, text, comment, categories);
 }
 
 
@@ -163,6 +165,7 @@ gfv_append_with_data (GthFileView  *file_view,
 		      GdkPixbuf    *pixbuf,
 		      const char   *text,
 		      const char   *comment,
+		      const char   *categories,
 		      gpointer      data)
 {
 	GthFileViewThumbs *gfv_thumbs = (GthFileViewThumbs *) file_view;
@@ -170,7 +173,7 @@ gfv_append_with_data (GthFileView  *file_view,
 
 	g_return_val_if_fail (pixbuf != NULL, -1);
 
-	return 	gth_image_list_append_with_data (ilist, pixbuf, text, comment, data);
+	return 	gth_image_list_append_with_data (ilist, pixbuf, text, comment, categories, data);
 }
 
 
@@ -242,6 +245,18 @@ gfv_set_image_comment (GthFileView  *file_view,
 }
 
 
+static void
+gfv_set_image_categories (GthFileView  *file_view,
+                          int           pos,
+                          const char   *categories)
+{
+	GthFileViewThumbs *gfv_thumbs = (GthFileViewThumbs *) file_view;
+	GthImageList      *ilist = gfv_thumbs->priv->ilist;
+
+	gth_image_list_set_image_categories (ilist, pos, categories);
+}
+
+
 static const char*
 gfv_get_image_comment (GthFileView  *file_view,
 		       int           pos)
@@ -457,7 +472,7 @@ gfv_enable_thumbs (GthFileView *file_view,
 
 static void
 gfv_set_view_mode (GthFileView *file_view,
-		   GthViewMode  mode)
+		   int          mode)
 {
 	GthFileViewThumbs *gfv_thumbs = (GthFileViewThumbs *) file_view;
 	GthImageList      *ilist = gfv_thumbs->priv->ilist;
@@ -466,7 +481,7 @@ gfv_set_view_mode (GthFileView *file_view,
 }
 
 
-static GthViewMode
+static int
 gfv_get_view_mode (GthFileView *file_view)
 {
 	GthFileViewThumbs *gfv_thumbs = (GthFileViewThumbs *) file_view;
@@ -883,6 +898,7 @@ gth_file_view_thumbs_class_init (GthFileViewThumbsClass *file_view_thumbs_class)
 	file_view_class->set_image_text       = gfv_set_image_text;
 	file_view_class->get_image_text       = gfv_get_image_text;
 	file_view_class->set_image_comment    = gfv_set_image_comment;
+	file_view_class->set_image_categories = gfv_set_image_categories;
 	file_view_class->get_image_comment    = gfv_get_image_comment;
 	file_view_class->get_images           = gfv_get_images;
 	file_view_class->get_list             = gfv_get_list;
diff --git a/libgthumb/gth-file-view.c b/libgthumb/gth-file-view.c
index 69b3bd0..0e66775 100644
--- a/libgthumb/gth-file-view.c
+++ b/libgthumb/gth-file-view.c
@@ -111,7 +111,8 @@ gfv_insert (GthFileView  *file_view,
 	    int           pos,
 	    GdkPixbuf    *pixbuf,
 	    const char   *text,
-	    const char   *comment)
+	    const char   *comment,
+            const char   *categories)
 {
 }
 
@@ -120,7 +121,8 @@ static int
 gfv_append (GthFileView  *file_view,
 	    GdkPixbuf    *pixbuf,
 	    const char   *text,
-	    const char   *comment)
+	    const char   *comment,
+            const char   *categories)
 {
 	return -1;
 }
@@ -131,6 +133,7 @@ gfv_append_with_data (GthFileView  *file_view,
 		      GdkPixbuf    *pixbuf,
 		      const char   *text,
 		      const char   *comment,
+                      const char   *categories,
 		      gpointer      data)
 {
 	return -1;
@@ -182,6 +185,14 @@ gfv_set_image_comment (GthFileView  *file_view,
 }
 
 
+static void
+gfv_set_image_categories (GthFileView  *file_view,
+                          int           pos,
+                          const char   *categories)
+{
+}
+
+
 static const char*
 gfv_get_image_comment (GthFileView  *file_view,
 		       int           pos)
@@ -325,12 +336,12 @@ gfv_enable_thumbs (GthFileView *file_view,
 
 static void
 gfv_set_view_mode (GthFileView *file_view,
-		   GthViewMode  mode)
+		   int          mode)
 {
 }
 
 
-static GthViewMode
+static int
 gfv_get_view_mode (GthFileView *file_view)
 {
 	return GTH_VIEW_MODE_COMMENTS;
@@ -510,6 +521,7 @@ gth_file_view_class_init (GthFileViewClass *file_view_class)
 	file_view_class->set_image_text       = gfv_set_image_text;
 	file_view_class->get_image_text       = gfv_get_image_text;
 	file_view_class->set_image_comment    = gfv_set_image_comment;
+	file_view_class->set_image_categories = gfv_set_image_categories;
 	file_view_class->get_image_comment    = gfv_get_image_comment;
 	file_view_class->get_images           = gfv_get_images;
 	file_view_class->get_list             = gfv_get_list;
@@ -693,9 +705,10 @@ gth_file_view_insert (GthFileView  *file_view,
 		      int           pos,
 		      GdkPixbuf    *pixbuf,
 		      const char   *text,
-		      const char   *comment)
+		      const char   *comment,
+                      const char   *categories)
 {
-	GTH_FILE_VIEW_GET_CLASS (file_view)->insert (file_view, pos, pixbuf, text, comment);
+	GTH_FILE_VIEW_GET_CLASS (file_view)->insert (file_view, pos, pixbuf, text, comment, categories);
 }
 
 
@@ -703,9 +716,10 @@ int
 gth_file_view_append (GthFileView  *file_view,
 		      GdkPixbuf    *pixbuf,
 		      const char   *text,
-		      const char   *comment)
+		      const char   *comment,
+                      const char   *categories)
 {
-	return GTH_FILE_VIEW_GET_CLASS (file_view)->append (file_view, pixbuf, text, comment);
+	return GTH_FILE_VIEW_GET_CLASS (file_view)->append (file_view, pixbuf, text, comment, categories);
 }
 
 
@@ -714,9 +728,10 @@ gth_file_view_append_with_data (GthFileView  *file_view,
 				GdkPixbuf    *pixbuf,
 				const char   *text,
 				const char   *comment,
+                                const char   *categories,
 				gpointer      data)
 {
-	return GTH_FILE_VIEW_GET_CLASS (file_view)->append_with_data (file_view, pixbuf, text, comment, data);
+	return GTH_FILE_VIEW_GET_CLASS (file_view)->append_with_data (file_view, pixbuf, text, comment, categories, data);
 }
 
 
@@ -770,6 +785,15 @@ gth_file_view_set_image_comment (GthFileView  *file_view,
 }
 
 
+void
+gth_file_view_set_image_categories (GthFileView  *file_view,
+                                    int           pos,
+                                    const char   *categories)
+{
+	GTH_FILE_VIEW_GET_CLASS (file_view)->set_image_categories (file_view, pos, categories);
+}
+
+
 const char*
 gth_file_view_get_image_comment (GthFileView  *file_view,
 				 int           pos)
@@ -920,13 +944,13 @@ gth_file_view_enable_thumbs (GthFileView *file_view,
 
 void
 gth_file_view_set_view_mode (GthFileView *file_view,
-			     GthViewMode  mode)
+			     int          mode)
 {
 	GTH_FILE_VIEW_GET_CLASS (file_view)->set_view_mode (file_view, mode);
 }
 
 
-GthViewMode
+int
 gth_file_view_get_view_mode (GthFileView *file_view)
 {
 	return GTH_FILE_VIEW_GET_CLASS (file_view)->get_view_mode (file_view);
diff --git a/libgthumb/gth-file-view.h b/libgthumb/gth-file-view.h
index 07e4f76..66e439a 100644
--- a/libgthumb/gth-file-view.h
+++ b/libgthumb/gth-file-view.h
@@ -77,15 +77,18 @@ typedef struct {
 						 int           pos,
 						 GdkPixbuf    *pixbuf,
 						 const char   *text,
-						 const char   *comment);
+						 const char   *comment,
+                                                 const char   *categories);
 	int            (* append)               (GthFileView  *file_view,
 						 GdkPixbuf    *pixbuf,
 						 const char   *text,
-						 const char   *comment);
+						 const char   *comment,
+                                                 const char   *categories);
 	int            (* append_with_data)     (GthFileView  *file_view,
 						 GdkPixbuf    *pixbuf,
 						 const char   *text,
 						 const char   *comment,
+                                                 const char   *categories,
 						 gpointer      data);
 	void           (* remove)               (GthFileView  *file_view,
 						 gpointer      data);
@@ -103,6 +106,9 @@ typedef struct {
 	void           (* set_image_comment)    (GthFileView  *file_view,
 						 int           pos,
 						 const char   *comment);
+	void           (* set_image_categories) (GthFileView  *file_view,
+						 int           pos,
+						 const char   *categories);
 	const char*    (* get_image_comment)    (GthFileView  *file_view,
 						 int           pos);
 	int            (* get_images)           (GthFileView  *file_view);
@@ -144,8 +150,8 @@ typedef struct {
 	void           (* enable_thumbs)        (GthFileView    *file_view,
 						 gboolean        enable_thumbs);
 	void           (* set_view_mode)        (GthFileView    *file_view,
-						 GthViewMode     mode);
-	GthViewMode    (* get_view_mode)        (GthFileView    *file_view);
+						 int             mode);
+	int            (* get_view_mode)        (GthFileView    *file_view);
 	void           (* moveto)               (GthFileView    *file_view,
 						 int             pos,
 						 double          yalign);
@@ -218,15 +224,18 @@ void           gth_file_view_insert              (GthFileView  *file_view,
 						  int           pos,
 						  GdkPixbuf    *pixbuf,
 						  const char   *text,
-						  const char   *comment);
+						  const char   *comment,
+                                                  const char   *categories);
 int            gth_file_view_append              (GthFileView  *file_view,
 						  GdkPixbuf    *pixbuf,
 						  const char   *text,
-						  const char   *comment);
+						  const char   *comment,
+                                                  const char   *categories);
 int            gth_file_view_append_with_data    (GthFileView  *file_view,
 						  GdkPixbuf    *pixbuf,
 						  const char   *text,
 						  const char   *comment,
+                                                  const char   *categories,
 						  gpointer      data);
 void           gth_file_view_remove              (GthFileView  *file_view,
 						  gpointer      data);
@@ -246,6 +255,9 @@ void           gth_file_view_set_image_comment   (GthFileView  *file_view,
 						  const char   *comment);
 const char*    gth_file_view_get_image_comment   (GthFileView  *file_view,
 						  int           pos);
+void           gth_file_view_set_image_categories(GthFileView  *file_view,
+						  int           pos,
+						  const char   *categories);
 int            gth_file_view_get_images          (GthFileView  *file_view);
 GList *        gth_file_view_get_list            (GthFileView  *file_view);
 GList *        gth_file_view_get_selection       (GthFileView  *file_view);
@@ -286,8 +298,8 @@ gpointer       gth_file_view_get_image_data       (GthFileView     *file_view,
 void           gth_file_view_enable_thumbs        (GthFileView *file_view,
 						   gboolean     enable_thumbs);
 void           gth_file_view_set_view_mode        (GthFileView *file_view,
-						   GthViewMode  mode);
-GthViewMode    gth_file_view_get_view_mode        (GthFileView *file_view);
+						   int          mode);
+int            gth_file_view_get_view_mode        (GthFileView *file_view);
 void           gth_file_view_moveto               (GthFileView *file_view,
 						   int          pos,
 						   double       yalign);
diff --git a/libgthumb/gth-image-list.c b/libgthumb/gth-image-list.c
index aec9d02..d3d51c9 100644
--- a/libgthumb/gth-image-list.c
+++ b/libgthumb/gth-image-list.c
@@ -48,6 +48,7 @@
 #define DEFAULT_TEXT_SPACING 6
 #define DEFAULT_IMAGE_BORDER 3
 #define TEXT_COMMENT_SPACE 6       /* space between text and comment. */
+#define TEXT_CATEGORIES_SPACE 6       /* space between text and categories. */
 #define KEYBOARD_SELECTION_BORDER 10
 #define FRAME_SELECTION_BORDER 3
 
@@ -69,6 +70,9 @@
   + ((((il)->comment_height > 0) || ((il)->text_height > 0)) ? (gil)->priv->text_spacing : 0) \
   + (il)->comment_height \
   + ((((il)->comment_height > 0) && ((il)->text_height > 0)) ? TEXT_COMMENT_SPACE : 0) \
+  + ((((il)->categories_height > 0) || ((il)->text_height > 0)) ? (gil)->priv->text_spacing : 0) \
+  + (il)->categories_height \
+  + ((((il)->categories_height > 0) && ((il)->text_height > 0)) ? TEXT_CATEGORIES_SPACE : 0) \
   + (il)->text_height \
   + (gil)->priv->row_spacing)
 
@@ -236,6 +240,7 @@ gth_image_list_item_new (GthImageList  *image_list,
 			 GdkPixbuf     *image,
 			 const char    *label,
 			 const char    *comment,
+			 const char    *categories,
 			 GType          data_type)
 {
 	GthImageListItem *item;
@@ -249,6 +254,7 @@ gth_image_list_item_new (GthImageList  *image_list,
 	item->image_area.width = -1;
 	item->label_area.width = -1;
 	item->comment_area.width = -1;
+	item->categories_area.width = -1;
 
 	if (image != NULL)
 		gth_image_list_item_set_pixbuf (image_list, item, image);
@@ -259,6 +265,9 @@ gth_image_list_item_new (GthImageList  *image_list,
 	if (comment != NULL)
 		item->comment = g_strdup (comment);
 
+	if (categories != NULL)
+		item->categories = g_strdup (categories);
+
 	return item;
 }
 
@@ -285,6 +294,7 @@ gth_image_list_item_unref (GthImageListItem *item)
 		gth_image_list_item_free_pixmap_and_mask (item);
 		g_free (item->label);
 		g_free (item->comment);
+		g_free (item->categories);
 		if (item->data != NULL) 
 			g_boxed_free (item->data_type, item->data);
 		g_free (item);
@@ -297,6 +307,7 @@ typedef struct {
 	int    image_height;
 	int    text_height;
 	int    comment_height;
+        int    categories_height;
 	GList *image_list;
 } GthImageListLine;
 
@@ -358,7 +369,7 @@ struct _GthImageListPrivate {
 	int               text_spacing;
 	int               image_border;
 
-	GthViewMode       view_mode;
+	int               view_mode;
 
 	guint             timer_tag; 	       /* Timeout ID for
 						* autoscrolling */
@@ -390,6 +401,7 @@ struct _GthImageListPrivate {
 
 	PangoLayout      *layout;
 	PangoLayout      *comment_layout;
+	PangoLayout      *categories_layout;
 	PangoLayout      *no_image_msg_layout;
 	guint             layout_timeout;
 
@@ -549,6 +561,11 @@ gth_image_list_finalize (GObject *object)
 		priv->comment_layout = NULL;
 	}
 
+	if (priv->categories_layout != NULL) {
+		g_object_unref (priv->categories_layout);
+		priv->categories_layout = NULL;
+	}
+
 	if (priv->no_image_msg_layout != NULL) {
 		g_object_unref (priv->no_image_msg_layout);
 		priv->no_image_msg_layout = NULL;
@@ -657,35 +674,55 @@ get_comment_size (GthImageList     *image_list,
 	}
 }
 
+static void
+get_categories_size (GthImageList     *image_list,
+		  GthImageListItem *item,
+		  int              *width,
+		  int              *height)
+{
+	if ((item->categories != NULL) && (*item->categories != 0)) {
+		if ((item->categories_area.width == -1) || (item->categories_area.height == -1))
+			get_text_size (image_list,
+				       item->categories,
+				       & (item->categories_area.width),
+				       & (item->categories_area.height),
+				       TRUE);
+
+		if (width != NULL)
+			*width = item->categories_area.width;
+
+		if (height != NULL)
+			*height = item->categories_area.height;
+
+	} else {
+		if (width != NULL)
+			*width = 0;
+		if (height != NULL)
+			*height = 0;
+	}
+}
+
+
 
 static void
 item_get_view_mode (GthImageList     *image_list,
 		    GthImageListItem *item,
 		    gboolean         *view_label,
-		    gboolean         *view_comment)
+		    gboolean         *view_comment,
+		    gboolean         *view_categories)
 {
 	GthImageListPrivate *priv = image_list->priv;
 
-	*view_label   = TRUE;
-	*view_comment = TRUE;
+	*view_label   = priv->view_mode & GTH_VIEW_MODE_LABEL;
+	*view_comment = priv->view_mode & GTH_VIEW_MODE_COMMENTS;
+	*view_categories = priv->view_mode & GTH_VIEW_MODE_CATEGORIES;
 
-	if (priv->view_mode == GTH_VIEW_MODE_VOID) {
-		*view_label   = FALSE;
-		*view_comment = FALSE;
-		return;
-	}
-	if (priv->view_mode == GTH_VIEW_MODE_LABEL)
-		*view_comment = FALSE;
-	if (priv->view_mode == GTH_VIEW_MODE_COMMENTS)
-		*view_label = FALSE;
-	if ((priv->view_mode == GTH_VIEW_MODE_COMMENTS_OR_TEXT)
-	    && ! STRING_IS_VOID (item->comment))
+	if (STRING_IS_VOID (item->label))
 		*view_label = FALSE;
-
 	if (STRING_IS_VOID (item->comment))
 		*view_comment = FALSE;
-	if (STRING_IS_VOID (item->label))
-		*view_label = FALSE;
+	if (STRING_IS_VOID (item->categories))
+		*view_categories = FALSE;
 }
 
 
@@ -694,11 +731,13 @@ get_item_height (GthImageList     *image_list,
 		 GthImageListItem *item,
 		 int              *image_height,
 		 int              *text_height,
-		 int              *comment_height)
+		 int              *comment_height,
+                 int              *categories_height)
 {
 	*image_height = image_list->priv->max_item_width;
 	get_label_size (image_list, item, NULL, text_height);
 	get_comment_size (image_list, item, NULL, comment_height);
+	get_categories_size (image_list, item, NULL, categories_height);
 }
 
 
@@ -723,7 +762,8 @@ place_item (GthImageList     *image_list,
 	    int               y,
 	    int               image_height,
 	    gboolean          view_label,
-	    gboolean          view_comment)
+	    gboolean          view_comment,
+            gboolean          view_categories)
 {
 	GthImageListPrivate *priv = image_list->priv;
 	int                  x_offset, y_offset;
@@ -752,6 +792,16 @@ place_item (GthImageList     *image_list,
 		y += comment_height + TEXT_COMMENT_SPACE;
 	}
 
+	x_offset = (priv->max_item_width - item->categories_area.width) / 2;
+	if (view_categories) {
+		int categories_height;
+
+		item->categories_area.x = x + x_offset + 1;
+		item->categories_area.y = y;
+		get_categories_size (image_list, item, NULL, &categories_height);
+		y += categories_height + TEXT_CATEGORIES_SPACE;
+	}
+
 	x_offset = (priv->max_item_width - item->label_area.width) / 2;
 	if (view_label) {
 		item->label_area.x = x + x_offset + 1;
@@ -766,13 +816,13 @@ layout_line (GthImageList     *image_list,
 {
 	GthImageListPrivate *priv = image_list->priv;
 	GList               *scan;
-	gboolean             view_label, view_comment;
+	gboolean             view_label, view_comment, view_categories;
 	int                  x = 0;
 
 	for (scan = line->image_list; scan; scan = scan->next) {
 		GthImageListItem *item = scan->data;
 
-		item_get_view_mode (image_list, item, &view_label, &view_comment);
+		item_get_view_mode (image_list, item, &view_label, &view_comment, &view_categories);
 
 		x += priv->col_spacing;
 		place_item (image_list,
@@ -781,7 +831,8 @@ layout_line (GthImageList     *image_list,
 			    line->y,
 			    line->image_height,
 			    view_label,
-			    view_comment);
+			    view_comment,
+                            view_categories);
 		x += priv->max_item_width;
 	}
 }
@@ -793,7 +844,8 @@ add_and_layout_line (GthImageList *image_list,
 		     int           y,
 		     int           image_height,
 		     int           text_height,
-		     int           comment_height)
+		     int           comment_height,
+                     int           categories_height)
 {
 	GthImageListPrivate *priv = image_list->priv;
 	GthImageListLine    *line;
@@ -804,6 +856,7 @@ add_and_layout_line (GthImageList *image_list,
 	line->image_height = image_height;
 	line->text_height = text_height;
 	line->comment_height = comment_height;
+	line->categories_height = categories_height;
 
 	layout_line (image_list, line);
 	priv->lines = g_list_append (priv->lines, line);
@@ -849,7 +902,7 @@ relayout_images_at (GthImageList *image_list,
 		    int           y)
 {
 	GthImageListPrivate *priv = image_list->priv;
-	int    text_height = 0, image_height = 0, comment_height = 0;
+	int    text_height = 0, image_height = 0, comment_height = 0, categories_height = 0;
 	int    images_per_line, n;
 	GList *line_images = NULL, *scan;
 	int    max_height = 0;
@@ -860,8 +913,8 @@ relayout_images_at (GthImageList *image_list,
 
 	for (; scan; scan = scan->next, n++) {
 		GthImageListItem *item = scan->data;
-		int               ih, th, ch;
-		gboolean          view_label, view_comment;
+		int               ih, th, ch, cath;
+		gboolean          view_label, view_comment, view_categories;
 
 		if (! (n % images_per_line)) {
 			if (line_images != NULL) {
@@ -870,7 +923,8 @@ relayout_images_at (GthImageList *image_list,
 						     y,
 						     image_height,
 						     text_height,
-						     comment_height);
+						     comment_height,
+                                                     categories_height);
 				line_images = NULL;
 				y += max_height + priv->row_spacing;
 			}
@@ -879,10 +933,11 @@ relayout_images_at (GthImageList *image_list,
 			image_height   = 0;
 			text_height    = 0;
 			comment_height = 0;
+                        categories_height = 0;
 		}
 
-		get_item_height (image_list, item, &ih, &th, &ch);
-		item_get_view_mode (image_list, item, &view_label, &view_comment);
+		get_item_height (image_list, item, &ih, &th, &ch, &cath);
+		item_get_view_mode (image_list, item, &view_label, &view_comment, &view_categories);
 
 		if (! view_label)
 			th = 0;
@@ -890,14 +945,21 @@ relayout_images_at (GthImageList *image_list,
 		if (! view_comment)
 			ch = 0;
 
+		if (! view_categories)
+			cath = 0;
+
 		image_height   = MAX (ih, image_height);
 		text_height    = MAX (th, text_height);
 		comment_height = MAX (ch, comment_height);
+		categories_height = MAX (cath, categories_height);
 
 		max_height = (image_height
 			      + ((comment_height || text_height) ? priv->text_spacing : 0)
 			      + comment_height
 			      + ((comment_height && text_height) ? TEXT_COMMENT_SPACE : 0)
+			      + ((categories_height || text_height) ? priv->text_spacing : 0)
+			      + categories_height
+			      + ((categories_height && text_height) ? TEXT_COMMENT_SPACE : 0)
 			      + text_height);
 
 		line_images = g_list_append (line_images, item);
@@ -909,7 +971,8 @@ relayout_images_at (GthImageList *image_list,
 				     y,
 				     image_height,
 				     text_height,
-				     comment_height);
+				     comment_height,
+                                     categories_height);
 
 	update_scrollbar_adjust (image_list);
 }
@@ -975,11 +1038,13 @@ reset_text_width (GthImageList *image_list)
 
 	pango_layout_set_width (priv->layout, priv->max_item_width * PANGO_SCALE);
 	pango_layout_set_width (priv->comment_layout, priv->max_item_width * PANGO_SCALE);
+	pango_layout_set_width (priv->categories_layout, priv->max_item_width * PANGO_SCALE);
 
 	for (scan = priv->image_list; scan; scan = scan->next) {
 		GthImageListItem *item = scan->data;
 		item->label_area.width = -1;
 		item->comment_area.width = -1;
+		item->categories_area.width = -1;
 	}
 	priv->update_width = FALSE;
 }
@@ -1140,12 +1205,20 @@ gth_image_list_realize (GtkWidget *widget)
 	if (priv->comment_layout != NULL)
 		g_object_unref (priv->comment_layout);
 
+	if (priv->categories_layout != NULL)
+		g_object_unref (priv->categories_layout);
+
 	priv->comment_layout = pango_layout_copy (priv->layout);
+	priv->categories_layout = pango_layout_copy (priv->layout);
 
 	font_desc = pango_font_description_copy (pango_context_get_font_description (pango_layout_get_context (priv->comment_layout)));
 	pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
 	pango_layout_set_font_description (priv->comment_layout, font_desc);
 
+	font_desc = pango_font_description_copy (pango_context_get_font_description (pango_layout_get_context (priv->categories_layout)));
+	pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
+	pango_layout_set_font_description (priv->categories_layout, font_desc);
+
 	/* 'No Image' message Layout */
 
 	if (priv->no_image_msg_layout != NULL)
@@ -1195,6 +1268,11 @@ gth_image_list_unrealize (GtkWidget *widget)
 		image_list->priv->comment_layout = NULL;
 	}
 
+	if (image_list->priv->categories_layout) {
+		g_object_unref (image_list->priv->categories_layout);
+		image_list->priv->categories_layout = NULL;
+	}
+
 	(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
 }
 
@@ -1371,9 +1449,9 @@ get_item_bounding_box (GthImageList     *image_list,
 		       GthImageListItem *item,
 		       GdkRectangle     *item_rectangle)
 {
-	gboolean view_text, view_comment;
+	gboolean view_text, view_comment, view_categories;
 
-	item_get_view_mode (image_list, item, &view_text, &view_comment);
+	item_get_view_mode (image_list, item, &view_text, &view_comment, &view_categories);
 
 	*item_rectangle = item->slide_area;
 	item_rectangle->width = image_list->priv->max_item_width;
@@ -1395,6 +1473,14 @@ get_item_bounding_box (GthImageList     *image_list,
 				     item_rectangle);
 	}
 
+	if (view_categories) {
+		GdkRectangle tmp_rectangle;
+		tmp_rectangle = *item_rectangle;
+		gdk_rectangle_union (&tmp_rectangle,
+				     &item->categories_area,
+				     item_rectangle);
+	}
+
 	/* include the border */
 
 	item_rectangle->x -= 1;
@@ -1419,7 +1505,7 @@ paint_item (GthImageList     *image_list,
 	GtkWidget    *widget = (GtkWidget*) image_list;
 	GtkStateType  state, text_state, focus_state;
 	GdkRectangle  item_rectangle, rect;
-	gboolean      view_label, view_comment;
+	gboolean      view_label, view_comment, view_categories;
 	gboolean      focused;
 
 	if ((item->image_area.x == -1) || (item->slide_area.x == -1))
@@ -1503,7 +1589,7 @@ paint_item (GthImageList     *image_list,
 		g_object_unref (image_gc);
 	}
 
-	item_get_view_mode (image_list, item, &view_label, &view_comment);
+	item_get_view_mode (image_list, item, &view_label, &view_comment, &view_categories);
 
 	/* Label */
 
@@ -1543,6 +1629,25 @@ paint_item (GthImageList     *image_list,
 				 image_list->priv->comment_layout);
 	}
 
+	/* Categories */
+
+	if (view_categories) {
+		gdk_draw_rectangle (image_list->priv->bin_window,
+				    widget->style->base_gc[text_state],
+				    TRUE,
+				    item->categories_area.x - 1,
+				    item->categories_area.y - 1,
+				    item->categories_area.width + 2,
+				    item->categories_area.height + 2);
+
+		pango_layout_set_text (image_list->priv->categories_layout, item->categories, strlen (item->categories));
+		gdk_draw_layout (image_list->priv->bin_window,
+				 widget->style->text_gc[text_state],
+				 item->categories_area.x - (image_list->priv->max_item_width - item->categories_area.width) / 2,
+				 item->categories_area.y,
+				 image_list->priv->categories_layout);
+	}
+
 	/* Focus */
 
 	if (focused) {
@@ -3515,7 +3620,7 @@ gth_image_list_init (GthImageList *image_list)
 	priv->selection_mode = GTK_SELECTION_MULTIPLE;
 	priv->last_selected_pos = -1;
 
-	priv->view_mode = GTH_VIEW_MODE_VOID;
+	priv->view_mode = 0;
 
 	priv->row_spacing = DEFAULT_ROW_SPACING;
 	priv->col_spacing = DEFAULT_COLUMN_SPACING;
@@ -3745,7 +3850,8 @@ gth_image_list_insert (GthImageList *image_list,
 		       int           pos,
 		       GdkPixbuf    *pixbuf,
 		       const char   *text,
-		       const char   *comment)
+		       const char   *comment,
+                       const char   *categories)
 {
 	GthImageListItem *item;
 	char             *comment2;
@@ -3755,7 +3861,7 @@ gth_image_list_insert (GthImageList *image_list,
 	g_return_if_fail ((pos >= 0) && (pos <= image_list->priv->n_images));
 
 	comment2 = truncate_comment_if_needed (image_list, comment);
-	item = gth_image_list_item_new (image_list, pixbuf, text, comment2, image_list->priv->data_type);
+	item = gth_image_list_item_new (image_list, pixbuf, text, comment2, categories, image_list->priv->data_type);
 	g_free (comment2);
 
 	image_list_insert_item (image_list, item, pos);
@@ -3767,6 +3873,7 @@ gth_image_list_append_with_data (GthImageList *image_list,
 				 GdkPixbuf    *pixbuf,
 				 const char   *text,
 				 const char   *comment,
+                                 const char   *categories,
 				 gpointer      data)
 {
 	GthImageListItem *item;
@@ -3776,7 +3883,7 @@ gth_image_list_append_with_data (GthImageList *image_list,
 	g_return_val_if_fail (pixbuf != NULL, -1);
 
 	comment2 = truncate_comment_if_needed (image_list, comment);
-	item = gth_image_list_item_new (image_list, pixbuf, text, comment2, image_list->priv->data_type);
+	item = gth_image_list_item_new (image_list, pixbuf, text, comment2, categories, image_list->priv->data_type);
 	g_free (comment2);
 
 	/**/
@@ -3802,9 +3909,10 @@ int
 gth_image_list_append (GthImageList  *image_list,
 		       GdkPixbuf     *pixbuf,
 		       const char    *text,
-		       const char    *comment)
+		       const char    *comment,
+                       const char    *categories)
 {
-	return gth_image_list_append_with_data (image_list, pixbuf, text, comment, NULL);
+	return gth_image_list_append_with_data (image_list, pixbuf, text, comment, categories, NULL);
 }
 
 
@@ -4025,6 +4133,36 @@ gth_image_list_set_image_comment (GthImageList  *image_list,
 }
 
 
+void
+gth_image_list_set_image_categories (GthImageList  *image_list,
+                                     int            pos,
+                                     const char    *categories)
+{
+	GthImageListItem *item;
+
+	g_return_if_fail (image_list != NULL);
+	g_return_if_fail ((pos >= 0) && (pos < image_list->priv->n_images));
+	g_return_if_fail (categories!= NULL);
+
+	item = g_list_nth (image_list->priv->image_list, pos)->data;
+	g_return_if_fail (item != NULL);
+
+	g_free (item->categories);
+	item->categories= NULL;
+	if (categories != NULL)
+		item->categories = g_strdup (categories);
+	item->categories_area.width = -1;
+	item->categories_area.height = -1;
+
+	if (image_list->priv->frozen) {
+		image_list->priv->dirty = TRUE;
+		return;
+	}
+
+	layout_from_line (image_list, pos / gth_image_list_get_items_per_line (image_list));
+}
+
+
 const char *
 gth_image_list_get_image_text (GthImageList *image_list,
 			       int           pos)
@@ -4206,7 +4344,7 @@ gth_image_list_enable_thumbs (GthImageList *image_list,
 
 void
 gth_image_list_set_view_mode (GthImageList *image_list,
-			      GthViewMode   mode)
+			      int           mode)
 {
 	g_return_if_fail (GTH_IS_IMAGE_LIST (image_list));
 	image_list->priv->view_mode = mode;
@@ -4215,7 +4353,7 @@ gth_image_list_set_view_mode (GthImageList *image_list,
 }
 
 
-GthViewMode
+int
 gth_image_list_get_view_mode (GthImageList *image_list)
 {
 	g_return_val_if_fail (GTH_IS_IMAGE_LIST (image_list), 0);
@@ -4350,7 +4488,7 @@ gth_image_list_get_image_at (GthImageList *image_list,
 
 	for (n = 0, scan = priv->image_list; scan; scan = scan->next, n++) {
 		GthImageListItem *item = scan->data;
-		gboolean          view_text, view_comment;
+		gboolean          view_text, view_comment, view_categories;
 
 		if ((x >= item->slide_area.x)
 		    && (y >= item->slide_area.y)
@@ -4359,7 +4497,7 @@ gth_image_list_get_image_at (GthImageList *image_list,
 			return n;
 		}
 
-		item_get_view_mode (image_list, item, &view_text, &view_comment);
+		item_get_view_mode (image_list, item, &view_text, &view_comment, &view_categories);
 
 		if (view_text && _gdk_rectangle_point_in (&item->label_area, x, y)) {
 			return n;
@@ -4368,6 +4506,10 @@ gth_image_list_get_image_at (GthImageList *image_list,
 		if (view_comment && _gdk_rectangle_point_in (&item->comment_area, x, y)) {
 			return n;
 		}
+
+		if (view_categories && _gdk_rectangle_point_in (&item->categories_area, x, y)) {
+			return n;
+                }
 	}
 
 	return -1;
diff --git a/libgthumb/gth-image-list.h b/libgthumb/gth-image-list.h
index 2ed0696..801b7cb 100644
--- a/libgthumb/gth-image-list.h
+++ b/libgthumb/gth-image-list.h
@@ -65,6 +65,7 @@ typedef struct {
 
 	char             *label;
 	char             *comment;
+	char             *categories;
 
 	gpointer          data;
 
@@ -83,6 +84,7 @@ typedef struct {
 	GdkRectangle      image_area;
 	GdkRectangle      label_area;
 	GdkRectangle      comment_area;
+	GdkRectangle      categories_area;
 
 	guint             tmp_selected : 1;
 } GthImageListItem;
@@ -147,15 +149,18 @@ void           gth_image_list_insert               (GthImageList  *image_list,
 						    int            pos,
 						    GdkPixbuf     *pixbuf,
 						    const char    *text,
-						    const char    *comment);
+						    const char    *comment,
+                                                    const char    *categories);
 int            gth_image_list_append               (GthImageList  *image_list,
 						    GdkPixbuf     *pixbuf,
 						    const char    *text,
-						    const char    *comment);
+						    const char    *comment,
+                                                    const char    *categories);
 int            gth_image_list_append_with_data     (GthImageList  *image_list,
 						    GdkPixbuf     *pixbuf,
 						    const char    *text,
 						    const char    *comment,
+                                                    const char    *categories,
 						    gpointer       data);
 void           gth_image_list_remove               (GthImageList  *image_list,
 						    gpointer       data);
@@ -171,6 +176,9 @@ const char*    gth_image_list_get_image_text       (GthImageList  *image_list,
 void           gth_image_list_set_image_comment    (GthImageList  *image_list,
 						    int            pos,
 						    const char    *comment);
+void           gth_image_list_set_image_categories (GthImageList  *image_list,
+						    int            pos,
+						    const char    *categories);
 const char*    gth_image_list_get_image_comment    (GthImageList  *image_list,
 						    int            pos);
 int            gth_image_list_get_images           (GthImageList  *image_list);
@@ -213,8 +221,8 @@ gpointer       gth_image_list_get_image_data       (GthImageList    *image_list,
 void           gth_image_list_enable_thumbs        (GthImageList *image_list,
 						    gboolean      enable_thumbs);
 void           gth_image_list_set_view_mode        (GthImageList *image_list,
-						    GthViewMode   mode);
-GthViewMode    gth_image_list_get_view_mode        (GthImageList *image_list);
+						    int           mode);
+int            gth_image_list_get_view_mode        (GthImageList *image_list);
 void           gth_image_list_moveto               (GthImageList *image_list,
 						    int           pos,
 						    double        yalign);
diff --git a/libgthumb/preferences.c b/libgthumb/preferences.c
index 2fb9cc3..4b51a55 100644
--- a/libgthumb/preferences.c
+++ b/libgthumb/preferences.c
@@ -515,25 +515,26 @@ GET_SET_FUNC(image_resolution,       PREF_PRINT_IMAGE_RESOLUTION,     GthImageRe
 GET_SET_FUNC(crop_ratio,             PREF_CROP_ASPECT_RATIO,          GthCropRatio)
 GET_SET_FUNC(import_subfolder,       PREF_PHOTO_IMPORT_SUBFOLDER,     GthSubFolder)
 
-GthViewMode
+int
 pref_get_view_mode (void)
 {
+        int view_mode = 0;
 	gboolean view_filenames;
 	gboolean view_comments;
+	gboolean view_categories;
 
 	view_filenames = eel_gconf_get_boolean (PREF_SHOW_FILENAMES, FALSE);
 	view_comments = eel_gconf_get_boolean (PREF_SHOW_COMMENTS, TRUE);
+	view_categories = eel_gconf_get_boolean (PREF_SHOW_CATEGORIES, TRUE);
 
-	if (view_filenames && view_comments)
-		return GTH_VIEW_MODE_ALL;
-	else if (view_filenames && ! view_comments)
-		return GTH_VIEW_MODE_LABEL;
-	else if (! view_filenames && view_comments)
-		return GTH_VIEW_MODE_COMMENTS;
-	else if (! view_filenames && ! view_comments)
-		return GTH_VIEW_MODE_VOID;
+        if (view_filenames)
+                view_mode |= GTH_VIEW_MODE_LABEL;
+        if (view_comments)
+                view_mode |= GTH_VIEW_MODE_COMMENTS;
+        if (view_categories)
+                view_mode |= GTH_VIEW_MODE_CATEGORIES;
 
-	return GTH_VIEW_MODE_VOID;
+	return view_mode;
 }
 
 
diff --git a/libgthumb/preferences.h b/libgthumb/preferences.h
index 60146b8..51325e9 100644
--- a/libgthumb/preferences.h
+++ b/libgthumb/preferences.h
@@ -49,6 +49,7 @@
 #define  PREF_SHOW_FILENAMES         "/apps/gthumb/browser/show_filenames"
 #define  PREF_SHOW_COMMENTS          "/apps/gthumb/browser/show_comments"
 #define  PREF_SHOW_THUMBNAILS        "/apps/gthumb/browser/show_thumbnails"
+#define  PREF_SHOW_CATEGORIES        "/apps/gthumb/browser/show_categories"
 #define  PREF_FAST_FILE_TYPE         "/apps/gthumb/browser/fast_file_type"
 #define  PREF_SAVE_THUMBNAILS        "/apps/gthumb/browser/save_thumbnails"
 #define  PREF_THUMBNAIL_SIZE         "/apps/gthumb/browser/thumbnail_size"
@@ -316,7 +317,7 @@ GthViewAs          pref_get_view_as                (void);
 void               pref_set_view_as                (GthViewAs value);
 void               pref_set_preview_content        (GthPreviewContent value);
 GthPreviewContent  pref_get_preview_content        (void);
-GthViewMode        pref_get_view_mode              (void);
+int                pref_get_view_mode              (void);
 void               pref_set_print_unit             (GthPrintUnit value);
 GthPrintUnit       pref_get_print_unit             (void);
 void               pref_set_image_unit             (GthPrintUnit value);
diff --git a/libgthumb/typedefs.h b/libgthumb/typedefs.h
index 23c7374..d73bf3d 100644
--- a/libgthumb/typedefs.h
+++ b/libgthumb/typedefs.h
@@ -90,15 +90,11 @@ typedef enum { /*< skip >*/
 } GthSidebarContent;
 
 
-typedef enum { /*< skip >*/
-	GTH_VIEW_MODE_VOID,               /* No text at all. */
-	GTH_VIEW_MODE_LABEL,              /* Display label. */
-	GTH_VIEW_MODE_COMMENTS,           /* Display comment. */
- 	GTH_VIEW_MODE_COMMENTS_OR_TEXT,   /* When a comment is present do
-					   * not display text. */
-	GTH_VIEW_MODE_ALL                 /* Display comment and text. */
-} GthViewMode;
-
+enum { /*< skip >*/
+	GTH_VIEW_MODE_LABEL = 0x1,              /* Display label. */
+	GTH_VIEW_MODE_COMMENTS = 0x2,           /* Display comment. */
+	GTH_VIEW_MODE_CATEGORIES = 0x4,         /* Display categories. */
+};
 
 typedef enum { /*< skip >*/
 	GTH_VIEW_AS_LIST = 0,
diff --git a/src/dlg-photo-importer.c b/src/dlg-photo-importer.c
index 03c0265..fa6a115 100644
--- a/src/dlg-photo-importer.c
+++ b/src/dlg-photo-importer.c
@@ -850,6 +850,7 @@ load_images_preview__step (AsyncOperationData *aodata,
 						 pixbuf,
 						 camera_filename,
 						 NULL,
+						 NULL,
 						 fdata);
 						 
 		g_object_unref (pixbuf);
diff --git a/src/dlg-preferences.c b/src/dlg-preferences.c
index 4083b30..7a7178f 100644
--- a/src/dlg-preferences.c
+++ b/src/dlg-preferences.c
@@ -81,6 +81,7 @@ typedef struct {
 	GtkWidget  *toggle_show_filenames;
 	GtkWidget  *toggle_show_comments;
 	GtkWidget  *toggle_show_thumbs;
+	GtkWidget  *toggle_show_categories;
 	GtkWidget  *toggle_file_type;
 	GtkWidget  *toggle_audio_video;
 	GtkWidget  *opt_thumbs_size;
@@ -255,6 +256,14 @@ show_thumbs_toggled_cb (GtkToggleButton *button,
 
 
 static void
+show_categories_toggled_cb (GtkToggleButton *button,
+                            DialogData      *data)
+{
+	eel_gconf_set_boolean (PREF_SHOW_CATEGORIES, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->toggle_show_categories)));
+}
+
+
+static void
 show_filenames_toggled_cb (GtkToggleButton *button,
 			   DialogData      *data)
 {
@@ -414,6 +423,7 @@ dlg_preferences (GthBrowser *browser)
         data->toggle_show_comments = glade_xml_get_widget (data->gui, "toggle_show_comments");
 
         data->toggle_show_thumbs = glade_xml_get_widget (data->gui, "toggle_show_thumbs");
+        data->toggle_show_categories = glade_xml_get_widget (data->gui, "toggle_show_categories");
         data->toggle_file_type = glade_xml_get_widget (data->gui, "toggle_file_type");
 	data->toggle_audio_video = glade_xml_get_widget (data->gui, "toggle_audio_video");
 
@@ -492,6 +502,7 @@ dlg_preferences (GthBrowser *browser)
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->toggle_show_filenames), eel_gconf_get_boolean (PREF_SHOW_FILENAMES, FALSE));
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->toggle_show_comments), eel_gconf_get_boolean (PREF_SHOW_COMMENTS, TRUE));
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->toggle_show_thumbs), eel_gconf_get_boolean (PREF_SHOW_THUMBNAILS, TRUE));
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->toggle_show_categories), eel_gconf_get_boolean (PREF_SHOW_CATEGORIES, TRUE));
 	gtk_option_menu_set_history (GTK_OPTION_MENU (data->opt_thumbs_size), get_idx_from_size (eel_gconf_get_integer (PREF_THUMBNAIL_SIZE, 95)));
 	gtk_option_menu_set_history (GTK_OPTION_MENU (data->opt_click_policy), pref_get_click_policy ());
 
@@ -573,6 +584,10 @@ dlg_preferences (GthBrowser *browser)
 			  "toggled",
 			  G_CALLBACK (show_thumbs_toggled_cb),
 			  data);
+	g_signal_connect (G_OBJECT (data->toggle_show_categories),
+			  "toggled",
+			  G_CALLBACK (show_categories_toggled_cb),
+			  data);
 	g_signal_connect (G_OBJECT (data->toggle_show_filenames),
 			  "toggled",
 			  G_CALLBACK (show_filenames_toggled_cb),
diff --git a/src/gth-browser.c b/src/gth-browser.c
index 642631f..125837c 100644
--- a/src/gth-browser.c
+++ b/src/gth-browser.c
@@ -71,7 +71,7 @@
 #include "jpegutils/jpeg-data.h"
 #include "icons/pixbufs.h"
 
-#define GCONF_NOTIFICATIONS 21
+#define GCONF_NOTIFICATIONS 22
 
 #define VIEW_AS_DELAY 500
 
@@ -4691,18 +4691,7 @@ pref_show_thumbnails_changed (GConfClient *client,
 
 
 static void
-pref_show_filenames_changed (GConfClient *client,
-			     guint        cnxn_id,
-			     GConfEntry  *entry,
-			     gpointer     user_data)
-{
-	GthBrowser  *browser = user_data;
-	gth_file_view_set_view_mode (browser->priv->file_list->view, pref_get_view_mode ());
-}
-
-
-static void
-pref_show_comments_changed (GConfClient *client,
+pref_view_mode_changed (GConfClient *client,
 			    guint        cnxn_id,
 			    GConfEntry  *entry,
 			    gpointer     user_data)
@@ -7042,12 +7031,17 @@ gth_browser_construct (GthBrowser  *browser,
 
 	priv->cnxn_id[i++] = eel_gconf_notification_add (
 					   PREF_SHOW_FILENAMES,
-					   pref_show_filenames_changed,
+					   pref_view_mode_changed,
 					   browser);
 
 	priv->cnxn_id[i++] = eel_gconf_notification_add (
 					   PREF_SHOW_COMMENTS,
-					   pref_show_comments_changed,
+					   pref_view_mode_changed,
+					   browser);
+
+	priv->cnxn_id[i++] = eel_gconf_notification_add (
+					   PREF_SHOW_CATEGORIES,
+					   pref_view_mode_changed,
 					   browser);
 
 	priv->cnxn_id[i++] = eel_gconf_notification_add (



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