]> www.fi.muni.cz Git - evince.git/blob - cut-n-paste/recent-files/egg-recent-item.c
Fix printing with poppler splash backend. Fixes bug #489774.
[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 static void
105 egg_recent_item_update_mime_type (EggRecentItem *item)
106 {
107         if (!item->mime_type_is_explicit) {
108                 g_free (item->mime_type);
109                 item->mime_type = NULL;
110
111                 if (item->uri)
112                         item->mime_type = gnome_vfs_get_mime_type (item->uri);
113
114                 if (!item->mime_type)
115                         item->mime_type = g_strdup (GNOME_VFS_MIME_TYPE_UNKNOWN);
116         }
117 }
118
119 gboolean
120 egg_recent_item_set_uri (EggRecentItem *item, const gchar *uri)
121 {
122         gchar *utf8_uri;
123
124         /* if G_BROKEN_FILENAMES is not set, this should succede */
125         if (g_utf8_validate (uri, -1, NULL)) {
126                 item->uri = gnome_vfs_make_uri_from_input (uri);
127         } else {
128                 utf8_uri = g_filename_to_utf8 (uri, -1, NULL, NULL, NULL);
129
130                 if (utf8_uri == NULL) {
131                         g_warning ("Couldn't convert URI to UTF-8");
132                         return FALSE;
133                 }
134
135                 if (g_utf8_validate (utf8_uri, -1, NULL)) {
136                         item->uri = gnome_vfs_make_uri_from_input (utf8_uri);
137                 } else {
138                         g_free (utf8_uri);
139                         return FALSE;
140                 }
141
142                 g_free (utf8_uri);
143         }
144
145         return TRUE;
146 }
147
148 gchar * 
149 egg_recent_item_get_uri (const EggRecentItem *item)
150 {
151         return g_strdup (item->uri);
152 }
153
154 G_CONST_RETURN gchar * 
155 egg_recent_item_peek_uri (const EggRecentItem *item)
156 {
157         return item->uri;
158 }
159
160 gchar * 
161 egg_recent_item_get_uri_utf8 (const EggRecentItem *item)
162 {
163         /* this could fail, but it's not likely, since we've already done it
164          * once in set_uri()
165          */
166         return g_filename_to_utf8 (item->uri, -1, NULL, NULL, NULL);
167 }
168
169 gchar *
170 egg_recent_item_get_uri_for_display (const EggRecentItem *item)
171 {
172         return gnome_vfs_format_uri_for_display (item->uri);
173 }
174
175 /* Stolen from gnome_vfs_make_valid_utf8() */
176 static char *
177 make_valid_utf8 (const char *name)
178 {
179         GString *string;
180         const char *remainder, *invalid;
181         int remaining_bytes, valid_bytes;
182
183         string = NULL;
184         remainder = name;
185         remaining_bytes = name ? strlen (name) : 0;
186
187         while (remaining_bytes != 0) {
188                 if (g_utf8_validate (remainder, remaining_bytes, &invalid))
189                         break;
190
191                 valid_bytes = invalid - remainder;
192
193                 if (string == NULL)
194                         string = g_string_sized_new (remaining_bytes);
195
196                 g_string_append_len (string, remainder, valid_bytes);
197                 g_string_append_c (string, '?');
198
199                 remaining_bytes -= valid_bytes + 1;
200                 remainder = invalid + 1;
201         }
202
203         if (string == NULL)
204                 return g_strdup (name);
205
206         g_string_append (string, remainder);
207 /*      g_string_append (string, _(" (invalid file name)")); */
208         g_assert (g_utf8_validate (string->str, -1, NULL));
209
210         return g_string_free (string, FALSE);
211 }
212
213 static gchar *
214 get_uri_shortname_for_display (GnomeVFSURI *uri)
215 {
216         gchar    *name; 
217         gboolean  validated;
218
219         validated = FALSE;
220         name = gnome_vfs_uri_extract_short_name (uri);
221         
222         if (name == NULL)
223         {
224                 name = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
225         }
226         else if (g_ascii_strcasecmp (uri->method_string, "file") == 0)
227         {
228                 gchar *text_uri;
229                 gchar *local_file;
230                 text_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
231                 local_file = gnome_vfs_get_local_path_from_uri (text_uri);
232                 
233                 if (local_file != NULL)
234                 {
235                         g_free (name);
236                         name = g_filename_display_basename (local_file);
237                         validated = TRUE;
238                 }
239                 
240                 g_free (local_file);
241                 g_free (text_uri);
242         } 
243         else if (!gnome_vfs_uri_has_parent (uri)) 
244         {
245                 const gchar *method;
246                 
247                 method = uri->method_string;
248                 
249                 if (name == NULL ||
250                     strcmp (name, GNOME_VFS_URI_PATH_STR) == 0) 
251                 {
252                         g_free (name);
253                         name = g_strdup (method);
254                 } 
255                 else 
256                 {
257                         gchar *tmp;
258                         
259                         tmp = name;
260                         name = g_strdup_printf ("%s: %s", method, name);
261                         g_free (tmp);
262                 }
263         }
264
265         if (!validated && !g_utf8_validate (name, -1, NULL)) 
266         {
267                 gchar *utf8_name;
268                 
269                 utf8_name = make_valid_utf8 (name);
270                 g_free (name);
271                 name = utf8_name;
272         }
273
274         return name;
275 }
276
277 /**
278  * egg_recent_item_get_short_name:
279  * @item: an #EggRecentItem
280  *
281  * Computes a valid UTF-8 string that can be used as the name of the item in a
282  * menu or list.  For example, calling this function on an item that refers to
283  * "file:///foo/bar.txt" will yield "bar.txt".
284  *
285  * Return value: A newly-allocated string in UTF-8 encoding; free it with
286  * g_free().
287  **/
288 gchar *
289 egg_recent_item_get_short_name (const EggRecentItem *item)
290 {
291         GnomeVFSURI *uri;
292         gchar *short_name;
293
294         g_return_val_if_fail (item != NULL, NULL);
295
296         if (item->uri == NULL)
297                 return NULL;
298
299         uri = gnome_vfs_uri_new (item->uri);
300         if (uri == NULL)
301                 return NULL;
302
303         short_name = get_uri_shortname_for_display (uri);
304
305         gnome_vfs_uri_unref (uri);
306
307         return short_name;
308 }
309
310 void 
311 egg_recent_item_set_mime_type (EggRecentItem *item, const gchar *mime)
312 {
313         g_free (item->mime_type);
314         item->mime_type = NULL;
315
316         if (mime && mime[0]) {
317                 item->mime_type_is_explicit = TRUE;
318                 item->mime_type             = g_strdup (mime);
319         } else {
320                 item->mime_type_is_explicit = FALSE;
321         }
322 }
323
324 gchar * 
325 egg_recent_item_get_mime_type (EggRecentItem *item)
326 {
327         egg_recent_item_update_mime_type (item);
328
329         return g_strdup (item->mime_type);
330 }
331
332 void 
333 egg_recent_item_set_timestamp (EggRecentItem *item, time_t timestamp)
334 {
335         if (timestamp == (time_t) -1)
336                 time (&timestamp);
337
338         item->timestamp = timestamp;
339 }
340
341 time_t 
342 egg_recent_item_get_timestamp (const EggRecentItem *item)
343 {
344         return item->timestamp;
345 }
346
347 G_CONST_RETURN GList *
348 egg_recent_item_get_groups (const EggRecentItem *item)
349 {
350         return item->groups;
351 }
352
353 gboolean
354 egg_recent_item_in_group (const EggRecentItem *item, const gchar *group_name)
355 {
356         GList *tmp;
357
358         tmp = item->groups;
359         while (tmp != NULL) {
360                 gchar *val = (gchar *)tmp->data;
361                 
362                 if (strcmp (group_name, val) == 0)
363                         return TRUE;
364
365                 tmp = tmp->next;
366         }
367         
368         return FALSE;
369 }
370
371 void
372 egg_recent_item_add_group (EggRecentItem *item, const gchar *group_name)
373 {
374         g_return_if_fail (group_name != NULL);
375
376         if (!egg_recent_item_in_group (item, group_name))
377                 item->groups = g_list_append (item->groups, g_strdup (group_name));
378 }
379
380 void
381 egg_recent_item_remove_group (EggRecentItem *item, const gchar *group_name)
382 {
383         GList *tmp;
384
385         g_return_if_fail (group_name != NULL);
386
387         tmp = item->groups;
388         while (tmp != NULL) {
389                 gchar *val = (gchar *)tmp->data;
390                 
391                 if (strcmp (group_name, val) == 0) {
392                         item->groups = g_list_remove (item->groups,
393                                                       val);
394                         g_free (val);
395                         break;
396                 }
397
398                 tmp = tmp->next;
399         }
400 }
401
402 void
403 egg_recent_item_set_private (EggRecentItem *item, gboolean priv)
404 {
405         item->private_data = priv;
406 }
407
408 gboolean
409 egg_recent_item_get_private (const EggRecentItem *item)
410 {
411         return item->private_data;
412 }
413
414 GType
415 egg_recent_item_get_type (void)
416 {
417         static GType boxed_type = 0;
418         
419         if (!boxed_type) {
420                 boxed_type = g_boxed_type_register_static ("EggRecentItem",
421                                         (GBoxedCopyFunc)egg_recent_item_ref,
422                                         (GBoxedFreeFunc)egg_recent_item_unref);
423         }
424         
425         return boxed_type;
426 }