diff options
Diffstat (limited to 'shell/e-local-folder.c')
-rw-r--r-- | shell/e-local-folder.c | 304 |
1 files changed, 296 insertions, 8 deletions
diff --git a/shell/e-local-folder.c b/shell/e-local-folder.c index 73ae6734da..21f6e6e1d8 100644 --- a/shell/e-local-folder.c +++ b/shell/e-local-folder.c @@ -60,11 +60,142 @@ static EFolderClass *parent_class = NULL; #define URI_PREFIX "file://" #define URI_PREFIX_LEN 7 +/* This provides the name and the description for a specific locale. */ +struct _I18nInfo { + char *language_id; + char *name; + char *description; +}; +typedef struct _I18nInfo I18nInfo; + struct _ELocalFolderPrivate { - int dummy; + GHashTable *language_id_to_i18n_info; }; +/* Locale information. */ + +static char *global_language_id = NULL; + + +/* I18nInfo handling. */ + +static I18nInfo * +i18n_info_new (const char *language_id, + const char *name, + const char *description) +{ + I18nInfo *info; + + info = g_new (I18nInfo, 1); + info->language_id = g_strdup (language_id); + info->name = g_strdup (name); + info->description = g_strdup (description); + + return info; +} + +static void +i18n_info_free (I18nInfo *info) +{ + g_free (info->language_id); + g_free (info->name); + g_free (info->description); + + g_free (info); +} + + +/* Language ID -> I18nInfo hash table handling. */ + +static void +add_i18n_info_to_hash (GHashTable *language_id_to_i18n_info_hash, + I18nInfo *i18n_info) +{ + I18nInfo *existing_i18n_info; + + existing_i18n_info = (I18nInfo *) g_hash_table_lookup (language_id_to_i18n_info_hash, + i18n_info->language_id); + if (existing_i18n_info != NULL) { + g_hash_table_remove (language_id_to_i18n_info_hash, + i18n_info->language_id); + i18n_info_free (existing_i18n_info); + } + + g_hash_table_insert (language_id_to_i18n_info_hash, i18n_info->language_id, i18n_info); +} + +static void +language_id_to_i18n_info_hash_foreach_free (void *key, + void *value, + void *data) +{ + i18n_info_free ((I18nInfo *) value); +} + +static I18nInfo * +get_i18n_info_for_language (ELocalFolder *local_folder, + const char *language_id) +{ + ELocalFolderPrivate *priv; + I18nInfo *i18n_info; + + priv = local_folder->priv; + + if (language_id == NULL) + language_id = global_language_id; + + i18n_info = g_hash_table_lookup (priv->language_id_to_i18n_info, language_id); + + /* For locale info like `en_UK@yadda', we try to use `en' as a backup. */ + /* Note: this is exactly the same thing that gnome-config does with the + I18N value handling. I hope it works. */ + if (i18n_info == NULL) { + size_t n; + + n = strcspn (language_id, "@_"); + if (language_id[n] != '\0') { + char *simplified_language_id; + + simplified_language_id = g_strndup (language_id, n); + i18n_info = g_hash_table_lookup (priv->language_id_to_i18n_info, + simplified_language_id); + } + } + + return i18n_info; +} + + +/* Locale handling. */ + +static void +setup_global_language_id (void) +{ + /* FIXME: Implement. */ + global_language_id = "C"; +} + +/* Update the EFolder attributes according to the current locale. */ +static void +update_for_global_locale (ELocalFolder *local_folder) +{ + I18nInfo *i18n_info; + + i18n_info = get_i18n_info_for_language (local_folder, NULL); + + if (i18n_info == NULL) + i18n_info = get_i18n_info_for_language (local_folder, "C"); + + g_assert (i18n_info != NULL); + + e_folder_set_name (E_FOLDER (local_folder), i18n_info->name); + e_folder_set_description (E_FOLDER (local_folder), i18n_info->description); +} + + +/* XML tree handling. */ + static char * get_string_value (xmlNode *node, const char *name) @@ -81,13 +212,51 @@ get_string_value (xmlNode *node, if (p == NULL) return NULL; - xml_string = xmlNodeListGetString (node->doc, p, 1); + xml_string = xmlNodeListGetString (node->doc, p, TRUE); retval = g_strdup ((char *) xml_string); xmlFree (xml_string); return retval; } +static void +retrieve_info_item (ELocalFolder *local_folder, + xmlNode *node) +{ + xmlChar *lang; + char *name; + char *description; + + lang = xmlGetProp (node, "lang"); + name = get_string_value (node, "name"); + description = get_string_value (node, "description"); + + if (lang == NULL) { + e_local_folder_add_i18n_info (local_folder, "C", name, description); + } else { + e_local_folder_add_i18n_info (local_folder, lang, name, description); + xmlFree (lang); + } + + g_free (name); + g_free (description); +} + +static void +retrieve_info (ELocalFolder *local_folder, + xmlNode *root_xml_node) +{ + ELocalFolderPrivate *priv; + xmlNode *p; + + priv = local_folder->priv; + + for (p = root_xml_node->childs; p != NULL; p = p->next) { + if (xmlStrcmp (p->name, "info") == 0) + retrieve_info_item (local_folder, p); + } +} + static gboolean construct_loading_metadata (ELocalFolder *local_folder, const char *path) @@ -96,7 +265,6 @@ construct_loading_metadata (ELocalFolder *local_folder, xmlDoc *doc; xmlNode *root; char *type; - char *description; char *metadata_path; char *physical_uri; @@ -118,12 +286,16 @@ construct_loading_metadata (ELocalFolder *local_folder, } type = get_string_value (root, "type"); - description = get_string_value (root, "description"); - - e_folder_construct (folder, g_basename (path), type, description); + if (type == NULL) { + g_free (metadata_path); + xmlFreeDoc (doc); + return FALSE; + } + e_local_folder_construct (local_folder, g_basename (path), type, NULL); g_free (type); - g_free (description); + + retrieve_info (local_folder, root); xmlFreeDoc (doc); @@ -180,7 +352,18 @@ save_metadata (ELocalFolder *local_folder) static void destroy (GtkObject *object) { - /* No ELocalFolder-specific data to free. */ + ELocalFolder *local_folder; + ELocalFolderPrivate *priv; + + local_folder = E_LOCAL_FOLDER (object); + priv = local_folder->priv; + + g_hash_table_foreach (priv->language_id_to_i18n_info, + language_id_to_i18n_info_hash_foreach_free, + NULL); + g_hash_table_destroy (priv->language_id_to_i18n_info); + + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -195,11 +378,19 @@ class_init (ELocalFolderClass *klass) object_class = GTK_OBJECT_CLASS (klass); object_class->destroy = destroy; + + setup_global_language_id (); } static void init (ELocalFolder *local_folder) { + ELocalFolderPrivate *priv; + + priv = g_new (ELocalFolderPrivate, 1); + priv->language_id_to_i18n_info = g_hash_table_new (g_str_hash, g_str_equal); + + local_folder->priv = priv; } @@ -209,12 +400,20 @@ e_local_folder_construct (ELocalFolder *local_folder, const char *type, const char *description) { + ELocalFolderPrivate *priv; + I18nInfo *i18n_info; + g_return_if_fail (local_folder != NULL); g_return_if_fail (E_IS_LOCAL_FOLDER (local_folder)); g_return_if_fail (name != NULL); g_return_if_fail (type != NULL); + priv = local_folder->priv; + e_folder_construct (E_FOLDER (local_folder), name, type, description); + + i18n_info = i18n_info_new ("C", name, description); + add_i18n_info_to_hash (priv->language_id_to_i18n_info, i18n_info); } EFolder * @@ -262,4 +461,93 @@ e_local_folder_save (ELocalFolder *local_folder) } +/** + * e_local_folder_add_i18n_info: + * @local_folder: A pointer to an ELocalFolder object + * @language_id: An I1I8N locale ID + * @name: Name for @local_folder in the specified @language_id + * @description: Description for @local_folder in the specified @language_id + * + * Set the @name and @description for the specified @language_id locale. + **/ +void +e_local_folder_add_i18n_info (ELocalFolder *local_folder, + const char *language_id, + const char *name, + const char *description) +{ + ELocalFolderPrivate *priv; + I18nInfo *info; + + g_return_if_fail (local_folder != NULL); + g_return_if_fail (E_IS_LOCAL_FOLDER (local_folder)); + g_return_if_fail (language_id != NULL); + g_return_if_fail (name != NULL || description != NULL); + + priv = local_folder->priv; + + info = i18n_info_new (language_id, name, description); + add_i18n_info_to_hash (priv->language_id_to_i18n_info, info); + + update_for_global_locale (local_folder); +} + +/** + * e_local_folder_get_i18n_info: + * @local_folder: A pointer to an ELocalFolder object + * @language_id: The ID of the language whose locale we want to retrieve name + * and description for + * @language_id_return: The actual locale ID that the name and description are + * saved under (e.g. if you ask for an "en_UK@yadda", we might give you the + * info for just "en") + * @name_return: A pointer to a pointer that will point to the i18nized name on + * return. Can be NULL. + * @description_return: A pointer to a pointer that will point to the i18n + * description on return. Can be NULL. + * + * Retrieve the name and description for @local_folder in the specified locale. + * + * Return value: %TRUE if some info is found for that @language_id, %FALSE + * otherwise. + **/ +gboolean +e_local_folder_get_i18n_info (ELocalFolder *local_folder, + const char *language_id, + const char **language_id_return, + const char **name_return, + const char **description_return) +{ + ELocalFolderPrivate *priv; + I18nInfo *i18n_info; + + g_return_val_if_fail (local_folder != NULL, FALSE); + g_return_val_if_fail (E_IS_LOCAL_FOLDER (local_folder), FALSE); + g_return_val_if_fail (language_id != NULL, FALSE); + + priv = local_folder->priv; + + i18n_info = get_i18n_info_for_language (local_folder, language_id); + + if (i18n_info == NULL) { + if (language_id_return != NULL) + *language_id_return = NULL; + if (name_return != NULL) + *name_return = NULL; + if (description_return != NULL) + *description_return = NULL; + + return FALSE; + } + + if (language_id_return != NULL) + *language_id_return = i18n_info->language_id; + if (name_return != NULL) + *name_return = i18n_info->name; + if (description_return != NULL) + *description_return = i18n_info->description; + + return TRUE; +} + + E_MAKE_TYPE (e_local_folder, "ELocalFolder", ELocalFolder, class_init, init, PARENT_TYPE) |