aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy-gtk')
-rw-r--r--libempathy-gtk/Makefile.am10
-rw-r--r--libempathy-gtk/empathy-account-widget-irc.c511
-rw-r--r--libempathy-gtk/empathy-account-widget-irc.glade451
-rw-r--r--libempathy-gtk/empathy-account-widget-irc.h33
-rw-r--r--libempathy-gtk/empathy-accounts-dialog.c5
-rw-r--r--libempathy-gtk/empathy-irc-network-dialog.c579
-rw-r--r--libempathy-gtk/empathy-irc-network-dialog.h35
-rw-r--r--libempathy-gtk/totem-subtitle-encoding.c585
-rw-r--r--libempathy-gtk/totem-subtitle-encoding.h12
9 files changed, 2219 insertions, 2 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 24c933714..f53215170 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -23,6 +23,7 @@ libempathy_gtk_la_SOURCES = \
empathy-contact-dialogs.c \
empathy-accounts-dialog.c \
empathy-account-widget.c \
+ empathy-account-widget-irc.c \
empathy-profile-chooser.c \
empathy-cell-renderer-expander.c \
empathy-cell-renderer-text.c \
@@ -53,7 +54,9 @@ libempathy_gtk_la_SOURCES = \
empathy-avatar-chooser.c \
empathy-avatar-image.c \
empathy-ui-utils.c \
- empathy-new-message-dialog.c
+ empathy-new-message-dialog.c \
+ empathy-irc-network-dialog.c \
+ totem-subtitle-encoding.c totem-subtitle-encoding.h
# do not distribute generated files
nodist_libempathy_gtk_la_SOURCES =\
@@ -76,6 +79,7 @@ libempathy_gtk_headers = \
empathy-contact-dialogs.h \
empathy-accounts-dialog.h \
empathy-account-widget.h \
+ empathy-account-widget-irc.h \
empathy-profile-chooser.h \
empathy-cell-renderer-expander.h \
empathy-cell-renderer-text.h \
@@ -106,7 +110,8 @@ libempathy_gtk_headers = \
empathy-avatar-chooser.h \
empathy-avatar-image.h \
empathy-ui-utils.h \
- empathy-new-message-dialog.h
+ empathy-new-message-dialog.h \
+ empathy-irc-network-dialog.h
libempathy_gtk_includedir = $(includedir)/libempathy-gtk/
libempathy_gtk_include_HEADERS = \
@@ -125,6 +130,7 @@ glade_DATA = \
empathy-account-widget-jabber.glade \
empathy-account-widget-msn.glade \
empathy-account-widget-salut.glade \
+ empathy-account-widget-irc.glade \
empathy-new-chatroom-dialog.glade \
empathy-group-chat.glade \
empathy-chatrooms-window.glade \
diff --git a/libempathy-gtk/empathy-account-widget-irc.c b/libempathy-gtk/empathy-account-widget-irc.c
new file mode 100644
index 000000000..35fa7697f
--- /dev/null
+++ b/libempathy-gtk/empathy-account-widget-irc.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#include <libmissioncontrol/mc-account.h>
+#include <libmissioncontrol/mc-protocol.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-debug.h>
+#include <libempathy/empathy-irc-network-manager.h>
+
+#include "empathy-irc-network-dialog.h"
+#include "empathy-account-widget.h"
+#include "empathy-account-widget-irc.h"
+#include "empathy-ui-utils.h"
+
+#define DEBUG_DOMAIN "AccountWidgetIRC"
+
+#define IRC_NETWORKS_FILENAME "irc-networks.xml"
+
+typedef struct {
+ McAccount *account;
+ EmpathyIrcNetworkManager *network_manager;
+
+ GtkWidget *vbox_settings;
+
+ GtkWidget *combobox_network;
+ GtkWidget *button_add_network;
+ GtkWidget *button_network;
+ GtkWidget *button_remove;
+} EmpathyAccountWidgetIrc;
+
+enum {
+ COL_NETWORK_OBJ,
+ COL_NETWORK_NAME,
+};
+
+static void
+account_widget_irc_destroy_cb (GtkWidget *widget,
+ EmpathyAccountWidgetIrc *settings)
+{
+ g_object_unref (settings->network_manager);
+ g_object_unref (settings->account);
+ g_slice_free (EmpathyAccountWidgetIrc, settings);
+}
+
+static void
+unset_server_params (EmpathyAccountWidgetIrc *settings)
+{
+ empathy_debug (DEBUG_DOMAIN, "Unset server, port and use-ssl");
+ mc_account_unset_param (settings->account, "server");
+ mc_account_unset_param (settings->account, "port");
+ mc_account_unset_param (settings->account, "use-ssl");
+}
+
+static void
+update_server_params (EmpathyAccountWidgetIrc *settings)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ EmpathyIrcNetwork *network;
+ GSList *servers;
+ gchar *charset;
+
+ if (!gtk_combo_box_get_active_iter (
+ GTK_COMBO_BOX (settings->combobox_network), &iter))
+ {
+ unset_server_params (settings);
+ return;
+ }
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
+ gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+
+ g_assert (network != NULL);
+
+ g_object_get (network, "charset", &charset, NULL);
+ empathy_debug (DEBUG_DOMAIN, "Setting charset to %s", charset);
+ mc_account_set_param_string (settings->account, "charset", charset);
+ g_free (charset);
+
+ servers = empathy_irc_network_get_servers (network);
+ if (g_slist_length (servers) > 0)
+ {
+ /* set the first server as CM server */
+ EmpathyIrcServer *server = servers->data;
+ gchar *address;
+ guint port;
+ gboolean ssl;
+
+ g_object_get (server,
+ "address", &address,
+ "port", &port,
+ "ssl", &ssl,
+ NULL);
+
+ empathy_debug (DEBUG_DOMAIN, "Setting server to %s", address);
+ mc_account_set_param_string (settings->account, "server", address);
+ empathy_debug (DEBUG_DOMAIN, "Setting port to %u", port);
+ mc_account_set_param_int (settings->account, "port", port);
+ empathy_debug (DEBUG_DOMAIN, "Setting use-ssl to %s",
+ ssl ? "TRUE": "FALSE" );
+ mc_account_set_param_boolean (settings->account, "use-ssl", ssl);
+
+ g_free (address);
+ }
+ else
+ {
+ /* No server. Unset values */
+ unset_server_params (settings);
+ }
+
+ g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
+ g_slist_free (servers);
+ g_object_unref (network);
+}
+
+static void
+irc_network_dialog_destroy_cb (GtkWidget *widget,
+ EmpathyAccountWidgetIrc *settings)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ EmpathyIrcNetwork *network;
+ gchar *name;
+
+ /* name could be changed */
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
+ &iter);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
+ gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+
+ g_object_get (network, "name", &name, NULL);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_NETWORK_NAME, name, -1);
+
+ update_server_params (settings);
+
+ g_object_unref (network);
+ g_free (name);
+}
+
+static void
+display_irc_network_dialog (EmpathyAccountWidgetIrc *settings,
+ EmpathyIrcNetwork *network)
+{
+ GtkWindow *window;
+ GtkWidget *dialog;
+
+ window = empathy_get_toplevel_window (settings->vbox_settings);
+ dialog = empathy_irc_network_dialog_show (network, GTK_WIDGET (window));
+ g_signal_connect (dialog, "destroy",
+ G_CALLBACK (irc_network_dialog_destroy_cb), settings);
+}
+
+static void
+account_widget_irc_button_edit_network_clicked_cb (
+ GtkWidget *button,
+ EmpathyAccountWidgetIrc *settings)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ EmpathyIrcNetwork *network;
+
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
+ &iter);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
+ gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+
+ g_assert (network != NULL);
+
+ display_irc_network_dialog (settings, network);
+
+ g_object_unref (network);
+}
+
+static void
+account_widget_irc_button_remove_clicked_cb (GtkWidget *button,
+ EmpathyAccountWidgetIrc *settings)
+{
+ EmpathyIrcNetwork *network;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gchar *name;
+
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
+ &iter);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
+ gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+
+ g_assert (network != NULL);
+
+ g_object_get (network, "name", &name, NULL);
+ empathy_debug (DEBUG_DOMAIN, "Remove network %s", name);
+
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ empathy_irc_network_manager_remove (settings->network_manager, network);
+
+ /* Select the first network */
+ if (gtk_tree_model_get_iter_first (model, &iter))
+ {
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX (settings->combobox_network), &iter);
+ }
+
+ g_free (name);
+ g_object_unref (network);
+}
+
+static void
+account_widget_irc_button_add_network_clicked_cb (GtkWidget *button,
+ EmpathyAccountWidgetIrc *settings)
+{
+ EmpathyIrcNetwork *network;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ gchar *name;
+ GtkTreeIter iter;
+
+ network = empathy_irc_network_new (_("New Network"));
+ empathy_irc_network_manager_add (settings->network_manager, network);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
+ store = GTK_LIST_STORE (model);
+
+ g_object_get (network, "name", &name, NULL);
+
+ gtk_list_store_insert_with_values (store, &iter, -1,
+ COL_NETWORK_OBJ, network,
+ COL_NETWORK_NAME, name,
+ -1);
+
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (settings->combobox_network),
+ &iter);
+
+ display_irc_network_dialog (settings, network);
+
+ g_free (name);
+ g_object_unref (network);
+}
+
+static void
+account_widget_irc_combobox_network_changed_cb (GtkWidget *combobox,
+ EmpathyAccountWidgetIrc *settings)
+{
+ update_server_params (settings);
+}
+
+static void
+fill_networks_model (EmpathyAccountWidgetIrc *settings,
+ EmpathyIrcNetwork *network_to_select)
+{
+ GSList *networks, *l;
+ GtkTreeModel *model;
+ GtkListStore *store;
+
+ networks = empathy_irc_network_manager_get_networks (
+ settings->network_manager);
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
+ store = GTK_LIST_STORE (model);
+
+ for (l = networks; l != NULL; l = g_slist_next (l))
+ {
+ gchar *name;
+ EmpathyIrcNetwork *network = l->data;
+ GtkTreeIter iter;
+
+ g_object_get (network, "name", &name, NULL);
+
+ gtk_list_store_insert_with_values (store, &iter, -1,
+ COL_NETWORK_OBJ, network,
+ COL_NETWORK_NAME, name,
+ -1);
+
+ if (network == network_to_select)
+ {
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX (settings->combobox_network), &iter);
+ }
+
+ g_free (name);
+ g_object_unref (network);
+ }
+
+ if (network_to_select == NULL)
+ {
+ /* Select the first network */
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_iter_first (model, &iter))
+ {
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX (settings->combobox_network), &iter);
+
+ update_server_params (settings);
+ }
+ }
+
+ g_slist_free (networks);
+}
+
+static void
+account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
+{
+ gchar *nick = NULL;
+ gchar *fullname = NULL;
+ gchar *server = NULL;
+ gint port = 6667;
+ gchar *charset;
+ gboolean ssl = FALSE;
+ EmpathyIrcNetwork *network = NULL;
+
+ mc_account_get_param_string (settings->account, "account", &nick);
+ mc_account_get_param_string (settings->account, "fullname", &fullname);
+ mc_account_get_param_string (settings->account, "server", &server);
+ mc_account_get_param_string (settings->account, "charset", &charset);
+ mc_account_get_param_int (settings->account, "port", &port);
+ mc_account_get_param_boolean (settings->account, "use-ssl", &ssl);
+
+ if (!nick)
+ {
+ nick = g_strdup (g_get_user_name ());
+ mc_account_set_param_string (settings->account, "account", nick);
+ }
+
+ if (!fullname)
+ {
+ fullname = g_strdup (g_get_real_name ());
+ if (!fullname)
+ {
+ fullname = g_strdup (nick);
+ }
+ mc_account_set_param_string (settings->account, "fullname", fullname);
+ }
+
+ if (server != NULL)
+ {
+ GtkListStore *store;
+
+ network = empathy_irc_network_manager_find_network_by_address (
+ settings->network_manager, server);
+
+
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (
+ GTK_COMBO_BOX (settings->combobox_network)));
+
+ if (network != NULL)
+ {
+ gchar *name;
+
+ g_object_set (network, "charset", charset, NULL);
+
+ g_object_get (network, "name", &name, NULL);
+ empathy_debug (DEBUG_DOMAIN, "Account use network %s", name);
+
+ g_free (name);
+ }
+ else
+ {
+ /* We don't have this network. Let's create it */
+ EmpathyIrcServer *srv;
+ GtkTreeIter iter;
+
+ empathy_debug (DEBUG_DOMAIN, "Create a network %s", server);
+ network = empathy_irc_network_new (server);
+ srv = empathy_irc_server_new (server, port, ssl);
+
+ empathy_irc_network_append_server (network, srv);
+ empathy_irc_network_manager_add (settings->network_manager, network);
+
+ gtk_list_store_insert_with_values (store, &iter, -1,
+ COL_NETWORK_OBJ, network,
+ COL_NETWORK_NAME, server,
+ -1);
+
+ gtk_combo_box_set_active_iter (
+ GTK_COMBO_BOX (settings->combobox_network), &iter);
+
+ g_object_unref (srv);
+ g_object_unref (network);
+ }
+ }
+
+
+ fill_networks_model (settings, network);
+
+ g_free (nick);
+ g_free (fullname);
+ g_free (server);
+ g_free (charset);
+}
+
+/**
+ * empathy_account_widget_irc_new:
+ * @account: the #McAccount to configure
+ *
+ * Creates a new IRC account widget to configure a given #McAccount
+ *
+ * Returns: The toplevel container of the configuration widget
+ */
+GtkWidget *
+empathy_account_widget_irc_new (McAccount *account)
+{
+ EmpathyAccountWidgetIrc *settings;
+ gchar *dir, *user_file_with_path, *global_file_with_path;
+ GladeXML *glade;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+
+ settings = g_slice_new0 (EmpathyAccountWidgetIrc);
+ settings->account = g_object_ref (account);
+
+ dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
+ g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
+ g_free (dir);
+
+ global_file_with_path = g_build_filename (UNINSTALLED_IRC_DIR,
+ IRC_NETWORKS_FILENAME, NULL);
+ if (!g_file_test (global_file_with_path, G_FILE_TEST_EXISTS))
+ {
+ g_free (global_file_with_path);
+ global_file_with_path = g_build_filename (DATADIR, "empathy",
+ IRC_NETWORKS_FILENAME, NULL);
+ }
+
+ settings->network_manager = empathy_irc_network_manager_new (
+ global_file_with_path,
+ user_file_with_path);
+
+ g_free (global_file_with_path);
+ g_free (user_file_with_path);
+
+ glade = empathy_glade_get_file ("empathy-account-widget-irc.glade",
+ "vbox_irc_settings",
+ NULL,
+ "vbox_irc_settings", &settings->vbox_settings,
+ "combobox_network", &settings->combobox_network,
+ "button_network", &settings->button_network,
+ "button_add_network", &settings->button_add_network,
+ "button_remove", &settings->button_remove,
+ NULL);
+
+ /* Fill the networks combobox */
+ store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
+
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (settings->combobox_network));
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (settings->combobox_network),
+ renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (settings->combobox_network),
+ renderer,
+ "text", COL_NETWORK_NAME,
+ NULL);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
+ COL_NETWORK_NAME,
+ GTK_SORT_ASCENDING);
+
+ gtk_combo_box_set_model (GTK_COMBO_BOX (settings->combobox_network),
+ GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ account_widget_irc_setup (settings);
+
+ empathy_account_widget_handle_params (account, glade,
+ "entry_nick", "account",
+ "entry_fullname", "fullname",
+ "entry_password", "password",
+ "entry_quit_message", "quit-message",
+ NULL);
+
+ empathy_glade_connect (glade, settings,
+ "vbox_irc_settings", "destroy", account_widget_irc_destroy_cb,
+ "button_network", "clicked", account_widget_irc_button_edit_network_clicked_cb,
+ "button_add_network", "clicked", account_widget_irc_button_add_network_clicked_cb,
+ "button_remove", "clicked", account_widget_irc_button_remove_clicked_cb,
+ "combobox_network", "changed", account_widget_irc_combobox_network_changed_cb,
+ NULL);
+
+ g_object_unref (glade);
+
+ return settings->vbox_settings;
+}
diff --git a/libempathy-gtk/empathy-account-widget-irc.glade b/libempathy-gtk/empathy-account-widget-irc.glade
new file mode 100644
index 000000000..14c757ce8
--- /dev/null
+++ b/libempathy-gtk/empathy-account-widget-irc.glade
@@ -0,0 +1,451 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.0 on Sun Feb 17 01:08:25 2008 -->
+<glade-interface>
+ <widget class="GtkWindow" id="account_irc_settings">
+ <property name="title" translatable="yes">irc account settings</property>
+ <property name="resizable">False</property>
+ <child>
+ <widget class="GtkTable" id="vbox_irc_settings">
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="label_network">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Network:</property>
+ <property name="use_underline">True</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="hbox174">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkComboBox" id="combobox_network">
+ <property name="visible">True</property>
+ <property name="items" translatable="yes"></property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_add_network">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Create a new IRC network</property>
+ <property name="response_id">0</property>
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_network">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Edit the selected IRC network</property>
+ <property name="response_id">0</property>
+ <child>
+ <widget class="GtkImage" id="image834">
+ <property name="visible">True</property>
+ <property name="stock">gtk-edit</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="tooltip" translatable="yes">Remove the selected IRC network</property>
+ <property name="response_id">0</property>
+ <child>
+ <widget class="GtkImage" id="image835">
+ <property name="visible">True</property>
+ <property name="stock">gtk-remove</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_nick">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Nickname:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry_nick</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_nick">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">*</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_fullname">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Real name:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_password">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Password:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_password">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="visibility">False</property>
+ <property name="invisible_char">*</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_fullname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_quit_message">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Quit message:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_quit_message">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkDialog" id="irc_network_dialog">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Network</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="icon_name">gtk-edit</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="skip_taskbar_hint">True</property>
+ <property name="skip_pager_hint">True</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox10">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkFrame" id="frame14">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment28">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkTable" id="table14">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkComboBox" id="combobox_charset">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="entry_network">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_charset">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Charset:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_network">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Network:</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_network">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Network&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="frame15">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment29">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkTable" id="table15">
+ <property name="visible">True</property>
+ <property name="n_rows">1</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkVButtonBox" id="vbuttonbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <child>
+ <widget class="GtkButton" id="button_add">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_remove">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_up">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-go-up</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button_down">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-go-down</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow19">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkTreeView" id="treeview_servers">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="enable_search">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label_servers">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Servers&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area10">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button_close">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-close</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">-7</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/libempathy-gtk/empathy-account-widget-irc.h b/libempathy-gtk/empathy-account-widget-irc.h
new file mode 100644
index 000000000..6ead048eb
--- /dev/null
+++ b/libempathy-gtk/empathy-account-widget-irc.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_ACCOUNT_WIDGET_IRC_H__
+#define __EMPATHY_ACCOUNT_WIDGET_IRC_H__
+
+#include <gtk/gtkwidget.h>
+#include <libmissioncontrol/mc-account.h>
+
+G_BEGIN_DECLS
+
+GtkWidget * empathy_account_widget_irc_new (McAccount *account);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_ACCOUNT_WIDGET_IRC_H__ */
diff --git a/libempathy-gtk/empathy-accounts-dialog.c b/libempathy-gtk/empathy-accounts-dialog.c
index 93b7b005b..832063371 100644
--- a/libempathy-gtk/empathy-accounts-dialog.c
+++ b/libempathy-gtk/empathy-accounts-dialog.c
@@ -46,6 +46,7 @@
#include "empathy-accounts-dialog.h"
#include "empathy-profile-chooser.h"
#include "empathy-account-widget.h"
+#include "empathy-account-widget-irc.h"
#define DEBUG_DOMAIN "AccountDialog"
@@ -269,6 +270,10 @@ accounts_dialog_update_account (EmpathyAccountsDialog *dialog,
dialog->settings_widget =
empathy_account_widget_salut_new (account);
}
+ else if (!tp_strdiff (config_ui, "irc")) {
+ dialog->settings_widget =
+ empathy_account_widget_irc_new (account);
+ }
else {
dialog->settings_widget =
empathy_account_widget_generic_new (account);
diff --git a/libempathy-gtk/empathy-irc-network-dialog.c b/libempathy-gtk/empathy-irc-network-dialog.c
new file mode 100644
index 000000000..9a42c649c
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-dialog.c
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+
+#include <libmissioncontrol/mc-account.h>
+#include <libmissioncontrol/mc-protocol.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-debug.h>
+
+#include <libempathy/empathy-irc-network-manager.h>
+#include "empathy-ui-utils.h"
+#include "totem-subtitle-encoding.h"
+
+#include "empathy-irc-network-dialog.h"
+
+#define DEBUG_DOMAIN "AccountWidgetIRC"
+
+typedef struct {
+ EmpathyIrcNetwork *network;
+
+ GtkWidget *dialog;
+ GtkWidget *button_close;
+
+ GtkWidget *entry_network;
+ GtkWidget *combobox_charset;
+
+ GtkWidget *treeview_servers;
+ GtkWidget *button_add;
+ GtkWidget *button_remove;
+ GtkWidget *button_up;
+ GtkWidget *button_down;
+} EmpathyIrcNetworkDialog;
+
+static void
+irc_network_dialog_destroy_cb (GtkWidget *widget,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ g_object_unref (dialog->network);
+
+ g_slice_free (EmpathyIrcNetworkDialog, dialog);
+}
+
+static void
+irc_network_dialog_close_clicked_cb (GtkWidget *widget,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ gtk_widget_destroy (dialog->dialog);
+}
+
+enum {
+ COL_SRV_OBJ,
+ COL_ADR,
+ COL_PORT,
+ COL_SSL
+};
+
+static void
+add_server_to_store (GtkListStore *store,
+ EmpathyIrcServer *server,
+ GtkTreeIter *iter)
+{
+ gchar *address;
+ guint port;
+ gboolean ssl;
+
+ g_object_get (server,
+ "address", &address,
+ "port", &port,
+ "ssl", &ssl,
+ NULL);
+
+ gtk_list_store_insert_with_values (store, iter, -1,
+ COL_SRV_OBJ, server,
+ COL_ADR, address,
+ COL_PORT, port,
+ COL_SSL, ssl,
+ -1);
+
+ g_free (address);
+}
+
+static void
+irc_network_dialog_setup (EmpathyIrcNetworkDialog *dialog)
+{
+ gchar *name, *charset;
+ GSList *servers, *l;
+ GtkListStore *store;
+
+ g_object_get (dialog->network,
+ "name", &name,
+ "charset", &charset,
+ NULL);
+ gtk_entry_set_text (GTK_ENTRY (dialog->entry_network), name);
+
+ store = GTK_LIST_STORE (gtk_tree_view_get_model (
+ GTK_TREE_VIEW (dialog->treeview_servers)));
+
+ servers = empathy_irc_network_get_servers (dialog->network);
+ for (l = servers; l != NULL; l = g_slist_next (l))
+ {
+ EmpathyIrcServer *server = l->data;
+ GtkTreeIter iter;
+
+ add_server_to_store (store, server, &iter);
+ }
+
+ totem_subtitle_encoding_set (GTK_COMBO_BOX (dialog->combobox_charset),
+ charset);
+
+ g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
+ g_slist_free (servers);
+ g_free (name);
+ g_free (charset);
+}
+
+static void
+irc_network_dialog_address_edited_cb (GtkCellRendererText *renderer,
+ gchar *path,
+ gchar *new_text,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ EmpathyIrcServer *server;
+ GtkTreeModel *model;
+ GtkTreePath *treepath;
+ GtkTreeIter iter;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
+ treepath = gtk_tree_path_new_from_string (path);
+ gtk_tree_model_get_iter (model, &iter, treepath);
+ gtk_tree_model_get (model, &iter,
+ COL_SRV_OBJ, &server,
+ -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_ADR, new_text,
+ -1);
+
+ g_object_set (server, "address", new_text, NULL);
+
+ gtk_tree_path_free (treepath);
+ g_object_unref (server);
+}
+
+static void
+irc_network_dialog_port_edited_cb (GtkCellRendererText *renderer,
+ gchar *path,
+ gchar *new_text,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ EmpathyIrcServer *server;
+ GtkTreeModel *model;
+ GtkTreePath *treepath;
+ GtkTreeIter iter;
+ guint port;
+
+ port = strtoul (new_text, NULL, 10);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
+ treepath = gtk_tree_path_new_from_string (path);
+ gtk_tree_model_get_iter (model, &iter, treepath);
+ gtk_tree_model_get (model, &iter,
+ COL_SRV_OBJ, &server,
+ -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_PORT, port,
+ -1);
+
+ g_object_set (server, "port", port, NULL);
+
+ gtk_tree_path_free (treepath);
+ g_object_unref (server);
+}
+
+static void
+irc_network_dialog_ssl_toggled_cb (GtkCellRendererText *renderer,
+ gchar *path,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ EmpathyIrcServer *server;
+ GtkTreeModel *model;
+ GtkTreePath *treepath;
+ GtkTreeIter iter;
+ gboolean ssl;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
+ treepath = gtk_tree_path_new_from_string (path);
+ gtk_tree_model_get_iter (model, &iter, treepath);
+ gtk_tree_model_get (model, &iter,
+ COL_SRV_OBJ, &server,
+ COL_SSL, &ssl,
+ -1);
+ ssl = !ssl;
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ COL_SSL, ssl,
+ -1);
+
+ g_object_set (server, "ssl", ssl, NULL);
+
+ gtk_tree_path_free (treepath);
+ g_object_unref (server);
+}
+
+static gboolean
+irc_network_dialog_network_focus_cb (GtkWidget *widget,
+ GdkEventFocus *event,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ const gchar *str;
+
+ str = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ g_object_set (dialog->network, "name", str, NULL);
+
+ return FALSE;
+}
+
+static void
+irc_network_dialog_network_update_buttons (EmpathyIrcNetworkDialog *dialog)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean can_remove = FALSE, can_move_up = FALSE, can_move_down = FALSE;
+ int selected;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
+ dialog->treeview_servers));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ path = gtk_tree_model_get_path (model, &iter);
+
+ selected = gtk_tree_path_get_indices (path)[0];
+
+ can_remove = TRUE;
+ can_move_up = selected > 0;
+ can_move_down =
+ selected < gtk_tree_model_iter_n_children (model, NULL) - 1;
+
+ gtk_tree_path_free (path);
+ }
+
+ gtk_widget_set_sensitive (dialog->button_remove, can_remove);
+ gtk_widget_set_sensitive (dialog->button_up, can_move_up);
+ gtk_widget_set_sensitive (dialog->button_down, can_move_down);
+}
+
+static void
+irc_network_dialog_button_add_clicked_cb (GtkWidget *widget,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ EmpathyIrcServer *server;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+
+ store = GTK_LIST_STORE (gtk_tree_view_get_model (
+ GTK_TREE_VIEW (dialog->treeview_servers)));
+
+ server = empathy_irc_server_new (_("new server"), 6667, FALSE);
+ empathy_irc_network_append_server (dialog->network, server);
+ add_server_to_store (store, server, &iter);
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
+ column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_servers),
+ 0);
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->treeview_servers), path,
+ column, TRUE);
+
+ irc_network_dialog_network_update_buttons (dialog);
+
+ gtk_tree_path_free (path);
+ g_object_unref (server);
+}
+
+static void
+irc_network_dialog_button_remove_clicked_cb (GtkWidget *widget,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ EmpathyIrcServer *server;
+
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (dialog->treeview_servers));
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
+
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ empathy_irc_network_remove_server (dialog->network, server);
+
+ irc_network_dialog_network_update_buttons (dialog);
+
+ g_object_unref (server);
+}
+
+static void
+irc_network_dialog_button_up_clicked_cb (GtkWidget *widget,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter, iter_prev;
+ GtkTreePath *path;
+ gint *pos;
+ EmpathyIrcServer *server;
+
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (dialog->treeview_servers));
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ path = gtk_tree_model_get_path (model, &iter);
+
+ if (!gtk_tree_path_prev (path))
+ {
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
+
+ gtk_tree_model_get_iter (model, &iter_prev, path);
+ gtk_list_store_swap (GTK_LIST_STORE (model), &iter_prev, &iter);
+
+ pos = gtk_tree_path_get_indices (path);
+ empathy_irc_network_set_server_position (dialog->network, server, *pos);
+
+ irc_network_dialog_network_update_buttons (dialog);
+
+ g_object_unref (server);
+ gtk_tree_path_free (path);
+}
+
+static void
+irc_network_dialog_button_down_clicked_cb (GtkWidget *widget,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter, iter_prev;
+ GtkTreePath *path;
+ EmpathyIrcServer *server;
+ gint *pos;
+
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (dialog->treeview_servers));
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ path = gtk_tree_model_get_path (model, &iter);
+
+ gtk_tree_path_next (path);
+ if (!gtk_tree_model_get_iter (model, &iter_prev, path))
+ {
+ gtk_tree_path_free (path);
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
+
+ gtk_list_store_swap (GTK_LIST_STORE (model), &iter_prev, &iter);
+
+ pos = gtk_tree_path_get_indices (path);
+ empathy_irc_network_set_server_position (dialog->network, server, *pos);
+
+ irc_network_dialog_network_update_buttons (dialog);
+
+ gtk_tree_path_free (path);
+}
+
+static void
+irc_network_dialog_selection_changed_cb (GtkTreeSelection *treeselection,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ irc_network_dialog_network_update_buttons (dialog);
+}
+
+static void
+irc_network_dialog_combobox_charset_changed_cb (GtkWidget *combobox,
+ EmpathyIrcNetworkDialog *dialog)
+{
+ const gchar *charset;
+
+ charset = totem_subtitle_encoding_get_selected (GTK_COMBO_BOX (combobox));
+ g_object_set (dialog->network, "charset", charset, NULL);
+}
+
+static void
+change_network (EmpathyIrcNetworkDialog *dialog,
+ EmpathyIrcNetwork *network)
+{
+ GtkListStore *store;
+
+ if (dialog->network == network)
+ /* No need to change */
+ return;
+
+ if (dialog->network != NULL)
+ {
+ g_object_unref (dialog->network);
+ }
+
+ dialog->network = network;
+ g_object_ref (network);
+
+ store = GTK_LIST_STORE (gtk_tree_view_get_model (
+ GTK_TREE_VIEW (dialog->treeview_servers)));
+ gtk_list_store_clear (store);
+
+ irc_network_dialog_setup (dialog);
+}
+
+/**
+ * empathy_irc_network_dialog_show:
+ * @network: the #EmpathyIrcNetwork to configure
+ * @parent: the parent of this dialog
+ *
+ * Display a dialog to configure a given #EmpathyIrcNetwork.
+ * This function is a singleton so if a configuration dialog already
+ * exists we use this one to edit the network.
+ *
+ * Returns: The displayed #GtkDialog
+ */
+GtkWidget *
+empathy_irc_network_dialog_show (EmpathyIrcNetwork *network,
+ GtkWidget *parent)
+{
+ static EmpathyIrcNetworkDialog *dialog = NULL;
+ GladeXML *glade;
+ GtkListStore *store;
+ GtkCellRenderer *renderer;
+ GtkAdjustment *adjustment;
+ GtkTreeSelection *selection;
+ GtkTreeViewColumn *column;
+
+ g_return_val_if_fail (network != NULL, NULL);
+
+ if (dialog != NULL)
+ {
+ change_network (dialog, network);
+ gtk_window_present (GTK_WINDOW (dialog->dialog));
+
+ return dialog->dialog;
+ }
+
+ dialog = g_slice_new0 (EmpathyIrcNetworkDialog);
+
+ dialog->network = network;
+ g_object_ref (dialog->network);
+
+ glade = empathy_glade_get_file ("empathy-account-widget-irc.glade",
+ "irc_network_dialog",
+ NULL,
+ "irc_network_dialog", &dialog->dialog,
+ "button_close", &dialog->button_close,
+ "entry_network", &dialog->entry_network,
+ "combobox_charset", &dialog->combobox_charset,
+ "treeview_servers", &dialog->treeview_servers,
+ "button_add", &dialog->button_add,
+ "button_remove", &dialog->button_remove,
+ "button_up", &dialog->button_up,
+ "button_down", &dialog->button_down,
+ NULL);
+
+ store = gtk_list_store_new (4, G_TYPE_OBJECT, G_TYPE_STRING,
+ G_TYPE_UINT, G_TYPE_BOOLEAN);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview_servers),
+ GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ /* address */
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "editable", TRUE, NULL);
+ g_signal_connect (renderer, "edited",
+ G_CALLBACK (irc_network_dialog_address_edited_cb), dialog);
+ gtk_tree_view_insert_column_with_attributes (
+ GTK_TREE_VIEW (dialog->treeview_servers),
+ -1, _("Server"), renderer, "text", COL_ADR,
+ NULL);
+
+ /* port */
+ adjustment = (GtkAdjustment *) gtk_adjustment_new (6667, 1, G_MAXUINT16,
+ 1, 10, 0);
+ renderer = gtk_cell_renderer_spin_new ();
+ g_object_set (renderer,
+ "editable", TRUE,
+ "adjustment", adjustment,
+ NULL);
+ g_signal_connect (renderer, "edited",
+ G_CALLBACK (irc_network_dialog_port_edited_cb), dialog);
+ gtk_tree_view_insert_column_with_attributes (
+ GTK_TREE_VIEW (dialog->treeview_servers),
+ -1, _("Port"), renderer, "text", COL_PORT,
+ NULL);
+ column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_servers),
+ 1);
+ gtk_tree_view_column_set_expand (column, TRUE);
+
+ /* SSL */
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_object_set (renderer, "activatable", TRUE, NULL);
+ g_signal_connect (renderer, "toggled",
+ G_CALLBACK (irc_network_dialog_ssl_toggled_cb), dialog);
+ gtk_tree_view_insert_column_with_attributes (
+ GTK_TREE_VIEW (dialog->treeview_servers),
+ -1, _("SSL"), renderer, "active", COL_SSL,
+ NULL);
+
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (dialog->treeview_servers));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+
+ /* charset */
+ totem_subtitle_encoding_init (GTK_COMBO_BOX (dialog->combobox_charset));
+
+ irc_network_dialog_setup (dialog);
+
+ empathy_glade_connect (glade, dialog,
+ "irc_network_dialog", "destroy", irc_network_dialog_destroy_cb,
+ "button_close", "clicked", irc_network_dialog_close_clicked_cb,
+ "entry_network", "focus-out-event", irc_network_dialog_network_focus_cb,
+ "button_add", "clicked", irc_network_dialog_button_add_clicked_cb,
+ "button_remove", "clicked", irc_network_dialog_button_remove_clicked_cb,
+ "button_up", "clicked", irc_network_dialog_button_up_clicked_cb,
+ "button_down", "clicked", irc_network_dialog_button_down_clicked_cb,
+ "combobox_charset", "changed", irc_network_dialog_combobox_charset_changed_cb,
+ NULL);
+
+ g_object_unref (glade);
+
+ g_object_add_weak_pointer (G_OBJECT (dialog->dialog),
+ (gpointer) &dialog);
+
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (irc_network_dialog_selection_changed_cb),
+ dialog);
+
+ gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog),
+ GTK_WINDOW (parent));
+ gtk_window_set_modal (GTK_WINDOW (dialog->dialog), TRUE);
+
+ irc_network_dialog_network_update_buttons (dialog);
+
+ return dialog->dialog;
+}
diff --git a/libempathy-gtk/empathy-irc-network-dialog.h b/libempathy-gtk/empathy-irc-network-dialog.h
new file mode 100644
index 000000000..985849696
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-dialog.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Guillaume Desmottes <gdesmott@gnome.org>
+ */
+
+#ifndef __EMPATHY_IRC_NETWORK_DIALOG_H__
+#define __EMPATHY_IRC_NETWORK_DIALOG_H__
+
+#include <gtk/gtkwidget.h>
+
+#include <libempathy/empathy-irc-network.h>
+
+G_BEGIN_DECLS
+
+GtkWidget * empathy_irc_network_dialog_show (EmpathyIrcNetwork *network,
+ GtkWidget *parent);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_DIALOG_H__ */
diff --git a/libempathy-gtk/totem-subtitle-encoding.c b/libempathy-gtk/totem-subtitle-encoding.c
new file mode 100644
index 000000000..e0eef082c
--- /dev/null
+++ b/libempathy-gtk/totem-subtitle-encoding.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2001-2006 Bastien Nocera <hadess@hadess.net>
+ *
+ * encoding list copied from gnome-terminal/encoding.c
+ *
+ * This program 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 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ *
+ */
+
+#include "config.h"
+#include <glib/gi18n.h>
+#include "totem-subtitle-encoding.h"
+#include <string.h>
+
+typedef enum
+{
+ SUBTITLE_ENCODING_CURRENT_LOCALE,
+
+ SUBTITLE_ENCODING_ISO_8859_6,
+ SUBTITLE_ENCODING_IBM_864,
+ SUBTITLE_ENCODING_MAC_ARABIC,
+ SUBTITLE_ENCODING_WINDOWS_1256,
+
+ SUBTITLE_ENCODING_ARMSCII_8,
+
+ SUBTITLE_ENCODING_ISO_8859_4,
+ SUBTITLE_ENCODING_ISO_8859_13,
+ SUBTITLE_ENCODING_WINDOWS_1257,
+
+ SUBTITLE_ENCODING_ISO_8859_14,
+
+ SUBTITLE_ENCODING_ISO_8859_2,
+ SUBTITLE_ENCODING_IBM_852,
+ SUBTITLE_ENCODING_MAC_CE,
+ SUBTITLE_ENCODING_WINDOWS_1250,
+
+ SUBTITLE_ENCODING_GB18030,
+ SUBTITLE_ENCODING_GB2312,
+ SUBTITLE_ENCODING_GBK,
+ SUBTITLE_ENCODING_HZ,
+
+ SUBTITLE_ENCODING_BIG5,
+ SUBTITLE_ENCODING_BIG5_HKSCS,
+ SUBTITLE_ENCODING_EUC_TW,
+
+ SUBTITLE_ENCODING_MAC_CROATIAN,
+
+ SUBTITLE_ENCODING_ISO_8859_5,
+ SUBTITLE_ENCODING_IBM_855,
+ SUBTITLE_ENCODING_ISO_IR_111,
+ SUBTITLE_ENCODING_KOI8_R,
+ SUBTITLE_ENCODING_MAC_CYRILLIC,
+ SUBTITLE_ENCODING_WINDOWS_1251,
+
+ SUBTITLE_ENCODING_CP_866,
+
+ SUBTITLE_ENCODING_MAC_UKRAINIAN,
+ SUBTITLE_ENCODING_KOI8_U,
+
+ SUBTITLE_ENCODING_GEOSTD8,
+
+ SUBTITLE_ENCODING_ISO_8859_7,
+ SUBTITLE_ENCODING_MAC_GREEK,
+ SUBTITLE_ENCODING_WINDOWS_1253,
+
+ SUBTITLE_ENCODING_MAC_GUJARATI,
+
+ SUBTITLE_ENCODING_MAC_GURMUKHI,
+
+ SUBTITLE_ENCODING_ISO_8859_8_I,
+ SUBTITLE_ENCODING_IBM_862,
+ SUBTITLE_ENCODING_MAC_HEBREW,
+ SUBTITLE_ENCODING_WINDOWS_1255,
+
+ SUBTITLE_ENCODING_ISO_8859_8,
+
+ SUBTITLE_ENCODING_MAC_DEVANAGARI,
+
+ SUBTITLE_ENCODING_MAC_ICELANDIC,
+
+ SUBTITLE_ENCODING_EUC_JP,
+ SUBTITLE_ENCODING_ISO_2022_JP,
+ SUBTITLE_ENCODING_SHIFT_JIS,
+
+ SUBTITLE_ENCODING_EUC_KR,
+ SUBTITLE_ENCODING_ISO_2022_KR,
+ SUBTITLE_ENCODING_JOHAB,
+ SUBTITLE_ENCODING_UHC,
+
+ SUBTITLE_ENCODING_ISO_8859_10,
+
+ SUBTITLE_ENCODING_MAC_FARSI,
+
+ SUBTITLE_ENCODING_ISO_8859_16,
+ SUBTITLE_ENCODING_MAC_ROMANIAN,
+
+ SUBTITLE_ENCODING_ISO_8859_3,
+
+ SUBTITLE_ENCODING_TIS_620,
+
+ SUBTITLE_ENCODING_ISO_8859_9,
+ SUBTITLE_ENCODING_IBM_857,
+ SUBTITLE_ENCODING_MAC_TURKISH,
+ SUBTITLE_ENCODING_WINDOWS_1254,
+
+ SUBTITLE_ENCODING_UTF_7,
+ SUBTITLE_ENCODING_UTF_8,
+ SUBTITLE_ENCODING_UTF_16,
+ SUBTITLE_ENCODING_UCS_2,
+ SUBTITLE_ENCODING_UCS_4,
+
+ SUBTITLE_ENCODING_ISO_8859_1,
+ SUBTITLE_ENCODING_ISO_8859_15,
+ SUBTITLE_ENCODING_IBM_850,
+ SUBTITLE_ENCODING_MAC_ROMAN,
+ SUBTITLE_ENCODING_WINDOWS_1252,
+
+ SUBTITLE_ENCODING_TCVN,
+ SUBTITLE_ENCODING_VISCII,
+ SUBTITLE_ENCODING_WINDOWS_1258,
+
+ SUBTITLE_ENCODING_LAST
+} SubtitleEncodingIndex;
+
+
+typedef struct
+{
+ int index;
+ gboolean valid;
+ char *charset;
+ char *name;
+} SubtitleEncoding;
+
+
+static SubtitleEncoding encodings[] = {
+
+ {SUBTITLE_ENCODING_CURRENT_LOCALE, TRUE,
+ NULL, N_("Current Locale")},
+
+ {SUBTITLE_ENCODING_ISO_8859_6, FALSE,
+ "ISO-8859-6", N_("Arabic")},
+ {SUBTITLE_ENCODING_IBM_864, FALSE,
+ "IBM864", N_("Arabic")},
+ {SUBTITLE_ENCODING_MAC_ARABIC, FALSE,
+ "MAC_ARABIC", N_("Arabic")},
+ {SUBTITLE_ENCODING_WINDOWS_1256, FALSE,
+ "WINDOWS-1256", N_("Arabic")},
+
+ {SUBTITLE_ENCODING_ARMSCII_8, FALSE,
+ "ARMSCII-8", N_("Armenian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_4, FALSE,
+ "ISO-8859-4", N_("Baltic")},
+ {SUBTITLE_ENCODING_ISO_8859_13, FALSE,
+ "ISO-8859-13", N_("Baltic")},
+ {SUBTITLE_ENCODING_WINDOWS_1257, FALSE,
+ "WINDOWS-1257", N_("Baltic")},
+
+ {SUBTITLE_ENCODING_ISO_8859_14, FALSE,
+ "ISO-8859-14", N_("Celtic")},
+
+ {SUBTITLE_ENCODING_ISO_8859_2, FALSE,
+ "ISO-8859-2", N_("Central European")},
+ {SUBTITLE_ENCODING_IBM_852, FALSE,
+ "IBM852", N_("Central European")},
+ {SUBTITLE_ENCODING_MAC_CE, FALSE,
+ "MAC_CE", N_("Central European")},
+ {SUBTITLE_ENCODING_WINDOWS_1250, FALSE,
+ "WINDOWS-1250", N_("Central European")},
+
+ {SUBTITLE_ENCODING_GB18030, FALSE,
+ "GB18030", N_("Chinese Simplified")},
+ {SUBTITLE_ENCODING_GB2312, FALSE,
+ "GB2312", N_("Chinese Simplified")},
+ {SUBTITLE_ENCODING_GBK, FALSE,
+ "GBK", N_("Chinese Simplified")},
+ {SUBTITLE_ENCODING_HZ, FALSE,
+ "HZ", N_("Chinese Simplified")},
+
+ {SUBTITLE_ENCODING_BIG5, FALSE,
+ "BIG5", N_("Chinese Traditional")},
+ {SUBTITLE_ENCODING_BIG5_HKSCS, FALSE,
+ "BIG5-HKSCS", N_("Chinese Traditional")},
+ {SUBTITLE_ENCODING_EUC_TW, FALSE,
+ "EUC-TW", N_("Chinese Traditional")},
+
+ {SUBTITLE_ENCODING_MAC_CROATIAN, FALSE,
+ "MAC_CROATIAN", N_("Croatian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_5, FALSE,
+ "ISO-8859-5", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_IBM_855, FALSE,
+ "IBM855", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_ISO_IR_111, FALSE,
+ "ISO-IR-111", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_KOI8_R, FALSE,
+ "KOI8-R", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_MAC_CYRILLIC, FALSE,
+ "MAC-CYRILLIC", N_("Cyrillic")},
+ {SUBTITLE_ENCODING_WINDOWS_1251, FALSE,
+ "WINDOWS-1251", N_("Cyrillic")},
+
+ {SUBTITLE_ENCODING_CP_866, FALSE,
+ "CP866", N_("Cyrillic/Russian")},
+
+ {SUBTITLE_ENCODING_MAC_UKRAINIAN, FALSE,
+ "MAC_UKRAINIAN", N_("Cyrillic/Ukrainian")},
+ {SUBTITLE_ENCODING_KOI8_U, FALSE,
+ "KOI8-U", N_("Cyrillic/Ukrainian")},
+
+ {SUBTITLE_ENCODING_GEOSTD8, FALSE,
+ "GEORGIAN-PS", N_("Georgian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_7, FALSE,
+ "ISO-8859-7", N_("Greek")},
+ {SUBTITLE_ENCODING_MAC_GREEK, FALSE,
+ "MAC_GREEK", N_("Greek")},
+ {SUBTITLE_ENCODING_WINDOWS_1253, FALSE,
+ "WINDOWS-1253", N_("Greek")},
+
+ {SUBTITLE_ENCODING_MAC_GUJARATI, FALSE,
+ "MAC_GUJARATI", N_("Gujarati")},
+
+ {SUBTITLE_ENCODING_MAC_GURMUKHI, FALSE,
+ "MAC_GURMUKHI", N_("Gurmukhi")},
+
+ {SUBTITLE_ENCODING_ISO_8859_8_I, FALSE,
+ "ISO-8859-8-I", N_("Hebrew")},
+ {SUBTITLE_ENCODING_IBM_862, FALSE,
+ "IBM862", N_("Hebrew")},
+ {SUBTITLE_ENCODING_MAC_HEBREW, FALSE,
+ "MAC_HEBREW", N_("Hebrew")},
+ {SUBTITLE_ENCODING_WINDOWS_1255, FALSE,
+ "WINDOWS-1255", N_("Hebrew")},
+
+ {SUBTITLE_ENCODING_ISO_8859_8, FALSE,
+ "ISO-8859-8", N_("Hebrew Visual")},
+
+ {SUBTITLE_ENCODING_MAC_DEVANAGARI, FALSE,
+ "MAC_DEVANAGARI", N_("Hindi")},
+
+ {SUBTITLE_ENCODING_MAC_ICELANDIC, FALSE,
+ "MAC_ICELANDIC", N_("Icelandic")},
+
+ {SUBTITLE_ENCODING_EUC_JP, FALSE,
+ "EUC-JP", N_("Japanese")},
+ {SUBTITLE_ENCODING_ISO_2022_JP, FALSE,
+ "ISO2022JP", N_("Japanese")},
+ {SUBTITLE_ENCODING_SHIFT_JIS, FALSE,
+ "SHIFT-JIS", N_("Japanese")},
+
+ {SUBTITLE_ENCODING_EUC_KR, FALSE,
+ "EUC-KR", N_("Korean")},
+ {SUBTITLE_ENCODING_ISO_2022_KR, FALSE,
+ "ISO2022KR", N_("Korean")},
+ {SUBTITLE_ENCODING_JOHAB, FALSE,
+ "JOHAB", N_("Korean")},
+ {SUBTITLE_ENCODING_UHC, FALSE,
+ "UHC", N_("Korean")},
+
+ {SUBTITLE_ENCODING_ISO_8859_10, FALSE,
+ "ISO-8859-10", N_("Nordic")},
+
+ {SUBTITLE_ENCODING_MAC_FARSI, FALSE,
+ "MAC_FARSI", N_("Persian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_16, FALSE,
+ "ISO-8859-16", N_("Romanian")},
+ {SUBTITLE_ENCODING_MAC_ROMANIAN, FALSE,
+ "MAC_ROMANIAN", N_("Romanian")},
+
+ {SUBTITLE_ENCODING_ISO_8859_3, FALSE,
+ "ISO-8859-3", N_("South European")},
+
+ {SUBTITLE_ENCODING_TIS_620, FALSE,
+ "TIS-620", N_("Thai")},
+
+ {SUBTITLE_ENCODING_ISO_8859_9, FALSE,
+ "ISO-8859-9", N_("Turkish")},
+ {SUBTITLE_ENCODING_IBM_857, FALSE,
+ "IBM857", N_("Turkish")},
+ {SUBTITLE_ENCODING_MAC_TURKISH, FALSE,
+ "MAC_TURKISH", N_("Turkish")},
+ {SUBTITLE_ENCODING_WINDOWS_1254, FALSE,
+ "WINDOWS-1254", N_("Turkish")},
+
+ {SUBTITLE_ENCODING_UTF_7, FALSE,
+ "UTF-7", N_("Unicode")},
+ {SUBTITLE_ENCODING_UTF_8, FALSE,
+ "UTF-8", N_("Unicode")},
+ {SUBTITLE_ENCODING_UTF_16, FALSE,
+ "UTF-16", N_("Unicode")},
+ {SUBTITLE_ENCODING_UCS_2, FALSE,
+ "UCS-2", N_("Unicode")},
+ {SUBTITLE_ENCODING_UCS_4, FALSE,
+ "UCS-4", N_("Unicode")},
+
+ {SUBTITLE_ENCODING_ISO_8859_1, FALSE,
+ "ISO-8859-1", N_("Western")},
+ {SUBTITLE_ENCODING_ISO_8859_15, FALSE,
+ "ISO-8859-15", N_("Western")},
+ {SUBTITLE_ENCODING_IBM_850, FALSE,
+ "IBM850", N_("Western")},
+ {SUBTITLE_ENCODING_MAC_ROMAN, FALSE,
+ "MAC_ROMAN", N_("Western")},
+ {SUBTITLE_ENCODING_WINDOWS_1252, FALSE,
+ "WINDOWS-1252", N_("Western")},
+
+ {SUBTITLE_ENCODING_TCVN, FALSE,
+ "TCVN", N_("Vietnamese")},
+ {SUBTITLE_ENCODING_VISCII, FALSE,
+ "VISCII", N_("Vietnamese")},
+ {SUBTITLE_ENCODING_WINDOWS_1258, FALSE,
+ "WINDOWS-1258", N_("Vietnamese")}
+};
+
+static const SubtitleEncoding *
+find_encoding_by_charset (const char *charset)
+{
+ int i;
+
+ i = 1; /* skip current locale */
+ while (i < SUBTITLE_ENCODING_LAST) {
+ if (strcasecmp (charset, encodings[i].charset) == 0)
+ return &encodings[i];
+
+ ++i;
+ }
+
+ if (strcasecmp (charset,
+ encodings[SUBTITLE_ENCODING_CURRENT_LOCALE].charset) == 0)
+ return &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
+
+ return NULL;
+}
+
+static void
+subtitle_encoding_init (void)
+{
+ int i;
+ gsize bytes_read, bytes_written;
+ gchar *converted;
+ gchar ascii_sample[96];
+
+ g_get_charset ((const char **)
+ &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE].charset);
+
+ g_assert (G_N_ELEMENTS (encodings) == SUBTITLE_ENCODING_LAST);
+
+ /* Initialize the sample text with all of the printing ASCII characters
+ * from space (32) to the tilde (126), 95 in all. */
+ for (i = 0; i < (int) sizeof (ascii_sample); i++)
+ ascii_sample[i] = i + 32;
+
+ ascii_sample[sizeof (ascii_sample) - 1] = '\0';
+
+ i = 0;
+ while (i < SUBTITLE_ENCODING_LAST) {
+ bytes_read = 0;
+ bytes_written = 0;
+
+ g_assert (encodings[i].index == i);
+
+ /* Translate the names */
+ encodings[i].name = _(encodings[i].name);
+
+ /* Test that the encoding is a proper superset of ASCII (which naive
+ * apps are going to use anyway) by attempting to validate the text
+ * using the current encoding. This also flushes out any encodings
+ * which the underlying GIConv implementation can't support.
+ */
+ converted = g_convert (ascii_sample, sizeof (ascii_sample) - 1,
+ encodings[i].charset, encodings[i].charset,
+ &bytes_read, &bytes_written, NULL);
+
+ /* The encoding is only valid if ASCII passes through cleanly. */
+ if (i == SUBTITLE_ENCODING_CURRENT_LOCALE)
+ encodings[i].valid = TRUE;
+ else
+ encodings[i].valid =
+ (bytes_read == (sizeof (ascii_sample) - 1)) &&
+ (converted != NULL) && (strcmp (converted, ascii_sample) == 0);
+
+#ifdef DEBUG_ENCODINGS
+ if (!encodings[i].valid) {
+ g_print ("Rejecting encoding %s as invalid:\n", encodings[i].charset);
+ g_print (" input \"%s\"\n", ascii_sample);
+ g_print (" output \"%s\"\n\n", converted ? converted : "(null)");
+ }
+#endif
+
+ /* Discard the converted string. */
+ g_free (converted);
+
+ ++i;
+ }
+}
+
+static int
+subtitle_encoding_get_index (const char *charset)
+{
+ const SubtitleEncoding *e;
+
+ e = find_encoding_by_charset (charset);
+ if (e != NULL)
+ return e->index;
+ else
+ return SUBTITLE_ENCODING_CURRENT_LOCALE;
+}
+
+static const char *
+subtitle_encoding_get_charset (int index)
+{
+ const SubtitleEncoding *e;
+
+ if (index >= SUBTITLE_ENCODING_LAST)
+ e = &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
+ else if (index < SUBTITLE_ENCODING_CURRENT_LOCALE)
+ e = &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
+ else if (!encodings[index].valid)
+ e = &encodings[SUBTITLE_ENCODING_CURRENT_LOCALE];
+ else
+ e = &encodings[index];
+ return e->charset;
+}
+
+enum
+{
+ INDEX_COL,
+ NAME_COL
+};
+
+static gint
+compare (GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer data)
+{
+ gchar *str_a, *str_b;
+ gint result;
+
+ gtk_tree_model_get (model, a, NAME_COL, &str_a, -1);
+ gtk_tree_model_get (model, b, NAME_COL, &str_b, -1);
+
+ result = strcmp (str_a, str_b);
+
+ g_free (str_a);
+ g_free (str_b);
+
+ return result;
+}
+
+static void
+is_encoding_sensitive (GtkCellLayout * cell_layout,
+ GtkCellRenderer * cell,
+ GtkTreeModel * tree_model, GtkTreeIter * iter, gpointer data)
+{
+
+ gboolean sensitive;
+
+ sensitive = !gtk_tree_model_iter_has_child (tree_model, iter);
+ g_object_set (cell, "sensitive", sensitive, NULL);
+}
+
+static GtkTreeModel *
+subtitle_encoding_create_store (void)
+{
+ gchar *label;
+ gchar *lastlang = "";
+ GtkTreeIter iter, iter2;
+ GtkTreeStore *store;
+ int i;
+
+ store = gtk_tree_store_new (2, G_TYPE_INT, G_TYPE_STRING);
+
+ for (i = 0; i < SUBTITLE_ENCODING_LAST; i++) {
+ if (encodings[i].valid) {
+ if (strcmp (lastlang, encodings[i].name)) {
+ lastlang = encodings[i].name;
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter, INDEX_COL,
+ -1, NAME_COL, lastlang, -1);
+ }
+ label = g_strdup_printf("%s (%s)", lastlang, encodings[i].charset);
+ gtk_tree_store_append (store, &iter2, &iter);
+ gtk_tree_store_set (store, &iter2, INDEX_COL,
+ encodings[i].index, NAME_COL, label, -1);
+ g_free(label);
+ }
+ }
+ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
+ compare, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
+ NAME_COL, GTK_SORT_ASCENDING);
+ return GTK_TREE_MODEL (store);
+}
+
+static void
+subtitle_encoding_combo_render (GtkComboBox * combo)
+{
+ GtkCellRenderer *renderer;
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
+ "text", NAME_COL, NULL);
+ gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo),
+ renderer, is_encoding_sensitive, NULL, NULL);
+}
+
+const char *
+totem_subtitle_encoding_get_selected (GtkComboBox * combo)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint index = -1;
+
+ model = gtk_combo_box_get_model (combo);
+ if (gtk_combo_box_get_active_iter (combo, &iter)) {
+ gtk_tree_model_get (model, &iter, INDEX_COL, &index, -1);
+ }
+ if (index == -1)
+ return NULL;
+ return subtitle_encoding_get_charset (index);
+}
+
+void
+totem_subtitle_encoding_set (GtkComboBox * combo, const char *encoding)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter, iter2;
+ gint index, i;
+
+ g_return_if_fail (encoding != NULL);
+
+ model = gtk_combo_box_get_model (combo);
+ index = subtitle_encoding_get_index (encoding);
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ if (!gtk_tree_model_iter_has_child (model, &iter))
+ continue;
+ if (!gtk_tree_model_iter_children (model, &iter2, &iter))
+ continue;
+ do {
+ gtk_tree_model_get (model, &iter2, INDEX_COL, &i, -1);
+ if (i == index)
+ break;
+ } while (gtk_tree_model_iter_next (model, &iter2));
+ if (i == index)
+ break;
+ } while (gtk_tree_model_iter_next (model, &iter));
+ gtk_combo_box_set_active_iter (combo, &iter2);
+}
+
+void
+totem_subtitle_encoding_init (GtkComboBox *combo)
+{
+ GtkTreeModel *model;
+ subtitle_encoding_init ();
+ model = subtitle_encoding_create_store ();
+ gtk_combo_box_set_model (combo, model);
+ g_object_unref (model);
+ subtitle_encoding_combo_render (combo);
+}
+
+/*
+ * vim: sw=2 ts=8 cindent noai bs=2
+ */
diff --git a/libempathy-gtk/totem-subtitle-encoding.h b/libempathy-gtk/totem-subtitle-encoding.h
new file mode 100644
index 000000000..7283f003a
--- /dev/null
+++ b/libempathy-gtk/totem-subtitle-encoding.h
@@ -0,0 +1,12 @@
+/* Encoding stuff */
+
+#ifndef TOTEM_SUBTITLE_ENCODING_H
+#define TOTEM_SUBTITLE_ENCODING_H
+
+#include <gtk/gtk.h>
+
+void totem_subtitle_encoding_init (GtkComboBox *combo);
+void totem_subtitle_encoding_set (GtkComboBox *combo, const char *encoding);
+const char * totem_subtitle_encoding_get_selected (GtkComboBox *combo);
+
+#endif /* SUBTITLE_ENCODING_H */