]> www.fi.muni.cz Git - evince.git/blob - cut-n-paste/recent-files/egg-recent-item.c
Initial revision
[evince.git] / cut-n-paste / recent-files / egg-recent-item.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as
5  * published by the Free Software Foundation; either version 2 of the
6  * License, or (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
16  *
17  * Authors:
18  *   James Willcox <jwillcox@cs.indiana.edu>
19  */
20
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <libgnomevfs/gnome-vfs.h>
26 #include <libgnomevfs/gnome-vfs-mime-utils.h>
27 #include "egg-recent-item.h"
28
29
30
31 EggRecentItem *
32 egg_recent_item_new (void)
33 {
34         EggRecentItem *item;
35
36         item = g_new (EggRecentItem, 1);
37
38         item->groups = NULL;
39         item->private_data = FALSE;
40         item->uri = NULL;
41         item->mime_type = NULL;
42
43         item->refcount = 1;
44
45         return item;
46 }
47
48 static void
49 egg_recent_item_free (EggRecentItem *item)
50 {
51         if (item->uri)
52                 g_free (item->uri);
53
54         if (item->mime_type)
55                 g_free (item->mime_type);
56
57         if (item->groups) {
58                 g_list_foreach (item->groups, (GFunc)g_free, NULL);
59                 g_list_free (item->groups);
60                 item->groups = NULL;
61         }
62
63         g_free (item);
64 }
65
66 EggRecentItem *
67 egg_recent_item_ref (EggRecentItem *item)
68 {
69         item->refcount++;
70         return item;
71 }
72
73 EggRecentItem *
74 egg_recent_item_unref (EggRecentItem *item)
75 {
76         item->refcount--;
77
78         if (item->refcount == 0) {
79                 egg_recent_item_free (item);
80         }
81
82         return item;
83 }
84
85
86 EggRecentItem * 
87 egg_recent_item_new_from_uri (const gchar *uri)
88 {
89         EggRecentItem *item;
90
91         g_return_val_if_fail (uri != NULL, NULL);
92
93         item = egg_recent_item_new ();
94
95         if (!egg_recent_item_set_uri (item ,uri)) {
96                 egg_recent_item_free (item);
97                 return NULL;
98         }
99         
100         item->mime_type = gnome_vfs_get_mime_type (item->uri);
101
102         if (!item->mime_type)
103                 item->mime_type = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN);
104
105         return item;
106 }
107
108 /*
109 static GList *
110 egg_recent_item_copy_groups (const GList *list)
111 {
112         GList *newlist = NULL;
113
114         while (list) {
115                 gchar *group = (gchar *)list->data;
116
117                 newlist = g_list_prepend (newlist, g_strdup (group));
118
119                 list = list->next;
120         }
121
122         return newlist;
123 }
124
125
126 EggRecentItem *
127 egg_recent_item_copy (const EggRecentItem *item)
128 {
129         EggRecentItem *newitem;
130
131         newitem = egg_recent_item_new ();
132         newitem->uri = g_strdup (item->uri);
133         if (item->mime_type)
134                 newitem->mime_type = g_strdup (item->mime_type);
135         newitem->timestamp = item->timestamp;
136         newitem->private_data = item->private_data;
137         newitem->groups = egg_recent_item_copy_groups (item->groups);
138
139         return newitem;
140 }
141 */
142
143 /*
144 EggRecentItem *
145 egg_recent_item_new_valist (const gchar *uri, va_list args)
146 {
147         EggRecentItem *item;
148         EggRecentArg arg;
149         gchar *str1;
150         gchar *str2;
151         gboolean priv;
152
153         item = egg_recent_item_new ();
154
155         arg = va_arg (args, EggRecentArg);
156
157         while (arg != EGG_RECENT_ARG_NONE) {
158                 switch (arg) {
159                         case EGG_RECENT_ARG_MIME_TYPE:
160                                 str1 = va_arg (args, gchar*);
161
162                                 egg_recent_item_set_mime_type (item, str1);
163                         break;
164                         case EGG_RECENT_ARG_GROUP:
165                                 str1 = va_arg (args, gchar*);
166
167                                 egg_recent_item_add_group (item, str1);
168                         break;
169                         case EGG_RECENT_ARG_PRIVATE:
170                                 priv = va_arg (args, gboolean);
171
172                                 egg_recent_item_set_private (item, priv);
173                         break;
174                         default:
175                         break;
176                 }
177
178                 arg = va_arg (args, EggRecentArg);
179         }
180
181         return item;
182 }
183 */
184
185 gboolean
186 egg_recent_item_set_uri (EggRecentItem *item, const gchar *uri)
187 {
188         gchar *utf8_uri;
189
190         /* if G_BROKEN_FILENAMES is not set, this should succede */
191         if (g_utf8_validate (uri, -1, NULL)) {
192                 item->uri = gnome_vfs_make_uri_from_input (uri);
193         } else {
194                 utf8_uri = g_filename_to_utf8 (uri, -1, NULL, NULL, NULL);
195
196                 if (utf8_uri == NULL) {
197                         g_warning ("Couldn't convert URI to UTF-8");
198                         return FALSE;
199                 }
200
201                 if (g_utf8_validate (utf8_uri, -1, NULL)) {
202                         item->uri = gnome_vfs_make_uri_from_input (utf8_uri);
203                 } else {
204                         g_free (utf8_uri);
205                         return FALSE;
206                 }
207
208                 g_free (utf8_uri);
209         }
210
211         return TRUE;
212 }
213
214 gchar * 
215 egg_recent_item_get_uri (const EggRecentItem *item)
216 {
217         return g_strdup (item->uri);
218 }
219
220 G_CONST_RETURN gchar * 
221 egg_recent_item_peek_uri (const EggRecentItem *item)
222 {
223         return item->uri;
224 }
225
226 gchar * 
227 egg_recent_item_get_uri_utf8 (const EggRecentItem *item)
228 {
229         /* this could fail, but it's not likely, since we've already done it
230          * once in set_uri()
231          */
232         return g_filename_to_utf8 (item->uri, -1, NULL, NULL, NULL);
233 }
234
235 gchar *
236 egg_recent_item_get_uri_for_display (const EggRecentItem *item)
237 {
238         return gnome_vfs_format_uri_for_display (item->uri);
239 }
240
241 /* Stolen from gnome_vfs_make_valid_utf8() */
242 static char *
243 make_valid_utf8 (const char *name)
244 {
245         GString *string;
246         const char *remainder, *invalid;
247         int remaining_bytes, valid_bytes;
248
249         string = NULL;
250         remainder = name;
251         remaining_bytes = strlen (name);
252
253         while (remaining_bytes != 0) {
254                 if (g_utf8_validate (remainder, remaining_bytes, &invalid))
255                         break;
256
257                 valid_bytes = invalid - remainder;
258
259                 if (string == NULL)
260                         string = g_string_sized_new (remaining_bytes);
261
262                 g_string_append_len (string, remainder, valid_bytes);
263                 g_string_append_c (string, '?');
264
265                 remaining_bytes -= valid_bytes + 1;
266                 remainder = invalid + 1;
267         }
268
269         if (string == NULL)
270                 return g_strdup (name);
271
272         g_string_append (string, remainder);
273 /*      g_string_append (string, _(" (invalid file name)")); */
274         g_assert (g_utf8_validate (string->str, -1, NULL));
275
276         return g_string_free (string, FALSE);
277 }
278
279 /**
280  * egg_recent_item_get_short_name:
281  * @item: an #EggRecentItem
282  *
283  * Computes a valid UTF-8 string that can be used as the name of the item in a
284  * menu or list.  For example, calling this function on an item that refers to
285  * "file:///foo/bar.txt" will yield "bar.txt".
286  *
287  * Return value: A newly-allocated string in UTF-8 encoding; free it with
288  * g_free().
289  **/
290 gchar *
291 egg_recent_item_get_short_name (const EggRecentItem *item)
292 {
293         GnomeVFSURI *uri;
294         char *short_name;
295         gboolean valid;
296
297         g_return_val_if_fail (item != NULL, NULL);
298
299         if (item->uri == NULL)
300                 return NULL;
301
302         uri = gnome_vfs_uri_new (item->uri);
303         if (uri == NULL)
304                 return NULL;
305
306         short_name = gnome_vfs_uri_extract_short_name (uri);
307         valid = FALSE;
308
309         if (strcmp (gnome_vfs_uri_get_scheme (uri), "file") == 0) {
310                 char *tmp;
311
312                 tmp = g_filename_to_utf8 (short_name, -1, NULL, NULL, NULL);
313                 if (tmp) {
314                         g_free (short_name);
315                         short_name = tmp;
316                         valid = TRUE;
317                 }
318         }
319
320         if (!valid) {
321                 char *tmp;
322
323                 tmp = make_valid_utf8 (short_name);
324                 g_assert (tmp != NULL);
325                 g_free (short_name);
326                 short_name = tmp;
327         }
328
329         gnome_vfs_uri_unref (uri);
330
331         return short_name;
332 }
333
334 void 
335 egg_recent_item_set_mime_type (EggRecentItem *item, const gchar *mime)
336 {
337         item->mime_type = g_strdup (mime);
338 }
339
340 gchar * 
341 egg_recent_item_get_mime_type (const EggRecentItem *item)
342 {
343         return g_strdup (item->mime_type);
344 }
345
346 void 
347 egg_recent_item_set_timestamp (EggRecentItem *item, time_t timestamp)
348 {
349         if (timestamp == (time_t) -1)
350                 time (&timestamp);
351
352         item->timestamp = timestamp;
353 }
354
355 time_t 
356 egg_recent_item_get_timestamp (const EggRecentItem *item)
357 {
358         return item->timestamp;
359 }
360
361 G_CONST_RETURN GList *
362 egg_recent_item_get_groups (const EggRecentItem *item)
363 {
364         return item->groups;
365 }
366
367 gboolean
368 egg_recent_item_in_group (const EggRecentItem *item, const gchar *group_name)
369 {
370         GList *tmp;
371
372         tmp = item->groups;
373         while (tmp != NULL) {
374                 gchar *val = (gchar *)tmp->data;
375                 
376                 if (strcmp (group_name, val) == 0)
377                         return TRUE;
378
379                 tmp = tmp->next;
380         }
381         
382         return FALSE;
383 }
384
385 void
386 egg_recent_item_add_group (EggRecentItem *item, const gchar *group_name)
387 {
388         g_return_if_fail (group_name != NULL);
389
390         if (!egg_recent_item_in_group (item, group_name))
391                 item->groups = g_list_append (item->groups, g_strdup (group_name));
392 }
393
394 void
395 egg_recent_item_remove_group (EggRecentItem *item, const gchar *group_name)
396 {
397         GList *tmp;
398
399         g_return_if_fail (group_name != NULL);
400
401         tmp = item->groups;
402         while (tmp != NULL) {
403                 gchar *val = (gchar *)tmp->data;
404                 
405                 if (strcmp (group_name, val) == 0) {
406                         item->groups = g_list_remove (item->groups,
407                                                       val);
408                         g_free (val);
409                         break;
410                 }
411
412                 tmp = tmp->next;
413         }
414 }
415
416 void
417 egg_recent_item_set_private (EggRecentItem *item, gboolean priv)
418 {
419         item->private_data = priv;
420 }
421
422 gboolean
423 egg_recent_item_get_private (const EggRecentItem *item)
424 {
425         return item->private_data;
426 }
427
428 GType
429 egg_recent_item_get_type (void)
430 {
431         static GType boxed_type = 0;
432         
433         if (!boxed_type) {
434                 boxed_type = g_boxed_type_register_static ("EggRecentItem",
435                                         (GBoxedCopyFunc)egg_recent_item_ref,
436                                         (GBoxedFreeFunc)egg_recent_item_unref);
437         }
438         
439         return boxed_type;
440 }