aboutsummaryrefslogtreecommitdiffstats
path: root/shell/e-local-folder.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/e-local-folder.c')
-rw-r--r--shell/e-local-folder.c304
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)