diff options
23 files changed, 2560 insertions, 1850 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index 7f93accd3..70e11e412 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -70,6 +70,7 @@ libempathy_gtk_la_SOURCES = \ # do not distribute generated files nodist_libempathy_gtk_la_SOURCES =\ + empathy-account-widget-private.h \ $(BUILT_SOURCES) libempathy_gtk_la_LIBADD = \ @@ -145,7 +146,7 @@ ui_DATA = \ empathy-account-widget-jabber.ui \ empathy-account-widget-msn.ui \ empathy-account-widget-sip.ui \ - empathy-account-widget-salut.ui \ + empathy-account-widget-local-xmpp.ui \ empathy-account-widget-irc.ui \ empathy-account-widget-icq.ui \ empathy-account-widget-yahoo.ui \ diff --git a/libempathy-gtk/empathy-account-widget-irc.c b/libempathy-gtk/empathy-account-widget-irc.c index c04f3463d..932e2f81d 100644 --- a/libempathy-gtk/empathy-account-widget-irc.c +++ b/libempathy-gtk/empathy-account-widget-irc.c @@ -32,6 +32,7 @@ #include "empathy-irc-network-dialog.h" #include "empathy-account-widget.h" +#include "empathy-account-widget-private.h" #include "empathy-account-widget-irc.h" #include "empathy-ui-utils.h" @@ -41,7 +42,7 @@ #define IRC_NETWORKS_FILENAME "irc-networks.xml" typedef struct { - EmpathyAccountSettings *settings; + EmpathyAccountWidget *self; EmpathyIrcNetworkManager *network_manager; GtkWidget *vbox_settings; @@ -59,17 +60,19 @@ account_widget_irc_destroy_cb (GtkWidget *widget, EmpathyAccountWidgetIrc *settings) { g_object_unref (settings->network_manager); - g_object_unref (settings->settings); 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 (settings->settings, "server"); - empathy_account_settings_unset (settings->settings, "port"); - empathy_account_settings_unset (settings->settings, "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 @@ -80,6 +83,9 @@ update_server_params (EmpathyAccountWidgetIrc *settings) 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)) @@ -95,7 +101,7 @@ update_server_params (EmpathyAccountWidgetIrc *settings) g_object_get (network, "charset", &charset, NULL); DEBUG ("Setting charset to %s", charset); - empathy_account_settings_set_string (settings->settings, "charset", charset); + empathy_account_settings_set_string (ac_settings, "charset", charset); g_free (charset); servers = empathy_irc_network_get_servers (network); @@ -114,13 +120,11 @@ update_server_params (EmpathyAccountWidgetIrc *settings) NULL); DEBUG ("Setting server to %s", address); - empathy_account_settings_set_string (settings->settings, - "server", address); + empathy_account_settings_set_string (ac_settings, "server", address); DEBUG ("Setting port to %u", port); - empathy_account_settings_set_uint32 (settings->settings, "port", port); + empathy_account_settings_set_uint32 (ac_settings, "port", port); DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" ); - empathy_account_settings_set_boolean (settings->settings, - "use-ssl", ssl); + empathy_account_settings_set_boolean (ac_settings, "use-ssl", ssl); g_free (address); } @@ -330,19 +334,22 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings) const gchar *charset; gboolean ssl = FALSE; EmpathyIrcNetwork *network = NULL; + EmpathyAccountSettings *ac_settings; - nick = empathy_account_settings_get_string (settings->settings, "account"); - fullname = empathy_account_settings_get_string (settings->settings, + g_object_get (settings->self, "settings", &ac_settings, NULL); + + nick = empathy_account_settings_get_string (ac_settings, "account"); + fullname = empathy_account_settings_get_string (ac_settings, "fullname"); - server = empathy_account_settings_get_string (settings->settings, "server"); - charset = empathy_account_settings_get_string (settings->settings, "charset"); - port = empathy_account_settings_get_uint32 (settings->settings, "port"); - ssl = empathy_account_settings_get_boolean (settings->settings, "use-ssl"); + 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"); if (!nick) { nick = g_strdup (g_get_user_name ()); - empathy_account_settings_set_string (settings->settings, + empathy_account_settings_set_string (ac_settings, "account", nick); } @@ -353,7 +360,7 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings) { fullname = g_strdup (nick); } - empathy_account_settings_set_string (settings->settings, + empathy_account_settings_set_string (ac_settings, "fullname", fullname); } @@ -409,27 +416,17 @@ account_widget_irc_setup (EmpathyAccountWidgetIrc *settings) fill_networks_model (settings, network); } -/** - * empathy_account_widget_irc_new: - * @settings: the #EmpathyAccountSettings to configure - * - * Creates a new IRC account widget to configure a given #EmpathyAccount - * - * Returns: The toplevel container of the configuration widget - */ -GtkWidget * -empathy_account_widget_irc_new (EmpathyAccountSettings *account_settings) +void +empathy_account_widget_irc_build (EmpathyAccountWidget *self, + const char *filename) { EmpathyAccountWidgetIrc *settings; gchar *dir, *user_file_with_path, *global_file_with_path; - GtkBuilder *gui; - GtkWidget *widget; GtkListStore *store; GtkCellRenderer *renderer; - gchar *filename; settings = g_slice_new0 (EmpathyAccountWidgetIrc); - settings->settings = g_object_ref (account_settings); + 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); @@ -452,14 +449,11 @@ empathy_account_widget_irc_new (EmpathyAccountSettings *account_settings) g_free (global_file_with_path); g_free (user_file_with_path); - filename = empathy_file_lookup ("empathy-account-widget-irc.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_irc", &widget, + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_irc", &self->ui_details->widget, "table_irc_settings", &settings->vbox_settings, "combobox_network", &settings->combobox_network, NULL); - g_free (filename); /* Fill the networks combobox */ store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING); @@ -483,14 +477,14 @@ empathy_account_widget_irc_new (EmpathyAccountSettings *account_settings) account_widget_irc_setup (settings); - empathy_account_widget_handle_params (account_settings, gui, + empathy_account_widget_handle_params (self, "entry_nick", "account", "entry_fullname", "fullname", "entry_password", "password", "entry_quit_message", "quit-message", NULL); - empathy_builder_connect (gui, settings, + 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, @@ -502,8 +496,5 @@ empathy_account_widget_irc_new (EmpathyAccountSettings *account_settings) account_widget_irc_combobox_network_changed_cb, NULL); - empathy_account_widget_set_default_focus (gui, "entry_nick"); - empathy_account_widget_add_apply_button (account_settings, widget); - - return empathy_builder_unref_and_keep_widget (gui, widget); + self->ui_details->default_focus = g_strdup ("entry_nick"); } diff --git a/libempathy-gtk/empathy-account-widget-irc.h b/libempathy-gtk/empathy-account-widget-irc.h index 0373238ed..a76787120 100644 --- a/libempathy-gtk/empathy-account-widget-irc.h +++ b/libempathy-gtk/empathy-account-widget-irc.h @@ -22,11 +22,12 @@ #define __EMPATHY_ACCOUNT_WIDGET_IRC_H__ #include <gtk/gtk.h> -#include <libempathy/empathy-account-settings.h> +#include <libempathy-gtk/empathy-account-widget.h> G_BEGIN_DECLS -GtkWidget * empathy_account_widget_irc_new (EmpathyAccountSettings *settings); +void empathy_account_widget_irc_build (EmpathyAccountWidget *self, + const char *filename); G_END_DECLS diff --git a/libempathy-gtk/empathy-account-widget-salut.ui b/libempathy-gtk/empathy-account-widget-local-xmpp.ui index ca633309d..ca633309d 100644 --- a/libempathy-gtk/empathy-account-widget-salut.ui +++ b/libempathy-gtk/empathy-account-widget-local-xmpp.ui diff --git a/libempathy-gtk/empathy-account-widget-private.h b/libempathy-gtk/empathy-account-widget-private.h new file mode 100644 index 000000000..aaa24e58f --- /dev/null +++ b/libempathy-gtk/empathy-account-widget-private.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> + */ + +#ifndef __EMPATHY_ACCOUNT_WIDGET_PRIVATE_H__ +#define __EMPATHY_ACCOUNT_WIDGET_PRIVATE_H__ + +#include <libempathy-gtk/empathy-account-widget.h> +#include <glib.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +struct _EmpathyAccountWidgetUIDetails { + GtkWidget *widget; + + GtkBuilder *gui; + + char *default_focus; + gboolean add_forget; +}; + + +void empathy_account_widget_handle_params (EmpathyAccountWidget *self, + const gchar *first_widget, + ...); + +G_END_DECLS + +#endif /* __EMPATHY_ACCOUNT_WIDGET_PRIVATE_H__ */
\ No newline at end of file diff --git a/libempathy-gtk/empathy-account-widget-sip.c b/libempathy-gtk/empathy-account-widget-sip.c index 9f08046b7..fedbf2aa6 100644 --- a/libempathy-gtk/empathy-account-widget-sip.c +++ b/libempathy-gtk/empathy-account-widget-sip.c @@ -31,12 +31,12 @@ #include <libempathy/empathy-utils.h> #include "empathy-account-widget.h" +#include "empathy-account-widget-private.h" #include "empathy-account-widget-sip.h" #include "empathy-ui-utils.h" typedef struct { - EmpathyAccountSettings *settings; - + EmpathyAccountWidget *self; GtkWidget *vbox_settings; GtkWidget *entry_stun_server; @@ -48,7 +48,6 @@ static void account_widget_sip_destroy_cb (GtkWidget *widget, EmpathyAccountWidgetSip *settings) { - g_object_unref (settings->settings); g_slice_free (EmpathyAccountWidgetSip, settings); } @@ -64,35 +63,23 @@ account_widget_sip_discover_stun_toggled_cb ( gtk_widget_set_sensitive (settings->spinbutton_stun_part, !active); } -/** - * empathy_account_widget_sip_new: - * @account: the #EmpathyAccount to configure - * - * Creates a new SIP account widget to configure a given #EmpathyAccount - * - * Returns: The toplevel container of the configuration widget - */ -GtkWidget * -empathy_account_widget_sip_new (EmpathyAccountSettings *account_settings) +void +empathy_account_widget_sip_build (EmpathyAccountWidget *self, + const char *filename) { EmpathyAccountWidgetSip *settings; - GtkBuilder *gui; - gchar *filename; settings = g_slice_new0 (EmpathyAccountWidgetSip); - settings->settings = g_object_ref (account_settings); + settings->self = self; - filename = empathy_file_lookup ("empathy-account-widget-sip.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, + self->ui_details->gui = empathy_builder_get_file (filename, "vbox_sip_settings", &settings->vbox_settings, "entry_stun-server", &settings->entry_stun_server, "spinbutton_stun-port", &settings->spinbutton_stun_part, "checkbutton_discover-stun", &settings->checkbutton_discover_stun, NULL); - g_free (filename); - empathy_account_widget_handle_params (account_settings, gui, + empathy_account_widget_handle_params (self, "entry_userid", "account", "entry_password", "password", "checkbutton_discover-stun", "discover-stun", @@ -100,23 +87,18 @@ empathy_account_widget_sip_new (EmpathyAccountSettings *account_settings) "spinbutton_stun-port", "stun-port", NULL); - empathy_account_widget_add_forget_button (account_settings, gui, - "button_forget", - "entry_password"); - account_widget_sip_discover_stun_toggled_cb ( settings->checkbutton_discover_stun, settings); - empathy_builder_connect (gui, settings, + empathy_builder_connect (self->ui_details->gui, settings, "vbox_sip_settings", "destroy", account_widget_sip_destroy_cb, "checkbutton_discover-stun", "toggled", account_widget_sip_discover_stun_toggled_cb, NULL); - empathy_account_widget_set_default_focus (gui, "entry_userid"); - empathy_account_widget_add_apply_button (account_settings, - settings->vbox_settings); + self->ui_details->add_forget = TRUE; + self->ui_details->default_focus = g_strdup ("entry_userid"); - return empathy_builder_unref_and_keep_widget (gui, settings->vbox_settings); + self->ui_details->widget = settings->vbox_settings; } diff --git a/libempathy-gtk/empathy-account-widget-sip.h b/libempathy-gtk/empathy-account-widget-sip.h index 15dd7244a..435ad6ea1 100644 --- a/libempathy-gtk/empathy-account-widget-sip.h +++ b/libempathy-gtk/empathy-account-widget-sip.h @@ -22,11 +22,12 @@ #define __EMPATHY_ACCOUNT_WIDGET_SIP_H__ #include <gtk/gtk.h> -#include <libempathy/empathy-account-settings.h> +#include <libempathy-gtk/empathy-account-widget.h> G_BEGIN_DECLS -GtkWidget * empathy_account_widget_sip_new (EmpathyAccountSettings *settings); +void empathy_account_widget_sip_build (EmpathyAccountWidget *self, + const char *filename); G_END_DECLS diff --git a/libempathy-gtk/empathy-account-widget.c b/libempathy-gtk/empathy-account-widget.c index 391125a5f..6d5b2b279 100644 --- a/libempathy-gtk/empathy-account-widget.c +++ b/libempathy-gtk/empathy-account-widget.c @@ -1,7 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 Collabora Ltd. + * Copyright (C) 2007-2009 Collabora Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,6 +20,7 @@ * * Authors: Xavier Claessens <xclaesse@gmail.com> * Martyn Russell <martyn@imendio.com> + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> */ #include <config.h> @@ -33,760 +34,922 @@ #include <libempathy/empathy-account.h> #include <telepathy-glib/connection-manager.h> +#include <telepathy-glib/util.h> #include <dbus/dbus-protocol.h> #include "empathy-account-widget.h" +#include "empathy-account-widget-private.h" +#include "empathy-account-widget-sip.h" +#include "empathy-account-widget-irc.h" #include "empathy-ui-utils.h" #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT #include <libempathy/empathy-debug.h> -static gboolean -account_widget_entry_focus_cb (GtkWidget *widget, - GdkEventFocus *event, - EmpathyAccountSettings *settings) -{ - const gchar *str; - const gchar *param_name; +G_DEFINE_TYPE (EmpathyAccountWidget, empathy_account_widget, G_TYPE_OBJECT) + +typedef struct { + char *protocol; + EmpathyAccountSettings *settings; + + GtkWidget *apply_button; + GtkWidget *entry_password; + GtkWidget *button_forget; + GtkWidget *spinbutton_port; + + gboolean dispose_run; +} EmpathyAccountWidgetPriv; + +enum { + PROP_PROTOCOL = 1, + PROP_SETTINGS +}; - str = gtk_entry_get_text (GTK_ENTRY (widget)); - param_name = g_object_get_data (G_OBJECT (widget), "param_name"); +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountWidget) - if (EMP_STR_EMPTY (str)) { - const gchar *value = NULL; +static void +account_widget_handle_apply_sensitivity (EmpathyAccountWidget *self) +{ + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); - empathy_account_settings_unset (settings, param_name); - value = empathy_account_settings_get_string (settings, param_name); - DEBUG ("Unset %s and restore to %s", param_name, value); - gtk_entry_set_text (GTK_ENTRY (widget), value ? value : ""); - } else { - DEBUG ("Setting %s to %s", param_name, - strstr (param_name, "password") ? "***" : str); - empathy_account_settings_set_string (settings, param_name, str); - } + gtk_widget_set_sensitive (priv->apply_button, + empathy_account_settings_is_valid (priv->settings)); +} - return FALSE; +static gboolean +account_widget_entry_focus_cb (GtkWidget *widget, + GdkEventFocus *event, + EmpathyAccountWidget *self) +{ + const gchar *str; + const gchar *param_name; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + str = gtk_entry_get_text (GTK_ENTRY (widget)); + param_name = g_object_get_data (G_OBJECT (widget), "param_name"); + + if (EMP_STR_EMPTY (str)) + { + const gchar *value = NULL; + + empathy_account_settings_unset (priv->settings, param_name); + value = empathy_account_settings_get_string (priv->settings, param_name); + DEBUG ("Unset %s and restore to %s", param_name, value); + gtk_entry_set_text (GTK_ENTRY (widget), value ? value : ""); + } + else + { + DEBUG ("Setting %s to %s", param_name, + strstr (param_name, "password") ? "***" : str); + empathy_account_settings_set_string (priv->settings, param_name, str); + } + + account_widget_handle_apply_sensitivity (self); + + return FALSE; } static void account_widget_int_changed_cb (GtkWidget *widget, - EmpathyAccountSettings *settings) -{ - const gchar *param_name; - gint value; - const gchar *signature; - - value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget)); - param_name = g_object_get_data (G_OBJECT (widget), "param_name"); - - signature = empathy_settings_get_dbus_signature (settings, param_name); - g_return_if_fail (signature != NULL); - - DEBUG ("Setting %s to %d", param_name, value); - - switch ((int)*signature) - { - case DBUS_TYPE_INT16: - case DBUS_TYPE_INT32: - empathy_account_settings_set_int32 (settings, param_name, value); - break; - case DBUS_TYPE_INT64: - empathy_account_settings_set_int64 (settings, param_name, value); - break; - case DBUS_TYPE_UINT16: - case DBUS_TYPE_UINT32: - empathy_account_settings_set_uint32 (settings, param_name, value); - break; - case DBUS_TYPE_UINT64: - empathy_account_settings_set_uint64 (settings, param_name, value); - break; - default: - g_return_if_reached (); - } + EmpathyAccountWidget *self) +{ + const gchar *param_name; + gint value; + const gchar *signature; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget)); + param_name = g_object_get_data (G_OBJECT (widget), "param_name"); + + signature = empathy_settings_get_dbus_signature (priv->settings, param_name); + g_return_if_fail (signature != NULL); + + DEBUG ("Setting %s to %d", param_name, value); + + switch ((int)*signature) + { + case DBUS_TYPE_INT16: + case DBUS_TYPE_INT32: + empathy_account_settings_set_int32 (priv->settings, param_name, value); + break; + case DBUS_TYPE_INT64: + empathy_account_settings_set_int64 (priv->settings, param_name, value); + break; + case DBUS_TYPE_UINT16: + case DBUS_TYPE_UINT32: + empathy_account_settings_set_uint32 (priv->settings, param_name, value); + break; + case DBUS_TYPE_UINT64: + empathy_account_settings_set_uint64 (priv->settings, param_name, value); + break; + default: + g_return_if_reached (); + } + + account_widget_handle_apply_sensitivity (self); } static void account_widget_checkbutton_toggled_cb (GtkWidget *widget, - EmpathyAccountSettings *settings) + EmpathyAccountWidget *self) { - gboolean value; - gboolean default_value; - const gchar *param_name; - - value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - param_name = g_object_get_data (G_OBJECT (widget), "param_name"); - - /* FIXME: This is ugly! checkbox don't have a "not-set" value so we - * always unset the param and set the value if different from the - * default value. */ - empathy_account_settings_unset (settings, param_name); - default_value = empathy_account_settings_get_boolean (settings, param_name); - - if (default_value == value) { - DEBUG ("Unset %s and restore to %d", param_name, default_value); - } else { - DEBUG ("Setting %s to %d", param_name, value); - empathy_account_settings_set_boolean (settings, param_name, value); - } + gboolean value; + gboolean default_value; + const gchar *param_name; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + param_name = g_object_get_data (G_OBJECT (widget), "param_name"); + + /* FIXME: This is ugly! checkbox don't have a "not-set" value so we + * always unset the param and set the value if different from the + * default value. */ + empathy_account_settings_unset (priv->settings, param_name); + default_value = empathy_account_settings_get_boolean (priv->settings, param_name); + + if (default_value == value) + { + DEBUG ("Unset %s and restore to %d", param_name, default_value); + } + else + { + DEBUG ("Setting %s to %d", param_name, value); + empathy_account_settings_set_boolean (priv->settings, param_name, value); + } + + account_widget_handle_apply_sensitivity (self); } static void account_widget_forget_clicked_cb (GtkWidget *button, - GtkWidget *entry) + EmpathyAccountWidget *self) { - EmpathyAccountSettings *settings; - const gchar *param_name; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + const gchar *param_name; - param_name = g_object_get_data (G_OBJECT (entry), "param_name"); - settings = g_object_get_data (G_OBJECT (entry), "settings"); + param_name = g_object_get_data (G_OBJECT (priv->entry_password), "param_name"); - DEBUG ("Unset %s", param_name); - empathy_account_settings_unset (settings, param_name); - gtk_entry_set_text (GTK_ENTRY (entry), ""); + DEBUG ("Unset %s", param_name); + empathy_account_settings_unset (priv->settings, param_name); + gtk_entry_set_text (GTK_ENTRY (priv->entry_password), ""); + + account_widget_handle_apply_sensitivity (self); } static void account_widget_password_changed_cb (GtkWidget *entry, - GtkWidget *button) + EmpathyAccountWidget *self) { - const gchar *str; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + const gchar *str; - str = gtk_entry_get_text (GTK_ENTRY (entry)); - gtk_widget_set_sensitive (button, !EMP_STR_EMPTY (str)); + str = gtk_entry_get_text (GTK_ENTRY (entry)); + gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (str)); } static void account_widget_jabber_ssl_toggled_cb (GtkWidget *checkbutton_ssl, - GtkWidget *spinbutton_port) + EmpathyAccountWidget *self) { - EmpathyAccountSettings *settings; - gboolean value; - gint32 port = 0; - - value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl)); - settings = g_object_get_data (G_OBJECT (spinbutton_port), "settings"); - port = empathy_account_settings_get_uint32 (settings, "port"); - - if (value) { - if (port == 5222 || port == 0) { - port = 5223; - } - } else { - if (port == 5223 || port == 0) { - port = 5222; - } - } - - gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton_port), port); + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + gboolean value; + gint32 port = 0; + + value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton_ssl)); + port = empathy_account_settings_get_uint32 (priv->settings, "port"); + + if (value) + { + if (port == 5222 || port == 0) + port = 5223; + } + else + { + if (port == 5223 || port == 0) + port = 5222; + } + + gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->spinbutton_port), port); } static void -account_widget_setup_widget (GtkWidget *widget, - EmpathyAccountSettings *settings, - const gchar *param_name) -{ - g_object_set_data_full (G_OBJECT (widget), "param_name", - g_strdup (param_name), g_free); - g_object_set_data_full (G_OBJECT (widget), "settings", - g_object_ref (settings), g_object_unref); - - if (GTK_IS_SPIN_BUTTON (widget)) { - gint value = 0; - const gchar *signature; - - signature = empathy_settings_get_dbus_signature (settings, param_name); - g_return_if_fail (signature != NULL); - - switch ((int)*signature) - { - case DBUS_TYPE_INT16: - case DBUS_TYPE_INT32: - value = empathy_account_settings_get_int32 (settings, param_name); - break; - case DBUS_TYPE_INT64: - value = empathy_account_settings_get_int64 (settings, param_name); - break; - case DBUS_TYPE_UINT16: - case DBUS_TYPE_UINT32: - value = empathy_account_settings_get_uint32 (settings, param_name); - break; - case DBUS_TYPE_UINT64: - value = empathy_account_settings_get_uint64 (settings, param_name); - break; - default: - g_return_if_reached (); - } - - gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value); - - g_signal_connect (widget, "value-changed", - G_CALLBACK (account_widget_int_changed_cb), - settings); - } - else if (GTK_IS_ENTRY (widget)) { - const gchar *str = NULL; - - str = empathy_account_settings_get_string (settings, param_name); - gtk_entry_set_text (GTK_ENTRY (widget), str ? str : ""); - - if (strstr (param_name, "password")) { - gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE); - } - - g_signal_connect (widget, "focus-out-event", - G_CALLBACK (account_widget_entry_focus_cb), - settings); - } - else if (GTK_IS_TOGGLE_BUTTON (widget)) { - gboolean value = FALSE; - - value = empathy_account_settings_get_boolean (settings, param_name); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value); - - g_signal_connect (widget, "toggled", - G_CALLBACK (account_widget_checkbutton_toggled_cb), - settings); - } else { - DEBUG ("Unknown type of widget for param %s", param_name); - } +account_widget_setup_widget (EmpathyAccountWidget *self, + GtkWidget *widget, + const gchar *param_name) +{ + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + g_object_set_data_full (G_OBJECT (widget), "param_name", + g_strdup (param_name), g_free); + + if (GTK_IS_SPIN_BUTTON (widget)) + { + gint value = 0; + const gchar *signature; + + signature = empathy_settings_get_dbus_signature (priv->settings, param_name); + g_return_if_fail (signature != NULL); + + switch ((int)*signature) + { + case DBUS_TYPE_INT16: + case DBUS_TYPE_INT32: + value = empathy_account_settings_get_int32 (priv->settings, param_name); + break; + case DBUS_TYPE_INT64: + value = empathy_account_settings_get_int64 (priv->settings, param_name); + break; + case DBUS_TYPE_UINT16: + case DBUS_TYPE_UINT32: + value = empathy_account_settings_get_uint32 (priv->settings, param_name); + break; + case DBUS_TYPE_UINT64: + value = empathy_account_settings_get_uint64 (priv->settings, param_name); + break; + default: + g_return_if_reached (); + } + + gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value); + + g_signal_connect (widget, "value-changed", + G_CALLBACK (account_widget_int_changed_cb), + self); + } + else if (GTK_IS_ENTRY (widget)) + { + const gchar *str = NULL; + + str = empathy_account_settings_get_string (priv->settings, param_name); + gtk_entry_set_text (GTK_ENTRY (widget), str ? str : ""); + + if (strstr (param_name, "password")) + { + gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE); + } + + g_signal_connect (widget, "focus-out-event", + G_CALLBACK (account_widget_entry_focus_cb), + self); + } + else if (GTK_IS_TOGGLE_BUTTON (widget)) + { + gboolean value = FALSE; + + value = empathy_account_settings_get_boolean (priv->settings, param_name); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), value); + + g_signal_connect (widget, "toggled", + G_CALLBACK (account_widget_checkbutton_toggled_cb), + self); + } + else + { + DEBUG ("Unknown type of widget for param %s", param_name); + } } static gchar * account_widget_generic_format_param_name (const gchar *param_name) { - gchar *str; - gchar *p; + gchar *str; + gchar *p; - str = g_strdup (param_name); + str = g_strdup (param_name); - if (str && g_ascii_isalpha (str[0])) { - str[0] = g_ascii_toupper (str[0]); - } + if (str && g_ascii_isalpha (str[0])) + str[0] = g_ascii_toupper (str[0]); - while ((p = strchr (str, '-')) != NULL) { - if (p[1] != '\0' && g_ascii_isalpha (p[1])) { - p[0] = ' '; - p[1] = g_ascii_toupper (p[1]); - } + while ((p = strchr (str, '-')) != NULL) + { + if (p[1] != '\0' && g_ascii_isalpha (p[1])) + { + p[0] = ' '; + p[1] = g_ascii_toupper (p[1]); + } - p++; - } + p++; + } - return str; + return str; } static void -accounts_widget_generic_setup (EmpathyAccountSettings *settings, - GtkWidget *table_common_settings, - GtkWidget *table_advanced_settings) -{ - TpConnectionManagerParam *params, *param; - - params = empathy_account_settings_get_tp_params (settings); - - for (param = params; param != NULL && param->name != NULL; param++) { - GtkWidget *table_settings; - guint n_rows = 0; - GtkWidget *widget = NULL; - gchar *param_name_formatted; - - if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED) { - table_settings = table_common_settings; - } else { - table_settings = table_advanced_settings; - } - param_name_formatted = account_widget_generic_format_param_name (param->name); - g_object_get (table_settings, "n-rows", &n_rows, NULL); - gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2); - - if (param->dbus_signature[0] == 's') { - gchar *str; - - str = g_strdup_printf (_("%s:"), param_name_formatted); - widget = gtk_label_new (str); - gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); - g_free (str); - - gtk_table_attach (GTK_TABLE (table_settings), - widget, - 0, 1, - n_rows - 1, n_rows, - GTK_FILL, 0, - 0, 0); - gtk_widget_show (widget); - - widget = gtk_entry_new (); - if (strcmp (param->name, "account") == 0) { - g_signal_connect (widget, "realize", - G_CALLBACK (gtk_widget_grab_focus), - NULL); - } - gtk_table_attach (GTK_TABLE (table_settings), - widget, - 1, 2, - n_rows - 1, n_rows, - GTK_FILL | GTK_EXPAND, 0, - 0, 0); - gtk_widget_show (widget); - } - /* int types: ynqiuxt. double type is 'd' */ - else if (param->dbus_signature[0] == 'y' || - param->dbus_signature[0] == 'n' || - param->dbus_signature[0] == 'q' || - param->dbus_signature[0] == 'i' || - param->dbus_signature[0] == 'u' || - param->dbus_signature[0] == 'x' || - param->dbus_signature[0] == 't' || - param->dbus_signature[0] == 'd') { - gchar *str = NULL; - gdouble minint = 0; - gdouble maxint = 0; - gdouble step = 1; - - switch (param->dbus_signature[0]) { - case 'y': minint = G_MININT8; maxint = G_MAXINT8; break; - case 'n': minint = G_MININT16; maxint = G_MAXINT16; break; - case 'q': minint = 0; maxint = G_MAXUINT16; break; - case 'i': minint = G_MININT32; maxint = G_MAXINT32; break; - case 'u': minint = 0; maxint = G_MAXUINT32; break; - case 'x': minint = G_MININT64; maxint = G_MAXINT64; break; - case 't': minint = 0; maxint = G_MAXUINT64; break; - case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break; - } - - str = g_strdup_printf (_("%s:"), param_name_formatted); - widget = gtk_label_new (str); - gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); - g_free (str); - - gtk_table_attach (GTK_TABLE (table_settings), - widget, - 0, 1, - n_rows - 1, n_rows, - GTK_FILL, 0, - 0, 0); - gtk_widget_show (widget); - - widget = gtk_spin_button_new_with_range (minint, maxint, step); - gtk_table_attach (GTK_TABLE (table_settings), - widget, - 1, 2, - n_rows - 1, n_rows, - GTK_FILL | GTK_EXPAND, 0, - 0, 0); - gtk_widget_show (widget); - } - else if (param->dbus_signature[0] == 'b') { - widget = gtk_check_button_new_with_label (param_name_formatted); - gtk_table_attach (GTK_TABLE (table_settings), - widget, - 0, 2, - n_rows - 1, n_rows, - GTK_FILL | GTK_EXPAND, 0, - 0, 0); - gtk_widget_show (widget); - } else { - DEBUG ("Unknown signature for param %s: %s", - param_name_formatted, param->dbus_signature); - } - - if (widget) { - account_widget_setup_widget (widget, settings, param->name); - } - - g_free (param_name_formatted); - } +accounts_widget_generic_setup (EmpathyAccountWidget *self, + GtkWidget *table_common_settings, + GtkWidget *table_advanced_settings) +{ + TpConnectionManagerParam *params, *param; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + params = empathy_account_settings_get_tp_params (priv->settings); + + for (param = params; param != NULL && param->name != NULL; param++) + { + GtkWidget *table_settings; + guint n_rows = 0; + GtkWidget *widget = NULL; + gchar *param_name_formatted; + + if (param->flags & TP_CONN_MGR_PARAM_FLAG_REQUIRED) + table_settings = table_common_settings; + else + table_settings = table_advanced_settings; + + param_name_formatted = account_widget_generic_format_param_name (param->name); + g_object_get (table_settings, "n-rows", &n_rows, NULL); + gtk_table_resize (GTK_TABLE (table_settings), ++n_rows, 2); + + if (param->dbus_signature[0] == 's') + { + gchar *str; + + str = g_strdup_printf (_("%s:"), param_name_formatted); + widget = gtk_label_new (str); + gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); + g_free (str); + + gtk_table_attach (GTK_TABLE (table_settings), + widget, + 0, 1, + n_rows - 1, n_rows, + GTK_FILL, 0, + 0, 0); + gtk_widget_show (widget); + + widget = gtk_entry_new (); + if (strcmp (param->name, "account") == 0) + { + g_signal_connect (widget, "realize", + G_CALLBACK (gtk_widget_grab_focus), + NULL); + } + gtk_table_attach (GTK_TABLE (table_settings), + widget, + 1, 2, + n_rows - 1, n_rows, + GTK_FILL | GTK_EXPAND, 0, + 0, 0); + gtk_widget_show (widget); + } + /* int types: ynqiuxt. double type is 'd' */ + else if (param->dbus_signature[0] == 'y' || + param->dbus_signature[0] == 'n' || + param->dbus_signature[0] == 'q' || + param->dbus_signature[0] == 'i' || + param->dbus_signature[0] == 'u' || + param->dbus_signature[0] == 'x' || + param->dbus_signature[0] == 't' || + param->dbus_signature[0] == 'd') + { + gchar *str = NULL; + gdouble minint = 0; + gdouble maxint = 0; + gdouble step = 1; + + switch (param->dbus_signature[0]) + { + case 'y': minint = G_MININT8; maxint = G_MAXINT8; break; + case 'n': minint = G_MININT16; maxint = G_MAXINT16; break; + case 'q': minint = 0; maxint = G_MAXUINT16; break; + case 'i': minint = G_MININT32; maxint = G_MAXINT32; break; + case 'u': minint = 0; maxint = G_MAXUINT32; break; + case 'x': minint = G_MININT64; maxint = G_MAXINT64; break; + case 't': minint = 0; maxint = G_MAXUINT64; break; + case 'd': minint = G_MININT32; maxint = G_MAXINT32; step = 0.1; break; + } + + str = g_strdup_printf (_("%s:"), param_name_formatted); + widget = gtk_label_new (str); + gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5); + g_free (str); + + gtk_table_attach (GTK_TABLE (table_settings), + widget, + 0, 1, + n_rows - 1, n_rows, + GTK_FILL, 0, + 0, 0); + gtk_widget_show (widget); + + widget = gtk_spin_button_new_with_range (minint, maxint, step); + gtk_table_attach (GTK_TABLE (table_settings), + widget, + 1, 2, + n_rows - 1, n_rows, + GTK_FILL | GTK_EXPAND, 0, + 0, 0); + gtk_widget_show (widget); + } + else if (param->dbus_signature[0] == 'b') + { + widget = gtk_check_button_new_with_label (param_name_formatted); + gtk_table_attach (GTK_TABLE (table_settings), + widget, + 0, 2, + n_rows - 1, n_rows, + GTK_FILL | GTK_EXPAND, 0, + 0, 0); + gtk_widget_show (widget); + } + else + { + DEBUG ("Unknown signature for param %s: %s", + param_name_formatted, param->dbus_signature); + } + + if (widget) + account_widget_setup_widget (self, widget, param->name); + + g_free (param_name_formatted); + } } static void -account_widget_handle_params_valist (EmpathyAccountSettings *settings, - GtkBuilder *gui, - const gchar *first_widget, - va_list args) +account_widget_handle_params_valist (EmpathyAccountWidget *self, + const gchar *first_widget, + va_list args) { - GObject *object; - const gchar *name; + GObject *object; + const gchar *name; - for (name = first_widget; name; name = va_arg (args, const gchar *)) { - const gchar *param_name; + for (name = first_widget; name; name = va_arg (args, const gchar *)) + { + const gchar *param_name; - param_name = va_arg (args, const gchar *); - object = gtk_builder_get_object (gui, name); + param_name = va_arg (args, const gchar *); + object = gtk_builder_get_object (self->ui_details->gui, name); - if (!object) { - g_warning ("Builder is missing object '%s'.", name); - continue; - } + if (!object) + { + g_warning ("Builder is missing object '%s'.", name); + continue; + } - account_widget_setup_widget (GTK_WIDGET (object), settings, param_name); - } -} - -void -empathy_account_widget_handle_params (EmpathyAccountSettings *settings, - GtkBuilder *gui, - const gchar *first_widget, - ...) -{ - va_list args; - - g_return_if_fail (GTK_IS_BUILDER (gui)); - - va_start (args, first_widget); - account_widget_handle_params_valist (settings, gui, first_widget, args); - va_end (args); + account_widget_setup_widget (self, GTK_WIDGET (object), param_name); + } } static void account_widget_apply_clicked_cb (GtkWidget *button, - EmpathyAccountSettings *settings) + EmpathyAccountWidget *self) { - empathy_account_settings_apply_async (settings, NULL, NULL); + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + empathy_account_settings_apply_async (priv->settings, NULL, NULL); } -void -empathy_account_widget_add_apply_button (EmpathyAccountSettings *settings, - GtkWidget *vbox) +static void +account_widget_setup_generic (EmpathyAccountWidget *self) { - GtkWidget *button; + GtkWidget *table_common_settings; + GtkWidget *table_advanced_settings; - button = gtk_button_new_from_stock (GTK_STOCK_APPLY); + table_common_settings = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui, + "table_common_settings")); + table_advanced_settings = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui, + "table_advanced_settings")); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 3); + accounts_widget_generic_setup (self, table_common_settings, + table_advanced_settings); - g_signal_connect (button, "clicked", - G_CALLBACK (account_widget_apply_clicked_cb), - settings); - gtk_widget_show (button); + g_object_unref (self->ui_details->gui); } -void -empathy_account_widget_add_forget_button (EmpathyAccountSettings *settings, - GtkBuilder *gui, - const gchar *button, - const gchar *entry) +static void +account_widget_settings_ready_cb (EmpathyAccountSettings *settings, + GParamSpec *pspec, + gpointer user_data) { - GtkWidget *button_forget; - GtkWidget *entry_password; - const gchar *password = NULL; + EmpathyAccountWidget *self = user_data; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); - button_forget = GTK_WIDGET (gtk_builder_get_object (gui, button)); - entry_password = GTK_WIDGET (gtk_builder_get_object (gui, entry)); - - password = empathy_account_settings_get_string (settings, "password"); - gtk_widget_set_sensitive (button_forget, !EMP_STR_EMPTY (password)); - - g_signal_connect (button_forget, "clicked", - G_CALLBACK (account_widget_forget_clicked_cb), - entry_password); - g_signal_connect (entry_password, "changed", - G_CALLBACK (account_widget_password_changed_cb), - button_forget); + if (empathy_account_settings_is_ready (priv->settings)) + account_widget_setup_generic (self); } -void -empathy_account_widget_set_default_focus (GtkBuilder *gui, - const gchar *entry) +static void +account_widget_build_generic (EmpathyAccountWidget *self, + const char *filename) { - GObject *default_focus_entry; - - default_focus_entry = gtk_builder_get_object (gui, entry); - g_signal_connect (default_focus_entry, "realize", - G_CALLBACK (gtk_widget_grab_focus), - NULL); + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_generic_settings", &self->ui_details->widget, + NULL); + + g_object_ref (self->ui_details->gui); + + if (empathy_account_settings_is_ready (priv->settings)) + account_widget_setup_generic (self); + else + g_signal_connect (priv->settings, "notify::ready", + G_CALLBACK (account_widget_settings_ready_cb), self); } static void -account_widget_setup_generic (EmpathyAccountSettings *settings, - GtkBuilder *builder) +account_widget_build_salut (EmpathyAccountWidget *self, + const char *filename) { - GtkWidget *table_common_settings; - GtkWidget *table_advanced_settings; - - table_common_settings = GTK_WIDGET (gtk_builder_get_object (builder, - "table_common_settings")); - table_advanced_settings = GTK_WIDGET (gtk_builder_get_object (builder, - "table_advanced_settings")); - - accounts_widget_generic_setup (settings, table_common_settings, - table_advanced_settings); - - g_object_unref (builder); + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_salut_settings", &self->ui_details->widget, + NULL); + + empathy_account_widget_handle_params (self, + "entry_published", "published-name", + "entry_nickname", "nickname", + "entry_first_name", "first-name", + "entry_last_name", "last-name", + "entry_email", "email", + "entry_jid", "jid", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_nickname"); } static void -account_widget_settings_ready_cb (EmpathyAccountSettings *settings, - GParamSpec *pspec, gpointer user_data) +account_widget_build_msn (EmpathyAccountWidget *self, + const char *filename) { - GtkBuilder *builder = GTK_BUILDER (user_data); - - if (empathy_account_settings_is_ready (settings)) - account_widget_setup_generic (settings, builder); + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_msn_settings", &self->ui_details->widget, + NULL); + + empathy_account_widget_handle_params (self, + "entry_id", "account", + "entry_password", "password", + "entry_server", "server", + "spinbutton_port", "port", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_id"); + self->ui_details->add_forget = TRUE; } -GtkWidget * -empathy_account_widget_generic_new (EmpathyAccountSettings *settings) +static void +account_widget_build_jabber (EmpathyAccountWidget *self, + const char *filename) { - GtkBuilder *gui; - GtkWidget *widget; - gchar *filename; - - filename = empathy_file_lookup ("empathy-account-widget-generic.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_generic_settings", &widget, - NULL); - - if (empathy_account_settings_is_ready (settings)) - account_widget_setup_generic (settings, gui); - else - g_signal_connect (settings, "notify::ready", - G_CALLBACK (account_widget_settings_ready_cb), gui); - - empathy_account_widget_add_apply_button (settings, widget); - - g_free (filename); - - g_object_ref (widget); - g_object_force_floating (G_OBJECT (widget)); - return widget; + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + GtkWidget *spinbutton_port; + GtkWidget *checkbutton_ssl; + + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_jabber_settings", &self->ui_details->widget, + "spinbutton_port", &spinbutton_port, + "checkbutton_ssl", &checkbutton_ssl, + NULL); + + empathy_account_widget_handle_params (self, + "entry_id", "account", + "entry_password", "password", + "entry_resource", "resource", + "entry_server", "server", + "spinbutton_port", "port", + "spinbutton_priority", "priority", + "checkbutton_ssl", "old-ssl", + "checkbutton_ignore_ssl_errors", "ignore-ssl-errors", + "checkbutton_encryption", "require-encryption", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_id"); + self->ui_details->add_forget = TRUE; + priv->spinbutton_port = spinbutton_port; + + g_signal_connect (checkbutton_ssl, "toggled", + G_CALLBACK (account_widget_jabber_ssl_toggled_cb), + self); } -GtkWidget * -empathy_account_widget_salut_new (EmpathyAccountSettings *settings) +static void +account_widget_build_icq (EmpathyAccountWidget *self, + const char *filename) { - GtkBuilder *gui; - GtkWidget *widget; - gchar *filename; - - filename = empathy_file_lookup ("empathy-account-widget-salut.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_salut_settings", &widget, - NULL); - g_free (filename); - - empathy_account_widget_handle_params (settings, gui, - "entry_published", "published-name", - "entry_nickname", "nickname", - "entry_first_name", "first-name", - "entry_last_name", "last-name", - "entry_email", "email", - "entry_jid", "jid", - NULL); - - empathy_account_widget_set_default_focus (gui, "entry_nickname"); - empathy_account_widget_add_apply_button (settings, widget); - - return empathy_builder_unref_and_keep_widget (gui, widget); + GtkWidget *spinbutton_port; + + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_icq_settings", &self->ui_details->widget, + "spinbutton_port", &spinbutton_port, + NULL); + + empathy_account_widget_handle_params (self, + "entry_uin", "account", + "entry_password", "password", + "entry_server", "server", + "spinbutton_port", "port", + "entry_charset", "charset", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_uin"); + self->ui_details->add_forget = TRUE; } -GtkWidget * -empathy_account_widget_msn_new (EmpathyAccountSettings *settings) +static void +account_widget_build_aim (EmpathyAccountWidget *self, + const char *filename) { - GtkBuilder *gui; - GtkWidget *widget; - gchar *filename; - - filename = empathy_file_lookup ("empathy-account-widget-msn.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_msn_settings", &widget, - NULL); - g_free (filename); - - empathy_account_widget_handle_params (settings, gui, - "entry_id", "account", - "entry_password", "password", - "entry_server", "server", - "spinbutton_port", "port", - NULL); + GtkWidget *spinbutton_port; + + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_aim_settings", &self->ui_details->widget, + "spinbutton_port", &spinbutton_port, + NULL); + + empathy_account_widget_handle_params (self, + "entry_screenname", "account", + "entry_password", "password", + "entry_server", "server", + "spinbutton_port", "port", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_screenname"); + self->ui_details->add_forget = TRUE; +} - empathy_account_widget_add_forget_button (settings, gui, - "button_forget", - "entry_password"); +static void +account_widget_build_yahoo (EmpathyAccountWidget *self, + const char *filename) +{ + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_yahoo_settings", &self->ui_details->widget, + NULL); + + empathy_account_widget_handle_params (self, + "entry_id", "account", + "entry_password", "password", + "entry_server", "server", + "entry_locale", "room-list-locale", + "entry_charset", "charset", + "spinbutton_port", "port", + "checkbutton_yahoojp", "yahoojp", + "checkbutton_ignore_invites", "ignore-invites", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_id"); + self->ui_details->add_forget = TRUE; +} - empathy_account_widget_set_default_focus (gui, "entry_id"); +static void +account_widget_build_groupwise (EmpathyAccountWidget *self, + const char *filename) +{ + self->ui_details->gui = empathy_builder_get_file (filename, + "vbox_groupwise_settings", &self->ui_details->widget, + NULL); + + empathy_account_widget_handle_params (self, + "entry_id", "account", + "entry_password", "password", + "entry_server", "server", + "spinbutton_port", "port", + NULL); + + self->ui_details->default_focus = g_strdup ("entry_id"); + self->ui_details->add_forget = TRUE; +} - return empathy_builder_unref_and_keep_widget (gui, widget); +static void +account_widget_destroy_cb (GtkWidget *widget, + EmpathyAccountWidget *self) +{ + g_object_unref (self); } -GtkWidget * -empathy_account_widget_jabber_new (EmpathyAccountSettings *settings) -{ - GtkBuilder *gui; - GtkWidget *widget; - GtkWidget *spinbutton_port; - GtkWidget *checkbutton_ssl; - gchar *filename; - - filename = empathy_file_lookup ("empathy-account-widget-jabber.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_jabber_settings", &widget, - "spinbutton_port", &spinbutton_port, - "checkbutton_ssl", &checkbutton_ssl, - NULL); - g_free (filename); - - empathy_account_widget_handle_params (settings, gui, - "entry_id", "account", - "entry_password", "password", - "entry_resource", "resource", - "entry_server", "server", - "spinbutton_port", "port", - "spinbutton_priority", "priority", - "checkbutton_ssl", "old-ssl", - "checkbutton_ignore_ssl_errors", "ignore-ssl-errors", - "checkbutton_encryption", "require-encryption", - NULL); - - empathy_account_widget_add_forget_button (settings, gui, - "button_forget", - "entry_password"); - - empathy_account_widget_set_default_focus (gui, "entry_id"); - - g_signal_connect (checkbutton_ssl, "toggled", - G_CALLBACK (account_widget_jabber_ssl_toggled_cb), - spinbutton_port); - - empathy_account_widget_add_apply_button (settings, widget); - - return empathy_builder_unref_and_keep_widget (gui, widget); +static void +do_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyAccountWidgetPriv *priv = GET_PRIV (object); + + switch (prop_id) + { + case PROP_PROTOCOL: + priv->protocol = g_value_dup_string (value); + break; + case PROP_SETTINGS: + priv->settings = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } } -GtkWidget * -empathy_account_widget_icq_new (EmpathyAccountSettings *settings) +static void +do_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GtkBuilder *gui; - GtkWidget *widget; - GtkWidget *spinbutton_port; - gchar *filename; + EmpathyAccountWidgetPriv *priv = GET_PRIV (object); + + switch (prop_id) + { + case PROP_PROTOCOL: + g_value_set_string (value, priv->protocol); + break; + case PROP_SETTINGS: + g_value_set_object (value, priv->settings); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} - filename = empathy_file_lookup ("empathy-account-widget-icq.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_icq_settings", &widget, - "spinbutton_port", &spinbutton_port, - NULL); - g_free (filename); +static void +do_constructed (GObject *obj) +{ + EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj); + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + char *uiname, *filename; + + uiname = g_strconcat ("empathy-account-widget-", priv->protocol, + ".ui", NULL); + filename = empathy_file_lookup (uiname, "libempathy-gtk"); + + if (!tp_strdiff (priv->protocol, "local-xmpp")) + account_widget_build_salut (self, filename); + else if (!tp_strdiff (priv->protocol, "msn")) + account_widget_build_msn (self, filename); + else if (!tp_strdiff (priv->protocol, "jabber")) + account_widget_build_jabber (self, filename); + else if (!tp_strdiff (priv->protocol, "icq")) + account_widget_build_icq (self, filename); + else if (!tp_strdiff (priv->protocol, "aim")) + account_widget_build_aim (self, filename); + else if (!tp_strdiff (priv->protocol, "yahoo")) + account_widget_build_yahoo (self, filename); + else if (!tp_strdiff (priv->protocol, "groupwise")) + account_widget_build_groupwise (self, filename); + else if (!tp_strdiff (priv->protocol, "irc")) + empathy_account_widget_irc_build (self, filename); + else if (!tp_strdiff (priv->protocol, "sip")) + empathy_account_widget_sip_build (self, filename); + else if (!tp_strdiff (priv->protocol, "generic")) + account_widget_build_generic (self, filename); + else + { + g_free (uiname); + g_free (filename); + g_critical ("Unknown protocol, can't build the account widget"); + return; + } + + g_free (uiname); + g_free (filename); + + /* handle default focus */ + if (self->ui_details->default_focus != NULL) + { + GObject *default_focus_entry; + + default_focus_entry = gtk_builder_get_object + (self->ui_details->gui, self->ui_details->default_focus); + g_signal_connect (default_focus_entry, "realize", + G_CALLBACK (gtk_widget_grab_focus), + NULL); + } + + /* handle forget button */ + if (self->ui_details->add_forget) + { + const gchar *password = NULL; + + priv->button_forget = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui, "button_forget")); + priv->entry_password = GTK_WIDGET (gtk_builder_get_object (self->ui_details->gui, "entry_password")); + + password = empathy_account_settings_get_string (priv->settings, "password"); + gtk_widget_set_sensitive (priv->button_forget, !EMP_STR_EMPTY (password)); + + g_signal_connect (priv->button_forget, "clicked", + G_CALLBACK (account_widget_forget_clicked_cb), + self); + g_signal_connect (priv->entry_password, "changed", + G_CALLBACK (account_widget_password_changed_cb), + self); + } + + /* handle apply button */ + priv->apply_button = gtk_button_new_from_stock (GTK_STOCK_APPLY); + gtk_box_pack_end (GTK_BOX (self->ui_details->widget), priv->apply_button, FALSE, FALSE, 3); + + g_signal_connect (priv->apply_button, "clicked", + G_CALLBACK (account_widget_apply_clicked_cb), + self); + account_widget_handle_apply_sensitivity (self); + gtk_widget_show (priv->apply_button); + + /* hook up to widget destruction to unref ourselves */ + g_signal_connect (self->ui_details->widget, "destroy", + G_CALLBACK (account_widget_destroy_cb), self); + + empathy_builder_unref_and_keep_widget (self->ui_details->gui, self->ui_details->widget); +} - empathy_account_widget_handle_params (settings, gui, - "entry_uin", "account", - "entry_password", "password", - "entry_server", "server", - "spinbutton_port", "port", - "entry_charset", "charset", - NULL); +static void +do_dispose (GObject *obj) +{ + EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj); + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); - empathy_account_widget_add_forget_button (settings, gui, - "button_forget", - "entry_password"); + if (priv->dispose_run) + return; - empathy_account_widget_set_default_focus (gui, "entry_uin"); + priv->dispose_run = TRUE; - empathy_account_widget_add_apply_button (settings, widget); + if (priv->settings != NULL) + { + g_object_unref (priv->settings); + priv->settings = NULL; + } - return empathy_builder_unref_and_keep_widget (gui, widget); + if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose != NULL) + G_OBJECT_CLASS (empathy_account_widget_parent_class)->dispose (obj); } -GtkWidget * -empathy_account_widget_aim_new (EmpathyAccountSettings *settings) +static void +do_finalize (GObject *obj) { - GtkBuilder *gui; - GtkWidget *widget; - GtkWidget *spinbutton_port; - gchar *filename; - - filename = empathy_file_lookup ("empathy-account-widget-aim.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_aim_settings", &widget, - "spinbutton_port", &spinbutton_port, - NULL); - g_free (filename); + EmpathyAccountWidget *self = EMPATHY_ACCOUNT_WIDGET (obj); + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); - empathy_account_widget_handle_params (settings, gui, - "entry_screenname", "account", - "entry_password", "password", - "entry_server", "server", - "spinbutton_port", "port", - NULL); + g_free (self->ui_details->default_focus); + g_slice_free (EmpathyAccountWidgetUIDetails, self->ui_details); - empathy_account_widget_add_forget_button (settings, gui, - "button_forget", - "entry_password"); + g_free (priv->protocol); - empathy_account_widget_set_default_focus (gui, "entry_screenname"); - empathy_account_widget_add_apply_button (settings, widget); + if (G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize != NULL) + G_OBJECT_CLASS (empathy_account_widget_parent_class)->finalize (obj); +} - return empathy_builder_unref_and_keep_widget (gui, widget); +static void +empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GParamSpec *param_spec; + + oclass->get_property = do_get_property; + oclass->set_property = do_set_property; + oclass->constructed = do_constructed; + oclass->dispose = do_dispose; + oclass->finalize = do_finalize; + + param_spec = g_param_spec_string ("protocol", + "protocol", "The protocol of the account", + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (oclass, PROP_PROTOCOL, param_spec); + + param_spec = g_param_spec_object ("settings", + "settings", "The settings of the account", + EMPATHY_TYPE_ACCOUNT_SETTINGS, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (oclass, PROP_SETTINGS, param_spec); + + g_type_class_add_private (klass, sizeof (EmpathyAccountWidgetPriv)); } -GtkWidget * -empathy_account_widget_yahoo_new (EmpathyAccountSettings *settings) +static void +empathy_account_widget_init (EmpathyAccountWidget *self) { - GtkBuilder *gui; - GtkWidget *widget; - gchar *filename; + EmpathyAccountWidgetPriv *priv = + G_TYPE_INSTANCE_GET_PRIVATE ((self), EMPATHY_TYPE_ACCOUNT_WIDGET, + EmpathyAccountWidgetPriv); - filename = empathy_file_lookup ("empathy-account-widget-yahoo.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_yahoo_settings", &widget, - NULL); - g_free (filename); + self->priv = priv; + priv->dispose_run = FALSE; - empathy_account_widget_handle_params (settings, gui, - "entry_id", "account", - "entry_password", "password", - "entry_server", "server", - "entry_locale", "room-list-locale", - "entry_charset", "charset", - "spinbutton_port", "port", - "checkbutton_yahoojp", "yahoojp", - "checkbutton_ignore_invites", "ignore-invites", - NULL); + self->ui_details = g_slice_new0 (EmpathyAccountWidgetUIDetails); +} - empathy_account_widget_add_forget_button (settings, gui, - "button_forget", - "entry_password"); +/* public methods */ - empathy_account_widget_set_default_focus (gui, "entry_id"); - empathy_account_widget_add_apply_button (settings, widget); +void +empathy_account_widget_handle_params (EmpathyAccountWidget *self, + const gchar *first_widget, + ...) +{ + va_list args; - return empathy_builder_unref_and_keep_widget (gui, widget); + va_start (args, first_widget); + account_widget_handle_params_valist (self, first_widget, args); + va_end (args); } GtkWidget * -empathy_account_widget_groupwise_new (EmpathyAccountSettings *settings) +empathy_account_widget_new_for_protocol (const char *protocol, + EmpathyAccountSettings *settings) { - GtkBuilder *gui; - GtkWidget *widget; - gchar *filename; - - filename = empathy_file_lookup ("empathy-account-widget-groupwise.ui", - "libempathy-gtk"); - gui = empathy_builder_get_file (filename, - "vbox_groupwise_settings", &widget, - NULL); - g_free (filename); + EmpathyAccountWidget *self; + EmpathyAccountWidgetPriv *priv; - empathy_account_widget_handle_params (settings, gui, - "entry_id", "account", - "entry_password", "password", - "entry_server", "server", - "spinbutton_port", "port", - NULL); + g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), NULL); + g_return_val_if_fail (settings != NULL, NULL); - empathy_account_widget_add_forget_button (settings, gui, - "button_forget", - "entry_password"); + self = g_object_new + (EMPATHY_TYPE_ACCOUNT_WIDGET, "protocol", protocol, + "settings", settings, NULL); + priv = GET_PRIV (self); - empathy_account_widget_set_default_focus (gui, "entry_id"); - empathy_account_widget_add_apply_button (settings, widget); - - return empathy_builder_unref_and_keep_widget (gui, widget); + return self->ui_details->widget; } - diff --git a/libempathy-gtk/empathy-account-widget.h b/libempathy-gtk/empathy-account-widget.h index f05c66012..8a5f0f2c2 100644 --- a/libempathy-gtk/empathy-account-widget.h +++ b/libempathy-gtk/empathy-account-widget.h @@ -22,8 +22,8 @@ * Martyn Russell <martyn@imendio.com> */ -#ifndef __EMPATHY_ACCOUNT_WIDGET_GENERIC_H__ -#define __EMPATHY_ACCOUNT_WIDGET_GENERIC_H__ +#ifndef __EMPATHY_ACCOUNT_WIDGET_H__ +#define __EMPATHY_ACCOUNT_WIDGET_H__ #include <gtk/gtk.h> @@ -31,28 +31,38 @@ G_BEGIN_DECLS -void empathy_account_widget_handle_params (EmpathyAccountSettings *settings, - GtkBuilder *gui, - const gchar *first_widget, - ...); -void empathy_account_widget_add_forget_button (EmpathyAccountSettings *settings, - GtkBuilder *gui, - const gchar *button, - const gchar *entry); -void empathy_account_widget_add_apply_button (EmpathyAccountSettings *settings, - GtkWidget *vbox); - -void empathy_account_widget_set_default_focus (GtkBuilder *gui, - const gchar *entry); -GtkWidget *empathy_account_widget_generic_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_salut_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_msn_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_jabber_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_icq_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_aim_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_yahoo_new (EmpathyAccountSettings *settings); -GtkWidget *empathy_account_widget_groupwise_new (EmpathyAccountSettings *settings); +#define EMPATHY_TYPE_ACCOUNT_WIDGET empathy_account_widget_get_type() +#define EMPATHY_ACCOUNT_WIDGET(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_ACCOUNT_WIDGET, EmpathyAccountWidget)) +#define EMPATHY_ACCOUNT_WIDGET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EMPATHY_TYPE_ACCOUNT_WIDGET, EmpathyAccountWidgetClass)) +#define EMPATHY_IS_ACCOUNT_WIDGET(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_ACCOUNT_WIDGET)) +#define EMPATHY_IS_ACCOUNT_WIDGET_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EMPATHY_TYPE_ACCOUNT_WIDGET)) +#define EMPATHY_ACCOUNT_WIDGET_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_ACCOUNT_WIDGET, EmpathyAccountWidgetClass)) + +typedef struct _EmpathyAccountWidgetUIDetails EmpathyAccountWidgetUIDetails; + +typedef struct { + GObject parent; + + EmpathyAccountWidgetUIDetails *ui_details; + + /* private */ + gpointer priv; +} EmpathyAccountWidget; + +typedef struct { + GObjectClass parent_class; +} EmpathyAccountWidgetClass; + +GType empathy_account_widget_get_type (void); + +GtkWidget *empathy_account_widget_new_for_protocol (const char *protocol, + EmpathyAccountSettings *settings); G_END_DECLS -#endif /* __EMPATHY_ACCOUNT_WIDGET_GENERIC_H__ */ +#endif /* __EMPATHY_ACCOUNT_WIDGET_H__ */ diff --git a/libempathy-gtk/empathy-contact-dialogs.c b/libempathy-gtk/empathy-contact-dialogs.c index fc1cbbc8e..725011c0b 100644 --- a/libempathy-gtk/empathy-contact-dialogs.c +++ b/libempathy-gtk/empathy-contact-dialogs.c @@ -337,6 +337,10 @@ can_add_contact_to_account (EmpathyAccount *account, if (connection == NULL) return FALSE; + if (connection == NULL) { + return FALSE; + } + contact_manager = empathy_contact_manager_dup_singleton (); result = empathy_contact_manager_get_flags_for_connection (contact_manager, connection) & EMPATHY_CONTACT_LIST_CAN_ADD; g_object_unref (contact_manager); diff --git a/libempathy-gtk/empathy-protocol-chooser.c b/libempathy-gtk/empathy-protocol-chooser.c index 65f778ac4..ecd26d8ff 100644 --- a/libempathy-gtk/empathy-protocol-chooser.c +++ b/libempathy-gtk/empathy-protocol-chooser.c @@ -29,6 +29,7 @@ #include <gtk/gtk.h> #include <libempathy/empathy-utils.h> +#include <libempathy/empathy-connection-managers.h> #include "empathy-protocol-chooser.h" #include "empathy-ui-utils.h" @@ -59,6 +60,7 @@ typedef struct { GtkListStore *store; gboolean dispose_run; + EmpathyConnectionManagers *cms; } EmpathyProtocolChooserPriv; @@ -121,6 +123,36 @@ protocol_chooser_sort_func (GtkTreeModel *model, return cmp; } +static const char * +protocol_chooser_proto_name_to_display_name (const gchar *proto_name) +{ + int i; + + static struct { + const gchar *proto; + const gchar *display; + } names[] = { + { "jabber", "XMPP" }, + { "msn", "MSN" }, + { "local-xmpp", "Salut" }, + { "irc", "IRC" }, + { "icq", "ICQ" }, + { "aim", "AIM" }, + { "yahoo", "Yahoo" }, + { "groupwise", "GroupWise" }, + { "sip", "SIP" }, + { NULL, NULL } + }; + + for (i = 0; names[i].proto != NULL; i++) + { + if (!tp_strdiff (proto_name, names[i].proto)) + return names[i].display; + } + + return NULL; +} + static void protocol_choosers_add_cm (EmpathyProtocolChooser *chooser, TpConnectionManager *cm) @@ -132,48 +164,52 @@ protocol_choosers_add_cm (EmpathyProtocolChooser *chooser, { const TpConnectionManagerProtocol *proto = *iter; gchar *icon_name; - gchar *display_name; + const gchar *display_name; + gchar *display_name_set; icon_name = empathy_protocol_icon_name (proto->name); + display_name = protocol_chooser_proto_name_to_display_name (proto->name); + + if (display_name == NULL) + display_name = proto->name; if (!tp_strdiff (cm->name, "haze")) - display_name = g_strdup_printf ("%s (Haze)", proto->name); + display_name_set = g_strdup_printf ("%s (Haze)", display_name); else - display_name = g_strdup (proto->name); + display_name_set = g_strdup (display_name); gtk_list_store_insert_with_values (priv->store, NULL, 0, COL_ICON, icon_name, - COL_LABEL, display_name, + COL_LABEL, display_name_set, COL_CM, cm, COL_PROTOCOL, proto, -1); - g_free (display_name); + g_free (display_name_set); g_free (icon_name); } } - static void -protocol_choosers_cms_listed (TpConnectionManager * const *cms, - gsize n_cms, - const GError *error, - gpointer user_data, - GObject *weak_object) +protocol_chooser_add_cms_list (EmpathyProtocolChooser *protocol_chooser, + GList *cms) { - TpConnectionManager * const *iter; + GList *l; - if (error != NULL) - { - DEBUG ("Failed to get connection managers: %s", error->message); - return; - } + for (l = cms; l != NULL; l = l->next) + protocol_choosers_add_cm (protocol_chooser, l->data); - for (iter = cms ; iter != NULL && *iter != NULL; iter++) - protocol_choosers_add_cm (EMPATHY_PROTOCOL_CHOOSER (weak_object), - *iter); + gtk_combo_box_set_active (GTK_COMBO_BOX (protocol_chooser), 0); +} - gtk_combo_box_set_active (GTK_COMBO_BOX (weak_object), 0); +static void +protocol_chooser_cms_ready_cb (EmpathyConnectionManagers *cms, + GParamSpec *pspec, + EmpathyProtocolChooser *protocol_chooser) +{ + if (empathy_connection_managers_is_ready (cms)) + protocol_chooser_add_cms_list + (protocol_chooser, empathy_connection_managers_get_cms (cms)); } static void @@ -182,7 +218,6 @@ protocol_chooser_constructed (GObject *object) EmpathyProtocolChooser *protocol_chooser; EmpathyProtocolChooserPriv *priv; GtkCellRenderer *renderer; - TpDBusDaemon *dbus; priv = GET_PRIV (object); protocol_chooser = EMPATHY_PROTOCOL_CHOOSER (object); @@ -210,11 +245,6 @@ protocol_chooser_constructed (GObject *object) "text", COL_LABEL, NULL); - dbus = tp_dbus_daemon_dup (NULL); - tp_list_connection_managers (dbus, protocol_choosers_cms_listed, - NULL, NULL, object); - g_object_unref (dbus); - /* Set the protocol sort function */ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->store), COL_PROTOCOL, @@ -224,6 +254,13 @@ protocol_chooser_constructed (GObject *object) COL_PROTOCOL, GTK_SORT_ASCENDING); + if (empathy_connection_managers_is_ready (priv->cms)) + protocol_chooser_add_cms_list (protocol_chooser, + empathy_connection_managers_get_cms (priv->cms)); + else + g_signal_connect (priv->cms, "notify::ready", + G_CALLBACK (protocol_chooser_cms_ready_cb), protocol_chooser); + if (G_OBJECT_CLASS (empathy_protocol_chooser_parent_class)->constructed) G_OBJECT_CLASS (empathy_protocol_chooser_parent_class)->constructed (object); } @@ -236,6 +273,7 @@ empathy_protocol_chooser_init (EmpathyProtocolChooser *protocol_chooser) EMPATHY_TYPE_PROTOCOL_CHOOSER, EmpathyProtocolChooserPriv); priv->dispose_run = FALSE; + priv->cms = empathy_connection_managers_dup_singleton (); protocol_chooser->priv = priv; } @@ -257,6 +295,12 @@ protocol_chooser_dispose (GObject *object) priv->store = NULL; } + if (priv->cms) + { + g_object_unref (priv->cms); + priv->cms = NULL; + } + (G_OBJECT_CLASS (empathy_protocol_chooser_parent_class)->dispose) (object); } @@ -271,6 +315,8 @@ empathy_protocol_chooser_class_init (EmpathyProtocolChooserClass *klass) g_type_class_add_private (object_class, sizeof (EmpathyProtocolChooserPriv)); } +/* public methods */ + /** * empathy_protocol_chooser_get_selected_protocol: * @protocol_chooser: an #EmpathyProtocolChooser @@ -307,30 +353,13 @@ empathy_protocol_chooser_dup_selected ( } /** - * empathy_protocol_chooser_n_protocols: - * @protocol_chooser: an #EmpathyProtocolChooser - * - * Returns the number of protocols in @protocol_chooser. - * - * Return value: the number of protocols in @protocol_chooser - */ -gint -empathy_protocol_chooser_n_protocols (EmpathyProtocolChooser *protocol_chooser) -{ - EmpathyProtocolChooserPriv *priv = GET_PRIV (protocol_chooser); - - g_return_val_if_fail (EMPATHY_IS_PROTOCOL_CHOOSER (protocol_chooser), 0); - - return gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->store), NULL); -} - -/** * empathy_protocol_chooser_new: * - * Creates a new #EmpathyProtocolChooser widget. + * Triggers the creation of a new #EmpathyProtocolChooser. * * Return value: a new #EmpathyProtocolChooser widget */ + GtkWidget * empathy_protocol_chooser_new (void) { diff --git a/libempathy-gtk/empathy-protocol-chooser.h b/libempathy-gtk/empathy-protocol-chooser.h index 75f9343cc..9d881958d 100644 --- a/libempathy-gtk/empathy-protocol-chooser.h +++ b/libempathy-gtk/empathy-protocol-chooser.h @@ -58,13 +58,15 @@ struct _EmpathyProtocolChooserClass GtkComboBoxClass parent_class; }; +typedef void (* EmpathyProtocolChooserReadyCb) (GtkWidget *chooser, + GError *error, + gpointer user_data); + GType empathy_protocol_chooser_get_type (void) G_GNUC_CONST; GtkWidget * empathy_protocol_chooser_new (void); TpConnectionManager *empathy_protocol_chooser_dup_selected ( EmpathyProtocolChooser *protocol_chooser, TpConnectionManagerProtocol **protocol); -gint empathy_protocol_chooser_n_protocols ( - EmpathyProtocolChooser *protocol_chooser); G_END_DECLS #endif /* __EMPATHY_PROTOCOL_CHOOSER_H__ */ diff --git a/libempathy/empathy-account-manager.c b/libempathy/empathy-account-manager.c index 727eb7eaf..18eff355f 100644 --- a/libempathy/empathy-account-manager.c +++ b/libempathy/empathy-account-manager.c @@ -55,6 +55,15 @@ typedef struct { TpConnectionPresenceType global_presence; gchar *global_status; gchar *global_status_message; + + /* desired global presence, could be different + * from the actual global one. + */ + TpConnectionPresenceType desired_presence; + gchar *desired_status; + gchar *desired_status_message; + + GHashTable *create_results; } EmpathyAccountManagerPriv; enum { @@ -97,8 +106,16 @@ emp_account_enabled_cb (EmpathyAccount *account, GParamSpec *spec, gpointer manager) { + EmpathyAccountManagerPriv *priv = GET_PRIV (manager); + if (empathy_account_is_enabled (account)) - g_signal_emit (manager, signals[ACCOUNT_ENABLED], 0, account); + { + g_signal_emit (manager, signals[ACCOUNT_ENABLED], 0, account); + + /* set the desired global presence on the account */ + empathy_account_request_presence (account, priv->desired_presence, + priv->desired_status, priv->desired_status_message); + } else g_signal_emit (manager, signals[ACCOUNT_DISABLED], 0, account); } @@ -264,10 +281,14 @@ empathy_account_manager_check_ready (EmpathyAccountManager *manager) } static void -emp_account_ready_cb (GObject *obj, GParamSpec *spec, gpointer user_data) +account_manager_account_ready_cb (GObject *obj, + GParamSpec *spec, + gpointer user_data) { EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (user_data); + EmpathyAccountManagerPriv *priv = GET_PRIV (manager); EmpathyAccount *account = EMPATHY_ACCOUNT (obj); + GSimpleAsyncResult *result; gboolean ready; g_object_get (account, "ready", &ready, NULL); @@ -275,6 +296,19 @@ emp_account_ready_cb (GObject *obj, GParamSpec *spec, gpointer user_data) if (!ready) return; + /* see if there's any pending callbacks for this account */ + result = g_hash_table_lookup (priv->create_results, account); + if (result != NULL) + { + g_simple_async_result_set_op_res_gpointer ( + G_SIMPLE_ASYNC_RESULT (result), account, NULL); + + g_simple_async_result_complete (result); + + g_hash_table_remove (priv->create_results, account); + g_object_unref (result); + } + g_signal_emit (manager, signals[ACCOUNT_CREATED], 0, account); g_signal_connect (account, "notify::connection", @@ -310,7 +344,7 @@ account_manager_add_account (EmpathyAccountManager *manager, g_hash_table_insert (priv->accounts, g_strdup (path), account); g_signal_connect (account, "notify::ready", - G_CALLBACK (emp_account_ready_cb), manager); + G_CALLBACK (account_manager_account_ready_cb), manager); return account; } @@ -406,6 +440,8 @@ empathy_account_manager_init (EmpathyAccountManager *manager) priv->accounts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + priv->create_results = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->dbus = tp_dbus_daemon_dup (NULL); tp_dbus_daemon_watch_name_owner (priv->dbus, @@ -433,8 +469,15 @@ do_finalize (GObject *obj) EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (obj); EmpathyAccountManagerPriv *priv = GET_PRIV (manager); + g_hash_table_destroy (priv->create_results); g_hash_table_destroy (priv->accounts); + g_free (priv->global_status); + g_free (priv->global_status_message); + + g_free (priv->desired_status); + g_free (priv->desired_status_message); + G_OBJECT_CLASS (empathy_account_manager_parent_class)->finalize (obj); } @@ -449,12 +492,35 @@ do_dispose (GObject *obj) priv->dispose_run = TRUE; + if (priv->create_results != NULL && + g_hash_table_size (priv->create_results) > 0) + { + /* the manager is being destroyed while there are account creation + * processes pending; this should not happen, but emit the callbacks + * with an error anyway. + */ + GHashTableIter iter; + GSimpleAsyncResult *result; + + g_hash_table_iter_init (&iter, priv->create_results); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &result)) + { + g_simple_async_result_set_error (result, G_IO_ERROR, + G_IO_ERROR_CANCELLED, "The account manager was disposed while " + "creating the account"); + g_simple_async_result_complete (result); + g_object_unref (result); + } + } + tp_dbus_daemon_cancel_name_owner_watch (priv->dbus, TP_ACCOUNT_MANAGER_BUS_NAME, account_manager_name_owner_cb, manager); - if (priv->dbus == NULL) - g_object_unref (priv->dbus); - priv->dbus = NULL; + if (priv->dbus != NULL) + { + g_object_unref (priv->dbus); + priv->dbus = NULL; + } G_OBJECT_CLASS (empathy_account_manager_parent_class)->dispose (obj); } @@ -767,8 +833,6 @@ empathy_account_manager_request_global_presence ( const gchar *status, const gchar *message) { - /* FIXME should remember requested presence and set it on new accounts - as well */ EmpathyAccountManagerPriv *priv = GET_PRIV (manager); GHashTableIter iter; gpointer value; @@ -784,6 +848,23 @@ empathy_account_manager_request_global_presence ( if (ready) empathy_account_request_presence (account, type, status, message); } + + /* save the requested global presence, to use it in case we create + * new accounts. + */ + priv->desired_presence = type; + + if (tp_strdiff (priv->desired_status, status)) + { + g_free (priv->desired_status); + priv->desired_status = g_strdup (status); + } + + if (tp_strdiff (priv->desired_status_message, message)) + { + g_free (priv->desired_status_message); + priv->desired_status_message = g_strdup (message); + } } TpConnectionPresenceType @@ -803,22 +884,6 @@ empathy_account_manager_get_global_presence ( } static void -empathy_account_manager_created_ready_cb (EmpathyAccount *account, - GParamSpec *spec, gpointer user_data) -{ - GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); - - if (!empathy_account_is_ready (account)) - return; - - g_simple_async_result_set_op_res_gpointer ( - G_SIMPLE_ASYNC_RESULT (result), account, NULL); - - g_simple_async_result_complete (result); - g_object_unref (G_OBJECT (result)); -} - -static void empathy_account_manager_created_cb (TpAccountManager *proxy, const gchar *account_path, const GError *error, @@ -826,23 +891,23 @@ empathy_account_manager_created_cb (TpAccountManager *proxy, GObject *weak_object) { EmpathyAccountManager *manager = EMPATHY_ACCOUNT_MANAGER (weak_object); - GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data); + EmpathyAccountManagerPriv *priv = GET_PRIV (manager); + GSimpleAsyncResult *my_res = user_data; EmpathyAccount *account; if (error != NULL) { - g_simple_async_result_set_from_error (result, (GError *) error); - g_simple_async_result_complete (result); - g_object_unref (G_OBJECT (result)); + g_simple_async_result_set_from_error (my_res, + (GError *) error); + g_simple_async_result_complete (my_res); + g_object_unref (my_res); + return; } account = account_manager_add_account (manager, account_path); - if (empathy_account_is_ready (account)) - empathy_account_manager_created_ready_cb (account, NULL, result); - else - g_signal_connect (account, "notify::ready", - G_CALLBACK (empathy_account_manager_created_ready_cb), result); + + g_hash_table_insert (priv->create_results, account, my_res); } void @@ -856,8 +921,11 @@ empathy_account_manager_create_account_async (EmpathyAccountManager *manager, gpointer user_data) { EmpathyAccountManagerPriv *priv = GET_PRIV (manager); - GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (manager), - callback, user_data, empathy_account_manager_create_account_finish); + GSimpleAsyncResult *res; + + res = g_simple_async_result_new + (G_OBJECT (manager), callback, user_data, + empathy_account_manager_create_account_finish); tp_cli_account_manager_call_create_account (priv->tp_manager, -1, @@ -867,7 +935,7 @@ empathy_account_manager_create_account_async (EmpathyAccountManager *manager, parameters, properties, empathy_account_manager_created_cb, - result, + res, NULL, G_OBJECT (manager)); } @@ -876,6 +944,8 @@ EmpathyAccount * empathy_account_manager_create_account_finish ( EmpathyAccountManager *manager, GAsyncResult *result, GError **error) { + EmpathyAccount *retval; + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) return NULL; @@ -883,7 +953,9 @@ empathy_account_manager_create_account_finish ( g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), empathy_account_manager_create_account_finish), NULL); - return EMPATHY_ACCOUNT (g_simple_async_result_get_op_res_gpointer ( + retval = EMPATHY_ACCOUNT (g_simple_async_result_get_op_res_gpointer ( G_SIMPLE_ASYNC_RESULT (result))); + + return retval; } diff --git a/libempathy/empathy-account-settings.c b/libempathy/empathy-account-settings.c index 0b92ec1b1..df99ea1c5 100644 --- a/libempathy/empathy-account-settings.c +++ b/libempathy/empathy-account-settings.c @@ -72,6 +72,7 @@ struct _EmpathyAccountSettingsPriv GHashTable *parameters; GArray *unset_parameters; + GArray *required_params; gulong managers_ready_id; gulong account_ready_id; @@ -360,6 +361,23 @@ empathy_account_settings_check_readyness (EmpathyAccountSettings *self) return; } + if (priv->required_params == NULL) + { + TpConnectionManagerParam *cur; + char *val; + + priv->required_params = g_array_new (TRUE, FALSE, sizeof (gchar *)); + + for (cur = priv->tp_protocol->params; cur->name != NULL; cur++) + { + if (tp_connection_manager_param_is_required (cur)) + { + val = g_strdup (cur->name); + g_array_append_val (priv->required_params, val); + } + } + } + g_object_ref (priv->manager); priv->ready = TRUE; @@ -430,13 +448,16 @@ empathy_account_settings_get_protocol (EmpathyAccountSettings *settings) return priv->protocol; } -const gchar * +gchar * empathy_account_settings_get_icon_name (EmpathyAccountSettings *settings) { EmpathyAccountSettingsPriv *priv = GET_PRIV (settings); if (priv->account != NULL) - return empathy_account_get_icon_name (priv->account); + return g_strdup (empathy_account_get_icon_name (priv->account)); + + if (priv->tp_protocol != NULL) + return g_strdup_printf ("im-%s", priv->tp_protocol->name); return NULL; } @@ -800,6 +821,26 @@ empathy_account_settings_set_boolean (EmpathyAccountSettings *settings, tp_asv_set_boolean (priv->parameters, param, value); } +static void +account_settings_display_name_set_cb (GObject *src, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + EmpathyAccount *account = EMPATHY_ACCOUNT (src); + GSimpleAsyncResult *set_result = user_data; + + empathy_account_set_display_name_finish (account, res, &error); + + if (error != NULL) + { + g_simple_async_result_set_from_error (set_result, error); + g_error_free (error); + } + + g_simple_async_result_complete (set_result); + g_object_unref (set_result); +} void empathy_account_settings_set_display_name_async ( @@ -808,6 +849,26 @@ empathy_account_settings_set_display_name_async ( GAsyncReadyCallback callback, gpointer user_data) { + EmpathyAccountSettingsPriv *priv = GET_PRIV (settings); + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (G_OBJECT (settings), + callback, user_data, empathy_account_settings_set_display_name_finish); + + if (priv->account == NULL) + { + if (priv->display_name != NULL) + g_free (priv->display_name); + + priv->display_name = g_strdup (name); + + g_simple_async_result_complete_in_idle (result); + + return; + } + + empathy_account_set_display_name_async (priv->account, name, + account_settings_display_name_set_cb, result); } gboolean @@ -816,6 +877,12 @@ empathy_account_settings_set_display_name_finish ( GAsyncResult *result, GError **error) { + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error)) + return FALSE; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, + G_OBJECT (settings), empathy_account_settings_set_display_name_finish), FALSE); return TRUE; } @@ -965,3 +1032,55 @@ empathy_account_settings_apply_finish (EmpathyAccountSettings *settings, return TRUE; } + +gboolean +empathy_account_settings_has_account (EmpathyAccountSettings *settings, + EmpathyAccount *account) +{ + EmpathyAccountSettingsPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE); + g_return_val_if_fail (EMPATHY_IS_ACCOUNT (account), FALSE); + + priv = GET_PRIV (settings); + + return (account == priv->account); +} + +gboolean +empathy_account_settings_is_valid (EmpathyAccountSettings *settings) +{ + EmpathyAccountSettingsPriv *priv; + int idx; + gchar *current; + gboolean missed = FALSE; + + g_return_val_if_fail (EMPATHY_IS_ACCOUNT_SETTINGS (settings), FALSE); + + priv = GET_PRIV (settings); + + for (idx = 0; idx < priv->required_params->len; idx++) + { + current = g_array_index (priv->required_params, gchar *, idx); + + /* first, look if it's set in our own parameters */ + if (tp_asv_lookup (priv->parameters, current)) + continue; + + /* if we did not unset the parameter, look if it's in the account */ + if (priv->account != NULL && + !empathy_account_settings_is_unset (settings, current)) + { + const GHashTable *account_params; + + account_params = empathy_account_get_parameters (priv->account); + if (tp_asv_lookup (account_params, current)) + continue; + } + + missed = TRUE; + break; + } + + return !missed; +} diff --git a/libempathy/empathy-account-settings.h b/libempathy/empathy-account-settings.h index d9231a50a..8ae692212 100644 --- a/libempathy/empathy-account-settings.h +++ b/libempathy/empathy-account-settings.h @@ -77,6 +77,9 @@ const gchar *empathy_account_settings_get_protocol ( EmpathyAccount *empathy_account_settings_get_account ( EmpathyAccountSettings *settings); +gboolean empathy_account_settings_has_account ( + EmpathyAccountSettings *settings, EmpathyAccount *account); + TpConnectionManagerParam *empathy_account_settings_get_tp_params ( EmpathyAccountSettings *settings); @@ -124,7 +127,7 @@ void empathy_account_settings_set_uint64 (EmpathyAccountSettings *settings, void empathy_account_settings_set_boolean (EmpathyAccountSettings *settings, const gchar *param, gboolean value); -const gchar *empathy_account_settings_get_icon_name ( +gchar *empathy_account_settings_get_icon_name ( EmpathyAccountSettings *settings); const gchar *empathy_account_settings_get_display_name ( @@ -150,6 +153,7 @@ gboolean empathy_account_settings_apply_finish ( GAsyncResult *result, GError **error); +gboolean empathy_account_settings_is_valid (EmpathyAccountSettings *settings); G_END_DECLS diff --git a/libempathy/empathy-account.c b/libempathy/empathy-account.c index df948b69c..ffb6e6786 100644 --- a/libempathy/empathy-account.c +++ b/libempathy/empathy-account.c @@ -32,6 +32,8 @@ #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT #include <libempathy/empathy-debug.h> +#include <glib/gi18n-lib.h> + #include "empathy-account.h" #include "empathy-utils.h" #include "empathy-marshal.h" @@ -998,6 +1000,63 @@ empathy_account_update_settings_finish (EmpathyAccount *account, } static void +account_display_name_set_cb (TpProxy *proxy, + const GError *error, + gpointer user_data, + GObject *weak_object) +{ + GSimpleAsyncResult *result = user_data; + + if (error != NULL) + g_simple_async_result_set_from_error (result, (GError *) error); + + g_simple_async_result_complete (result); + g_object_unref (result); +} + +void +empathy_account_set_display_name_async (EmpathyAccount *account, + const char *display_name, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + GValue value = {0, }; + EmpathyAccountPriv *priv = GET_PRIV (account); + + if (display_name == NULL) + { + g_simple_async_report_error_in_idle (G_OBJECT (account), + callback, user_data, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + _("Can't set an empty display name")); + return; + } + + result = g_simple_async_result_new (G_OBJECT (account), callback, + user_data, empathy_account_set_display_name_finish); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, display_name); + + tp_cli_dbus_properties_call_set (priv->account, -1, TP_IFACE_ACCOUNT, + "DisplayName", &value, account_display_name_set_cb, result, NULL, + G_OBJECT (account)); +} + +gboolean +empathy_account_set_display_name_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error) || + !g_simple_async_result_is_valid (result, G_OBJECT (account), + empathy_account_set_display_name_finish)) + return FALSE; + + return TRUE; +} + +static void empathy_account_remove_cb (TpAccount *proxy, const GError *error, gpointer user_data, diff --git a/libempathy/empathy-account.h b/libempathy/empathy-account.h index 00daa46ee..67939d748 100644 --- a/libempathy/empathy-account.h +++ b/libempathy/empathy-account.h @@ -84,8 +84,11 @@ void empathy_account_remove_async (EmpathyAccount *account, gboolean empathy_account_remove_finish (EmpathyAccount *account, GAsyncResult *result, GError **error); -void empathy_account_set_display_name (EmpathyAccount *account, - const gchar *display_name); +void empathy_account_set_display_name_async (EmpathyAccount *account, + const gchar *display_name, GAsyncReadyCallback callback, + gpointer user_data); +gboolean empathy_account_set_display_name_finish (EmpathyAccount *account, + GAsyncResult *result, GError **error); EmpathyAccount *empathy_account_new (TpDBusDaemon *bus_daemon, const gchar *unique_name); diff --git a/libempathy/empathy-connection-managers.c b/libempathy/empathy-connection-managers.c index 587a463a8..82699d3d6 100644 --- a/libempathy/empathy-connection-managers.c +++ b/libempathy/empathy-connection-managers.c @@ -295,3 +295,15 @@ empathy_connection_managers_get_cm (EmpathyConnectionManagers *managers, return NULL; } + +guint +empathy_connection_managers_get_cms_num (EmpathyConnectionManagers *managers) +{ + EmpathyConnectionManagersPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_CONNECTION_MANAGERS (managers), 0); + + priv = GET_PRIV (managers); + + return g_list_length (priv->cms); +} diff --git a/libempathy/empathy-connection-managers.h b/libempathy/empathy-connection-managers.h index 0c4147951..17289d36d 100644 --- a/libempathy/empathy-connection-managers.h +++ b/libempathy/empathy-connection-managers.h @@ -66,6 +66,8 @@ void empathy_connection_managers_update (EmpathyConnectionManagers *managers); GList * empathy_connection_managers_get_cms ( EmpathyConnectionManagers *managers); +guint empathy_connection_managers_get_cms_num + (EmpathyConnectionManagers *managers); TpConnectionManager *empathy_connection_managers_get_cm ( EmpathyConnectionManagers *managers, const gchar *cm); diff --git a/po/POTFILES.in b/po/POTFILES.in index 5260bb738..89387f58d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,6 +4,7 @@ data/empathy.desktop.in.in data/empathy.schemas.in +libempathy/empathy-account.c libempathy/empathy-ft-handler.c libempathy/empathy-tp-contact-list.c libempathy/empathy-tp-file.c @@ -20,7 +21,7 @@ libempathy-gtk/empathy-account-widget-irc.c [type: gettext/glade]libempathy-gtk/empathy-account-widget-irc.ui [type: gettext/glade]libempathy-gtk/empathy-account-widget-jabber.ui [type: gettext/glade]libempathy-gtk/empathy-account-widget-msn.ui -[type: gettext/glade]libempathy-gtk/empathy-account-widget-salut.ui +[type: gettext/glade]libempathy-gtk/empathy-account-widget-local-xmpp.ui [type: gettext/glade]libempathy-gtk/empathy-account-widget-sip.ui [type: gettext/glade]libempathy-gtk/empathy-account-widget-yahoo.ui libempathy-gtk/empathy-avatar-chooser.c diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c index 010493ff2..974b6dcc4 100644 --- a/src/empathy-accounts-dialog.c +++ b/src/empathy-accounts-dialog.c @@ -1,7 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2005-2007 Imendio AB - * Copyright (C) 2007-2008 Collabora Ltd. + * Copyright (C) 2007-2009 Collabora Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,6 +19,7 @@ * * Authors: Martyn Russell <martyn@imendio.com> * Xavier Claessens <xclaesse@gmail.com> + * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk> */ #include <config.h> @@ -35,7 +35,9 @@ #include <libempathy/empathy-utils.h> #include <libempathy/empathy-account-manager.h> +#include <libempathy/empathy-connection-managers.h> #include <libempathy-gtk/empathy-ui-utils.h> + #include <libempathy-gtk/empathy-protocol-chooser.h> #include <libempathy-gtk/empathy-account-widget.h> #include <libempathy-gtk/empathy-account-widget-irc.h> @@ -54,1265 +56,1447 @@ /* Flashing delay for icons (milliseconds). */ #define FLASH_TIMEOUT 500 +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog) +G_DEFINE_TYPE (EmpathyAccountsDialog, empathy_accounts_dialog, G_TYPE_OBJECT); + +static EmpathyAccountsDialog *dialog_singleton = NULL; + typedef struct { - GtkWidget *window; + GtkWidget *window; + + GtkWidget *alignment_settings; + + GtkWidget *vbox_details; + GtkWidget *frame_no_protocol; - GtkWidget *alignment_settings; + GtkWidget *treeview; - GtkWidget *vbox_details; - GtkWidget *frame_no_protocol; + GtkWidget *button_add; + GtkWidget *button_remove; + GtkWidget *button_import; - GtkWidget *treeview; + GtkWidget *frame_new_account; + GtkWidget *combobox_protocol; + GtkWidget *hbox_type; + GtkWidget *button_create; + GtkWidget *button_back; + GtkWidget *radiobutton_reuse; + GtkWidget *radiobutton_register; - GtkWidget *button_add; - GtkWidget *button_remove; - GtkWidget *button_import; + GtkWidget *image_type; + GtkWidget *label_name; + GtkWidget *label_type; + GtkWidget *settings_widget; - GtkWidget *frame_new_account; - GtkWidget *combobox_protocol; - GtkWidget *hbox_type; - GtkWidget *button_create; - GtkWidget *button_back; - GtkWidget *radiobutton_reuse; - GtkWidget *radiobutton_register; + gboolean connecting_show; + guint connecting_id; - GtkWidget *image_type; - GtkWidget *label_name; - GtkWidget *label_type; - GtkWidget *settings_widget; + gulong settings_ready_id; + EmpathyAccountSettings *settings_ready; - gboolean connecting_show; - guint connecting_id; + EmpathyAccountManager *account_manager; + EmpathyConnectionManagers *cms; - gulong settings_ready_id; - EmpathyAccountSettings *settings_ready; + GtkWindow *parent_window; + EmpathyAccount *initial_selection; +} EmpathyAccountsDialogPriv; - EmpathyAccountManager *account_manager; -} EmpathyAccountsDialog; +enum { + COL_ENABLED, + COL_NAME, + COL_STATUS, + COL_ACCOUNT_POINTER, + COL_ACCOUNT_SETTINGS_POINTER, + COL_COUNT +}; enum { - COL_ENABLED, - COL_NAME, - COL_STATUS, - COL_ACCOUNT_POINTER, - COL_ACCOUNT_SETTINGS_POINTER, - COL_COUNT + PROP_PARENT = 1 }; -static void accounts_dialog_update (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings); -static void accounts_dialog_model_setup (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog); -static void accounts_dialog_name_editing_started_cb (GtkCellRenderer *renderer, - GtkCellEditable *editable, - gchar *path, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings); -static gboolean accounts_dialog_model_remove_selected (EmpathyAccountsDialog *dialog); -static void accounts_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_account_added_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_account_removed_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog); -static gboolean accounts_dialog_row_changed_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data); -static gboolean accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog *dialog); -static void accounts_dialog_connection_changed_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_create_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_back_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_add_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_help_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_button_remove_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); +static void accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings); + #if 0 /* FIXME MC-5 */ -static void accounts_dialog_button_import_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog); +static void accounts_dialog_button_import_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog); #endif -static void accounts_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyAccountsDialog *dialog); -static void accounts_dialog_destroy_cb (GtkWidget *widget, - EmpathyAccountsDialog *dialog); static void accounts_dialog_update_name_label (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) + EmpathyAccountSettings *settings) { - gchar *text; + gchar *text; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - text = g_markup_printf_escaped ("<big><b>%s</b></big>", - empathy_account_settings_get_display_name (settings)); - gtk_label_set_markup (GTK_LABEL (dialog->label_name), text); + text = g_markup_printf_escaped ("<big><b>%s</b></big>", + empathy_account_settings_get_display_name (settings)); + gtk_label_set_markup (GTK_LABEL (priv->label_name), text); - g_free (text); + g_free (text); } -typedef GtkWidget *CreateWidget (EmpathyAccountSettings *); - static GtkWidget * get_account_setup_widget (EmpathyAccountSettings *settings) { - const gchar *cm = empathy_account_settings_get_cm (settings); - const gchar *proto = empathy_account_settings_get_protocol (settings); - struct { - const gchar *cm; - const gchar *proto; - CreateWidget *cb; - } dialogs[] = { - { "gabble", "jabber", empathy_account_widget_jabber_new}, - { "butterfly", "msn", empathy_account_widget_msn_new}, - { "salut", "local-xmpp", empathy_account_widget_salut_new}, - { "idle", "irc", empathy_account_widget_irc_new}, - { "haze", "icq", empathy_account_widget_icq_new}, - { "haze", "aim", empathy_account_widget_aim_new}, - { "haze", "yahoo", empathy_account_widget_yahoo_new}, - { "haze", "groupwise", empathy_account_widget_groupwise_new}, - { "sofiasip", "sip", empathy_account_widget_sip_new}, - { NULL, NULL, NULL } - }; - int i; - - for (i = 0; dialogs[i].cm != NULL; i++) { - if (!tp_strdiff (cm, dialogs[i].cm) - && !tp_strdiff (proto, dialogs[i].proto)) - return dialogs[i].cb (settings); - } - - return empathy_account_widget_generic_new (settings); + const gchar *cm = empathy_account_settings_get_cm (settings); + const gchar *proto = empathy_account_settings_get_protocol (settings); + + struct { + const gchar *cm; + const gchar *proto; + } dialogs[] = { + { "gabble", "jabber" }, + { "butterfly", "msn" }, + { "salut", "local-xmpp" }, + { "idle", "irc" }, + { "haze", "icq" }, + { "haze", "aim" }, + { "haze", "yahoo" }, + { "haze", "groupwise" }, + { "sofiasip", "sip" }, + { NULL, NULL } + }; + int i; + + for (i = 0; dialogs[i].cm != NULL; i++) + { + if (!tp_strdiff (cm, dialogs[i].cm) + && !tp_strdiff (proto, dialogs[i].proto)) + return empathy_account_widget_new_for_protocol (dialogs[i].proto, settings); + } + + return empathy_account_widget_new_for_protocol ("generic", settings); } - static void account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) + EmpathyAccountSettings *settings) { - dialog->settings_widget = get_account_setup_widget (settings); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + gchar *icon_name; - gtk_container_add (GTK_CONTAINER (dialog->alignment_settings), - dialog->settings_widget); - gtk_widget_show (dialog->settings_widget); + priv->settings_widget = get_account_setup_widget (settings); + gtk_container_add (GTK_CONTAINER (priv->alignment_settings), + priv->settings_widget); + gtk_widget_show (priv->settings_widget); - gtk_image_set_from_icon_name (GTK_IMAGE (dialog->image_type), - empathy_account_settings_get_icon_name (settings), - GTK_ICON_SIZE_DIALOG); - gtk_widget_set_tooltip_text (dialog->image_type, - empathy_account_settings_get_protocol (settings)); + icon_name = empathy_account_settings_get_icon_name (settings); - accounts_dialog_update_name_label (dialog, settings); + gtk_image_set_from_icon_name (GTK_IMAGE (priv->image_type), + icon_name, GTK_ICON_SIZE_DIALOG); + gtk_widget_set_tooltip_text (priv->image_type, + empathy_account_settings_get_protocol (settings)); + + accounts_dialog_update_name_label (dialog, settings); + + g_free (icon_name); } static void account_dialog_settings_ready_cb (EmpathyAccountSettings *settings, - GParamSpec *spec, EmpathyAccountsDialog *dialog) + GParamSpec *spec, + EmpathyAccountsDialog *dialog) { - if (empathy_account_settings_is_ready (settings)) - account_dialog_create_settings_widget (dialog, settings); + if (empathy_account_settings_is_ready (settings)) + account_dialog_create_settings_widget (dialog, settings); } static void -accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) +accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog) { - if (dialog->settings_ready != NULL) { - g_signal_handler_disconnect (dialog->settings_ready, - dialog->settings_ready_id); - dialog->settings_ready = NULL; - dialog->settings_ready_id = 0; - } - - if (!settings) { - GtkTreeView *view; - GtkTreeModel *model; - - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - - if (gtk_tree_model_iter_n_children (model, NULL) > 0) { - /* We have configured accounts, select the first one */ - accounts_dialog_model_select_first (dialog); - return; - } - if (empathy_protocol_chooser_n_protocols ( - EMPATHY_PROTOCOL_CHOOSER (dialog->combobox_protocol)) > 0) { - /* We have no account configured but we have some - * profiles instsalled. The user obviously wants to add - * an account. Click on the Add button for him. */ - accounts_dialog_button_add_clicked_cb (dialog->button_add, - dialog); - return; - } - - /* No account and no profile, warn the user */ - gtk_widget_hide (dialog->vbox_details); - gtk_widget_hide (dialog->frame_new_account); - gtk_widget_show (dialog->frame_no_protocol); - gtk_widget_set_sensitive (dialog->button_add, FALSE); - gtk_widget_set_sensitive (dialog->button_remove, FALSE); - return; - } - - /* We have an account selected, destroy old settings and create a new - * one for the account selected */ - gtk_widget_hide (dialog->frame_new_account); - gtk_widget_hide (dialog->frame_no_protocol); - gtk_widget_show (dialog->vbox_details); - gtk_widget_set_sensitive (dialog->button_add, TRUE); - gtk_widget_set_sensitive (dialog->button_remove, TRUE); - - if (dialog->settings_widget) { - gtk_widget_destroy (dialog->settings_widget); - dialog->settings_widget = NULL; - } - - if (empathy_account_settings_is_ready (settings)) - { - account_dialog_create_settings_widget (dialog, settings); - } - else - { - dialog->settings_ready = settings; - dialog->settings_ready_id = - g_signal_connect (settings, "notify::ready", - G_CALLBACK (account_dialog_settings_ready_cb), dialog); - } - + GtkTreeView *view; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + /* select first */ + view = GTK_TREE_VIEW (priv->treeview); + model = gtk_tree_view_get_model (view); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + selection = gtk_tree_view_get_selection (view); + gtk_tree_selection_select_iter (selection, &iter); + } + else + { + accounts_dialog_update_settings (dialog, NULL); + } } static void -accounts_dialog_model_setup (EmpathyAccountsDialog *dialog) +accounts_dialog_protocol_changed_cb (GtkWidget *widget, + EmpathyAccountsDialog *dialog) { - GtkListStore *store; - GtkTreeSelection *selection; - - store = gtk_list_store_new (COL_COUNT, - G_TYPE_BOOLEAN, /* enabled */ - G_TYPE_STRING, /* name */ - G_TYPE_UINT, /* status */ - EMPATHY_TYPE_ACCOUNT, /* account */ - EMPATHY_TYPE_ACCOUNT_SETTINGS); /* settings */ + TpConnectionManager *cm; + TpConnectionManagerProtocol *proto; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + cm = empathy_protocol_chooser_dup_selected ( + EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto); + + if (tp_connection_manager_protocol_can_register (proto)) + { + gtk_widget_show (priv->radiobutton_register); + gtk_widget_show (priv->radiobutton_reuse); + } + else + { + gtk_widget_hide (priv->radiobutton_register); + gtk_widget_hide (priv->radiobutton_reuse); + } + g_object_unref (cm); +} - gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview), - GTK_TREE_MODEL (store)); +static void +accounts_dialog_button_add_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) +{ + GtkTreeView *view; + GtkTreeSelection *selection; + GtkTreeModel *model; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + view = GTK_TREE_VIEW (priv->treeview); + model = gtk_tree_view_get_model (view); + selection = gtk_tree_view_get_selection (view); + gtk_tree_selection_unselect_all (selection); + + gtk_widget_set_sensitive (priv->button_add, FALSE); + gtk_widget_set_sensitive (priv->button_remove, FALSE); + gtk_widget_hide (priv->vbox_details); + gtk_widget_hide (priv->frame_no_protocol); + gtk_widget_show (priv->frame_new_account); + + /* If we have no account, no need of a back button */ + if (gtk_tree_model_iter_n_children (model, NULL) > 0) + gtk_widget_show (priv->button_back); + else + gtk_widget_hide (priv->button_back); + + accounts_dialog_protocol_changed_cb (priv->radiobutton_register, dialog); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->radiobutton_reuse), + TRUE); + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combobox_protocol), 0); + gtk_widget_grab_focus (priv->combobox_protocol); +} - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); +static void +accounts_dialog_update_settings (EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings) +{ + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (priv->settings_ready != NULL) + { + g_signal_handler_disconnect (priv->settings_ready, + priv->settings_ready_id); + priv->settings_ready = NULL; + priv->settings_ready_id = 0; + } + + if (!settings) + { + GtkTreeView *view; + GtkTreeModel *model; + + view = GTK_TREE_VIEW (priv->treeview); + model = gtk_tree_view_get_model (view); + + if (gtk_tree_model_iter_n_children (model, NULL) > 0) + { + /* We have configured accounts, select the first one */ + accounts_dialog_model_select_first (dialog); + return; + } + if (empathy_connection_managers_get_cms_num (priv->cms) > 0) + { + /* We have no account configured but we have some + * profiles instsalled. The user obviously wants to add + * an account. Click on the Add button for him. */ + accounts_dialog_button_add_clicked_cb (priv->button_add, + dialog); + return; + } + + /* No account and no profile, warn the user */ + gtk_widget_hide (priv->vbox_details); + gtk_widget_hide (priv->frame_new_account); + gtk_widget_show (priv->frame_no_protocol); + gtk_widget_set_sensitive (priv->button_add, FALSE); + gtk_widget_set_sensitive (priv->button_remove, FALSE); + return; + } + + /* We have an account selected, destroy old settings and create a new + * one for the account selected */ + gtk_widget_hide (priv->frame_new_account); + gtk_widget_hide (priv->frame_no_protocol); + gtk_widget_show (priv->vbox_details); + gtk_widget_set_sensitive (priv->button_add, TRUE); + gtk_widget_set_sensitive (priv->button_remove, TRUE); + + if (priv->settings_widget) + { + gtk_widget_destroy (priv->settings_widget); + priv->settings_widget = NULL; + } + + if (empathy_account_settings_is_ready (settings)) + { + account_dialog_create_settings_widget (dialog, settings); + } + else + { + priv->settings_ready = settings; + priv->settings_ready_id = + g_signal_connect (settings, "notify::ready", + G_CALLBACK (account_dialog_settings_ready_cb), dialog); + } - g_signal_connect (selection, "changed", - G_CALLBACK (accounts_dialog_model_selection_changed), - dialog); +} - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - COL_NAME, GTK_SORT_ASCENDING); +static void +accounts_dialog_name_editing_started_cb (GtkCellRenderer *renderer, + GtkCellEditable *editable, + gchar *path, + EmpathyAccountsDialog *dialog) +{ + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - accounts_dialog_model_add_columns (dialog); + if (priv->connecting_id) + g_source_remove (priv->connecting_id); - g_object_unref (store); + DEBUG ("Editing account name started; stopping flashing"); } static void -accounts_dialog_name_edited_cb (GtkCellRendererText *renderer, - gchar *path, - gchar *new_text, - EmpathyAccountsDialog *dialog) +accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + EmpathyAccountsDialog *dialog) { - EmpathyAccountSettings *settings; - GtkTreeModel *model; - GtkTreePath *treepath; - GtkTreeIter iter; - - if (empathy_account_manager_get_connecting_accounts (dialog->account_manager) > 0) { - dialog->connecting_id = g_timeout_add (FLASH_TIMEOUT, - (GSourceFunc) accounts_dialog_flash_connecting_cb, - dialog); - } - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - treepath = gtk_tree_path_new_from_string (path); - gtk_tree_model_get_iter (model, &iter, treepath); - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_SETTINGS_POINTER, &settings, - -1); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_NAME, new_text, - -1); - gtk_tree_path_free (treepath); - - empathy_account_settings_set_display_name_async (settings, new_text, - NULL, NULL); - g_object_unref (settings); + EmpathyAccountSettings *settings; + gchar *icon_name; + GdkPixbuf *pixbuf; + TpConnectionStatus status; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + gtk_tree_model_get (model, iter, + COL_STATUS, &status, + COL_ACCOUNT_SETTINGS_POINTER, &settings, + -1); + + icon_name = empathy_account_settings_get_icon_name (settings); + pixbuf = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON); + + g_free (icon_name); + + if (pixbuf) + { + if (status == TP_CONNECTION_STATUS_DISCONNECTED || + (status == TP_CONNECTION_STATUS_CONNECTING && + !priv->connecting_show)) + { + GdkPixbuf *modded_pixbuf; + + modded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, + TRUE, + 8, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + + gdk_pixbuf_saturate_and_pixelate (pixbuf, + modded_pixbuf, + 1.0, + TRUE); + g_object_unref (pixbuf); + pixbuf = modded_pixbuf; + } + } + + g_object_set (cell, + "visible", TRUE, + "pixbuf", pixbuf, + NULL); + + g_object_unref (settings); + + if (pixbuf) + g_object_unref (pixbuf); } static void accounts_dialog_enable_toggled_cb (GtkCellRendererToggle *cell_renderer, - gchar *path, - EmpathyAccountsDialog *dialog) + gchar *path, + EmpathyAccountsDialog *dialog) { - EmpathyAccount *account; - GtkTreeModel *model; - GtkTreePath *treepath; - GtkTreeIter iter; - gboolean enabled; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - treepath = gtk_tree_path_new_from_string (path); - gtk_tree_model_get_iter (model, &iter, treepath); - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_POINTER, &account, - -1); - gtk_tree_path_free (treepath); - - if (account == NULL) - return; - - enabled = empathy_account_is_enabled (account); - empathy_account_set_enabled (account, !enabled); - - DEBUG ("%s account %s", enabled ? "Disabled" : "Enable", - empathy_account_get_display_name (account)); - - g_object_unref (account); + EmpathyAccount *account; + GtkTreeModel *model; + GtkTreePath *treepath; + GtkTreeIter iter; + gboolean enabled; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + treepath = gtk_tree_path_new_from_string (path); + gtk_tree_model_get_iter (model, &iter, treepath); + gtk_tree_model_get (model, &iter, + COL_ACCOUNT_POINTER, &account, + -1); + gtk_tree_path_free (treepath); + + if (account == NULL) + return; + + enabled = empathy_account_is_enabled (account); + empathy_account_set_enabled (account, !enabled); + + DEBUG ("%s account %s", enabled ? "Disabled" : "Enable", + empathy_account_get_display_name (account)); + + g_object_unref (account); } -static void -accounts_dialog_name_editing_started_cb (GtkCellRenderer *renderer, - GtkCellEditable *editable, - gchar *path, - EmpathyAccountsDialog *dialog) +static gboolean +accounts_dialog_row_changed_foreach (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer user_data) { - if (dialog->connecting_id) { - g_source_remove (dialog->connecting_id); - } - DEBUG ("Editing account name started; stopping flashing"); + gtk_tree_model_row_changed (model, path, iter); + + return FALSE; } -static void -accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) +static gboolean +accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - - view = GTK_TREE_VIEW (dialog->treeview); - gtk_tree_view_set_headers_visible (view, TRUE); - - /* Enabled column */ - cell = gtk_cell_renderer_toggle_new (); - gtk_tree_view_insert_column_with_attributes (view, -1, - _("Enabled"), - cell, - "active", COL_ENABLED, - NULL); - g_signal_connect (cell, "toggled", - G_CALLBACK (accounts_dialog_enable_toggled_cb), - dialog); - - /* Account column */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Accounts")); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - /* Icon renderer */ - cell = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_set_cell_data_func (column, cell, - (GtkTreeCellDataFunc) - accounts_dialog_model_pixbuf_data_func, - dialog, - NULL); - - /* Name renderer */ - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "ellipsize", PANGO_ELLIPSIZE_END, - "width-chars", 25, - "editable", TRUE, - NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); - g_signal_connect (cell, "edited", - G_CALLBACK (accounts_dialog_name_edited_cb), - dialog); - g_signal_connect (cell, "editing-started", - G_CALLBACK (accounts_dialog_name_editing_started_cb), - dialog); + GtkTreeView *view; + GtkTreeModel *model; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + priv->connecting_show = !priv->connecting_show; + + view = GTK_TREE_VIEW (priv->treeview); + model = gtk_tree_view_get_model (view); + + gtk_tree_model_foreach (model, accounts_dialog_row_changed_foreach, NULL); + + return TRUE; } static void -accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog) +accounts_dialog_name_edited_cb (GtkCellRendererText *renderer, + gchar *path, + gchar *new_text, + EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - - /* select first */ - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - - if (gtk_tree_model_get_iter_first (model, &iter)) { - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_select_iter (selection, &iter); - } else { - accounts_dialog_update_settings (dialog, NULL); - } + EmpathyAccountSettings *settings; + GtkTreeModel *model; + GtkTreePath *treepath; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (empathy_account_manager_get_connecting_accounts + (priv->account_manager) > 0) + { + priv->connecting_id = g_timeout_add (FLASH_TIMEOUT, + (GSourceFunc) accounts_dialog_flash_connecting_cb, + dialog); + } + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + treepath = gtk_tree_path_new_from_string (path); + gtk_tree_model_get_iter (model, &iter, treepath); + gtk_tree_model_get (model, &iter, + COL_ACCOUNT_SETTINGS_POINTER, &settings, + -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_NAME, new_text, + -1); + gtk_tree_path_free (treepath); + + empathy_account_settings_set_display_name_async (settings, new_text, + NULL, NULL); + g_object_unref (settings); } static void -accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - EmpathyAccountsDialog *dialog) +accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) { - EmpathyAccountSettings *settings; - const gchar *icon_name; - GdkPixbuf *pixbuf; - TpConnectionStatus status; - - gtk_tree_model_get (model, iter, - COL_STATUS, &status, - COL_ACCOUNT_SETTINGS_POINTER, &settings, - -1); - - icon_name = empathy_account_settings_get_icon_name (settings); - pixbuf = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON); - - if (pixbuf) { - if (status == TP_CONNECTION_STATUS_DISCONNECTED || - (status == TP_CONNECTION_STATUS_CONNECTING && - !dialog->connecting_show)) { - GdkPixbuf *modded_pixbuf; - - modded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, - TRUE, - 8, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - - gdk_pixbuf_saturate_and_pixelate (pixbuf, - modded_pixbuf, - 1.0, - TRUE); - g_object_unref (pixbuf); - pixbuf = modded_pixbuf; - } - } - - g_object_set (cell, - "visible", TRUE, - "pixbuf", pixbuf, - NULL); - - g_object_unref (settings); - if (pixbuf) { - g_object_unref (pixbuf); - } + GtkTreeView *view; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + view = GTK_TREE_VIEW (priv->treeview); + gtk_tree_view_set_headers_visible (view, TRUE); + + /* Enabled column */ + cell = gtk_cell_renderer_toggle_new (); + gtk_tree_view_insert_column_with_attributes (view, -1, + _("Enabled"), + cell, + "active", COL_ENABLED, + NULL); + g_signal_connect (cell, "toggled", + G_CALLBACK (accounts_dialog_enable_toggled_cb), + dialog); + + /* Account column */ + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, _("Accounts")); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (view, column); + + /* Icon renderer */ + cell = gtk_cell_renderer_pixbuf_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_cell_data_func (column, cell, + (GtkTreeCellDataFunc) + accounts_dialog_model_pixbuf_data_func, + dialog, + NULL); + + /* Name renderer */ + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, + "ellipsize", PANGO_ELLIPSIZE_END, + "width-chars", 25, + "editable", TRUE, + NULL); + gtk_tree_view_column_pack_start (column, cell, TRUE); + gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); + g_signal_connect (cell, "edited", + G_CALLBACK (accounts_dialog_name_edited_cb), + dialog); + g_signal_connect (cell, "editing-started", + G_CALLBACK (accounts_dialog_name_editing_started_cb), + dialog); } -static gboolean -accounts_dialog_get_settings_iter (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings, - GtkTreeIter *iter) +static EmpathyAccountSettings * +accounts_dialog_model_get_selected_settings (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; - gboolean ok; - - /* Update the status in the model */ - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - - for (ok = gtk_tree_model_get_iter_first (model, iter); - ok; - ok = gtk_tree_model_iter_next (model, iter)) { - EmpathyAccountSettings *this_settings; - gboolean equal; - - gtk_tree_model_get (model, iter, - COL_ACCOUNT_SETTINGS_POINTER, &this_settings, - -1); - - equal = (this_settings == settings); - g_object_unref (this_settings); - - if (equal) { - return TRUE; - } - } - - return FALSE; + GtkTreeView *view; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccountSettings *settings; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + view = GTK_TREE_VIEW (priv->treeview); + selection = gtk_tree_view_get_selection (view); + + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return NULL; + + gtk_tree_model_get (model, &iter, + COL_ACCOUNT_SETTINGS_POINTER, &settings, -1); + + return settings; } -static gboolean -accounts_dialog_get_account_iter (EmpathyAccountsDialog *dialog, - EmpathyAccount *account, - GtkTreeIter *iter) +static void +accounts_dialog_model_selection_changed (GtkTreeSelection *selection, + EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; - gboolean ok; - - /* Update the status in the model */ - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); - model = gtk_tree_view_get_model (view); - - for (ok = gtk_tree_model_get_iter_first (model, iter); - ok; - ok = gtk_tree_model_iter_next (model, iter)) { - EmpathyAccount *this_account; - gboolean equal; - - gtk_tree_model_get (model, iter, - COL_ACCOUNT_POINTER, &this_account, - -1); - - equal = (this_account == account); - g_object_unref (this_account); - - if (equal) { - return TRUE; - } - } - - return FALSE; + EmpathyAccountSettings *settings; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean is_selection; + + is_selection = gtk_tree_selection_get_selected (selection, &model, &iter); + + settings = accounts_dialog_model_get_selected_settings (dialog); + accounts_dialog_update_settings (dialog, settings); + + if (settings) + g_object_unref (settings); } -static EmpathyAccountSettings * -accounts_dialog_model_get_selected_settings (EmpathyAccountsDialog *dialog) +static void +accounts_dialog_model_setup (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - EmpathyAccountSettings *settings; + GtkListStore *store; + GtkTreeSelection *selection; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + store = gtk_list_store_new (COL_COUNT, + G_TYPE_BOOLEAN, /* enabled */ + G_TYPE_STRING, /* name */ + G_TYPE_UINT, /* status */ + EMPATHY_TYPE_ACCOUNT, /* account */ + EMPATHY_TYPE_ACCOUNT_SETTINGS); /* settings */ + + gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview), + GTK_TREE_MODEL (store)); - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return NULL; - } + g_signal_connect (selection, "changed", + G_CALLBACK (accounts_dialog_model_selection_changed), + dialog); - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_SETTINGS_POINTER, &settings, -1); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), + COL_NAME, GTK_SORT_ASCENDING); - return settings; + accounts_dialog_model_add_columns (dialog); + + g_object_unref (store); +} + +static gboolean +accounts_dialog_get_settings_iter (EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings, + GtkTreeIter *iter) +{ + GtkTreeView *view; + GtkTreeSelection *selection; + GtkTreeModel *model; + gboolean ok; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + /* Update the status in the model */ + view = GTK_TREE_VIEW (priv->treeview); + selection = gtk_tree_view_get_selection (view); + model = gtk_tree_view_get_model (view); + + for (ok = gtk_tree_model_get_iter_first (model, iter); + ok; + ok = gtk_tree_model_iter_next (model, iter)) + { + EmpathyAccountSettings *this_settings; + gboolean equal; + + gtk_tree_model_get (model, iter, + COL_ACCOUNT_SETTINGS_POINTER, &this_settings, + -1); + + equal = (this_settings == settings); + g_object_unref (this_settings); + + if (equal) + return TRUE; + } + + return FALSE; } +static gboolean +accounts_dialog_get_account_iter (EmpathyAccountsDialog *dialog, + EmpathyAccount *account, + GtkTreeIter *iter) +{ + GtkTreeView *view; + GtkTreeSelection *selection; + GtkTreeModel *model; + gboolean ok; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + /* Update the status in the model */ + view = GTK_TREE_VIEW (priv->treeview); + selection = gtk_tree_view_get_selection (view); + model = gtk_tree_view_get_model (view); + + for (ok = gtk_tree_model_get_iter_first (model, iter); + ok; + ok = gtk_tree_model_iter_next (model, iter)) + { + EmpathyAccountSettings *settings; + gboolean equal; + + gtk_tree_model_get (model, iter, + COL_ACCOUNT_SETTINGS_POINTER, &settings, + -1); + + equal = empathy_account_settings_has_account + (settings, account); + g_object_unref (settings); + + if (equal) + return TRUE; + } + + return FALSE; +} static EmpathyAccount * accounts_dialog_model_get_selected_account (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - EmpathyAccount *account; + GtkTreeView *view; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccount *account; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); + view = GTK_TREE_VIEW (priv->treeview); + selection = gtk_tree_view_get_selection (view); - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return NULL; - } + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return NULL; - gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1); + gtk_tree_model_get (model, &iter, COL_ACCOUNT_POINTER, &account, -1); - return account; + return account; } static void accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) + EmpathyAccountSettings *settings) { - GtkTreeSelection *selection; - GtkTreeIter iter; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->treeview)); - if (accounts_dialog_get_settings_iter (dialog, settings, &iter)) { - gtk_tree_selection_select_iter (selection, &iter); - } + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + if (accounts_dialog_get_settings_iter (dialog, settings, &iter)) + gtk_tree_selection_select_iter (selection, &iter); } static gboolean accounts_dialog_model_remove_selected (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - EmpathyAccount *account; + GtkTreeView *view; + GtkTreeModel *model; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccount *account; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - view = GTK_TREE_VIEW (dialog->treeview); - selection = gtk_tree_view_get_selection (view); + view = GTK_TREE_VIEW (priv->treeview); + selection = gtk_tree_view_get_selection (view); - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return FALSE; - } + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return FALSE; - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_POINTER, &account, - -1); + gtk_tree_model_get (model, &iter, + COL_ACCOUNT_POINTER, &account, + -1); - if (account != NULL) - empathy_account_remove_async (account, NULL, NULL); + if (account != NULL) + empathy_account_remove_async (account, NULL, NULL); - return gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + return gtk_list_store_remove (GTK_LIST_STORE (model), &iter); } static void -accounts_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyAccountsDialog *dialog) +accounts_dialog_add (EmpathyAccountsDialog *dialog, + EmpathyAccountSettings *settings) { - EmpathyAccountSettings *settings; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean is_selection; - - is_selection = gtk_tree_selection_get_selected (selection, &model, &iter); - - settings = accounts_dialog_model_get_selected_settings (dialog); - accounts_dialog_update_settings (dialog, settings); - - if (settings) { - g_object_unref (settings); - } + GtkTreeModel *model; + GtkTreeIter iter; + const gchar *name; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + name = empathy_account_settings_get_display_name (settings); + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_ENABLED, FALSE, + COL_NAME, name, + COL_STATUS, TP_CONNECTION_STATUS_DISCONNECTED, + COL_ACCOUNT_SETTINGS_POINTER, settings, + -1); } static void -accounts_dialog_add (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) +accounts_dialog_connection_changed_cb (EmpathyAccountManager *manager, + EmpathyAccount *account, + TpConnectionStatusReason reason, + TpConnectionStatus current, + TpConnectionStatus previous, + EmpathyAccountsDialog *dialog) { - GtkTreeModel *model; - GtkTreeIter iter; - const gchar *name; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - name = empathy_account_settings_get_display_name (settings); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, FALSE, - COL_NAME, name, - COL_STATUS, TP_CONNECTION_STATUS_DISCONNECTED, - COL_ACCOUNT_SETTINGS_POINTER, settings, - -1); + GtkTreeModel *model; + GtkTreeIter iter; + gboolean found; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + /* Update the status in the model */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + if (accounts_dialog_get_account_iter (dialog, account, &iter)) + { + GtkTreePath *path; + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_STATUS, current, + -1); + + path = gtk_tree_model_get_path (model, &iter); + gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); + } + + found = (empathy_account_manager_get_connecting_accounts (manager) > 0); + + if (!found && priv->connecting_id) + { + g_source_remove (priv->connecting_id); + priv->connecting_id = 0; + } + + if (found && !priv->connecting_id) + priv->connecting_id = g_timeout_add (FLASH_TIMEOUT, + (GSourceFunc) accounts_dialog_flash_connecting_cb, + dialog); } - static void accounts_dialog_add_account (EmpathyAccountsDialog *dialog, - EmpathyAccount *account) + EmpathyAccount *account) { - EmpathyAccountSettings *settings; - GtkTreeModel *model; - GtkTreeIter iter; - TpConnectionStatus status; - const gchar *name; - gboolean enabled; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - g_object_get (account, "status", &status, NULL); - name = empathy_account_get_display_name (account); - enabled = empathy_account_is_enabled (account); - - gtk_list_store_append (GTK_LIST_STORE (model), &iter); - - settings = empathy_account_settings_new_for_account (account); - - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, - COL_NAME, name, - COL_STATUS, status, - COL_ACCOUNT_POINTER, account, - COL_ACCOUNT_SETTINGS_POINTER, settings, - -1); - - accounts_dialog_connection_changed_cb (dialog->account_manager, - account, - TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED, - status, - TP_CONNECTION_STATUS_DISCONNECTED, - dialog); - - g_object_unref (settings); + EmpathyAccountSettings *settings; + GtkTreeModel *model; + GtkTreeIter iter; + TpConnectionStatus status; + const gchar *name; + gboolean enabled; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + g_object_get (account, "connection-status", &status, NULL); + name = empathy_account_get_display_name (account); + enabled = empathy_account_is_enabled (account); + + if (!accounts_dialog_get_account_iter (dialog, account, &iter)) + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + settings = empathy_account_settings_new_for_account (account); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_ENABLED, enabled, + COL_NAME, name, + COL_STATUS, status, + COL_ACCOUNT_POINTER, account, + COL_ACCOUNT_SETTINGS_POINTER, settings, + -1); + + accounts_dialog_connection_changed_cb (priv->account_manager, + account, + TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED, + status, + TP_CONNECTION_STATUS_DISCONNECTED, + dialog); + + g_object_unref (settings); } static void accounts_dialog_update (EmpathyAccountsDialog *dialog, - EmpathyAccountSettings *settings) + EmpathyAccountSettings *settings) { - GtkTreeModel *model; - GtkTreeIter iter; - TpConnectionStatus status = TP_CONNECTION_STATUS_DISCONNECTED; - const gchar *name; - gboolean enabled = FALSE; - EmpathyAccount *account; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - name = empathy_account_settings_get_display_name (settings); - - account = empathy_account_settings_get_account (settings); - if (account != NULL) - { - enabled = empathy_account_is_enabled (account); - g_object_get (account, "connection-status", &status, NULL); - } - - accounts_dialog_get_settings_iter (dialog, settings, &iter); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, - COL_NAME, name, - COL_STATUS, status, - COL_ACCOUNT_POINTER, account, - COL_ACCOUNT_SETTINGS_POINTER, settings, - -1); + GtkTreeModel *model; + GtkTreeIter iter; + TpConnectionStatus status = TP_CONNECTION_STATUS_DISCONNECTED; + const gchar *name; + gboolean enabled = FALSE; + EmpathyAccount *account; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + name = empathy_account_settings_get_display_name (settings); + + account = empathy_account_settings_get_account (settings); + if (account != NULL) + { + enabled = empathy_account_is_enabled (account); + g_object_get (account, "connection-status", &status, NULL); + } + + accounts_dialog_get_settings_iter (dialog, settings, &iter); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_ENABLED, enabled, + COL_NAME, name, + COL_STATUS, status, + COL_ACCOUNT_POINTER, account, + COL_ACCOUNT_SETTINGS_POINTER, settings, + -1); } static void accounts_dialog_account_added_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog) + EmpathyAccount *account, + EmpathyAccountsDialog *dialog) { - accounts_dialog_add_account (dialog, account); + accounts_dialog_add_account (dialog, account); } static void accounts_dialog_account_removed_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog) + EmpathyAccount *account, + EmpathyAccountsDialog *dialog) { - GtkTreeIter iter; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - if (accounts_dialog_get_account_iter (dialog, account, &iter)) - gtk_list_store_remove (GTK_LIST_STORE ( - gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview))), &iter); + if (accounts_dialog_get_account_iter (dialog, account, &iter)) + gtk_list_store_remove (GTK_LIST_STORE ( + gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))), &iter); } -static gboolean -accounts_dialog_row_changed_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) +static void +enable_or_disable_account (EmpathyAccountsDialog *dialog, + EmpathyAccount *account, + gboolean enabled) { - gtk_tree_model_row_changed (model, path, iter); + GtkTreeModel *model; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - return FALSE; + /* Update the status in the model */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + DEBUG ("Account %s is now %s", + empathy_account_get_display_name (account), + enabled ? "enabled" : "disabled"); + + if (accounts_dialog_get_account_iter (dialog, account, &iter)) + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + COL_ENABLED, enabled, + -1); } -static gboolean -accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog *dialog) +static void +accounts_dialog_account_disabled_cb (EmpathyAccountManager *manager, + EmpathyAccount *account, + EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeModel *model; + enable_or_disable_account (dialog, account, FALSE); +} - dialog->connecting_show = !dialog->connecting_show; +static void +accounts_dialog_account_enabled_cb (EmpathyAccountManager *manager, + EmpathyAccount *account, + EmpathyAccountsDialog *dialog) +{ + enable_or_disable_account (dialog, account, TRUE); +} - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); +static void +accounts_dialog_account_changed_cb (EmpathyAccountManager *manager, + EmpathyAccount *account, + EmpathyAccountsDialog *dialog) +{ + EmpathyAccountSettings *settings, *selected_settings; + GtkTreeModel *model; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - gtk_tree_model_foreach (model, accounts_dialog_row_changed_foreach, NULL); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); - return TRUE; + if (!accounts_dialog_get_account_iter (dialog, account, &iter)) + return; + + gtk_tree_model_get (model, &iter, + COL_ACCOUNT_SETTINGS_POINTER, &settings, + -1); + + accounts_dialog_update (dialog, settings); + selected_settings = accounts_dialog_model_get_selected_settings (dialog); + + if (settings == selected_settings) + accounts_dialog_update_name_label (dialog, settings); } static void -accounts_dialog_connection_changed_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - TpConnectionStatusReason reason, - TpConnectionStatus current, - TpConnectionStatus previous, - EmpathyAccountsDialog *dialog) +accounts_dialog_button_create_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) { - GtkTreeModel *model; - GtkTreeIter iter; - gboolean found; + EmpathyAccountSettings *settings; + gchar *str; + TpConnectionManager *cm; + TpConnectionManagerProtocol *proto; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + cm = empathy_protocol_chooser_dup_selected ( + EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol), &proto); - /* Update the status in the model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); + /* Create account */ + /* To translator: %s is the protocol name */ + str = g_strdup_printf (_("New %s account"), proto->name); - if (accounts_dialog_get_account_iter (dialog, account, &iter)) { - GtkTreePath *path; + settings = empathy_account_settings_new (cm->name, proto->name, str); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_STATUS, current, - -1); + g_free (str); - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_row_changed (model, path, &iter); - gtk_tree_path_free (path); - } + if (tp_connection_manager_protocol_can_register (proto)) + { + gboolean active; - found = (empathy_account_manager_get_connecting_accounts (manager) > 0); + active = gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON (priv->radiobutton_register)); + if (active) + empathy_account_settings_set_boolean (settings, "register", TRUE); + } - if (!found && dialog->connecting_id) { - g_source_remove (dialog->connecting_id); - dialog->connecting_id = 0; - } + accounts_dialog_add (dialog, settings); + accounts_dialog_model_set_selected (dialog, settings); - if (found && !dialog->connecting_id) { - dialog->connecting_id = g_timeout_add (FLASH_TIMEOUT, - (GSourceFunc) accounts_dialog_flash_connecting_cb, - dialog); - } + g_object_unref (settings); + g_object_unref (cm); } static void -enable_or_disable_account (EmpathyAccountsDialog *dialog, - EmpathyAccount *account, - gboolean enabled) +accounts_dialog_button_back_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) { - GtkTreeModel *model; - GtkTreeIter iter; - - /* Update the status in the model */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); - - DEBUG ("Account %s is now %s", - empathy_account_get_display_name (account), - enabled ? "enabled" : "disabled"); + EmpathyAccountSettings *settings; - if (accounts_dialog_get_account_iter (dialog, account, &iter)) { - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - COL_ENABLED, enabled, - -1); - } + settings = accounts_dialog_model_get_selected_settings (dialog); + accounts_dialog_update (dialog, settings); } static void -accounts_dialog_account_disabled_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog) +accounts_dialog_button_help_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) { - enable_or_disable_account (dialog, account, FALSE); + empathy_url_show (button, "ghelp:empathy?empathy-create-account"); } static void -accounts_dialog_account_enabled_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog) +accounts_dialog_button_remove_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) { - enable_or_disable_account (dialog, account, TRUE); + EmpathyAccount *account; + GtkWidget *message_dialog; + gint res; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + account = accounts_dialog_model_get_selected_account (dialog); + + if (account == NULL || !empathy_account_is_valid (account)) + { + accounts_dialog_model_remove_selected (dialog); + accounts_dialog_model_select_first (dialog); + return; + } + message_dialog = gtk_message_dialog_new + (GTK_WINDOW (priv->window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("You are about to remove your %s account!\n" + "Are you sure you want to proceed?"), + empathy_account_get_display_name (account)); + + gtk_message_dialog_format_secondary_text + (GTK_MESSAGE_DIALOG (message_dialog), + _("Any associated conversations and chat rooms will NOT be " + "removed if you decide to proceed.\n" + "\n" + "Should you decide to add the account back at a later time, " + "they will still be available.")); + + gtk_dialog_add_button (GTK_DIALOG (message_dialog), + GTK_STOCK_CANCEL, + GTK_RESPONSE_NO); + gtk_dialog_add_button (GTK_DIALOG (message_dialog), + GTK_STOCK_REMOVE, + GTK_RESPONSE_YES); + + gtk_widget_show (message_dialog); + res = gtk_dialog_run (GTK_DIALOG (message_dialog)); + + if (res == GTK_RESPONSE_YES) + { + accounts_dialog_model_remove_selected (dialog); + accounts_dialog_model_select_first (dialog); + } + gtk_widget_destroy (message_dialog); } +#if 0 +/* FIXME MC-5 */ static void -accounts_dialog_account_changed_cb (EmpathyAccountManager *manager, - EmpathyAccount *account, - EmpathyAccountsDialog *dialog) +accounts_dialog_button_import_clicked_cb (GtkWidget *button, + EmpathyAccountsDialog *dialog) { - EmpathyAccountSettings *settings, *selected_settings; - GtkTreeModel *model; - GtkTreeIter iter; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview)); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - if (!accounts_dialog_get_account_iter (dialog, account, &iter)) - return; - - gtk_tree_model_get (model, &iter, - COL_ACCOUNT_SETTINGS_POINTER, &settings, - -1); - - accounts_dialog_update (dialog, settings); - selected_settings = accounts_dialog_model_get_selected_settings (dialog); - - if (settings == selected_settings) - accounts_dialog_update_name_label (dialog, settings); + empathy_import_dialog_show (GTK_WINDOW (priv->window), TRUE); } +#endif static void -accounts_dialog_button_create_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +accounts_dialog_response_cb (GtkWidget *widget, + gint response, + EmpathyAccountsDialog *dialog) { - EmpathyAccountSettings *settings; - gchar *str; - TpConnectionManager *cm; - TpConnectionManagerProtocol *proto; - - cm = empathy_protocol_chooser_dup_selected ( - EMPATHY_PROTOCOL_CHOOSER (dialog->combobox_protocol), &proto); - - /* Create account */ - /* To translator: %s is the protocol name */ - str = g_strdup_printf (_("New %s account"), proto->name); - - settings = empathy_account_settings_new (cm->name, proto->name, str); - - g_free (str); - - if (tp_connection_manager_protocol_can_register (proto)) { - gboolean active; - - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->radiobutton_register)); - if (active) { - empathy_account_settings_set_boolean (settings, "register", TRUE); - } - } + GList *accounts, *l; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (response == GTK_RESPONSE_CLOSE) + { + /* Delete incomplete accounts */ + accounts = empathy_account_manager_dup_accounts + (priv->account_manager); + for (l = accounts; l; l = l->next) + { + EmpathyAccount *account; + + account = l->data; + if (!empathy_account_is_valid (account)) + /* FIXME: Warn the user the account is not + * complete and is going to be removed. + */ + empathy_account_manager_remove + (priv->account_manager, account); + + g_object_unref (account); + } + g_list_free (accounts); + + gtk_widget_destroy (widget); + } +} - accounts_dialog_add (dialog, settings); - accounts_dialog_model_set_selected (dialog, settings); +static void +accounts_dialog_destroy_cb (GtkObject *obj, + EmpathyAccountsDialog *dialog) +{ + DEBUG ("%p", obj); - g_object_unref (settings); - g_object_unref (cm); + g_object_unref (dialog); } static void -accounts_dialog_button_back_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +accounts_dialog_set_selected_account (EmpathyAccountsDialog *dialog, + EmpathyAccount *account) { - EmpathyAccountSettings *settings; + GtkTreeSelection *selection; + GtkTreeIter iter; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - settings = accounts_dialog_model_get_selected_settings (dialog); - accounts_dialog_update (dialog, settings); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + if (accounts_dialog_get_account_iter (dialog, account, &iter)) + gtk_tree_selection_select_iter (selection, &iter); } static void -accounts_dialog_protocol_changed_cb (GtkWidget *widget, - EmpathyAccountsDialog *dialog) +accounts_dialog_cms_ready_cb (EmpathyConnectionManagers *cms, + GParamSpec *pspec, + EmpathyAccountsDialog *dialog) { - TpConnectionManager *cm; - TpConnectionManagerProtocol *proto; - - cm = empathy_protocol_chooser_dup_selected ( - EMPATHY_PROTOCOL_CHOOSER (dialog->combobox_protocol), &proto); - - if (tp_connection_manager_protocol_can_register (proto)) { - gtk_widget_show (dialog->radiobutton_register); - gtk_widget_show (dialog->radiobutton_reuse); - } else { - gtk_widget_hide (dialog->radiobutton_register); - gtk_widget_hide (dialog->radiobutton_reuse); - } - g_object_unref (cm); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (empathy_connection_managers_is_ready (cms)) + { + accounts_dialog_update_settings (dialog, NULL); + + if (priv->initial_selection != NULL) + { + accounts_dialog_set_selected_account + (dialog, priv->initial_selection); + priv->initial_selection = NULL; + } + } } static void -accounts_dialog_button_add_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +accounts_dialog_build_ui (EmpathyAccountsDialog *dialog) { - GtkTreeView *view; - GtkTreeSelection *selection; - GtkTreeModel *model; - - view = GTK_TREE_VIEW (dialog->treeview); - model = gtk_tree_view_get_model (view); - selection = gtk_tree_view_get_selection (view); - gtk_tree_selection_unselect_all (selection); - - gtk_widget_set_sensitive (dialog->button_add, FALSE); - gtk_widget_set_sensitive (dialog->button_remove, FALSE); - gtk_widget_hide (dialog->vbox_details); - gtk_widget_hide (dialog->frame_no_protocol); - gtk_widget_show (dialog->frame_new_account); - - /* If we have no account, no need of a back button */ - if (gtk_tree_model_iter_n_children (model, NULL) > 0) { - gtk_widget_show (dialog->button_back); - } else { - gtk_widget_hide (dialog->button_back); - } - - accounts_dialog_protocol_changed_cb (dialog->radiobutton_register, dialog); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->radiobutton_reuse), - TRUE); - gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combobox_protocol), 0); - gtk_widget_grab_focus (dialog->combobox_protocol); + GtkBuilder *gui; + gchar *filename; + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + filename = empathy_file_lookup ("empathy-accounts-dialog.ui", "src"); + + gui = empathy_builder_get_file (filename, + "accounts_dialog", &priv->window, + "vbox_details", &priv->vbox_details, + "frame_no_protocol", &priv->frame_no_protocol, + "alignment_settings", &priv->alignment_settings, + "treeview", &priv->treeview, + "frame_new_account", &priv->frame_new_account, + "hbox_type", &priv->hbox_type, + "button_create", &priv->button_create, + "button_back", &priv->button_back, + "radiobutton_reuse", &priv->radiobutton_reuse, + "radiobutton_register", &priv->radiobutton_register, + "image_type", &priv->image_type, + "label_name", &priv->label_name, + "button_add", &priv->button_add, + "button_remove", &priv->button_remove, + "button_import", &priv->button_import, + NULL); + g_free (filename); + + empathy_builder_connect (gui, dialog, + "accounts_dialog", "response", accounts_dialog_response_cb, + "accounts_dialog", "destroy", accounts_dialog_destroy_cb, + "button_create", "clicked", accounts_dialog_button_create_clicked_cb, + "button_back", "clicked", accounts_dialog_button_back_clicked_cb, + "button_add", "clicked", accounts_dialog_button_add_clicked_cb, + "button_remove", "clicked", accounts_dialog_button_remove_clicked_cb, +#if 0 + /* FIXME MC-5 */ + "button_import", "clicked", accounts_dialog_button_import_clicked_cb, +#endif + "button_help", "clicked", accounts_dialog_button_help_clicked_cb, + NULL); + + g_object_unref (gui); + + priv->combobox_protocol = empathy_protocol_chooser_new (); + gtk_box_pack_end (GTK_BOX (priv->hbox_type), + priv->combobox_protocol, + TRUE, TRUE, 0); + gtk_widget_show (priv->combobox_protocol); + g_signal_connect (priv->combobox_protocol, "changed", + G_CALLBACK (accounts_dialog_protocol_changed_cb), + dialog); + + if (priv->parent_window) + gtk_window_set_transient_for (GTK_WINDOW (priv->window), + priv->parent_window); } static void -accounts_dialog_button_help_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +do_dispose (GObject *obj) { - empathy_url_show (button, "ghelp:empathy?empathy-create-account"); + EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (obj); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + /* Disconnect signals */ + g_signal_handlers_disconnect_by_func (priv->account_manager, + accounts_dialog_account_added_cb, + dialog); + g_signal_handlers_disconnect_by_func (priv->account_manager, + accounts_dialog_account_removed_cb, + dialog); + g_signal_handlers_disconnect_by_func (priv->account_manager, + accounts_dialog_account_enabled_cb, + dialog); + g_signal_handlers_disconnect_by_func (priv->account_manager, + accounts_dialog_account_disabled_cb, + dialog); + g_signal_handlers_disconnect_by_func (priv->account_manager, + accounts_dialog_account_changed_cb, + dialog); + g_signal_handlers_disconnect_by_func (priv->account_manager, + accounts_dialog_connection_changed_cb, + dialog); + + if (priv->connecting_id) + g_source_remove (priv->connecting_id); + + if (priv->account_manager != NULL) + { + g_object_unref (priv->account_manager); + priv->account_manager = NULL; + } + + if (priv->cms != NULL) + { + g_object_unref (priv->cms); + priv->cms = NULL; + } + + G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->dispose (obj); +} + +static GObject * +do_constructor (GType type, + guint n_props, + GObjectConstructParam *props) +{ + GObject *retval; + + if (dialog_singleton) + { + retval = G_OBJECT (dialog_singleton); + } + else + { + retval = + G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->constructor + (type, n_props, props); + + dialog_singleton = EMPATHY_ACCOUNTS_DIALOG (retval); + g_object_add_weak_pointer (retval, (gpointer) &dialog_singleton); + } + + return retval; } static void -accounts_dialog_button_remove_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +do_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - EmpathyAccount *account; - GtkWidget *message_dialog; - gint res; - - account = accounts_dialog_model_get_selected_account (dialog); - - if (account == NULL || !empathy_account_is_valid (account)) { - accounts_dialog_model_remove_selected (dialog); - accounts_dialog_model_select_first (dialog); - return; - } - message_dialog = gtk_message_dialog_new - (GTK_WINDOW (dialog->window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("You are about to remove your %s account!\n" - "Are you sure you want to proceed?"), - empathy_account_get_display_name (account)); - - gtk_message_dialog_format_secondary_text - (GTK_MESSAGE_DIALOG (message_dialog), - _("Any associated conversations and chat rooms will NOT be " - "removed if you decide to proceed.\n" - "\n" - "Should you decide to add the account back at a later time, " - "they will still be available.")); - - gtk_dialog_add_button (GTK_DIALOG (message_dialog), - GTK_STOCK_CANCEL, - GTK_RESPONSE_NO); - gtk_dialog_add_button (GTK_DIALOG (message_dialog), - GTK_STOCK_REMOVE, - GTK_RESPONSE_YES); - - gtk_widget_show (message_dialog); - res = gtk_dialog_run (GTK_DIALOG (message_dialog)); - - if (res == GTK_RESPONSE_YES) { - empathy_account_manager_remove (dialog->account_manager, account); - accounts_dialog_model_select_first (dialog); - } - gtk_widget_destroy (message_dialog); + EmpathyAccountsDialogPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_PARENT: + g_value_set_object (value, priv->parent_window); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } } -#if 0 -/* FIXME MC-5 */ static void -accounts_dialog_button_import_clicked_cb (GtkWidget *button, - EmpathyAccountsDialog *dialog) +do_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - empathy_import_dialog_show (GTK_WINDOW (dialog->window), TRUE); + EmpathyAccountsDialogPriv *priv = GET_PRIV (object); + + switch (property_id) + { + case PROP_PARENT: + priv->parent_window = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } } + +static void +do_constructed (GObject *object) +{ + EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (object); + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + GList *accounts, *l; + gboolean import_asked; + + accounts_dialog_build_ui (dialog); + + /* Set up signalling */ + priv->account_manager = empathy_account_manager_dup_singleton (); + + g_signal_connect (priv->account_manager, "account-created", + G_CALLBACK (accounts_dialog_account_added_cb), + dialog); + g_signal_connect (priv->account_manager, "account-deleted", + G_CALLBACK (accounts_dialog_account_removed_cb), + dialog); + g_signal_connect (priv->account_manager, "account-enabled", + G_CALLBACK (accounts_dialog_account_enabled_cb), + dialog); + g_signal_connect (priv->account_manager, "account-disabled", + G_CALLBACK (accounts_dialog_account_disabled_cb), + dialog); + g_signal_connect (priv->account_manager, "account-changed", + G_CALLBACK (accounts_dialog_account_changed_cb), + dialog); + g_signal_connect (priv->account_manager, "account-connection-changed", + G_CALLBACK (accounts_dialog_connection_changed_cb), + dialog); + + accounts_dialog_model_setup (dialog); + + /* Add existing accounts */ + accounts = empathy_account_manager_dup_accounts (priv->account_manager); + for (l = accounts; l; l = l->next) + { + accounts_dialog_add_account (dialog, l->data); + g_object_unref (l->data); + } + g_list_free (accounts); + + priv->cms = empathy_connection_managers_dup_singleton (); + if (!empathy_connection_managers_is_ready (priv->cms)) + g_signal_connect (priv->cms, "notify::ready", + G_CALLBACK (accounts_dialog_cms_ready_cb), dialog); + + accounts_dialog_model_select_first (dialog); + + empathy_conf_get_bool (empathy_conf_get (), + EMPATHY_PREFS_IMPORT_ASKED, &import_asked); + + +#if 0 + /* FIXME MC-5 */ + if (empathy_import_dialog_accounts_to_import ()) + { + + if (!import_asked) + { + empathy_conf_set_bool (empathy_conf_get (), + EMPATHY_PREFS_IMPORT_ASKED, TRUE); + empathy_import_dialog_show (GTK_WINDOW (priv->window), + FALSE); + } + } + else + { + gtk_widget_set_sensitive (priv->button_import, FALSE); + } #endif +} static void -accounts_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyAccountsDialog *dialog) +empathy_accounts_dialog_class_init (EmpathyAccountsDialogClass *klass) { - if (response == GTK_RESPONSE_CLOSE) { - gtk_widget_destroy (widget); - } + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GParamSpec *param_spec; + + oclass->constructor = do_constructor; + oclass->dispose = do_dispose; + oclass->constructed = do_constructed; + oclass->set_property = do_set_property; + oclass->get_property = do_get_property; + + param_spec = g_param_spec_object ("parent", + "parent", "The parent window", + GTK_TYPE_WINDOW, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (oclass, PROP_PARENT, param_spec); + + g_type_class_add_private (klass, sizeof (EmpathyAccountsDialogPriv)); } static void -accounts_dialog_destroy_cb (GtkWidget *widget, - EmpathyAccountsDialog *dialog) +empathy_accounts_dialog_init (EmpathyAccountsDialog *dialog) { - GList *accounts, *l; - - /* Disconnect signals */ - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_added_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_removed_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_enabled_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_disabled_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_account_changed_cb, - dialog); - g_signal_handlers_disconnect_by_func (dialog->account_manager, - accounts_dialog_connection_changed_cb, - dialog); - - /* Delete incomplete accounts */ - accounts = empathy_account_manager_dup_accounts (dialog->account_manager); - for (l = accounts; l; l = l->next) { - EmpathyAccount *account; - - account = l->data; - if (!empathy_account_is_valid (account)) { - /* FIXME: Warn the user the account is not complete - * and is going to be removed. */ - empathy_account_manager_remove (dialog->account_manager, account); - } - - g_object_unref (account); - } - g_list_free (accounts); - - if (dialog->connecting_id) { - g_source_remove (dialog->connecting_id); - } - - g_object_unref (dialog->account_manager); - - g_free (dialog); + EmpathyAccountsDialogPriv *priv; + + priv = G_TYPE_INSTANCE_GET_PRIVATE ((dialog), + EMPATHY_TYPE_ACCOUNTS_DIALOG, + EmpathyAccountsDialogPriv); + dialog->priv = priv; } +/* public methods */ + GtkWidget * empathy_accounts_dialog_show (GtkWindow *parent, - EmpathyAccount *selected_account) + EmpathyAccount *selected_account) { - static EmpathyAccountsDialog *dialog = NULL; - GtkBuilder *gui; - gchar *filename; - GList *accounts, *l; - gboolean import_asked; - - if (dialog) { - gtk_window_present (GTK_WINDOW (dialog->window)); - return dialog->window; - } - - dialog = g_new0 (EmpathyAccountsDialog, 1); - - filename = empathy_file_lookup ("empathy-accounts-dialog.ui", - "src"); - gui = empathy_builder_get_file (filename, - "accounts_dialog", &dialog->window, - "vbox_details", &dialog->vbox_details, - "frame_no_protocol", &dialog->frame_no_protocol, - "alignment_settings", &dialog->alignment_settings, - "treeview", &dialog->treeview, - "frame_new_account", &dialog->frame_new_account, - "hbox_type", &dialog->hbox_type, - "button_create", &dialog->button_create, - "button_back", &dialog->button_back, - "radiobutton_reuse", &dialog->radiobutton_reuse, - "radiobutton_register", &dialog->radiobutton_register, - "image_type", &dialog->image_type, - "label_name", &dialog->label_name, - "button_add", &dialog->button_add, - "button_remove", &dialog->button_remove, - "button_import", &dialog->button_import, - NULL); - g_free (filename); - - empathy_builder_connect (gui, dialog, - "accounts_dialog", "destroy", accounts_dialog_destroy_cb, - "accounts_dialog", "response", accounts_dialog_response_cb, - "button_create", "clicked", accounts_dialog_button_create_clicked_cb, - "button_back", "clicked", accounts_dialog_button_back_clicked_cb, - "button_add", "clicked", accounts_dialog_button_add_clicked_cb, - "button_remove", "clicked", accounts_dialog_button_remove_clicked_cb, -#if 0 -/* FIXME MC-5 */ - "button_import", "clicked", accounts_dialog_button_import_clicked_cb, -#endif - "button_help", "clicked", accounts_dialog_button_help_clicked_cb, - NULL); - - g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog); - - g_object_unref (gui); - - /* Create protocol chooser */ - dialog->combobox_protocol = empathy_protocol_chooser_new (); - gtk_box_pack_end (GTK_BOX (dialog->hbox_type), - dialog->combobox_protocol, - TRUE, TRUE, 0); - gtk_widget_show (dialog->combobox_protocol); - g_signal_connect (dialog->combobox_protocol, "changed", - G_CALLBACK (accounts_dialog_protocol_changed_cb), - dialog); - - /* Set up signalling */ - dialog->account_manager = empathy_account_manager_dup_singleton (); - - g_signal_connect (dialog->account_manager, "account-created", - G_CALLBACK (accounts_dialog_account_added_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-deleted", - G_CALLBACK (accounts_dialog_account_removed_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-enabled", - G_CALLBACK (accounts_dialog_account_enabled_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-disabled", - G_CALLBACK (accounts_dialog_account_disabled_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-changed", - G_CALLBACK (accounts_dialog_account_changed_cb), - dialog); - g_signal_connect (dialog->account_manager, "account-connection-changed", - G_CALLBACK (accounts_dialog_connection_changed_cb), - dialog); - - accounts_dialog_model_setup (dialog); - - /* Add existing accounts */ - accounts = empathy_account_manager_dup_accounts (dialog->account_manager); - for (l = accounts; l; l = l->next) { - accounts_dialog_add_account (dialog, l->data); - g_object_unref (l->data); - } - g_list_free (accounts); - - if (selected_account) { - GtkTreeSelection *selection; - GtkTreeIter iter; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->treeview)); - if (accounts_dialog_get_account_iter (dialog, selected_account, &iter)) { - gtk_tree_selection_select_iter (selection, &iter); - } - } else { - accounts_dialog_model_select_first (dialog); - } - - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (dialog->window), - GTK_WINDOW (parent)); - } - - gtk_widget_show (dialog->window); - - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_IMPORT_ASKED, &import_asked); + EmpathyAccountsDialog *dialog; + EmpathyAccountsDialogPriv *priv; + dialog = g_object_new (EMPATHY_TYPE_ACCOUNTS_DIALOG, + "parent", parent, NULL); -#if 0 -/* FIXME MC-5 */ - if (empathy_import_dialog_accounts_to_import ()) { - - if (!import_asked) { - empathy_conf_set_bool (empathy_conf_get (), - EMPATHY_PREFS_IMPORT_ASKED, TRUE); - empathy_import_dialog_show (GTK_WINDOW (dialog->window), - FALSE); - } - } else { - gtk_widget_set_sensitive (dialog->button_import, FALSE); - } -#endif + priv = GET_PRIV (dialog); - return dialog->window; -} + if (selected_account && empathy_connection_managers_is_ready (priv->cms)) + accounts_dialog_set_selected_account (dialog, selected_account); + else + /* save the selection to set it later when the cms + * becomes ready. + */ + priv->initial_selection = selected_account; + gtk_window_present (GTK_WINDOW (priv->window)); + + return priv->window; +} diff --git a/src/empathy-accounts-dialog.h b/src/empathy-accounts-dialog.h index 11e237c8f..aa8f7c06b 100644 --- a/src/empathy-accounts-dialog.h +++ b/src/empathy-accounts-dialog.h @@ -1,4 +1,3 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2005-2007 Imendio AB * Copyright (C) 2007-2008 Collabora Ltd. @@ -31,8 +30,32 @@ G_BEGIN_DECLS +#define EMPATHY_TYPE_ACCOUNTS_DIALOG empathy_accounts_dialog_get_type() +#define EMPATHY_ACCOUNTS_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_ACCOUNTS_DIALOG, EmpathyAccountsDialog)) +#define EMPATHY_ACCOUNTS_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EMPATHY_TYPE_ACCOUNTS_DIALOG, EmpathyAccountsDialogClass)) +#define EMPATHY_IS_ACCOUNTS_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_ACCOUNTS_DIALOG)) +#define EMPATHY_IS_ACCOUNTS_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EMPATHY_TYPE_ACCOUNTS_DIALOG)) +#define EMPATHY_ACCOUNTS_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_ACCOUNTS_DIALOG, EmpathyAccountsDialogClass)) + +typedef struct { + GObject parent; + + /* private */ + gpointer priv; +} EmpathyAccountsDialog; + +typedef struct { + GObjectClass parent_class; +} EmpathyAccountsDialogClass; + +GType empathy_accounts_dialog_get_type (void); GtkWidget *empathy_accounts_dialog_show (GtkWindow *parent, - EmpathyAccount *selected_account); + EmpathyAccount *selected_account); G_END_DECLS diff --git a/tests/test-empathy-protocol-chooser.c b/tests/test-empathy-protocol-chooser.c index 07b1c70e1..90b1797a3 100644 --- a/tests/test-empathy-protocol-chooser.c +++ b/tests/test-empathy-protocol-chooser.c @@ -9,15 +9,15 @@ int main (int argc, char **argv) { - GtkWidget *window; - GtkWidget *chooser; + GtkWidget *window, *c; gtk_init (&argc, &argv); empathy_gtk_init (); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - chooser = empathy_protocol_chooser_new (); - gtk_container_add (GTK_CONTAINER (window), chooser); + c = empathy_protocol_chooser_new (); + + gtk_container_add (GTK_CONTAINER (window), c); /* gtk_window_set_default_size (GTK_WINDOW (window), 150, -1);*/ gtk_widget_show_all (window); |