Blame gtksourceview/gtksourceencoding.c

Packit a7d494
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
Packit a7d494
/* gtksourceencoding.c
Packit a7d494
 * This file is part of GtkSourceView
Packit a7d494
 *
Packit a7d494
 * Copyright (C) 2002-2005 - Paolo Maggi
Packit a7d494
 * Copyright (C) 2014, 2015 - Sébastien Wilmet <swilmet@gnome.org>
Packit a7d494
 *
Packit a7d494
 * GtkSourceView is free software; you can redistribute it and/or
Packit a7d494
 * modify it under the terms of the GNU Lesser General Public
Packit a7d494
 * License as published by the Free Software Foundation; either
Packit a7d494
 * version 2.1 of the License, or (at your option) any later version.
Packit a7d494
 *
Packit a7d494
 * GtkSourceView is distributed in the hope that it will be useful,
Packit a7d494
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a7d494
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a7d494
 * Lesser General Public License for more details.
Packit a7d494
 *
Packit a7d494
 * You should have received a copy of the GNU Lesser General Public
Packit a7d494
 * License along with this library; if not, write to the Free Software
Packit a7d494
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit a7d494
 */
Packit a7d494
Packit a7d494
#ifdef HAVE_CONFIG_H
Packit a7d494
#include <config.h>
Packit a7d494
#endif
Packit a7d494
Packit a7d494
#include "gtksourceencoding.h"
Packit a7d494
#include "gtksourceencoding-private.h"
Packit a7d494
#include "gtksourceview-i18n.h"
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * SECTION:encoding
Packit a7d494
 * @Short_description: Character encoding
Packit a7d494
 * @Title: GtkSourceEncoding
Packit a7d494
 * @See_also: #GtkSourceFileSaver, #GtkSourceFileLoader
Packit a7d494
 *
Packit a7d494
 * The #GtkSourceEncoding boxed type represents a character encoding. It is used
Packit a7d494
 * for example by #GtkSourceFile. Note that the text in GTK+ widgets is always
Packit a7d494
 * encoded in UTF-8.
Packit a7d494
 */
Packit a7d494
Packit a7d494
struct _GtkSourceEncoding
Packit a7d494
{
Packit a7d494
	gint index;
Packit a7d494
	const gchar *charset;
Packit a7d494
	const gchar *name;
Packit a7d494
};
Packit a7d494
Packit a7d494
G_DEFINE_BOXED_TYPE (GtkSourceEncoding, gtk_source_encoding,
Packit a7d494
                     gtk_source_encoding_copy,
Packit a7d494
                     gtk_source_encoding_free)
Packit a7d494
Packit a7d494
/*
Packit a7d494
 * The original versions of the following tables are taken from profterm
Packit a7d494
 *
Packit a7d494
 * Copyright (C) 2002 Red Hat, Inc.
Packit a7d494
 */
Packit a7d494
Packit a7d494
typedef enum _GtkSourceEncodingIndex
Packit a7d494
{
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_1,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_2,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_3,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_4,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_5,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_6,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_7,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_8,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_9,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_10,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_13,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_14,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_15,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_8859_16,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_7,
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_16,
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_16_BE,
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_16_LE,
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_32,
Packit a7d494
	GTK_SOURCE_ENCODING_UCS_2,
Packit a7d494
	GTK_SOURCE_ENCODING_UCS_4,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_ARMSCII_8,
Packit a7d494
	GTK_SOURCE_ENCODING_BIG5,
Packit a7d494
	GTK_SOURCE_ENCODING_BIG5_HKSCS,
Packit a7d494
	GTK_SOURCE_ENCODING_CP_866,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_EUC_JP,
Packit a7d494
	GTK_SOURCE_ENCODING_EUC_JP_MS,
Packit a7d494
	GTK_SOURCE_ENCODING_CP932,
Packit a7d494
	GTK_SOURCE_ENCODING_EUC_KR,
Packit a7d494
	GTK_SOURCE_ENCODING_EUC_TW,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_GB18030,
Packit a7d494
	GTK_SOURCE_ENCODING_GB2312,
Packit a7d494
	GTK_SOURCE_ENCODING_GBK,
Packit a7d494
	GTK_SOURCE_ENCODING_GEOSTD8,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_IBM_850,
Packit a7d494
	GTK_SOURCE_ENCODING_IBM_852,
Packit a7d494
	GTK_SOURCE_ENCODING_IBM_855,
Packit a7d494
	GTK_SOURCE_ENCODING_IBM_857,
Packit a7d494
	GTK_SOURCE_ENCODING_IBM_862,
Packit a7d494
	GTK_SOURCE_ENCODING_IBM_864,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_2022_JP,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_2022_KR,
Packit a7d494
	GTK_SOURCE_ENCODING_ISO_IR_111,
Packit a7d494
	GTK_SOURCE_ENCODING_JOHAB,
Packit a7d494
	GTK_SOURCE_ENCODING_KOI8_R,
Packit a7d494
	GTK_SOURCE_ENCODING_KOI8__R,
Packit a7d494
	GTK_SOURCE_ENCODING_KOI8_U,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_SHIFT_JIS,
Packit a7d494
	GTK_SOURCE_ENCODING_TCVN,
Packit a7d494
	GTK_SOURCE_ENCODING_TIS_620,
Packit a7d494
	GTK_SOURCE_ENCODING_UHC,
Packit a7d494
	GTK_SOURCE_ENCODING_VISCII,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1250,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1251,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1252,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1253,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1254,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1255,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1256,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1257,
Packit a7d494
	GTK_SOURCE_ENCODING_WINDOWS_1258,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_LAST,
Packit a7d494
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_8,
Packit a7d494
	GTK_SOURCE_ENCODING_UNKNOWN
Packit a7d494
} GtkSourceEncodingIndex;
Packit a7d494
Packit a7d494
static const GtkSourceEncoding utf8_encoding =
Packit a7d494
{
Packit a7d494
	GTK_SOURCE_ENCODING_UTF_8,
Packit a7d494
	"UTF-8",
Packit a7d494
	N_("Unicode")
Packit a7d494
};
Packit a7d494
Packit a7d494
/* Initialized in gtk_source_encoding_lazy_init(). */
Packit a7d494
static GtkSourceEncoding unknown_encoding =
Packit a7d494
{
Packit a7d494
	GTK_SOURCE_ENCODING_UNKNOWN,
Packit a7d494
	NULL,
Packit a7d494
	NULL
Packit a7d494
};
Packit a7d494
Packit a7d494
static const GtkSourceEncoding encodings[] =
Packit a7d494
{
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_1,
Packit a7d494
	  "ISO-8859-1", N_("Western") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_2,
Packit a7d494
	 "ISO-8859-2", N_("Central European") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_3,
Packit a7d494
	  "ISO-8859-3", N_("South European") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_4,
Packit a7d494
	  "ISO-8859-4", N_("Baltic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_5,
Packit a7d494
	  "ISO-8859-5", N_("Cyrillic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_6,
Packit a7d494
	  "ISO-8859-6", N_("Arabic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_7,
Packit a7d494
	  "ISO-8859-7", N_("Greek") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_8,
Packit a7d494
	  "ISO-8859-8", N_("Hebrew Visual") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_9,
Packit a7d494
	  "ISO-8859-9", N_("Turkish") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_10,
Packit a7d494
	  "ISO-8859-10", N_("Nordic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_13,
Packit a7d494
	  "ISO-8859-13", N_("Baltic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_14,
Packit a7d494
	  "ISO-8859-14", N_("Celtic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_15,
Packit a7d494
	  "ISO-8859-15", N_("Western") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_8859_16,
Packit a7d494
	  "ISO-8859-16", N_("Romanian") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_UTF_7,
Packit a7d494
	  "UTF-7", N_("Unicode") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UTF_16,
Packit a7d494
	  "UTF-16", N_("Unicode") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UTF_16_BE,
Packit a7d494
	  "UTF-16BE", N_("Unicode") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UTF_16_LE,
Packit a7d494
	  "UTF-16LE", N_("Unicode") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UTF_32,
Packit a7d494
	  "UTF-32", N_("Unicode") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UCS_2,
Packit a7d494
	  "UCS-2", N_("Unicode") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UCS_4,
Packit a7d494
	  "UCS-4", N_("Unicode") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_ARMSCII_8,
Packit a7d494
	  "ARMSCII-8", N_("Armenian") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_BIG5,
Packit a7d494
	  "BIG5", N_("Chinese Traditional") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_BIG5_HKSCS,
Packit a7d494
	  "BIG5-HKSCS", N_("Chinese Traditional") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_CP_866,
Packit a7d494
	  "CP866", N_("Cyrillic/Russian") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_EUC_JP,
Packit a7d494
	  "EUC-JP", N_("Japanese") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_EUC_JP_MS,
Packit a7d494
	  "EUC-JP-MS", N_("Japanese") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_CP932,
Packit a7d494
	  "CP932", N_("Japanese") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_EUC_KR,
Packit a7d494
	  "EUC-KR", N_("Korean") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_EUC_TW,
Packit a7d494
	  "EUC-TW", N_("Chinese Traditional") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_GB18030,
Packit a7d494
	  "GB18030", N_("Chinese Simplified") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_GB2312,
Packit a7d494
	  "GB2312", N_("Chinese Simplified") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_GBK,
Packit a7d494
	  "GBK", N_("Chinese Simplified") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_GEOSTD8,
Packit a7d494
	  "GEORGIAN-ACADEMY", N_("Georgian") }, /* FIXME GEOSTD8 ? */
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_IBM_850,
Packit a7d494
	  "IBM850", N_("Western") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_IBM_852,
Packit a7d494
	  "IBM852", N_("Central European") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_IBM_855,
Packit a7d494
	  "IBM855", N_("Cyrillic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_IBM_857,
Packit a7d494
	  "IBM857", N_("Turkish") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_IBM_862,
Packit a7d494
	  "IBM862", N_("Hebrew") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_IBM_864,
Packit a7d494
	  "IBM864", N_("Arabic") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_2022_JP,
Packit a7d494
	  "ISO-2022-JP", N_("Japanese") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_2022_KR,
Packit a7d494
	  "ISO-2022-KR", N_("Korean") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_ISO_IR_111,
Packit a7d494
	  "ISO-IR-111", N_("Cyrillic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_JOHAB,
Packit a7d494
	  "JOHAB", N_("Korean") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_KOI8_R,
Packit a7d494
	  "KOI8R", N_("Cyrillic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_KOI8__R,
Packit a7d494
	  "KOI8-R", N_("Cyrillic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_KOI8_U,
Packit a7d494
	  "KOI8U", N_("Cyrillic/Ukrainian") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_SHIFT_JIS,
Packit a7d494
	  "SHIFT_JIS", N_("Japanese") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_TCVN,
Packit a7d494
	  "TCVN", N_("Vietnamese") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_TIS_620,
Packit a7d494
	  "TIS-620", N_("Thai") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_UHC,
Packit a7d494
	  "UHC", N_("Korean") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_VISCII,
Packit a7d494
	  "VISCII", N_("Vietnamese") },
Packit a7d494
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1250,
Packit a7d494
	  "WINDOWS-1250", N_("Central European") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1251,
Packit a7d494
	  "WINDOWS-1251", N_("Cyrillic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1252,
Packit a7d494
	  "WINDOWS-1252", N_("Western") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1253,
Packit a7d494
	  "WINDOWS-1253", N_("Greek") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1254,
Packit a7d494
	  "WINDOWS-1254", N_("Turkish") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1255,
Packit a7d494
	  "WINDOWS-1255", N_("Hebrew") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1256,
Packit a7d494
	  "WINDOWS-1256", N_("Arabic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1257,
Packit a7d494
	  "WINDOWS-1257", N_("Baltic") },
Packit a7d494
	{ GTK_SOURCE_ENCODING_WINDOWS_1258,
Packit a7d494
	  "WINDOWS-1258", N_("Vietnamese") }
Packit a7d494
};
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_encoding_lazy_init (void)
Packit a7d494
{
Packit a7d494
	static gboolean initialized = FALSE;
Packit a7d494
	const gchar *locale_charset;
Packit a7d494
Packit a7d494
	if (G_LIKELY (initialized))
Packit a7d494
	{
Packit a7d494
		return;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	if (g_get_charset (&locale_charset) == FALSE)
Packit a7d494
	{
Packit a7d494
		unknown_encoding.charset = g_strdup (locale_charset);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	initialized = TRUE;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_from_charset:
Packit a7d494
 * @charset: a character set.
Packit a7d494
 *
Packit a7d494
 * Gets a #GtkSourceEncoding from a character set such as "UTF-8" or
Packit a7d494
 * "ISO-8859-1".
Packit a7d494
 *
Packit a7d494
 * Returns: (nullable): the corresponding #GtkSourceEncoding, or %NULL
Packit a7d494
 * if not found.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
const GtkSourceEncoding *
Packit a7d494
gtk_source_encoding_get_from_charset (const gchar *charset)
Packit a7d494
{
Packit a7d494
	gint i;
Packit a7d494
Packit a7d494
	g_return_val_if_fail (charset != NULL, NULL);
Packit a7d494
Packit a7d494
	if (g_ascii_strcasecmp (charset, "UTF-8") == 0)
Packit a7d494
	{
Packit a7d494
		return gtk_source_encoding_get_utf8 ();
Packit a7d494
	}
Packit a7d494
Packit a7d494
	for (i = 0; i < GTK_SOURCE_ENCODING_LAST; i++)
Packit a7d494
	{
Packit a7d494
		if (g_ascii_strcasecmp (charset, encodings[i].charset) == 0)
Packit a7d494
		{
Packit a7d494
			return &encodings[i];
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
Packit a7d494
	gtk_source_encoding_lazy_init ();
Packit a7d494
Packit a7d494
	if (unknown_encoding.charset != NULL &&
Packit a7d494
	    g_ascii_strcasecmp (charset, unknown_encoding.charset) == 0)
Packit a7d494
	{
Packit a7d494
		return &unknown_encoding;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	return NULL;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_all:
Packit a7d494
 *
Packit a7d494
 * Gets all encodings.
Packit a7d494
 *
Packit a7d494
 * Returns: (transfer container) (element-type GtkSource.Encoding): a list of
Packit a7d494
 * all #GtkSourceEncoding's. Free with g_slist_free().
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
GSList *
Packit a7d494
gtk_source_encoding_get_all (void)
Packit a7d494
{
Packit a7d494
	GSList *all = NULL;
Packit a7d494
	gint i;
Packit a7d494
Packit a7d494
	for (i = GTK_SOURCE_ENCODING_LAST - 1; i >= 0; i--)
Packit a7d494
	{
Packit a7d494
		all = g_slist_prepend (all, (gpointer) &encodings[i]);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	all = g_slist_prepend (all, (gpointer) &utf8_encoding);
Packit a7d494
Packit a7d494
	return all;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_utf8:
Packit a7d494
 *
Packit a7d494
 * Returns: the UTF-8 encoding.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
const GtkSourceEncoding *
Packit a7d494
gtk_source_encoding_get_utf8 (void)
Packit a7d494
{
Packit a7d494
	return &utf8_encoding;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_current:
Packit a7d494
 *
Packit a7d494
 * Gets the #GtkSourceEncoding for the current locale. See also g_get_charset().
Packit a7d494
 *
Packit a7d494
 * Returns: the current locale encoding.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
const GtkSourceEncoding *
Packit a7d494
gtk_source_encoding_get_current (void)
Packit a7d494
{
Packit a7d494
	static gboolean initialized = FALSE;
Packit a7d494
	static const GtkSourceEncoding *locale_encoding = NULL;
Packit a7d494
Packit a7d494
	const gchar *locale_charset;
Packit a7d494
Packit a7d494
	gtk_source_encoding_lazy_init ();
Packit a7d494
Packit a7d494
	if (G_LIKELY (initialized))
Packit a7d494
	{
Packit a7d494
		return locale_encoding;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	if (g_get_charset (&locale_charset))
Packit a7d494
	{
Packit a7d494
		locale_encoding = &utf8_encoding;
Packit a7d494
	}
Packit a7d494
	else
Packit a7d494
	{
Packit a7d494
		locale_encoding = gtk_source_encoding_get_from_charset (locale_charset);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	if (locale_encoding == NULL)
Packit a7d494
	{
Packit a7d494
		locale_encoding = &unknown_encoding;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	initialized = TRUE;
Packit a7d494
Packit a7d494
	return locale_encoding;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_to_string:
Packit a7d494
 * @enc: a #GtkSourceEncoding.
Packit a7d494
 *
Packit a7d494
 * Returns: a string representation. Free with g_free() when no longer needed.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
gchar *
Packit a7d494
gtk_source_encoding_to_string (const GtkSourceEncoding* enc)
Packit a7d494
{
Packit a7d494
	g_return_val_if_fail (enc != NULL, NULL);
Packit a7d494
Packit a7d494
	gtk_source_encoding_lazy_init ();
Packit a7d494
Packit a7d494
	g_return_val_if_fail (enc->charset != NULL, NULL);
Packit a7d494
Packit a7d494
	if (enc->name != NULL)
Packit a7d494
	{
Packit a7d494
	    	return g_strdup_printf ("%s (%s)", _(enc->name), enc->charset);
Packit a7d494
	}
Packit a7d494
	else if (g_ascii_strcasecmp (enc->charset, "ANSI_X3.4-1968") == 0)
Packit a7d494
	{
Packit a7d494
		return g_strdup_printf ("US-ASCII (%s)", enc->charset);
Packit a7d494
	}
Packit a7d494
	else
Packit a7d494
	{
Packit a7d494
		return g_strdup (enc->charset);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_charset:
Packit a7d494
 * @enc: a #GtkSourceEncoding.
Packit a7d494
 *
Packit a7d494
 * Gets the character set of the #GtkSourceEncoding, such as "UTF-8" or
Packit a7d494
 * "ISO-8859-1".
Packit a7d494
 *
Packit a7d494
 * Returns: the character set of the #GtkSourceEncoding.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
const gchar *
Packit a7d494
gtk_source_encoding_get_charset (const GtkSourceEncoding* enc)
Packit a7d494
{
Packit a7d494
	g_return_val_if_fail (enc != NULL, NULL);
Packit a7d494
Packit a7d494
	gtk_source_encoding_lazy_init ();
Packit a7d494
Packit a7d494
	g_return_val_if_fail (enc->charset != NULL, NULL);
Packit a7d494
Packit a7d494
	return enc->charset;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_name:
Packit a7d494
 * @enc: a #GtkSourceEncoding.
Packit a7d494
 *
Packit a7d494
 * Gets the name of the #GtkSourceEncoding such as "Unicode" or "Western".
Packit a7d494
 *
Packit a7d494
 * Returns: the name of the #GtkSourceEncoding.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
const gchar *
Packit a7d494
gtk_source_encoding_get_name (const GtkSourceEncoding* enc)
Packit a7d494
{
Packit a7d494
	g_return_val_if_fail (enc != NULL, NULL);
Packit a7d494
Packit a7d494
	gtk_source_encoding_lazy_init ();
Packit a7d494
Packit a7d494
	return (enc->name == NULL) ? _("Unknown") : _(enc->name);
Packit a7d494
}
Packit a7d494
Packit a7d494
static GSList *
Packit a7d494
strv_to_list (const gchar * const *enc_str)
Packit a7d494
{
Packit a7d494
	GSList *res = NULL;
Packit a7d494
	gchar **p;
Packit a7d494
Packit a7d494
	for (p = (gchar **)enc_str; p != NULL && *p != NULL; p++)
Packit a7d494
	{
Packit a7d494
		const gchar *charset = *p;
Packit a7d494
		const GtkSourceEncoding *enc;
Packit a7d494
Packit a7d494
		if (g_str_equal (charset, "CURRENT"))
Packit a7d494
		{
Packit a7d494
			g_get_charset (&charset);
Packit a7d494
		}
Packit a7d494
Packit a7d494
		g_return_val_if_fail (charset != NULL, NULL);
Packit a7d494
		enc = gtk_source_encoding_get_from_charset (charset);
Packit a7d494
Packit a7d494
		if (enc != NULL &&
Packit a7d494
		    g_slist_find (res, enc) == NULL)
Packit a7d494
		{
Packit a7d494
			res = g_slist_prepend (res, (gpointer)enc);
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
Packit a7d494
	return g_slist_reverse (res);
Packit a7d494
}
Packit a7d494
Packit a7d494
static GSList *
Packit a7d494
remove_duplicates_keep_first (GSList *list)
Packit a7d494
{
Packit a7d494
	GSList *new_list = NULL;
Packit a7d494
	GSList *l;
Packit a7d494
Packit a7d494
	for (l = list; l != NULL; l = l->next)
Packit a7d494
	{
Packit a7d494
		gpointer cur_encoding = l->data;
Packit a7d494
Packit a7d494
		if (g_slist_find (new_list, cur_encoding) == NULL)
Packit a7d494
		{
Packit a7d494
			new_list = g_slist_prepend (new_list, cur_encoding);
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
Packit a7d494
	new_list = g_slist_reverse (new_list);
Packit a7d494
Packit a7d494
	g_slist_free (list);
Packit a7d494
	return new_list;
Packit a7d494
}
Packit a7d494
Packit a7d494
static GSList *
Packit a7d494
remove_duplicates_keep_last (GSList *list)
Packit a7d494
{
Packit a7d494
	GSList *new_list = NULL;
Packit a7d494
	GSList *l;
Packit a7d494
Packit a7d494
	list = g_slist_reverse (list);
Packit a7d494
Packit a7d494
	for (l = list; l != NULL; l = l->next)
Packit a7d494
	{
Packit a7d494
		gpointer cur_encoding = l->data;
Packit a7d494
Packit a7d494
		if (g_slist_find (new_list, cur_encoding) == NULL)
Packit a7d494
		{
Packit a7d494
			new_list = g_slist_prepend (new_list, cur_encoding);
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
Packit a7d494
	g_slist_free (list);
Packit a7d494
	return new_list;
Packit a7d494
}
Packit a7d494
Packit a7d494
/*
Packit a7d494
 * _gtk_source_encoding_remove_duplicates:
Packit a7d494
 * @list: (element-type GtkSource.Encoding): a list of #GtkSourceEncoding's.
Packit a7d494
 * @removal_type: the #GtkSourceEncodingDuplicates.
Packit a7d494
 *
Packit a7d494
 * A convenience function to remove duplicated encodings in a list.
Packit a7d494
 *
Packit a7d494
 * Returns: (transfer container) (element-type GtkSource.Encoding): the new
Packit a7d494
 * start of the #GSList.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
GSList *
Packit a7d494
_gtk_source_encoding_remove_duplicates (GSList                      *list,
Packit a7d494
					GtkSourceEncodingDuplicates  removal_type)
Packit a7d494
{
Packit a7d494
	switch (removal_type)
Packit a7d494
	{
Packit a7d494
		case GTK_SOURCE_ENCODING_DUPLICATES_KEEP_FIRST:
Packit a7d494
			return remove_duplicates_keep_first (list);
Packit a7d494
Packit a7d494
		case GTK_SOURCE_ENCODING_DUPLICATES_KEEP_LAST:
Packit a7d494
			return remove_duplicates_keep_last (list);
Packit a7d494
Packit a7d494
		default:
Packit a7d494
			break;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	g_return_val_if_reached (list);
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_get_default_candidates:
Packit a7d494
 *
Packit a7d494
 * Gets the list of default candidate encodings to try when loading a file. See
Packit a7d494
 * gtk_source_file_loader_set_candidate_encodings().
Packit a7d494
 *
Packit a7d494
 * This function returns a different list depending on the current locale (i.e.
Packit a7d494
 * language, country and default encoding). The UTF-8 encoding and the current
Packit a7d494
 * locale encoding are guaranteed to be present in the returned list.
Packit a7d494
 *
Packit a7d494
 * Returns: (transfer container) (element-type GtkSource.Encoding): the list of
Packit a7d494
 * default candidate encodings. Free with g_slist_free().
Packit a7d494
 * Since: 3.18
Packit a7d494
 */
Packit a7d494
GSList *
Packit a7d494
gtk_source_encoding_get_default_candidates (void)
Packit a7d494
{
Packit a7d494
	const gchar *encodings_str;
Packit a7d494
	const gchar *encodings_str_translated;
Packit a7d494
	GVariant *encodings_variant;
Packit a7d494
	const gchar **encodings_strv;
Packit a7d494
	GSList *encodings_list;
Packit a7d494
	GError *error = NULL;
Packit a7d494
Packit a7d494
	/* Translators: This is the sorted list of encodings used by
Packit a7d494
	 * GtkSourceView for automatic detection of the file encoding. You may
Packit a7d494
	 * want to customize it adding encodings that are common in your
Packit a7d494
	 * country, for instance the GB18030 encoding for the Chinese
Packit a7d494
	 * translation. You may also want to remove the ISO-8859-15 encoding
Packit a7d494
	 * (covering English and most Western European languages) if you think
Packit a7d494
	 * people in your country will rarely use it.  "CURRENT" is a magic
Packit a7d494
	 * value used by GtkSourceView and it represents the encoding for the
Packit a7d494
	 * current locale, so please don't translate the "CURRENT" term.  Only
Packit a7d494
	 * recognized encodings are used. See
Packit a7d494
	 * https://git.gnome.org/browse/gtksourceview/tree/gtksourceview/gtksourceencoding.c#n147
Packit a7d494
	 * for a list of supported encodings.
Packit a7d494
	 * Keep the same format: square brackets, single quotes, commas.
Packit a7d494
	 */
Packit a7d494
	encodings_str = N_("['UTF-8', 'CURRENT', 'ISO-8859-15', 'UTF-16']");
Packit a7d494
Packit a7d494
	encodings_str_translated = _(encodings_str);
Packit a7d494
Packit a7d494
	encodings_variant = g_variant_parse (G_VARIANT_TYPE_STRING_ARRAY,
Packit a7d494
					     encodings_str_translated,
Packit a7d494
					     NULL,
Packit a7d494
					     NULL,
Packit a7d494
					     &error);
Packit a7d494
Packit a7d494
	if (error != NULL)
Packit a7d494
	{
Packit a7d494
		const gchar * const *language_names = g_get_language_names ();
Packit a7d494
Packit a7d494
		g_warning ("Error while parsing encodings list for locale %s:\n"
Packit a7d494
			   "Translated list: %s\n"
Packit a7d494
			   "Error message: %s",
Packit a7d494
			   language_names[0],
Packit a7d494
			   encodings_str_translated,
Packit a7d494
			   error->message);
Packit a7d494
Packit a7d494
		g_clear_error (&error);
Packit a7d494
Packit a7d494
		encodings_variant = g_variant_parse (G_VARIANT_TYPE_STRING_ARRAY,
Packit a7d494
						     encodings_str,
Packit a7d494
						     NULL,
Packit a7d494
						     NULL,
Packit a7d494
						     &error);
Packit a7d494
Packit a7d494
		g_assert_no_error (error);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	encodings_strv = g_variant_get_strv (encodings_variant, NULL);
Packit a7d494
	encodings_list = strv_to_list (encodings_strv);
Packit a7d494
	g_free ((gpointer) encodings_strv);
Packit a7d494
Packit a7d494
	/* Ensure that UTF-8 and CURRENT are present. */
Packit a7d494
	encodings_list = g_slist_prepend (encodings_list,
Packit a7d494
					  (gpointer) gtk_source_encoding_get_current ());
Packit a7d494
Packit a7d494
	encodings_list = g_slist_prepend (encodings_list,
Packit a7d494
					  (gpointer) &utf8_encoding);
Packit a7d494
Packit a7d494
	encodings_list = _gtk_source_encoding_remove_duplicates (encodings_list,
Packit a7d494
								 GTK_SOURCE_ENCODING_DUPLICATES_KEEP_LAST);
Packit a7d494
Packit a7d494
	g_variant_unref (encodings_variant);
Packit a7d494
	return encodings_list;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_copy:
Packit a7d494
 * @enc: a #GtkSourceEncoding.
Packit a7d494
 *
Packit a7d494
 * Used by language bindings.
Packit a7d494
 *
Packit a7d494
 * Returns: a copy of @enc.
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
GtkSourceEncoding *
Packit a7d494
gtk_source_encoding_copy (const GtkSourceEncoding *enc)
Packit a7d494
{
Packit a7d494
	g_return_val_if_fail (enc != NULL, NULL);
Packit a7d494
Packit a7d494
	return (GtkSourceEncoding *) enc;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_encoding_free:
Packit a7d494
 * @enc: a #GtkSourceEncoding.
Packit a7d494
 *
Packit a7d494
 * Used by language bindings.
Packit a7d494
 *
Packit a7d494
 * Since: 3.14
Packit a7d494
 */
Packit a7d494
void
Packit a7d494
gtk_source_encoding_free (GtkSourceEncoding *enc)
Packit a7d494
{
Packit a7d494
	g_return_if_fail (enc != NULL);
Packit a7d494
}