]> www.fi.muni.cz Git - evince.git/blob - cut-n-paste/recent-files/egg-recent-item.c
Update egg-recent from libegg. This should fix long delay on startup
[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         item->mime_type_is_explicit = FALSE;
43
44         item->refcount = 1;
45
46         return item;
47 }
48
49 static void
50 egg_recent_item_free (EggRecentItem *item)
51 {
52         if (item->uri)
53                 g_free (item->uri);
54
55         if (item->mime_type)
56                 g_free (item->mime_type);
57
58         if (item->groups) {
59                 g_list_foreach (item->groups, (GFunc)g_free, NULL);
60                 g_list_free (item->groups);
61                 item->groups = NULL;
62         }
63
64         g_free (item);
65 }
66
67 EggRecentItem *
68 egg_recent_item_ref (EggRecentItem *item)
69 {
70         item->refcount++;
71         return item;
72 }
73
74 EggRecentItem *
75 egg_recent_item_unref (EggRecentItem *item)
76 {
77         item->refcount--;
78
79         if (item->refcount == 0) {
80                 egg_recent_item_free (item);
81         }
82
83         return item;
84 }
85
86
87 EggRecentItem * 
88 egg_recent_item_new_from_uri (const gchar *uri)
89 {
90         EggRecentItem *item;
91
92         g_return_val_if_fail (uri != NULL, NULL);
93
94         item = egg_recent_item_new ();
95
96         if (!egg_recent_item_set_uri (item ,uri)) {
97                 egg_recent_item_free (item);
98                 return NULL;
99         }
100         
101         return item;
102 }
103
104 /*
105 static GList *
106 egg_recent_item_copy_groups (const GList *list)
107 {
108         GList *newlist = NULL;
109
110         while (list) {
111                 gchar *group = (gchar *)list->data;
112
113                 newlist = g_list_prepend (newlist, g_strdup (group));
114
115                 list = list->next;
116         }
117
118         return newlist;
119 }
120
121
122 EggRecentItem *
123 egg_recent_item_copy (const EggRecentItem *item)
124 {
125         EggRecentItem *newitem;
126
127         newitem = egg_recent_item_new ();
128         newitem->uri = g_strdup (item->uri);
129         if (item->mime_type)
130                 newitem->mime_type = g_strdup (item->mime_type);
131         newitem->mime_type_is_explicit = item->mime_type_is_explicit
132         newitem->timestamp = item->timestamp;
133         newitem->private_data = item->private_data;
134         newitem->groups = egg_recent_item_copy_groups (item->groups);
135
136         return newitem;
137 }
138 */
139
140 /*
141 EggRecentItem *
142 egg_recent_item_new_valist (const gchar *uri, va_list args)
143 {
144         EggRecentItem *item;
145         EggRecentArg arg;
146         gchar *str1;
147         gchar *str2;
148         gboolean priv;
149
150         item = egg_recent_item_new ();
151
152         arg = va_arg (args, EggRecentArg);
153
154         while (arg != EGG_RECENT_ARG_NONE) {
155                 switch (arg) {
156                         case EGG_RECENT_ARG_MIME_TYPE:
157                                 str1 = va_arg (args, gchar*);
158
159                                 egg_recent_item_set_mime_type (item, str1);
160                         break;
161                         case EGG_RECENT_ARG_GROUP:
162                                 str1 = va_arg (args, gchar*);
163
164                                 egg_recent_item_add_group (item, str1);
165                         break;
166                         case EGG_RECENT_ARG_PRIVATE:
167                                 priv = va_arg (args, gboolean);
168
169                                 egg_recent_item_set_private (item, priv);
170                         break;
171                         default:
172                         break;
173                 }
174
175                 arg = va_arg (args, EggRecentArg);
176         }
177
178         return item;
179 }
180 */
181
182 static void
183 egg_recent_item_update_mime_type (EggRecentItem *item)
184 {
185         if (!item->mime_type_is_explicit) {
186                 g_free (item->mime_type);
187                 item->mime_type = NULL;
188
189                 if (item->uri)
190                         item->mime_type = gnome_vfs_get_mime_type (item->uri);
191
192                 if (!item->mime_type)
193                         item->mime_type = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN);
194         }
195 }
196
197 gboolean
198 egg_recent_item_set_uri (EggRecentItem *item, const gchar *uri)
199 {
200         gchar *utf8_uri;
201
202         /* if G_BROKEN_FILENAMES is not set, this should succede */
203         if (g_utf8_validate (uri, -1, NULL)) {
204                 item->uri = gnome_vfs_make_uri_from_input (uri);
205         } else {
206                 utf8_uri = g_filename_to_utf8 (uri, -1, NULL, NULL, NULL);
207
208                 if (utf8_uri == NULL) {
209                         g_warning ("Couldn't convert URI to UTF-8");
210                         return FALSE;
211                 }
212
213                 if (g_utf8_validate (utf8_uri, -1, NULL)) {
214                         item->uri = gnome_vfs_make_uri_from_input (utf8_uri);
215                 } else {
216                         g_free (utf8_uri);
217                         return FALSE;
218                 }
219
220                 g_free (utf8_uri);
221         }
222
223         return TRUE;
224 }
225
226 gchar * 
227 egg_recent_item_get_uri (const EggRecentItem *item)
228 {
229         return g_strdup (item->uri);
230 }
231
232 G_CONST_RETURN gchar * 
233 egg_recent_item_peek_uri (const EggRecentItem *item)
234 {
235         return item->uri;
236 }
237
238 gchar * 
239 egg_recent_item_get_uri_utf8 (const EggRecentItem *item)
240 {
241         /* this could fail, but it's not likely, since we've already done it
242          * once in set_uri()
243          */
244         return g_filename_to_utf8 (item->uri, -1, NULL, NULL, NULL);
245 }
246
247 gchar *
248 egg_recent_item_get_uri_for_display (const EggRecentItem *item)
249 {
250         return gnome_vfs_format_uri_for_display (item->uri);
251 }
252
253 /* Stolen from gnome_vfs_make_valid_utf8() */
254 static char *
255 make_valid_utf8 (const char *name)
256 {
257         GString *string;
258         const char *remainder, *invalid;
259         int remaining_bytes, valid_bytes;
260
261         string = NULL;
262         remainder = name;
263         remaining_bytes = name ? strlen (name) : 0;
264
265         while (remaining_bytes != 0) {
266                 if (g_utf8_validate (remainder, remaining_bytes, &invalid))
267                         break;
268
269                 valid_bytes = invalid - remainder;
270
271                 if (string == NULL)
272                         string = g_string_sized_new (remaining_bytes);
273
274                 g_string_append_len (string, remainder, valid_bytes);
275                 g_string_append_c (string, '?');
276
277                 remaining_bytes -= valid_bytes + 1;
278                 remainder = invalid + 1;
279         }
280
281         if (string == NULL)
282                 return g_strdup (name);
283
284         g_string_append (string, remainder);
285 /*      g_string_append (string, _(" (invalid file name)")); */
286         g_assert (g_utf8_validate (string->str, -1, NULL));
287
288         return g_string_free (string, FALSE);
289 }
290
291 /**
292  * egg_recent_item_get_short_name:
293  * @item: an #EggRecentItem
294  *
295  * Computes a valid UTF-8 string that can be used as the name of the item in a
296  * menu or list.  For example, calling this function on an item that refers to
297  * "file:///foo/bar.txt" will yield "bar.txt".
298  *
299  * Return value: A newly-allocated string in UTF-8 encoding; free it with
300  * g_free().
301  **/
302 gchar *
303 egg_recent_item_get_short_name (const EggRecentItem *item)
304 {
305         GnomeVFSURI *uri;
306         char *short_name;
307         gboolean valid;
308
309         g_return_val_if_fail (item != NULL, NULL);
310
311         if (item->uri == NULL)
312                 return NULL;
313
314         uri = gnome_vfs_uri_new (item->uri);
315         if (uri == NULL)
316                 return NULL;
317
318         short_name = gnome_vfs_uri_extract_short_name (uri);
319         valid = FALSE;
320
321         if (strcmp (gnome_vfs_uri_get_scheme (uri), "file") == 0) {
322                 char *tmp;
323
324                 tmp = g_filename_to_utf8 (short_name, -1, NULL, NULL, NULL);
325                 if (tmp) {
326                         g_free (short_name);
327                         short_name = tmp;
328                         valid = TRUE;
329                 }
330         }
331
332         if (!valid) {
333                 char *tmp;
334
335                 tmp = make_valid_utf8 (short_name);
336                 g_assert (tmp != NULL);
337                 g_free (short_name);
338                 short_name = tmp;
339         }
340
341         gnome_vfs_uri_unref (uri);
342
343         return short_name;
344 }
345
346 void 
347 egg_recent_item_set_mime_type (EggRecentItem *item, const gchar *mime)
348 {
349         g_free (item->mime_type);
350         item->mime_type = NULL;
351
352         if (mime && mime[0]) {
353                 item->mime_type_is_explicit = TRUE;
354                 item->mime_type             = g_strdup (mime);
355         } else {
356                 item->mime_type_is_explicit = FALSE;
357         }
358 }
359
360 gchar * 
361 egg_recent_item_get_mime_type (EggRecentItem *item)
362 {
363         egg_recent_item_update_mime_type (item);
364
365         return g_strdup (item->mime_type);
366 }
367
368 void 
369 egg_recent_item_set_timestamp (EggRecentItem *item, time_t timestamp)
370 {
371         if (timestamp == (time_t) -1)
372                 time (&timestamp);
373
374         item->timestamp = timestamp;
375 }
376
377 time_t 
378 egg_recent_item_get_timestamp (const EggRecentItem *item)
379 {
380         return item->timestamp;
381 }
382
383 G_CONST_RETURN GList *
384 egg_recent_item_get_groups (const EggRecentItem *item)
385 {
386         return item->groups;
387 }
388
389 gboolean
390 egg_recent_item_in_group (const EggRecentItem *item, const gchar *group_name)
391 {
392         GList *tmp;
393
394         tmp = item->groups;
395         while (tmp != NULL) {
396                 gchar *val = (gchar *)tmp->data;
397                 
398                 if (strcmp (group_name, val) == 0)
399                         return TRUE;
400
401                 tmp = tmp->next;
402         }
403         
404         return FALSE;
405 }
406
407 void
408 egg_recent_item_add_group (EggRecentItem *item, const gchar *group_name)
409 {
410         g_return_if_fail (group_name != NULL);
411
412         if (!egg_recent_item_in_group (item, group_name))
413                 item->groups = g_list_append (item->groups, g_strdup (group_name));
414 }
415
416 void
417 egg_recent_item_remove_group (EggRecentItem *item, const gchar *group_name)
418 {
419         GList *tmp;
420
421         g_return_if_fail (group_name != NULL);
422
423         tmp = item->groups;
424         while (tmp != NULL) {
425                 gchar *val = (gchar *)tmp->data;
426                 
427                 if (strcmp (group_name, val) == 0) {
428                         item->groups = g_list_remove (item->groups,
429                                                       val);
430                         g_free (val);
431                         break;
432                 }
433
434                 tmp = tmp->next;
435         }
436 }
437
438 void
439 egg_recent_item_set_private (EggRecentItem *item, gboolean priv)
440 {
441         item->private_data = priv;
442 }
443
444 gboolean
445 egg_recent_item_get_private (const EggRecentItem *item)
446 {
447         return item->private_data;
448 }
449
450 GType
451 egg_recent_item_get_type (void)
452 {
453         static GType boxed_type = 0;
454         
455         if (!boxed_type) {
456                 boxed_type = g_boxed_type_register_static ("EggRecentItem",
457                                         (GBoxedCopyFunc)egg_recent_item_ref,
458                                         (GBoxedFreeFunc)egg_recent_item_unref);
459         }
460         
461         return boxed_type;
462 }