1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
3 nautilus-emblem-utils.c: Utilities for handling emblems
5 Copyright (C) 2002 Red Hat, Inc.
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public
18 License along with this program; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Author: Alexander Larsson <alexl@redhat.com>
27 #include <sys/types.h>
33 #include "nautilus-file.h"
34 #include <eel/eel-glib-extensions.h>
35 #include <eel/eel-gdk-pixbuf-extensions.h>
36 #include <eel/eel-stock-dialogs.h>
37 #include <glib/gi18n.h>
38 #include <gtk/gtkicontheme.h>
39 #include "nautilus-emblem-utils.h"
41 #define EMBLEM_NAME_TRASH "emblem-trash"
42 #define EMBLEM_NAME_SYMLINK "emblem-symbolic-link"
43 #define EMBLEM_NAME_NOREAD "emblem-noread"
44 #define EMBLEM_NAME_NOWRITE "emblem-nowrite"
45 #define EMBLEM_NAME_NOTE "emblem-note"
46 #define EMBLEM_NAME_DESKTOP "emblem-desktop"
49 nautilus_emblem_list_available (void)
51 GtkIconTheme
*icon_theme
;
54 icon_theme
= gtk_icon_theme_get_default ();
55 list
= gtk_icon_theme_list_icons (icon_theme
, "Emblems");
60 nautilus_emblem_refresh_list (void)
62 GtkIconTheme
*icon_theme
;
64 icon_theme
= gtk_icon_theme_get_default ();
65 gtk_icon_theme_rescan_if_needed (icon_theme
);
69 nautilus_emblem_get_icon_name_from_keyword (const char *keyword
)
71 return g_strconcat ("emblem-", keyword
, NULL
);
75 /* check for reserved keywords */
77 is_reserved_keyword (const char *keyword
)
83 g_assert (keyword
!= NULL
);
85 /* check intrinsic emblems */
86 if (g_ascii_strcasecmp (keyword
, NAUTILUS_FILE_EMBLEM_NAME_TRASH
) == 0) {
89 if (g_ascii_strcasecmp (keyword
, NAUTILUS_FILE_EMBLEM_NAME_CANT_READ
) == 0) {
92 if (g_ascii_strcasecmp (keyword
, NAUTILUS_FILE_EMBLEM_NAME_CANT_WRITE
) == 0) {
95 if (g_ascii_strcasecmp (keyword
, NAUTILUS_FILE_EMBLEM_NAME_SYMBOLIC_LINK
) == 0) {
98 if (g_ascii_strcasecmp (keyword
, NAUTILUS_FILE_EMBLEM_NAME_NOTE
) == 0) {
101 if (g_ascii_strcasecmp (keyword
, NAUTILUS_FILE_EMBLEM_NAME_DESKTOP
) == 0) {
105 available
= nautilus_emblem_list_available ();
106 icon_name
= nautilus_emblem_get_icon_name_from_keyword (keyword
);
107 /* see if the keyword already exists */
108 result
= g_list_find_custom (available
,
110 (GCompareFunc
) g_ascii_strcasecmp
) != NULL
;
111 eel_g_list_free_deep (available
);
117 nautilus_emblem_should_show_in_list (const char *emblem
)
119 if (strcmp (emblem
, EMBLEM_NAME_TRASH
) == 0) {
122 if (strcmp (emblem
, EMBLEM_NAME_SYMLINK
) == 0) {
125 if (strcmp (emblem
, EMBLEM_NAME_NOREAD
) == 0) {
128 if (strcmp (emblem
, EMBLEM_NAME_NOWRITE
) == 0) {
131 if (strcmp (emblem
, EMBLEM_NAME_NOTE
) == 0) {
134 if (strcmp (emblem
, EMBLEM_NAME_DESKTOP
) == 0) {
142 nautilus_emblem_get_keyword_from_icon_name (const char *emblem
)
144 g_return_val_if_fail (emblem
!= NULL
, NULL
);
146 if (g_str_has_prefix (emblem
, "emblem-")) {
147 return g_strdup (&emblem
[7]);
149 return g_strdup (emblem
);
154 nautilus_emblem_load_pixbuf_for_emblem (GFile
*emblem
)
156 GInputStream
*stream
;
160 stream
= (GInputStream
*) g_file_read (emblem
, NULL
, NULL
);
165 pixbuf
= eel_gdk_pixbuf_load_from_stream (stream
);
166 g_return_val_if_fail (pixbuf
!= NULL
, NULL
);
168 scaled
= eel_gdk_pixbuf_scale_down_to_fit (pixbuf
,
169 NAUTILUS_ICON_SIZE_STANDARD
,
170 NAUTILUS_ICON_SIZE_STANDARD
);
172 g_object_unref (pixbuf
);
173 g_object_unref (stream
);
178 /* utility to make sure the passed-in keyword only contains alphanumeric characters */
180 emblem_keyword_valid (const char *keyword
)
185 for (p
= keyword
; *p
; p
= g_utf8_next_char (p
)) {
186 c
= g_utf8_get_char (p
);
188 if (!g_unichar_isalnum (c
) &&
189 !g_unichar_isspace (c
)) {
198 nautilus_emblem_verify_keyword (GtkWindow
*parent_window
,
200 const char *display_name
)
202 if (keyword
== NULL
|| strlen (keyword
) == 0) {
203 eel_show_error_dialog (_("The emblem cannot be installed."),
204 _("Sorry, but you must specify a non-blank keyword for the new emblem."),
205 GTK_WINDOW (parent_window
));
207 } else if (!emblem_keyword_valid (keyword
)) {
208 eel_show_error_dialog (_("The emblem cannot be installed."),
209 _("Sorry, but emblem keywords can only contain letters, spaces and numbers."),
210 GTK_WINDOW (parent_window
));
212 } else if (is_reserved_keyword (keyword
)) {
215 /* this really should never happen, as a user has no idea
216 * what a keyword is, and people should be passing a unique
217 * keyword to us anyway
219 error_string
= g_strdup_printf (_("Sorry, but there is already an emblem named \"%s\"."), display_name
);
220 eel_show_error_dialog (_("Please choose a different emblem name."), error_string
,
221 GTK_WINDOW (parent_window
));
222 g_free (error_string
);
230 nautilus_emblem_install_custom_emblem (GdkPixbuf
*pixbuf
,
232 const char *display_name
,
233 GtkWindow
*parent_window
)
235 char *basename
, *path
, *dir
, *stat_dir
;
236 struct stat stat_buf
;
239 g_return_if_fail (pixbuf
!= NULL
);
241 if (!nautilus_emblem_verify_keyword (parent_window
, keyword
, display_name
)) {
245 dir
= g_build_filename (g_get_home_dir (),
246 ".icons", "hicolor", "48x48", "emblems",
248 stat_dir
= g_build_filename (g_get_home_dir (),
252 if (g_mkdir_with_parents (dir
, 0755) != 0) {
253 eel_show_error_dialog (_("The emblem cannot be installed."),
254 _("Sorry, unable to save custom emblem."),
255 GTK_WINDOW (parent_window
));
261 basename
= g_strdup_printf ("emblem-%s.png", keyword
);
262 path
= g_build_filename (dir
, basename
, NULL
);
266 if (eel_gdk_pixbuf_save_to_file (pixbuf
, path
) != TRUE
) {
267 eel_show_error_dialog (_("The emblem cannot be installed."),
268 _("Sorry, unable to save custom emblem."),
269 GTK_WINDOW (parent_window
));
278 if (display_name
!= NULL
) {
281 basename
= g_strdup_printf ("emblem-%s.icon", keyword
);
282 path
= g_build_filename (dir
, basename
, NULL
);
285 contents
= g_strdup_printf ("\n[Icon Data]\n\nDisplayName=%s\n",
288 if (!g_file_set_contents (path
, contents
, strlen (contents
), NULL
)) {
289 eel_show_error_dialog (_("The emblem cannot be installed."),
290 _("Sorry, unable to save custom emblem name."),
291 GTK_WINDOW (parent_window
));
303 /* Touch the toplevel dir */
304 if (stat (stat_dir
, &stat_buf
) == 0) {
305 ubuf
.actime
= stat_buf
.st_atime
;
306 ubuf
.modtime
= time (NULL
);
307 utime (stat_dir
, &ubuf
);
317 nautilus_emblem_can_remove_emblem (const char *keyword
)
322 path
= g_strdup_printf ("%s/.icons/hicolor/48x48/emblems/emblem-%s.png",
323 g_get_home_dir (), keyword
);
325 if (access (path
, F_OK
|W_OK
) != 0) {
335 nautilus_emblem_can_rename_emblem (const char *keyword
)
340 path
= g_strdup_printf ("%s/.icons/hicolor/48x48/emblems/emblem-%s.png",
341 g_get_home_dir (), keyword
);
343 if (access (path
, F_OK
|R_OK
) != 0) {
352 /* of course, this only works for custom installed emblems */
354 nautilus_emblem_remove_emblem (const char *keyword
)
356 char *path
, *dir
, *stat_dir
;
357 struct stat stat_buf
;
361 dir
= g_strdup_printf ("%s/.icons/hicolor/48x48/emblems",
363 stat_dir
= g_strdup_printf ("%s/.icons/hicolor",
366 path
= g_strdup_printf ("%s/emblem-%s.png", dir
, keyword
);
368 /* delete the image */
369 if (unlink (path
) != 0) {
370 /* couldn't delete it */
379 path
= g_strdup_printf ("%s/emblem-%s.icon", dir
, keyword
);
381 if (unlink (path
) != 0) {
388 /* Touch the toplevel dir */
389 if (stat (stat_dir
, &stat_buf
) == 0) {
390 ubuf
.actime
= stat_buf
.st_atime
;
391 ubuf
.modtime
= time (NULL
);
392 utime (stat_dir
, &ubuf
);
401 /* this only works for custom emblems as well */
403 nautilus_emblem_rename_emblem (const char *keyword
, const char *name
)
405 char *path
, *dir
, *stat_dir
, *icon_name
;
406 struct stat stat_buf
;
410 dir
= g_strdup_printf ("%s/.icons/hicolor/48x48/emblems",
412 stat_dir
= g_strdup_printf ("%s/.icons/hicolor",
415 path
= g_strdup_printf ("%s/emblem-%s.icon", dir
, keyword
);
417 file
= fopen (path
, "w+");
427 /* write the new icon description */
428 fprintf (file
, "\n[Icon Data]\n\nDisplayName=%s\n", name
);
432 icon_name
= nautilus_emblem_get_icon_name_from_keyword (keyword
);
433 nautilus_icon_info_clear_caches (); /* A bit overkill, but this happens rarely */
437 /* Touch the toplevel dir */
438 if (stat (stat_dir
, &stat_buf
) == 0) {
439 ubuf
.actime
= stat_buf
.st_atime
;
440 ubuf
.modtime
= time (NULL
);
441 utime (stat_dir
, &ubuf
);
451 nautilus_emblem_create_unique_keyword (const char *base
)
463 keyword
= g_strdup_printf ("user%s%d%d", base
, (int)t
, i
++);
464 } while (is_reserved_keyword (keyword
));