aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-08-26 20:03:11 +0800
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-08-26 20:03:11 +0800
commit2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893 (patch)
tree1e10eda9d904d4d29664f79193b4b6f70823c5a8
parentf7a63b4c249208122cfa17f668a19d853d158dfa (diff)
parente62460125c8a90e0f77f18326d597868ca01a42c (diff)
downloadgsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.tar
gsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.tar.gz
gsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.tar.bz2
gsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.tar.lz
gsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.tar.xz
gsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.tar.zst
gsoc2013-empathy-2de3bc4c03f97f1ceea44f43a1b86dedcb7e6893.zip
Merge branch 'irc-widget-588243'
-rw-r--r--libempathy-gtk/Makefile.am4
-rw-r--r--libempathy-gtk/empathy-account-widget-irc.c403
-rw-r--r--libempathy-gtk/empathy-account-widget-irc.ui78
-rw-r--r--libempathy-gtk/empathy-irc-network-chooser-dialog.c629
-rw-r--r--libempathy-gtk/empathy-irc-network-chooser-dialog.h71
-rw-r--r--libempathy-gtk/empathy-irc-network-chooser.c360
-rw-r--r--libempathy-gtk/empathy-irc-network-chooser.h61
-rw-r--r--libempathy/empathy-irc-network-manager.c34
-rw-r--r--libempathy/empathy-irc-network-manager.h2
-rw-r--r--libempathy/empathy-irc-network.c16
-rw-r--r--libempathy/empathy-irc-network.h4
11 files changed, 1204 insertions, 458 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index de6cba2f1..d81b97253 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -63,6 +63,8 @@ libempathy_gtk_handwritten_source = \
empathy-individual-store.c \
empathy-individual-view.c \
empathy-individual-widget.c \
+ empathy-irc-network-chooser.c \
+ empathy-irc-network-chooser-dialog.c \
empathy-irc-network-dialog.c \
empathy-kludge-label.c \
empathy-log-window.c \
@@ -123,6 +125,8 @@ libempathy_gtk_headers = \
empathy-individual-store.h \
empathy-individual-view.h \
empathy-individual-widget.h \
+ empathy-irc-network-chooser.h \
+ empathy-irc-network-chooser-dialog.h \
empathy-irc-network-dialog.h \
empathy-kludge-label.h \
empathy-log-window.h \
diff --git a/libempathy-gtk/empathy-account-widget-irc.c b/libempathy-gtk/empathy-account-widget-irc.c
index f98d54bbd..d60af5ea8 100644
--- a/libempathy-gtk/empathy-account-widget-irc.c
+++ b/libempathy-gtk/empathy-account-widget-irc.c
@@ -28,9 +28,9 @@
#include <gtk/gtk.h>
#include <libempathy/empathy-utils.h>
-#include <libempathy/empathy-irc-network-manager.h>
#include "empathy-irc-network-dialog.h"
+#include "empathy-irc-network-chooser.h"
#include "empathy-account-widget.h"
#include "empathy-account-widget-private.h"
#include "empathy-account-widget-irc.h"
@@ -39,304 +39,29 @@
#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
#include <libempathy/empathy-debug.h>
-#define IRC_NETWORKS_FILENAME "irc-networks.xml"
-#define DEFAULT_IRC_NETWORK "irc.gimp.org"
-
typedef struct {
EmpathyAccountWidget *self;
- EmpathyIrcNetworkManager *network_manager;
GtkWidget *vbox_settings;
- GtkWidget *combobox_network;
+ GtkWidget *network_chooser;
} 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_slice_free (EmpathyAccountWidgetIrc, settings);
}
static void
-unset_server_params (EmpathyAccountWidgetIrc *settings)
-{
- EmpathyAccountSettings *ac_settings;
-
- g_object_get (settings->self, "settings", &ac_settings, NULL);
- DEBUG ("Unset server, port and use-ssl");
- empathy_account_settings_unset (ac_settings, "server");
- empathy_account_settings_unset (ac_settings, "port");
- empathy_account_settings_unset (ac_settings, "use-ssl");
-}
-
-static void
-update_server_params (EmpathyAccountWidgetIrc *settings)
-{
- GtkTreeIter iter;
- GtkTreeModel *model;
- EmpathyIrcNetwork *network;
- GSList *servers;
- gchar *charset;
- EmpathyAccountSettings *ac_settings;
-
- g_object_get (settings->self, "settings", &ac_settings, NULL);
-
- 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);
- DEBUG ("Setting charset to %s", charset);
- empathy_account_settings_set_string (ac_settings, "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);
-
- DEBUG ("Setting server to %s", address);
- empathy_account_settings_set_string (ac_settings, "server", address);
- DEBUG ("Setting port to %u", port);
- empathy_account_settings_set_uint32 (ac_settings, "port", port);
- DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
- empathy_account_settings_set_boolean (ac_settings, "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);
- empathy_account_widget_changed (settings->self);
-
- 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);
- DEBUG ("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);
- empathy_account_widget_changed (settings->self);
-}
-
-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)
{
const gchar *nick = NULL;
const gchar *fullname = NULL;
- const gchar *server = NULL;
gint port = 6667;
const gchar *charset;
gboolean ssl = FALSE;
- EmpathyIrcNetwork *network = NULL;
EmpathyAccountSettings *ac_settings;
g_object_get (settings->self, "settings", &ac_settings, NULL);
@@ -344,7 +69,6 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
nick = empathy_account_settings_get_string (ac_settings, "account");
fullname = empathy_account_settings_get_string (ac_settings,
"fullname");
- server = empathy_account_settings_get_string (ac_settings, "server");
charset = empathy_account_settings_get_string (ac_settings, "charset");
port = empathy_account_settings_get_uint32 (ac_settings, "port");
ssl = empathy_account_settings_get_boolean (ac_settings, "use-ssl");
@@ -366,63 +90,13 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
empathy_account_settings_set_string (ac_settings,
"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);
- DEBUG ("Account use network %s", name);
-
- g_free (name);
- }
- else
- {
- /* We don't have this network. Let's create it */
- EmpathyIrcServer *srv;
- GtkTreeIter iter;
-
- DEBUG ("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);
- }
- }
-
- if (network == NULL)
- {
- network = empathy_irc_network_manager_find_network_by_address (
- settings->network_manager, DEFAULT_IRC_NETWORK);
- }
-
- fill_networks_model (settings, network);
- update_server_params (settings);
+static void
+network_changed_cb (EmpathyIrcNetworkChooser *chooser,
+ EmpathyAccountWidgetIrc *settings)
+{
+ empathy_account_widget_changed (settings->self);
}
void
@@ -431,60 +105,29 @@ empathy_account_widget_irc_build (EmpathyAccountWidget *self,
GtkWidget **table_common_settings)
{
EmpathyAccountWidgetIrc *settings;
- gchar *dir, *user_file_with_path, *global_file_with_path;
- GtkListStore *store;
- GtkCellRenderer *renderer;
+ EmpathyAccountSettings *ac_settings;
settings = g_slice_new0 (EmpathyAccountWidgetIrc);
settings->self = self;
- dir = g_build_filename (g_get_user_config_dir (), 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 (g_getenv ("EMPATHY_SRCDIR"),
- "libempathy", 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);
-
self->ui_details->gui = empathy_builder_get_file (filename,
"table_irc_settings", table_common_settings,
"vbox_irc", &self->ui_details->widget,
"table_irc_settings", &settings->vbox_settings,
- "combobox_network", &settings->combobox_network,
NULL);
- /* Fill the networks combobox */
- store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
+ /* Add network chooser button */
+ g_object_get (settings->self, "settings", &ac_settings, NULL);
- 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);
+ settings->network_chooser = empathy_irc_network_chooser_new (ac_settings);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
- COL_NETWORK_NAME,
- GTK_SORT_ASCENDING);
+ g_signal_connect (settings->network_chooser, "changed",
+ G_CALLBACK (network_changed_cb), settings);
- gtk_combo_box_set_model (GTK_COMBO_BOX (settings->combobox_network),
- GTK_TREE_MODEL (store));
- g_object_unref (store);
+ gtk_table_attach (GTK_TABLE (*table_common_settings),
+ settings->network_chooser, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
+
+ gtk_widget_show (settings->network_chooser);
account_widget_irc_setup (settings);
@@ -497,15 +140,9 @@ empathy_account_widget_irc_build (EmpathyAccountWidget *self,
empathy_builder_connect (self->ui_details->gui, settings,
"table_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_network", "clicked",
- account_widget_irc_button_remove_clicked_cb,
- "combobox_network", "changed",
- account_widget_irc_combobox_network_changed_cb,
NULL);
self->ui_details->default_focus = g_strdup ("entry_nick");
+
+ g_object_unref (ac_settings);
}
diff --git a/libempathy-gtk/empathy-account-widget-irc.ui b/libempathy-gtk/empathy-account-widget-irc.ui
index af733fb95..de0aa00cd 100644
--- a/libempathy-gtk/empathy-account-widget-irc.ui
+++ b/libempathy-gtk/empathy-account-widget-irc.ui
@@ -257,7 +257,6 @@
</object>
<object class="GtkVBox" id="vbox_irc">
<property name="visible">True</property>
- <property name="orientation">vertical</property>
<child>
<object class="GtkTable" id="table_irc_settings">
<property name="visible">True</property>
@@ -373,80 +372,6 @@
</packing>
</child>
<child>
- <object class="GtkHBox" id="hbox174">
- <property name="visible">True</property>
- <property name="spacing">2</property>
- <child>
- <object class="GtkComboBox" id="combobox_network">
- <property name="visible">True</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_add_network">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <child>
- <object class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-add</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_network">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <child>
- <object class="GtkImage" id="image834">
- <property name="visible">True</property>
- <property name="stock">gtk-edit</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button_remove_network">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <child>
- <object class="GtkImage" id="image835">
- <property name="visible">True</property>
- <property name="stock">gtk-remove</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- <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>
<object class="GtkLabel" id="label_network2">
<property name="visible">True</property>
<property name="xalign">0</property>
@@ -458,6 +383,9 @@
<property name="y_options"></property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="position">0</property>
diff --git a/libempathy-gtk/empathy-irc-network-chooser-dialog.c b/libempathy-gtk/empathy-irc-network-chooser-dialog.c
new file mode 100644
index 000000000..c1335e539
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser-dialog.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * 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-lib.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-irc-network-manager.h>
+
+#include "empathy-irc-network-dialog.h"
+#include "empathy-ui-utils.h"
+#include "empathy-live-search.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-irc-network-chooser-dialog.h"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooserDialog)
+
+enum {
+ PROP_SETTINGS = 1,
+ PROP_NETWORK
+};
+
+typedef struct {
+ EmpathyAccountSettings *settings;
+ EmpathyIrcNetwork *network;
+
+ EmpathyIrcNetworkManager *network_manager;
+ gboolean changed;
+
+ GtkWidget *treeview;
+ GtkListStore *store;
+ GtkTreeModelFilter *filter;
+ GtkWidget *search;
+ GtkWidget *select_button;
+
+ gulong search_sig;
+} EmpathyIrcNetworkChooserDialogPriv;
+
+enum {
+ COL_NETWORK_OBJ,
+ COL_NETWORK_NAME,
+};
+
+G_DEFINE_TYPE (EmpathyIrcNetworkChooserDialog, empathy_irc_network_chooser_dialog,
+ GTK_TYPE_DIALOG);
+
+static void
+empathy_irc_network_chooser_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (object);
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ priv->settings = g_value_dup_object (value);
+ break;
+ case PROP_NETWORK:
+ priv->network = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_network_chooser_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (object);
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ case PROP_NETWORK:
+ g_value_set_object (value, priv->network);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* The iter returned by *it is a priv->store iter (not a filter one) */
+static EmpathyIrcNetwork *
+dup_selected_network (EmpathyIrcNetworkChooserDialog *self,
+ GtkTreeIter *it)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ EmpathyIrcNetwork *network;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return NULL;
+
+ gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
+ g_assert (network != NULL);
+
+ if (it != NULL)
+ {
+ gtk_tree_model_filter_convert_iter_to_child_iter (priv->filter, it,
+ &iter);
+ }
+
+ return network;
+}
+
+static void
+treeview_changed_cb (GtkTreeView *treeview,
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ EmpathyIrcNetwork *network;
+
+ network = dup_selected_network (self, NULL);
+ if (network == priv->network)
+ {
+ g_object_unref (network);
+ return;
+ }
+
+ tp_clear_object (&priv->network);
+ /* Transfer the reference */
+ priv->network = network;
+
+ priv->changed = TRUE;
+}
+
+/* Take a filter iterator as argument */
+static void
+scroll_to_iter (EmpathyIrcNetworkChooserDialog *self,
+ GtkTreeIter *filter_iter)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ GtkTreePath *path;
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter), filter_iter);
+
+ if (path != NULL)
+ {
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->treeview),
+ path, NULL, FALSE, 0, 0);
+
+ gtk_tree_path_free (path);
+ }
+}
+
+/* Take a filter iterator as argument */
+static void
+select_iter (EmpathyIrcNetworkChooserDialog *self,
+ GtkTreeIter *filter_iter,
+ gboolean emulate_changed)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ GtkTreeSelection *selection;
+ GtkTreePath *path;
+
+ /* Select the network */
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (priv->treeview));
+
+ gtk_tree_selection_select_iter (selection, filter_iter);
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->filter), filter_iter);
+ if (path != NULL)
+ {
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->treeview), path,
+ NULL, FALSE);
+
+ gtk_tree_path_free (path);
+ }
+
+ /* Scroll to the selected network */
+ scroll_to_iter (self, filter_iter);
+
+ if (emulate_changed)
+ {
+ /* gtk_tree_selection_select_iter doesn't fire the 'cursor-changed' signal
+ * so we call the callback manually. */
+ treeview_changed_cb (GTK_TREE_VIEW (priv->treeview), self);
+ }
+}
+
+static GtkTreeIter
+iter_to_filter_iter (EmpathyIrcNetworkChooserDialog *self,
+ GtkTreeIter *iter)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ GtkTreeIter filter_iter;
+
+ g_assert (gtk_tree_model_filter_convert_child_iter_to_iter (priv->filter,
+ &filter_iter, iter));
+
+ return filter_iter;
+}
+
+static void
+fill_store (EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ GSList *networks, *l;
+
+ networks = empathy_irc_network_manager_get_networks (
+ priv->network_manager);
+
+ for (l = networks; l != NULL; l = g_slist_next (l))
+ {
+ EmpathyIrcNetwork *network = l->data;
+ GtkTreeIter iter;
+
+ gtk_list_store_insert_with_values (priv->store, &iter, -1,
+ COL_NETWORK_OBJ, network,
+ COL_NETWORK_NAME, empathy_irc_network_get_name (network),
+ -1);
+
+ if (network == priv->network)
+ {
+ GtkTreeIter filter_iter = iter_to_filter_iter (self, &iter);
+
+ select_iter (self, &filter_iter, FALSE);
+ }
+
+ g_object_unref (network);
+ }
+
+ g_slist_free (networks);
+}
+
+static void
+irc_network_dialog_destroy_cb (GtkWidget *widget,
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ EmpathyIrcNetwork *network;
+ GtkTreeIter iter, filter_iter;
+
+ priv->changed = TRUE;
+
+ network = dup_selected_network (self, &iter);
+ if (network == NULL)
+ return;
+
+ /* name could be changed */
+ gtk_list_store_set (GTK_LIST_STORE (priv->store), &iter,
+ COL_NETWORK_NAME, empathy_irc_network_get_name (network), -1);
+
+ filter_iter = iter_to_filter_iter (self, &iter);
+ scroll_to_iter (self, &filter_iter);
+
+ gtk_widget_grab_focus (priv->treeview);
+
+ g_object_unref (network);
+}
+
+static void
+display_irc_network_dialog (EmpathyIrcNetworkChooserDialog *self,
+ EmpathyIrcNetwork *network)
+{
+ GtkWidget *dialog;
+
+ dialog = empathy_irc_network_dialog_show (network, NULL);
+
+ g_signal_connect (dialog, "destroy",
+ G_CALLBACK (irc_network_dialog_destroy_cb), self);
+}
+
+static void
+edit_network (EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetwork *network;
+
+ network = dup_selected_network (self, NULL);
+ if (network == NULL)
+ return;
+
+ display_irc_network_dialog (self, network);
+
+ g_object_unref (network);
+}
+
+static void
+add_network (EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ EmpathyIrcNetwork *network;
+ GtkTreeIter iter, filter_iter;
+
+ gtk_widget_hide (priv->search);
+
+ network = empathy_irc_network_new (_("New Network"));
+ empathy_irc_network_manager_add (priv->network_manager, network);
+
+ gtk_list_store_insert_with_values (priv->store, &iter, -1,
+ COL_NETWORK_OBJ, network,
+ COL_NETWORK_NAME, empathy_irc_network_get_name (network),
+ -1);
+
+ filter_iter = iter_to_filter_iter (self, &iter);
+ select_iter (self, &filter_iter, TRUE);
+
+ display_irc_network_dialog (self, network);
+
+ g_object_unref (network);
+}
+
+static void
+remove_network (EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ EmpathyIrcNetwork *network;
+ GtkTreeIter iter;
+
+ network = dup_selected_network (self, &iter);
+ if (network == NULL)
+ return;
+
+ /* Hide the search after picking the network to get the right one */
+ gtk_widget_hide (priv->search);
+
+ DEBUG ("Remove network %s", empathy_irc_network_get_name (network));
+
+ gtk_list_store_remove (priv->store, &iter);
+ empathy_irc_network_manager_remove (priv->network_manager, network);
+
+ /* Select next network */
+ if (gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), &iter))
+ {
+ GtkTreeIter filter_iter = iter_to_filter_iter (self, &iter);
+
+ select_iter (self, &filter_iter, TRUE);
+ }
+
+ gtk_widget_grab_focus (priv->treeview);
+
+ g_object_unref (network);
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+ gint response,
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ if (response == GTK_RESPONSE_OK)
+ add_network (self);
+ else if (response == GTK_RESPONSE_APPLY)
+ edit_network (self);
+ else if (response == GTK_RESPONSE_REJECT)
+ remove_network (self);
+}
+
+static gboolean
+filter_visible_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (user_data);
+ EmpathyIrcNetwork *network;
+ gboolean visible;
+
+ gtk_tree_model_get (model, iter, COL_NETWORK_OBJ, &network, -1);
+
+ visible = empathy_live_search_match (EMPATHY_LIVE_SEARCH (priv->search),
+ empathy_irc_network_get_name (network));
+
+ g_object_unref (network);
+ return visible;
+}
+
+
+static void
+search_text_notify_cb (EmpathyLiveSearch *search,
+ GParamSpec *pspec,
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ GtkTreeIter filter_iter;
+ gboolean sensitive = FALSE;
+
+ gtk_tree_model_filter_refilter (priv->filter);
+
+ /* Is there at least one network in the view ? */
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->filter),
+ &filter_iter))
+ {
+ const gchar *text;
+
+ text = empathy_live_search_get_text (EMPATHY_LIVE_SEARCH (priv->search));
+ if (!EMP_STR_EMPTY (text))
+ {
+ /* We are doing a search, select the first matching network */
+ select_iter (self, &filter_iter, TRUE);
+ }
+ else
+ {
+ /* Search has been cancelled. Scroll to the selected network */
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (priv->treeview));
+
+ if (gtk_tree_selection_get_selected (selection, NULL, &filter_iter))
+ scroll_to_iter (self, &filter_iter);
+ }
+
+ sensitive = TRUE;
+ }
+
+ gtk_widget_set_sensitive (priv->select_button, sensitive);
+}
+
+static void
+dialog_destroy_cb (GtkWidget *widget,
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+ g_signal_handler_disconnect (priv->search, priv->search_sig);
+}
+
+static void
+empathy_irc_network_chooser_dialog_constructed (GObject *object)
+{
+ EmpathyIrcNetworkChooserDialog *self = (EmpathyIrcNetworkChooserDialog *) object;
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+ GtkDialog *dialog = GTK_DIALOG (self);
+ GtkCellRenderer *renderer;
+ GtkWidget *vbox;
+ GtkTreeViewColumn *column;
+ GtkWidget *scroll;
+
+ g_assert (priv->settings != NULL);
+
+ gtk_window_set_title (GTK_WINDOW (self), _("Choose an IRC network"));
+
+ /* Create store and treeview */
+ priv->store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->store),
+ COL_NETWORK_NAME,
+ GTK_SORT_ASCENDING);
+
+ priv->treeview = gtk_tree_view_new ();
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+ gtk_tree_view_set_enable_search (GTK_TREE_VIEW (priv->treeview), FALSE);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column),
+ renderer,
+ "text", COL_NETWORK_NAME,
+ NULL);
+
+ /* add the treeview in a GtkScrolledWindow */
+ vbox = gtk_dialog_get_content_area (dialog);
+
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+ gtk_container_add (GTK_CONTAINER (scroll), priv->treeview);
+ gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 6);
+
+ /* Live search */
+ priv->search = empathy_live_search_new (priv->treeview);
+
+ gtk_box_pack_start (GTK_BOX (vbox), priv->search, FALSE, TRUE, 0);
+
+ priv->filter = GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (
+ GTK_TREE_MODEL (priv->store), NULL));
+ gtk_tree_model_filter_set_visible_func (priv->filter,
+ filter_visible_func, self, NULL);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
+ GTK_TREE_MODEL (priv->filter));
+
+ priv->search_sig = g_signal_connect (priv->search, "notify::text",
+ G_CALLBACK (search_text_notify_cb), self);
+
+ /* Add buttons */
+ gtk_dialog_add_buttons (dialog,
+ GTK_STOCK_ADD, GTK_RESPONSE_OK,
+ GTK_STOCK_EDIT, GTK_RESPONSE_APPLY,
+ GTK_STOCK_REMOVE, GTK_RESPONSE_REJECT,
+ NULL);
+
+ priv->select_button = gtk_dialog_add_button (dialog, _("Select"),
+ GTK_RESPONSE_CLOSE);
+
+ fill_store (self);
+
+ g_signal_connect (priv->treeview, "cursor-changed",
+ G_CALLBACK (treeview_changed_cb), self);
+
+ g_signal_connect (self, "response",
+ G_CALLBACK (dialog_response_cb), self);
+ g_signal_connect (self, "destroy",
+ G_CALLBACK (dialog_destroy_cb), self);
+
+ /* Request a side ensuring to display at least some networks */
+ gtk_widget_set_size_request (GTK_WIDGET (self), -1, 300);
+
+ gtk_window_set_modal (GTK_WINDOW (self), TRUE);
+}
+
+static void
+empathy_irc_network_chooser_dialog_dispose (GObject *object)
+{
+ EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+ tp_clear_object (&priv->settings);
+ tp_clear_object (&priv->network);
+ tp_clear_object (&priv->network_manager);
+ tp_clear_object (&priv->store);
+ tp_clear_object (&priv->filter);
+
+ if (G_OBJECT_CLASS (empathy_irc_network_chooser_dialog_parent_class)->dispose)
+ G_OBJECT_CLASS (empathy_irc_network_chooser_dialog_parent_class)->dispose (object);
+}
+
+static void
+empathy_irc_network_chooser_dialog_class_init (EmpathyIrcNetworkChooserDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = empathy_irc_network_chooser_dialog_get_property;
+ object_class->set_property = empathy_irc_network_chooser_dialog_set_property;
+ object_class->constructed = empathy_irc_network_chooser_dialog_constructed;
+ object_class->dispose = empathy_irc_network_chooser_dialog_dispose;
+
+ g_object_class_install_property (object_class, PROP_SETTINGS,
+ g_param_spec_object ("settings",
+ "Settings",
+ "The EmpathyAccountSettings to show and edit",
+ EMPATHY_TYPE_ACCOUNT_SETTINGS,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class, PROP_NETWORK,
+ g_param_spec_object ("network",
+ "Network",
+ "The EmpathyIrcNetwork selected in the treeview",
+ EMPATHY_TYPE_IRC_NETWORK,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_type_class_add_private (object_class,
+ sizeof (EmpathyIrcNetworkChooserDialogPriv));
+}
+
+static void
+empathy_irc_network_chooser_dialog_init (EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialogPriv);
+ self->priv = priv;
+
+ priv->network_manager = empathy_irc_network_manager_dup_default ();
+}
+
+GtkWidget *
+empathy_irc_network_chooser_dialog_new (EmpathyAccountSettings *settings,
+ EmpathyIrcNetwork *network,
+ GtkWindow *parent)
+{
+ return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG,
+ "settings", settings,
+ "network", network,
+ "transient-for", parent,
+ NULL);
+}
+
+EmpathyIrcNetwork *
+empathy_irc_network_chooser_dialog_get_network (
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+ return priv->network;
+}
+
+gboolean
+empathy_irc_network_chooser_dialog_get_changed (
+ EmpathyIrcNetworkChooserDialog *self)
+{
+ EmpathyIrcNetworkChooserDialogPriv *priv = GET_PRIV (self);
+
+ return priv->changed;
+}
diff --git a/libempathy-gtk/empathy-irc-network-chooser-dialog.h b/libempathy-gtk/empathy-irc-network-chooser-dialog.h
new file mode 100644
index 000000000..0d4f24e7f
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser-dialog.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * 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_CHOOSER_DIALOG_H__
+#define __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-account-settings.h>
+#include <libempathy/empathy-irc-network.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG (empathy_irc_network_chooser_dialog_get_type ())
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialog))
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, EmpathyIrcNetworkChooserDialogClass))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG))
+#define EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_GET_CLASS(o) ( \
+ G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK_CHOOSER_DIALOG, \
+ EmpathyIrcNetworkChooserDialogClass))
+
+typedef struct {
+ GtkDialog parent;
+
+ /*<private>*/
+ gpointer priv;
+} EmpathyIrcNetworkChooserDialog;
+
+typedef struct {
+ GtkDialogClass parent_class;
+} EmpathyIrcNetworkChooserDialogClass;
+
+GType empathy_irc_network_chooser_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget * empathy_irc_network_chooser_dialog_new (
+ EmpathyAccountSettings *settings,
+ EmpathyIrcNetwork *network,
+ GtkWindow *parent);
+
+EmpathyIrcNetwork * empathy_irc_network_chooser_dialog_get_network (
+ EmpathyIrcNetworkChooserDialog *self);
+
+gboolean empathy_irc_network_chooser_dialog_get_changed (
+ EmpathyIrcNetworkChooserDialog *self);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_CHOOSER_DIALOG_H__ */
diff --git a/libempathy-gtk/empathy-irc-network-chooser.c b/libempathy-gtk/empathy-irc-network-chooser.c
new file mode 100644
index 000000000..55a90fd0c
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * 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-lib.h>
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-irc-network-manager.h>
+
+#include "empathy-irc-network-dialog.h"
+#include "empathy-ui-utils.h"
+#include "empathy-irc-network-chooser-dialog.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
+#include <libempathy/empathy-debug.h>
+
+#include "empathy-irc-network-chooser.h"
+
+#define DEFAULT_IRC_NETWORK "irc.gimp.org"
+
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooser)
+
+enum {
+ PROP_SETTINGS = 1
+};
+
+enum {
+ SIG_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct {
+ EmpathyAccountSettings *settings;
+
+ EmpathyIrcNetworkManager *network_manager;
+ GtkWidget *dialog;
+ /* Displayed network */
+ EmpathyIrcNetwork *network;
+} EmpathyIrcNetworkChooserPriv;
+
+G_DEFINE_TYPE (EmpathyIrcNetworkChooser, empathy_irc_network_chooser,
+ GTK_TYPE_BUTTON);
+
+static void
+empathy_irc_network_chooser_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ priv->settings = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_irc_network_chooser_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+unset_server_params (EmpathyIrcNetworkChooser *self)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+ DEBUG ("Unset server, port and use-ssl");
+ empathy_account_settings_unset (priv->settings, "server");
+ empathy_account_settings_unset (priv->settings, "port");
+ empathy_account_settings_unset (priv->settings, "use-ssl");
+}
+
+static void
+update_server_params (EmpathyIrcNetworkChooser *self)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+ GSList *servers;
+ const gchar *charset;
+
+ g_assert (priv->network != NULL);
+
+ charset = empathy_irc_network_get_charset (priv->network);
+ DEBUG ("Setting charset to %s", charset);
+ empathy_account_settings_set_string (priv->settings, "charset", charset);
+
+ servers = empathy_irc_network_get_servers (priv->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);
+
+ DEBUG ("Setting server to %s", address);
+ empathy_account_settings_set_string (priv->settings, "server", address);
+ DEBUG ("Setting port to %u", port);
+ empathy_account_settings_set_uint32 (priv->settings, "port", port);
+ DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
+ empathy_account_settings_set_boolean (priv->settings, "use-ssl", ssl);
+
+ g_free (address);
+ }
+ else
+ {
+ /* No server. Unset values */
+ unset_server_params (self);
+ }
+
+ g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
+ g_slist_free (servers);
+}
+
+static void
+set_label (EmpathyIrcNetworkChooser *self)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+ g_assert (priv->network != NULL);
+
+ gtk_button_set_label (GTK_BUTTON (self),
+ empathy_irc_network_get_name (priv->network));
+}
+
+static void
+set_label_from_settings (EmpathyIrcNetworkChooser *self)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+ const gchar *server;
+
+ tp_clear_object (&priv->network);
+
+ server = empathy_account_settings_get_string (priv->settings, "server");
+
+ if (server != NULL)
+ {
+ EmpathyIrcServer *srv;
+ gint port;
+ gboolean ssl;
+
+ priv->network = empathy_irc_network_manager_find_network_by_address (
+ priv->network_manager, server);
+
+ if (priv->network != NULL)
+ {
+ /* The network is known */
+ g_object_ref (priv->network);
+ set_label (self);
+ return;
+ }
+
+ /* We don't have this network. Let's create it */
+ port = empathy_account_settings_get_uint32 (priv->settings, "port");
+ ssl = empathy_account_settings_get_boolean (priv->settings,
+ "use-ssl");
+
+ DEBUG ("Create a network %s", server);
+ priv->network = empathy_irc_network_new (server);
+ srv = empathy_irc_server_new (server, port, ssl);
+
+ empathy_irc_network_append_server (priv->network, srv);
+ empathy_irc_network_manager_add (priv->network_manager, priv->network);
+
+ set_label (self);
+
+ g_object_unref (srv);
+ return;
+ }
+
+ /* Set default network */
+ priv->network = empathy_irc_network_manager_find_network_by_address (
+ priv->network_manager, DEFAULT_IRC_NETWORK);
+ g_assert (priv->network != NULL);
+
+ set_label (self);
+ update_server_params (self);
+ g_object_ref (priv->network);
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+ gint response,
+ EmpathyIrcNetworkChooser *self)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+ EmpathyIrcNetworkChooserDialog *chooser =
+ EMPATHY_IRC_NETWORK_CHOOSER_DIALOG (priv->dialog);
+
+ if (response != GTK_RESPONSE_CLOSE &&
+ response != GTK_RESPONSE_DELETE_EVENT)
+ return;
+
+ if (empathy_irc_network_chooser_dialog_get_changed (chooser))
+ {
+ tp_clear_object (&priv->network);
+
+ priv->network = g_object_ref (
+ empathy_irc_network_chooser_dialog_get_network (chooser));
+
+ update_server_params (self);
+ set_label (self);
+
+ g_signal_emit (self, signals[SIG_CHANGED], 0);
+ }
+
+ gtk_widget_destroy (priv->dialog);
+ priv->dialog = NULL;
+}
+
+static void
+clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (button);
+ GtkWindow *window;
+
+ if (priv->dialog != NULL)
+ goto out;
+
+ window = empathy_get_toplevel_window (GTK_WIDGET (button));
+
+ priv->dialog = empathy_irc_network_chooser_dialog_new (priv->settings,
+ priv->network, window);
+ gtk_widget_show_all (priv->dialog);
+
+ tp_g_signal_connect_object (priv->dialog, "response",
+ G_CALLBACK (dialog_response_cb), button, 0);
+
+out:
+ empathy_window_present (GTK_WINDOW (priv->dialog));
+}
+
+static void
+empathy_irc_network_chooser_constructed (GObject *object)
+{
+ EmpathyIrcNetworkChooser *self = (EmpathyIrcNetworkChooser *) object;
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+ g_assert (priv->settings != NULL);
+
+ set_label_from_settings (self);
+
+ g_signal_connect (self, "clicked", G_CALLBACK (clicked_cb), self);
+}
+
+static void
+empathy_irc_network_chooser_dispose (GObject *object)
+{
+ EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
+ EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
+
+ tp_clear_object (&priv->settings);
+ tp_clear_object (&priv->network_manager);
+ tp_clear_object (&priv->network);
+
+ if (G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose)
+ G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose (object);
+}
+
+static void
+empathy_irc_network_chooser_class_init (EmpathyIrcNetworkChooserClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->get_property = empathy_irc_network_chooser_get_property;
+ object_class->set_property = empathy_irc_network_chooser_set_property;
+ object_class->constructed = empathy_irc_network_chooser_constructed;
+ object_class->dispose = empathy_irc_network_chooser_dispose;
+
+ g_object_class_install_property (object_class, PROP_SETTINGS,
+ g_param_spec_object ("settings",
+ "Settings",
+ "The EmpathyAccountSettings to show and edit",
+ EMPATHY_TYPE_ACCOUNT_SETTINGS,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ signals[SIG_CHANGED] = g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private (object_class,
+ sizeof (EmpathyIrcNetworkChooserPriv));
+}
+
+static void
+empathy_irc_network_chooser_init (EmpathyIrcNetworkChooser *self)
+{
+ EmpathyIrcNetworkChooserPriv *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooserPriv);
+ self->priv = priv;
+
+ priv->network_manager = empathy_irc_network_manager_dup_default ();
+}
+
+GtkWidget *
+empathy_irc_network_chooser_new (EmpathyAccountSettings *settings)
+{
+ return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER,
+ "settings", settings,
+ NULL);
+}
diff --git a/libempathy-gtk/empathy-irc-network-chooser.h b/libempathy-gtk/empathy-irc-network-chooser.h
new file mode 100644
index 000000000..442ac2d53
--- /dev/null
+++ b/libempathy-gtk/empathy-irc-network-chooser.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2008 Guillaume Desmottes
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * 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_CHOOSER_H__
+#define __EMPATHY_IRC_NETWORK_CHOOSER_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy/empathy-account-settings.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_IRC_NETWORK_CHOOSER (empathy_irc_network_chooser_get_type ())
+#define EMPATHY_IRC_NETWORK_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooser))
+#define EMPATHY_IRC_NETWORK_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooserClass))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER))
+#define EMPATHY_IS_IRC_NETWORK_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+ EMPATHY_TYPE_IRC_NETWORK_CHOOSER))
+#define EMPATHY_IRC_NETWORK_CHOOSER_GET_CLASS(o) ( \
+ G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_IRC_NETWORK_CHOOSER, \
+ EmpathyIrcNetworkChooserClass))
+
+typedef struct {
+ GtkButton parent;
+
+ /*<private>*/
+ gpointer priv;
+} EmpathyIrcNetworkChooser;
+
+typedef struct {
+ GtkButtonClass parent_class;
+} EmpathyIrcNetworkChooserClass;
+
+GType empathy_irc_network_chooser_get_type (void) G_GNUC_CONST;
+
+GtkWidget * empathy_irc_network_chooser_new (EmpathyAccountSettings *settings);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_IRC_NETWORK_CHOOSER_H__ */
diff --git a/libempathy/empathy-irc-network-manager.c b/libempathy/empathy-irc-network-manager.c
index 97d19a0eb..5e0530938 100644
--- a/libempathy/empathy-irc-network-manager.c
+++ b/libempathy/empathy-irc-network-manager.c
@@ -32,6 +32,7 @@
#include "empathy-debug.h"
#define IRC_NETWORKS_DTD_FILENAME "empathy-irc-networks.dtd"
+#define IRC_NETWORKS_FILENAME "irc-networks.xml"
#define SAVE_TIMER 4
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkManager)
@@ -781,3 +782,36 @@ empathy_irc_network_manager_find_network_by_address (
return network;
}
+
+EmpathyIrcNetworkManager *
+empathy_irc_network_manager_dup_default (void)
+{
+ static EmpathyIrcNetworkManager *default_mgr = NULL;
+ gchar *dir, *user_file_with_path, *global_file_with_path;
+
+ if (default_mgr != NULL)
+ return g_object_ref (default_mgr);
+
+ dir = g_build_filename (g_get_user_config_dir (), 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 (g_getenv ("EMPATHY_SRCDIR"),
+ "libempathy", 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);
+ }
+
+ default_mgr = empathy_irc_network_manager_new (
+ global_file_with_path, user_file_with_path);
+
+ g_object_add_weak_pointer (G_OBJECT (default_mgr), (gpointer *) &default_mgr);
+
+ g_free (global_file_with_path);
+ g_free (user_file_with_path);
+ return default_mgr;
+}
diff --git a/libempathy/empathy-irc-network-manager.h b/libempathy/empathy-irc-network-manager.h
index a050f4723..11c84836f 100644
--- a/libempathy/empathy-irc-network-manager.h
+++ b/libempathy/empathy-irc-network-manager.h
@@ -63,6 +63,8 @@ GType empathy_irc_network_manager_get_type (void);
EmpathyIrcNetworkManager * empathy_irc_network_manager_new (
const gchar *global_file, const gchar *user_file);
+EmpathyIrcNetworkManager * empathy_irc_network_manager_dup_default (void);
+
void empathy_irc_network_manager_add (EmpathyIrcNetworkManager *manager,
EmpathyIrcNetwork *network);
diff --git a/libempathy/empathy-irc-network.c b/libempathy/empathy-irc-network.c
index 9b75f0e82..d5b0bdcb9 100644
--- a/libempathy/empathy-irc-network.c
+++ b/libempathy/empathy-irc-network.c
@@ -359,3 +359,19 @@ empathy_irc_network_set_server_position (EmpathyIrcNetwork *self,
g_signal_emit (self, signals[MODIFIED], 0);
}
+
+const gchar *
+empathy_irc_network_get_name (EmpathyIrcNetwork *self)
+{
+ EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
+
+ return priv->name;
+}
+
+const gchar *
+empathy_irc_network_get_charset (EmpathyIrcNetwork *self)
+{
+ EmpathyIrcNetworkPriv *priv = GET_PRIV (self);
+
+ return priv->charset;
+}
diff --git a/libempathy/empathy-irc-network.h b/libempathy/empathy-irc-network.h
index b10b2769e..9d78f3c3f 100644
--- a/libempathy/empathy-irc-network.h
+++ b/libempathy/empathy-irc-network.h
@@ -75,6 +75,10 @@ void empathy_irc_network_remove_server (EmpathyIrcNetwork *network,
void empathy_irc_network_set_server_position (EmpathyIrcNetwork *network,
EmpathyIrcServer *server, gint pos);
+const gchar * empathy_irc_network_get_name (EmpathyIrcNetwork *network);
+
+const gchar * empathy_irc_network_get_charset (EmpathyIrcNetwork *network);
+
G_END_DECLS
#endif /* __EMPATHY_IRC_NETWORK_H__ */