From 0e004c696b0e68b2cff37a4c3315b022a35eaf43 Mon Sep 17 00:00:00 2001 From: Perberos Date: Thu, 1 Dec 2011 22:24:23 -0300 Subject: moving from https://github.com/perberos/mate-desktop-environment --- libcaja-private/caja-emblem-utils.c | 511 ++++++++++++++++++++++++++++++++++++ 1 file changed, 511 insertions(+) create mode 100644 libcaja-private/caja-emblem-utils.c (limited to 'libcaja-private/caja-emblem-utils.c') diff --git a/libcaja-private/caja-emblem-utils.c b/libcaja-private/caja-emblem-utils.c new file mode 100644 index 00000000..b1813e10 --- /dev/null +++ b/libcaja-private/caja-emblem-utils.c @@ -0,0 +1,511 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + caja-emblem-utils.c: Utilities for handling emblems + + Copyright (C) 2002 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Alexander Larsson +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "caja-file.h" +#include "caja-emblem-utils.h" + +#define EMBLEM_NAME_TRASH "emblem-trash" +#define EMBLEM_NAME_SYMLINK "emblem-symbolic-link" +#define EMBLEM_NAME_NOREAD "emblem-noread" +#define EMBLEM_NAME_NOWRITE "emblem-nowrite" +#define EMBLEM_NAME_NOTE "emblem-note" +#define EMBLEM_NAME_SHARED "emblem-shared" + +GList * +caja_emblem_list_available (void) +{ + GtkIconTheme *icon_theme; + GList *list; + + icon_theme = gtk_icon_theme_get_default (); + list = gtk_icon_theme_list_icons (icon_theme, "Emblems"); + return list; +} + +void +caja_emblem_refresh_list (void) +{ + GtkIconTheme *icon_theme; + + icon_theme = gtk_icon_theme_get_default (); + gtk_icon_theme_rescan_if_needed (icon_theme); +} + +char * +caja_emblem_get_icon_name_from_keyword (const char *keyword) +{ + return g_strconcat ("emblem-", keyword, NULL); +} + + +/* check for reserved keywords */ +static gboolean +is_reserved_keyword (const char *keyword) +{ + GList *available; + char *icon_name; + gboolean result; + + g_assert (keyword != NULL); + + /* check intrinsic emblems */ + if (g_ascii_strcasecmp (keyword, CAJA_FILE_EMBLEM_NAME_TRASH) == 0) + { + return TRUE; + } + if (g_ascii_strcasecmp (keyword, CAJA_FILE_EMBLEM_NAME_CANT_READ) == 0) + { + return TRUE; + } + if (g_ascii_strcasecmp (keyword, CAJA_FILE_EMBLEM_NAME_CANT_WRITE) == 0) + { + return TRUE; + } + if (g_ascii_strcasecmp (keyword, CAJA_FILE_EMBLEM_NAME_SYMBOLIC_LINK) == 0) + { + return TRUE; + } + if (g_ascii_strcasecmp (keyword, CAJA_FILE_EMBLEM_NAME_NOTE) == 0) + { + return TRUE; + } + if (g_ascii_strcasecmp (keyword, CAJA_FILE_EMBLEM_NAME_SHARED) == 0) + { + return TRUE; + } + + available = caja_emblem_list_available (); + icon_name = caja_emblem_get_icon_name_from_keyword (keyword); + /* see if the keyword already exists */ + result = g_list_find_custom (available, + (char *) icon_name, + (GCompareFunc) g_ascii_strcasecmp) != NULL; + eel_g_list_free_deep (available); + g_free (icon_name); + return result; +} + +gboolean +caja_emblem_should_show_in_list (const char *emblem) +{ + if (strcmp (emblem, EMBLEM_NAME_TRASH) == 0) + { + return FALSE; + } + if (strcmp (emblem, EMBLEM_NAME_SYMLINK) == 0) + { + return FALSE; + } + if (strcmp (emblem, EMBLEM_NAME_NOREAD) == 0) + { + return FALSE; + } + if (strcmp (emblem, EMBLEM_NAME_NOWRITE) == 0) + { + return FALSE; + } + if (strcmp (emblem, EMBLEM_NAME_NOTE) == 0) + { + return FALSE; + } + if (strcmp (emblem, EMBLEM_NAME_SHARED) == 0) + { + return FALSE; + } + + return TRUE; +} + +char * +caja_emblem_get_keyword_from_icon_name (const char *emblem) +{ + g_return_val_if_fail (emblem != NULL, NULL); + + if (g_str_has_prefix (emblem, "emblem-")) + { + return g_strdup (&emblem[7]); + } + else + { + return g_strdup (emblem); + } +} + +GdkPixbuf * +caja_emblem_load_pixbuf_for_emblem (GFile *emblem) +{ + GInputStream *stream; + GdkPixbuf *pixbuf; + GdkPixbuf *scaled; + + stream = (GInputStream *) g_file_read (emblem, NULL, NULL); + if (!stream) + { + return NULL; + } + + pixbuf = eel_gdk_pixbuf_load_from_stream (stream); + g_return_val_if_fail (pixbuf != NULL, NULL); + + scaled = eel_gdk_pixbuf_scale_down_to_fit (pixbuf, + CAJA_ICON_SIZE_STANDARD, + CAJA_ICON_SIZE_STANDARD); + + g_object_unref (pixbuf); + g_object_unref (stream); + + return scaled; +} + +/* utility to make sure the passed-in keyword only contains alphanumeric characters */ +static gboolean +emblem_keyword_valid (const char *keyword) +{ + const char *p; + gunichar c; + + for (p = keyword; *p; p = g_utf8_next_char (p)) + { + c = g_utf8_get_char (p); + + if (!g_unichar_isalnum (c) && + !g_unichar_isspace (c)) + { + return FALSE; + } + } + + return TRUE; +} + +gboolean +caja_emblem_verify_keyword (GtkWindow *parent_window, + const char *keyword, + const char *display_name) +{ + if (keyword == NULL || strlen (keyword) == 0) + { + eel_show_error_dialog (_("The emblem cannot be installed."), + _("Sorry, but you must specify a non-blank keyword for the new emblem."), + GTK_WINDOW (parent_window)); + return FALSE; + } + else if (!emblem_keyword_valid (keyword)) + { + eel_show_error_dialog (_("The emblem cannot be installed."), + _("Sorry, but emblem keywords can only contain letters, spaces and numbers."), + GTK_WINDOW (parent_window)); + return FALSE; + } + else if (is_reserved_keyword (keyword)) + { + char *error_string; + + /* this really should never happen, as a user has no idea + * what a keyword is, and people should be passing a unique + * keyword to us anyway + */ + error_string = g_strdup_printf (_("Sorry, but there is already an emblem named \"%s\"."), display_name); + eel_show_error_dialog (_("Please choose a different emblem name."), error_string, + GTK_WINDOW (parent_window)); + g_free (error_string); + return FALSE; + } + + return TRUE; +} + +void +caja_emblem_install_custom_emblem (GdkPixbuf *pixbuf, + const char *keyword, + const char *display_name, + GtkWindow *parent_window) +{ + char *basename, *path, *dir, *stat_dir; + struct stat stat_buf; + struct utimbuf ubuf; + + g_return_if_fail (pixbuf != NULL); + + if (!caja_emblem_verify_keyword (parent_window, keyword, display_name)) + { + return; + } + + dir = g_build_filename (g_get_home_dir (), + ".icons", "hicolor", "48x48", "emblems", + NULL); + stat_dir = g_build_filename (g_get_home_dir (), + ".icons", "hicolor", + NULL); + + if (g_mkdir_with_parents (dir, 0755) != 0) + { + eel_show_error_dialog (_("The emblem cannot be installed."), + _("Sorry, unable to save custom emblem."), + GTK_WINDOW (parent_window)); + g_free (dir); + g_free (stat_dir); + return; + } + + basename = g_strdup_printf ("emblem-%s.png", keyword); + path = g_build_filename (dir, basename, NULL); + g_free (basename); + + /* save the image */ + if (eel_gdk_pixbuf_save_to_file (pixbuf, path) != TRUE) + { + eel_show_error_dialog (_("The emblem cannot be installed."), + _("Sorry, unable to save custom emblem."), + GTK_WINDOW (parent_window)); + g_free (dir); + g_free (stat_dir); + g_free (path); + return; + } + + g_free (path); + + if (display_name != NULL) + { + char *contents; + + basename = g_strdup_printf ("emblem-%s.icon", keyword); + path = g_build_filename (dir, basename, NULL); + g_free (basename); + + contents = g_strdup_printf ("\n[Icon Data]\n\nDisplayName=%s\n", + display_name); + + if (!g_file_set_contents (path, contents, strlen (contents), NULL)) + { + eel_show_error_dialog (_("The emblem cannot be installed."), + _("Sorry, unable to save custom emblem name."), + GTK_WINDOW (parent_window)); + g_free (contents); + g_free (path); + g_free (stat_dir); + g_free (dir); + return; + } + + g_free (contents); + g_free (path); + } + + /* Touch the toplevel dir */ + if (g_stat (stat_dir, &stat_buf) == 0) + { + ubuf.actime = stat_buf.st_atime; + ubuf.modtime = time (NULL); + utime (stat_dir, &ubuf); + } + + g_free (dir); + g_free (stat_dir); + + return; +} + +gboolean +caja_emblem_can_remove_emblem (const char *keyword) +{ + char *path; + gboolean ret = TRUE; + + path = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems/emblem-%s.png", + g_get_home_dir (), keyword); + + if (g_access (path, F_OK|W_OK) != 0) + { + ret = FALSE; + } + + g_free (path); + + return ret; +} + +gboolean +caja_emblem_can_rename_emblem (const char *keyword) +{ + char *path; + gboolean ret = TRUE; + + path = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems/emblem-%s.png", + g_get_home_dir (), keyword); + + if (access (path, F_OK|R_OK) != 0) + { + ret = FALSE; + } + + g_free (path); + + return ret; +} + +/* of course, this only works for custom installed emblems */ +gboolean +caja_emblem_remove_emblem (const char *keyword) +{ + char *path, *dir, *stat_dir; + struct stat stat_buf; + struct utimbuf ubuf; + + + dir = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems", + g_get_home_dir ()); + stat_dir = g_strdup_printf ("%s/.icons/hicolor", + g_get_home_dir ()); + + path = g_strdup_printf ("%s/emblem-%s.png", dir, keyword); + + /* delete the image */ + if (unlink (path) != 0) + { + /* couldn't delete it */ + g_free (dir); + g_free (stat_dir); + g_free (path); + return FALSE; + } + + g_free (path); + + path = g_strdup_printf ("%s/emblem-%s.icon", dir, keyword); + + if (unlink (path) != 0) + { + g_free (dir); + g_free (stat_dir); + g_free (path); + return FALSE; + } + + /* Touch the toplevel dir */ + if (stat (stat_dir, &stat_buf) == 0) + { + ubuf.actime = stat_buf.st_atime; + ubuf.modtime = time (NULL); + utime (stat_dir, &ubuf); + } + + g_free (dir); + g_free (stat_dir); + + return TRUE; +} + +/* this only works for custom emblems as well */ +gboolean +caja_emblem_rename_emblem (const char *keyword, const char *name) +{ + char *path, *dir, *stat_dir, *icon_name; + struct stat stat_buf; + struct utimbuf ubuf; + FILE *file; + + dir = g_strdup_printf ("%s/.icons/hicolor/48x48/emblems", + g_get_home_dir ()); + stat_dir = g_strdup_printf ("%s/.icons/hicolor", + g_get_home_dir ()); + + path = g_strdup_printf ("%s/emblem-%s.icon", dir, keyword); + + file = fopen (path, "w+"); + g_free (path); + + if (file == NULL) + { + g_free (dir); + g_free (stat_dir); + return FALSE; + } + + + /* write the new icon description */ + fprintf (file, "\n[Icon Data]\n\nDisplayName=%s\n", name); + fflush (file); + fclose (file); + + icon_name = caja_emblem_get_icon_name_from_keyword (keyword); + caja_icon_info_clear_caches (); /* A bit overkill, but this happens rarely */ + + g_free (icon_name); + + /* Touch the toplevel dir */ + if (stat (stat_dir, &stat_buf) == 0) + { + ubuf.actime = stat_buf.st_atime; + ubuf.modtime = time (NULL); + utime (stat_dir, &ubuf); + } + + g_free (dir); + g_free (stat_dir); + + return TRUE; +} + +char * +caja_emblem_create_unique_keyword (const char *base) +{ + char *keyword; + time_t t; + int i; + + time (&t); + i=0; + + keyword = NULL; + do + { + g_free (keyword); + keyword = g_strdup_printf ("user%s%d%d", base, (int)t, i++); + } + while (is_reserved_keyword (keyword)); + + return keyword; +} -- cgit v1.2.1