diff options
Diffstat (limited to 'src')
47 files changed, 2269 insertions, 2772 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 06eaf1733..dfde20558 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,6 @@ include $(top_srcdir)/tools/flymake.mk CPPFLAGS_COMMON = \ - $(YELL_CFLAGS) \ $(EMPATHY_CFLAGS) \ $(EDS_CFLAGS) \ $(ERROR_CFLAGS) \ @@ -24,7 +23,6 @@ LDADD = \ $(top_builddir)/extensions/libemp-extensions.la \ $(GCR_LIBS) \ $(EMPATHY_LIBS) \ - $(YELL_LIBS) \ $(LIBCHAMPLAIN_LIBS) \ $(NULL) @@ -32,9 +30,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 \ @@ -56,7 +52,7 @@ bin_PROGRAMS = \ libexec_PROGRAMS = \ empathy-auth-client \ - empathy-av \ + empathy-call \ empathy-chat empathy_accounts_SOURCES = \ @@ -73,6 +69,7 @@ empathy_debugger_SOURCES = \ empathy-debugger.c \ $(NULL) +if HAVE_EMPATHY_AV empathy_av_SOURCES = \ empathy-av.c \ empathy-audio-sink.c \ @@ -100,7 +97,12 @@ empathy_av_SOURCES = \ empathy_av_CFLAGS = $(EMPATHY_AV_CFLAGS) empathy_av_LDFLAGS = $(EMPATHY_AV_LIBS) $(LIBM) +libexec_PROGRAMS += empathy-av + +endif + empathy_auth_client_SOURCES = \ + empathy-sanity-cleaning.c empathy-sanity-cleaning.h \ empathy-auth-client.c \ $(NULL) @@ -113,10 +115,6 @@ empathy_chat_SOURCES = \ gedit-close-button.c gedit-close-button.h \ $(NULL) -if HAVE_CALL - -libexec_PROGRAMS += empathy-call - empathy_call_SOURCES = \ empathy-call.c \ empathy-call-factory.c \ @@ -139,8 +137,6 @@ empathy_call_SOURCES = \ empathy-video-widget.h \ empathy-preferences.c \ empathy-preferences.h \ - ev-sidebar.c \ - ev-sidebar.h \ empathy-camera-menu.c \ empathy-camera-menu.h \ empathy-mic-menu.c \ @@ -157,8 +153,6 @@ empathy_call_SOURCES = \ empathy_call_CFLAGS = $(EMPATHY_CALL_CFLAGS) empathy_call_LDFLAGS = $(EMPATHY_CALL_LIBS) -endif - empathy_handwritten_source = \ empathy-about-dialog.c empathy-about-dialog.h \ empathy-chat-window.c empathy-chat-window.h \ @@ -192,7 +186,12 @@ empathy_LDADD = \ check_c_sources = \ $(empathy_handwritten_source) \ $(empathy_logs_SOURCES) \ - $(empathy_handwritten_av_source) + $(libempathy_accounts_common_la_SOURCES) \ + $(empathy_accounts_SOURCES) \ + $(empathy_debugger_SOURCES) \ + $(empathy_auth_client_SOURCES) \ + $(empathy_chat_SOURCES) \ + $(empathy_call_SOURCES) include $(top_srcdir)/tools/check-coding-style.mk check-local: check-coding-style diff --git a/src/empathy-account-assistant.c b/src/empathy-account-assistant.c deleted file mode 100644 index 0a5f1d76b..000000000 --- a/src/empathy-account-assistant.c +++ /dev/null @@ -1,1309 +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); - } - - empathy_account_widget_hide_buttons (widget_object); - - 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 0e33de2a6..189f22b58 100644 --- a/src/empathy-accounts-dialog.c +++ b/src/empathy-accounts-dialog.c @@ -41,6 +41,7 @@ #include <libempathy/empathy-utils.h> #include <libempathy/empathy-connection-managers.h> #include <libempathy/empathy-connectivity.h> +#include <libempathy/empathy-pkg-kit.h> #include <libempathy/empathy-tp-contact-factory.h> #include <libempathy-gtk/empathy-ui-utils.h> @@ -51,8 +52,10 @@ #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" @@ -78,7 +81,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 { @@ -91,7 +95,6 @@ typedef struct { GtkWidget *image_status; GtkWidget *throbber; GtkWidget *enabled_switch; - GtkWidget *frame_no_protocol; GtkWidget *treeview; @@ -99,8 +102,6 @@ typedef struct { GtkWidget *button_remove; GtkWidget *button_import; - GtkWidget *hbox_protocol; - GtkWidget *image_type; GtkWidget *label_name; GtkWidget *label_type; @@ -161,21 +162,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, @@ -220,6 +213,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); } @@ -267,6 +263,21 @@ accounts_dialog_enable_switch_active_cb (GtkSwitch *sw, } static void +install_haze_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + if (!empathy_pkg_kit_install_packages_finish (result, &error)) + { + DEBUG ("Failed to install telepathy-haze: %s", error->message); + + g_error_free (error); + } +} + +static void accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog, TpAccount *account) { @@ -283,6 +294,7 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog, gboolean account_enabled; gboolean creating_account; TpStorageRestrictionFlags storage_restrictions = 0; + gboolean display_switch = TRUE; view = GTK_TREE_VIEW (priv->treeview); selection = gtk_tree_view_get_selection (view); @@ -319,6 +331,13 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog, presence = TP_CONNECTION_PRESENCE_TYPE_OFFLINE; storage_restrictions = tp_account_get_storage_restrictions (account); + if (storage_restrictions & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED) + display_switch = FALSE; + + /* Butterfly accounts shouldn't be used any more */ + if (!tp_strdiff (tp_account_get_connection_manager (account), + "butterfly")) + display_switch = FALSE; } else { @@ -340,8 +359,7 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog, accounts_dialog_enable_switch_active_cb, dialog); /* Display the Enable switch if account supports it */ - gtk_widget_set_visible (priv->enabled_switch, - !(storage_restrictions & TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED)); + gtk_widget_set_visible (priv->enabled_switch, display_switch); if (account_enabled) { @@ -431,8 +449,24 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog, } else { - accounts_dialog_status_infobar_set_message (dialog, - _("Offline — Account Disabled")); + if (!tp_strdiff (tp_account_get_connection_manager (account), + "butterfly")) + { + const gchar *packages[] = { "telepathy-haze", NULL }; + + accounts_dialog_status_infobar_set_message (dialog, + _("This account has been disabled because it relies on an old, " + "unsupported backend. Please install telepathy-haze and " + "restart your session to migrate the account.")); + + empathy_pkg_kit_install_packages_async (0, packages, NULL, NULL, + install_haze_cb, NULL); + } + else + { + accounts_dialog_status_infobar_set_message (dialog, + _("Offline — Account Disabled")); + } gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar), GTK_MESSAGE_WARNING); @@ -534,6 +568,8 @@ account_dialog_create_edit_params_dialog (EmpathyAccountsDialog *dialog) GtkWidget *subdialog, *content, *content_area, *align; settings = accounts_dialog_model_get_selected_settings (dialog); + if (settings == NULL) + return; subdialog = gtk_dialog_new_with_buttons (_("Edit Connection Parameters"), GTK_WINDOW (dialog), @@ -667,6 +703,8 @@ account_dialow_show_edit_params_dialog (EmpathyAccountsDialog *dialog, TpStorageRestrictionFlags storage_restrictions; settings = accounts_dialog_model_get_selected_settings (dialog); + if (settings == NULL) + return; account = empathy_account_settings_get_account (settings); g_return_if_fail (account != NULL); @@ -940,12 +978,16 @@ accounts_dialog_button_add_clicked_cb (GtkWidget *button, if (response == GTK_RESPONSE_OK) { EmpathyAccountSettings *settings; + TpAccount *account; settings = empathy_new_account_dialog_get_settings ( EMPATHY_NEW_ACCOUNT_DIALOG (dialog)); - accounts_dialog_add (self, settings); - accounts_dialog_model_set_selected (self, settings); + /* 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); } gtk_widget_destroy (dialog); @@ -984,28 +1026,19 @@ 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->dialog_content) { @@ -1585,41 +1618,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) @@ -1637,15 +1635,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; @@ -1678,11 +1676,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); } @@ -1781,27 +1779,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, @@ -1925,6 +1902,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); @@ -1932,15 +1910,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); } @@ -1980,31 +1961,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 @@ -2083,15 +2045,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 @@ -2127,6 +2098,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); @@ -2147,6 +2197,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 @@ -2289,14 +2341,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, @@ -2304,8 +2354,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, @@ -2387,7 +2435,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 fbffa4885..2968fb53c 100644 --- a/src/empathy-audio-sink.c +++ b/src/empathy-audio-sink.c @@ -355,6 +355,8 @@ empathy_audio_sink_request_new_pad (GstElement *element, goto error; subpad = gst_ghost_pad_new ("sink", filterpad); + gst_object_unref (filterpad); + if (!gst_element_add_pad (GST_ELEMENT (bin), subpad)) goto error; diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index 22a625229..ecf1ad173 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -41,6 +41,8 @@ #include <libempathy-gtk/empathy-tls-dialog.h> #include <libempathy-gtk/empathy-ui-utils.h> +#include "empathy-sanity-cleaning.h" + #include <gnutls/gnutls.h> #include <extensions/extensions.h> @@ -351,6 +353,7 @@ main (int argc, } start_timer (); + empathy_sanity_checking_run_if_needed (); gtk_main (); 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-call-factory.c b/src/empathy-call-factory.c index b3c85f4b0..95c828d94 100644 --- a/src/empathy-call-factory.c +++ b/src/empathy-call-factory.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> @@ -27,8 +28,6 @@ #include <telepathy-glib/interfaces.h> #include <telepathy-glib/util.h> -#include <telepathy-yell/telepathy-yell.h> - #include <libempathy/empathy-client-factory.h> #include <libempathy/empathy-request-util.h> #include <libempathy/empathy-tp-contact-factory.h> @@ -76,39 +75,41 @@ empathy_call_factory_init (EmpathyCallFactory *obj) tp_base_client_take_approver_filter (client, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TPY_IFACE_CHANNEL_TYPE_CALL, + TP_IFACE_CHANNEL_TYPE_CALL, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, NULL)); tp_base_client_take_handler_filter (client, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TPY_IFACE_CHANNEL_TYPE_CALL, + TP_IFACE_CHANNEL_TYPE_CALL, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, NULL)); tp_base_client_take_handler_filter (client, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TPY_IFACE_CHANNEL_TYPE_CALL, + TP_IFACE_CHANNEL_TYPE_CALL, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, - TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, G_TYPE_BOOLEAN, TRUE, + TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, G_TYPE_BOOLEAN, TRUE, NULL)); tp_base_client_take_handler_filter (client, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TPY_IFACE_CHANNEL_TYPE_CALL, + TP_IFACE_CHANNEL_TYPE_CALL, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, - TPY_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, G_TYPE_BOOLEAN, TRUE, + TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, G_TYPE_BOOLEAN, TRUE, NULL)); tp_base_client_add_handler_capabilities_varargs (client, - "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/ice-udp", - "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/gtalk-p2p", - "org.freedesktop.Telepathy.Channel.Interface.MediaSignalling/video/h264", - NULL); + "org.freedesktop.Telepathy.Channel.Type.Call1/audio", + "org.freedesktop.Telepathy.Channel.Type.Call1/video", + "org.freedesktop.Telepathy.Channel.Type.Call1/ice", + "org.freedesktop.Telepathy.Channel.Type.Call1/gtalk-p2p", + "org.freedesktop.Telepathy.Channel.Type.Call1/video/h264", + NULL); } static GObject * @@ -151,7 +152,7 @@ empathy_call_factory_class_init (EmpathyCallFactoryClass *klass) NULL, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, - 4, G_TYPE_UINT, TPY_TYPE_CALL_CHANNEL, + 4, G_TYPE_UINT, TP_TYPE_CALL_CHANNEL, TP_TYPE_CHANNEL_DISPATCH_OPERATION, TP_TYPE_ADD_DISPATCH_OPERATION_CONTEXT); } @@ -189,66 +190,6 @@ empathy_call_factory_get (void) } static void -call_channel_got_contact (TpConnection *connection, - EmpathyContact *contact, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - EmpathyCallFactory *factory = EMPATHY_CALL_FACTORY (weak_object); - EmpathyCallHandler *handler; - TpyCallChannel *call = TPY_CALL_CHANNEL (user_data); - - if (contact == NULL) - { - /* FIXME use hangup with an appropriate error */ - tp_channel_close_async (TP_CHANNEL (call), NULL, NULL); - return; - } - - handler = empathy_call_handler_new_for_channel (call, contact); - - g_signal_emit (factory, signals[NEW_CALL_HANDLER], 0, - handler, FALSE); - - g_object_unref (handler); -} - -static void -call_channel_ready (EmpathyCallFactory *factory, - TpyCallChannel *call) -{ - TpChannel *channel = TP_CHANNEL (call); - const gchar *id; - - id = tp_channel_get_identifier (channel); - - /* The ready callback has a reference, so pass that on */ - empathy_tp_contact_factory_get_from_id ( - tp_channel_borrow_connection (channel), - id, - call_channel_got_contact, - channel, - g_object_unref, - (GObject *) factory); -} - -static void -call_channel_ready_cb (TpyCallChannel *call, - GParamSpec *spec, - EmpathyCallFactory *factory) -{ - gboolean ready; - - g_object_get (call, "ready", &ready, NULL); - if (!ready) - return; - - call_channel_ready (factory, call); -} - - -static void handle_channels (TpBaseClient *client, TpAccount *account, TpConnection *connection, @@ -263,36 +204,38 @@ handle_channels (TpBaseClient *client, for (l = channels; l != NULL; l = g_list_next (l)) { TpChannel *channel = l->data; - TpyCallChannel *call; - gboolean ready; + TpCallChannel *call; + TpContact *tp_contact; + EmpathyContact *contact; + EmpathyCallHandler *handler; if (tp_proxy_get_invalidated (channel) != NULL) continue; if (tp_channel_get_channel_type_id (channel) != - TPY_IFACE_QUARK_CHANNEL_TYPE_CALL) + TP_IFACE_QUARK_CHANNEL_TYPE_CALL) continue; - if (!TPY_IS_CALL_CHANNEL (channel)) + if (!TP_IS_CALL_CHANNEL (channel)) continue; - call = TPY_CALL_CHANNEL (channel); + call = TP_CALL_CHANNEL (channel); + + tp_contact = tp_channel_get_target_contact (channel); + contact = empathy_contact_dup_from_tp_contact (tp_contact); + handler = empathy_call_handler_new_for_channel (call, contact); - /* Take a ref to keep while hopping through the async callbacks */ - g_object_ref (call); - g_object_get (call, "ready", &ready, NULL); + g_signal_emit (self, signals[NEW_CALL_HANDLER], 0, + handler, FALSE); - if (!ready) - tp_g_signal_connect_object (call, "notify::ready", - G_CALLBACK (call_channel_ready_cb), self, 0); - else - call_channel_ready (self, call); + g_object_unref (handler); + g_object_unref (contact); } tp_handle_channels_context_accept (context); } -static TpyCallChannel * +static TpCallChannel * find_call_channel (GList *channels) { GList *l; @@ -307,8 +250,8 @@ find_call_channel (GList *channels) channel_type = tp_channel_get_channel_type_id (channel); - if (channel_type == TPY_IFACE_QUARK_CHANNEL_TYPE_CALL) - return TPY_CALL_CHANNEL (channel); + if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL) + return TP_CALL_CHANNEL (channel); } return NULL; @@ -323,7 +266,7 @@ approve_channels (TpBaseClient *client, TpAddDispatchOperationContext *context) { EmpathyCallFactory *self = EMPATHY_CALL_FACTORY (client); - TpyCallChannel *channel; + TpCallChannel *channel; guint handle; GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "" }; gboolean handled = FALSE; diff --git a/src/empathy-call-handler.c b/src/empathy-call-handler.c index 4014ad6c6..33ae9c709 100644 --- a/src/empathy-call-handler.c +++ b/src/empathy-call-handler.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> @@ -26,8 +27,6 @@ #include <telepathy-glib/util.h> #include <telepathy-glib/interfaces.h> -#include <telepathy-yell/telepathy-yell.h> - #include <telepathy-farstream/telepathy-farstream.h> #include <libempathy/empathy-utils.h> @@ -63,7 +62,6 @@ enum { PROP_CALL_CHANNEL = 1, PROP_GST_BUS, PROP_CONTACT, - PROP_MEMBERS, PROP_INITIAL_AUDIO, PROP_INITIAL_VIDEO, PROP_SEND_AUDIO_CODEC, @@ -79,11 +77,9 @@ enum { /* private structure */ struct _EmpathyCallHandlerPriv { - TpyCallChannel *call; + TpCallChannel *call; EmpathyContact *contact; - /* GArray of TpContacts */ - GArray *members; TfChannel *tfchannel; gboolean initial_audio; gboolean initial_video; @@ -96,6 +92,7 @@ struct _EmpathyCallHandlerPriv { FsCandidate *video_remote_candidate; FsCandidate *audio_local_candidate; FsCandidate *video_local_candidate; + gboolean accept_when_initialised; }; #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyCallHandler) @@ -109,8 +106,6 @@ empathy_call_handler_dispose (GObject *object) tp_clear_object (&priv->call); tp_clear_object (&priv->contact); - tp_clear_pointer (&priv->members, g_array_unref); - G_OBJECT_CLASS (empathy_call_handler_parent_class)->dispose (object); } @@ -141,36 +136,22 @@ empathy_call_handler_init (EmpathyCallHandler *obj) } static void -on_get_contacts_cb (TpConnection *connection, - guint n_contacts, - EmpathyContact * const * contacts, - guint n_failed, - const TpHandle *failed, - const GError *error, - gpointer user_data, - GObject *weak_object) +on_call_accepted_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (weak_object); - EmpathyCallHandlerPriv *priv = GET_PRIV (self); - guint i; - - if (n_failed > 0) - g_warning ("Failed to get %d EmpathyContacts: %s", - n_failed, error->message); - - priv->members = g_array_sized_new (FALSE, TRUE, - sizeof (EmpathyContact *), n_contacts); - - for (i = 0; i < n_contacts; i++) - g_object_ref (contacts[i]); - - g_array_append_vals (priv->members, contacts, n_contacts); + TpCallChannel *call = TP_CALL_CHANNEL (source_object); + GError *error = NULL; - g_object_notify (G_OBJECT (self), "members"); + if (!tp_call_channel_accept_finish (call, res, &error)) + { + g_warning ("could not accept Call: %s", error->message); + g_error_free (error); + } } static void -on_call_invalidated_cb (TpyCallChannel *call, +on_call_invalidated_cb (TpCallChannel *call, guint domain, gint code, gchar *message, @@ -182,91 +163,43 @@ on_call_invalidated_cb (TpyCallChannel *call, { /* Invalidated unexpectedly? Fake call ending */ g_signal_emit (self, signals[STATE_CHANGED], 0, - TPY_CALL_STATE_ENDED, NULL); + TP_CALL_STATE_ENDED, NULL); + priv->accept_when_initialised = FALSE; tp_clear_object (&priv->call); tp_clear_object (&priv->tfchannel); } } static void -on_call_state_changed_cb (TpyCallChannel *call, - TpyCallState state, - TpyCallFlags flags, - const GValueArray *call_state_reason, - GHashTable *call_state_details, +on_call_state_changed_cb (TpCallChannel *call, + TpCallState state, + TpCallFlags flags, + TpCallStateReason *reason, + GHashTable *details, EmpathyCallHandler *handler) { EmpathyCallHandlerPriv *priv = handler->priv; - gchar *dbus_reason; - guint actor, reason; - tp_value_array_unpack ((GValueArray *) call_state_reason, 3, - &actor, &reason, &dbus_reason); + g_signal_emit (handler, signals[STATE_CHANGED], 0, state, + reason->dbus_reason); - g_signal_emit (handler, signals[STATE_CHANGED], 0, state, dbus_reason); + if (state == TP_CALL_STATE_INITIALISED && + priv->accept_when_initialised) + { + tp_call_channel_accept_async (priv->call, on_call_accepted_cb, NULL); + priv->accept_when_initialised = FALSE; + } - if (state == TPY_CALL_STATE_ENDED) + if (state == TP_CALL_STATE_ENDED) { tp_channel_close_async (TP_CHANNEL (call), NULL, NULL); - + priv->accept_when_initialised = FALSE; tp_clear_object (&priv->call); tp_clear_object (&priv->tfchannel); } } static void -on_members_changed_cb (TpyCallChannel *call, - GHashTable *members, - EmpathyCallHandler *self) -{ - EmpathyCallHandlerPriv *priv = GET_PRIV (self); - GHashTableIter iter; - gpointer key, value; - TpHandle *handles; - guint n_handles; - guint i = 0; - - if (members == NULL) - return; - - n_handles = g_hash_table_size (members); - if (n_handles == 0) - return; - - handles = g_new0 (TpHandle, n_handles); - - g_hash_table_iter_init (&iter, members); - while (g_hash_table_iter_next (&iter, &key, &value)) - handles[i++] = GPOINTER_TO_UINT (key); - - empathy_tp_contact_factory_get_from_handles ( - tp_channel_borrow_connection (TP_CHANNEL (priv->call)), - n_handles, handles, - on_get_contacts_cb, - NULL, NULL, G_OBJECT (self)); - - g_free (handles); -} - -static void -empathy_call_handler_constructed (GObject *object) -{ - EmpathyCallHandler *self = EMPATHY_CALL_HANDLER (object); - EmpathyCallHandlerPriv *priv = GET_PRIV (self); -// GHashTable *members; - - g_signal_connect (priv->call, "members-changed", - G_CALLBACK (on_members_changed_cb), object); - -/* FIXME - g_object_get (priv->call, "members", &members, NULL); - - if (members) - on_members_changed_cb (priv->call, members, self); -*/ -} - -static void empathy_call_handler_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { @@ -277,9 +210,6 @@ empathy_call_handler_set_property (GObject *object, case PROP_CONTACT: priv->contact = g_value_dup_object (value); break; - case PROP_MEMBERS: - priv->members = g_value_get_boxed (value); - break; case PROP_CALL_CHANNEL: g_return_if_fail (priv->call == NULL); @@ -312,9 +242,6 @@ empathy_call_handler_get_property (GObject *object, case PROP_CONTACT: g_value_set_object (value, priv->contact); break; - case PROP_MEMBERS: - g_value_set_boxed (value, priv->members); - break; case PROP_CALL_CHANNEL: g_value_set_object (value, priv->call); break; @@ -362,7 +289,6 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass) g_type_class_add_private (klass, sizeof (EmpathyCallHandlerPriv)); - object_class->constructed = empathy_call_handler_constructed; object_class->set_property = empathy_call_handler_set_property; object_class->get_property = empathy_call_handler_get_property; object_class->dispose = empathy_call_handler_dispose; @@ -374,15 +300,9 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_CONTACT, param_spec); - param_spec = g_param_spec_boxed ("members", - "call members", "The call participants", - G_TYPE_ARRAY, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_MEMBERS, param_spec); - param_spec = g_param_spec_object ("call-channel", "call channel", "The call channel", - TPY_TYPE_CALL_CHANNEL, + TP_TYPE_CALL_CHANNEL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_CALL_CHANNEL, param_spec); @@ -529,12 +449,12 @@ empathy_call_handler_class_init (EmpathyCallHandlerClass *klass) } EmpathyCallHandler * -empathy_call_handler_new_for_channel (TpyCallChannel *call, +empathy_call_handler_new_for_channel (TpCallChannel *call, EmpathyContact *contact) { return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER, "call-channel", call, - "initial-video", tpy_call_channel_has_initial_video (call), + "initial-video", tp_call_channel_has_initial_video (call, NULL), "target-contact", contact, NULL)); } @@ -748,8 +668,7 @@ src_pad_added_error_idle (gpointer data) { TfContent *content = data; - tf_content_error (content, 0 /* FIXME */, - "Could not link sink", NULL); + tf_content_error_literal (content, "Could not link sink"); g_object_unref (content); return FALSE; @@ -822,8 +741,7 @@ on_tf_channel_content_added_cb (TfChannel *tfchannel, content, &retval); if (!retval) - tf_content_error (content, 0 /* FIXME */, - "Could not link source", NULL); + tf_content_error_literal (content, "Could not link source"); /* Get sending codec */ g_object_get (content, "fs-session", &session, NULL); @@ -891,8 +809,7 @@ on_tf_channel_content_removed_cb (TfChannel *tfchannel, { g_warning ("Could not remove content!"); - tf_content_error (content, 0 /* FIXME */, - "Could not link source", NULL); + tf_content_error_literal (content, "Could not link source"); } } @@ -945,21 +862,6 @@ empathy_call_handler_start_tpfs (EmpathyCallHandler *self) } static void -on_call_accepted_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - TpyCallChannel *call = TPY_CALL_CHANNEL (source_object); - GError *error = NULL; - - if (!tpy_call_channel_accept_finish (call, res, &error)) - { - g_warning ("could not accept Call: %s", error->message); - g_error_free (error); - } -} - -static void empathy_call_handler_request_cb (GObject *source, GAsyncResult *result, gpointer user_data) @@ -979,13 +881,13 @@ empathy_call_handler_request_cb (GObject *source, return; } - if (!TPY_IS_CALL_CHANNEL (channel)) + if (!TP_IS_CALL_CHANNEL (channel)) { DEBUG ("The channel is not a Call channel!"); return; } - priv->call = TPY_CALL_CHANNEL (channel); + priv->call = TP_CALL_CHANNEL (channel); tp_g_signal_connect_object (priv->call, "state-changed", G_CALLBACK (on_call_state_changed_cb), self, 0); tp_g_signal_connect_object (priv->call, "invalidated", @@ -994,7 +896,7 @@ empathy_call_handler_request_cb (GObject *source, g_object_notify (G_OBJECT (self), "call-channel"); empathy_call_handler_start_tpfs (self); - tpy_call_channel_accept_async (priv->call, on_call_accepted_cb, NULL); + tp_call_channel_accept_async (priv->call, on_call_accepted_cb, NULL); } void @@ -1009,11 +911,28 @@ empathy_call_handler_start_call (EmpathyCallHandler *handler, if (priv->call != NULL) { empathy_call_handler_start_tpfs (handler); - tpy_call_channel_accept_async (priv->call, on_call_accepted_cb, NULL); + + if (tp_channel_get_requested (TP_CHANNEL (priv->call))) + { + /* accept outgoing channels immediately */ + tp_call_channel_accept_async (priv->call, + on_call_accepted_cb, NULL); + } + else + { + /* accepting incoming channels when they are INITIALISED */ + if (tp_call_channel_get_state (priv->call, NULL, NULL, NULL) == + TP_CALL_STATE_INITIALISED) + tp_call_channel_accept_async (priv->call, + on_call_accepted_cb, NULL); + else + priv->accept_when_initialised = TRUE; + } + return; } - /* No TpyCallChannel (we are redialing). Request a new call channel */ + /* No TpCallChannel (we are redialing). Request a new call channel */ g_assert (priv->contact != NULL); account = empathy_contact_get_account (priv->contact); @@ -1043,13 +962,9 @@ empathy_call_handler_stop_call (EmpathyCallHandler *handler) if (priv->call != NULL) { - tpy_call_channel_hangup_async (priv->call, - TPY_CALL_STATE_CHANGE_REASON_USER_REQUESTED, + tp_call_channel_hangup_async (priv->call, + TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "", NULL, NULL); - tp_channel_close_async (TP_CHANNEL (priv->call), - NULL, NULL); - tp_clear_object (&priv->call); - tp_clear_object (&priv->tfchannel); } } @@ -1137,3 +1052,9 @@ empathy_call_handler_get_video_local_candidate ( return priv->video_local_candidate; } + +EmpathyContact * +empathy_call_handler_get_contact (EmpathyCallHandler *self) +{ + return self->priv->contact; +} diff --git a/src/empathy-call-handler.h b/src/empathy-call-handler.h index 330d368a5..36c6cfdc2 100644 --- a/src/empathy-call-handler.h +++ b/src/empathy-call-handler.h @@ -24,9 +24,9 @@ #include <glib-object.h> #include <gst/gst.h> -#include <gst/farsight/fs-conference-iface.h> +#include <farstream/fs-conference.h> -#include <telepathy-yell/telepathy-yell.h> +#include <telepathy-glib/telepathy-glib.h> #include <libempathy/empathy-contact.h> @@ -68,7 +68,7 @@ EmpathyCallHandler * empathy_call_handler_new_for_contact ( EmpathyContact *contact); EmpathyCallHandler * empathy_call_handler_new_for_channel ( - TpyCallChannel *call, + TpCallChannel *call, EmpathyContact *contact); void empathy_call_handler_start_call (EmpathyCallHandler *handler, @@ -104,6 +104,8 @@ FsCandidate * empathy_call_handler_get_video_remote_candidate ( FsCandidate * empathy_call_handler_get_video_local_candidate ( EmpathyCallHandler *self); +EmpathyContact * empathy_call_handler_get_contact (EmpathyCallHandler *self); + G_END_DECLS #endif /* #ifndef __EMPATHY_CALL_HANDLER_H__*/ diff --git a/src/empathy-call-observer.c b/src/empathy-call-observer.c index 0fecbdca6..2019cd02f 100644 --- a/src/empathy-call-observer.c +++ b/src/empathy-call-observer.c @@ -24,8 +24,6 @@ #include <telepathy-glib/telepathy-glib.h> -#include <telepathy-yell/telepathy-yell.h> - #include <libnotify/notification.h> #include <libempathy/empathy-utils.h> @@ -185,7 +183,7 @@ find_main_channel (GList *channels) channel_type = tp_channel_get_channel_type_id (channel); if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - channel_type == TPY_IFACE_QUARK_CHANNEL_TYPE_CALL) + channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL) return channel; } @@ -203,9 +201,9 @@ has_ongoing_calls (EmpathyCallObserver *self) GQuark type = tp_channel_get_channel_type_id (channel); /* Check that Call channels are not ended */ - if (type == TPY_IFACE_QUARK_CHANNEL_TYPE_CALL && - tpy_call_channel_get_state (TPY_CALL_CHANNEL (channel), NULL, NULL) - == TPY_CALL_STATE_ENDED) + if (type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL && + tp_call_channel_get_state (TP_CALL_CHANNEL (channel), + NULL, NULL, NULL) == TP_CALL_STATE_ENDED) continue; return TRUE; @@ -372,7 +370,7 @@ empathy_call_observer_init (EmpathyCallObserver *self) tp_base_client_take_observer_filter (self->priv->observer, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TPY_IFACE_CHANNEL_TYPE_CALL, + TP_IFACE_CHANNEL_TYPE_CALL, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, NULL)); diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index a89d220c4..565c65d00 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -38,8 +38,8 @@ #include <telepathy-farstream/telepathy-farstream.h> #include <telepathy-glib/util.h> -#include <gst/farsight/fs-element-added-notifier.h> -#include <gst/farsight/fs-utils.h> +#include <farstream/fs-element-added-notifier.h> +#include <farstream/fs-utils.h> #include <libempathy/empathy-camera-monitor.h> #include <libempathy/empathy-gsettings.h> @@ -53,6 +53,7 @@ #include <libempathy-gtk/empathy-sound-manager.h> #include <libempathy-gtk/empathy-geometry.h> #include <libempathy-gtk/empathy-images.h> +#include <libempathy-gtk/empathy-call-utils.h> #define DEBUG_FLAG EMPATHY_DEBUG_VOIP #include <libempathy/empathy-debug.h> @@ -78,7 +79,8 @@ #define SELF_VIDEO_SECTION_WIDTH 120 #define SELF_VIDEO_SECTION_HEIGHT 90 -#define SELF_VIDEO_SECTION_MARGIN 10 +#define SELF_VIDEO_SECTION_MARGIN 2 +#define SELF_VIDEO_SECTION_BORDER SELF_VIDEO_SECTION_MARGIN*2 #define FLOATING_TOOLBAR_OPACITY 192 #define FLOATING_TOOLBAR_WIDTH 280 @@ -99,6 +101,9 @@ /* The time interval in milliseconds between 2 outgoing rings */ #define MS_BETWEEN_RING 500 +/* The roundedness of preview box and placeholders */ +#define PREVIEW_ROUND_FACTOR 16 + G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW) enum { @@ -194,17 +199,13 @@ struct _EmpathyCallWindowPriv /* These are used to accept or reject an incoming call when the status is RINGING. */ GtkWidget *incoming_call_dialog; - TpyCallChannel *pending_channel; + TpCallChannel *pending_channel; TpChannelDispatchOperation *pending_cdo; TpAddDispatchOperationContext *pending_context; gulong video_output_motion_handler_id; guint bus_message_source_id; - /* String that contains the queued tones to send after the current ones - are sent */ - GString *tones; - gboolean sending_tones; GtkWidget *dtmf_panel; /* Details vbox */ @@ -347,60 +348,20 @@ empathy_call_window_video_call_cb (GtkToggleToolButton *button, } static void -empathy_call_window_emit_tones (EmpathyCallWindow *self) -{ - TpChannel *channel; - - if (tp_str_empty (self->priv->tones->str)) - return; - - g_object_get (self->priv->handler, "call-channel", &channel, NULL); - - DEBUG ("Emitting multiple tones: %s", self->priv->tones->str); - - tp_cli_channel_interface_dtmf_call_multiple_tones (channel, -1, - self->priv->tones->str, - NULL, NULL, NULL, NULL); - - self->priv->sending_tones = TRUE; - - g_string_set_size (self->priv->tones, 0); - - g_object_unref (channel); -} - -static void -empathy_call_window_maybe_emit_tones (EmpathyCallWindow *self) -{ - if (self->priv->sending_tones) - return; - - empathy_call_window_emit_tones (self); -} - -static void -empathy_call_window_tones_stopped_cb (TpChannel *proxy, - gboolean arg_cancelled, - gpointer user_data, - GObject *weak_object) -{ - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - - self->priv->sending_tones = FALSE; - - empathy_call_window_emit_tones (self); -} - -static void dtmf_start_tone_cb (EmpathyDialpadWidget *dialpad, TpDTMFEvent event, EmpathyCallWindow *self) { - EmpathyCallWindowPriv *priv = GET_PRIV (self); + TpCallChannel *call; + gchar tones[2]; + + g_object_get (self->priv->handler, "call-channel", &call, NULL); - g_string_append_c (priv->tones, tp_dtmf_event_to_char (event)); + tones[0] = tp_dtmf_event_to_char (event); + tones[1] = '\0'; + tp_call_channel_send_tones_async (call, tones, NULL, NULL, NULL); - empathy_call_window_maybe_emit_tones (self); + g_object_unref (call); } static void @@ -439,8 +400,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); @@ -670,7 +634,7 @@ empathy_call_window_create_preview_rectangle (EmpathyCallWindow *self, ClutterBinAlignment y) { ClutterLayoutManager *layout1, *layout2; - ClutterActor *rectangle; + EmpathyRoundedRectangle *rectangle; ClutterActor *box1, *box2; layout1 = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, @@ -681,8 +645,9 @@ empathy_call_window_create_preview_rectangle (EmpathyCallWindow *self, *box = box1; rectangle = empathy_rounded_rectangle_new ( - SELF_VIDEO_SECTION_WIDTH + 5, - SELF_VIDEO_SECTION_HEIGHT + 5); + SELF_VIDEO_SECTION_WIDTH + 2 * SELF_VIDEO_SECTION_MARGIN, + SELF_VIDEO_SECTION_HEIGHT + 2 * SELF_VIDEO_SECTION_MARGIN, + PREVIEW_ROUND_FACTOR); clutter_actor_set_size (box1, SELF_VIDEO_SECTION_WIDTH + 2 * SELF_VIDEO_SECTION_MARGIN, @@ -702,14 +667,14 @@ empathy_call_window_create_preview_rectangle (EmpathyCallWindow *self, SELF_VIDEO_SECTION_HEIGHT + 2 * SELF_VIDEO_SECTION_MARGIN); clutter_container_add_actor (CLUTTER_CONTAINER (box1), box2); - clutter_container_add_actor (CLUTTER_CONTAINER (box2), rectangle); + clutter_container_add_actor (CLUTTER_CONTAINER (box2), CLUTTER_ACTOR (rectangle)); clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (self->priv->video_layout), box1, x, y); - clutter_actor_hide (rectangle); + clutter_actor_hide (CLUTTER_ACTOR (rectangle)); - return rectangle; + return CLUTTER_ACTOR (rectangle); } static void @@ -828,7 +793,7 @@ empathy_call_window_get_preview_position (EmpathyCallWindow *self, } else if (box.width - SELF_VIDEO_SECTION_MARGIN >= event_x && event_x >= (box.width - SELF_VIDEO_SECTION_MARGIN - (gint) SELF_VIDEO_SECTION_WIDTH) && - box.height - SELF_VIDEO_SECTION_MARGIN - SELF_VIDEO_SECTION_MARGIN - FLOATING_TOOLBAR_HEIGHT - FLOATING_TOOLBAR_SPACING >= event_y && + box.height - 2 * SELF_VIDEO_SECTION_MARGIN - FLOATING_TOOLBAR_HEIGHT - FLOATING_TOOLBAR_SPACING >= event_y && event_y >= (box.height - SELF_VIDEO_SECTION_MARGIN - FLOATING_TOOLBAR_HEIGHT - FLOATING_TOOLBAR_SPACING - (gint) SELF_VIDEO_SECTION_HEIGHT)) { pos = PREVIEW_POS_BOTTOM_RIGHT; @@ -916,7 +881,7 @@ empathy_call_window_highlight_preview_rectangle (EmpathyCallWindow *self, rectangle = empathy_call_window_get_preview_rectangle (self, pos); empathy_rounded_rectangle_set_border_width ( - EMPATHY_ROUNDED_RECTANGLE (rectangle), 5); + EMPATHY_ROUNDED_RECTANGLE (rectangle), 2 * SELF_VIDEO_SECTION_MARGIN); empathy_rounded_rectangle_set_border_color ( EMPATHY_ROUNDED_RECTANGLE (rectangle), CLUTTER_COLOR_Red); } @@ -1105,6 +1070,7 @@ create_video_preview (EmpathyCallWindow *self) GtkWidget *button; PreviewPosition pos; GdkRGBA transparent = { 0., 0., 0., 0. }; + GtkWidget *bin; g_assert (priv->video_preview == NULL); @@ -1113,8 +1079,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, @@ -1127,9 +1097,7 @@ create_video_preview (EmpathyCallWindow *self) /* Spinner for when changing the camera device */ priv->preview_spinner_widget = gtk_spinner_new (); - priv->preview_spinner_actor = empathy_rounded_actor_new (); - empathy_rounded_actor_set_round_factor ( - EMPATHY_ROUNDED_ACTOR (priv->preview_spinner_actor), 16); + priv->preview_spinner_actor = empathy_rounded_actor_new (PREVIEW_ROUND_FACTOR); g_object_set (priv->preview_spinner_widget, "expand", TRUE, NULL); gtk_widget_override_background_color ( @@ -1170,18 +1138,17 @@ create_video_preview (EmpathyCallWindow *self) /* Translators: this is an "Info" label. It should be as short * as possible. */ button = gtk_button_new_with_label (_("i")); - priv->preview_shown_button = b = empathy_rounded_actor_new (); - gtk_container_add ( - GTK_CONTAINER (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (b))), - button); + priv->preview_shown_button = b = gtk_clutter_actor_new_with_contents (button); clutter_actor_set_size (b, 24, 24); + bin = gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (b)); + gtk_widget_override_background_color (bin, GTK_STATE_FLAG_NORMAL, &transparent); layout_end = clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_END, CLUTTER_BIN_ALIGNMENT_END); box = clutter_box_new (layout_end); clutter_actor_set_size (box, - SELF_VIDEO_SECTION_WIDTH, - SELF_VIDEO_SECTION_HEIGHT + SELF_VIDEO_SECTION_MARGIN); + SELF_VIDEO_SECTION_WIDTH - 4, + SELF_VIDEO_SECTION_HEIGHT - 2); clutter_container_add_actor (CLUTTER_CONTAINER (box), b); clutter_container_add_actor (CLUTTER_CONTAINER (priv->video_preview), box); @@ -1193,12 +1160,9 @@ create_video_preview (EmpathyCallWindow *self) /* Translators: this is an "Info" label. It should be as short * as possible. */ button = gtk_button_new_with_label (_("i")); - b = empathy_rounded_actor_new (); - gtk_container_add ( - GTK_CONTAINER (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (b))), - button); + priv->preview_hidden_button = b = gtk_clutter_actor_new_with_contents (button); clutter_actor_set_size (b, 24, 24); - priv->preview_hidden_button = b; + gtk_widget_override_background_color (bin, GTK_STATE_FLAG_NORMAL, &transparent); clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (priv->video_layout), priv->preview_hidden_button, @@ -1550,7 +1514,7 @@ empathy_call_window_set_state_ringing (EmpathyCallWindow *self) g_assert (self->priv->call_state != CONNECTED); - video = tpy_call_channel_has_initial_video (self->priv->pending_channel); + video = tp_call_channel_has_initial_video (self->priv->pending_channel, NULL); empathy_call_window_status_message (self, _("Incoming call")); self->priv->call_state = RINGING; @@ -1594,7 +1558,7 @@ empathy_call_window_cdo_invalidated_cb (TpProxy *channel, void empathy_call_window_start_ringing (EmpathyCallWindow *self, - TpyCallChannel *channel, + TpCallChannel *channel, TpChannelDispatchOperation *dispatch_operation, TpAddDispatchOperationContext *context) { @@ -1762,7 +1726,7 @@ empathy_call_window_init (EmpathyCallWindow *self) create_audio_input (self); create_video_input (self); - priv->floating_toolbar = empathy_rounded_actor_new (); + priv->floating_toolbar = empathy_rounded_actor_new (2); gtk_widget_reparent (priv->bottom_toolbar, gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (priv->floating_toolbar))); @@ -1818,8 +1782,6 @@ empathy_call_window_init (EmpathyCallWindow *self) g_signal_connect (priv->dtmf_panel, "start-tone", G_CALLBACK (dtmf_start_tone_cb), self); - priv->tones = g_string_new (""); - gtk_box_pack_start (GTK_BOX (priv->pane), priv->dtmf_panel, FALSE, FALSE, 6); @@ -2247,18 +2209,19 @@ empathy_call_window_constructed (GObject *object) { EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object); EmpathyCallWindowPriv *priv = GET_PRIV (self); - TpyCallChannel *call; - TpyCallState state; + TpCallChannel *call; + TpCallState state; g_assert (priv->handler != NULL); g_object_get (priv->handler, "call-channel", &call, NULL); - state = tpy_call_channel_get_state (call, NULL, NULL); - priv->outgoing = (state == TPY_CALL_STATE_PENDING_INITIATOR); + state = tp_call_channel_get_state (call, NULL, NULL, NULL); + priv->outgoing = (state == TP_CALL_STATE_PENDING_INITIATOR); tp_clear_object (&call); - g_object_get (priv->handler, "target-contact", &priv->contact, NULL); + priv->contact = empathy_call_handler_get_contact (priv->handler); g_assert (priv->contact != NULL); + g_object_ref (priv->contact); if (!empathy_contact_can_voip_video (priv->contact)) { @@ -2401,6 +2364,7 @@ empathy_call_window_dispose (GObject *object) tp_clear_object (&priv->sound_mgr); tp_clear_object (&priv->mic_menu); tp_clear_object (&priv->camera_menu); + tp_clear_object (&priv->transitions); g_list_free_full (priv->notifiers, g_object_unref); @@ -2408,12 +2372,7 @@ empathy_call_window_dispose (GObject *object) g_source_remove (priv->timer_id); priv->timer_id = 0; - if (priv->contact != NULL) - { - g_signal_handlers_disconnect_by_func (priv->contact, - contact_name_changed_cb, self); - priv->contact = NULL; - } + tp_clear_object (&priv->contact); G_OBJECT_CLASS (empathy_call_window_parent_class)->dispose (object); } @@ -2444,8 +2403,6 @@ empathy_call_window_finalize (GObject *object) g_timer_destroy (priv->timer); - g_string_free (priv->tones, TRUE); - G_OBJECT_CLASS (empathy_call_window_parent_class)->finalize (object); } @@ -2597,9 +2554,6 @@ empathy_call_window_disconnected (EmpathyCallWindow *self, gtk_action_set_sensitive (priv->menu_fullscreen, FALSE); gtk_widget_set_sensitive (priv->dtmf_panel, FALSE); - priv->sending_tones = FALSE; - g_string_set_size (priv->tones, 0); - could_reset_pipeline = empathy_call_window_reset_pipeline (self); if (priv->call_state == CONNECTING) @@ -3055,7 +3009,7 @@ display_error (EmpathyCallWindow *self, #if 0 static gchar * media_stream_error_to_txt (EmpathyCallWindow *self, - TpyCallChannel *call, + TpCallChannel *call, gboolean audio, TpMediaStreamError error) { @@ -3127,7 +3081,7 @@ media_stream_error_to_txt (EmpathyCallWindow *self, static void empathy_call_window_stream_error (EmpathyCallWindow *self, - TpyCallChannel *call, + TpCallChannel *call, gboolean audio, guint code, const gchar *msg, @@ -3151,7 +3105,7 @@ empathy_call_window_stream_error (EmpathyCallWindow *self, } static void -empathy_call_window_audio_stream_error (TpyCallChannel *call, +empathy_call_window_audio_stream_error (TpCallChannel *call, guint code, const gchar *msg, EmpathyCallWindow *self) @@ -3161,7 +3115,7 @@ empathy_call_window_audio_stream_error (TpyCallChannel *call, } static void -empathy_call_window_video_stream_error (TpyCallChannel *call, +empathy_call_window_video_stream_error (TpCallChannel *call, guint code, const gchar *msg, EmpathyCallWindow *self) @@ -3220,22 +3174,22 @@ show_balance_error (EmpathyCallWindow *self) static void empathy_call_window_state_changed_cb (EmpathyCallHandler *handler, - TpyCallState state, + TpCallState state, gchar *reason, EmpathyCallWindow *self) { EmpathyCallWindowPriv *priv = GET_PRIV (self); - TpyCallChannel *call; + TpCallChannel *call; gboolean can_send_video; - if (state == TPY_CALL_STATE_ENDED && + if (state == TP_CALL_STATE_ENDED && !tp_strdiff (reason, TP_ERROR_STR_INSUFFICIENT_BALANCE)) { show_balance_error (self); return; } - if (state != TPY_CALL_STATE_ACCEPTED) + if (state != TP_CALL_STATE_ACCEPTED) return; if (priv->call_state == CONNECTED) @@ -3252,7 +3206,7 @@ empathy_call_window_state_changed_cb (EmpathyCallHandler *handler, g_object_get (priv->handler, "call-channel", &call, NULL); - if (tpy_call_channel_has_dtmf (call)) + if (tp_call_channel_has_dtmf (call)) gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); if (priv->video_input == NULL) @@ -3519,9 +3473,11 @@ empathy_call_window_content_added_cb (EmpathyCallHandler *handler, if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sink))) { gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_input); + gst_object_unref (pad); g_warning ("Could not link audio source to farsight"); break; } + gst_object_unref (pad); if (gst_element_set_state (priv->audio_input, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { @@ -3597,20 +3553,20 @@ start_call (EmpathyCallWindow *self) if (empathy_call_handler_has_initial_video (priv->handler)) { - TpyCallChannel *call; - TpySendingState s; + TpCallChannel *call; + TpSendingState s; g_object_get (priv->handler, "call-channel", &call, NULL); /* If the call channel isn't set yet we're requesting it, if we're * requesting it with initial video it should be PENDING_SEND when we get * it */ if (call == NULL) - s = TPY_SENDING_STATE_PENDING_SEND; + s = TP_SENDING_STATE_PENDING_SEND; else - s = tpy_call_channel_get_video_state (call); + s = empathy_call_channel_get_video_state (call); - if (s == TPY_SENDING_STATE_PENDING_SEND || - s == TPY_SENDING_STATE_SENDING) + if (s == TP_SENDING_STATE_PENDING_SEND || + s == TP_SENDING_STATE_SENDING) { /* Enable 'send video' buttons and display the preview */ gtk_toggle_tool_button_set_active ( @@ -3726,8 +3682,10 @@ empathy_call_window_bus_message (GstBus *bus, GstMessage *message, } static void -empathy_call_window_members_changed_cb (TpyCallChannel *call, - GHashTable *members, +empathy_call_window_members_changed_cb (TpCallChannel *call, + GHashTable *updates, + GPtrArray *removed, + TpCallStateReason *reason, EmpathyCallWindow *self) { EmpathyCallWindowPriv *priv = GET_PRIV (self); @@ -3735,10 +3693,10 @@ empathy_call_window_members_changed_cb (TpyCallChannel *call, gpointer key, value; gboolean held = FALSE; - g_hash_table_iter_init (&iter, members); + g_hash_table_iter_init (&iter, updates); while (g_hash_table_iter_next (&iter, &key, &value)) { - if (GPOINTER_TO_INT (value) & TPY_CALL_MEMBER_FLAG_HELD) + if (GPOINTER_TO_INT (value) & TP_CALL_MEMBER_FLAG_HELD) { /* This assumes this is a 1-1 call, otherwise one participant * putting the call on hold wouldn't mean the call is on hold @@ -3760,7 +3718,7 @@ call_handler_notify_call_cb (EmpathyCallHandler *handler, EmpathyCallWindow *self) { EmpathyCallWindowPriv *priv = GET_PRIV (self); - TpyCallChannel *call; + TpCallChannel *call; g_object_get (priv->handler, "call-channel", &call, NULL); if (call == NULL) @@ -3776,10 +3734,6 @@ call_handler_notify_call_cb (EmpathyCallHandler *handler, tp_g_signal_connect_object (call, "members-changed", G_CALLBACK (empathy_call_window_members_changed_cb), self, 0); - tp_cli_channel_interface_dtmf_connect_to_stopped_tones (TP_CHANNEL (call), - empathy_call_window_tones_stopped_cb, self, NULL, - G_OBJECT (call), NULL); - g_object_unref (call); } @@ -3787,7 +3741,7 @@ static void empathy_call_window_connect_handler (EmpathyCallWindow *self) { EmpathyCallWindowPriv *priv = GET_PRIV (self); - TpyCallChannel *call; + TpCallChannel *call; g_signal_connect (priv->handler, "state-changed", G_CALLBACK (empathy_call_window_state_changed_cb), self); @@ -4000,7 +3954,7 @@ empathy_call_window_set_send_video (EmpathyCallWindow *window, CameraState state) { EmpathyCallWindowPriv *priv = GET_PRIV (window); - TpyCallChannel *call; + TpCallChannel *call; priv->sending_video = (state == CAMERA_STATE_ON); @@ -4020,7 +3974,7 @@ empathy_call_window_set_send_video (EmpathyCallWindow *window, g_object_get (priv->handler, "call-channel", &call, NULL); DEBUG ("%s sending video", priv->sending_video ? "start": "stop"); - tpy_call_channel_send_video (call, priv->sending_video); + empathy_call_channel_send_video (call, priv->sending_video); g_object_unref (call); } diff --git a/src/empathy-call-window.h b/src/empathy-call-window.h index abaae2763..a5df2dac4 100644 --- a/src/empathy-call-window.h +++ b/src/empathy-call-window.h @@ -66,7 +66,7 @@ EmpathyCallWindow *empathy_call_window_new (EmpathyCallHandler *handler); void empathy_call_window_present (EmpathyCallWindow *window, EmpathyCallHandler *handler); void empathy_call_window_start_ringing (EmpathyCallWindow *self, - TpyCallChannel *channel, + TpCallChannel *channel, TpChannelDispatchOperation *dispatch_operation, TpAddDispatchOperationContext *context); diff --git a/src/empathy-call.c b/src/empathy-call.c index 2ff49a81b..207f32f25 100644 --- a/src/empathy-call.c +++ b/src/empathy-call.c @@ -30,9 +30,11 @@ #include <clutter-gtk/clutter-gtk.h> #include <clutter-gst/clutter-gst.h> -#include <telepathy-glib/debug-sender.h> +#ifdef CLUTTER_WINDOWING_X11 +#include <X11/Xlib.h> +#endif -#include <telepathy-yell/telepathy-yell.h> +#include <telepathy-glib/debug-sender.h> #include <libempathy/empathy-client-factory.h> @@ -87,7 +89,7 @@ find_window_for_handle (gpointer key, static gboolean incoming_call_cb (EmpathyCallFactory *factory, guint handle, - TpyCallChannel *channel, + TpCallChannel *channel, TpChannelDispatchOperation *dispatch_operation, TpAddDispatchOperationContext *context, gpointer user_data) @@ -117,7 +119,7 @@ new_call_handler_cb (EmpathyCallFactory *factory, DEBUG ("Show the call window"); - g_object_get (handler, "target-contact", &contact, NULL); + contact = empathy_call_handler_get_contact (handler); window = g_hash_table_lookup (call_windows, contact); @@ -187,6 +189,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 (); @@ -209,9 +217,6 @@ main (int argc, g_option_context_free (optcontext); - tpy_cli_init (); - - gtk_clutter_init (&argc, &argv); clutter_gst_init (&argc, &argv); empathy_gtk_init (); diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c index a52585736..dd828fa68 100644 --- a/src/empathy-chat-manager.c +++ b/src/empathy-chat-manager.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include <telepathy-glib/telepathy-glib.h> #include <telepathy-glib/proxy-subclass.h> diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index 1bb9de4aa..587ae7d4b 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -47,6 +47,7 @@ #include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-request-util.h> +#include <libempathy/empathy-individual-manager.h> #include <libempathy-gtk/empathy-images.h> #include <libempathy-gtk/empathy-contact-dialogs.h> @@ -129,12 +130,14 @@ static const guint tab_accel_keys[] = { typedef enum { DND_DRAG_TYPE_CONTACT_ID, + DND_DRAG_TYPE_INDIVIDUAL_ID, DND_DRAG_TYPE_URI_LIST, DND_DRAG_TYPE_TAB } DndDragType; static const GtkTargetEntry drag_types_dest[] = { { "text/contact-id", 0, DND_DRAG_TYPE_CONTACT_ID }, + { "text/x-individual-id", 0, DND_DRAG_TYPE_INDIVIDUAL_ID }, { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, DND_DRAG_TYPE_TAB }, { "text/uri-list", 0, DND_DRAG_TYPE_URI_LIST }, { "text/path-list", 0, DND_DRAG_TYPE_URI_LIST }, @@ -142,6 +145,7 @@ static const GtkTargetEntry drag_types_dest[] = { static const GtkTargetEntry drag_types_dest_contact[] = { { "text/contact-id", 0, DND_DRAG_TYPE_CONTACT_ID }, + { "text/x-individual-id", 0, DND_DRAG_TYPE_INDIVIDUAL_ID }, }; static const GtkTargetEntry drag_types_dest_file[] = { @@ -213,13 +217,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 @@ -765,6 +924,19 @@ chat_window_update_chat_tab_full (EmpathyChat *chat, append_markup_printf (tooltip, "\n%s", _("Typing a message.")); } + if (remote_contact != NULL) { + const gchar * const *types; + + types = empathy_contact_get_client_types (remote_contact); + if (types != NULL && !tp_strdiff (types[0], "phone")) { + /* I'm on a phone ! */ + gchar *tmp = name; + + name = g_strdup_printf ("☎ %s", name); + g_free (tmp); + } + } + markup = g_string_free (tooltip, FALSE); widget = g_object_get_data (G_OBJECT (chat), "chat-window-tab-tooltip-widget"); gtk_widget_set_tooltip_markup (widget, markup); @@ -773,10 +945,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 +1208,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 +1452,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 +1586,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 +1605,7 @@ static void chat_window_new_message_cb (EmpathyChat *chat, EmpathyMessage *message, gboolean pending, + gboolean should_highlight, EmpathyChatWindow *window) { EmpathyChatWindowPriv *priv; @@ -1496,15 +1665,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); } @@ -1818,6 +1985,70 @@ chat_window_drag_motion (GtkWidget *widget, } static void +drag_data_received_individual_id (EmpathyChatWindow *self, + GtkWidget *widget, + GdkDragContext *context, + int x, + int y, + GtkSelectionData *selection, + guint info, + guint time_) +{ + const gchar *id; + EmpathyIndividualManager *manager = NULL; + FolksIndividual *individual; + EmpathyChatWindowPriv *priv = GET_PRIV (self); + EmpathyTpChat *chat; + TpContact *tp_contact; + TpConnection *conn; + EmpathyContact *contact; + + id = (const gchar *) gtk_selection_data_get_data (selection); + + DEBUG ("DND invididual %s", id); + + if (priv->current_chat == NULL) + goto out; + + chat = empathy_chat_get_tp_chat (priv->current_chat); + if (chat == NULL) + goto out; + + if (!empathy_tp_chat_can_add_contact (chat)) { + DEBUG ("Can't invite contact to %s", + tp_proxy_get_object_path (chat)); + goto out; + } + + manager = empathy_individual_manager_dup_singleton (); + + individual = empathy_individual_manager_lookup_member (manager, id); + if (individual == NULL) { + DEBUG ("Failed to find individual %s", id); + goto out; + } + + conn = tp_channel_borrow_connection ((TpChannel *) chat); + tp_contact = empathy_get_tp_contact_for_individual (individual, conn); + if (tp_contact == NULL) { + DEBUG ("Can't find a TpContact on connection %s for %s", + tp_proxy_get_object_path (conn), id); + goto out; + } + + DEBUG ("Inviting %s to join %s", tp_contact_get_identifier (tp_contact), + tp_channel_get_identifier ((TpChannel *) chat)); + + contact = empathy_contact_dup_from_tp_contact (tp_contact); + empathy_contact_list_add (EMPATHY_CONTACT_LIST (chat), contact, NULL); + g_object_unref (contact); + +out: + gtk_drag_finish (context, TRUE, FALSE, time_); + tp_clear_object (&manager); +} + +static void chat_window_drag_data_received (GtkWidget *widget, GdkDragContext *context, int x, @@ -1897,6 +2128,10 @@ chat_window_drag_data_received (GtkWidget *widget, */ gtk_drag_finish (context, TRUE, FALSE, time_); } + else if (info == DND_DRAG_TYPE_INDIVIDUAL_ID) { + drag_data_received_individual_id (window, widget, context, x, y, + selection, info, time_); + } else if (info == DND_DRAG_TYPE_URI_LIST) { EmpathyChatWindowPriv *priv; EmpathyContact *contact; diff --git a/src/empathy-chat-window.ui b/src/empathy-chat-window.ui index 25749861c..ef2011895 100644 --- a/src/empathy-chat-window.ui +++ b/src/empathy-chat-window.ui @@ -43,6 +43,7 @@ <property name="active">TRUE</property> <property name="label" translatable="yes">_Show Contact List</property> </object> + <accelerator key="F9" modifiers=""/> </child> <child> <object class="GtkAction" id="menu_conv_invite_participant"> @@ -205,8 +206,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-debug-window.c b/src/empathy-debug-window.c index b298600a9..79e4d2ad1 100644 --- a/src/empathy-debug-window.c +++ b/src/empathy-debug-window.c @@ -21,10 +21,13 @@ #include "config.h" +#include <string.h> + #include <glib/gi18n.h> #include <gtk/gtk.h> #include <gio/gio.h> #include <gdk/gdkkeysyms.h> +#include <libsoup/soup.h> #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include <libempathy/empathy-debug.h> @@ -69,6 +72,9 @@ enum COL_NAME = 0, COL_UNIQUE_NAME, COL_GONE, + COL_ACTIVE_BUFFER, + COL_PAUSE_BUFFER, + COL_PROXY, NUM_COLS }; @@ -85,17 +91,14 @@ typedef struct /* Toolbar items */ GtkWidget *chooser; GtkToolItem *save_button; + GtkToolItem *send_to_pastebin; GtkToolItem *copy_button; GtkToolItem *clear_button; GtkToolItem *pause_button; GtkToolItem *level_label; GtkWidget *level_filter; - /* Cache */ - GHashTable *cache; - /* TreeView */ - GtkListStore *store; GtkTreeModel *store_filter; GtkWidget *view; GtkWidget *scrolled_win; @@ -104,10 +107,7 @@ typedef struct /* Connection */ TpDBusDaemon *dbus; - TpProxy *proxy; - TpProxySignalConnection *new_debug_message_signal; TpProxySignalConnection *name_owner_changed_signal; - gulong invalid_signal_id; /* Whether NewDebugMessage will be fired */ gboolean paused; @@ -115,12 +115,17 @@ typedef struct /* Service (CM, Client) chooser store */ GtkListStore *service_store; + /* Counters on services detected and added */ + guint services_detected; + guint name_owner_cb_count; + /* Debug to show upon creation */ gchar *select_name; /* Misc. */ gboolean dispose_run; TpAccountManager *am; + GtkListStore *all_active_buffer; } EmpathyDebugWindowPriv; static const gchar * @@ -152,48 +157,6 @@ log_level_to_string (guint level) } } -typedef struct -{ - gdouble timestamp; - gchar *domain; - guint level; - gchar *message; -} DebugMessage; - -static DebugMessage * -debug_message_new (gdouble timestamp, - const gchar *domain, - guint level, - const gchar *message) -{ - DebugMessage *retval = g_slice_new0 (DebugMessage); - - retval->timestamp = timestamp; - retval->domain = g_strdup (domain); - retval->level = level; - retval->message = g_strdup (message); - - return retval; -} - -static void -debug_message_free (DebugMessage *dm) -{ - g_free (dm->domain); - g_free (dm->message); - - g_slice_free (DebugMessage, dm); -} - -static void -debug_message_list_free (gpointer data) -{ - GList *list = data; - - g_list_foreach (list, (GFunc) debug_message_free, NULL); - g_list_free (list); -} - static gchar * get_active_service_name (EmpathyDebugWindow *self) { @@ -210,30 +173,66 @@ get_active_service_name (EmpathyDebugWindow *self) return name; } -static void -debug_window_cache_new_message (EmpathyDebugWindow *debug_window, - gdouble timestamp, - const gchar *domain, - guint level, - const gchar *message) +static gboolean +copy_buffered_messages (GtkTreeModel *buffer, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - GList *messages; - DebugMessage *dm; - char *name; + GtkListStore *active_buffer = data; + GtkTreeIter active_buffer_iter; + gdouble timestamp; + gchar *domain, *category, *message, *level_string; + guint level; - name = get_active_service_name (debug_window); - messages = g_hash_table_lookup (priv->cache, name); + gtk_tree_model_get (buffer, iter, + COL_DEBUG_TIMESTAMP, ×tamp, + COL_DEBUG_DOMAIN, &domain, + COL_DEBUG_CATEGORY, &category, + COL_DEBUG_LEVEL_STRING, &level_string, + COL_DEBUG_MESSAGE, &message, + COL_DEBUG_LEVEL_VALUE, &level, + -1); + gtk_list_store_insert_with_values (active_buffer, &active_buffer_iter, -1, + COL_DEBUG_TIMESTAMP, timestamp, + COL_DEBUG_DOMAIN, domain, + COL_DEBUG_CATEGORY, category, + COL_DEBUG_LEVEL_STRING, level_string, + COL_DEBUG_MESSAGE, message, + COL_DEBUG_LEVEL_VALUE, level, + -1); - dm = debug_message_new (timestamp, domain, level, message); - messages = g_list_append (messages, dm); + g_free (domain); + g_free (category); + g_free (level_string); + g_free (message); + + return FALSE; +} + +static void +insert_values_in_buffer (GtkListStore *store, + gdouble timestamp, + const gchar *domain, + const gchar *category, + guint level, + const gchar *string) +{ + GtkTreeIter iter; - g_hash_table_insert (priv->cache, name, messages); + gtk_list_store_insert_with_values (store, &iter, -1, + COL_DEBUG_TIMESTAMP, timestamp, + COL_DEBUG_DOMAIN, domain, + COL_DEBUG_CATEGORY, category, + COL_DEBUG_LEVEL_STRING, log_level_to_string (level), + COL_DEBUG_MESSAGE, string, + COL_DEBUG_LEVEL_VALUE, level, + -1); } static void debug_window_add_message (EmpathyDebugWindow *debug_window, - gboolean should_cache, + TpProxy *proxy, gdouble timestamp, const gchar *domain_category, guint level, @@ -241,12 +240,8 @@ debug_window_add_message (EmpathyDebugWindow *debug_window, { EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); gchar *domain, *category; - GtkTreeIter iter; gchar *string; - - if (should_cache) - debug_window_cache_new_message (debug_window, timestamp, domain_category, - level, message); + GtkListStore *active_buffer, *pause_buffer; if (g_strrstr (domain_category, "/")) { @@ -266,16 +261,26 @@ debug_window_add_message (EmpathyDebugWindow *debug_window, else string = g_strdup (message); + pause_buffer = g_object_get_data (G_OBJECT (proxy), "pause-buffer"); + active_buffer = g_object_get_data (G_OBJECT (proxy), "active-buffer"); - gtk_list_store_append (priv->store, &iter); - gtk_list_store_set (priv->store, &iter, - COL_DEBUG_TIMESTAMP, timestamp, - COL_DEBUG_DOMAIN, domain, - COL_DEBUG_CATEGORY, category, - COL_DEBUG_LEVEL_STRING, log_level_to_string (level), - COL_DEBUG_MESSAGE, string, - COL_DEBUG_LEVEL_VALUE, level, - -1); + if (priv->paused) + { + insert_values_in_buffer (pause_buffer, timestamp, + domain, category, level, + string); + } + else + { + /* Append 'this' message to this service's and All's active-buffers */ + insert_values_in_buffer (active_buffer, timestamp, + domain, category, level, + string); + + insert_values_in_buffer (priv->all_active_buffer, timestamp, + domain, category, level, + string); + } g_free (string); g_free (domain); @@ -293,20 +298,21 @@ debug_window_new_debug_message_cb (TpProxy *proxy, { EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; - debug_window_add_message (debug_window, TRUE, timestamp, domain, level, + debug_window_add_message (debug_window, proxy, timestamp, domain, level, message); } static void -debug_window_set_enabled (EmpathyDebugWindow *debug_window, +debug_window_set_enabled (TpProxy *proxy, gboolean enabled) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GValue *val; + g_return_if_fail (proxy != NULL); + val = tp_g_value_slice_new_boolean (enabled); - tp_cli_dbus_properties_call_set (priv->proxy, -1, TP_IFACE_DEBUG, + tp_cli_dbus_properties_call_set (proxy, -1, TP_IFACE_DEBUG, "Enabled", val, NULL, NULL, NULL, NULL); tp_g_value_slice_free (val); @@ -320,6 +326,7 @@ debug_window_set_toolbar_sensitivity (EmpathyDebugWindow *debug_window, GtkWidget *vbox = gtk_bin_get_child (GTK_BIN (debug_window)); gtk_widget_set_sensitive (GTK_WIDGET (priv->save_button), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (priv->send_to_pastebin), sensitive); gtk_widget_set_sensitive (GTK_WIDGET (priv->copy_button), sensitive); gtk_widget_set_sensitive (GTK_WIDGET (priv->clear_button), sensitive); gtk_widget_set_sensitive (GTK_WIDGET (priv->pause_button), sensitive); @@ -344,6 +351,74 @@ debug_window_set_toolbar_sensitivity (EmpathyDebugWindow *debug_window, } } +static gboolean +debug_window_get_iter_for_active_buffer (GtkListStore *active_buffer, + GtkTreeIter *iter, + EmpathyDebugWindow *debug_window) +{ + EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + gboolean valid_iter; + GtkTreeModel *model = GTK_TREE_MODEL (priv->service_store); + + gtk_tree_model_get_iter_first (model, iter); + for (valid_iter = gtk_tree_model_iter_next (model, iter); + valid_iter; + valid_iter = gtk_tree_model_iter_next (model, iter)) + { + GtkListStore *stored_active_buffer; + + gtk_tree_model_get (model, iter, + COL_ACTIVE_BUFFER, &stored_active_buffer, + -1); + if (active_buffer == stored_active_buffer) + { + g_object_unref (stored_active_buffer); + return valid_iter; + } + g_object_unref (stored_active_buffer); + } + + return valid_iter; +} + +static void refresh_all_buffer (EmpathyDebugWindow *debug_window); + +static void +proxy_invalidated_cb (TpProxy *proxy, + guint domain, + gint code, + gchar *msg, + gpointer user_data) +{ + EmpathyDebugWindow *self = (EmpathyDebugWindow *) user_data; + EmpathyDebugWindowPriv *priv = GET_PRIV (self); + GtkTreeModel *service_store = GTK_TREE_MODEL (priv->service_store); + TpProxy *stored_proxy; + GtkTreeIter iter; + gboolean valid_iter; + + /* Proxy has been invalidated so we find and set it to NULL + * in service store */ + gtk_tree_model_get_iter_first (service_store, &iter); + for (valid_iter = gtk_tree_model_iter_next (service_store, &iter); + valid_iter; + valid_iter = gtk_tree_model_iter_next (service_store, &iter)) + { + gtk_tree_model_get (service_store, &iter, + COL_PROXY, &stored_proxy, + -1); + + if (proxy == stored_proxy) + gtk_list_store_set (priv->service_store, &iter, + COL_PROXY, NULL, + -1); + } + + /* Also, we refresh "All" selection's active buffer since it should not + * show messages obtained from the proxy getting destroyed above */ + refresh_all_buffer (self); +} + static void debug_window_get_messages_cb (TpProxy *proxy, const GPtrArray *messages, @@ -353,87 +428,300 @@ debug_window_get_messages_cb (TpProxy *proxy, { EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - gchar *name; - GList *old_messages; + gchar *active_service_name; guint i; + GtkListStore *active_buffer; + gboolean valid_iter; + GtkTreeIter iter; + gchar *proxy_service_name; + + active_buffer = g_object_get_data (G_OBJECT (proxy), "active-buffer"); + valid_iter = debug_window_get_iter_for_active_buffer (active_buffer, &iter, + debug_window); + gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), &iter, + COL_NAME, &proxy_service_name, + -1); + active_service_name = get_active_service_name (debug_window); if (error != NULL) { DEBUG ("GetMessages failed: %s", error->message); - debug_window_set_toolbar_sensitivity (debug_window, FALSE); + + /* We want to set the window sensitivity to false only when proxy for the + * selected service is unable to fetch debug messages */ + if (!tp_strdiff (active_service_name, proxy_service_name)) + debug_window_set_toolbar_sensitivity (debug_window, FALSE); + + /* We created the proxy for GetMessages call. Now destroy it. */ + tp_clear_object (&proxy); return; } + DEBUG ("Retrieved debug messages for %s", active_service_name); + g_free (active_service_name); debug_window_set_toolbar_sensitivity (debug_window, TRUE); - name = get_active_service_name (debug_window); - old_messages = g_hash_table_lookup (priv->cache, name); - - /* we call get_messages either when a new CM is added or - * when a CM that we've already seen re-appears; in both cases - * we don't need our old cache anymore. - */ - if (old_messages != NULL) - { - g_hash_table_remove (priv->cache, name); - debug_message_list_free (old_messages); - } for (i = 0; i < messages->len; i++) { GValueArray *values = g_ptr_array_index (messages, i); - debug_window_add_message (debug_window, TRUE, + debug_window_add_message (debug_window, proxy, g_value_get_double (g_value_array_get_nth (values, 0)), g_value_get_string (g_value_array_get_nth (values, 1)), g_value_get_uint (g_value_array_get_nth (values, 2)), g_value_get_string (g_value_array_get_nth (values, 3))); } - /* Connect to NewDebugMessage */ - priv->new_debug_message_signal = emp_cli_debug_connect_to_new_debug_message ( + /* Now we save this precious proxy in the service_store along its service */ + if (valid_iter) + { + DEBUG ("Proxy for service: %s was successful in fetching debug" + " messages. Saving it.", proxy_service_name); + + gtk_list_store_set (priv->service_store, &iter, + COL_PROXY, proxy, + -1); + } + + g_free (proxy_service_name); + + /* Connect to "invalidated" signal */ + g_signal_connect (proxy, "invalidated", + G_CALLBACK (proxy_invalidated_cb), debug_window); + + /* Connect to NewDebugMessage */ + emp_cli_debug_connect_to_new_debug_message ( proxy, debug_window_new_debug_message_cb, debug_window, NULL, NULL, NULL); - /* Set Enabled as appropriate */ - debug_window_set_enabled (debug_window, !priv->paused); + /* Now that active-buffer is up to date, we can see which messages are + * to be visible */ + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->store_filter)); + + /* Set the proxy to signal for new debug messages */ + debug_window_set_enabled (proxy, TRUE); } static void -debug_window_add_log_messages_from_cache (EmpathyDebugWindow *debug_window, - const gchar *name) +create_proxy_to_get_messages (EmpathyDebugWindow *debug_window, + GtkTreeIter *iter, + TpDBusDaemon *dbus) { - GList *messages, *l; - DebugMessage *dm; EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + gchar *bus_name, *name = NULL; + TpProxy *new_proxy, *stored_proxy = NULL; + GtkTreeModel *pause_buffer, *active_buffer; + gboolean gone; - DEBUG ("Adding logs from cache for CM %s", name); + gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), iter, + COL_NAME, &name, + COL_GONE, &gone, + COL_ACTIVE_BUFFER, &active_buffer, + COL_PAUSE_BUFFER, &pause_buffer, + COL_PROXY, &stored_proxy, + -1); - messages = g_hash_table_lookup (priv->cache, name); + /* If the stored_proxy is not NULL then messages have been obtained and + * new-debug-message-signal has been set on it. Also, the proxy is valid. + * If the service is gone, we still display the messages-cached till now. */ + if (gone || + (!gone && stored_proxy != NULL)) + { + /* Nothing needs to be done. The associated active-buffer has already + * been set as view's model */ + goto finally; + } - if (messages == NULL) - return; + DEBUG ("Preparing proxy to obtain messages for service %s", name); - for (l = messages; l != NULL; l = l->next) - { - dm = l->data; + gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), iter, + COL_UNIQUE_NAME, &bus_name, -1); + new_proxy = g_object_new (TP_TYPE_PROXY, + "bus-name", bus_name, + "dbus-daemon", dbus, + "object-path", DEBUG_OBJECT_PATH, + NULL); + g_free (bus_name); + + g_object_set_data (G_OBJECT (new_proxy), "active-buffer", active_buffer); + g_object_set_data (G_OBJECT (new_proxy), "pause-buffer", pause_buffer); + + /* Now we call GetMessages with fresh proxy. + * The old proxy is NULL due to one of the following - + * * Wasn't saved as last GetMessages call failed + * * The service has newly arrived and no proxy has been prepared yet for it + * * A service with the same name has reappeared but the owner maybe new */ + tp_proxy_add_interface_by_id (new_proxy, emp_iface_quark_debug ()); + + emp_cli_debug_call_get_messages (new_proxy, -1, + debug_window_get_messages_cb, debug_window, NULL, NULL); + +finally: + g_free (name); + tp_clear_object (&stored_proxy); + g_object_unref (active_buffer); + g_object_unref (pause_buffer); +} + +static GtkListStore * +new_list_store_for_service (void) +{ + return gtk_list_store_new (NUM_DEBUG_COLS, + G_TYPE_DOUBLE, /* COL_DEBUG_TIMESTAMP */ + G_TYPE_STRING, /* COL_DEBUG_DOMAIN */ + G_TYPE_STRING, /* COL_DEBUG_CATEGORY */ + G_TYPE_STRING, /* COL_DEBUG_LEVEL_STRING */ + G_TYPE_STRING, /* COL_DEBUG_MESSAGE */ + G_TYPE_UINT); /* COL_DEBUG_LEVEL_VALUE */ +} + +static gboolean +debug_window_visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) +{ + EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; + EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + guint filter_value, level; + GtkTreeModel *filter_model; + GtkTreeIter filter_iter; + + filter_model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->level_filter)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->level_filter), + &filter_iter); + + gtk_tree_model_get (model, iter, COL_DEBUG_LEVEL_VALUE, &level, -1); + gtk_tree_model_get (filter_model, &filter_iter, + COL_LEVEL_VALUE, &filter_value, -1); + + if (level <= filter_value) + return TRUE; + + return FALSE; +} + +static gboolean +tree_view_search_equal_func_cb (GtkTreeModel *model, + gint column, + const gchar *key, + GtkTreeIter *iter, + gpointer search_data) +{ + gchar *str; + gint key_len; + gint len; + gint i; + gboolean ret = TRUE; /* The return value is counter-intuitive */ - debug_window_add_message (debug_window, FALSE, dm->timestamp, - dm->domain, dm->level, dm->message); + gtk_tree_model_get (model, iter, column, &str, -1); + + key_len = strlen (key); + len = strlen (str) - key_len; + + for (i = 0; i <= len; ++i) + { + if (!g_ascii_strncasecmp (key, str + i, key_len)) + { + ret = FALSE; + break; + } } + + g_free (str); + return ret; } static void -proxy_invalidated_cb (TpProxy *proxy, - guint domain, - gint code, - gchar *msg, - EmpathyDebugWindowPriv *self) +update_store_filter (EmpathyDebugWindow *debug_window, + GtkListStore *active_buffer) { - EmpathyDebugWindowPriv *priv = GET_PRIV (self); + EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + debug_window_set_toolbar_sensitivity (debug_window, FALSE); + + tp_clear_object (&priv->store_filter); + priv->store_filter = gtk_tree_model_filter_new ( + GTK_TREE_MODEL (active_buffer), NULL); - /* Proxy has been invalidated so we can't disconnect the signal any more */ - priv->new_debug_message_signal = NULL; + gtk_tree_model_filter_set_visible_func ( + GTK_TREE_MODEL_FILTER (priv->store_filter), + debug_window_visible_func, debug_window, NULL); + gtk_tree_view_set_model (GTK_TREE_VIEW (priv->view), + priv->store_filter); + + /* Since view's model has changed, reset the search column and + * search_equal_func */ + gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->view), + COL_DEBUG_MESSAGE); + gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (priv->view), + tree_view_search_equal_func_cb, NULL, NULL); + + debug_window_set_toolbar_sensitivity (debug_window, TRUE); +} + +static void +refresh_all_buffer (EmpathyDebugWindow *debug_window) +{ + EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + gboolean valid_iter; + GtkTreeIter iter; + GtkTreeModel *service_store = GTK_TREE_MODEL (priv->service_store); + + /* Clear All's active-buffer */ + gtk_list_store_clear (priv->all_active_buffer); + + /* Skipping the first service store iter which is reserved for "All" */ + gtk_tree_model_get_iter_first (service_store, &iter); + for (valid_iter = gtk_tree_model_iter_next (service_store, &iter); + valid_iter; + valid_iter = gtk_tree_model_iter_next (service_store, &iter)) + { + TpProxy *proxy = NULL; + GtkListStore *service_active_buffer; + gboolean gone; + + gtk_tree_model_get (service_store, &iter, + COL_GONE, &gone, + COL_PROXY, &proxy, + COL_ACTIVE_BUFFER, &service_active_buffer, + -1); + + if (gone) + { + gtk_tree_model_foreach (GTK_TREE_MODEL (service_active_buffer), + copy_buffered_messages, priv->all_active_buffer); + } + else + { + if (proxy != NULL) + { + if (service_active_buffer == NULL) + break; + + /* Copy the debug messages to all_active_buffer */ + gtk_tree_model_foreach (GTK_TREE_MODEL (service_active_buffer), + copy_buffered_messages, priv->all_active_buffer); + } + else + { + GError *error = NULL; + TpDBusDaemon *dbus = tp_dbus_daemon_dup (&error); + + if (error != NULL) + { + DEBUG ("Failed at duping the dbus daemon: %s", error->message); + g_error_free (error); + } + + create_proxy_to_get_messages (debug_window, &iter, dbus); + + g_object_unref (dbus); + } + } + + g_object_unref (service_active_buffer); + tp_clear_object (&proxy); + } } static void @@ -443,8 +731,8 @@ debug_window_service_chooser_changed_cb (GtkComboBox *chooser, EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); TpDBusDaemon *dbus; GError *error = NULL; - gchar *bus_name, *name = NULL; - TpProxy *proxy; + GtkListStore *stored_active_buffer = NULL; + gchar *name = NULL; GtkTreeIter iter; gboolean gone; @@ -459,64 +747,44 @@ debug_window_service_chooser_changed_cb (GtkComboBox *chooser, return; } - gtk_list_store_clear (priv->store); + debug_window_set_toolbar_sensitivity (debug_window, TRUE); gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), &iter, - COL_NAME, &name, COL_GONE, &gone, -1); + COL_NAME, &name, + COL_GONE, &gone, + COL_ACTIVE_BUFFER, &stored_active_buffer, + -1); - if (gone) + DEBUG ("Service chosen: %s", name); + + if (tp_strdiff (name, "All") && stored_active_buffer == NULL) { - debug_window_add_log_messages_from_cache (debug_window, name); - g_free (name); - return; + DEBUG ("No list store assigned to service %s", name); + goto finally; } - g_free (name); - - dbus = tp_dbus_daemon_dup (&error); - - if (error != NULL) + if (!tp_strdiff (name, "All")) { - DEBUG ("Failed at duping the dbus daemon: %s", error->message); + update_store_filter (debug_window, priv->all_active_buffer); + goto finally; } - gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), &iter, - COL_UNIQUE_NAME, &bus_name, -1); - proxy = g_object_new (TP_TYPE_PROXY, - "bus-name", bus_name, - "dbus-daemon", dbus, - "object-path", DEBUG_OBJECT_PATH, - NULL); - g_free (bus_name); - - /* Disable debug signalling */ - if (priv->proxy != NULL) - debug_window_set_enabled (debug_window, FALSE); + update_store_filter (debug_window, stored_active_buffer); - /* Disconnect from previous NewDebugMessage signal */ - if (priv->new_debug_message_signal != NULL) - { - tp_proxy_signal_connection_disconnect (priv->new_debug_message_signal); - priv->new_debug_message_signal = NULL; - } + dbus = tp_dbus_daemon_dup (&error); - if (priv->proxy != NULL) + if (error != NULL) { - g_signal_handler_disconnect (priv->proxy, priv->invalid_signal_id); - g_object_unref (priv->proxy); + DEBUG ("Failed at duping the dbus daemon: %s", error->message); } - priv->proxy = proxy; - - tp_proxy_add_interface_by_id (priv->proxy, emp_iface_quark_debug ()); - - emp_cli_debug_call_get_messages (priv->proxy, -1, - debug_window_get_messages_cb, debug_window, NULL, NULL); - - priv->invalid_signal_id = g_signal_connect (proxy, "invalidated", - G_CALLBACK (proxy_invalidated_cb), debug_window); + create_proxy_to_get_messages (debug_window, &iter, dbus); g_object_unref (dbus); + +finally: + g_free (name); + tp_clear_object (&stored_active_buffer); } typedef struct @@ -673,6 +941,9 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, FillServiceChooserData *data = (FillServiceChooserData *) user_data; EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (data->debug_window); EmpathyDebugWindowPriv *priv = GET_PRIV (data->debug_window); + GtkTreeIter iter; + + priv->name_owner_cb_count++; if (error != NULL) { @@ -682,8 +953,8 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, if (!debug_window_service_is_in_model (data->debug_window, out, NULL, FALSE)) { - GtkTreeIter iter; char *name; + GtkListStore *active_buffer, *pause_buffer; DEBUG ("Adding %s to list: %s at unique name: %s", data->type == SERVICE_TYPE_CM? "CM": "Client", @@ -694,12 +965,21 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, else name = g_strdup (data->name); - gtk_list_store_append (priv->service_store, &iter); - gtk_list_store_set (priv->service_store, &iter, + active_buffer = new_list_store_for_service (); + pause_buffer = new_list_store_for_service (); + + gtk_list_store_insert_with_values (priv->service_store, &iter, -1, COL_NAME, name, COL_UNIQUE_NAME, out, + COL_GONE, FALSE, + COL_ACTIVE_BUFFER, active_buffer, + COL_PAUSE_BUFFER, pause_buffer, + COL_PROXY, NULL, -1); + g_object_unref (active_buffer); + g_object_unref (pause_buffer); + if (priv->select_name != NULL && !tp_strdiff (name, priv->select_name)) { @@ -710,6 +990,22 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, g_free (name); } + if (priv->services_detected == priv->name_owner_cb_count) + { + /* Time to add "All" selection to service_store */ + gtk_list_store_insert_with_values (priv->service_store, &iter, 0, + COL_NAME, "All", + COL_ACTIVE_BUFFER, NULL, + -1); + + priv->all_active_buffer = new_list_store_for_service (); + + /* Populate active buffers for all services */ + refresh_all_buffer (self); + + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->chooser), 0); + } + OUT: fill_service_chooser_data_free (data); } @@ -724,6 +1020,7 @@ debug_window_list_connection_names_cb (const gchar * const *names, GObject *weak_object) { EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; + EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); guint i; TpDBusDaemon *dbus; GError *error2 = NULL; @@ -751,6 +1048,8 @@ debug_window_list_connection_names_cb (const gchar * const *names, tp_cli_dbus_daemon_call_get_name_owner (dbus, -1, names[i], debug_window_get_name_owner_cb, data, NULL, NULL); + + priv->services_detected ++; } g_object_unref (dbus); @@ -786,6 +1085,7 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, if (EMP_STR_EMPTY (arg1) && !EMP_STR_EMPTY (arg2)) { + GtkTreeIter *found_at_iter = NULL; gchar *display_name; if (type == SERVICE_TYPE_CM) @@ -794,41 +1094,72 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, display_name = g_strdup (name); /* A service joined */ - if (!g_hash_table_lookup (priv->cache, name)) + if (!debug_window_service_is_in_model (user_data, display_name, + &found_at_iter, TRUE)) { GtkTreeIter iter; + GtkListStore *active_buffer, *pause_buffer; DEBUG ("Adding new service '%s' at %s.", name, arg2); - gtk_list_store_append (priv->service_store, &iter); - gtk_list_store_set (priv->service_store, &iter, + active_buffer = new_list_store_for_service (); + pause_buffer = new_list_store_for_service (); + + gtk_list_store_insert_with_values (priv->service_store, &iter, -1, COL_NAME, display_name, COL_UNIQUE_NAME, arg2, + COL_GONE, FALSE, + COL_ACTIVE_BUFFER, active_buffer, + COL_PAUSE_BUFFER, pause_buffer, + COL_PROXY, NULL, -1); + + g_object_unref (active_buffer); + g_object_unref (pause_buffer); } else { - /* a service with the same name is already in the hash table, - * update it and set it as re-enabled in the model. + /* a service with the same name is already in the service_store, + * update it and set it as re-enabled. */ - GtkTreeIter *iter = NULL; + GtkListStore *active_buffer, *pause_buffer; + TpProxy *stored_proxy; - if (debug_window_service_is_in_model (user_data, name, &iter, TRUE)) - { - DEBUG ("Refreshing CM '%s' at '%s'.", name, arg2); + DEBUG ("Refreshing CM '%s' at '%s'.", name, arg2); - gtk_list_store_set (priv->service_store, iter, - COL_NAME, display_name, - COL_UNIQUE_NAME, arg2, - COL_GONE, FALSE, - -1); - gtk_tree_iter_free (iter); + active_buffer= new_list_store_for_service (); + pause_buffer = new_list_store_for_service (); - debug_window_service_chooser_changed_cb - (GTK_COMBO_BOX (priv->chooser), user_data); - } + gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), + found_at_iter, COL_PROXY, &stored_proxy, -1); + + tp_clear_object (&stored_proxy); + + gtk_list_store_set (priv->service_store, found_at_iter, + COL_NAME, display_name, + COL_UNIQUE_NAME, arg2, + COL_GONE, FALSE, + COL_ACTIVE_BUFFER, active_buffer, + COL_PAUSE_BUFFER, pause_buffer, + COL_PROXY, NULL, + -1); + + g_object_unref (active_buffer); + g_object_unref (pause_buffer); + + gtk_tree_iter_free (found_at_iter); + + debug_window_service_chooser_changed_cb + (GTK_COMBO_BOX (priv->chooser), user_data); } + /* If a new service arrives when "All" is selected, the view will + * not show its messages which we do not want. So we refresh All's + * active buffer. + * Similarly for when a service with an already seen service name + * appears. */ + refresh_all_buffer (self); + g_free (display_name); } else if (!EMP_STR_EMPTY (arg1) && EMP_STR_EMPTY (arg2)) @@ -845,6 +1176,9 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, iter, COL_GONE, TRUE, -1); gtk_tree_iter_free (iter); } + + /* Refresh all's active buffer */ + refresh_all_buffer (self); } } @@ -862,6 +1196,8 @@ add_client (EmpathyDebugWindow *self, tp_cli_dbus_daemon_call_get_name_owner (priv->dbus, -1, name, debug_window_get_name_owner_cb, data, NULL, NULL); + + priv->services_detected ++; } static void @@ -895,6 +1231,7 @@ debug_window_fill_service_chooser (EmpathyDebugWindow *debug_window) EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GError *error = NULL; GtkTreeIter iter; + GtkListStore *active_buffer, *pause_buffer; priv->dbus = tp_dbus_daemon_dup (&error); @@ -905,18 +1242,28 @@ debug_window_fill_service_chooser (EmpathyDebugWindow *debug_window) return; } + /* Keep a count of the services detected and added */ + priv->services_detected = 0; + priv->name_owner_cb_count = 0; + /* Add CMs to list */ tp_list_connection_names (priv->dbus, debug_window_list_connection_names_cb, debug_window, NULL, NULL); /* add Mission Control */ - gtk_list_store_append (priv->service_store, &iter); - gtk_list_store_set (priv->service_store, &iter, + active_buffer= new_list_store_for_service (); + pause_buffer = new_list_store_for_service (); + + gtk_list_store_insert_with_values (priv->service_store, &iter, -1, COL_NAME, "mission-control", COL_UNIQUE_NAME, "org.freedesktop.Telepathy.MissionControl5", + COL_GONE, FALSE, + COL_ACTIVE_BUFFER, active_buffer, + COL_PAUSE_BUFFER, pause_buffer, + COL_PROXY, NULL, -1); - - gtk_combo_box_set_active (GTK_COMBO_BOX (priv->chooser), 0); + g_object_unref (active_buffer); + g_object_unref (pause_buffer); /* add clients */ tp_dbus_daemon_list_names (priv->dbus, 2000, @@ -932,35 +1279,41 @@ debug_window_pause_toggled_cb (GtkToggleToolButton *pause_, EmpathyDebugWindow *debug_window) { EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + GtkTreeIter iter; + gboolean valid_iter; + GtkTreeModel *model = GTK_TREE_MODEL (priv->service_store); priv->paused = gtk_toggle_tool_button_get_active (pause_); - debug_window_set_enabled (debug_window, !priv->paused); -} - -static gboolean -debug_window_visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - guint filter_value, level; - GtkTreeModel *filter_model; - GtkTreeIter filter_iter; + if (!priv->paused) + { + /* Pause has been released - flush all pause buffers */ + GtkTreeModel *service_store = GTK_TREE_MODEL (priv->service_store); + + /* Skipping the first iter which is reserved for "All" */ + gtk_tree_model_get_iter_first (model, &iter); + for (valid_iter = gtk_tree_model_iter_next (model, &iter); + valid_iter; + valid_iter = gtk_tree_model_iter_next (model, &iter)) + { + GtkListStore *pause_buffer, *active_buffer; - filter_model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->level_filter)); - gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->level_filter), - &filter_iter); + gtk_tree_model_get (service_store, &iter, + COL_PAUSE_BUFFER, &pause_buffer, + COL_ACTIVE_BUFFER, &active_buffer, + -1); - gtk_tree_model_get (model, iter, COL_DEBUG_LEVEL_VALUE, &level, -1); - gtk_tree_model_get (filter_model, &filter_iter, - COL_LEVEL_VALUE, &filter_value, -1); + gtk_tree_model_foreach (GTK_TREE_MODEL (pause_buffer), + copy_buffered_messages, active_buffer); + gtk_tree_model_foreach (GTK_TREE_MODEL (pause_buffer), + copy_buffered_messages, priv->all_active_buffer); - if (level <= filter_value) - return TRUE; + gtk_list_store_clear (pause_buffer); - return FALSE; + g_object_unref (active_buffer); + g_object_unref (pause_buffer); + } + } } static void @@ -978,8 +1331,25 @@ debug_window_clear_clicked_cb (GtkToolButton *clear_button, EmpathyDebugWindow *debug_window) { EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + GtkTreeIter iter; + GtkListStore *active_buffer; - gtk_list_store_clear (priv->store); + /* "All" is the first choice in the service chooser and it's buffer is + * not saved in the service-store but is accessed using a private + * reference */ + if (gtk_combo_box_get_active (GTK_COMBO_BOX (priv->chooser)) == 0) + { + gtk_list_store_clear (priv->all_active_buffer); + return; + } + + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->chooser), &iter); + gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), &iter, + COL_ACTIVE_BUFFER, &active_buffer, -1); + + gtk_list_store_clear (active_buffer); + + g_object_unref (active_buffer); } static void @@ -1125,12 +1495,10 @@ debug_window_store_filter_foreach (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { - GFileOutputStream *output_stream = (GFileOutputStream *) user_data; + gchar **debug_data = (gchar **)user_data; gchar *domain, *category, *message, *level_str, *level_upper; gdouble timestamp; - gchar *line, *time_str; - GError *error = NULL; - gboolean out = FALSE; + gchar *line, *time_str, *tmp; gtk_tree_model_get (model, iter, COL_DEBUG_TIMESTAMP, ×tamp, @@ -1150,15 +1518,14 @@ debug_window_store_filter_foreach (GtkTreeModel *model, g_free (time_str); - g_output_stream_write (G_OUTPUT_STREAM (output_stream), line, - strlen (line), NULL, &error); + /* Compact all message lines in the out parameter debug_data */ + if (!tp_str_empty (*debug_data)) + tmp = g_strconcat (*debug_data, line, NULL); + else + tmp = g_strdup (line); - if (error != NULL) - { - DEBUG ("Failed to write to file: %s", error->message); - g_error_free (error); - out = TRUE; - } + g_free (*debug_data); + *debug_data = tmp; g_free (line); g_free (level_upper); @@ -1167,7 +1534,7 @@ debug_window_store_filter_foreach (GtkTreeModel *model, g_free (category); g_free (message); - return out; + return FALSE; } static void @@ -1178,8 +1545,10 @@ debug_window_save_file_chooser_response_cb (GtkDialog *dialog, EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); gchar *filename = NULL; GFile *gfile = NULL; + gchar *debug_data = NULL; GFileOutputStream *output_stream = NULL; - GError *error = NULL; + GError *file_open_error = NULL; + GError *file_write_error = NULL; if (response_id != GTK_RESPONSE_ACCEPT) goto OUT; @@ -1190,17 +1559,27 @@ debug_window_save_file_chooser_response_cb (GtkDialog *dialog, gfile = g_file_new_for_path (filename); output_stream = g_file_replace (gfile, NULL, FALSE, - G_FILE_CREATE_NONE, NULL, &error); + G_FILE_CREATE_NONE, NULL, &file_open_error); - if (error != NULL) + if (file_open_error != NULL) { - DEBUG ("Failed to open file for writing: %s", error->message); - g_error_free (error); + DEBUG ("Failed to open file for writing: %s", file_open_error->message); + g_error_free (file_open_error); goto OUT; } gtk_tree_model_foreach (priv->store_filter, - debug_window_store_filter_foreach, output_stream); + debug_window_store_filter_foreach, &debug_data); + + g_output_stream_write (G_OUTPUT_STREAM (output_stream), debug_data, + strlen (debug_data), NULL, &file_write_error); + g_free (debug_data); + + if (file_write_error != NULL) + { + DEBUG ("Failed to write to file: %s", file_write_error->message); + g_error_free (file_write_error); + } OUT: if (gfile != NULL) @@ -1244,7 +1623,7 @@ debug_window_save_clicked_cb (GtkToolButton *tool_button, tm_s = localtime (&t); if (tm_s != NULL) { - if (strftime(time_str, sizeof (time_str), "%d-%m-%y_%H-%M-%S", tm_s)) + if (strftime (time_str, sizeof (time_str), "%d-%m-%y_%H-%M-%S", tm_s)) tmp = g_strdup_printf ("%s-%s.log", name, time_str); } @@ -1262,6 +1641,135 @@ debug_window_save_clicked_cb (GtkToolButton *tool_button, gtk_widget_show (file_chooser); } +static void +debug_window_pastebin_response_dialog_closed_cb (GtkDialog *dialog, + gint response_id, + SoupBuffer *buffer) +{ + soup_buffer_free (buffer); + + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void +debug_window_pastebin_callback (SoupSession *session, + SoupMessage *msg, + gpointer debug_window) +{ + GtkWidget *dialog; + SoupBuffer *buffer; + + buffer = soup_message_body_flatten (msg->response_body); + if (g_str_has_prefix (buffer->data, "http://pastebin.com/")) + { + dialog = gtk_message_dialog_new (GTK_WINDOW (debug_window), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, + _("Pastebin link")); + + gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), + "<a href=\"%s\">%s</a>", buffer->data, buffer->data); + } + else + { + dialog = gtk_message_dialog_new (GTK_WINDOW (debug_window), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, + _("Pastebin response")); + + if (!tp_str_empty (buffer->data)) + gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), + _("%s"), buffer->data); + else + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("Data too large for a single paste. Please save logs to file.")); + } + + g_object_unref (session); + + gtk_window_set_transient_for (GTK_WINDOW (dialog), debug_window); + + gtk_widget_show_all (GTK_WIDGET (dialog)); + + g_signal_connect_after (dialog, "response", G_CALLBACK ( + debug_window_pastebin_response_dialog_closed_cb), buffer); +} + +static void +debug_window_message_dialog (EmpathyDebugWindow *debug_window, + const gchar *primary_text, + const gchar *secondary_text) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (debug_window), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, + "%s", _(primary_text)); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", _(secondary_text)); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (debug_window)); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +static void +debug_window_send_to_pastebin (EmpathyDebugWindow *debug_window, + gchar *debug_data) +{ + SoupSession *session; + SoupMessage *msg; + gchar *api_dev_key, *api_paste_code, *api_paste_name, *formdata; + + if (tp_str_empty (debug_data)) + { + debug_window_message_dialog (debug_window, "Error", "No data to send"); + return; + } + + /* Constructing a valid URL for http post. See http://pastebin.com/api#2 */ + + /* The api_dev_key is the author's developer key to access the Pastebin API + * This developer key is published here with the autorization of pastebin; + * see PASTEBIN-API-KEY.txt */ + api_dev_key = soup_uri_encode ("f6ccfabfdcd4b77b825ee38a30d11d52", NULL); + api_paste_code = soup_uri_encode (debug_data, NULL); + api_paste_name = soup_uri_encode ("Empathy debug data", NULL); + formdata = g_strdup_printf ("api_dev_key=%s&api_paste_code=%s" + "&api_paste_name=%s&api_paste_format=text&api_option=paste", + api_dev_key, api_paste_code, api_paste_name); + + session = soup_session_async_new (); + + msg = soup_message_new ("POST", "http://pastebin.com/api/api_post.php"); + soup_message_set_request (msg, + "application/x-www-form-urlencoded;charset=UTF-8", SOUP_MEMORY_COPY, + formdata, strlen (formdata)); + + g_free (api_dev_key); + g_free (api_paste_code); + g_free (api_paste_name); + g_free (formdata); + + soup_session_queue_message (session, msg, debug_window_pastebin_callback, + debug_window); +} + +static void +debug_window_send_to_pastebin_cb (GtkToolButton *tool_button, + EmpathyDebugWindow *debug_window) +{ + EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + gchar *debug_data = NULL; + + DEBUG ("Preparing debug data for sending to pastebin."); + + gtk_tree_model_foreach (priv->store_filter, + debug_window_store_filter_foreach, &debug_data); + + debug_window_send_to_pastebin (debug_window, debug_data); + g_free (debug_data); +} + static gboolean debug_window_copy_model_foreach (GtkTreeModel *model, GtkTreePath *path, @@ -1347,37 +1855,6 @@ debug_window_key_press_event_cb (GtkWidget *widget, return FALSE; } -static gboolean -tree_view_search_equal_func_cb (GtkTreeModel *model, - gint column, - const gchar *key, - GtkTreeIter *iter, - gpointer search_data) -{ - gchar *str; - gint key_len; - gint len; - gint i; - gboolean ret = TRUE; /* The return value is counter-intuitive */ - - gtk_tree_model_get (model, iter, column, &str, -1); - - key_len = strlen (key); - len = strlen (str) - key_len; - - for (i = 0; i <= len; ++i) - { - if (!g_ascii_strncasecmp (key, str + i, key_len)) - { - ret = FALSE; - break; - } - } - - g_free (str); - return ret; -} - static void empathy_debug_window_select_name (EmpathyDebugWindow *self, const gchar *name) @@ -1456,8 +1933,13 @@ am_prepared_cb (GObject *am, /* CM */ priv->chooser = gtk_combo_box_text_new (); - priv->service_store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_BOOLEAN); + priv->service_store = gtk_list_store_new (NUM_COLS, + G_TYPE_STRING, /* COL_NAME */ + G_TYPE_STRING, /* COL_UNIQUE_NAME */ + G_TYPE_BOOLEAN, /* COL_GONE */ + G_TYPE_OBJECT, /* COL_ACTIVE_BUFFER */ + G_TYPE_OBJECT, /* COL_PAUSE_BUFFER */ + TP_TYPE_PROXY); /* COL_PROXY */ gtk_combo_box_set_model (GTK_COMBO_BOX (priv->chooser), GTK_TREE_MODEL (priv->service_store)); gtk_widget_show (priv->chooser); @@ -1482,6 +1964,16 @@ am_prepared_cb (GObject *am, gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->save_button), TRUE); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->save_button, -1); + /* Send to pastebin */ + priv->send_to_pastebin = gtk_tool_button_new_from_stock (GTK_STOCK_PASTE); + gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->send_to_pastebin), + _("Send to pastebin")); + g_signal_connect (priv->send_to_pastebin, "clicked", + G_CALLBACK (debug_window_send_to_pastebin_cb), object); + gtk_widget_show (GTK_WIDGET (priv->send_to_pastebin)); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->send_to_pastebin), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->send_to_pastebin, -1); + /* Copy */ priv->copy_button = gtk_tool_button_new_from_stock (GTK_STOCK_COPY); g_signal_connect (priv->copy_button, "clicked", @@ -1544,38 +2036,32 @@ am_prepared_cb (GObject *am, gtk_combo_box_set_model (GTK_COMBO_BOX (priv->level_filter), GTK_TREE_MODEL (level_store)); - gtk_list_store_append (level_store, &iter); - gtk_list_store_set (level_store, &iter, + gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Debug"), COL_LEVEL_VALUE, TP_DEBUG_LEVEL_DEBUG, -1); - gtk_list_store_append (level_store, &iter); - gtk_list_store_set (level_store, &iter, + gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Info"), COL_LEVEL_VALUE, TP_DEBUG_LEVEL_INFO, -1); - gtk_list_store_append (level_store, &iter); - gtk_list_store_set (level_store, &iter, + gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Message"), COL_LEVEL_VALUE, TP_DEBUG_LEVEL_MESSAGE, -1); - gtk_list_store_append (level_store, &iter); - gtk_list_store_set (level_store, &iter, + gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Warning"), COL_LEVEL_VALUE, TP_DEBUG_LEVEL_WARNING, -1); - gtk_list_store_append (level_store, &iter); - gtk_list_store_set (level_store, &iter, + gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Critical"), COL_LEVEL_VALUE, TP_DEBUG_LEVEL_CRITICAL, -1); - gtk_list_store_append (level_store, &iter); - gtk_list_store_set (level_store, &iter, + gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Error"), COL_LEVEL_VALUE, TP_DEBUG_LEVEL_ERROR, -1); @@ -1609,24 +2095,10 @@ am_prepared_cb (GObject *am, gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view), -1, _("Message"), renderer, "text", COL_DEBUG_MESSAGE, NULL); - priv->store = gtk_list_store_new (NUM_DEBUG_COLS, G_TYPE_DOUBLE, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_UINT); - - priv->store_filter = gtk_tree_model_filter_new ( - GTK_TREE_MODEL (priv->store), NULL); - - gtk_tree_model_filter_set_visible_func ( - GTK_TREE_MODEL_FILTER (priv->store_filter), - debug_window_visible_func, object, NULL); + priv->store_filter = NULL; gtk_tree_view_set_model (GTK_TREE_VIEW (priv->view), priv->store_filter); - gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->view), - COL_DEBUG_MESSAGE); - gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (priv->view), - tree_view_search_equal_func_cb, NULL, NULL); - /* Scrolled window */ priv->scrolled_win = g_object_ref (gtk_scrolled_window_new (NULL, NULL)); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_win), @@ -1647,6 +2119,8 @@ am_prepared_cb (GObject *am, priv->view_visible = FALSE; + priv->all_active_buffer = NULL; + debug_window_set_toolbar_sensitivity (EMPATHY_DEBUG_WINDOW (object), FALSE); debug_window_fill_service_chooser (EMPATHY_DEBUG_WINDOW (object)); gtk_widget_show (GTK_WIDGET (object)); @@ -1671,8 +2145,6 @@ empathy_debug_window_init (EmpathyDebugWindow *empathy_debug_window) empathy_debug_window->priv = priv; priv->dispose_run = FALSE; - priv->cache = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); } static void @@ -1707,22 +2179,9 @@ static void debug_window_finalize (GObject *object) { EmpathyDebugWindowPriv *priv = GET_PRIV (object); - GHashTableIter iter; - char *key; - GList *values; g_free (priv->select_name); - g_hash_table_iter_init (&iter, priv->cache); - - while (g_hash_table_iter_next (&iter, (gpointer *) &key, - (gpointer *) &values)) - { - debug_message_list_free (values); - } - - g_hash_table_unref (priv->cache); - (G_OBJECT_CLASS (empathy_debug_window_parent_class)->finalize) (object); } @@ -1737,22 +2196,9 @@ debug_window_dispose (GObject *object) priv->dispose_run = TRUE; - if (priv->store != NULL) - g_object_unref (priv->store); - if (priv->name_owner_changed_signal != NULL) tp_proxy_signal_connection_disconnect (priv->name_owner_changed_signal); - if (priv->new_debug_message_signal != NULL) - tp_proxy_signal_connection_disconnect (priv->new_debug_message_signal); - - if (priv->proxy != NULL) - { - debug_window_set_enabled (EMPATHY_DEBUG_WINDOW (object), FALSE); - g_signal_handler_disconnect (priv->proxy, priv->invalid_signal_id); - g_object_unref (priv->proxy); - } - if (priv->service_store != NULL) g_object_unref (priv->service_store); @@ -1765,6 +2211,8 @@ debug_window_dispose (GObject *object) priv->am = NULL; } + tp_clear_object (&priv->all_active_buffer); + (G_OBJECT_CLASS (empathy_debug_window_parent_class)->dispose) (object); } diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c index 321cd1cca..c6b3e29ed 100644 --- a/src/empathy-event-manager.c +++ b/src/empathy-event-manager.c @@ -29,8 +29,6 @@ #include <telepathy-glib/interfaces.h> #include <telepathy-glib/simple-approver.h> -#include <telepathy-yell/telepathy-yell.h> - #include <libempathy/empathy-presence-manager.h> #include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-connection-aggregator.h> @@ -45,6 +43,7 @@ #include <libempathy-gtk/empathy-contact-dialogs.h> #include <libempathy-gtk/empathy-sound-manager.h> #include <libempathy-gtk/empathy-ui-utils.h> +#include <libempathy-gtk/empathy-call-utils.h> #include "empathy-event-manager.h" #include "empathy-roster-window.h" @@ -413,10 +412,10 @@ reject_channel_claim_cb (GObject *source, { empathy_tp_streamed_media_close (user_data); } - else if (TPY_IS_CALL_CHANNEL (user_data)) + else if (TP_IS_CALL_CHANNEL (user_data)) { - tpy_call_channel_hangup_async (user_data, - TPY_CALL_STATE_CHANGE_REASON_USER_REQUESTED, + tp_call_channel_hangup_async (user_data, + TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, "", "", NULL, NULL); tp_channel_close_async (user_data, NULL, NULL); } @@ -474,7 +473,7 @@ event_manager_call_window_confirmation_dialog_response_cb (GtkDialog *dialog, } else if (response == ACCEPT_WITHOUT_VIDEO) { - tpy_call_channel_send_video (TPY_CALL_CHANNEL (approval->main_channel), + empathy_call_channel_send_video (TP_CALL_CHANNEL (approval->main_channel), FALSE); event_manager_approval_approve (approval); } @@ -508,9 +507,9 @@ event_channel_process_voip_func (EventPriv *event) } else if (etype == EMPATHY_EVENT_TYPE_CALL) { - TpyCallChannel *call; - call = TPY_CALL_CHANNEL (event->approval->handler_instance); - g_object_get (G_OBJECT (call), "initial-video", &video, NULL); + TpCallChannel *call; + call = TP_CALL_CHANNEL (event->approval->handler_instance); + video = tp_call_channel_has_initial_video (call, NULL); } else { @@ -638,7 +637,7 @@ event_manager_approval_done (EventManagerApproval *approval) channel_type = tp_channel_get_channel_type_id (approval->main_channel); if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - channel_type == TPY_IFACE_QUARK_CHANNEL_TYPE_CALL) + channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL) { priv->ringing--; if (priv->ringing == 0) @@ -676,14 +675,14 @@ cdo_invalidated_cb (TpProxy *cdo, } static void -event_manager_call_state_changed_cb (TpyCallChannel *call, - TpyCallState state, - TpyCallFlags flags, - const GValueArray *call_state_reason, - GHashTable *call_state_details, +event_manager_call_state_changed_cb (TpCallChannel *call, + TpCallState state, + TpCallFlags flags, + TpCallStateReason *reason, + GHashTable *details, EventManagerApproval *approval) { - if (state == TPY_CALL_STATE_ENDED) + if (state == TP_CALL_STATE_ENDED) { DEBUG ("Call ended, seems we missed it :/"); reject_approval (approval); @@ -700,11 +699,11 @@ event_manager_call_channel_got_contact_cb (TpConnection *connection, EventManagerApproval *approval = (EventManagerApproval *) user_data; EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); GtkWidget *window; - TpyCallChannel *call; + TpCallChannel *call; gchar *header; gboolean video; - call = TPY_CALL_CHANNEL (approval->handler_instance); + call = TP_CALL_CHANNEL (approval->handler_instance); if (error != NULL) { @@ -713,7 +712,7 @@ event_manager_call_channel_got_contact_cb (TpConnection *connection, return; } - if (tpy_call_channel_get_state (call, NULL, NULL) == TPY_CALL_STATE_ENDED) + if (tp_call_channel_get_state (call, NULL, NULL, NULL) == TP_CALL_STATE_ENDED) { DEBUG ("Call already ended, seems we missed it :/"); reject_approval (approval); @@ -982,7 +981,7 @@ find_main_channel (GList *channels) channel_type = tp_channel_get_channel_type_id (channel); if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - channel_type == TPY_IFACE_QUARK_CHANNEL_TYPE_CALL || + channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL || channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER || channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION) return channel; @@ -1104,9 +1103,9 @@ approve_channels (TpSimpleApprover *approver, } } - else if (channel_type == TPY_IFACE_QUARK_CHANNEL_TYPE_CALL) + else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL) { - TpyCallChannel *call = TPY_CALL_CHANNEL (channel); + TpCallChannel *call = TP_CALL_CHANNEL (channel); const gchar *id; approval->handler_instance = g_object_ref (call); @@ -1510,7 +1509,7 @@ empathy_event_manager_init (EmpathyEventManager *manager) tp_base_client_take_approver_filter (priv->approver, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TPY_IFACE_CHANNEL_TYPE_CALL, + TP_IFACE_CHANNEL_TYPE_CALL, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, NULL)); 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 aaf20d5c5..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 { @@ -359,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) { @@ -392,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); } @@ -410,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); } @@ -468,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 @@ -490,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)); } @@ -501,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 ece86f1b6..fd5bd8f76 100644 --- a/src/empathy-invite-participant-dialog.c +++ b/src/empathy-invite-participant-dialog.c @@ -9,6 +9,8 @@ * Danielle Madeley <danielle.madeley@collabora.co.uk> */ +#include "config.h" + #include <glib/gi18n.h> #include <folks/folks-telepathy.h> diff --git a/src/empathy-notifications-approver.c b/src/empathy-notifications-approver.c index ac51459fb..7a4f03731 100644 --- a/src/empathy-notifications-approver.c +++ b/src/empathy-notifications-approver.c @@ -25,11 +25,10 @@ #include <libnotify/notify.h> #include <telepathy-glib/telepathy-glib.h> -#include <telepathy-yell/telepathy-yell.h> - #include <libempathy/empathy-tp-streamed-media.h> #include <libempathy-gtk/empathy-notify-manager.h> +#include <libempathy-gtk/empathy-call-utils.h> #include "empathy-event-manager.h" @@ -127,8 +126,8 @@ notification_approve_no_video_cb (NotifyNotification *notification, { if (self->priv->event) { - tpy_call_channel_send_video ( - TPY_CALL_CHANNEL (self->priv->event->handler_instance), + empathy_call_channel_send_video ( + TP_CALL_CHANNEL (self->priv->event->handler_instance), FALSE); empathy_event_approve (self->priv->event); } @@ -197,8 +196,8 @@ add_notification_actions (EmpathyNotificationsApprover *self, video = empathy_tp_streamed_media_has_initial_video ( EMPATHY_TP_STREAMED_MEDIA (self->priv->event->handler_instance)); else - video = tpy_call_channel_has_initial_video ( - TPY_CALL_CHANNEL (self->priv->event->handler_instance)); + video = tp_call_channel_has_initial_video ( + TP_CALL_CHANNEL (self->priv->event->handler_instance), NULL); notify_notification_add_action (notification, "reject", _("Reject"), (NotifyActionCallback) notification_decline_cb, 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-roster-window.c b/src/empathy-roster-window.c index 575f719c1..454cd256a 100644 --- a/src/empathy-roster-window.c +++ b/src/empathy-roster-window.c @@ -92,7 +92,7 @@ enum { PAGE_CONTACT_LIST = 0, - PAGE_NO_MATCH + PAGE_MESSAGE }; enum @@ -111,6 +111,7 @@ struct _EmpathyRosterWindowPriv { EmpathyEventManager *event_manager; EmpathySoundManager *sound_mgr; EmpathyCallObserver *call_observer; + EmpathyIndividualManager *individual_manager; guint flash_timeout_id; gboolean flash_on; gboolean empty; @@ -129,6 +130,8 @@ struct _EmpathyRosterWindowPriv { GtkWidget *search_bar; GtkWidget *notebook; GtkWidget *no_entry_label; + GtkWidget *button_account_settings; + GtkWidget *spinner_loading; GtkToggleAction *show_protocols; GtkRadioAction *sort_by_name; @@ -608,6 +611,53 @@ OUT: } 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) @@ -620,24 +670,24 @@ roster_window_row_deleted_cb (GtkTreeModel *model, if (empathy_individual_view_is_searching (self->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 (self->priv->no_entry_label), tmp); - g_free (tmp); - - gtk_label_set_line_wrap (GTK_LABEL (self->priv->no_entry_label), - TRUE); - - gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook), - PAGE_NO_MATCH); + 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, @@ -646,8 +696,8 @@ roster_window_row_inserted_cb (GtkTreeModel *model, if (self->priv->empty) { self->priv->empty = FALSE; - gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook), - PAGE_CONTACT_LIST); + + 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. @@ -1376,6 +1426,7 @@ empathy_roster_window_finalize (GObject *window) 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); } @@ -2088,6 +2139,81 @@ add_account (EmpathyRosterWindow *self, 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, @@ -2098,6 +2224,8 @@ roster_window_account_validity_changed_cb (TpAccountManager *manager, add_account (self, account); else roster_window_account_removed_cb (manager, account, self); + + set_notebook_page (self); } static void @@ -2123,7 +2251,6 @@ roster_window_connection_items_setup (EmpathyRosterWindow *self, "chat_new_call", "chat_search_contacts", "chat_add_contact", - "edit_personal_information", "edit_blocked_contacts", "edit_search_contacts" }; @@ -2138,6 +2265,22 @@ roster_window_connection_items_setup (EmpathyRosterWindow *self, } 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) @@ -2164,6 +2307,10 @@ account_manager_prepared_cb (GObject *source_object, 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); @@ -2171,6 +2318,8 @@ account_manager_prepared_cb (GObject *source_object, gtk_action_set_sensitive (self->priv->view_history, g_list_length (accounts) > 0); + set_notebook_page (self); + g_list_free (accounts); } @@ -2264,9 +2413,31 @@ empathy_roster_window_class_init (EmpathyRosterWindowClass *klass) } 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) { - EmpathyIndividualManager *individual_manager; GtkBuilder *gui, *gui_mgr; GtkWidget *sw; GtkToggleAction *show_offline_widget; @@ -2306,6 +2477,8 @@ empathy_roster_window_init (EmpathyRosterWindow *self) "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); @@ -2434,10 +2607,19 @@ empathy_roster_window_init (EmpathyRosterWindow *self) * 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. */ - individual_manager = empathy_individual_manager_dup_singleton (); + 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 (individual_manager)); - g_object_unref (individual_manager); + 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). @@ -2461,7 +2643,6 @@ empathy_roster_window_init (EmpathyRosterWindow *self) EMPATHY_INDIVIDUAL_FEATURE_CALL | EMPATHY_INDIVIDUAL_FEATURE_EDIT | EMPATHY_INDIVIDUAL_FEATURE_INFO | - EMPATHY_INDIVIDUAL_FEATURE_LINK | EMPATHY_INDIVIDUAL_FEATURE_SMS | EMPATHY_INDIVIDUAL_FEATURE_CALL_PHONE); @@ -2504,6 +2685,9 @@ empathy_roster_window_init (EmpathyRosterWindow *self) 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 (); @@ -2557,6 +2741,9 @@ empathy_roster_window_init (EmpathyRosterWindow *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 * diff --git a/src/empathy-roster-window.ui b/src/empathy-roster-window.ui index a09d123f8..8c8f63001 100644 --- a/src/empathy-roster-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..646682fb5 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> @@ -74,15 +75,12 @@ empathy_rounded_actor_class_init (EmpathyRoundedActorClass *klass) } ClutterActor * -empathy_rounded_actor_new (void) +empathy_rounded_actor_new (guint round_factor) { - return CLUTTER_ACTOR ( + EmpathyRoundedActor *self = EMPATHY_ROUNDED_ACTOR ( g_object_new (EMPATHY_TYPE_ROUNDED_ACTOR, NULL)); -} -void -empathy_rounded_actor_set_round_factor (EmpathyRoundedActor *self, - guint round_factor) -{ self->priv->round_factor = round_factor; + + return CLUTTER_ACTOR (self); } diff --git a/src/empathy-rounded-actor.h b/src/empathy-rounded-actor.h index 4287cf389..49fc03fd3 100644 --- a/src/empathy-rounded-actor.h +++ b/src/empathy-rounded-actor.h @@ -59,10 +59,7 @@ GType empathy_rounded_actor_get_type (void); (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_ROUNDED_ACTOR, \ EmpathyRoundedActorClass)) -ClutterActor *empathy_rounded_actor_new (void); - -void empathy_rounded_actor_set_round_factor (EmpathyRoundedActor *self, - guint round_factor); +ClutterActor *empathy_rounded_actor_new (guint round_factor); G_END_DECLS diff --git a/src/empathy-rounded-rectangle.c b/src/empathy-rounded-rectangle.c index e06889d58..7b8951f80 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> @@ -30,21 +32,26 @@ G_DEFINE_TYPE (EmpathyRoundedRectangle, struct _EmpathyRoundedRectanglePriv { + guint width, height; ClutterColor border_color; guint border_width; + guint round_factor; }; -static void -empathy_rounded_rectangle_paint (EmpathyRoundedRectangle *self) +static gboolean +draw_cb (ClutterCairoTexture *canvas, + cairo_t *cr) { + EmpathyRoundedRectangle *self = EMPATHY_ROUNDED_RECTANGLE (canvas); guint width, height; + guint border_width; guint tmp_alpha; - cairo_t *cr; - -#define RADIUS (height / 8.) + gdouble radius; - clutter_cairo_texture_get_surface_size (CLUTTER_CAIRO_TEXTURE (self), - &width, &height); + width = self->priv->width; + height = self->priv->height; + radius = self->priv->height / self->priv->round_factor; + border_width = self->priv->border_width; /* compute the composited opacity of the actor taking into * account the opacity of the color set by the user */ @@ -52,35 +59,35 @@ empathy_rounded_rectangle_paint (EmpathyRoundedRectangle *self) * self->priv->border_color.alpha / 255; - cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (self)); - cairo_set_source_rgba (cr, self->priv->border_color.red, self->priv->border_color.green, self->priv->border_color.blue, tmp_alpha); - cairo_set_line_width (cr, self->priv->border_width); + cairo_set_line_width (cr, border_width); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + /* make room for the portion of the border drawn on the outside */ + cairo_translate (cr, border_width/2.0, border_width/2.0); + cairo_new_sub_path (cr); - cairo_arc (cr, width - RADIUS, RADIUS, RADIUS, + cairo_arc (cr, width - radius, radius, radius, -M_PI/2.0, 0); - cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS, + cairo_arc (cr, width - radius, height - radius, radius, 0, M_PI/2.0); - cairo_arc (cr, RADIUS, height - RADIUS, RADIUS, + cairo_arc (cr, radius, height - radius, radius, M_PI/2.0, M_PI); - cairo_arc (cr, RADIUS, RADIUS, RADIUS, + cairo_arc (cr, radius, radius, radius, M_PI, -M_PI/2.0); cairo_close_path (cr); cairo_stroke (cr); - cairo_destroy (cr); -#undef RADIUS + return TRUE; } static void @@ -90,26 +97,50 @@ empathy_rounded_rectangle_init (EmpathyRoundedRectangle *self) EMPATHY_TYPE_ROUNDED_RECTANGLE, EmpathyRoundedRectanglePriv); self->priv->border_width = 1; + self->priv->round_factor = 2; +} + +static void +empathy_rounded_rectangle_finalize (GObject *object) +{ + G_OBJECT_CLASS (empathy_rounded_rectangle_parent_class)->finalize (object); } static void empathy_rounded_rectangle_class_init (EmpathyRoundedRectangleClass *klass) { + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = empathy_rounded_rectangle_finalize; + g_type_class_add_private (klass, sizeof (EmpathyRoundedRectanglePriv)); } -ClutterActor * +static void +empathy_rounded_rectangle_update_surface_size (EmpathyRoundedRectangle *self) +{ + clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (self), + self->priv->width + self->priv->border_width, + self->priv->height + self->priv->border_width); +} + +EmpathyRoundedRectangle * empathy_rounded_rectangle_new (guint width, - guint height) + guint height, + guint round_factor) { - ClutterActor *self; + EmpathyRoundedRectangle *self; - self = CLUTTER_ACTOR (g_object_new (EMPATHY_TYPE_ROUNDED_RECTANGLE, NULL)); + self = EMPATHY_ROUNDED_RECTANGLE (g_object_new (EMPATHY_TYPE_ROUNDED_RECTANGLE, NULL)); - clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (self), - width, height); + self->priv->width = width; + self->priv->height = height; + self->priv->round_factor = round_factor; + + g_signal_connect (self, "draw", G_CALLBACK (draw_cb), NULL); - empathy_rounded_rectangle_paint (EMPATHY_ROUNDED_RECTANGLE (self)); + empathy_rounded_rectangle_update_surface_size (self); + clutter_cairo_texture_invalidate (CLUTTER_CAIRO_TEXTURE (self)); return self; } @@ -120,7 +151,8 @@ empathy_rounded_rectangle_set_border_width (EmpathyRoundedRectangle *self, { self->priv->border_width = border_width; - empathy_rounded_rectangle_paint (self); + empathy_rounded_rectangle_update_surface_size (self); + clutter_cairo_texture_invalidate (CLUTTER_CAIRO_TEXTURE (self)); } void @@ -129,5 +161,5 @@ empathy_rounded_rectangle_set_border_color (EmpathyRoundedRectangle *self, { self->priv->border_color = *color; - empathy_rounded_rectangle_paint (self); + clutter_cairo_texture_invalidate (CLUTTER_CAIRO_TEXTURE (self)); } diff --git a/src/empathy-rounded-rectangle.h b/src/empathy-rounded-rectangle.h index 38d396f39..e4bf72c6e 100644 --- a/src/empathy-rounded-rectangle.h +++ b/src/empathy-rounded-rectangle.h @@ -59,8 +59,9 @@ GType empathy_rounded_rectangle_get_type (void); (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_ROUNDED_RECTANGLE, \ EmpathyRoundedRectangleClass)) -ClutterActor *empathy_rounded_rectangle_new (guint width, - guint height); +EmpathyRoundedRectangle *empathy_rounded_rectangle_new (guint width, + guint height, + guint round_factor); void empathy_rounded_rectangle_set_border_width (EmpathyRoundedRectangle *self, diff --git a/src/empathy-sanity-cleaning.c b/src/empathy-sanity-cleaning.c new file mode 100644 index 000000000..740d84206 --- /dev/null +++ b/src/empathy-sanity-cleaning.c @@ -0,0 +1,151 @@ +/* + * empathy-sanity-cleaning.c + * Code automatically called when starting a specific version of Empathy for + * the first time doing misc cleaning. + * + * Copyright (C) 2012 Collabora Ltd. + * @author Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> + * + * 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 + */ + +#include "config.h" + +#include "empathy-sanity-cleaning.h" + +#include <telepathy-glib/telepathy-glib.h> + +#include <libempathy/empathy-gsettings.h> + +#define DEBUG_FLAG EMPATHY_DEBUG_OTHER +#include <libempathy/empathy-debug.h> + +/* + * This number has to be increased each time a new task is added or modified. + * + * If the number stored in gsettings is lower than it, all the tasks will + * be executed. + */ +#define SANITY_CLEANING_NUMBER 1 + +static void +account_update_parameters_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + TpAccount *account = TP_ACCOUNT (source); + + if (!tp_account_update_parameters_finish (account, result, NULL, &error)) + { + DEBUG ("Failed to update parameters of account '%s': %s", + tp_account_get_path_suffix (account), error->message); + + g_error_free (error); + return; + } + + tp_account_reconnect_async (account, NULL, NULL); +} + +/* Make sure XMPP accounts don't have a negative priority (bgo #671452) */ +static void +fix_xmpp_account_priority (TpAccountManager *am) +{ + GList *accounts, *l; + + accounts = tp_account_manager_get_valid_accounts (am); + for (l = accounts; l != NULL; l = g_list_next (l)) + { + TpAccount *account = l->data; + GHashTable *params; + gint priority; + + if (tp_strdiff (tp_account_get_protocol (account), "jabber")) + continue; + + params = (GHashTable *) tp_account_get_parameters (account); + if (params == NULL) + continue; + + priority = tp_asv_get_int32 (params, "priority", NULL); + if (priority >= 0) + continue; + + DEBUG ("Resetting XMPP priority of account '%s' to 0", + tp_account_get_path_suffix (account)); + + params = tp_asv_new ( + "priority", G_TYPE_INT, 0, + NULL); + + tp_account_update_parameters_async (account, params, NULL, + account_update_parameters_cb, NULL); + + g_hash_table_unref (params); + } + + g_list_free (accounts); +} + +static void +run_sanity_cleaning_tasks (TpAccountManager *am) +{ + DEBUG ("Starting sanity cleaning tasks"); + + fix_xmpp_account_priority (am); +} + +static void +am_prepare_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + TpAccountManager *am = TP_ACCOUNT_MANAGER (source); + + if (!tp_proxy_prepare_finish (am, result, &error)) + { + DEBUG ("Failed to prepare account manager: %s", error->message); + g_error_free (error); + return; + } + + run_sanity_cleaning_tasks (am); +} + +void empathy_sanity_checking_run_if_needed (void) +{ + GSettings *settings; + guint number; + TpAccountManager *am; + + settings = g_settings_new (EMPATHY_PREFS_SCHEMA); + number = g_settings_get_uint (settings, EMPATHY_PREFS_SANITY_CLEANING_NUMBER); + + if (number == SANITY_CLEANING_NUMBER) + goto out; + + am = tp_account_manager_dup (); + + tp_proxy_prepare_async (am, NULL, am_prepare_cb, NULL); + + g_settings_set_uint (settings, EMPATHY_PREFS_SANITY_CLEANING_NUMBER, + SANITY_CLEANING_NUMBER); + + g_object_unref (am); +out: + g_object_unref (settings); +} diff --git a/src/empathy-auto-salut-account-helper.h b/src/empathy-sanity-cleaning.h index f0409d01d..593f9adce 100644 --- a/src/empathy-auto-salut-account-helper.h +++ b/src/empathy-sanity-cleaning.h @@ -1,5 +1,8 @@ /* - * Copyright (C) 2007-2010 Collabora Ltd. + * empathy-sanity-cleaning.h + * + * Copyright (C) 2012 Collabora Ltd. + * @author Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,23 +17,11 @@ * 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); +#ifndef __EMPATHY_SANITY_CLEANING_H__ +#define __EMPATHY_SANITY_CLEANING_H__ -EmpathyAccountSettings * create_salut_account_settings (void); +void empathy_sanity_checking_run_if_needed (void); #endif diff --git a/src/empathy-streamed-media-factory.c b/src/empathy-streamed-media-factory.c index 1c25ae253..713d441df 100644 --- a/src/empathy-streamed-media-factory.c +++ b/src/empathy-streamed-media-factory.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> diff --git a/src/empathy-streamed-media-handler.c b/src/empathy-streamed-media-handler.c index a3c539773..5e2cac50f 100644 --- a/src/empathy-streamed-media-handler.c +++ b/src/empathy-streamed-media-handler.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> @@ -26,8 +27,7 @@ #include <telepathy-glib/util.h> #include <telepathy-glib/interfaces.h> -#include <telepathy-farsight/channel.h> -#include <telepathy-farsight/stream.h> +#include <telepathy-farstream/telepathy-farstream.h> #include <libempathy/empathy-utils.h> @@ -45,7 +45,7 @@ enum { CONFERENCE_ADDED, SRC_PAD_ADDED, SINK_PAD_ADDED, - REQUEST_RESOURCE, + START_RECEIVING, CLOSED, STREAM_CLOSED, CANDIDATES_CHANGED, @@ -359,8 +359,8 @@ empathy_streamed_media_handler_class_init (EmpathyStreamedMediaHandlerClass *kla G_TYPE_BOOLEAN, 2, GST_TYPE_PAD, G_TYPE_UINT); - signals[REQUEST_RESOURCE] = - g_signal_new ("request-resource", G_TYPE_FROM_CLASS (klass), + signals[START_RECEIVING] = + g_signal_new ("start-receiving", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, g_signal_accumulator_true_handled, NULL, g_cclosure_marshal_generic, @@ -377,7 +377,7 @@ empathy_streamed_media_handler_class_init (EmpathyStreamedMediaHandlerClass *kla g_signal_new ("stream-closed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, - G_TYPE_NONE, 1, TF_TYPE_STREAM); + G_TYPE_NONE, 1, TF_TYPE_CONTENT); signals[CANDIDATES_CHANGED] = g_signal_new ("candidates-changed", G_TYPE_FROM_CLASS (klass), @@ -539,7 +539,7 @@ empathy_streamed_media_handler_bus_message (EmpathyStreamedMediaHandler *handler return; if (s != NULL && - gst_structure_has_name (s, "farsight-send-codec-changed")) + gst_structure_has_name (s, "farstream-send-codec-changed")) { const GValue *val; FsCodec *codec; @@ -554,7 +554,7 @@ empathy_streamed_media_handler_bus_message (EmpathyStreamedMediaHandler *handler update_sending_codec (handler, codec, session); } else if (s != NULL && - gst_structure_has_name (s, "farsight-recv-codecs-changed")) + gst_structure_has_name (s, "farstream-recv-codecs-changed")) { const GValue *val; GList *codecs; @@ -569,7 +569,7 @@ empathy_streamed_media_handler_bus_message (EmpathyStreamedMediaHandler *handler update_receiving_codec (handler, codecs, stream); } else if (s != NULL && - gst_structure_has_name (s, "farsight-new-active-candidate-pair")) + gst_structure_has_name (s, "farstream-new-active-candidate-pair")) { const GValue *val; FsCandidate *remote_candidate, *local_candidate; @@ -591,8 +591,8 @@ empathy_streamed_media_handler_bus_message (EmpathyStreamedMediaHandler *handler } static void -empathy_streamed_media_handler_tf_channel_session_created_cb (TfChannel *tfchannel, - FsConference *conference, FsParticipant *participant, +empathy_streamed_media_handler_tf_channel_conference_added_cb (TfChannel *tfchannel, + FsConference *conference, EmpathyStreamedMediaHandler *self) { g_signal_emit (G_OBJECT (self), signals[CONFERENCE_ADDED], 0, @@ -602,86 +602,85 @@ empathy_streamed_media_handler_tf_channel_session_created_cb (TfChannel *tfchann static gboolean src_pad_added_error_idle (gpointer data) { - TfStream *stream = data; + TfContent *content = data; - tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_MEDIA_ERROR, - "Could not link sink"); - g_object_unref (stream); + tf_content_error_literal (content, "Could not link sink"); + g_object_unref (content); return FALSE; } static void -empathy_streamed_media_handler_tf_stream_src_pad_added_cb (TfStream *stream, - GstPad *pad, FsCodec *codec, EmpathyStreamedMediaHandler *handler) +empathy_streamed_media_handler_tf_content_src_pad_added_cb (TfContent *content, + guint handle, + FsStream *stream, + GstPad *pad, + FsCodec *codec, + EmpathyStreamedMediaHandler *handler) { guint media_type; gboolean retval; - g_object_get (stream, "media-type", &media_type, NULL); + g_object_get (content, "media-type", &media_type, NULL); g_signal_emit (G_OBJECT (handler), signals[SRC_PAD_ADDED], 0, pad, media_type, &retval); if (!retval) - g_idle_add (src_pad_added_error_idle, g_object_ref (stream)); + g_idle_add (src_pad_added_error_idle, g_object_ref (content)); } static gboolean -empathy_streamed_media_handler_tf_stream_request_resource_cb (TfStream *stream, - guint direction, EmpathyTpStreamedMedia *call) +empathy_streamed_media_handler_tf_content_start_receiving_cb (TfContent *content, + guint *handles, guint handle_count, EmpathyTpStreamedMedia *call) { - gboolean ret; + gboolean ret = FALSE; guint media_type; - g_object_get (G_OBJECT (stream), "media-type", &media_type, NULL); + g_object_get (G_OBJECT (content), "media-type", &media_type, NULL); g_signal_emit (G_OBJECT (call), - signals[REQUEST_RESOURCE], 0, media_type, direction, &ret); + signals[START_RECEIVING], 0, media_type, &ret); return ret; } static void -empathy_streamed_media_handler_tf_stream_closed_cb (TfStream *stream, - EmpathyStreamedMediaHandler *handler) +empathy_streamed_media_handler_tf_content_removed_cb (TfChannel *channel, + TfContent *content, EmpathyStreamedMediaHandler *handler) { - g_signal_emit (handler, signals[STREAM_CLOSED], 0, stream); + g_signal_emit (handler, signals[STREAM_CLOSED], 0, content); } static void -empathy_streamed_media_handler_tf_channel_stream_created_cb (TfChannel *tfchannel, - TfStream *stream, EmpathyStreamedMediaHandler *handler) +empathy_streamed_media_handler_tf_channel_content_added_cb (TfChannel *tfchannel, + TfContent *content, EmpathyStreamedMediaHandler *handler) { guint media_type; GstPad *spad; gboolean retval; - FsStream *fs_stream; - GList *codecs; FsSession *session; FsCodec *codec; - g_signal_connect (stream, "src-pad-added", - G_CALLBACK (empathy_streamed_media_handler_tf_stream_src_pad_added_cb), handler); - g_signal_connect (stream, "request-resource", - G_CALLBACK (empathy_streamed_media_handler_tf_stream_request_resource_cb), + g_signal_connect (content, "src-pad-added", + G_CALLBACK (empathy_streamed_media_handler_tf_content_src_pad_added_cb), handler); + + g_signal_connect (content, "start-receiving", + G_CALLBACK (empathy_streamed_media_handler_tf_content_start_receiving_cb), handler); - g_signal_connect (stream, "closed", - G_CALLBACK (empathy_streamed_media_handler_tf_stream_closed_cb), handler); - g_object_get (stream, "media-type", &media_type, + g_object_get (content, "media-type", &media_type, "sink-pad", &spad, NULL); g_signal_emit (G_OBJECT (handler), signals[SINK_PAD_ADDED], 0, spad, media_type, &retval); if (!retval) - tf_stream_error (stream, TP_MEDIA_STREAM_ERROR_MEDIA_ERROR, - "Could not link source"); + tf_content_error_literal (content, "Could not link source"); /* Get sending codec */ - g_object_get (stream, "farsight-session", &session, NULL); + g_object_get (content, "fs-session", &session, NULL); g_object_get (session, "current-send-codec", &codec, NULL); update_sending_codec (handler, codec, session); @@ -689,15 +688,6 @@ empathy_streamed_media_handler_tf_channel_stream_created_cb (TfChannel *tfchanne tp_clear_object (&session); tp_clear_object (&codec); - /* Get receiving codec */ - g_object_get (stream, "farsight-stream", &fs_stream, NULL); - g_object_get (fs_stream, "current-recv-codecs", &codecs, NULL); - - update_receiving_codec (handler, codecs, fs_stream); - - fs_codec_list_destroy (codecs); - tp_clear_object (&fs_stream); - gst_object_unref (spad); } @@ -709,26 +699,45 @@ empathy_streamed_media_handler_tf_channel_closed_cb (TfChannel *tfchannel, } static void -empathy_streamed_media_handler_start_tpfs (EmpathyStreamedMediaHandler *self) +empathy_streamed_media_handler_start_tpfs (GAsyncInitable *initable, + GAsyncResult *res, EmpathyStreamedMediaHandler *self) { EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - TpChannel *channel; - - g_object_get (priv->call, "channel", &channel, NULL); - - g_assert (channel != NULL); - - priv->tfchannel = tf_channel_new (channel); + GError *error = NULL; + GPtrArray *conferences; - /* Set up the telepathy farsight channel */ - g_signal_connect (priv->tfchannel, "session-created", - G_CALLBACK (empathy_streamed_media_handler_tf_channel_session_created_cb), self); - g_signal_connect (priv->tfchannel, "stream-created", - G_CALLBACK (empathy_streamed_media_handler_tf_channel_stream_created_cb), self); - g_signal_connect (priv->tfchannel, "closed", - G_CALLBACK (empathy_streamed_media_handler_tf_channel_closed_cb), self); + if (g_async_initable_init_finish (initable, res, &error)) + { + priv->tfchannel = TF_CHANNEL (initable); + + /* Set up the telepathy farsight channel */ + g_signal_connect (priv->tfchannel, "fs-conference-added", + G_CALLBACK (empathy_streamed_media_handler_tf_channel_conference_added_cb), self); + g_signal_connect (priv->tfchannel, "content-added", + G_CALLBACK (empathy_streamed_media_handler_tf_channel_content_added_cb), self); + g_signal_connect (priv->tfchannel, "content-removed", + G_CALLBACK (empathy_streamed_media_handler_tf_content_removed_cb), + self); + g_signal_connect (priv->tfchannel, "closed", + G_CALLBACK (empathy_streamed_media_handler_tf_channel_closed_cb), self); + + g_object_get (priv->tfchannel, "fs-conferences", &conferences, NULL); + if (conferences) + { + if (conferences->len > 0) + empathy_streamed_media_handler_tf_channel_conference_added_cb ( + priv->tfchannel, g_ptr_array_index (conferences, 0), self); + g_ptr_array_unref (conferences); + } - g_object_unref (channel); + empathy_tp_streamed_media_accept_incoming_call (priv->call); + } + else + { + g_warning ("Error creating tf channel"); + g_clear_error (&error); + } + g_object_unref (self); } static void @@ -758,7 +767,10 @@ empathy_streamed_media_handler_request_cb (GObject *source, g_object_notify (G_OBJECT (self), "tp-call"); - empathy_streamed_media_handler_start_tpfs (self); + + tf_channel_new_async (channel, + (GAsyncReadyCallback) empathy_streamed_media_handler_start_tpfs, + g_object_ref (self)); g_object_unref (channel); } @@ -774,8 +786,14 @@ empathy_streamed_media_handler_start_call (EmpathyStreamedMediaHandler *handler, if (priv->call != NULL) { - empathy_streamed_media_handler_start_tpfs (handler); - empathy_tp_streamed_media_accept_incoming_call (priv->call); + TpChannel *channel; + + g_object_get (priv->call, "channel", &channel, NULL); + + tf_channel_new_async (channel, + (GAsyncReadyCallback) empathy_streamed_media_handler_start_tpfs, + g_object_ref (handler)); + g_object_unref (channel); return; } diff --git a/src/empathy-streamed-media-handler.h b/src/empathy-streamed-media-handler.h index ab655b8e4..429c95447 100644 --- a/src/empathy-streamed-media-handler.h +++ b/src/empathy-streamed-media-handler.h @@ -24,7 +24,7 @@ #include <glib-object.h> #include <gst/gst.h> -#include <gst/farsight/fs-conference-iface.h> +#include <farstream/fs-conference.h> #include <libempathy/empathy-tp-streamed-media.h> #include <libempathy/empathy-contact.h> diff --git a/src/empathy-streamed-media-window.c b/src/empathy-streamed-media-window.c index df3fbab00..87887e75f 100644 --- a/src/empathy-streamed-media-window.c +++ b/src/empathy-streamed-media-window.c @@ -31,11 +31,11 @@ #include <glib/gi18n.h> #include <telepathy-glib/util.h> -#include <telepathy-farsight/channel.h> -#include <telepathy-glib/util.h> -#include <gst/farsight/fs-element-added-notifier.h> -#include <gst/farsight/fs-utils.h> +#include <telepathy-farstream/telepathy-farstream.h> + +#include <farstream/fs-element-added-notifier.h> +#include <farstream/fs-utils.h> #include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-utils.h> @@ -372,7 +372,8 @@ empathy_streamed_media_window_create_video_input_add_slider (EmpathyStreamedMedi gchar *label_text, GtkWidget *bin) { GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); - GtkWidget *scale = gtk_vscale_new_with_range (0, 100, 10); + GtkWidget *scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, 0, + 100, 10); GtkWidget *label = gtk_label_new (label_text); gtk_widget_set_sensitive (scale, FALSE); @@ -540,7 +541,8 @@ empathy_streamed_media_window_create_audio_input (EmpathyStreamedMediaWindow *se vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3); gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3); - priv->volume_scale = gtk_vscale_new_with_range (0, 150, 100); + priv->volume_scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL, 0, + 150, 100); gtk_range_set_inverted (GTK_RANGE (priv->volume_scale), TRUE); label = gtk_label_new (_("Volume")); @@ -1759,8 +1761,8 @@ empathy_streamed_media_window_conference_added_cb (EmpathyStreamedMediaHandler * } static gboolean -empathy_streamed_media_window_request_resource_cb (EmpathyStreamedMediaHandler *handler, - FsMediaType type, FsStreamDirection direction, gpointer user_data) +empathy_streamed_media_window_start_receiving_cb (EmpathyStreamedMediaHandler *handler, + FsMediaType type,gpointer user_data) { EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); @@ -1768,9 +1770,6 @@ empathy_streamed_media_window_request_resource_cb (EmpathyStreamedMediaHandler * if (type != FS_MEDIA_TYPE_VIDEO) return TRUE; - if (direction == FS_DIRECTION_RECV) - return TRUE; - /* video and direction is send */ return priv->video_input != NULL; } @@ -1952,13 +1951,13 @@ empathy_streamed_media_window_channel_closed_cb (EmpathyStreamedMediaHandler *ha static void empathy_streamed_media_window_channel_stream_closed_cb (EmpathyStreamedMediaHandler *handler, - TfStream *stream, gpointer user_data) + TfContent *content, gpointer user_data) { EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); guint media_type; - g_object_get (stream, "media-type", &media_type, NULL); + g_object_get (content, "media-type", &media_type, NULL); /* * This assumes that there is only one video stream per channel... @@ -2719,8 +2718,8 @@ empathy_streamed_media_window_realized_cb (GtkWidget *widget, EmpathyStreamedMed g_signal_connect (priv->handler, "conference-added", G_CALLBACK (empathy_streamed_media_window_conference_added_cb), window); - g_signal_connect (priv->handler, "request-resource", - G_CALLBACK (empathy_streamed_media_window_request_resource_cb), window); + g_signal_connect (priv->handler, "start-receiving", + G_CALLBACK (empathy_streamed_media_window_start_receiving_cb), window); g_signal_connect (priv->handler, "closed", G_CALLBACK (empathy_streamed_media_window_channel_closed_cb), window); g_signal_connect (priv->handler, "src-pad-added", diff --git a/src/empathy-video-src.c b/src/empathy-video-src.c index 3b9e6f8fc..8c9c75015 100644 --- a/src/empathy-video-src.c +++ b/src/empathy-video-src.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> diff --git a/src/empathy-video-widget.c b/src/empathy-video-widget.c index 0eee9e0bc..adca53ef6 100644 --- a/src/empathy-video-widget.c +++ b/src/empathy-video-widget.c @@ -25,7 +25,7 @@ #include <gdk/gdkx.h> #include <gst/interfaces/xoverlay.h> -#include <gst/farsight/fs-element-added-notifier.h> +#include <farstream/fs-element-added-notifier.h> #include "empathy-video-widget.h" @@ -130,8 +130,6 @@ empathy_video_widget_constructed (GObject *object) gst_object_ref (priv->videosink); gst_object_sink (priv->videosink); - priv->sink_pad = gst_element_get_static_pad (priv->videosink, "sink"); - sink = gst_element_factory_make ("gconfvideosink", NULL); g_assert (sink != NULL); diff --git a/src/empathy.c b/src/empathy.c index f59a54f17..2ed3bab5d 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -44,8 +44,6 @@ #include <telepathy-glib/connection-manager.h> #include <telepathy-glib/interfaces.h> -#include <telepathy-yell/telepathy-yell.h> - #include <telepathy-logger/log-manager.h> #include <libempathy/empathy-client-factory.h> @@ -850,11 +848,11 @@ main (int argc, char *argv[]) g_type_init (); #ifdef HAVE_LIBCHAMPLAIN - gtk_clutter_init (&argc, &argv); + g_return_val_if_fail (gtk_clutter_init (&argc, &argv) == + CLUTTER_INIT_SUCCESS, 1); #endif g_type_init (); - tpy_cli_init (); empathy_init (); gtk_init (&argc, &argv); empathy_gtk_init (); |