aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am8
-rw-r--r--src/empathy-about-dialog.c18
-rw-r--r--src/empathy-account-assistant.c1307
-rw-r--r--src/empathy-account-assistant.h66
-rw-r--r--src/empathy-accounts-common.c69
-rw-r--r--src/empathy-accounts-common.h1
-rw-r--r--src/empathy-accounts-dialog.c705
-rw-r--r--src/empathy-accounts-dialog.ui105
-rw-r--r--src/empathy-accounts.c11
-rw-r--r--src/empathy-audio-sink.c6
-rw-r--r--src/empathy-audio-src.c2
-rw-r--r--src/empathy-auth-client.c2
-rw-r--r--src/empathy-auto-salut-account-helper.c129
-rw-r--r--src/empathy-auto-salut-account-helper.h36
-rw-r--r--src/empathy-call-window.c17
-rw-r--r--src/empathy-call.c10
-rw-r--r--src/empathy-chat-window.c228
-rw-r--r--src/empathy-chat-window.ui4
-rw-r--r--src/empathy-chat.c7
-rw-r--r--src/empathy-event-manager.c156
-rw-r--r--src/empathy-ft-manager.c5
-rw-r--r--src/empathy-import-dialog.c48
-rw-r--r--src/empathy-import-dialog.h5
-rw-r--r--src/empathy-import-widget.c66
-rw-r--r--src/empathy-import-widget.h5
-rw-r--r--src/empathy-invite-participant-dialog.c2
-rw-r--r--src/empathy-main-window.c2586
-rw-r--r--src/empathy-main-window.h63
-rw-r--r--src/empathy-map-view.c147
-rw-r--r--src/empathy-new-chatroom-dialog.c14
-rw-r--r--src/empathy-preferences.c24
-rw-r--r--src/empathy-preferences.ui47
-rw-r--r--src/empathy-roster-window-menubar.ui (renamed from src/empathy-main-window-menubar.ui)7
-rw-r--r--src/empathy-roster-window.c2753
-rw-r--r--src/empathy-roster-window.h65
-rw-r--r--src/empathy-roster-window.ui (renamed from src/empathy-main-window.ui)76
-rw-r--r--src/empathy-rounded-actor.c1
-rw-r--r--src/empathy-rounded-rectangle.c2
-rw-r--r--src/empathy.c41
39 files changed, 3981 insertions, 4863 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c6855d338..8623ac2dd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,9 +32,7 @@ noinst_LTLIBRARIES = libempathy-accounts-common.la
libempathy_accounts_common_la_SOURCES = \
empathy-accounts-common.c empathy-accounts-common.h \
- empathy-account-assistant.c empathy-account-assistant.h \
empathy-accounts-dialog.c empathy-accounts-dialog.h \
- empathy-auto-salut-account-helper.c empathy-auto-salut-account-helper.h \
empathy-import-dialog.c empathy-import-dialog.h \
empathy-import-pidgin.c empathy-import-pidgin.h \
empathy-import-widget.c empathy-import-widget.h \
@@ -166,7 +164,7 @@ empathy_handwritten_source = \
empathy-event-manager.c empathy-event-manager.h \
empathy-ft-manager.c empathy-ft-manager.h \
empathy-invite-participant-dialog.c empathy-invite-participant-dialog.h \
- empathy-main-window.c empathy-main-window.h \
+ empathy-roster-window.c empathy-roster-window.h \
empathy-new-chatroom-dialog.c empathy-new-chatroom-dialog.h \
empathy-notifications-approver.c empathy-notifications-approver.h \
empathy-call-observer.c empathy-call-observer.h \
@@ -207,8 +205,8 @@ ui_DATA = \
empathy-chatrooms-window.ui \
empathy-ft-manager.ui \
empathy-import-dialog.ui \
- empathy-main-window.ui \
- empathy-main-window-menubar.ui \
+ empathy-roster-window.ui \
+ empathy-roster-window-menubar.ui \
empathy-new-chatroom-dialog.ui \
empathy-preferences.ui \
empathy-status-icon.ui
diff --git a/src/empathy-about-dialog.c b/src/empathy-about-dialog.c
index 04b2753b6..3204d0f08 100644
--- a/src/empathy-about-dialog.c
+++ b/src/empathy-about-dialog.c
@@ -88,24 +88,26 @@ static const char *license[] = {
"GNU General Public License for more details."),
N_("You should have received a copy of the GNU General Public License "
"along with Empathy; if not, write to the Free Software Foundation, Inc., "
- "51 Franklin Street, Fifth Floor, Boston, MA 02110-130159 USA")
+ "51 Franklin Street, Fifth Floor, Boston, MA 02110-130159 USA"),
+ NULL
};
void
empathy_about_dialog_new (GtkWindow *parent)
{
- gchar *license_trans;
+ GString *license_trans = g_string_new (NULL);
+ int i;
- license_trans = g_strconcat (_(license[0]), "\n\n",
- _(license[1]), "\n\n",
- _(license[2]), "\n\n",
- NULL);
+ for (i = 0; license[i] != NULL; i++) {
+ g_string_append (license_trans, _(license[i]));
+ g_string_append (license_trans, "\n\n");
+ }
gtk_show_about_dialog (parent,
"artists", artists,
"authors", authors,
"comments", _("An Instant Messaging client for GNOME"),
- "license", license_trans,
+ "license", license_trans->str,
"wrap-license", TRUE,
"copyright", "Imendio AB 2002-2007\nCollabora Ltd 2007-2011",
"documenters", documenters,
@@ -115,7 +117,7 @@ empathy_about_dialog_new (GtkWindow *parent)
"website", WEB_SITE,
NULL);
- g_free (license_trans);
+ g_string_free (license_trans, TRUE);
}
diff --git a/src/empathy-account-assistant.c b/src/empathy-account-assistant.c
deleted file mode 100644
index ecfd78344..000000000
--- a/src/empathy-account-assistant.c
+++ /dev/null
@@ -1,1307 +0,0 @@
-/*
- * Copyright (C) 2009 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
- */
-
-/* empathy-account-assistant.c */
-
-#include <config.h>
-#include <glib/gi18n-lib.h>
-#include <telepathy-glib/util.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "empathy-account-assistant.h"
-#include "empathy-import-widget.h"
-#include "empathy-import-utils.h"
-#include "empathy-auto-salut-account-helper.h"
-
-#include <libempathy/empathy-account-settings.h>
-#include <libempathy/empathy-utils.h>
-
-#include <libempathy-gtk/empathy-account-widget.h>
-#include <libempathy-gtk/empathy-protocol-chooser.h>
-#include <libempathy-gtk/empathy-ui-utils.h>
-
-#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
-#include <libempathy/empathy-debug.h>
-
-G_DEFINE_TYPE (EmpathyAccountAssistant, empathy_account_assistant,
- GTK_TYPE_ASSISTANT)
-
-#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountAssistant)
-
-typedef enum {
- RESPONSE_IMPORT = 1,
- RESPONSE_ENTER_ACCOUNT = 2,
- RESPONSE_CREATE_ACCOUNT = 3,
- RESPONSE_SALUT_ONLY = 4
-} FirstPageResponse;
-
-typedef enum {
- RESPONSE_CREATE_AGAIN = 1,
- RESPONSE_CREATE_STOP = 2
-} CreateEnterPageResponse;
-
-typedef enum {
- PAGE_INTRO = 0,
- PAGE_IMPORT = 1,
- PAGE_ENTER_CREATE = 2,
- PAGE_SALUT = 3,
-} PageID;
-
-enum {
- PROP_PARENT = 1,
- PROP_CONNECTION_MGRS,
-};
-
-typedef struct {
- FirstPageResponse first_resp;
- CreateEnterPageResponse create_enter_resp;
- gboolean enter_create_forward;
- TpAccountManager *account_mgr;
- EmpathyConnectionManagers *connection_mgrs;
- PageID current_page_id;
-
- /* enter or create page */
- GtkWidget *enter_or_create_page;
- GtkWidget *current_account_widget;
- EmpathyAccountWidget *current_widget_object;
- GtkWidget *first_label;
- GtkWidget *second_label;
- GtkWidget *chooser;
- GtkWidget *create_again_radio;
- EmpathyAccountSettings *settings;
- gboolean is_creating;
-
- /* import page */
- EmpathyImportWidget *iw;
- GtkWidget *import_page;
-
- /* salut page */
- GtkWidget *salut_page;
- EmpathyAccountSettings *salut_settings;
- GtkWidget *salut_account_widget;
- gboolean create_salut_account;
- gboolean display_salut_page;
-
- GtkWindow *parent_window;
-
- gboolean dispose_run;
-} EmpathyAccountAssistantPriv;
-
-static GtkWidget * account_assistant_build_enter_or_create_page (
- EmpathyAccountAssistant *self);
-static void account_assistant_finish_enter_or_create_page (
- EmpathyAccountAssistant *self,
- gboolean is_enter);
-
-static void do_constructed (GObject *object);
-
-static GtkWidget *
-build_error_vbox (const gchar *primary_message,
- const gchar *secondary_message)
-{
- GtkWidget *main_vbox, *w, *hbox;
- PangoAttrList *list;
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
- gtk_widget_show (main_vbox);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR,
- GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
-
- w = gtk_label_new (primary_message);
- gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
- list = pango_attr_list_new ();
- pango_attr_list_insert (list, pango_attr_scale_new (PANGO_SCALE_LARGE));
- pango_attr_list_insert (list, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
- gtk_label_set_attributes (GTK_LABEL (w), list);
- gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_show (w);
-
- pango_attr_list_unref (list);
-
- w = gtk_label_new (secondary_message);
- gtk_label_set_use_markup (GTK_LABEL (w), TRUE);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_show (w);
-
- return main_vbox;
-}
-
-static GtkWidget *
-account_assistant_build_error_page (EmpathyAccountAssistant *self,
- GError *error, gint page_num)
-{
- GtkWidget *main_vbox, *w;
- const char *primary_message;
- gchar *secondary_message, *markup;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- if (page_num == PAGE_IMPORT)
- primary_message = _("There was an error while importing the accounts.");
- else if (page_num >= PAGE_ENTER_CREATE &&
- priv->first_resp == RESPONSE_ENTER_ACCOUNT)
- primary_message = _("There was an error while parsing the account details.");
- else if (page_num >= PAGE_ENTER_CREATE &&
- priv->first_resp == RESPONSE_CREATE_ACCOUNT)
- primary_message = _("There was an error while creating the account.");
- else
- primary_message = _("There was an error.");
-
- markup = g_markup_printf_escaped ("<span style=\"italic\">%s</span>",
- error->message);
- secondary_message = g_strdup_printf (_("The error message was: %s"), markup);
-
- main_vbox = build_error_vbox (primary_message, secondary_message);
-
- w = gtk_label_new (_("You can either go back and try to enter your "
- "accounts' details again or quit this assistant and add accounts "
- "later from the Edit menu."));
- gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 6);
- gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_widget_show (w);
-
- g_free (markup);
- g_free (secondary_message);
- return main_vbox;
-}
-
-static void
-account_assistant_back_button_clicked_cb (GtkButton *button,
- EmpathyAccountAssistant *self)
-{
- gint page_num;
-
- page_num = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
- "page-num"));
- gtk_assistant_remove_action_widget (GTK_ASSISTANT (self),
- GTK_WIDGET (button));
- gtk_assistant_set_current_page (GTK_ASSISTANT (self), page_num);
-}
-
-static void
-account_assistant_present_error_page (EmpathyAccountAssistant *self,
- GError *error, gint page_num)
-{
- GtkWidget *error_page, *back_button;
- gint num;
-
- error_page = account_assistant_build_error_page (self, error,
- page_num);
- num = gtk_assistant_append_page (GTK_ASSISTANT (self), error_page);
- gtk_assistant_set_page_title (GTK_ASSISTANT (self), error_page,
- _("An error occurred"));
- gtk_assistant_set_page_type (GTK_ASSISTANT (self), error_page,
- GTK_ASSISTANT_PAGE_SUMMARY);
-
- back_button = gtk_button_new_from_stock (GTK_STOCK_GO_BACK);
- gtk_assistant_add_action_widget (GTK_ASSISTANT (self), back_button);
- g_object_set_data (G_OBJECT (back_button),
- "page-num", GINT_TO_POINTER (page_num));
- g_signal_connect (back_button, "clicked",
- G_CALLBACK (account_assistant_back_button_clicked_cb), self);
- gtk_widget_show (back_button);
-
- gtk_assistant_set_current_page (GTK_ASSISTANT (self), num);
-}
-
-static void
-update_create_page_buttons (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- GtkAssistantPageType type;
-
- if (priv->display_salut_page ||
- priv->create_enter_resp == RESPONSE_CREATE_AGAIN)
- type = GTK_ASSISTANT_PAGE_CONTENT;
- else
- type = GTK_ASSISTANT_PAGE_CONFIRM;
-
- gtk_assistant_set_page_type (GTK_ASSISTANT (self), priv->enter_or_create_page,
- type);
-}
-
-static void
-account_assistant_reset_enter_create_page (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- GtkWidget *page;
- gint idx;
-
- page = account_assistant_build_enter_or_create_page (self);
- idx = gtk_assistant_append_page (GTK_ASSISTANT (self), page);
- priv->enter_or_create_page = page;
- update_create_page_buttons (self);
-
- gtk_assistant_set_current_page (GTK_ASSISTANT (self), idx);
-
- account_assistant_finish_enter_or_create_page (self,
- priv->first_resp == RESPONSE_ENTER_ACCOUNT ?
- TRUE : FALSE);
-}
-
-static void
-account_assistant_account_enabled_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GError *error = NULL;
- EmpathyAccountAssistant *self = user_data;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- const gchar *protocol;
- TpAccount *account = TP_ACCOUNT (source);
- gint current_idx;
- gboolean salut_created = FALSE;
-
- tp_account_set_enabled_finish (account, result, &error);
-
- if (error)
- {
- g_warning ("Error enabling an account: %s", error->message);
- g_error_free (error);
- }
-
- protocol = tp_account_get_protocol (account);
- if (!tp_strdiff (protocol, "local-xmpp"))
- {
- salut_created = TRUE;
- }
-
- empathy_connect_new_account (account, priv->account_mgr);
-
- current_idx = gtk_assistant_get_current_page (GTK_ASSISTANT (self));
- if (current_idx == PAGE_SALUT && !salut_created)
- /* We are on the Salut page and aren't creating the salut account so don't
- * terminate the assistant. */
- return;
-
- if (priv->create_enter_resp == RESPONSE_CREATE_STOP)
- g_signal_emit_by_name (self, "close");
- else
- account_assistant_reset_enter_create_page (self);
-}
-
-static void
-account_assistant_apply_account_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GError *error = NULL;
- EmpathyAccountAssistant *self = user_data;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- EmpathyAccountSettings *settings = EMPATHY_ACCOUNT_SETTINGS (source);
- TpAccount *account;
-
- empathy_account_settings_apply_finish (settings, result, NULL, &error);
-
- priv->is_creating = FALSE;
-
- if (error != NULL)
- {
- account_assistant_present_error_page (self, error,
- gtk_assistant_get_current_page (GTK_ASSISTANT (self)));
- g_error_free (error);
- return;
- }
-
- /* enable the newly created account */
- account = empathy_account_settings_get_account (settings);
- tp_account_set_enabled_async (account, TRUE,
- account_assistant_account_enabled_cb, self);
-}
-
-static void
-account_assistant_apply_account_and_finish (EmpathyAccountAssistant *self,
- EmpathyAccountSettings *settings,
- gboolean set_display_name)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- if (settings == NULL)
- return;
-
- priv->is_creating = TRUE;
-
- if (set_display_name)
- {
- gchar *display_name;
-
- display_name = empathy_account_widget_get_default_display_name (
- priv->current_widget_object);
-
- empathy_account_settings_set_display_name_async (settings,
- display_name, NULL, NULL);
-
- g_free (display_name);
- }
-
- empathy_account_settings_apply_async (settings,
- account_assistant_apply_account_cb, self);
-}
-
-static void
-account_assistant_handle_apply_cb (EmpathyAccountWidget *widget_object,
- gboolean is_valid,
- EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
- priv->enter_or_create_page, is_valid);
-}
-
-static void
-account_assistant_protocol_changed_cb (GtkComboBox *chooser,
- EmpathyAccountAssistant *self)
-{
- EmpathyAccountSettings *settings;
- EmpathyAccountAssistantPriv *priv;
- GtkWidget *account_widget;
- EmpathyAccountWidget *widget_object = NULL;
-
- priv = GET_PRIV (self);
-
- settings = empathy_protocol_chooser_create_account_settings (
- EMPATHY_PROTOCOL_CHOOSER (chooser));
-
- if (settings == NULL)
- return;
-
- if (priv->first_resp == RESPONSE_CREATE_ACCOUNT)
- empathy_account_settings_set_boolean (settings, "register", TRUE);
-
- widget_object = empathy_account_widget_new_for_protocol (settings, TRUE);
- account_widget = empathy_account_widget_get_widget (widget_object);
-
- if (priv->current_account_widget != NULL)
- {
- g_signal_handlers_disconnect_by_func (priv->current_widget_object,
- account_assistant_handle_apply_cb, self);
- gtk_widget_destroy (priv->current_account_widget);
- }
-
- priv->current_account_widget = account_widget;
- priv->current_widget_object = widget_object;
-
- if (priv->settings != NULL)
- g_object_unref (priv->settings);
-
- priv->settings = settings;
-
- g_signal_connect (priv->current_widget_object, "handle-apply",
- G_CALLBACK (account_assistant_handle_apply_cb), self);
-
- if (empathy_account_settings_is_valid (settings))
- {
- gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
- priv->enter_or_create_page, TRUE);
- }
-
- gtk_box_pack_start (GTK_BOX (priv->enter_or_create_page), account_widget,
- FALSE, FALSE, 0);
- gtk_widget_show (account_widget);
-}
-
-static gboolean
-account_assistant_chooser_enter_details_filter_func (
- TpConnectionManager *cm,
- TpConnectionManagerProtocol *protocol,
- const gchar *service,
- gpointer user_data)
-{
- if (!tp_strdiff (protocol->name, "local-xmpp"))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-account_assistant_chooser_create_account_filter_func (
- TpConnectionManager *cm,
- TpConnectionManagerProtocol *protocol,
- const gchar *service,
- gpointer user_data)
-{
- if (service != NULL)
- return FALSE;
-
- return tp_connection_manager_protocol_can_register (protocol);
-}
-
-static void
-account_assistant_finish_enter_or_create_page (EmpathyAccountAssistant *self,
- gboolean is_enter)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- if (is_enter)
- {
- gtk_label_set_label (GTK_LABEL (priv->first_label),
- _("What kind of chat account do you have?"));
- /* gtk_label_set_label (GTK_LABEL (priv->second_label),
- _("If you have other accounts to set up, you can do "
- "that at any time from the Edit menu."));
- */
- gtk_label_set_label (GTK_LABEL (priv->second_label),
- _("Do you have any other chat accounts you want to set up?"));
- empathy_protocol_chooser_set_visible (
- EMPATHY_PROTOCOL_CHOOSER (priv->chooser),
- account_assistant_chooser_enter_details_filter_func, self);
-
- gtk_assistant_set_page_title (GTK_ASSISTANT (self),
- priv->enter_or_create_page, _("Enter your account details"));
- }
- else
- {
- gtk_label_set_label (GTK_LABEL (priv->first_label),
- _("What kind of chat account do you want to create?"));
- /* gtk_label_set_label (GTK_LABEL (priv->second_label),
- _("You can register other accounts, or setup "
- "an existing one at any time from the Edit menu."));
- */
- gtk_label_set_label (GTK_LABEL (priv->second_label),
- _("Do you want to create other chat accounts?"));
- empathy_protocol_chooser_set_visible (
- EMPATHY_PROTOCOL_CHOOSER (priv->chooser),
- account_assistant_chooser_create_account_filter_func, self);
-
- gtk_assistant_set_page_title (GTK_ASSISTANT (self),
- priv->enter_or_create_page,
- _("Enter the details for the new account"));
- }
-
- g_signal_connect (priv->chooser, "changed",
- G_CALLBACK (account_assistant_protocol_changed_cb), self);
-
- /* trigger show the first account widget */
- account_assistant_protocol_changed_cb (GTK_COMBO_BOX (priv->chooser), self);
-}
-
-static gint
-account_assistant_page_forward_func (gint current_page,
- gpointer user_data)
-{
- EmpathyAccountAssistant *self = user_data;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- gint retval;
-
- retval = current_page;
-
- if (current_page == PAGE_INTRO)
- {
- if (priv->first_resp == RESPONSE_ENTER_ACCOUNT ||
- priv->first_resp == RESPONSE_CREATE_ACCOUNT)
- retval = PAGE_ENTER_CREATE;
- else if (priv->first_resp == RESPONSE_IMPORT)
- retval = PAGE_IMPORT;
- else if (priv->first_resp == RESPONSE_SALUT_ONLY)
- retval = PAGE_SALUT;
- }
- else if (current_page == PAGE_IMPORT)
- {
- if (priv->display_salut_page)
- retval = PAGE_SALUT;
- else
- /* Don't go forward */
- retval = -1;
- }
- else if (current_page == PAGE_SALUT)
- {
- /* Don't go forward */
- retval = -1;
- }
- else if (current_page >= PAGE_ENTER_CREATE)
- {
- if (priv->create_enter_resp == RESPONSE_CREATE_AGAIN)
- {
- priv->enter_create_forward = TRUE;
- retval = current_page;
- }
- else if (priv->display_salut_page)
- {
- retval = PAGE_SALUT;
- }
- else
- {
- /* Don't go forward */
- retval = -1;
- }
- }
-
- return retval;
-}
-
-static void
-update_intro_page_buttons (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- GtkWidget *intro_page;
-
- intro_page = gtk_assistant_get_nth_page (GTK_ASSISTANT (self),
- PAGE_INTRO);
-
- if (priv->first_resp == RESPONSE_SALUT_ONLY &&
- !priv->display_salut_page)
- gtk_assistant_set_page_type (GTK_ASSISTANT (self), intro_page,
- GTK_ASSISTANT_PAGE_SUMMARY);
- else
- gtk_assistant_set_page_type (GTK_ASSISTANT (self), intro_page,
- GTK_ASSISTANT_PAGE_INTRO);
-}
-
-static void
-account_assistant_radio_choice_toggled_cb (GtkToggleButton *button,
- EmpathyAccountAssistant *self)
-{
- FirstPageResponse response;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- response = GPOINTER_TO_INT (g_object_get_data
- (G_OBJECT (button), "response"));
-
- priv->first_resp = response;
-
- update_intro_page_buttons (self);
-}
-
-static GtkWidget *
-account_assistant_build_introduction_page (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- GtkWidget *main_vbox, *hbox_1, *w, *vbox_1;
- GtkWidget *radio = NULL;
- GdkPixbuf *pix;
- const gchar *str;
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_widget_show (main_vbox);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
-
- hbox_1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox_1, TRUE, TRUE, 0);
- gtk_widget_show (hbox_1);
-
- w = gtk_label_new (
- _("With Empathy you can chat with people "
- "online nearby and with friends and colleagues "
- "who use Google Talk, AIM, Windows Live "
- "and many other chat programs. With a microphone "
- "or a webcam you can also have audio or video calls."));
- gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
-
- pix = empathy_pixbuf_from_icon_name_sized ("empathy", 80);
- w = gtk_image_new_from_pixbuf (pix);
- gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 6);
- gtk_widget_show (w);
-
- g_object_unref (pix);
-
- w = gtk_label_new (_("Do you have an account you've been using "
- "with another chat program?"));
- gtk_misc_set_alignment (GTK_MISC (w), 0, 0);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
-
- w = gtk_alignment_new (0, 0, 0, 0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, TRUE, TRUE, 0);
- gtk_widget_show (w);
-
- vbox_1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
- gtk_box_set_homogeneous (GTK_BOX (vbox_1), TRUE);
- gtk_container_add (GTK_CONTAINER (w), vbox_1);
- gtk_widget_show (vbox_1);
-
- if (empathy_import_accounts_to_import ())
- {
- hbox_1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_pack_start (GTK_BOX (vbox_1), hbox_1, TRUE, TRUE, 0);
- gtk_widget_show (hbox_1);
-
- radio = gtk_radio_button_new_with_label (NULL,
- _("Yes, import my account details from "));
- gtk_box_pack_start (GTK_BOX (hbox_1), radio, TRUE, TRUE, 0);
- g_object_set_data (G_OBJECT (radio), "response",
- GINT_TO_POINTER (RESPONSE_IMPORT));
- gtk_widget_show (radio);
-
- w = gtk_combo_box_text_new ();
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (w), "Pidgin");
- gtk_box_pack_start (GTK_BOX (hbox_1), w, TRUE, TRUE, 0);
- gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
- gtk_widget_show (w);
-
- g_signal_connect (radio, "clicked",
- G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
- priv->first_resp = RESPONSE_IMPORT;
- }
- else
- {
- priv->first_resp = RESPONSE_ENTER_ACCOUNT;
- }
-
- str = _("Yes, I'll enter my account details now");
-
- if (radio == NULL)
- {
- radio = gtk_radio_button_new_with_label (NULL, str);
- w = radio;
- }
- else
- {
- w = gtk_radio_button_new_with_label_from_widget (
- GTK_RADIO_BUTTON (radio), str);
- }
-
- gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
- g_object_set_data (G_OBJECT (w), "response",
- GINT_TO_POINTER (RESPONSE_ENTER_ACCOUNT));
- gtk_widget_show (w);
-
- g_signal_connect (w, "clicked",
- G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
-
- w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
- _("No, I want a new account"));
- gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
- g_object_set_data (G_OBJECT (w), "response",
- GINT_TO_POINTER (RESPONSE_CREATE_ACCOUNT));
- gtk_widget_show (w);
-
- g_signal_connect (w, "clicked",
- G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
-
- w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
- _("No, I just want to see people online nearby for now"));
- gtk_box_pack_start (GTK_BOX (vbox_1), w, TRUE, TRUE, 0);
- g_object_set_data (G_OBJECT (w), "response",
- GINT_TO_POINTER (RESPONSE_SALUT_ONLY));
- gtk_widget_show (w);
-
- g_signal_connect (w, "clicked",
- G_CALLBACK (account_assistant_radio_choice_toggled_cb), self);
-
- return main_vbox;
-}
-
-static GtkWidget *
-account_assistant_build_import_page (EmpathyAccountAssistant *self)
-{
- GtkWidget *main_vbox, *w, *import;
- EmpathyImportWidget *iw;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
- w = gtk_label_new (_("Select the accounts you want to import:"));
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
- gtk_widget_show (w);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 6);
-
- w = gtk_alignment_new (0, 0, 1, 1);
- gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, TRUE, TRUE, 0);
- gtk_widget_show (w);
-
- /* NOTE: this is hardcoded as we support pidgin only */
- iw = empathy_import_widget_new (EMPATHY_IMPORT_APPLICATION_PIDGIN);
- import = empathy_import_widget_get_widget (iw);
- gtk_container_add (GTK_CONTAINER (w), import);
- gtk_widget_show (import);
-
- priv->iw = iw;
-
- gtk_widget_show (main_vbox);
-
- return main_vbox;
-}
-
-static void
-account_assistant_radio_create_again_clicked_cb (GtkButton *button,
- EmpathyAccountAssistant *self)
-{
- CreateEnterPageResponse response;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
- "response"));
-
- priv->create_enter_resp = response;
-
- update_create_page_buttons (self);
-}
-
-static GtkWidget *
-account_assistant_build_enter_or_create_page (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- GtkWidget *main_vbox, *w, *chooser, *vbox, *hbox, *radio;
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
- gtk_widget_show (main_vbox);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
- gtk_widget_show (hbox);
-
- w = gtk_label_new (NULL);
- gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
- priv->first_label = w;
-
- w = gtk_alignment_new (0, 0, 0, 0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
-
- chooser = empathy_protocol_chooser_new ();
- gtk_box_pack_start (GTK_BOX (hbox), chooser, FALSE, FALSE, 0);
- gtk_widget_show (chooser);
- priv->chooser = chooser;
-
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_box_pack_end (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
- gtk_widget_show (vbox);
-
- w = gtk_label_new (NULL);
- gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
- gtk_widget_show (w);
- priv->second_label = w;
-
- w = gtk_alignment_new (0, 0, 0, 0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
- gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_container_add (GTK_CONTAINER (w), hbox);
- gtk_widget_show (hbox);
-
- radio = gtk_radio_button_new_with_label (NULL, _("Yes"));
- gtk_box_pack_start (GTK_BOX (hbox), radio, FALSE, FALSE, 0);
- g_object_set_data (G_OBJECT (radio), "response",
- GINT_TO_POINTER (RESPONSE_CREATE_AGAIN));
- gtk_widget_show (radio);
-
- w = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
- _("No, that's all for now"));
- gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
- g_object_set_data (G_OBJECT (w), "response",
- GINT_TO_POINTER (RESPONSE_CREATE_STOP));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
- priv->create_enter_resp = RESPONSE_CREATE_STOP;
- priv->create_again_radio = w;
- gtk_widget_show (w);
-
- g_signal_connect (w, "clicked",
- G_CALLBACK (account_assistant_radio_create_again_clicked_cb), self);
- g_signal_connect (radio, "clicked",
- G_CALLBACK (account_assistant_radio_create_again_clicked_cb), self);
-
- return main_vbox;
-}
-
-static void
-account_assistant_close_cb (GtkAssistant *assistant,
- gpointer user_data)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (assistant);
-
- if (priv->is_creating)
- return;
-
- gtk_widget_destroy (GTK_WIDGET (assistant));
-}
-
-static void
-impl_signal_apply (GtkAssistant *assistant)
-{
- EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (assistant);
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- gint current_page;
-
- current_page = gtk_assistant_get_current_page (assistant);
-
- if (current_page == PAGE_SALUT)
- {
- if (priv->create_salut_account)
- /* create_salut_account_settings() already set the display name of the
- * account so there is no need to set it again. */
- account_assistant_apply_account_and_finish (self, priv->salut_settings,
- FALSE);
- return;
- }
- else if (current_page >= PAGE_ENTER_CREATE &&
- priv->settings != NULL &&
- empathy_account_settings_is_valid (priv->settings))
- {
- account_assistant_apply_account_and_finish (self, priv->settings, TRUE);
- g_object_unref (priv->settings);
- priv->settings = NULL;
- }
- else if (current_page == PAGE_IMPORT)
- {
- empathy_import_widget_add_selected_accounts (priv->iw);
- }
-}
-
-static void
-impl_signal_cancel (GtkAssistant *assistant)
-{
- gtk_widget_destroy (GTK_WIDGET (assistant));
-}
-
-static void
-impl_signal_prepare (GtkAssistant *assistant,
- GtkWidget *current_page)
-{
- EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (assistant);
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- gint current_idx;
-
- /* check from which page we are coming from */
- if (priv->current_page_id == PAGE_IMPORT)
- empathy_import_widget_add_selected_accounts (priv->iw);
-
- current_idx = gtk_assistant_get_current_page (assistant);
- priv->current_page_id = current_idx;
-
- if (current_idx >= PAGE_ENTER_CREATE)
- {
- if (!priv->enter_create_forward && current_idx != PAGE_SALUT)
- {
- account_assistant_finish_enter_or_create_page (self,
- priv->first_resp == RESPONSE_ENTER_ACCOUNT ?
- TRUE : FALSE);
- }
- else
- {
- priv->enter_create_forward = FALSE;
- }
-
- if (priv->settings != NULL &&
- empathy_account_settings_is_valid (priv->settings))
- {
- account_assistant_apply_account_and_finish (self, priv->settings,
- TRUE);
- g_object_unref (priv->settings);
- priv->settings = NULL;
- }
- }
-}
-
-static void
-do_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
-
- switch (property_id)
- {
- case PROP_PARENT:
- g_value_set_object (value, priv->parent_window);
- break;
- case PROP_CONNECTION_MGRS:
- g_value_set_object (value, priv->connection_mgrs);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-do_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
-
- switch (property_id)
- {
- case PROP_PARENT:
- priv->parent_window = g_value_get_object (value);
- break;
- case PROP_CONNECTION_MGRS:
- priv->connection_mgrs = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-do_dispose (GObject *obj)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (obj);
-
- if (priv->dispose_run)
- return;
-
- priv->dispose_run = TRUE;
-
- if (priv->settings != NULL)
- {
- g_object_unref (priv->settings);
- priv->settings = NULL;
- }
-
- g_object_unref (priv->account_mgr);
- priv->account_mgr = NULL;
-
- g_object_unref (priv->connection_mgrs);
- priv->connection_mgrs = NULL;
-
- if (G_OBJECT_CLASS (empathy_account_assistant_parent_class)->dispose != NULL)
- G_OBJECT_CLASS (empathy_account_assistant_parent_class)->dispose (obj);
-}
-
-static void
-empathy_account_assistant_class_init (EmpathyAccountAssistantClass *klass)
-{
- GObjectClass *oclass = G_OBJECT_CLASS (klass);
- GtkAssistantClass *gtkclass = GTK_ASSISTANT_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;
-
- gtkclass->apply = impl_signal_apply;
- gtkclass->prepare = impl_signal_prepare;
- gtkclass->cancel = impl_signal_cancel;
-
- param_spec = g_param_spec_object ("parent-window",
- "parent-window", "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);
-
- param_spec = g_param_spec_object ("connection-managers",
- "connection-managers", "A EmpathyConnectionManagers",
- EMPATHY_TYPE_CONNECTION_MANAGERS,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_property (oclass, PROP_CONNECTION_MGRS, param_spec);
-
- g_type_class_add_private (klass, sizeof (EmpathyAccountAssistantPriv));
-}
-
-static void
-create_salut_check_box_toggled_cb (GtkWidget *widget,
- EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- gboolean sensitive;
- gboolean page_valid;
-
- sensitive = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
-
- gtk_widget_set_sensitive (priv->salut_account_widget, sensitive);
-
- if (!sensitive)
- {
- page_valid = TRUE;
- priv->create_salut_account = FALSE;
- }
- else
- {
- /* page is complete if the account is valid */
- page_valid = empathy_account_settings_is_valid (priv->salut_settings);
- priv->create_salut_account = TRUE;
- }
-
- gtk_assistant_set_page_complete (GTK_ASSISTANT (self), priv->salut_page,
- page_valid);
-}
-
-static void
-account_assistant_salut_handle_apply_cb (EmpathyAccountWidget *widget_object,
- gboolean is_valid,
- EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
-
- gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
- priv->salut_page, is_valid);
-}
-
-static GtkWidget *
-account_assistant_build_salut_page (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- GtkWidget *main_vbox, *hbox_1, *w;
- GdkPixbuf *pix;
- EmpathyAccountSettings *settings;
- GtkWidget *account_widget;
- EmpathyAccountWidget *widget_object;
- gchar *markup;
-
- main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
- gtk_widget_show (main_vbox);
- gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
-
- hbox_1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
- gtk_box_pack_start (GTK_BOX (main_vbox), hbox_1, TRUE, TRUE, 0);
- gtk_widget_show (hbox_1);
-
- w = gtk_label_new (NULL);
- markup = g_strdup_printf ("%s (<span style=\"italic\">%s</span>).",
- _("Empathy can automatically discover and chat with the people "
- "connected on the same network as you. "
- "If you want to use this feature, please check that the "
- "details below are correct. "
- "You can easily change these details later or disable this feature "
- "by using the 'Accounts' dialog"),
- _("Edit->Accounts"));
- gtk_label_set_markup (GTK_LABEL (w), markup);
- g_free (markup);
- gtk_misc_set_alignment (GTK_MISC (w), 0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
- gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 0);
- gtk_widget_show (w);
-
- pix = empathy_pixbuf_from_icon_name_sized ("im-local-xmpp", 80);
- w = gtk_image_new_from_pixbuf (pix);
- gtk_box_pack_start (GTK_BOX (hbox_1), w, FALSE, FALSE, 6);
- gtk_widget_show (w);
-
- g_object_unref (pix);
-
- w = gtk_check_button_new_with_mnemonic (
- _("I do _not want to enable this feature for now"));
- gtk_box_pack_start (GTK_BOX (main_vbox), w, FALSE, FALSE, 0);
- g_signal_connect (w, "toggled",
- G_CALLBACK (create_salut_check_box_toggled_cb), self);
- gtk_widget_show (w);
-
- w = gtk_alignment_new (0, 0, 0, 0);
- gtk_alignment_set_padding (GTK_ALIGNMENT (w), 0, 0, 12, 0);
- gtk_box_pack_start (GTK_BOX (main_vbox), w, TRUE, TRUE, 0);
- gtk_widget_show (w);
-
- settings = create_salut_account_settings ();
-
- widget_object = empathy_account_widget_new_for_protocol (settings, TRUE);
- account_widget = empathy_account_widget_get_widget (widget_object);
-
- priv->salut_settings = settings;
- priv->salut_account_widget = account_widget;
-
- g_signal_connect (widget_object, "handle-apply",
- G_CALLBACK (account_assistant_salut_handle_apply_cb), self);
-
- gtk_box_pack_start (GTK_BOX (main_vbox), account_widget,
- FALSE, FALSE, 0);
- gtk_widget_show (account_widget);
-
- return main_vbox;
-}
-
-static GtkWidget *
-account_assistant_build_salut_error_page (EmpathyAccountAssistant *self)
-{
- GtkWidget *vbox;
- gchar *markup;
-
- markup = g_strdup_printf ("%s (<span style=\"italic\">%s</span>).",
- _("You won't be able to chat with people connected to your local "
- "network, as telepathy-salut is not installed. If you want to enable "
- "this feature, please install the telepathy-salut package and create "
- "a People Nearby account from the Accounts dialog"),
- _("Edit->Accounts"));
-
- vbox = build_error_vbox (_("telepathy-salut not installed"), markup);
- g_free (markup);
- return vbox;
-}
-
-static void
-account_mgr_prepare_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- EmpathyAccountAssistant *self = user_data;
- EmpathyAccountAssistantPriv *priv = GET_PRIV (self);
- TpAccountManager *manager = TP_ACCOUNT_MANAGER (source_object);
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (manager, result, &error))
- {
- DEBUG ("Failed to prepare account manager: %s", error->message);
- g_error_free (error);
- return;
- }
-
- if (!should_create_salut_account (manager))
- {
- DEBUG ("No need to create a Salut account");
- priv->display_salut_page = FALSE;
-
- update_intro_page_buttons (self);
-
- gtk_assistant_set_page_type (GTK_ASSISTANT (self), priv->import_page,
- GTK_ASSISTANT_PAGE_CONFIRM);
-
- update_create_page_buttons (self);
- }
-}
-
-static void
-empathy_account_assistant_init (EmpathyAccountAssistant *self)
-{
- EmpathyAccountAssistantPriv *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_ACCOUNT_ASSISTANT,
- EmpathyAccountAssistantPriv);
- self->priv = priv;
-
- gtk_window_set_title (GTK_WINDOW (self),
- _("Messaging and VoIP Accounts Assistant"));
-
- priv->account_mgr = tp_account_manager_dup ();
-}
-
-static void
-do_constructed (GObject *object)
-{
- GtkAssistant *assistant = GTK_ASSISTANT (object);
- EmpathyAccountAssistant *self = EMPATHY_ACCOUNT_ASSISTANT (object);
- EmpathyAccountAssistantPriv *priv = GET_PRIV (object);
- GtkWidget *page;
-
- /* set us as transient for the parent window if any */
- if (priv->parent_window)
- gtk_window_set_transient_for (GTK_WINDOW (object),
- priv->parent_window);
-
- /* set the dialog hint, so this will be centered over the parent window */
- gtk_window_set_type_hint (GTK_WINDOW (object), GDK_WINDOW_TYPE_HINT_DIALOG);
-
- g_assert (priv->connection_mgrs != NULL);
- g_assert (empathy_connection_managers_is_ready (priv->connection_mgrs));
-
- g_signal_connect (self, "close",
- G_CALLBACK (account_assistant_close_cb), NULL);
-
- gtk_assistant_set_forward_page_func (assistant,
- account_assistant_page_forward_func, self, NULL);
-
- /* first page (introduction) */
- page = account_assistant_build_introduction_page (self);
- gtk_assistant_append_page (assistant, page);
- gtk_assistant_set_page_title (assistant, page,
- _("Welcome to Empathy"));
- gtk_assistant_set_page_type (assistant, page,
- GTK_ASSISTANT_PAGE_INTRO);
- gtk_assistant_set_page_complete (assistant, page, TRUE);
-
- /* second page (import accounts) */
- page = account_assistant_build_import_page (self);
- gtk_assistant_append_page (assistant, page);
- gtk_assistant_set_page_title (assistant, page,
- _("Import your existing accounts"));
- gtk_assistant_set_page_complete (assistant, page, TRUE);
- gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
- priv->import_page = page;
-
- /* third page (enter account details) */
- page = account_assistant_build_enter_or_create_page (self);
- gtk_assistant_append_page (assistant, page);
- gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONTENT);
- priv->enter_or_create_page = page;
-
- /* fourth page (salut details) */
- if (empathy_connection_managers_get_cm (priv->connection_mgrs, "salut")
- != NULL)
- {
- page = account_assistant_build_salut_page (self);
- gtk_assistant_append_page (assistant, page);
- gtk_assistant_set_page_title (assistant, page,
- _("Please enter personal details"));
- gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_CONFIRM);
-
- priv->create_salut_account = TRUE;
-
- if (empathy_account_settings_is_valid (priv->salut_settings))
- {
- gtk_assistant_set_page_complete (GTK_ASSISTANT (self),
- page, TRUE);
- }
- }
- else
- {
- page = account_assistant_build_salut_error_page (self);
- gtk_assistant_append_page (assistant, page);
- gtk_assistant_set_page_title (assistant, page, _("An error occurred"));
- gtk_assistant_set_page_type (assistant, page, GTK_ASSISTANT_PAGE_SUMMARY);
-
- priv->create_salut_account = FALSE;
- }
-
- priv->salut_page = page;
- priv->display_salut_page = TRUE;
-
- tp_proxy_prepare_async (priv->account_mgr, NULL,
- account_mgr_prepare_cb, self);
-
- gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
-}
-
-GtkWidget *
-empathy_account_assistant_show (GtkWindow *window,
- EmpathyConnectionManagers *connection_mgrs)
-{
- static GtkWidget *dialog = NULL;
-
- if (dialog == NULL)
- {
- dialog = g_object_new (EMPATHY_TYPE_ACCOUNT_ASSISTANT,
- "parent-window", window,
- "connection-managers", connection_mgrs,
- NULL);
- g_object_add_weak_pointer (G_OBJECT (dialog), (gpointer *) &dialog);
- }
-
- gtk_window_present (GTK_WINDOW (dialog));
-
- return dialog;
-}
-
-
diff --git a/src/empathy-account-assistant.h b/src/empathy-account-assistant.h
deleted file mode 100644
index d99475fe3..000000000
--- a/src/empathy-account-assistant.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
- */
-
-/* empathy-account-assistant.h */
-
-#ifndef __EMPATHY_ACCOUNT_ASSISTANT_H__
-#define __EMPATHY_ACCOUNT_ASSISTANT_H__
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include <libempathy/empathy-connection-managers.h>
-
-G_BEGIN_DECLS
-
-#define EMPATHY_TYPE_ACCOUNT_ASSISTANT empathy_account_assistant_get_type()
-#define EMPATHY_ACCOUNT_ASSISTANT(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_ACCOUNT_ASSISTANT,\
- EmpathyAccountAssistant))
-#define EMPATHY_ACCOUNT_ASSISTANT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), EMPATHY_TYPE_ACCOUNT_ASSISTANT,\
- EmpathyAccountAssistantClass))
-#define EMPATHY_IS_ACCOUNT_ASSISTANT(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_ACCOUNT_ASSISTANT))
-#define EMPATHY_IS_ACCOUNT_ASSISTANT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), EMPATHY_TYPE_ACCOUNT_ASSISTANT))
-#define EMPATHY_ACCOUNT_ASSISTANT_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_ACCOUNT_ASSISTANT,\
- EmpathyAccountAssistantClass))
-
-typedef struct {
- GtkAssistant parent;
-
- /* private */
- gpointer priv;
-} EmpathyAccountAssistant;
-
-typedef struct {
- GtkAssistantClass parent_class;
-} EmpathyAccountAssistantClass;
-
-GType empathy_account_assistant_get_type (void);
-
-GtkWidget *empathy_account_assistant_show (GtkWindow *parent,
- EmpathyConnectionManagers *connection_mgrs);
-
-G_END_DECLS
-
-#endif /* __EMPATHY_ACCOUNT_ASSISTANT_H__ */
diff --git a/src/empathy-accounts-common.c b/src/empathy-accounts-common.c
index 88d14c321..f6bb40278 100644
--- a/src/empathy-accounts-common.c
+++ b/src/empathy-accounts-common.c
@@ -41,8 +41,6 @@
#include "empathy-accounts-common.h"
#include "empathy-accounts-dialog.h"
-#include "empathy-account-assistant.h"
-#include "empathy-auto-salut-account-helper.h"
#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
#include <libempathy/empathy-debug.h>
@@ -82,13 +80,16 @@ empathy_accounts_has_accounts (TpAccountManager *manager)
return has_accounts;
}
-static void
-do_show_accounts_ui (TpAccountManager *manager,
+void
+empathy_accounts_show_accounts_ui (TpAccountManager *manager,
TpAccount *account,
GApplication *app)
{
static GtkWidget *accounts_window = NULL;
+ g_return_if_fail (TP_IS_ACCOUNT_MANAGER (manager));
+ g_return_if_fail (!account || TP_IS_ACCOUNT (account));
+
if (accounts_window == NULL)
{
accounts_window = empathy_accounts_dialog_show (NULL, account);
@@ -99,63 +100,3 @@ do_show_accounts_ui (TpAccountManager *manager,
gtk_window_present (GTK_WINDOW (accounts_window));
}
-
-static GtkWidget *
-show_account_assistant (EmpathyConnectionManagers *connection_mgrs,
- GApplication *app)
-{
- GtkWidget *assistant;
-
- assistant = empathy_account_assistant_show (NULL, connection_mgrs);
-
- gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (assistant));
-
- return assistant;
-}
-
-static void
-connection_managers_prepare_for_accounts (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- EmpathyConnectionManagers *cm_mgr = EMPATHY_CONNECTION_MANAGERS (source);
- GApplication *app = user_data;
-
- if (!empathy_connection_managers_prepare_finish (cm_mgr, result, NULL))
- goto out;
-
- show_account_assistant (cm_mgr, app);
- DEBUG ("would show the account assistant");
-
-out:
- g_object_unref (cm_mgr);
- g_application_release (app);
-}
-
-void
-empathy_accounts_show_accounts_ui (TpAccountManager *manager,
- TpAccount *account,
- gboolean assistant,
- GApplication *app)
-{
- g_return_if_fail (TP_IS_ACCOUNT_MANAGER (manager));
- g_return_if_fail (!account || TP_IS_ACCOUNT (account));
-
- if ((empathy_accounts_has_non_salut_accounts (manager) && !assistant) ||
- account != NULL)
- {
- do_show_accounts_ui (manager, account, app);
- }
- else
- {
- EmpathyConnectionManagers *cm_mgr;
-
- cm_mgr = empathy_connection_managers_dup_singleton ();
-
- /* Hold the application while preparing cm_mgr */
- g_application_hold (app);
-
- empathy_connection_managers_prepare_async (cm_mgr,
- connection_managers_prepare_for_accounts, app);
- }
-}
diff --git a/src/empathy-accounts-common.h b/src/empathy-accounts-common.h
index f9294fbd2..39d094d22 100644
--- a/src/empathy-accounts-common.h
+++ b/src/empathy-accounts-common.h
@@ -28,7 +28,6 @@ gboolean empathy_accounts_has_accounts (TpAccountManager *manager);
void empathy_accounts_show_accounts_ui (TpAccountManager *manager,
TpAccount *account,
- gboolean assistant,
GApplication *app);
#endif /* __EMPATHY_ACCOUNTS_COMMON_H__ */
diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c
index 9e2fea781..b2b57dec1 100644
--- a/src/empathy-accounts-dialog.c
+++ b/src/empathy-accounts-dialog.c
@@ -21,6 +21,7 @@
* Xavier Claessens <xclaesse@gmail.com>
* Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
* Jonathan Tellier <jonathan.tellier@gmail.com>
+ * Danielle Madeley <danielle.madeley@collabora.co.uk>
*/
#include <config.h>
@@ -31,6 +32,7 @@
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
#include <dbus/dbus-glib.h>
+#include <gio/gdesktopappinfo.h>
#include <telepathy-glib/account-manager.h>
#include <telepathy-glib/defs.h>
@@ -39,6 +41,7 @@
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-connection-managers.h>
#include <libempathy/empathy-connectivity.h>
+#include <libempathy/empathy-tp-contact-factory.h>
#include <libempathy-gtk/empathy-ui-utils.h>
#include <libempathy-gtk/empathy-protocol-chooser.h>
@@ -46,8 +49,12 @@
#include <libempathy-gtk/empathy-account-widget-irc.h>
#include <libempathy-gtk/empathy-account-widget-sip.h>
#include <libempathy-gtk/empathy-cell-renderer-activatable.h>
+#include <libempathy-gtk/empathy-contact-widget.h>
#include <libempathy-gtk/empathy-images.h>
+#include <libempathy-gtk/empathy-local-xmpp-assistant-widget.h>
+#include <libempathy-gtk/empathy-new-account-dialog.h>
+#include "empathy-accounts-common.h"
#include "empathy-accounts-dialog.h"
#include "empathy-import-dialog.h"
#include "empathy-import-utils.h"
@@ -73,7 +80,8 @@ G_DEFINE_TYPE (EmpathyAccountsDialog, empathy_accounts_dialog, GTK_TYPE_DIALOG);
enum
{
NOTEBOOK_PAGE_ACCOUNT = 0,
- NOTEBOOK_PAGE_LOADING
+ NOTEBOOK_PAGE_LOADING,
+ NOTEBOOK_PAGE_NO_PROTOCOL
};
typedef struct {
@@ -86,7 +94,6 @@ typedef struct {
GtkWidget *image_status;
GtkWidget *throbber;
GtkWidget *enabled_switch;
- GtkWidget *frame_no_protocol;
GtkWidget *treeview;
@@ -94,13 +101,10 @@ typedef struct {
GtkWidget *button_remove;
GtkWidget *button_import;
- GtkWidget *combobox_protocol;
- GtkWidget *hbox_protocol;
-
GtkWidget *image_type;
GtkWidget *label_name;
GtkWidget *label_type;
- GtkWidget *settings_widget;
+ GtkWidget *dialog_content;
GtkWidget *notebook_account;
GtkWidget *spinner;
@@ -157,21 +161,13 @@ enum {
static EmpathyAccountSettings * accounts_dialog_model_get_selected_settings (
EmpathyAccountsDialog *dialog);
-static gboolean accounts_dialog_get_settings_iter (
- EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *settings,
- GtkTreeIter *iter);
-
static void accounts_dialog_model_select_first (EmpathyAccountsDialog *dialog);
static void accounts_dialog_update_settings (EmpathyAccountsDialog *dialog,
EmpathyAccountSettings *settings);
-static void accounts_dialog_add (EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *settings);
-
static void accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *settings);
+ TpAccount *account);
static void accounts_dialog_connection_changed_cb (TpAccount *account,
guint old_status,
@@ -191,6 +187,9 @@ static void accounts_dialog_model_selection_changed (
GtkTreeSelection *selection,
EmpathyAccountsDialog *dialog);
+static gboolean accounts_dialog_has_pending_change (
+ EmpathyAccountsDialog *dialog, TpAccount **account);
+
static void
accounts_dialog_update_name_label (EmpathyAccountsDialog *dialog,
const gchar *display_name)
@@ -213,6 +212,9 @@ accounts_dialog_status_infobar_set_message (EmpathyAccountsDialog *dialog,
message_markup = g_markup_printf_escaped ("<i>%s</i>", message);
gtk_label_set_markup (GTK_LABEL (priv->label_status), message_markup);
+
+ gtk_widget_set_tooltip_text (priv->label_status, message);
+
g_free (message_markup);
}
@@ -497,28 +499,6 @@ empathy_account_dialog_widget_cancelled_cb (
empathy_account_dialog_cancel (dialog);
}
-static void
-empathy_account_dialog_account_created_cb (EmpathyAccountWidget *widget_object,
- TpAccount *account,
- EmpathyAccountsDialog *dialog)
-{
- EmpathyAccountSettings *settings =
- accounts_dialog_model_get_selected_settings (dialog);
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-
- accounts_dialog_update_settings (dialog, settings);
- accounts_dialog_update_status_infobar (dialog,
- empathy_account_settings_get_account (settings));
-
- gtk_widget_set_sensitive (priv->treeview, TRUE);
- gtk_widget_set_sensitive (priv->button_add, TRUE);
- gtk_widget_set_sensitive (priv->button_remove, TRUE);
- gtk_widget_set_sensitive (priv->button_import, TRUE);
-
- if (settings)
- g_object_unref (settings);
-}
-
static gboolean
accounts_dialog_has_valid_accounts (EmpathyAccountsDialog *dialog)
{
@@ -542,19 +522,21 @@ accounts_dialog_has_valid_accounts (EmpathyAccountsDialog *dialog)
}
static void
-account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *settings)
+account_dialog_create_edit_params_dialog (EmpathyAccountsDialog *dialog)
{
EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
- const gchar *icon_name;
- TpAccount *account;
+ EmpathyAccountSettings *settings;
+ GtkWidget *subdialog, *content, *content_area, *align;
- if (priv->setting_widget_object != NULL)
- g_object_remove_weak_pointer (G_OBJECT (priv->setting_widget_object),
- (gpointer *) &priv->setting_widget_object);
+ settings = accounts_dialog_model_get_selected_settings (dialog);
+
+ subdialog = gtk_dialog_new_with_buttons (_("Edit Connection Parameters"),
+ GTK_WINDOW (dialog),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ NULL, NULL);
priv->setting_widget_object =
- empathy_account_widget_new_for_protocol (settings, FALSE);
+ empathy_account_widget_new_for_protocol (settings, FALSE);
g_object_add_weak_pointer (G_OBJECT (priv->setting_widget_object),
(gpointer *) &priv->setting_widget_object);
@@ -563,17 +545,250 @@ account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog,
empathy_account_widget_set_other_accounts_exist (
priv->setting_widget_object, TRUE);
- priv->settings_widget =
- empathy_account_widget_get_widget (priv->setting_widget_object);
+ content = empathy_account_widget_get_widget (priv->setting_widget_object);
- g_signal_connect (priv->setting_widget_object, "account-created",
- G_CALLBACK (empathy_account_dialog_account_created_cb), dialog);
g_signal_connect (priv->setting_widget_object, "cancelled",
G_CALLBACK (empathy_account_dialog_widget_cancelled_cb), dialog);
+ g_signal_connect_swapped (priv->setting_widget_object, "close",
+ G_CALLBACK (gtk_widget_destroy), subdialog);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (subdialog));
+
+ align = gtk_alignment_new (0.5, 0.5, 1, 1);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 0, 6, 6);
+
+ gtk_container_add (GTK_CONTAINER (align), content);
+ gtk_box_pack_start (GTK_BOX (content_area), align, TRUE, TRUE, 0);
+
+ gtk_widget_show (content);
+ gtk_widget_show (align);
+ gtk_widget_show (subdialog);
+}
+
+static void
+start_external_app (GAppInfo *app_info)
+{
+ GError *error = NULL;
+ GdkAppLaunchContext *context = NULL;
+ GdkDisplay *display;
+
+ display = gdk_display_get_default ();
+ context = gdk_display_get_app_launch_context (display);
+
+ if (!g_app_info_launch (app_info, NULL, (GAppLaunchContext *) context,
+ &error))
+ {
+ g_critical ("Failed to bisho: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ tp_clear_object (&context);
+}
+
+static void
+use_external_storage_provider (EmpathyAccountsDialog *self,
+ TpAccount *account)
+{
+ const gchar *provider;
+
+ provider = tp_account_get_storage_provider (account);
+ if (!tp_strdiff (provider, "com.meego.libsocialweb"))
+ {
+ GDesktopAppInfo *desktop_info;
+ gchar *cmd;
+ GAppInfo *app_info;
+ GError *error = NULL;
+
+ desktop_info = g_desktop_app_info_new ("gnome-control-center.desktop");
+ if (desktop_info == NULL)
+ {
+ g_critical ("Could not locate 'gnome-control-center.desktop'");
+ return;
+ }
+
+ /* glib doesn't have API to start a desktop file with args... (#637875) */
+ cmd = g_strdup_printf ("%s bisho.desktop", g_app_info_get_commandline (
+ (GAppInfo *) desktop_info));
+
+ app_info = g_app_info_create_from_commandline (cmd, NULL, 0, &error);
+
+ if (app_info == NULL)
+ {
+ DEBUG ("Failed to create app info: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ start_external_app (app_info);
+ g_object_unref (app_info);
+ }
+
+ g_object_unref (desktop_info);
+ g_free (cmd);
+ return;
+ }
+ else if (!tp_strdiff (provider, "org.gnome.OnlineAccounts"))
+ {
+ GDesktopAppInfo *desktop_info;
+
+ desktop_info = g_desktop_app_info_new (
+ "gnome-online-accounts-panel.desktop");
+ if (desktop_info == NULL)
+ {
+ g_critical ("Could not locate 'gnome-online-accounts-panel.desktop'");
+ }
+ else
+ {
+ start_external_app (G_APP_INFO (desktop_info));
+ g_object_unref (desktop_info);
+ }
+
+ return;
+ }
+ else
+ {
+ DEBUG ("Don't know how to handle %s", provider);
+ return;
+ }
+}
+
+static void
+account_dialow_show_edit_params_dialog (EmpathyAccountsDialog *dialog,
+ GtkButton *button)
+{
+ EmpathyAccountSettings *settings;
+ TpAccount *account;
+ TpStorageRestrictionFlags storage_restrictions;
+
+ settings = accounts_dialog_model_get_selected_settings (dialog);
+
+ account = empathy_account_settings_get_account (settings);
+ g_return_if_fail (account != NULL);
+
+ storage_restrictions = tp_account_get_storage_restrictions (account);
+
+ /* Empathy can only edit accounts without the Cannot_Set_Parameters flag */
+ if (storage_restrictions & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS)
+ {
+ DEBUG ("Account is provided by an external storage provider");
+
+ use_external_storage_provider (dialog, account);
+ }
+ else
+ {
+ account_dialog_create_edit_params_dialog (dialog);
+ }
+}
+
+static void
+account_dialog_show_contact_details_failed (EmpathyAccountsDialog *dialog,
+ gboolean error)
+{
+ EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
+ GtkWidget *infobar, *label;
+
+ infobar = gtk_info_bar_new ();
+
+ if (error)
+ {
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (infobar), GTK_MESSAGE_ERROR);
+ label = gtk_label_new (_("Failed to retrieve your personal information "
+ "from the server."));
+ }
+ else
+ {
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (infobar), GTK_MESSAGE_INFO);
+ label = gtk_label_new (_("Go online to edit your personal information."));
+ }
+
+ gtk_container_add (
+ GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (infobar))),
+ label);
+ gtk_box_pack_start (GTK_BOX (priv->dialog_content), infobar, FALSE, FALSE, 0);
+ gtk_widget_show_all (infobar);
+}
+
+static void
+account_dialog_got_self_contact (TpConnection *conn,
+ EmpathyContact *contact,
+ const GError *in_error,
+ gpointer user_data,
+ GObject *dialog)
+{
+ EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
+ GtkWidget *editor, *alig;
+
+ if (in_error != NULL)
+ {
+ DEBUG ("Failed to get self-contact: %s", in_error->message);
+ account_dialog_show_contact_details_failed (
+ EMPATHY_ACCOUNTS_DIALOG (dialog), TRUE);
+ return;
+ }
+
+ alig = gtk_alignment_new (0.5, 0, 1, 1);
+
+ /* create the contact info editor for this account */
+ editor = empathy_contact_widget_new (contact,
+ EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
+ EMPATHY_CONTACT_WIDGET_EDIT_AVATAR |
+ EMPATHY_CONTACT_WIDGET_NO_STATUS |
+ EMPATHY_CONTACT_WIDGET_EDIT_DETAILS);
+
+ gtk_box_pack_start (GTK_BOX (priv->dialog_content), alig, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (alig), editor);
+ gtk_widget_show (alig);
+ gtk_widget_show (editor);
+}
+
+static void
+account_dialog_create_dialog_content (EmpathyAccountsDialog *dialog,
+ EmpathyAccountSettings *settings)
+{
+ EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
+ const gchar *icon_name;
+ TpAccount *account;
+ TpConnection *conn = NULL;
+ GtkWidget *bbox, *button;
+
+ account = empathy_account_settings_get_account (settings);
+
+ // if (priv->setting_widget_object != NULL)
+ // g_object_remove_weak_pointer (G_OBJECT (priv->setting_widget_object),
+ // (gpointer *) &priv->setting_widget_object);
+
+ priv->dialog_content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (priv->alignment_settings),
- priv->settings_widget);
- gtk_widget_show (priv->settings_widget);
+ priv->dialog_content);
+ gtk_widget_show (priv->dialog_content);
+
+ /* request the self contact */
+ if (account != NULL)
+ conn = tp_account_get_connection (account);
+
+ if (conn != NULL)
+ {
+ empathy_tp_contact_factory_get_from_handle (conn,
+ tp_connection_get_self_handle (conn),
+ account_dialog_got_self_contact,
+ NULL, NULL, G_OBJECT (dialog));
+ }
+ else
+ {
+ account_dialog_show_contact_details_failed (dialog, FALSE);
+ }
+
+ bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_box_pack_end (GTK_BOX (priv->dialog_content), bbox, FALSE, TRUE, 0);
+ gtk_widget_show (bbox);
+
+ button = gtk_button_new_with_mnemonic (_("_Edit Connection Parameters..."));
+ gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+ g_signal_connect_swapped (button, "clicked",
+ G_CALLBACK (account_dialow_show_edit_params_dialog), dialog);
icon_name = empathy_account_settings_get_icon_name (settings);
@@ -594,7 +809,6 @@ account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog,
accounts_dialog_update_name_label (dialog,
empathy_account_settings_get_display_name (settings));
- account = empathy_account_settings_get_account (settings);
accounts_dialog_update_status_infobar (dialog, account);
}
@@ -604,7 +818,7 @@ account_dialog_settings_ready_cb (EmpathyAccountSettings *settings,
EmpathyAccountsDialog *dialog)
{
if (empathy_account_settings_is_ready (settings))
- account_dialog_create_settings_widget (dialog, settings);
+ account_dialog_create_dialog_content (dialog, settings);
}
static void
@@ -651,97 +865,6 @@ accounts_dialog_has_pending_change (EmpathyAccountsDialog *dialog,
}
static void
-accounts_dialog_setup_ui_to_add_account (EmpathyAccountsDialog *dialog)
-{
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
- EmpathyAccountSettings *settings;
-
- settings = empathy_protocol_chooser_create_account_settings (
- EMPATHY_PROTOCOL_CHOOSER (priv->combobox_protocol));
- if (settings == NULL)
- return;
-
- accounts_dialog_add (dialog, settings);
- accounts_dialog_model_set_selected (dialog, settings);
-
- gtk_widget_show_all (priv->hbox_protocol);
-
- g_object_unref (settings);
-}
-
-static void
-accounts_dialog_protocol_changed_cb (GtkWidget *widget,
- EmpathyAccountsDialog *dialog)
-{
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
- GtkTreeSelection *selection;
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean creating;
- EmpathyAccountSettings *settings;
- gchar *account = NULL, *password = NULL;
-
- /* The "changed" signal is fired during the initiation of the
- * EmpathyProtocolChooser while populating the widget. Such signals should
- * be ignored so we check if we are actually creating a new account. */
- if (priv->setting_widget_object == NULL)
- return;
-
- g_object_get (priv->setting_widget_object,
- "creating-account", &creating, NULL);
- if (!creating)
- return;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
-
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- return;
-
- /* Save "account" and "password" parameters */
- g_object_get (priv->setting_widget_object, "settings", &settings, NULL);
-
- if (settings != NULL)
- {
- account = g_strdup (empathy_account_settings_get_string (settings,
- "account"));
- password = g_strdup (empathy_account_settings_get_string (settings,
- "password"));
- g_object_unref (settings);
- }
-
- /* We are creating a new widget to replace the current one, don't ask
- * confirmation to the user. */
- priv->force_change_row = TRUE;
-
- /* We'll update the selection after we create the new account widgets;
- * updating it right now causes problems for the # of accounts = zero case */
- g_signal_handlers_block_by_func (selection,
- accounts_dialog_model_selection_changed, dialog);
-
- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-
- g_signal_handlers_unblock_by_func (selection,
- accounts_dialog_model_selection_changed, dialog);
-
- accounts_dialog_setup_ui_to_add_account (dialog);
-
- /* Restore "account" and "password" parameters in the new widget */
- if (account != NULL)
- {
- empathy_account_widget_set_account_param (priv->setting_widget_object,
- account);
- g_free (account);
- }
-
- if (password != NULL)
- {
- empathy_account_widget_set_password_param (priv->setting_widget_object,
- password);
- g_free (password);
- }
-}
-
-static void
accounts_dialog_show_question_dialog (EmpathyAccountsDialog *dialog,
const gchar *primary_text,
const gchar *secondary_text,
@@ -781,24 +904,6 @@ accounts_dialog_show_question_dialog (EmpathyAccountsDialog *dialog,
gtk_widget_show (message_dialog);
}
-static void
-accounts_dialog_add_pending_changes_response_cb (GtkDialog *message_dialog,
- gint response_id,
- gpointer *user_data)
-{
- EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (user_data);
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-
- gtk_widget_destroy (GTK_WIDGET (message_dialog));
-
- if (response_id == GTK_RESPONSE_YES)
- {
- empathy_account_widget_discard_pending_changes (
- priv->setting_widget_object);
- accounts_dialog_setup_ui_to_add_account (dialog);
- }
-}
-
static gchar *
get_dialog_primary_text (TpAccount *account)
{
@@ -817,37 +922,32 @@ get_dialog_primary_text (TpAccount *account)
static void
accounts_dialog_button_add_clicked_cb (GtkWidget *button,
- EmpathyAccountsDialog *dialog)
+ EmpathyAccountsDialog *self)
{
- TpAccount *account = NULL;
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
+ GtkWidget *dialog;
+ gint response;
- if (accounts_dialog_has_pending_change (dialog, &account))
- {
- gchar *question_dialog_primary_text = get_dialog_primary_text (account);
+ dialog = empathy_new_account_dialog_new (GTK_WINDOW (self));
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- accounts_dialog_show_question_dialog (dialog,
- question_dialog_primary_text,
- _("You are about to create a new account, which will discard\n"
- "your changes. Are you sure you want to proceed?"),
- G_CALLBACK (accounts_dialog_add_pending_changes_response_cb),
- dialog,
- GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
- GTK_STOCK_DISCARD, GTK_RESPONSE_YES, NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
- g_free (question_dialog_primary_text);
- }
- else
+ if (response == GTK_RESPONSE_OK)
{
- accounts_dialog_setup_ui_to_add_account (dialog);
- gtk_widget_set_sensitive (priv->treeview, FALSE);
- gtk_widget_set_sensitive (priv->button_add, FALSE);
- gtk_widget_set_sensitive (priv->button_remove, FALSE);
- gtk_widget_set_sensitive (priv->button_import, FALSE);
+ EmpathyAccountSettings *settings;
+ TpAccount *account;
+
+ settings = empathy_new_account_dialog_get_settings (
+ EMPATHY_NEW_ACCOUNT_DIALOG (dialog));
+
+ /* The newly created account has already been added by
+ * accounts_dialog_account_validity_changed_cb so we just
+ * have to select it. */
+ account = empathy_account_settings_get_account (settings);
+ accounts_dialog_model_set_selected (self, account);
}
- if (account != NULL)
- g_object_unref (account);
+ gtk_widget_destroy (dialog);
}
static void
@@ -883,38 +983,29 @@ accounts_dialog_update_settings (EmpathyAccountsDialog *dialog,
return;
}
- if (empathy_connection_managers_get_cms_num (priv->cms) > 0)
- {
- /* We have no account configured but we have some
- * profiles installed. 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_show (priv->frame_no_protocol);
gtk_widget_set_sensitive (priv->button_add, FALSE);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook_account),
+ NOTEBOOK_PAGE_NO_PROTOCOL);
return;
}
/* We have an account selected, destroy old settings and create a new
* one for the account selected */
- gtk_widget_hide (priv->frame_no_protocol);
gtk_widget_show (priv->vbox_details);
- gtk_widget_hide (priv->hbox_protocol);
- if (priv->settings_widget)
+ if (priv->dialog_content)
{
- gtk_widget_destroy (priv->settings_widget);
- priv->settings_widget = NULL;
+ gtk_widget_destroy (priv->dialog_content);
+ priv->dialog_content = NULL;
}
if (empathy_account_settings_is_ready (settings))
{
- account_dialog_create_settings_widget (dialog, settings);
+ account_dialog_create_dialog_content (dialog, settings);
}
else
{
@@ -1484,41 +1575,6 @@ accounts_dialog_model_setup (EmpathyAccountsDialog *dialog)
}
static gboolean
-accounts_dialog_get_settings_iter (EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *settings,
- GtkTreeIter *iter)
-{
- GtkTreeView *view;
- GtkTreeModel *model;
- gboolean ok;
- EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
-
- /* Update the status in the model */
- view = GTK_TREE_VIEW (priv->treeview);
- 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, &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,
TpAccount *account,
GtkTreeIter *iter)
@@ -1536,15 +1592,15 @@ accounts_dialog_get_account_iter (EmpathyAccountsDialog *dialog,
ok;
ok = gtk_tree_model_iter_next (model, iter))
{
- EmpathyAccountSettings *settings;
+ TpAccount *this_account;
gboolean equal;
gtk_tree_model_get (model, iter,
- COL_ACCOUNT_SETTINGS, &settings,
+ COL_ACCOUNT, &this_account,
-1);
- equal = empathy_account_settings_has_account (settings, account);
- g_object_unref (settings);
+ equal = (this_account == account);
+ g_object_unref (this_account);
if (equal)
return TRUE;
@@ -1577,11 +1633,11 @@ select_and_scroll_to_iter (EmpathyAccountsDialog *dialog,
static void
accounts_dialog_model_set_selected (EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *settings)
+ TpAccount *account)
{
GtkTreeIter iter;
- if (accounts_dialog_get_settings_iter (dialog, settings, &iter))
+ if (accounts_dialog_get_account_iter (dialog, account, &iter))
select_and_scroll_to_iter (dialog, &iter);
}
@@ -1680,27 +1736,6 @@ finally:
}
static void
-accounts_dialog_add (EmpathyAccountsDialog *dialog,
- EmpathyAccountSettings *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_NAME, name,
- COL_STATUS, TP_CONNECTION_STATUS_DISCONNECTED,
- COL_ACCOUNT_SETTINGS, settings,
- -1);
-}
-
-static void
accounts_dialog_connection_changed_cb (TpAccount *account,
guint old_status,
guint current,
@@ -1824,6 +1859,7 @@ accounts_dialog_add_account (EmpathyAccountsDialog *dialog,
const gchar *name;
EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
gboolean selected = FALSE;
+ GtkTreeSelection *selection;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
status = tp_account_get_connection_status (account, NULL);
@@ -1831,15 +1867,18 @@ accounts_dialog_add_account (EmpathyAccountsDialog *dialog,
settings = empathy_account_settings_new_for_account (account);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+
if (!accounts_dialog_get_account_iter (dialog, account, &iter))
{
+ /* Select the account if it's the first added */
+ if (gtk_tree_selection_count_selected_rows (selection) == 0)
+ selected = TRUE;
+
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
}
else
{
- GtkTreeSelection *selection;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
selected = gtk_tree_selection_iter_is_selected (selection, &iter);
}
@@ -1879,31 +1918,12 @@ accounts_dialog_add_account (EmpathyAccountsDialog *dialog,
}
static void
-account_prepare_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (user_data);
- TpAccount *account = TP_ACCOUNT (source_object);
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (account, result, &error))
- {
- DEBUG ("Failed to prepare account: %s", error->message);
- g_error_free (error);
- return;
- }
-
- accounts_dialog_add_account (dialog, account);
-}
-
-static void
accounts_dialog_account_validity_changed_cb (TpAccountManager *manager,
TpAccount *account,
gboolean valid,
EmpathyAccountsDialog *dialog)
{
- tp_proxy_prepare_async (account, NULL, account_prepare_cb, dialog);
+ accounts_dialog_add_account (dialog, account);
}
static void
@@ -1982,15 +2002,24 @@ accounts_dialog_account_enabled_cb (TpAccountManager *manager,
enable_or_disable_account (dialog, account, TRUE);
}
-static void
-accounts_dialog_button_import_clicked_cb (GtkWidget *button,
- EmpathyAccountsDialog *dialog)
+static GtkWidget *
+display_import_dialog (EmpathyAccountsDialog *dialog)
{
+ EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog);
GtkWidget *import_dialog;
import_dialog = empathy_import_dialog_new (GTK_WINDOW (dialog),
- FALSE);
+ FALSE, priv->cms);
gtk_widget_show (import_dialog);
+
+ return import_dialog;
+}
+
+static void
+accounts_dialog_button_import_clicked_cb (GtkWidget *button,
+ EmpathyAccountsDialog *dialog)
+{
+ display_import_dialog (dialog);
}
static void
@@ -2026,6 +2055,85 @@ accounts_dialog_set_selected_account (EmpathyAccountsDialog *dialog,
}
static void
+salut_valid_cb (GtkWidget *widget,
+ gboolean valid,
+ GtkWidget *button)
+{
+ gtk_widget_set_sensitive (button, valid);
+}
+
+static void
+maybe_show_salut_dialog (EmpathyAccountsDialog *self)
+{
+ EmpathyAccountsDialogPriv *priv = GET_PRIV (self);
+ GtkWidget *dialog, *widget, *content, *button;
+ gint response;
+
+ if (!empathy_local_xmpp_assistant_widget_should_create_account (
+ priv->account_manager))
+ return;
+
+ widget = empathy_local_xmpp_assistant_widget_new ();
+ gtk_widget_show (widget);
+
+ dialog = gtk_dialog_new ();
+
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Skip"),
+ GTK_RESPONSE_NO);
+
+ button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ _("_Connect"), GTK_RESPONSE_YES);
+ gtk_widget_set_sensitive (button, FALSE);
+
+ g_signal_connect (widget, "valid", G_CALLBACK (salut_valid_cb),
+ button);
+
+ content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_start (GTK_BOX (content), widget, TRUE, TRUE, 0);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_YES)
+ {
+ empathy_local_xmpp_assistant_widget_create_account (
+ EMPATHY_LOCAL_XMPP_ASSISTANT_WIDGET (widget));
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+import_dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ EmpathyAccountsDialog *self)
+{
+ maybe_show_salut_dialog (self);
+}
+
+static void
+maybe_show_import_dialog (EmpathyAccountsDialog *self)
+{
+ EmpathyAccountsDialogPriv *priv = GET_PRIV (self);
+ GtkWidget *dialog;
+
+ if (empathy_accounts_has_non_salut_accounts (priv->account_manager))
+ return;
+
+ if (!empathy_import_accounts_to_import ())
+ {
+ maybe_show_salut_dialog (self);
+ return;
+ }
+
+ dialog = display_import_dialog (self);
+
+ tp_g_signal_connect_object (dialog, "response",
+ G_CALLBACK (import_dialog_response_cb), self, 0);
+}
+
+static void
finished_loading (EmpathyAccountsDialog *self)
{
EmpathyAccountsDialogPriv *priv = GET_PRIV (self);
@@ -2046,6 +2154,8 @@ finished_loading (EmpathyAccountsDialog *self)
gtk_spinner_stop (GTK_SPINNER (priv->spinner));
gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook_account),
NOTEBOOK_PAGE_ACCOUNT);
+
+ maybe_show_import_dialog (self);
}
static void
@@ -2188,14 +2298,12 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
gui = empathy_builder_get_file (filename,
"accounts_dialog_hbox", &top_hbox,
"vbox_details", &priv->vbox_details,
- "frame_no_protocol", &priv->frame_no_protocol,
"alignment_settings", &priv->alignment_settings,
"alignment_infobar", &priv->alignment_infobar,
"treeview", &priv->treeview,
"button_add", &priv->button_add,
"button_remove", &priv->button_remove,
"button_import", &priv->button_import,
- "hbox_protocol", &priv->hbox_protocol,
"notebook_account", &priv->notebook_account,
"alignment_loading", &alig,
"accounts_sw", &sw,
@@ -2203,8 +2311,6 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
NULL);
g_free (filename);
- gtk_widget_set_no_show_all (priv->frame_no_protocol, TRUE);
-
empathy_builder_connect (gui, dialog,
"button_add", "clicked", accounts_dialog_button_add_clicked_cb,
"button_remove", "clicked", accounts_dialog_button_remove_clicked_cb,
@@ -2248,13 +2354,6 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
gtk_widget_set_sensitive (priv->button_import, FALSE);
gtk_widget_set_sensitive (priv->treeview, FALSE);
- priv->combobox_protocol = empathy_protocol_chooser_new ();
- gtk_box_pack_start (GTK_BOX (priv->hbox_protocol), priv->combobox_protocol,
- TRUE, TRUE, 0);
- 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 (dialog),
priv->parent_window);
@@ -2293,7 +2392,7 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog)
TP_CONNECTION_PRESENCE_TYPE_OFFLINE), GTK_ICON_SIZE_SMALL_TOOLBAR);
priv->label_status = gtk_label_new (NULL);
- gtk_label_set_line_wrap (GTK_LABEL (priv->label_status), TRUE);
+ gtk_label_set_ellipsize (GTK_LABEL (priv->label_status), PANGO_ELLIPSIZE_END);
gtk_box_pack_start (GTK_BOX (hbox), priv->throbber, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), priv->image_status, FALSE, FALSE, 0);
diff --git a/src/empathy-accounts-dialog.ui b/src/empathy-accounts-dialog.ui
index 4a1b8bbb3..549a92651 100644
--- a/src/empathy-accounts-dialog.ui
+++ b/src/empathy-accounts-dialog.ui
@@ -112,31 +112,6 @@
<property name="visible">True</property>
<property name="spacing">18</property>
<child>
- <object class="GtkHBox" id="hbox_protocol">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label_protocol">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Protocol:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
<object class="GtkVBox" id="vbox_details">
<property name="visible">True</property>
<property name="spacing">18</property>
@@ -173,43 +148,6 @@
<property name="position">1</property>
</packing>
</child>
- <child>
- <object class="GtkFrame" id="frame_no_protocol">
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment21">
- <property name="visible">True</property>
- <property name="top_padding">6</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">To add a new account, you first have to install a backend for each protocol you want to use.</property>
- <property name="wrap">True</property>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label_no_protocol">
- <property name="visible">True</property>
- <property name="label" translatable="yes">No protocol installed</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
<child type="tab">
@@ -254,6 +192,49 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkVBox" id="vbox_no_protocol">
+ <property name="visible">True</property>
+ <property name="spacing">18</property>
+ <child>
+ <object class="GtkFrame" id="frame_no_protocol">
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment21">
+ <property name="visible">True</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">To add a new account, you first have to install a backend for each protocol you want to use.</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label_no_protocol">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">No protocol backends installed</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ </child>
</object>
<packing>
<property name="position">1</property>
diff --git a/src/empathy-accounts.c b/src/empathy-accounts.c
index 3b25201c5..6b51820f7 100644
--- a/src/empathy-accounts.c
+++ b/src/empathy-accounts.c
@@ -43,8 +43,6 @@
#include "empathy-accounts.h"
#include "empathy-accounts-common.h"
#include "empathy-accounts-dialog.h"
-#include "empathy-account-assistant.h"
-#include "empathy-auto-salut-account-helper.h"
#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
#include <libempathy/empathy-debug.h>
@@ -54,7 +52,6 @@
static gboolean only_if_needed = FALSE;
static gboolean hidden = FALSE;
static gchar *selected_account_name = NULL;
-static gboolean assistant = FALSE;
static void
maybe_show_accounts_ui (TpAccountManager *manager,
@@ -66,7 +63,7 @@ maybe_show_accounts_ui (TpAccountManager *manager,
if (only_if_needed && empathy_accounts_has_non_salut_accounts (manager))
return;
- empathy_accounts_show_accounts_ui (manager, NULL, assistant, app);
+ empathy_accounts_show_accounts_ui (manager, NULL, app);
}
static TpAccount *
@@ -123,7 +120,7 @@ account_manager_ready_for_accounts_cb (GObject *source_object,
if (account != NULL)
{
- empathy_accounts_show_accounts_ui (manager, account, assistant, app);
+ empathy_accounts_show_accounts_ui (manager, account, app);
goto out;
}
else
@@ -191,10 +188,6 @@ local_cmdline (GApplication *app,
N_("Initially select given account (eg, "
"gabble/jabber/foo_40example_2eorg0)"),
N_("<account-id>") },
- { "assistant", 'a',
- 0, G_OPTION_ARG_NONE, &assistant,
- N_("Show account assistant"),
- NULL },
{ NULL }
};
diff --git a/src/empathy-audio-sink.c b/src/empathy-audio-sink.c
index 5ab14b541..fbffa4885 100644
--- a/src/empathy-audio-sink.c
+++ b/src/empathy-audio-sink.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <config.h>
#include <stdio.h>
#include <stdlib.h>
@@ -222,7 +223,10 @@ create_sink (EmpathyGstAudioSink *self)
/* Set latency (buffering on the PulseAudio side) of 40ms and transfer data
* in 10ms chunks */
- g_object_set (sink, "buffer-time", 40000, "latency-time", 10000, NULL);
+ g_object_set (sink,
+ "buffer-time", (gint64) 40000,
+ "latency-time", (gint64) 10000,
+ NULL);
return sink;
}
diff --git a/src/empathy-audio-src.c b/src/empathy-audio-src.c
index aa271fa1c..9a882c146 100644
--- a/src/empathy-audio-src.c
+++ b/src/empathy-audio-src.c
@@ -332,7 +332,7 @@ create_src (void)
empathy_call_set_stream_properties (src, TRUE);
/* Set latency (buffering on the PulseAudio side) of 20ms */
- g_object_set (src, "buffer-time", 20000, NULL);
+ g_object_set (src, "buffer-time", (gint64) 20000, NULL);
return src;
}
diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c
index 5b3e48ce8..22a625229 100644
--- a/src/empathy-auth-client.c
+++ b/src/empathy-auth-client.c
@@ -231,6 +231,8 @@ auth_factory_new_sasl_handler_cb (EmpathyAuthFactory *factory,
/* If the handler has the password it will deal with it itself. */
if (!empathy_server_sasl_handler_has_password (handler))
{
+ DEBUG ("SASL handler doesn't have a password, prompt for one");
+
dialog = empathy_password_dialog_new (handler);
gtk_widget_show (dialog);
}
diff --git a/src/empathy-auto-salut-account-helper.c b/src/empathy-auto-salut-account-helper.c
deleted file mode 100644
index 409b6936c..000000000
--- a/src/empathy-auto-salut-account-helper.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2007-2010 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Xavier Claessens <xclaesse@gmail.com>
- * Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
- */
-
-#include <config.h>
-
-#include <glib.h>
-#include <glib/gi18n-lib.h>
-
-#include <telepathy-glib/account-manager.h>
-#include <telepathy-glib/util.h>
-
-#if HAVE_EDS
-#include <libebook/e-book.h>
-#endif
-
-#include <libempathy/empathy-account-settings.h>
-
-#define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
-#include <libempathy/empathy-debug.h>
-
-#include "empathy-auto-salut-account-helper.h"
-
-/* Salut account creation. The TpAccountManager first argument
- * must already be prepared when calling this function. */
-gboolean
-should_create_salut_account (TpAccountManager *manager)
-{
- gboolean salut_created = FALSE;
- GList *accounts, *l;
-
- accounts = tp_account_manager_get_valid_accounts (manager);
-
- for (l = accounts; l != NULL; l = g_list_next (l))
- {
- TpAccount *account = TP_ACCOUNT (l->data);
-
- if (!tp_strdiff (tp_account_get_protocol (account), "local-xmpp"))
- {
- salut_created = TRUE;
- break;
- }
- }
-
- g_list_free (accounts);
-
- return !salut_created;
-}
-
-EmpathyAccountSettings *
-create_salut_account_settings (void)
-{
- EmpathyAccountSettings *settings;
-#if HAVE_EDS
- EBook *book;
- EContact *contact;
- gchar *nickname = NULL;
- gchar *first_name = NULL;
- gchar *last_name = NULL;
- gchar *email = NULL;
- gchar *jid = NULL;
- GError *error = NULL;
-#endif
-
- settings = empathy_account_settings_new ("salut", "local-xmpp", NULL,
- _("People nearby"));
-
-#if HAVE_EDS
- /* Get self EContact from EDS */
- if (!e_book_get_self (&contact, &book, &error))
- {
- DEBUG ("Failed to get self econtact: %s", error->message);
- g_error_free (error);
- return settings;
- }
-
- nickname = e_contact_get (contact, E_CONTACT_NICKNAME);
- first_name = e_contact_get (contact, E_CONTACT_GIVEN_NAME);
- last_name = e_contact_get (contact, E_CONTACT_FAMILY_NAME);
- email = e_contact_get (contact, E_CONTACT_EMAIL_1);
- jid = e_contact_get (contact, E_CONTACT_IM_JABBER_HOME_1);
-
- if (!tp_strdiff (nickname, "nickname"))
- {
- g_free (nickname);
- nickname = NULL;
- }
-
- DEBUG ("Salut account created:\nnickname=%s\nfirst-name=%s\n"
- "last-name=%s\nemail=%s\njid=%s\n",
- nickname, first_name, last_name, email, jid);
-
- empathy_account_settings_set_string (settings,
- "nickname", nickname ? nickname : "");
- empathy_account_settings_set_string (settings,
- "first-name", first_name ? first_name : "");
- empathy_account_settings_set_string (settings,
- "last-name", last_name ? last_name : "");
- empathy_account_settings_set_string (settings, "email", email ? email : "");
- empathy_account_settings_set_string (settings, "jid", jid ? jid : "");
-
- g_free (nickname);
- g_free (first_name);
- g_free (last_name);
- g_free (email);
- g_free (jid);
- g_object_unref (contact);
- g_object_unref (book);
-#endif
-
- return settings;
-}
diff --git a/src/empathy-auto-salut-account-helper.h b/src/empathy-auto-salut-account-helper.h
deleted file mode 100644
index f0409d01d..000000000
--- a/src/empathy-auto-salut-account-helper.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007-2010 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Xavier Claessens <xclaesse@gmail.com>
- * Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
- */
-
-/* Helper functions to automatically create a Salut account */
-
-#ifndef __AUTO_SALUT_ACCOUNT_HELPER_H__
-#define __AUTO_SALUT_ACCOUNT_HELPER_H__
-
-#include <telepathy-glib/account-manager.h>
-
-#include <libempathy/empathy-connection-managers.h>
-#include <libempathy/empathy-account-settings.h>
-
-gboolean should_create_salut_account (TpAccountManager *manager);
-
-EmpathyAccountSettings * create_salut_account_settings (void);
-
-#endif
diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c
index 7a4994c93..451722839 100644
--- a/src/empathy-call-window.c
+++ b/src/empathy-call-window.c
@@ -439,8 +439,11 @@ create_video_output_widget (EmpathyCallWindow *self)
clutter_texture_set_keep_aspect_ratio (CLUTTER_TEXTURE (priv->video_output),
TRUE);
- priv->video_output_sink = clutter_gst_video_sink_new (
- CLUTTER_TEXTURE (priv->video_output));
+ priv->video_output_sink = gst_element_factory_make ("cluttersink", NULL);
+ if (priv->video_output_sink == NULL)
+ g_error ("Missing cluttersink");
+ else
+ g_object_set (priv->video_output_sink, "texture", priv->video_output, NULL);
clutter_container_add_actor (CLUTTER_CONTAINER (priv->video_box),
priv->video_output);
@@ -1113,8 +1116,12 @@ create_video_preview (EmpathyCallWindow *self)
preview = empathy_rounded_texture_new ();
clutter_actor_set_size (preview,
SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGHT);
- priv->video_preview_sink = clutter_gst_video_sink_new (
- CLUTTER_TEXTURE (preview));
+
+ priv->video_preview_sink = gst_element_factory_make ("cluttersink", NULL);
+ if (priv->video_preview_sink == NULL)
+ g_error ("Missing cluttersink");
+ else
+ g_object_set (priv->video_preview_sink, "texture", preview, NULL);
/* Add a little offset to the video preview */
layout = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER,
@@ -3365,7 +3372,7 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
G_CALLBACK (empathy_call_window_video_probe_cb), self);
if (priv->got_video_src > 0)
g_source_remove (priv->got_video_src);
- priv->got_video_src = g_timeout_add_seconds (5,
+ priv->got_video_src = g_timeout_add_seconds (1,
empathy_call_window_check_video_cb, self);
break;
default:
diff --git a/src/empathy-call.c b/src/empathy-call.c
index 2ff49a81b..71d9db707 100644
--- a/src/empathy-call.c
+++ b/src/empathy-call.c
@@ -30,6 +30,10 @@
#include <clutter-gtk/clutter-gtk.h>
#include <clutter-gst/clutter-gst.h>
+#ifdef CLUTTER_WINDOWING_X11
+#include <X11/Xlib.h>
+#endif
+
#include <telepathy-glib/debug-sender.h>
#include <telepathy-yell/telepathy-yell.h>
@@ -187,6 +191,12 @@ main (int argc,
/* Init */
g_thread_init (NULL);
+#ifdef GDK_WINDOWING_X11
+ /* We can't call clutter_gst_init() before gtk_clutter_init(), so no choice
+ * but to intiialise X11 threading ourself */
+ XInitThreads ();
+#endif
+
/* Clutter needs this */
gdk_disable_multidevice ();
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 9ad6b2975..4e3f04807 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -213,13 +213,168 @@ chat_window_find_chat (EmpathyChat *chat)
}
static void
+remove_all_chats (EmpathyChatWindow *window)
+{
+ EmpathyChatWindowPriv *priv;
+
+ priv = GET_PRIV (window);
+ g_object_ref (window);
+
+ while (priv->chats) {
+ empathy_chat_window_remove_chat (window, priv->chats->data);
+ }
+
+ g_object_unref (window);
+}
+
+static void
+confirm_close_response_cb (GtkWidget *dialog,
+ int response,
+ EmpathyChatWindow *window)
+{
+ EmpathyChat *chat;
+
+ chat = g_object_get_data (G_OBJECT (dialog), "chat");
+
+ gtk_widget_destroy (dialog);
+
+ if (response != GTK_RESPONSE_ACCEPT)
+ return;
+
+ if (chat != NULL) {
+ empathy_chat_window_remove_chat (window, chat);
+ } else {
+ remove_all_chats (window);
+ }
+}
+
+static void
+confirm_close (EmpathyChatWindow *window,
+ gboolean close_window,
+ guint n_rooms,
+ EmpathyChat *chat)
+{
+ EmpathyChatWindowPriv *priv;
+ GtkWidget *dialog;
+ gchar *primary, *secondary;
+
+ g_return_if_fail (n_rooms > 0);
+
+ if (n_rooms > 1) {
+ g_return_if_fail (chat == NULL);
+ } else {
+ g_return_if_fail (chat != NULL);
+ }
+
+ priv = GET_PRIV (window);
+
+ /* If there are no chats in this window, how could we possibly have got
+ * here?
+ */
+ g_return_if_fail (priv->chats != NULL);
+
+ /* Treat closing a window which only has one tab exactly like closing
+ * that tab.
+ */
+ if (close_window && priv->chats->next == NULL) {
+ close_window = FALSE;
+ chat = priv->chats->data;
+ }
+
+ if (close_window) {
+ primary = g_strdup (_("Close this window?"));
+
+ if (n_rooms == 1) {
+ gchar *chat_name = empathy_chat_dup_name (chat);
+ secondary = g_strdup_printf (
+ _("Closing this window will leave %s. You will "
+ "not receive any further messages until you "
+ "rejoin it."),
+ chat_name);
+ g_free (chat_name);
+ } else {
+ secondary = g_strdup_printf (
+ /* Note to translators: the number of chats will
+ * always be at least 2.
+ */
+ ngettext (
+ "Closing this window will leave a chat room. You will "
+ "not receive any further messages until you rejoin it.",
+ "Closing this window will leave %u chat rooms. You will "
+ "not receive any further messages until you rejoin them.",
+ n_rooms),
+ n_rooms);
+ }
+ } else {
+ gchar *chat_name = empathy_chat_dup_name (chat);
+ primary = g_strdup_printf (_("Leave %s?"), chat_name);
+ secondary = g_strdup (_("You will not receive any further messages from this chat "
+ "room until you rejoin it."));
+ g_free (chat_name);
+ }
+
+ dialog = gtk_message_dialog_new (
+ GTK_WINDOW (priv->dialog),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CANCEL,
+ "%s", primary);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), "");
+ g_object_set (dialog, "secondary-text", secondary, NULL);
+
+ g_free (primary);
+ g_free (secondary);
+
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
+ close_window ? _("Close window") : _("Leave room"),
+ GTK_RESPONSE_ACCEPT);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+ GTK_RESPONSE_ACCEPT);
+
+ if (!close_window) {
+ g_object_set_data (G_OBJECT (dialog), "chat", chat);
+ }
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (confirm_close_response_cb), window);
+
+ gtk_window_present (GTK_WINDOW (dialog));
+}
+
+/* Returns TRUE if we should check if the user really wants to leave. If it's
+ * a multi-user chat, and it has a TpChat (so there's an underlying channel, so
+ * the user is actually in the room as opposed to having been kicked or gone
+ * offline or something), then we should check.
+ */
+static gboolean
+chat_needs_close_confirmation (EmpathyChat *chat)
+{
+ return (empathy_chat_is_room (chat)
+ && empathy_chat_get_tp_chat (chat) != NULL);
+}
+
+static void
+maybe_close_chat (EmpathyChatWindow *window,
+ EmpathyChat *chat)
+{
+ g_return_if_fail (chat != NULL);
+
+ if (chat_needs_close_confirmation (chat)) {
+ confirm_close (window, FALSE, 1, chat);
+ } else {
+ empathy_chat_window_remove_chat (window, chat);
+ }
+}
+
+static void
chat_window_close_clicked_cb (GtkAction *action,
EmpathyChat *chat)
{
EmpathyChatWindow *window;
window = chat_window_find_chat (chat);
- empathy_chat_window_remove_chat (window, chat);
+ maybe_close_chat (window, chat);
}
static void
@@ -773,10 +928,19 @@ chat_window_update_chat_tab_full (EmpathyChat *chat,
g_free (markup);
/* Update tab and menu label */
+ if (empathy_chat_is_highlighted (chat)) {
+ markup = g_markup_printf_escaped (
+ "<span color=\"red\" weight=\"bold\">%s</span>",
+ name);
+ } else {
+ markup = g_markup_escape_text (name, -1);
+ }
+
widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-label");
- gtk_label_set_text (GTK_LABEL (widget), name);
+ gtk_label_set_markup (GTK_LABEL (widget), markup);
widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-label");
- gtk_label_set_text (GTK_LABEL (widget), name);
+ gtk_label_set_markup (GTK_LABEL (widget), markup);
+ g_free (markup);
/* Update the window if it's the current chat */
if (priv->current_chat == chat) {
@@ -1027,7 +1191,7 @@ chat_window_close_activate_cb (GtkAction *action,
g_return_if_fail (priv->current_chat != NULL);
- empathy_chat_window_remove_chat (window, priv->current_chat);
+ maybe_close_chat (window, priv->current_chat);
}
static void
@@ -1271,14 +1435,25 @@ chat_window_delete_event_cb (GtkWidget *dialog,
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv = GET_PRIV (window);
+ EmpathyChat *chat = NULL;
+ guint n_rooms = 0;
+ GList *l;
DEBUG ("Delete event received");
- g_object_ref (window);
- while (priv->chats) {
- empathy_chat_window_remove_chat (window, priv->chats->data);
+ for (l = priv->chats; l != NULL; l = l->next) {
+ if (chat_needs_close_confirmation (l->data)) {
+ chat = l->data;
+ n_rooms++;
+ }
+ }
+
+ if (n_rooms > 0) {
+ confirm_close (window, TRUE, n_rooms,
+ (n_rooms == 1 ? chat : NULL));
+ } else {
+ remove_all_chats (window);
}
- g_object_unref (window);
return TRUE;
}
@@ -1394,30 +1569,6 @@ chat_window_show_or_update_notification (EmpathyChatWindow *window,
g_free (escaped);
}
-static void
-chat_window_set_highlight_room_labels (EmpathyChat *chat)
-{
- gchar *markup, *name;
- GtkWidget *widget;
-
- if (!empathy_chat_is_room (chat))
- return;
-
- name = empathy_chat_dup_name (chat);
- markup = g_markup_printf_escaped (
- "<span color=\"red\" weight=\"bold\">%s</span>",
- name);
-
- widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-label");
- gtk_label_set_markup (GTK_LABEL (widget), markup);
-
- widget = g_object_get_data (G_OBJECT (chat), "chat-window-menu-label");
- gtk_label_set_markup (GTK_LABEL (widget), markup);
-
- g_free (name);
- g_free (markup);
-}
-
static gboolean
empathy_chat_window_has_focus (EmpathyChatWindow *window)
{
@@ -1437,6 +1588,7 @@ static void
chat_window_new_message_cb (EmpathyChat *chat,
EmpathyMessage *message,
gboolean pending,
+ gboolean should_highlight,
EmpathyChatWindow *window)
{
EmpathyChatWindowPriv *priv;
@@ -1496,15 +1648,13 @@ chat_window_new_message_cb (EmpathyChat *chat,
if (chatroom != NULL && empathy_chatroom_is_always_urgent (chatroom)) {
needs_urgency = TRUE;
} else {
- needs_urgency = empathy_message_should_highlight (message);
+ needs_urgency = should_highlight;
}
} else {
needs_urgency = TRUE;
}
if (needs_urgency) {
- chat_window_set_highlight_room_labels (chat);
-
if (!has_focus) {
chat_window_set_urgency_hint (window, TRUE);
}
@@ -2488,8 +2638,12 @@ empathy_chat_window_present_chat (EmpathyChat *chat,
}
empathy_chat_window_switch_to_chat (window, chat);
- empathy_window_present_with_time (GTK_WINDOW (priv->dialog),
- x_timestamp);
+
+ /* Don't use empathy_window_present_with_time () which would move the window
+ * to our current desktop but move to the window's desktop instead. This is
+ * more coherent with Shell's 'app is ready' notication which moves the view
+ * to the app desktop rather than moving the app itself. */
+ empathy_move_to_window_desktop (GTK_WINDOW (priv->dialog), x_timestamp);
gtk_widget_grab_focus (chat->input_text_view);
}
diff --git a/src/empathy-chat-window.ui b/src/empathy-chat-window.ui
index 25749861c..bf95bff16 100644
--- a/src/empathy-chat-window.ui
+++ b/src/empathy-chat-window.ui
@@ -205,8 +205,8 @@
<object class="GtkWindow" id="chat_window">
<property name="title" translatable="yes">Chat</property>
<property name="role">chat</property>
- <property name="default_width">350</property>
- <property name="default_height">250</property>
+ <property name="default_width">580</property>
+ <property name="default_height">480</property>
<child>
<object class="GtkVBox" id="chat_vbox">
<property name="visible">True</property>
diff --git a/src/empathy-chat.c b/src/empathy-chat.c
index 43ab00270..bebca4382 100644
--- a/src/empathy-chat.c
+++ b/src/empathy-chat.c
@@ -31,6 +31,7 @@
#include <telepathy-glib/debug-sender.h>
#include <libempathy/empathy-presence-manager.h>
+#include <libempathy/empathy-individual-manager.h>
#include <libempathy-gtk/empathy-theme-manager.h>
#include <libempathy-gtk/empathy-ui-utils.h>
@@ -100,6 +101,7 @@ main (int argc,
EmpathyPresenceManager *presence_mgr;
EmpathyThemeManager *theme_mgr;
gint retval;
+ EmpathyIndividualManager *individual_mgr;
/* Init */
g_thread_init (NULL);
@@ -143,6 +145,10 @@ main (int argc,
/* Keep the theme manager alive as it does some caching */
theme_mgr = empathy_theme_manager_dup_singleton ();
+ /* Keep the individual manager alive so we won't fetch everything from Folks
+ * each time we need to use it. */
+ individual_mgr = empathy_individual_manager_dup_singleton ();
+
if (g_getenv ("EMPATHY_PERSIST") != NULL)
{
DEBUG ("Disable timer");
@@ -163,6 +169,7 @@ main (int argc,
g_object_unref (presence_mgr);
g_object_unref (theme_mgr);
tp_clear_object (&chat_mgr);
+ g_object_unref (individual_mgr);
#ifdef ENABLE_DEBUG
g_object_unref (debug_sender);
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index da677d42d..321cd1cca 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -33,10 +33,9 @@
#include <libempathy/empathy-presence-manager.h>
#include <libempathy/empathy-tp-contact-factory.h>
-#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-connection-aggregator.h>
#include <libempathy/empathy-tp-chat.h>
#include <libempathy/empathy-tp-streamed-media.h>
-#include <libempathy/empathy-tp-file.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-gsettings.h>
@@ -48,7 +47,7 @@
#include <libempathy-gtk/empathy-ui-utils.h>
#include "empathy-event-manager.h"
-#include "empathy-main-window.h"
+#include "empathy-roster-window.h"
#define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER
#include <libempathy/empathy-debug.h>
@@ -81,7 +80,7 @@ typedef struct {
typedef struct {
TpBaseClient *approver;
TpBaseClient *auth_approver;
- EmpathyContactManager *contact_manager;
+ EmpathyConnectionAggregator *conn_aggregator;
GSList *events;
/* Ongoing approvals */
GSList *approvals;
@@ -92,6 +91,9 @@ typedef struct {
GSettings *gsettings_ui;
EmpathySoundManager *sound_mgr;
+
+ /* TpContact -> EmpathyContact */
+ GHashTable *contacts;
} EmpathyEventManagerPriv;
typedef struct _EventPriv EventPriv;
@@ -422,9 +424,9 @@ reject_channel_claim_cb (GObject *source,
{
empathy_tp_chat_leave (user_data, "");
}
- else if (EMPATHY_IS_TP_FILE (user_data))
+ else if (TP_IS_FILE_TRANSFER_CHANNEL (user_data))
{
- empathy_tp_file_close (user_data);
+ tp_channel_close_async (user_data, NULL, NULL);
}
out:
@@ -615,7 +617,7 @@ event_manager_chat_message_received_cb (EmpathyTpChat *tp_chat,
EMPATHY_EVENT_TYPE_CHAT, EMPATHY_IMAGE_NEW_MESSAGE, header, msg,
approval, event_text_channel_process_func, NULL);
- window = empathy_main_window_dup ();
+ window = empathy_roster_window_dup ();
empathy_sound_manager_play (priv->sound_mgr, window,
EMPATHY_SOUND_CONVERSATION_NEW);
@@ -721,7 +723,7 @@ event_manager_call_channel_got_contact_cb (TpConnection *connection,
approval->handler = g_signal_connect (call, "state-changed",
G_CALLBACK (event_manager_call_state_changed_cb), approval);
- window = empathy_main_window_dup ();
+ window = empathy_roster_window_dup ();
approval->contact = g_object_ref (contact);
g_object_get (G_OBJECT (call), "initial-video", &video, NULL);
@@ -750,7 +752,7 @@ static void
event_manager_media_channel_got_contact (EventManagerApproval *approval)
{
EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager);
- GtkWidget *window = empathy_main_window_dup ();
+ GtkWidget *window = empathy_roster_window_dup ();
gchar *header;
EmpathyTpStreamedMedia *call;
gboolean video;
@@ -870,7 +872,7 @@ event_room_channel_process_func (EventPriv *event)
static void
display_invite_room_dialog (EventManagerApproval *approval)
{
- GtkWidget *window = empathy_main_window_dup ();
+ GtkWidget *window = empathy_roster_window_dup ();
const gchar *invite_msg;
gchar *msg;
TpHandle self_handle;
@@ -933,7 +935,7 @@ event_manager_ft_got_contact_cb (TpConnection *connection,
GObject *object)
{
EventManagerApproval *approval = (EventManagerApproval *) user_data;
- GtkWidget *window = empathy_main_window_dup ();
+ GtkWidget *window = empathy_roster_window_dup ();
char *header;
EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager);
@@ -1115,7 +1117,7 @@ approve_channels (TpSimpleApprover *approver,
event_manager_call_channel_got_contact_cb,
approval, NULL, G_OBJECT (self));
}
- else if (EMPATHY_IS_TP_FILE (channel))
+ else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER)
{
TpHandle handle;
@@ -1179,15 +1181,20 @@ event_pending_subscribe_func (EventPriv *event)
}
static void
-event_manager_pendings_changed_cb (EmpathyContactList *list,
- EmpathyContact *contact, EmpathyContact *actor,
- guint reason, gchar *message, gboolean is_pending,
- EmpathyEventManager *manager)
+check_publish_state (EmpathyEventManager *self,
+ TpContact *tp_contact)
{
- EmpathyEventManagerPriv *priv = GET_PRIV (manager);
- gchar *header, *event_msg;
+ EmpathyEventManagerPriv *priv = GET_PRIV (self);
+ gchar *header, *event_msg;
+ TpSubscriptionState state;
+ EmpathyContact *contact;
+ const gchar *message;
+
+ state = tp_contact_get_publish_state (tp_contact);
+
+ contact = empathy_contact_dup_from_tp_contact (tp_contact);
- if (!is_pending)
+ if (state != TP_SUBSCRIPTION_STATE_ASK)
{
GSList *l;
@@ -1203,24 +1210,37 @@ event_manager_pendings_changed_cb (EmpathyContactList *list,
}
}
- return;
+ goto out;
}
header = g_strdup_printf (
_("%s would like permission to see when you are online"),
empathy_contact_get_alias (contact));
+ message = tp_contact_get_publish_request (tp_contact);
+
if (!EMP_STR_EMPTY (message))
event_msg = g_strdup_printf (_("\nMessage: %s"), message);
else
event_msg = NULL;
- event_manager_add (manager, NULL, contact, EMPATHY_EVENT_TYPE_SUBSCRIPTION,
+ event_manager_add (self, NULL, contact, EMPATHY_EVENT_TYPE_SUBSCRIPTION,
GTK_STOCK_DIALOG_QUESTION, header, event_msg, NULL,
event_pending_subscribe_func, NULL);
g_free (event_msg);
g_free (header);
+
+out:
+ g_object_unref (contact);
+}
+
+static void
+event_manager_publish_state_changed_cb (TpContact *contact,
+ GParamSpec *spec,
+ EmpathyEventManager *self)
+{
+ check_publish_state (self, contact);
}
static void
@@ -1232,7 +1252,7 @@ event_manager_presence_changed_cb (EmpathyContact *contact,
EmpathyEventManagerPriv *priv = GET_PRIV (manager);
TpAccount *account;
EmpathyPresenceManager *presence_mgr;
- GtkWidget *window = empathy_main_window_dup ();
+ GtkWidget *window = empathy_roster_window_dup ();
account = empathy_contact_get_account (contact);
presence_mgr = empathy_presence_manager_dup_singleton ();
@@ -1289,23 +1309,6 @@ out:
g_object_unref (window);
}
-static void
-event_manager_members_changed_cb (EmpathyContactList *list,
- EmpathyContact *contact,
- EmpathyContact *actor,
- guint reason,
- gchar *message,
- gboolean is_member,
- EmpathyEventManager *manager)
-{
- if (is_member)
- g_signal_connect (contact, "presence-changed",
- G_CALLBACK (event_manager_presence_changed_cb), manager);
- else
- g_signal_handlers_disconnect_by_func (contact,
- event_manager_presence_changed_cb, manager);
-}
-
static GObject *
event_manager_constructor (GType type,
guint n_props,
@@ -1338,12 +1341,13 @@ event_manager_finalize (GObject *object)
g_slist_free (priv->events);
g_slist_foreach (priv->approvals, (GFunc) event_manager_approval_free, NULL);
g_slist_free (priv->approvals);
- g_object_unref (priv->contact_manager);
+ g_object_unref (priv->conn_aggregator);
g_object_unref (priv->approver);
g_object_unref (priv->auth_approver);
g_object_unref (priv->gsettings_notif);
g_object_unref (priv->gsettings_ui);
g_object_unref (priv->sound_mgr);
+ g_hash_table_unref (priv->contacts);
}
static void
@@ -1386,12 +1390,63 @@ empathy_event_manager_class_init (EmpathyEventManagerClass *klass)
}
static void
+contact_list_changed_cb (EmpathyConnectionAggregator *aggregator,
+ GPtrArray *added,
+ GPtrArray *removed,
+ EmpathyEventManager *self)
+{
+ EmpathyEventManagerPriv *priv = GET_PRIV (self);
+ guint i;
+
+ for (i = 0; i < added->len; i++)
+ {
+ TpContact *tp_contact = g_ptr_array_index (added, i);
+ EmpathyContact *contact;
+
+ if (g_hash_table_lookup (priv->contacts, tp_contact) != NULL)
+ continue;
+
+ contact = empathy_contact_dup_from_tp_contact (tp_contact);
+
+ tp_g_signal_connect_object (contact, "presence-changed",
+ G_CALLBACK (event_manager_presence_changed_cb), self, 0);
+
+ tp_g_signal_connect_object (tp_contact, "notify::publish-state",
+ G_CALLBACK (event_manager_publish_state_changed_cb), self, 0);
+
+ check_publish_state (self, tp_contact);
+
+ /* Pass ownership to the hash table */
+ g_hash_table_insert (priv->contacts, g_object_ref (tp_contact), contact);
+ }
+
+ for (i = 0; i < removed->len; i++)
+ {
+ TpContact *tp_contact = g_ptr_array_index (removed, i);
+ EmpathyContact *contact;
+
+ contact = g_hash_table_lookup (priv->contacts, tp_contact);
+ if (contact == NULL)
+ continue;
+
+ g_signal_handlers_disconnect_by_func (contact,
+ event_manager_presence_changed_cb, self);
+
+ g_signal_handlers_disconnect_by_func (tp_contact,
+ event_manager_publish_state_changed_cb, self);
+
+ g_hash_table_remove (priv->contacts, tp_contact);
+ }
+}
+
+static void
empathy_event_manager_init (EmpathyEventManager *manager)
{
EmpathyEventManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
EMPATHY_TYPE_EVENT_MANAGER, EmpathyEventManagerPriv);
GError *error = NULL;
TpAccountManager *am;
+ GPtrArray *contacts, *empty;
manager->priv = priv;
@@ -1400,12 +1455,23 @@ empathy_event_manager_init (EmpathyEventManager *manager)
priv->sound_mgr = empathy_sound_manager_dup_singleton ();
- priv->contact_manager = empathy_contact_manager_dup_singleton ();
- g_signal_connect (priv->contact_manager, "pendings-changed",
- G_CALLBACK (event_manager_pendings_changed_cb), manager);
+ priv->contacts = g_hash_table_new_full (NULL, NULL, g_object_unref,
+ g_object_unref);
+
+ priv->conn_aggregator = empathy_connection_aggregator_dup_singleton ();
+
+ tp_g_signal_connect_object (priv->conn_aggregator, "contact-list-changed",
+ G_CALLBACK (contact_list_changed_cb), manager, 0);
+
+ contacts = empathy_connection_aggregator_dup_all_contacts (
+ priv->conn_aggregator);
+
+ empty = g_ptr_array_new ();
+
+ contact_list_changed_cb (priv->conn_aggregator, contacts, empty, manager);
- g_signal_connect (priv->contact_manager, "members-changed",
- G_CALLBACK (event_manager_members_changed_cb), manager);
+ g_ptr_array_unref (contacts);
+ g_ptr_array_unref (empty);
am = tp_account_manager_dup ();
diff --git a/src/empathy-ft-manager.c b/src/empathy-ft-manager.c
index 606600e99..18ca1938a 100644
--- a/src/empathy-ft-manager.c
+++ b/src/empathy-ft-manager.c
@@ -37,7 +37,6 @@
#define DEBUG_FLAG EMPATHY_DEBUG_FT
#include <libempathy/empathy-debug.h>
-#include <libempathy/empathy-tp-file.h>
#include <libempathy/empathy-utils.h>
#include <libempathy-gtk/empathy-ui-utils.h>
@@ -518,7 +517,7 @@ do_real_transfer_done (EmpathyFTManager *manager,
static void
ft_handler_transfer_done_cb (EmpathyFTHandler *handler,
- EmpathyTpFile *tp_file,
+ TpFileTransferChannel *channel,
EmpathyFTManager *manager)
{
if (empathy_ft_handler_is_incoming (handler) &&
@@ -574,7 +573,7 @@ ft_handler_transfer_progress_cb (EmpathyFTHandler *handler,
static void
ft_handler_transfer_started_cb (EmpathyFTHandler *handler,
- EmpathyTpFile *tp_file,
+ TpFileTransferChannel *channel,
EmpathyFTManager *manager)
{
guint64 transferred_bytes, total_bytes;
diff --git a/src/empathy-import-dialog.c b/src/empathy-import-dialog.c
index 77d11298f..4e00bd11a 100644
--- a/src/empathy-import-dialog.c
+++ b/src/empathy-import-dialog.c
@@ -39,7 +39,8 @@
enum {
PROP_PARENT = 1,
- PROP_SHOW_WARNING
+ PROP_SHOW_WARNING,
+ PROP_CMS,
};
typedef struct {
@@ -48,6 +49,7 @@ typedef struct {
EmpathyImportWidget *iw;
gboolean show_warning;
+ EmpathyConnectionManagers *cms;
} EmpathyImportDialogPriv;
G_DEFINE_TYPE (EmpathyImportDialog, empathy_import_dialog, GTK_TYPE_DIALOG)
@@ -62,15 +64,17 @@ import_dialog_add_import_widget (EmpathyImportDialog *self)
area = gtk_dialog_get_content_area (GTK_DIALOG (self));
- iw = empathy_import_widget_new (EMPATHY_IMPORT_APPLICATION_ALL);
+ iw = empathy_import_widget_new (EMPATHY_IMPORT_APPLICATION_ALL, priv->cms);
widget = empathy_import_widget_get_widget (iw);
- gtk_box_pack_start (GTK_BOX (area), widget, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (area), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
priv->iw = iw;
- gtk_dialog_add_buttons (GTK_DIALOG (self), GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+ gtk_dialog_add_buttons (GTK_DIALOG (self),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ _("_Import"), GTK_RESPONSE_OK,
+ NULL);
}
static void
@@ -134,6 +138,9 @@ do_get_property (GObject *object,
case PROP_SHOW_WARNING:
g_value_set_boolean (value, priv->show_warning);
break;
+ case PROP_CMS:
+ g_value_set_object (value, priv->cms);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -155,6 +162,9 @@ do_set_property (GObject *object,
case PROP_SHOW_WARNING:
priv->show_warning = g_value_get_boolean (value);
break;
+ case PROP_CMS:
+ priv->cms = g_value_dup_object (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -199,6 +209,15 @@ empathy_import_dialog_init (EmpathyImportDialog *self)
gtk_window_set_title (GTK_WINDOW (self), _("Import Accounts"));
gtk_window_set_modal (GTK_WINDOW (self), TRUE);
}
+static void
+do_dispose (GObject *obj)
+{
+ EmpathyImportDialogPriv *priv = GET_PRIV (obj);
+
+ g_clear_object (&priv->cms);
+
+ G_OBJECT_CLASS (empathy_import_dialog_parent_class)->dispose (obj);
+}
static void
empathy_import_dialog_class_init (EmpathyImportDialogClass *klass)
@@ -210,6 +229,7 @@ empathy_import_dialog_class_init (EmpathyImportDialogClass *klass)
oclass->constructed = do_constructed;
oclass->get_property = do_get_property;
oclass->set_property = do_set_property;
+ oclass->dispose = do_dispose;
gtkclass->response = impl_signal_response;
@@ -226,13 +246,25 @@ empathy_import_dialog_class_init (EmpathyImportDialogClass *klass)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (oclass, PROP_SHOW_WARNING, param_spec);
+ param_spec = g_param_spec_object ("cms",
+ "EmpathyConnectionManagers", "EmpathyConnectionManager",
+ EMPATHY_TYPE_CONNECTION_MANAGERS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (oclass, PROP_CMS, param_spec);
+
g_type_class_add_private (klass, sizeof (EmpathyImportDialogPriv));
}
GtkWidget *
empathy_import_dialog_new (GtkWindow *parent,
- gboolean warning)
+ gboolean warning,
+ EmpathyConnectionManagers *cms)
{
- return g_object_new (EMPATHY_TYPE_IMPORT_DIALOG, "parent-window",
- parent, "show-warning", warning, NULL);
+ g_return_val_if_fail (EMPATHY_IS_CONNECTION_MANAGERS (cms), NULL);
+
+ return g_object_new (EMPATHY_TYPE_IMPORT_DIALOG,
+ "parent-window", parent,
+ "show-warning", warning,
+ "cms", cms,
+ NULL);
}
diff --git a/src/empathy-import-dialog.h b/src/empathy-import-dialog.h
index 0e9d225c4..a412037d1 100644
--- a/src/empathy-import-dialog.h
+++ b/src/empathy-import-dialog.h
@@ -25,6 +25,8 @@
#ifndef __EMPATHY_IMPORT_DIALOG_H__
#define __EMPATHY_IMPORT_DIALOG_H__
+#include <libempathy/empathy-connection-managers.h>
+
G_BEGIN_DECLS
#define EMPATHY_TYPE_IMPORT_DIALOG empathy_import_dialog_get_type()
@@ -56,7 +58,8 @@ typedef struct {
GType empathy_import_dialog_get_type (void);
GtkWidget* empathy_import_dialog_new (GtkWindow *parent_window,
- gboolean show_warning);
+ gboolean show_warning,
+ EmpathyConnectionManagers *cms);
G_END_DECLS
diff --git a/src/empathy-import-widget.c b/src/empathy-import-widget.c
index 9a8917ffc..041c51003 100644
--- a/src/empathy-import-widget.c
+++ b/src/empathy-import-widget.c
@@ -55,7 +55,8 @@ enum
};
enum {
- PROP_APPLICATION_ID = 1
+ PROP_APPLICATION_ID = 1,
+ PROP_CMS
};
typedef struct {
@@ -200,7 +201,7 @@ import_widget_add_account (EmpathyImportWidget *self,
EmpathyImportAccountData *data)
{
TpAccountManager *account_manager;
- gchar *display_name;
+ gchar *display_name = NULL;
GHashTable *properties;
GValue *username;
@@ -210,9 +211,23 @@ import_widget_add_account (EmpathyImportWidget *self,
/* Set the display name of the account */
username = g_hash_table_lookup (data->settings, "account");
- display_name = g_strdup_printf ("%s (%s)",
- data->protocol,
- g_value_get_string (username));
+
+ if (!tp_strdiff (data->protocol, "irc"))
+ {
+ const gchar *server;
+
+ server = tp_asv_get_string (data->settings, "server");
+
+ if (server != NULL)
+ display_name = g_strdup_printf ("%s on %s",
+ g_value_get_string (username), server);
+ }
+
+ if (display_name == NULL)
+ {
+ display_name = g_strdup_printf ("%s (%s)",
+ data->protocol, g_value_get_string (username));
+ }
DEBUG ("display name: %s\n", display_name);
@@ -345,20 +360,6 @@ import_widget_set_up_account_list (EmpathyImportWidget *self)
}
static void
-import_widget_cms_prepare_cb (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- EmpathyImportWidget *self = user_data;
-
- if (!empathy_connection_managers_prepare_finish (
- EMPATHY_CONNECTION_MANAGERS (source), result, NULL))
- return;
-
- import_widget_set_up_account_list (self);
-}
-
-static void
import_widget_destroy_cb (GtkWidget *w,
EmpathyImportWidget *self)
{
@@ -378,6 +379,9 @@ do_get_property (GObject *object,
case PROP_APPLICATION_ID:
g_value_set_int (value, priv->app_id);
break;
+ case PROP_CMS:
+ g_value_set_object (value, priv->cms);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -396,6 +400,9 @@ do_set_property (GObject *object,
case PROP_APPLICATION_ID:
priv->app_id = g_value_get_int (value);
break;
+ case PROP_CMS:
+ priv->cms = g_value_dup_object (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -454,8 +461,7 @@ do_constructed (GObject *obj)
g_signal_connect (priv->vbox, "destroy",
G_CALLBACK (import_widget_destroy_cb), self);
- empathy_connection_managers_prepare_async (priv->cms,
- import_widget_cms_prepare_cb, self);
+ import_widget_set_up_account_list (self);
}
static void
@@ -476,6 +482,12 @@ empathy_import_widget_class_init (EmpathyImportWidgetClass *klass)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property (oclass, PROP_APPLICATION_ID, param_spec);
+ param_spec = g_param_spec_object ("cms",
+ "EmpathyConnectionManagers", "EmpathyConnectionManager",
+ EMPATHY_TYPE_CONNECTION_MANAGERS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (oclass, PROP_CMS, param_spec);
+
g_type_class_add_private (klass, sizeof (EmpathyImportWidgetPriv));
}
@@ -487,14 +499,18 @@ empathy_import_widget_init (EmpathyImportWidget *self)
EmpathyImportWidgetPriv);
self->priv = priv;
-
- priv->cms = empathy_connection_managers_dup_singleton ();
}
EmpathyImportWidget *
-empathy_import_widget_new (EmpathyImportApplication id)
+empathy_import_widget_new (EmpathyImportApplication id,
+ EmpathyConnectionManagers *cms)
{
- return g_object_new (EMPATHY_TYPE_IMPORT_WIDGET, "application-id", id, NULL);
+ g_return_val_if_fail (EMPATHY_IS_CONNECTION_MANAGERS (cms), NULL);
+
+ return g_object_new (EMPATHY_TYPE_IMPORT_WIDGET,
+ "application-id", id,
+ "cms", cms,
+ NULL);
}
GtkWidget *
diff --git a/src/empathy-import-widget.h b/src/empathy-import-widget.h
index 48f2e1d48..14a01d79d 100644
--- a/src/empathy-import-widget.h
+++ b/src/empathy-import-widget.h
@@ -27,6 +27,8 @@
#include <glib-object.h>
+#include <libempathy/empathy-connection-managers.h>
+
#include "empathy-import-utils.h"
G_BEGIN_DECLS
@@ -59,7 +61,8 @@ typedef struct {
GType empathy_import_widget_get_type (void);
-EmpathyImportWidget* empathy_import_widget_new (EmpathyImportApplication id);
+EmpathyImportWidget* empathy_import_widget_new (EmpathyImportApplication id,
+ EmpathyConnectionManagers *cms);
GtkWidget * empathy_import_widget_get_widget (EmpathyImportWidget *self);
diff --git a/src/empathy-invite-participant-dialog.c b/src/empathy-invite-participant-dialog.c
index f905c827e..ece86f1b6 100644
--- a/src/empathy-invite-participant-dialog.c
+++ b/src/empathy-invite-participant-dialog.c
@@ -114,6 +114,8 @@ get_tp_contact_for_chat (EmpathyInviteParticipantDialog *self,
TpConnection *chat_conn;
chat_conn = tp_channel_borrow_connection (TP_CHANNEL (self->priv->tp_chat));
+ if (chat_conn == NULL)
+ return NULL;
return empathy_get_tp_contact_for_individual (individual, chat_conn);
}
diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c
deleted file mode 100644
index 2f73acf92..000000000
--- a/src/empathy-main-window.c
+++ /dev/null
@@ -1,2586 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2002-2007 Imendio AB
- * Copyright (C) 2007-2010 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: Xavier Claessens <xclaesse@gmail.com>
- * Danielle Madeley <danielle.madeley@collabora.co.uk>
- */
-
-#include <config.h>
-
-#include <sys/stat.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-
-#include <telepathy-glib/account-manager.h>
-#include <telepathy-glib/util.h>
-#include <folks/folks.h>
-
-#include <libempathy/empathy-contact.h>
-#include <libempathy/empathy-utils.h>
-#include <libempathy/empathy-request-util.h>
-#include <libempathy/empathy-chatroom-manager.h>
-#include <libempathy/empathy-chatroom.h>
-#include <libempathy/empathy-contact-list.h>
-#include <libempathy/empathy-contact-manager.h>
-#include <libempathy/empathy-gsettings.h>
-#include <libempathy/empathy-individual-manager.h>
-#include <libempathy/empathy-gsettings.h>
-#include <libempathy/empathy-status-presets.h>
-#include <libempathy/empathy-tp-contact-factory.h>
-
-#include <libempathy-gtk/empathy-contact-dialogs.h>
-#include <libempathy-gtk/empathy-live-search.h>
-#include <libempathy-gtk/empathy-contact-blocking-dialog.h>
-#include <libempathy-gtk/empathy-contact-search-dialog.h>
-#include <libempathy-gtk/empathy-geometry.h>
-#include <libempathy-gtk/empathy-gtk-enum-types.h>
-#include <libempathy-gtk/empathy-individual-dialogs.h>
-#include <libempathy-gtk/empathy-individual-store.h>
-#include <libempathy-gtk/empathy-individual-store-manager.h>
-#include <libempathy-gtk/empathy-individual-view.h>
-#include <libempathy-gtk/empathy-new-message-dialog.h>
-#include <libempathy-gtk/empathy-new-call-dialog.h>
-#include <libempathy-gtk/empathy-log-window.h>
-#include <libempathy-gtk/empathy-presence-chooser.h>
-#include <libempathy-gtk/empathy-sound-manager.h>
-#include <libempathy-gtk/empathy-ui-utils.h>
-
-#include "empathy-accounts-dialog.h"
-#include "empathy-call-observer.h"
-#include "empathy-chat-manager.h"
-#include "empathy-main-window.h"
-#include "empathy-preferences.h"
-#include "empathy-about-dialog.h"
-#include "empathy-debug-window.h"
-#include "empathy-new-chatroom-dialog.h"
-#include "empathy-map-view.h"
-#include "empathy-chatrooms-window.h"
-#include "empathy-event-manager.h"
-#include "empathy-ft-manager.h"
-
-#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
-#include <libempathy/empathy-debug.h>
-
-/* Flashing delay for icons (milliseconds). */
-#define FLASH_TIMEOUT 500
-
-/* Minimum width of roster window if something goes wrong. */
-#define MIN_WIDTH 50
-
-/* Accels (menu shortcuts) can be configured and saved */
-#define ACCELS_FILENAME "accels.txt"
-
-/* Name in the geometry file */
-#define GEOMETRY_NAME "main-window"
-
-enum {
- PAGE_CONTACT_LIST = 0,
- PAGE_NO_MATCH
-};
-
-enum {
- PROP_0,
- PROP_SHELL_RUNNING
-};
-
-G_DEFINE_TYPE (EmpathyMainWindow, empathy_main_window, GTK_TYPE_WINDOW);
-
-#define GET_PRIV(self) ((EmpathyMainWindowPriv *)((EmpathyMainWindow *) self)->priv)
-
-struct _EmpathyMainWindowPriv {
- EmpathyContactList *contact_manager;
- EmpathyIndividualStore *individual_store;
- EmpathyIndividualView *individual_view;
- TpAccountManager *account_manager;
- EmpathyChatroomManager *chatroom_manager;
- EmpathyEventManager *event_manager;
- EmpathySoundManager *sound_mgr;
- EmpathyCallObserver *call_observer;
- guint flash_timeout_id;
- gboolean flash_on;
- gboolean empty;
-
- GSettings *gsettings_ui;
- GSettings *gsettings_contacts;
-
- GtkWidget *preferences;
- GtkWidget *main_vbox;
- GtkWidget *throbber;
- GtkWidget *throbber_tool_item;
- GtkWidget *presence_toolbar;
- GtkWidget *presence_chooser;
- GtkWidget *errors_vbox;
- GtkWidget *auth_vbox;
- GtkWidget *search_bar;
- GtkWidget *notebook;
- GtkWidget *no_entry_label;
-
- GtkToggleAction *show_protocols;
- GtkRadioAction *sort_by_name;
- GtkRadioAction *sort_by_status;
- GtkRadioAction *normal_with_avatars;
- GtkRadioAction *normal_size;
- GtkRadioAction *compact_size;
-
- GtkUIManager *ui_manager;
- GtkAction *view_history;
- GtkAction *room_join_favorites;
- GtkWidget *room_menu;
- GtkWidget *room_separator;
- GtkWidget *edit_context;
- GtkWidget *edit_context_separator;
-
- GtkActionGroup *balance_action_group;
- GtkAction *view_balance_show_in_roster;
- GtkWidget *balance_vbox;
-
- guint size_timeout_id;
-
- /* reffed TpAccount* => visible GtkInfoBar* */
- GHashTable *errors;
-
- /* EmpathyEvent* => visible GtkInfoBar* */
- GHashTable *auths;
-
- /* stores a mapping from TpAccount to Handler ID to prevent
- * to listen more than once to the status-changed signal */
- GHashTable *status_changed_handlers;
-
- /* Actions that are enabled when there are connected accounts */
- GList *actions_connected;
-
- gboolean shell_running;
-};
-
-static void
-main_window_flash_stop (EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- if (priv->flash_timeout_id == 0) {
- return;
- }
-
- DEBUG ("Stop flashing");
- g_source_remove (priv->flash_timeout_id);
- priv->flash_timeout_id = 0;
- priv->flash_on = FALSE;
-}
-
-typedef struct {
- EmpathyEvent *event;
- gboolean on;
- EmpathyMainWindow *window;
-} FlashForeachData;
-
-static gboolean
-main_window_flash_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- FlashForeachData *data = (FlashForeachData *) user_data;
- FolksIndividual *individual;
- EmpathyContact *contact;
- const gchar *icon_name;
- GtkTreePath *parent_path = NULL;
- GtkTreeIter parent_iter;
- GdkPixbuf *pixbuf = NULL;
-
- gtk_tree_model_get (model, iter,
- EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual,
- -1);
-
- if (individual == NULL)
- return FALSE;
-
- contact = empathy_contact_dup_from_folks_individual (individual);
- if (contact != data->event->contact)
- goto out;
-
- if (data->on) {
- icon_name = data->event->icon_name;
- pixbuf = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
- } else {
- pixbuf = empathy_individual_store_get_individual_status_icon (
- GET_PRIV (data->window)->individual_store,
- individual);
- if (pixbuf != NULL)
- g_object_ref (pixbuf);
- }
-
- gtk_tree_store_set (GTK_TREE_STORE (model), iter,
- EMPATHY_INDIVIDUAL_STORE_COL_ICON_STATUS, pixbuf,
- -1);
-
- /* To make sure the parent is shown correctly, we emit
- * the row-changed signal on the parent so it prompts
- * it to be refreshed by the filter func.
- */
- if (gtk_tree_model_iter_parent (model, &parent_iter, iter)) {
- parent_path = gtk_tree_model_get_path (model, &parent_iter);
- }
- if (parent_path) {
- gtk_tree_model_row_changed (model, parent_path, &parent_iter);
- gtk_tree_path_free (parent_path);
- }
-
-out:
- g_object_unref (individual);
- tp_clear_object (&contact);
- tp_clear_object (&pixbuf);
-
- return FALSE;
-}
-
-static gboolean
-main_window_flash_cb (EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkTreeModel *model;
- GSList *events, *l;
- gboolean found_event = FALSE;
- FlashForeachData data;
-
- priv->flash_on = !priv->flash_on;
- data.on = priv->flash_on;
- model = GTK_TREE_MODEL (priv->individual_store);
-
- events = empathy_event_manager_get_events (priv->event_manager);
- for (l = events; l; l = l->next) {
- data.event = l->data;
- data.window = window;
- if (!data.event->contact || !data.event->must_ack) {
- continue;
- }
-
- found_event = TRUE;
- gtk_tree_model_foreach (model,
- main_window_flash_foreach,
- &data);
- }
-
- if (!found_event) {
- main_window_flash_stop (window);
- }
-
- return TRUE;
-}
-
-static void
-main_window_flash_start (EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- if (priv->flash_timeout_id != 0) {
- return;
- }
-
- DEBUG ("Start flashing");
- priv->flash_timeout_id = g_timeout_add (FLASH_TIMEOUT,
- (GSourceFunc) main_window_flash_cb,
- window);
- main_window_flash_cb (window);
-}
-
-static void
-main_window_remove_auth (EmpathyMainWindow *window,
- EmpathyEvent *event)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *error_widget;
-
- error_widget = g_hash_table_lookup (priv->auths, event);
- if (error_widget != NULL) {
- gtk_widget_destroy (error_widget);
- g_hash_table_remove (priv->auths, event);
- }
-}
-
-static void
-main_window_auth_add_clicked_cb (GtkButton *button,
- EmpathyMainWindow *window)
-{
- EmpathyEvent *event;
-
- event = g_object_get_data (G_OBJECT (button), "event");
-
- empathy_event_approve (event);
-
- main_window_remove_auth (window, event);
-}
-
-static void
-main_window_auth_close_clicked_cb (GtkButton *button,
- EmpathyMainWindow *window)
-{
- EmpathyEvent *event;
-
- event = g_object_get_data (G_OBJECT (button), "event");
-
- empathy_event_decline (event);
- main_window_remove_auth (window, event);
-}
-
-static void
-main_window_auth_display (EmpathyMainWindow *window,
- EmpathyEvent *event)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- TpAccount *account = event->account;
- GtkWidget *info_bar;
- GtkWidget *content_area;
- GtkWidget *image;
- GtkWidget *label;
- GtkWidget *add_button;
- GtkWidget *close_button;
- GtkWidget *action_area;
- GtkWidget *action_grid;
- const gchar *icon_name;
- gchar *str;
-
- if (g_hash_table_lookup (priv->auths, event) != NULL) {
- return;
- }
-
- info_bar = gtk_info_bar_new ();
- gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_QUESTION);
-
- gtk_widget_set_no_show_all (info_bar, TRUE);
- gtk_box_pack_start (GTK_BOX (priv->auth_vbox), info_bar, FALSE, TRUE, 0);
- gtk_widget_show (info_bar);
-
- icon_name = tp_account_get_icon_name (account);
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_widget_show (image);
-
- str = g_markup_printf_escaped ("<b>%s</b>\n%s",
- tp_account_get_display_name (account),
- _("Password required"));
-
- label = gtk_label_new (str);
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- gtk_widget_show (label);
-
- g_free (str);
-
- content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
- gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
-
- image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
- add_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (add_button), image);
- gtk_widget_set_tooltip_text (add_button, _("Provide Password"));
- gtk_widget_show (add_button);
-
- image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON);
- close_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (close_button), image);
- gtk_widget_set_tooltip_text (close_button, _("Disconnect"));
- gtk_widget_show (close_button);
-
- action_grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (action_grid), 6);
- gtk_widget_show (action_grid);
-
- action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
- gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
-
- gtk_grid_attach (GTK_GRID (action_grid), add_button, 0, 0, 1, 1);
- gtk_grid_attach (GTK_GRID (action_grid), close_button, 1, 0, 1, 1);
-
- g_object_set_data_full (G_OBJECT (info_bar),
- "event", event, NULL);
- g_object_set_data_full (G_OBJECT (add_button),
- "event", event, NULL);
- g_object_set_data_full (G_OBJECT (close_button),
- "event", event, NULL);
-
- g_signal_connect (add_button, "clicked",
- G_CALLBACK (main_window_auth_add_clicked_cb),
- window);
- g_signal_connect (close_button, "clicked",
- G_CALLBACK (main_window_auth_close_clicked_cb),
- window);
-
- gtk_widget_show (priv->auth_vbox);
-
- g_hash_table_insert (priv->auths, event, info_bar);
-}
-
-static void
-modify_event_count (GtkTreeModel *model,
- GtkTreeIter *iter,
- EmpathyEvent *event,
- gboolean increase)
-{
- FolksIndividual *individual;
- EmpathyContact *contact;
- guint count;
-
- gtk_tree_model_get (model, iter,
- EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual,
- EMPATHY_INDIVIDUAL_STORE_COL_EVENT_COUNT, &count,
- -1);
-
- if (individual == NULL)
- return;
-
- increase ? count++ : count--;
-
- contact = empathy_contact_dup_from_folks_individual (individual);
- if (contact == event->contact) {
- gtk_tree_store_set (GTK_TREE_STORE (model), iter,
- EMPATHY_INDIVIDUAL_STORE_COL_EVENT_COUNT, count, -1);
- }
-
- tp_clear_object (&contact);
- g_object_unref (individual);
-}
-
-static gboolean
-increase_event_count_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- EmpathyEvent *event = user_data;
-
- modify_event_count (model, iter, event, TRUE);
-
- return FALSE;
-}
-
-static void
-increase_event_count (EmpathyMainWindow *self,
- EmpathyEvent *event)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (self);
- GtkTreeModel *model;
-
- model = GTK_TREE_MODEL (priv->individual_store);
-
- gtk_tree_model_foreach (model, increase_event_count_foreach, event);
-}
-
-static gboolean
-decrease_event_count_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer user_data)
-{
- EmpathyEvent *event = user_data;
-
- modify_event_count (model, iter, event, FALSE);
-
- return FALSE;
-}
-
-static void
-decrease_event_count (EmpathyMainWindow *self,
- EmpathyEvent *event)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (self);
- GtkTreeModel *model;
-
- model = GTK_TREE_MODEL (priv->individual_store);
-
- gtk_tree_model_foreach (model, decrease_event_count_foreach, event);
-}
-
-static void
-main_window_event_added_cb (EmpathyEventManager *manager,
- EmpathyEvent *event,
- EmpathyMainWindow *window)
-{
- if (event->contact) {
- increase_event_count (window, event);
-
- main_window_flash_start (window);
- } else if (event->type == EMPATHY_EVENT_TYPE_AUTH) {
- main_window_auth_display (window, event);
- }
-}
-
-static void
-main_window_event_removed_cb (EmpathyEventManager *manager,
- EmpathyEvent *event,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- FlashForeachData data;
-
- if (event->type == EMPATHY_EVENT_TYPE_AUTH) {
- main_window_remove_auth (window, event);
- return;
- }
-
- if (!event->contact) {
- return;
- }
-
- decrease_event_count (window, event);
-
- data.on = FALSE;
- data.event = event;
- data.window = window;
- gtk_tree_model_foreach (GTK_TREE_MODEL (priv->individual_store),
- main_window_flash_foreach,
- &data);
-}
-
-static gboolean
-main_window_load_events_idle_cb (gpointer user_data)
-{
- EmpathyMainWindow *window = user_data;
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GSList *l;
-
- l = empathy_event_manager_get_events (priv->event_manager);
- while (l) {
- main_window_event_added_cb (priv->event_manager, l->data,
- window);
- l = l->next;
- }
-
- return FALSE;
-}
-
-static void
-main_window_row_activated_cb (EmpathyIndividualView *view,
- GtkTreePath *path,
- GtkTreeViewColumn *col,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- EmpathyContact *contact = NULL;
- FolksIndividual *individual;
- GtkTreeModel *model;
- GtkTreeIter iter;
- GSList *events, *l;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->individual_view));
- gtk_tree_model_get_iter (model, &iter, path);
-
- gtk_tree_model_get (model, &iter,
- EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL,
- &individual,
- -1);
-
- if (individual != NULL) {
- contact = empathy_contact_dup_from_folks_individual (individual);
- }
-
- if (!contact) {
- goto OUT;
- }
-
- /* If the contact has an event activate it, otherwise the
- * default handler of row-activated will be called. */
- events = empathy_event_manager_get_events (priv->event_manager);
- for (l = events; l; l = l->next) {
- EmpathyEvent *event = l->data;
-
- if (event->contact == contact) {
- DEBUG ("Activate event");
- empathy_event_activate (event);
-
- /* We don't want the default handler of this signal
- * (e.g. open a chat) */
- g_signal_stop_emission_by_name (view, "row-activated");
- break;
- }
- }
-
- g_object_unref (contact);
-OUT:
- tp_clear_object (&individual);
-}
-
-static void
-main_window_row_deleted_cb (GtkTreeModel *model,
- GtkTreePath *path,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkTreeIter help_iter;
-
- if (!gtk_tree_model_get_iter_first (model, &help_iter)) {
- priv->empty = TRUE;
-
- if (empathy_individual_view_is_searching (
- priv->individual_view)) {
- gchar *tmp;
-
- tmp = g_strdup_printf ("<b><span size='xx-large'>%s</span></b>",
- _("No match found"));
-
- gtk_label_set_markup (GTK_LABEL (priv->no_entry_label), tmp);
- g_free (tmp);
-
- gtk_label_set_line_wrap (GTK_LABEL (priv->no_entry_label),
- TRUE);
-
- gtk_notebook_set_current_page (
- GTK_NOTEBOOK (priv->notebook), PAGE_NO_MATCH);
- }
- }
-}
-
-static void
-main_window_row_inserted_cb (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- if (priv->empty) {
- priv->empty = FALSE;
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook),
- PAGE_CONTACT_LIST);
- gtk_widget_grab_focus (GTK_WIDGET (priv->individual_view));
-
- /* The store is being filled, it will be done after an idle cb.
- * So we can then get events. If we do that too soon, event's
- * contact is not yet in the store and it won't get marked as
- * having events. */
- g_idle_add (main_window_load_events_idle_cb, window);
- }
-}
-
-static void
-main_window_remove_error (EmpathyMainWindow *window,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *error_widget;
-
- error_widget = g_hash_table_lookup (priv->errors, account);
- if (error_widget != NULL) {
- gtk_widget_destroy (error_widget);
- g_hash_table_remove (priv->errors, account);
- }
-}
-
-static void
-main_window_account_disabled_cb (TpAccountManager *manager,
- TpAccount *account,
- EmpathyMainWindow *window)
-{
- main_window_remove_error (window, account);
-}
-
-static void
-main_window_error_retry_clicked_cb (GtkButton *button,
- EmpathyMainWindow *window)
-{
- TpAccount *account;
-
- account = g_object_get_data (G_OBJECT (button), "account");
- tp_account_reconnect_async (account, NULL, NULL);
-
- main_window_remove_error (window, account);
-}
-
-static void
-main_window_error_edit_clicked_cb (GtkButton *button,
- EmpathyMainWindow *window)
-{
- TpAccount *account;
-
- account = g_object_get_data (G_OBJECT (button), "account");
-
- empathy_accounts_dialog_show_application (
- gtk_widget_get_screen (GTK_WIDGET (button)),
- account, FALSE, FALSE);
-
- main_window_remove_error (window, account);
-}
-
-static void
-main_window_error_close_clicked_cb (GtkButton *button,
- EmpathyMainWindow *window)
-{
- TpAccount *account;
-
- account = g_object_get_data (G_OBJECT (button), "account");
- main_window_remove_error (window, account);
-}
-
-static void
-main_window_error_upgrade_sw_clicked_cb (GtkButton *button,
- EmpathyMainWindow *window)
-{
- TpAccount *account;
- GtkWidget *dialog;
-
- account = g_object_get_data (G_OBJECT (button), "account");
- main_window_remove_error (window, account);
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (window),
- GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("Sorry, %s accounts can’t be used until your %s software is updated."),
- tp_account_get_protocol (account),
- tp_account_get_protocol (account));
-
- g_signal_connect_swapped (dialog, "response",
- G_CALLBACK (gtk_widget_destroy),
- dialog);
-
- gtk_widget_show (dialog);
-}
-
-static void
-main_window_upgrade_software_error (EmpathyMainWindow *window,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *info_bar;
- GtkWidget *content_area;
- GtkWidget *label;
- GtkWidget *image;
- GtkWidget *upgrade_button;
- GtkWidget *close_button;
- GtkWidget *action_area;
- GtkWidget *action_grid;
- gchar *str;
- const gchar *icon_name;
- const gchar *error_message;
- gboolean user_requested;
-
- error_message =
- empathy_account_get_error_message (account, &user_requested);
-
- if (user_requested) {
- return;
- }
-
- str = g_markup_printf_escaped ("<b>%s</b>\n%s",
- tp_account_get_display_name (account),
- error_message);
-
- /* If there are other errors, remove them */
- main_window_remove_error (window, account);
-
- info_bar = gtk_info_bar_new ();
- gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR);
-
- gtk_widget_set_no_show_all (info_bar, TRUE);
- gtk_box_pack_start (GTK_BOX (priv->errors_vbox), info_bar, FALSE, TRUE, 0);
- gtk_widget_show (info_bar);
-
- icon_name = tp_account_get_icon_name (account);
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_widget_show (image);
-
- label = gtk_label_new (str);
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- gtk_widget_show (label);
- g_free (str);
-
- content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
- gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
-
- image = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON);
- upgrade_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (upgrade_button), image);
- gtk_widget_set_tooltip_text (upgrade_button, _("Update software..."));
- gtk_widget_show (upgrade_button);
-
- image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON);
- close_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (close_button), image);
- gtk_widget_set_tooltip_text (close_button, _("Close"));
- gtk_widget_show (close_button);
-
- action_grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (action_grid), 2);
- gtk_widget_show (action_grid);
-
- action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
- gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
-
- gtk_grid_attach (GTK_GRID (action_grid), upgrade_button, 0, 0, 1, 1);
- gtk_grid_attach (GTK_GRID (action_grid), close_button, 1, 0, 1, 1);
-
- g_object_set_data (G_OBJECT (info_bar), "label", label);
- g_object_set_data_full (G_OBJECT (info_bar),
- "account", g_object_ref (account),
- g_object_unref);
- g_object_set_data_full (G_OBJECT (upgrade_button),
- "account", g_object_ref (account),
- g_object_unref);
- g_object_set_data_full (G_OBJECT (close_button),
- "account", g_object_ref (account),
- g_object_unref);
-
- g_signal_connect (upgrade_button, "clicked",
- G_CALLBACK (main_window_error_upgrade_sw_clicked_cb),
- window);
- g_signal_connect (close_button, "clicked",
- G_CALLBACK (main_window_error_close_clicked_cb),
- window);
-
- gtk_widget_set_tooltip_text (priv->errors_vbox, error_message);
- gtk_widget_show (priv->errors_vbox);
-
- g_hash_table_insert (priv->errors, g_object_ref (account), info_bar);
-}
-
-static void
-main_window_error_display (EmpathyMainWindow *window,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *info_bar;
- GtkWidget *content_area;
- GtkWidget *label;
- GtkWidget *image;
- GtkWidget *retry_button;
- GtkWidget *edit_button;
- GtkWidget *close_button;
- GtkWidget *action_area;
- GtkWidget *action_grid;
- gchar *str;
- const gchar *icon_name;
- const gchar *error_message;
- gboolean user_requested;
-
- if (!tp_strdiff (TP_ERROR_STR_SOFTWARE_UPGRADE_REQUIRED,
- tp_account_get_detailed_error (account, NULL))) {
- main_window_upgrade_software_error (window, account);
- return;
- }
-
- error_message =
- empathy_account_get_error_message (account, &user_requested);
-
- if (user_requested) {
- return;
- }
-
- str = g_markup_printf_escaped ("<b>%s</b>\n%s",
- tp_account_get_display_name (account),
- error_message);
-
- info_bar = g_hash_table_lookup (priv->errors, account);
- if (info_bar) {
- label = g_object_get_data (G_OBJECT (info_bar), "label");
-
- /* Just set the latest error and return */
- gtk_label_set_markup (GTK_LABEL (label), str);
- g_free (str);
-
- return;
- }
-
- info_bar = gtk_info_bar_new ();
- gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR);
-
- gtk_widget_set_no_show_all (info_bar, TRUE);
- gtk_box_pack_start (GTK_BOX (priv->errors_vbox), info_bar, FALSE, TRUE, 0);
- gtk_widget_show (info_bar);
-
- icon_name = tp_account_get_icon_name (account);
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_widget_show (image);
-
- label = gtk_label_new (str);
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- gtk_widget_show (label);
- g_free (str);
-
- content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
- gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
-
- image = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON);
- retry_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (retry_button), image);
- gtk_widget_set_tooltip_text (retry_button, _("Reconnect"));
- gtk_widget_show (retry_button);
-
- image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON);
- edit_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (edit_button), image);
- gtk_widget_set_tooltip_text (edit_button, _("Edit Account"));
- gtk_widget_show (edit_button);
-
- image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON);
- close_button = gtk_button_new ();
- gtk_button_set_image (GTK_BUTTON (close_button), image);
- gtk_widget_set_tooltip_text (close_button, _("Close"));
- gtk_widget_show (close_button);
-
- action_grid = gtk_grid_new ();
- gtk_grid_set_column_spacing (GTK_GRID (action_grid), 2);
- gtk_widget_show (action_grid);
-
- action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
- gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
-
- gtk_grid_attach (GTK_GRID (action_grid), retry_button, 0, 0, 1, 1);
- gtk_grid_attach (GTK_GRID (action_grid), edit_button, 1, 0, 1, 1);
- gtk_grid_attach (GTK_GRID (action_grid), close_button, 2, 0, 1, 1);
-
- g_object_set_data (G_OBJECT (info_bar), "label", label);
- g_object_set_data_full (G_OBJECT (info_bar),
- "account", g_object_ref (account),
- g_object_unref);
- g_object_set_data_full (G_OBJECT (edit_button),
- "account", g_object_ref (account),
- g_object_unref);
- g_object_set_data_full (G_OBJECT (close_button),
- "account", g_object_ref (account),
- g_object_unref);
- g_object_set_data_full (G_OBJECT (retry_button),
- "account", g_object_ref (account),
- g_object_unref);
-
- g_signal_connect (edit_button, "clicked",
- G_CALLBACK (main_window_error_edit_clicked_cb),
- window);
- g_signal_connect (close_button, "clicked",
- G_CALLBACK (main_window_error_close_clicked_cb),
- window);
- g_signal_connect (retry_button, "clicked",
- G_CALLBACK (main_window_error_retry_clicked_cb),
- window);
-
- gtk_widget_set_tooltip_text (priv->errors_vbox, error_message);
- gtk_widget_show (priv->errors_vbox);
-
- g_hash_table_insert (priv->errors, g_object_ref (account), info_bar);
-}
-
-static void
-main_window_update_status (EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- gboolean connected, connecting;
- GList *l, *children;
-
- connected = empathy_account_manager_get_accounts_connected (&connecting);
-
- /* Update the spinner state */
- if (connecting) {
- gtk_spinner_start (GTK_SPINNER (priv->throbber));
- gtk_widget_show (priv->throbber_tool_item);
- } else {
- gtk_spinner_stop (GTK_SPINNER (priv->throbber));
- gtk_widget_hide (priv->throbber_tool_item);
- }
-
- /* Update widgets sensibility */
- for (l = priv->actions_connected; l; l = l->next) {
- gtk_action_set_sensitive (l->data, connected);
- }
-
- /* Update favourite rooms sensitivity */
- children = gtk_container_get_children (GTK_CONTAINER (priv->room_menu));
- for (l = children; l != NULL; l = l->next) {
- if (g_object_get_data (G_OBJECT (l->data), "is_favorite") != NULL) {
- gtk_widget_set_sensitive (GTK_WIDGET (l->data), connected);
- }
- }
- g_list_free (children);
-}
-
-static char *
-main_window_account_to_action_name (TpAccount *account)
-{
- char *r;
-
- /* action names can't have '/' in them, replace it with '.' */
- r = g_strdup (tp_account_get_path_suffix (account));
- r = g_strdelimit (r, "/", '.');
-
- return r;
-}
-
-static void
-main_window_balance_activate_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- const char *uri;
-
- uri = g_object_get_data (G_OBJECT (action), "manage-credit-uri");
-
- if (!tp_str_empty (uri)) {
- DEBUG ("Top-up credit URI: %s", uri);
- empathy_url_show (GTK_WIDGET (window), uri);
- } else {
- DEBUG ("unknown protocol for top-up");
- }
-}
-
-static void
-main_window_balance_update_balance (GtkAction *action,
- TpConnection *conn)
-{
- TpAccount *account = tp_connection_get_account (conn);
- GtkWidget *label;
- int amount = 0;
- guint scale = G_MAXINT32;
- const gchar *currency = "";
- char *money, *str;
-
- if (!tp_connection_get_balance (conn, &amount, &scale, &currency))
- return;
-
- if (amount == 0 &&
- scale == G_MAXINT32 &&
- tp_str_empty (currency)) {
- /* unknown balance */
- money = g_strdup ("--");
- } else {
- char *tmp = empathy_format_currency (amount, scale, currency);
-
- money = g_strdup_printf ("%s %s", currency, tmp);
- g_free (tmp);
- }
-
- /* Translators: this string will be something like:
- * Top up My Account ($1.23)..." */
- str = g_strdup_printf (_("Top up %s (%s)..."),
- tp_account_get_display_name (account),
- money);
-
- gtk_action_set_label (action, str);
- g_free (str);
-
- /* update the money label in the roster */
- label = g_object_get_data (G_OBJECT (action), "money-label");
-
- gtk_label_set_text (GTK_LABEL (label), money);
- g_free (money);
-}
-
-static void
-main_window_balance_changed_cb (TpConnection *conn,
- guint balance,
- guint scale,
- const gchar *currency,
- GtkAction *action)
-{
- main_window_balance_update_balance (action, conn);
-}
-
-static GtkAction *
-main_window_setup_balance_create_action (EmpathyMainWindow *window,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkAction *action;
- char *name, *ui;
- guint merge_id;
- GError *error = NULL;
-
- /* create the action group if required */
- if (priv->balance_action_group == NULL) {
- priv->balance_action_group =
- gtk_action_group_new ("balance-action-group");
-
- gtk_ui_manager_insert_action_group (priv->ui_manager,
- priv->balance_action_group, -1);
- }
-
- /* create the action */
- name = main_window_account_to_action_name (account);
- action = gtk_action_new (name,
- tp_account_get_display_name (account),
- _("Top up account credit"),
- NULL);
- g_object_bind_property (account, "icon-name", action, "icon-name",
- G_BINDING_SYNC_CREATE);
-
- g_signal_connect (action, "activate",
- G_CALLBACK (main_window_balance_activate_cb), window);
-
- gtk_action_group_add_action (priv->balance_action_group, action);
- g_object_unref (action);
-
- ui = g_strdup_printf (
- "<ui>"
- " <menubar name='menubar'>"
- " <menu action='view'>"
- " <placeholder name='view_balance_placeholder'>"
- " <menuitem action='%s'/>"
- " </placeholder>"
- " </menu>"
- " </menubar>"
- "</ui>",
- name);
-
- merge_id = gtk_ui_manager_add_ui_from_string (priv->ui_manager,
- ui, -1, &error);
- if (error != NULL) {
- DEBUG ("Failed to add balance UI for %s: %s",
- tp_account_get_display_name (account),
- error->message);
- g_error_free (error);
- }
-
- g_object_set_data (G_OBJECT (action),
- "merge-id", GUINT_TO_POINTER (merge_id));
-
- g_free (name);
- g_free (ui);
-
- return action;
-}
-
-static GtkWidget *
-main_window_setup_balance_create_widget (EmpathyMainWindow *window,
- GtkAction *action,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *hbox, *image, *label, *button;
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
- /* protocol icon */
- image = gtk_image_new ();
- gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
- g_object_bind_property (action, "icon-name", image, "icon-name",
- G_BINDING_SYNC_CREATE);
-
- /* account name label */
- label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
- g_object_bind_property (account, "display-name", label, "label",
- G_BINDING_SYNC_CREATE);
-
- /* balance label */
- label = gtk_label_new ("");
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
- g_object_set_data (G_OBJECT (action), "money-label", label);
-
- /* top up button */
- button = gtk_button_new_with_label (_("Top Up..."));
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
- g_signal_connect_swapped (button, "clicked",
- G_CALLBACK (gtk_action_activate), action);
-
- gtk_box_pack_start (GTK_BOX (priv->balance_vbox), hbox, FALSE, TRUE, 0);
- gtk_widget_show_all (hbox);
-
- /* tie the lifetime of the widget to the lifetime of the action */
- g_object_weak_ref (G_OBJECT (action),
- (GWeakNotify) gtk_widget_destroy, hbox);
-
- return hbox;
-}
-
-static void
-main_window_setup_balance (EmpathyMainWindow *window,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- TpConnection *conn = tp_account_get_connection (account);
- GtkAction *action;
- const gchar *uri;
-
- if (conn == NULL)
- return;
-
- if (!tp_proxy_is_prepared (conn, TP_CONNECTION_FEATURE_BALANCE))
- return;
-
- DEBUG ("Setting up balance for acct: %s",
- tp_account_get_display_name (account));
-
- /* create the action */
- action = main_window_setup_balance_create_action (window, account);
-
- if (action == NULL)
- return;
-
- gtk_action_set_visible (priv->view_balance_show_in_roster, TRUE);
-
- /* create the display widget */
- main_window_setup_balance_create_widget (window, action, account);
-
- /* check the current balance and monitor for any changes */
- uri = tp_connection_get_balance_uri (conn);
-
- g_object_set_data_full (G_OBJECT (action), "manage-credit-uri",
- g_strdup (uri), g_free);
- gtk_action_set_sensitive (GTK_ACTION (action), !tp_str_empty (uri));
-
- main_window_balance_update_balance (GTK_ACTION (action), conn);
-
- g_signal_connect (conn, "balance-changed",
- G_CALLBACK (main_window_balance_changed_cb), action);
-
-}
-
-static void
-main_window_remove_balance_action (EmpathyMainWindow *window,
- TpAccount *account)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkAction *action;
- char *name;
- GList *a;
-
- if (priv->balance_action_group == NULL)
- return;
-
- name = main_window_account_to_action_name (account);
-
- action = gtk_action_group_get_action (
- priv->balance_action_group, name);
-
- if (action != NULL) {
- guint merge_id;
-
- DEBUG ("Removing action");
-
- merge_id = GPOINTER_TO_UINT (g_object_get_data (
- G_OBJECT (action),
- "merge-id"));
-
- gtk_ui_manager_remove_ui (priv->ui_manager,
- merge_id);
- gtk_action_group_remove_action (
- priv->balance_action_group, action);
- }
-
- g_free (name);
-
- a = gtk_action_group_list_actions (
- priv->balance_action_group);
-
- gtk_action_set_visible (
- priv->view_balance_show_in_roster,
- g_list_length (a) > 0);
-
- g_list_free (a);
-}
-
-static void
-main_window_connection_changed_cb (TpAccount *account,
- guint old_status,
- guint current,
- guint reason,
- gchar *dbus_error_name,
- GHashTable *details,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- main_window_update_status (window);
-
- if (current == TP_CONNECTION_STATUS_DISCONNECTED &&
- reason != TP_CONNECTION_STATUS_REASON_REQUESTED) {
- main_window_error_display (window, account);
- }
-
- if (current == TP_CONNECTION_STATUS_DISCONNECTED) {
- empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (window),
- EMPATHY_SOUND_ACCOUNT_DISCONNECTED);
-
- /* remove balance action if required */
- main_window_remove_balance_action (window, account);
- }
-
- if (current == TP_CONNECTION_STATUS_CONNECTED) {
- empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (window),
- EMPATHY_SOUND_ACCOUNT_CONNECTED);
-
- /* Account connected without error, remove error message if any */
- main_window_remove_error (window, account);
- main_window_setup_balance (window, account);
- }
-}
-
-static void
-main_window_accels_load (void)
-{
- gchar *filename;
-
- filename = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, ACCELS_FILENAME, NULL);
- if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
- DEBUG ("Loading from:'%s'", filename);
- gtk_accel_map_load (filename);
- }
-
- g_free (filename);
-}
-
-static void
-main_window_accels_save (void)
-{
- gchar *dir;
- gchar *file_with_path;
-
- dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
- g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
- file_with_path = g_build_filename (dir, ACCELS_FILENAME, NULL);
- g_free (dir);
-
- DEBUG ("Saving to:'%s'", file_with_path);
- gtk_accel_map_save (file_with_path);
-
- g_free (file_with_path);
-}
-
-static void
-empathy_main_window_finalize (GObject *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GHashTableIter iter;
- gpointer key, value;
-
- /* Save user-defined accelerators. */
- main_window_accels_save ();
-
- g_list_free (priv->actions_connected);
-
- g_object_unref (priv->account_manager);
- g_object_unref (priv->individual_store);
- g_object_unref (priv->contact_manager);
- g_object_unref (priv->sound_mgr);
- g_hash_table_unref (priv->errors);
- g_hash_table_unref (priv->auths);
-
- /* disconnect all handlers of status-changed signal */
- g_hash_table_iter_init (&iter, priv->status_changed_handlers);
- while (g_hash_table_iter_next (&iter, &key, &value))
- g_signal_handler_disconnect (TP_ACCOUNT (key),
- GPOINTER_TO_UINT (value));
-
- g_hash_table_unref (priv->status_changed_handlers);
-
- g_signal_handlers_disconnect_by_func (priv->event_manager,
- main_window_event_added_cb,
- window);
- g_signal_handlers_disconnect_by_func (priv->event_manager,
- main_window_event_removed_cb,
- window);
- g_object_unref (priv->call_observer);
- g_object_unref (priv->event_manager);
- g_object_unref (priv->ui_manager);
- g_object_unref (priv->chatroom_manager);
-
- g_object_unref (priv->gsettings_ui);
- g_object_unref (priv->gsettings_contacts);
-
- G_OBJECT_CLASS (empathy_main_window_parent_class)->finalize (window);
-}
-
-static gboolean
-main_window_key_press_event_cb (GtkWidget *window,
- GdkEventKey *event,
- gpointer user_data)
-{
- if (event->keyval == GDK_KEY_T
- && event->state & GDK_SHIFT_MASK
- && event->state & GDK_CONTROL_MASK) {
- empathy_chat_manager_call_undo_closed_chat ();
- }
- return FALSE;
-}
-
-static void
-main_window_chat_quit_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- gtk_widget_destroy (GTK_WIDGET (window));
-}
-
-static void
-main_window_view_history_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_log_window_show (NULL, NULL, FALSE, GTK_WINDOW (window));
-}
-
-static void
-main_window_chat_new_message_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_new_message_dialog_show (GTK_WINDOW (window));
-}
-
-static void
-main_window_chat_new_call_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_new_call_dialog_show (GTK_WINDOW (window));
-}
-
-static void
-main_window_chat_add_contact_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_new_individual_dialog_show (GTK_WINDOW (window));
-}
-
-static void
-main_window_chat_search_contacts_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- GtkWidget *dialog = empathy_contact_search_dialog_new (
- GTK_WINDOW (window));
- gtk_widget_show (dialog);
-}
-
-static void
-main_window_view_show_ft_manager (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_ft_manager_show ();
-}
-
-static void
-main_window_view_show_offline_cb (GtkToggleAction *action,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- gboolean current;
-
- current = gtk_toggle_action_get_active (action);
- g_settings_set_boolean (priv->gsettings_ui,
- EMPATHY_PREFS_UI_SHOW_OFFLINE,
- current);
-
- empathy_individual_view_set_show_offline (priv->individual_view,
- current);
-}
-
-static void
-main_window_notify_sort_contact_cb (GSettings *gsettings,
- const gchar *key,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- gchar *str;
-
- str = g_settings_get_string (gsettings, key);
-
- if (str != NULL) {
- GType type;
- GEnumClass *enum_class;
- GEnumValue *enum_value;
-
- type = empathy_individual_store_sort_get_type ();
- enum_class = G_ENUM_CLASS (g_type_class_peek (type));
- enum_value = g_enum_get_value_by_nick (enum_class, str);
- if (enum_value) {
- /* By changing the value of the GtkRadioAction,
- it emits a signal that calls main_window_view_sort_contacts_cb
- which updates the contacts list */
- gtk_radio_action_set_current_value (priv->sort_by_name,
- enum_value->value);
- } else {
- g_warning ("Wrong value for sort_criterium configuration : %s", str);
- }
- g_free (str);
- }
-}
-
-static void
-main_window_view_sort_contacts_cb (GtkRadioAction *action,
- GtkRadioAction *current,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- EmpathyIndividualStoreSort value;
- GSList *group;
- GType type;
- GEnumClass *enum_class;
- GEnumValue *enum_value;
-
- value = gtk_radio_action_get_current_value (action);
- group = gtk_radio_action_get_group (action);
-
- /* Get string from index */
- type = empathy_individual_store_sort_get_type ();
- enum_class = G_ENUM_CLASS (g_type_class_peek (type));
- enum_value = g_enum_get_value (enum_class, g_slist_index (group, current));
-
- if (!enum_value) {
- g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioAction index:%d",
- g_slist_index (group, action));
- } else {
- g_settings_set_string (priv->gsettings_contacts,
- EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM,
- enum_value->value_nick);
- }
- empathy_individual_store_set_sort_criterium (priv->individual_store,
- value);
-}
-
-static void
-main_window_view_show_protocols_cb (GtkToggleAction *action,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- gboolean value;
-
- value = gtk_toggle_action_get_active (action);
-
- g_settings_set_boolean (priv->gsettings_ui,
- EMPATHY_PREFS_UI_SHOW_PROTOCOLS,
- value);
- empathy_individual_store_set_show_protocols (priv->individual_store,
- value);
-}
-
-/* Matches GtkRadioAction values set in empathy-main-window.ui */
-#define CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS 0
-#define CONTACT_LIST_NORMAL_SIZE 1
-#define CONTACT_LIST_COMPACT_SIZE 2
-
-static void
-main_window_view_contacts_list_size_cb (GtkRadioAction *action,
- GtkRadioAction *current,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GSettings *gsettings_ui;
- gint value;
-
- value = gtk_radio_action_get_current_value (action);
- /* create a new GSettings, so we can delay the setting until both
- * values are set */
- gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
-
- DEBUG ("radio button toggled, value = %i", value);
-
- g_settings_delay (gsettings_ui);
- g_settings_set_boolean (gsettings_ui,
- EMPATHY_PREFS_UI_SHOW_AVATARS,
- value == CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS);
-
- g_settings_set_boolean (gsettings_ui,
- EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST,
- value == CONTACT_LIST_COMPACT_SIZE);
- g_settings_apply (gsettings_ui);
-
- /* FIXME: these enums probably have the wrong namespace */
- empathy_individual_store_set_show_avatars (priv->individual_store,
- value == CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS);
- empathy_individual_store_set_is_compact (priv->individual_store,
- value == CONTACT_LIST_COMPACT_SIZE);
-
- g_object_unref (gsettings_ui);
-}
-
-static void main_window_notify_show_protocols_cb (GSettings *gsettings,
- const gchar *key,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- gtk_toggle_action_set_active (priv->show_protocols,
- g_settings_get_boolean (gsettings,
- EMPATHY_PREFS_UI_SHOW_PROTOCOLS));
-}
-
-
-static void
-main_window_notify_contact_list_size_cb (GSettings *gsettings,
- const gchar *key,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- gint value;
-
- if (g_settings_get_boolean (gsettings,
- EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST)) {
- value = CONTACT_LIST_COMPACT_SIZE;
- } else if (g_settings_get_boolean (gsettings,
- EMPATHY_PREFS_UI_SHOW_AVATARS)) {
- value = CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS;
- } else {
- value = CONTACT_LIST_NORMAL_SIZE;
- }
-
- DEBUG ("setting changed, value = %i", value);
-
- /* By changing the value of the GtkRadioAction,
- it emits a signal that calls main_window_view_contacts_list_size_cb
- which updates the contacts list */
- gtk_radio_action_set_current_value (priv->normal_with_avatars, value);
-}
-
-static void
-main_window_edit_search_contacts_cb (GtkCheckMenuItem *item,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- empathy_individual_view_start_search (priv->individual_view);
-}
-
-static void
-main_window_view_show_map_cb (GtkCheckMenuItem *item,
- EmpathyMainWindow *window)
-{
-#ifdef HAVE_LIBCHAMPLAIN
- empathy_map_view_show ();
-#endif
-}
-
-static void
-join_chatroom (EmpathyChatroom *chatroom,
- gint64 timestamp)
-{
- TpAccount *account;
- const gchar *room;
-
- account = empathy_chatroom_get_account (chatroom);
- room = empathy_chatroom_get_room (chatroom);
-
- DEBUG ("Requesting channel for '%s'", room);
- empathy_join_muc (account, room, timestamp);
-}
-
-typedef struct
-{
- TpAccount *account;
- EmpathyChatroom *chatroom;
- gint64 timestamp;
- glong sig_id;
- guint timeout;
-} join_fav_account_sig_ctx;
-
-static join_fav_account_sig_ctx *
-join_fav_account_sig_ctx_new (TpAccount *account,
- EmpathyChatroom *chatroom,
- gint64 timestamp)
-{
- join_fav_account_sig_ctx *ctx = g_slice_new0 (
- join_fav_account_sig_ctx);
-
- ctx->account = g_object_ref (account);
- ctx->chatroom = g_object_ref (chatroom);
- ctx->timestamp = timestamp;
- return ctx;
-}
-
-static void
-join_fav_account_sig_ctx_free (join_fav_account_sig_ctx *ctx)
-{
- g_object_unref (ctx->account);
- g_object_unref (ctx->chatroom);
- g_slice_free (join_fav_account_sig_ctx, ctx);
-}
-
-static void
-account_status_changed_cb (TpAccount *account,
- TpConnectionStatus old_status,
- TpConnectionStatus new_status,
- guint reason,
- gchar *dbus_error_name,
- GHashTable *details,
- gpointer user_data)
-{
- join_fav_account_sig_ctx *ctx = user_data;
-
- switch (new_status) {
- case TP_CONNECTION_STATUS_DISCONNECTED:
- /* Don't wait any longer */
- goto finally;
- break;
-
- case TP_CONNECTION_STATUS_CONNECTING:
- /* Wait a bit */
- return;
-
- case TP_CONNECTION_STATUS_CONNECTED:
- /* We can join the room */
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- join_chatroom (ctx->chatroom, ctx->timestamp);
-
-finally:
- g_source_remove (ctx->timeout);
- g_signal_handler_disconnect (account, ctx->sig_id);
-}
-
-#define JOIN_FAVORITE_TIMEOUT 5
-
-static gboolean
-join_favorite_timeout_cb (gpointer data)
-{
- join_fav_account_sig_ctx *ctx = data;
-
- /* stop waiting for joining the favorite room */
- g_signal_handler_disconnect (ctx->account, ctx->sig_id);
- return FALSE;
-}
-
-static void
-main_window_favorite_chatroom_join (EmpathyChatroom *chatroom)
-{
- TpAccount *account;
-
- account = empathy_chatroom_get_account (chatroom);
- if (tp_account_get_connection_status (account, NULL) !=
- TP_CONNECTION_STATUS_CONNECTED) {
- join_fav_account_sig_ctx *ctx;
-
- ctx = join_fav_account_sig_ctx_new (account, chatroom,
- empathy_get_current_action_time ());
-
- ctx->sig_id = g_signal_connect_data (account, "status-changed",
- G_CALLBACK (account_status_changed_cb), ctx,
- (GClosureNotify) join_fav_account_sig_ctx_free, 0);
-
- ctx->timeout = g_timeout_add_seconds (JOIN_FAVORITE_TIMEOUT,
- join_favorite_timeout_cb, ctx);
- return;
- }
-
- join_chatroom (chatroom, empathy_get_current_action_time ());
-}
-
-static void
-main_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item,
- EmpathyChatroom *chatroom)
-{
- main_window_favorite_chatroom_join (chatroom);
-}
-
-static void
-main_window_favorite_chatroom_menu_add (EmpathyMainWindow *window,
- EmpathyChatroom *chatroom)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *menu_item;
- const gchar *name, *account_name;
- gchar *label;
-
-
- if (g_object_get_data (G_OBJECT (chatroom), "menu_item")) {
- return;
- }
-
- name = empathy_chatroom_get_name (chatroom);
- account_name = tp_account_get_display_name (
- empathy_chatroom_get_account (chatroom));
- label = g_strdup_printf ("%s (%s)", name, account_name);
- menu_item = gtk_menu_item_new_with_label (label);
- g_free (label);
- g_object_set_data (G_OBJECT (menu_item), "is_favorite",
- GUINT_TO_POINTER (TRUE));
-
- g_object_set_data (G_OBJECT (chatroom), "menu_item", menu_item);
- g_signal_connect (menu_item, "activate",
- G_CALLBACK (main_window_favorite_chatroom_menu_activate_cb),
- chatroom);
-
- gtk_menu_shell_insert (GTK_MENU_SHELL (priv->room_menu),
- menu_item, 4);
-
- gtk_widget_show (menu_item);
-}
-
-static void
-main_window_favorite_chatroom_menu_added_cb (EmpathyChatroomManager *manager,
- EmpathyChatroom *chatroom,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- main_window_favorite_chatroom_menu_add (window, chatroom);
- gtk_widget_show (priv->room_separator);
- gtk_action_set_sensitive (priv->room_join_favorites, TRUE);
-}
-
-static void
-main_window_favorite_chatroom_menu_removed_cb (EmpathyChatroomManager *manager,
- EmpathyChatroom *chatroom,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *menu_item;
- GList *chatrooms;
-
- menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
- g_object_set_data (G_OBJECT (chatroom), "menu_item", NULL);
- gtk_widget_destroy (menu_item);
-
- chatrooms = empathy_chatroom_manager_get_chatrooms (priv->chatroom_manager, NULL);
- if (chatrooms) {
- gtk_widget_show (priv->room_separator);
- } else {
- gtk_widget_hide (priv->room_separator);
- }
-
- gtk_action_set_sensitive (priv->room_join_favorites, chatrooms != NULL);
- g_list_free (chatrooms);
-}
-
-static void
-main_window_favorite_chatroom_menu_setup (EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GList *chatrooms, *l;
- GtkWidget *room;
-
- priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
- chatrooms = empathy_chatroom_manager_get_chatrooms (
- priv->chatroom_manager, NULL);
- room = gtk_ui_manager_get_widget (priv->ui_manager,
- "/menubar/room");
- priv->room_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (room));
- priv->room_separator = gtk_ui_manager_get_widget (priv->ui_manager,
- "/menubar/room/room_separator");
-
- for (l = chatrooms; l; l = l->next) {
- main_window_favorite_chatroom_menu_add (window, l->data);
- }
-
- if (!chatrooms) {
- gtk_widget_hide (priv->room_separator);
- }
-
- gtk_action_set_sensitive (priv->room_join_favorites, chatrooms != NULL);
-
- g_signal_connect (priv->chatroom_manager, "chatroom-added",
- G_CALLBACK (main_window_favorite_chatroom_menu_added_cb),
- window);
- g_signal_connect (priv->chatroom_manager, "chatroom-removed",
- G_CALLBACK (main_window_favorite_chatroom_menu_removed_cb),
- window);
-
- g_list_free (chatrooms);
-}
-
-static void
-main_window_room_join_new_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_new_chatroom_dialog_show (GTK_WINDOW (window));
-}
-
-static void
-main_window_room_join_favorites_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GList *chatrooms, *l;
-
- chatrooms = empathy_chatroom_manager_get_chatrooms (priv->chatroom_manager, NULL);
- for (l = chatrooms; l; l = l->next) {
- main_window_favorite_chatroom_join (l->data);
- }
- g_list_free (chatrooms);
-}
-
-static void
-main_window_room_manage_favorites_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_chatrooms_window_show (GTK_WINDOW (window));
-}
-
-static void
-main_window_edit_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GtkWidget *submenu;
-
- /* FIXME: It should use the UIManager to merge the contact/group submenu */
- submenu = empathy_individual_view_get_individual_menu (
- priv->individual_view);
- if (submenu) {
- GtkMenuItem *item;
- GtkWidget *label;
-
- item = GTK_MENU_ITEM (priv->edit_context);
- label = gtk_bin_get_child (GTK_BIN (item));
- gtk_label_set_text (GTK_LABEL (label), _("Contact"));
-
- gtk_widget_show (priv->edit_context);
- gtk_widget_show (priv->edit_context_separator);
-
- gtk_menu_item_set_submenu (item, submenu);
-
- return;
- }
-
- submenu = empathy_individual_view_get_group_menu (
- priv->individual_view);
- if (submenu) {
- GtkMenuItem *item;
- GtkWidget *label;
-
- item = GTK_MENU_ITEM (priv->edit_context);
- label = gtk_bin_get_child (GTK_BIN (item));
- gtk_label_set_text (GTK_LABEL (label), _("Group"));
-
- gtk_widget_show (priv->edit_context);
- gtk_widget_show (priv->edit_context_separator);
-
- gtk_menu_item_set_submenu (item, submenu);
-
- return;
- }
-
- gtk_widget_hide (priv->edit_context);
- gtk_widget_hide (priv->edit_context_separator);
-
- return;
-}
-
-static void
-main_window_edit_accounts_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_accounts_dialog_show_application (gdk_screen_get_default (),
- NULL, FALSE, FALSE);
-}
-
-static void
-main_window_edit_personal_information_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_contact_personal_dialog_show (GTK_WINDOW (window));
-}
-
-static void
-main_window_edit_blocked_contacts_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- GtkWidget *dialog;
-
- dialog = empathy_contact_blocking_dialog_new (GTK_WINDOW (window));
- gtk_widget_show (dialog);
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
-}
-
-void
-empathy_main_window_show_preferences (EmpathyMainWindow *window,
- const gchar *tab)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- if (priv->preferences == NULL) {
- priv->preferences = empathy_preferences_new (GTK_WINDOW (window),
- priv->shell_running);
- g_object_add_weak_pointer (G_OBJECT (priv->preferences),
- (gpointer) &priv->preferences);
-
- gtk_widget_show (priv->preferences);
- } else {
- gtk_window_present (GTK_WINDOW (priv->preferences));
- }
-
- if (tab != NULL)
- empathy_preferences_show_tab (
- EMPATHY_PREFERENCES (priv->preferences), tab);
-}
-
-static void
-main_window_edit_preferences_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_main_window_show_preferences (window, NULL);
-}
-
-static void
-main_window_help_about_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_about_dialog_new (GTK_WINDOW (window));
-}
-
-static void
-main_window_help_debug_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_launch_program (BIN_DIR, "empathy-debugger", NULL);
-}
-
-static void
-main_window_help_contents_cb (GtkAction *action,
- EmpathyMainWindow *window)
-{
- empathy_url_show (GTK_WIDGET (window), "ghelp:empathy");
-}
-
-static gboolean
-main_window_throbber_button_press_event_cb (GtkWidget *throbber,
- GdkEventButton *event,
- EmpathyMainWindow *window)
-{
- if (event->type != GDK_BUTTON_PRESS ||
- event->button != 1) {
- return FALSE;
- }
-
- empathy_accounts_dialog_show_application (
- gtk_widget_get_screen (GTK_WIDGET (throbber)),
- NULL, FALSE, FALSE);
-
- return FALSE;
-}
-
-static void
-main_window_account_removed_cb (TpAccountManager *manager,
- TpAccount *account,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GList *a;
-
- a = tp_account_manager_get_valid_accounts (manager);
-
- gtk_action_set_sensitive (priv->view_history,
- g_list_length (a) > 0);
-
- g_list_free (a);
-
- /* remove errors if any */
- main_window_remove_error (window, account);
-
- /* remove the balance action if required */
- main_window_remove_balance_action (window, account);
-}
-
-static void
-main_window_account_validity_changed_cb (TpAccountManager *manager,
- TpAccount *account,
- gboolean valid,
- EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- if (valid) {
- gulong handler_id;
- handler_id = GPOINTER_TO_UINT (g_hash_table_lookup (
- priv->status_changed_handlers, account));
-
- /* connect signal only if it was not connected yet */
- if (handler_id == 0) {
- handler_id = g_signal_connect (account,
- "status-changed",
- G_CALLBACK (main_window_connection_changed_cb),
- window);
- g_hash_table_insert (priv->status_changed_handlers,
- account, GUINT_TO_POINTER (handler_id));
- }
- }
-
- main_window_account_removed_cb (manager, account, window);
-}
-
-static void
-main_window_notify_show_offline_cb (GSettings *gsettings,
- const gchar *key,
- gpointer toggle_action)
-{
- gtk_toggle_action_set_active (toggle_action,
- g_settings_get_boolean (gsettings, key));
-}
-
-static void
-main_window_connection_items_setup (EmpathyMainWindow *window,
- GtkBuilder *gui)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GList *list;
- GObject *action;
- guint i;
- const gchar *actions_connected[] = {
- "room_join_new",
- "room_join_favorites",
- "chat_new_message",
- "chat_new_call",
- "chat_search_contacts",
- "chat_add_contact",
- "edit_personal_information",
- "edit_blocked_contacts",
- "edit_search_contacts"
- };
-
- for (i = 0, list = NULL; i < G_N_ELEMENTS (actions_connected); i++) {
- action = gtk_builder_get_object (gui, actions_connected[i]);
- list = g_list_prepend (list, action);
- }
-
- priv->actions_connected = list;
-}
-
-static void
-account_manager_prepared_cb (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GList *accounts, *j;
- TpAccountManager *manager = TP_ACCOUNT_MANAGER (source_object);
- EmpathyMainWindow *window = user_data;
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
- GError *error = NULL;
-
- if (!tp_proxy_prepare_finish (manager, result, &error)) {
- DEBUG ("Failed to prepare account manager: %s", error->message);
- g_error_free (error);
- return;
- }
-
- accounts = tp_account_manager_get_valid_accounts (priv->account_manager);
- for (j = accounts; j != NULL; j = j->next) {
- TpAccount *account = TP_ACCOUNT (j->data);
- gulong handler_id;
-
- handler_id = g_signal_connect (account, "status-changed",
- G_CALLBACK (main_window_connection_changed_cb),
- window);
- g_hash_table_insert (priv->status_changed_handlers,
- account, GUINT_TO_POINTER (handler_id));
-
- main_window_setup_balance (window, account);
- }
-
- g_signal_connect (manager, "account-validity-changed",
- G_CALLBACK (main_window_account_validity_changed_cb),
- window);
-
- main_window_update_status (window);
-
- /* Disable the "Previous Conversations" menu entry if there is no account */
- gtk_action_set_sensitive (priv->view_history,
- g_list_length (accounts) > 0);
-
- g_list_free (accounts);
-}
-
-void
-empathy_main_window_set_shell_running (EmpathyMainWindow *window,
- gboolean shell_running)
-{
- EmpathyMainWindowPriv *priv = GET_PRIV (window);
-
- if (priv->shell_running == shell_running)
- return;
-
- priv->shell_running = shell_running;
- g_object_notify (G_OBJECT (window), "shell-running");
-}
-
-static GObject *
-empathy_main_window_constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- static GObject *window = NULL;
-
- if (window != NULL)
- return g_object_ref (window);
-
- window = G_OBJECT_CLASS (empathy_main_window_parent_class)->constructor (
- type, n_construct_params, construct_params);
-
- g_object_add_weak_pointer (window, (gpointer) &window);
-
- return window;
-}
-
-static void
-empathy_main_window_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EmpathyMainWindow *self = EMPATHY_MAIN_WINDOW (object);
- EmpathyMainWindowPriv *priv = GET_PRIV (self);
-
- switch (property_id)
- {
- case PROP_SHELL_RUNNING:
- priv->shell_running = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-empathy_main_window_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EmpathyMainWindow *self = EMPATHY_MAIN_WINDOW (object);
- EmpathyMainWindowPriv *priv = GET_PRIV (self);
-
- switch (property_id)
- {
- case PROP_SHELL_RUNNING:
- g_value_set_boolean (value, priv->shell_running);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-empathy_main_window_class_init (EmpathyMainWindowClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *pspec;
-
- object_class->finalize = empathy_main_window_finalize;
- object_class->constructor = empathy_main_window_constructor;
-
- object_class->set_property = empathy_main_window_set_property;
- object_class->get_property = empathy_main_window_get_property;
-
- pspec = g_param_spec_boolean ("shell-running",
- "Shell running",
- "Whether the Shell is running or not",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SHELL_RUNNING, pspec);
-
- g_type_class_add_private (object_class, sizeof (EmpathyMainWindowPriv));
-}
-
-static void
-empathy_main_window_init (EmpathyMainWindow *window)
-{
- EmpathyMainWindowPriv *priv;
- EmpathyIndividualManager *individual_manager;
- GtkBuilder *gui, *gui_mgr;
- GtkWidget *sw;
- GtkToggleAction *show_offline_widget;
- GtkAction *show_map_widget;
- GtkToolItem *item;
- gboolean show_offline;
- gchar *filename;
- GtkTreeModel *model;
- GtkWidget *search_vbox;
- GtkWidget *menubar;
-
- priv = window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
- EMPATHY_TYPE_MAIN_WINDOW, EmpathyMainWindowPriv);
-
- priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
- priv->gsettings_contacts = g_settings_new (EMPATHY_PREFS_CONTACTS_SCHEMA);
-
- priv->sound_mgr = empathy_sound_manager_dup_singleton ();
-
- gtk_window_set_title (GTK_WINDOW (window), _("Contact List"));
- gtk_window_set_role (GTK_WINDOW (window), "contact_list");
- gtk_window_set_default_size (GTK_WINDOW (window), 225, 325);
-
- /* don't finalize the widget on delete-event, just hide it */
- g_signal_connect (window, "delete-event",
- G_CALLBACK (gtk_widget_hide_on_delete), NULL);
-
- /* Set up interface */
- filename = empathy_file_lookup ("empathy-main-window.ui", "src");
- gui = empathy_builder_get_file (filename,
- "main_vbox", &priv->main_vbox,
- "balance_vbox", &priv->balance_vbox,
- "errors_vbox", &priv->errors_vbox,
- "auth_vbox", &priv->auth_vbox,
- "search_vbox", &search_vbox,
- "presence_toolbar", &priv->presence_toolbar,
- "notebook", &priv->notebook,
- "no_entry_label", &priv->no_entry_label,
- "roster_scrolledwindow", &sw,
- NULL);
- g_free (filename);
-
- /* Set UI manager */
- filename = empathy_file_lookup ("empathy-main-window-menubar.ui", "src");
- gui_mgr = empathy_builder_get_file (filename,
- "ui_manager", &priv->ui_manager,
- "view_show_offline", &show_offline_widget,
- "view_show_protocols", &priv->show_protocols,
- "view_sort_by_name", &priv->sort_by_name,
- "view_sort_by_status", &priv->sort_by_status,
- "view_normal_size_with_avatars", &priv->normal_with_avatars,
- "view_normal_size", &priv->normal_size,
- "view_compact_size", &priv->compact_size,
- "view_history", &priv->view_history,
- "view_show_map", &show_map_widget,
- "room_join_favorites", &priv->room_join_favorites,
- "view_balance_show_in_roster", &priv->view_balance_show_in_roster,
- "menubar", &menubar,
- NULL);
- g_free (filename);
-
- /* The UI manager is living in its own .ui file as Glade doesn't support
- * those. The GtkMenubar has to be in this file as well to we manually add
- * it to the first position of the vbox. */
- gtk_box_pack_start (GTK_BOX (priv->main_vbox), menubar, FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (priv->main_vbox), menubar, 0);
-
- gtk_container_add (GTK_CONTAINER (window), priv->main_vbox);
- gtk_widget_show (priv->main_vbox);
-
- g_signal_connect (window, "key-press-event",
- G_CALLBACK (main_window_key_press_event_cb), NULL);
-
- empathy_builder_connect (gui_mgr, window,
- "chat_quit", "activate", main_window_chat_quit_cb,
- "chat_new_message", "activate", main_window_chat_new_message_cb,
- "chat_new_call", "activate", main_window_chat_new_call_cb,
- "view_history", "activate", main_window_view_history_cb,
- "room_join_new", "activate", main_window_room_join_new_cb,
- "room_join_favorites", "activate", main_window_room_join_favorites_cb,
- "room_manage_favorites", "activate", main_window_room_manage_favorites_cb,
- "chat_add_contact", "activate", main_window_chat_add_contact_cb,
- "chat_search_contacts", "activate", main_window_chat_search_contacts_cb,
- "view_show_ft_manager", "activate", main_window_view_show_ft_manager,
- "view_show_offline", "toggled", main_window_view_show_offline_cb,
- "view_show_protocols", "toggled", main_window_view_show_protocols_cb,
- "view_sort_by_name", "changed", main_window_view_sort_contacts_cb,
- "view_normal_size_with_avatars", "changed", main_window_view_contacts_list_size_cb,
- "view_show_map", "activate", main_window_view_show_map_cb,
- "edit", "activate", main_window_edit_cb,
- "edit_accounts", "activate", main_window_edit_accounts_cb,
- "edit_personal_information", "activate", main_window_edit_personal_information_cb,
- "edit_blocked_contacts", "activate", main_window_edit_blocked_contacts_cb,
- "edit_preferences", "activate", main_window_edit_preferences_cb,
- "edit_search_contacts", "activate", main_window_edit_search_contacts_cb,
- "help_about", "activate", main_window_help_about_cb,
- "help_debug", "activate", main_window_help_debug_cb,
- "help_contents", "activate", main_window_help_contents_cb,
- NULL);
-
- /* Set up connection related widgets. */
- main_window_connection_items_setup (window, gui_mgr);
-
- g_object_ref (priv->ui_manager);
- g_object_unref (gui);
- g_object_unref (gui_mgr);
-
-#ifndef HAVE_LIBCHAMPLAIN
- gtk_action_set_visible (show_map_widget, FALSE);
-#endif
-
- priv->account_manager = tp_account_manager_dup ();
-
- tp_proxy_prepare_async (priv->account_manager, NULL,
- account_manager_prepared_cb, window);
-
- priv->errors = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- g_object_unref,
- NULL);
-
- priv->auths = g_hash_table_new (NULL, NULL);
-
- priv->status_changed_handlers = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- NULL);
-
- /* Set up menu */
- main_window_favorite_chatroom_menu_setup (window);
-
- priv->edit_context = gtk_ui_manager_get_widget (priv->ui_manager,
- "/menubar/edit/edit_context");
- priv->edit_context_separator = gtk_ui_manager_get_widget (
- priv->ui_manager,
- "/menubar/edit/edit_context_separator");
- gtk_widget_hide (priv->edit_context);
- gtk_widget_hide (priv->edit_context_separator);
-
- /* Set up contact list. */
- empathy_status_presets_get_all ();
-
- /* Set up presence chooser */
- priv->presence_chooser = empathy_presence_chooser_new ();
- gtk_widget_show (priv->presence_chooser);
- item = gtk_tool_item_new ();
- gtk_widget_show (GTK_WIDGET (item));
- gtk_widget_set_size_request (priv->presence_chooser, 10, -1);
- gtk_container_add (GTK_CONTAINER (item), priv->presence_chooser);
- gtk_tool_item_set_is_important (item, TRUE);
- gtk_tool_item_set_expand (item, TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->presence_toolbar), item, -1);
-
- /* Set up the throbber */
- priv->throbber = gtk_spinner_new ();
- gtk_widget_set_size_request (priv->throbber, 16, -1);
- gtk_widget_set_events (priv->throbber, GDK_BUTTON_PRESS_MASK);
- g_signal_connect (priv->throbber, "button-press-event",
- G_CALLBACK (main_window_throbber_button_press_event_cb),
- window);
- gtk_widget_show (priv->throbber);
-
- item = gtk_tool_item_new ();
- gtk_container_set_border_width (GTK_CONTAINER (item), 6);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->presence_toolbar), item, -1);
- gtk_container_add (GTK_CONTAINER (item), priv->throbber);
- priv->throbber_tool_item = GTK_WIDGET (item);
-
- /* XXX: this class is designed to live for the duration of the program,
- * so it's got a race condition between its signal handlers and its
- * finalization. The class is planned to be removed, so we won't fix
- * this before then. */
- priv->contact_manager = EMPATHY_CONTACT_LIST (
- empathy_contact_manager_dup_singleton ());
- individual_manager = empathy_individual_manager_dup_singleton ();
- priv->individual_store = EMPATHY_INDIVIDUAL_STORE (
- empathy_individual_store_manager_new (individual_manager));
- g_object_unref (individual_manager);
-
- /* For the moment, we disallow Persona drops onto the main contact list (e.g. from things such as
- * the EmpathyPersonaView in the linking dialogue). No code is hooked up to do anything on a Persona
- * drop, so allowing them would achieve nothing except confusion. */
- priv->individual_view = empathy_individual_view_new (
- priv->individual_store,
- EMPATHY_INDIVIDUAL_VIEW_FEATURE_ALL ^ EMPATHY_INDIVIDUAL_VIEW_FEATURE_PERSONA_DROP,
- EMPATHY_INDIVIDUAL_FEATURE_ALL ^ EMPATHY_INDIVIDUAL_FEATURE_ADD_CONTACT);
-
- gtk_widget_show (GTK_WIDGET (priv->individual_view));
- gtk_container_add (GTK_CONTAINER (sw),
- GTK_WIDGET (priv->individual_view));
- g_signal_connect (priv->individual_view, "row-activated",
- G_CALLBACK (main_window_row_activated_cb),
- window);
-
- /* Set up search bar */
- priv->search_bar = empathy_live_search_new (
- GTK_WIDGET (priv->individual_view));
- empathy_individual_view_set_live_search (priv->individual_view,
- EMPATHY_LIVE_SEARCH (priv->search_bar));
- gtk_box_pack_start (GTK_BOX (search_vbox), priv->search_bar,
- FALSE, TRUE, 0);
-
- g_signal_connect_swapped (window, "map",
- G_CALLBACK (gtk_widget_grab_focus), priv->individual_view);
-
- /* Connect to proper signals to check if contact list is empty or not */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->individual_view));
- priv->empty = TRUE;
- g_signal_connect (model, "row-inserted",
- G_CALLBACK (main_window_row_inserted_cb),
- window);
- g_signal_connect (model, "row-deleted",
- G_CALLBACK (main_window_row_deleted_cb),
- window);
-
- /* Load user-defined accelerators. */
- main_window_accels_load ();
-
- /* Set window size. */
- empathy_geometry_bind (GTK_WINDOW (window), GEOMETRY_NAME);
-
- /* bind view_balance_show_in_roster */
- g_settings_bind (priv->gsettings_ui, "show-balance-in-roster",
- priv->view_balance_show_in_roster, "active",
- G_SETTINGS_BIND_DEFAULT);
- g_object_bind_property (priv->view_balance_show_in_roster, "active",
- priv->balance_vbox, "visible",
- G_BINDING_SYNC_CREATE);
-
- /* Enable event handling */
- priv->call_observer = empathy_call_observer_dup_singleton ();
- priv->event_manager = empathy_event_manager_dup_singleton ();
-
- g_signal_connect (priv->event_manager, "event-added",
- G_CALLBACK (main_window_event_added_cb), window);
- g_signal_connect (priv->event_manager, "event-removed",
- G_CALLBACK (main_window_event_removed_cb), window);
- g_signal_connect (priv->account_manager, "account-validity-changed",
- G_CALLBACK (main_window_account_validity_changed_cb),
- window);
- g_signal_connect (priv->account_manager, "account-removed",
- G_CALLBACK (main_window_account_removed_cb),
- window);
- g_signal_connect (priv->account_manager, "account-disabled",
- G_CALLBACK (main_window_account_disabled_cb),
- window);
-
- /* Show offline ? */
- show_offline = g_settings_get_boolean (priv->gsettings_ui,
- EMPATHY_PREFS_UI_SHOW_OFFLINE);
- g_signal_connect (priv->gsettings_ui,
- "changed::" EMPATHY_PREFS_UI_SHOW_OFFLINE,
- G_CALLBACK (main_window_notify_show_offline_cb),
- show_offline_widget);
-
- gtk_toggle_action_set_active (show_offline_widget, show_offline);
-
- /* Show protocol ? */
- g_signal_connect (priv->gsettings_ui,
- "changed::" EMPATHY_PREFS_UI_SHOW_PROTOCOLS,
- G_CALLBACK (main_window_notify_show_protocols_cb),
- window);
-
- main_window_notify_show_protocols_cb (priv->gsettings_ui,
- EMPATHY_PREFS_UI_SHOW_PROTOCOLS,
- window);
-
- /* Sort by name / by status ? */
- g_signal_connect (priv->gsettings_contacts,
- "changed::" EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM,
- G_CALLBACK (main_window_notify_sort_contact_cb),
- window);
-
- main_window_notify_sort_contact_cb (priv->gsettings_contacts,
- EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM,
- window);
-
- /* Contacts list size */
- g_signal_connect (priv->gsettings_ui,
- "changed::" EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST,
- G_CALLBACK (main_window_notify_contact_list_size_cb),
- window);
- g_signal_connect (priv->gsettings_ui,
- "changed::" EMPATHY_PREFS_UI_SHOW_AVATARS,
- G_CALLBACK (main_window_notify_contact_list_size_cb),
- window);
-
- main_window_notify_contact_list_size_cb (priv->gsettings_ui,
- EMPATHY_PREFS_UI_SHOW_AVATARS,
- window);
-}
-
-GtkWidget *
-empathy_main_window_dup (void)
-{
- return g_object_new (EMPATHY_TYPE_MAIN_WINDOW, NULL);
-}
diff --git a/src/empathy-main-window.h b/src/empathy-main-window.h
deleted file mode 100644
index af4c1924e..000000000
--- a/src/empathy-main-window.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2002-2007 Imendio AB
- * Copyright (C) 2007-2008 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: Xavier Claessens <xclaesse@gmail.com>
- * Danielle Madeley <danielle.madeley@collabora.co.uk>
- */
-
-#ifndef __EMPATHY_MAIN_WINDOW_H__
-#define __EMPATHY_MAIN_WINDOW_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define EMPATHY_TYPE_MAIN_WINDOW (empathy_main_window_get_type ())
-#define EMPATHY_MAIN_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_MAIN_WINDOW, EmpathyMainWindow))
-#define EMPATHY_MAIN_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_MAIN_WINDOW, EmpathyMainWindowClass))
-#define EMPATHY_IS_MAIN_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_MAIN_WINDOW))
-#define EMPATHY_IS_MAIN_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_MAIN_WINDOW))
-#define EMPATHY_MAIN_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_MAIN_WINDOW, EmpathyMainWindowClass))
-
-typedef struct _EmpathyMainWindow EmpathyMainWindow;
-typedef struct _EmpathyMainWindowClass EmpathyMainWindowClass;
-typedef struct _EmpathyMainWindowPriv EmpathyMainWindowPriv;
-
-struct _EmpathyMainWindow {
- GtkWindow parent;
- gpointer priv;
-};
-
-struct _EmpathyMainWindowClass {
- GtkWindowClass parent_class;
-};
-
-GType empathy_main_window_get_type (void);
-
-GtkWidget *empathy_main_window_dup (void);
-
-void empathy_main_window_show_preferences (EmpathyMainWindow *window,
- const gchar *tab);
-void empathy_main_window_set_shell_running (EmpathyMainWindow *window,
- gboolean shell_running);
-
-G_END_DECLS
-
-#endif /* __EMPATHY_MAIN_WINDOW_H__ */
diff --git a/src/empathy-map-view.c b/src/empathy-map-view.c
index 72aab0b2c..9ab82c091 100644
--- a/src/empathy-map-view.c
+++ b/src/empathy-map-view.c
@@ -31,11 +31,11 @@
#include <telepathy-glib/util.h>
#include <libempathy/empathy-contact.h>
-#include <libempathy/empathy-contact-manager.h>
+#include <libempathy/empathy-connection-aggregator.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-location.h>
-#include <libempathy-gtk/empathy-contact-menu.h>
+#include <libempathy-gtk/empathy-individual-menu.h>
#include <libempathy-gtk/empathy-ui-utils.h>
#include "empathy-map-view.h"
@@ -48,7 +48,7 @@ G_DEFINE_TYPE (EmpathyMapView, empathy_map_view, GTK_TYPE_WINDOW);
#define GET_PRIV(self) ((EmpathyMapViewPriv *)((EmpathyMapView *) self)->priv)
struct _EmpathyMapViewPriv {
- EmpathyContactList *contact_list;
+ EmpathyConnectionAggregator *aggregator;
GtkWidget *zoom_in;
GtkWidget *zoom_out;
@@ -59,6 +59,9 @@ struct _EmpathyMapViewPriv {
/* reffed (EmpathyContact *) => borrowed (ChamplainMarker *) */
GHashTable *markers;
gulong members_changed_id;
+
+ /* TpContact -> EmpathyContact */
+ GHashTable *contacts;
};
static void
@@ -189,28 +192,41 @@ marker_clicked_cb (ChamplainMarker *marker,
{
GtkWidget *menu;
EmpathyContact *contact;
+ TpContact *tp_contact;
+ FolksIndividual *individual;
if (event->button != 3)
return FALSE;
contact = g_object_get_data (G_OBJECT (marker), "contact");
+ if (contact == NULL)
+ return FALSE;
- menu = empathy_contact_menu_new (contact,
- EMPATHY_CONTACT_FEATURE_CHAT |
- EMPATHY_CONTACT_FEATURE_CALL |
- EMPATHY_CONTACT_FEATURE_LOG |
- EMPATHY_CONTACT_FEATURE_FT |
- EMPATHY_CONTACT_FEATURE_INFO);
+ tp_contact = empathy_contact_get_tp_contact (contact);
+ if (tp_contact == NULL)
+ return FALSE;
- if (menu == NULL)
+ individual = empathy_create_individual_from_tp_contact (tp_contact);
+ if (individual == NULL)
return FALSE;
+ menu = empathy_individual_menu_new (individual,
+ EMPATHY_INDIVIDUAL_FEATURE_CHAT |
+ EMPATHY_INDIVIDUAL_FEATURE_CALL |
+ EMPATHY_INDIVIDUAL_FEATURE_LOG |
+ EMPATHY_INDIVIDUAL_FEATURE_INFO, NULL);
+
+ if (menu == NULL)
+ goto out;
+
gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (self), NULL);
gtk_widget_show (menu);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
event->button, event->time);
+out:
+ g_object_unref (individual);
return FALSE;
}
@@ -303,16 +319,6 @@ create_marker (EmpathyMapView *self,
return marker;
}
-static void
-contact_added (EmpathyMapView *self,
- EmpathyContact *contact)
-{
- g_signal_connect (contact, "notify::location",
- G_CALLBACK (map_view_contact_location_notify), self);
-
- map_view_update_contact_position (self, contact);
-}
-
static gboolean
map_view_key_press_cb (GtkWidget *widget,
GdkEventKey *event,
@@ -344,36 +350,55 @@ map_view_tick (EmpathyMapView *self)
}
static void
-contact_removed (EmpathyMapView *self,
- EmpathyContact *contact)
+contact_list_changed_cb (EmpathyConnectionAggregator *aggregator,
+ GPtrArray *added,
+ GPtrArray *removed,
+ EmpathyMapView *self)
{
EmpathyMapViewPriv *priv = GET_PRIV (self);
- ClutterActor *marker;
+ guint i;
- marker = g_hash_table_lookup (priv->markers, contact);
- if (marker == NULL)
- return;
+ for (i = 0; i < added->len; i++)
+ {
+ TpContact *tp_contact = g_ptr_array_index (added, i);
+ EmpathyContact *contact;
- clutter_actor_destroy (marker);
- g_hash_table_remove (priv->markers, contact);
-}
+ if (g_hash_table_lookup (priv->contacts, tp_contact) != NULL)
+ continue;
-static void
-members_changed_cb (EmpathyContactList *list,
- EmpathyContact *contact,
- EmpathyContact *actor,
- guint reason,
- gchar *message,
- gboolean is_member,
- EmpathyMapView *self)
-{
- if (is_member)
- {
- contact_added (self, contact);
+ contact = empathy_contact_dup_from_tp_contact (tp_contact);
+
+ tp_g_signal_connect_object (contact, "notify::location",
+ G_CALLBACK (map_view_contact_location_notify), self, 0);
+
+ map_view_update_contact_position (self, contact);
+
+ /* Pass ownership to the hash table */
+ g_hash_table_insert (priv->contacts, g_object_ref (tp_contact),
+ contact);
}
- else
+
+ for (i = 0; i < removed->len; i++)
{
- contact_removed (self, contact);
+ TpContact *tp_contact = g_ptr_array_index (removed, i);
+ EmpathyContact *contact;
+ ClutterActor *marker;
+
+ contact = g_hash_table_lookup (priv->contacts, tp_contact);
+ if (contact == NULL)
+ continue;
+
+ marker = g_hash_table_lookup (priv->markers, contact);
+ if (marker != NULL)
+ {
+ clutter_actor_destroy (marker);
+ g_hash_table_remove (priv->markers, contact);
+ }
+
+ g_signal_handlers_disconnect_by_func (contact,
+ map_view_contact_location_notify, self);
+
+ g_hash_table_remove (priv->contacts, tp_contact);
}
}
@@ -409,12 +434,10 @@ empathy_map_view_finalize (GObject *object)
g_signal_handlers_disconnect_by_func (contact,
map_view_contact_location_notify, object);
- g_signal_handler_disconnect (priv->contact_list,
- priv->members_changed_id);
-
g_hash_table_unref (priv->markers);
- g_object_unref (priv->contact_list);
+ g_object_unref (priv->aggregator);
g_object_unref (priv->layer);
+ g_hash_table_unref (priv->contacts);
G_OBJECT_CLASS (empathy_map_view_parent_class)->finalize (object);
}
@@ -439,7 +462,7 @@ empathy_map_view_init (EmpathyMapView *self)
GtkWidget *embed;
GtkWidget *throbber_holder;
gchar *filename;
- GList *members, *l;
+ GPtrArray *contacts, *empty;
GtkWidget *main_vbox;
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
@@ -474,12 +497,6 @@ empathy_map_view_init (EmpathyMapView *self)
g_object_unref (gui);
- priv->contact_list = EMPATHY_CONTACT_LIST (
- empathy_contact_manager_dup_singleton ());
-
- priv->members_changed_id = g_signal_connect (priv->contact_list,
- "members-changed", G_CALLBACK (members_changed_cb), self);
-
priv->throbber = gtk_spinner_new ();
gtk_widget_set_size_request (priv->throbber, 16, 16);
gtk_container_add (GTK_CONTAINER (throbber_holder), priv->throbber);
@@ -506,14 +523,20 @@ empathy_map_view_init (EmpathyMapView *self)
priv->markers = g_hash_table_new_full (NULL, NULL,
(GDestroyNotify) g_object_unref, NULL);
- members = empathy_contact_list_get_members (
- priv->contact_list);
- for (l = members; l != NULL; l = g_list_next (l))
- {
- contact_added (self, l->data);
- g_object_unref (l->data);
- }
- g_list_free (members);
+ priv->aggregator = empathy_connection_aggregator_dup_singleton ();
+ priv->contacts = g_hash_table_new_full (NULL, NULL, g_object_unref,
+ g_object_unref);
+
+ tp_g_signal_connect_object (priv->aggregator, "contact-list-changed",
+ G_CALLBACK (contact_list_changed_cb), self, 0);
+
+ contacts = empathy_connection_aggregator_dup_all_contacts (priv->aggregator);
+ empty = g_ptr_array_new ();
+
+ contact_list_changed_cb (priv->aggregator, contacts, empty, self);
+
+ g_ptr_array_unref (contacts);
+ g_ptr_array_unref (empty);
/* Set up time updating loop */
priv->timeout_id = g_timeout_add_seconds (5,
diff --git a/src/empathy-new-chatroom-dialog.c b/src/empathy-new-chatroom-dialog.c
index 8176c4803..df30c2a85 100644
--- a/src/empathy-new-chatroom-dialog.c
+++ b/src/empathy-new-chatroom-dialog.c
@@ -395,13 +395,21 @@ static void
update_join_button_sensitivity (EmpathyNewChatroomDialog *dialog)
{
const gchar *room;
+ const gchar *protocol;
gboolean sensitive = FALSE;
room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room));
+ protocol = tp_account_get_protocol (dialog->account);
if (EMP_STR_EMPTY (room))
goto out;
+ if (!tp_strdiff (protocol, "irc") && (!tp_strdiff (room, "#") ||
+ !tp_strdiff (room, "&")))
+ {
+ goto out;
+ }
+
if (dialog->account == NULL)
goto out;
@@ -441,10 +449,16 @@ new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog)
gtk_widget_set_sensitive (dialog->entry_server, TRUE);
}
+ if (!tp_strdiff (protocol, "irc"))
+ gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), "#");
+ else
+ gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), "");
+
update_join_button_sensitivity (dialog);
/* Final set up of the dialog */
gtk_widget_grab_focus (dialog->entry_room);
+ gtk_editable_set_position (GTK_EDITABLE (dialog->entry_room), -1);
}
static void
diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c
index 6775d4a24..77ec49c26 100644
--- a/src/empathy-preferences.c
+++ b/src/empathy-preferences.c
@@ -67,7 +67,7 @@ struct _EmpathyPreferencesPriv {
GtkWidget *checkbutton_show_smileys;
GtkWidget *checkbutton_show_contacts_in_rooms;
- GtkWidget *checkbutton_separate_chat_windows;
+ GtkWidget *radiobutton_chats_new_windows;
GtkWidget *checkbutton_events_notif_area;
GtkWidget *checkbutton_autoconnect;
GtkWidget *checkbutton_logging;
@@ -166,7 +166,7 @@ static SoundEventEntry sound_entries [] = {
{ N_("Message received"), EMPATHY_PREFS_SOUNDS_INCOMING_MESSAGE },
{ N_("Message sent"), EMPATHY_PREFS_SOUNDS_OUTGOING_MESSAGE },
{ N_("New conversation"), EMPATHY_PREFS_SOUNDS_NEW_CONVERSATION },
- { N_("Contact goes online"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGIN },
+ { N_("Contact comes online"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGIN },
{ N_("Contact goes offline"), EMPATHY_PREFS_SOUNDS_CONTACT_LOGOUT },
{ N_("Account connected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGIN },
{ N_("Account disconnected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGOUT }
@@ -248,7 +248,7 @@ preferences_setup_widgets (EmpathyPreferences *preferences)
g_settings_bind (priv->gsettings_ui,
EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS,
- priv->checkbutton_separate_chat_windows,
+ priv->radiobutton_chats_new_windows,
"active",
G_SETTINGS_BIND_DEFAULT);
@@ -678,7 +678,8 @@ static void
preferences_preview_theme_append_message (EmpathyChatView *view,
EmpathyContact *sender,
EmpathyContact *receiver,
- const gchar *text)
+ const gchar *text,
+ gboolean should_highlight)
{
EmpathyMessage *message;
@@ -688,7 +689,7 @@ preferences_preview_theme_append_message (EmpathyChatView *view,
"body", text,
NULL);
- empathy_chat_view_append_message (view, message);
+ empathy_chat_view_append_message (view, message, should_highlight);
g_object_unref (message);
}
@@ -735,19 +736,20 @@ preferences_preview_theme_changed_cb (EmpathyThemeManager *manager,
preferences_preview_theme_append_message (priv->chat_theme_preview,
/* translators: Quote from Romeo & Julier, for chat theme preview */
- juliet, romeo, _("O Romeo, Romeo, wherefore art thou Romeo?"));
+ juliet, romeo, _("O Romeo, Romeo, wherefore art thou Romeo?"),
+ TRUE /* this message mentions Romeo */);
preferences_preview_theme_append_message (priv->chat_theme_preview,
/* translators: Quote from Romeo & Julier, for chat theme preview */
- juliet, romeo, _("Deny thy father and refuse thy name;"));
+ juliet, romeo, _("Deny thy father and refuse thy name;"), FALSE);
preferences_preview_theme_append_message (priv->chat_theme_preview,
/* translators: Quote from Romeo & Julier, for chat theme preview */
- juliet, romeo, _("Or if thou wilt not, be but sworn my love"));
+ juliet, romeo, _("Or if thou wilt not, be but sworn my love"), FALSE);
preferences_preview_theme_append_message (priv->chat_theme_preview,
/* translators: Quote from Romeo & Julier, for chat theme preview */
- juliet, romeo, _("And I'll no longer be a Capulet."));
+ juliet, romeo, _("And I'll no longer be a Capulet."), FALSE);
preferences_preview_theme_append_message (priv->chat_theme_preview,
/* translators: Quote from Romeo & Julier, for chat theme preview */
- romeo, juliet, _("Shall I hear more, or shall I speak at this?"));
+ romeo, juliet, _("Shall I hear more, or shall I speak at this?"), FALSE);
/* translators: Quote from Romeo & Julier, for chat theme preview */
empathy_chat_view_append_event (priv->chat_theme_preview, _("Juliet has disconnected"));
@@ -1170,7 +1172,7 @@ empathy_preferences_init (EmpathyPreferences *preferences)
"combobox_chat_theme_variant", &priv->combobox_chat_theme_variant,
"hbox_chat_theme_variant", &priv->hbox_chat_theme_variant,
"sw_chat_theme_preview", &priv->sw_chat_theme_preview,
- "checkbutton_separate_chat_windows", &priv->checkbutton_separate_chat_windows,
+ "radiobutton_chats_new_windows", &priv->radiobutton_chats_new_windows,
"checkbutton_events_notif_area", &priv->checkbutton_events_notif_area,
"checkbutton_autoconnect", &priv->checkbutton_autoconnect,
"checkbutton_logging", &priv->checkbutton_logging,
diff --git a/src/empathy-preferences.ui b/src/empathy-preferences.ui
index 03a628cb6..f13f6c0b2 100644
--- a/src/empathy-preferences.ui
+++ b/src/empathy-preferences.ui
@@ -107,14 +107,47 @@
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
- <object class="GtkCheckButton" id="checkbutton_separate_chat_windows">
- <property name="label" translatable="yes">_Open new chats in separate windows</property>
+ <object class="GtkBox" id="vbox2180">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">3</property>
+ <child>
+ <object class="GtkLabel" id="label1000">
+ <property name="label" translatable="yes">Start chats in:</property>
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_chats_new_tabs">
+ <property name="label" translatable="yes">new ta_bs</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="radiobutton_chats_new_windows">
+ <property name="label" translatable="yes">new _windows</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_chats_new_tabs</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
diff --git a/src/empathy-main-window-menubar.ui b/src/empathy-roster-window-menubar.ui
index 0bb5d14f0..d342abca8 100644
--- a/src/empathy-main-window-menubar.ui
+++ b/src/empathy-roster-window-menubar.ui
@@ -109,12 +109,6 @@
<accelerator key="F4" modifiers=""/>
</child>
<child>
- <object class="GtkAction" id="edit_personal_information">
- <property name="name">edit_personal_information</property>
- <property name="label" translatable="yes">_Personal Information</property>
- </object>
- </child>
- <child>
<object class="GtkAction" id="edit_blocked_contacts">
<property name="name">edit_blocked_contacts</property>
<property name="label" translatable="yes">_Blocked Contacts</property>
@@ -263,7 +257,6 @@
<menuitem action="edit_context"/>
<separator name="edit_context_separator"/>
<menuitem action="edit_accounts"/>
- <menuitem action="edit_personal_information"/>
<menuitem action="edit_search_contacts"/>
<menuitem action="edit_blocked_contacts"/>
<separator/>
diff --git a/src/empathy-roster-window.c b/src/empathy-roster-window.c
new file mode 100644
index 000000000..454cd256a
--- /dev/null
+++ b/src/empathy-roster-window.c
@@ -0,0 +1,2753 @@
+/*
+ * Copyright (C) 2002-2007 Imendio AB
+ * Copyright (C) 2007-2010 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: Xavier Claessens <xclaesse@gmail.com>
+ * Danielle Madeley <danielle.madeley@collabora.co.uk>
+ */
+
+#include <config.h>
+
+#include <sys/stat.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+
+#include <telepathy-glib/account-manager.h>
+#include <telepathy-glib/util.h>
+#include <folks/folks.h>
+
+#include <libempathy/empathy-contact.h>
+#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-request-util.h>
+#include <libempathy/empathy-chatroom-manager.h>
+#include <libempathy/empathy-chatroom.h>
+#include <libempathy/empathy-contact-list.h>
+#include <libempathy/empathy-gsettings.h>
+#include <libempathy/empathy-individual-manager.h>
+#include <libempathy/empathy-gsettings.h>
+#include <libempathy/empathy-status-presets.h>
+#include <libempathy/empathy-tp-contact-factory.h>
+
+#include <libempathy-gtk/empathy-contact-dialogs.h>
+#include <libempathy-gtk/empathy-live-search.h>
+#include <libempathy-gtk/empathy-contact-blocking-dialog.h>
+#include <libempathy-gtk/empathy-contact-search-dialog.h>
+#include <libempathy-gtk/empathy-geometry.h>
+#include <libempathy-gtk/empathy-gtk-enum-types.h>
+#include <libempathy-gtk/empathy-individual-dialogs.h>
+#include <libempathy-gtk/empathy-individual-store.h>
+#include <libempathy-gtk/empathy-individual-store-manager.h>
+#include <libempathy-gtk/empathy-individual-view.h>
+#include <libempathy-gtk/empathy-new-message-dialog.h>
+#include <libempathy-gtk/empathy-new-call-dialog.h>
+#include <libempathy-gtk/empathy-log-window.h>
+#include <libempathy-gtk/empathy-presence-chooser.h>
+#include <libempathy-gtk/empathy-sound-manager.h>
+#include <libempathy-gtk/empathy-ui-utils.h>
+
+#include "empathy-accounts-dialog.h"
+#include "empathy-call-observer.h"
+#include "empathy-chat-manager.h"
+#include "empathy-roster-window.h"
+#include "empathy-preferences.h"
+#include "empathy-about-dialog.h"
+#include "empathy-debug-window.h"
+#include "empathy-new-chatroom-dialog.h"
+#include "empathy-map-view.h"
+#include "empathy-chatrooms-window.h"
+#include "empathy-event-manager.h"
+#include "empathy-ft-manager.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
+#include <libempathy/empathy-debug.h>
+
+/* Flashing delay for icons (milliseconds). */
+#define FLASH_TIMEOUT 500
+
+/* Minimum width of roster window if something goes wrong. */
+#define MIN_WIDTH 50
+
+/* Accels (menu shortcuts) can be configured and saved */
+#define ACCELS_FILENAME "accels.txt"
+
+/* Name in the geometry file */
+#define GEOMETRY_NAME "roster-window"
+
+enum
+{
+ PAGE_CONTACT_LIST = 0,
+ PAGE_MESSAGE
+};
+
+enum
+{
+ PROP_0,
+ PROP_SHELL_RUNNING
+};
+
+G_DEFINE_TYPE (EmpathyRosterWindow, empathy_roster_window, GTK_TYPE_WINDOW);
+
+struct _EmpathyRosterWindowPriv {
+ EmpathyIndividualStore *individual_store;
+ EmpathyIndividualView *individual_view;
+ TpAccountManager *account_manager;
+ EmpathyChatroomManager *chatroom_manager;
+ EmpathyEventManager *event_manager;
+ EmpathySoundManager *sound_mgr;
+ EmpathyCallObserver *call_observer;
+ EmpathyIndividualManager *individual_manager;
+ guint flash_timeout_id;
+ gboolean flash_on;
+ gboolean empty;
+
+ GSettings *gsettings_ui;
+ GSettings *gsettings_contacts;
+
+ GtkWidget *preferences;
+ GtkWidget *main_vbox;
+ GtkWidget *throbber;
+ GtkWidget *throbber_tool_item;
+ GtkWidget *presence_toolbar;
+ GtkWidget *presence_chooser;
+ GtkWidget *errors_vbox;
+ GtkWidget *auth_vbox;
+ GtkWidget *search_bar;
+ GtkWidget *notebook;
+ GtkWidget *no_entry_label;
+ GtkWidget *button_account_settings;
+ GtkWidget *spinner_loading;
+
+ GtkToggleAction *show_protocols;
+ GtkRadioAction *sort_by_name;
+ GtkRadioAction *sort_by_status;
+ GtkRadioAction *normal_with_avatars;
+ GtkRadioAction *normal_size;
+ GtkRadioAction *compact_size;
+
+ GtkUIManager *ui_manager;
+ GtkAction *view_history;
+ GtkAction *room_join_favorites;
+ GtkWidget *room_menu;
+ GtkWidget *room_separator;
+ GtkWidget *edit_context;
+ GtkWidget *edit_context_separator;
+
+ GtkActionGroup *balance_action_group;
+ GtkAction *view_balance_show_in_roster;
+ GtkWidget *balance_vbox;
+
+ guint size_timeout_id;
+
+ /* reffed TpAccount* => visible GtkInfoBar* */
+ GHashTable *errors;
+
+ /* EmpathyEvent* => visible GtkInfoBar* */
+ GHashTable *auths;
+
+ /* stores a mapping from TpAccount to Handler ID to prevent
+ * to listen more than once to the status-changed signal */
+ GHashTable *status_changed_handlers;
+
+ /* Actions that are enabled when there are connected accounts */
+ GList *actions_connected;
+
+ gboolean shell_running;
+};
+
+static void
+roster_window_flash_stop (EmpathyRosterWindow *self)
+{
+ if (self->priv->flash_timeout_id == 0)
+ return;
+
+ DEBUG ("Stop flashing");
+ g_source_remove (self->priv->flash_timeout_id);
+ self->priv->flash_timeout_id = 0;
+ self->priv->flash_on = FALSE;
+}
+
+typedef struct
+{
+ EmpathyEvent *event;
+ gboolean on;
+ EmpathyRosterWindow *self;
+} FlashForeachData;
+
+static gboolean
+roster_window_flash_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ FlashForeachData *data = (FlashForeachData *) user_data;
+ FolksIndividual *individual;
+ EmpathyContact *contact;
+ const gchar *icon_name;
+ GtkTreePath *parent_path = NULL;
+ GtkTreeIter parent_iter;
+ GdkPixbuf *pixbuf = NULL;
+
+ gtk_tree_model_get (model, iter,
+ EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual,
+ -1);
+
+ if (individual == NULL)
+ return FALSE;
+
+ contact = empathy_contact_dup_from_folks_individual (individual);
+ if (contact != data->event->contact)
+ goto out;
+
+ if (data->on)
+ {
+ icon_name = data->event->icon_name;
+ pixbuf = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
+ }
+ else
+ {
+ pixbuf = empathy_individual_store_get_individual_status_icon (
+ data->self->priv->individual_store,
+ individual);
+ if (pixbuf != NULL)
+ g_object_ref (pixbuf);
+ }
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ EMPATHY_INDIVIDUAL_STORE_COL_ICON_STATUS, pixbuf,
+ -1);
+
+ /* To make sure the parent is shown correctly, we emit
+ * the row-changed signal on the parent so it prompts
+ * it to be refreshed by the filter func.
+ */
+ if (gtk_tree_model_iter_parent (model, &parent_iter, iter))
+ {
+ parent_path = gtk_tree_model_get_path (model, &parent_iter);
+ }
+
+ if (parent_path != NULL)
+ {
+ gtk_tree_model_row_changed (model, parent_path, &parent_iter);
+ gtk_tree_path_free (parent_path);
+ }
+
+out:
+ g_object_unref (individual);
+ tp_clear_object (&contact);
+ tp_clear_object (&pixbuf);
+
+ return FALSE;
+}
+
+static gboolean
+roster_window_flash_cb (EmpathyRosterWindow *self)
+{
+ GtkTreeModel *model;
+ GSList *events, *l;
+ gboolean found_event = FALSE;
+ FlashForeachData data;
+
+ self->priv->flash_on = !self->priv->flash_on;
+ data.on = self->priv->flash_on;
+ model = GTK_TREE_MODEL (self->priv->individual_store);
+
+ events = empathy_event_manager_get_events (self->priv->event_manager);
+ for (l = events; l; l = l->next)
+ {
+ data.event = l->data;
+ data.self = self;
+ if (!data.event->contact || !data.event->must_ack)
+ continue;
+
+ found_event = TRUE;
+ gtk_tree_model_foreach (model,
+ roster_window_flash_foreach,
+ &data);
+ }
+
+ if (!found_event)
+ roster_window_flash_stop (self);
+
+ return TRUE;
+}
+
+static void
+roster_window_flash_start (EmpathyRosterWindow *self)
+{
+ if (self->priv->flash_timeout_id != 0)
+ return;
+
+ DEBUG ("Start flashing");
+ self->priv->flash_timeout_id = g_timeout_add (FLASH_TIMEOUT,
+ (GSourceFunc) roster_window_flash_cb, self);
+
+ roster_window_flash_cb (self);
+}
+
+static void
+roster_window_remove_auth (EmpathyRosterWindow *self,
+ EmpathyEvent *event)
+{
+ GtkWidget *error_widget;
+
+ error_widget = g_hash_table_lookup (self->priv->auths, event);
+ if (error_widget != NULL)
+ {
+ gtk_widget_destroy (error_widget);
+ g_hash_table_remove (self->priv->auths, event);
+ }
+}
+
+static void
+roster_window_auth_add_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ EmpathyEvent *event;
+
+ event = g_object_get_data (G_OBJECT (button), "event");
+
+ empathy_event_approve (event);
+
+ roster_window_remove_auth (self, event);
+}
+
+static void
+roster_window_auth_close_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ EmpathyEvent *event;
+
+ event = g_object_get_data (G_OBJECT (button), "event");
+
+ empathy_event_decline (event);
+ roster_window_remove_auth (self, event);
+}
+
+static void
+roster_window_auth_display (EmpathyRosterWindow *self,
+ EmpathyEvent *event)
+{
+ TpAccount *account = event->account;
+ GtkWidget *info_bar;
+ GtkWidget *content_area;
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *add_button;
+ GtkWidget *close_button;
+ GtkWidget *action_area;
+ GtkWidget *action_grid;
+ const gchar *icon_name;
+ gchar *str;
+
+ if (g_hash_table_lookup (self->priv->auths, event) != NULL)
+ return;
+
+ info_bar = gtk_info_bar_new ();
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_QUESTION);
+
+ gtk_widget_set_no_show_all (info_bar, TRUE);
+ gtk_box_pack_start (GTK_BOX (self->priv->auth_vbox), info_bar, FALSE, TRUE, 0);
+ gtk_widget_show (info_bar);
+
+ icon_name = tp_account_get_icon_name (account);
+ image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_widget_show (image);
+
+ str = g_markup_printf_escaped ("<b>%s</b>\n%s",
+ tp_account_get_display_name (account),
+ _("Password required"));
+
+ label = gtk_label_new (str);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_widget_show (label);
+
+ g_free (str);
+
+ content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
+ gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
+ add_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (add_button), image);
+ gtk_widget_set_tooltip_text (add_button, _("Provide Password"));
+ gtk_widget_show (add_button);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON);
+ close_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (close_button), image);
+ gtk_widget_set_tooltip_text (close_button, _("Disconnect"));
+ gtk_widget_show (close_button);
+
+ action_grid = gtk_grid_new ();
+ gtk_grid_set_column_spacing (GTK_GRID (action_grid), 6);
+ gtk_widget_show (action_grid);
+
+ action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
+ gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
+
+ gtk_grid_attach (GTK_GRID (action_grid), add_button, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (action_grid), close_button, 1, 0, 1, 1);
+
+ g_object_set_data_full (G_OBJECT (info_bar),
+ "event", event, NULL);
+ g_object_set_data_full (G_OBJECT (add_button),
+ "event", event, NULL);
+ g_object_set_data_full (G_OBJECT (close_button),
+ "event", event, NULL);
+
+ g_signal_connect (add_button, "clicked",
+ G_CALLBACK (roster_window_auth_add_clicked_cb), self);
+ g_signal_connect (close_button, "clicked",
+ G_CALLBACK (roster_window_auth_close_clicked_cb), self);
+
+ gtk_widget_show (self->priv->auth_vbox);
+
+ g_hash_table_insert (self->priv->auths, event, info_bar);
+}
+
+static void
+modify_event_count (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ EmpathyEvent *event,
+ gboolean increase)
+{
+ FolksIndividual *individual;
+ EmpathyContact *contact;
+ guint count;
+
+ gtk_tree_model_get (model, iter,
+ EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual,
+ EMPATHY_INDIVIDUAL_STORE_COL_EVENT_COUNT, &count,
+ -1);
+
+ if (individual == NULL)
+ return;
+
+ increase ? count++ : count--;
+
+ contact = empathy_contact_dup_from_folks_individual (individual);
+ if (contact == event->contact)
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ EMPATHY_INDIVIDUAL_STORE_COL_EVENT_COUNT, count, -1);
+
+ tp_clear_object (&contact);
+ g_object_unref (individual);
+}
+
+static gboolean
+increase_event_count_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ EmpathyEvent *event = user_data;
+
+ modify_event_count (model, iter, event, TRUE);
+
+ return FALSE;
+}
+
+static void
+increase_event_count (EmpathyRosterWindow *self,
+ EmpathyEvent *event)
+{
+ GtkTreeModel *model;
+
+ model = GTK_TREE_MODEL (self->priv->individual_store);
+
+ gtk_tree_model_foreach (model, increase_event_count_foreach, event);
+}
+
+static gboolean
+decrease_event_count_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ EmpathyEvent *event = user_data;
+
+ modify_event_count (model, iter, event, FALSE);
+
+ return FALSE;
+}
+
+static void
+decrease_event_count (EmpathyRosterWindow *self,
+ EmpathyEvent *event)
+{
+ GtkTreeModel *model;
+
+ model = GTK_TREE_MODEL (self->priv->individual_store);
+
+ gtk_tree_model_foreach (model, decrease_event_count_foreach, event);
+}
+
+static void
+roster_window_event_added_cb (EmpathyEventManager *manager,
+ EmpathyEvent *event,
+ EmpathyRosterWindow *self)
+{
+ if (event->contact)
+ {
+ increase_event_count (self, event);
+
+ roster_window_flash_start (self);
+ }
+ else if (event->type == EMPATHY_EVENT_TYPE_AUTH)
+ {
+ roster_window_auth_display (self, event);
+ }
+}
+
+static void
+roster_window_event_removed_cb (EmpathyEventManager *manager,
+ EmpathyEvent *event,
+ EmpathyRosterWindow *self)
+{
+ FlashForeachData data;
+
+ if (event->type == EMPATHY_EVENT_TYPE_AUTH)
+ {
+ roster_window_remove_auth (self, event);
+ return;
+ }
+
+ if (!event->contact)
+ return;
+
+ decrease_event_count (self, event);
+
+ data.on = FALSE;
+ data.event = event;
+ data.self = self;
+
+ gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->individual_store),
+ roster_window_flash_foreach,
+ &data);
+}
+
+static gboolean
+roster_window_load_events_idle_cb (gpointer user_data)
+{
+ EmpathyRosterWindow *self = user_data;
+ GSList *l;
+
+ l = empathy_event_manager_get_events (self->priv->event_manager);
+ while (l != NULL)
+ {
+ roster_window_event_added_cb (self->priv->event_manager, l->data,
+ self);
+ l = l->next;
+ }
+
+ return FALSE;
+}
+
+static void
+roster_window_row_activated_cb (EmpathyIndividualView *view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *col,
+ EmpathyRosterWindow *self)
+{
+ EmpathyContact *contact = NULL;
+ FolksIndividual *individual;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GSList *events, *l;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->individual_view));
+ gtk_tree_model_get_iter (model, &iter, path);
+
+ gtk_tree_model_get (model, &iter, EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL,
+ &individual, -1);
+
+ if (individual != NULL)
+ contact = empathy_contact_dup_from_folks_individual (individual);
+
+ if (contact == NULL)
+ goto OUT;
+
+ /* If the contact has an event activate it, otherwise the
+ * default handler of row-activated will be called. */
+ events = empathy_event_manager_get_events (self->priv->event_manager);
+ for (l = events; l; l = l->next)
+ {
+ EmpathyEvent *event = l->data;
+
+ if (event->contact == contact)
+ {
+ DEBUG ("Activate event");
+ empathy_event_activate (event);
+
+ /* We don't want the default handler of this signal
+ * (e.g. open a chat) */
+ g_signal_stop_emission_by_name (view, "row-activated");
+ break;
+ }
+ }
+
+ g_object_unref (contact);
+OUT:
+ tp_clear_object (&individual);
+}
+
+static void
+button_account_settings_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ empathy_accounts_dialog_show_application (gdk_screen_get_default (),
+ NULL, FALSE, FALSE);
+}
+
+static void
+display_page_message (EmpathyRosterWindow *self,
+ const gchar *msg,
+ gboolean display_accounts_button,
+ gboolean display_spinner)
+{
+ if (msg != NULL)
+ {
+ gchar *tmp;
+
+ tmp = g_strdup_printf ("<b><span size='xx-large'>%s</span></b>", msg);
+
+ gtk_label_set_markup (GTK_LABEL (self->priv->no_entry_label), tmp);
+ g_free (tmp);
+
+ gtk_label_set_line_wrap (GTK_LABEL (self->priv->no_entry_label), TRUE);
+ gtk_widget_show (self->priv->no_entry_label);
+ }
+ else
+ {
+ gtk_widget_hide (self->priv->no_entry_label);
+ }
+
+ gtk_widget_set_visible (self->priv->button_account_settings,
+ display_accounts_button);
+ gtk_widget_set_visible (self->priv->spinner_loading,
+ display_spinner);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook),
+ PAGE_MESSAGE);
+}
+
+static void
+display_page_no_account (EmpathyRosterWindow *self)
+{
+ display_page_message (self,
+ _("You need to setup an account to see contacts here."), TRUE, FALSE);
+}
+
+static void
+roster_window_row_deleted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ EmpathyRosterWindow *self)
+{
+ GtkTreeIter help_iter;
+
+ if (!gtk_tree_model_get_iter_first (model, &help_iter))
+ {
+ self->priv->empty = TRUE;
+
+ if (empathy_individual_view_is_searching (self->priv->individual_view))
+ {
+ display_page_message (self, _("No match found"), FALSE, FALSE);
+ }
+ }
+}
+
+static void
+display_page_contact_list (EmpathyRosterWindow *self)
+{
+ if (!empathy_individual_manager_get_contacts_loaded (
+ self->priv->individual_manager))
+ /* We'll display the contact list once we're done loading */
+ return;
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook),
+ PAGE_CONTACT_LIST);
+}
+
+static void
+roster_window_row_inserted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ EmpathyRosterWindow *self)
+{
+ if (self->priv->empty)
+ {
+ self->priv->empty = FALSE;
+
+ display_page_contact_list (self);
+ gtk_widget_grab_focus (GTK_WIDGET (self->priv->individual_view));
+
+ /* The store is being filled, it will be done after an idle cb.
+ * So we can then get events. If we do that too soon, event's
+ * contact is not yet in the store and it won't get marked as
+ * having events. */
+ g_idle_add (roster_window_load_events_idle_cb, self);
+ }
+}
+
+static void
+roster_window_remove_error (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ GtkWidget *error_widget;
+
+ error_widget = g_hash_table_lookup (self->priv->errors, account);
+ if (error_widget != NULL)
+ {
+ gtk_widget_destroy (error_widget);
+ g_hash_table_remove (self->priv->errors, account);
+ }
+}
+
+static void
+roster_window_account_disabled_cb (TpAccountManager *manager,
+ TpAccount *account,
+ EmpathyRosterWindow *self)
+{
+ roster_window_remove_error (self, account);
+}
+
+static void
+roster_window_error_retry_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ TpAccount *account;
+
+ account = g_object_get_data (G_OBJECT (button), "account");
+ tp_account_reconnect_async (account, NULL, NULL);
+
+ roster_window_remove_error (self, account);
+}
+
+static void
+roster_window_error_edit_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ TpAccount *account;
+
+ account = g_object_get_data (G_OBJECT (button), "account");
+
+ empathy_accounts_dialog_show_application (
+ gtk_widget_get_screen (GTK_WIDGET (button)),
+ account, FALSE, FALSE);
+
+ roster_window_remove_error (self, account);
+}
+
+static void
+roster_window_error_close_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ TpAccount *account;
+
+ account = g_object_get_data (G_OBJECT (button), "account");
+ roster_window_remove_error (self, account);
+}
+
+static void
+roster_window_error_upgrade_sw_clicked_cb (GtkButton *button,
+ EmpathyRosterWindow *self)
+{
+ TpAccount *account;
+ GtkWidget *dialog;
+
+ account = g_object_get_data (G_OBJECT (button), "account");
+ roster_window_remove_error (self, account);
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (self),
+ GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Sorry, %s accounts can’t be used until your %s software is updated."),
+ tp_account_get_protocol (account),
+ tp_account_get_protocol (account));
+
+ g_signal_connect_swapped (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy),
+ dialog);
+
+ gtk_widget_show (dialog);
+}
+
+static void
+roster_window_upgrade_software_error (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ GtkWidget *info_bar;
+ GtkWidget *content_area;
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *upgrade_button;
+ GtkWidget *close_button;
+ GtkWidget *action_area;
+ GtkWidget *action_grid;
+ gchar *str;
+ const gchar *icon_name;
+ const gchar *error_message;
+ gboolean user_requested;
+
+ error_message =
+ empathy_account_get_error_message (account, &user_requested);
+
+ if (user_requested)
+ return;
+
+ str = g_markup_printf_escaped ("<b>%s</b>\n%s",
+ tp_account_get_display_name (account),
+ error_message);
+
+ /* If there are other errors, remove them */
+ roster_window_remove_error (self, account);
+
+ info_bar = gtk_info_bar_new ();
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR);
+
+ gtk_widget_set_no_show_all (info_bar, TRUE);
+ gtk_box_pack_start (GTK_BOX (self->priv->errors_vbox), info_bar, FALSE, TRUE, 0);
+ gtk_widget_show (info_bar);
+
+ icon_name = tp_account_get_icon_name (account);
+ image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_widget_show (image);
+
+ label = gtk_label_new (str);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_widget_show (label);
+ g_free (str);
+
+ content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
+ gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON);
+ upgrade_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (upgrade_button), image);
+ gtk_widget_set_tooltip_text (upgrade_button, _("Update software..."));
+ gtk_widget_show (upgrade_button);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON);
+ close_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (close_button), image);
+ gtk_widget_set_tooltip_text (close_button, _("Close"));
+ gtk_widget_show (close_button);
+
+ action_grid = gtk_grid_new ();
+ gtk_grid_set_column_spacing (GTK_GRID (action_grid), 2);
+ gtk_widget_show (action_grid);
+
+ action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
+ gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
+
+ gtk_grid_attach (GTK_GRID (action_grid), upgrade_button, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (action_grid), close_button, 1, 0, 1, 1);
+
+ g_object_set_data (G_OBJECT (info_bar), "label", label);
+ g_object_set_data_full (G_OBJECT (info_bar),
+ "account", g_object_ref (account),
+ g_object_unref);
+ g_object_set_data_full (G_OBJECT (upgrade_button),
+ "account", g_object_ref (account),
+ g_object_unref);
+ g_object_set_data_full (G_OBJECT (close_button),
+ "account", g_object_ref (account),
+ g_object_unref);
+
+ g_signal_connect (upgrade_button, "clicked",
+ G_CALLBACK (roster_window_error_upgrade_sw_clicked_cb), self);
+ g_signal_connect (close_button, "clicked",
+ G_CALLBACK (roster_window_error_close_clicked_cb), self);
+
+ gtk_widget_set_tooltip_text (self->priv->errors_vbox, error_message);
+ gtk_widget_show (self->priv->errors_vbox);
+
+ g_hash_table_insert (self->priv->errors, g_object_ref (account), info_bar);
+}
+
+static void
+roster_window_error_display (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ GtkWidget *info_bar;
+ GtkWidget *content_area;
+ GtkWidget *label;
+ GtkWidget *image;
+ GtkWidget *retry_button;
+ GtkWidget *edit_button;
+ GtkWidget *close_button;
+ GtkWidget *action_area;
+ GtkWidget *action_grid;
+ gchar *str;
+ const gchar *icon_name;
+ const gchar *error_message;
+ gboolean user_requested;
+
+ if (!tp_strdiff (TP_ERROR_STR_SOFTWARE_UPGRADE_REQUIRED,
+ tp_account_get_detailed_error (account, NULL)))
+ {
+ roster_window_upgrade_software_error (self, account);
+ return;
+ }
+
+ error_message = empathy_account_get_error_message (account, &user_requested);
+
+ if (user_requested)
+ return;
+
+ str = g_markup_printf_escaped ("<b>%s</b>\n%s",
+ tp_account_get_display_name (account), error_message);
+
+ info_bar = g_hash_table_lookup (self->priv->errors, account);
+ if (info_bar)
+ {
+ label = g_object_get_data (G_OBJECT (info_bar), "label");
+
+ /* Just set the latest error and return */
+ gtk_label_set_markup (GTK_LABEL (label), str);
+ g_free (str);
+
+ return;
+ }
+
+ info_bar = gtk_info_bar_new ();
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_ERROR);
+
+ gtk_widget_set_no_show_all (info_bar, TRUE);
+ gtk_box_pack_start (GTK_BOX (self->priv->errors_vbox), info_bar, FALSE, TRUE, 0);
+ gtk_widget_show (info_bar);
+
+ icon_name = tp_account_get_icon_name (account);
+ image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_widget_show (image);
+
+ label = gtk_label_new (str);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_widget_show (label);
+ g_free (str);
+
+ content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
+ gtk_box_pack_start (GTK_BOX (content_area), image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_BUTTON);
+ retry_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (retry_button), image);
+ gtk_widget_set_tooltip_text (retry_button, _("Reconnect"));
+ gtk_widget_show (retry_button);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON);
+ edit_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (edit_button), image);
+ gtk_widget_set_tooltip_text (edit_button, _("Edit Account"));
+ gtk_widget_show (edit_button);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON);
+ close_button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (close_button), image);
+ gtk_widget_set_tooltip_text (close_button, _("Close"));
+ gtk_widget_show (close_button);
+
+ action_grid = gtk_grid_new ();
+ gtk_grid_set_column_spacing (GTK_GRID (action_grid), 2);
+ gtk_widget_show (action_grid);
+
+ action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
+ gtk_box_pack_start (GTK_BOX (action_area), action_grid, FALSE, FALSE, 0);
+
+ gtk_grid_attach (GTK_GRID (action_grid), retry_button, 0, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (action_grid), edit_button, 1, 0, 1, 1);
+ gtk_grid_attach (GTK_GRID (action_grid), close_button, 2, 0, 1, 1);
+
+ g_object_set_data (G_OBJECT (info_bar), "label", label);
+ g_object_set_data_full (G_OBJECT (info_bar),
+ "account", g_object_ref (account),
+ g_object_unref);
+ g_object_set_data_full (G_OBJECT (edit_button),
+ "account", g_object_ref (account),
+ g_object_unref);
+ g_object_set_data_full (G_OBJECT (close_button),
+ "account", g_object_ref (account),
+ g_object_unref);
+ g_object_set_data_full (G_OBJECT (retry_button),
+ "account", g_object_ref (account),
+ g_object_unref);
+
+ g_signal_connect (edit_button, "clicked",
+ G_CALLBACK (roster_window_error_edit_clicked_cb), self);
+ g_signal_connect (close_button, "clicked",
+ G_CALLBACK (roster_window_error_close_clicked_cb), self);
+ g_signal_connect (retry_button, "clicked",
+ G_CALLBACK (roster_window_error_retry_clicked_cb), self);
+
+ gtk_widget_set_tooltip_text (self->priv->errors_vbox, error_message);
+ gtk_widget_show (self->priv->errors_vbox);
+
+ g_hash_table_insert (self->priv->errors, g_object_ref (account), info_bar);
+}
+
+static void
+roster_window_update_status (EmpathyRosterWindow *self)
+{
+ gboolean connected, connecting;
+ GList *l, *children;
+
+ connected = empathy_account_manager_get_accounts_connected (&connecting);
+
+ /* Update the spinner state */
+ if (connecting)
+ {
+ gtk_spinner_start (GTK_SPINNER (self->priv->throbber));
+ gtk_widget_show (self->priv->throbber_tool_item);
+ }
+ else
+ {
+ gtk_spinner_stop (GTK_SPINNER (self->priv->throbber));
+ gtk_widget_hide (self->priv->throbber_tool_item);
+ }
+
+ /* Update widgets sensibility */
+ for (l = self->priv->actions_connected; l; l = l->next)
+ gtk_action_set_sensitive (l->data, connected);
+
+ /* Update favourite rooms sensitivity */
+ children = gtk_container_get_children (GTK_CONTAINER (self->priv->room_menu));
+ for (l = children; l != NULL; l = l->next)
+ {
+ if (g_object_get_data (G_OBJECT (l->data), "is_favorite") != NULL)
+ gtk_widget_set_sensitive (GTK_WIDGET (l->data), connected);
+ }
+
+ g_list_free (children);
+}
+
+static char *
+roster_window_account_to_action_name (TpAccount *account)
+{
+ char *r;
+
+ /* action names can't have '/' in them, replace it with '.' */
+ r = g_strdup (tp_account_get_path_suffix (account));
+ r = g_strdelimit (r, "/", '.');
+
+ return r;
+}
+
+static void
+roster_window_balance_activate_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ const char *uri;
+
+ uri = g_object_get_data (G_OBJECT (action), "manage-credit-uri");
+
+ if (!tp_str_empty (uri))
+ {
+ DEBUG ("Top-up credit URI: %s", uri);
+ empathy_url_show (GTK_WIDGET (self), uri);
+ }
+ else
+ {
+ DEBUG ("unknown protocol for top-up");
+ }
+}
+
+static void
+roster_window_balance_update_balance (GtkAction *action,
+ TpConnection *conn)
+{
+ TpAccount *account = tp_connection_get_account (conn);
+ GtkWidget *label;
+ int amount = 0;
+ guint scale = G_MAXINT32;
+ const gchar *currency = "";
+ char *money, *str;
+
+ if (!tp_connection_get_balance (conn, &amount, &scale, &currency))
+ return;
+
+ if (amount == 0 &&
+ scale == G_MAXINT32 &&
+ tp_str_empty (currency))
+ {
+ /* unknown balance */
+ money = g_strdup ("--");
+ }
+ else
+ {
+ char *tmp = empathy_format_currency (amount, scale, currency);
+
+ money = g_strdup_printf ("%s %s", currency, tmp);
+ g_free (tmp);
+ }
+
+ /* Translators: this string will be something like:
+ * Top up My Account ($1.23)..." */
+ str = g_strdup_printf (_("Top up %s (%s)..."),
+ tp_account_get_display_name (account), money);
+
+ gtk_action_set_label (action, str);
+ g_free (str);
+
+ /* update the money label in the roster */
+ label = g_object_get_data (G_OBJECT (action), "money-label");
+
+ gtk_label_set_text (GTK_LABEL (label), money);
+ g_free (money);
+}
+
+static void
+roster_window_balance_changed_cb (TpConnection *conn,
+ guint balance,
+ guint scale,
+ const gchar *currency,
+ GtkAction *action)
+{
+ roster_window_balance_update_balance (action, conn);
+}
+
+static GtkAction *
+roster_window_setup_balance_create_action (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ GtkAction *action;
+ char *name, *ui;
+ guint merge_id;
+ GError *error = NULL;
+
+ /* create the action group if required */
+ if (self->priv->balance_action_group == NULL)
+ {
+ self->priv->balance_action_group =
+ gtk_action_group_new ("balance-action-group");
+
+ gtk_ui_manager_insert_action_group (self->priv->ui_manager,
+ self->priv->balance_action_group, -1);
+ }
+
+ /* create the action */
+ name = roster_window_account_to_action_name (account);
+ action = gtk_action_new (name,
+ tp_account_get_display_name (account),
+ _("Top up account credit"), NULL);
+
+ g_object_bind_property (account, "icon-name", action, "icon-name",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (action, "activate",
+ G_CALLBACK (roster_window_balance_activate_cb), self);
+
+ gtk_action_group_add_action (self->priv->balance_action_group, action);
+ g_object_unref (action);
+
+ ui = g_strdup_printf (
+ "<ui>"
+ " <menubar name='menubar'>"
+ " <menu action='view'>"
+ " <placeholder name='view_balance_placeholder'>"
+ " <menuitem action='%s'/>"
+ " </placeholder>"
+ " </menu>"
+ " </menubar>"
+ "</ui>",
+ name);
+
+ merge_id = gtk_ui_manager_add_ui_from_string (self->priv->ui_manager,
+ ui, -1, &error);
+
+ if (error != NULL)
+ {
+ DEBUG ("Failed to add balance UI for %s: %s",
+ tp_account_get_display_name (account),
+ error->message);
+ g_error_free (error);
+ }
+
+ g_object_set_data (G_OBJECT (action),
+ "merge-id", GUINT_TO_POINTER (merge_id));
+
+ g_free (name);
+ g_free (ui);
+
+ return action;
+}
+
+static GtkWidget *
+roster_window_setup_balance_create_widget (EmpathyRosterWindow *self,
+ GtkAction *action,
+ TpAccount *account)
+{
+ GtkWidget *hbox, *image, *label, *button;
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+
+ /* protocol icon */
+ image = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
+ g_object_bind_property (action, "icon-name", image, "icon-name",
+ G_BINDING_SYNC_CREATE);
+
+ /* account name label */
+ label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+ g_object_bind_property (account, "display-name", label, "label",
+ G_BINDING_SYNC_CREATE);
+
+ /* balance label */
+ label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ g_object_set_data (G_OBJECT (action), "money-label", label);
+
+ /* top up button */
+ button = gtk_button_new_with_label (_("Top Up..."));
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
+ g_signal_connect_swapped (button, "clicked",
+ G_CALLBACK (gtk_action_activate), action);
+
+ gtk_box_pack_start (GTK_BOX (self->priv->balance_vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show_all (hbox);
+
+ /* tie the lifetime of the widget to the lifetime of the action */
+ g_object_weak_ref (G_OBJECT (action),
+ (GWeakNotify) gtk_widget_destroy, hbox);
+
+ return hbox;
+}
+
+static void
+roster_window_setup_balance (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ TpConnection *conn = tp_account_get_connection (account);
+ GtkAction *action;
+ const gchar *uri;
+
+ if (conn == NULL)
+ return;
+
+ if (!tp_proxy_is_prepared (conn, TP_CONNECTION_FEATURE_BALANCE))
+ return;
+
+ DEBUG ("Setting up balance for acct: %s",
+ tp_account_get_display_name (account));
+
+ /* create the action */
+ action = roster_window_setup_balance_create_action (self, account);
+
+ if (action == NULL)
+ return;
+
+ gtk_action_set_visible (self->priv->view_balance_show_in_roster, TRUE);
+
+ /* create the display widget */
+ roster_window_setup_balance_create_widget (self, action, account);
+
+ /* check the current balance and monitor for any changes */
+ uri = tp_connection_get_balance_uri (conn);
+
+ g_object_set_data_full (G_OBJECT (action), "manage-credit-uri",
+ g_strdup (uri), g_free);
+ gtk_action_set_sensitive (GTK_ACTION (action), !tp_str_empty (uri));
+
+ roster_window_balance_update_balance (GTK_ACTION (action), conn);
+
+ g_signal_connect (conn, "balance-changed",
+ G_CALLBACK (roster_window_balance_changed_cb), action);
+}
+
+static void
+roster_window_remove_balance_action (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ GtkAction *action;
+ char *name;
+ GList *a;
+
+ if (self->priv->balance_action_group == NULL)
+ return;
+
+ name = roster_window_account_to_action_name (account);
+
+ action = gtk_action_group_get_action (
+ self->priv->balance_action_group, name);
+
+ if (action != NULL)
+ {
+ guint merge_id;
+
+ DEBUG ("Removing action");
+
+ merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (action),
+ "merge-id"));
+
+ gtk_ui_manager_remove_ui (self->priv->ui_manager,
+ merge_id);
+ gtk_action_group_remove_action (
+ self->priv->balance_action_group, action);
+ }
+
+ g_free (name);
+
+ a = gtk_action_group_list_actions (
+ self->priv->balance_action_group);
+
+ gtk_action_set_visible (self->priv->view_balance_show_in_roster,
+ g_list_length (a) > 0);
+
+ g_list_free (a);
+}
+
+static void
+roster_window_connection_changed_cb (TpAccount *account,
+ guint old_status,
+ guint current,
+ guint reason,
+ gchar *dbus_error_name,
+ GHashTable *details,
+ EmpathyRosterWindow *self)
+{
+ roster_window_update_status (self);
+
+ if (current == TP_CONNECTION_STATUS_DISCONNECTED &&
+ reason != TP_CONNECTION_STATUS_REASON_REQUESTED)
+ {
+ roster_window_error_display (self, account);
+ }
+
+ if (current == TP_CONNECTION_STATUS_DISCONNECTED)
+ {
+ empathy_sound_manager_play (self->priv->sound_mgr, GTK_WIDGET (self),
+ EMPATHY_SOUND_ACCOUNT_DISCONNECTED);
+ }
+
+ if (current == TP_CONNECTION_STATUS_CONNECTED)
+ {
+ empathy_sound_manager_play (self->priv->sound_mgr, GTK_WIDGET (self),
+ EMPATHY_SOUND_ACCOUNT_CONNECTED);
+
+ /* Account connected without error, remove error message if any */
+ roster_window_remove_error (self, account);
+ }
+}
+
+static void
+roster_window_accels_load (void)
+{
+ gchar *filename;
+
+ filename = g_build_filename (g_get_user_config_dir (),
+ PACKAGE_NAME, ACCELS_FILENAME, NULL);
+ if (g_file_test (filename, G_FILE_TEST_EXISTS))
+ {
+ DEBUG ("Loading from:'%s'", filename);
+ gtk_accel_map_load (filename);
+ }
+
+ g_free (filename);
+}
+
+static void
+roster_window_accels_save (void)
+{
+ gchar *dir;
+ gchar *file_with_path;
+
+ dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
+ g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
+ file_with_path = g_build_filename (dir, ACCELS_FILENAME, NULL);
+ g_free (dir);
+
+ DEBUG ("Saving to:'%s'", file_with_path);
+ gtk_accel_map_save (file_with_path);
+
+ g_free (file_with_path);
+}
+
+static void
+empathy_roster_window_finalize (GObject *window)
+{
+ EmpathyRosterWindow *self = EMPATHY_ROSTER_WINDOW (window);
+ GHashTableIter iter;
+ gpointer key, value;
+
+ /* Save user-defined accelerators. */
+ roster_window_accels_save ();
+
+ g_list_free (self->priv->actions_connected);
+
+ g_object_unref (self->priv->account_manager);
+ g_object_unref (self->priv->individual_store);
+ g_object_unref (self->priv->sound_mgr);
+ g_hash_table_unref (self->priv->errors);
+ g_hash_table_unref (self->priv->auths);
+
+ /* disconnect all handlers of status-changed signal */
+ g_hash_table_iter_init (&iter, self->priv->status_changed_handlers);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ g_signal_handler_disconnect (TP_ACCOUNT (key), GPOINTER_TO_UINT (value));
+
+ g_hash_table_unref (self->priv->status_changed_handlers);
+
+ g_signal_handlers_disconnect_by_func (self->priv->event_manager,
+ roster_window_event_added_cb, self);
+ g_signal_handlers_disconnect_by_func (self->priv->event_manager,
+ roster_window_event_removed_cb, self);
+
+ g_object_unref (self->priv->call_observer);
+ g_object_unref (self->priv->event_manager);
+ g_object_unref (self->priv->ui_manager);
+ g_object_unref (self->priv->chatroom_manager);
+
+ g_object_unref (self->priv->gsettings_ui);
+ g_object_unref (self->priv->gsettings_contacts);
+ g_object_unref (self->priv->individual_manager);
+
+ G_OBJECT_CLASS (empathy_roster_window_parent_class)->finalize (window);
+}
+
+static gboolean
+roster_window_key_press_event_cb (GtkWidget *window,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ if (event->keyval == GDK_KEY_T
+ && event->state & GDK_SHIFT_MASK
+ && event->state & GDK_CONTROL_MASK)
+ empathy_chat_manager_call_undo_closed_chat ();
+
+ return FALSE;
+}
+
+static void
+roster_window_chat_quit_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ gtk_widget_destroy (GTK_WIDGET (self));
+}
+
+static void
+roster_window_view_history_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_log_window_show (NULL, NULL, FALSE, GTK_WINDOW (self));
+}
+
+static void
+roster_window_chat_new_message_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_new_message_dialog_show (GTK_WINDOW (self));
+}
+
+static void
+roster_window_chat_new_call_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_new_call_dialog_show (GTK_WINDOW (self));
+}
+
+static void
+roster_window_chat_add_contact_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_new_individual_dialog_show (GTK_WINDOW (self));
+}
+
+static void
+roster_window_chat_search_contacts_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ GtkWidget *dialog = empathy_contact_search_dialog_new (
+ GTK_WINDOW (self));
+
+ gtk_widget_show (dialog);
+}
+
+static void
+roster_window_view_show_ft_manager (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_ft_manager_show ();
+}
+
+static void
+roster_window_view_show_offline_cb (GtkToggleAction *action,
+ EmpathyRosterWindow *self)
+{
+ gboolean current;
+
+ current = gtk_toggle_action_get_active (action);
+ g_settings_set_boolean (self->priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_OFFLINE,
+ current);
+
+ empathy_individual_view_set_show_offline (self->priv->individual_view,
+ current);
+}
+
+static void
+roster_window_notify_sort_contact_cb (GSettings *gsettings,
+ const gchar *key,
+ EmpathyRosterWindow *self)
+{
+ gchar *str;
+
+ str = g_settings_get_string (gsettings, key);
+
+ if (str != NULL)
+ {
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ type = empathy_individual_store_sort_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_peek (type));
+ enum_value = g_enum_get_value_by_nick (enum_class, str);
+ if (enum_value)
+ {
+ /* By changing the value of the GtkRadioAction,
+ it emits a signal that calls roster_window_view_sort_contacts_cb
+ which updates the contacts list */
+ gtk_radio_action_set_current_value (self->priv->sort_by_name,
+ enum_value->value);
+ }
+ else
+ {
+ g_warning ("Wrong value for sort_criterium configuration : %s", str);
+ }
+ g_free (str);
+ }
+}
+
+static void
+roster_window_view_sort_contacts_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EmpathyRosterWindow *self)
+{
+ EmpathyIndividualStoreSort value;
+ GSList *group;
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ value = gtk_radio_action_get_current_value (action);
+ group = gtk_radio_action_get_group (action);
+
+ /* Get string from index */
+ type = empathy_individual_store_sort_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_peek (type));
+ enum_value = g_enum_get_value (enum_class, g_slist_index (group, current));
+
+ if (!enum_value)
+ g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioAction index:%d",
+ g_slist_index (group, action));
+ else
+ g_settings_set_string (self->priv->gsettings_contacts,
+ EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM,
+ enum_value->value_nick);
+
+ empathy_individual_store_set_sort_criterium (self->priv->individual_store,
+ value);
+}
+
+static void
+roster_window_view_show_protocols_cb (GtkToggleAction *action,
+ EmpathyRosterWindow *self)
+{
+ gboolean value;
+
+ value = gtk_toggle_action_get_active (action);
+
+ g_settings_set_boolean (self->priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_PROTOCOLS,
+ value);
+
+ empathy_individual_store_set_show_protocols (self->priv->individual_store,
+ value);
+}
+
+/* Matches GtkRadioAction values set in empathy-roster-window.ui */
+#define CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS 0
+#define CONTACT_LIST_NORMAL_SIZE 1
+#define CONTACT_LIST_COMPACT_SIZE 2
+
+static void
+roster_window_view_contacts_list_size_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EmpathyRosterWindow *self)
+{
+ GSettings *gsettings_ui;
+ gint value;
+
+ value = gtk_radio_action_get_current_value (action);
+ /* create a new GSettings, so we can delay the setting until both
+ * values are set */
+ gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
+
+ DEBUG ("radio button toggled, value = %i", value);
+
+ g_settings_delay (gsettings_ui);
+ g_settings_set_boolean (gsettings_ui, EMPATHY_PREFS_UI_SHOW_AVATARS,
+ value == CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS);
+
+ g_settings_set_boolean (gsettings_ui, EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST,
+ value == CONTACT_LIST_COMPACT_SIZE);
+ g_settings_apply (gsettings_ui);
+
+ /* FIXME: these enums probably have the wrong namespace */
+ empathy_individual_store_set_show_avatars (self->priv->individual_store,
+ value == CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS);
+ empathy_individual_store_set_is_compact (self->priv->individual_store,
+ value == CONTACT_LIST_COMPACT_SIZE);
+
+ g_object_unref (gsettings_ui);
+}
+
+static void roster_window_notify_show_protocols_cb (GSettings *gsettings,
+ const gchar *key,
+ EmpathyRosterWindow *self)
+{
+ gtk_toggle_action_set_active (self->priv->show_protocols,
+ g_settings_get_boolean (gsettings, EMPATHY_PREFS_UI_SHOW_PROTOCOLS));
+}
+
+
+static void
+roster_window_notify_contact_list_size_cb (GSettings *gsettings,
+ const gchar *key,
+ EmpathyRosterWindow *self)
+{
+ gint value;
+
+ if (g_settings_get_boolean (gsettings,
+ EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST))
+ value = CONTACT_LIST_COMPACT_SIZE;
+ else if (g_settings_get_boolean (gsettings,
+ EMPATHY_PREFS_UI_SHOW_AVATARS))
+ value = CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS;
+ else
+ value = CONTACT_LIST_NORMAL_SIZE;
+
+ DEBUG ("setting changed, value = %i", value);
+
+ /* By changing the value of the GtkRadioAction,
+ it emits a signal that calls roster_window_view_contacts_list_size_cb
+ which updates the contacts list */
+ gtk_radio_action_set_current_value (self->priv->normal_with_avatars, value);
+}
+
+static void
+roster_window_edit_search_contacts_cb (GtkCheckMenuItem *item,
+ EmpathyRosterWindow *self)
+{
+ empathy_individual_view_start_search (self->priv->individual_view);
+}
+
+static void
+roster_window_view_show_map_cb (GtkCheckMenuItem *item,
+ EmpathyRosterWindow *self)
+{
+#ifdef HAVE_LIBCHAMPLAIN
+ empathy_map_view_show ();
+#endif
+}
+
+static void
+join_chatroom (EmpathyChatroom *chatroom,
+ gint64 timestamp)
+{
+ TpAccount *account;
+ const gchar *room;
+
+ account = empathy_chatroom_get_account (chatroom);
+ room = empathy_chatroom_get_room (chatroom);
+
+ DEBUG ("Requesting channel for '%s'", room);
+ empathy_join_muc (account, room, timestamp);
+}
+
+typedef struct
+{
+ TpAccount *account;
+ EmpathyChatroom *chatroom;
+ gint64 timestamp;
+ glong sig_id;
+ guint timeout;
+} join_fav_account_sig_ctx;
+
+static join_fav_account_sig_ctx *
+join_fav_account_sig_ctx_new (TpAccount *account,
+ EmpathyChatroom *chatroom,
+ gint64 timestamp)
+{
+ join_fav_account_sig_ctx *ctx = g_slice_new0 (
+ join_fav_account_sig_ctx);
+
+ ctx->account = g_object_ref (account);
+ ctx->chatroom = g_object_ref (chatroom);
+ ctx->timestamp = timestamp;
+ return ctx;
+}
+
+static void
+join_fav_account_sig_ctx_free (join_fav_account_sig_ctx *ctx)
+{
+ g_object_unref (ctx->account);
+ g_object_unref (ctx->chatroom);
+ g_slice_free (join_fav_account_sig_ctx, ctx);
+}
+
+static void
+account_status_changed_cb (TpAccount *account,
+ TpConnectionStatus old_status,
+ TpConnectionStatus new_status,
+ guint reason,
+ gchar *dbus_error_name,
+ GHashTable *details,
+ gpointer user_data)
+{
+ join_fav_account_sig_ctx *ctx = user_data;
+
+ switch (new_status)
+ {
+ case TP_CONNECTION_STATUS_DISCONNECTED:
+ /* Don't wait any longer */
+ goto finally;
+ break;
+
+ case TP_CONNECTION_STATUS_CONNECTING:
+ /* Wait a bit */
+ return;
+
+ case TP_CONNECTION_STATUS_CONNECTED:
+ /* We can join the room */
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ join_chatroom (ctx->chatroom, ctx->timestamp);
+
+finally:
+ g_source_remove (ctx->timeout);
+ g_signal_handler_disconnect (account, ctx->sig_id);
+}
+
+#define JOIN_FAVORITE_TIMEOUT 5
+
+static gboolean
+join_favorite_timeout_cb (gpointer data)
+{
+ join_fav_account_sig_ctx *ctx = data;
+
+ /* stop waiting for joining the favorite room */
+ g_signal_handler_disconnect (ctx->account, ctx->sig_id);
+ return FALSE;
+}
+
+static void
+roster_window_favorite_chatroom_join (EmpathyChatroom *chatroom)
+{
+ TpAccount *account;
+
+ account = empathy_chatroom_get_account (chatroom);
+ if (tp_account_get_connection_status (account, NULL) !=
+ TP_CONNECTION_STATUS_CONNECTED)
+ {
+ join_fav_account_sig_ctx *ctx;
+
+ ctx = join_fav_account_sig_ctx_new (account, chatroom,
+ empathy_get_current_action_time ());
+
+ ctx->sig_id = g_signal_connect_data (account, "status-changed",
+ G_CALLBACK (account_status_changed_cb), ctx,
+ (GClosureNotify) join_fav_account_sig_ctx_free, 0);
+
+ ctx->timeout = g_timeout_add_seconds (JOIN_FAVORITE_TIMEOUT,
+ join_favorite_timeout_cb, ctx);
+ return;
+ }
+
+ join_chatroom (chatroom, empathy_get_current_action_time ());
+}
+
+static void
+roster_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item,
+ EmpathyChatroom *chatroom)
+{
+ roster_window_favorite_chatroom_join (chatroom);
+}
+
+static void
+roster_window_favorite_chatroom_menu_add (EmpathyRosterWindow *self,
+ EmpathyChatroom *chatroom)
+{
+ GtkWidget *menu_item;
+ const gchar *name, *account_name;
+ gchar *label;
+
+ if (g_object_get_data (G_OBJECT (chatroom), "menu_item"))
+ return;
+
+ name = empathy_chatroom_get_name (chatroom);
+ account_name = tp_account_get_display_name (
+ empathy_chatroom_get_account (chatroom));
+ label = g_strdup_printf ("%s (%s)", name, account_name);
+ menu_item = gtk_menu_item_new_with_label (label);
+ g_free (label);
+ g_object_set_data (G_OBJECT (menu_item), "is_favorite",
+ GUINT_TO_POINTER (TRUE));
+
+ g_object_set_data (G_OBJECT (chatroom), "menu_item", menu_item);
+ g_signal_connect (menu_item, "activate",
+ G_CALLBACK (roster_window_favorite_chatroom_menu_activate_cb),
+ chatroom);
+
+ gtk_menu_shell_insert (GTK_MENU_SHELL (self->priv->room_menu),
+ menu_item, 4);
+
+ gtk_widget_show (menu_item);
+}
+
+static void
+roster_window_favorite_chatroom_menu_added_cb (EmpathyChatroomManager *manager,
+ EmpathyChatroom *chatroom,
+ EmpathyRosterWindow *self)
+{
+ roster_window_favorite_chatroom_menu_add (self, chatroom);
+ gtk_widget_show (self->priv->room_separator);
+ gtk_action_set_sensitive (self->priv->room_join_favorites, TRUE);
+}
+
+static void
+roster_window_favorite_chatroom_menu_removed_cb (
+ EmpathyChatroomManager *manager,
+ EmpathyChatroom *chatroom,
+ EmpathyRosterWindow *self)
+{
+ GtkWidget *menu_item;
+ GList *chatrooms;
+
+ menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item");
+ g_object_set_data (G_OBJECT (chatroom), "menu_item", NULL);
+ gtk_widget_destroy (menu_item);
+
+ chatrooms = empathy_chatroom_manager_get_chatrooms (self->priv->chatroom_manager,
+ NULL);
+ if (chatrooms)
+ gtk_widget_show (self->priv->room_separator);
+ else
+ gtk_widget_hide (self->priv->room_separator);
+
+ gtk_action_set_sensitive (self->priv->room_join_favorites, chatrooms != NULL);
+ g_list_free (chatrooms);
+}
+
+static void
+roster_window_favorite_chatroom_menu_setup (EmpathyRosterWindow *self)
+{
+ GList *chatrooms, *l;
+ GtkWidget *room;
+
+ self->priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL);
+ chatrooms = empathy_chatroom_manager_get_chatrooms (
+ self->priv->chatroom_manager, NULL);
+ room = gtk_ui_manager_get_widget (self->priv->ui_manager,
+ "/menubar/room");
+ self->priv->room_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (room));
+ self->priv->room_separator = gtk_ui_manager_get_widget (self->priv->ui_manager,
+ "/menubar/room/room_separator");
+
+ for (l = chatrooms; l; l = l->next)
+ roster_window_favorite_chatroom_menu_add (self, l->data);
+
+ if (!chatrooms)
+ gtk_widget_hide (self->priv->room_separator);
+
+ gtk_action_set_sensitive (self->priv->room_join_favorites, chatrooms != NULL);
+
+ g_signal_connect (self->priv->chatroom_manager, "chatroom-added",
+ G_CALLBACK (roster_window_favorite_chatroom_menu_added_cb),
+ self);
+
+ g_signal_connect (self->priv->chatroom_manager, "chatroom-removed",
+ G_CALLBACK (roster_window_favorite_chatroom_menu_removed_cb),
+ self);
+
+ g_list_free (chatrooms);
+}
+
+static void
+roster_window_room_join_new_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_new_chatroom_dialog_show (GTK_WINDOW (self));
+}
+
+static void
+roster_window_room_join_favorites_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ GList *chatrooms, *l;
+
+ chatrooms = empathy_chatroom_manager_get_chatrooms (self->priv->chatroom_manager,
+ NULL);
+
+ for (l = chatrooms; l; l = l->next)
+ roster_window_favorite_chatroom_join (l->data);
+
+ g_list_free (chatrooms);
+}
+
+static void
+roster_window_room_manage_favorites_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_chatrooms_window_show (GTK_WINDOW (self));
+}
+
+static void
+roster_window_edit_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ GtkWidget *submenu;
+
+ /* FIXME: It should use the UIManager to merge the contact/group submenu */
+ submenu = empathy_individual_view_get_individual_menu (
+ self->priv->individual_view);
+ if (submenu)
+ {
+ GtkMenuItem *item;
+ GtkWidget *label;
+
+ item = GTK_MENU_ITEM (self->priv->edit_context);
+ label = gtk_bin_get_child (GTK_BIN (item));
+ gtk_label_set_text (GTK_LABEL (label), _("Contact"));
+
+ gtk_widget_show (self->priv->edit_context);
+ gtk_widget_show (self->priv->edit_context_separator);
+
+ gtk_menu_item_set_submenu (item, submenu);
+
+ return;
+ }
+
+ submenu = empathy_individual_view_get_group_menu (self->priv->individual_view);
+ if (submenu)
+ {
+ GtkMenuItem *item;
+ GtkWidget *label;
+
+ item = GTK_MENU_ITEM (self->priv->edit_context);
+ label = gtk_bin_get_child (GTK_BIN (item));
+ gtk_label_set_text (GTK_LABEL (label), _("Group"));
+
+ gtk_widget_show (self->priv->edit_context);
+ gtk_widget_show (self->priv->edit_context_separator);
+
+ gtk_menu_item_set_submenu (item, submenu);
+
+ return;
+ }
+
+ gtk_widget_hide (self->priv->edit_context);
+ gtk_widget_hide (self->priv->edit_context_separator);
+
+ return;
+}
+
+static void
+roster_window_edit_accounts_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_accounts_dialog_show_application (gdk_screen_get_default (),
+ NULL, FALSE, FALSE);
+}
+
+static void
+roster_window_edit_blocked_contacts_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ GtkWidget *dialog;
+
+ dialog = empathy_contact_blocking_dialog_new (GTK_WINDOW (self));
+ gtk_widget_show (dialog);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+}
+
+void
+empathy_roster_window_show_preferences (EmpathyRosterWindow *self,
+ const gchar *tab)
+{
+ if (self->priv->preferences == NULL)
+ {
+ self->priv->preferences = empathy_preferences_new (GTK_WINDOW (self),
+ self->priv->shell_running);
+ g_object_add_weak_pointer (G_OBJECT (self->priv->preferences),
+ (gpointer) &self->priv->preferences);
+
+ gtk_widget_show (self->priv->preferences);
+ }
+ else
+ {
+ gtk_window_present (GTK_WINDOW (self->priv->preferences));
+ }
+
+ if (tab != NULL)
+ empathy_preferences_show_tab (
+ EMPATHY_PREFERENCES (self->priv->preferences), tab);
+}
+
+static void
+roster_window_edit_preferences_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_roster_window_show_preferences (self, NULL);
+}
+
+static void
+roster_window_help_about_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_about_dialog_new (GTK_WINDOW (self));
+}
+
+static void
+roster_window_help_debug_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_launch_program (BIN_DIR, "empathy-debugger", NULL);
+}
+
+static void
+roster_window_help_contents_cb (GtkAction *action,
+ EmpathyRosterWindow *self)
+{
+ empathy_url_show (GTK_WIDGET (self), "ghelp:empathy");
+}
+
+static gboolean
+roster_window_throbber_button_press_event_cb (GtkWidget *throbber,
+ GdkEventButton *event,
+ EmpathyRosterWindow *self)
+{
+ if (event->type != GDK_BUTTON_PRESS ||
+ event->button != 1)
+ return FALSE;
+
+ empathy_accounts_dialog_show_application (
+ gtk_widget_get_screen (GTK_WIDGET (throbber)),
+ NULL, FALSE, FALSE);
+
+ return FALSE;
+}
+
+static void
+roster_window_account_removed_cb (TpAccountManager *manager,
+ TpAccount *account,
+ EmpathyRosterWindow *self)
+{
+ GList *a;
+
+ a = tp_account_manager_get_valid_accounts (manager);
+
+ gtk_action_set_sensitive (self->priv->view_history,
+ g_list_length (a) > 0);
+
+ g_list_free (a);
+
+ /* remove errors if any */
+ roster_window_remove_error (self, account);
+
+ /* remove the balance action if required */
+ roster_window_remove_balance_action (self, account);
+}
+
+static void
+account_connection_notify_cb (TpAccount *account,
+ GParamSpec *spec,
+ EmpathyRosterWindow *self)
+{
+ TpConnection *conn;
+
+ conn = tp_account_get_connection (account);
+
+ if (conn != NULL)
+ {
+ roster_window_setup_balance (self, account);
+ }
+ else
+ {
+ /* remove balance action if required */
+ roster_window_remove_balance_action (self, account);
+ }
+}
+
+static void
+add_account (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ gulong handler_id;
+
+ handler_id = GPOINTER_TO_UINT (g_hash_table_lookup (
+ self->priv->status_changed_handlers, account));
+
+ /* connect signal only if it was not connected yet */
+ if (handler_id != 0)
+ return;
+
+ handler_id = g_signal_connect (account, "status-changed",
+ G_CALLBACK (roster_window_connection_changed_cb), self);
+
+ g_hash_table_insert (self->priv->status_changed_handlers,
+ account, GUINT_TO_POINTER (handler_id));
+
+ /* roster_window_setup_balance() relies on the TpConnection to be ready on
+ * the TpAccount so we connect this signal as well. */
+ tp_g_signal_connect_object (account, "notify::connection",
+ G_CALLBACK (account_connection_notify_cb), self, 0);
+
+ roster_window_setup_balance (self, account);
+}
+
+/* @account: if not %NULL, the only account which can be enabled */
+static void
+display_page_account_not_enabled (EmpathyRosterWindow *self,
+ TpAccount *account)
+{
+ if (account == NULL)
+ {
+ display_page_message (self,
+ _("You need to enable one of your accounts to see contacts here."),
+ TRUE, FALSE);
+ }
+ else
+ {
+ gchar *tmp;
+
+ /* translators: argument is an account name */
+ tmp = g_strdup_printf (_("You need to enable %s to see contacts here."),
+ tp_account_get_display_name (account));
+
+ display_page_message (self, tmp, TRUE, FALSE);
+ g_free (tmp);
+ }
+}
+static gboolean
+has_enabled_account (GList *accounts)
+{
+ GList *l;
+
+ for (l = accounts; l != NULL; l = g_list_next (l))
+ {
+ TpAccount *account = l->data;
+
+ if (tp_account_is_enabled (account))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+set_notebook_page (EmpathyRosterWindow *self)
+{
+ GList *accounts;
+ guint len;
+
+ accounts = tp_account_manager_get_valid_accounts (
+ self->priv->account_manager);
+
+ len = g_list_length (accounts);
+
+ if (len == 0)
+ {
+ /* No account */
+ display_page_no_account (self);
+ goto out;
+ }
+
+ if (!has_enabled_account (accounts))
+ {
+ TpAccount *account = NULL;
+
+ /* Pass the account if there is only one which can be enabled */
+ if (len == 1)
+ account = accounts->data;
+
+ display_page_account_not_enabled (self, account);
+ goto out;
+ }
+
+ display_page_contact_list (self);
+
+out:
+ g_list_free (accounts);
+}
+
+static void
+roster_window_account_validity_changed_cb (TpAccountManager *manager,
+ TpAccount *account,
+ gboolean valid,
+ EmpathyRosterWindow *self)
+{
+ if (valid)
+ add_account (self, account);
+ else
+ roster_window_account_removed_cb (manager, account, self);
+
+ set_notebook_page (self);
+}
+
+static void
+roster_window_notify_show_offline_cb (GSettings *gsettings,
+ const gchar *key,
+ gpointer toggle_action)
+{
+ gtk_toggle_action_set_active (toggle_action,
+ g_settings_get_boolean (gsettings, key));
+}
+
+static void
+roster_window_connection_items_setup (EmpathyRosterWindow *self,
+ GtkBuilder *gui)
+{
+ GList *list;
+ GObject *action;
+ guint i;
+ const gchar *actions_connected[] = {
+ "room_join_new",
+ "room_join_favorites",
+ "chat_new_message",
+ "chat_new_call",
+ "chat_search_contacts",
+ "chat_add_contact",
+ "edit_blocked_contacts",
+ "edit_search_contacts"
+ };
+
+ for (i = 0, list = NULL; i < G_N_ELEMENTS (actions_connected); i++)
+ {
+ action = gtk_builder_get_object (gui, actions_connected[i]);
+ list = g_list_prepend (list, action);
+ }
+
+ self->priv->actions_connected = list;
+}
+
+static void
+account_enabled_cb (TpAccountManager *manager,
+ TpAccount *account,
+ EmpathyRosterWindow *self)
+{
+ set_notebook_page (self);
+}
+
+static void
+account_disabled_cb (TpAccountManager *manager,
+ TpAccount *account,
+ EmpathyRosterWindow *self)
+{
+ set_notebook_page (self);
+}
+
+static void
+account_manager_prepared_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GList *accounts, *j;
+ TpAccountManager *manager = TP_ACCOUNT_MANAGER (source_object);
+ EmpathyRosterWindow *self = user_data;
+ GError *error = NULL;
+
+ if (!tp_proxy_prepare_finish (manager, result, &error))
+ {
+ DEBUG ("Failed to prepare account manager: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ accounts = tp_account_manager_get_valid_accounts (self->priv->account_manager);
+ for (j = accounts; j != NULL; j = j->next)
+ {
+ TpAccount *account = TP_ACCOUNT (j->data);
+
+ add_account (self, account);
+ }
+
+ g_signal_connect (manager, "account-validity-changed",
+ G_CALLBACK (roster_window_account_validity_changed_cb), self);
+ tp_g_signal_connect_object (manager, "account-disabled",
+ G_CALLBACK (account_disabled_cb), self, 0);
+ tp_g_signal_connect_object (manager, "account-enabled",
+ G_CALLBACK (account_enabled_cb), self, 0);
+
+ roster_window_update_status (self);
+
+ /* Disable the "Previous Conversations" menu entry if there is no account */
+ gtk_action_set_sensitive (self->priv->view_history,
+ g_list_length (accounts) > 0);
+
+ set_notebook_page (self);
+
+ g_list_free (accounts);
+}
+
+void
+empathy_roster_window_set_shell_running (EmpathyRosterWindow *self,
+ gboolean shell_running)
+{
+ if (self->priv->shell_running == shell_running)
+ return;
+
+ self->priv->shell_running = shell_running;
+ g_object_notify (G_OBJECT (self), "shell-running");
+}
+
+static GObject *
+empathy_roster_window_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ static GObject *window = NULL;
+
+ if (window != NULL)
+ return g_object_ref (window);
+
+ window = G_OBJECT_CLASS (empathy_roster_window_parent_class)->constructor (
+ type, n_construct_params, construct_params);
+
+ g_object_add_weak_pointer (window, (gpointer) &window);
+
+ return window;
+}
+
+static void
+empathy_roster_window_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyRosterWindow *self = EMPATHY_ROSTER_WINDOW (object);
+
+ switch (property_id)
+ {
+ case PROP_SHELL_RUNNING:
+ self->priv->shell_running = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_roster_window_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyRosterWindow *self = EMPATHY_ROSTER_WINDOW (object);
+
+ switch (property_id)
+ {
+ case PROP_SHELL_RUNNING:
+ g_value_set_boolean (value, self->priv->shell_running);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+empathy_roster_window_class_init (EmpathyRosterWindowClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ object_class->finalize = empathy_roster_window_finalize;
+ object_class->constructor = empathy_roster_window_constructor;
+
+ object_class->set_property = empathy_roster_window_set_property;
+ object_class->get_property = empathy_roster_window_get_property;
+
+ pspec = g_param_spec_boolean ("shell-running",
+ "Shell running",
+ "Whether the Shell is running or not",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_SHELL_RUNNING, pspec);
+
+ g_type_class_add_private (object_class, sizeof (EmpathyRosterWindowPriv));
+}
+
+static void
+show_contacts_loading (EmpathyRosterWindow *self)
+{
+ display_page_message (self, NULL, FALSE, TRUE);
+
+ gtk_spinner_start (GTK_SPINNER (self->priv->spinner_loading));
+}
+
+static void
+hide_contacts_loading (EmpathyRosterWindow *self)
+{
+ gtk_spinner_stop (GTK_SPINNER (self->priv->spinner_loading));
+
+ display_page_contact_list (self);
+}
+
+static void
+contacts_loaded_cb (EmpathyIndividualManager *manager,
+ EmpathyRosterWindow *self)
+{
+ hide_contacts_loading (self);
+}
+
+static void
+empathy_roster_window_init (EmpathyRosterWindow *self)
+{
+ GtkBuilder *gui, *gui_mgr;
+ GtkWidget *sw;
+ GtkToggleAction *show_offline_widget;
+ GtkAction *show_map_widget;
+ GtkToolItem *item;
+ gboolean show_offline;
+ gchar *filename;
+ GtkTreeModel *model;
+ GtkWidget *search_vbox;
+ GtkWidget *menubar;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EMPATHY_TYPE_ROSTER_WINDOW, EmpathyRosterWindowPriv);
+
+ self->priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
+ self->priv->gsettings_contacts = g_settings_new (EMPATHY_PREFS_CONTACTS_SCHEMA);
+
+ self->priv->sound_mgr = empathy_sound_manager_dup_singleton ();
+
+ gtk_window_set_title (GTK_WINDOW (self), _("Contact List"));
+ gtk_window_set_role (GTK_WINDOW (self), "contact_list");
+ gtk_window_set_default_size (GTK_WINDOW (self), 225, 325);
+
+ /* don't finalize the widget on delete-event, just hide it */
+ g_signal_connect (self, "delete-event",
+ G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+
+ /* Set up interface */
+ filename = empathy_file_lookup ("empathy-roster-window.ui", "src");
+ gui = empathy_builder_get_file (filename,
+ "main_vbox", &self->priv->main_vbox,
+ "balance_vbox", &self->priv->balance_vbox,
+ "errors_vbox", &self->priv->errors_vbox,
+ "auth_vbox", &self->priv->auth_vbox,
+ "search_vbox", &search_vbox,
+ "presence_toolbar", &self->priv->presence_toolbar,
+ "notebook", &self->priv->notebook,
+ "no_entry_label", &self->priv->no_entry_label,
+ "roster_scrolledwindow", &sw,
+ "button_account_settings", &self->priv->button_account_settings,
+ "spinner_loading", &self->priv->spinner_loading,
+ NULL);
+ g_free (filename);
+
+ /* Set UI manager */
+ filename = empathy_file_lookup ("empathy-roster-window-menubar.ui", "src");
+ gui_mgr = empathy_builder_get_file (filename,
+ "ui_manager", &self->priv->ui_manager,
+ "view_show_offline", &show_offline_widget,
+ "view_show_protocols", &self->priv->show_protocols,
+ "view_sort_by_name", &self->priv->sort_by_name,
+ "view_sort_by_status", &self->priv->sort_by_status,
+ "view_normal_size_with_avatars", &self->priv->normal_with_avatars,
+ "view_normal_size", &self->priv->normal_size,
+ "view_compact_size", &self->priv->compact_size,
+ "view_history", &self->priv->view_history,
+ "view_show_map", &show_map_widget,
+ "room_join_favorites", &self->priv->room_join_favorites,
+ "view_balance_show_in_roster", &self->priv->view_balance_show_in_roster,
+ "menubar", &menubar,
+ NULL);
+ g_free (filename);
+
+ /* The UI manager is living in its own .ui file as Glade doesn't support
+ * those. The GtkMenubar has to be in this file as well to we manually add
+ * it to the first position of the vbox. */
+ gtk_box_pack_start (GTK_BOX (self->priv->main_vbox), menubar, FALSE, FALSE, 0);
+ gtk_box_reorder_child (GTK_BOX (self->priv->main_vbox), menubar, 0);
+
+ gtk_container_add (GTK_CONTAINER (self), self->priv->main_vbox);
+ gtk_widget_show (self->priv->main_vbox);
+
+ g_signal_connect (self, "key-press-event",
+ G_CALLBACK (roster_window_key_press_event_cb), NULL);
+
+ empathy_builder_connect (gui_mgr, self,
+ "chat_quit", "activate", roster_window_chat_quit_cb,
+ "chat_new_message", "activate", roster_window_chat_new_message_cb,
+ "chat_new_call", "activate", roster_window_chat_new_call_cb,
+ "view_history", "activate", roster_window_view_history_cb,
+ "room_join_new", "activate", roster_window_room_join_new_cb,
+ "room_join_favorites", "activate", roster_window_room_join_favorites_cb,
+ "room_manage_favorites", "activate", roster_window_room_manage_favorites_cb,
+ "chat_add_contact", "activate", roster_window_chat_add_contact_cb,
+ "chat_search_contacts", "activate", roster_window_chat_search_contacts_cb,
+ "view_show_ft_manager", "activate", roster_window_view_show_ft_manager,
+ "view_show_offline", "toggled", roster_window_view_show_offline_cb,
+ "view_show_protocols", "toggled", roster_window_view_show_protocols_cb,
+ "view_sort_by_name", "changed", roster_window_view_sort_contacts_cb,
+ "view_normal_size_with_avatars", "changed", roster_window_view_contacts_list_size_cb,
+ "view_show_map", "activate", roster_window_view_show_map_cb,
+ "edit", "activate", roster_window_edit_cb,
+ "edit_accounts", "activate", roster_window_edit_accounts_cb,
+ "edit_blocked_contacts", "activate", roster_window_edit_blocked_contacts_cb,
+ "edit_preferences", "activate", roster_window_edit_preferences_cb,
+ "edit_search_contacts", "activate", roster_window_edit_search_contacts_cb,
+ "help_about", "activate", roster_window_help_about_cb,
+ "help_debug", "activate", roster_window_help_debug_cb,
+ "help_contents", "activate", roster_window_help_contents_cb,
+ NULL);
+
+ /* Set up connection related widgets. */
+ roster_window_connection_items_setup (self, gui_mgr);
+
+ g_object_ref (self->priv->ui_manager);
+ g_object_unref (gui);
+ g_object_unref (gui_mgr);
+
+#ifndef HAVE_LIBCHAMPLAIN
+ gtk_action_set_visible (show_map_widget, FALSE);
+#endif
+
+ self->priv->account_manager = tp_account_manager_dup ();
+
+ tp_proxy_prepare_async (self->priv->account_manager, NULL,
+ account_manager_prepared_cb, self);
+
+ self->priv->errors = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ g_object_unref, NULL);
+
+ self->priv->auths = g_hash_table_new (NULL, NULL);
+
+ self->priv->status_changed_handlers = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal, NULL, NULL);
+
+ /* Set up menu */
+ roster_window_favorite_chatroom_menu_setup (self);
+
+ self->priv->edit_context = gtk_ui_manager_get_widget (self->priv->ui_manager,
+ "/menubar/edit/edit_context");
+ self->priv->edit_context_separator = gtk_ui_manager_get_widget (
+ self->priv->ui_manager,
+ "/menubar/edit/edit_context_separator");
+ gtk_widget_hide (self->priv->edit_context);
+ gtk_widget_hide (self->priv->edit_context_separator);
+
+ /* Set up contact list. */
+ empathy_status_presets_get_all ();
+
+ /* Set up presence chooser */
+ self->priv->presence_chooser = empathy_presence_chooser_new ();
+ gtk_widget_show (self->priv->presence_chooser);
+ item = gtk_tool_item_new ();
+ gtk_widget_show (GTK_WIDGET (item));
+ gtk_widget_set_size_request (self->priv->presence_chooser, 10, -1);
+ gtk_container_add (GTK_CONTAINER (item), self->priv->presence_chooser);
+ gtk_tool_item_set_is_important (item, TRUE);
+ gtk_tool_item_set_expand (item, TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (self->priv->presence_toolbar), item, -1);
+
+ /* Set up the throbber */
+ self->priv->throbber = gtk_spinner_new ();
+ gtk_widget_set_size_request (self->priv->throbber, 16, -1);
+ gtk_widget_set_events (self->priv->throbber, GDK_BUTTON_PRESS_MASK);
+ g_signal_connect (self->priv->throbber, "button-press-event",
+ G_CALLBACK (roster_window_throbber_button_press_event_cb),
+ self);
+ gtk_widget_show (self->priv->throbber);
+
+ item = gtk_tool_item_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (item), 6);
+ gtk_toolbar_insert (GTK_TOOLBAR (self->priv->presence_toolbar), item, -1);
+ gtk_container_add (GTK_CONTAINER (item), self->priv->throbber);
+ self->priv->throbber_tool_item = GTK_WIDGET (item);
+
+ /* XXX: this class is designed to live for the duration of the program,
+ * so it's got a race condition between its signal handlers and its
+ * finalization. The class is planned to be removed, so we won't fix
+ * this before then. */
+ self->priv->individual_manager = empathy_individual_manager_dup_singleton ();
+
+ if (!empathy_individual_manager_get_contacts_loaded (
+ self->priv->individual_manager))
+ {
+ show_contacts_loading (self);
+
+ tp_g_signal_connect_object (self->priv->individual_manager,
+ "contacts-loaded", G_CALLBACK (contacts_loaded_cb), self, 0);
+ }
+
+ self->priv->individual_store = EMPATHY_INDIVIDUAL_STORE (
+ empathy_individual_store_manager_new (self->priv->individual_manager));
+
+ /* For the moment, we disallow Persona drops onto the roster contact list
+ * (e.g. from things such as the EmpathyPersonaView in the linking dialogue).
+ * No code is hooked up to do anything on a Persona drop, so allowing them
+ * would achieve nothing except confusion. */
+ self->priv->individual_view = empathy_individual_view_new (
+ self->priv->individual_store,
+ /* EmpathyIndividualViewFeatureFlags */
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_GROUPS_SAVE |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_GROUPS_RENAME |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_GROUPS_REMOVE |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_GROUPS_CHANGE |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_INDIVIDUAL_REMOVE |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_INDIVIDUAL_DROP |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_INDIVIDUAL_DRAG |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_INDIVIDUAL_TOOLTIP |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_INDIVIDUAL_CALL |
+ EMPATHY_INDIVIDUAL_VIEW_FEATURE_FILE_DROP,
+ /* EmpathyIndividualFeatureFlags */
+ EMPATHY_INDIVIDUAL_FEATURE_CHAT |
+ EMPATHY_INDIVIDUAL_FEATURE_CALL |
+ EMPATHY_INDIVIDUAL_FEATURE_EDIT |
+ EMPATHY_INDIVIDUAL_FEATURE_INFO |
+ EMPATHY_INDIVIDUAL_FEATURE_SMS |
+ EMPATHY_INDIVIDUAL_FEATURE_CALL_PHONE);
+
+ gtk_widget_show (GTK_WIDGET (self->priv->individual_view));
+ gtk_container_add (GTK_CONTAINER (sw),
+ GTK_WIDGET (self->priv->individual_view));
+ g_signal_connect (self->priv->individual_view, "row-activated",
+ G_CALLBACK (roster_window_row_activated_cb), self);
+
+ /* Set up search bar */
+ self->priv->search_bar = empathy_live_search_new (
+ GTK_WIDGET (self->priv->individual_view));
+ empathy_individual_view_set_live_search (self->priv->individual_view,
+ EMPATHY_LIVE_SEARCH (self->priv->search_bar));
+ gtk_box_pack_start (GTK_BOX (search_vbox), self->priv->search_bar,
+ FALSE, TRUE, 0);
+
+ g_signal_connect_swapped (self, "map",
+ G_CALLBACK (gtk_widget_grab_focus), self->priv->individual_view);
+
+ /* Connect to proper signals to check if contact list is empty or not */
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->individual_view));
+ self->priv->empty = TRUE;
+ g_signal_connect (model, "row-inserted",
+ G_CALLBACK (roster_window_row_inserted_cb), self);
+ g_signal_connect (model, "row-deleted",
+ G_CALLBACK (roster_window_row_deleted_cb), self);
+
+ /* Load user-defined accelerators. */
+ roster_window_accels_load ();
+
+ /* Set window size. */
+ empathy_geometry_bind (GTK_WINDOW (self), GEOMETRY_NAME);
+
+ /* bind view_balance_show_in_roster */
+ g_settings_bind (self->priv->gsettings_ui, "show-balance-in-roster",
+ self->priv->view_balance_show_in_roster, "active",
+ G_SETTINGS_BIND_DEFAULT);
+ g_object_bind_property (self->priv->view_balance_show_in_roster, "active",
+ self->priv->balance_vbox, "visible",
+ G_BINDING_SYNC_CREATE);
+
+ g_settings_bind (self->priv->gsettings_ui, "show-groups",
+ self->priv->individual_store, "show-groups", G_SETTINGS_BIND_DEFAULT);
+
+ /* Enable event handling */
+ self->priv->call_observer = empathy_call_observer_dup_singleton ();
+ self->priv->event_manager = empathy_event_manager_dup_singleton ();
+
+ g_signal_connect (self->priv->event_manager, "event-added",
+ G_CALLBACK (roster_window_event_added_cb), self);
+ g_signal_connect (self->priv->event_manager, "event-removed",
+ G_CALLBACK (roster_window_event_removed_cb), self);
+ g_signal_connect (self->priv->account_manager, "account-validity-changed",
+ G_CALLBACK (roster_window_account_validity_changed_cb), self);
+ g_signal_connect (self->priv->account_manager, "account-removed",
+ G_CALLBACK (roster_window_account_removed_cb), self);
+ g_signal_connect (self->priv->account_manager, "account-disabled",
+ G_CALLBACK (roster_window_account_disabled_cb), self);
+
+ /* Show offline ? */
+ show_offline = g_settings_get_boolean (self->priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_OFFLINE);
+
+ g_signal_connect (self->priv->gsettings_ui,
+ "changed::" EMPATHY_PREFS_UI_SHOW_OFFLINE,
+ G_CALLBACK (roster_window_notify_show_offline_cb), show_offline_widget);
+
+ gtk_toggle_action_set_active (show_offline_widget, show_offline);
+
+ /* Show protocol ? */
+ g_signal_connect (self->priv->gsettings_ui,
+ "changed::" EMPATHY_PREFS_UI_SHOW_PROTOCOLS,
+ G_CALLBACK (roster_window_notify_show_protocols_cb), self);
+
+ roster_window_notify_show_protocols_cb (self->priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_PROTOCOLS, self);
+
+ /* Sort by name / by status ? */
+ g_signal_connect (self->priv->gsettings_contacts,
+ "changed::" EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM,
+ G_CALLBACK (roster_window_notify_sort_contact_cb), self);
+
+ roster_window_notify_sort_contact_cb (self->priv->gsettings_contacts,
+ EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, self);
+
+ /* Contacts list size */
+ g_signal_connect (self->priv->gsettings_ui,
+ "changed::" EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST,
+ G_CALLBACK (roster_window_notify_contact_list_size_cb), self);
+
+ g_signal_connect (self->priv->gsettings_ui,
+ "changed::" EMPATHY_PREFS_UI_SHOW_AVATARS,
+ G_CALLBACK (roster_window_notify_contact_list_size_cb),
+ self);
+
+ roster_window_notify_contact_list_size_cb (self->priv->gsettings_ui,
+ EMPATHY_PREFS_UI_SHOW_AVATARS, self);
+
+ g_signal_connect (self->priv->button_account_settings, "clicked",
+ G_CALLBACK (button_account_settings_clicked_cb), self);
+}
+
+GtkWidget *
+empathy_roster_window_dup (void)
+{
+ return g_object_new (EMPATHY_TYPE_ROSTER_WINDOW, NULL);
+}
diff --git a/src/empathy-roster-window.h b/src/empathy-roster-window.h
new file mode 100644
index 000000000..54404ad38
--- /dev/null
+++ b/src/empathy-roster-window.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2002-2007 Imendio AB
+ * Copyright (C) 2007-2008 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: Xavier Claessens <xclaesse@gmail.com>
+ * Danielle Madeley <danielle.madeley@collabora.co.uk>
+ */
+
+#ifndef __EMPATHY_ROSTER_WINDOW_H__
+#define __EMPATHY_ROSTER_WINDOW_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_ROSTER_WINDOW (empathy_roster_window_get_type ())
+#define EMPATHY_ROSTER_WINDOW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_ROSTER_WINDOW, EmpathyRosterWindow))
+#define EMPATHY_ROSTER_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_ROSTER_WINDOW, EmpathyRosterWindowClass))
+#define EMPATHY_IS_ROSTER_WINDOW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_ROSTER_WINDOW))
+#define EMPATHY_IS_ROSTER_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_ROSTER_WINDOW))
+#define EMPATHY_ROSTER_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_ROSTER_WINDOW, EmpathyRosterWindowClass))
+
+typedef struct _EmpathyRosterWindow EmpathyRosterWindow;
+typedef struct _EmpathyRosterWindowClass EmpathyRosterWindowClass;
+typedef struct _EmpathyRosterWindowPriv EmpathyRosterWindowPriv;
+
+struct _EmpathyRosterWindow
+{
+ GtkWindow parent;
+ EmpathyRosterWindowPriv *priv;
+};
+
+struct _EmpathyRosterWindowClass
+{
+ GtkWindowClass parent_class;
+};
+
+GType empathy_roster_window_get_type (void);
+
+GtkWidget *empathy_roster_window_dup (void);
+
+void empathy_roster_window_show_preferences (EmpathyRosterWindow *self,
+ const gchar *tab);
+
+void empathy_roster_window_set_shell_running (EmpathyRosterWindow *self,
+ gboolean shell_running);
+
+G_END_DECLS
+
+#endif /* __EMPATHY_ROSTER_WINDOW_H__ */
diff --git a/src/empathy-main-window.ui b/src/empathy-roster-window.ui
index a09d123f8..8c8f63001 100644
--- a/src/empathy-main-window.ui
+++ b/src/empathy-roster-window.ui
@@ -91,10 +91,82 @@
</object>
</child>
<child>
- <object class="GtkLabel" id="no_entry_label">
+ <object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="yalign">0.30000001192092896</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="yalign">1</property>
+ <property name="ypad">1</property>
+ <property name="icon_name">avatar-default</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="no_entry_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="yalign">0.30000001192092896</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkButton" id="button_account_settings">
+ <property name="label" translatable="yes">Account settings</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="use_action_appearance">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="yalign">0</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkSpinner" id="spinner_loading">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">1</property>
diff --git a/src/empathy-rounded-actor.c b/src/empathy-rounded-actor.c
index 0537dea96..045f08de7 100644
--- a/src/empathy-rounded-actor.c
+++ b/src/empathy-rounded-actor.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
#include <clutter/clutter.h>
#include <clutter-gtk/clutter-gtk.h>
diff --git a/src/empathy-rounded-rectangle.c b/src/empathy-rounded-rectangle.c
index e06889d58..4cce28b06 100644
--- a/src/empathy-rounded-rectangle.c
+++ b/src/empathy-rounded-rectangle.c
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+
#include <math.h>
#include <clutter/clutter.h>
diff --git a/src/empathy.c b/src/empathy.c
index b73bf1b03..f59a54f17 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -48,6 +48,8 @@
#include <telepathy-logger/log-manager.h>
+#include <libempathy/empathy-client-factory.h>
+#include <libempathy/empathy-connection-aggregator.h>
#include <libempathy/empathy-presence-manager.h>
#include <libempathy/empathy-utils.h>
#include <libempathy/empathy-chatroom-manager.h>
@@ -63,7 +65,7 @@
#include <libempathy-gtk/empathy-location-manager.h>
#include <libempathy-gtk/empathy-notify-manager.h>
-#include "empathy-main-window.h"
+#include "empathy-roster-window.h"
#include "empathy-accounts-common.h"
#include "empathy-accounts-dialog.h"
#include "empathy-status-icon.h"
@@ -122,6 +124,7 @@ struct _EmpathyApp
EmpathyConnectivity *connectivity;
GSettings *gsettings;
EmpathyNotificationsApprover *notifications_approver;
+ EmpathyConnectionAggregator *conn_aggregator;
#ifdef HAVE_GEOCLUE
EmpathyLocationManager *location_manager;
#endif
@@ -167,6 +170,7 @@ empathy_app_dispose (GObject *object)
tp_clear_object (&self->ft_factory);
tp_clear_object (&self->gsettings);
tp_clear_object (&self->notifications_approver);
+ tp_clear_object (&self->conn_aggregator);
if (dispose != NULL)
dispose (object);
@@ -285,8 +289,8 @@ out:
/* Rely on GNOME Shell to watch session state */
empathy_presence_manager_set_auto_away (self->presence_mgr, FALSE);
- empathy_main_window_set_shell_running (EMPATHY_MAIN_WINDOW (self->window),
- TRUE);
+ empathy_roster_window_set_shell_running (
+ EMPATHY_ROSTER_WINDOW (self->window), TRUE);
}
else
{
@@ -351,7 +355,7 @@ empathy_app_command_line (GApplication *app,
self->activated = TRUE;
/* Setting up UI */
- self->window = empathy_main_window_dup ();
+ self->window = empathy_roster_window_dup ();
gtk_application_add_window (GTK_APPLICATION (app),
GTK_WINDOW (self->window));
@@ -377,8 +381,8 @@ empathy_app_command_line (GApplication *app,
}
if (self->show_preferences)
- empathy_main_window_show_preferences (EMPATHY_MAIN_WINDOW (self->window),
- self->preferences_tab);
+ empathy_roster_window_show_preferences (
+ EMPATHY_ROSTER_WINDOW (self->window), self->preferences_tab);
if (!self->start_hidden)
empathy_window_present (GTK_WINDOW (self->window));
@@ -808,11 +812,34 @@ empathy_app_constructed (GObject *object)
self->location_manager = empathy_location_manager_dup_singleton ();
#endif
+ self->conn_aggregator = empathy_connection_aggregator_dup_singleton ();
+
self->activated = FALSE;
self->ft_factory = NULL;
self->window = NULL;
}
+static void
+add_empathy_features (void)
+{
+ /* Add 'empathy' specific feature before doing any preparation */
+ EmpathyClientFactory *factory;
+
+ factory = empathy_client_factory_dup ();
+
+ tp_simple_client_factory_add_connection_features_varargs (
+ TP_SIMPLE_CLIENT_FACTORY (factory),
+ /* empathy_connection_aggregator_get_all_groups(), used by
+ * EmpathyGroupsWidget relies on it */
+ TP_CONNECTION_FEATURE_CONTACT_GROUPS,
+ /* empathy_connection_aggregator_dup_all_contacts(), used by
+ * EmpathyEventManager relies on it */
+ TP_CONNECTION_FEATURE_CONTACT_LIST,
+ NULL);
+
+ g_object_unref (factory);
+}
+
int
main (int argc, char *argv[])
{
@@ -832,6 +859,8 @@ main (int argc, char *argv[])
gtk_init (&argc, &argv);
empathy_gtk_init ();
+ add_empathy_features ();
+
app = g_object_new (EMPATHY_TYPE_APP,
"application-id", EMPATHY_DBUS_NAME,
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,