Commit e251aadd authored by Matthias Klumpp's avatar Matthias Klumpp
Browse files

Use the same locale fallback algorithm everywhere

Some entities only did subpar locale fallbacks. So instead of having
modules roll their own, use the same algorithm everywhere.
Resolves: #262
parent 6facb344
......@@ -33,6 +33,7 @@
#include "as-agreement-section-private.h"
#include "as-utils-private.h"
#include "as-context-private.h"
typedef struct {
gchar *kind;
......@@ -129,21 +130,17 @@ const gchar*
as_agreement_section_get_name (AsAgreementSection *agreement_section)
{
AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section);
const gchar *name;
name = g_hash_table_lookup (priv->name,
as_agreement_section_get_active_locale (agreement_section));
if (name == NULL)
name = g_hash_table_lookup (priv->name, "C");
return name;
return as_context_localized_ht_get (priv->context,
priv->name,
priv->active_locale_override,
AS_VALUE_FLAG_NONE);
}
/**
* as_agreement_section_set_name:
* @agreement_section: a #AsAgreementSection instance.
* @locale: (nullable): the locale. e.g. "en_GB"
* @name: the agreement name, e.g. "GDPR"
* @locale: (nullable): the locale. e.g. "en_GB"
*
* Sets the agreement section name.
*
......@@ -154,12 +151,10 @@ as_agreement_section_set_name (AsAgreementSection *agreement_section,
const gchar *name, const gchar *locale)
{
AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section);
if (locale == NULL)
locale = as_agreement_section_get_active_locale (agreement_section);
g_hash_table_insert (priv->name,
as_locale_strip_encoding (g_strdup (locale)),
g_strdup (name));
as_context_localized_ht_set (priv->context,
priv->name,
name,
locale);
}
/**
......@@ -176,14 +171,10 @@ const gchar*
as_agreement_section_get_description (AsAgreementSection *agreement_section)
{
AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section);
const gchar *desc;
desc = g_hash_table_lookup (priv->description,
as_agreement_section_get_active_locale (agreement_section));
if (desc == NULL)
desc = g_hash_table_lookup (priv->description, "C");
return desc;
return as_context_localized_ht_get (priv->context,
priv->description,
priv->active_locale_override,
AS_VALUE_FLAG_NONE);
}
/**
......@@ -201,12 +192,10 @@ as_agreement_section_set_description (AsAgreementSection *agreement_section,
const gchar *desc, const gchar *locale)
{
AsAgreementSectionPrivate *priv = GET_PRIVATE (agreement_section);
if (locale == NULL)
locale = as_agreement_section_get_active_locale (agreement_section);
g_hash_table_insert (priv->description,
as_locale_strip_encoding (g_strdup (locale)),
g_strdup (desc));
as_context_localized_ht_set (priv->context,
priv->description,
desc,
locale);
}
/**
......
......@@ -38,7 +38,7 @@
#include <glib/gstdio.h>
#include "as-utils-private.h"
#include "as-context.h"
#include "as-context-private.h"
#include "as-component-private.h"
#include "as-launchable.h"
......
......@@ -28,6 +28,7 @@
#include "as-utils-private.h"
#include "as-stemmer.h"
#include "as-context-private.h"
#include "as-icon-private.h"
#include "as-screenshot-private.h"
#include "as-bundle-private.h"
......@@ -1129,58 +1130,6 @@ as_component_set_active_locale (AsComponent *cpt, const gchar *locale)
priv->active_locale_override = g_strdup (locale);
}
/**
* as_component_localized_get:
* @cpt: a #AsComponent instance.
* @lht: (element-type utf8 utf8): the #GHashTable on which the value will be retreived.
*
* Helper function to get a localized property using the current
* active locale for this component.
*/
static const gchar*
as_component_localized_get (AsComponent *cpt, GHashTable *lht)
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
const gchar *locale;
gchar *msg;
locale = as_component_get_active_locale (cpt);
msg = g_hash_table_lookup (lht, locale);
if ((msg == NULL) && (!as_flags_contains (priv->value_flags, AS_VALUE_FLAG_NO_TRANSLATION_FALLBACK))) {
g_autofree gchar *lang = as_utils_locale_to_language (locale);
/* fall back to language string */
msg = g_hash_table_lookup (lht, lang);
if (msg == NULL) {
/* fall back to untranslated / default */
msg = g_hash_table_lookup (lht, "C");
}
}
return msg;
}
/**
* as_component_localized_set:
* @cpt: a #AsComponent instance.
* @lht: (element-type utf8 utf8): the #GHashTable on which the value will be added.
* @value: the value to add.
* @locale: (nullable): the locale, or %NULL. e.g. "en_GB".
*
* Helper function to set a localized property.
*/
static void
as_component_localized_set (AsComponent *cpt, GHashTable *lht, const gchar* value, const gchar *locale)
{
/* if no locale was specified, we assume the default locale */
/* CAVE: %NULL does NOT mean lang=C! */
if (locale == NULL)
locale = as_component_get_active_locale (cpt);
g_hash_table_insert (lht,
as_locale_strip_encoding (g_strdup (locale)),
g_strdup (value));
}
/**
* as_component_get_name:
* @cpt: a #AsComponent instance.
......@@ -1193,7 +1142,10 @@ const gchar*
as_component_get_name (AsComponent *cpt)
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
return as_component_localized_get (cpt, priv->name);
return as_context_localized_ht_get (priv->context,
priv->name,
priv->active_locale_override,
priv->value_flags);
}
/**
......@@ -1209,7 +1161,7 @@ as_component_set_name (AsComponent *cpt, const gchar* value, const gchar *locale
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
as_component_localized_set (cpt, priv->name, value, locale);
as_context_localized_ht_set (priv->context, priv->name, value, locale);
g_object_notify ((GObject *) cpt, "name");
}
......@@ -1225,7 +1177,10 @@ const gchar*
as_component_get_summary (AsComponent *cpt)
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
return as_component_localized_get (cpt, priv->summary);
return as_context_localized_ht_get (priv->context,
priv->summary,
priv->active_locale_override,
priv->value_flags);
}
/**
......@@ -1241,7 +1196,10 @@ as_component_set_summary (AsComponent *cpt, const gchar* value, const gchar *loc
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
as_component_localized_set (cpt, priv->summary, value, locale);
as_context_localized_ht_set (priv->context,
priv->summary,
value,
locale);
g_object_notify ((GObject *) cpt, "summary");
}
......@@ -1257,7 +1215,10 @@ const gchar*
as_component_get_description (AsComponent *cpt)
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
return as_component_localized_get (cpt, priv->description);
return as_context_localized_ht_get (priv->context,
priv->description,
priv->active_locale_override,
priv->value_flags);
}
/**
......@@ -1273,7 +1234,10 @@ as_component_set_description (AsComponent *cpt, const gchar* value, const gchar
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
as_component_localized_set (cpt, priv->description, value, locale);
as_context_localized_ht_set (priv->context,
priv->description,
value,
locale);
g_object_notify ((GObject *) cpt, "description");
}
......@@ -1556,7 +1520,10 @@ const gchar*
as_component_get_developer_name (AsComponent *cpt)
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
return as_component_localized_get (cpt, priv->developer_name);
return as_context_localized_ht_get (priv->context,
priv->developer_name,
priv->active_locale_override,
priv->value_flags);
}
/**
......@@ -1571,7 +1538,10 @@ void
as_component_set_developer_name (AsComponent *cpt, const gchar *value, const gchar *locale)
{
AsComponentPrivate *priv = GET_PRIVATE (cpt);
as_component_localized_set (cpt, priv->developer_name, value, locale);
as_context_localized_ht_set (priv->context,
priv->developer_name,
value,
locale);
}
/**
......@@ -1591,7 +1561,10 @@ as_component_get_name_variant_suffix (AsComponent *cpt)
AsComponentPrivate *priv = GET_PRIVATE (cpt);
if (priv->name_variant_suffix == NULL)
return NULL;
return as_component_localized_get (cpt, priv->name_variant_suffix);
return as_context_localized_ht_get (priv->context,
priv->name_variant_suffix,
priv->active_locale_override,
priv->value_flags);
}
/**
......@@ -1611,7 +1584,10 @@ as_component_set_name_variant_suffix (AsComponent *cpt, const gchar *value, cons
AsComponentPrivate *priv = GET_PRIVATE (cpt);
if (priv->name_variant_suffix == NULL)
priv->name_variant_suffix = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
as_component_localized_set (cpt, priv->name_variant_suffix, value, locale);
as_context_localized_ht_set (priv->context,
priv->name_variant_suffix,
value,
locale);
}
/**
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012-2020 Matthias Klumpp <matthias@tenstral.net>
*
* Licensed under the GNU Lesser General Public License Version 2.1
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the license, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __AS_CONTEXT_PRIVATE_H
#define __AS_CONTEXT_PRIVATE_H
#include "as-context.h"
G_BEGIN_DECLS
#pragma GCC visibility push(hidden)
gboolean as_context_get_internal_mode (AsContext *ctx);
void as_context_set_internal_mode (AsContext *ctx,
gboolean enabled);
const gchar *as_context_localized_ht_get (AsContext *ctx,
GHashTable *lht,
const gchar *locale_override,
AsValueFlags value_flags);
void as_context_localized_ht_set (AsContext *ctx,
GHashTable *lht,
const gchar *value,
const gchar *locale);
#pragma GCC visibility pop
G_END_DECLS
#endif /* __AS_CONTEXT_PRIVATE_H */
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012-2017 Matthias Klumpp <matthias@tenstral.net>
* Copyright (C) 2012-2020 Matthias Klumpp <matthias@tenstral.net>
*
* Licensed under the GNU Lesser General Public License Version 2.1
*
......@@ -369,6 +369,84 @@ as_context_set_internal_mode (AsContext *ctx, gboolean enabled)
priv->internal_mode = enabled;
}
/**
* as_context_localized_ht_get:
* @ctx: a #AsContext instance, or %NULL
* @lht: (element-type utf8 utf8): the #GHashTable from which the value will be retreived.
* @locale_override: Override the default locale defined by @ctx, or %NULL
*
* Helper function to get a value for the current locale from a localization
* hash table (which maps locale to localized strings).
*
* This is used by all entities which have a context and have localized strings.
*
* Returns: The localized string in the best matching localization.
*/
const gchar*
as_context_localized_ht_get (AsContext *ctx, GHashTable *lht, const gchar *locale_override, AsValueFlags value_flags)
{
const gchar *locale;
const gchar *msg;
/* retrieve context locale, if the locale isn't explicitly overridden */
if ((ctx != NULL) && (locale_override == NULL)) {
AsContextPrivate *priv = GET_PRIVATE (ctx);
locale = priv->locale;
} else {
locale = locale_override;
}
/* NULL is not an acceptable value here and means "C" */
if (locale == NULL)
locale = "C";
msg = g_hash_table_lookup (lht, locale);
if ((msg == NULL) && (!as_flags_contains (value_flags, AS_VALUE_FLAG_NO_TRANSLATION_FALLBACK))) {
g_autofree gchar *lang = as_utils_locale_to_language (locale);
/* fall back to language string */
msg = g_hash_table_lookup (lht, lang);
if (msg == NULL) {
/* fall back to untranslated / default */
msg = g_hash_table_lookup (lht, "C");
}
}
return msg;
}
/**
* as_context_localized_ht_set:
* @ctx: a #AsContext instance, or %NULL
* @lht: (element-type utf8 utf8): the #GHashTable to which the value will be added.
* @value: the value to add.
* @locale: (nullable): the locale, or %NULL. e.g. "en_GB".
*
* Helper function to set a localized value on a trabslation mapping.
*
* This is used by all entities which have a context and have localized strings.
*/
void
as_context_localized_ht_set (AsContext *ctx, GHashTable *lht, const gchar *value, const gchar *locale)
{
const gchar *selected_locale;
/* if no locale was specified, we assume the default locale
* NOTE: %NULL does NOT necessarily mean lang=C here! */
if ((ctx != NULL) && (locale == NULL)) {
AsContextPrivate *priv = GET_PRIVATE (ctx);
selected_locale = priv->locale;
} else {
selected_locale = locale;
}
/* if we still have no locale, assume "C" as best option */
if (selected_locale == NULL)
selected_locale = "C";
g_hash_table_insert (lht,
as_locale_strip_encoding (g_strdup (selected_locale)),
g_strdup (value));
}
/**
* as_context_new:
*
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2012-2017 Matthias Klumpp <matthias@tenstral.net>
* Copyright (C) 2012-2020 Matthias Klumpp <matthias@tenstral.net>
*
* Licensed under the GNU Lesser General Public License Version 2.1
*
......@@ -82,10 +82,6 @@ const gchar *as_context_get_filename (AsContext *ctx);
void as_context_set_filename (AsContext *ctx,
const gchar *fname);
gboolean as_context_get_internal_mode (AsContext *ctx);
void as_context_set_internal_mode (AsContext *ctx,
gboolean enabled);
G_END_DECLS
#endif /* __AS_CONTEXT_H */
......@@ -38,6 +38,7 @@
#include "as-utils.h"
#include "as-utils-private.h"
#include "as-context-private.h"
#include "as-artifact-private.h"
#include "as-checksum-private.h"
#include "as-issue-private.h"
......@@ -481,16 +482,11 @@ as_release_set_urgency (AsRelease *release, AsUrgencyKind urgency)
const gchar*
as_release_get_description (AsRelease *release)
{
const gchar *desc;
AsReleasePrivate *priv = GET_PRIVATE (release);
desc = g_hash_table_lookup (priv->description, as_release_get_active_locale (release));
if (desc == NULL) {
/* fall back to untranslated / default */
desc = g_hash_table_lookup (priv->description, "C");
}
return desc;
return as_context_localized_ht_get (priv->context,
priv->description,
priv->active_locale_override,
AS_VALUE_FLAG_NONE);
}
/**
......@@ -504,13 +500,10 @@ void
as_release_set_description (AsRelease *release, const gchar *description, const gchar *locale)
{
AsReleasePrivate *priv = GET_PRIVATE (release);
if (locale == NULL)
locale = as_release_get_active_locale (release);
g_hash_table_insert (priv->description,
g_strdup (locale),
g_strdup (description));
as_context_localized_ht_set (priv->context,
priv->description,
description,
locale);
}
/**
......
......@@ -34,6 +34,7 @@
#include "as-utils.h"
#include "as-utils-private.h"
#include "as-context-private.h"
#include "as-image-private.h"
#include "as-video-private.h"
......@@ -267,17 +268,11 @@ as_screenshot_add_video (AsScreenshot *screenshot, AsVideo *video)
const gchar*
as_screenshot_get_caption (AsScreenshot *screenshot)
{
const gchar *caption;
AsScreenshotPrivate *priv = GET_PRIVATE (screenshot);
caption = g_hash_table_lookup (priv->caption,
as_screenshot_get_active_locale (screenshot));
if (caption == NULL) {
/* fall back to untranslated / default */
caption = g_hash_table_lookup (priv->caption, "C");
}
return caption;
return as_context_localized_ht_get (priv->context,
priv->caption,
priv->active_locale_override,
AS_VALUE_FLAG_NONE);
}
/**
......@@ -291,13 +286,10 @@ void
as_screenshot_set_caption (AsScreenshot *screenshot, const gchar *caption, const gchar *locale)
{
AsScreenshotPrivate *priv = GET_PRIVATE (screenshot);
if (locale == NULL)
locale = as_screenshot_get_active_locale (screenshot);
g_hash_table_insert (priv->caption,
as_locale_strip_encoding (g_strdup (locale)),
g_strdup (caption));
as_context_localized_ht_set (priv->context,
priv->caption,
caption,
locale);
}
/**
......
......@@ -78,6 +78,7 @@ aslib_priv_headers = [
'as-utils-private.h',
'as-tag.h',
'as-context.h',
'as-context-private.h',
'as-xml.h',
'as-yaml.h',
'as-cache.h',
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment