[gthumb/ext] added a tags expander in the metadata dialog



commit 270d5d00418829a78478361fb68c002321f10e45
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Oct 24 21:30:46 2009 +0200

    added a tags expander in the metadata dialog

 extensions/comments/data/ui/edit-comment-page.ui |   27 ++-
 extensions/comments/gth-edit-comment-page.c      |   16 +-
 extensions/photo_importer/dlg-photo-importer.c   |    2 +-
 gthumb/Makefile.am                               |    2 +
 gthumb/gth-tags-entry.c                          |   66 ++---
 gthumb/gth-tags-entry.h                          |    5 +-
 gthumb/gth-tags-expander.c                       |  378 ++++++++++++++++++++++
 gthumb/gth-tags-expander.h                       |   55 ++++
 gthumb/gth-tags-file.c                           |   49 +++-
 9 files changed, 534 insertions(+), 66 deletions(-)
---
diff --git a/extensions/comments/data/ui/edit-comment-page.ui b/extensions/comments/data/ui/edit-comment-page.ui
index d9012e4..683f166 100644
--- a/extensions/comments/data/ui/edit-comment-page.ui
+++ b/extensions/comments/data/ui/edit-comment-page.ui
@@ -106,6 +106,7 @@
       <object class="GtkVBox" id="date_datetime_container">
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
         <child>
           <placeholder/>
         </child>
@@ -119,29 +120,39 @@
       </packing>
     </child>
     <child>
-      <object class="GtkLabel" id="label1">
+      <object class="GtkHBox" id="tags_entry_container">
         <property name="visible">True</property>
-        <property name="xalign">0</property>
-        <property name="label" translatable="yes">_Tags:</property>
-        <property name="use_underline">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child>
+          <placeholder/>
+        </child>
       </object>
       <packing>
+        <property name="left_attach">1</property>
+        <property name="right_attach">2</property>
         <property name="top_attach">4</property>
         <property name="bottom_attach">5</property>
       </packing>
     </child>
     <child>
-      <object class="GtkHBox" id="tags_entry_container">
+      <object class="GtkAlignment" id="alignment1">
         <property name="visible">True</property>
+        <property name="top_padding">2</property>
         <child>
-          <placeholder/>
+          <object class="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+            <property name="label" translatable="yes">_Tags:</property>
+            <property name="use_underline">True</property>
+          </object>
         </child>
       </object>
       <packing>
-        <property name="left_attach">1</property>
-        <property name="right_attach">2</property>
         <property name="top_attach">4</property>
         <property name="bottom_attach">5</property>
+        <property name="y_options">GTK_FILL</property>
       </packing>
     </child>
     <child>
diff --git a/extensions/comments/gth-edit-comment-page.c b/extensions/comments/gth-edit-comment-page.c
index c7e5298..8798f08 100644
--- a/extensions/comments/gth-edit-comment-page.c
+++ b/extensions/comments/gth-edit-comment-page.c
@@ -166,7 +166,7 @@ gth_edit_comment_page_real_update_info (GthEditMetadataPage *base,
 
 	/* tags */
 
-	tagv = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (self->priv->tags_entry));
+	tagv = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (self->priv->tags_entry), TRUE);
 	tags = NULL;
 	for (i = 0; tagv[i] != NULL; i++)
 		tags = g_list_prepend (tags, tagv[i]);
@@ -275,6 +275,8 @@ date_combobox_changed_cb (GtkComboBox *widget,
 static void
 gth_edit_comment_page_init (GthEditCommentPage *self)
 {
+	GtkWidget *expander;
+
 	self->priv = GTH_EDIT_COMMENT_PAGE_GET_PRIVATE (self);
 
 	gtk_container_set_border_width (GTK_CONTAINER (self), 12);
@@ -296,9 +298,9 @@ gth_edit_comment_page_init (GthEditCommentPage *self)
   	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("date_combobox_container")), self->priv->date_combobox, FALSE, FALSE, 0);
 
   	g_signal_connect (self->priv->date_combobox,
-			    "changed",
-			    G_CALLBACK (date_combobox_changed_cb),
-			    self);
+			  "changed",
+			  G_CALLBACK (date_combobox_changed_cb),
+			  self);
 
   	self->priv->date_datetime = gtk_entry_new ();
   	gtk_widget_show (self->priv->date_datetime);
@@ -306,7 +308,11 @@ gth_edit_comment_page_init (GthEditCommentPage *self)
 
   	self->priv->tags_entry = gth_tags_entry_new ();
   	gtk_widget_show (self->priv->tags_entry);
-  	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("tags_entry_container")), self->priv->tags_entry, TRUE, TRUE, 0);
+  	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("tags_entry_container")), self->priv->tags_entry, FALSE, FALSE, 0);
+
+  	expander = gth_tags_expander_new (GTK_ENTRY (self->priv->tags_entry));
+  	gtk_widget_show (expander);
+  	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("tags_entry_container")), expander, TRUE, TRUE, 0);
 }
 
 
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 95c28e8..55250cf 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -120,7 +120,7 @@ destroy_dialog (gpointer user_data)
 
 		file_store = (GthFileStore *) gth_file_view_get_model (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (data->file_list))));
 		files = gth_file_store_get_checked (file_store);
-		tags = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (data->tags_entry));
+		tags = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (data->tags_entry), TRUE);
 		task = gth_import_task_new (data->browser,
 					    files,
 					    destination,
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index fa36212..f687bb9 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -86,6 +86,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-stock.h					\
 	gth-string-list.h				\
 	gth-tags-entry.h				\
+	gth-tags-expander.h				\
 	gth-tags-file.h					\
 	gth-task.h					\
 	gth-test.h					\
@@ -203,6 +204,7 @@ gthumb_SOURCES = 					\
 	gth-statusbar.c					\
 	gth-string-list.c				\
 	gth-tags-entry.c				\
+	gth-tags-expander.c				\
 	gth-tags-file.c					\
 	gth-task.c					\
 	gth-test.c					\
diff --git a/gthumb/gth-tags-entry.c b/gthumb/gth-tags-entry.c
index bca0c7b..3f8ad6e 100644
--- a/gthumb/gth-tags-entry.c
+++ b/gthumb/gth-tags-entry.c
@@ -310,18 +310,6 @@ completion_action_activated_cb (GtkEntryCompletion *widget,
 }
 
 
-static int
-sort_tag_by_name (gconstpointer a,
-		  gconstpointer b,
-		  gpointer      user_data)
-{
-	char *sa = * (char **) a;
-	char *sb = * (char **) b;
-
-	return g_utf8_collate (sa, sb);
-}
-
-
 static void
 update_tag_list (GthTagsEntry *self)
 {
@@ -342,36 +330,6 @@ update_tag_list (GthTagsEntry *self)
 				    -1);
 	}
 
-	if ((self->priv->tags == NULL) || self->priv->tags[0] == NULL) {
-		char *default_tags[] = { N_("Holidays"),
-                                         N_("Temporary"),
-                                         N_("Screenshots"),
-                                         N_("Science"),
-                                         N_("Favorite"),
-                                         N_("Important"),
-                                         N_("GNOME"),
-                                         N_("Games"),
-                                         N_("Party"),
-                                         N_("Birthday"),
-                                         N_("Astronomy"),
-                                         N_("Family"),
-                                         NULL };
-
-		if (self->priv->tags != NULL)
-			g_strfreev (self->priv->tags);
-
-		self->priv->tags = g_new (char *, g_strv_length (default_tags) + 1);
-		for (i = 0; default_tags[i] != NULL; i++)
-			self->priv->tags[i] = g_strdup (_(default_tags[i]));
-		self->priv->tags[i] = NULL;
-	}
-
-	g_qsort_with_data (self->priv->tags,
-			   g_strv_length (self->priv->tags),
-			   sizeof (char *),
-			   sort_tag_by_name,
-			   NULL);
-
 	gtk_list_store_clear (self->priv->store);
 	for (i = 0; self->priv->tags[i] != NULL; i++) {
 		GtkTreeIter iter;
@@ -465,7 +423,8 @@ gth_tags_entry_new (void)
 
 
 char **
-gth_tags_entry_get_tags (GthTagsEntry *self)
+gth_tags_entry_get_tags (GthTagsEntry *self,
+			 gboolean      update_globals)
 {
 	GthTagsFile  *tags_file;
 	char        **all_tags;
@@ -487,10 +446,23 @@ gth_tags_entry_get_tags (GthTagsEntry *self)
 	}
 	g_strfreev (all_tags);
 
-	for (i = 0; self->priv->tags[i] != NULL; i++)
-		gth_tags_file_add (tags_file, self->priv->tags[i]);
-
-	gth_main_tags_changed ();
+	if (update_globals) {
+		for (i = 0; self->priv->tags[i] != NULL; i++)
+			gth_tags_file_add (tags_file, self->priv->tags[i]);
+		gth_main_tags_changed ();
+	}
 
 	return tags;
 }
+
+
+void
+gth_tags_entry_set_tags (GthTagsEntry  *self,
+			 char         **tags)
+{
+	char *s;
+
+	s = g_strjoinv(", ", tags);
+	gtk_entry_set_text (GTK_ENTRY (self), s);
+	g_free (s);
+}
diff --git a/gthumb/gth-tags-entry.h b/gthumb/gth-tags-entry.h
index e36948e..c91cf58 100644
--- a/gthumb/gth-tags-entry.h
+++ b/gthumb/gth-tags-entry.h
@@ -49,7 +49,10 @@ struct _GthTagsEntryClass {
 
 GType        gth_tags_entry_get_type  (void);
 GtkWidget *  gth_tags_entry_new       (void);
-char **      gth_tags_entry_get_tags  (GthTagsEntry  *self);
+char **      gth_tags_entry_get_tags  (GthTagsEntry  *self,
+				       gboolean       update_globals);
+void         gth_tags_entry_set_tags  (GthTagsEntry  *self,
+				       char         **tags);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-tags-expander.c b/gthumb/gth-tags-expander.c
new file mode 100644
index 0000000..dc3abd2
--- /dev/null
+++ b/gthumb/gth-tags-expander.c
@@ -0,0 +1,378 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include "gth-main.h"
+#include "gth-tags-entry.h"
+#include "gth-tags-expander.h"
+#include "gth-tags-file.h"
+#include "glib-utils.h"
+
+
+enum {
+	USED_COLUMN,
+	NAME_COLUMN,
+	N_COLUMNS
+};
+
+
+struct _GthTagsExpanderPrivate {
+	GtkEntry            *entry;
+	char               **tags;
+	GtkWidget           *tree_view;
+	GtkListStore        *store;
+	gulong               monitor_event;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_tags_expander_finalize (GObject *obj)
+{
+	GthTagsExpander *self;
+
+	self = GTH_TAGS_EXPANDER (obj);
+
+	g_signal_handler_disconnect (gth_main_get_default_monitor (), self->priv->monitor_event);
+	g_strfreev (self->priv->tags);
+
+	G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+
+static void
+gth_tags_expander_class_init (GthTagsExpanderClass *klass)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthTagsExpanderPrivate));
+
+	object_class = (GObjectClass*) (klass);
+	object_class->finalize = gth_tags_expander_finalize;
+}
+
+
+static void
+update_tag_list (GthTagsExpander *self)
+{
+	GthTagsFile *tags;
+	int          i;
+
+	tags = gth_main_get_default_tag_file ();
+
+	g_strfreev (self->priv->tags);
+	self->priv->tags = g_strdupv (gth_tags_file_get_tags (tags));
+
+	for (i = 0; self->priv->tags[i] != NULL; i++) {
+		GtkTreeIter iter;
+
+		gtk_list_store_append (self->priv->store, &iter);
+		gtk_list_store_set (self->priv->store, &iter,
+				    NAME_COLUMN, self->priv->tags[i],
+				    -1);
+	}
+
+	gtk_list_store_clear (self->priv->store);
+	for (i = 0; self->priv->tags[i] != NULL; i++) {
+		GtkTreeIter iter;
+
+		gtk_list_store_append (self->priv->store, &iter);
+		gtk_list_store_set (self->priv->store, &iter,
+				    NAME_COLUMN, self->priv->tags[i],
+				    -1);
+	}
+}
+
+
+static void
+tags_changed_cb (GthMonitor      *monitor,
+		 GthTagsExpander *self)
+{
+	update_tag_list (self);
+}
+
+
+static void
+update_list_view_from_entry (GthTagsExpander *self)
+{
+	char        **tags;
+	GtkTreeIter   iter;
+
+	tags = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (self->priv->entry), FALSE);
+	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->store), &iter))
+		do {
+			char     *name;
+			gboolean  used = FALSE;
+			int       i;
+
+			gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), &iter,
+					    NAME_COLUMN, &name,
+					    -1);
+
+			for (i = 0; ! used && (tags[i] != NULL); i++)
+				if (g_utf8_collate (name, tags[i]) == 0)
+					used = TRUE;
+
+			gtk_list_store_set (self->priv->store, &iter,
+					    USED_COLUMN, used,
+					    -1);
+
+			g_free (name);
+		}
+		while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->store), &iter));
+
+	g_strfreev (tags);
+}
+
+
+
+static void
+update_entry_from_list_view (GthTagsExpander *self)
+{
+	GtkTreeIter   iter;
+	GList        *name_list;
+	char        **tags;
+	GList        *scan;
+	int           i;
+
+	if (! gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->store), &iter))
+		return;
+
+	name_list = NULL;
+	do {
+		char     *name;
+		gboolean  used;
+
+		gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), &iter,
+				    NAME_COLUMN, &name,
+				    USED_COLUMN, &used,
+				    -1);
+
+		if (used)
+			name_list = g_list_prepend (name_list, name);
+		else
+			g_free (name);
+	}
+	while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->store), &iter));
+
+	if (name_list == NULL)
+		return;
+
+	name_list = g_list_reverse (name_list);
+	tags = g_new (char *, g_list_length (name_list) + 1);
+	for (i = 0, scan = name_list; scan; scan = scan->next)
+		tags[i++] = scan->data;
+	tags[i] = NULL;
+	gth_tags_entry_set_tags (GTH_TAGS_ENTRY (self->priv->entry), tags);
+
+	g_free (tags);
+	_g_string_list_free (name_list);
+}
+
+
+static void
+cell_renderer_toggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
+				 char                  *path,
+                                 gpointer               user_data)
+{
+	GthTagsExpander *self = user_data;
+	GtkTreePath     *tpath;
+	GtkTreeModel    *tree_model;
+	GtkTreeIter      iter;
+
+	tpath = gtk_tree_path_new_from_string (path);
+	if (tpath == NULL)
+		return;
+
+	tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->tree_view));
+	if (gtk_tree_model_get_iter (tree_model, &iter, tpath)) {
+		gboolean used;
+
+		gtk_tree_model_get (tree_model, &iter,
+				    USED_COLUMN, &used,
+				    -1);
+		gtk_list_store_set (GTK_LIST_STORE (tree_model), &iter,
+				    USED_COLUMN, ! used,
+				    -1);
+	}
+
+	update_entry_from_list_view (self);
+
+	gtk_tree_path_free (tpath);
+}
+
+
+static void
+tag_list_map_cb (GtkWidget       *widget,
+		 GthTagsExpander *self)
+{
+	GtkWidget   *toplevel;
+        GdkGeometry  geometry;
+
+return; /* FIXME */
+
+        toplevel = gtk_widget_get_toplevel (widget);
+        if (! GTK_WIDGET_TOPLEVEL (toplevel))
+        	return;
+
+        geometry.min_width = -1;
+        geometry.min_height = 230;
+        gtk_window_set_geometry_hints (GTK_WINDOW (toplevel),
+				       widget,
+				       &geometry,
+                                       GDK_HINT_MIN_SIZE);
+}
+
+
+static void
+tag_list_unmap_cb (GtkWidget       *widget,
+	           GthTagsExpander *self)
+{
+	GtkWidget   *toplevel;
+        GdkGeometry  geometry;
+
+        toplevel = gtk_widget_get_toplevel (widget);
+        if (! GTK_WIDGET_TOPLEVEL (toplevel))
+        	return;
+
+        geometry.max_height = -1;
+        geometry.max_width = G_MAXINT;
+        gtk_window_set_geometry_hints (GTK_WINDOW (toplevel),
+				       toplevel,
+                                       &geometry,
+                                       GDK_HINT_MAX_SIZE);
+}
+
+
+static void
+gth_tags_expander_instance_init (GthTagsExpander *self)
+{
+	GtkTreeViewColumn *column;
+	GtkCellRenderer   *renderer;
+	GtkWidget         *scrolled_window;
+
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TAGS_EXPANDER, GthTagsExpanderPrivate);
+
+	/* the treeview */
+
+	self->priv->store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
+	self->priv->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->priv->store));
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->tree_view), FALSE);
+	g_object_unref (self->priv->store);
+
+	/* the checkbox column */
+
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_toggle_new ();
+	g_signal_connect (renderer,
+			  "toggled",
+			  G_CALLBACK (cell_renderer_toggle_toggled_cb),
+			  self);
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_attributes (column, renderer,
+					     "active", USED_COLUMN,
+					     NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->tree_view), column);
+
+	/* the name 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", NAME_COLUMN,
+                                             NULL);
+        gtk_tree_view_column_set_expand (column, TRUE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->tree_view), column);
+
+	self->priv->monitor_event = g_signal_connect (gth_main_get_default_monitor (),
+						      "tags-changed",
+						      G_CALLBACK (tags_changed_cb),
+						      self);
+	gtk_widget_show (self->priv->tree_view);
+
+	/* the scrolled window */
+
+	scrolled_window = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
+					"hadjustment", NULL,
+					"vadjustment", NULL,
+					"hscrollbar_policy", GTK_POLICY_AUTOMATIC,
+					"vscrollbar_policy", GTK_POLICY_AUTOMATIC,
+					"shadow_type", GTK_SHADOW_IN,
+					NULL);
+	gtk_widget_set_size_request (scrolled_window, -1, 230);
+	gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->tree_view);
+	g_signal_connect (scrolled_window, "map", G_CALLBACK (tag_list_map_cb), self);
+	g_signal_connect (scrolled_window, "unmap", G_CALLBACK (tag_list_unmap_cb), self);
+	gtk_widget_show (scrolled_window);
+	gtk_container_add (GTK_CONTAINER (self), scrolled_window);
+}
+
+
+GType
+gth_tags_expander_get_type (void)
+{
+	static GType type = 0;
+
+	if (type == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthTagsExpanderClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_tags_expander_class_init,
+			NULL,
+			NULL,
+			sizeof (GthTagsExpander),
+			0,
+			(GInstanceInitFunc) gth_tags_expander_instance_init,
+			NULL
+		};
+		type = g_type_register_static (GTK_TYPE_EXPANDER,
+					       "GthTagsExpander",
+					       &g_define_type_info,
+					       0);
+	}
+
+	return type;
+}
+
+
+GtkWidget *
+gth_tags_expander_new (GtkEntry *entry)
+{
+	GthTagsExpander *self;
+
+	self = g_object_new (GTH_TYPE_TAGS_EXPANDER, "label", _("_Show all the tags"), "use-underline", TRUE, NULL);
+	self->priv->entry = entry;
+	update_tag_list (self);
+
+	g_signal_connect_swapped (self->priv->entry,
+				  "notify::text",
+				  G_CALLBACK (update_list_view_from_entry),
+				  self);
+
+	return (GtkWidget *) self;
+}
diff --git a/gthumb/gth-tags-expander.h b/gthumb/gth-tags-expander.h
new file mode 100644
index 0000000..bd17f6a
--- /dev/null
+++ b/gthumb/gth-tags-expander.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_TAGS_EXPANDER_H
+#define GTH_TAGS_EXPANDER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_TAGS_EXPANDER            (gth_tags_expander_get_type ())
+#define GTH_TAGS_EXPANDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_TAGS_EXPANDER, GthTagsExpander))
+#define GTH_TAGS_EXPANDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_TAGS_EXPANDER, GthTagsExpanderClass))
+#define GTH_IS_TAGS_EXPANDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_TAGS_EXPANDER))
+#define GTH_IS_TAGS_EXPANDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_TAGS_EXPANDER))
+#define GTH_TAGS_EXPANDER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_TAGS_EXPANDER, GthTagsExpanderClass))
+
+typedef struct _GthTagsExpander GthTagsExpander;
+typedef struct _GthTagsExpanderClass GthTagsExpanderClass;
+typedef struct _GthTagsExpanderPrivate GthTagsExpanderPrivate;
+
+struct _GthTagsExpander {
+	GtkExpander parent_instance;
+	GthTagsExpanderPrivate *priv;
+};
+
+struct _GthTagsExpanderClass {
+	GtkExpanderClass parent_class;
+};
+
+GType        gth_tags_expander_get_type  (void);
+GtkWidget *  gth_tags_expander_new       (GtkEntry *entry);
+
+G_END_DECLS
+
+#endif /* GTH_TAGS_EXPANDER_H */
diff --git a/gthumb/gth-tags-file.c b/gthumb/gth-tags-file.c
index 83e3189..2596c2d 100644
--- a/gthumb/gth-tags-file.c
+++ b/gthumb/gth-tags-file.c
@@ -22,6 +22,7 @@
 
 #include <config.h>
 #include <string.h>
+#include <glib/gi18n.h>
 #include "dom.h"
 #include "glib-utils.h"
 #include "gth-tags-file.h"
@@ -201,6 +202,18 @@ gth_tags_file_to_file (GthTagsFile  *tags,
 }
 
 
+static int
+sort_tag_by_name (gconstpointer a,
+		  gconstpointer b,
+		  gpointer      user_data)
+{
+	char *sa = * (char **) a;
+	char *sb = * (char **) b;
+
+	return g_utf8_collate (sa, sb);
+}
+
+
 char **
 gth_tags_file_get_tags (GthTagsFile *tags)
 {
@@ -212,10 +225,38 @@ gth_tags_file_get_tags (GthTagsFile *tags)
 		tags->tags = NULL;
 	}
 
-	tags->tags = g_new (char *, g_list_length (tags->items) + 1);
-	for (i = 0, scan = tags->items; scan; scan = scan->next)
-		tags->tags[i++] = g_strdup ((char *) scan->data);
-	tags->tags[i] = NULL;
+	if (g_list_length (tags->items) > 0) {
+		tags->tags = g_new (char *, g_list_length (tags->items) + 1);
+		for (i = 0, scan = tags->items; scan; scan = scan->next)
+			tags->tags[i++] = g_strdup ((char *) scan->data);
+		tags->tags[i] = NULL;
+	}
+	else {
+		char *default_tags[] = { N_("Holidays"),
+					 N_("Temporary"),
+					 N_("Screenshots"),
+					 N_("Science"),
+					 N_("Favorite"),
+					 N_("Important"),
+					 N_("GNOME"),
+					 N_("Games"),
+					 N_("Party"),
+					 N_("Birthday"),
+					 N_("Astronomy"),
+					 N_("Family"),
+					 NULL };
+
+		tags->tags = g_new (char *, g_strv_length (default_tags) + 1);
+		for (i = 0; default_tags[i] != NULL; i++)
+			tags->tags[i] = g_strdup (_(default_tags[i]));
+		tags->tags[i] = NULL;
+	}
+
+	g_qsort_with_data (tags->tags,
+			   g_strv_length (tags->tags),
+			   sizeof (char *),
+			   sort_tag_by_name,
+			   NULL);
 
 	return tags->tags;
 }



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