Updated Slovenian translation
[nautilus.git] / libnautilus-private / nautilus-emblem-utils.c
blob92d2176301b23858bcd6218d47d3a8da0bf52c85
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>
25 #include <config.h>
27 #include <sys/types.h>
28 #include <utime.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.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"
48 GList *
49 nautilus_emblem_list_available (void)
51 GtkIconTheme *icon_theme;
52 GList *list;
54 icon_theme = gtk_icon_theme_get_default ();
55 list = gtk_icon_theme_list_icons (icon_theme, "Emblems");
56 return list;
59 void
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);
68 char *
69 nautilus_emblem_get_icon_name_from_keyword (const char *keyword)
71 return g_strconcat ("emblem-", keyword, NULL);
75 /* check for reserved keywords */
76 static gboolean
77 is_reserved_keyword (const char *keyword)
79 GList *available;
80 char *icon_name;
81 gboolean result;
83 g_assert (keyword != NULL);
85 /* check intrinsic emblems */
86 if (g_ascii_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_TRASH) == 0) {
87 return TRUE;
89 if (g_ascii_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_CANT_READ) == 0) {
90 return TRUE;
92 if (g_ascii_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_CANT_WRITE) == 0) {
93 return TRUE;
95 if (g_ascii_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_SYMBOLIC_LINK) == 0) {
96 return TRUE;
98 if (g_ascii_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_NOTE) == 0) {
99 return TRUE;
101 if (g_ascii_strcasecmp (keyword, NAUTILUS_FILE_EMBLEM_NAME_DESKTOP) == 0) {
102 return TRUE;
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,
109 (char *) icon_name,
110 (GCompareFunc) g_ascii_strcasecmp) != NULL;
111 eel_g_list_free_deep (available);
112 g_free (icon_name);
113 return result;
116 gboolean
117 nautilus_emblem_should_show_in_list (const char *emblem)
119 if (strcmp (emblem, EMBLEM_NAME_TRASH) == 0) {
120 return FALSE;
122 if (strcmp (emblem, EMBLEM_NAME_SYMLINK) == 0) {
123 return FALSE;
125 if (strcmp (emblem, EMBLEM_NAME_NOREAD) == 0) {
126 return FALSE;
128 if (strcmp (emblem, EMBLEM_NAME_NOWRITE) == 0) {
129 return FALSE;
131 if (strcmp (emblem, EMBLEM_NAME_NOTE) == 0) {
132 return FALSE;
134 if (strcmp (emblem, EMBLEM_NAME_DESKTOP) == 0) {
135 return FALSE;
138 return TRUE;
141 char *
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]);
148 } else {
149 return g_strdup (emblem);
153 GdkPixbuf *
154 nautilus_emblem_load_pixbuf_for_emblem (GFile *emblem)
156 GInputStream *stream;
157 GdkPixbuf *pixbuf;
158 GdkPixbuf *scaled;
160 stream = (GInputStream *) g_file_read (emblem, NULL, NULL);
161 if (!stream) {
162 return 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);
175 return scaled;
178 /* utility to make sure the passed-in keyword only contains alphanumeric characters */
179 static gboolean
180 emblem_keyword_valid (const char *keyword)
182 const char *p;
183 gunichar c;
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)) {
190 return FALSE;
194 return TRUE;
197 gboolean
198 nautilus_emblem_verify_keyword (GtkWindow *parent_window,
199 const char *keyword,
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));
206 return FALSE;
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));
211 return FALSE;
212 } else if (is_reserved_keyword (keyword)) {
213 char *error_string;
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);
223 return FALSE;
226 return TRUE;
229 void
230 nautilus_emblem_install_custom_emblem (GdkPixbuf *pixbuf,
231 const char *keyword,
232 const char *display_name,
233 GtkWindow *parent_window)
235 char *basename, *path, *dir, *stat_dir;
236 struct stat stat_buf;
237 struct utimbuf ubuf;
239 g_return_if_fail (pixbuf != NULL);
241 if (!nautilus_emblem_verify_keyword (parent_window, keyword, display_name)) {
242 return;
245 dir = g_build_filename (g_get_home_dir (),
246 ".icons", "hicolor", "48x48", "emblems",
247 NULL);
248 stat_dir = g_build_filename (g_get_home_dir (),
249 ".icons", "hicolor",
250 NULL);
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));
256 g_free (dir);
257 g_free (stat_dir);
258 return;
261 basename = g_strdup_printf ("emblem-%s.png", keyword);
262 path = g_build_filename (dir, basename, NULL);
263 g_free (basename);
265 /* save the image */
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));
270 g_free (dir);
271 g_free (stat_dir);
272 g_free (path);
273 return;
276 g_free (path);
278 if (display_name != NULL) {
279 char *contents;
281 basename = g_strdup_printf ("emblem-%s.icon", keyword);
282 path = g_build_filename (dir, basename, NULL);
283 g_free (basename);
285 contents = g_strdup_printf ("\n[Icon Data]\n\nDisplayName=%s\n",
286 display_name);
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));
292 g_free (contents);
293 g_free (path);
294 g_free (stat_dir);
295 g_free (dir);
296 return;
299 g_free (contents);
300 g_free (path);
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);
310 g_free (dir);
311 g_free (stat_dir);
313 return;
316 gboolean
317 nautilus_emblem_can_remove_emblem (const char *keyword)
319 char *path;
320 gboolean ret = TRUE;
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) {
326 ret = FALSE;
329 g_free (path);
331 return ret;
334 gboolean
335 nautilus_emblem_can_rename_emblem (const char *keyword)
337 char *path;
338 gboolean ret = TRUE;
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) {
344 ret = FALSE;
347 g_free (path);
349 return ret;
352 /* of course, this only works for custom installed emblems */
353 gboolean
354 nautilus_emblem_remove_emblem (const char *keyword)
356 char *path, *dir, *stat_dir;
357 struct stat stat_buf;
358 struct utimbuf ubuf;
361 dir = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems",
362 g_get_home_dir ());
363 stat_dir = g_strdup_printf ("%s/.icons/hicolor",
364 g_get_home_dir ());
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 */
371 g_free (dir);
372 g_free (stat_dir);
373 g_free (path);
374 return FALSE;
377 g_free (path);
379 path = g_strdup_printf ("%s/emblem-%s.icon", dir, keyword);
381 if (unlink (path) != 0) {
382 g_free (dir);
383 g_free (stat_dir);
384 g_free (path);
385 return FALSE;
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);
395 g_free (dir);
396 g_free (stat_dir);
398 return TRUE;
401 /* this only works for custom emblems as well */
402 gboolean
403 nautilus_emblem_rename_emblem (const char *keyword, const char *name)
405 char *path, *dir, *stat_dir, *icon_name;
406 struct stat stat_buf;
407 struct utimbuf ubuf;
408 FILE *file;
410 dir = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems",
411 g_get_home_dir ());
412 stat_dir = g_strdup_printf ("%s/.icons/hicolor",
413 g_get_home_dir ());
415 path = g_strdup_printf ("%s/emblem-%s.icon", dir, keyword);
417 file = fopen (path, "w+");
418 g_free (path);
420 if (file == NULL) {
421 g_free (dir);
422 g_free (stat_dir);
423 return FALSE;
427 /* write the new icon description */
428 fprintf (file, "\n[Icon Data]\n\nDisplayName=%s\n", name);
429 fflush (file);
430 fclose (file);
432 icon_name = nautilus_emblem_get_icon_name_from_keyword (keyword);
433 nautilus_icon_info_clear_caches (); /* A bit overkill, but this happens rarely */
435 g_free (icon_name);
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);
444 g_free (dir);
445 g_free (stat_dir);
447 return TRUE;
450 char *
451 nautilus_emblem_create_unique_keyword (const char *base)
453 char *keyword;
454 time_t t;
455 int i;
457 time (&t);
458 i=0;
460 keyword = NULL;
461 do {
462 g_free (keyword);
463 keyword = g_strdup_printf ("user%s%d%d", base, (int)t, i++);
464 } while (is_reserved_keyword (keyword));
466 return keyword;