diff options
author | Xavier Claessens <xclaesse@src.gnome.org> | 2008-02-18 07:38:19 +0800 |
---|---|---|
committer | Xavier Claessens <xclaesse@src.gnome.org> | 2008-02-18 07:38:19 +0800 |
commit | 8107cb72c02be53157fc87955b4bc4f454662182 (patch) | |
tree | c37e04a560b3c654a5b509e2dd02c5a79178bed1 /libempathy-gtk | |
parent | 20c9a85036f7c951eb24df9587db695895869342 (diff) | |
download | gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.gz gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.bz2 gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.lz gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.xz gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.tar.zst gsoc2013-empathy-8107cb72c02be53157fc87955b4bc4f454662182.zip |
Merge commit 'cassidy/irc'
svn path=/trunk/; revision=649
Diffstat (limited to 'libempathy-gtk')
-rw-r--r-- | libempathy-gtk/Makefile.am | 10 | ||||
-rw-r--r-- | libempathy-gtk/empathy-account-widget-irc.c | 511 | ||||
-rw-r--r-- | libempathy-gtk/empathy-account-widget-irc.glade | 451 | ||||
-rw-r--r-- | libempathy-gtk/empathy-account-widget-irc.h | 33 | ||||
-rw-r--r-- | libempathy-gtk/empathy-accounts-dialog.c | 5 | ||||
-rw-r--r-- | libempathy-gtk/empathy-irc-network-dialog.c | 579 | ||||
-rw-r--r-- | libempathy-gtk/empathy-irc-network-dialog.h | 35 | ||||
-rw-r--r-- | libempathy-gtk/totem-subtitle-encoding.c | 585 | ||||
-rw-r--r-- | libempathy-gtk/totem-subtitle-encoding.h | 12 |
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"><b>Network</b></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"><b>Servers</b></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 */ |