1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  GThumb
5  *
6  *  Copyright (C) 2009 Free Software Foundation, Inc.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <config.h>
23 #include <glib.h>
24 #include <gthumb.h>
25 #include "gth-comment.h"
26 #include "gth-metadata-provider-comment.h"
27 
28 
G_DEFINE_TYPE(GthMetadataProviderComment,gth_metadata_provider_comment,GTH_TYPE_METADATA_PROVIDER)29 G_DEFINE_TYPE (GthMetadataProviderComment, gth_metadata_provider_comment, GTH_TYPE_METADATA_PROVIDER)
30 
31 
32 static gboolean
33 gth_metadata_provider_comment_can_read (GthMetadataProvider  *self,
34 				        const char           *mime_type,
35 				        char                **attribute_v)
36 {
37 	return _g_file_attributes_matches_any_v ("comment::*,"
38 						 "general::datetime,"
39 						 "general::title,"
40 						 "general::description,"
41 						 "general::location,"
42 						 "general::tags,"
43 						 "general::rating",
44 					         attribute_v);
45 }
46 
47 
48 static gboolean
gth_metadata_provider_comment_can_write(GthMetadataProvider * self,const char * mime_type,char ** attribute_v)49 gth_metadata_provider_comment_can_write (GthMetadataProvider  *self,
50 				         const char           *mime_type,
51 				         char                **attribute_v)
52 {
53 	return _g_file_attributes_matches_any_v ("comment::*,"
54 						 "general::datetime,"
55 						 "general::title,"
56 						 "general::description,"
57 						 "general::location,"
58 						 "general::tags,"
59 						 "general::rating",
60 					         attribute_v);
61 }
62 
63 
64 static void
gth_metadata_provider_comment_read(GthMetadataProvider * self,GthFileData * file_data,const char * attributes,GCancellable * cancellable)65 gth_metadata_provider_comment_read (GthMetadataProvider *self,
66 				    GthFileData         *file_data,
67 				    const char          *attributes,
68 				    GCancellable        *cancellable)
69 {
70 	GthComment *comment;
71 	const char *value;
72 	GPtrArray  *categories;
73 	char       *comment_time;
74 
75 	comment = gth_comment_new_for_file (file_data->file, cancellable, NULL);
76 	g_file_info_set_attribute_boolean (file_data->info, "comment::no-comment-file", (comment == NULL));
77 
78 	if (comment == NULL)
79 		return;
80 
81 	value = gth_comment_get_note (comment);
82 	if (value != NULL)
83 		g_file_info_set_attribute_string (file_data->info, "comment::note", value);
84 
85 	value = gth_comment_get_caption (comment);
86 	if (value != NULL)
87 		g_file_info_set_attribute_string (file_data->info, "comment::caption", value);
88 
89 	value = gth_comment_get_place (comment);
90 	if (value != NULL)
91 		g_file_info_set_attribute_string (file_data->info, "comment::place", value);
92 
93 	if (gth_comment_get_rating (comment) > 0)
94 		g_file_info_set_attribute_int32 (file_data->info, "comment::rating", gth_comment_get_rating (comment));
95 	else
96 		g_file_info_remove_attribute (file_data->info, "comment::rating");
97 
98 	categories = gth_comment_get_categories (comment);
99 	if (categories->len > 0) {
100 		GthStringList *list;
101 		GthMetadata   *metadata;
102 
103 		list =  gth_string_list_new_from_ptr_array (categories);
104 		metadata = gth_metadata_new_for_string_list (list);
105 		g_file_info_set_attribute_object (file_data->info, "comment::categories", G_OBJECT (metadata));
106 
107 		g_object_unref (metadata);
108 		g_object_unref (list);
109 	}
110 	else
111 		g_file_info_remove_attribute (file_data->info, "comment::categories");
112 
113 	comment_time = gth_comment_get_time_as_exif_format (comment);
114 	if (comment_time != NULL) {
115 		GTimeVal  time_;
116 		char     *formatted;
117 
118 		if (_g_time_val_from_exif_date (comment_time, &time_))
119 			formatted = _g_time_val_strftime (&time_, "%x %X");
120 		else
121 			formatted = g_strdup (comment_time);
122 		set_attribute_from_string (file_data->info, "comment::time", comment_time, formatted);
123 
124 		g_free (formatted);
125 		g_free (comment_time);
126 	}
127 	else
128 		g_file_info_remove_attribute (file_data->info, "comment::time");
129 
130 	gth_comment_update_general_attributes (file_data);
131 
132 	g_object_unref (comment);
133 }
134 
135 
136 static void
gth_metadata_provider_comment_write(GthMetadataProvider * self,GthMetadataWriteFlags flags,GthFileData * file_data,const char * attributes,GCancellable * cancellable)137 gth_metadata_provider_comment_write (GthMetadataProvider   *self,
138 				     GthMetadataWriteFlags  flags,
139 				     GthFileData           *file_data,
140 				     const char            *attributes,
141 				     GCancellable          *cancellable)
142 {
143 	GthComment    *comment;
144 	GthMetadata   *metadata;
145 	const char    *text;
146 	char          *data;
147 	gsize          length;
148 	GthStringList *categories;
149 	GFile         *comment_file;
150 	GFile         *comment_folder;
151 
152 	comment = gth_comment_new ();
153 
154 	/* caption */
155 
156 	text = NULL;
157 	metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::title");
158 	if (metadata != NULL)
159 		text = gth_metadata_get_raw (metadata);
160 	gth_comment_set_caption (comment, text);
161 
162 	/* comment */
163 
164 	text = NULL;
165 	metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::description");
166 	if (metadata != NULL)
167 		text = gth_metadata_get_raw (metadata);
168 	gth_comment_set_note (comment, text);
169 
170 	/* location */
171 
172 	text = NULL;
173 	metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::location");
174 	if (metadata != NULL)
175 		text = gth_metadata_get_raw (metadata);
176 	gth_comment_set_place (comment, text);
177 
178 	/* time */
179 
180 	text = NULL;
181 	metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::datetime");
182 	if (metadata != NULL)
183 		text = gth_metadata_get_raw (metadata);
184 	gth_comment_set_time_from_exif_format (comment, text);
185 
186 	/* keywords */
187 
188 	metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::tags");
189 	categories = gth_metadata_get_string_list (metadata);
190 	if (categories != NULL) {
191 		GList *list;
192 		GList *scan;
193 
194 		list = gth_string_list_get_list (categories);
195 		for (scan = list; scan; scan = scan->next)
196 			gth_comment_add_category (comment, (char *) scan->data);
197 	}
198 
199 	/* rating */
200 
201 	metadata = (GthMetadata *) g_file_info_get_attribute_object (file_data->info, "general::rating");
202 	if (metadata != NULL) {
203 		int rating;
204 
205 		sscanf (gth_metadata_get_raw (metadata), "%d", &rating);
206 		gth_comment_set_rating (comment, rating);
207 	}
208 
209 	data = gth_comment_to_data (comment, &length);
210 	comment_file = gth_comment_get_comment_file (file_data->file);
211 	comment_folder = g_file_get_parent (comment_file);
212 
213 	g_file_make_directory (comment_folder, NULL, NULL);
214 	_g_file_write (comment_file, FALSE, 0, data, length, cancellable, NULL);
215 
216 	g_object_unref (comment_folder);
217 	g_object_unref (comment_file);
218 	g_free (data);
219 	g_object_unref (comment);
220 }
221 
222 
223 static void
gth_metadata_provider_comment_class_init(GthMetadataProviderCommentClass * klass)224 gth_metadata_provider_comment_class_init (GthMetadataProviderCommentClass *klass)
225 {
226 	GthMetadataProviderClass *mp_class;
227 
228 	mp_class = GTH_METADATA_PROVIDER_CLASS (klass);
229 	mp_class->can_read = gth_metadata_provider_comment_can_read;
230 	mp_class->can_write = gth_metadata_provider_comment_can_write;
231 	mp_class->read = gth_metadata_provider_comment_read;
232 	mp_class->write = gth_metadata_provider_comment_write;
233 }
234 
235 static void
gth_metadata_provider_comment_init(GthMetadataProviderComment * self)236 gth_metadata_provider_comment_init (GthMetadataProviderComment *self)
237 {
238 	/* void */
239 }
240