diff options
author | Perberos <[email protected]> | 2011-12-01 22:24:23 -0300 |
---|---|---|
committer | Perberos <[email protected]> | 2011-12-01 22:24:23 -0300 |
commit | 0e004c696b0e68b2cff37a4c3315b022a35eaf43 (patch) | |
tree | 43261e815529cb9518ed7be37af13b846af8b26b /libcaja-private/caja-customization-data.c | |
download | caja-0e004c696b0e68b2cff37a4c3315b022a35eaf43.tar.bz2 caja-0e004c696b0e68b2cff37a4c3315b022a35eaf43.tar.xz |
moving from https://github.com/perberos/mate-desktop-environment
Diffstat (limited to 'libcaja-private/caja-customization-data.c')
-rw-r--r-- | libcaja-private/caja-customization-data.c | 498 |
1 files changed, 498 insertions, 0 deletions
diff --git a/libcaja-private/caja-customization-data.c b/libcaja-private/caja-customization-data.c new file mode 100644 index 00000000..e96cd7c6 --- /dev/null +++ b/libcaja-private/caja-customization-data.c @@ -0,0 +1,498 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* + * Caja + * + * Copyright (C) 2000 Eazel, Inc. + * + * Caja 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. + * + * Caja 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: Rebecca Schulman <[email protected]> + */ + +/* caja-customization-data.c - functions to collect and load customization + names and imges */ + +#include <config.h> +#include "caja-customization-data.h" + +#include "caja-file-utilities.h" +#include <eel/eel-gdk-extensions.h> +#include <eel/eel-gdk-extensions.h> +#include <eel/eel-pango-extensions.h> +#include <eel/eel-gdk-pixbuf-extensions.h> +#include <eel/eel-glib-extensions.h> +#include <eel/eel-gtk-extensions.h> +#include <eel/eel-vfs-extensions.h> +#include <eel/eel-string.h> +#include <eel/eel-xml-extensions.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <glib.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> +#include <libxml/parser.h> +#include <stdlib.h> +#include <string.h> + +typedef enum +{ + READ_PUBLIC_CUSTOMIZATIONS, + READ_PRIVATE_CUSTOMIZATIONS +} CustomizationReadingMode; + +struct CajaCustomizationData +{ + char *customization_name; + + GList *public_file_list; + GList *private_file_list; + GList *current_file_list; + + GHashTable *name_map_hash; + + GdkPixbuf *pattern_frame; + + int maximum_icon_height; + int maximum_icon_width; + + guint private_data_was_displayed : 1; + guint reading_mode : 2; /* enough bits for CustomizationReadingMode */ +}; + + +/* The Property here should be one of "emblems", "colors" or "patterns" */ +static char * get_global_customization_path (const char *customization_name); +static char * get_private_customization_path (const char *customization_name); +static char * get_file_path_for_mode (const CajaCustomizationData *data, + const char *file_name); +static char* format_name_for_display (CajaCustomizationData *data, const char *name); +static void load_name_map_hash_table (CajaCustomizationData *data); + + +static gboolean +read_all_children (char *filename, + const char *attributes, + GList **list_out) +{ + GFileEnumerator *enumerator; + GList *list; + GFile *file; + GFileInfo *info; + + file = g_file_new_for_path (filename); + + enumerator = g_file_enumerate_children (file, attributes, 0, NULL, NULL); + if (enumerator == NULL) + { + return FALSE; + } + + list = NULL; + do + { + info = g_file_enumerator_next_file (enumerator, NULL, NULL); + if (info) + { + list = g_list_prepend (list, info); + } + } + while (info != NULL); + + g_object_unref (enumerator); + g_object_unref (file); + + *list_out = g_list_reverse (list); + return TRUE; +} + + +CajaCustomizationData* +caja_customization_data_new (const char *customization_name, + gboolean show_public_customizations, + int maximum_icon_height, + int maximum_icon_width) +{ + CajaCustomizationData *data; + char *public_directory_path, *private_directory_path; + char *temp_str; + gboolean public_result, private_result; + + data = g_new0 (CajaCustomizationData, 1); + + public_result = TRUE; + + if (show_public_customizations) + { + public_directory_path = get_global_customization_path (customization_name); + + public_result = read_all_children (public_directory_path, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + &data->public_file_list); + g_free (public_directory_path); + } + + private_directory_path = get_private_customization_path (customization_name); + private_result = read_all_children (private_directory_path, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + &data->private_file_list); + g_free (private_directory_path); + if (!public_result && !private_result) + { + g_warning ("Couldn't read any of the emblem directories\n"); + g_free (data); + return NULL; + } + if (private_result) + { + data->reading_mode = READ_PRIVATE_CUSTOMIZATIONS; + data->current_file_list = data->private_file_list; + } + if (show_public_customizations && public_result) + { + data->reading_mode = READ_PUBLIC_CUSTOMIZATIONS; + data->current_file_list = data->public_file_list; + } + + data->pattern_frame = NULL; + + /* load the frame if necessary */ + if (strcmp (customization_name, "patterns") == 0) + { + temp_str = caja_pixmap_file ("chit_frame.png"); + if (temp_str != NULL) + { + data->pattern_frame = gdk_pixbuf_new_from_file (temp_str, NULL); + } + g_free (temp_str); + } + + data->private_data_was_displayed = FALSE; + data->customization_name = g_strdup (customization_name); + + data->maximum_icon_height = maximum_icon_height; + data->maximum_icon_width = maximum_icon_width; + + load_name_map_hash_table (data); + + return data; +} + +gboolean +caja_customization_data_get_next_element_for_display (CajaCustomizationData *data, + char **emblem_name, + GdkPixbuf **pixbuf_out, + char **label_out) +{ + GFileInfo *current_file_info; + char *image_file_name; + GdkPixbuf *pixbuf; + GdkPixbuf *orig_pixbuf; + gboolean is_reset_image; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (emblem_name != NULL, FALSE); + g_return_val_if_fail (pixbuf_out != NULL, FALSE); + g_return_val_if_fail (label_out != NULL, FALSE); + + if (data->current_file_list == NULL) + { + if (data->reading_mode == READ_PUBLIC_CUSTOMIZATIONS) + { + if (data->private_file_list == NULL) + { + return FALSE; + } + data->reading_mode = READ_PRIVATE_CUSTOMIZATIONS; + data->current_file_list = data->private_file_list; + return caja_customization_data_get_next_element_for_display (data, + emblem_name, + pixbuf_out, + label_out); + } + else + { + return FALSE; + } + } + + + current_file_info = data->current_file_list->data; + data->current_file_list = data->current_file_list->next; + + g_assert (current_file_info != NULL); + + if (!eel_istr_has_prefix (g_file_info_get_content_type (current_file_info), "image/") + || eel_istr_has_prefix (g_file_info_get_name (current_file_info), ".")) + { + return caja_customization_data_get_next_element_for_display (data, + emblem_name, + pixbuf_out, + label_out); + } + + image_file_name = get_file_path_for_mode (data, + g_file_info_get_name (current_file_info)); + orig_pixbuf = gdk_pixbuf_new_from_file_at_scale (image_file_name, + data->maximum_icon_width, + data->maximum_icon_height, + TRUE, + NULL); + g_free (image_file_name); + + if (orig_pixbuf == NULL) + { + return caja_customization_data_get_next_element_for_display (data, + emblem_name, + pixbuf_out, + label_out); + } + + is_reset_image = eel_strcmp(g_file_info_get_name (current_file_info), RESET_IMAGE_NAME) == 0; + + *emblem_name = g_strdup (g_file_info_get_name (current_file_info)); + + if (strcmp (data->customization_name, "patterns") == 0 && + data->pattern_frame != NULL) + { + pixbuf = caja_customization_make_pattern_chit (orig_pixbuf, data->pattern_frame, FALSE, is_reset_image); + } + else + { + pixbuf = eel_gdk_pixbuf_scale_down_to_fit (orig_pixbuf, + data->maximum_icon_width, + data->maximum_icon_height); + } + + g_object_unref (orig_pixbuf); + + *pixbuf_out = pixbuf; + + *label_out = format_name_for_display (data, g_file_info_get_name (current_file_info)); + + if (data->reading_mode == READ_PRIVATE_CUSTOMIZATIONS) + { + data->private_data_was_displayed = TRUE; + } + return TRUE; +} + +gboolean +caja_customization_data_private_data_was_displayed (CajaCustomizationData *data) +{ + return data->private_data_was_displayed; +} + +void +caja_customization_data_destroy (CajaCustomizationData *data) +{ + g_assert (data->public_file_list != NULL || + data->private_file_list != NULL); + + if (data->pattern_frame != NULL) + { + g_object_unref (data->pattern_frame); + } + + eel_g_object_list_free (data->public_file_list); + eel_g_object_list_free (data->private_file_list); + + if (data->name_map_hash != NULL) + { + g_hash_table_destroy (data->name_map_hash); + } + + g_free (data->customization_name); + g_free (data); +} + + +/* get_global_customization_directory + Get the path where a property's pixmaps are stored + @customization_name : the name of the customization to get. + Should be one of "emblems", "colors", or "paterns" + + Return value: The directory name where the customization's + public pixmaps are stored */ +static char * +get_global_customization_path (const char *customization_name) +{ + return g_build_filename (CAJA_DATADIR, + customization_name, + NULL); +} + + +/* get_private_customization_directory + Get the path where a customization's pixmaps are stored + @customization_name : the name of the customization to get. + Should be one of "emblems", "colors", or "patterns" + + Return value: The directory name where the customization's + user-specific pixmaps are stored */ +static char * +get_private_customization_path (const char *customization_name) +{ + char *user_directory; + char *directory_path; + + user_directory = caja_get_user_directory (); + directory_path = g_build_filename (user_directory, + customization_name, + NULL); + g_free (user_directory); + + return directory_path; +} + + +static char * +get_file_path_for_mode (const CajaCustomizationData *data, + const char *file_name) +{ + char *directory_path, *file; + if (data->reading_mode == READ_PUBLIC_CUSTOMIZATIONS) + { + directory_path = get_global_customization_path (data->customization_name); + } + else + { + directory_path = get_private_customization_path (data->customization_name); + } + + file = g_build_filename (directory_path, file_name, NULL); + g_free (directory_path); + + return file; +} + + +/* utility to make an attractive pattern image by compositing with a frame */ +GdkPixbuf* +caja_customization_make_pattern_chit (GdkPixbuf *pattern_tile, GdkPixbuf *frame, gboolean dragging, gboolean is_reset) +{ + GdkPixbuf *pixbuf, *temp_pixbuf; + int frame_width, frame_height; + int pattern_width, pattern_height; + + g_assert (pattern_tile != NULL); + g_assert (frame != NULL); + + frame_width = gdk_pixbuf_get_width (frame); + frame_height = gdk_pixbuf_get_height (frame); + pattern_width = gdk_pixbuf_get_width (pattern_tile); + pattern_height = gdk_pixbuf_get_height (pattern_tile); + + pixbuf = gdk_pixbuf_copy (frame); + + /* scale the pattern tile to the proper size */ + gdk_pixbuf_scale (pattern_tile, + pixbuf, + 2, 2, frame_width - 8, frame_height - 8, + 0, 0, + (double)(frame_width - 8 + 1)/pattern_width, + (double)(frame_height - 8 + 1)/pattern_height, + GDK_INTERP_BILINEAR); + + /* if we're dragging, get rid of the light-colored halo */ + if (dragging) + { + temp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, frame_width - 8, frame_height - 8); + gdk_pixbuf_copy_area (pixbuf, 2, 2, frame_width - 8, frame_height - 8, temp_pixbuf, 0, 0); + g_object_unref (pixbuf); + pixbuf = temp_pixbuf; + } + + return pixbuf; +} + + +/* utility to format the passed-in name for display by stripping the extension, mapping underscore + and capitalizing as necessary */ + +static char* +format_name_for_display (CajaCustomizationData *data, const char* name) +{ + char *formatted_str, *mapped_name; + + if (!eel_strcmp(name, RESET_IMAGE_NAME)) + { + return g_strdup (_("Reset")); + } + + /* map file names to display names using the mappings defined in the hash table */ + + formatted_str = eel_filename_strip_extension (name); + if (data->name_map_hash != NULL) + { + mapped_name = g_hash_table_lookup (data->name_map_hash, formatted_str); + if (mapped_name) + { + g_free (formatted_str); + formatted_str = g_strdup (mapped_name); + } + } + + return formatted_str; +} + +/* utility routine to allocate a hash table and load it with the appropriate + * name mapping data from the browser xml file + */ +static void +load_name_map_hash_table (CajaCustomizationData *data) +{ + char *xml_path; + char *filename, *display_name; + + xmlDocPtr browser_data; + xmlNodePtr category_node, current_node; + + /* allocate the hash table */ + data->name_map_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* build the path name to the browser.xml file and load it */ + xml_path = g_build_filename (CAJA_DATADIR, "browser.xml", NULL); + if (xml_path) + { + browser_data = xmlParseFile (xml_path); + g_free (xml_path); + + if (browser_data) + { + /* get the category node */ + category_node = eel_xml_get_root_child_by_name_and_property (browser_data, "category", "name", data->customization_name); + current_node = category_node->children; + + /* loop through the entries, adding a mapping to the hash table */ + while (current_node != NULL) + { + display_name = eel_xml_get_property_translated (current_node, "display_name"); + filename = xmlGetProp (current_node, "filename"); + if (display_name && filename) + { + g_hash_table_replace (data->name_map_hash, g_strdup (filename), g_strdup (display_name)); + } + xmlFree (filename); + xmlFree (display_name); + current_node = current_node->next; + } + + /* close the xml file */ + xmlFreeDoc (browser_data); + } + } +} |