/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Pix
*
* 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, see .
*/
#include
#include
#include
#include "gth-comment.h"
#include "gth-metadata-provider-comment.h"
struct _GthMetadataProviderCommentPrivate {
GHashTable *checked_folders;
};
G_DEFINE_TYPE_WITH_CODE (GthMetadataProviderComment,
gth_metadata_provider_comment,
GTH_TYPE_METADATA_PROVIDER,
G_ADD_PRIVATE (GthMetadataProviderComment))
static gboolean
gth_metadata_provider_comment_can_read (GthMetadataProvider *base,
GthFileData *file_data,
const char *mime_type,
char **attribute_v)
{
GthMetadataProviderComment *self = GTH_METADATA_PROVIDER_COMMENT (base);
gboolean can_read;
can_read = _g_file_attributes_matches_any_v ("comment::*,"
"general::datetime,"
"general::title,"
"general::description,"
"general::location,"
"general::tags,"
"general::rating",
attribute_v);
if (! can_read)
return FALSE;
if (file_data != NULL) {
GFile *comment_file;
GFile *comment_folder;
gboolean comment_folder_exists;
gpointer value;
comment_file = gth_comment_get_comment_file (file_data->file);
if (comment_file == NULL)
return FALSE;
comment_folder = g_file_get_parent (comment_file);
if (comment_folder == NULL)
return FALSE;
value = g_hash_table_lookup (self->priv->checked_folders, comment_folder);
if (value == NULL) {
comment_folder_exists = g_file_query_exists (comment_folder, NULL);
g_hash_table_insert (self->priv->checked_folders,
g_object_ref (comment_folder),
GINT_TO_POINTER (comment_folder_exists ? 1 : 2));
}
else
comment_folder_exists = GPOINTER_TO_INT (value) == 1;
can_read = comment_folder_exists;
g_object_unref (comment_folder);
g_object_unref (comment_file);
}
return can_read;
}
static gboolean
gth_metadata_provider_comment_can_write (GthMetadataProvider *self,
const char *mime_type,
char **attribute_v)
{
return _g_file_attributes_matches_any_v ("comment::*,"
"general::datetime,"
"general::title,"
"general::description,"
"general::location,"
"general::tags,"
"general::rating",
attribute_v);
}
static void
gth_metadata_provider_comment_read (GthMetadataProvider *self,
GthFileData *file_data,
const char *attributes,
GCancellable *cancellable)
{
GthComment *comment;
const char *value;
GPtrArray *categories;
char *comment_time;
comment = gth_comment_new_for_file (file_data->file, cancellable, NULL);
g_file_info_set_attribute_boolean (file_data->info, "comment::no-comment-file", (comment == NULL));
if (comment == NULL)
return;
value = gth_comment_get_note (comment);
if (value != NULL)
g_file_info_set_attribute_string (file_data->info, "comment::note", value);
value = gth_comment_get_caption (comment);
if (value != NULL)
g_file_info_set_attribute_string (file_data->info, "comment::caption", value);
value = gth_comment_get_place (comment);
if (value != NULL)
g_file_info_set_attribute_string (file_data->info, "comment::place", value);
if (gth_comment_get_rating (comment) > 0)
g_file_info_set_attribute_int32 (file_data->info, "comment::rating", gth_comment_get_rating (comment));
else
g_file_info_remove_attribute (file_data->info, "comment::rating");
categories = gth_comment_get_categories (comment);
if (categories->len > 0) {
GthStringList *list;
GthMetadata *metadata;
list = gth_string_list_new_from_ptr_array (categories);
metadata = gth_metadata_new_for_string_list (list);
g_file_info_set_attribute_object (file_data->info, "comment::categories", G_OBJECT (metadata));
g_object_unref (metadata);
g_object_unref (list);
}
else
g_file_info_remove_attribute (file_data->info, "comment::categories");
comment_time = gth_comment_get_time_as_exif_format (comment);
if (comment_time != NULL) {
GTimeVal time_;
char *formatted;
if (_g_time_val_from_exif_date (comment_time, &time_))
formatted = _g_time_val_strftime (&time_, "%x %X");
else
formatted = g_strdup (comment_time);
set_attribute_from_string (file_data->info, "comment::time", comment_time, formatted);
g_free (formatted);
g_free (comment_time);
}
else
g_file_info_remove_attribute (file_data->info, "comment::time");
gth_comment_update_general_attributes (file_data);
g_object_unref (comment);
}
static void
gth_metadata_provider_comment_write (GthMetadataProvider *self,
GthMetadataWriteFlags flags,
GthFileData *file_data,
const char *attributes,
GCancellable *cancellable)
{
GthComment *comment;
GthMetadata *metadata;
const char *text;
char *data;
gsize length;
GthStringList *categories;
GFile *comment_file;
GFile *comment_folder;
comment = gth_comment_new ();
/* caption */
text = NULL;
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::title");
if (metadata != NULL)
text = gth_metadata_get_raw (metadata);
gth_comment_set_caption (comment, text);
/* comment */
text = NULL;
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::description");
if (metadata != NULL)
text = gth_metadata_get_raw (metadata);
gth_comment_set_note (comment, text);
/* location */
text = NULL;
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::location");
if (metadata != NULL)
text = gth_metadata_get_raw (metadata);
gth_comment_set_place (comment, text);
/* time */
text = NULL;
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::datetime");
if (metadata != NULL)
text = gth_metadata_get_raw (metadata);
gth_comment_set_time_from_exif_format (comment, text);
/* keywords */
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::tags");
categories = gth_metadata_get_string_list (metadata);
if (categories != NULL) {
GList *list;
GList *scan;
list = gth_string_list_get_list (categories);
for (scan = list; scan; scan = scan->next)
gth_comment_add_category (comment, (char *) scan->data);
}
/* rating */
metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::rating");
if (metadata != NULL) {
int rating;
sscanf (gth_metadata_get_raw (metadata), "%d", &rating);
gth_comment_set_rating (comment, rating);
}
data = gth_comment_to_data (comment, &length);
comment_file = gth_comment_get_comment_file (file_data->file);
comment_folder = g_file_get_parent (comment_file);
g_file_make_directory (comment_folder, NULL, NULL);
_g_file_write (comment_file, FALSE, 0, data, length, cancellable, NULL);
g_object_unref (comment_folder);
g_object_unref (comment_file);
g_free (data);
g_object_unref (comment);
}
static void
gth_metadata_provider_comment_finalize (GObject *object)
{
GthMetadataProviderComment *self;
g_return_if_fail (object != NULL);
g_return_if_fail (GTH_IS_METADATA_PROVIDER_COMMENT (object));
self = GTH_METADATA_PROVIDER_COMMENT (object);
g_hash_table_unref (self->priv->checked_folders);
/* Chain up */
G_OBJECT_CLASS (gth_metadata_provider_comment_parent_class)->finalize (object);
}
static void
gth_metadata_provider_comment_class_init (GthMetadataProviderCommentClass *klass)
{
GObjectClass *gobject_class;
GthMetadataProviderClass *mp_class;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gth_metadata_provider_comment_finalize;
mp_class = GTH_METADATA_PROVIDER_CLASS (klass);
mp_class->can_read = gth_metadata_provider_comment_can_read;
mp_class->can_write = gth_metadata_provider_comment_can_write;
mp_class->read = gth_metadata_provider_comment_read;
mp_class->write = gth_metadata_provider_comment_write;
}
static void
gth_metadata_provider_comment_init (GthMetadataProviderComment *self)
{
self->priv = gth_metadata_provider_comment_get_instance_private (self);
self->priv->checked_folders = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
}