aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc/e-charset-picker.c
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2001-07-03 02:13:16 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2001-07-03 02:13:16 +0800
commit3b88e97ddc7011d3b97f059c4b7c2b0c0fa44851 (patch)
tree27c03966a7b5793f463765383f39cf1b73c1f4e6 /widgets/misc/e-charset-picker.c
parente232ded38af4bfba708f2d405bf0c1c849872054 (diff)
downloadgsoc2013-evolution-3b88e97ddc7011d3b97f059c4b7c2b0c0fa44851.tar.gz
gsoc2013-evolution-3b88e97ddc7011d3b97f059c4b7c2b0c0fa44851.tar.zst
gsoc2013-evolution-3b88e97ddc7011d3b97f059c4b7c2b0c0fa44851.zip
Updated to build e-charset-picker.c
2001-07-02 Jeffrey Stedfast <fejj@ximian.com> * Makefile.am: Updated to build e-charset-picker.c * e-charset-picker.[c,h]: Moved here from gal. (e_charset_picker_bonobo_ui_populate): New function to populate a bonobo-ui with a charset picker menu. svn path=/trunk/; revision=10687
Diffstat (limited to 'widgets/misc/e-charset-picker.c')
-rw-r--r--widgets/misc/e-charset-picker.c440
1 files changed, 440 insertions, 0 deletions
diff --git a/widgets/misc/e-charset-picker.c b/widgets/misc/e-charset-picker.c
new file mode 100644
index 0000000000..b275930dfd
--- /dev/null
+++ b/widgets/misc/e-charset-picker.c
@@ -0,0 +1,440 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * This program 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.
+ *
+ * This program 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-charset-picker.h"
+#include <gal/widgets/e-gui-utils.h>
+#include <gal/unicode/gunicode.h>
+
+#include <iconv.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtksignal.h>
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnomeui/gnome-dialog-util.h>
+#include <libgnomeui/gnome-stock.h>
+#include <bonobo/bonobo-ui-node.h>
+#include <bonobo/bonobo-ui-util.h>
+
+typedef enum {
+ E_CHARSET_UNKNOWN,
+ E_CHARSET_BALTIC,
+ E_CHARSET_CENTRAL_EUROPEAN,
+ E_CHARSET_CHINESE,
+ E_CHARSET_CYRILLIC,
+ E_CHARSET_GREEK,
+ E_CHARSET_JAPANESE,
+ E_CHARSET_KOREAN,
+ E_CHARSET_TURKISH,
+ E_CHARSET_UNICODE,
+ E_CHARSET_WESTERN_EUROPEAN
+} ECharsetClass;
+
+static const char *classnames[] = {
+ N_("Unknown"),
+ N_("Baltic"),
+ N_("Central European"),
+ N_("Chinese"),
+ N_("Cyrillic"),
+ N_("Greek"),
+ N_("Japanese"),
+ N_("Korean"),
+ N_("Turkish"),
+ N_("Unicode"),
+ N_("Western European"),
+};
+
+typedef struct {
+ char *name;
+ ECharsetClass class;
+ char *subclass;
+} ECharset;
+
+/* This list is based on what other mailers/browsers support. There's
+ * not a lot of point in using, say, ISO-8859-3, if anything that can
+ * read that can read UTF8 too.
+ */
+static ECharset charsets[] = {
+ { "ISO-8859-13", E_CHARSET_BALTIC, NULL },
+ { "ISO-8859-4", E_CHARSET_BALTIC, NULL },
+ { "ISO-8859-2", E_CHARSET_CENTRAL_EUROPEAN, NULL },
+ { "Big5", E_CHARSET_CHINESE, N_("Traditional") },
+ { "GB-2312", E_CHARSET_CHINESE, N_("Simplified") },
+ { "HZ", E_CHARSET_CHINESE, N_("Simplified") },
+ { "ISO-2022-CN", E_CHARSET_CHINESE, NULL },
+ { "KOI8-R", E_CHARSET_CYRILLIC, NULL },
+ { "Windows-1251", E_CHARSET_CYRILLIC, NULL },
+ { "KOI8-U", E_CHARSET_CYRILLIC, N_("Ukrainian") },
+ { "ISO-8859-5", E_CHARSET_CYRILLIC, NULL },
+ { "ISO-8859-7", E_CHARSET_GREEK, NULL },
+ { "ISO-2022-JP", E_CHARSET_JAPANESE, NULL },
+ { "EUC-JP", E_CHARSET_JAPANESE, NULL },
+ { "Shift_JIS", E_CHARSET_JAPANESE, NULL },
+ { "EUC-KR", E_CHARSET_KOREAN, NULL },
+ { "ISO-8859-9", E_CHARSET_TURKISH, NULL },
+ { "UTF-8", E_CHARSET_UNICODE, NULL },
+ { "UTF-7", E_CHARSET_UNICODE, NULL },
+ { "ISO-8859-1", E_CHARSET_WESTERN_EUROPEAN, NULL },
+ { "ISO-8859-15", E_CHARSET_WESTERN_EUROPEAN, N_("New") },
+};
+static const int num_charsets = sizeof (charsets) / sizeof (charsets[0]);
+
+static void
+select_item (GtkMenuShell *menu_shell, GtkWidget *item)
+{
+ gtk_menu_shell_select_item (menu_shell, item);
+ gtk_menu_shell_deactivate (menu_shell);
+}
+
+static void
+activate (GtkWidget *item, gpointer menu)
+{
+ gtk_object_set_data (GTK_OBJECT (menu), "activated_item", item);
+}
+
+static GtkWidget *
+add_charset (GtkWidget *menu, ECharset *charset, gboolean free_name)
+{
+ GtkWidget *item;
+ char *label;
+
+ if (charset->subclass) {
+ label = g_strdup_printf ("%s, %s (%s)",
+ _(classnames[charset->class]),
+ _(charset->subclass),
+ charset->name);
+ } else {
+ label = g_strdup_printf ("%s (%s)",
+ _(classnames[charset->class]),
+ charset->name);
+ }
+
+ item = gtk_menu_item_new_with_label (label);
+ gtk_object_set_data_full (GTK_OBJECT (item), "charset",
+ charset->name, free_name ? g_free : NULL);
+ g_free (label);
+
+ gtk_widget_show (item);
+ gtk_menu_append (GTK_MENU (menu), item);
+ gtk_signal_connect (GTK_OBJECT (item), "activate",
+ GTK_SIGNAL_FUNC (activate), menu);
+
+ return item;
+}
+
+static gboolean
+add_other_charset (GtkWidget *menu, GtkWidget *other, char *new_charset)
+{
+ ECharset charset = { NULL, E_CHARSET_UNKNOWN, NULL };
+ GtkWidget *item;
+ iconv_t ic;
+
+ ic = iconv_open ("UTF-8", new_charset);
+ if (ic == (iconv_t)-1) {
+ GtkWidget *window = gtk_widget_get_ancestor (other, GTK_TYPE_WINDOW);
+ e_notice (GTK_WINDOW (window), GNOME_MESSAGE_BOX_ERROR,
+ _("Unknown character set: %s"), new_charset);
+ return FALSE;
+ }
+ iconv_close (ic);
+
+ /* Temporarily remove the "Other..." item */
+ gtk_object_ref (GTK_OBJECT (other));
+ gtk_container_remove (GTK_CONTAINER (menu), other);
+
+ /* Create new menu item */
+ charset.name = new_charset;
+ item = add_charset (menu, &charset, TRUE);
+
+ /* And re-add "Other..." */
+ gtk_menu_append (GTK_MENU (menu), other);
+ gtk_object_unref (GTK_OBJECT (other));
+
+ gtk_object_set_data_full (GTK_OBJECT (menu), "other_charset",
+ g_strdup (new_charset), g_free);
+
+ gtk_object_set_data (GTK_OBJECT (menu), "activated_item", item);
+ select_item (GTK_MENU_SHELL (menu), item);
+ return TRUE;
+}
+
+static void
+other_charset_callback (char *new_charset, gpointer data)
+{
+ char **out = data;
+
+ *out = new_charset;
+}
+
+static void
+activate_other (GtkWidget *item, gpointer menu)
+{
+ GtkWidget *window, *dialog;
+ char *old_charset, *new_charset;
+
+ window = gtk_widget_get_ancestor (item, GTK_TYPE_WINDOW);
+ old_charset = gtk_object_get_data (GTK_OBJECT (menu), "other_charset");
+ dialog = gnome_request_dialog (FALSE,
+ _("Enter the character set to use"),
+ old_charset, 0, other_charset_callback,
+ &new_charset, GTK_WINDOW (window));
+ gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
+
+ if (new_charset) {
+ if (add_other_charset (menu, item, new_charset))
+ return;
+ g_free (new_charset);
+ }
+
+ /* Revert to previous selection */
+ select_item (GTK_MENU_SHELL (menu), gtk_object_get_data (GTK_OBJECT (menu), "activated_item"));
+}
+
+/**
+ * e_charset_picker_new:
+ * @default_charset: the default character set, or %NULL to use the
+ * locale character set.
+ *
+ * This creates an option menu widget and fills it in with a selection
+ * of available character sets. The @default_charset (or locale character
+ * set if @default_charset is %NULL) will be listed first, and selected
+ * by default (except that iso-8859-1 will always be used instead of
+ * US-ASCII). Any other character sets of the same language class as
+ * the default will be listed next, followed by the remaining character
+ * sets, a separator, and an "Other..." menu item, which can be used to
+ * select other charsets.
+ *
+ * Return value: an option menu widget, filled in and with signals
+ * attached.
+ */
+GtkWidget *
+e_charset_picker_new (const char *default_charset)
+{
+ GtkWidget *menu, *item;
+ int def, i;
+ char *locale_charset;
+
+ g_get_charset (&locale_charset);
+ if (!g_strcasecmp (locale_charset, "US-ASCII"))
+ locale_charset = "iso-8859-1";
+
+ if (!default_charset)
+ default_charset = locale_charset;
+ for (def = 0; def < num_charsets; def++) {
+ if (!g_strcasecmp (charsets[def].name, default_charset))
+ break;
+ }
+
+ menu = gtk_menu_new ();
+ for (i = 0; i < num_charsets; i++) {
+ item = add_charset (menu, &charsets[i], FALSE);
+ if (i == def) {
+ activate (item, menu);
+ select_item (GTK_MENU_SHELL (menu), item);
+ }
+ }
+
+ /* do the Unknown/Other section */
+ gtk_menu_append (GTK_MENU (menu), gtk_menu_item_new ());
+
+ if (def == num_charsets) {
+ ECharset other = { NULL, E_CHARSET_UNKNOWN, NULL };
+
+ /* Add an entry for @default_charset */
+ other.name = g_strdup (default_charset);
+ item = add_charset (menu, &other, TRUE);
+ activate (item, menu);
+ select_item (GTK_MENU_SHELL (menu), item);
+ gtk_object_set_data_full (GTK_OBJECT (menu), "other_charset",
+ g_strdup (default_charset), g_free);
+ def++;
+ }
+
+ item = gtk_menu_item_new_with_label (_("Other..."));
+ gtk_signal_connect (GTK_OBJECT (item), "activate",
+ GTK_SIGNAL_FUNC (activate_other), menu);
+ gtk_menu_append (GTK_MENU (menu), item);
+
+ gtk_widget_show_all (menu);
+ return menu;
+}
+
+/**
+ * e_charset_picker_get_charset:
+ * @menu: a character set menu from e_charset_picker_new()
+ *
+ * Return value: the currently-selected character set in @picker,
+ * which must be freed with g_free().
+ **/
+char *
+e_charset_picker_get_charset (GtkWidget *menu)
+{
+ GtkWidget *item;
+ char *charset;
+
+ g_return_val_if_fail (GTK_IS_MENU (menu), NULL);
+
+ item = gtk_menu_get_active (GTK_MENU (menu));
+ charset = gtk_object_get_data (GTK_OBJECT (item), "charset");
+
+ return g_strdup (charset);
+}
+
+/**
+ * e_charset_picker_dialog:
+ * @title: title for the dialog box
+ * @prompt: prompt string for the dialog box
+ * @default_charset: as for e_charset_picker_new()
+ * @parent: a parent window for the dialog box, or %NULL
+ *
+ * This creates a new dialog box with the given @title and @prompt and
+ * a character set picker menu. It then runs the dialog and returns
+ * the selected character set, or %NULL if the user clicked "Cancel".
+ *
+ * Return value: the selected character set (which must be freed with
+ * g_free()), or %NULL.
+ **/
+char *
+e_charset_picker_dialog (const char *title, const char *prompt,
+ const char *default_charset, GtkWindow *parent)
+{
+ GnomeDialog *dialog;
+ GtkWidget *label, *omenu, *picker;
+ int button;
+ char *charset;
+
+ dialog = GNOME_DIALOG (gnome_dialog_new (title, GNOME_STOCK_BUTTON_OK,
+ GNOME_STOCK_BUTTON_CANCEL,
+ NULL));
+ if (parent)
+ gnome_dialog_set_parent (dialog, parent);
+
+ label = gtk_label_new (prompt);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+ picker = e_charset_picker_new (default_charset);
+ omenu = gtk_option_menu_new ();
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), picker);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 4);
+ gtk_box_pack_start (GTK_BOX (dialog->vbox), label, FALSE, FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (dialog->vbox), omenu, FALSE, FALSE, 4);
+
+ gtk_widget_show_all (GTK_WIDGET (dialog));
+ button = gnome_dialog_run (dialog);
+
+ if (button == 0)
+ charset = e_charset_picker_get_charset (picker);
+ else
+ charset = NULL;
+ gnome_dialog_close (dialog);
+
+ return charset;
+}
+
+
+void
+e_charset_picker_bonobo_ui_populate (BonoboUIComponent *uic, const char *default_charset)
+{
+ char *locale_charset, *encoded_label, *label;
+ GString *menuitems;
+ int def, i;
+
+ g_get_charset (&locale_charset);
+ if (!g_strcasecmp (locale_charset, "US-ASCII"))
+ locale_charset = "iso-8859-1";
+
+ if (!default_charset)
+ default_charset = locale_charset;
+ for (def = 0; def < num_charsets; def++) {
+ if (!g_strcasecmp (charsets[def].name, default_charset))
+ break;
+ }
+
+ label = g_strdup (_("Character Encoding"));
+ encoded_label = bonobo_ui_util_encode_str (label);
+ menuitems = g_string_new ("");
+ g_string_sprintf (menuitems, "<submenu name=\"ECharsetPicker\" label=\"%s\">\n", encoded_label);
+ g_free (encoded_label);
+ g_free (label);
+
+ for (i = 0; i < num_charsets; i++) {
+ char *command, *label, *encoded_label;
+
+ if (charsets[i].subclass) {
+ label = g_strdup_printf ("%s, %s (%s)",
+ _(classnames[charsets[i].class]),
+ _(charsets[i].subclass),
+ charsets[i].name);
+ } else {
+ label = g_strdup_printf ("%s (%s)",
+ _(classnames[charsets[i].class]),
+ charsets[i].name);
+ }
+
+ encoded_label = bonobo_ui_util_encode_str (label);
+ g_free (label);
+
+ command = g_strdup_printf ("<cmd name=\"Charset-%s\" label=\"%s\" type=\"radio\""
+ " group=\"charset_picker\" state=\"%d\"/>\n",
+ charsets[i].name, encoded_label, i == def);
+
+ bonobo_ui_component_set (uic, "/commands", command, NULL);
+ g_free (command);
+
+ g_string_sprintfa (menuitems, " <menuitem name=\"Charset-%s\" verb=\"\"/>\n",
+ charsets[i].name);
+
+ g_free (encoded_label);
+ }
+
+ if (def == num_charsets) {
+ char *command, *label, *encoded_label;
+
+ label = g_strdup_printf ("%s (%s)", _("Unknown"), default_charset);
+ encoded_label = bonobo_ui_util_encode_str (label);
+ g_free (label);
+
+ command = g_strdup_printf ("<cmd name=\"Charset-%s\" label=\"%s\" type=\"radio\""
+ " group=\"charset_picker\" state=\"1\"/>\n",
+ default_charset, encoded_label);
+
+ bonobo_ui_component_set (uic, "/commands", command, NULL);
+ g_free (command);
+
+ g_string_append (menuitems, " <separator/>\n");
+ g_string_sprintfa (menuitems, " <menuitem name=\"Charset-%s\" verb=\"\"/>\n",
+ default_charset);
+
+ g_free (encoded_label);
+ }
+
+ g_string_append (menuitems, "</submenu>\n");
+
+ bonobo_ui_component_set (uic, "/menu/Edit", menuitems->str, NULL);
+ g_string_free (menuitems, TRUE);
+}