[gthumb/ext] [tags] load and save the default tags using a configuration file
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext] [tags] load and save the default tags using a configuration file
- Date: Fri, 21 Aug 2009 15:56:41 +0000 (UTC)
commit 2b1df2c3a8c05400293485c7ba0f09d9236d114c
Author: Paolo Bacchilega <paobac src gnome org>
Date: Fri Aug 21 17:53:17 2009 +0200
[tags] load and save the default tags using a configuration file
extensions/comments/data/ui/edit-comment-page.ui | 6 +-
extensions/comments/gth-edit-comment-page.c | 2 +-
extensions/photo_importer/dlg-photo-importer.c | 2 +-
gthumb/Makefile.am | 2 +
gthumb/gth-main.c | 42 +++-
gthumb/gth-main.h | 4 +
gthumb/gth-monitor.c | 21 ++
gthumb/gth-monitor.h | 2 +
gthumb/gth-tags-entry.c | 329 +++++++++++++++-------
gthumb/gth-tags-entry.h | 2 +-
gthumb/gth-tags-file.c | 263 +++++++++++++++++
gthumb/gth-tags-file.h | 59 ++++
gthumb/typedefs.h | 1 +
13 files changed, 620 insertions(+), 115 deletions(-)
---
diff --git a/extensions/comments/data/ui/edit-comment-page.ui b/extensions/comments/data/ui/edit-comment-page.ui
index 0a68fa6..d9012e4 100644
--- a/extensions/comments/data/ui/edit-comment-page.ui
+++ b/extensions/comments/data/ui/edit-comment-page.ui
@@ -131,9 +131,6 @@
</packing>
</child>
<child>
- <placeholder/>
- </child>
- <child>
<object class="GtkHBox" id="tags_entry_container">
<property name="visible">True</property>
<child>
@@ -147,5 +144,8 @@
<property name="bottom_attach">5</property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
</object>
</interface>
diff --git a/extensions/comments/gth-edit-comment-page.c b/extensions/comments/gth-edit-comment-page.c
index 63f3174..b30b99f 100644
--- a/extensions/comments/gth-edit-comment-page.c
+++ b/extensions/comments/gth-edit-comment-page.c
@@ -277,7 +277,7 @@ gth_edit_comment_page_init (GthEditCommentPage *self)
gtk_widget_show (self->priv->date_datetime);
gtk_box_pack_start (GTK_BOX (GET_WIDGET ("date_datetime_container")), self->priv->date_datetime, FALSE, FALSE, 0);
- self->priv->tags_entry = gth_tags_entry_new (NULL);
+ 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);
}
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index bdc1f8a..09277fa 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -707,7 +707,7 @@ dlg_photo_importer (GthBrowser *browser,
g_free (last_destination);
}
- data->tags_entry = gth_tags_entry_new (NULL);
+ data->tags_entry = gth_tags_entry_new ();
gtk_widget_show (data->tags_entry);
gtk_box_pack_start (GTK_BOX (GET_WIDGET ("tags_entry_box")), data->tags_entry, TRUE, TRUE, 0);
gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("tags_label")), data->tags_entry);
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 057b014..bd175cf 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -80,6 +80,7 @@ PUBLIC_HEADER_FILES = \
gth-stock.h \
gth-string-list.h \
gth-tags-entry.h \
+ gth-tags-file.h \
gth-task.h \
gth-test.h \
gth-test-chain.h \
@@ -189,6 +190,7 @@ gthumb_SOURCES = \
gth-statusbar.c \
gth-string-list.c \
gth-tags-entry.c \
+ gth-tags-file.c \
gth-task.c \
gth-test.c \
gth-test-chain.c \
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 491efb8..52dd13b 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -101,6 +101,7 @@ struct _GthMainPrivate
GHashTable *objects;
GBookmarkFile *bookmarks;
GthFilterFile *filters;
+ GthTagsFile *tags;
GthMonitor *monitor;
GthExtensionManager *extension_manager;
};
@@ -1034,15 +1035,54 @@ gth_main_filters_changed (void)
char *filename;
gth_user_dir_make_dir_for_file (GTH_DIR_CONFIG, GTHUMB_DIR, FILTERS_FILE, NULL);
-
filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, FILTERS_FILE, NULL);
gth_filter_file_to_file (Main->priv->filters, filename, NULL);
+
g_free (filename);
gth_monitor_filters_changed (gth_main_get_default_monitor ());
}
+GthTagsFile *
+gth_main_get_default_tag_file (void)
+{
+ char *path;
+
+ if (Main->priv->tags != NULL)
+ return Main->priv->tags;
+
+ Main->priv->tags = gth_tags_file_new ();
+ path = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, TAGS_FILE, NULL);
+ gth_tags_file_load_from_file (Main->priv->tags, path, NULL);
+ g_free (path);
+
+ return Main->priv->tags;
+}
+
+
+const char **
+gth_main_get_all_tags (void)
+{
+ return gth_tags_file_get_tags (gth_main_get_default_tag_file ());
+}
+
+
+void
+gth_main_tags_changed (void)
+{
+ char *filename;
+
+ gth_user_dir_make_dir_for_file (GTH_DIR_CONFIG, GTHUMB_DIR, TAGS_FILE, NULL);
+ filename = gth_user_dir_get_file (GTH_DIR_CONFIG, GTHUMB_DIR, TAGS_FILE, NULL);
+ gth_tags_file_to_file (Main->priv->tags, filename, NULL);
+
+ g_free (filename);
+
+ gth_monitor_tags_changed (gth_main_get_default_monitor ());
+}
+
+
GthMonitor *
gth_main_get_default_monitor (void)
{
diff --git a/gthumb/gth-main.h b/gthumb/gth-main.h
index c04b439..3c77467 100644
--- a/gthumb/gth-main.h
+++ b/gthumb/gth-main.h
@@ -33,6 +33,7 @@
#include "gth-hook.h"
#include "gth-metadata-provider.h"
#include "gth-monitor.h"
+#include "gth-tags-file.h"
#include "gth-test.h"
G_BEGIN_DECLS
@@ -108,6 +109,9 @@ void gth_main_bookmarks_changed (void);
GthFilterFile * gth_main_get_default_filter_file (void);
GList * gth_main_get_all_filters (void);
void gth_main_filters_changed (void);
+GthTagsFile * gth_main_get_default_tag_file (void);
+const char ** gth_main_get_all_tags (void);
+void gth_main_tags_changed (void);
GthMonitor * gth_main_get_default_monitor (void);
GthExtensionManager * gth_main_get_default_extension_manager (void);
void gth_main_register_default_hooks (void);
diff --git a/gthumb/gth-monitor.c b/gthumb/gth-monitor.c
index 471760d..043b083 100644
--- a/gthumb/gth-monitor.c
+++ b/gthumb/gth-monitor.c
@@ -35,6 +35,7 @@ enum {
ICON_THEME_CHANGED,
BOOKMARKS_CHANGED,
FILTERS_CHANGED,
+ TAGS_CHANGED,
FOLDER_CONTENT_CHANGED,
FILE_RENAMED,
METADATA_CHANGED,
@@ -110,6 +111,15 @@ gth_monitor_class_init (GthMonitorClass *class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+ monitor_signals[TAGS_CHANGED] =
+ g_signal_new ("tags-changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GthMonitorClass, tags_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
monitor_signals[FOLDER_CONTENT_CHANGED] =
g_signal_new ("folder-changed",
G_TYPE_FROM_CLASS (class),
@@ -238,6 +248,17 @@ gth_monitor_filters_changed (GthMonitor *monitor)
void
+gth_monitor_tags_changed (GthMonitor *monitor)
+{
+ g_return_if_fail (GTH_IS_MONITOR (monitor));
+
+ g_signal_emit (G_OBJECT (monitor),
+ monitor_signals[TAGS_CHANGED],
+ 0);
+}
+
+
+void
gth_monitor_folder_changed (GthMonitor *monitor,
GFile *parent,
GList *list,
diff --git a/gthumb/gth-monitor.h b/gthumb/gth-monitor.h
index 8a7e589..1fb562d 100644
--- a/gthumb/gth-monitor.h
+++ b/gthumb/gth-monitor.h
@@ -62,6 +62,7 @@ struct _GthMonitorClass
void (*icon_theme_changed) (GthMonitor *monitor);
void (*bookmarks_changed) (GthMonitor *monitor);
void (*filters_changed) (GthMonitor *monitor);
+ void (*tags_changed) (GthMonitor *monitor);
void (*folder_changed) (GthMonitor *monitor,
GFile *parent,
GList *list,
@@ -81,6 +82,7 @@ void gth_monitor_resume (GthMonitor *monitor);
void gth_monitor_icon_theme_changed (GthMonitor *monitor);
void gth_monitor_bookmarks_changed (GthMonitor *monitor);
void gth_monitor_filters_changed (GthMonitor *monitor);
+void gth_monitor_tags_changed (GthMonitor *monitor);
void gth_monitor_folder_changed (GthMonitor *monitor,
GFile *parent,
GList *list,
diff --git a/gthumb/gth-tags-entry.c b/gthumb/gth-tags-entry.c
index d316bc2..090b1f9 100644
--- a/gthumb/gth-tags-entry.c
+++ b/gthumb/gth-tags-entry.c
@@ -22,7 +22,9 @@
#include <config.h>
#include <glib/gi18n.h>
+#include "gth-main.h"
#include "gth-tags-entry.h"
+#include "gth-tags-file.h"
enum {
@@ -30,11 +32,6 @@ enum {
N_COLUMNS
};
-enum {
- PROP_0,
- PROP_TAGS
-};
-
struct _GthTagsEntryPrivate {
char **tags;
@@ -42,6 +39,7 @@ struct _GthTagsEntryPrivate {
GtkListStore *store;
char *new_tag;
gboolean action_create;
+ gulong monitor_event;
};
@@ -49,56 +47,17 @@ static gpointer parent_class = NULL;
static void
-gth_tags_entry_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GthTagsEntry *self;
-
- self = GTH_TAGS_ENTRY (object);
-
- switch (property_id) {
- case PROP_TAGS:
- g_value_set_boxed (value, self->priv->tags);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-
-static void
-gth_tags_entry_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GthTagsEntry *self;
-
- self = GTH_TAGS_ENTRY (object);
-
- switch (property_id) {
- case PROP_TAGS:
- self->priv->tags = g_strdupv (g_value_get_boxed (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-
-static void
gth_tags_entry_finalize (GObject *obj)
{
GthTagsEntry *self;
self = GTH_TAGS_ENTRY (obj);
+ g_signal_handler_disconnect (gth_main_get_default_monitor (), self->priv->monitor_event);
+
g_free (self->priv->new_tag);
g_object_unref (self->priv->completion);
+ g_strfreev (self->priv->tags);
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@@ -113,17 +72,7 @@ gth_tags_entry_class_init (GthTagsEntryClass *klass)
g_type_class_add_private (klass, sizeof (GthTagsEntryPrivate));
object_class = (GObjectClass*) (klass);
- object_class->get_property = gth_tags_entry_get_property;
- object_class->set_property = gth_tags_entry_set_property;
object_class->finalize = gth_tags_entry_finalize;
-
- g_object_class_install_property (object_class,
- PROP_TAGS,
- g_param_spec_boxed ("tags",
- "Tags",
- "List of tags",
- G_TYPE_STRV,
- G_PARAM_READWRITE));
}
@@ -171,16 +120,36 @@ get_tag_limits (GthTagsEntry *self,
}
+static gboolean
+can_create_tag (GthTagsEntry *self,
+ const char *tag)
+{
+ int i;
+
+ if (tag == NULL)
+ return FALSE;
+ if (tag[0] == '\0')
+ return FALSE;
+
+ for (i = 0; self->priv->tags[i] != NULL; i++)
+ if (strcmp (self->priv->tags[i], tag) == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+
static void
text_changed_cb (GthTagsEntry *self)
{
const char *tag_start;
const char *tag_end;
+ g_free (self->priv->new_tag);
+ self->priv->new_tag = NULL;
+
if (self->priv->action_create) {
gtk_entry_completion_delete_action (self->priv->completion, 0);
- g_free (self->priv->new_tag);
- self->priv->new_tag = NULL;
self->priv->action_create = FALSE;
}
@@ -190,10 +159,10 @@ text_changed_cb (GthTagsEntry *self)
self->priv->new_tag = g_strndup (tag_start, tag_end - tag_start);
self->priv->new_tag = g_strstrip (self->priv->new_tag);
- if (self->priv->new_tag[0] != '\0') {
+
+ if (can_create_tag (self, self->priv->new_tag)) {
char *action_text;
- /* â??%sâ?? */
action_text = g_strdup_printf (_("Create tag «%s»"), self->priv->new_tag);
gtk_entry_completion_insert_action_text (self->priv->completion, 0, action_text);
self->priv->action_create = TRUE;
@@ -211,8 +180,6 @@ match_func (GtkEntryCompletion *completion,
{
GthTagsEntry *self = user_data;
char *name;
- char *k1;
- char *k2;
gboolean result;
if (self->priv->new_tag == NULL)
@@ -224,13 +191,23 @@ match_func (GtkEntryCompletion *completion,
gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), iter,
NAME_COLUMN, &name,
-1);
- k1 = g_utf8_casefold (self->priv->new_tag, -1);
- k2 = g_utf8_casefold (name, strlen (self->priv->new_tag));
- result = g_utf8_collate (k1, k2) == 0;
+ if (name != NULL) {
+ char *k1;
+ char *k2;
+
+ k1 = g_utf8_casefold (self->priv->new_tag, -1);
+ k2 = g_utf8_casefold (name, strlen (self->priv->new_tag));
+
+ result = g_utf8_collate (k1, k2) == 0;
+
+
+ g_free (k2);
+ g_free (k1);
+ }
+ else
+ result = FALSE;
- g_free (k2);
- g_free (k1);
g_free (name);
return result;
@@ -250,7 +227,6 @@ completion_match_selected_cb (GtkEntryCompletion *widget,
char *head;
const char *tail;
char *tag_name = NULL;
- char *new_text;
get_tag_limits (self, &tag_start, &tag_end);
text = gtk_entry_get_text (GTK_ENTRY (self));
@@ -263,29 +239,162 @@ completion_match_selected_cb (GtkEntryCompletion *widget,
gtk_tree_model_get (model, iter,
NAME_COLUMN, &tag_name,
-1);
+
+ if (tag_name != NULL) {
+ char *new_text;
+
+ new_text = g_strconcat (head,
+ " ",
+ tag_name,
+ ", " /*(tail != tag_end ? ", " : "")*/,
+ tail,
+ NULL);
+ gtk_entry_set_text (GTK_ENTRY (self), new_text);
+ gtk_editable_set_position (GTK_EDITABLE (self), -1);
+
+ g_free (new_text);
+ g_free (tag_name);
+ }
+
+ g_free (head);
+
+ return TRUE;
+}
+
+
+static void
+completion_action_activated_cb (GtkEntryCompletion *widget,
+ int index,
+ gpointer user_data)
+{
+ GthTagsEntry *self = user_data;
+ const char *tag_start;
+ const char *tag_end;
+ const char *text;
+ char *head;
+ const char *tail;
+ char *tag_name = NULL;
+ char *new_text;
+ GthTagsFile *tags_file;
+
+ if (index != 0)
+ return;
+
+ get_tag_limits (self, &tag_start, &tag_end);
+ text = gtk_entry_get_text (GTK_ENTRY (self));
+ head = g_strndup (text, tag_start - text);
+ head = g_strstrip (head);
+ if (tag_end[0] != '\0')
+ tail = g_utf8_next_char (tag_end);
+ else
+ tail = tag_end;
+ tag_name = g_strndup (tag_start, tag_end - tag_start);
+ tag_name = g_strstrip (tag_name);
new_text = g_strconcat (head,
" ",
tag_name,
- (tail != tag_end ? ", " : ""),
+ ", ",
tail,
NULL);
gtk_entry_set_text (GTK_ENTRY (self), new_text);
gtk_editable_set_position (GTK_EDITABLE (self), -1);
+ tags_file = gth_main_get_default_tag_file ();
+ gth_tags_file_add (tags_file, tag_name);
+ gth_main_tags_changed ();
+
g_free (new_text);
g_free (tag_name);
g_free (head);
+}
- return TRUE;
+
+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
-gth_tags_entry_instance_init (GthTagsEntry *self)
+update_tag_list (GthTagsEntry *self)
+{
+ GthTagsFile *tags;
+ int i;
+
+ tags = gth_main_get_default_tag_file ();
+
+ g_strfreev (self->priv->tags);
+ self->priv->tags = g_strdupv ((char **)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);
+ }
+
+ 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;
+
+ 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,
+ GthTagsEntry *self)
{
+ update_tag_list (self);
+}
+static void
+gth_tags_entry_instance_init (GthTagsEntry *self)
+{
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TAGS_ENTRY, GthTagsEntryPrivate);
self->priv->completion = gtk_entry_completion_new ();
gtk_entry_completion_set_popup_completion (self->priv->completion, TRUE);
@@ -296,34 +405,22 @@ gth_tags_entry_instance_init (GthTagsEntry *self)
gtk_entry_completion_set_text_column (self->priv->completion, NAME_COLUMN);
gtk_entry_completion_set_match_func (self->priv->completion, match_func, self, 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 };
- int i;
-
- for (i = 0; default_tags[i] != NULL; i++) {
- GtkTreeIter iter;
-
- gtk_list_store_append (self->priv->store, &iter);
- gtk_list_store_set (self->priv->store, &iter,
- NAME_COLUMN, _(default_tags[i]),
- -1);
- }
- }
-
- g_signal_connect (self, "notify::text", G_CALLBACK (text_changed_cb), self);
- g_signal_connect (self->priv->completion, "match-selected", G_CALLBACK (completion_match_selected_cb), self);
+ g_signal_connect (self,
+ "notify::text",
+ G_CALLBACK (text_changed_cb),
+ self);
+ g_signal_connect (self->priv->completion,
+ "match-selected",
+ G_CALLBACK (completion_match_selected_cb),
+ self);
+ g_signal_connect (self->priv->completion,
+ "action-activated",
+ G_CALLBACK (completion_action_activated_cb),
+ self);
+ self->priv->monitor_event = g_signal_connect (gth_main_get_default_monitor (),
+ "tags-changed",
+ G_CALLBACK (tags_changed_cb),
+ self);
}
@@ -356,28 +453,44 @@ gth_tags_entry_get_type (void)
GtkWidget *
-gth_tags_entry_new (char **tags)
+gth_tags_entry_new (void)
{
- return g_object_new (GTH_TYPE_TAGS_ENTRY, "tags", tags, NULL);
+ GthTagsEntry *self;
+
+ self = g_object_new (GTH_TYPE_TAGS_ENTRY, NULL);
+ update_tag_list (self);
+
+ return (GtkWidget *) self;
}
char **
gth_tags_entry_get_tags (GthTagsEntry *self)
{
- char **all_tags;
- char **tags;
- int i;
- int j;
+ GthTagsFile *tags_file;
+ char **all_tags;
+ char **tags;
+ int i;
+ int j;
+
+ tags_file = gth_main_get_default_tag_file ();
all_tags = g_strsplit (gtk_entry_get_text (GTK_ENTRY (self)), ",", -1);
tags = g_new0 (char *, g_strv_length (all_tags) + 1);
for (i = 0, j = 0; all_tags[i] != NULL; i++) {
all_tags[i] = g_strstrip (all_tags[i]);
- if (all_tags[i][0] != '\0')
- tags[j++] = g_strdup (all_tags[i]);
+ if (all_tags[i][0] != '\0') {
+ tags[j] = g_strdup (all_tags[i]);
+ gth_tags_file_add (tags_file, tags[j]);
+ j++;
+ }
}
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 ();
+
return tags;
}
diff --git a/gthumb/gth-tags-entry.h b/gthumb/gth-tags-entry.h
index 3023f1f..e36948e 100644
--- a/gthumb/gth-tags-entry.h
+++ b/gthumb/gth-tags-entry.h
@@ -48,7 +48,7 @@ struct _GthTagsEntryClass {
};
GType gth_tags_entry_get_type (void);
-GtkWidget * gth_tags_entry_new (char **tags);
+GtkWidget * gth_tags_entry_new (void);
char ** gth_tags_entry_get_tags (GthTagsEntry *self);
G_END_DECLS
diff --git a/gthumb/gth-tags-file.c b/gthumb/gth-tags-file.c
new file mode 100644
index 0000000..7016299
--- /dev/null
+++ b/gthumb/gth-tags-file.c
@@ -0,0 +1,263 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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 <string.h>
+#include "dom.h"
+#include "glib-utils.h"
+#include "gth-tags-file.h"
+
+
+#define FILE_FORMAT "1.0"
+
+
+struct _GthTagsFile
+{
+ GList *items;
+ char **tags;
+};
+
+
+GthTagsFile *
+gth_tags_file_new (void)
+{
+ GthTagsFile *tags;
+
+ tags = g_new0 (GthTagsFile, 1);
+ tags->items = NULL;
+ tags->tags = NULL;
+
+ return tags;
+}
+
+
+void
+gth_tags_file_free (GthTagsFile *tags)
+{
+ _g_string_list_free (tags->items);
+ g_strfreev (tags->tags);
+ g_free (tags);
+}
+
+
+gboolean
+gth_tags_file_load_from_data (GthTagsFile *tags,
+ const char *data,
+ gsize length,
+ GError **error)
+{
+ DomDocument *doc;
+ gboolean success;
+
+ _g_string_list_free (tags->items);
+ tags->items = NULL;
+
+ doc = dom_document_new ();
+ success = dom_document_load (doc, data, length, error);
+ if (success) {
+ DomElement *tags_node;
+ DomElement *child;
+
+ tags_node = DOM_ELEMENT (doc)->first_child;
+ if ((tags_node != NULL) && (g_strcmp0 (tags_node->tag_name, "tags") == 0)) {
+ for (child = tags_node->first_child;
+ child != NULL;
+ child = child->next_sibling)
+ {
+ if (strcmp (child->tag_name, "tag") == 0) {
+ const char *tag_value;
+
+ tag_value = dom_element_get_attribute (child, "value");
+ if (tag_value != NULL)
+ tags->items = g_list_prepend (tags->items, g_strdup (tag_value));
+ }
+ }
+
+ tags->items = g_list_reverse (tags->items);
+ }
+ }
+
+ g_object_unref (doc);
+
+ return success;
+}
+
+
+gboolean
+gth_tags_file_load_from_file (GthTagsFile *tags,
+ const char *filename,
+ GError **error)
+{
+ char *buffer;
+ gsize len;
+ GError *read_error;
+ gboolean retval;
+
+ g_return_val_if_fail (tags != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ read_error = NULL;
+ g_file_get_contents (filename, &buffer, &len, &read_error);
+ if (read_error != NULL) {
+ g_propagate_error (error, read_error);
+ return FALSE;
+ }
+
+ read_error = NULL;
+ retval = gth_tags_file_load_from_data (tags,
+ buffer,
+ len,
+ &read_error);
+ if (read_error != NULL) {
+ g_propagate_error (error, read_error);
+ g_free (buffer);
+ return FALSE;
+ }
+
+ g_free (buffer);
+
+ return retval;
+}
+
+
+char *
+gth_tags_file_to_data (GthTagsFile *tags,
+ gsize *len,
+ GError **data_error)
+{
+ DomDocument *doc;
+ DomElement *root;
+ char *data;
+ GList *scan;
+
+ doc = dom_document_new ();
+ root = dom_document_create_element (doc, "tags",
+ "version", FILE_FORMAT,
+ NULL);
+ dom_element_append_child (DOM_ELEMENT (doc), root);
+ for (scan = tags->items; scan; scan = scan->next) {
+ const char *tag_value = scan->data;
+ dom_element_append_child (root, dom_document_create_element (doc, "tag", "value", tag_value, NULL));
+ }
+ data = dom_document_dump (doc, len);
+
+ g_object_unref (doc);
+
+ return data;
+}
+
+
+gboolean
+gth_tags_file_to_file (GthTagsFile *tags,
+ const char *filename,
+ GError **error)
+{
+ char *data;
+ GError *data_error, *write_error;
+ gsize len;
+ gboolean retval;
+
+ g_return_val_if_fail (tags != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ data_error = NULL;
+ data = gth_tags_file_to_data (tags, &len, &data_error);
+ if (data_error) {
+ g_propagate_error (error, data_error);
+ return FALSE;
+ }
+
+ write_error = NULL;
+ g_file_set_contents (filename, data, len, &write_error);
+ if (write_error) {
+ g_propagate_error (error, write_error);
+ retval = FALSE;
+ }
+ else
+ retval = TRUE;
+
+ g_free (data);
+
+ return retval;
+}
+
+
+const char **
+gth_tags_file_get_tags (GthTagsFile *tags)
+{
+ GList *scan;
+ int i;
+
+ if (tags->tags != NULL) {
+ g_strfreev (tags->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;
+
+ return tags->tags;
+}
+
+
+gboolean
+gth_tags_file_has_tag (GthTagsFile *tags,
+ const char *tag)
+{
+ return g_list_find_custom (tags->items, tag, (GCompareFunc) strcmp) != NULL;
+}
+
+
+void
+gth_tags_file_add (GthTagsFile *tags,
+ const char *tag)
+{
+ GList *link;
+
+ link = g_list_find_custom (tags->items, tag, (GCompareFunc) strcmp);
+ if (link == NULL)
+ tags->items = g_list_append (tags->items, g_strdup (tag));
+}
+
+
+void
+gth_tags_file_remove (GthTagsFile *tags,
+ const char *tag)
+{
+ GList *link;
+
+ link = g_list_find_custom (tags->items, tag, (GCompareFunc) strcmp);
+ if (link == NULL)
+ return;
+ tags->items = g_list_remove_link (tags->items, link);
+ _g_string_list_free (link);
+}
+
+
+void
+gth_tags_file_clear (GthTagsFile *tags)
+{
+ _g_string_list_free (tags->items);
+ tags->items = NULL;
+}
diff --git a/gthumb/gth-tags-file.h b/gthumb/gth-tags-file.h
new file mode 100644
index 0000000..aa3d15a
--- /dev/null
+++ b/gthumb/gth-tags-file.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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_FILE_H
+#define GTH_TAGS_FILE_H
+
+#include <glib.h>
+#include "gth-test.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GthTagsFile GthTagsFile;
+
+GthTagsFile * gth_tags_file_new (void);
+void gth_tags_file_free (GthTagsFile *tags);
+gboolean gth_tags_file_load_from_data (GthTagsFile *tags,
+ const char *data,
+ gsize length,
+ GError **error);
+gboolean gth_tags_file_load_from_file (GthTagsFile *bookmark,
+ const char *filename,
+ GError **error);
+char * gth_tags_file_to_data (GthTagsFile *tags,
+ gsize *len,
+ GError **data_error);
+gboolean gth_tags_file_to_file (GthTagsFile *tags,
+ const char *filename,
+ GError **error);
+const char ** gth_tags_file_get_tags (GthTagsFile *tags);
+gboolean gth_tags_file_has_tag (GthTagsFile *tags,
+ const char *tag);
+void gth_tags_file_add (GthTagsFile *tags,
+ const char *tag);
+void gth_tags_file_remove (GthTagsFile *tags,
+ const char *tag);
+void gth_tags_file_clear (GthTagsFile *tags);
+
+G_END_DECLS
+
+#endif /* GTH_TAGS_FILE_H */
diff --git a/gthumb/typedefs.h b/gthumb/typedefs.h
index 1ef0975..1a30ca9 100644
--- a/gthumb/typedefs.h
+++ b/gthumb/typedefs.h
@@ -39,6 +39,7 @@ G_BEGIN_DECLS
#define BOOKMARKS_FILE "bookmarks.xbel"
#define FILTERS_FILE "filters.xml"
+#define TAGS_FILE "tags.xml"
#define FILE_CACHE "cache"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]