diff options
Diffstat (limited to 'src')
52 files changed, 2598 insertions, 11311 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index dc85dd9ca..086d13be8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,38 +74,6 @@ empathy_debugger_SOURCES = \ empathy-debugger.c \ $(NULL) -if HAVE_EMPATHY_AV -empathy_av_SOURCES = \ - empathy-av.c \ - empathy-audio-sink.c \ - empathy-audio-sink.h \ - empathy-audio-src.c \ - empathy-audio-src.h \ - empathy-streamed-media-factory.c \ - empathy-streamed-media-factory.h \ - empathy-streamed-media-handler.c \ - empathy-streamed-media-handler.h \ - empathy-streamed-media-window-fullscreen.c \ - empathy-streamed-media-window-fullscreen.h \ - empathy-streamed-media-window.c \ - empathy-streamed-media-window.h \ - empathy-video-src.c \ - empathy-video-src.h \ - empathy-video-widget.c \ - empathy-video-widget.h \ - ev-sidebar.c \ - ev-sidebar.h \ - empathy-mic-monitor.c \ - empathy-mic-monitor.h - $(NULL) - -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 \ @@ -117,7 +85,6 @@ empathy_chat_SOURCES = \ empathy-chat-window.c empathy-chat-window.h \ empathy-invite-participant-dialog.c empathy-invite-participant-dialog.h \ empathy-chat.c \ - gedit-close-button.c gedit-close-button.h \ $(NULL) empathy_call_SOURCES = \ @@ -138,8 +105,6 @@ empathy_call_SOURCES = \ empathy-audio-src.h \ empathy-video-src.c \ empathy-video-src.h \ - empathy-video-widget.c \ - empathy-video-widget.h \ empathy-preferences.c \ empathy-preferences.h \ empathy-camera-menu.c \ @@ -172,7 +137,6 @@ empathy_handwritten_source = \ empathy-preferences.c empathy-preferences.h \ empathy-status-icon.c empathy-status-icon.h \ empathy-chat-manager.c empathy-chat-manager.h \ - gedit-close-button.c gedit-close-button.h \ empathy.c empathy_SOURCES = \ @@ -206,7 +170,6 @@ ui_DATA = \ empathy-accounts-dialog.ui \ empathy-call-window-fullscreen.ui \ empathy-call-window.ui \ - empathy-streamed-media-window.ui \ empathy-chat-window.ui \ empathy-chatrooms-window.ui \ empathy-ft-manager.ui \ @@ -221,20 +184,6 @@ EXTRA_DIST = \ $(autostart_DATA) \ $(ui_DATA) -if HAVE_LIBCHAMPLAIN -empathy_handwritten_source += \ - empathy-map-view.c \ - empathy-map-view.h - -ui_DATA += \ - empathy-map-view.ui -else -EXTRA_DIST += \ - empathy-map-view.c \ - empathy-map-view.h \ - empathy-map-view.ui -endif - dist_man_MANS = \ empathy.1 \ empathy-accounts.1 diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c index 0e004f5a5..578f998bc 100644 --- a/src/empathy-accounts-dialog.c +++ b/src/empathy-accounts-dialog.c @@ -40,9 +40,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> #include <libempathy-gtk/empathy-protocol-chooser.h> @@ -97,6 +95,7 @@ typedef struct { GtkWidget *enabled_switch; GtkWidget *treeview; + GtkCellRenderer *name_renderer; GtkWidget *button_add; GtkWidget *button_remove; @@ -123,7 +122,7 @@ typedef struct { * That's kinda ugly; cf bgo #640417. * * */ - EmpathyAccountWidget *setting_widget_object; + EmpathyAccountWidget *setting_widget; gboolean connecting_show; guint connecting_id; @@ -133,7 +132,7 @@ typedef struct { TpAccountManager *account_manager; EmpathyConnectionManagers *cms; - EmpathyConnectivity *connectivity; + GNetworkMonitor *connectivity; GtkWindow *parent_window; TpAccount *initial_selection; @@ -463,7 +462,7 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog, g_free (message); } - if (!empathy_connectivity_is_online (priv->connectivity)) + if (!g_network_monitor_get_network_available (priv->connectivity)) accounts_dialog_status_infobar_set_message (dialog, _("Offline — No Network Connection")); @@ -540,7 +539,7 @@ empathy_account_dialog_cancel (EmpathyAccountsDialog *dialog) COL_ACCOUNT_SETTINGS, &settings, COL_ACCOUNT, &account, -1); - empathy_account_widget_discard_pending_changes (priv->setting_widget_object); + empathy_account_widget_discard_pending_changes (priv->setting_widget); if (account == NULL) { @@ -580,7 +579,7 @@ accounts_dialog_has_valid_accounts (EmpathyAccountsDialog *dialog) GtkTreeIter iter; gboolean creating; - g_object_get (priv->setting_widget_object, + g_object_get (priv->setting_widget, "creating-account", &creating, NULL); if (!creating) @@ -599,7 +598,7 @@ account_dialog_create_edit_params_dialog (EmpathyAccountsDialog *dialog) { EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); EmpathyAccountSettings *settings; - GtkWidget *subdialog, *content, *content_area, *align; + GtkWidget *subdialog, *content_area, *align; settings = accounts_dialog_model_get_selected_settings (dialog); if (settings == NULL) @@ -610,22 +609,20 @@ account_dialog_create_edit_params_dialog (EmpathyAccountsDialog *dialog) GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, NULL, NULL); - priv->setting_widget_object = + priv->setting_widget = (EmpathyAccountWidget *) empathy_account_widget_new_for_protocol (settings, FALSE); - g_object_add_weak_pointer (G_OBJECT (priv->setting_widget_object), - (gpointer *) &priv->setting_widget_object); + g_object_add_weak_pointer (G_OBJECT (priv->setting_widget), + (gpointer *) &priv->setting_widget); if (accounts_dialog_has_valid_accounts (dialog)) empathy_account_widget_set_other_accounts_exist ( - priv->setting_widget_object, TRUE); + priv->setting_widget, TRUE); - content = empathy_account_widget_get_widget (priv->setting_widget_object); - - g_signal_connect (priv->setting_widget_object, "cancelled", + g_signal_connect (priv->setting_widget, "cancelled", G_CALLBACK (empathy_account_dialog_widget_cancelled_cb), dialog); - g_signal_connect_swapped (priv->setting_widget_object, "close", + g_signal_connect_swapped (priv->setting_widget, "close", G_CALLBACK (gtk_widget_destroy), subdialog); content_area = gtk_dialog_get_content_area (GTK_DIALOG (subdialog)); @@ -633,10 +630,10 @@ account_dialog_create_edit_params_dialog (EmpathyAccountsDialog *dialog) align = gtk_alignment_new (0.5, 0.5, 1, 1); gtk_alignment_set_padding (GTK_ALIGNMENT (align), 6, 0, 6, 6); - gtk_container_add (GTK_CONTAINER (align), content); + gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET (priv->setting_widget)); gtk_box_pack_start (GTK_BOX (content_area), align, TRUE, TRUE, 0); - gtk_widget_show (content); + gtk_widget_show (GTK_WIDGET (priv->setting_widget)); gtk_widget_show (align); gtk_widget_show (subdialog); } @@ -787,22 +784,14 @@ account_dialog_show_contact_details_failed (EmpathyAccountsDialog *dialog, } static void -account_dialog_got_self_contact (TpConnection *conn, - EmpathyContact *contact, - const GError *in_error, - gpointer user_data, - GObject *dialog) +create_contact_info_editor (EmpathyAccountsDialog *self, + TpContact *tp_contact) { - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + EmpathyAccountsDialogPriv *priv = GET_PRIV (self); GtkWidget *editor, *alig; + EmpathyContact *contact; - if (in_error != NULL) - { - DEBUG ("Failed to get self-contact: %s", in_error->message); - account_dialog_show_contact_details_failed ( - EMPATHY_ACCOUNTS_DIALOG (dialog), TRUE); - return; - } + contact = empathy_contact_dup_from_tp_contact (tp_contact); alig = gtk_alignment_new (0.5, 0, 1, 1); @@ -818,6 +807,7 @@ account_dialog_got_self_contact (TpConnection *conn, gtk_container_add (GTK_CONTAINER (alig), editor); gtk_widget_show (alig); gtk_widget_show (editor); + g_object_unref (contact); } static void @@ -828,14 +818,11 @@ account_dialog_create_dialog_content (EmpathyAccountsDialog *dialog, const gchar *icon_name; TpAccount *account; TpConnection *conn = NULL; + TpContact *contact = NULL; GtkWidget *bbox, *button; account = empathy_account_settings_get_account (settings); - // if (priv->setting_widget_object != NULL) - // g_object_remove_weak_pointer (G_OBJECT (priv->setting_widget_object), - // (gpointer *) &priv->setting_widget_object); - priv->dialog_content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_container_add (GTK_CONTAINER (priv->alignment_settings), priv->dialog_content); @@ -848,10 +835,12 @@ account_dialog_create_dialog_content (EmpathyAccountsDialog *dialog, if (conn != NULL && tp_proxy_get_invalidated (conn) == NULL) { - empathy_tp_contact_factory_get_from_handle (conn, - tp_connection_get_self_handle (conn), - account_dialog_got_self_contact, - NULL, NULL, G_OBJECT (dialog)); + contact = tp_connection_get_self_contact (conn); + } + + if (contact != NULL) + { + create_contact_info_editor (dialog, contact); } else { @@ -938,9 +927,9 @@ accounts_dialog_has_pending_change (EmpathyAccountsDialog *dialog, if (gtk_tree_selection_get_selected (selection, &model, &iter)) gtk_tree_model_get (model, &iter, COL_ACCOUNT, account, -1); - return priv->setting_widget_object != NULL + return priv->setting_widget != NULL && empathy_account_widget_contains_pending_changes ( - priv->setting_widget_object); + priv->setting_widget); } static void @@ -1011,7 +1000,7 @@ accounts_dialog_button_add_clicked_cb (GtkWidget *button, response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response == GTK_RESPONSE_OK) + if (response == GTK_RESPONSE_APPLY) { EmpathyAccountSettings *settings; TpAccount *account; @@ -1390,24 +1379,6 @@ accounts_dialog_button_remove_clicked_cb (GtkWidget *button, accounts_dialog_remove_account_iter (dialog, &iter); } -#ifdef HAVE_MEEGO -static void -accounts_dialog_view_delete_activated_cb (EmpathyCellRendererActivatable *cell, - const gchar *path_string, - EmpathyAccountsDialog *dialog) -{ - EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - GtkTreeModel *model; - GtkTreeIter iter; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); - if (!gtk_tree_model_get_iter_from_string (model, &iter, path_string)) - return; - - accounts_dialog_remove_account_iter (dialog, &iter); -} -#endif /* HAVE_MEEGO */ - static void accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) { @@ -1443,35 +1414,22 @@ accounts_dialog_model_add_columns (EmpathyAccountsDialog *dialog) NULL); /* Name renderer */ - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, + priv->name_renderer = gtk_cell_renderer_text_new (); + g_object_set (priv->name_renderer, "ellipsize", PANGO_ELLIPSIZE_END, "width-chars", 25, "editable", TRUE, NULL); - gtk_tree_view_column_pack_start (column, cell, TRUE); - gtk_tree_view_column_add_attribute (column, cell, "text", COL_NAME); - g_signal_connect (cell, "edited", + gtk_tree_view_column_pack_start (column, priv->name_renderer, TRUE); + gtk_tree_view_column_add_attribute (column, priv->name_renderer, + "text", COL_NAME); + g_signal_connect (priv->name_renderer, "edited", G_CALLBACK (accounts_dialog_name_edited_cb), dialog); - g_signal_connect (cell, "editing-started", + g_signal_connect (priv->name_renderer, "editing-started", G_CALLBACK (accounts_dialog_name_editing_started_cb), dialog); - g_object_set (cell, "ypad", 4, NULL); - -#ifdef HAVE_MEEGO - /* Delete column */ - cell = empathy_cell_renderer_activatable_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - g_object_set (cell, - "icon-name", GTK_STOCK_DELETE, - "show-on-select", TRUE, - NULL); - - g_signal_connect (cell, "path-activated", - G_CALLBACK (accounts_dialog_view_delete_activated_cb), - dialog); -#endif /* HAVE_MEEGO */ + g_object_set (priv->name_renderer, "ypad", 4, NULL); } static EmpathyAccountSettings * @@ -1515,9 +1473,9 @@ accounts_dialog_model_selection_changed (GtkTreeSelection *selection, if (settings != NULL) g_object_unref (settings); - if (priv->setting_widget_object != NULL) + if (priv->setting_widget != NULL) { - g_object_get (priv->setting_widget_object, + g_object_get (priv->setting_widget, "creating-account", &creating, NULL); } @@ -1546,7 +1504,7 @@ accounts_dialog_selection_change_response_cb (GtkDialog *message_dialog, priv->force_change_row = TRUE; empathy_account_widget_discard_pending_changes ( - priv->setting_widget_object); + priv->setting_widget); path = gtk_tree_row_reference_get_path (priv->destination_row); selection = gtk_tree_view_get_selection ( @@ -1731,6 +1689,30 @@ accounts_dialog_treeview_enabled_cb (GtkMenuItem *item, enable_and_connect_account (account, !enabled); } +static void +accounts_dialog_treeview_rename_cb (GtkMenuItem *item, + EmpathyAccountsDialog *self) +{ + EmpathyAccountsDialogPriv *priv = GET_PRIV (self); + GtkTreePath *path; + GtkTreeIter iter; + GtkTreeSelection *selection; + GtkTreeModel *model; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + path = gtk_tree_model_get_path (model, &iter); + + g_object_set (G_OBJECT (priv->name_renderer), "editable", TRUE, NULL); + + gtk_widget_grab_focus (GTK_WIDGET (priv->treeview)); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->treeview), path, + gtk_tree_view_get_column (GTK_TREE_VIEW (priv->treeview), 0), TRUE); + + gtk_tree_path_free (path); +} + static gboolean accounts_dialog_treeview_button_press_event_cb (GtkTreeView *view, GdkEventButton *event, @@ -1742,8 +1724,7 @@ accounts_dialog_treeview_button_press_event_cb (GtkTreeView *view, GtkTreePath *path = NULL; GtkTreeIter iter; GtkWidget *menu; - GtkWidget *item_enable, *item_disable; - GtkWidget *image_enable, *image_disable; + GtkWidget *item; /* ignore multiple clicks */ if (event->type != GDK_BUTTON_PRESS) @@ -1766,49 +1747,37 @@ accounts_dialog_treeview_button_press_event_cb (GtkTreeView *view, /* Create the menu */ menu = empathy_context_menu_new (GTK_WIDGET (view)); - /* Get images for menu items */ - image_enable = gtk_image_new_from_icon_name (empathy_icon_name_for_presence ( - tp_account_manager_get_most_available_presence ( - priv->account_manager, NULL, NULL)), - GTK_ICON_SIZE_MENU); - image_disable = gtk_image_new_from_icon_name ( - empathy_icon_name_for_presence (TP_CONNECTION_PRESENCE_TYPE_OFFLINE), - GTK_ICON_SIZE_MENU); - - /* Menu items: to enabled/disable the account */ - item_enable = gtk_image_menu_item_new_with_mnemonic (_("_Enable")); - item_disable = gtk_image_menu_item_new_with_mnemonic (_("_Disable")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_enable), - image_enable); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_disable), - image_disable); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item_enable); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item_disable); + /* Menu item: to enabled/disable the account */ + item = gtk_check_menu_item_new_with_mnemonic (_("_Enabled")); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); if (account_can_be_enabled (account)) { - if (tp_account_is_enabled (account)) - { - tp_g_signal_connect_object (item_disable, "activate", - G_CALLBACK (accounts_dialog_treeview_enabled_cb), account, 0); - gtk_widget_set_sensitive (item_enable, FALSE); - } - else - { - tp_g_signal_connect_object (item_enable, "activate", - G_CALLBACK (accounts_dialog_treeview_enabled_cb), account, 0); - gtk_widget_set_sensitive (item_disable, FALSE); - } + gboolean active; + + active = tp_account_is_enabled (account); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), + active); + + tp_g_signal_connect_object (item, "activate", + G_CALLBACK (accounts_dialog_treeview_enabled_cb), account, 0); } else { - gtk_widget_set_sensitive (item_enable, FALSE); - gtk_widget_set_sensitive (item_disable, FALSE); + gtk_widget_set_sensitive (item, FALSE); } - gtk_widget_show (item_enable); - gtk_widget_show (item_disable); + gtk_widget_show (item); + + /* Menu item: Rename */ + item = gtk_menu_item_new_with_mnemonic (_("Rename")); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + tp_g_signal_connect_object (item, "activate", + G_CALLBACK (accounts_dialog_treeview_rename_cb), dialog, 0); + + gtk_widget_show (item); /* FIXME: Add here presence items, to be able to set per-account presence */ @@ -2072,11 +2041,11 @@ accounts_dialog_accounts_model_row_inserted_cb (GtkTreeModel *model, { EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - if (priv->setting_widget_object != NULL && + if (priv->setting_widget != NULL && accounts_dialog_has_valid_accounts (dialog)) { empathy_account_widget_set_other_accounts_exist ( - priv->setting_widget_object, TRUE); + priv->setting_widget, TRUE); } } @@ -2087,11 +2056,11 @@ accounts_dialog_accounts_model_row_deleted_cb (GtkTreeModel *model, { EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); - if (priv->setting_widget_object != NULL && + if (priv->setting_widget != NULL && !accounts_dialog_has_valid_accounts (dialog)) { empathy_account_widget_set_other_accounts_exist ( - priv->setting_widget_object, FALSE); + priv->setting_widget, FALSE); } } @@ -2467,11 +2436,6 @@ accounts_dialog_build_ui (EmpathyAccountsDialog *dialog) action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); -#ifdef HAVE_MEEGO - gtk_widget_hide (action_area); - gtk_widget_hide (priv->button_remove); -#endif /* HAVE_MEEGO */ - /* Display loading page */ priv->loading = TRUE; @@ -2590,6 +2554,12 @@ do_dispose (GObject *obj) priv->connecting_id = 0; } + if (priv->connectivity) + { + g_object_unref (priv->connectivity); + priv->connectivity = NULL; + } + if (priv->account_manager != NULL) { g_object_unref (priv->account_manager); @@ -2602,12 +2572,6 @@ do_dispose (GObject *obj) priv->cms = NULL; } - if (priv->connectivity) - { - g_object_unref (priv->connectivity); - priv->connectivity = NULL; - } - if (priv->initial_selection != NULL) { g_object_unref (priv->initial_selection); @@ -2675,7 +2639,8 @@ do_constructed (GObject *object) tp_proxy_prepare_async (priv->account_manager, NULL, accounts_dialog_manager_ready_cb, dialog); - priv->connectivity = empathy_connectivity_dup_singleton (); + priv->connectivity = g_network_monitor_get_default (); + g_object_ref (priv->connectivity); } static void @@ -2777,10 +2742,10 @@ empathy_accounts_dialog_is_creating (EmpathyAccountsDialog *dialog) EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); gboolean result = FALSE; - if (priv->setting_widget_object == NULL) + if (priv->setting_widget == NULL) goto out; - g_object_get (priv->setting_widget_object, + g_object_get (priv->setting_widget, "creating-account", &result, NULL); out: diff --git a/src/empathy-accounts-dialog.ui b/src/empathy-accounts-dialog.ui index 549a92651..777187bf5 100644 --- a/src/empathy-accounts-dialog.ui +++ b/src/empathy-accounts-dialog.ui @@ -13,7 +13,7 @@ <child> <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> - <property name="spacing">0</property> + <property name="can_focus">False</property> <child> <object class="GtkScrolledWindow" id="accounts_sw"> <property name="height_request">200</property> @@ -114,7 +114,8 @@ <child> <object class="GtkVBox" id="vbox_details"> <property name="visible">True</property> - <property name="spacing">18</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> <child> <placeholder/> </child> @@ -133,8 +134,9 @@ <child> <object class="GtkAlignment" id="alignment_settings"> <property name="visible">True</property> - <property name="top_padding">6</property> - <property name="left_padding">20</property> + <property name="can_focus">False</property> + <property name="left_padding">6</property> + <property name="right_padding">6</property> <child> <placeholder/> </child> diff --git a/src/empathy-accounts.c b/src/empathy-accounts.c index efb98e9b3..027d99918 100644 --- a/src/empathy-accounts.c +++ b/src/empathy-accounts.c @@ -199,6 +199,7 @@ local_cmdline (GApplication *app, optcontext = g_option_context_new (N_("- Empathy Accounts")); g_option_context_add_group (optcontext, gtk_get_option_group (TRUE)); g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE); + g_option_context_set_translation_domain (optcontext, GETTEXT_PACKAGE); argv = *arguments; for (i = 0; argv[i] != NULL; i++) @@ -226,7 +227,6 @@ main (int argc, char *argv[]) GObjectClass *app_class; gint retval; - g_thread_init (NULL); g_type_init (); #ifdef HAVE_CHEESE @@ -244,7 +244,6 @@ main (int argc, char *argv[]) /* Make empathy and empathy-accounts appear as the same app in gnome-shell */ gdk_set_program_class ("Empathy"); gtk_window_set_default_icon_name ("empathy"); - textdomain (GETTEXT_PACKAGE); app = gtk_application_new (EMPATHY_ACCOUNTS_DBUS_NAME, G_APPLICATION_HANDLES_COMMAND_LINE); diff --git a/src/empathy-audio-sink.c b/src/empathy-audio-sink.c index 2968fb53c..d48e6af20 100644 --- a/src/empathy-audio-sink.c +++ b/src/empathy-audio-sink.c @@ -65,7 +65,7 @@ struct _EmpathyGstAudioSinkPrivate gboolean echo_cancel; gdouble volume; gint volume_idle_id; - GStaticMutex volume_mutex; + GMutex volume_mutex; }; #define EMPATHY_GST_AUDIO_SINK_GET_PRIVATE(o) \ @@ -77,7 +77,7 @@ empathy_audio_sink_init (EmpathyGstAudioSink *self) { self->priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self); self->priv->echo_cancel = TRUE; - g_static_mutex_init (&self->priv->volume_mutex); + g_mutex_init (&self->priv->volume_mutex); } static GstPad * empathy_audio_sink_request_new_pad (GstElement *self, @@ -95,9 +95,9 @@ empathy_audio_sink_set_property (GObject *object, switch (property_id) { case PROP_VOLUME: - g_static_mutex_lock (&self->priv->volume_mutex); + g_mutex_lock (&self->priv->volume_mutex); self->priv->volume = g_value_get_double (value); - g_static_mutex_unlock (&self->priv->volume_mutex); + g_mutex_unlock (&self->priv->volume_mutex); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -129,7 +129,7 @@ empathy_audio_sink_dispose (GObject *object) g_source_remove (priv->volume_idle_id); priv->volume_idle_id = 0; - g_static_mutex_free (&self->priv->volume_mutex); + g_mutex_clear (&self->priv->volume_mutex); /* release any references held by the object here */ if (G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose) @@ -236,9 +236,9 @@ empathy_audio_sink_volume_idle_updated (gpointer user_data) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (user_data); - g_static_mutex_lock (&self->priv->volume_mutex); + g_mutex_lock (&self->priv->volume_mutex); self->priv->volume_idle_id = 0; - g_static_mutex_unlock (&self->priv->volume_mutex); + g_mutex_unlock (&self->priv->volume_mutex); g_object_notify (G_OBJECT (self), "volume"); @@ -253,7 +253,7 @@ empathy_audio_sink_volume_updated (GObject *object, EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (user_data); gdouble volume; - g_static_mutex_lock (&self->priv->volume_mutex); + g_mutex_lock (&self->priv->volume_mutex); g_object_get (object, "volume", &volume, NULL); if (self->priv->volume == volume) @@ -265,7 +265,7 @@ empathy_audio_sink_volume_updated (GObject *object, empathy_audio_sink_volume_idle_updated, self); out: - g_static_mutex_unlock (&self->priv->volume_mutex); + g_mutex_unlock (&self->priv->volume_mutex); } static gboolean @@ -274,9 +274,9 @@ empathy_audio_sink_volume_idle_setup (gpointer user_data) EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (user_data); gdouble volume; - g_static_mutex_lock (&self->priv->volume_mutex); + g_mutex_lock (&self->priv->volume_mutex); self->priv->volume_idle_id = 0; - g_static_mutex_unlock (&self->priv->volume_mutex); + g_mutex_unlock (&self->priv->volume_mutex); /* We can't do a bidirection bind as the ::notify comes from another * thread, for other bits of empathy it's most simpler if it comes from @@ -329,11 +329,11 @@ empathy_audio_sink_request_new_pad (GstElement *element, if (GST_IS_STREAM_VOLUME (self->priv->sink)) { - g_static_mutex_lock (&self->priv->volume_mutex); + g_mutex_lock (&self->priv->volume_mutex); if (self->priv->volume_idle_id == 0) self->priv->volume_idle_id = g_idle_add ( empathy_audio_sink_volume_idle_setup, self); - g_static_mutex_unlock (&self->priv->volume_mutex); + g_mutex_unlock (&self->priv->volume_mutex); } else { diff --git a/src/empathy-audio-src.c b/src/empathy-audio-src.c index ca086148f..9a6ddee24 100644 --- a/src/empathy-audio-src.c +++ b/src/empathy-audio-src.c @@ -77,7 +77,7 @@ struct _EmpathyGstAudioSrcPrivate gboolean mute; gboolean have_stream_volume; - GMutex *lock; + GMutex lock; guint level_idle_id; guint volume_idle_id; }; @@ -285,7 +285,8 @@ empathy_audio_src_init (EmpathyGstAudioSrc *obj) obj->priv = priv; priv->peak_level = -G_MAXDOUBLE; - priv->lock = g_mutex_new (); + g_mutex_init (&priv->lock); + priv->volume = 1.0; priv->src = create_src (); @@ -413,14 +414,14 @@ empathy_audio_src_get_property (GObject *object, g_value_set_boolean (value, priv->mute); break; case PROP_PEAK_LEVEL: - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); g_value_set_double (value, priv->peak_level); - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); break; case PROP_RMS_LEVEL: - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); g_value_set_double (value, priv->rms_level); - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); break; case PROP_MICROPHONE: g_value_set_uint (value, priv->source_idx); @@ -526,7 +527,7 @@ empathy_audio_src_finalize (GObject *object) EmpathyGstAudioSrcPrivate *priv = EMPATHY_GST_AUDIO_SRC_GET_PRIVATE (self); /* free any data held directly by the object here */ - g_mutex_free (priv->lock); + g_mutex_clear (&priv->lock); G_OBJECT_CLASS (empathy_audio_src_parent_class)->finalize (object); } @@ -537,13 +538,13 @@ empathy_audio_src_levels_updated (gpointer user_data) EmpathyGstAudioSrc *self = EMPATHY_GST_AUDIO_SRC (user_data); EmpathyGstAudioSrcPrivate *priv = EMPATHY_GST_AUDIO_SRC_GET_PRIVATE (self); - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); g_signal_emit (self, signals[PEAK_LEVEL_CHANGED], 0, priv->peak_level); g_signal_emit (self, signals[RMS_LEVEL_CHANGED], 0, priv->rms_level); priv->level_idle_id = 0; - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); return FALSE; } @@ -556,9 +557,9 @@ empathy_audio_src_volume_changed_idle (gpointer user_data) gdouble volume; gboolean mute; - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); priv->volume_idle_id = 0; - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); volume = empathy_audio_src_get_hw_volume (self); @@ -587,11 +588,11 @@ empathy_audio_src_volume_changed (GObject *object, { EmpathyGstAudioSrc *self = EMPATHY_GST_AUDIO_SRC (user_data); - g_mutex_lock (self->priv->lock); + g_mutex_lock (&self->priv->lock); if (self->priv->volume_idle_id == 0) self->priv->volume_idle_id = g_idle_add ( empathy_audio_src_volume_changed_idle, self); - g_mutex_unlock (self->priv->lock); + g_mutex_unlock (&self->priv->lock); return FALSE; } @@ -644,7 +645,7 @@ empathy_audio_src_handle_message (GstBin *bin, GstMessage *message) rms = MAX (db, rms); } - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); priv->peak_level = peak; priv->rms_level = rms; @@ -652,7 +653,7 @@ empathy_audio_src_handle_message (GstBin *bin, GstMessage *message) priv->level_idle_id = g_idle_add ( empathy_audio_src_levels_updated, self); - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); } out: GST_BIN_CLASS (empathy_audio_src_parent_class)->handle_message (bin, diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c index 0797952c3..ec433ca97 100644 --- a/src/empathy-auth-client.c +++ b/src/empathy-auth-client.c @@ -93,8 +93,8 @@ tls_dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data) { - EmpathyTLSCertificate *certificate = NULL; - EmpTLSCertificateRejectReason reason = 0; + TpTLSCertificate *certificate = NULL; + TpTLSCertificateRejectReason reason = 0; GHashTable *details = NULL; EmpathyTLSDialog *tls_dialog = EMPATHY_TLS_DIALOG (dialog); gboolean remember = FALSE; @@ -113,13 +113,15 @@ tls_dialog_response_cb (GtkDialog *dialog, if (response_id == GTK_RESPONSE_YES) { - empathy_tls_certificate_accept_async (certificate, NULL, NULL); + tp_tls_certificate_accept_async (certificate, NULL, NULL); } else { tp_asv_set_boolean (details, "user-requested", TRUE); - empathy_tls_certificate_reject_async (certificate, reason, details, - NULL, NULL); + tp_tls_certificate_add_rejection (certificate, reason, NULL, + g_variant_new_parsed ("{ 'user-requested': <%b> }", TRUE)); + + tp_tls_certificate_reject_async (certificate, NULL, NULL); } if (remember) @@ -138,9 +140,9 @@ tls_dialog_response_cb (GtkDialog *dialog, } static void -display_interactive_dialog (EmpathyTLSCertificate *certificate, +display_interactive_dialog (TpTLSCertificate *certificate, EmpathyTLSVerifier *verifier, - EmpTLSCertificateRejectReason reason, + TpTLSCertificateRejectReason reason, GHashTable *details) { GtkWidget *tls_dialog; @@ -162,9 +164,9 @@ verifier_verify_cb (GObject *source, GAsyncResult *result, gpointer user_data) { - EmpTLSCertificateRejectReason reason; + TpTLSCertificateRejectReason reason; GError *error = NULL; - EmpathyTLSCertificate *certificate = NULL; + TpTLSCertificate *certificate = NULL; GHashTable *details = NULL; gchar *hostname = NULL; @@ -185,7 +187,7 @@ verifier_verify_cb (GObject *source, } else { - empathy_tls_certificate_accept_async (certificate, NULL, NULL); + tp_tls_certificate_accept_async (certificate, NULL, NULL); } g_free (hostname); @@ -197,7 +199,7 @@ auth_factory_new_tls_handler_cb (EmpathyAuthFactory *factory, EmpathyServerTLSHandler *handler, gpointer user_data) { - EmpathyTLSCertificate *certificate = NULL; + TpTLSCertificate *certificate = NULL; gchar *hostname = NULL; gchar **reference_identities = NULL; EmpathyTLSVerifier *verifier; @@ -261,7 +263,7 @@ auth_factory_auth_passsword_failed (EmpathyAuthFactory *factory, { GtkWidget *dialog; - DEBUG ("Authentification on %s failed, popup password dialog", + DEBUG ("Authentication on %s failed, popup password dialog", tp_account_get_path_suffix (account)); dialog = empathy_bad_password_dialog_new (account, password); @@ -283,8 +285,6 @@ main (int argc, TpSimpleClientFactory *tp_factory; TpDBusDaemon *dbus; - g_thread_init (NULL); - context = g_option_context_new (N_(" - Empathy authentication client")); g_option_context_add_group (context, gtk_get_option_group (TRUE)); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); @@ -309,6 +309,9 @@ main (int argc, gtk_window_set_default_icon_name ("empathy"); textdomain (GETTEXT_PACKAGE); + /* There is no 'main' UI window so just use the default GdkScreen */ + empathy_set_css_provider (NULL); + #ifdef ENABLE_DEBUG /* Set up debug sender */ debug_sender = tp_debug_sender_dup (); diff --git a/src/empathy-av.c b/src/empathy-av.c deleted file mode 100644 index 70acfc4f3..000000000 --- a/src/empathy-av.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2007-2010 Collabora Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - * - * Authors: Xavier Claessens <xclaesse@gmail.com> - * Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> - */ - -#include <config.h> - -#include <glib.h> -#include <glib/gi18n.h> -#include <gtk/gtk.h> - -#include <telepathy-glib/debug-sender.h> - -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-streamed-media-window.h" -#include "empathy-streamed-media-factory.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_VOIP -#include <libempathy/empathy-debug.h> - -#include <gst/gst.h> - -/* Exit after $TIMEOUT seconds if not displaying any call window */ -#define TIMEOUT 60 - -#define EMPATHY_AV_DBUS_NAME "org.gnome.Empathy.AudioVideo" - -static GtkApplication *app = NULL; -static gboolean activated = FALSE; -static gboolean use_timer = TRUE; - -static EmpathyStreamedMediaFactory *call_factory = NULL; - -static void -new_call_handler_cb (EmpathyStreamedMediaFactory *factory, - EmpathyStreamedMediaHandler *handler, - gboolean outgoing, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *window; - - DEBUG ("Create a new StreamedMedia window"); - - window = empathy_streamed_media_window_new (handler); - - g_application_hold (G_APPLICATION (app)); - - g_signal_connect_swapped (window, "destroy", - G_CALLBACK (g_application_release), app); - - gtk_widget_show (GTK_WIDGET (window)); -} - -static void -activate_cb (GApplication *application) -{ - GError *error = NULL; - - if (activated) - return; - - activated = TRUE; - - if (!use_timer) - { - /* keep a 'ref' to the application */ - g_application_hold (G_APPLICATION (app)); - } - - g_assert (call_factory == NULL); - call_factory = empathy_streamed_media_factory_initialise (); - - g_signal_connect (G_OBJECT (call_factory), "new-streamed-media-handler", - G_CALLBACK (new_call_handler_cb), NULL); - - if (!empathy_streamed_media_factory_register (call_factory, &error)) - { - g_critical ("Failed to register Handler: %s", error->message); - g_error_free (error); - } -} - -int -main (int argc, - char *argv[]) -{ - GOptionContext *optcontext; - GOptionEntry options[] = { - { NULL } - }; -#ifdef ENABLE_DEBUG - TpDebugSender *debug_sender; -#endif - GError *error = NULL; - gint retval; - - /* Init */ - g_thread_init (NULL); - - optcontext = g_option_context_new (N_("- Empathy Audio/Video Client")); - g_option_context_add_group (optcontext, gst_init_get_option_group ()); - g_option_context_add_group (optcontext, gtk_get_option_group (TRUE)); - g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE); - - if (!g_option_context_parse (optcontext, &argc, &argv, &error)) { - g_print ("%s\nRun '%s --help' to see a full list of available command " - "line options.\n", - error->message, argv[0]); - g_warning ("Error in empathy-av init: %s", error->message); - return EXIT_FAILURE; - } - - g_option_context_free (optcontext); - - empathy_gtk_init (); - g_set_application_name (_("Empathy Audio/Video Client")); - - /* Make empathy and empathy-av appear as the same app in gnome-shell */ - gdk_set_program_class ("Empathy"); - gtk_window_set_default_icon_name ("empathy"); - textdomain (GETTEXT_PACKAGE); - - app = gtk_application_new (EMPATHY_AV_DBUS_NAME, G_APPLICATION_FLAGS_NONE); - g_signal_connect (app, "activate", G_CALLBACK (activate_cb), NULL); - -#ifdef ENABLE_DEBUG - /* Set up debug sender */ - debug_sender = tp_debug_sender_dup (); - g_log_set_default_handler (tp_debug_sender_log_handler, G_LOG_DOMAIN); -#endif - - if (g_getenv ("EMPATHY_PERSIST") != NULL) - { - DEBUG ("Disable timer"); - - use_timer = FALSE; - } - - /* the inactivity timeout can only be set while the application is held */ - g_application_hold (G_APPLICATION (app)); - g_application_set_inactivity_timeout (G_APPLICATION (app), TIMEOUT * 1000); - g_application_release (G_APPLICATION (app)); - - retval = g_application_run (G_APPLICATION (app), argc, argv); - - g_object_unref (app); - tp_clear_object (&call_factory); - -#ifdef ENABLE_DEBUG - g_object_unref (debug_sender); -#endif - - return retval; -} diff --git a/src/empathy-call-factory.c b/src/empathy-call-factory.c index 783c44e95..9401ae71b 100644 --- a/src/empathy-call-factory.c +++ b/src/empathy-call-factory.c @@ -30,7 +30,6 @@ #include <libempathy/empathy-client-factory.h> #include <libempathy/empathy-request-util.h> -#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-utils.h> #include "empathy-call-factory.h" diff --git a/src/empathy-call-handler.c b/src/empathy-call-handler.c index 33ae9c709..be0987e95 100644 --- a/src/empathy-call-handler.c +++ b/src/empathy-call-handler.c @@ -30,7 +30,6 @@ #include <telepathy-farstream/telepathy-farstream.h> #include <libempathy/empathy-utils.h> -#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy-gtk/empathy-call-utils.h> diff --git a/src/empathy-call-observer.c b/src/empathy-call-observer.c index 35ceeb046..de21506d5 100644 --- a/src/empathy-call-observer.c +++ b/src/empathy-call-observer.c @@ -102,29 +102,16 @@ auto_reject_ctx_free (AutoRejectCtx *ctx) } static void -get_contact_cb (TpConnection *connection, - guint n_contacts, - TpContact * const *contacts, - guint n_failed, - const TpHandle *failed, - const GError *error, - gpointer user_data, - GObject *weak_object) +display_reject_notification (EmpathyCallObserver *self, + TpChannel *channel) { - EmpathyCallObserver *self = (EmpathyCallObserver *) weak_object; - NotifyNotification *notification; TpContact *contact; + NotifyNotification *notification; gchar *summary, *body; EmpathyContact *emp_contact; GdkPixbuf *pixbuf; - if (n_contacts != 1) - { - DEBUG ("Failed to get TpContact; ignoring notification bubble"); - return; - } - - contact = contacts[0]; + contact = tp_channel_get_target_contact (channel); summary = g_strdup_printf (_("Missed call from %s"), tp_contact_get_alias (contact)); @@ -152,21 +139,6 @@ get_contact_cb (TpConnection *connection, g_object_unref (emp_contact); } -static void -display_reject_notification (EmpathyCallObserver *self, - TpChannel *channel) -{ - TpHandle handle; - TpContactFeature features[] = { TP_CONTACT_FEATURE_ALIAS, - TP_CONTACT_FEATURE_AVATAR_DATA }; - - handle = tp_channel_get_handle (channel, NULL); - - tp_connection_get_contacts_by_handle (tp_channel_borrow_connection (channel), - 1, &handle, G_N_ELEMENTS (features), features, get_contact_cb, - g_object_ref (channel), g_object_unref, G_OBJECT (self)); -} - static TpChannel * find_main_channel (GList *channels) { diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index bd2067865..6286cab57 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -43,7 +43,6 @@ #include <libempathy/empathy-camera-monitor.h> #include <libempathy/empathy-gsettings.h> -#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-request-util.h> #include <libempathy/empathy-utils.h> @@ -61,7 +60,6 @@ #include "empathy-call-window.h" #include "empathy-call-window-fullscreen.h" #include "empathy-call-factory.h" -#include "empathy-video-widget.h" #include "empathy-about-dialog.h" #include "empathy-audio-src.h" #include "empathy-audio-sink.h" @@ -77,19 +75,18 @@ #define CONTENT_HBOX_CHILDREN_PACKING_PADDING 0 #define OVERLAY_MARGIN 6 +#define REMOTE_VIDEO_DEFAULT_WIDTH 320 +#define REMOTE_VIDEO_DEFAULT_HEIGHT 240 + #define SELF_VIDEO_SECTION_WIDTH 120 #define SELF_VIDEO_SECTION_HEIGHT 90 #define SELF_VIDEO_SECTION_MARGIN 2 #define SELF_VIDEO_SECTION_BORDER SELF_VIDEO_SECTION_MARGIN*2 -#define FLOATING_TOOLBAR_OPACITY 192 -#define FLOATING_TOOLBAR_SPACING 20 - /* The avatar's default width and height are set to the same value because we want a square icon. */ -#define REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT -#define REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT \ - EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT +#define REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT REMOTE_VIDEO_DEFAULT_HEIGHT +#define REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH REMOTE_VIDEO_DEFAULT_HEIGHT #define SMALL_TOOLBAR_SIZE 36 @@ -243,7 +240,7 @@ struct _EmpathyCallWindowPriv GTimer *timer; guint timer_id; - GMutex *lock; + GMutex lock; gboolean call_started; gboolean sending_video; CameraState camera_state; @@ -542,8 +539,8 @@ empathy_call_window_disable_camera_cb (GtkAction *action, { clutter_actor_destroy (self->priv->preview_hidden_button); - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (self->priv->camera_button), FALSE); + gtk_toggle_button_set_active ( + GTK_TOGGLE_BUTTON (self->priv->camera_button), FALSE); } static void @@ -1550,7 +1547,6 @@ empathy_call_window_init (EmpathyCallWindow *self) gchar *filename; ClutterConstraint *constraint; ClutterActor *remote_avatar; - GtkCssProvider *provider; ClutterColor black = { 0, 0, 0, 0 }; ClutterMargin overlay_margin = { OVERLAY_MARGIN, OVERLAY_MARGIN, OVERLAY_MARGIN, OVERLAY_MARGIN }; @@ -1615,17 +1611,7 @@ empathy_call_window_init (EmpathyCallWindow *self) "menupreviewswap", "activate", empathy_call_window_swap_camera_cb, NULL); - /* FIXME: we should use a stock "OSD" style class for the toolbar, - * once it's available in GTK+/Adwaita. - */ - provider = gtk_css_provider_new (); - gtk_css_provider_load_from_data (provider, - "#CallFloatingToolbar { border-radius: 6px; }", -1, NULL); - gtk_style_context_add_provider ( - gtk_widget_get_style_context (priv->bottom_toolbar), - GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - g_object_unref (provider); - + empathy_set_css_provider (GTK_WIDGET (self)); gtk_action_set_sensitive (priv->menu_fullscreen, FALSE); priv->camera_monitor = empathy_camera_monitor_dup_singleton (); @@ -1639,7 +1625,7 @@ empathy_call_window_init (EmpathyCallWindow *self) g_signal_connect (priv->camera_monitor, "removed", G_CALLBACK (empathy_call_window_camera_removed_cb), self); - priv->lock = g_mutex_new (); + g_mutex_init (&priv->lock); gtk_container_add (GTK_CONTAINER (self), top_vbox); @@ -1657,7 +1643,7 @@ empathy_call_window_init (EmpathyCallWindow *self) priv->video_container = gtk_clutter_embed_new (); gtk_widget_set_size_request (priv->video_container, - EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH, EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT); + REMOTE_VIDEO_DEFAULT_WIDTH, REMOTE_VIDEO_DEFAULT_HEIGHT); /* Set the background black */ clutter_stage_set_color ( @@ -1711,6 +1697,9 @@ empathy_call_window_init (EmpathyCallWindow *self) clutter_actor_set_reactive (priv->floating_toolbar, TRUE); make_background_transparent (GTK_CLUTTER_ACTOR (priv->floating_toolbar)); + gtk_style_context_add_class ( + gtk_widget_get_style_context (GTK_WIDGET (priv->bottom_toolbar)), + GTK_STYLE_CLASS_OSD); gtk_widget_reparent (priv->bottom_toolbar, gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (priv->floating_toolbar))); @@ -1718,8 +1707,6 @@ empathy_call_window_init (EmpathyCallWindow *self) priv->floating_toolbar, CLUTTER_BIN_ALIGNMENT_CENTER, CLUTTER_BIN_ALIGNMENT_END); - clutter_actor_set_opacity (priv->floating_toolbar, FLOATING_TOOLBAR_OPACITY); - clutter_actor_raise_top (priv->floating_toolbar); /* Transitions for the floating toolbar */ @@ -1737,7 +1724,7 @@ empathy_call_window_init (EmpathyCallWindow *self) /* transition from any state to "fade-in" state */ clutter_state_set (priv->transitions, NULL, "fade-in", priv->floating_toolbar, - "opacity", CLUTTER_EASE_OUT_QUAD, FLOATING_TOOLBAR_OPACITY, + "opacity", CLUTTER_EASE_OUT_QUAD, 255, NULL); /* put the actor into the "fade-in" state with no animation */ @@ -2208,8 +2195,8 @@ empathy_call_window_constructed (GObject *object) if (!empathy_call_handler_has_initial_video (priv->handler)) { - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), FALSE); + gtk_toggle_button_set_active ( + GTK_TOGGLE_BUTTON (priv->camera_button), FALSE); } /* If call has InitialVideo, the preview will be started once the call has * been started (start_call()). */ @@ -2373,7 +2360,7 @@ empathy_call_window_finalize (GObject *object) disconnect_video_output_motion_handler (self); /* free any data held directly by the object here */ - g_mutex_free (priv->lock); + g_mutex_clear (&priv->lock); g_timer_destroy (priv->timer); @@ -2546,7 +2533,7 @@ empathy_call_window_disconnected (EmpathyCallWindow *self, if (could_reset_pipeline) { - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); g_timer_stop (priv->timer); @@ -2554,7 +2541,7 @@ empathy_call_window_disconnected (EmpathyCallWindow *self, g_source_remove (priv->timer_id); priv->timer_id = 0; - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); if (!restart) /* We are about to destroy the window, no need to update it or create @@ -2570,8 +2557,8 @@ empathy_call_window_disconnected (EmpathyCallWindow *self, gtk_widget_set_sensitive (priv->mic_button, FALSE); /* Be sure that the mic button is enabled */ - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button), TRUE); + gtk_toggle_button_set_active ( + GTK_TOGGLE_BUTTON (priv->mic_button), TRUE); if (priv->camera_state == CAMERA_STATE_ON) { @@ -2860,8 +2847,8 @@ empathy_call_window_update_timer (gpointer user_data) if (priv->call_state == HELD) status = _("On hold"); - else if (!gtk_toggle_tool_button_get_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button))) + else if (!gtk_toggle_button_get_active ( + GTK_TOGGLE_BUTTON (priv->mic_button))) status = _("Mute"); else status = _("Duration"); @@ -3204,12 +3191,12 @@ empathy_call_window_state_changed_cb (EmpathyCallHandler *handler, g_object_unref (call); - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); priv->timer_id = g_timeout_add_seconds (1, empathy_call_window_update_timer, self); - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); empathy_call_window_update_timer (self); @@ -3283,7 +3270,7 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler, GstPad *pad; - g_mutex_lock (priv->lock); + g_mutex_lock (&priv->lock); g_object_get (content, "media-type", &media_type, NULL); @@ -3350,7 +3337,7 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler, } - g_mutex_unlock (priv->lock); + g_mutex_unlock (&priv->lock); return TRUE; } @@ -3550,13 +3537,13 @@ start_call (EmpathyCallWindow *self) s == TP_SENDING_STATE_SENDING) { /* Enable 'send video' buttons and display the preview */ - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), TRUE); + gtk_toggle_button_set_active ( + GTK_TOGGLE_BUTTON (priv->camera_button), TRUE); } else { - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->camera_button), FALSE); + gtk_toggle_button_set_active ( + GTK_TOGGLE_BUTTON (priv->camera_button), FALSE); if (priv->video_preview == NULL) { diff --git a/src/empathy-call-window.ui b/src/empathy-call-window.ui index 2caa242b8..7149a3e8b 100644 --- a/src/empathy-call-window.ui +++ b/src/empathy-call-window.ui @@ -254,37 +254,56 @@ <object class="GtkToolbar" id="bottom_toolbar"> <property name="visible">True</property> <property name="show_arrow">False</property> - <property name="name">CallFloatingToolbar</property> <child> - <object class="GtkToggleToolButton" id="camera"> - <property name="visible">True</property> - <property name="label" translatable="yes">Send Video</property> - <property name="icon_name">camera-web</property> - <property name="sensitive">False</property> - <property name="tooltip_text" translatable="yes">Toggle video transmission</property> - </object> - </child> - <child> - <object class="GtkToolItem" id="toolitem3"> + <object class="GtkToolItem" id="toolitem_group"> <property name="visible">True</property> <child> - <object class="GtkVolumeButton" id="volume"> + <object class="GtkBox" id="button_group"> + <property name="orientation">horizontal</property> + <property name="spacing">0</property> <property name="visible">True</property> - <property name="value">1.0</property> + <child> + <object class="GtkToggleButton" id="camera"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="tooltip_text" translatable="yes">Toggle video transmission</property> + <child> + <object class="GtkImage" id="camera_icon"> + <property name="visible">True</property> + <property name="icon_name">camera-web-symbolic</property> + <property name="icon_size">1</property> + </object> + </child> + </object> + </child> + <child> + <object class="GtkVolumeButton" id="volume"> + <property name="visible">True</property> + <property name="value">1.0</property> + <property name="relief">normal</property> + <property name="use_symbolic">True</property> + <property name="size">1</property> + </object> + </child> + <child> + <object class="GtkToggleButton" id="microphone"> + <property name="visible">True</property> + <property name="active">True</property> + <property name="tooltip_text" translatable="yes">Toggle audio transmission</property> + <child> + <object class="GtkImage" id="microphone_icon"> + <property name="visible">True</property> + <property name="icon_name">audio-input-microphone-symbolic</property> + <property name="icon_size">1</property> + </object> + </child> + </object> + </child> </object> </child> </object> </child> <child> - <object class="GtkToggleToolButton" id="microphone"> - <property name="visible">True</property> - <property name="active">True</property> - <property name="label" translatable="yes">Send Audio</property> - <property name="icon_name">gnome-stock-mic</property> - <property name="tooltip_text" translatable="yes">Toggle audio transmission</property> - </object> - </child> - <child> <object class="GtkSeparatorToolItem" id="toolbutton2"> <property name="draw">False</property> <property name="visible">True</property> diff --git a/src/empathy-call.c b/src/empathy-call.c index 2188d3726..9d7a2b355 100644 --- a/src/empathy-call.c +++ b/src/empathy-call.c @@ -186,9 +186,6 @@ main (int argc, gint retval; GtkSettings *gtk_settings; - /* 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 */ @@ -203,6 +200,7 @@ main (int argc, clutter_get_option_group_without_init ()); g_option_context_add_group (optcontext, gtk_clutter_get_option_group ()); g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE); + g_option_context_set_translation_domain (optcontext, GETTEXT_PACKAGE); if (!g_option_context_parse (optcontext, &argc, &argv, &error)) { g_print ("%s\nRun '%s --help' to see a full list of available command " @@ -217,12 +215,12 @@ main (int argc, clutter_gst_init (&argc, &argv); empathy_gtk_init (); + textdomain (GETTEXT_PACKAGE); g_set_application_name (_("Empathy Audio/Video Client")); /* Make empathy and empathy-call appear as the same app in gnome-shell */ gdk_set_program_class ("Empathy"); gtk_window_set_default_icon_name ("empathy"); - textdomain (GETTEXT_PACKAGE); gtk_settings = gtk_settings_get_default (); g_object_set (G_OBJECT (gtk_settings), "gtk-application-prefer-dark-theme", diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c index dd828fa68..6a163aaae 100644 --- a/src/empathy-chat-manager.c +++ b/src/empathy-chat-manager.c @@ -136,6 +136,22 @@ chat_destroyed_cb (gpointer data, } static void +join_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + TpChannel *channel = TP_CHANNEL (source); + GError *error = NULL; + + if (!tp_channel_join_finish (channel, result, &error)) + { + DEBUG ("Failed to join chat (%s): %s", + tp_channel_get_identifier (channel), error->message); + g_error_free (error); + } +} + +static void process_tp_chat (EmpathyChatManager *self, EmpathyTpChat *tp_chat, TpAccount *account, @@ -193,7 +209,7 @@ process_tp_chat (EmpathyChatManager *self, { /* We have been invited to the room. Add ourself as member as this * channel has been approved. */ - empathy_tp_chat_join (tp_chat); + tp_channel_join_async (TP_CHANNEL (tp_chat), "", join_cb, self); } } diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index ac3584f34..ad48fcbac 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -44,8 +44,6 @@ #include <libempathy/empathy-chatroom-manager.h> #include <libempathy/empathy-gsettings.h> #include <libempathy/empathy-utils.h> -#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> @@ -62,7 +60,6 @@ #include "empathy-chat-window.h" #include "empathy-about-dialog.h" #include "empathy-invite-participant-dialog.h" -#include "gedit-close-button.h" #define DEBUG_FLAG EMPATHY_DEBUG_CHAT #include <libempathy/empathy-debug.h> @@ -415,6 +412,35 @@ chat_tab_style_updated_cb (GtkWidget *hbox, } static GtkWidget * +create_close_button (void) +{ + GtkWidget *button, *image; + GtkStyleContext *context; + + button = gtk_button_new (); + + context = gtk_widget_get_style_context (button); + gtk_style_context_add_class (context, "empathy-tab-close-button"); + + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE); + + /* We don't want focus/keynav for the button to avoid clutter, and + * Ctrl-W works anyway. + */ + gtk_widget_set_can_focus (button, FALSE); + gtk_widget_set_can_default (button, FALSE); + + image = gtk_image_new_from_icon_name ("window-close-symbolic", + GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + + gtk_container_add (GTK_CONTAINER (button), image); + + return button; +} + +static GtkWidget * chat_window_create_label (EmpathyChatWindow *window, EmpathyChat *chat, gboolean is_tab_label) @@ -481,15 +507,9 @@ chat_window_create_label (EmpathyChatWindow *window, "chat-window-tab-sending-spinner", sending_spinner); - close_button = gedit_close_button_new (); + close_button = create_close_button (); g_object_set_data (G_OBJECT (chat), "chat-window-tab-close-button", close_button); - /* We don't want focus/keynav for the button to avoid clutter, and - * Ctrl-W works anyway. - */ - gtk_widget_set_can_focus (close_button, FALSE); - gtk_widget_set_can_default (close_button, FALSE); - gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0); g_signal_connect (close_button, @@ -1188,8 +1208,7 @@ chat_window_invite_participant_activate_cb (GtkAction *action, contact = empathy_contact_dup_from_tp_contact (tp_contact); - empathy_contact_list_add (EMPATHY_CONTACT_LIST (tp_chat), - contact, _("Inviting you to this room")); + empathy_tp_chat_add (tp_chat, contact, _("Inviting you to this room")); g_object_unref (contact); } @@ -2045,7 +2064,7 @@ drag_data_received_individual_id (EmpathyChatWindow *self, 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); + empathy_tp_chat_add (chat, contact, NULL); g_object_unref (contact); out: @@ -2310,6 +2329,8 @@ empathy_chat_window_init (EmpathyChatWindow *window) g_object_ref (priv->ui_manager); g_object_unref (gui); + empathy_set_css_provider (GTK_WIDGET (priv->dialog)); + priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA); priv->gsettings_notif = g_settings_new (EMPATHY_PREFS_NOTIFICATIONS_SCHEMA); priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA); diff --git a/src/empathy-chat.c b/src/empathy-chat.c index bebca4382..3094b5137 100644 --- a/src/empathy-chat.c +++ b/src/empathy-chat.c @@ -103,12 +103,10 @@ main (int argc, gint retval; EmpathyIndividualManager *individual_mgr; - /* Init */ - g_thread_init (NULL); - optcontext = g_option_context_new (N_("- Empathy Chat Client")); g_option_context_add_group (optcontext, gtk_get_option_group (TRUE)); g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE); + g_option_context_set_translation_domain (optcontext, GETTEXT_PACKAGE); if (!g_option_context_parse (optcontext, &argc, &argv, &error)) { diff --git a/src/empathy-debug-window.c b/src/empathy-debug-window.c index 8110a14f3..b2e229da2 100644 --- a/src/empathy-debug-window.c +++ b/src/empathy-debug-window.c @@ -58,12 +58,7 @@ typedef enum enum { - COL_DEBUG_TIMESTAMP = 0, - COL_DEBUG_DOMAIN, - COL_DEBUG_CATEGORY, - COL_DEBUG_LEVEL_STRING, - COL_DEBUG_MESSAGE, - COL_DEBUG_LEVEL_VALUE, + COL_DEBUG_MESSAGE = 0, NUM_DEBUG_COLS }; @@ -86,7 +81,7 @@ enum }; #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyDebugWindow) -typedef struct +struct _EmpathyDebugWindowPriv { /* Toolbar items */ GtkWidget *chooser; @@ -126,29 +121,29 @@ typedef struct gboolean dispose_run; TpAccountManager *am; GtkListStore *all_active_buffer; -} EmpathyDebugWindowPriv; +}; static const gchar * -log_level_to_string (guint level) +log_level_to_string (GLogLevelFlags level) { switch (level) { - case TP_DEBUG_LEVEL_ERROR: + case G_LOG_LEVEL_ERROR: return "Error"; break; - case TP_DEBUG_LEVEL_CRITICAL: + case G_LOG_LEVEL_CRITICAL: return "Critical"; break; - case TP_DEBUG_LEVEL_WARNING: + case G_LOG_LEVEL_WARNING: return "Warning"; break; - case TP_DEBUG_LEVEL_MESSAGE: + case G_LOG_LEVEL_MESSAGE: return "Message"; break; - case TP_DEBUG_LEVEL_INFO: + case G_LOG_LEVEL_INFO: return "Info"; break; - case TP_DEBUG_LEVEL_DEBUG: + case G_LOG_LEVEL_DEBUG: return "Debug"; break; default: @@ -160,14 +155,14 @@ log_level_to_string (guint level) static gchar * get_active_service_name (EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (self); GtkTreeIter iter; gchar *name; - if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->chooser), &iter)) + if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->priv->chooser), + &iter)) return NULL; - gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), &iter, + gtk_tree_model_get (GTK_TREE_MODEL (self->priv->service_store), &iter, COL_NAME, &name, -1); return name; @@ -181,184 +176,133 @@ copy_buffered_messages (GtkTreeModel *buffer, { GtkListStore *active_buffer = data; GtkTreeIter active_buffer_iter; - gdouble timestamp; - gchar *domain, *category, *message, *level_string; - guint level; + TpDebugMessage *msg; 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, + COL_DEBUG_MESSAGE, &msg, -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, + COL_DEBUG_MESSAGE, msg, -1); - g_free (domain); - g_free (category); - g_free (level_string); - g_free (message); + g_object_unref (msg); return FALSE; } static void insert_values_in_buffer (GtkListStore *store, - gdouble timestamp, - const gchar *domain, - const gchar *category, - guint level, - const gchar *string) + TpDebugMessage *msg) { GtkTreeIter iter; 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, + COL_DEBUG_MESSAGE, msg, -1); } static void -debug_window_add_message (EmpathyDebugWindow *debug_window, - TpProxy *proxy, - gdouble timestamp, - const gchar *domain_category, - guint level, - const gchar *message) -{ - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - gchar *domain, *category; - gchar *string; +debug_window_add_message (EmpathyDebugWindow *self, + TpDebugClient *debug, + TpDebugMessage *msg) +{ GtkListStore *active_buffer, *pause_buffer; - if (g_strrstr (domain_category, "/")) - { - gchar **parts = g_strsplit (domain_category, "/", 2); - domain = g_strdup (parts[0]); - category = g_strdup (parts[1]); - g_strfreev (parts); - } - else - { - domain = g_strdup (domain_category); - category = g_strdup (""); - } - - if (g_str_has_suffix (message, "\n")) - string = g_strchomp (g_strdup (message)); - 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"); + pause_buffer = g_object_get_data (G_OBJECT (debug), "pause-buffer"); + active_buffer = g_object_get_data (G_OBJECT (debug), "active-buffer"); - if (priv->paused) + if (self->priv->paused) { - insert_values_in_buffer (pause_buffer, timestamp, - domain, category, level, - string); + insert_values_in_buffer (pause_buffer, msg); } 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 (active_buffer, msg); - insert_values_in_buffer (priv->all_active_buffer, timestamp, - domain, category, level, - string); + insert_values_in_buffer (self->priv->all_active_buffer, msg); } - - g_free (string); - g_free (domain); - g_free (category); } static void -debug_window_new_debug_message_cb (TpProxy *proxy, - gdouble timestamp, - const gchar *domain, - guint level, - const gchar *message, - gpointer user_data, - GObject *weak_object) +debug_window_new_debug_message_cb (TpDebugClient *debug, + TpDebugMessage *msg, + gpointer user_data) { - EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; + EmpathyDebugWindow *self = user_data; - debug_window_add_message (debug_window, proxy, timestamp, domain, level, - message); + debug_window_add_message (self, debug, msg); } static void -debug_window_set_enabled (TpProxy *proxy, - gboolean enabled) +set_enabled_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) { - GValue *val; - - g_return_if_fail (proxy != NULL); + TpDebugClient *debug = TP_DEBUG_CLIENT (source); + gboolean enabled = GPOINTER_TO_UINT (user_data); + GError *error = NULL; - val = tp_g_value_slice_new_boolean (enabled); + if (!tp_debug_client_set_enabled_finish (debug, result, &error)) + { + DEBUG ("Failed to %s debugging on %s", enabled ? "enable" : "disable", + tp_proxy_get_bus_name (debug)); + g_error_free (error); + } +} - tp_cli_dbus_properties_call_set (proxy, -1, TP_IFACE_DEBUG, - "Enabled", val, NULL, NULL, NULL, NULL); +static void +debug_window_set_enabled (TpDebugClient *debug, + gboolean enabled) +{ + g_return_if_fail (debug != NULL); - tp_g_value_slice_free (val); + tp_debug_client_set_enabled_async (debug, enabled, + set_enabled_cb, GUINT_TO_POINTER (enabled)); } static void -debug_window_set_toolbar_sensitivity (EmpathyDebugWindow *debug_window, +debug_window_set_toolbar_sensitivity (EmpathyDebugWindow *self, gboolean sensitive) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - GtkWidget *vbox = gtk_bin_get_child (GTK_BIN (debug_window)); + GtkWidget *vbox = gtk_bin_get_child (GTK_BIN (self)); - 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); - gtk_widget_set_sensitive (GTK_WIDGET (priv->level_label), sensitive); - gtk_widget_set_sensitive (GTK_WIDGET (priv->level_filter), sensitive); - gtk_widget_set_sensitive (GTK_WIDGET (priv->view), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->save_button), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->send_to_pastebin), + sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->copy_button), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->clear_button), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->pause_button), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->level_label), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->level_filter), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (self->priv->view), sensitive); - if (sensitive && !priv->view_visible) + if (sensitive && !self->priv->view_visible) { /* Add view and remove label */ - gtk_container_remove (GTK_CONTAINER (vbox), priv->not_supported_label); - gtk_box_pack_start (GTK_BOX (vbox), priv->scrolled_win, TRUE, TRUE, 0); - priv->view_visible = TRUE; + gtk_container_remove (GTK_CONTAINER (vbox), + self->priv->not_supported_label); + gtk_box_pack_start (GTK_BOX (vbox), + self->priv->scrolled_win, TRUE, TRUE, 0); + self->priv->view_visible = TRUE; } - else if (!sensitive && priv->view_visible) + else if (!sensitive && self->priv->view_visible) { /* Add label and remove view */ - gtk_container_remove (GTK_CONTAINER (vbox), priv->scrolled_win); - gtk_box_pack_start (GTK_BOX (vbox), priv->not_supported_label, + gtk_container_remove (GTK_CONTAINER (vbox), self->priv->scrolled_win); + gtk_box_pack_start (GTK_BOX (vbox), self->priv->not_supported_label, TRUE, TRUE, 0); - priv->view_visible = FALSE; + self->priv->view_visible = FALSE; } } static gboolean debug_window_get_iter_for_active_buffer (GtkListStore *active_buffer, GtkTreeIter *iter, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); gboolean valid_iter; - GtkTreeModel *model = GTK_TREE_MODEL (priv->service_store); + GtkTreeModel *model = GTK_TREE_MODEL (self->priv->service_store); gtk_tree_model_get_iter_first (model, iter); for (valid_iter = gtk_tree_model_iter_next (model, iter); @@ -381,7 +325,7 @@ debug_window_get_iter_for_active_buffer (GtkListStore *active_buffer, return valid_iter; } -static void refresh_all_buffer (EmpathyDebugWindow *debug_window); +static void refresh_all_buffer (EmpathyDebugWindow *self); static void proxy_invalidated_cb (TpProxy *proxy, @@ -391,8 +335,7 @@ proxy_invalidated_cb (TpProxy *proxy, gpointer user_data) { EmpathyDebugWindow *self = (EmpathyDebugWindow *) user_data; - EmpathyDebugWindowPriv *priv = GET_PRIV (self); - GtkTreeModel *service_store = GTK_TREE_MODEL (priv->service_store); + GtkTreeModel *service_store = GTK_TREE_MODEL (self->priv->service_store); TpProxy *stored_proxy; GtkTreeIter iter; gboolean valid_iter; @@ -409,7 +352,7 @@ proxy_invalidated_cb (TpProxy *proxy, -1); if (proxy == stored_proxy) - gtk_list_store_set (priv->service_store, &iter, + gtk_list_store_set (self->priv->service_store, &iter, COL_PROXY, NULL, -1); } @@ -420,57 +363,55 @@ proxy_invalidated_cb (TpProxy *proxy, } static void -debug_window_get_messages_cb (TpProxy *proxy, - const GPtrArray *messages, - const GError *error, - gpointer user_data, - GObject *weak_object) +debug_window_get_messages_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) { - EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + TpDebugClient *debug = TP_DEBUG_CLIENT (object); + EmpathyDebugWindow *self = user_data; gchar *active_service_name; guint i; GtkListStore *active_buffer; gboolean valid_iter; GtkTreeIter iter; gchar *proxy_service_name; + GPtrArray *messages; + GError *error = NULL; - active_buffer = g_object_get_data (G_OBJECT (proxy), "active-buffer"); + active_buffer = g_object_get_data (object, "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, + self); + gtk_tree_model_get (GTK_TREE_MODEL (self->priv->service_store), &iter, COL_NAME, &proxy_service_name, -1); - active_service_name = get_active_service_name (debug_window); - if (error != NULL) + active_service_name = get_active_service_name (self); + + messages = tp_debug_client_get_messages_finish (debug, result, &error); + if (messages == NULL) { - DEBUG ("GetMessages failed: %s", error->message); + DEBUG ("Failed to get debug messsages: %s", error->message); + g_error_free (error); /* 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); + debug_window_set_toolbar_sensitivity (self, FALSE); /* We created the proxy for GetMessages call. Now destroy it. */ - tp_clear_object (&proxy); + tp_clear_object (&debug); return; } DEBUG ("Retrieved debug messages for %s", active_service_name); g_free (active_service_name); - debug_window_set_toolbar_sensitivity (debug_window, TRUE); - + debug_window_set_toolbar_sensitivity (self, TRUE); for (i = 0; i < messages->len; i++) { - GValueArray *values = g_ptr_array_index (messages, i); + TpDebugMessage *msg = g_ptr_array_index (messages, i); - 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))); + debug_window_add_message (self, debug, msg); } /* Now we save this precious proxy in the service_store along its service */ @@ -479,42 +420,42 @@ debug_window_get_messages_cb (TpProxy *proxy, 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, + gtk_list_store_set (self->priv->service_store, &iter, + COL_PROXY, debug, -1); } g_free (proxy_service_name); /* Connect to "invalidated" signal */ - g_signal_connect (proxy, "invalidated", - G_CALLBACK (proxy_invalidated_cb), debug_window); + g_signal_connect (debug, "invalidated", + G_CALLBACK (proxy_invalidated_cb), self); /* Connect to NewDebugMessage */ - emp_cli_debug_connect_to_new_debug_message ( - proxy, debug_window_new_debug_message_cb, debug_window, - NULL, NULL, NULL); + tp_g_signal_connect_object (debug, "new-debug-message", + G_CALLBACK (debug_window_new_debug_message_cb), self, 0); /* 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)); + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER ( + self->priv->store_filter)); /* Set the proxy to signal for new debug messages */ - debug_window_set_enabled (proxy, TRUE); + debug_window_set_enabled (debug, TRUE); } static void -create_proxy_to_get_messages (EmpathyDebugWindow *debug_window, +create_proxy_to_get_messages (EmpathyDebugWindow *self, GtkTreeIter *iter, TpDBusDaemon *dbus) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); gchar *bus_name, *name = NULL; - TpProxy *new_proxy, *stored_proxy = NULL; + TpDebugClient *new_proxy, *stored_proxy = NULL; GtkTreeModel *pause_buffer, *active_buffer; gboolean gone; + GError *error = NULL; - gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), iter, + gtk_tree_model_get (GTK_TREE_MODEL (self->priv->service_store), iter, COL_NAME, &name, COL_GONE, &gone, COL_ACTIVE_BUFFER, &active_buffer, @@ -535,13 +476,19 @@ create_proxy_to_get_messages (EmpathyDebugWindow *debug_window, DEBUG ("Preparing proxy to obtain messages for service %s", name); - gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), iter, + gtk_tree_model_get (GTK_TREE_MODEL (self->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); + + new_proxy = tp_debug_client_new (dbus, bus_name, &error); + + if (new_proxy == NULL) + { + DEBUG ("Failed to create TpDebugClient on bus %s: %s", bus_name, + error->message); + g_free (bus_name); + goto finally; + } + g_free (bus_name); g_object_set_data (G_OBJECT (new_proxy), "active-buffer", active_buffer); @@ -552,10 +499,9 @@ create_proxy_to_get_messages (EmpathyDebugWindow *debug_window, * * 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); + tp_debug_client_get_messages_async (TP_DEBUG_CLIENT (new_proxy), + debug_window_get_messages_cb, self); finally: g_free (name); @@ -568,12 +514,7 @@ 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 */ + TP_TYPE_DEBUG_MESSAGE); /* COL_DEBUG_MESSAGE */ } static gboolean @@ -581,24 +522,26 @@ 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; + EmpathyDebugWindow *self = user_data; + GLogLevelFlags filter_value; GtkTreeModel *filter_model; GtkTreeIter filter_iter; + TpDebugMessage *msg; + gboolean result; - 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_model = gtk_combo_box_get_model ( + GTK_COMBO_BOX (self->priv->level_filter)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->priv->level_filter), &filter_iter); - gtk_tree_model_get (model, iter, COL_DEBUG_LEVEL_VALUE, &level, -1); + gtk_tree_model_get (model, iter, COL_DEBUG_MESSAGE, &msg, -1); gtk_tree_model_get (filter_model, &filter_iter, COL_LEVEL_VALUE, &filter_value, -1); - if (level <= filter_value) - return TRUE; + result = (tp_debug_message_get_level (msg) <= filter_value); + g_object_unref (msg); - return FALSE; + return result; } static gboolean @@ -633,42 +576,40 @@ tree_view_search_equal_func_cb (GtkTreeModel *model, } static void -update_store_filter (EmpathyDebugWindow *debug_window, +update_store_filter (EmpathyDebugWindow *self, GtkListStore *active_buffer) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - debug_window_set_toolbar_sensitivity (debug_window, FALSE); + debug_window_set_toolbar_sensitivity (self, FALSE); - tp_clear_object (&priv->store_filter); - priv->store_filter = gtk_tree_model_filter_new ( + tp_clear_object (&self->priv->store_filter); + self->priv->store_filter = gtk_tree_model_filter_new ( GTK_TREE_MODEL (active_buffer), 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); + GTK_TREE_MODEL_FILTER (self->priv->store_filter), + debug_window_visible_func, self, NULL); + gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->view), + self->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), + gtk_tree_view_set_search_column (GTK_TREE_VIEW (self->priv->view), COL_DEBUG_MESSAGE); - gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (priv->view), + gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (self->priv->view), tree_view_search_equal_func_cb, NULL, NULL); - debug_window_set_toolbar_sensitivity (debug_window, TRUE); + debug_window_set_toolbar_sensitivity (self, TRUE); } static void -refresh_all_buffer (EmpathyDebugWindow *debug_window) +refresh_all_buffer (EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); gboolean valid_iter; GtkTreeIter iter; - GtkTreeModel *service_store = GTK_TREE_MODEL (priv->service_store); + GtkTreeModel *service_store = GTK_TREE_MODEL (self->priv->service_store); /* Clear All's active-buffer */ - gtk_list_store_clear (priv->all_active_buffer); + gtk_list_store_clear (self->priv->all_active_buffer); /* Skipping the first service store iter which is reserved for "All" */ gtk_tree_model_get_iter_first (service_store, &iter); @@ -689,7 +630,7 @@ refresh_all_buffer (EmpathyDebugWindow *debug_window) if (gone) { gtk_tree_model_foreach (GTK_TREE_MODEL (service_active_buffer), - copy_buffered_messages, priv->all_active_buffer); + copy_buffered_messages, self->priv->all_active_buffer); } else { @@ -700,7 +641,7 @@ refresh_all_buffer (EmpathyDebugWindow *debug_window) /* 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); + copy_buffered_messages, self->priv->all_active_buffer); } else { @@ -713,7 +654,7 @@ refresh_all_buffer (EmpathyDebugWindow *debug_window) g_error_free (error); } - create_proxy_to_get_messages (debug_window, &iter, dbus); + create_proxy_to_get_messages (self, &iter, dbus); g_object_unref (dbus); } @@ -726,9 +667,8 @@ refresh_all_buffer (EmpathyDebugWindow *debug_window) static void debug_window_service_chooser_changed_cb (GtkComboBox *chooser, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); TpDBusDaemon *dbus; GError *error = NULL; GtkListStore *stored_active_buffer = NULL; @@ -740,16 +680,16 @@ debug_window_service_chooser_changed_cb (GtkComboBox *chooser, { DEBUG ("No CM is selected"); if (gtk_tree_model_iter_n_children ( - GTK_TREE_MODEL (priv->service_store), NULL) > 0) + GTK_TREE_MODEL (self->priv->service_store), NULL) > 0) { gtk_combo_box_set_active (chooser, 0); } return; } - debug_window_set_toolbar_sensitivity (debug_window, TRUE); + debug_window_set_toolbar_sensitivity (self, TRUE); - gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), &iter, + gtk_tree_model_get (GTK_TREE_MODEL (self->priv->service_store), &iter, COL_NAME, &name, COL_GONE, &gone, COL_ACTIVE_BUFFER, &stored_active_buffer, @@ -765,11 +705,11 @@ debug_window_service_chooser_changed_cb (GtkComboBox *chooser, if (!tp_strdiff (name, "All")) { - update_store_filter (debug_window, priv->all_active_buffer); + update_store_filter (self, self->priv->all_active_buffer); goto finally; } - update_store_filter (debug_window, stored_active_buffer); + update_store_filter (self, stored_active_buffer); dbus = tp_dbus_daemon_dup (&error); @@ -778,7 +718,7 @@ debug_window_service_chooser_changed_cb (GtkComboBox *chooser, DEBUG ("Failed at duping the dbus daemon: %s", error->message); } - create_proxy_to_get_messages (debug_window, &iter, dbus); + create_proxy_to_get_messages (self, &iter, dbus); g_object_unref (dbus); @@ -823,12 +763,11 @@ debug_window_service_foreach (GtkTreeModel *model, } static gboolean -debug_window_service_is_in_model (EmpathyDebugWindow *debug_window, +debug_window_service_is_in_model (EmpathyDebugWindow *self, const gchar *name, GtkTreeIter **iter, gboolean use_name) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); CmInModelForeachData *data; gboolean found; @@ -838,7 +777,7 @@ debug_window_service_is_in_model (EmpathyDebugWindow *debug_window, data->found_iter = iter; data->use_name = use_name; - gtk_tree_model_foreach (GTK_TREE_MODEL (priv->service_store), + gtk_tree_model_foreach (GTK_TREE_MODEL (self->priv->service_store), debug_window_service_foreach, data); found = data->found; @@ -852,12 +791,11 @@ static gchar * get_cm_display_name (EmpathyDebugWindow *self, const char *cm_name) { - EmpathyDebugWindowPriv *priv = GET_PRIV (self); GHashTable *protocols = g_hash_table_new (g_str_hash, g_str_equal); GList *accounts, *ptr; char *retval; - accounts = tp_account_manager_get_valid_accounts (priv->am); + accounts = tp_account_manager_get_valid_accounts (self->priv->am); for (ptr = accounts; ptr != NULL; ptr = ptr->next) { @@ -906,7 +844,7 @@ get_cm_display_name (EmpathyDebugWindow *self, typedef struct { - EmpathyDebugWindow *debug_window; + EmpathyDebugWindow *self; gchar *name; ServiceType type; } FillServiceChooserData; @@ -918,7 +856,7 @@ fill_service_chooser_data_new (EmpathyDebugWindow *window, { FillServiceChooserData * data = g_slice_new (FillServiceChooserData); - data->debug_window = window; + data->self = window; data->name = g_strdup (name); data->type = SERVICE_TYPE_CM; return data; @@ -939,11 +877,10 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, GObject *weak_object) { FillServiceChooserData *data = (FillServiceChooserData *) user_data; - EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (data->debug_window); - EmpathyDebugWindowPriv *priv = GET_PRIV (data->debug_window); + EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (data->self); GtkTreeIter iter; - priv->name_owner_cb_count++; + self->priv->name_owner_cb_count++; if (error != NULL) { @@ -951,7 +888,7 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, goto OUT; } - if (!debug_window_service_is_in_model (data->debug_window, out, NULL, FALSE)) + if (!debug_window_service_is_in_model (data->self, out, NULL, FALSE)) { char *name; GtkListStore *active_buffer, *pause_buffer; @@ -968,7 +905,7 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, 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, + gtk_list_store_insert_with_values (self->priv->service_store, &iter, -1, COL_NAME, name, COL_UNIQUE_NAME, out, COL_GONE, FALSE, @@ -980,30 +917,31 @@ debug_window_get_name_owner_cb (TpDBusDaemon *proxy, g_object_unref (active_buffer); g_object_unref (pause_buffer); - if (priv->select_name != NULL && - !tp_strdiff (name, priv->select_name)) + if (self->priv->select_name != NULL && + !tp_strdiff (name, self->priv->select_name)) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->chooser), &iter); - tp_clear_pointer (&priv->select_name, g_free); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->priv->chooser), + &iter); + tp_clear_pointer (&self->priv->select_name, g_free); } g_free (name); } - if (priv->services_detected == priv->name_owner_cb_count) + if (self->priv->services_detected == self->priv->name_owner_cb_count) { /* Time to add "All" selection to service_store */ - gtk_list_store_insert_with_values (priv->service_store, &iter, 0, + gtk_list_store_insert_with_values (self->priv->service_store, &iter, 0, COL_NAME, "All", COL_ACTIVE_BUFFER, NULL, -1); - priv->all_active_buffer = new_list_store_for_service (); + self->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); + gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->chooser), 0); } OUT: @@ -1019,8 +957,7 @@ debug_window_list_connection_names_cb (const gchar * const *names, gpointer user_data, GObject *weak_object) { - EmpathyDebugWindow *debug_window = (EmpathyDebugWindow *) user_data; - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); + EmpathyDebugWindow *self = user_data; guint i; TpDBusDaemon *dbus; GError *error2 = NULL; @@ -1043,13 +980,13 @@ debug_window_list_connection_names_cb (const gchar * const *names, for (i = 0; cms[i] != NULL; i++) { FillServiceChooserData *data = fill_service_chooser_data_new ( - debug_window, cms[i], SERVICE_TYPE_CM); + self, cms[i], SERVICE_TYPE_CM); tp_cli_dbus_daemon_call_get_name_owner (dbus, -1, names[i], debug_window_get_name_owner_cb, data, NULL, NULL); - priv->services_detected ++; + self->priv->services_detected ++; } g_object_unref (dbus); @@ -1064,7 +1001,6 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, GObject *weak_object) { EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (user_data); - EmpathyDebugWindowPriv *priv = GET_PRIV (user_data); ServiceType type; const gchar *name; @@ -1105,7 +1041,8 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, 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, + gtk_list_store_insert_with_values (self->priv->service_store, + &iter, -1, COL_NAME, display_name, COL_UNIQUE_NAME, arg2, COL_GONE, FALSE, @@ -1130,12 +1067,12 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, active_buffer= new_list_store_for_service (); pause_buffer = new_list_store_for_service (); - gtk_tree_model_get (GTK_TREE_MODEL (priv->service_store), + gtk_tree_model_get (GTK_TREE_MODEL (self->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, + gtk_list_store_set (self->priv->service_store, found_at_iter, COL_NAME, display_name, COL_UNIQUE_NAME, arg2, COL_GONE, FALSE, @@ -1150,7 +1087,7 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, gtk_tree_iter_free (found_at_iter); debug_window_service_chooser_changed_cb - (GTK_COMBO_BOX (priv->chooser), user_data); + (GTK_COMBO_BOX (self->priv->chooser), user_data); } /* If a new service arrives when "All" is selected, the view will @@ -1172,7 +1109,7 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy, /* set the service as disabled in the model */ if (debug_window_service_is_in_model (user_data, arg1, &iter, FALSE)) { - gtk_list_store_set (priv->service_store, + gtk_list_store_set (self->priv->service_store, iter, COL_GONE, TRUE, -1); gtk_tree_iter_free (iter); } @@ -1186,7 +1123,6 @@ static void add_client (EmpathyDebugWindow *self, const gchar *name) { - EmpathyDebugWindowPriv *priv = GET_PRIV (self); const gchar *suffix; FillServiceChooserData *data; @@ -1194,10 +1130,10 @@ add_client (EmpathyDebugWindow *self, data = fill_service_chooser_data_new (self, suffix, SERVICE_TYPE_CLIENT); - tp_cli_dbus_daemon_call_get_name_owner (priv->dbus, -1, + tp_cli_dbus_daemon_call_get_name_owner (self->priv->dbus, -1, name, debug_window_get_name_owner_cb, data, NULL, NULL); - priv->services_detected ++; + self->priv->services_detected ++; } static void @@ -1226,14 +1162,13 @@ list_names_cb (TpDBusDaemon *bus_daemon, } static void -debug_window_fill_service_chooser (EmpathyDebugWindow *debug_window) +debug_window_fill_service_chooser (EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GError *error = NULL; GtkTreeIter iter; GtkListStore *active_buffer, *pause_buffer; - priv->dbus = tp_dbus_daemon_dup (&error); + self->priv->dbus = tp_dbus_daemon_dup (&error); if (error != NULL) { @@ -1243,18 +1178,18 @@ debug_window_fill_service_chooser (EmpathyDebugWindow *debug_window) } /* Keep a count of the services detected and added */ - priv->services_detected = 0; - priv->name_owner_cb_count = 0; + self->priv->services_detected = 0; + self->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); + tp_list_connection_names (self->priv->dbus, + debug_window_list_connection_names_cb, self, NULL, NULL); /* add Mission Control */ 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, + gtk_list_store_insert_with_values (self->priv->service_store, &iter, -1, COL_NAME, "mission-control", COL_UNIQUE_NAME, "org.freedesktop.Telepathy.MissionControl5", COL_GONE, FALSE, @@ -1266,29 +1201,28 @@ debug_window_fill_service_chooser (EmpathyDebugWindow *debug_window) g_object_unref (pause_buffer); /* add clients */ - tp_dbus_daemon_list_names (priv->dbus, 2000, - list_names_cb, NULL, NULL, G_OBJECT (debug_window)); + tp_dbus_daemon_list_names (self->priv->dbus, 2000, + list_names_cb, NULL, NULL, G_OBJECT (self)); - priv->name_owner_changed_signal = - tp_cli_dbus_daemon_connect_to_name_owner_changed (priv->dbus, - debug_window_name_owner_changed_cb, debug_window, NULL, NULL, NULL); + self->priv->name_owner_changed_signal = + tp_cli_dbus_daemon_connect_to_name_owner_changed (self->priv->dbus, + debug_window_name_owner_changed_cb, self, NULL, NULL, NULL); } static void debug_window_pause_toggled_cb (GtkToggleToolButton *pause_, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GtkTreeIter iter; gboolean valid_iter; - GtkTreeModel *model = GTK_TREE_MODEL (priv->service_store); + GtkTreeModel *model = GTK_TREE_MODEL (self->priv->service_store); - priv->paused = gtk_toggle_tool_button_get_active (pause_); + self->priv->paused = gtk_toggle_tool_button_get_active (pause_); - if (!priv->paused) + if (!self->priv->paused) { /* Pause has been released - flush all pause buffers */ - GtkTreeModel *service_store = GTK_TREE_MODEL (priv->service_store); + GtkTreeModel *service_store = GTK_TREE_MODEL (self->priv->service_store); /* Skipping the first iter which is reserved for "All" */ gtk_tree_model_get_iter_first (model, &iter); @@ -1306,7 +1240,7 @@ debug_window_pause_toggled_cb (GtkToggleToolButton *pause_, 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); + copy_buffered_messages, self->priv->all_active_buffer); gtk_list_store_clear (pause_buffer); @@ -1318,33 +1252,30 @@ debug_window_pause_toggled_cb (GtkToggleToolButton *pause_, static void debug_window_filter_changed_cb (GtkComboBox *filter, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); - gtk_tree_model_filter_refilter ( - GTK_TREE_MODEL_FILTER (priv->store_filter)); + GTK_TREE_MODEL_FILTER (self->priv->store_filter)); } static void debug_window_clear_clicked_cb (GtkToolButton *clear_button, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GtkTreeIter iter; GtkListStore *active_buffer; /* "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 + * not saved in the service-store but is accessed using a self->private * reference */ - if (gtk_combo_box_get_active (GTK_COMBO_BOX (priv->chooser)) == 0) + if (gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->chooser)) == 0) { - gtk_list_store_clear (priv->all_active_buffer); + gtk_list_store_clear (self->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, + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self->priv->chooser), &iter); + gtk_tree_model_get (GTK_TREE_MODEL (self->priv->service_store), &iter, COL_ACTIVE_BUFFER, &active_buffer, -1); gtk_list_store_clear (active_buffer); @@ -1354,16 +1285,16 @@ debug_window_clear_clicked_cb (GtkToolButton *clear_button, static void debug_window_menu_copy_activate_cb (GtkMenuItem *menu_item, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GtkTreePath *path; GtkTreeViewColumn *focus_column; GtkTreeIter iter; - gchar *message; + TpDebugMessage *msg; + const gchar *message; GtkClipboard *clipboard; - gtk_tree_view_get_cursor (GTK_TREE_VIEW (priv->view), + gtk_tree_view_get_cursor (GTK_TREE_VIEW (self->priv->view), &path, &focus_column); if (path == NULL) @@ -1372,12 +1303,14 @@ debug_window_menu_copy_activate_cb (GtkMenuItem *menu_item, return; } - gtk_tree_model_get_iter (priv->store_filter, &iter, path); + gtk_tree_model_get_iter (self->priv->store_filter, &iter, path); - gtk_tree_model_get (priv->store_filter, &iter, - COL_DEBUG_MESSAGE, &message, + gtk_tree_model_get (self->priv->store_filter, &iter, + COL_DEBUG_MESSAGE, &msg, -1); + message = tp_debug_message_get_message (msg); + if (EMP_STR_EMPTY (message)) { DEBUG ("Log message is empty"); @@ -1390,12 +1323,12 @@ debug_window_menu_copy_activate_cb (GtkMenuItem *menu_item, gtk_clipboard_set_text (clipboard, message, -1); - g_free (message); + g_object_unref (msg); } typedef struct { - EmpathyDebugWindow *debug_window; + EmpathyDebugWindow *self; guint button; guint32 time; } MenuPopupData; @@ -1407,13 +1340,13 @@ debug_window_show_menu (gpointer user_data) GtkWidget *menu, *item; GtkMenuShell *shell; - menu = empathy_context_menu_new (GTK_WIDGET (data->debug_window)); + menu = empathy_context_menu_new (GTK_WIDGET (data->self)); shell = GTK_MENU_SHELL (menu); item = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL); g_signal_connect (item, "activate", - G_CALLBACK (debug_window_menu_copy_activate_cb), data->debug_window); + G_CALLBACK (debug_window_menu_copy_activate_cb), data->self); gtk_menu_shell_append (shell, item); gtk_widget_show (item); @@ -1438,7 +1371,7 @@ debug_window_button_press_event_cb (GtkTreeView *view, /* The tree view was right-clicked. (3 == third mouse button) */ MenuPopupData *data; data = g_slice_new0 (MenuPopupData); - data->debug_window = user_data; + data->self = user_data; data->button = event->button; data->time = event->time; g_idle_add (debug_window_show_menu, data); @@ -1448,25 +1381,20 @@ debug_window_button_press_event_cb (GtkTreeView *view, } static gchar * -debug_window_format_timestamp (gdouble timestamp) +debug_window_format_timestamp (TpDebugMessage *msg) { - struct tm *tstruct; - char time_str[32]; + GDateTime *t; + gchar *time_str, *text; gint ms; - time_t sec; - gchar *text; - ms = (int) ((timestamp - (int) timestamp)*1e6); - sec = (long) timestamp; - tstruct = localtime ((time_t *) &sec); - if (!strftime (time_str, sizeof (time_str), "%x %T", tstruct)) - { - DEBUG ("Failed to format timestamp: %e", timestamp); - time_str[0] = '\0'; - } + t = tp_debug_message_get_time (msg); + + time_str = g_date_time_format (t, "%x %T"); + ms = g_date_time_get_microsecond (t); text = g_strdup_printf ("%s.%d", time_str, ms); + g_free (time_str); return text; } @@ -1477,62 +1405,131 @@ debug_window_time_formatter (GtkTreeViewColumn *tree_column, GtkTreeIter *iter, gpointer data) { - gdouble timestamp; + TpDebugMessage *msg; gchar *time_str; - gtk_tree_model_get (tree_model, iter, COL_DEBUG_TIMESTAMP, ×tamp, -1); + gtk_tree_model_get (tree_model, iter, COL_DEBUG_MESSAGE, &msg, -1); - time_str = debug_window_format_timestamp (timestamp); + time_str = debug_window_format_timestamp (msg); g_object_set (G_OBJECT (cell), "text", time_str, NULL); - g_free (time_str); + g_object_unref (msg); +} + +static void +debug_window_domain_formatter (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + TpDebugMessage *msg; + + gtk_tree_model_get (tree_model, iter, COL_DEBUG_MESSAGE, &msg, -1); + + g_object_set (G_OBJECT (cell), "text", tp_debug_message_get_domain (msg), + NULL); + + g_object_unref (msg); +} + +static void +debug_window_category_formatter (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + TpDebugMessage *msg; + const gchar *category; + + gtk_tree_model_get (tree_model, iter, COL_DEBUG_MESSAGE, &msg, -1); + + category = tp_debug_message_get_category (msg); + + g_object_set (G_OBJECT (cell), "text", category ? category : "", NULL); + + g_object_unref (msg); +} + +static void +debug_window_message_formatter (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + TpDebugMessage *msg; + + gtk_tree_model_get (tree_model, iter, COL_DEBUG_MESSAGE, &msg, -1); + + g_object_set (G_OBJECT (cell), "text", + tp_debug_message_get_message (msg), NULL); + + g_object_unref (msg); +} + +static void +debug_window_level_formatter (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + TpDebugMessage *msg; + const gchar *level; + + gtk_tree_model_get (tree_model, iter, COL_DEBUG_MESSAGE, &msg, -1); + + level = log_level_to_string (tp_debug_message_get_level (msg)); + + g_object_set (G_OBJECT (cell), "text", level, NULL); + + g_object_unref (msg); } static gboolean -debug_window_store_filter_foreach (GtkTreeModel *model, +debug_window_copy_model_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { - gchar **debug_data = (gchar **)user_data; - gchar *domain, *category, *message, *level_str, *level_upper; - gdouble timestamp; - gchar *line, *time_str, *tmp; + gchar **text = (gchar **) user_data; + gchar *tmp; + gchar *level_upper; + const gchar *level_str, *category; + gchar *line, *time_str; + TpDebugMessage *msg; + + if (*text == NULL) + *text = g_strdup (""); gtk_tree_model_get (model, iter, - COL_DEBUG_TIMESTAMP, ×tamp, - COL_DEBUG_DOMAIN, &domain, - COL_DEBUG_CATEGORY, &category, - COL_DEBUG_LEVEL_STRING, &level_str, - COL_DEBUG_MESSAGE, &message, + COL_DEBUG_MESSAGE, &msg, -1); + level_str = log_level_to_string (tp_debug_message_get_level (msg)); level_upper = g_ascii_strup (level_str, -1); - time_str = debug_window_format_timestamp (timestamp); + time_str = debug_window_format_timestamp (msg); + category = tp_debug_message_get_category (msg); line = g_strdup_printf ("%s%s%s-%s: %s: %s\n", - domain, EMP_STR_EMPTY (category) ? "" : "/", - category, level_upper, time_str, message); + tp_debug_message_get_domain (msg), + category ? "" : "/", category ? category : "", + level_upper, time_str, tp_debug_message_get_message (msg)); g_free (time_str); - /* 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); - - g_free (*debug_data); - *debug_data = tmp; + tmp = g_strconcat (*text, line, NULL); + g_free (*text); g_free (line); g_free (level_upper); - g_free (level_str); - g_free (domain); - g_free (category); - g_free (message); + g_object_unref (msg); + + *text = tmp; return FALSE; } @@ -1540,9 +1537,8 @@ debug_window_store_filter_foreach (GtkTreeModel *model, static void debug_window_save_file_chooser_response_cb (GtkDialog *dialog, gint response_id, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); gchar *filename = NULL; GFile *gfile = NULL; gchar *debug_data = NULL; @@ -1568,8 +1564,8 @@ debug_window_save_file_chooser_response_cb (GtkDialog *dialog, goto OUT; } - gtk_tree_model_foreach (priv->store_filter, - debug_window_store_filter_foreach, &debug_data); + gtk_tree_model_foreach (self->priv->store_filter, + debug_window_copy_model_foreach, &debug_data); g_output_stream_write (G_OUTPUT_STREAM (output_stream), debug_data, strlen (debug_data), NULL, &file_write_error); @@ -1596,7 +1592,7 @@ OUT: static void debug_window_save_clicked_cb (GtkToolButton *tool_button, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { GtkWidget *file_chooser; gchar *name, *tmp = NULL; @@ -1605,7 +1601,7 @@ debug_window_save_clicked_cb (GtkToolButton *tool_button, struct tm *tm_s; file_chooser = gtk_file_chooser_dialog_new (_("Save"), - GTK_WINDOW (debug_window), GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_WINDOW (self), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); @@ -1617,7 +1613,7 @@ debug_window_save_clicked_cb (GtkToolButton *tool_button, gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (file_chooser), g_get_home_dir ()); - name = get_active_service_name (debug_window); + name = get_active_service_name (self); t = time (NULL); tm_s = localtime (&t); @@ -1636,7 +1632,7 @@ debug_window_save_clicked_cb (GtkToolButton *tool_button, g_signal_connect (file_chooser, "response", G_CALLBACK (debug_window_save_file_chooser_response_cb), - debug_window); + self); gtk_widget_show (file_chooser); } @@ -1654,7 +1650,7 @@ debug_window_pastebin_response_dialog_closed_cb (GtkDialog *dialog, static void debug_window_pastebin_callback (SoupSession *session, SoupMessage *msg, - gpointer debug_window) + gpointer self) { GtkWidget *dialog; SoupBuffer *buffer; @@ -1662,7 +1658,7 @@ debug_window_pastebin_callback (SoupSession *session, 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), + dialog = gtk_message_dialog_new (GTK_WINDOW (self), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("Pastebin link")); @@ -1671,7 +1667,7 @@ debug_window_pastebin_callback (SoupSession *session, } else { - dialog = gtk_message_dialog_new (GTK_WINDOW (debug_window), + dialog = gtk_message_dialog_new (GTK_WINDOW (self), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, _("Pastebin response")); @@ -1685,7 +1681,7 @@ debug_window_pastebin_callback (SoupSession *session, g_object_unref (session); - gtk_window_set_transient_for (GTK_WINDOW (dialog), debug_window); + gtk_window_set_transient_for (GTK_WINDOW (dialog), self); gtk_widget_show_all (GTK_WIDGET (dialog)); @@ -1694,26 +1690,26 @@ debug_window_pastebin_callback (SoupSession *session, } static void -debug_window_message_dialog (EmpathyDebugWindow *debug_window, +debug_window_message_dialog (EmpathyDebugWindow *self, const gchar *primary_text, const gchar *secondary_text) { GtkWidget *dialog; - dialog = gtk_message_dialog_new (GTK_WINDOW (debug_window), + dialog = gtk_message_dialog_new (GTK_WINDOW (self), 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_WINDOW (self)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } static void -debug_window_send_to_pastebin (EmpathyDebugWindow *debug_window, +debug_window_send_to_pastebin (EmpathyDebugWindow *self, gchar *debug_data) { SoupSession *session; @@ -1722,7 +1718,7 @@ debug_window_send_to_pastebin (EmpathyDebugWindow *debug_window, if (tp_str_empty (debug_data)) { - debug_window_message_dialog (debug_window, "Error", "No data to send"); + debug_window_message_dialog (self, "Error", "No data to send"); return; } @@ -1751,81 +1747,32 @@ debug_window_send_to_pastebin (EmpathyDebugWindow *debug_window, g_free (formdata); soup_session_queue_message (session, msg, debug_window_pastebin_callback, - debug_window); + self); } static void debug_window_send_to_pastebin_cb (GtkToolButton *tool_button, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - 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); + gtk_tree_model_foreach (self->priv->store_filter, + debug_window_copy_model_foreach, &debug_data); - debug_window_send_to_pastebin (debug_window, debug_data); + debug_window_send_to_pastebin (self, debug_data); g_free (debug_data); } -static gboolean -debug_window_copy_model_foreach (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer user_data) -{ - gchar **text = (gchar **) user_data; - gchar *tmp; - gchar *domain, *category, *message, *level_str, *level_upper; - gdouble timestamp; - gchar *line, *time_str; - - gtk_tree_model_get (model, iter, - COL_DEBUG_TIMESTAMP, ×tamp, - COL_DEBUG_DOMAIN, &domain, - COL_DEBUG_CATEGORY, &category, - COL_DEBUG_LEVEL_STRING, &level_str, - COL_DEBUG_MESSAGE, &message, - -1); - - level_upper = g_ascii_strup (level_str, -1); - - time_str = debug_window_format_timestamp (timestamp); - - line = g_strdup_printf ("%s%s%s-%s: %s: %s\n", - domain, EMP_STR_EMPTY (category) ? "" : "/", - category, level_upper, time_str, message); - - g_free (time_str); - - tmp = g_strconcat (*text, line, NULL); - - g_free (*text); - g_free (line); - g_free (level_upper); - g_free (level_str); - g_free (domain); - g_free (category); - g_free (message); - - *text = tmp; - - return FALSE; -} - static void debug_window_copy_clicked_cb (GtkToolButton *tool_button, - EmpathyDebugWindow *debug_window) + EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = GET_PRIV (debug_window); GtkClipboard *clipboard; - gchar *text; - - text = g_strdup (""); + gchar *text = NULL; - gtk_tree_model_foreach (priv->store_filter, + gtk_tree_model_foreach (self->priv->store_filter, debug_window_copy_model_foreach, &text); clipboard = gtk_clipboard_get_for_display ( @@ -1859,8 +1806,7 @@ static void empathy_debug_window_select_name (EmpathyDebugWindow *self, const gchar *name) { - EmpathyDebugWindowPriv *priv = GET_PRIV (self); - GtkTreeModel *model = GTK_TREE_MODEL (priv->service_store); + GtkTreeModel *model = GTK_TREE_MODEL (self->priv->service_store); GtkTreeIter iter; gchar *iter_name; gboolean valid, found = FALSE; @@ -1883,7 +1829,7 @@ empathy_debug_window_select_name (EmpathyDebugWindow *self, } if (found) - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->chooser), &iter); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self->priv->chooser), &iter); } static void @@ -1891,8 +1837,8 @@ am_prepared_cb (GObject *am, GAsyncResult *res, gpointer user_data) { + EmpathyDebugWindow *self = user_data; GObject *object = user_data; - EmpathyDebugWindowPriv *priv = GET_PRIV (object); GtkWidget *vbox; GtkWidget *toolbar; GtkWidget *image; @@ -1909,6 +1855,8 @@ am_prepared_cb (GObject *am, g_clear_error (&error); } + empathy_set_css_provider (GTK_WIDGET (object)); + gtk_window_set_title (GTK_WINDOW (object), _("Debug Window")); gtk_window_set_default_size (GTK_WINDOW (object), 800, 400); empathy_geometry_bind (GTK_WINDOW (object), "debug-window"); @@ -1932,194 +1880,209 @@ am_prepared_cb (GObject *am, gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0); /* CM */ - priv->chooser = gtk_combo_box_text_new (); - priv->service_store = gtk_list_store_new (NUM_COLS, + self->priv->chooser = gtk_combo_box_text_new (); + self->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); + gtk_combo_box_set_model (GTK_COMBO_BOX (self->priv->chooser), + GTK_TREE_MODEL (self->priv->service_store)); + gtk_widget_show (self->priv->chooser); item = gtk_tool_item_new (); gtk_widget_show (GTK_WIDGET (item)); - gtk_container_add (GTK_CONTAINER (item), priv->chooser); + gtk_container_add (GTK_CONTAINER (item), self->priv->chooser); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); - g_signal_connect (priv->chooser, "changed", + g_signal_connect (self->priv->chooser, "changed", G_CALLBACK (debug_window_service_chooser_changed_cb), object); - gtk_widget_show (GTK_WIDGET (priv->chooser)); + gtk_widget_show (GTK_WIDGET (self->priv->chooser)); item = gtk_separator_tool_item_new (); gtk_widget_show (GTK_WIDGET (item)); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* Save */ - priv->save_button = gtk_tool_button_new_from_stock (GTK_STOCK_SAVE); - g_signal_connect (priv->save_button, "clicked", + self->priv->save_button = gtk_tool_button_new_from_stock (GTK_STOCK_SAVE); + g_signal_connect (self->priv->save_button, "clicked", G_CALLBACK (debug_window_save_clicked_cb), object); - gtk_widget_show (GTK_WIDGET (priv->save_button)); - gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->save_button), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->save_button, -1); + gtk_widget_show (GTK_WIDGET (self->priv->save_button)); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (self->priv->save_button), + TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->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), + self->priv->send_to_pastebin = gtk_tool_button_new_from_stock ( + GTK_STOCK_PASTE); + gtk_tool_button_set_label (GTK_TOOL_BUTTON (self->priv->send_to_pastebin), _("Send to pastebin")); - g_signal_connect (priv->send_to_pastebin, "clicked", + g_signal_connect (self->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); + gtk_widget_show (GTK_WIDGET (self->priv->send_to_pastebin)); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (self->priv->send_to_pastebin), + TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->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", + self->priv->copy_button = gtk_tool_button_new_from_stock (GTK_STOCK_COPY); + g_signal_connect (self->priv->copy_button, "clicked", G_CALLBACK (debug_window_copy_clicked_cb), object); - gtk_widget_show (GTK_WIDGET (priv->copy_button)); - gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->copy_button), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->copy_button, -1); + gtk_widget_show (GTK_WIDGET (self->priv->copy_button)); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (self->priv->copy_button), + TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->priv->copy_button, -1); /* Clear */ - priv->clear_button = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR); - g_signal_connect (priv->clear_button, "clicked", + self->priv->clear_button = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR); + g_signal_connect (self->priv->clear_button, "clicked", G_CALLBACK (debug_window_clear_clicked_cb), object); - gtk_widget_show (GTK_WIDGET (priv->clear_button)); - gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->clear_button), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->clear_button, -1); + gtk_widget_show (GTK_WIDGET (self->priv->clear_button)); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (self->priv->clear_button), + TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->priv->clear_button, -1); item = gtk_separator_tool_item_new (); gtk_widget_show (GTK_WIDGET (item)); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* Pause */ - priv->paused = FALSE; + self->priv->paused = FALSE; image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_MENU); gtk_widget_show (image); - priv->pause_button = gtk_toggle_tool_button_new (); + self->priv->pause_button = gtk_toggle_tool_button_new (); gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->pause_button), priv->paused); - g_signal_connect (priv->pause_button, "toggled", + GTK_TOGGLE_TOOL_BUTTON (self->priv->pause_button), self->priv->paused); + g_signal_connect (self->priv->pause_button, "toggled", G_CALLBACK (debug_window_pause_toggled_cb), object); - gtk_widget_show (GTK_WIDGET (priv->pause_button)); - gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->pause_button), TRUE); - gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->pause_button), _("Pause")); + gtk_widget_show (GTK_WIDGET (self->priv->pause_button)); + gtk_tool_item_set_is_important (GTK_TOOL_ITEM (self->priv->pause_button), + TRUE); + gtk_tool_button_set_label (GTK_TOOL_BUTTON (self->priv->pause_button), + _("Pause")); gtk_tool_button_set_icon_widget ( - GTK_TOOL_BUTTON (priv->pause_button), image); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->pause_button, -1); + GTK_TOOL_BUTTON (self->priv->pause_button), image); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->priv->pause_button, -1); item = gtk_separator_tool_item_new (); gtk_widget_show (GTK_WIDGET (item)); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); /* Level */ - priv->level_label = gtk_tool_item_new (); - gtk_widget_show (GTK_WIDGET (priv->level_label)); + self->priv->level_label = gtk_tool_item_new (); + gtk_widget_show (GTK_WIDGET (self->priv->level_label)); label = gtk_label_new (_("Level ")); gtk_widget_show (label); - gtk_container_add (GTK_CONTAINER (priv->level_label), label); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->level_label, -1); + gtk_container_add (GTK_CONTAINER (self->priv->level_label), label); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), self->priv->level_label, -1); - priv->level_filter = gtk_combo_box_text_new (); - gtk_widget_show (priv->level_filter); + self->priv->level_filter = gtk_combo_box_text_new (); + gtk_widget_show (self->priv->level_filter); item = gtk_tool_item_new (); gtk_widget_show (GTK_WIDGET (item)); - gtk_container_add (GTK_CONTAINER (item), priv->level_filter); + gtk_container_add (GTK_CONTAINER (item), self->priv->level_filter); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); level_store = gtk_list_store_new (NUM_COLS_LEVEL, G_TYPE_STRING, G_TYPE_UINT); - gtk_combo_box_set_model (GTK_COMBO_BOX (priv->level_filter), + gtk_combo_box_set_model (GTK_COMBO_BOX (self->priv->level_filter), GTK_TREE_MODEL (level_store)); gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Debug"), - COL_LEVEL_VALUE, TP_DEBUG_LEVEL_DEBUG, + COL_LEVEL_VALUE, G_LOG_LEVEL_DEBUG, -1); gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Info"), - COL_LEVEL_VALUE, TP_DEBUG_LEVEL_INFO, + COL_LEVEL_VALUE, G_LOG_LEVEL_INFO, -1); gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Message"), - COL_LEVEL_VALUE, TP_DEBUG_LEVEL_MESSAGE, + COL_LEVEL_VALUE, G_LOG_LEVEL_MESSAGE, -1); gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Warning"), - COL_LEVEL_VALUE, TP_DEBUG_LEVEL_WARNING, + COL_LEVEL_VALUE, G_LOG_LEVEL_WARNING, -1); gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Critical"), - COL_LEVEL_VALUE, TP_DEBUG_LEVEL_CRITICAL, + COL_LEVEL_VALUE, G_LOG_LEVEL_CRITICAL, -1); gtk_list_store_insert_with_values (level_store, &iter, -1, COL_LEVEL_NAME, _("Error"), - COL_LEVEL_VALUE, TP_DEBUG_LEVEL_ERROR, + COL_LEVEL_VALUE, G_LOG_LEVEL_ERROR, -1); - gtk_combo_box_set_active (GTK_COMBO_BOX (priv->level_filter), 0); - g_signal_connect (priv->level_filter, "changed", + gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->level_filter), 0); + g_signal_connect (self->priv->level_filter, "changed", G_CALLBACK (debug_window_filter_changed_cb), object); /* Debug treeview */ - priv->view = gtk_tree_view_new (); - gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (priv->view), TRUE); + self->priv->view = gtk_tree_view_new (); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (self->priv->view), TRUE); - g_signal_connect (priv->view, "button-press-event", + g_signal_connect (self->priv->view, "button-press-event", G_CALLBACK (debug_window_button_press_event_cb), object); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "yalign", 0, NULL); - gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (priv->view), + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (self->priv->view), -1, _("Time"), renderer, (GtkTreeCellDataFunc) debug_window_time_formatter, NULL, NULL); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view), - -1, _("Domain"), renderer, "text", COL_DEBUG_DOMAIN, NULL); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view), - -1, _("Category"), renderer, "text", COL_DEBUG_CATEGORY, NULL); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view), - -1, _("Level"), renderer, "text", COL_DEBUG_LEVEL_STRING, NULL); + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (self->priv->view), + -1, _("Domain"), renderer, + (GtkTreeCellDataFunc) debug_window_domain_formatter, NULL, NULL); + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (self->priv->view), + -1, _("Category"), renderer, + (GtkTreeCellDataFunc) debug_window_category_formatter, NULL, NULL); + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (self->priv->view), + -1, _("Level"), renderer, + (GtkTreeCellDataFunc) debug_window_level_formatter, NULL, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "family", "Monospace", NULL); - gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view), - -1, _("Message"), renderer, "text", COL_DEBUG_MESSAGE, NULL); + gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (self->priv->view), + -1, _("Message"), renderer, + (GtkTreeCellDataFunc) debug_window_message_formatter, NULL, NULL); - priv->store_filter = NULL; + self->priv->store_filter = NULL; - gtk_tree_view_set_model (GTK_TREE_VIEW (priv->view), priv->store_filter); + gtk_tree_view_set_model (GTK_TREE_VIEW (self->priv->view), + self->priv->store_filter); /* 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), + self->priv->scrolled_win = g_object_ref (gtk_scrolled_window_new ( + NULL, NULL)); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (self->priv->scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_widget_show (priv->view); - gtk_container_add (GTK_CONTAINER (priv->scrolled_win), priv->view); + gtk_widget_show (self->priv->view); + gtk_container_add (GTK_CONTAINER (self->priv->scrolled_win), + self->priv->view); - gtk_widget_show (priv->scrolled_win); + gtk_widget_show (self->priv->scrolled_win); /* Not supported label */ - priv->not_supported_label = g_object_ref (gtk_label_new ( + self->priv->not_supported_label = g_object_ref (gtk_label_new ( _("The selected connection manager does not support the remote " "debugging extension."))); - gtk_widget_show (priv->not_supported_label); - gtk_box_pack_start (GTK_BOX (vbox), priv->not_supported_label, + gtk_widget_show (self->priv->not_supported_label); + gtk_box_pack_start (GTK_BOX (vbox), self->priv->not_supported_label, TRUE, TRUE, 0); - priv->view_visible = FALSE; + self->priv->view_visible = FALSE; - priv->all_active_buffer = NULL; + self->priv->all_active_buffer = NULL; debug_window_set_toolbar_sensitivity (EMPATHY_DEBUG_WINDOW (object), FALSE); debug_window_fill_service_chooser (EMPATHY_DEBUG_WINDOW (object)); @@ -2129,22 +2092,17 @@ am_prepared_cb (GObject *am, static void debug_window_constructed (GObject *object) { - EmpathyDebugWindowPriv *priv = GET_PRIV (object); + EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (object); - priv->am = tp_account_manager_dup (); - tp_proxy_prepare_async (priv->am, NULL, am_prepared_cb, object); + self->priv->am = tp_account_manager_dup (); + tp_proxy_prepare_async (self->priv->am, NULL, am_prepared_cb, object); } static void -empathy_debug_window_init (EmpathyDebugWindow *empathy_debug_window) +empathy_debug_window_init (EmpathyDebugWindow *self) { - EmpathyDebugWindowPriv *priv = - G_TYPE_INSTANCE_GET_PRIVATE (empathy_debug_window, + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_DEBUG_WINDOW, EmpathyDebugWindowPriv); - - empathy_debug_window->priv = priv; - - priv->dispose_run = FALSE; } static void @@ -2178,9 +2136,9 @@ debug_window_get_property (GObject *object, static void debug_window_finalize (GObject *object) { - EmpathyDebugWindowPriv *priv = GET_PRIV (object); + EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (object); - g_free (priv->select_name); + g_free (self->priv->select_name); (G_OBJECT_CLASS (empathy_debug_window_parent_class)->finalize) (object); } @@ -2188,30 +2146,16 @@ debug_window_finalize (GObject *object) static void debug_window_dispose (GObject *object) { - EmpathyDebugWindow *selector = EMPATHY_DEBUG_WINDOW (object); - EmpathyDebugWindowPriv *priv = GET_PRIV (selector); + EmpathyDebugWindow *self = EMPATHY_DEBUG_WINDOW (object); - if (priv->dispose_run) - return; + if (self->priv->name_owner_changed_signal != NULL) + tp_proxy_signal_connection_disconnect ( + self->priv->name_owner_changed_signal); - priv->dispose_run = TRUE; - - if (priv->name_owner_changed_signal != NULL) - tp_proxy_signal_connection_disconnect (priv->name_owner_changed_signal); - - if (priv->service_store != NULL) - g_object_unref (priv->service_store); - - if (priv->dbus != NULL) - g_object_unref (priv->dbus); - - if (priv->am != NULL) - { - g_object_unref (priv->am); - priv->am = NULL; - } - - tp_clear_object (&priv->all_active_buffer); + g_clear_object (&self->priv->service_store); + g_clear_object (&self->priv->dbus); + g_clear_object (&self->priv->am); + g_clear_object (&self->priv->all_active_buffer); (G_OBJECT_CLASS (empathy_debug_window_parent_class)->dispose) (object); } @@ -2225,6 +2169,7 @@ empathy_debug_window_class_init (EmpathyDebugWindowClass *klass) object_class->finalize = debug_window_finalize; object_class->set_property = debug_window_set_property; object_class->get_property = debug_window_get_property; + g_type_class_add_private (klass, sizeof (EmpathyDebugWindowPriv)); } @@ -2243,15 +2188,13 @@ void empathy_debug_window_show (EmpathyDebugWindow *self, const gchar *name) { - EmpathyDebugWindowPriv *priv = GET_PRIV (self); - - if (priv->service_store != NULL) + if (self->priv->service_store != NULL) { empathy_debug_window_select_name (self, name); } else { - g_free (priv->select_name); - priv->select_name = g_strdup (name); + g_free (self->priv->select_name); + self->priv->select_name = g_strdup (name); } } diff --git a/src/empathy-debug-window.h b/src/empathy-debug-window.h index 9815c85de..42bb43ef7 100644 --- a/src/empathy-debug-window.h +++ b/src/empathy-debug-window.h @@ -42,11 +42,12 @@ G_BEGIN_DECLS typedef struct _EmpathyDebugWindow EmpathyDebugWindow; typedef struct _EmpathyDebugWindowClass EmpathyDebugWindowClass; +typedef struct _EmpathyDebugWindowPriv EmpathyDebugWindowPriv; struct _EmpathyDebugWindow { GtkWindow parent; - gpointer priv; + EmpathyDebugWindowPriv *priv; }; struct _EmpathyDebugWindowClass diff --git a/src/empathy-debugger.c b/src/empathy-debugger.c index 0bf34e015..d4ce3273a 100644 --- a/src/empathy-debugger.c +++ b/src/empathy-debugger.c @@ -74,7 +74,7 @@ command_line_cb (GApplication *application, optcontext = g_option_context_new (N_("- Empathy Debugger")); g_option_context_add_group (optcontext, gtk_get_option_group (TRUE)); g_option_context_add_main_entries (optcontext, options, GETTEXT_PACKAGE); - + g_option_context_set_translation_domain (optcontext, GETTEXT_PACKAGE); argv = g_application_command_line_get_arguments (command_line, &argc); if (!g_option_context_parse (optcontext, &argc, &argv, &error)) @@ -101,9 +101,9 @@ main (int argc, GtkApplication *app; gint retval; - g_thread_init (NULL); gtk_init (&argc, &argv); empathy_gtk_init (); + textdomain (GETTEXT_PACKAGE); app = gtk_application_new (EMPATHY_DEBUGGER_DBUS_NAME, G_APPLICATION_HANDLES_COMMAND_LINE); @@ -115,7 +115,6 @@ main (int argc, /* Make empathy and empathy-debugger appear as the same app in gnome-shell */ gdk_set_program_class ("Empathy"); gtk_window_set_default_icon_name ("empathy"); - textdomain (GETTEXT_PACKAGE); retval = g_application_run (G_APPLICATION (app), argc, argv); diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c index 33854974b..d10af58e8 100644 --- a/src/empathy-event-manager.c +++ b/src/empathy-event-manager.c @@ -30,10 +30,8 @@ #include <telepathy-glib/simple-approver.h> #include <libempathy/empathy-presence-manager.h> -#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy/empathy-connection-aggregator.h> #include <libempathy/empathy-tp-chat.h> -#include <libempathy/empathy-tp-streamed-media.h> #include <libempathy/empathy-utils.h> #include <libempathy/empathy-gsettings.h> @@ -408,11 +406,7 @@ reject_channel_claim_cb (GObject *source, goto out; } - if (EMPATHY_IS_TP_STREAMED_MEDIA (user_data)) - { - empathy_tp_streamed_media_close (user_data); - } - else if (TP_IS_CALL_CHANNEL (user_data)) + if (TP_IS_CALL_CHANNEL (user_data)) { tp_call_channel_hangup_async (user_data, TP_CALL_STATE_CHANGE_REASON_USER_REQUESTED, @@ -499,13 +493,7 @@ event_channel_process_voip_func (EventPriv *event) return; } - if (etype == EMPATHY_EVENT_TYPE_VOIP) - { - EmpathyTpStreamedMedia *call; - call = EMPATHY_TP_STREAMED_MEDIA (event->approval->handler_instance); - video = empathy_tp_streamed_media_has_initial_video (call); - } - else if (etype == EMPATHY_EVENT_TYPE_CALL) + if (etype == EMPATHY_EVENT_TYPE_CALL) { TpCallChannel *call; call = TP_CALL_CHANNEL (event->approval->handler_instance); @@ -588,7 +576,6 @@ event_manager_chat_message_received_cb (EmpathyTpChat *tp_chat, EmpathyMessage *message, EventManagerApproval *approval) { - GtkWidget *window; EmpathyContact *sender; const gchar *header; const gchar *msg; @@ -616,12 +603,8 @@ event_manager_chat_message_received_cb (EmpathyTpChat *tp_chat, EMPATHY_EVENT_TYPE_CHAT, EMPATHY_IMAGE_NEW_MESSAGE, header, msg, approval, event_text_channel_process_func, NULL); - window = empathy_roster_window_dup (); - - empathy_sound_manager_play (priv->sound_mgr, window, + empathy_sound_manager_play (priv->sound_mgr, NULL, EMPATHY_SOUND_CONVERSATION_NEW); - - g_object_unref (window); } static void @@ -690,112 +673,6 @@ event_manager_call_state_changed_cb (TpCallChannel *call, } static void -event_manager_call_channel_got_contact_cb (TpConnection *connection, - EmpathyContact *contact, - const GError *error, - gpointer user_data, - GObject *object) -{ - EventManagerApproval *approval = (EventManagerApproval *) user_data; - EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); - GtkWidget *window; - TpCallChannel *call; - gchar *header; - gboolean video; - - call = TP_CALL_CHANNEL (approval->handler_instance); - - if (error != NULL) - { - DEBUG ("Can't get the contact for the call.. Rejecting?"); - reject_approval (approval); - return; - } - - 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); - return; - } - - approval->handler = g_signal_connect (call, "state-changed", - G_CALLBACK (event_manager_call_state_changed_cb), approval); - - window = empathy_roster_window_dup (); - approval->contact = g_object_ref (contact); - - g_object_get (G_OBJECT (call), "initial-video", &video, NULL); - - header = g_strdup_printf ( - video ? _("Incoming video call from %s") :_("Incoming call from %s"), - empathy_contact_get_alias (approval->contact)); - - event_manager_add (approval->manager, NULL, - approval->contact, EMPATHY_EVENT_TYPE_CALL, - video ? EMPATHY_IMAGE_VIDEO_CALL : EMPATHY_IMAGE_VOIP, - header, NULL, approval, - event_channel_process_voip_func, NULL); - - g_free (header); - - priv->ringing++; - if (priv->ringing == 1) - empathy_sound_manager_start_playing (priv->sound_mgr, window, - EMPATHY_SOUND_PHONE_INCOMING, MS_BETWEEN_RING); - - g_object_unref (window); -} - -static void -event_manager_media_channel_got_contact (EventManagerApproval *approval) -{ - EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); - GtkWidget *window = empathy_roster_window_dup (); - gchar *header; - EmpathyTpStreamedMedia *call; - gboolean video; - - call = EMPATHY_TP_STREAMED_MEDIA (approval->handler_instance); - - video = empathy_tp_streamed_media_has_initial_video (call); - - header = g_strdup_printf ( - video ? _("Incoming video call from %s") :_("Incoming call from %s"), - empathy_contact_get_alias (approval->contact)); - - event_manager_add (approval->manager, NULL, - approval->contact, EMPATHY_EVENT_TYPE_VOIP, - video ? EMPATHY_IMAGE_VIDEO_CALL : EMPATHY_IMAGE_VOIP, - header, NULL, approval, - event_channel_process_voip_func, NULL); - - g_free (header); - - priv->ringing++; - if (priv->ringing == 1) - empathy_sound_manager_start_playing (priv->sound_mgr, window, - EMPATHY_SOUND_PHONE_INCOMING, MS_BETWEEN_RING); - - g_object_unref (window); -} - -static void -event_manager_media_channel_contact_changed_cb (EmpathyTpStreamedMedia *call, - GParamSpec *param, EventManagerApproval *approval) -{ - EmpathyContact *contact; - - g_object_get (G_OBJECT (call), "contact", &contact, NULL); - - if (contact == NULL) - return; - - approval->contact = contact; - event_manager_media_channel_got_contact (approval); -} - -static void invite_dialog_response_cb (GtkDialog *dialog, gint response, EventManagerApproval *approval) @@ -871,15 +748,14 @@ event_room_channel_process_func (EventPriv *event) static void display_invite_room_dialog (EventManagerApproval *approval) { - GtkWidget *window = empathy_roster_window_dup (); const gchar *invite_msg; gchar *msg; - TpHandle self_handle; + TpContact *self_contact; EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); - self_handle = tp_channel_group_get_self_handle (approval->main_channel); - tp_channel_group_get_local_pending_info (approval->main_channel, self_handle, - NULL, NULL, &invite_msg); + self_contact = tp_channel_group_get_self_contact (approval->main_channel); + tp_channel_group_get_local_pending_contact_info (approval->main_channel, + self_contact, NULL, NULL, &invite_msg); if (approval->contact != NULL) { @@ -898,50 +774,178 @@ display_invite_room_dialog (EventManagerApproval *approval) EMPATHY_IMAGE_GROUP_MESSAGE, msg, invite_msg, approval, event_room_channel_process_func, NULL); - empathy_sound_manager_play (priv->sound_mgr, window, + empathy_sound_manager_play (priv->sound_mgr, NULL, EMPATHY_SOUND_CONVERSATION_NEW); g_free (msg); - g_object_unref (window); } static void -event_manager_muc_invite_got_contact_cb (TpConnection *connection, - EmpathyContact *contact, - const GError *error, - gpointer user_data, - GObject *object) +event_manager_auth_process_func (EventPriv *event) { - EventManagerApproval *approval = (EventManagerApproval *) user_data; + empathy_event_approve ((EmpathyEvent *) event); +} - if (error != NULL) +/* If there is a file-transfer, media, or auth channel consider it as + * the main one. */ +static TpChannel * +find_main_channel (GList *channels) +{ + GList *l; + TpChannel *text = NULL; + + for (l = channels; l != NULL; l = g_list_next (l)) { - DEBUG ("Error: %s", error->message); + TpChannel *channel = l->data; + GQuark channel_type; + + if (tp_proxy_get_invalidated (channel) != NULL) + continue; + + channel_type = tp_channel_get_channel_type_id (channel); + + if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || + 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; + + else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT) + text = channel; } - else + + return text; +} + +static void +approve_text_channel (EmpathyEventManager *self, + EventManagerApproval *approval, + TpAddDispatchOperationContext *context, + EmpathyTpChat *tp_chat) +{ + GList *messages, *l; + + approval->handler_instance = g_object_ref (tp_chat); + + if (tp_proxy_has_interface (tp_chat, TP_IFACE_CHANNEL_INTERFACE_GROUP)) { - approval->contact = g_object_ref (contact); + /* Are we in local-pending ? */ + TpContact *inviter; + + if (empathy_tp_chat_is_invited (tp_chat, &inviter)) + { + /* We are invited to a room */ + DEBUG ("Have been invited to %s. Ask user if he wants to accept", + tp_channel_get_identifier (TP_CHANNEL_GROUP_CHANGE_REASON_NONE)); + + if (inviter != NULL) + { + approval->contact = empathy_contact_dup_from_tp_contact ( + inviter); + } + + display_invite_room_dialog (approval); + tp_add_dispatch_operation_context_accept (context); + + return; + } + + /* We are not invited, approve the channel right now */ + tp_add_dispatch_operation_context_accept (context); + + approval->auto_approved = TRUE; + event_manager_approval_approve (approval); + return; } - display_invite_room_dialog (approval); + /* 1-1 text channel, wait for the first message */ + approval->handler = g_signal_connect (tp_chat, "message-received-empathy", + G_CALLBACK (event_manager_chat_message_received_cb), approval); + + messages = (GList *) empathy_tp_chat_get_pending_messages (tp_chat); + for (l = messages; l != NULL; l = g_list_next (l)) + { + EmpathyMessage *msg = l->data; + + event_manager_chat_message_received_cb (tp_chat, msg, approval); + } + + tp_add_dispatch_operation_context_accept (context); +} + +static void +approval_set_target_contact (EventManagerApproval *approval, + TpChannel *channel) +{ + TpContact *contact; + + contact = tp_channel_get_target_contact (channel); + approval->contact = empathy_contact_dup_from_tp_contact (contact); } static void -event_manager_ft_got_contact_cb (TpConnection *connection, - EmpathyContact *contact, - const GError *error, - gpointer user_data, - GObject *object) +approve_call_channel (EmpathyEventManager *self, + EventManagerApproval *approval, + TpAddDispatchOperationContext *context, + TpCallChannel *call) { - EventManagerApproval *approval = (EventManagerApproval *) user_data; - GtkWidget *window = empathy_roster_window_dup (); - char *header; + TpChannel *channel = TP_CHANNEL (call); EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); + gchar *header; + gboolean video; - approval->contact = g_object_ref (contact); + approval->handler_instance = g_object_ref (call); + approval_set_target_contact (approval, channel); + + tp_add_dispatch_operation_context_accept (context); + + 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); + return; + } + + approval->handler = g_signal_connect (call, "state-changed", + G_CALLBACK (event_manager_call_state_changed_cb), approval); + + g_object_get (G_OBJECT (call), "initial-video", &video, NULL); + + header = g_strdup_printf ( + video ? _("Incoming video call from %s") :_("Incoming call from %s"), + empathy_contact_get_alias (approval->contact)); + + event_manager_add (approval->manager, NULL, + approval->contact, EMPATHY_EVENT_TYPE_CALL, + video ? EMPATHY_IMAGE_VIDEO_CALL : EMPATHY_IMAGE_VOIP, + header, NULL, approval, + event_channel_process_voip_func, NULL); + + g_free (header); + + priv->ringing++; + if (priv->ringing == 1) + empathy_sound_manager_start_playing (priv->sound_mgr, NULL, + EMPATHY_SOUND_PHONE_INCOMING, MS_BETWEEN_RING); +} + +static void +approve_ft_channel (EmpathyEventManager *self, + EventManagerApproval *approval, + TpAddDispatchOperationContext *context, + TpFileTransferChannel *ft) +{ + TpChannel *channel = TP_CHANNEL (ft); + EmpathyEventManagerPriv *priv = GET_PRIV (approval->manager); + gchar *header; + + approval->handler_instance = g_object_ref (ft); + approval_set_target_contact (approval, channel); + + tp_add_dispatch_operation_context_accept (context); header = g_strdup_printf (_("Incoming file transfer from %s"), - empathy_contact_get_alias (approval->contact)); + empathy_contact_get_alias (approval->contact)); event_manager_add (approval->manager, NULL, approval->contact, EMPATHY_EVENT_TYPE_TRANSFER, @@ -949,48 +953,46 @@ event_manager_ft_got_contact_cb (TpConnection *connection, approval, event_channel_process_func, NULL); /* FIXME better sound for incoming file transfers ?*/ - empathy_sound_manager_play (priv->sound_mgr, window, + empathy_sound_manager_play (priv->sound_mgr, NULL, EMPATHY_SOUND_CONVERSATION_NEW); g_free (header); - g_object_unref (window); } static void -event_manager_auth_process_func (EventPriv *event) +approve_sasl_channel (EmpathyEventManager *self, + TpAccount *account, + EventManagerApproval *approval, + TpAddDispatchOperationContext *context, + TpChannel *channel) { - empathy_event_approve ((EmpathyEvent *) event); -} + GHashTable *props; + const gchar * const *available_mechanisms; -/* If there is a file-transfer, media, or auth channel consider it as - * the main one. */ -static TpChannel * -find_main_channel (GList *channels) -{ - GList *l; - TpChannel *text = NULL; + props = tp_channel_borrow_immutable_properties (channel); + available_mechanisms = tp_asv_get_boxed (props, + TP_PROP_CHANNEL_INTERFACE_SASL_AUTHENTICATION_AVAILABLE_MECHANISMS, + G_TYPE_STRV); - for (l = channels; l != NULL; l = g_list_next (l)) + if (tp_strv_contains (available_mechanisms, "X-TELEPATHY-PASSWORD")) { - TpChannel *channel = l->data; - GQuark channel_type; - - if (tp_proxy_get_invalidated (channel) != NULL) - continue; - - channel_type = tp_channel_get_channel_type_id (channel); - - if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA || - 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; + event_manager_add (approval->manager, account, NULL, + EMPATHY_EVENT_TYPE_AUTH, + GTK_STOCK_DIALOG_AUTHENTICATION, + tp_account_get_display_name (account), + _("Password required"), approval, + event_manager_auth_process_func, NULL); + } + else + { + GError error = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, + "Support only X-TELEPATHY-PASSWORD auth method" }; - else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT) - text = channel; + tp_add_dispatch_operation_context_fail (context, &error); + return; } - return text; + tp_add_dispatch_operation_context_accept (context); } static void @@ -1028,132 +1030,22 @@ approve_channels (TpSimpleApprover *approver, channel_type = tp_channel_get_channel_type_id (channel); - if (TP_IS_TEXT_CHANNEL (channel)) - { - EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (channel); - GList *messages, *l; - - approval->handler_instance = g_object_ref (tp_chat); - - if (tp_proxy_has_interface (channel, TP_IFACE_CHANNEL_INTERFACE_GROUP)) - { - /* Are we in local-pending ? */ - TpHandle inviter; - - if (empathy_tp_chat_is_invited (tp_chat, &inviter)) - { - /* We are invited to a room */ - DEBUG ("Have been invited to %s. Ask user if he wants to accept", - tp_channel_get_identifier (channel)); - - if (inviter != 0) - { - empathy_tp_contact_factory_get_from_handle (connection, - inviter, event_manager_muc_invite_got_contact_cb, - approval, NULL, G_OBJECT (self)); - } - else - { - display_invite_room_dialog (approval); - } - - goto out; - } - - /* We are not invited, approve the channel right now */ - tp_add_dispatch_operation_context_accept (context); - - approval->auto_approved = TRUE; - event_manager_approval_approve (approval); - return; - } - - /* 1-1 text channel, wait for the first message */ - approval->handler = g_signal_connect (tp_chat, "message-received-empathy", - G_CALLBACK (event_manager_chat_message_received_cb), approval); - - messages = (GList *) empathy_tp_chat_get_pending_messages (tp_chat); - for (l = messages; l != NULL; l = g_list_next (l)) - { - EmpathyMessage *msg = l->data; - - event_manager_chat_message_received_cb (tp_chat, msg, approval); - } - } - else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) + if (EMPATHY_IS_TP_CHAT (channel)) { - EmpathyContact *contact; - EmpathyTpStreamedMedia *call = empathy_tp_streamed_media_new (account, - channel); - - approval->handler_instance = G_OBJECT (call); - - g_object_get (G_OBJECT (call), "contact", &contact, NULL); - - if (contact == NULL) - { - g_signal_connect (call, "notify::contact", - G_CALLBACK (event_manager_media_channel_contact_changed_cb), - approval); - } - else - { - approval->contact = contact; - event_manager_media_channel_got_contact (approval); - } - + approve_text_channel (self, approval, context, EMPATHY_TP_CHAT (channel)); } - else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_CALL) + else if (TP_IS_CALL_CHANNEL (channel)) { - TpCallChannel *call = TP_CALL_CHANNEL (channel); - const gchar *id; - - approval->handler_instance = g_object_ref (call); - - id = tp_channel_get_identifier (channel); - - empathy_tp_contact_factory_get_from_id (connection, id, - event_manager_call_channel_got_contact_cb, - approval, NULL, G_OBJECT (self)); + approve_call_channel (self, approval, context, TP_CALL_CHANNEL (channel)); } - else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER) + else if (TP_IS_FILE_TRANSFER_CHANNEL (channel)) { - TpHandle handle; - - approval->handler_instance = g_object_ref (channel); - - handle = tp_channel_get_handle (channel, NULL); - - empathy_tp_contact_factory_get_from_handle (connection, handle, - event_manager_ft_got_contact_cb, approval, NULL, G_OBJECT (self)); + approve_ft_channel (self, approval, context, + TP_FILE_TRANSFER_CHANNEL (channel)); } else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION) { - GHashTable *props; - const gchar * const *available_mechanisms; - - props = tp_channel_borrow_immutable_properties (channel); - available_mechanisms = tp_asv_get_boxed (props, - TP_PROP_CHANNEL_INTERFACE_SASL_AUTHENTICATION_AVAILABLE_MECHANISMS, - G_TYPE_STRV); - - if (tp_strv_contains (available_mechanisms, "X-TELEPATHY-PASSWORD")) - { - event_manager_add (approval->manager, account, NULL, - EMPATHY_EVENT_TYPE_AUTH, - GTK_STOCK_DIALOG_AUTHENTICATION, - tp_account_get_display_name (account), - _("Password required"), approval, - event_manager_auth_process_func, NULL); - } - else - { - GError error = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, - "Support only X-TELEPATHY-PASSWORD auth method" }; - - tp_add_dispatch_operation_context_fail (context, &error); - return; - } + approve_sasl_channel (self, account, approval, context, channel); } else { @@ -1166,9 +1058,6 @@ approve_channels (TpSimpleApprover *approver, tp_add_dispatch_operation_context_fail (context, &error); return; } - -out: - tp_add_dispatch_operation_context_accept (context); } static void @@ -1251,7 +1140,6 @@ event_manager_presence_changed_cb (EmpathyContact *contact, EmpathyEventManagerPriv *priv = GET_PRIV (manager); TpAccount *account; EmpathyPresenceManager *presence_mgr; - GtkWidget *window = empathy_roster_window_dup (); account = empathy_contact_get_account (contact); presence_mgr = empathy_presence_manager_dup_singleton (); @@ -1267,7 +1155,7 @@ event_manager_presence_changed_cb (EmpathyContact *contact, TP_CONNECTION_PRESENCE_TYPE_OFFLINE) <= 0) { /* someone is logging off */ - empathy_sound_manager_play (priv->sound_mgr, window, + empathy_sound_manager_play (priv->sound_mgr, NULL, EMPATHY_SOUND_CONTACT_DISCONNECTED); if (g_settings_get_boolean (priv->gsettings_notif, @@ -1288,7 +1176,7 @@ event_manager_presence_changed_cb (EmpathyContact *contact, TP_CONNECTION_PRESENCE_TYPE_OFFLINE) > 0) { /* someone is logging in */ - empathy_sound_manager_play (priv->sound_mgr, window, + empathy_sound_manager_play (priv->sound_mgr, NULL, EMPATHY_SOUND_CONTACT_CONNECTED); if (g_settings_get_boolean (priv->gsettings_notif, @@ -1305,7 +1193,6 @@ event_manager_presence_changed_cb (EmpathyContact *contact, out: g_object_unref (presence_mgr); - g_object_unref (window); } static GObject * diff --git a/src/empathy-event-manager.h b/src/empathy-event-manager.h index e50ab8884..394db8d9c 100644 --- a/src/empathy-event-manager.h +++ b/src/empathy-event-manager.h @@ -50,7 +50,6 @@ struct _EmpathyEventManagerClass { typedef enum { EMPATHY_EVENT_TYPE_CHAT, - EMPATHY_EVENT_TYPE_VOIP, EMPATHY_EVENT_TYPE_CALL, EMPATHY_EVENT_TYPE_TRANSFER, EMPATHY_EVENT_TYPE_SUBSCRIPTION, diff --git a/src/empathy-invite-participant-dialog.c b/src/empathy-invite-participant-dialog.c index fd5bd8f76..ecbf00be9 100644 --- a/src/empathy-invite-participant-dialog.c +++ b/src/empathy-invite-participant-dialog.c @@ -17,7 +17,6 @@ #include "empathy-invite-participant-dialog.h" #include <libempathy/empathy-utils.h> -#include <libempathy/empathy-contact-list.h> #include <libempathy-gtk/empathy-contact-chooser.h> #include <libempathy-gtk/empathy-individual-view.h> @@ -146,22 +145,22 @@ filter_individual (EmpathyContactChooser *chooser, return FALSE; /* Filter out contacts which are already in the chat */ - members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST ( - self->priv->tp_chat)); + members = empathy_tp_chat_get_members (self->priv->tp_chat); for (l = members; l != NULL; l = g_list_next (l)) { EmpathyContact *member = l->data; - TpHandle handle; + TpContact *owner; - /* Try to get the non-channel specific handle. */ - handle = tp_channel_group_get_handle_owner ( + /* Try to get the non-channel specific contact. */ + owner = tp_channel_group_get_contact_owner ( TP_CHANNEL (self->priv->tp_chat), - empathy_contact_get_handle (member)); - if (handle == 0) - handle = empathy_contact_get_handle (member); + empathy_contact_get_tp_contact (member)); - if (handle == tp_contact_get_handle (contact)) + if (owner == NULL) + owner = empathy_contact_get_tp_contact (member); + + if (owner == contact) { display = FALSE; break; diff --git a/src/empathy-map-view.c b/src/empathy-map-view.c deleted file mode 100644 index 9ab82c091..000000000 --- a/src/empathy-map-view.c +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (C) 2008, 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: Pierre-Luc Beaudoin <pierre-luc.beaudoin@collabora.co.uk> - */ - -#include <config.h> - -#include <sys/stat.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <gdk/gdkkeysyms.h> - -#include <champlain/champlain.h> -#include <champlain-gtk/champlain-gtk.h> -#include <clutter-gtk/clutter-gtk.h> -#include <telepathy-glib/util.h> - -#include <libempathy/empathy-contact.h> -#include <libempathy/empathy-connection-aggregator.h> -#include <libempathy/empathy-utils.h> -#include <libempathy/empathy-location.h> - -#include <libempathy-gtk/empathy-individual-menu.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -#include "empathy-map-view.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_LOCATION -#include <libempathy/empathy-debug.h> - -G_DEFINE_TYPE (EmpathyMapView, empathy_map_view, GTK_TYPE_WINDOW); - -#define GET_PRIV(self) ((EmpathyMapViewPriv *)((EmpathyMapView *) self)->priv) - -struct _EmpathyMapViewPriv { - EmpathyConnectionAggregator *aggregator; - - GtkWidget *zoom_in; - GtkWidget *zoom_out; - GtkWidget *throbber; - ChamplainView *map_view; - ChamplainMarkerLayer *layer; - guint timeout_id; - /* reffed (EmpathyContact *) => borrowed (ChamplainMarker *) */ - GHashTable *markers; - gulong members_changed_id; - - /* TpContact -> EmpathyContact */ - GHashTable *contacts; -}; - -static void -map_view_state_changed (ChamplainView *view, - GParamSpec *gobject, - EmpathyMapView *self) -{ - ChamplainState state; - EmpathyMapViewPriv *priv = GET_PRIV (self); - - g_object_get (G_OBJECT (view), "state", &state, NULL); - if (state == CHAMPLAIN_STATE_LOADING) - { - gtk_spinner_start (GTK_SPINNER (priv->throbber)); - gtk_widget_show (priv->throbber); - } - else - { - gtk_spinner_stop (GTK_SPINNER (priv->throbber)); - gtk_widget_hide (priv->throbber); - } -} - -static gboolean -contact_has_location (EmpathyContact *contact) -{ - GHashTable *location; - - location = empathy_contact_get_location (contact); - - if (location == NULL || g_hash_table_size (location) == 0) - return FALSE; - - return TRUE; -} - -static ClutterActor * create_marker (EmpathyMapView *window, - EmpathyContact *contact); - -static void -map_view_update_contact_position (EmpathyMapView *self, - EmpathyContact *contact) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - gdouble lon, lat; - GValue *value; - GHashTable *location; - ClutterActor *marker; - gboolean has_location; - - has_location = contact_has_location (contact); - - marker = g_hash_table_lookup (priv->markers, contact); - if (marker == NULL) - { - if (!has_location) - return; - - marker = create_marker (self, contact); - } - else if (!has_location) - { - champlain_marker_animate_out (CHAMPLAIN_MARKER (marker)); - return; - } - - location = empathy_contact_get_location (contact); - - value = g_hash_table_lookup (location, EMPATHY_LOCATION_LAT); - if (value == NULL) - { - clutter_actor_hide (marker); - return; - } - lat = g_value_get_double (value); - - value = g_hash_table_lookup (location, EMPATHY_LOCATION_LON); - if (value == NULL) - { - clutter_actor_hide (marker); - return; - } - lon = g_value_get_double (value); - - champlain_location_set_location (CHAMPLAIN_LOCATION (marker), lat, lon); - champlain_marker_animate_in (CHAMPLAIN_MARKER (marker)); -} - -static void -map_view_contact_location_notify (EmpathyContact *contact, - GParamSpec *arg1, - EmpathyMapView *self) -{ - map_view_update_contact_position (self, contact); -} - -static void -map_view_zoom_in_cb (GtkWidget *widget, - EmpathyMapView *self) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - - champlain_view_zoom_in (priv->map_view); -} - -static void -map_view_zoom_out_cb (GtkWidget *widget, - EmpathyMapView *self) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - - champlain_view_zoom_out (priv->map_view); -} - -static void -map_view_zoom_fit_cb (GtkWidget *widget, - EmpathyMapView *self) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - - champlain_view_ensure_layers_visible (priv->map_view, TRUE); -} - -static gboolean -marker_clicked_cb (ChamplainMarker *marker, - ClutterButtonEvent *event, - EmpathyMapView *self) -{ - GtkWidget *menu; - EmpathyContact *contact; - TpContact *tp_contact; - FolksIndividual *individual; - - if (event->button != 3) - return FALSE; - - contact = g_object_get_data (G_OBJECT (marker), "contact"); - if (contact == NULL) - return FALSE; - - tp_contact = empathy_contact_get_tp_contact (contact); - if (tp_contact == NULL) - return FALSE; - - individual = empathy_create_individual_from_tp_contact (tp_contact); - if (individual == NULL) - return FALSE; - - menu = empathy_individual_menu_new (individual, - EMPATHY_INDIVIDUAL_FEATURE_CHAT | - EMPATHY_INDIVIDUAL_FEATURE_CALL | - EMPATHY_INDIVIDUAL_FEATURE_LOG | - EMPATHY_INDIVIDUAL_FEATURE_INFO, NULL); - - if (menu == NULL) - goto out; - - gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (self), NULL); - - gtk_widget_show (menu); - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, - event->button, event->time); - -out: - g_object_unref (individual); - return FALSE; -} - -static void -map_view_contacts_update_label (ClutterActor *marker) -{ - const gchar *name; - gchar *date; - gchar *label; - GValue *gtime; - gint64 loctime; - GHashTable *location; - EmpathyContact *contact; - - contact = g_object_get_data (G_OBJECT (marker), "contact"); - location = empathy_contact_get_location (contact); - name = empathy_contact_get_alias (contact); - gtime = g_hash_table_lookup (location, EMPATHY_LOCATION_TIMESTAMP); - - if (gtime != NULL) - { - GDateTime *now, *d; - GTimeSpan delta; - - loctime = g_value_get_int64 (gtime); - date = empathy_time_to_string_relative (loctime); - label = g_strconcat ("<b>", name, "</b>\n<small>", date, "</small>", NULL); - g_free (date); - - now = g_date_time_new_now_utc (); - d = g_date_time_new_from_unix_utc (loctime); - delta = g_date_time_difference (now, d); - - /* if location is older than a week */ - if (delta > G_TIME_SPAN_DAY * 7) - clutter_actor_set_opacity (marker, 0.75 * 255); - - g_date_time_unref (now); - g_date_time_unref (d); - } - else - { - label = g_strconcat ("<b>", name, "</b>\n", NULL); - } - - champlain_label_set_use_markup (CHAMPLAIN_LABEL (marker), TRUE); - champlain_label_set_text (CHAMPLAIN_LABEL (marker), label); - - g_free (label); -} - -static ClutterActor * -create_marker (EmpathyMapView *self, - EmpathyContact *contact) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - ClutterActor *marker; - GdkPixbuf *avatar; - ClutterActor *texture = NULL; - - avatar = empathy_pixbuf_avatar_from_contact_scaled (contact, 32, 32); - if (avatar != NULL) - { - texture = gtk_clutter_texture_new (); - - gtk_clutter_texture_set_from_pixbuf (GTK_CLUTTER_TEXTURE (texture), - avatar, NULL); - - g_object_unref (avatar); - } - - marker = champlain_label_new_with_image (texture); - - g_object_set_data_full (G_OBJECT (marker), "contact", - g_object_ref (contact), g_object_unref); - - g_hash_table_insert (priv->markers, g_object_ref (contact), marker); - - map_view_contacts_update_label (marker); - - clutter_actor_set_reactive (CLUTTER_ACTOR (marker), TRUE); - g_signal_connect (marker, "button-release-event", - G_CALLBACK (marker_clicked_cb), self); - - champlain_marker_layer_add_marker (priv->layer, CHAMPLAIN_MARKER (marker)); - - DEBUG ("Create marker for %s", empathy_contact_get_id (contact)); - - tp_clear_object (&texture); - return marker; -} - -static gboolean -map_view_key_press_cb (GtkWidget *widget, - GdkEventKey *event, - gpointer user_data) -{ - if ((event->state & GDK_CONTROL_MASK && event->keyval == GDK_KEY_w) - || event->keyval == GDK_KEY_Escape) - { - gtk_widget_destroy (widget); - return TRUE; - } - - return FALSE; -} - -static gboolean -map_view_tick (EmpathyMapView *self) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - GList *marker, *l; - - marker = champlain_marker_layer_get_markers (priv->layer); - - for (l = marker; l != NULL; l = g_list_next (l)) - map_view_contacts_update_label (l->data); - - g_list_free (marker); - return TRUE; -} - -static void -contact_list_changed_cb (EmpathyConnectionAggregator *aggregator, - GPtrArray *added, - GPtrArray *removed, - EmpathyMapView *self) -{ - EmpathyMapViewPriv *priv = GET_PRIV (self); - guint i; - - for (i = 0; i < added->len; i++) - { - TpContact *tp_contact = g_ptr_array_index (added, i); - EmpathyContact *contact; - - if (g_hash_table_lookup (priv->contacts, tp_contact) != NULL) - continue; - - contact = empathy_contact_dup_from_tp_contact (tp_contact); - - tp_g_signal_connect_object (contact, "notify::location", - G_CALLBACK (map_view_contact_location_notify), self, 0); - - map_view_update_contact_position (self, contact); - - /* Pass ownership to the hash table */ - g_hash_table_insert (priv->contacts, g_object_ref (tp_contact), - contact); - } - - for (i = 0; i < removed->len; i++) - { - TpContact *tp_contact = g_ptr_array_index (removed, i); - EmpathyContact *contact; - ClutterActor *marker; - - contact = g_hash_table_lookup (priv->contacts, tp_contact); - if (contact == NULL) - continue; - - marker = g_hash_table_lookup (priv->markers, contact); - if (marker != NULL) - { - clutter_actor_destroy (marker); - g_hash_table_remove (priv->markers, contact); - } - - g_signal_handlers_disconnect_by_func (contact, - map_view_contact_location_notify, self); - - g_hash_table_remove (priv->contacts, tp_contact); - } -} - -static GObject * -empathy_map_view_constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - static GObject *window = NULL; - - if (window != NULL) - return window; - - window = G_OBJECT_CLASS (empathy_map_view_parent_class)->constructor ( - type, n_construct_params, construct_params); - - g_object_add_weak_pointer (window, (gpointer) &window); - - return window; -} - -static void -empathy_map_view_finalize (GObject *object) -{ - EmpathyMapViewPriv *priv = GET_PRIV (object); - GHashTableIter iter; - gpointer contact; - - g_source_remove (priv->timeout_id); - - g_hash_table_iter_init (&iter, priv->markers); - while (g_hash_table_iter_next (&iter, &contact, NULL)) - g_signal_handlers_disconnect_by_func (contact, - map_view_contact_location_notify, object); - - g_hash_table_unref (priv->markers); - g_object_unref (priv->aggregator); - g_object_unref (priv->layer); - g_hash_table_unref (priv->contacts); - - G_OBJECT_CLASS (empathy_map_view_parent_class)->finalize (object); -} - -static void -empathy_map_view_class_init (EmpathyMapViewClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructor = empathy_map_view_constructor; - object_class->finalize = empathy_map_view_finalize; - - g_type_class_add_private (object_class, sizeof (EmpathyMapViewPriv)); -} - -static void -empathy_map_view_init (EmpathyMapView *self) -{ - EmpathyMapViewPriv *priv; - GtkBuilder *gui; - GtkWidget *sw; - GtkWidget *embed; - GtkWidget *throbber_holder; - gchar *filename; - GPtrArray *contacts, *empty; - GtkWidget *main_vbox; - - priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - EMPATHY_TYPE_MAP_VIEW, EmpathyMapViewPriv); - - gtk_window_set_title (GTK_WINDOW (self), _("Contact Map View")); - gtk_window_set_role (GTK_WINDOW (self), "map_view"); - gtk_window_set_default_size (GTK_WINDOW (self), 512, 384); - gtk_window_set_position (GTK_WINDOW (self), GTK_WIN_POS_CENTER); - - /* Set up interface */ - filename = empathy_file_lookup ("empathy-map-view.ui", "src"); - gui = empathy_builder_get_file (filename, - "main_vbox", &main_vbox, - "zoom_in", &priv->zoom_in, - "zoom_out", &priv->zoom_out, - "map_scrolledwindow", &sw, - "throbber", &throbber_holder, - NULL); - g_free (filename); - - gtk_container_add (GTK_CONTAINER (self), main_vbox); - - empathy_builder_connect (gui, self, - "zoom_in", "clicked", map_view_zoom_in_cb, - "zoom_out", "clicked", map_view_zoom_out_cb, - "zoom_fit", "clicked", map_view_zoom_fit_cb, - NULL); - - g_signal_connect (self, "key-press-event", - G_CALLBACK (map_view_key_press_cb), self); - - g_object_unref (gui); - - priv->throbber = gtk_spinner_new (); - gtk_widget_set_size_request (priv->throbber, 16, 16); - gtk_container_add (GTK_CONTAINER (throbber_holder), priv->throbber); - - /* Set up map view */ - embed = gtk_champlain_embed_new (); - priv->map_view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (embed)); - g_object_set (G_OBJECT (priv->map_view), - "zoom-level", 1, - "kinetic-mode", TRUE, - NULL); - champlain_view_center_on (priv->map_view, 36, 0); - - gtk_container_add (GTK_CONTAINER (sw), embed); - gtk_widget_show_all (embed); - - priv->layer = g_object_ref (champlain_marker_layer_new ()); - champlain_view_add_layer (priv->map_view, CHAMPLAIN_LAYER (priv->layer)); - - g_signal_connect (priv->map_view, "notify::state", - G_CALLBACK (map_view_state_changed), self); - - /* Set up contact list. */ - priv->markers = g_hash_table_new_full (NULL, NULL, - (GDestroyNotify) g_object_unref, NULL); - - priv->aggregator = empathy_connection_aggregator_dup_singleton (); - priv->contacts = g_hash_table_new_full (NULL, NULL, g_object_unref, - g_object_unref); - - tp_g_signal_connect_object (priv->aggregator, "contact-list-changed", - G_CALLBACK (contact_list_changed_cb), self, 0); - - contacts = empathy_connection_aggregator_dup_all_contacts (priv->aggregator); - empty = g_ptr_array_new (); - - contact_list_changed_cb (priv->aggregator, contacts, empty, self); - - g_ptr_array_unref (contacts); - g_ptr_array_unref (empty); - - /* Set up time updating loop */ - priv->timeout_id = g_timeout_add_seconds (5, - (GSourceFunc) map_view_tick, self); -} - -GtkWidget * -empathy_map_view_show (void) -{ - GtkWidget *window; - - window = g_object_new (EMPATHY_TYPE_MAP_VIEW, NULL); - gtk_widget_show_all (window); - empathy_window_present (GTK_WINDOW (window)); - - return window; -} diff --git a/src/empathy-map-view.h b/src/empathy-map-view.h deleted file mode 100644 index 3184b8c9e..000000000 --- a/src/empathy-map-view.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2008 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: Pierre-Luc Beaudoin <pierre-luc@pierlux.com> - */ - -#ifndef __EMPATHY_MAP_VIEW_H__ -#define __EMPATHY_MAP_VIEW_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define EMPATHY_TYPE_MAP_VIEW (empathy_map_view_get_type ()) -#define EMPATHY_MAP_VIEW(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_MAP_VIEW, EmpathyMapView)) -#define EMPATHY_MAP_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_MAP_VIEW, EmpathyMapViewClass)) -#define EMPATHY_IS_MAP_VIEW(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_MAP_VIEW)) -#define EMPATHY_IS_MAP_VIEW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_MAP_VIEW)) -#define EMPATHY_MAP_VIEW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_MAP_VIEW, EmpathyMapViewClass)) - -typedef struct _EmpathyMapView EmpathyMapView; -typedef struct _EmpathyMapViewClass EmpathyMapViewClass; -typedef struct _EmpathyMapViewPriv EmpathyMapViewPriv; - -struct _EmpathyMapView -{ - GtkWindow parent; - gpointer priv; -}; - -struct _EmpathyMapViewClass -{ - GtkWindowClass parent_class; -}; - -GType empathy_map_view_get_type (void); - -GtkWidget *empathy_map_view_show (void); - -G_END_DECLS - -#endif /* __EMPATHY_MAP_VIEW_H__ */ diff --git a/src/empathy-map-view.ui b/src/empathy-map-view.ui deleted file mode 100644 index 715de8fa4..000000000 --- a/src/empathy-map-view.ui +++ /dev/null @@ -1,89 +0,0 @@ -<?xml version="1.0"?> -<interface> - <requires lib="gtk+" version="2.16"/> - <!-- interface-naming-policy toplevel-contextual --> - <object class="GtkVBox" id="main_vbox"> - <property name="visible">True</property> - <child> - <object class="GtkToolbar" id="toolbar"> - <property name="visible">True</property> - <child> - <object class="GtkToolButton" id="zoom_in"> - <property name="visible">True</property> - <property name="stock_id">gtk-zoom-in</property> - </object> - <packing> - <property name="expand">False</property> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToolButton" id="zoom_out"> - <property name="visible">True</property> - <property name="stock_id">gtk-zoom-out</property> - </object> - <packing> - <property name="expand">False</property> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToolButton" id="zoom_fit"> - <property name="visible">True</property> - <property name="stock_id">gtk-zoom-fit</property> - </object> - <packing> - <property name="expand">False</property> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToolItem" id="toolbutton1"> - <property name="visible">True</property> - <child> - <object class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <child> - <placeholder/> - </child> - </object> - </child> - </object> - <packing> - <property name="expand">True</property> - </packing> - </child> - <child> - <object class="GtkToolItem" id="throbber"> - <property name="visible">True</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="expand">False</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkFrame" id="map_scrolledwindow"> - <property name="visible">True</property> - <property name="resize_mode">queue</property> - <property name="label_xalign">0</property> - <property name="shadow_type">in</property> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">1</property> - </packing> - </child> - </object> -</interface> diff --git a/src/empathy-new-chatroom-dialog.c b/src/empathy-new-chatroom-dialog.c index dd7e70ac1..72505472c 100644 --- a/src/empathy-new-chatroom-dialog.c +++ b/src/empathy-new-chatroom-dialog.c @@ -1,7 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 Collabora Ltd. + * Copyright (C) 2007-2011 Collabora Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -31,9 +30,8 @@ #include <glib/gi18n.h> #include <glib/gprintf.h> -#include <telepathy-glib/interfaces.h> +#include <telepathy-glib/telepathy-glib.h> -#include <libempathy/empathy-tp-roomlist.h> #include <libempathy/empathy-chatroom.h> #include <libempathy/empathy-utils.h> #include <libempathy/empathy-request-util.h> @@ -47,793 +45,777 @@ #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include <libempathy/empathy-debug.h> -typedef struct { - EmpathyTpRoomlist *room_list; - /* Currently selected account */ - TpAccount *account; - /* Signal id of the "status-changed" signal connected on the currently - * selected account */ - gulong status_changed_id; - - GtkWidget *window; - GtkWidget *vbox_widgets; - GtkWidget *table_grid; - GtkWidget *label_account; - GtkWidget *account_chooser; - GtkWidget *label_server; - GtkWidget *entry_server; - GtkWidget *label_room; - GtkWidget *entry_room; - GtkWidget *expander_browse; - GtkWidget *hbox_expander; - GtkWidget *throbber; - GtkWidget *treeview; - GtkTreeModel *model; - GtkWidget *button_join; - GtkWidget *label_error_message; - GtkWidget *viewport_error; - - GSettings *gsettings; -} EmpathyNewChatroomDialog; - -enum { - COL_NEED_PASSWORD, - COL_INVITE_ONLY, - COL_NAME, - COL_ROOM, - COL_MEMBERS, - COL_MEMBERS_INT, - COL_TOOLTIP, - COL_COUNT +G_DEFINE_TYPE (EmpathyNewChatroomDialog, empathy_new_chatroom_dialog, + GTK_TYPE_DIALOG) + +struct _EmpathyNewChatroomDialogPriv +{ + TpRoomList *room_list; + /* Currently selected account */ + TpAccount *account; + /* Signal id of the "status-changed" signal connected on the currently + * selected account */ + gulong status_changed_id; + + GtkWidget *table_grid; + GtkWidget *label_account; + GtkWidget *account_chooser; + GtkWidget *label_server; + GtkWidget *entry_server; + GtkWidget *label_room; + GtkWidget *entry_room; + GtkWidget *expander_browse; + GtkWidget *hbox_expander; + GtkWidget *throbber; + GtkWidget *treeview; + GtkTreeModel *model; + GtkWidget *button_join; + GtkWidget *label_error_message; + GtkWidget *viewport_error; + + GSettings *gsettings; }; -static void new_chatroom_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_destroy_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_account_ready_cb (EmpathyAccountChooser *combobox, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, - EmpathyChatroom *chatroom, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, - gpointer unused, - EmpathyNewChatroomDialog *dialog); -static void start_listing_error_cb (EmpathyTpRoomlist *room_list, - GError *error, - EmpathyNewChatroomDialog *dialog); -static void stop_listing_error_cb (EmpathyTpRoomlist *room_list, - GError *error, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_browse_stop (EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_expander_browse_activate_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog); -static gboolean new_chatroom_dialog_entry_server_focus_out_cb (GtkWidget *widget, - GdkEventFocus *event, - EmpathyNewChatroomDialog *dialog); -static void new_chatroom_dialog_button_close_error_clicked_cb (GtkButton *button, - EmpathyNewChatroomDialog *dialog); +enum +{ + COL_NEED_PASSWORD, + COL_INVITE_ONLY, + COL_NAME, + COL_ROOM, + COL_MEMBERS, + COL_MEMBERS_INT, + COL_TOOLTIP, + COL_COUNT +}; static EmpathyNewChatroomDialog *dialog_p = NULL; - -void -empathy_new_chatroom_dialog_show (GtkWindow *parent) +static void +new_chatroom_dialog_store_last_account (GSettings *gsettings, + EmpathyAccountChooser *account_chooser) { - EmpathyNewChatroomDialog *dialog; - GtkBuilder *gui; - GtkSizeGroup *size_group; - gchar *filename; - - if (dialog_p) { - gtk_window_present (GTK_WINDOW (dialog_p->window)); - return; - } - - dialog_p = dialog = g_new0 (EmpathyNewChatroomDialog, 1); - - filename = empathy_file_lookup ("empathy-new-chatroom-dialog.ui", "src"); - gui = empathy_builder_get_file (filename, - "new_chatroom_dialog", &dialog->window, - "table_grid", &dialog->table_grid, - "label_account", &dialog->label_account, - "label_server", &dialog->label_server, - "label_room", &dialog->label_room, - "entry_server", &dialog->entry_server, - "entry_room", &dialog->entry_room, - "treeview", &dialog->treeview, - "button_join", &dialog->button_join, - "expander_browse", &dialog->expander_browse, - "hbox_expander", &dialog->hbox_expander, - "label_error_message", &dialog->label_error_message, - "viewport_error", &dialog->viewport_error, - NULL); - g_free (filename); - - empathy_builder_connect (gui, dialog, - "new_chatroom_dialog", "response", new_chatroom_dialog_response_cb, - "new_chatroom_dialog", "destroy", new_chatroom_dialog_destroy_cb, - "entry_server", "changed", new_chatroom_dialog_entry_changed_cb, - "entry_server", "activate", new_chatroom_dialog_entry_server_activate_cb, - "entry_server", "focus-out-event", new_chatroom_dialog_entry_server_focus_out_cb, - "entry_room", "changed", new_chatroom_dialog_entry_changed_cb, - "expander_browse", "activate", new_chatroom_dialog_expander_browse_activate_cb, - "button_close_error", "clicked", new_chatroom_dialog_button_close_error_clicked_cb, - NULL); - - g_object_unref (gui); - - g_object_add_weak_pointer (G_OBJECT (dialog->window), (gpointer) &dialog_p); - - /* Label alignment */ - size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - - gtk_size_group_add_widget (size_group, dialog->label_account); - gtk_size_group_add_widget (size_group, dialog->label_server); - gtk_size_group_add_widget (size_group, dialog->label_room); - - g_object_unref (size_group); - - /* Set up chatrooms treeview */ - new_chatroom_dialog_model_setup (dialog); - - /* Add throbber */ - dialog->throbber = gtk_spinner_new (); - gtk_box_pack_start (GTK_BOX (dialog->hbox_expander), dialog->throbber, - TRUE, TRUE, 0); - - dialog->gsettings = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA); - - /* Account chooser for custom */ - dialog->account_chooser = empathy_account_chooser_new (); - empathy_account_chooser_set_filter (EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser), - empathy_account_chooser_filter_supports_chatrooms, - NULL); - gtk_grid_attach (GTK_GRID (dialog->table_grid), - dialog->account_chooser, - 1, 0, 1, 1); - gtk_widget_show (dialog->account_chooser); - - g_signal_connect (EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser), "ready", - G_CALLBACK (new_chatroom_dialog_account_ready_cb), - dialog); - g_signal_connect (GTK_COMBO_BOX (dialog->account_chooser), "changed", - G_CALLBACK (new_chatroom_dialog_account_changed_cb), - dialog); - new_chatroom_dialog_account_changed_cb (GTK_COMBO_BOX (dialog->account_chooser), - dialog); - - if (parent) { - gtk_window_set_transient_for (GTK_WINDOW (dialog->window), - GTK_WINDOW (parent)); - } - - gtk_widget_show (dialog->window); + TpAccount *account; + const char *account_path; + + account = empathy_account_chooser_get_account (account_chooser); + if (account == NULL) + return; + + account_path = tp_proxy_get_object_path (account); + DEBUG ("Storing account path '%s'", account_path); + + g_settings_set (gsettings, EMPATHY_PREFS_CHAT_ROOM_LAST_ACCOUNT, + "o", account_path); } static void -new_chatroom_dialog_store_last_account (GSettings *gsettings, - EmpathyAccountChooser *account_chooser) +new_chatroom_dialog_join (EmpathyNewChatroomDialog *self) { - TpAccount *account; - const char *account_path; + EmpathyAccountChooser *account_chooser; + TpAccount *account; + const gchar *room; + const gchar *server = NULL; + gchar *room_name = NULL; + + room = gtk_entry_get_text (GTK_ENTRY (self->priv->entry_room)); + server = gtk_entry_get_text (GTK_ENTRY (self->priv->entry_server)); + + account_chooser = EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser); + account = empathy_account_chooser_get_account (account_chooser); + + if (!EMP_STR_EMPTY (server)) + room_name = g_strconcat (room, "@", server, NULL); + else + room_name = g_strdup (room); - account = empathy_account_chooser_get_account (account_chooser); - if (account == NULL) - return; + g_strstrip (room_name); - account_path = tp_proxy_get_object_path (account); - DEBUG ("Storing account path '%s'", account_path); + DEBUG ("Requesting channel for '%s'", room_name); - g_settings_set (gsettings, EMPATHY_PREFS_CHAT_ROOM_LAST_ACCOUNT, - "o", account_path); + empathy_join_muc (account, room_name, empathy_get_current_action_time ()); + + g_free (room_name); } static void -new_chatroom_dialog_response_cb (GtkWidget *widget, - gint response, - EmpathyNewChatroomDialog *dialog) +empathy_new_chatroom_dialog_response (GtkDialog *dialog, + gint response) { - if (response == GTK_RESPONSE_OK) { - new_chatroom_dialog_join (dialog); - new_chatroom_dialog_store_last_account (dialog->gsettings, - EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser)); - } + EmpathyNewChatroomDialog *self = EMPATHY_NEW_CHATROOM_DIALOG (dialog); + + if (response == GTK_RESPONSE_OK) + { + new_chatroom_dialog_join (self); + new_chatroom_dialog_store_last_account (self->priv->gsettings, + EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser)); + } - gtk_widget_destroy (widget); + gtk_widget_destroy (GTK_WIDGET (dialog)); } static void -new_chatroom_dialog_destroy_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *self) { - if (dialog->room_list) { - g_object_unref (dialog->room_list); - } - g_object_unref (dialog->model); + GtkTreeView *view; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + gint width, height; + + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); + + view = GTK_TREE_VIEW (self->priv->treeview); - if (dialog->account != NULL) { - g_signal_handler_disconnect (dialog->account, dialog->status_changed_id); - g_object_unref (dialog->account); - } + cell = gtk_cell_renderer_pixbuf_new (); + g_object_set (cell, + "width", width, + "height", height, + "stock-size", GTK_ICON_SIZE_MENU, + NULL); - g_clear_object (&dialog->gsettings); + column = gtk_tree_view_column_new_with_attributes (NULL, cell, + "stock-id", COL_INVITE_ONLY, NULL); - g_free (dialog); + gtk_tree_view_column_set_sort_column_id (column, COL_INVITE_ONLY); + gtk_tree_view_append_column (view, column); + + column = gtk_tree_view_column_new_with_attributes (NULL, cell, + "stock-id", COL_NEED_PASSWORD, NULL); + + gtk_tree_view_column_set_sort_column_id (column, COL_NEED_PASSWORD); + gtk_tree_view_append_column (view, column); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, + "xpad", (guint) 4, + "ypad", (guint) 2, + "ellipsize", PANGO_ELLIPSIZE_END, + NULL); + + column = gtk_tree_view_column_new_with_attributes (_("Chat Room"), cell, + "text", COL_NAME, NULL); + + gtk_tree_view_column_set_sort_column_id (column, COL_NAME); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (view, column); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, + "xpad", (guint) 4, + "ypad", (guint) 2, + "ellipsize", PANGO_ELLIPSIZE_END, + "alignment", PANGO_ALIGN_RIGHT, + NULL); + + column = gtk_tree_view_column_new_with_attributes (_("Members"), cell, + "text", COL_MEMBERS, NULL); + + gtk_tree_view_column_set_sort_column_id (column, COL_MEMBERS_INT); + gtk_tree_view_append_column (view, column); } static void -new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + EmpathyNewChatroomDialog *self) { - GtkTreeView *view; - GtkListStore *store; - GtkTreeSelection *selection; - - /* View */ - view = GTK_TREE_VIEW (dialog->treeview); - - g_signal_connect (view, "row-activated", - G_CALLBACK (new_chatroom_dialog_model_row_activated_cb), - dialog); - - /* Store/Model */ - store = gtk_list_store_new (COL_COUNT, - G_TYPE_STRING, /* Invite */ - G_TYPE_STRING, /* Password */ - G_TYPE_STRING, /* Name */ - G_TYPE_STRING, /* Room */ - G_TYPE_STRING, /* Member count */ - G_TYPE_INT, /* Member count int */ - G_TYPE_STRING); /* Tool tip */ - - dialog->model = GTK_TREE_MODEL (store); - gtk_tree_view_set_model (view, dialog->model); - gtk_tree_view_set_tooltip_column (view, COL_TOOLTIP); - gtk_tree_view_set_search_column (view, COL_NAME); - - /* Selection */ - selection = gtk_tree_view_get_selection (view); - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), - COL_NAME, GTK_SORT_ASCENDING); - - g_signal_connect (selection, "changed", - G_CALLBACK (new_chatroom_dialog_model_selection_changed), - dialog); - - /* Columns */ - new_chatroom_dialog_model_add_columns (dialog); + gtk_widget_activate (self->priv->button_join); } static void -new_chatroom_dialog_model_add_columns (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, + EmpathyNewChatroomDialog *self) { - GtkTreeView *view; - GtkTreeViewColumn *column; - GtkCellRenderer *cell; - gint width, height; - - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); - - view = GTK_TREE_VIEW (dialog->treeview); - - cell = gtk_cell_renderer_pixbuf_new (); - g_object_set (cell, - "width", width, - "height", height, - "stock-size", GTK_ICON_SIZE_MENU, - NULL); - column = gtk_tree_view_column_new_with_attributes (NULL, - cell, - "stock-id", COL_INVITE_ONLY, - NULL); - - gtk_tree_view_column_set_sort_column_id (column, COL_INVITE_ONLY); - gtk_tree_view_append_column (view, column); - - column = gtk_tree_view_column_new_with_attributes (NULL, - cell, - "stock-id", COL_NEED_PASSWORD, - NULL); - - gtk_tree_view_column_set_sort_column_id (column, COL_NEED_PASSWORD); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "xpad", (guint) 4, - "ypad", (guint) 2, - "ellipsize", PANGO_ELLIPSIZE_END, - NULL); - - column = gtk_tree_view_column_new_with_attributes (_("Chat Room"), - cell, - "text", COL_NAME, - NULL); - - gtk_tree_view_column_set_sort_column_id (column, COL_NAME); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (view, column); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, - "xpad", (guint) 4, - "ypad", (guint) 2, - "ellipsize", PANGO_ELLIPSIZE_END, - "alignment", PANGO_ALIGN_RIGHT, - NULL); - column = gtk_tree_view_column_new_with_attributes (_("Members"), - cell, - "text", COL_MEMBERS, - NULL); - - gtk_tree_view_column_set_sort_column_id (column, COL_MEMBERS_INT); - gtk_tree_view_append_column (view, column); + GtkTreeModel *model; + GtkTreeIter iter; + gchar *room = NULL; + gchar *server = NULL; + + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + + gtk_tree_model_get (model, &iter, COL_ROOM, &room, -1); + server = strstr (room, "@"); + if (server) + { + *server = '\0'; + server++; + } + + gtk_entry_set_text (GTK_ENTRY (self->priv->entry_server), + server ? server : ""); + gtk_entry_set_text (GTK_ENTRY (self->priv->entry_room), room ? room : ""); + + g_free (room); } static void -update_join_button_sensitivity (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_model_setup (EmpathyNewChatroomDialog *self) { - const gchar *room; - const gchar *protocol; - gboolean sensitive = FALSE; + GtkTreeView *view; + GtkListStore *store; + GtkTreeSelection *selection; + + /* View */ + view = GTK_TREE_VIEW (self->priv->treeview); + + g_signal_connect (view, "row-activated", + G_CALLBACK (new_chatroom_dialog_model_row_activated_cb), self); + + /* Store/Model */ + store = gtk_list_store_new (COL_COUNT, + G_TYPE_STRING, /* Invite */ + G_TYPE_STRING, /* Password */ + G_TYPE_STRING, /* Name */ + G_TYPE_STRING, /* Room */ + G_TYPE_STRING, /* Member count */ + G_TYPE_INT, /* Member count int */ + G_TYPE_STRING); /* Tool tip */ + + self->priv->model = GTK_TREE_MODEL (store); + gtk_tree_view_set_model (view, self->priv->model); + gtk_tree_view_set_tooltip_column (view, COL_TOOLTIP); + gtk_tree_view_set_search_column (view, COL_NAME); + + /* Selection */ + selection = gtk_tree_view_get_selection (view); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), + COL_NAME, GTK_SORT_ASCENDING); + + g_signal_connect (selection, "changed", + G_CALLBACK (new_chatroom_dialog_model_selection_changed), self); + + /* Columns */ + new_chatroom_dialog_model_add_columns (self); +} +static void +update_join_button_sensitivity (EmpathyNewChatroomDialog *self) +{ + const gchar *room; + const gchar *protocol; + gboolean sensitive = FALSE; - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - protocol = tp_account_get_protocol (dialog->account); - if (EMP_STR_EMPTY (room)) - goto out; + room = gtk_entry_get_text (GTK_ENTRY (self->priv->entry_room)); + protocol = tp_account_get_protocol (self->priv->account); + if (EMP_STR_EMPTY (room)) + goto out; - if (!tp_strdiff (protocol, "irc") && (!tp_strdiff (room, "#") || - !tp_strdiff (room, "&"))) - { - goto out; - } + if (!tp_strdiff (protocol, "irc") && + (!tp_strdiff (room, "#") || !tp_strdiff (room, "&"))) + goto out; - if (dialog->account == NULL) - goto out; + if (self->priv->account == NULL) + goto out; - if (tp_account_get_connection_status (dialog->account, NULL) != - TP_CONNECTION_STATUS_CONNECTED) - goto out; + if (tp_account_get_connection_status (self->priv->account, NULL) != + TP_CONNECTION_STATUS_CONNECTED) + goto out; - sensitive = TRUE; + sensitive = TRUE; out: - gtk_widget_set_sensitive (dialog->button_join, sensitive); + gtk_widget_set_sensitive (self->priv->button_join, sensitive); } static void -new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_update_widgets (EmpathyNewChatroomDialog *self) { - const gchar *protocol; - - if (dialog->account == NULL) - return; - - protocol = tp_account_get_protocol (dialog->account); - - gtk_entry_set_text (GTK_ENTRY (dialog->entry_server), ""); - - /* hardcode here known protocols */ - if (strcmp (protocol, "jabber") == 0) { - gtk_widget_set_sensitive (dialog->entry_server, TRUE); - } - else if (strcmp (protocol, "local-xmpp") == 0) { - gtk_widget_set_sensitive (dialog->entry_server, FALSE); - } - else if (strcmp (protocol, "irc") == 0) { - gtk_widget_set_sensitive (dialog->entry_server, FALSE); - } - else { - gtk_widget_set_sensitive (dialog->entry_server, TRUE); - } - - if (!tp_strdiff (protocol, "irc")) - gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), "#"); - else - gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), ""); - - update_join_button_sensitivity (dialog); - - /* Final set up of the dialog */ - gtk_widget_grab_focus (dialog->entry_room); - gtk_editable_set_position (GTK_EDITABLE (dialog->entry_room), -1); + const gchar *protocol; + + if (self->priv->account == NULL) + return; + + protocol = tp_account_get_protocol (self->priv->account); + + gtk_entry_set_text (GTK_ENTRY (self->priv->entry_server), ""); + + /* hardcode here known protocols */ + if (strcmp (protocol, "jabber") == 0) + gtk_widget_set_sensitive (self->priv->entry_server, TRUE); + else if (strcmp (protocol, "local-xmpp") == 0) + gtk_widget_set_sensitive (self->priv->entry_server, FALSE); + else if (strcmp (protocol, "irc") == 0) + gtk_widget_set_sensitive (self->priv->entry_server, FALSE); + else + gtk_widget_set_sensitive (self->priv->entry_server, TRUE); + + if (!tp_strdiff (protocol, "irc")) + gtk_entry_set_text (GTK_ENTRY (self->priv->entry_room), "#"); + else + gtk_entry_set_text (GTK_ENTRY (self->priv->entry_room), ""); + + update_join_button_sensitivity (self); + + /* Final set up of the dialog */ + gtk_widget_grab_focus (self->priv->entry_room); + gtk_editable_set_position (GTK_EDITABLE (self->priv->entry_room), -1); } static void account_status_changed_cb (TpAccount *account, - guint old_status, - guint new_status, - guint reason, - gchar *dbus_error_name, - GHashTable *details, - EmpathyNewChatroomDialog *self) + guint old_status, + guint new_status, + guint reason, + gchar *dbus_error_name, + GHashTable *details, + EmpathyNewChatroomDialog *self) { - update_join_button_sensitivity (self); + update_join_button_sensitivity (self); } static void -new_chatroom_dialog_select_last_account (GSettings *gsettings, - EmpathyAccountChooser *account_chooser) +new_chatroom_dialog_select_last_account (GSettings *gsettings, + EmpathyAccountChooser *account_chooser) { - const gchar *account_path; - TpAccountManager *manager; - TpSimpleClientFactory *factory; - TpAccount *account; - TpConnectionStatus status; - - account_path = g_settings_get_string (gsettings, EMPATHY_PREFS_CHAT_ROOM_LAST_ACCOUNT); - DEBUG ("Selecting account path '%s'", account_path); - - manager = tp_account_manager_dup (); - factory = tp_proxy_get_factory (manager); - account = tp_simple_client_factory_ensure_account (factory, - account_path, - NULL, - NULL); - - if (account != NULL) { - status = tp_account_get_connection_status (account, NULL); - if (status == TP_CONNECTION_STATUS_CONNECTED) { - empathy_account_chooser_set_account (account_chooser, - account); - } - g_object_unref (account); - } - g_object_unref (manager); + const gchar *account_path; + TpAccountManager *manager; + TpSimpleClientFactory *factory; + TpAccount *account; + TpConnectionStatus status; + + account_path = g_settings_get_string (gsettings, + EMPATHY_PREFS_CHAT_ROOM_LAST_ACCOUNT); + DEBUG ("Selecting account path '%s'", account_path); + + manager = tp_account_manager_dup (); + factory = tp_proxy_get_factory (manager); + account = tp_simple_client_factory_ensure_account (factory, account_path, + NULL, NULL); + + if (account != NULL) + { + status = tp_account_get_connection_status (account, NULL); + if (status == TP_CONNECTION_STATUS_CONNECTED) + empathy_account_chooser_set_account (account_chooser, account); + g_object_unref (account); + } + + g_object_unref (manager); } static void -new_chatroom_dialog_account_ready_cb (EmpathyAccountChooser *combobox, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_account_ready_cb (EmpathyAccountChooser *combobox, + EmpathyNewChatroomDialog *self) { - new_chatroom_dialog_select_last_account (dialog->gsettings, combobox); + new_chatroom_dialog_select_last_account (self->priv->gsettings, combobox); } static void -new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, - EmpathyNewChatroomDialog *dialog) +listing_failed_cb (TpRoomList *room_list, + GError *error, + EmpathyNewChatroomDialog *self) { - EmpathyAccountChooser *account_chooser; - gboolean listing = FALSE; - gboolean expanded = FALSE; - TpConnection *connection; - TpCapabilities *caps; - - if (dialog->room_list) { - g_object_unref (dialog->room_list); - dialog->room_list = NULL; - } - - gtk_spinner_stop (GTK_SPINNER (dialog->throbber)); - gtk_widget_hide (dialog->throbber); - new_chatroom_dialog_model_clear (dialog); - - if (dialog->account != NULL) { - g_signal_handler_disconnect (dialog->account, dialog->status_changed_id); - g_object_unref (dialog->account); - } - - account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); - dialog->account = empathy_account_chooser_dup_account (account_chooser); - connection = empathy_account_chooser_get_connection (account_chooser); - if (dialog->account == NULL) - goto out; - - dialog->status_changed_id = g_signal_connect (dialog->account, - "status-changed", G_CALLBACK (account_status_changed_cb), dialog); - - /* empathy_account_chooser_filter_supports_chatrooms ensures that the - * account has a connection and CAPABILITIES has been prepared. */ - g_assert (connection != NULL); - g_assert (tp_proxy_is_prepared (connection, - TP_CONNECTION_FEATURE_CAPABILITIES)); - caps = tp_connection_get_capabilities (connection); - - if (tp_capabilities_supports_room_list (caps, NULL)) { - /* Roomlist channels are supported */ - dialog->room_list = empathy_tp_roomlist_new (dialog->account); - } - else { - dialog->room_list = NULL; - } - - if (dialog->room_list) { - g_signal_connect (dialog->room_list, "destroy", - G_CALLBACK (new_chatroom_dialog_roomlist_destroy_cb), - dialog); - g_signal_connect (dialog->room_list, "new-room", - G_CALLBACK (new_chatroom_dialog_new_room_cb), - dialog); - g_signal_connect (dialog->room_list, "notify::is-listing", - G_CALLBACK (new_chatroom_dialog_listing_cb), - dialog); - g_signal_connect (dialog->room_list, "error::start", - G_CALLBACK (start_listing_error_cb), - dialog); - g_signal_connect (dialog->room_list, "error::stop", - G_CALLBACK (stop_listing_error_cb), - dialog); - - expanded = gtk_expander_get_expanded (GTK_EXPANDER (dialog->expander_browse)); - if (expanded) { - gtk_widget_hide (dialog->viewport_error); - gtk_widget_set_sensitive (dialog->treeview, TRUE); - new_chatroom_dialog_browse_start (dialog); - } - - listing = empathy_tp_roomlist_is_listing (dialog->room_list); - if (listing) { - gtk_spinner_start (GTK_SPINNER (dialog->throbber)); - gtk_widget_show (dialog->throbber); - } - } - - gtk_widget_set_sensitive (dialog->expander_browse, dialog->room_list != NULL); + gtk_label_set_text (GTK_LABEL (self->priv->label_error_message), + _("Failed to list rooms")); + gtk_widget_show_all (self->priv->viewport_error); + gtk_widget_set_sensitive (self->priv->treeview, FALSE); +} -out: - new_chatroom_dialog_update_widgets (dialog); +static void +new_chatroom_dialog_got_room_cb (TpRoomList *room_list, + TpRoomInfo *room, + EmpathyNewChatroomDialog *self) +{ + GtkListStore *store; + gchar *members; + gchar *tooltip; + const gchar *need_password; + const gchar *invite_only; + gchar *tmp; + + DEBUG ("New room listed: %s (%s)", tp_room_info_get_name (room), + tp_room_info_get_handle_name (room)); + + /* Add to model */ + store = GTK_LIST_STORE (self->priv->model); + members = g_strdup_printf ("%d", tp_room_info_get_members_count ( + room, NULL)); + tmp = g_strdup_printf ("<b>%s</b>", tp_room_info_get_name (room)); + + /* Translators: Room/Join's roomlist tooltip. Parameters are a channel name, + yes/no, yes/no and a number. */ + tooltip = g_strdup_printf ( + _("%s\nInvite required: %s\nPassword required: %s\nMembers: %s"), + tmp, + tp_room_info_get_invite_only (room, NULL) ? _("Yes") : _("No"), + tp_room_info_get_requires_password (room, NULL) ? _("Yes") : _("No"), + members); + g_free (tmp); + + invite_only = (tp_room_info_get_invite_only (room, NULL) ? + GTK_STOCK_INDEX : NULL); + need_password = (tp_room_info_get_requires_password (room, NULL) ? + GTK_STOCK_DIALOG_AUTHENTICATION : NULL); + + gtk_list_store_insert_with_values (store, NULL, -1, + COL_NEED_PASSWORD, need_password, + COL_INVITE_ONLY, invite_only, + COL_NAME, tp_room_info_get_name (room), + COL_ROOM, tp_room_info_get_handle_name (room), + COL_MEMBERS, members, + COL_MEMBERS_INT, tp_room_info_get_members_count (room, NULL), + COL_TOOLTIP, tooltip, + -1); + + g_free (members); + g_free (tooltip); } static void -new_chatroom_dialog_button_close_error_clicked_cb (GtkButton *button, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_listing_cb (TpRoomList *room_list, + GParamSpec *spec, + EmpathyNewChatroomDialog *self) { - gtk_widget_hide (dialog->viewport_error); + /* Update the throbber */ + if (tp_room_list_is_listing (room_list)) + { + gtk_spinner_start (GTK_SPINNER (self->priv->throbber)); + gtk_widget_show (self->priv->throbber); + } + else + { + gtk_spinner_stop (GTK_SPINNER (self->priv->throbber)); + gtk_widget_hide (self->priv->throbber); + } } static void -new_chatroom_dialog_roomlist_destroy_cb (EmpathyTpRoomlist *room_list, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *self) { - g_object_unref (dialog->room_list); - dialog->room_list = NULL; + GtkListStore *store; + + store = GTK_LIST_STORE (self->priv->model); + gtk_list_store_clear (store); } static void -new_chatroom_dialog_new_room_cb (EmpathyTpRoomlist *room_list, - EmpathyChatroom *chatroom, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *self) { - GtkListStore *store; - gchar *members; - gchar *tooltip; - const gchar *need_password; - const gchar *invite_only; - gchar *tmp; - - DEBUG ("New chatroom listed: %s (%s)", - empathy_chatroom_get_name (chatroom), - empathy_chatroom_get_room (chatroom)); - - /* Add to model */ - store = GTK_LIST_STORE (dialog->model); - members = g_strdup_printf ("%d", empathy_chatroom_get_members_count (chatroom)); - tmp = g_strdup_printf ("<b>%s</b>", empathy_chatroom_get_name (chatroom)); - /* Translators: Room/Join's roomlist tooltip. Parameters are a channel name, - yes/no, yes/no and a number. */ - tooltip = g_strdup_printf (_("%s\nInvite required: %s\nPassword required: %s\nMembers: %s"), - tmp, - empathy_chatroom_get_invite_only (chatroom) ? _("Yes") : _("No"), - empathy_chatroom_get_need_password (chatroom) ? _("Yes") : _("No"), - members); - g_free (tmp); - invite_only = (empathy_chatroom_get_invite_only (chatroom) ? - GTK_STOCK_INDEX : NULL); - need_password = (empathy_chatroom_get_need_password (chatroom) ? - GTK_STOCK_DIALOG_AUTHENTICATION : NULL); - - gtk_list_store_insert_with_values (store, NULL, -1, - COL_NEED_PASSWORD, need_password, - COL_INVITE_ONLY, invite_only, - COL_NAME, empathy_chatroom_get_name (chatroom), - COL_ROOM, empathy_chatroom_get_room (chatroom), - COL_MEMBERS, members, - COL_MEMBERS_INT, empathy_chatroom_get_members_count (chatroom), - COL_TOOLTIP, tooltip, - -1); - - g_free (members); - g_free (tooltip); + new_chatroom_dialog_model_clear (self); + + if (self->priv->room_list != NULL) + tp_room_list_start (self->priv->room_list); } static void -start_listing_error_cb (EmpathyTpRoomlist *room_list, - GError *error, - EmpathyNewChatroomDialog *dialog) +new_room_list_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) { - gtk_label_set_text (GTK_LABEL (dialog->label_error_message), _("Could not start room listing")); - gtk_widget_show_all (dialog->viewport_error); - gtk_widget_set_sensitive (dialog->treeview, FALSE); + EmpathyNewChatroomDialog *self = user_data; + GError *error = NULL; + + self->priv->room_list = tp_room_list_new_finish (result, &error); + if (self->priv->room_list == NULL) + { + DEBUG ("Failed to create TpRoomList: %s\n", error->message); + g_error_free (error); + return; + } + + g_signal_connect (self->priv->room_list, "got-room", + G_CALLBACK (new_chatroom_dialog_got_room_cb), self); + g_signal_connect (self->priv->room_list, "failed", + G_CALLBACK (listing_failed_cb), self); + g_signal_connect (self->priv->room_list, "notify::listing", + G_CALLBACK (new_chatroom_dialog_listing_cb), self); + + if (gtk_expander_get_expanded (GTK_EXPANDER (self->priv->expander_browse))) + { + gtk_widget_hide (self->priv->viewport_error); + gtk_widget_set_sensitive (self->priv->treeview, TRUE); + new_chatroom_dialog_browse_start (self); + } + + if (tp_room_list_is_listing (self->priv->room_list)) + { + gtk_spinner_start (GTK_SPINNER (self->priv->throbber)); + gtk_widget_show (self->priv->throbber); + } + + gtk_widget_set_sensitive (self->priv->expander_browse, TRUE); + + new_chatroom_dialog_update_widgets (self); + } static void -stop_listing_error_cb (EmpathyTpRoomlist *room_list, - GError *error, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_account_changed_cb (GtkComboBox *combobox, + EmpathyNewChatroomDialog *self) { - gtk_label_set_text (GTK_LABEL (dialog->label_error_message), _("Could not stop room listing")); - gtk_widget_show_all (dialog->viewport_error); - gtk_widget_set_sensitive (dialog->treeview, FALSE); + EmpathyAccountChooser *account_chooser; + TpConnection *connection; + TpCapabilities *caps; + + g_clear_object (&self->priv->room_list); + + gtk_spinner_stop (GTK_SPINNER (self->priv->throbber)); + gtk_widget_hide (self->priv->throbber); + new_chatroom_dialog_model_clear (self); + + if (self->priv->account != NULL) + { + g_signal_handler_disconnect (self->priv->account, + self->priv->status_changed_id); + g_object_unref (self->priv->account); + } + + account_chooser = EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser); + self->priv->account = empathy_account_chooser_dup_account (account_chooser); + connection = empathy_account_chooser_get_connection (account_chooser); + if (self->priv->account == NULL) + goto out; + + self->priv->status_changed_id = g_signal_connect (self->priv->account, + "status-changed", G_CALLBACK (account_status_changed_cb), self); + + /* empathy_account_chooser_filter_supports_chatrooms ensures that the + * account has a connection and CAPABILITIES has been prepared. */ + g_assert (connection != NULL); + g_assert (tp_proxy_is_prepared (connection, + TP_CONNECTION_FEATURE_CAPABILITIES)); + caps = tp_connection_get_capabilities (connection); + + if (tp_capabilities_supports_room_list (caps, NULL)) + { + /* Roomlist channels are supported */ + tp_room_list_new_async (self->priv->account, NULL, new_room_list_cb, + self); + } + + gtk_widget_set_sensitive (self->priv->expander_browse, FALSE); + +out: + new_chatroom_dialog_update_widgets (self); } static void -new_chatroom_dialog_listing_cb (EmpathyTpRoomlist *room_list, - gpointer unused, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_button_close_error_clicked_cb (GtkButton *button, + EmpathyNewChatroomDialog *self) { - gboolean listing; - - listing = empathy_tp_roomlist_is_listing (room_list); - - /* Update the throbber */ - if (listing) { - gtk_spinner_start (GTK_SPINNER (dialog->throbber)); - gtk_widget_show (dialog->throbber); - } else { - gtk_spinner_stop (GTK_SPINNER (dialog->throbber)); - gtk_widget_hide (dialog->throbber); - } + gtk_widget_hide (self->priv->viewport_error); } static void -new_chatroom_dialog_model_clear (EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, + EmpathyNewChatroomDialog *self) { - GtkListStore *store; + if (entry == self->priv->entry_room) + { + update_join_button_sensitivity (self); - store = GTK_LIST_STORE (dialog->model); - gtk_list_store_clear (store); + /* FIXME: Select the room in the list */ + } } static void -new_chatroom_dialog_model_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget, + EmpathyNewChatroomDialog *self) { - gtk_widget_activate (dialog->button_join); + new_chatroom_dialog_browse_start (self); } static void -new_chatroom_dialog_model_selection_changed (GtkTreeSelection *selection, - EmpathyNewChatroomDialog *dialog) +new_chatroom_dialog_expander_browse_activate_cb (GtkWidget *widget, + EmpathyNewChatroomDialog *self) { - GtkTreeModel *model; - GtkTreeIter iter; - gchar *room = NULL; - gchar *server = NULL; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { - return; - } - - gtk_tree_model_get (model, &iter, COL_ROOM, &room, -1); - server = strstr (room, "@"); - if (server) { - *server = '\0'; - server++; - } - - gtk_entry_set_text (GTK_ENTRY (dialog->entry_server), server ? server : ""); - gtk_entry_set_text (GTK_ENTRY (dialog->entry_room), room ? room : ""); - - g_free (room); + gboolean expanded; + + expanded = gtk_expander_get_expanded (GTK_EXPANDER (widget)); + if (expanded) + { + gtk_window_set_resizable (GTK_WINDOW (self), FALSE); + } + else + { + gtk_widget_hide (self->priv->viewport_error); + gtk_widget_set_sensitive (self->priv->treeview, TRUE); + new_chatroom_dialog_browse_start (self); + gtk_window_set_resizable (GTK_WINDOW (self), TRUE); + } } -static void -new_chatroom_dialog_join (EmpathyNewChatroomDialog *dialog) +static gboolean +new_chatroom_dialog_entry_server_focus_out_cb (GtkWidget *widget, + GdkEventFocus *event, + EmpathyNewChatroomDialog *self) { - EmpathyAccountChooser *account_chooser; - TpAccount *account; - const gchar *room; - const gchar *server = NULL; - gchar *room_name = NULL; + gboolean expanded; - room = gtk_entry_get_text (GTK_ENTRY (dialog->entry_room)); - server = gtk_entry_get_text (GTK_ENTRY (dialog->entry_server)); + expanded = gtk_expander_get_expanded ( + GTK_EXPANDER (self->priv->expander_browse)); + if (expanded) + new_chatroom_dialog_browse_start (self); - account_chooser = EMPATHY_ACCOUNT_CHOOSER (dialog->account_chooser); - account = empathy_account_chooser_get_account (account_chooser); + return FALSE; +} - if (!EMP_STR_EMPTY (server)) { - room_name = g_strconcat (room, "@", server, NULL); - } else { - room_name = g_strdup (room); - } +static GObject * +empathy_new_chatroom_dialog_constructor (GType type, + guint n_props, + GObjectConstructParam *props) +{ + GObject *retval; + + if (dialog_p) + { + retval = G_OBJECT (dialog_p); + g_object_ref (retval); + } + else + { + retval = G_OBJECT_CLASS ( + empathy_new_chatroom_dialog_parent_class)->constructor (type, + n_props, props); + + dialog_p = EMPATHY_NEW_CHATROOM_DIALOG (retval); + g_object_add_weak_pointer (retval, (gpointer) &dialog_p); + } + + return retval; +} - g_strstrip (room_name); +GtkWidget * +empathy_new_chatroom_dialog_show (GtkWindow *parent) +{ + GtkWidget *dialog; - DEBUG ("Requesting channel for '%s'", room_name); + dialog = g_object_new (EMPATHY_TYPE_NEW_CHATROOM_DIALOG, NULL); - empathy_join_muc (account, room_name, empathy_get_current_action_time ()); + if (parent != NULL) + { + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (parent)); + } - g_free (room_name); + gtk_window_present (GTK_WINDOW (dialog)); + return dialog; } static void -new_chatroom_dialog_entry_changed_cb (GtkWidget *entry, - EmpathyNewChatroomDialog *dialog) +empathy_new_chatroom_dialog_dispose (GObject *object) { - if (entry == dialog->entry_room) { - update_join_button_sensitivity (dialog); + EmpathyNewChatroomDialog *self = EMPATHY_NEW_CHATROOM_DIALOG (object); + void (*chain_up) (GObject *) = + ((GObjectClass *) empathy_new_chatroom_dialog_parent_class)->dispose; - /* FIXME: Select the room in the list */ - } -} + g_clear_object (&self->priv->room_list); + g_clear_object (&self->priv->model); -static void -new_chatroom_dialog_browse_start (EmpathyNewChatroomDialog *dialog) -{ - new_chatroom_dialog_model_clear (dialog); - if (dialog->room_list) { - empathy_tp_roomlist_start (dialog->room_list); - } -} + if (self->priv->account != NULL) + { + g_signal_handler_disconnect (self->priv->account, + self->priv->status_changed_id); + g_clear_object (&self->priv->account); + } -static void -new_chatroom_dialog_browse_stop (EmpathyNewChatroomDialog *dialog) -{ - if (dialog->room_list) { - empathy_tp_roomlist_stop (dialog->room_list); - } -} + g_clear_object (&self->priv->gsettings); -static void -new_chatroom_dialog_entry_server_activate_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog) -{ - new_chatroom_dialog_browse_start (dialog); + if (chain_up != NULL) + chain_up (object); } static void -new_chatroom_dialog_expander_browse_activate_cb (GtkWidget *widget, - EmpathyNewChatroomDialog *dialog) +empathy_new_chatroom_dialog_class_init (EmpathyNewChatroomDialogClass *klass) { - gboolean expanded; - - expanded = gtk_expander_get_expanded (GTK_EXPANDER (widget)); - if (expanded) { - new_chatroom_dialog_browse_stop (dialog); - gtk_window_set_resizable (GTK_WINDOW (dialog->window), FALSE); - } else { - gtk_widget_hide (dialog->viewport_error); - gtk_widget_set_sensitive (dialog->treeview, TRUE); - new_chatroom_dialog_browse_start (dialog); - gtk_window_set_resizable (GTK_WINDOW (dialog->window), TRUE); - } + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass); + + oclass->constructor = empathy_new_chatroom_dialog_constructor; + oclass->dispose = empathy_new_chatroom_dialog_dispose; + + dialog_class->response = empathy_new_chatroom_dialog_response; + + g_type_class_add_private (klass, sizeof (EmpathyNewChatroomDialogPriv)); } -static gboolean -new_chatroom_dialog_entry_server_focus_out_cb (GtkWidget *widget, - GdkEventFocus *event, - EmpathyNewChatroomDialog *dialog) +static void +empathy_new_chatroom_dialog_init (EmpathyNewChatroomDialog *self) { - gboolean expanded; - - expanded = gtk_expander_get_expanded (GTK_EXPANDER (dialog->expander_browse)); - if (expanded) { - new_chatroom_dialog_browse_start (dialog); - } - return FALSE; + GtkBuilder *gui; + GtkSizeGroup *size_group; + gchar *filename; + GtkWidget *vbox, *content; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_NEW_CHATROOM_DIALOG, EmpathyNewChatroomDialogPriv); + + filename = empathy_file_lookup ("empathy-new-chatroom-dialog.ui", "src"); + gui = empathy_builder_get_file (filename, + "vbox_new_chatroom", &vbox, + "table_grid", &self->priv->table_grid, + "label_account", &self->priv->label_account, + "label_server", &self->priv->label_server, + "label_room", &self->priv->label_room, + "entry_server", &self->priv->entry_server, + "entry_room", &self->priv->entry_room, + "treeview", &self->priv->treeview, + "expander_browse", &self->priv->expander_browse, + "hbox_expander", &self->priv->hbox_expander, + "label_error_message", &self->priv->label_error_message, + "viewport_error", &self->priv->viewport_error, + NULL); + g_free (filename); + + empathy_builder_connect (gui, self, + "entry_server", "changed", new_chatroom_dialog_entry_changed_cb, + "entry_server", "activate", new_chatroom_dialog_entry_server_activate_cb, + "entry_server", "focus-out-event", + new_chatroom_dialog_entry_server_focus_out_cb, + "entry_room", "changed", new_chatroom_dialog_entry_changed_cb, + "expander_browse", "activate", + new_chatroom_dialog_expander_browse_activate_cb, + "button_close_error", "clicked", + new_chatroom_dialog_button_close_error_clicked_cb, + NULL); + + /* Create dialog */ + content = gtk_dialog_get_content_area (GTK_DIALOG (self)); + gtk_container_add (GTK_CONTAINER (content), vbox); + + gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + self->priv->button_join = gtk_dialog_add_button (GTK_DIALOG (self), + _("Join"), GTK_RESPONSE_OK); + + gtk_window_set_title (GTK_WINDOW (self), _("Join Room")); + gtk_window_set_role (GTK_WINDOW (self), "join_new_chatroom"); + + g_object_unref (gui); + + /* Label alignment */ + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + gtk_size_group_add_widget (size_group, self->priv->label_account); + gtk_size_group_add_widget (size_group, self->priv->label_server); + gtk_size_group_add_widget (size_group, self->priv->label_room); + + g_object_unref (size_group); + + /* Set up chatrooms treeview */ + new_chatroom_dialog_model_setup (self); + + /* Add throbber */ + self->priv->throbber = gtk_spinner_new (); + gtk_box_pack_start (GTK_BOX (self->priv->hbox_expander), self->priv->throbber, + TRUE, TRUE, 0); + + self->priv->gsettings = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA); + + /* Account chooser for custom */ + self->priv->account_chooser = empathy_account_chooser_new (); + empathy_account_chooser_set_filter ( + EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser), + empathy_account_chooser_filter_supports_chatrooms, NULL); + gtk_grid_attach (GTK_GRID (self->priv->table_grid), + self->priv->account_chooser, 1, 0, 1, 1); + gtk_widget_show (self->priv->account_chooser); + + g_signal_connect (EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser), + "ready", G_CALLBACK (new_chatroom_dialog_account_ready_cb), self); + g_signal_connect (GTK_COMBO_BOX (self->priv->account_chooser), "changed", + G_CALLBACK (new_chatroom_dialog_account_changed_cb), self); + new_chatroom_dialog_account_changed_cb ( + GTK_COMBO_BOX (self->priv->account_chooser), self); } diff --git a/src/empathy-new-chatroom-dialog.h b/src/empathy-new-chatroom-dialog.h index b1cef0daa..02bf3b2a0 100644 --- a/src/empathy-new-chatroom-dialog.h +++ b/src/empathy-new-chatroom-dialog.h @@ -1,7 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2006-2007 Imendio AB - * Copyright (C) 2007-2008 Collabora Ltd. + * Copyright (C) 2007-2011 Collabora Ltd. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,13 +21,56 @@ * Xavier Claessens <xclaesse@gmail.com> */ -#ifndef __EMPATHY_NEW_CHATROOMS_WINDOW_H__ -#define __EMPATHY_NEW_CHATROOMS_WINDOW_H__ +#ifndef __EMPATHY_NEW_CHATROOM_DIALOG_H__ +#define __EMPATHY_NEW_CHATROOM_DIALOG_H__ + +#include <glib-object.h> G_BEGIN_DECLS -void empathy_new_chatroom_dialog_show (GtkWindow *parent); +typedef struct _EmpathyNewChatroomDialog EmpathyNewChatroomDialog; +typedef struct _EmpathyNewChatroomDialogClass EmpathyNewChatroomDialogClass; +typedef struct _EmpathyNewChatroomDialogPriv EmpathyNewChatroomDialogPriv; + +struct _EmpathyNewChatroomDialogClass +{ + /*<private>*/ + GtkDialogClass parent_class; +}; + +struct _EmpathyNewChatroomDialog +{ + /*<private>*/ + GtkDialog parent; + EmpathyNewChatroomDialogPriv *priv; +}; + +GType empathy_new_chatroom_dialog_get_type (void); + +/* TYPE MACROS */ +#define EMPATHY_TYPE_NEW_CHATROOM_DIALOG \ + (empathy_new_chatroom_dialog_get_type ()) +#define EMPATHY_NEW_CHATROOM_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), \ + EMPATHY_TYPE_NEW_CHATROOM_DIALOG, \ + EmpathyNewChatroomDialog)) +#define EMPATHY_NEW_CHATROOM_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), \ + EMPATHY_TYPE_NEW_CHATROOM_DIALOG, \ + EmpathyNewChatroomDialogClass)) +#define EMPATHY_IS_NEW_CHATROOM_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), \ + EMPATHY_TYPE_NEW_CHATROOM_DIALOG)) +#define EMPATHY_IS_NEW_CHATROOM_DIALOG_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), \ + EMPATHY_TYPE_NEW_CHATROOM_DIALOG)) +#define EMPATHY_NEW_CHATROOM_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + EMPATHY_TYPE_NEW_CHATROOM_DIALOG, \ + EmpathyNewChatroomDialogClass)) + +GtkWidget * empathy_new_chatroom_dialog_show (GtkWindow *parent); G_END_DECLS -#endif /* __EMPATHY_NEW_CHATROOMS_WINDOW_H__ */ +#endif /* #ifndef __EMPATHY_NEW_CHATROOM_DIALOG_H__*/ diff --git a/src/empathy-new-chatroom-dialog.ui b/src/empathy-new-chatroom-dialog.ui index e77ec60cd..ee2d74bdf 100644 --- a/src/empathy-new-chatroom-dialog.ui +++ b/src/empathy-new-chatroom-dialog.ui @@ -1,259 +1,141 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> <!-- interface-requires gtk+ 3.0 --> - <object class="GtkImage" id="join_image"> - <property name="can_focus">False</property> - <property name="stock">gtk-jump-to</property> - </object> - <object class="GtkDialog" id="new_chatroom_dialog"> + <object class="GtkVBox" id="vbox_new_chatroom"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="border_width">5</property> - <property name="title" translatable="yes">Join Room</property> - <property name="role">join_new_chatroom</property> - <property name="default_width">350</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox4"> + <property name="spacing">5</property> + <child> + <object class="GtkGrid" id="table_grid"> <property name="visible">True</property> <property name="can_focus">False</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area4"> + <property name="row_spacing">5</property> + <property name="column_spacing">5</property> + <child> + <object class="GtkEntry" id="entry_room"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup" translatable="yes">Enter the room name to join here or click on one or more rooms in the list.</property> + <property name="tooltip_text" translatable="yes">Enter the room name to join here or click on one or more rooms in the list.</property> + <property name="activates_default">True</property> + <property name="width_chars">25</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_room"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="button_cancel"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_action_appearance">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button_join"> - <property name="label" translatable="yes">_Join</property> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="receives_default">False</property> - <property name="use_action_appearance">False</property> - <property name="image">join_image</property> - <property name="use_underline">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Room:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_room</property> </object> <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">end</property> - <property name="position">0</property> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + <property name="width">1</property> + <property name="height">1</property> </packing> </child> <child> - <object class="GtkVBox" id="vbox_widgets"> + <object class="GtkEntry" id="entry_server"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_tooltip">True</property> + <property name="tooltip_markup" translatable="yes">Enter the server which hosts the room, or leave it empty if the room is on the current account&apos;s server</property> + <property name="tooltip_text" translatable="yes">Enter the server which hosts the room, or leave it empty if the room is on the current account's server</property> + <property name="width_chars">25</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_server"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="border_width">5</property> - <property name="spacing">5</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Server:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_server</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_account"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Account:</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + <property name="width">1</property> + <property name="height">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkExpander" id="expander_browse"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> <child> - <object class="GtkGrid" id="table_grid"> - <property name="visible">True</property> + <object class="GtkViewport" id="viewport_error"> <property name="can_focus">False</property> - <property name="row_spacing">5</property> - <property name="column_spacing">5</property> - <child> - <object class="GtkEntry" id="entry_room"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip_text" translatable="yes">Enter the room name to join here or click on one or more rooms in the list.</property> - <property name="activates_default">True</property> - <property name="width_chars">25</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_room"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Room:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_room</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="entry_server"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="tooltip_text" translatable="yes">Enter the server which hosts the room, or leave it empty if the room is on the current account's server</property> - <property name="width_chars">25</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_server"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">_Server:</property> - <property name="use_underline">True</property> - <property name="mnemonic_widget">entry_server</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_account"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Account:</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - <property name="width">1</property> - <property name="height">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkExpander" id="expander_browse"> - <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="resize_mode">queue</property> <child> - <object class="GtkVBox" id="vbox1"> + <object class="GtkHBox" id="hbox1"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="spacing">2</property> <child> - <object class="GtkViewport" id="viewport_error"> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> <property name="can_focus">False</property> - <property name="resize_mode">queue</property> - <child> - <object class="GtkHBox" id="hbox1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkImage" id="image1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-dialog-error</property> - <property name="icon-size">1</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="padding">5</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label_error_message"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="xpad">10</property> - <property name="label" translatable="yes">Couldn't load room list</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkButton" id="button_close_error"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="use_action_appearance">False</property> - <property name="relief">none</property> - <child> - <object class="GtkImage" id="image2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-close</property> - <property name="icon-size">1</property> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - </object> - </child> + <property name="stock">gtk-dialog-error</property> + <property name="icon-size">1</property> </object> <packing> <property name="expand">False</property> <property name="fill">False</property> + <property name="padding">5</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkScrolledWindow" id="scrolledwindow2"> - <property name="width_request">350</property> - <property name="height_request">150</property> + <object class="GtkLabel" id="label_error_message"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">never</property> - <property name="shadow_type">in</property> - <child> - <object class="GtkTreeView" id="treeview"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="search_column">0</property> - <property name="show_expanders">False</property> - <child internal-child="selection"> - <object class="GtkTreeSelection" id="treeview-selection1"/> - </child> - </object> - </child> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="xpad">10</property> + <property name="label" translatable="yes">Couldn't load room list</property> </object> <packing> <property name="expand">True</property> @@ -261,27 +143,53 @@ <property name="position">1</property> </packing> </child> - </object> - </child> - <child type="label"> - <object class="GtkHBox" id="hbox_expander"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="spacing">6</property> <child> - <object class="GtkLabel" id="label1"> + <object class="GtkButton" id="button_close_error"> <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes">Room List</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="relief">none</property> + <child> + <object class="GtkImage" id="image2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="stock">gtk-close</property> + <property name="icon-size">1</property> + </object> + </child> </object> <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> </packing> </child> - <child> - <placeholder/> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="width_request">350</property> + <property name="height_request">150</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="search_column">0</property> + <property name="show_expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection"/> </child> </object> </child> @@ -293,17 +201,35 @@ </packing> </child> </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> + </child> + <child type="label"> + <object class="GtkHBox" id="hbox_expander"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Room List</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> </child> </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> </child> - <action-widgets> - <action-widget response="-7">button_cancel</action-widget> - <action-widget response="-5">button_join</action-widget> - </action-widgets> </object> </interface> diff --git a/src/empathy-notifications-approver.c b/src/empathy-notifications-approver.c index 92b3f7475..b6abd8c6b 100644 --- a/src/empathy-notifications-approver.c +++ b/src/empathy-notifications-approver.c @@ -25,8 +25,6 @@ #include <libnotify/notify.h> #include <telepathy-glib/telepathy-glib.h> -#include <libempathy/empathy-tp-streamed-media.h> - #include <libempathy-gtk/empathy-notify-manager.h> #include <libempathy-gtk/empathy-call-utils.h> @@ -191,12 +189,7 @@ add_notification_actions (EmpathyNotificationsApprover *self, self, NULL); break; - case EMPATHY_EVENT_TYPE_VOIP: case EMPATHY_EVENT_TYPE_CALL: - if (self->priv->event->type == EMPATHY_EVENT_TYPE_VOIP) - video = empathy_tp_streamed_media_has_initial_video ( - EMPATHY_TP_STREAMED_MEDIA (self->priv->event->handler_instance)); - else video = tp_call_channel_has_initial_video ( TP_CALL_CHANNEL (self->priv->event->handler_instance), NULL); @@ -261,7 +254,6 @@ notification_is_urgent (EmpathyNotificationsApprover *self, * interact ASAP */ switch (self->priv->event->type) { case EMPATHY_EVENT_TYPE_CHAT: - case EMPATHY_EVENT_TYPE_VOIP: case EMPATHY_EVENT_TYPE_CALL: case EMPATHY_EVENT_TYPE_TRANSFER: case EMPATHY_EVENT_TYPE_INVITATION: @@ -288,7 +280,6 @@ get_category_for_event_type (EmpathyEventType type) CASE(CHAT) CASE(PRESENCE_ONLINE) CASE(PRESENCE_OFFLINE) - CASE(VOIP) CASE(CALL) CASE(TRANSFER) CASE(INVITATION) diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c index 14f178072..c72c6ae61 100644 --- a/src/empathy-preferences.c +++ b/src/empathy-preferences.c @@ -65,33 +65,11 @@ static const gchar * empathy_preferences_tabs[] = struct _EmpathyPreferencesPriv { GtkWidget *notebook; - GtkWidget *checkbutton_show_smileys; - GtkWidget *checkbutton_show_contacts_in_rooms; - GtkWidget *radiobutton_chats_new_windows; GtkWidget *checkbutton_events_notif_area; - GtkWidget *checkbutton_autoconnect; - GtkWidget *checkbutton_logging; - GtkWidget *checkbutton_sounds_enabled; - GtkWidget *checkbutton_sounds_disabled_away; GtkWidget *treeview_sounds; - - GtkWidget *checkbutton_notifications_enabled; - GtkWidget *checkbutton_notifications_disabled_away; - GtkWidget *checkbutton_notifications_focus; - GtkWidget *checkbutton_notifications_contact_signin; - GtkWidget *checkbutton_notifications_contact_signout; - - GtkWidget *echo_cancellation; - GtkWidget *treeview_spell_checker; - GtkWidget *checkbutton_location_publish; - GtkWidget *checkbutton_location_reduce_accuracy; - GtkWidget *checkbutton_location_resource_network; - GtkWidget *checkbutton_location_resource_cell; - GtkWidget *checkbutton_location_resource_gps; - GtkWidget *vbox_chat_theme; GtkWidget *combobox_chat_theme; GtkWidget *combobox_chat_theme_variant; @@ -108,9 +86,11 @@ struct _EmpathyPreferencesPriv { GSettings *gsettings_sound; GSettings *gsettings_ui; GSettings *gsettings_logger; + GSettings *gsettings_contacts; }; -static void preferences_setup_widgets (EmpathyPreferences *preferences); +static void preferences_setup_widgets (EmpathyPreferences *preferences, + GtkBuilder *gui); static void preferences_languages_setup (EmpathyPreferences *preferences); static void preferences_languages_add (EmpathyPreferences *preferences); static void preferences_languages_save (EmpathyPreferences *preferences); @@ -172,170 +152,144 @@ static SoundEventEntry sound_entries [] = { { N_("Account disconnected"), EMPATHY_PREFS_SOUNDS_SERVICE_LOGOUT } }; -static void -preferences_setup_widgets (EmpathyPreferences *preferences) +static gboolean +sort_criterium_get_mapping (GValue *value, + GVariant *variant, + gpointer user_data) { - EmpathyPreferencesPriv *priv = GET_PRIV (preferences); - - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - priv->checkbutton_notifications_enabled, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_DISABLED_AWAY, - priv->checkbutton_notifications_disabled_away, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_FOCUS, - priv->checkbutton_notifications_focus, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNIN, - priv->checkbutton_notifications_contact_signin, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_CONTACT_SIGNOUT, - priv->checkbutton_notifications_contact_signout, - "active", - G_SETTINGS_BIND_DEFAULT); + const char *s = g_variant_get_string (variant, NULL); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - priv->checkbutton_notifications_disabled_away, - "sensitive", - G_SETTINGS_BIND_GET); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - priv->checkbutton_notifications_focus, - "sensitive", - G_SETTINGS_BIND_GET); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - priv->checkbutton_notifications_contact_signin, - "sensitive", - G_SETTINGS_BIND_GET); - g_settings_bind (priv->gsettings_notify, - EMPATHY_PREFS_NOTIFICATIONS_ENABLED, - priv->checkbutton_notifications_contact_signout, - "sensitive", - G_SETTINGS_BIND_GET); - - g_settings_bind (priv->gsettings_sound, - EMPATHY_PREFS_SOUNDS_ENABLED, - priv->checkbutton_sounds_enabled, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_sound, - EMPATHY_PREFS_SOUNDS_DISABLED_AWAY, - priv->checkbutton_sounds_disabled_away, - "active", - G_SETTINGS_BIND_DEFAULT); + if (!tp_strdiff (s, "state")) + g_value_set_boolean (value, TRUE); + else if (!tp_strdiff (s, "name")) + g_value_set_boolean (value, FALSE); + else + return FALSE; - g_settings_bind (priv->gsettings_sound, - EMPATHY_PREFS_SOUNDS_ENABLED, - priv->checkbutton_sounds_disabled_away, - "sensitive", - G_SETTINGS_BIND_GET); - g_settings_bind (priv->gsettings_sound, - EMPATHY_PREFS_SOUNDS_ENABLED, - priv->treeview_sounds, - "sensitive", - G_SETTINGS_BIND_GET); + return TRUE; +} - g_settings_bind (priv->gsettings_ui, - EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, - priv->radiobutton_chats_new_windows, - "active", - G_SETTINGS_BIND_DEFAULT); +static GVariant * +sort_criterium_set_mapping (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) +{ + gboolean b = g_value_get_boolean (value); - g_settings_bind (priv->gsettings_ui, - EMPATHY_PREFS_UI_EVENTS_NOTIFY_AREA, - priv->checkbutton_events_notif_area, - "active", - G_SETTINGS_BIND_DEFAULT); + if (b) + return g_variant_new_string ("state"); + else + return g_variant_new_string ("name"); +} - g_settings_bind (priv->gsettings_chat, - EMPATHY_PREFS_CHAT_SHOW_SMILEYS, - priv->checkbutton_show_smileys, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_chat, - EMPATHY_PREFS_CHAT_SHOW_CONTACTS_IN_ROOMS, - priv->checkbutton_show_contacts_in_rooms, - "active", +static void +preferences_setup_widgets (EmpathyPreferences *preferences, + GtkBuilder *gui) +{ + EmpathyPreferencesPriv *priv = GET_PRIV (preferences); +#define BIND_ACTIVE(schema, key, widget) \ + g_settings_bind (priv->gsettings_##schema, EMPATHY_PREFS_##key, \ + gtk_builder_get_object (gui, widget), "active", \ G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_call, - EMPATHY_PREFS_CALL_ECHO_CANCELLATION, - priv->echo_cancellation, - "active", - G_SETTINGS_BIND_DEFAULT); + BIND_ACTIVE (notify, NOTIFICATIONS_ENABLED, + "checkbutton_notifications_enabled"); + BIND_ACTIVE (notify, NOTIFICATIONS_DISABLED_AWAY, + "checkbutton_notifications_disabled_away"); + BIND_ACTIVE (notify, NOTIFICATIONS_FOCUS, + "checkbutton_notifications_focus"); + BIND_ACTIVE (notify, NOTIFICATIONS_CONTACT_SIGNIN, + "checkbutton_notifications_contact_signin"); + BIND_ACTIVE (notify, NOTIFICATIONS_CONTACT_SIGNOUT, + "checkbutton_notifications_contact_signout"); + + BIND_ACTIVE (sound, SOUNDS_ENABLED, + "checkbutton_sounds_enabled"); + BIND_ACTIVE (sound, SOUNDS_DISABLED_AWAY, + "checkbutton_sounds_disabled_away"); + + BIND_ACTIVE (ui, UI_SHOW_OFFLINE, + "checkbutton_show_offline"); + BIND_ACTIVE (ui, UI_SHOW_PROTOCOLS, + "checkbutton_show_protocols"); + BIND_ACTIVE (ui, UI_SEPARATE_CHAT_WINDOWS, + "radiobutton_chats_new_windows"); + BIND_ACTIVE (ui, UI_EVENTS_NOTIFY_AREA, + "checkbutton_events_notif_area"); + BIND_ACTIVE (ui, UI_SHOW_BALANCES, + "checkbutton_show_balances"); + + BIND_ACTIVE (chat, CHAT_SHOW_SMILEYS, + "checkbutton_show_smileys"); + BIND_ACTIVE (chat, CHAT_SHOW_CONTACTS_IN_ROOMS, + "checkbutton_show_contacts_in_rooms"); + + BIND_ACTIVE (call, CALL_ECHO_CANCELLATION, + "call_echo_cancellation"); + + BIND_ACTIVE (loc, LOCATION_PUBLISH, + "checkbutton_location_publish"); + BIND_ACTIVE (loc, LOCATION_RESOURCE_NETWORK, + "checkbutton_location_resource_network"); + BIND_ACTIVE (loc, LOCATION_RESOURCE_CELL, + "checkbutton_location_resource_cell"); + BIND_ACTIVE (loc, LOCATION_RESOURCE_GPS, + "checkbutton_location_resource_gps"); + BIND_ACTIVE (loc, LOCATION_REDUCE_ACCURACY, + "checkbutton_location_reduce_accuracy"); + + BIND_ACTIVE (logger, LOGGER_ENABLED, + "checkbutton_logging"); + +#undef BIND_ACTIVE + +#define BIND_SENSITIVE(schema, key, widget) \ + g_settings_bind (priv->gsettings_##schema, EMPATHY_PREFS_##key, \ + gtk_builder_get_object (gui, widget), "sensitive", \ + G_SETTINGS_BIND_GET); + /* N.B. BIND_SENSITIVE() is in addition to the sensitivity setting of + * BIND_ACTIVE() */ + BIND_SENSITIVE (notify, NOTIFICATIONS_ENABLED, + "checkbutton_notifications_disabled_away"); + BIND_SENSITIVE (notify, NOTIFICATIONS_ENABLED, + "checkbutton_notifications_focus"); + BIND_SENSITIVE (notify, NOTIFICATIONS_ENABLED, + "checkbutton_notifications_contact_signin"); + BIND_SENSITIVE (notify, NOTIFICATIONS_ENABLED, + "checkbutton_notifications_contact_signout"); + + BIND_SENSITIVE (sound, SOUNDS_ENABLED, + "checkbutton_sounds_disabled_away"); + BIND_SENSITIVE (sound, SOUNDS_ENABLED, + "treeview_sounds"); + + BIND_SENSITIVE (loc, LOCATION_PUBLISH, + "checkbutton_location_resource_network"); + BIND_SENSITIVE (loc, LOCATION_PUBLISH, + "checkbutton_location_resource_cell"); + BIND_SENSITIVE (loc, LOCATION_PUBLISH, + "checkbutton_location_resource_gps"); + BIND_SENSITIVE (loc, LOCATION_PUBLISH, + "checkbutton_location_reduce_accuracy"); + +#undef BIND_SENSITIVE g_settings_bind (priv->gsettings, EMPATHY_PREFS_AUTOCONNECT, - priv->checkbutton_autoconnect, - "active", - G_SETTINGS_BIND_DEFAULT); - - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_PUBLISH, - priv->checkbutton_location_publish, + gtk_builder_get_object (gui, + "checkbutton_autoconnect"), "active", G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_RESOURCE_NETWORK, - priv->checkbutton_location_resource_network, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_PUBLISH, - priv->checkbutton_location_resource_network, - "sensitive", - G_SETTINGS_BIND_GET); - - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_RESOURCE_CELL, - priv->checkbutton_location_resource_cell, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_PUBLISH, - priv->checkbutton_location_resource_cell, - "sensitive", - G_SETTINGS_BIND_GET); - - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_RESOURCE_GPS, - priv->checkbutton_location_resource_gps, - "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_PUBLISH, - priv->checkbutton_location_resource_gps, - "sensitive", - G_SETTINGS_BIND_GET); - - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY, - priv->checkbutton_location_reduce_accuracy, + g_settings_bind_with_mapping (priv->gsettings_contacts, + EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, + gtk_builder_get_object (gui, + "radiobutton_sort_by_status"), "active", - G_SETTINGS_BIND_DEFAULT); - g_settings_bind (priv->gsettings_loc, - EMPATHY_PREFS_LOCATION_PUBLISH, - priv->checkbutton_location_reduce_accuracy, - "sensitive", - G_SETTINGS_BIND_GET); - - g_settings_bind (priv->gsettings_logger, - EMPATHY_PREFS_LOGGER_ENABLED, - priv->checkbutton_logging, - "active", - G_SETTINGS_BIND_DEFAULT); + G_SETTINGS_BIND_DEFAULT, + sort_criterium_get_mapping, + sort_criterium_set_mapping, + NULL, NULL); } static void @@ -1121,6 +1075,7 @@ empathy_preferences_finalize (GObject *self) g_object_unref (priv->gsettings_sound); g_object_unref (priv->gsettings_ui); g_object_unref (priv->gsettings_logger); + g_object_unref (priv->gsettings_contacts); G_OBJECT_CLASS (empathy_preferences_parent_class)->finalize (self); } @@ -1163,40 +1118,20 @@ empathy_preferences_init (EmpathyPreferences *preferences) filename = empathy_file_lookup ("empathy-preferences.ui", "src"); gui = empathy_builder_get_file (filename, "notebook", &priv->notebook, - "checkbutton_show_smileys", &priv->checkbutton_show_smileys, - "checkbutton_show_contacts_in_rooms", &priv->checkbutton_show_contacts_in_rooms, "vbox_chat_theme", &priv->vbox_chat_theme, "combobox_chat_theme", &priv->combobox_chat_theme, "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, - "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, - "checkbutton_notifications_enabled", &priv->checkbutton_notifications_enabled, - "checkbutton_notifications_disabled_away", &priv->checkbutton_notifications_disabled_away, - "checkbutton_notifications_focus", &priv->checkbutton_notifications_focus, - "checkbutton_notifications_contact_signin", &priv->checkbutton_notifications_contact_signin, - "checkbutton_notifications_contact_signout", &priv->checkbutton_notifications_contact_signout, - "checkbutton_sounds_enabled", &priv->checkbutton_sounds_enabled, - "checkbutton_sounds_disabled_away", &priv->checkbutton_sounds_disabled_away, "treeview_sounds", &priv->treeview_sounds, "treeview_spell_checker", &priv->treeview_spell_checker, - "checkbutton_location_publish", &priv->checkbutton_location_publish, - "checkbutton_location_reduce_accuracy", &priv->checkbutton_location_reduce_accuracy, - "checkbutton_location_resource_network", &priv->checkbutton_location_resource_network, - "checkbutton_location_resource_cell", &priv->checkbutton_location_resource_cell, - "checkbutton_location_resource_gps", &priv->checkbutton_location_resource_gps, - "call_echo_cancellation", &priv->echo_cancellation, NULL); g_free (filename); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (preferences))), priv->notebook); gtk_widget_show (priv->notebook); - g_object_unref (gui); - priv->gsettings = g_settings_new (EMPATHY_PREFS_SCHEMA); priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA); priv->gsettings_call = g_settings_new (EMPATHY_PREFS_CALL_SCHEMA); @@ -1205,6 +1140,7 @@ empathy_preferences_init (EmpathyPreferences *preferences) priv->gsettings_sound = g_settings_new (EMPATHY_PREFS_SOUNDS_SCHEMA); priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA); priv->gsettings_logger = g_settings_new (EMPATHY_PREFS_LOGGER_SCHEMA); + priv->gsettings_contacts = g_settings_new (EMPATHY_PREFS_CONTACTS_SCHEMA); /* Create chat theme preview, and track changes */ priv->theme_manager = empathy_theme_manager_dup_singleton (); @@ -1215,7 +1151,7 @@ empathy_preferences_init (EmpathyPreferences *preferences) preferences_themes_setup (preferences); - preferences_setup_widgets (preferences); + preferences_setup_widgets (preferences, gui); preferences_languages_setup (preferences); preferences_languages_add (preferences); @@ -1224,6 +1160,8 @@ empathy_preferences_init (EmpathyPreferences *preferences) preferences_sound_setup (preferences); preferences_sound_load (preferences); + g_object_unref (gui); + if (empathy_spell_supported ()) { page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), EMPATHY_PREFERENCES_TAB_SPELL); gtk_widget_show (page); diff --git a/src/empathy-preferences.ui b/src/empathy-preferences.ui index f13f6c0b2..a17f00055 100644 --- a/src/empathy-preferences.ui +++ b/src/empathy-preferences.ui @@ -1,11 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> <requires lib="gtk+" version="2.16"/> - <object class="GtkAdjustment" id="call_volume_adjustment"> - <property name="upper">150</property> - <property name="step_increment">1</property> - <property name="page_increment">10</property> - </object> <object class="GtkNotebook" id="notebook"> <property name="visible">True</property> <property name="can_focus">True</property> @@ -18,53 +13,125 @@ <property name="orientation">vertical</property> <property name="spacing">18</property> <child> - <object class="GtkFrame" id="frame3"> + <object class="GtkFrame" id="frame6"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> - <object class="GtkAlignment" id="alignment11"> + <object class="GtkAlignment" id="alignment5"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="top_padding">6</property> <property name="left_padding">12</property> <child> - <object class="GtkBox" id="vbox199"> + <object class="GtkBox" id="box2"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> <child> - <object class="GtkCheckButton" id="checkbutton_show_smileys"> - <property name="label" translatable="yes">Show _smileys as images</property> + <object class="GtkCheckButton" id="checkbutton_show_offline"> + <property name="label" translatable="yes">Show offline contacts</property> <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="active">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> <child> - <object class="GtkCheckButton" id="checkbutton_show_contacts_in_rooms"> - <property name="label" translatable="yes">Show contact _list in rooms</property> + <object class="GtkCheckButton" id="checkbutton_show_protocols"> + <property name="label" translatable="yes">Show protocol in avatar</property> <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="active">True</property> + <property name="xalign">0</property> <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="checkbutton_show_balances"> + <property name="label" translatable="yes">Show account balances</property> + <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="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">3</property> + <child> + <object class="GtkLabel" id="label9"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Sort contacts by:</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="radiobutton_sort_by_status"> + <property name="label" translatable="yes">status</property> + <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="xalign">0</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkRadioButton" id="radiobutton_sort_by_name"> + <property name="label" translatable="yes">name</property> + <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="xalign">0</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <property name="group">radiobutton_sort_by_status</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">3</property> </packing> </child> @@ -73,10 +140,11 @@ </object> </child> <child type="label"> - <object class="GtkLabel" id="label611"> + <object class="GtkLabel" id="label8"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="label" translatable="yes">Appearance</property> + <property name="label" translatable="yes">Contact List</property> + <property name="use_markup">True</property> <attributes> <attribute name="weight" value="bold"/> </attributes> @@ -85,24 +153,24 @@ </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> - <object class="GtkFrame" id="frame4"> + <object class="GtkFrame" id="frame3"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label_xalign">0</property> <property name="shadow_type">none</property> <child> - <object class="GtkAlignment" id="alignment12"> + <object class="GtkAlignment" id="alignment11"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="top_padding">6</property> <property name="left_padding">12</property> <child> - <object class="GtkBox" id="vbox218"> + <object class="GtkBox" id="vbox199"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> @@ -110,14 +178,16 @@ <object class="GtkBox" id="vbox2180"> <property name="visible">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> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Start chats in:</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">0</property> </packing> </child> @@ -127,10 +197,15 @@ <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="xalign">0</property> + <property name="active">True</property> <property name="draw_indicator">True</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> @@ -140,11 +215,15 @@ <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="xalign">0</property> <property name="draw_indicator">True</property> <property name="group">radiobutton_chats_new_tabs</property> </object> <packing> + <property name="expand">False</property> + <property name="fill">True</property> <property name="position">2</property> </packing> </child> @@ -156,24 +235,25 @@ </packing> </child> <child> - <object class="GtkCheckButton" id="checkbutton_events_notif_area"> - <property name="label" translatable="yes">Display incoming events in the notification area</property> + <object class="GtkCheckButton" id="checkbutton_show_smileys"> + <property name="label" translatable="yes">Show _smileys as images</property> <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="active">True</property> <property name="draw_indicator">True</property> </object> <packing> <property name="expand">False</property> - <property name="fill">False</property> + <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> - <object class="GtkCheckButton" id="checkbutton_autoconnect"> - <property name="label" translatable="yes">_Automatically connect on startup</property> + <object class="GtkCheckButton" id="checkbutton_show_contacts_in_rooms"> + <property name="label" translatable="yes">Show contact _list in rooms</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> @@ -196,6 +276,7 @@ <property name="receives_default">False</property> <property name="use_action_appearance">False</property> <property name="use_underline">True</property> + <property name="xalign">0</property> <property name="active">True</property> <property name="draw_indicator">True</property> </object> @@ -210,6 +291,77 @@ </object> </child> <child type="label"> + <object class="GtkLabel" id="label611"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Chat</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">1</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame4"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment12"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="top_padding">6</property> + <property name="left_padding">12</property> + <child> + <object class="GtkBox" id="vbox218"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkCheckButton" id="checkbutton_events_notif_area"> + <property name="label" translatable="yes">Display incoming events in the notification area</property> + <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> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="checkbutton_autoconnect"> + <property name="label" translatable="yes">_Automatically connect on startup</property> + <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="active">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> <object class="GtkLabel" id="label612"> <property name="visible">True</property> <property name="can_focus">False</property> @@ -223,7 +375,7 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </object> @@ -523,7 +675,10 @@ <property name="label" translatable="yes">Use _echo cancellation to improve call quality</property> <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> </object> <packing> <property name="expand">False</property> diff --git a/src/empathy-roster-window-menubar.ui b/src/empathy-roster-window-menubar.ui index d342abca8..a70b7461e 100644 --- a/src/empathy-roster-window-menubar.ui +++ b/src/empathy-roster-window-menubar.ui @@ -1,301 +1,100 @@ <?xml version="1.0"?> <!--*- mode: xml -*--> <interface> - <object class="GtkUIManager" id="ui_manager"> - <child> - <object class="GtkActionGroup" id="actiongroup1"> - <child> - <object class="GtkAction" id="chat"> - <property name="name">chat</property> - <property name="label" translatable="yes">_Chat</property> - </object> - </child> - <child> - <object class="GtkAction" id="chat_new_message"> - <property name="icon-name">im-message-new</property> - <property name="name">chat_new_message</property> - <property name="label" translatable="yes">_New Conversation…</property> - </object> - <accelerator key="N" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="chat_new_call"> - <property name="icon-name">audio-input-microphone</property> - <property name="name">chat_new_call</property> - <property name="label" translatable="yes">New _Call…</property> - </object> - <accelerator key="M" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="view_history"> - <property name="icon-name">document-open-recent</property> - <property name="name">view_history</property> - <property name="label" translatable="yes">_Previous Conversations</property> - </object> - <accelerator key="F3" modifiers=""/> - </child> - <child> - <object class="GtkAction" id="chat_add_contact"> - <property name="stock_id">gtk-add</property> - <property name="name">chat_add_contact</property> - <property name="label" translatable="yes">_Add Contact…</property> - </object> - </child> - <child> - <object class="GtkAction" id="chat_search_contacts"> - <property name="stock_id">gtk-find</property> - <property name="name">chat_search_contacts</property> - <property name="label" translatable="yes">_Search for Contacts…</property> - </object> - <accelerator key="f" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="view_show_ft_manager"> - <property name="icon-name">document-send</property> - <property name="name">view_show_ft_manager</property> - <property name="label" translatable="yes">_File Transfers</property> - </object> - </child> - <child> - <object class="GtkToggleAction" id="view_show_offline"> - <property name="name">view_show_offline</property> - <property name="label" translatable="yes">_Offline Contacts</property> - </object> - <accelerator key="H" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkToggleAction" id="view_show_protocols"> - <property name="name">view_show_protocols</property> - <property name="label" translatable="yes">Show P_rotocols</property> - </object> - </child> - <child> - <object class="GtkToggleAction" id="view_balance_show_in_roster"> - <property name="name">view_balance_show_in_roster</property> - <property name="label" translatable="yes">Credit Balance</property> - <property name="visible">False</property> - </object> - </child> - <child> - <object class="GtkAction" id="view_show_map"> - <property name="name">view_show_map</property> - <property name="label" translatable="yes">Contacts on a _Map</property> - </object> - </child> - <child> - <object class="GtkAction" id="chat_quit"> - <property name="stock_id">gtk-quit</property> - <property name="name">chat_quit</property> - </object> - <accelerator key="Q" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="edit"> - <property name="name">edit</property> - <property name="label" translatable="yes">_Edit</property> - </object> - </child> - <child> - <object class="GtkAction" id="edit_context"> - <property name="name">edit_context</property> - <property name="label" translatable="no">Context</property> - </object> - </child> - <child> - <object class="GtkAction" id="edit_accounts"> - <property name="name">edit_accounts</property> - <property name="label" translatable="yes">_Accounts</property> - </object> - <accelerator key="F4" modifiers=""/> - </child> - <child> - <object class="GtkAction" id="edit_blocked_contacts"> - <property name="name">edit_blocked_contacts</property> - <property name="label" translatable="yes">_Blocked Contacts</property> - </object> - </child> - <child> - <object class="GtkAction" id="edit_preferences"> - <property name="stock_id">gtk-preferences</property> - <property name="name">edit_preferences</property> - <property name="label" translatable="yes">P_references</property> - </object> - </child> - <child> - <object class="GtkAction" id="edit_search_contacts"> - <property name="name">edit_search_contacts</property> - <property name="label" translatable="yes">Find in Contact _List</property> - </object> - <accelerator key="f" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="view"> - <property name="name">view</property> - <property name="label" translatable="yes">_View</property> - </object> - </child> - <child> - <object class="GtkRadioAction" id="view_sort_by_name"> - <property name="name">view_sort_by_name</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Sort by _Name</property> - <property name="draw_as_radio">True</property> - <property name="value">1</property> - <property name="current-value">1</property> - </object> - </child> - <child> - <object class="GtkRadioAction" id="view_sort_by_status"> - <property name="name">view_sort_by_status</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Sort by _Status</property> - <property name="draw_as_radio">True</property> - <property name="group">view_sort_by_name</property> - <property name="value">0</property> - </object> - </child> - <child> - <object class="GtkRadioAction" id="view_normal_size_with_avatars"> - <property name="name">view_normal_size_with_avatars</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Normal Size With _Avatars</property> - <property name="draw_as_radio">True</property> - <property name="value">0</property> - <property name="current-value">0</property> - </object> - <accelerator key="1" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkRadioAction" id="view_normal_size"> - <property name="name">view_normal_size</property> - <property name="visible">True</property> - <property name="label" translatable="yes">N_ormal Size</property> - <property name="draw_as_radio">True</property> - <property name="group">view_normal_size_with_avatars</property> - <property name="value">1</property> - </object> - <accelerator key="2" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkRadioAction" id="view_compact_size"> - <property name="name">view_compact_size</property> - <property name="visible">True</property> - <property name="label" translatable="yes">_Compact Size</property> - <property name="draw_as_radio">True</property> - <property name="group">view_normal_size_with_avatars</property> - <property name="value">2</property> - </object> - <accelerator key="3" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="room"> - <property name="name">room</property> - <property name="label" translatable="yes">_Room</property> - </object> - </child> - <child> - <object class="GtkAction" id="room_join_new"> - <property name="name">room_join_new</property> - <property name="label" translatable="yes">_Join…</property> - </object> - <accelerator key="j" modifiers="GDK_CONTROL_MASK"/> - </child> - <child> - <object class="GtkAction" id="room_join_favorites"> - <property name="name">room_join_favorites</property> - <property name="label" translatable="yes">Join _Favorites</property> - </object> - <accelerator key="F5" modifiers=""/> - </child> - <child> - <object class="GtkAction" id="room_manage_favorites"> - <property name="icon-name">system-users</property> - <property name="name">room_manage_favorites</property> - <property name="label" translatable="yes">Manage Favorites</property> - </object> - </child> - <child> - <object class="GtkAction" id="help"> - <property name="name">help</property> - <property name="label" translatable="yes">_Help</property> - </object> - </child> - <child> - <object class="GtkAction" id="help_contents"> - <property name="stock_id">gtk-help</property> - <property name="name">help_contents</property> - <property name="label" translatable="yes">_Contents</property> - </object> - <accelerator key="F1" modifiers=""/> - </child> - <child> - <object class="GtkAction" id="help_debug"> - <property name="name">help_debug</property> - <property name="label" translatable="yes">_Debug</property> - </object> - </child> - <child> - <object class="GtkAction" id="help_about"> - <property name="stock_id">gtk-about</property> - <property name="name">help_about</property> - </object> - </child> - </object> - </child> - <ui> - <menubar name="menubar"> - <menu action="chat"> - <menuitem action="chat_new_message"/> - <menuitem action="chat_new_call"/> - <separator/> - <menuitem action="chat_add_contact"/> - <menuitem action="chat_search_contacts"/> - <separator/> - <menuitem action="chat_quit"/> - </menu> - <menu action="edit"> - <menuitem action="edit_context"/> - <separator name="edit_context_separator"/> - <menuitem action="edit_accounts"/> - <menuitem action="edit_search_contacts"/> - <menuitem action="edit_blocked_contacts"/> - <separator/> - <menuitem action="edit_preferences"/> - </menu> - <menu action="view"> - <menuitem action="view_show_offline"/> - <menuitem action="view_show_protocols"/> - <separator/> - <menuitem action="view_balance_show_in_roster"/> - <placeholder name="view_balance_placeholder"/> - <separator/> - <menuitem action="view_sort_by_name"/> - <menuitem action="view_sort_by_status"/> - <separator/> - <menuitem action="view_normal_size_with_avatars"/> - <menuitem action="view_normal_size"/> - <menuitem action="view_compact_size"/> - <separator/> - <menuitem action="view_history"/> - <menuitem action="view_show_ft_manager"/> - <menuitem action="view_show_map"/> - </menu> - <menu action="room"> - <menuitem action="room_join_new"/> - <menuitem action="room_join_favorites"/> - <separator/> - <separator name="room_separator"/> - <menuitem action="room_manage_favorites"/> - </menu> - <menu action="help"> - <menuitem action="help_contents"/> - <menuitem action="help_debug"/> - <menuitem action="help_about"/> - </menu> - </menubar> - </ui> - </object> - <object class="GtkMenuBar" constructor="ui_manager" id="menubar"> - <property name="visible">True</property> - </object> + <menu id="appmenu"> + <section> + <item> + <attribute translatable="yes" name="label">_New Conversation...</attribute> + <attribute name="action">win.chat_new_message</attribute> + <attribute name="accel"><Primary>n</attribute> + </item> + <item> + <attribute translatable="yes" name="label">New _Call...</attribute> + <attribute name="action">win.chat_new_call</attribute> + <attribute name="accel"><Primary>m</attribute> + </item> + </section> + <submenu> + <attribute translatable="yes" name="label">Contacts</attribute> + <section> + <item> + <attribute translatable="yes" name="label">_Add Contacts...</attribute> + <attribute name="action">win.chat_add_contact</attribute> + </item> + <item> + <attribute translatable="yes" name="label">_Search for Contacts...</attribute> + <attribute name="action">win.chat_search_contacts</attribute> + <attribute name="accel"><Shift>f</attribute> + </item> + </section> + <section> + <item> + <attribute translatable="yes" name="label">_Blocked Contacts</attribute> + <attribute name="action">win.edit_blocked_contacts</attribute> + </item> + </section> + </submenu> + <submenu> + <attribute translatable="yes" name="label">_Rooms</attribute> + <section> + <item> + <attribute translatable="yes" name="label">_Join...</attribute> + <attribute name="action">win.room_join_new</attribute> + <attribute name="accel"><Primary>j</attribute> + </item> + <item> + <attribute translatable="yes" name="label">Join _Favorites</attribute> + <attribute name="action">win.room_join_favorites</attribute> + <attribute name="accel">F5</attribute> + </item> + </section> + <item> + <link name="section" id="rooms"/> + </item> + <section> + <item> + <attribute translatable="yes" name="label">_Manage Favorites</attribute> + <attribute name="action">win.room_manage_favorites</attribute> + </item> + </section> + </submenu> + <section> + <item> + <attribute translatable="yes" name="label">_Previous Conversations</attribute> + <attribute name="action">win.view_history</attribute> + <attribute name="accel">F3</attribute> + </item> + <item> + <attribute translatable="yes" name="label">_File Transfers</attribute> + <attribute name="action">win.view_show_ft_manager</attribute> + </item> + </section> + <section> + <item> + <attribute translatable="yes" name="label">_Accounts</attribute> + <attribute name="action">win.edit_accounts</attribute> + <attribute name="accel">F4</attribute> + </item> + <item> + <attribute translatable="yes" name="label">P_references</attribute> + <attribute name="action">win.edit_preferences</attribute> + </item> + </section> + <section> + <item> + <attribute translatable="yes" name="label">Help</attribute> + <attribute name="action">win.help_contents</attribute> + <attribute name="accel">F1</attribute> + </item> + <item> + <attribute translatable="yes" name="label">About Empathy</attribute> + <attribute name="action">win.help_about</attribute> + </item> + <item> + <attribute translatable="yes" name="label">_Quit</attribute> + <attribute name="action">win.chat_quit</attribute> + <attribute name="accel"><Primary>q</attribute> + </item> + </section> + </menu> </interface> diff --git a/src/empathy-roster-window.c b/src/empathy-roster-window.c index 203a5aede..f614a806b 100644 --- a/src/empathy-roster-window.c +++ b/src/empathy-roster-window.c @@ -37,12 +37,10 @@ #include <libempathy/empathy-request-util.h> #include <libempathy/empathy-chatroom-manager.h> #include <libempathy/empathy-chatroom.h> -#include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-gsettings.h> #include <libempathy/empathy-individual-manager.h> #include <libempathy/empathy-gsettings.h> #include <libempathy/empathy-status-presets.h> -#include <libempathy/empathy-tp-contact-factory.h> #include <libempathy-gtk/empathy-contact-dialogs.h> #include <libempathy-gtk/empathy-live-search.h> @@ -69,7 +67,6 @@ #include "empathy-about-dialog.h" #include "empathy-debug-window.h" #include "empathy-new-chatroom-dialog.h" -#include "empathy-map-view.h" #include "empathy-chatrooms-window.h" #include "empathy-event-manager.h" #include "empathy-ft-manager.h" @@ -101,7 +98,7 @@ enum PROP_SHELL_RUNNING }; -G_DEFINE_TYPE (EmpathyRosterWindow, empathy_roster_window, GTK_TYPE_WINDOW); +G_DEFINE_TYPE (EmpathyRosterWindow, empathy_roster_window, GTK_TYPE_APPLICATION_WINDOW) struct _EmpathyRosterWindowPriv { EmpathyIndividualStore *individual_store; @@ -122,7 +119,6 @@ struct _EmpathyRosterWindowPriv { GtkWidget *preferences; GtkWidget *main_vbox; GtkWidget *throbber; - GtkWidget *throbber_tool_item; GtkWidget *presence_toolbar; GtkWidget *presence_chooser; GtkWidget *errors_vbox; @@ -133,23 +129,9 @@ struct _EmpathyRosterWindowPriv { GtkWidget *button_account_settings; GtkWidget *spinner_loading; - GtkToggleAction *show_protocols; - GtkRadioAction *sort_by_name; - GtkRadioAction *sort_by_status; - GtkRadioAction *normal_with_avatars; - GtkRadioAction *normal_size; - GtkRadioAction *compact_size; - - GtkUIManager *ui_manager; - GtkAction *view_history; - GtkAction *room_join_favorites; - GtkWidget *room_menu; - GtkWidget *room_separator; - GtkWidget *edit_context; - GtkWidget *edit_context_separator; - - GtkActionGroup *balance_action_group; - GtkAction *view_balance_show_in_roster; + GMenu *menumodel; + GMenu *rooms_section; + GtkWidget *balance_vbox; guint size_timeout_id; @@ -1014,7 +996,7 @@ static void roster_window_update_status (EmpathyRosterWindow *self) { gboolean connected, connecting; - GList *l, *children; + GList *l; connected = empathy_account_manager_get_accounts_connected (&connecting); @@ -1022,70 +1004,33 @@ roster_window_update_status (EmpathyRosterWindow *self) if (connecting) { gtk_spinner_start (GTK_SPINNER (self->priv->throbber)); - gtk_widget_show (self->priv->throbber_tool_item); + gtk_widget_show (self->priv->throbber); } else { gtk_spinner_stop (GTK_SPINNER (self->priv->throbber)); - gtk_widget_hide (self->priv->throbber_tool_item); + gtk_widget_hide (self->priv->throbber); } /* Update widgets sensibility */ for (l = self->priv->actions_connected; l; l = l->next) - gtk_action_set_sensitive (l->data, connected); - - /* Update favourite rooms sensitivity */ - children = gtk_container_get_children (GTK_CONTAINER (self->priv->room_menu)); - for (l = children; l != NULL; l = l->next) - { - if (g_object_get_data (G_OBJECT (l->data), "is_favorite") != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (l->data), connected); - } - - g_list_free (children); -} - -static char * -roster_window_account_to_action_name (TpAccount *account) -{ - char *r; - - /* action names can't have '/' in them, replace it with '.' */ - r = g_strdup (tp_account_get_path_suffix (account)); - r = g_strdelimit (r, "/", '.'); - - return r; -} - -static void -roster_window_balance_activate_cb (GtkAction *action, - EmpathyRosterWindow *self) -{ - const char *uri; - - uri = g_object_get_data (G_OBJECT (action), "manage-credit-uri"); - - if (!tp_str_empty (uri)) - { - DEBUG ("Top-up credit URI: %s", uri); - empathy_url_show (GTK_WIDGET (self), uri); - } - else - { - DEBUG ("unknown protocol for top-up"); - } + g_simple_action_set_enabled (l->data, connected); } static void -roster_window_balance_update_balance (GtkAction *action, - TpConnection *conn) +roster_window_balance_update_balance (EmpathyRosterWindow *self, + TpAccount *account) { - TpAccount *account = tp_connection_get_account (conn); + TpConnection *conn; GtkWidget *label; int amount = 0; guint scale = G_MAXINT32; const gchar *currency = ""; - char *money, *str; + char *money; + + conn = tp_account_get_connection (account); + if (conn == NULL) + return; if (!tp_connection_get_balance (conn, &amount, &scale, ¤cy)) return; @@ -1105,16 +1050,8 @@ roster_window_balance_update_balance (GtkAction *action, g_free (tmp); } - /* Translators: this string will be something like: - * Top up My Account ($1.23)..." */ - str = g_strdup_printf (_("Top up %s (%s)..."), - tp_account_get_display_name (account), money); - - gtk_action_set_label (action, str); - g_free (str); - /* update the money label in the roster */ - label = g_object_get_data (G_OBJECT (action), "money-label"); + label = g_object_get_data (G_OBJECT (account), "balance-money-label"); gtk_label_set_text (GTK_LABEL (label), money); g_free (money); @@ -1125,95 +1062,48 @@ roster_window_balance_changed_cb (TpConnection *conn, guint balance, guint scale, const gchar *currency, - GtkAction *action) + EmpathyRosterWindow *self) { - roster_window_balance_update_balance (action, conn); + TpAccount *account; + + account = tp_connection_get_account (conn); + if (account == NULL) + return; + + roster_window_balance_update_balance (self, account); } -static GtkAction * -roster_window_setup_balance_create_action (EmpathyRosterWindow *self, +static void +roster_window_setup_balance (EmpathyRosterWindow *self, TpAccount *account) { - GtkAction *action; - char *name, *ui; - guint merge_id; - GError *error = NULL; - - /* create the action group if required */ - if (self->priv->balance_action_group == NULL) - { - self->priv->balance_action_group = - gtk_action_group_new ("balance-action-group"); - - gtk_ui_manager_insert_action_group (self->priv->ui_manager, - self->priv->balance_action_group, -1); - } - - /* create the action */ - name = roster_window_account_to_action_name (account); - action = gtk_action_new (name, - tp_account_get_display_name (account), - _("Top up account credit"), NULL); - - g_object_bind_property (account, "icon-name", action, "icon-name", - G_BINDING_SYNC_CREATE); - - g_signal_connect (action, "activate", - G_CALLBACK (roster_window_balance_activate_cb), self); - - gtk_action_group_add_action (self->priv->balance_action_group, action); - g_object_unref (action); - - ui = g_strdup_printf ( - "<ui>" - " <menubar name='menubar'>" - " <menu action='view'>" - " <placeholder name='view_balance_placeholder'>" - " <menuitem action='%s'/>" - " </placeholder>" - " </menu>" - " </menubar>" - "</ui>", - name); - - merge_id = gtk_ui_manager_add_ui_from_string (self->priv->ui_manager, - ui, -1, &error); - - if (error != NULL) - { - DEBUG ("Failed to add balance UI for %s: %s", - tp_account_get_display_name (account), - error->message); - g_error_free (error); - } - - g_object_set_data (G_OBJECT (action), - "merge-id", GUINT_TO_POINTER (merge_id)); + TpConnection *conn = tp_account_get_connection (account); + GtkWidget *hbox, *image, *label; + const gchar *uri; - g_free (name); - g_free (ui); + if (conn == NULL) + return; - return action; -} + if (!tp_proxy_is_prepared (conn, TP_CONNECTION_FEATURE_BALANCE)) + return; -static GtkWidget * -roster_window_setup_balance_create_widget (EmpathyRosterWindow *self, - GtkAction *action, - TpAccount *account) -{ - GtkWidget *hbox, *image, *label, *button; + DEBUG ("Setting up balance for acct: %s", + tp_account_get_display_name (account)); - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + /* create the display widget */ + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 3); /* protocol icon */ image = gtk_image_new (); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0); - g_object_bind_property (action, "icon-name", image, "icon-name", + g_object_bind_property (account, "icon-name", image, "icon-name", G_BINDING_SYNC_CREATE); /* account name label */ label = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); g_object_bind_property (account, "display-name", label, "label", G_BINDING_SYNC_CREATE); @@ -1222,105 +1112,53 @@ roster_window_setup_balance_create_widget (EmpathyRosterWindow *self, label = gtk_label_new (""); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0); - g_object_set_data (G_OBJECT (action), "money-label", label); /* top up button */ - button = gtk_button_new_with_label (_("Top Up...")); - gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0); - g_signal_connect_swapped (button, "clicked", - G_CALLBACK (gtk_action_activate), action); + uri = tp_connection_get_balance_uri (conn); + + if (!tp_str_empty (uri)) + { + GtkWidget *button; + + button = gtk_button_new (); + gtk_container_add (GTK_CONTAINER (button), + gtk_image_new_from_icon_name ("emblem-symbolic-link", + GTK_ICON_SIZE_SMALL_TOOLBAR)); + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + gtk_widget_set_tooltip_text (button, _("Top up account")); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0); + + g_signal_connect_data (button, "clicked", + G_CALLBACK (empathy_url_show), + g_strdup (uri), (GClosureNotify) g_free, + 0); + } gtk_box_pack_start (GTK_BOX (self->priv->balance_vbox), hbox, FALSE, TRUE, 0); gtk_widget_show_all (hbox); - /* tie the lifetime of the widget to the lifetime of the action */ - g_object_weak_ref (G_OBJECT (action), - (GWeakNotify) gtk_widget_destroy, hbox); - - return hbox; -} - -static void -roster_window_setup_balance (EmpathyRosterWindow *self, - TpAccount *account) -{ - TpConnection *conn = tp_account_get_connection (account); - GtkAction *action; - const gchar *uri; - - if (conn == NULL) - return; - - if (!tp_proxy_is_prepared (conn, TP_CONNECTION_FEATURE_BALANCE)) - return; - - DEBUG ("Setting up balance for acct: %s", - tp_account_get_display_name (account)); - - /* create the action */ - action = roster_window_setup_balance_create_action (self, account); - - if (action == NULL) - return; - - gtk_action_set_visible (self->priv->view_balance_show_in_roster, TRUE); - - /* create the display widget */ - roster_window_setup_balance_create_widget (self, action, account); - - /* check the current balance and monitor for any changes */ - uri = tp_connection_get_balance_uri (conn); - - g_object_set_data_full (G_OBJECT (action), "manage-credit-uri", - g_strdup (uri), g_free); - gtk_action_set_sensitive (GTK_ACTION (action), !tp_str_empty (uri)); + g_object_set_data (G_OBJECT (account), "balance-money-label", label); + g_object_set_data (G_OBJECT (account), "balance-money-hbox", hbox); - roster_window_balance_update_balance (GTK_ACTION (action), conn); + roster_window_balance_update_balance (self, account); g_signal_connect (conn, "balance-changed", - G_CALLBACK (roster_window_balance_changed_cb), action); + G_CALLBACK (roster_window_balance_changed_cb), self); } static void roster_window_remove_balance_action (EmpathyRosterWindow *self, TpAccount *account) { - GtkAction *action; - char *name; - GList *a; + GtkWidget *hbox = + g_object_get_data (G_OBJECT (account), "balance-money-hbox"); - if (self->priv->balance_action_group == NULL) + if (hbox == NULL) return; - name = roster_window_account_to_action_name (account); + g_return_if_fail (GTK_IS_BOX (hbox)); - action = gtk_action_group_get_action ( - self->priv->balance_action_group, name); - - if (action != NULL) - { - guint merge_id; - - DEBUG ("Removing action"); - - merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (action), - "merge-id")); - - gtk_ui_manager_remove_ui (self->priv->ui_manager, - merge_id); - gtk_action_group_remove_action ( - self->priv->balance_action_group, action); - } - - g_free (name); - - a = gtk_action_group_list_actions ( - self->priv->balance_action_group); - - gtk_action_set_visible (self->priv->view_balance_show_in_roster, - g_list_length (a) > 0); - - g_list_free (a); + gtk_widget_destroy (hbox); } static void @@ -1421,13 +1259,15 @@ empathy_roster_window_finalize (GObject *window) g_object_unref (self->priv->call_observer); g_object_unref (self->priv->event_manager); - g_object_unref (self->priv->ui_manager); g_object_unref (self->priv->chatroom_manager); g_object_unref (self->priv->gsettings_ui); g_object_unref (self->priv->gsettings_contacts); g_object_unref (self->priv->individual_manager); + g_object_unref (self->priv->menumodel); + g_object_unref (self->priv->rooms_section); + G_OBJECT_CLASS (empathy_roster_window_parent_class)->finalize (window); } @@ -1445,240 +1285,88 @@ roster_window_key_press_event_cb (GtkWidget *window, } static void -roster_window_chat_quit_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_chat_quit_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + gtk_widget_destroy (GTK_WIDGET (self)); } static void -roster_window_view_history_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_view_history_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_log_window_show (NULL, NULL, FALSE, GTK_WINDOW (self)); } static void -roster_window_chat_new_message_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_chat_new_message_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_new_message_dialog_show (GTK_WINDOW (self)); } static void -roster_window_chat_new_call_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_chat_new_call_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_new_call_dialog_show (GTK_WINDOW (self)); } static void -roster_window_chat_add_contact_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_chat_add_contact_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_new_individual_dialog_show (GTK_WINDOW (self)); } static void -roster_window_chat_search_contacts_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_chat_search_contacts_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { - GtkWidget *dialog = empathy_contact_search_dialog_new ( + EmpathyRosterWindow *self = user_data; + GtkWidget *dialog; + + dialog = empathy_contact_search_dialog_new ( GTK_WINDOW (self)); gtk_widget_show (dialog); } static void -roster_window_view_show_ft_manager (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_view_show_ft_manager (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { empathy_ft_manager_show (); } static void -roster_window_view_show_offline_cb (GtkToggleAction *action, - EmpathyRosterWindow *self) -{ - gboolean current; - - current = gtk_toggle_action_get_active (action); - g_settings_set_boolean (self->priv->gsettings_ui, - EMPATHY_PREFS_UI_SHOW_OFFLINE, - current); - - empathy_individual_view_set_show_offline (self->priv->individual_view, - current); -} - -static void -roster_window_notify_sort_contact_cb (GSettings *gsettings, - const gchar *key, - EmpathyRosterWindow *self) -{ - gchar *str; - - str = g_settings_get_string (gsettings, key); - - if (str != NULL) - { - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - - type = empathy_individual_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - enum_value = g_enum_get_value_by_nick (enum_class, str); - if (enum_value) - { - /* By changing the value of the GtkRadioAction, - it emits a signal that calls roster_window_view_sort_contacts_cb - which updates the contacts list */ - gtk_radio_action_set_current_value (self->priv->sort_by_name, - enum_value->value); - } - else - { - g_warning ("Wrong value for sort_criterium configuration : %s", str); - } - g_free (str); - } -} - -static void -roster_window_view_sort_contacts_cb (GtkRadioAction *action, - GtkRadioAction *current, - EmpathyRosterWindow *self) -{ - EmpathyIndividualStoreSort value; - GSList *group; - GType type; - GEnumClass *enum_class; - GEnumValue *enum_value; - - value = gtk_radio_action_get_current_value (action); - group = gtk_radio_action_get_group (action); - - /* Get string from index */ - type = empathy_individual_store_sort_get_type (); - enum_class = G_ENUM_CLASS (g_type_class_peek (type)); - enum_value = g_enum_get_value (enum_class, g_slist_index (group, current)); - - if (!enum_value) - g_warning ("No GEnumValue for EmpathyContactListSort with GtkRadioAction index:%d", - g_slist_index (group, action)); - else - g_settings_set_string (self->priv->gsettings_contacts, - EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, - enum_value->value_nick); - - empathy_individual_store_set_sort_criterium (self->priv->individual_store, - value); -} - -static void -roster_window_view_show_protocols_cb (GtkToggleAction *action, - EmpathyRosterWindow *self) -{ - gboolean value; - - value = gtk_toggle_action_get_active (action); - - g_settings_set_boolean (self->priv->gsettings_ui, - EMPATHY_PREFS_UI_SHOW_PROTOCOLS, - value); - - empathy_individual_store_set_show_protocols (self->priv->individual_store, - value); -} - -/* Matches GtkRadioAction values set in empathy-roster-window.ui */ -#define CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS 0 -#define CONTACT_LIST_NORMAL_SIZE 1 -#define CONTACT_LIST_COMPACT_SIZE 2 - -static void -roster_window_view_contacts_list_size_cb (GtkRadioAction *action, - GtkRadioAction *current, - EmpathyRosterWindow *self) -{ - GSettings *gsettings_ui; - gint value; - - value = gtk_radio_action_get_current_value (action); - /* create a new GSettings, so we can delay the setting until both - * values are set */ - gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA); - - DEBUG ("radio button toggled, value = %i", value); - - g_settings_delay (gsettings_ui); - g_settings_set_boolean (gsettings_ui, EMPATHY_PREFS_UI_SHOW_AVATARS, - value == CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS); - - g_settings_set_boolean (gsettings_ui, EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - value == CONTACT_LIST_COMPACT_SIZE); - g_settings_apply (gsettings_ui); - - /* FIXME: these enums probably have the wrong namespace */ - empathy_individual_store_set_show_avatars (self->priv->individual_store, - value == CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS); - empathy_individual_store_set_is_compact (self->priv->individual_store, - value == CONTACT_LIST_COMPACT_SIZE); - - g_object_unref (gsettings_ui); -} - -static void roster_window_notify_show_protocols_cb (GSettings *gsettings, - const gchar *key, - EmpathyRosterWindow *self) -{ - gtk_toggle_action_set_active (self->priv->show_protocols, - g_settings_get_boolean (gsettings, EMPATHY_PREFS_UI_SHOW_PROTOCOLS)); -} - - -static void -roster_window_notify_contact_list_size_cb (GSettings *gsettings, - const gchar *key, - EmpathyRosterWindow *self) +roster_window_edit_search_contacts_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { - gint value; - - if (g_settings_get_boolean (gsettings, - EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST)) - value = CONTACT_LIST_COMPACT_SIZE; - else if (g_settings_get_boolean (gsettings, - EMPATHY_PREFS_UI_SHOW_AVATARS)) - value = CONTACT_LIST_NORMAL_SIZE_WITH_AVATARS; - else - value = CONTACT_LIST_NORMAL_SIZE; - - DEBUG ("setting changed, value = %i", value); - - /* By changing the value of the GtkRadioAction, - it emits a signal that calls roster_window_view_contacts_list_size_cb - which updates the contacts list */ - gtk_radio_action_set_current_value (self->priv->normal_with_avatars, value); -} + EmpathyRosterWindow *self = user_data; -static void -roster_window_edit_search_contacts_cb (GtkCheckMenuItem *item, - EmpathyRosterWindow *self) -{ empathy_individual_view_start_search (self->priv->individual_view); } static void -roster_window_view_show_map_cb (GtkCheckMenuItem *item, - EmpathyRosterWindow *self) -{ -#ifdef HAVE_LIBCHAMPLAIN - empathy_map_view_show (); -#endif -} - -static void join_chatroom (EmpathyChatroom *chatroom, gint64 timestamp) { @@ -1799,41 +1487,55 @@ roster_window_favorite_chatroom_join (EmpathyChatroom *chatroom) } static void -roster_window_favorite_chatroom_menu_activate_cb (GtkMenuItem *menu_item, +roster_window_favorite_chatroom_menu_activate_cb (GAction *action, + GVariant *parameter, EmpathyChatroom *chatroom) { roster_window_favorite_chatroom_join (chatroom); } +static gchar * +dup_join_action_name (EmpathyChatroom *chatroom, + gboolean prefix) +{ + return g_strconcat (prefix ? "win." : "", "join-", + empathy_chatroom_get_name (chatroom), NULL); +} + static void roster_window_favorite_chatroom_menu_add (EmpathyRosterWindow *self, EmpathyChatroom *chatroom) { - GtkWidget *menu_item; + GMenuItem *item; const gchar *name, *account_name; - gchar *label; - - if (g_object_get_data (G_OBJECT (chatroom), "menu_item")) - return; + gchar *label, *action_name; + GAction *action; name = empathy_chatroom_get_name (chatroom); account_name = tp_account_get_display_name ( empathy_chatroom_get_account (chatroom)); + label = g_strdup_printf ("%s (%s)", name, account_name); - menu_item = gtk_menu_item_new_with_label (label); - g_free (label); - g_object_set_data (G_OBJECT (menu_item), "is_favorite", - GUINT_TO_POINTER (TRUE)); + action_name = dup_join_action_name (chatroom, FALSE); + + action = (GAction *) g_simple_action_new (action_name, NULL); + g_free (action_name); - g_object_set_data (G_OBJECT (chatroom), "menu_item", menu_item); - g_signal_connect (menu_item, "activate", + g_signal_connect (action, "activate", G_CALLBACK (roster_window_favorite_chatroom_menu_activate_cb), chatroom); - gtk_menu_shell_insert (GTK_MENU_SHELL (self->priv->room_menu), - menu_item, 4); + g_action_map_add_action (G_ACTION_MAP (self), action); + + action_name = dup_join_action_name (chatroom, TRUE); + + item = g_menu_item_new (label, action_name); + g_menu_item_set_attribute (item, "room-name", "s", name); + g_menu_append_item (self->priv->rooms_section, item); - gtk_widget_show (menu_item); + g_free (label); + g_free (action_name); + g_object_unref (action); } static void @@ -1842,8 +1544,6 @@ roster_window_favorite_chatroom_menu_added_cb (EmpathyChatroomManager *manager, EmpathyRosterWindow *self) { roster_window_favorite_chatroom_menu_add (self, chatroom); - gtk_widget_show (self->priv->room_separator); - gtk_action_set_sensitive (self->priv->room_join_favorites, TRUE); } static void @@ -1852,21 +1552,32 @@ roster_window_favorite_chatroom_menu_removed_cb ( EmpathyChatroom *chatroom, EmpathyRosterWindow *self) { - GtkWidget *menu_item; GList *chatrooms; + gchar *act; + gint i; - menu_item = g_object_get_data (G_OBJECT (chatroom), "menu_item"); - g_object_set_data (G_OBJECT (chatroom), "menu_item", NULL); - gtk_widget_destroy (menu_item); + act = dup_join_action_name (chatroom, TRUE); - chatrooms = empathy_chatroom_manager_get_chatrooms (self->priv->chatroom_manager, - NULL); - if (chatrooms) - gtk_widget_show (self->priv->room_separator); - else - gtk_widget_hide (self->priv->room_separator); + g_action_map_remove_action (G_ACTION_MAP (self), act); + + for (i = 0; i < g_menu_model_get_n_items ( + G_MENU_MODEL (self->priv->rooms_section)); i++) + { + const gchar *name; + + if (g_menu_model_get_item_attribute ( + G_MENU_MODEL (self->priv->rooms_section), i, "room-name", + "s", &name) + && !tp_strdiff (name, empathy_chatroom_get_name (chatroom))) + { + g_menu_remove (self->priv->rooms_section, i); + break; + } + } + + chatrooms = empathy_chatroom_manager_get_chatrooms ( + self->priv->chatroom_manager, NULL); - gtk_action_set_sensitive (self->priv->room_join_favorites, chatrooms != NULL); g_list_free (chatrooms); } @@ -1874,25 +1585,15 @@ static void roster_window_favorite_chatroom_menu_setup (EmpathyRosterWindow *self) { GList *chatrooms, *l; - GtkWidget *room; self->priv->chatroom_manager = empathy_chatroom_manager_dup_singleton (NULL); + chatrooms = empathy_chatroom_manager_get_chatrooms ( self->priv->chatroom_manager, NULL); - room = gtk_ui_manager_get_widget (self->priv->ui_manager, - "/menubar/room"); - self->priv->room_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (room)); - self->priv->room_separator = gtk_ui_manager_get_widget (self->priv->ui_manager, - "/menubar/room/room_separator"); for (l = chatrooms; l; l = l->next) roster_window_favorite_chatroom_menu_add (self, l->data); - if (!chatrooms) - gtk_widget_hide (self->priv->room_separator); - - gtk_action_set_sensitive (self->priv->room_join_favorites, chatrooms != NULL); - g_signal_connect (self->priv->chatroom_manager, "chatroom-added", G_CALLBACK (roster_window_favorite_chatroom_menu_added_cb), self); @@ -1905,16 +1606,21 @@ roster_window_favorite_chatroom_menu_setup (EmpathyRosterWindow *self) } static void -roster_window_room_join_new_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_room_join_new_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_new_chatroom_dialog_show (GTK_WINDOW (self)); } static void -roster_window_room_join_favorites_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_room_join_favorites_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; GList *chatrooms, *l; chatrooms = empathy_chatroom_manager_get_chatrooms (self->priv->chatroom_manager, @@ -1927,74 +1633,30 @@ roster_window_room_join_favorites_cb (GtkAction *action, } static void -roster_window_room_manage_favorites_cb (GtkAction *action, - EmpathyRosterWindow *self) -{ - empathy_chatrooms_window_show (GTK_WINDOW (self)); -} - -static void -roster_window_edit_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_room_manage_favorites_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { - GtkWidget *submenu; - - /* FIXME: It should use the UIManager to merge the contact/group submenu */ - submenu = empathy_individual_view_get_individual_menu ( - self->priv->individual_view); - if (submenu) - { - GtkMenuItem *item; - GtkWidget *label; - - item = GTK_MENU_ITEM (self->priv->edit_context); - label = gtk_bin_get_child (GTK_BIN (item)); - gtk_label_set_text (GTK_LABEL (label), _("Contact")); - - gtk_widget_show (self->priv->edit_context); - gtk_widget_show (self->priv->edit_context_separator); - - gtk_menu_item_set_submenu (item, submenu); - - return; - } - - submenu = empathy_individual_view_get_group_menu (self->priv->individual_view); - if (submenu) - { - GtkMenuItem *item; - GtkWidget *label; - - item = GTK_MENU_ITEM (self->priv->edit_context); - label = gtk_bin_get_child (GTK_BIN (item)); - gtk_label_set_text (GTK_LABEL (label), _("Group")); - - gtk_widget_show (self->priv->edit_context); - gtk_widget_show (self->priv->edit_context_separator); - - gtk_menu_item_set_submenu (item, submenu); - - return; - } - - gtk_widget_hide (self->priv->edit_context); - gtk_widget_hide (self->priv->edit_context_separator); + EmpathyRosterWindow *self = user_data; - return; + empathy_chatrooms_window_show (GTK_WINDOW (self)); } static void -roster_window_edit_accounts_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_edit_accounts_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { empathy_accounts_dialog_show_application (gdk_screen_get_default (), NULL, FALSE, FALSE); } static void -roster_window_edit_blocked_contacts_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_edit_blocked_contacts_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; GtkWidget *dialog; dialog = empathy_contact_blocking_dialog_new (GTK_WINDOW (self)); @@ -2028,30 +1690,40 @@ empathy_roster_window_show_preferences (EmpathyRosterWindow *self, } static void -roster_window_edit_preferences_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_edit_preferences_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_roster_window_show_preferences (self, NULL); } static void -roster_window_help_about_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_help_about_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_about_dialog_new (GTK_WINDOW (self)); } static void -roster_window_help_debug_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_help_debug_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { empathy_launch_program (BIN_DIR, "empathy-debugger", NULL); } static void -roster_window_help_contents_cb (GtkAction *action, - EmpathyRosterWindow *self) +roster_window_help_contents_cb (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { + EmpathyRosterWindow *self = user_data; + empathy_url_show (GTK_WIDGET (self), "help:empathy"); } @@ -2076,15 +1748,6 @@ roster_window_account_removed_cb (TpAccountManager *manager, TpAccount *account, EmpathyRosterWindow *self) { - GList *a; - - a = tp_account_manager_get_valid_accounts (manager); - - gtk_action_set_sensitive (self->priv->view_history, - g_list_length (a) > 0); - - g_list_free (a); - /* remove errors if any */ roster_window_remove_error (self, account); @@ -2229,20 +1892,8 @@ roster_window_account_validity_changed_cb (TpAccountManager *manager, } static void -roster_window_notify_show_offline_cb (GSettings *gsettings, - const gchar *key, - gpointer toggle_action) +roster_window_connection_items_setup (EmpathyRosterWindow *self) { - gtk_toggle_action_set_active (toggle_action, - g_settings_get_boolean (gsettings, key)); -} - -static void -roster_window_connection_items_setup (EmpathyRosterWindow *self, - GtkBuilder *gui) -{ - GList *list; - GObject *action; guint i; const gchar *actions_connected[] = { "room_join_new", @@ -2255,13 +1906,16 @@ roster_window_connection_items_setup (EmpathyRosterWindow *self, "edit_search_contacts" }; - for (i = 0, list = NULL; i < G_N_ELEMENTS (actions_connected); i++) + for (i = 0; i < G_N_ELEMENTS (actions_connected); i++) { - action = gtk_builder_get_object (gui, actions_connected[i]); - list = g_list_prepend (list, action); - } + GAction *action; + + action = g_action_map_lookup_action (G_ACTION_MAP (self), + actions_connected[i]); - self->priv->actions_connected = list; + self->priv->actions_connected = g_list_prepend ( + self->priv->actions_connected, action); + } } static void @@ -2314,10 +1968,6 @@ account_manager_prepared_cb (GObject *source_object, roster_window_update_status (self); - /* Disable the "Previous Conversations" menu entry if there is no account */ - gtk_action_set_sensitive (self->priv->view_history, - g_list_length (accounts) > 0); - set_notebook_page (self); g_list_free (accounts); @@ -2352,6 +2002,30 @@ empathy_roster_window_constructor (GType type, return window; } +static GActionEntry menubar_entries[] = { + { "chat_new_message", roster_window_chat_new_message_cb, NULL, NULL, NULL }, + { "chat_new_call", roster_window_chat_new_call_cb, NULL, NULL, NULL }, + { "chat_add_contact", roster_window_chat_add_contact_cb, NULL, NULL, NULL }, + { "chat_search_contacts", roster_window_chat_search_contacts_cb, NULL, NULL, NULL }, + { "chat_quit", roster_window_chat_quit_cb, NULL, NULL, NULL }, + + { "edit_accounts", roster_window_edit_accounts_cb, NULL, NULL, NULL }, + { "edit_search_contacts", roster_window_edit_search_contacts_cb, NULL, NULL, NULL }, + { "edit_blocked_contacts", roster_window_edit_blocked_contacts_cb, NULL, NULL, NULL }, + { "edit_preferences", roster_window_edit_preferences_cb, NULL, NULL, NULL }, + + { "view_history", roster_window_view_history_cb, NULL, NULL, NULL }, + { "view_show_ft_manager", roster_window_view_show_ft_manager, NULL, NULL, NULL }, + + { "room_join_new", roster_window_room_join_new_cb, NULL, NULL, NULL }, + { "room_join_favorites", roster_window_room_join_favorites_cb, NULL, NULL, NULL }, + { "room_manage_favorites", roster_window_room_manage_favorites_cb, NULL, NULL, NULL }, + + { "help_contents", roster_window_help_contents_cb, NULL, NULL, NULL }, + { "help_debug", roster_window_help_debug_cb, NULL, NULL, NULL }, + { "help_about", roster_window_help_about_cb, NULL, NULL, NULL }, +}; + static void empathy_roster_window_set_property (GObject *object, guint property_id, @@ -2391,6 +2065,12 @@ empathy_roster_window_get_property (GObject *object, } static void +empathy_roster_window_constructed (GObject *self) +{ + G_OBJECT_CLASS (empathy_roster_window_parent_class)->constructed (self); +} + +static void empathy_roster_window_class_init (EmpathyRosterWindowClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -2398,6 +2078,7 @@ empathy_roster_window_class_init (EmpathyRosterWindowClass *klass) object_class->finalize = empathy_roster_window_finalize; object_class->constructor = empathy_roster_window_constructor; + object_class->constructed = empathy_roster_window_constructed; object_class->set_property = empathy_roster_window_set_property; object_class->get_property = empathy_roster_window_get_property; @@ -2436,22 +2117,35 @@ contacts_loaded_cb (EmpathyIndividualManager *manager, } static void +roster_window_setup_actions (EmpathyRosterWindow *self) +{ + GAction *action; + +#define ADD_GSETTINGS_ACTION(schema, key) \ + action = g_settings_create_action (self->priv->gsettings_##schema, \ + EMPATHY_PREFS_##key); \ + g_action_map_add_action (G_ACTION_MAP (self), action); \ + g_object_unref (action); + + ADD_GSETTINGS_ACTION (ui, UI_SHOW_OFFLINE); + +#undef ADD_GSETTINGS_ACTION +} + +static void empathy_roster_window_init (EmpathyRosterWindow *self) { - GtkBuilder *gui, *gui_mgr; + GtkBuilder *gui; GtkWidget *sw; - GtkToggleAction *show_offline_widget; - GtkAction *show_map_widget; - GtkToolItem *item; - gboolean show_offline; gchar *filename; GtkTreeModel *model; GtkWidget *search_vbox; - GtkWidget *menubar; self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EMPATHY_TYPE_ROSTER_WINDOW, EmpathyRosterWindowPriv); + empathy_set_css_provider (GTK_WIDGET (self)); + self->priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA); self->priv->gsettings_contacts = g_settings_new (EMPATHY_PREFS_CONTACTS_SCHEMA); @@ -2482,73 +2176,13 @@ empathy_roster_window_init (EmpathyRosterWindow *self) NULL); g_free (filename); - /* Set UI manager */ - filename = empathy_file_lookup ("empathy-roster-window-menubar.ui", "src"); - gui_mgr = empathy_builder_get_file (filename, - "ui_manager", &self->priv->ui_manager, - "view_show_offline", &show_offline_widget, - "view_show_protocols", &self->priv->show_protocols, - "view_sort_by_name", &self->priv->sort_by_name, - "view_sort_by_status", &self->priv->sort_by_status, - "view_normal_size_with_avatars", &self->priv->normal_with_avatars, - "view_normal_size", &self->priv->normal_size, - "view_compact_size", &self->priv->compact_size, - "view_history", &self->priv->view_history, - "view_show_map", &show_map_widget, - "room_join_favorites", &self->priv->room_join_favorites, - "view_balance_show_in_roster", &self->priv->view_balance_show_in_roster, - "menubar", &menubar, - NULL); - g_free (filename); - - /* The UI manager is living in its own .ui file as Glade doesn't support - * those. The GtkMenubar has to be in this file as well to we manually add - * it to the first position of the vbox. */ - gtk_box_pack_start (GTK_BOX (self->priv->main_vbox), menubar, FALSE, FALSE, 0); - gtk_box_reorder_child (GTK_BOX (self->priv->main_vbox), menubar, 0); - gtk_container_add (GTK_CONTAINER (self), self->priv->main_vbox); gtk_widget_show (self->priv->main_vbox); g_signal_connect (self, "key-press-event", G_CALLBACK (roster_window_key_press_event_cb), NULL); - empathy_builder_connect (gui_mgr, self, - "chat_quit", "activate", roster_window_chat_quit_cb, - "chat_new_message", "activate", roster_window_chat_new_message_cb, - "chat_new_call", "activate", roster_window_chat_new_call_cb, - "view_history", "activate", roster_window_view_history_cb, - "room_join_new", "activate", roster_window_room_join_new_cb, - "room_join_favorites", "activate", roster_window_room_join_favorites_cb, - "room_manage_favorites", "activate", roster_window_room_manage_favorites_cb, - "chat_add_contact", "activate", roster_window_chat_add_contact_cb, - "chat_search_contacts", "activate", roster_window_chat_search_contacts_cb, - "view_show_ft_manager", "activate", roster_window_view_show_ft_manager, - "view_show_offline", "toggled", roster_window_view_show_offline_cb, - "view_show_protocols", "toggled", roster_window_view_show_protocols_cb, - "view_sort_by_name", "changed", roster_window_view_sort_contacts_cb, - "view_normal_size_with_avatars", "changed", roster_window_view_contacts_list_size_cb, - "view_show_map", "activate", roster_window_view_show_map_cb, - "edit", "activate", roster_window_edit_cb, - "edit_accounts", "activate", roster_window_edit_accounts_cb, - "edit_blocked_contacts", "activate", roster_window_edit_blocked_contacts_cb, - "edit_preferences", "activate", roster_window_edit_preferences_cb, - "edit_search_contacts", "activate", roster_window_edit_search_contacts_cb, - "help_about", "activate", roster_window_help_about_cb, - "help_debug", "activate", roster_window_help_debug_cb, - "help_contents", "activate", roster_window_help_contents_cb, - NULL); - - /* Set up connection related widgets. */ - roster_window_connection_items_setup (self, gui_mgr); - - g_object_ref (self->priv->ui_manager); g_object_unref (gui); - g_object_unref (gui_mgr); - -#ifndef HAVE_LIBCHAMPLAIN - gtk_action_set_visible (show_map_widget, FALSE); -#endif self->priv->account_manager = tp_account_manager_dup (); @@ -2563,16 +2197,26 @@ empathy_roster_window_init (EmpathyRosterWindow *self) self->priv->status_changed_handlers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); - /* Set up menu */ + /* set up menus */ + g_action_map_add_action_entries (G_ACTION_MAP (self), + menubar_entries, G_N_ELEMENTS (menubar_entries), self); + roster_window_setup_actions (self); + + filename = empathy_file_lookup ("empathy-roster-window-menubar.ui", "src"); + gui = empathy_builder_get_file (filename, + "appmenu", &self->priv->menumodel, + "rooms", &self->priv->rooms_section, + NULL); + g_free (filename); + + g_object_ref (self->priv->menumodel); + g_object_ref (self->priv->rooms_section); + + /* Set up connection related actions. */ + roster_window_connection_items_setup (self); roster_window_favorite_chatroom_menu_setup (self); - self->priv->edit_context = gtk_ui_manager_get_widget (self->priv->ui_manager, - "/menubar/edit/edit_context"); - self->priv->edit_context_separator = gtk_ui_manager_get_widget ( - self->priv->ui_manager, - "/menubar/edit/edit_context_separator"); - gtk_widget_hide (self->priv->edit_context); - gtk_widget_hide (self->priv->edit_context_separator); + g_object_unref (gui); /* Set up contact list. */ empathy_status_presets_get_all (); @@ -2580,13 +2224,9 @@ empathy_roster_window_init (EmpathyRosterWindow *self) /* Set up presence chooser */ self->priv->presence_chooser = empathy_presence_chooser_new (); gtk_widget_show (self->priv->presence_chooser); - item = gtk_tool_item_new (); - gtk_widget_show (GTK_WIDGET (item)); - gtk_widget_set_size_request (self->priv->presence_chooser, 10, -1); - gtk_container_add (GTK_CONTAINER (item), self->priv->presence_chooser); - gtk_tool_item_set_is_important (item, TRUE); - gtk_tool_item_set_expand (item, TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (self->priv->presence_toolbar), item, -1); + gtk_box_pack_start (GTK_BOX (self->priv->presence_toolbar), + self->priv->presence_chooser, + TRUE, TRUE, 0); /* Set up the throbber */ self->priv->throbber = gtk_spinner_new (); @@ -2595,18 +2235,10 @@ empathy_roster_window_init (EmpathyRosterWindow *self) g_signal_connect (self->priv->throbber, "button-press-event", G_CALLBACK (roster_window_throbber_button_press_event_cb), self); - gtk_widget_show (self->priv->throbber); - - item = gtk_tool_item_new (); - gtk_container_set_border_width (GTK_CONTAINER (item), 6); - gtk_toolbar_insert (GTK_TOOLBAR (self->priv->presence_toolbar), item, -1); - gtk_container_add (GTK_CONTAINER (item), self->priv->throbber); - self->priv->throbber_tool_item = GTK_WIDGET (item); - - /* XXX: this class is designed to live for the duration of the program, - * so it's got a race condition between its signal handlers and its - * finalization. The class is planned to be removed, so we won't fix - * this before then. */ + gtk_box_pack_start (GTK_BOX (self->priv->presence_toolbar), + self->priv->throbber, + FALSE, TRUE, 0); + self->priv->individual_manager = empathy_individual_manager_dup_singleton (); if (!empathy_individual_manager_get_contacts_loaded ( @@ -2675,20 +2307,10 @@ empathy_roster_window_init (EmpathyRosterWindow *self) /* Load user-defined accelerators. */ roster_window_accels_load (); + gtk_window_set_default_size (GTK_WINDOW (self), -1, 600); /* Set window size. */ empathy_geometry_bind (GTK_WINDOW (self), GEOMETRY_NAME); - /* bind view_balance_show_in_roster */ - g_settings_bind (self->priv->gsettings_ui, "show-balance-in-roster", - self->priv->view_balance_show_in_roster, "active", - G_SETTINGS_BIND_DEFAULT); - g_object_bind_property (self->priv->view_balance_show_in_roster, "active", - self->priv->balance_vbox, "visible", - G_BINDING_SYNC_CREATE); - - g_settings_bind (self->priv->gsettings_ui, "show-groups", - self->priv->individual_store, "show-groups", G_SETTINGS_BIND_DEFAULT); - /* Enable event handling */ self->priv->call_observer = empathy_call_observer_dup_singleton (); self->priv->event_manager = empathy_event_manager_dup_singleton (); @@ -2704,51 +2326,44 @@ empathy_roster_window_init (EmpathyRosterWindow *self) g_signal_connect (self->priv->account_manager, "account-disabled", G_CALLBACK (roster_window_account_disabled_cb), self); - /* Show offline ? */ - show_offline = g_settings_get_boolean (self->priv->gsettings_ui, - EMPATHY_PREFS_UI_SHOW_OFFLINE); - - g_signal_connect (self->priv->gsettings_ui, - "changed::" EMPATHY_PREFS_UI_SHOW_OFFLINE, - G_CALLBACK (roster_window_notify_show_offline_cb), show_offline_widget); - - gtk_toggle_action_set_active (show_offline_widget, show_offline); - - /* Show protocol ? */ - g_signal_connect (self->priv->gsettings_ui, - "changed::" EMPATHY_PREFS_UI_SHOW_PROTOCOLS, - G_CALLBACK (roster_window_notify_show_protocols_cb), self); - - roster_window_notify_show_protocols_cb (self->priv->gsettings_ui, - EMPATHY_PREFS_UI_SHOW_PROTOCOLS, self); - - /* Sort by name / by status ? */ - g_signal_connect (self->priv->gsettings_contacts, - "changed::" EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, - G_CALLBACK (roster_window_notify_sort_contact_cb), self); - - roster_window_notify_sort_contact_cb (self->priv->gsettings_contacts, - EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, self); - - /* Contacts list size */ - g_signal_connect (self->priv->gsettings_ui, - "changed::" EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, - G_CALLBACK (roster_window_notify_contact_list_size_cb), self); - - g_signal_connect (self->priv->gsettings_ui, - "changed::" EMPATHY_PREFS_UI_SHOW_AVATARS, - G_CALLBACK (roster_window_notify_contact_list_size_cb), - self); - - roster_window_notify_contact_list_size_cb (self->priv->gsettings_ui, - EMPATHY_PREFS_UI_SHOW_AVATARS, self); + g_settings_bind (self->priv->gsettings_ui, EMPATHY_PREFS_UI_SHOW_OFFLINE, + self->priv->individual_view, "show-offline", + G_SETTINGS_BIND_GET); + g_settings_bind (self->priv->gsettings_ui, EMPATHY_PREFS_UI_SHOW_PROTOCOLS, + self->priv->individual_store, "show-protocols", + G_SETTINGS_BIND_GET); + g_settings_bind (self->priv->gsettings_ui, EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST, + self->priv->individual_store, "is-compact", + G_SETTINGS_BIND_GET); + g_settings_bind (self->priv->gsettings_ui, EMPATHY_PREFS_UI_SHOW_AVATARS, + self->priv->individual_store, "show-avatars", + G_SETTINGS_BIND_GET); + g_settings_bind (self->priv->gsettings_contacts, EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM, + self->priv->individual_store, "sort-criterium", + G_SETTINGS_BIND_GET); + g_settings_bind (self->priv->gsettings_ui, EMPATHY_PREFS_UI_SHOW_GROUPS, + self->priv->individual_store, "show-groups", + G_SETTINGS_BIND_GET); + g_settings_bind (self->priv->gsettings_ui, "show-balance-in-roster", + self->priv->balance_vbox, "visible", + G_SETTINGS_BIND_GET); g_signal_connect (self->priv->button_account_settings, "clicked", G_CALLBACK (button_account_settings_clicked_cb), self); } GtkWidget * -empathy_roster_window_dup (void) +empathy_roster_window_new (GtkApplication *app) { - return g_object_new (EMPATHY_TYPE_ROSTER_WINDOW, NULL); + return g_object_new (EMPATHY_TYPE_ROSTER_WINDOW, + "application", app, + NULL); +} + +GMenuModel * +empathy_roster_window_get_menu_model (EmpathyRosterWindow *self) +{ + g_return_val_if_fail (EMPATHY_IS_ROSTER_WINDOW (self), NULL); + + return G_MENU_MODEL (self->priv->menumodel); } diff --git a/src/empathy-roster-window.h b/src/empathy-roster-window.h index 54404ad38..4620a9980 100644 --- a/src/empathy-roster-window.h +++ b/src/empathy-roster-window.h @@ -41,18 +41,18 @@ typedef struct _EmpathyRosterWindowPriv EmpathyRosterWindowPriv; struct _EmpathyRosterWindow { - GtkWindow parent; + GtkApplicationWindow parent; EmpathyRosterWindowPriv *priv; }; struct _EmpathyRosterWindowClass { - GtkWindowClass parent_class; + GtkApplicationWindowClass parent_class; }; GType empathy_roster_window_get_type (void); -GtkWidget *empathy_roster_window_dup (void); +GtkWidget * empathy_roster_window_new (GtkApplication *app); void empathy_roster_window_show_preferences (EmpathyRosterWindow *self, const gchar *tab); @@ -60,6 +60,8 @@ void empathy_roster_window_show_preferences (EmpathyRosterWindow *self, void empathy_roster_window_set_shell_running (EmpathyRosterWindow *self, gboolean shell_running); +GMenuModel *empathy_roster_window_get_menu_model (EmpathyRosterWindow *self); + G_END_DECLS #endif /* __EMPATHY_ROSTER_WINDOW_H__ */ diff --git a/src/empathy-roster-window.ui b/src/empathy-roster-window.ui index 8c8f63001..843f94e69 100644 --- a/src/empathy-roster-window.ui +++ b/src/empathy-roster-window.ui @@ -5,13 +5,11 @@ <property name="visible">True</property> <property name="can_focus">False</property> <child> - <object class="GtkToolbar" id="presence_toolbar"> + <object class="GtkHBox" id="presence_toolbar"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="toolbar_style">both</property> - <style> - <class name="primary-toolbar"/> - </style> + <property name="spacing">3</property> + <property name="border-width">3</property> </object> <packing> <property name="expand">False</property> @@ -101,7 +99,7 @@ <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_name">avatar-default-symbolic</property> <property name="icon-size">6</property> </object> <packing> diff --git a/src/empathy-streamed-media-factory.c b/src/empathy-streamed-media-factory.c deleted file mode 100644 index 713d441df..000000000 --- a/src/empathy-streamed-media-factory.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * empathy-streamed-media-factory.c - Source for EmpathyStreamedMediaFactory - * Copyright (C) 2008-2011 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 <stdio.h> -#include <stdlib.h> - -#include <telepathy-glib/account-channel-request.h> -#include <telepathy-glib/simple-handler.h> -#include <telepathy-glib/interfaces.h> -#include <telepathy-glib/util.h> - -#include <libempathy/empathy-request-util.h> -#include <libempathy/empathy-utils.h> - -#include "empathy-streamed-media-factory.h" -#include "empathy-streamed-media-handler.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_VOIP -#include <libempathy/empathy-debug.h> - -G_DEFINE_TYPE(EmpathyStreamedMediaFactory, empathy_streamed_media_factory, G_TYPE_OBJECT) - -static void handle_channels_cb (TpSimpleHandler *handler, - TpAccount *account, - TpConnection *connection, - GList *channels, - GList *requests_satisfied, - gint64 user_action_time, - TpHandleChannelsContext *context, - gpointer user_data); - -/* signal enum */ -enum -{ - NEW_STREAMED_MEDIA_HANDLER, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -/* private structure */ -typedef struct { - TpBaseClient *handler; - gboolean dispose_has_run; -} EmpathyStreamedMediaFactoryPriv; - -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyStreamedMediaFactory) - -static GObject *call_factory = NULL; - -static void -empathy_streamed_media_factory_init (EmpathyStreamedMediaFactory *obj) -{ - EmpathyStreamedMediaFactoryPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, - EMPATHY_TYPE_STREAMED_MEDIA_FACTORY, EmpathyStreamedMediaFactoryPriv); - TpAccountManager *am; - - obj->priv = priv; - - am = tp_account_manager_dup (); - - priv->handler = tp_simple_handler_new_with_am (am, FALSE, FALSE, - EMPATHY_AV_BUS_NAME_SUFFIX, FALSE, handle_channels_cb, obj, NULL); - - tp_base_client_take_handler_filter (priv->handler, tp_asv_new ( - TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, - NULL)); - - tp_base_client_take_handler_filter (priv->handler, tp_asv_new ( - TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, - TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, G_TYPE_BOOLEAN, TRUE, - NULL)); - - tp_base_client_take_handler_filter (priv->handler, tp_asv_new ( - TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, - TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, - TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT, - TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, G_TYPE_BOOLEAN, TRUE, - NULL)); - - tp_base_client_add_handler_capabilities_varargs (priv->handler, - "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); - - g_object_unref (am); -} - -static GObject * -empathy_streamed_media_factory_constructor (GType type, guint n_construct_params, - GObjectConstructParam *construct_params) -{ - g_return_val_if_fail (call_factory == NULL, NULL); - - call_factory = G_OBJECT_CLASS (empathy_streamed_media_factory_parent_class)->constructor - (type, n_construct_params, construct_params); - g_object_add_weak_pointer (call_factory, (gpointer)&call_factory); - - return call_factory; -} - -static void -empathy_streamed_media_factory_finalize (GObject *object) -{ - /* free any data held directly by the object here */ - - if (G_OBJECT_CLASS (empathy_streamed_media_factory_parent_class)->finalize) - G_OBJECT_CLASS (empathy_streamed_media_factory_parent_class)->finalize (object); -} - -static void -empathy_streamed_media_factory_dispose (GObject *object) -{ - EmpathyStreamedMediaFactoryPriv *priv = GET_PRIV (object); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - tp_clear_object (&priv->handler); - - if (G_OBJECT_CLASS (empathy_streamed_media_factory_parent_class)->dispose) - G_OBJECT_CLASS (empathy_streamed_media_factory_parent_class)->dispose (object); -} - -static void -empathy_streamed_media_factory_class_init ( - EmpathyStreamedMediaFactoryClass *empathy_streamed_media_factory_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (empathy_streamed_media_factory_class); - - g_type_class_add_private (empathy_streamed_media_factory_class, - sizeof (EmpathyStreamedMediaFactoryPriv)); - - object_class->constructor = empathy_streamed_media_factory_constructor; - object_class->dispose = empathy_streamed_media_factory_dispose; - object_class->finalize = empathy_streamed_media_factory_finalize; - - signals[NEW_STREAMED_MEDIA_HANDLER] = - g_signal_new ("new-streamed-media-handler", - G_TYPE_FROM_CLASS (empathy_streamed_media_factory_class), - G_SIGNAL_RUN_LAST, 0, - NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, - 2, EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, G_TYPE_BOOLEAN); -} - -EmpathyStreamedMediaFactory * -empathy_streamed_media_factory_initialise (void) -{ - g_return_val_if_fail (call_factory == NULL, NULL); - - return EMPATHY_STREAMED_MEDIA_FACTORY (g_object_new (EMPATHY_TYPE_STREAMED_MEDIA_FACTORY, NULL)); -} - -EmpathyStreamedMediaFactory * -empathy_streamed_media_factory_get (void) -{ - g_return_val_if_fail (call_factory != NULL, NULL); - - return EMPATHY_STREAMED_MEDIA_FACTORY (call_factory); -} - -static void -create_streamed_media_handler (EmpathyStreamedMediaFactory *factory, - EmpathyTpStreamedMedia *call) -{ - EmpathyStreamedMediaHandler *handler; - - g_return_if_fail (factory != NULL); - - handler = empathy_streamed_media_handler_new_for_channel (call); - - g_signal_emit (factory, signals[NEW_STREAMED_MEDIA_HANDLER], 0, - handler, FALSE); - - g_object_unref (handler); -} - -static void -call_status_changed_cb (EmpathyTpStreamedMedia *call, - GParamSpec *spec, - EmpathyStreamedMediaFactory *self) -{ - if (empathy_tp_streamed_media_get_status (call) <= EMPATHY_TP_STREAMED_MEDIA_STATUS_READYING) - return; - - create_streamed_media_handler (self, call); - - g_signal_handlers_disconnect_by_func (call, call_status_changed_cb, self); - g_object_unref (call); -} - -static void -handle_channels_cb (TpSimpleHandler *handler, - TpAccount *account, - TpConnection *connection, - GList *channels, - GList *requests_satisfied, - gint64 user_action_time, - TpHandleChannelsContext *context, - gpointer user_data) -{ - EmpathyStreamedMediaFactory *self = user_data; - GList *l; - - for (l = channels; l != NULL; l = g_list_next (l)) - { - TpChannel *channel = l->data; - EmpathyTpStreamedMedia *call; - - if (tp_proxy_get_invalidated (channel) != NULL) - continue; - - if (tp_channel_get_channel_type_id (channel) != - TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) - continue; - - call = empathy_tp_streamed_media_new (account, channel); - - if (empathy_tp_streamed_media_get_status (call) <= EMPATHY_TP_STREAMED_MEDIA_STATUS_READYING) - { - /* We have to wait that the TpStreamedMedia is ready as the - * call-handler rely on it. */ - tp_g_signal_connect_object (call, "notify::status", - G_CALLBACK (call_status_changed_cb), self, 0); - continue; - } - - create_streamed_media_handler (self, call); - g_object_unref (call); - } - - tp_handle_channels_context_accept (context); -} - -gboolean -empathy_streamed_media_factory_register (EmpathyStreamedMediaFactory *self, - GError **error) -{ - EmpathyStreamedMediaFactoryPriv *priv = GET_PRIV (self); - - return tp_base_client_register (priv->handler, error); -} diff --git a/src/empathy-streamed-media-factory.h b/src/empathy-streamed-media-factory.h deleted file mode 100644 index c69073ec4..000000000 --- a/src/empathy-streamed-media-factory.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * empathy-streamed-media-factory.h - Header for EmpathyStreamedMediaFactory - * Copyright (C) 2008-2011 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 - */ - -#ifndef __EMPATHY_STREAMED_MEDIA_FACTORY_H__ -#define __EMPATHY_STREAMED_MEDIA_FACTORY_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -typedef struct _EmpathyStreamedMediaFactory EmpathyStreamedMediaFactory; -typedef struct _EmpathyStreamedMediaFactoryClass EmpathyStreamedMediaFactoryClass; - -struct _EmpathyStreamedMediaFactoryClass { - GObjectClass parent_class; -}; - -struct _EmpathyStreamedMediaFactory { - GObject parent; - gpointer priv; -}; - -GType empathy_streamed_media_factory_get_type (void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_STREAMED_MEDIA_FACTORY \ - (empathy_streamed_media_factory_get_type ()) -#define EMPATHY_STREAMED_MEDIA_FACTORY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_STREAMED_MEDIA_FACTORY, \ - EmpathyStreamedMediaFactory)) -#define EMPATHY_STREAMED_MEDIA_FACTORY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_STREAMED_MEDIA_FACTORY, \ - EmpathyStreamedMediaFactoryClass)) -#define EMPATHY_IS_STREAMED_MEDIA_FACTORY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_STREAMED_MEDIA_FACTORY)) -#define EMPATHY_IS_STREAMED_MEDIA_FACTORY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_STREAMED_MEDIA_FACTORY)) -#define EMPATHY_STREAMED_MEDIA_FACTORY_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_STREAMED_MEDIA_FACTORY, \ - EmpathyStreamedMediaFactoryClass)) - - -EmpathyStreamedMediaFactory *empathy_streamed_media_factory_initialise (void); - -EmpathyStreamedMediaFactory *empathy_streamed_media_factory_get (void); - -gboolean empathy_streamed_media_factory_register (EmpathyStreamedMediaFactory *self, - GError **error); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_STREAMED_MEDIA_FACTORY_H__*/ diff --git a/src/empathy-streamed-media-handler.c b/src/empathy-streamed-media-handler.c deleted file mode 100644 index 5e2cac50f..000000000 --- a/src/empathy-streamed-media-handler.c +++ /dev/null @@ -1,921 +0,0 @@ -/* - * empathy-streamed-media-handler.c - Source for EmpathyStreamedMediaHandler - * Copyright (C) 2008-2011 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 <stdio.h> -#include <stdlib.h> - -#include <telepathy-glib/account-channel-request.h> -#include <telepathy-glib/util.h> -#include <telepathy-glib/interfaces.h> - -#include <telepathy-farstream/telepathy-farstream.h> - -#include <libempathy/empathy-utils.h> - -#include <libempathy-gtk/empathy-call-utils.h> - -#include "empathy-streamed-media-handler.h" - -#define DEBUG_FLAG EMPATHY_DEBUG_VOIP -#include <libempathy/empathy-debug.h> - -G_DEFINE_TYPE(EmpathyStreamedMediaHandler, empathy_streamed_media_handler, G_TYPE_OBJECT) - -/* signal enum */ -enum { - CONFERENCE_ADDED, - SRC_PAD_ADDED, - SINK_PAD_ADDED, - START_RECEIVING, - CLOSED, - STREAM_CLOSED, - CANDIDATES_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; - -enum { - PROP_TP_STREAMED_MEDIA = 1, - PROP_GST_BUS, - PROP_CONTACT, - PROP_INITIAL_AUDIO, - PROP_INITIAL_VIDEO, - PROP_SEND_AUDIO_CODEC, - PROP_SEND_VIDEO_CODEC, - PROP_RECV_AUDIO_CODECS, - PROP_RECV_VIDEO_CODECS, - PROP_AUDIO_REMOTE_CANDIDATE, - PROP_VIDEO_REMOTE_CANDIDATE, - PROP_AUDIO_LOCAL_CANDIDATE, - PROP_VIDEO_LOCAL_CANDIDATE, -}; - -/* private structure */ - -typedef struct { - gboolean dispose_has_run; - EmpathyTpStreamedMedia *call; - EmpathyContact *contact; - TfChannel *tfchannel; - gboolean initial_audio; - gboolean initial_video; - - FsCodec *send_audio_codec; - FsCodec *send_video_codec; - GList *recv_audio_codecs; - GList *recv_video_codecs; - FsCandidate *audio_remote_candidate; - FsCandidate *video_remote_candidate; - FsCandidate *audio_local_candidate; - FsCandidate *video_local_candidate; -} EmpathyStreamedMediaHandlerPriv; - -#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyStreamedMediaHandler) - -static void -empathy_streamed_media_handler_dispose (GObject *object) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (object); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - if (priv->contact != NULL) - g_object_unref (priv->contact); - - priv->contact = NULL; - - if (priv->tfchannel != NULL) - g_object_unref (priv->tfchannel); - - priv->tfchannel = NULL; - - if (priv->call != NULL) - { - empathy_tp_streamed_media_close (priv->call); - g_object_unref (priv->call); - } - - priv->call = NULL; - - /* release any references held by the object here */ - if (G_OBJECT_CLASS (empathy_streamed_media_handler_parent_class)->dispose) - G_OBJECT_CLASS (empathy_streamed_media_handler_parent_class)->dispose (object); -} - -static void -empathy_streamed_media_handler_finalize (GObject *object) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (object); - - fs_codec_destroy (priv->send_audio_codec); - fs_codec_destroy (priv->send_video_codec); - fs_codec_list_destroy (priv->recv_audio_codecs); - fs_codec_list_destroy (priv->recv_video_codecs); - fs_candidate_destroy (priv->audio_remote_candidate); - fs_candidate_destroy (priv->video_remote_candidate); - fs_candidate_destroy (priv->audio_local_candidate); - fs_candidate_destroy (priv->video_local_candidate); - - if (G_OBJECT_CLASS (empathy_streamed_media_handler_parent_class)->finalize) - G_OBJECT_CLASS (empathy_streamed_media_handler_parent_class)->finalize (object); -} - -static void -empathy_streamed_media_handler_init (EmpathyStreamedMediaHandler *obj) -{ - EmpathyStreamedMediaHandlerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (obj, - EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, EmpathyStreamedMediaHandlerPriv); - - obj->priv = priv; -} - -static void -empathy_streamed_media_handler_constructed (GObject *object) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (object); - - if (priv->contact == NULL) - { - g_object_get (priv->call, "contact", &(priv->contact), NULL); - } -} - -static void -empathy_streamed_media_handler_set_property (GObject *object, - guint property_id, const GValue *value, GParamSpec *pspec) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_CONTACT: - priv->contact = g_value_dup_object (value); - break; - case PROP_TP_STREAMED_MEDIA: - priv->call = g_value_dup_object (value); - break; - case PROP_INITIAL_AUDIO: - priv->initial_audio = g_value_get_boolean (value); - break; - case PROP_INITIAL_VIDEO: - priv->initial_video = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -empathy_streamed_media_handler_get_property (GObject *object, - guint property_id, GValue *value, GParamSpec *pspec) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_CONTACT: - g_value_set_object (value, priv->contact); - break; - case PROP_TP_STREAMED_MEDIA: - g_value_set_object (value, priv->call); - break; - case PROP_INITIAL_AUDIO: - g_value_set_boolean (value, priv->initial_audio); - break; - case PROP_INITIAL_VIDEO: - g_value_set_boolean (value, priv->initial_video); - break; - case PROP_SEND_AUDIO_CODEC: - g_value_set_boxed (value, priv->send_audio_codec); - break; - case PROP_SEND_VIDEO_CODEC: - g_value_set_boxed (value, priv->send_video_codec); - break; - case PROP_RECV_AUDIO_CODECS: - g_value_set_boxed (value, priv->recv_audio_codecs); - break; - case PROP_RECV_VIDEO_CODECS: - g_value_set_boxed (value, priv->recv_video_codecs); - break; - case PROP_AUDIO_REMOTE_CANDIDATE: - g_value_set_boxed (value, priv->audio_remote_candidate); - break; - case PROP_VIDEO_REMOTE_CANDIDATE: - g_value_set_boxed (value, priv->video_remote_candidate); - break; - case PROP_AUDIO_LOCAL_CANDIDATE: - g_value_set_boxed (value, priv->audio_local_candidate); - break; - case PROP_VIDEO_LOCAL_CANDIDATE: - g_value_set_boxed (value, priv->video_local_candidate); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - - -static void -empathy_streamed_media_handler_class_init (EmpathyStreamedMediaHandlerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GParamSpec *param_spec; - - g_type_class_add_private (klass, sizeof (EmpathyStreamedMediaHandlerPriv)); - - object_class->constructed = empathy_streamed_media_handler_constructed; - object_class->set_property = empathy_streamed_media_handler_set_property; - object_class->get_property = empathy_streamed_media_handler_get_property; - object_class->dispose = empathy_streamed_media_handler_dispose; - object_class->finalize = empathy_streamed_media_handler_finalize; - - param_spec = g_param_spec_object ("contact", - "contact", "The remote contact", - EMPATHY_TYPE_CONTACT, - 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_object ("tp-call", - "tp-call", "The calls channel wrapper", - EMPATHY_TYPE_TP_STREAMED_MEDIA, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_TP_STREAMED_MEDIA, param_spec); - - param_spec = g_param_spec_boolean ("initial-audio", - "initial-audio", "Whether the call should start with audio", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INITIAL_AUDIO, - param_spec); - - param_spec = g_param_spec_boolean ("initial-video", - "initial-video", "Whether the call should start with video", - FALSE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_INITIAL_VIDEO, - param_spec); - - param_spec = g_param_spec_boxed ("send-audio-codec", - "send audio codec", "Codec used to encode the outgoing video stream", - FS_TYPE_CODEC, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_SEND_AUDIO_CODEC, - param_spec); - - param_spec = g_param_spec_boxed ("send-video-codec", - "send video codec", "Codec used to encode the outgoing video stream", - FS_TYPE_CODEC, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_SEND_VIDEO_CODEC, - param_spec); - - param_spec = g_param_spec_boxed ("recv-audio-codecs", - "recvs audio codec", "Codecs used to decode the incoming audio stream", - FS_TYPE_CODEC_LIST, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_RECV_AUDIO_CODECS, - param_spec); - - param_spec = g_param_spec_boxed ("recv-video-codecs", - "recvs video codec", "Codecs used to decode the incoming video stream", - FS_TYPE_CODEC_LIST, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_RECV_VIDEO_CODECS, - param_spec); - - param_spec = g_param_spec_boxed ("audio-remote-candidate", - "audio remote candidate", - "Remote candidate used for the audio stream", - FS_TYPE_CANDIDATE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_AUDIO_REMOTE_CANDIDATE, param_spec); - - param_spec = g_param_spec_boxed ("video-remote-candidate", - "video remote candidate", - "Remote candidate used for the video stream", - FS_TYPE_CANDIDATE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_VIDEO_REMOTE_CANDIDATE, param_spec); - - param_spec = g_param_spec_boxed ("audio-local-candidate", - "audio local candidate", - "Local candidate used for the audio stream", - FS_TYPE_CANDIDATE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_AUDIO_REMOTE_CANDIDATE, param_spec); - - param_spec = g_param_spec_boxed ("video-local-candidate", - "video local candidate", - "Local candidate used for the video stream", - FS_TYPE_CANDIDATE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_VIDEO_REMOTE_CANDIDATE, param_spec); - - signals[CONFERENCE_ADDED] = - g_signal_new ("conference-added", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, - 1, FS_TYPE_CONFERENCE); - - signals[SRC_PAD_ADDED] = - g_signal_new ("src-pad-added", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_BOOLEAN, - 2, GST_TYPE_PAD, G_TYPE_UINT); - - signals[SINK_PAD_ADDED] = - g_signal_new ("sink-pad-added", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_BOOLEAN, - 2, GST_TYPE_PAD, G_TYPE_UINT); - - 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, - G_TYPE_BOOLEAN, 2, G_TYPE_UINT, G_TYPE_UINT); - - signals[CLOSED] = - g_signal_new ("closed", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, - 0); - - signals[STREAM_CLOSED] = - 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_CONTENT); - - signals[CANDIDATES_CHANGED] = - g_signal_new ("candidates-changed", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, 1, G_TYPE_UINT); -} - -/** - * empathy_streamed_media_handler_new_for_contact: - * @contact: an #EmpathyContact - * - * Creates a new #EmpathyStreamedMediaHandler with contact @contact. - * - * Return value: a new #EmpathyStreamedMediaHandler - */ -EmpathyStreamedMediaHandler * -empathy_streamed_media_handler_new_for_contact (EmpathyContact *contact) -{ - return EMPATHY_STREAMED_MEDIA_HANDLER (g_object_new (EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, - "contact", contact, NULL)); -} - -EmpathyStreamedMediaHandler * -empathy_streamed_media_handler_new_for_channel (EmpathyTpStreamedMedia *call) -{ - return EMPATHY_STREAMED_MEDIA_HANDLER (g_object_new (EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, - "tp-call", call, - "initial-video", empathy_tp_streamed_media_is_receiving_video (call), - NULL)); -} - -static void -update_sending_codec (EmpathyStreamedMediaHandler *self, - FsCodec *codec, - FsSession *session) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - FsMediaType type; - - if (codec == NULL || session == NULL) - return; - - g_object_get (session, "media-type", &type, NULL); - - if (type == FS_MEDIA_TYPE_AUDIO) - { - priv->send_audio_codec = fs_codec_copy (codec); - g_object_notify (G_OBJECT (self), "send-audio-codec"); - } - else if (type == FS_MEDIA_TYPE_VIDEO) - { - priv->send_video_codec = fs_codec_copy (codec); - g_object_notify (G_OBJECT (self), "send-video-codec"); - } -} - -static void -update_receiving_codec (EmpathyStreamedMediaHandler *self, - GList *codecs, - FsStream *stream) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - FsSession *session; - FsMediaType type; - - if (codecs == NULL || stream == NULL) - return; - - g_object_get (stream, "session", &session, NULL); - if (session == NULL) - return; - - g_object_get (session, "media-type", &type, NULL); - - if (type == FS_MEDIA_TYPE_AUDIO) - { - priv->recv_audio_codecs = fs_codec_list_copy (codecs); - g_object_notify (G_OBJECT (self), "recv-audio-codecs"); - } - else if (type == FS_MEDIA_TYPE_VIDEO) - { - priv->recv_video_codecs = fs_codec_list_copy (codecs); - g_object_notify (G_OBJECT (self), "recv-video-codecs"); - } - - g_object_unref (session); -} - -static void -update_candidates (EmpathyStreamedMediaHandler *self, - FsCandidate *remote_candidate, - FsCandidate *local_candidate, - FsStream *stream) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - FsSession *session; - FsMediaType type; - - if (stream == NULL) - return; - - g_object_get (stream, "session", &session, NULL); - if (session == NULL) - return; - - g_object_get (session, "media-type", &type, NULL); - - if (type == FS_MEDIA_TYPE_AUDIO) - { - if (remote_candidate != NULL) - { - fs_candidate_destroy (priv->audio_remote_candidate); - priv->audio_remote_candidate = fs_candidate_copy (remote_candidate); - g_object_notify (G_OBJECT (self), "audio-remote-candidate"); - } - - if (local_candidate != NULL) - { - fs_candidate_destroy (priv->audio_local_candidate); - priv->audio_local_candidate = fs_candidate_copy (local_candidate); - g_object_notify (G_OBJECT (self), "audio-local-candidate"); - } - - g_signal_emit (G_OBJECT (self), signals[CANDIDATES_CHANGED], 0, - FS_MEDIA_TYPE_AUDIO); - } - else if (type == FS_MEDIA_TYPE_VIDEO) - { - if (remote_candidate != NULL) - { - fs_candidate_destroy (priv->video_remote_candidate); - priv->video_remote_candidate = fs_candidate_copy (remote_candidate); - g_object_notify (G_OBJECT (self), "video-remote-candidate"); - } - - if (local_candidate != NULL) - { - fs_candidate_destroy (priv->video_local_candidate); - priv->video_local_candidate = fs_candidate_copy (local_candidate); - g_object_notify (G_OBJECT (self), "video-local-candidate"); - } - - g_signal_emit (G_OBJECT (self), signals[CANDIDATES_CHANGED], 0, - FS_MEDIA_TYPE_VIDEO); - } - - g_object_unref (session); -} - -void -empathy_streamed_media_handler_bus_message (EmpathyStreamedMediaHandler *handler, - GstBus *bus, GstMessage *message) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (handler); - const GstStructure *s = gst_message_get_structure (message); - - if (priv->tfchannel == NULL) - return; - - if (s != NULL && - gst_structure_has_name (s, "farstream-send-codec-changed")) - { - const GValue *val; - FsCodec *codec; - FsSession *session; - - val = gst_structure_get_value (s, "codec"); - codec = g_value_get_boxed (val); - - val = gst_structure_get_value (s, "session"); - session = g_value_get_object (val); - - update_sending_codec (handler, codec, session); - } - else if (s != NULL && - gst_structure_has_name (s, "farstream-recv-codecs-changed")) - { - const GValue *val; - GList *codecs; - FsStream *stream; - - val = gst_structure_get_value (s, "codecs"); - codecs = g_value_get_boxed (val); - - val = gst_structure_get_value (s, "stream"); - stream = g_value_get_object (val); - - update_receiving_codec (handler, codecs, stream); - } - else if (s != NULL && - gst_structure_has_name (s, "farstream-new-active-candidate-pair")) - { - const GValue *val; - FsCandidate *remote_candidate, *local_candidate; - FsStream *stream; - - val = gst_structure_get_value (s, "remote-candidate"); - remote_candidate = g_value_get_boxed (val); - - val = gst_structure_get_value (s, "local-candidate"); - local_candidate = g_value_get_boxed (val); - - val = gst_structure_get_value (s, "stream"); - stream = g_value_get_object (val); - - update_candidates (handler, remote_candidate, local_candidate, stream); - } - - tf_channel_bus_message (priv->tfchannel, message); -} - -static void -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, - GST_ELEMENT (conference)); -} - -static gboolean -src_pad_added_error_idle (gpointer data) -{ - TfContent *content = data; - - tf_content_error_literal (content, "Could not link sink"); - g_object_unref (content); - - return FALSE; -} - -static void -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 (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 (content)); -} - - -static gboolean -empathy_streamed_media_handler_tf_content_start_receiving_cb (TfContent *content, - guint *handles, guint handle_count, EmpathyTpStreamedMedia *call) -{ - gboolean ret = FALSE; - guint media_type; - - g_object_get (G_OBJECT (content), "media-type", &media_type, NULL); - - g_signal_emit (G_OBJECT (call), - signals[START_RECEIVING], 0, media_type, &ret); - - return ret; -} - -static void -empathy_streamed_media_handler_tf_content_removed_cb (TfChannel *channel, - TfContent *content, EmpathyStreamedMediaHandler *handler) -{ - g_signal_emit (handler, signals[STREAM_CLOSED], 0, content); -} - -static void -empathy_streamed_media_handler_tf_channel_content_added_cb (TfChannel *tfchannel, - TfContent *content, EmpathyStreamedMediaHandler *handler) -{ - guint media_type; - GstPad *spad; - gboolean retval; - FsSession *session; - FsCodec *codec; - - 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_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_content_error_literal (content, "Could not link source"); - - /* Get sending codec */ - g_object_get (content, "fs-session", &session, NULL); - g_object_get (session, "current-send-codec", &codec, NULL); - - update_sending_codec (handler, codec, session); - - tp_clear_object (&session); - tp_clear_object (&codec); - - gst_object_unref (spad); -} - -static void -empathy_streamed_media_handler_tf_channel_closed_cb (TfChannel *tfchannel, - EmpathyStreamedMediaHandler *handler) -{ - g_signal_emit (G_OBJECT (handler), signals[CLOSED], 0); -} - -static void -empathy_streamed_media_handler_start_tpfs (GAsyncInitable *initable, - GAsyncResult *res, EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - GError *error = NULL; - GPtrArray *conferences; - - 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); - } - - 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 -empathy_streamed_media_handler_request_cb (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - EmpathyStreamedMediaHandler *self = EMPATHY_STREAMED_MEDIA_HANDLER (user_data); - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - TpChannel *channel; - GError *error = NULL; - TpAccountChannelRequest *req = TP_ACCOUNT_CHANNEL_REQUEST (source); - TpAccount *account; - - channel = tp_account_channel_request_create_and_handle_channel_finish (req, - result, NULL, &error); - if (channel == NULL) - { - DEBUG ("Failed to create the channel: %s", error->message); - g_error_free (error); - return; - } - - account = tp_account_channel_request_get_account (req); - - priv->call = empathy_tp_streamed_media_new (account, channel); - - g_object_notify (G_OBJECT (self), "tp-call"); - - - tf_channel_new_async (channel, - (GAsyncReadyCallback) empathy_streamed_media_handler_start_tpfs, - g_object_ref (self)); - - g_object_unref (channel); -} - -void -empathy_streamed_media_handler_start_call (EmpathyStreamedMediaHandler *handler, - gint64 timestamp) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (handler); - TpAccountChannelRequest *req; - TpAccount *account; - GHashTable *request; - - if (priv->call != NULL) - { - 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; - } - - /* No TpStreamedMedia object (we are redialing). Request a new media channel that - * will be used to create a new EmpathyTpStreamedMedia. */ - g_assert (priv->contact != NULL); - - account = empathy_contact_get_account (priv->contact); - request = empathy_call_create_streamed_media_request ( - empathy_contact_get_id (priv->contact), - priv->initial_audio, priv->initial_video); - - req = tp_account_channel_request_new (account, request, timestamp); - - tp_account_channel_request_create_and_handle_channel_async (req, NULL, - empathy_streamed_media_handler_request_cb, handler); - - g_object_unref (req); - g_hash_table_unref (request); -} - -/** - * empathy_streamed_media_handler_stop_call: - * @handler: an #EmpathyStreamedMediaHandler - * - * Closes the #EmpathyStreamedMediaHandler's call and frees its resources. - */ -void -empathy_streamed_media_handler_stop_call (EmpathyStreamedMediaHandler *handler) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (handler); - - if (priv->call != NULL) - { - empathy_tp_streamed_media_leave (priv->call); - g_object_unref (priv->call); - } - - priv->call = NULL; -} - -/** - * empathy_streamed_media_handler_has_initial_video: - * @handler: an #EmpathyStreamedMediaHandler - * - * Return %TRUE if the call managed by this #EmpathyStreamedMediaHandler was - * created with video enabled - * - * Return value: %TRUE if the call was created as a video conversation. - */ -gboolean -empathy_streamed_media_handler_has_initial_video (EmpathyStreamedMediaHandler *handler) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (handler); - - return priv->initial_video; -} - -FsCodec * -empathy_streamed_media_handler_get_send_audio_codec (EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->send_audio_codec; -} - -FsCodec * -empathy_streamed_media_handler_get_send_video_codec (EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->send_video_codec; -} - -GList * -empathy_streamed_media_handler_get_recv_audio_codecs (EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->recv_audio_codecs; -} - -GList * -empathy_streamed_media_handler_get_recv_video_codecs (EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->recv_video_codecs; -} - -FsCandidate * -empathy_streamed_media_handler_get_audio_remote_candidate ( - EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->audio_remote_candidate; -} - -FsCandidate * -empathy_streamed_media_handler_get_audio_local_candidate ( - EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->audio_local_candidate; -} - -FsCandidate * -empathy_streamed_media_handler_get_video_remote_candidate ( - EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->video_remote_candidate; -} - -FsCandidate * -empathy_streamed_media_handler_get_video_local_candidate ( - EmpathyStreamedMediaHandler *self) -{ - EmpathyStreamedMediaHandlerPriv *priv = GET_PRIV (self); - - return priv->video_local_candidate; -} diff --git a/src/empathy-streamed-media-handler.h b/src/empathy-streamed-media-handler.h deleted file mode 100644 index 429c95447..000000000 --- a/src/empathy-streamed-media-handler.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * empathy-streamed-media-handler.h - Header for EmpathyStreamedMediaHandler - * Copyright (C) 2008-2009 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 - */ - -#ifndef __EMPATHY_STREAMED_MEDIA_HANDLER_H__ -#define __EMPATHY_STREAMED_MEDIA_HANDLER_H__ - -#include <glib-object.h> - -#include <gst/gst.h> -#include <farstream/fs-conference.h> - -#include <libempathy/empathy-tp-streamed-media.h> -#include <libempathy/empathy-contact.h> - -G_BEGIN_DECLS - -typedef struct _EmpathyStreamedMediaHandler EmpathyStreamedMediaHandler; -typedef struct _EmpathyStreamedMediaHandlerClass EmpathyStreamedMediaHandlerClass; - -struct _EmpathyStreamedMediaHandlerClass { - GObjectClass parent_class; -}; - -struct _EmpathyStreamedMediaHandler { - GObject parent; - gpointer priv; -}; - -GType empathy_streamed_media_handler_get_type (void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_STREAMED_MEDIA_HANDLER \ - (empathy_streamed_media_handler_get_type ()) -#define EMPATHY_STREAMED_MEDIA_HANDLER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, \ - EmpathyStreamedMediaHandler)) -#define EMPATHY_STREAMED_MEDIA_HANDLER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, \ - EmpathyStreamedMediaHandlerClass)) -#define EMPATHY_IS_STREAMED_MEDIA_HANDLER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_STREAMED_MEDIA_HANDLER)) -#define EMPATHY_IS_STREAMED_MEDIA_HANDLER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_STREAMED_MEDIA_HANDLER)) -#define EMPATHY_STREAMED_MEDIA_HANDLER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, \ - EmpathyStreamedMediaHandlerClass)) - -EmpathyStreamedMediaHandler * empathy_streamed_media_handler_new_for_contact ( - EmpathyContact *contact); - -EmpathyStreamedMediaHandler * empathy_streamed_media_handler_new_for_channel ( - EmpathyTpStreamedMedia *call); - -void empathy_streamed_media_handler_start_call (EmpathyStreamedMediaHandler *handler, - gint64 timestamp); -void empathy_streamed_media_handler_stop_call (EmpathyStreamedMediaHandler *handler); - -gboolean empathy_streamed_media_handler_has_initial_video (EmpathyStreamedMediaHandler *handler); - -void empathy_streamed_media_handler_bus_message (EmpathyStreamedMediaHandler *handler, - GstBus *bus, GstMessage *message); - -FsCodec * empathy_streamed_media_handler_get_send_audio_codec ( - EmpathyStreamedMediaHandler *self); - -FsCodec * empathy_streamed_media_handler_get_send_video_codec ( - EmpathyStreamedMediaHandler *self); - -GList * empathy_streamed_media_handler_get_recv_audio_codecs ( - EmpathyStreamedMediaHandler *self); - -GList * empathy_streamed_media_handler_get_recv_video_codecs ( - EmpathyStreamedMediaHandler *self); - -FsCandidate * empathy_streamed_media_handler_get_audio_remote_candidate ( - EmpathyStreamedMediaHandler *self); - -FsCandidate * empathy_streamed_media_handler_get_audio_local_candidate ( - EmpathyStreamedMediaHandler *self); - -FsCandidate * empathy_streamed_media_handler_get_video_remote_candidate ( - EmpathyStreamedMediaHandler *self); - -FsCandidate * empathy_streamed_media_handler_get_video_local_candidate ( - EmpathyStreamedMediaHandler *self); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_STREAMED_MEDIA_HANDLER_H__*/ diff --git a/src/empathy-streamed-media-window-fullscreen.c b/src/empathy-streamed-media-window-fullscreen.c deleted file mode 100644 index caa34ffd1..000000000 --- a/src/empathy-streamed-media-window-fullscreen.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * empathy-streamed-media-window-fullscreen.c - Source for EmpathyStreamedMediaWindowFullscreen - * Copyright (C) 2009 Collabora Ltd. - * - * Some code is based on the Totem Movie Player, especially - * totem-fullscreen.c which has the following copyright: - * Copyright (C) 2001-2007 Bastien Nocera <hadess@hadess.net> - * Copyright (C) 2007 Sunil Mohan Adapa <sunilmohan@gnu.org.in> - * - * 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 "empathy-streamed-media-window-fullscreen.h" - -#include <gtk/gtk.h> - -#include <libempathy/empathy-utils.h> -#include <libempathy-gtk/empathy-ui-utils.h> - -/* The number of seconds for which the "leave fullscreen" popup should - be shown */ -#define FULLSCREEN_POPUP_TIMEOUT 5 - -G_DEFINE_TYPE (EmpathyStreamedMediaWindowFullscreen, empathy_streamed_media_window_fullscreen, - G_TYPE_OBJECT) - -/* private structure */ -typedef struct _EmpathyStreamedMediaWindowFullscreenPriv - EmpathyStreamedMediaWindowFullscreenPriv; - -struct _EmpathyStreamedMediaWindowFullscreenPriv -{ - EmpathyStreamedMediaWindow *parent_window; - - GtkWidget *leave_fullscreen_popup; - GtkWidget *video_widget; - - guint popup_timeout; - gboolean popup_creation_in_progress; - gboolean dispose_has_run; -}; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN, \ - EmpathyStreamedMediaWindowFullscreenPriv)) - -static void empathy_streamed_media_window_fullscreen_dispose (GObject *object); -static void empathy_streamed_media_window_fullscreen_finalize (GObject *object); - -static gboolean empathy_streamed_media_window_fullscreen_hide_popup ( - EmpathyStreamedMediaWindowFullscreen *fs); - -static void -empathy_streamed_media_window_fullscreen_set_cursor_visible ( - EmpathyStreamedMediaWindowFullscreen *fs, - gboolean show_cursor) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (fs); - GdkWindow *window; - - if (priv->video_widget == NULL) - return; - - window = gtk_widget_get_window (priv->video_widget); - - if (!show_cursor) - gdk_window_set_cursor (window, gdk_cursor_new (GDK_BLANK_CURSOR)); - else - gdk_window_set_cursor (window, NULL); -} - -static void -empathy_streamed_media_window_fullscreen_add_popup_timeout ( - EmpathyStreamedMediaWindowFullscreen *self) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - - if (priv->popup_timeout == 0) - { - priv->popup_timeout = g_timeout_add_seconds (FULLSCREEN_POPUP_TIMEOUT, - (GSourceFunc) empathy_streamed_media_window_fullscreen_hide_popup, self); - } -} - -static void -empathy_streamed_media_window_fullscreen_remove_popup_timeout ( - EmpathyStreamedMediaWindowFullscreen *self) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - - if (priv->popup_timeout != 0) - { - g_source_remove (priv->popup_timeout); - priv->popup_timeout = 0; - } -} - -void -empathy_streamed_media_window_fullscreen_show_popup (EmpathyStreamedMediaWindowFullscreen *self) -{ - gint leave_fullscreen_width, leave_fullscreen_height; - GdkScreen *screen; - GdkRectangle fullscreen_rect; - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - - g_assert (self->is_fullscreen); - - g_return_if_fail (priv->parent_window != NULL); - - if (priv->popup_creation_in_progress) - return; - - if (!gtk_window_is_active (GTK_WINDOW (priv->parent_window))) - return; - - priv->popup_creation_in_progress = TRUE; - - empathy_streamed_media_window_fullscreen_set_cursor_visible (self, TRUE); - - /* Obtaining the screen rectangle */ - screen = gtk_window_get_screen (GTK_WINDOW (priv->parent_window)); - gdk_screen_get_monitor_geometry (screen, - gdk_screen_get_monitor_at_window (screen, - gtk_widget_get_window (GTK_WIDGET (priv->parent_window))), - &fullscreen_rect); - - /* Getting the popup window sizes */ - gtk_window_get_size (GTK_WINDOW (priv->leave_fullscreen_popup), - &leave_fullscreen_width, &leave_fullscreen_height); - - /* Moving the popup to the top-right corner (if the direction is LTR) or the - top-left corner (if the direction is RTL).*/ - if (gtk_widget_get_direction (priv->leave_fullscreen_popup) - == GTK_TEXT_DIR_LTR) - { - gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), - fullscreen_rect.width + fullscreen_rect.x - leave_fullscreen_width, - fullscreen_rect.y); - - } - else - { - gtk_window_move (GTK_WINDOW (priv->leave_fullscreen_popup), - fullscreen_rect.x, fullscreen_rect.y); - } - - gtk_widget_show_all (priv->leave_fullscreen_popup); - empathy_streamed_media_window_fullscreen_add_popup_timeout (self); - - priv->popup_creation_in_progress = FALSE; -} - -static gboolean -empathy_streamed_media_window_fullscreen_hide_popup (EmpathyStreamedMediaWindowFullscreen *fs) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (fs); - - if (priv->video_widget == NULL || !fs->is_fullscreen) - return TRUE; - - gtk_widget_hide (priv->leave_fullscreen_popup); - empathy_streamed_media_window_fullscreen_remove_popup_timeout (fs); - - empathy_streamed_media_window_fullscreen_set_cursor_visible (fs, FALSE); - - return FALSE; -} - -static void -empathy_streamed_media_window_fullscreen_init (EmpathyStreamedMediaWindowFullscreen *self) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - GtkBuilder *gui; - gchar *filename; - - filename = empathy_file_lookup ("empathy-call-window-fullscreen.ui", "src"); - gui = empathy_builder_get_file (filename, - "leave_fullscreen_window", &priv->leave_fullscreen_popup, - "leave_fullscreen_button", &self->leave_fullscreen_button, - NULL); - - gtk_widget_add_events (priv->leave_fullscreen_popup, GDK_POINTER_MOTION_MASK); - - g_object_unref (gui); - g_free (filename); -} - -static void -empathy_streamed_media_window_fullscreen_class_init ( - EmpathyStreamedMediaWindowFullscreenClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (EmpathyStreamedMediaWindowFullscreenPriv)); - - object_class->dispose = empathy_streamed_media_window_fullscreen_dispose; - object_class->finalize = empathy_streamed_media_window_fullscreen_finalize; -} - -void -empathy_streamed_media_window_fullscreen_dispose (GObject *object) -{ - EmpathyStreamedMediaWindowFullscreen *self = EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN (object); - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - if (priv->leave_fullscreen_popup != NULL) - gtk_widget_destroy (priv->leave_fullscreen_popup); - priv->leave_fullscreen_popup = NULL; - - if (G_OBJECT_CLASS (empathy_streamed_media_window_fullscreen_parent_class)->dispose) - { - G_OBJECT_CLASS ( - empathy_streamed_media_window_fullscreen_parent_class)->dispose (object); - } -} - -void -empathy_streamed_media_window_fullscreen_finalize (GObject *object) -{ - EmpathyStreamedMediaWindowFullscreen *self = EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN (object); - - empathy_streamed_media_window_fullscreen_remove_popup_timeout (self); - - G_OBJECT_CLASS ( - empathy_streamed_media_window_fullscreen_parent_class)->finalize (object); -} - -static void -empathy_streamed_media_window_fullscreen_parent_window_notify (GtkWidget *parent_window, - GParamSpec *property, EmpathyStreamedMediaWindowFullscreen *fs) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (fs); - - if (!fs->is_fullscreen) - return; - - if (parent_window == GTK_WIDGET (priv->parent_window) && - !gtk_window_is_active (GTK_WINDOW (parent_window))) - { - empathy_streamed_media_window_fullscreen_hide_popup (fs); - empathy_streamed_media_window_fullscreen_set_cursor_visible (fs, TRUE); - } -} - -EmpathyStreamedMediaWindowFullscreen * -empathy_streamed_media_window_fullscreen_new (EmpathyStreamedMediaWindow *parent_window) -{ - EmpathyStreamedMediaWindowFullscreen *self = EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN ( - g_object_new (EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN, NULL)); - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - - priv->parent_window = parent_window; - g_signal_connect (G_OBJECT (priv->parent_window), "notify::is-active", - G_CALLBACK (empathy_streamed_media_window_fullscreen_parent_window_notify), self); - - return self; -} - -void -empathy_streamed_media_window_fullscreen_set_fullscreen (EmpathyStreamedMediaWindowFullscreen *fs, - gboolean set_fullscreen) -{ - - if (set_fullscreen) - empathy_streamed_media_window_fullscreen_remove_popup_timeout (fs); - else - empathy_streamed_media_window_fullscreen_hide_popup (fs); - - empathy_streamed_media_window_fullscreen_set_cursor_visible (fs, !set_fullscreen); - fs->is_fullscreen = set_fullscreen; -} - -static void -video_widget_destroy_cb (GtkWidget *widget, - EmpathyStreamedMediaWindowFullscreen *self) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (self); - - priv->video_widget = NULL; -} - -void -empathy_streamed_media_window_fullscreen_set_video_widget ( - EmpathyStreamedMediaWindowFullscreen *fs, - GtkWidget *video_widget) -{ - EmpathyStreamedMediaWindowFullscreenPriv *priv = GET_PRIV (fs); - priv->video_widget = video_widget; - - tp_g_signal_connect_object (video_widget, "destroy", - G_CALLBACK (video_widget_destroy_cb), fs, 0); -} diff --git a/src/empathy-streamed-media-window-fullscreen.h b/src/empathy-streamed-media-window-fullscreen.h deleted file mode 100644 index bdb95fb0b..000000000 --- a/src/empathy-streamed-media-window-fullscreen.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * empathy-streamed-media-window-fullscreen.h - Header for EmpathyStreamedMediaWindowFullscreen - * 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 - */ - -#ifndef __EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN_H__ -#define __EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN_H__ - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "empathy-streamed-media-window.h" - -G_BEGIN_DECLS - -typedef struct _EmpathyStreamedMediaWindowFullscreen EmpathyStreamedMediaWindowFullscreen; -typedef struct _EmpathyStreamedMediaWindowFullscreenClass - EmpathyStreamedMediaWindowFullscreenClass; - -struct _EmpathyStreamedMediaWindowFullscreenClass { - GObjectClass parent_class; -}; - -struct _EmpathyStreamedMediaWindowFullscreen { - GObject parent; - gboolean is_fullscreen; - GtkWidget *leave_fullscreen_button; -}; - -GType empathy_streamed_media_window_fullscreen_get_type (void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN \ - (empathy_streamed_media_window_fullscreen_get_type ()) -#define EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN, \ - EmpathyStreamedMediaWindowFullscreen)) -#define EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN, \ - EmpathyStreamedMediaWindowClassFullscreen)) -#define EMPATHY_IS_STREAMED_MEDIA_WINDOW_FULLSCREEN(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN)) -#define EMPATHY_IS_STREAMED_MEDIA_WINDOW_FULLSCREEN_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN)) -#define EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW_FULLSCREEN, \ - EmpathyStreamedMediaWindowFullscreenClass)) - -EmpathyStreamedMediaWindowFullscreen *empathy_streamed_media_window_fullscreen_new ( - EmpathyStreamedMediaWindow *parent); - -void empathy_streamed_media_window_fullscreen_set_fullscreen ( - EmpathyStreamedMediaWindowFullscreen *fs, - gboolean set_fullscreen); -void empathy_streamed_media_window_fullscreen_set_video_widget ( - EmpathyStreamedMediaWindowFullscreen *fs, - GtkWidget *video_widget); -void empathy_streamed_media_window_fullscreen_show_popup ( - EmpathyStreamedMediaWindowFullscreen *fs); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_STREAMED_MEDIA_WINDOW_FULLSCREEN_H__*/ diff --git a/src/empathy-streamed-media-window.c b/src/empathy-streamed-media-window.c deleted file mode 100644 index 0984e5bb8..000000000 --- a/src/empathy-streamed-media-window.c +++ /dev/null @@ -1,3200 +0,0 @@ -/* - * empathy-streamed-media-window.c - Source for EmpathyStreamedMediaWindow - * Copyright (C) 2008-2009 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 <stdio.h> -#include <stdlib.h> - -#include <math.h> - -#include <gdk/gdkkeysyms.h> -#include <gst/gst.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> - -#include <telepathy-glib/util.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> -#include <libempathy-gtk/empathy-avatar-image.h> -#include <libempathy-gtk/empathy-dialpad-widget.h> -#include <libempathy-gtk/empathy-ui-utils.h> -#include <libempathy-gtk/empathy-sound-manager.h> -#include <libempathy-gtk/empathy-geometry.h> -#include <libempathy-gtk/empathy-images.h> - -#define DEBUG_FLAG EMPATHY_DEBUG_VOIP -#include <libempathy/empathy-debug.h> - -#include "empathy-streamed-media-window.h" -#include "empathy-streamed-media-window-fullscreen.h" -#include "empathy-video-widget.h" -#include "empathy-audio-src.h" -#include "empathy-audio-sink.h" -#include "empathy-video-src.h" -#include "ev-sidebar.h" - -#define CONTENT_HBOX_BORDER_WIDTH 6 -#define CONTENT_HBOX_SPACING 3 -#define CONTENT_HBOX_CHILDREN_PACKING_PADDING 3 - -#define SELF_VIDEO_SECTION_WIDTH 160 -#define SELF_VIDEO_SECTION_HEIGTH 120 - -/* The avatar's default width and height are set to the same value because we - want a square icon. */ -#define REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT -#define REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT \ - EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT - -/* If an video input error occurs, the error message will start with "v4l" */ -#define VIDEO_INPUT_ERROR_PREFIX "v4l" - -/* The time interval in milliseconds between 2 outgoing rings */ -#define MS_BETWEEN_RING 500 - -G_DEFINE_TYPE(EmpathyStreamedMediaWindow, empathy_streamed_media_window, GTK_TYPE_WINDOW) - -/* signal enum */ -#if 0 -enum -{ - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; -#endif - -enum { - PROP_STREAMED_MEDIA_HANDLER = 1, -}; - -typedef enum { - CONNECTING, - CONNECTED, - DISCONNECTED, - REDIALING -} CallState; - -typedef enum { - CAMERA_STATE_OFF = 0, - CAMERA_STATE_PREVIEW, - CAMERA_STATE_ON, -} CameraState; - -/* private structure */ -typedef struct _EmpathyStreamedMediaWindowPriv EmpathyStreamedMediaWindowPriv; - -struct _EmpathyStreamedMediaWindowPriv -{ - gboolean dispose_has_run; - EmpathyStreamedMediaHandler *handler; - EmpathyContact *contact; - - guint call_state; - gboolean outgoing; - - GtkUIManager *ui_manager; - GtkWidget *errors_vbox; - /* widget displays the video received from the remote user. This widget is - * alive only during call. */ - GtkWidget *video_output; - GtkWidget *video_preview; - GtkWidget *remote_user_avatar_widget; - GtkWidget *self_user_avatar_widget; - GtkWidget *sidebar; - GtkWidget *sidebar_button; - GtkWidget *statusbar; - GtkWidget *volume_button; - GtkWidget *redial_button; - GtkWidget *mic_button; - GtkWidget *toolbar; - GtkWidget *pane; - GtkAction *redial; - GtkAction *menu_fullscreen; - GtkAction *action_camera_on; - GtkWidget *tool_button_camera_off; - GtkWidget *tool_button_camera_preview; - GtkWidget *tool_button_camera_on; - - /* The frames and boxes that contain self and remote avatar and video - input/output. When we redial, we destroy and re-create the boxes */ - GtkWidget *remote_user_output_frame; - GtkWidget *self_user_output_frame; - GtkWidget *remote_user_output_hbox; - GtkWidget *self_user_output_hbox; - - /* We keep a reference on the hbox which contains the main content so we can - easilly repack everything when toggling fullscreen */ - GtkWidget *content_hbox; - - /* This vbox is contained in the content_hbox and it contains the - self_user_output_frame and the sidebar button. When toggling fullscreen, - it needs to be repacked. We keep a reference on it for easier access. */ - GtkWidget *vbox; - - gulong video_output_motion_handler_id; - guint bus_message_source_id; - - gdouble volume; - GtkWidget *volume_scale; - GtkWidget *volume_progress_bar; - GtkAdjustment *audio_input_adj; - - GtkWidget *dtmf_panel; - - /* Details vbox */ - GtkWidget *details_vbox; - GtkWidget *vcodec_encoding_label; - GtkWidget *acodec_encoding_label; - GtkWidget *vcodec_decoding_label; - GtkWidget *acodec_decoding_label; - - GtkWidget *audio_remote_candidate_label; - GtkWidget *audio_local_candidate_label; - GtkWidget *video_remote_candidate_label; - GtkWidget *video_local_candidate_label; - GtkWidget *video_remote_candidate_info_img; - GtkWidget *video_local_candidate_info_img; - GtkWidget *audio_remote_candidate_info_img; - GtkWidget *audio_local_candidate_info_img; - - GstElement *video_input; - GstElement *audio_input; - GstElement *audio_output; - GstElement *pipeline; - GstElement *video_tee; - - GstElement *funnel; - - FsElementAddedNotifier *fsnotifier; - - guint context_id; - - GTimer *timer; - guint timer_id; - - GtkWidget *video_contrast; - GtkWidget *video_brightness; - GtkWidget *video_gamma; - - GMutex *lock; - gboolean call_started; - gboolean sending_video; - CameraState camera_state; - - EmpathyStreamedMediaWindowFullscreen *fullscreen; - gboolean is_fullscreen; - - /* Those fields represent the state of the window before it actually was in - fullscreen mode. */ - gboolean sidebar_was_visible_before_fs; - gint original_width_before_fs; - gint original_height_before_fs; - - /* TRUE if the call should be started when the pipeline is playing */ - gboolean start_call_when_playing; - /* TRUE if we requested to set the pipeline in the playing state */ - gboolean pipeline_playing; - - EmpathySoundManager *sound_mgr; -}; - -#define GET_PRIV(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW, \ - EmpathyStreamedMediaWindowPriv)) - -static void empathy_streamed_media_window_realized_cb (GtkWidget *widget, - EmpathyStreamedMediaWindow *window); - -static gboolean empathy_streamed_media_window_delete_cb (GtkWidget *widget, - GdkEvent *event, EmpathyStreamedMediaWindow *window); - -static gboolean empathy_streamed_media_window_state_event_cb (GtkWidget *widget, - GdkEventWindowState *event, EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_sidebar_toggled_cb (GtkToggleButton *toggle, - EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_set_send_video (EmpathyStreamedMediaWindow *window, - CameraState state); - -static void empathy_streamed_media_window_mic_toggled_cb ( - GtkToggleToolButton *toggle, EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_sidebar_hidden_cb (EvSidebar *sidebar, - EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_sidebar_shown_cb (EvSidebar *sidebar, - EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_hangup_cb (gpointer object, - EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_fullscreen_cb (gpointer object, - EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_fullscreen_toggle (EmpathyStreamedMediaWindow *window); - -static gboolean empathy_streamed_media_window_video_button_press_cb ( - GtkWidget *video_output, GdkEventButton *event, EmpathyStreamedMediaWindow *window); - -static gboolean empathy_streamed_media_window_key_press_cb (GtkWidget *video_output, - GdkEventKey *event, EmpathyStreamedMediaWindow *window); - -static gboolean empathy_streamed_media_window_video_output_motion_notify ( - GtkWidget *widget, GdkEventMotion *event, EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_video_menu_popup (EmpathyStreamedMediaWindow *window, - guint button); - -static void empathy_streamed_media_window_redial_cb (gpointer object, - EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_restart_call (EmpathyStreamedMediaWindow *window); - -static void empathy_streamed_media_window_status_message (EmpathyStreamedMediaWindow *window, - gchar *message); - -static void empathy_streamed_media_window_update_avatars_visibility (EmpathyTpStreamedMedia *call, - EmpathyStreamedMediaWindow *window); - -static gboolean empathy_streamed_media_window_bus_message (GstBus *bus, - GstMessage *message, gpointer user_data); - -static void -empathy_streamed_media_window_volume_changed_cb (GtkScaleButton *button, - gdouble value, EmpathyStreamedMediaWindow *window); - -static void block_camera_control_signals (EmpathyStreamedMediaWindow *self); -static void unblock_camera_control_signals (EmpathyStreamedMediaWindow *self); - -static void -empathy_streamed_media_window_setup_toolbar (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GtkToolItem *tool_item; - GtkWidget *camera_off_icon; - GdkPixbuf *pixbuf, *modded_pixbuf; - - /* set the icon of the 'camera off' button by greying off the webcam icon */ - pixbuf = empathy_pixbuf_from_icon_name ("camera-web", - GTK_ICON_SIZE_SMALL_TOOLBAR); - - modded_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, - gdk_pixbuf_get_width (pixbuf), - gdk_pixbuf_get_height (pixbuf)); - - gdk_pixbuf_saturate_and_pixelate (pixbuf, modded_pixbuf, 1.0, TRUE); - g_object_unref (pixbuf); - - camera_off_icon = gtk_image_new_from_pixbuf (modded_pixbuf); - g_object_unref (modded_pixbuf); - gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON ( - priv->tool_button_camera_off), camera_off_icon); - - /* Add an empty expanded GtkToolItem so the volume button is at the end of - * the toolbar. */ - tool_item = gtk_tool_item_new (); - gtk_tool_item_set_expand (tool_item, TRUE); - gtk_widget_show (GTK_WIDGET (tool_item)); - gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), tool_item, -1); - - priv->volume_button = gtk_volume_button_new (); - /* FIXME listen to the audiosinks signals and update the button according to - * that, for now starting out at 1.0 and assuming only the app changes the - * volume will do */ - gtk_scale_button_set_value (GTK_SCALE_BUTTON (priv->volume_button), 1.0); - g_signal_connect (G_OBJECT (priv->volume_button), "value-changed", - G_CALLBACK (empathy_streamed_media_window_volume_changed_cb), self); - - tool_item = gtk_tool_item_new (); - gtk_container_add (GTK_CONTAINER (tool_item), priv->volume_button); - gtk_widget_show_all (GTK_WIDGET (tool_item)); - gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), tool_item, -1); -} - -static void -dtmf_start_tone_cb (EmpathyDialpadWidget *dialpad, - TpDTMFEvent event, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - EmpathyTpStreamedMedia *call; - - g_object_get (priv->handler, "tp-call", &call, NULL); - - empathy_tp_streamed_media_start_tone (call, event); - - g_object_unref (call); -} - -static void -dtmf_stop_tone_cb (EmpathyDialpadWidget *self, - TpDTMFEvent event, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - EmpathyTpStreamedMedia *call; - - g_object_get (priv->handler, "tp-call", &call, NULL); - - empathy_tp_streamed_media_stop_tone (call); - - g_object_unref (call); -} - -static GtkWidget * -empathy_streamed_media_window_create_video_input_add_slider (EmpathyStreamedMediaWindow *self, - gchar *label_text, GtkWidget *bin) -{ - GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); - 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); - - gtk_container_add (GTK_CONTAINER (bin), vbox); - - gtk_range_set_inverted (GTK_RANGE (scale), TRUE); - gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - return scale; -} - -static void -empathy_streamed_media_window_video_contrast_changed_cb (GtkAdjustment *adj, - EmpathyStreamedMediaWindow *self) - -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - empathy_video_src_set_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_CONTRAST, gtk_adjustment_get_value (adj)); -} - -static void -empathy_streamed_media_window_video_brightness_changed_cb (GtkAdjustment *adj, - EmpathyStreamedMediaWindow *self) - -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - empathy_video_src_set_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_BRIGHTNESS, gtk_adjustment_get_value (adj)); -} - -static void -empathy_streamed_media_window_video_gamma_changed_cb (GtkAdjustment *adj, - EmpathyStreamedMediaWindow *self) - -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - empathy_video_src_set_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_GAMMA, gtk_adjustment_get_value (adj)); -} - - -static GtkWidget * -empathy_streamed_media_window_create_video_input (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GtkWidget *hbox; - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); - - priv->video_contrast = empathy_streamed_media_window_create_video_input_add_slider ( - self, _("Contrast"), hbox); - - priv->video_brightness = empathy_streamed_media_window_create_video_input_add_slider ( - self, _("Brightness"), hbox); - - priv->video_gamma = empathy_streamed_media_window_create_video_input_add_slider ( - self, _("Gamma"), hbox); - - return hbox; -} - -static void -empathy_streamed_media_window_setup_video_input (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - guint supported; - GtkAdjustment *adj; - - supported = empathy_video_src_get_supported_channels (priv->video_input); - - if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_CONTRAST) - { - adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_contrast)); - - gtk_adjustment_set_value (adj, - empathy_video_src_get_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_CONTRAST)); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_streamed_media_window_video_contrast_changed_cb), self); - - gtk_widget_set_sensitive (priv->video_contrast, TRUE); - } - - if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_BRIGHTNESS) - { - adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_brightness)); - - gtk_adjustment_set_value (adj, - empathy_video_src_get_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_BRIGHTNESS)); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_streamed_media_window_video_brightness_changed_cb), self); - gtk_widget_set_sensitive (priv->video_brightness, TRUE); - } - - if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_GAMMA) - { - adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_gamma)); - - gtk_adjustment_set_value (adj, - empathy_video_src_get_channel (priv->video_input, - EMPATHY_GST_VIDEO_SRC_CHANNEL_GAMMA)); - - g_signal_connect (G_OBJECT (adj), "value-changed", - G_CALLBACK (empathy_streamed_media_window_video_gamma_changed_cb), self); - gtk_widget_set_sensitive (priv->video_gamma, TRUE); - } -} - -static void -empathy_streamed_media_window_mic_volume_changed_cb (GtkAdjustment *adj, - EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - gdouble volume; - - volume = gtk_adjustment_get_value (adj)/100.0; - - /* Don't store the volume because of muting */ - if (volume > 0 || gtk_toggle_tool_button_get_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button))) - priv->volume = volume; - - /* Ensure that the toggle button is active if the volume is > 0 and inactive - * if it's smaller than 0 */ - if ((volume > 0) != gtk_toggle_tool_button_get_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button))) - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button), volume > 0); - - empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input), - volume); -} - -static void -empathy_streamed_media_window_audio_input_level_changed_cb (EmpathyGstAudioSrc *src, - gdouble level, EmpathyStreamedMediaWindow *window) -{ - gdouble value; - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - value = CLAMP (pow (10, level / 20), 0.0, 1.0); - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->volume_progress_bar), - value); -} - -static GtkWidget * -empathy_streamed_media_window_create_audio_input (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GtkWidget *hbox, *vbox, *label; - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3); - - 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")); - - priv->audio_input_adj = gtk_range_get_adjustment ( - GTK_RANGE (priv->volume_scale)); - priv->volume = empathy_audio_src_get_volume (EMPATHY_GST_AUDIO_SRC - (priv->audio_input)); - gtk_adjustment_set_value (priv->audio_input_adj, priv->volume * 100); - - g_signal_connect (G_OBJECT (priv->audio_input_adj), "value-changed", - G_CALLBACK (empathy_streamed_media_window_mic_volume_changed_cb), self); - - gtk_box_pack_start (GTK_BOX (vbox), priv->volume_scale, TRUE, TRUE, 3); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 3); - - priv->volume_progress_bar = gtk_progress_bar_new (); - - gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->volume_progress_bar), - GTK_ORIENTATION_VERTICAL); - - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->volume_progress_bar), - 0); - - gtk_box_pack_start (GTK_BOX (hbox), priv->volume_progress_bar, FALSE, FALSE, - 3); - - return hbox; -} - -static void -create_video_output_widget (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstBus *bus; - - g_assert (priv->video_output == NULL); - g_assert (priv->pipeline != NULL); - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - priv->video_output = empathy_video_widget_new (bus); - - gtk_box_pack_start (GTK_BOX (priv->remote_user_output_hbox), - priv->video_output, TRUE, TRUE, 0); - - gtk_widget_add_events (priv->video_output, - GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK); - g_signal_connect (G_OBJECT (priv->video_output), "button-press-event", - G_CALLBACK (empathy_streamed_media_window_video_button_press_cb), self); - - g_object_unref (bus); -} - -static void -create_video_input (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - g_assert (priv->video_input == NULL); - priv->video_input = empathy_video_src_new (); - gst_object_ref_sink (priv->video_input); -} - -static void -create_audio_input (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - g_assert (priv->audio_input == NULL); - priv->audio_input = empathy_audio_src_new (); - gst_object_ref_sink (priv->audio_input); - - tp_g_signal_connect_object (priv->audio_input, "peak-level-changed", - G_CALLBACK (empathy_streamed_media_window_audio_input_level_changed_cb), - self, 0); -} - -static void -add_video_preview_to_pipeline (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstElement *preview; - - g_assert (priv->video_preview != NULL); - g_assert (priv->pipeline != NULL); - g_assert (priv->video_input != NULL); - g_assert (priv->video_tee != NULL); - - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - - if (!gst_bin_add (GST_BIN (priv->pipeline), priv->video_input)) - { - g_warning ("Could not add video input to pipeline"); - return; - } - - if (!gst_bin_add (GST_BIN (priv->pipeline), priv->video_tee)) - { - g_warning ("Could not add video tee to pipeline"); - return; - } - - if (!gst_bin_add (GST_BIN (priv->pipeline), preview)) - { - g_warning ("Could not add video preview to pipeline"); - return; - } - - if (!gst_element_link (priv->video_input, priv->video_tee)) - { - g_warning ("Could not link video input to video tee"); - return; - } - - if (!gst_element_link (priv->video_tee, preview)) - { - g_warning ("Could not link video tee to video preview"); - return; - } -} - -static void -create_video_preview (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstBus *bus; - - g_assert (priv->video_preview == NULL); - g_assert (priv->video_tee == NULL); - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - - priv->video_preview = empathy_video_widget_new_with_size (bus, - SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); - g_object_set (priv->video_preview, - "sync", FALSE, - "async", TRUE, - "flip-video", TRUE, - NULL); - - gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), - priv->video_preview, TRUE, TRUE, 0); - - priv->video_tee = gst_element_factory_make ("tee", NULL); - gst_object_ref_sink (priv->video_tee); - - g_object_unref (bus); -} - -static void -play_camera (EmpathyStreamedMediaWindow *window, - gboolean play) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - GstElement *preview; - GstState state; - - if (priv->video_preview == NULL) - { - create_video_preview (window); - add_video_preview_to_pipeline (window); - } - - if (play) - state = GST_STATE_PLAYING; - else - state = GST_STATE_NULL; - - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - - gst_element_set_state (preview, state); - gst_element_set_state (priv->video_input, state); - gst_element_set_state (priv->video_tee, state); -} - -static void -display_video_preview (EmpathyStreamedMediaWindow *self, - gboolean display) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (display) - { - /* Display the preview and hide the self avatar */ - DEBUG ("Show video preview"); - - play_camera (self, TRUE); - gtk_widget_show (priv->video_preview); - gtk_widget_hide (priv->self_user_avatar_widget); - } - else - { - /* Display the self avatar and hide the preview */ - DEBUG ("Show self avatar"); - - if (priv->video_preview != NULL) - { - gtk_widget_hide (priv->video_preview); - play_camera (self, FALSE); - } - gtk_widget_show (priv->self_user_avatar_widget); - } -} - -static void -empathy_streamed_media_window_set_state_connecting (EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - empathy_streamed_media_window_status_message (window, _("Connecting…")); - priv->call_state = CONNECTING; - - if (priv->outgoing) - empathy_sound_manager_start_playing (priv->sound_mgr, GTK_WIDGET (window), - EMPATHY_SOUND_PHONE_OUTGOING, MS_BETWEEN_RING); -} - -static void -disable_camera (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (priv->camera_state == CAMERA_STATE_OFF) - return; - - DEBUG ("Disable camera"); - - display_video_preview (self, FALSE); - - if (priv->camera_state == CAMERA_STATE_ON) - empathy_streamed_media_window_set_send_video (self, CAMERA_STATE_OFF); - - block_camera_control_signals (self); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_on), FALSE); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_preview), FALSE); - - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_off), TRUE); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (priv->action_camera_on), - CAMERA_STATE_OFF); - unblock_camera_control_signals (self); - - priv->camera_state = CAMERA_STATE_OFF; -} - -static void -tool_button_camera_off_toggled_cb (GtkToggleToolButton *toggle, - EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (!gtk_toggle_tool_button_get_active (toggle)) - { - if (priv->camera_state == CAMERA_STATE_OFF) - { - /* We can't change the state by disabling the button */ - block_camera_control_signals (self); - gtk_toggle_tool_button_set_active (toggle, TRUE); - unblock_camera_control_signals (self); - } - - return; - } - - disable_camera (self); -} - -static void -enable_preview (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (priv->camera_state == CAMERA_STATE_PREVIEW) - return; - - DEBUG ("Enable preview"); - - if (priv->camera_state == CAMERA_STATE_ON) - { - /* preview is already displayed so we just have to stop sending */ - empathy_streamed_media_window_set_send_video (self, CAMERA_STATE_PREVIEW); - } - else - { - display_video_preview (self, TRUE); - } - - block_camera_control_signals (self); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_off), FALSE); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_on), FALSE); - - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_preview), TRUE); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (priv->action_camera_on), - CAMERA_STATE_PREVIEW); - unblock_camera_control_signals (self); - - priv->camera_state = CAMERA_STATE_PREVIEW; -} - -static void -tool_button_camera_preview_toggled_cb (GtkToggleToolButton *toggle, - EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (!gtk_toggle_tool_button_get_active (toggle)) - { - if (priv->camera_state == CAMERA_STATE_PREVIEW) - { - /* We can't change the state by disabling the button */ - block_camera_control_signals (self); - gtk_toggle_tool_button_set_active (toggle, TRUE); - unblock_camera_control_signals (self); - } - - return; - } - - enable_preview (self); -} - -static void -enable_camera (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (priv->camera_state == CAMERA_STATE_ON) - return; - - if (priv->video_input == NULL) - { - DEBUG ("Can't enable camera, no input"); - return; - } - - - DEBUG ("Enable camera"); - - empathy_streamed_media_window_set_send_video (self, CAMERA_STATE_ON); - - block_camera_control_signals (self); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_off), FALSE); - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_preview), FALSE); - - gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( - priv->tool_button_camera_on), TRUE); - gtk_radio_action_set_current_value (GTK_RADIO_ACTION (priv->action_camera_on), - CAMERA_STATE_ON); - unblock_camera_control_signals (self); - - priv->camera_state = CAMERA_STATE_ON; -} - -static void -tool_button_camera_on_toggled_cb (GtkToggleToolButton *toggle, - EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (!gtk_toggle_tool_button_get_active (toggle)) - { - if (priv->camera_state == CAMERA_STATE_ON) - { - /* We can't change the state by disabling the button */ - block_camera_control_signals (self); - gtk_toggle_tool_button_set_active (toggle, TRUE); - unblock_camera_control_signals (self); - } - - return; - } - - enable_camera (self); -} - -static void -action_camera_change_cb (GtkRadioAction *action, - GtkRadioAction *current, - EmpathyStreamedMediaWindow *self) -{ - CameraState state; - - state = gtk_radio_action_get_current_value (current); - - switch (state) - { - case CAMERA_STATE_OFF: - disable_camera (self); - break; - - case CAMERA_STATE_PREVIEW: - enable_preview (self); - break; - - case CAMERA_STATE_ON: - enable_camera (self); - break; - - default: - g_assert_not_reached (); - } -} - -static void -create_pipeline (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstBus *bus; - - g_assert (priv->pipeline == NULL); - - priv->pipeline = gst_pipeline_new (NULL); - priv->pipeline_playing = FALSE; - - bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline)); - priv->bus_message_source_id = gst_bus_add_watch (bus, - empathy_streamed_media_window_bus_message, self); - - g_object_unref (bus); -} - - -static void -empathy_streamed_media_window_init (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GtkBuilder *gui; - GtkWidget *top_vbox; - GtkWidget *h; - GtkWidget *arrow; - GtkWidget *page; - gchar *filename; - GtkWidget *scroll; - - filename = empathy_file_lookup ("empathy-streamed-media-window.ui", "src"); - gui = empathy_builder_get_file (filename, - "call_window_vbox", &top_vbox, - "errors_vbox", &priv->errors_vbox, - "pane", &priv->pane, - "statusbar", &priv->statusbar, - "redial", &priv->redial_button, - "microphone", &priv->mic_button, - "toolbar", &priv->toolbar, - "menuredial", &priv->redial, - "ui_manager", &priv->ui_manager, - "menufullscreen", &priv->menu_fullscreen, - "camera_off", &priv->tool_button_camera_off, - "camera_preview", &priv->tool_button_camera_preview, - "camera_on", &priv->tool_button_camera_on, - "action_camera_on", &priv->action_camera_on, - "details_vbox", &priv->details_vbox, - "vcodec_encoding_label", &priv->vcodec_encoding_label, - "acodec_encoding_label", &priv->acodec_encoding_label, - "acodec_decoding_label", &priv->acodec_decoding_label, - "vcodec_decoding_label", &priv->vcodec_decoding_label, - "audio_remote_candidate_label", &priv->audio_remote_candidate_label, - "audio_local_candidate_label", &priv->audio_local_candidate_label, - "video_remote_candidate_label", &priv->video_remote_candidate_label, - "video_local_candidate_label", &priv->video_local_candidate_label, - "video_remote_candidate_info_img", &priv->video_remote_candidate_info_img, - "video_local_candidate_info_img", &priv->video_local_candidate_info_img, - "audio_remote_candidate_info_img", &priv->audio_remote_candidate_info_img, - "audio_local_candidate_info_img", &priv->audio_local_candidate_info_img, - NULL); - g_free (filename); - - empathy_builder_connect (gui, self, - "menuhangup", "activate", empathy_streamed_media_window_hangup_cb, - "hangup", "clicked", empathy_streamed_media_window_hangup_cb, - "menuredial", "activate", empathy_streamed_media_window_redial_cb, - "redial", "clicked", empathy_streamed_media_window_redial_cb, - "microphone", "toggled", empathy_streamed_media_window_mic_toggled_cb, - "menufullscreen", "activate", empathy_streamed_media_window_fullscreen_cb, - "camera_off", "toggled", tool_button_camera_off_toggled_cb, - "camera_preview", "toggled", tool_button_camera_preview_toggled_cb, - "camera_on", "toggled", tool_button_camera_on_toggled_cb, - "action_camera_on", "changed", action_camera_change_cb, - NULL); - - gtk_action_set_sensitive (priv->menu_fullscreen, FALSE); - - priv->lock = g_mutex_new (); - - gtk_container_add (GTK_CONTAINER (self), top_vbox); - - priv->content_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, - CONTENT_HBOX_SPACING); - gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), - CONTENT_HBOX_BORDER_WIDTH); - gtk_paned_pack1 (GTK_PANED (priv->pane), priv->content_hbox, TRUE, FALSE); - - /* remote user output frame */ - priv->remote_user_output_frame = gtk_frame_new (NULL); - gtk_widget_set_size_request (priv->remote_user_output_frame, - EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH, EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT); - gtk_box_pack_start (GTK_BOX (priv->content_hbox), - priv->remote_user_output_frame, TRUE, TRUE, - CONTENT_HBOX_CHILDREN_PACKING_PADDING); - - priv->remote_user_output_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - - priv->remote_user_avatar_widget = gtk_image_new (); - - gtk_box_pack_start (GTK_BOX (priv->remote_user_output_hbox), - priv->remote_user_avatar_widget, TRUE, TRUE, 0); - - gtk_container_add (GTK_CONTAINER (priv->remote_user_output_frame), - priv->remote_user_output_hbox); - - /* self user output frame */ - priv->self_user_output_frame = gtk_frame_new (NULL); - gtk_widget_set_size_request (priv->self_user_output_frame, - SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH); - - priv->self_user_output_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - - priv->self_user_avatar_widget = gtk_image_new (); - gtk_box_pack_start (GTK_BOX (priv->self_user_output_hbox), - priv->self_user_avatar_widget, TRUE, TRUE, 0); - - gtk_container_add (GTK_CONTAINER (priv->self_user_output_frame), - priv->self_user_output_hbox); - - create_pipeline (self); - create_video_output_widget (self); - create_audio_input (self); - create_video_input (self); - - priv->fsnotifier = fs_element_added_notifier_new (); - fs_element_added_notifier_add (priv->fsnotifier, GST_BIN (priv->pipeline)); - - /* The call will be started as soon the pipeline is playing */ - priv->start_call_when_playing = TRUE; - - priv->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3); - gtk_box_pack_start (GTK_BOX (priv->content_hbox), priv->vbox, - FALSE, FALSE, CONTENT_HBOX_CHILDREN_PACKING_PADDING); - gtk_box_pack_start (GTK_BOX (priv->vbox), priv->self_user_output_frame, - FALSE, FALSE, 0); - - empathy_streamed_media_window_setup_toolbar (self); - - priv->sidebar_button = gtk_toggle_button_new_with_mnemonic (_("_Sidebar")); - arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - g_signal_connect (G_OBJECT (priv->sidebar_button), "toggled", - G_CALLBACK (empathy_streamed_media_window_sidebar_toggled_cb), self); - - gtk_button_set_image (GTK_BUTTON (priv->sidebar_button), arrow); - - h = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - gtk_box_pack_end (GTK_BOX (priv->vbox), h, FALSE, FALSE, 3); - gtk_box_pack_end (GTK_BOX (h), priv->sidebar_button, FALSE, FALSE, 3); - - priv->sidebar = ev_sidebar_new (); - g_signal_connect (G_OBJECT (priv->sidebar), - "hide", G_CALLBACK (empathy_streamed_media_window_sidebar_hidden_cb), self); - g_signal_connect (G_OBJECT (priv->sidebar), - "show", G_CALLBACK (empathy_streamed_media_window_sidebar_shown_cb), self); - gtk_paned_pack2 (GTK_PANED (priv->pane), priv->sidebar, FALSE, FALSE); - - page = empathy_streamed_media_window_create_audio_input (self); - ev_sidebar_add_page (EV_SIDEBAR (priv->sidebar), "audio-input", - _("Audio input"), page); - - page = empathy_streamed_media_window_create_video_input (self); - ev_sidebar_add_page (EV_SIDEBAR (priv->sidebar), "video-input", - _("Video input"), page); - - priv->dtmf_panel = empathy_dialpad_widget_new (); - g_signal_connect (priv->dtmf_panel, "start-tone", - G_CALLBACK (dtmf_start_tone_cb), self); - g_signal_connect (priv->dtmf_panel, "stop-tone", - G_CALLBACK (dtmf_stop_tone_cb), self); - ev_sidebar_add_page (EV_SIDEBAR (priv->sidebar), "dialpad", - _("Dialpad"), priv->dtmf_panel); - - gtk_widget_set_sensitive (priv->dtmf_panel, FALSE); - - /* Put the details vbox in a scroll window as it can require a lot of - * horizontal space. */ - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll), - priv->details_vbox); - - ev_sidebar_add_page (EV_SIDEBAR (priv->sidebar), "details", - _("Details"), scroll); - - gtk_widget_show_all (top_vbox); - - gtk_widget_hide (priv->sidebar); - - priv->fullscreen = empathy_streamed_media_window_fullscreen_new (self); - empathy_streamed_media_window_fullscreen_set_video_widget (priv->fullscreen, - priv->video_output); - g_signal_connect (G_OBJECT (priv->fullscreen->leave_fullscreen_button), - "clicked", G_CALLBACK (empathy_streamed_media_window_fullscreen_cb), self); - - g_signal_connect (G_OBJECT (self), "realize", - G_CALLBACK (empathy_streamed_media_window_realized_cb), self); - - g_signal_connect (G_OBJECT (self), "delete-event", - G_CALLBACK (empathy_streamed_media_window_delete_cb), self); - - g_signal_connect (G_OBJECT (self), "window-state-event", - G_CALLBACK (empathy_streamed_media_window_state_event_cb), self); - - g_signal_connect (G_OBJECT (self), "key-press-event", - G_CALLBACK (empathy_streamed_media_window_key_press_cb), self); - - priv->timer = g_timer_new (); - - g_object_ref (priv->ui_manager); - g_object_unref (gui); - - priv->sound_mgr = empathy_sound_manager_dup_singleton (); - - empathy_geometry_bind (GTK_WINDOW (self), "av-window"); -} - -/* Instead of specifying a width and a height, we specify only one size. That's - because we want a square avatar icon. */ -static void -init_contact_avatar_with_size (EmpathyContact *contact, - GtkWidget *image_widget, - gint size) -{ - GdkPixbuf *pixbuf_avatar = NULL; - - if (contact != NULL) - { - pixbuf_avatar = empathy_pixbuf_avatar_from_contact_scaled (contact, - size, size); - } - - if (pixbuf_avatar == NULL) - { - pixbuf_avatar = empathy_pixbuf_from_icon_name_sized ( - EMPATHY_IMAGE_AVATAR_DEFAULT, size); - } - - gtk_image_set_from_pixbuf (GTK_IMAGE (image_widget), pixbuf_avatar); - - if (pixbuf_avatar != NULL) - g_object_unref (pixbuf_avatar); -} - -static void -set_window_title (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - gchar *tmp; - - /* translators: Call is a noun and %s is the contact name. This string - * is used in the window title */ - tmp = g_strdup_printf (_("Call with %s"), - empathy_contact_get_alias (priv->contact)); - gtk_window_set_title (GTK_WINDOW (self), tmp); - g_free (tmp); -} - -static void -contact_name_changed_cb (EmpathyContact *contact, - GParamSpec *pspec, EmpathyStreamedMediaWindow *self) -{ - set_window_title (self); -} - -static void -contact_avatar_changed_cb (EmpathyContact *contact, - GParamSpec *pspec, GtkWidget *avatar_widget) -{ - int size; - GtkAllocation allocation; - - gtk_widget_get_allocation (avatar_widget, &allocation); - size = allocation.height; - - if (size == 0) - { - /* the widget is not allocated yet, set a default size */ - size = MIN (REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT, - REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH); - } - - init_contact_avatar_with_size (contact, avatar_widget, size); -} - -static void -empathy_streamed_media_window_got_self_contact_cb (TpConnection *connection, - EmpathyContact *contact, const GError *error, gpointer user_data, - GObject *weak_object) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - init_contact_avatar_with_size (contact, priv->self_user_avatar_widget, - MIN (SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH)); - - g_signal_connect (contact, "notify::avatar", - G_CALLBACK (contact_avatar_changed_cb), priv->self_user_avatar_widget); -} - -static void -empathy_streamed_media_window_setup_avatars (EmpathyStreamedMediaWindow *self, - EmpathyStreamedMediaHandler *handler) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - g_object_get (handler, "contact", &(priv->contact), NULL); - - if (priv->contact != NULL) - { - TpConnection *connection; - - set_window_title (self); - - g_signal_connect (priv->contact, "notify::name", - G_CALLBACK (contact_name_changed_cb), self); - g_signal_connect (priv->contact, "notify::avatar", - G_CALLBACK (contact_avatar_changed_cb), - priv->remote_user_avatar_widget); - - /* Retreiving the self avatar */ - connection = empathy_contact_get_connection (priv->contact); - empathy_tp_contact_factory_get_from_handle (connection, - tp_connection_get_self_handle (connection), - empathy_streamed_media_window_got_self_contact_cb, self, NULL, G_OBJECT (self)); - } - else - { - g_warning ("call handler doesn't have a contact"); - /* translators: Call is a noun. This string is used in the window - * title */ - gtk_window_set_title (GTK_WINDOW (self), _("Call")); - - /* Since we can't access the remote contact, we can't get a connection - to it and can't get the self contact (and its avatar). This means - that we have to manually set the self avatar. */ - init_contact_avatar_with_size (NULL, priv->self_user_avatar_widget, - MIN (SELF_VIDEO_SECTION_WIDTH, SELF_VIDEO_SECTION_HEIGTH)); - } - - init_contact_avatar_with_size (priv->contact, - priv->remote_user_avatar_widget, - MIN (REMOTE_CONTACT_AVATAR_DEFAULT_WIDTH, - REMOTE_CONTACT_AVATAR_DEFAULT_HEIGHT)); - - /* The remote avatar is shown by default and will be hidden when we receive - video from the remote side. */ - gtk_widget_hide (priv->video_output); - gtk_widget_show (priv->remote_user_avatar_widget); -} - -static void -update_send_codec (EmpathyStreamedMediaWindow *self, - gboolean audio) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - FsCodec *codec; - GtkWidget *widget; - gchar *tmp; - - if (audio) - { - codec = empathy_streamed_media_handler_get_send_audio_codec (priv->handler); - widget = priv->acodec_encoding_label; - } - else - { - codec = empathy_streamed_media_handler_get_send_video_codec (priv->handler); - widget = priv->vcodec_encoding_label; - } - - if (codec == NULL) - return; - - tmp = g_strdup_printf ("%s/%u", codec->encoding_name, codec->clock_rate); - gtk_label_set_text (GTK_LABEL (widget), tmp); - g_free (tmp); -} - -static void -send_audio_codec_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = user_data; - - update_send_codec (self, TRUE); -} - -static void -send_video_codec_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = user_data; - - update_send_codec (self, FALSE); -} - -static void -update_recv_codec (EmpathyStreamedMediaWindow *self, - gboolean audio) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GList *codecs, *l; - GtkWidget *widget; - GString *str = NULL; - - if (audio) - { - codecs = empathy_streamed_media_handler_get_recv_audio_codecs (priv->handler); - widget = priv->acodec_decoding_label; - } - else - { - codecs = empathy_streamed_media_handler_get_recv_video_codecs (priv->handler); - widget = priv->vcodec_decoding_label; - } - - if (codecs == NULL) - return; - - for (l = codecs; l != NULL; l = g_list_next (l)) - { - FsCodec *codec = l->data; - - if (str == NULL) - str = g_string_new (NULL); - else - g_string_append (str, ", "); - - g_string_append_printf (str, "%s/%u", codec->encoding_name, - codec->clock_rate); - } - - gtk_label_set_text (GTK_LABEL (widget), str->str); - g_string_free (str, TRUE); -} - -static void -recv_audio_codecs_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = user_data; - - update_recv_codec (self, TRUE); -} - -static void -recv_video_codecs_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = user_data; - - update_recv_codec (self, FALSE); -} - -static const gchar * -candidate_type_to_str (FsCandidate *candidate) -{ - switch (candidate->type) - { - case FS_CANDIDATE_TYPE_HOST: - return "host"; - case FS_CANDIDATE_TYPE_SRFLX: - return "server reflexive"; - case FS_CANDIDATE_TYPE_PRFLX: - return "peer reflexive"; - case FS_CANDIDATE_TYPE_RELAY: - return "relay"; - case FS_CANDIDATE_TYPE_MULTICAST: - return "multicast"; - } - - return NULL; -} - -static const gchar * -candidate_type_to_desc (FsCandidate *candidate) -{ - switch (candidate->type) - { - case FS_CANDIDATE_TYPE_HOST: - return _("The IP address as seen by the machine"); - case FS_CANDIDATE_TYPE_SRFLX: - return _("The IP address as seen by a server on the Internet"); - case FS_CANDIDATE_TYPE_PRFLX: - return _("The IP address of the peer as seen by the other side"); - case FS_CANDIDATE_TYPE_RELAY: - return _("The IP address of a relay server"); - case FS_CANDIDATE_TYPE_MULTICAST: - return _("The IP address of the multicast group"); - } - - return NULL; -} - -static void -update_candidat_widget (EmpathyStreamedMediaWindow *self, - GtkWidget *label, - GtkWidget *img, - FsCandidate *candidate) -{ - gchar *str; - - g_assert (candidate != NULL); - str = g_strdup_printf ("%s %u (%s)", candidate->ip, - candidate->port, candidate_type_to_str (candidate)); - - gtk_label_set_text (GTK_LABEL (label), str); - gtk_widget_set_tooltip_text (img, candidate_type_to_desc (candidate)); - - g_free (str); -} - -static void -candidates_changed_cb (GObject *object, - FsMediaType type, - EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - FsCandidate *candidate = NULL; - - if (type == FS_MEDIA_TYPE_VIDEO) - { - /* Update remote candidate */ - candidate = empathy_streamed_media_handler_get_video_remote_candidate ( - priv->handler); - - update_candidat_widget (self, priv->video_remote_candidate_label, - priv->video_remote_candidate_info_img, candidate); - - /* Update local candidate */ - candidate = empathy_streamed_media_handler_get_video_local_candidate ( - priv->handler); - - update_candidat_widget (self, priv->video_local_candidate_label, - priv->video_local_candidate_info_img, candidate); - } - else - { - /* Update remote candidate */ - candidate = empathy_streamed_media_handler_get_audio_remote_candidate ( - priv->handler); - - update_candidat_widget (self, priv->audio_remote_candidate_label, - priv->audio_remote_candidate_info_img, candidate); - - /* Update local candidate */ - candidate = empathy_streamed_media_handler_get_audio_local_candidate ( - priv->handler); - - update_candidat_widget (self, priv->audio_local_candidate_label, - priv->audio_local_candidate_info_img, candidate); - } -} - -static void -empathy_streamed_media_window_constructed (GObject *object) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (object); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - EmpathyTpStreamedMedia *call; - - g_assert (priv->handler != NULL); - - g_object_get (priv->handler, "tp-call", &call, NULL); - priv->outgoing = (call == NULL); - if (call != NULL) - g_object_unref (call); - - empathy_streamed_media_window_setup_avatars (self, priv->handler); - empathy_streamed_media_window_set_state_connecting (self); - - if (!empathy_streamed_media_handler_has_initial_video (priv->handler)) - { - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->tool_button_camera_off), TRUE); - } - /* If call has InitialVideo, the preview will be started once the call has - * been started (start_call()). */ - - update_send_codec (self, TRUE); - update_send_codec (self, FALSE); - update_recv_codec (self, TRUE); - update_recv_codec (self, FALSE); - - tp_g_signal_connect_object (priv->handler, "notify::send-audio-codec", - G_CALLBACK (send_audio_codec_notify_cb), self, 0); - tp_g_signal_connect_object (priv->handler, "notify::send-video-codec", - G_CALLBACK (send_video_codec_notify_cb), self, 0); - tp_g_signal_connect_object (priv->handler, "notify::recv-audio-codecs", - G_CALLBACK (recv_audio_codecs_notify_cb), self, 0); - tp_g_signal_connect_object (priv->handler, "notify::recv-video-codecs", - G_CALLBACK (recv_video_codecs_notify_cb), self, 0); - - tp_g_signal_connect_object (priv->handler, "candidates-changed", - G_CALLBACK (candidates_changed_cb), self, 0); -} - -static void empathy_streamed_media_window_dispose (GObject *object); -static void empathy_streamed_media_window_finalize (GObject *object); - -static void -empathy_streamed_media_window_set_property (GObject *object, - guint property_id, const GValue *value, GParamSpec *pspec) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_STREAMED_MEDIA_HANDLER: - priv->handler = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -empathy_streamed_media_window_get_property (GObject *object, - guint property_id, GValue *value, GParamSpec *pspec) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_STREAMED_MEDIA_HANDLER: - g_value_set_object (value, priv->handler); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -empathy_streamed_media_window_class_init ( - EmpathyStreamedMediaWindowClass *empathy_streamed_media_window_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (empathy_streamed_media_window_class); - GParamSpec *param_spec; - - g_type_class_add_private (empathy_streamed_media_window_class, - sizeof (EmpathyStreamedMediaWindowPriv)); - - object_class->constructed = empathy_streamed_media_window_constructed; - object_class->set_property = empathy_streamed_media_window_set_property; - object_class->get_property = empathy_streamed_media_window_get_property; - - object_class->dispose = empathy_streamed_media_window_dispose; - object_class->finalize = empathy_streamed_media_window_finalize; - - param_spec = g_param_spec_object ("handler", - "handler", "The call handler", - EMPATHY_TYPE_STREAMED_MEDIA_HANDLER, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, - PROP_STREAMED_MEDIA_HANDLER, param_spec); -} - -static void -empathy_streamed_media_window_video_stream_changed_cb (EmpathyTpStreamedMedia *call, - GParamSpec *property, EmpathyStreamedMediaWindow *self) -{ - DEBUG ("video stream changed"); - empathy_streamed_media_window_update_avatars_visibility (call, self); -} - -void -empathy_streamed_media_window_dispose (GObject *object) -{ - EmpathyTpStreamedMedia *call; - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (object); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - g_object_get (priv->handler, "tp-call", &call, NULL); - - if (call != NULL) - { - g_object_unref (call); - } - - if (priv->handler != NULL) - { - empathy_streamed_media_handler_stop_call (priv->handler); - g_object_unref (priv->handler); - } - priv->handler = NULL; - - if (priv->bus_message_source_id != 0) - { - g_source_remove (priv->bus_message_source_id); - priv->bus_message_source_id = 0; - } - - if (priv->pipeline != NULL) - g_object_unref (priv->pipeline); - priv->pipeline = NULL; - - if (priv->video_input != NULL) - g_object_unref (priv->video_input); - priv->video_input = NULL; - - if (priv->audio_input != NULL) - g_object_unref (priv->audio_input); - priv->audio_input = NULL; - - if (priv->video_tee != NULL) - g_object_unref (priv->video_tee); - priv->video_tee = NULL; - - if (priv->fsnotifier != NULL) - g_object_unref (priv->fsnotifier); - priv->fsnotifier = NULL; - - if (priv->timer_id != 0) - g_source_remove (priv->timer_id); - priv->timer_id = 0; - - if (priv->ui_manager != NULL) - g_object_unref (priv->ui_manager); - priv->ui_manager = NULL; - - if (priv->fullscreen != NULL) - g_object_unref (priv->fullscreen); - priv->fullscreen = NULL; - - if (priv->contact != NULL) - { - g_signal_handlers_disconnect_by_func (priv->contact, - contact_name_changed_cb, self); - g_object_unref (priv->contact); - priv->contact = NULL; - } - - tp_clear_object (&priv->sound_mgr); - - /* release any references held by the object here */ - if (G_OBJECT_CLASS (empathy_streamed_media_window_parent_class)->dispose) - G_OBJECT_CLASS (empathy_streamed_media_window_parent_class)->dispose (object); -} - -static void -disconnect_video_output_motion_handler (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (priv->video_output_motion_handler_id != 0) - { - g_signal_handler_disconnect (G_OBJECT (priv->video_output), - priv->video_output_motion_handler_id); - priv->video_output_motion_handler_id = 0; - } -} - -void -empathy_streamed_media_window_finalize (GObject *object) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (object); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - disconnect_video_output_motion_handler (self); - - /* free any data held directly by the object here */ - g_mutex_free (priv->lock); - - g_timer_destroy (priv->timer); - - G_OBJECT_CLASS (empathy_streamed_media_window_parent_class)->finalize (object); -} - - -EmpathyStreamedMediaWindow * -empathy_streamed_media_window_new (EmpathyStreamedMediaHandler *handler) -{ - return EMPATHY_STREAMED_MEDIA_WINDOW ( - g_object_new (EMPATHY_TYPE_STREAMED_MEDIA_WINDOW, "handler", handler, NULL)); -} - -static void -empathy_streamed_media_window_conference_added_cb (EmpathyStreamedMediaHandler *handler, - GstElement *conference, gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GKeyFile *keyfile; - - keyfile = fs_utils_get_default_element_properties (conference); - if (keyfile != NULL) - fs_element_added_notifier_set_properties_from_keyfile (priv->fsnotifier, - keyfile); - - gst_bin_add (GST_BIN (priv->pipeline), conference); - - gst_element_set_state (conference, GST_STATE_PLAYING); -} - -static gboolean -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); - - if (type != FS_MEDIA_TYPE_VIDEO) - return TRUE; - - /* video and direction is send */ - return priv->video_input != NULL; -} - -static gboolean -empathy_streamed_media_window_reset_pipeline (EmpathyStreamedMediaWindow *self) -{ - GstStateChangeReturn state_change_return; - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (priv->pipeline == NULL) - return TRUE; - - if (priv->bus_message_source_id != 0) - { - g_source_remove (priv->bus_message_source_id); - priv->bus_message_source_id = 0; - } - - state_change_return = gst_element_set_state (priv->pipeline, GST_STATE_NULL); - - if (state_change_return == GST_STATE_CHANGE_SUCCESS || - state_change_return == GST_STATE_CHANGE_NO_PREROLL) - { - if (priv->pipeline != NULL) - g_object_unref (priv->pipeline); - priv->pipeline = NULL; - - g_signal_handlers_disconnect_by_func (priv->audio_input_adj, - empathy_streamed_media_window_mic_volume_changed_cb, self); - - if (priv->video_tee != NULL) - g_object_unref (priv->video_tee); - priv->video_tee = NULL; - - if (priv->video_preview != NULL) - gtk_widget_destroy (priv->video_preview); - priv->video_preview = NULL; - - priv->funnel = NULL; - - create_pipeline (self); - /* Call will be started when user will hit the 'redial' button */ - priv->start_call_when_playing = FALSE; - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); - - return TRUE; - } - else - { - g_message ("Error: could not destroy pipeline. Closing call window"); - gtk_widget_destroy (GTK_WIDGET (self)); - - return FALSE; - } -} - -static void -reset_details_pane (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - /* translators: encoding video codec is unknown */ - gtk_label_set_text (GTK_LABEL (priv->vcodec_encoding_label), - C_("codec", "Unknown")); - /* translators: encoding audio codec is unknown */ - gtk_label_set_text (GTK_LABEL (priv->acodec_encoding_label), - C_("codec", "Unknown")); - /* translators: decoding video codec is unknown */ - gtk_label_set_text (GTK_LABEL (priv->vcodec_decoding_label), - C_("codec", "Unknown")); - /* translators: decoding audio codec is unknown */ - gtk_label_set_text (GTK_LABEL (priv->acodec_decoding_label), - C_("codec", "Unknown")); -} - -static gboolean -empathy_streamed_media_window_disconnected (EmpathyStreamedMediaWindow *self, - gboolean restart) -{ - gboolean could_disconnect = FALSE; - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - gboolean could_reset_pipeline; - - /* Leave full screen mode if needed */ - gtk_window_unfullscreen (GTK_WINDOW (self)); - - gtk_action_set_sensitive (priv->menu_fullscreen, FALSE); - - could_reset_pipeline = empathy_streamed_media_window_reset_pipeline (self); - - if (priv->call_state == CONNECTING) - empathy_sound_manager_stop (priv->sound_mgr, - EMPATHY_SOUND_PHONE_OUTGOING); - - if (priv->call_state != REDIALING) - priv->call_state = DISCONNECTED; - - if (could_reset_pipeline) - { - g_mutex_lock (priv->lock); - - g_timer_stop (priv->timer); - - if (priv->timer_id != 0) - g_source_remove (priv->timer_id); - priv->timer_id = 0; - - g_mutex_unlock (priv->lock); - - if (!restart) - /* We are about to destroy the window, no need to update it or create - * a video preview */ - return TRUE; - - empathy_streamed_media_window_status_message (self, _("Disconnected")); - - gtk_action_set_sensitive (priv->redial, TRUE); - gtk_widget_set_sensitive (priv->redial_button, TRUE); - - /* Unsensitive the camera and mic button */ - gtk_widget_set_sensitive (priv->tool_button_camera_on, FALSE); - gtk_action_set_sensitive (priv->action_camera_on, FALSE); - gtk_widget_set_sensitive (priv->mic_button, FALSE); - - /* Be sure that the mic button is enabled */ - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->mic_button), TRUE); - - if (priv->camera_state == CAMERA_STATE_ON) - { - /* Enable the 'preview' button as we are not sending atm. */ - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->tool_button_camera_preview), TRUE); - } - else if (priv->camera_state == CAMERA_STATE_PREVIEW) - { - /* Restart the preview with the new pipeline. */ - display_video_preview (self, TRUE); - } - - gtk_progress_bar_set_fraction ( - GTK_PROGRESS_BAR (priv->volume_progress_bar), 0); - - /* destroy the video output; it will be recreated when we'll redial */ - disconnect_video_output_motion_handler (self); - gtk_widget_destroy (priv->video_output); - priv->video_output = NULL; - - gtk_widget_show (priv->remote_user_avatar_widget); - - reset_details_pane (self); - - priv->sending_video = FALSE; - priv->call_started = FALSE; - - could_disconnect = TRUE; - - /* TODO: display the self avatar of the preview (depends if the "Always - * Show Video Preview" is enabled or not) */ - } - - return could_disconnect; -} - - -static void -empathy_streamed_media_window_channel_closed_cb (EmpathyStreamedMediaHandler *handler, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - if (empathy_streamed_media_window_disconnected (self, TRUE) && - priv->call_state == REDIALING) - empathy_streamed_media_window_restart_call (self); -} - - -static void -empathy_streamed_media_window_channel_stream_closed_cb (EmpathyStreamedMediaHandler *handler, - TfContent *content, gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - guint media_type; - - g_object_get (content, "media-type", &media_type, NULL); - - /* - * This assumes that there is only one video stream per channel... - */ - - if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO) - { - if (priv->funnel != NULL) - { - GstElement *output; - - output = empathy_video_widget_get_element (EMPATHY_VIDEO_WIDGET - (priv->video_output)); - - gst_element_set_state (output, GST_STATE_NULL); - gst_element_set_state (priv->funnel, GST_STATE_NULL); - - gst_bin_remove (GST_BIN (priv->pipeline), output); - gst_bin_remove (GST_BIN (priv->pipeline), priv->funnel); - priv->funnel = NULL; - } - } - else if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO) - { - if (priv->audio_output != NULL) - { - gst_element_set_state (priv->audio_output, GST_STATE_NULL); - - gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_output); - priv->audio_output = NULL; - } - } -} - -/* Called with global lock held */ -static GstPad * -empathy_streamed_media_window_get_video_sink_pad (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstPad *pad; - GstElement *output; - - if (priv->funnel == NULL) - { - output = empathy_video_widget_get_element (EMPATHY_VIDEO_WIDGET - (priv->video_output)); - - priv->funnel = gst_element_factory_make ("fsfunnel", NULL); - - if (!priv->funnel) - { - g_warning ("Could not create fsfunnel"); - return NULL; - } - - if (!gst_bin_add (GST_BIN (priv->pipeline), priv->funnel)) - { - gst_object_unref (priv->funnel); - priv->funnel = NULL; - g_warning ("Could not add funnel to pipeline"); - return NULL; - } - - if (!gst_bin_add (GST_BIN (priv->pipeline), output)) - { - g_warning ("Could not add the video output widget to the pipeline"); - goto error; - } - - if (!gst_element_link (priv->funnel, output)) - { - g_warning ("Could not link output sink to funnel"); - goto error_output_added; - } - - if (gst_element_set_state (output, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start video sink"); - goto error_output_added; - } - - if (gst_element_set_state (priv->funnel, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start funnel"); - goto error_output_added; - } - } - - pad = gst_element_get_request_pad (priv->funnel, "sink%d"); - - if (!pad) - g_warning ("Could not get request pad from funnel"); - - return pad; - - - error_output_added: - - gst_element_set_locked_state (priv->funnel, TRUE); - gst_element_set_locked_state (output, TRUE); - - gst_element_set_state (priv->funnel, GST_STATE_NULL); - gst_element_set_state (output, GST_STATE_NULL); - - gst_bin_remove (GST_BIN (priv->pipeline), output); - gst_element_set_locked_state (output, FALSE); - - error: - - gst_bin_remove (GST_BIN (priv->pipeline), priv->funnel); - priv->funnel = NULL; - - return NULL; -} - -/* Called with global lock held */ -static GstPad * -empathy_streamed_media_window_get_audio_sink_pad (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstPad *pad; - GstPadTemplate *template; - - if (priv->audio_output == NULL) - { - priv->audio_output = empathy_audio_sink_new (); - - if (!gst_bin_add (GST_BIN (priv->pipeline), priv->audio_output)) - { - g_warning ("Could not add audio sink to pipeline"); - g_object_unref (priv->audio_output); - goto error_add_output; - } - - if (gst_element_set_state (priv->audio_output, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start audio sink"); - goto error; - } - } - - template = gst_element_class_get_pad_template ( - GST_ELEMENT_GET_CLASS (priv->audio_output), "sink%d"); - - pad = gst_element_request_pad (priv->audio_output, - template, NULL, NULL); - - if (pad == NULL) - { - g_warning ("Could not get sink pad from sink"); - return NULL; - } - - return pad; - -error: - gst_element_set_locked_state (priv->audio_output, TRUE); - gst_element_set_state (priv->audio_output, GST_STATE_NULL); - gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_output); - priv->audio_output = NULL; - -error_add_output: - - return NULL; -} - -static gboolean -empathy_streamed_media_window_update_timer (gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - gchar *str; - gdouble time_; - - time_ = g_timer_elapsed (priv->timer, NULL); - - /* Translators: number of minutes:seconds the caller has been connected */ - str = g_strdup_printf (_("Connected — %d:%02dm"), (int) time_ / 60, - (int) time_ % 60); - empathy_streamed_media_window_status_message (self, str); - g_free (str); - - return TRUE; -} - -static void -display_error (EmpathyStreamedMediaWindow *self, - EmpathyTpStreamedMedia *call, - const gchar *img, - const gchar *title, - const gchar *desc, - const gchar *details) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GtkWidget *info_bar; - GtkWidget *content_area; - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *image; - GtkWidget *label; - gchar *txt; - - /* Create info bar */ - info_bar = gtk_info_bar_new_with_buttons (GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_WARNING); - - content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar)); - - /* hbox containing the image and the messages vbox */ - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - gtk_container_add (GTK_CONTAINER (content_area), hbox); - - /* Add image */ - image = gtk_image_new_from_icon_name (img, GTK_ICON_SIZE_DIALOG); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); - - /* vbox containing the main message and the details expander */ - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3); - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - - /* Add text */ - txt = g_strdup_printf ("<b>%s</b>\n%s", title, desc); - - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), txt); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0); - g_free (txt); - - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); - - /* Add details */ - if (details != NULL) - { - GtkWidget *expander; - - expander = gtk_expander_new (_("Technical Details")); - - txt = g_strdup_printf ("<i>%s</i>", details); - - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), txt); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0); - g_free (txt); - - gtk_container_add (GTK_CONTAINER (expander), label); - gtk_box_pack_start (GTK_BOX (vbox), expander, TRUE, TRUE, 0); - } - - g_signal_connect (info_bar, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - - gtk_box_pack_start (GTK_BOX (priv->errors_vbox), info_bar, - FALSE, FALSE, CONTENT_HBOX_CHILDREN_PACKING_PADDING); - gtk_widget_show_all (info_bar); -} - -static gchar * -media_stream_error_to_txt (EmpathyStreamedMediaWindow *self, - EmpathyTpStreamedMedia *call, - gboolean audio, - TpMediaStreamError error) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - const gchar *cm; - gchar *url; - gchar *result; - - switch (error) - { - case TP_MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED: - if (audio) - return g_strdup_printf ( - _("%s's software does not understand any of the audio formats " - "supported by your computer"), - empathy_contact_get_alias (priv->contact)); - else - return g_strdup_printf ( - _("%s's software does not understand any of the video formats " - "supported by your computer"), - empathy_contact_get_alias (priv->contact)); - - case TP_MEDIA_STREAM_ERROR_CONNECTION_FAILED: - return g_strdup_printf ( - _("Can't establish a connection to %s. " - "One of you might be on a network that does not allow " - "direct connections."), - empathy_contact_get_alias (priv->contact)); - - case TP_MEDIA_STREAM_ERROR_NETWORK_ERROR: - return g_strdup (_("There was a failure on the network")); - - case TP_MEDIA_STREAM_ERROR_NO_CODECS: - if (audio) - return g_strdup (_("The audio formats necessary for this call " - "are not installed on your computer")); - else - return g_strdup (_("The video formats necessary for this call " - "are not installed on your computer")); - - case TP_MEDIA_STREAM_ERROR_INVALID_CM_BEHAVIOR: - cm = empathy_tp_streamed_media_get_connection_manager (call); - - url = g_strdup_printf ("http://bugs.freedesktop.org/enter_bug.cgi?" - "product=Telepathy&component=%s", cm); - - result = g_strdup_printf ( - _("Something unexpected happened in a Telepathy component. " - "Please <a href=\"%s\">report this bug</a> and attach " - "logs gathered from the 'Debug' window in the Help menu."), url); - - g_free (url); - return result; - - case TP_MEDIA_STREAM_ERROR_MEDIA_ERROR: - return g_strdup (_("There was a failure in the call engine")); - - case TP_MEDIA_STREAM_ERROR_EOS: - return g_strdup (_("The end of the stream was reached")); - - case TP_MEDIA_STREAM_ERROR_UNKNOWN: - default: - return NULL; - } -} - -static void -empathy_streamed_media_window_stream_error (EmpathyStreamedMediaWindow *self, - EmpathyTpStreamedMedia *call, - gboolean audio, - guint code, - const gchar *msg, - const gchar *icon, - const gchar *title) -{ - gchar *desc; - - desc = media_stream_error_to_txt (self, call, audio, code); - if (desc == NULL) - { - /* No description, use the error message. That's not great as it's not - * localized but it's better than nothing. */ - display_error (self, call, icon, title, msg, NULL); - } - else - { - display_error (self, call, icon, title, desc, msg); - g_free (desc); - } -} - -static void -empathy_streamed_media_window_audio_stream_error (EmpathyTpStreamedMedia *call, - guint code, - const gchar *msg, - EmpathyStreamedMediaWindow *self) -{ - empathy_streamed_media_window_stream_error (self, call, TRUE, code, msg, - "gnome-stock-mic", _("Can't establish audio stream")); -} - -static void -empathy_streamed_media_window_video_stream_error (EmpathyTpStreamedMedia *call, - guint code, - const gchar *msg, - EmpathyStreamedMediaWindow *self) -{ - empathy_streamed_media_window_stream_error (self, call, FALSE, code, msg, - "camera-web", _("Can't establish video stream")); -} - -static gboolean -empathy_streamed_media_window_connected (gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - EmpathyTpStreamedMedia *call; - gboolean can_send_video; - - empathy_sound_manager_stop (priv->sound_mgr, EMPATHY_SOUND_PHONE_OUTGOING); - - can_send_video = priv->video_input != NULL && priv->contact != NULL && - empathy_contact_can_voip_video (priv->contact); - - g_object_get (priv->handler, "tp-call", &call, NULL); - - tp_g_signal_connect_object (call, "notify::video-stream", - G_CALLBACK (empathy_streamed_media_window_video_stream_changed_cb), - self, 0); - - if (empathy_tp_streamed_media_has_dtmf (call)) - gtk_widget_set_sensitive (priv->dtmf_panel, TRUE); - - if (priv->video_input == NULL) - empathy_streamed_media_window_set_send_video (self, CAMERA_STATE_OFF); - - priv->sending_video = can_send_video ? - empathy_tp_streamed_media_is_sending_video (call) : FALSE; - - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->tool_button_camera_on), - priv->sending_video && priv->video_input != NULL); - gtk_widget_set_sensitive (priv->tool_button_camera_on, can_send_video); - gtk_action_set_sensitive (priv->action_camera_on, can_send_video); - - gtk_action_set_sensitive (priv->redial, FALSE); - gtk_widget_set_sensitive (priv->redial_button, FALSE); - - gtk_widget_set_sensitive (priv->mic_button, TRUE); - - empathy_streamed_media_window_update_avatars_visibility (call, self); - - g_object_unref (call); - - g_mutex_lock (priv->lock); - - priv->timer_id = g_timeout_add_seconds (1, - empathy_streamed_media_window_update_timer, self); - - g_mutex_unlock (priv->lock); - - empathy_streamed_media_window_update_timer (self); - - gtk_action_set_sensitive (priv->menu_fullscreen, TRUE); - - return FALSE; -} - - -/* Called from the streaming thread */ -static gboolean -empathy_streamed_media_window_src_added_cb (EmpathyStreamedMediaHandler *handler, - GstPad *src, guint media_type, gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - gboolean retval = FALSE; - - GstPad *pad; - - g_mutex_lock (priv->lock); - - if (priv->call_state != CONNECTED) - { - g_timer_start (priv->timer); - priv->timer_id = g_idle_add (empathy_streamed_media_window_connected, self); - priv->call_state = CONNECTED; - } - - switch (media_type) - { - case TP_MEDIA_STREAM_TYPE_AUDIO: - pad = empathy_streamed_media_window_get_audio_sink_pad (self); - break; - case TP_MEDIA_STREAM_TYPE_VIDEO: - gtk_widget_hide (priv->remote_user_avatar_widget); - gtk_widget_show (priv->video_output); - pad = empathy_streamed_media_window_get_video_sink_pad (self); - break; - default: - g_assert_not_reached (); - } - - if (pad == NULL) - goto out; - - if (GST_PAD_LINK_FAILED (gst_pad_link (src, pad))) - g_warning ("Could not link %s sink pad", - media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video"); - else - retval = TRUE; - - gst_object_unref (pad); - - out: - - /* If no sink could be linked, try to add fakesink to prevent the whole call - * aborting */ - - if (!retval) - { - GstElement *fakesink = gst_element_factory_make ("fakesink", NULL); - - if (gst_bin_add (GST_BIN (priv->pipeline), fakesink)) - { - GstPad *sinkpad = gst_element_get_static_pad (fakesink, "sink"); - if (gst_element_set_state (fakesink, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE || - GST_PAD_LINK_FAILED (gst_pad_link (src, sinkpad))) - { - gst_element_set_locked_state (fakesink, TRUE); - gst_element_set_state (fakesink, GST_STATE_NULL); - gst_bin_remove (GST_BIN (priv->pipeline), fakesink); - } - else - { - DEBUG ("Could not link real sink, linked fakesink instead"); - } - gst_object_unref (sinkpad); - } - else - { - gst_object_unref (fakesink); - } - } - - - g_mutex_unlock (priv->lock); - - return TRUE; -} - -static gboolean -empathy_streamed_media_window_sink_added_cb (EmpathyStreamedMediaHandler *handler, - GstPad *sink, guint media_type, gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstPad *pad; - gboolean retval = FALSE; - - switch (media_type) - { - case TP_MEDIA_STREAM_TYPE_AUDIO: - if (!gst_bin_add (GST_BIN (priv->pipeline), priv->audio_input)) - { - g_warning ("Could not add audio source to pipeline"); - break; - } - - pad = gst_element_get_static_pad (priv->audio_input, "src"); - if (!pad) - { - gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_input); - g_warning ("Could not get source pad from audio source"); - break; - } - - if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sink))) - { - gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_input); - g_warning ("Could not link audio source to farsight"); - break; - } - - if (gst_element_set_state (priv->audio_input, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) - { - g_warning ("Could not start audio source"); - gst_element_set_state (priv->audio_input, GST_STATE_NULL); - gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_input); - break; - } - - retval = TRUE; - break; - case TP_MEDIA_STREAM_TYPE_VIDEO: - if (priv->video_input != NULL) - { - if (priv->video_tee != NULL) - { - pad = gst_element_get_request_pad (priv->video_tee, "src%d"); - if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sink))) - { - g_warning ("Could not link videp soure input pipeline"); - break; - } - gst_object_unref (pad); - } - - retval = TRUE; - } - break; - default: - g_assert_not_reached (); - } - - return retval; -} - -static void -empathy_streamed_media_window_remove_video_input (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstElement *preview; - - disable_camera (self); - - DEBUG ("remove video input"); - preview = empathy_video_widget_get_element ( - EMPATHY_VIDEO_WIDGET (priv->video_preview)); - - gst_element_set_state (priv->video_input, GST_STATE_NULL); - gst_element_set_state (priv->video_tee, GST_STATE_NULL); - gst_element_set_state (preview, GST_STATE_NULL); - - gst_bin_remove_many (GST_BIN (priv->pipeline), priv->video_input, - priv->video_tee, preview, NULL); - - g_object_unref (priv->video_input); - priv->video_input = NULL; - g_object_unref (priv->video_tee); - priv->video_tee = NULL; - gtk_widget_destroy (priv->video_preview); - priv->video_preview = NULL; - - gtk_widget_set_sensitive (priv->tool_button_camera_on, FALSE); - gtk_action_set_sensitive (priv->action_camera_on, FALSE); - gtk_widget_set_sensitive (priv->tool_button_camera_preview, FALSE); -} - -static void -start_call (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - priv->call_started = TRUE; - empathy_streamed_media_handler_start_call (priv->handler, - empathy_get_current_action_time ()); - - if (empathy_streamed_media_handler_has_initial_video (priv->handler)) - { - /* Enable 'send video' buttons and display the preview */ - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (priv->tool_button_camera_on), TRUE); - } -} - -static gboolean -empathy_streamed_media_window_bus_message (GstBus *bus, GstMessage *message, - gpointer user_data) -{ - EmpathyStreamedMediaWindow *self = EMPATHY_STREAMED_MEDIA_WINDOW (user_data); - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - GstState newstate; - - empathy_streamed_media_handler_bus_message (priv->handler, bus, message); - - switch (GST_MESSAGE_TYPE (message)) - { - case GST_MESSAGE_STATE_CHANGED: - if (GST_MESSAGE_SRC (message) == GST_OBJECT (priv->video_input)) - { - gst_message_parse_state_changed (message, NULL, &newstate, NULL); - if (newstate == GST_STATE_PAUSED) - empathy_streamed_media_window_setup_video_input (self); - } - if (GST_MESSAGE_SRC (message) == GST_OBJECT (priv->pipeline) && - !priv->call_started) - { - gst_message_parse_state_changed (message, NULL, &newstate, NULL); - if (newstate == GST_STATE_PAUSED) - { - gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); - priv->pipeline_playing = TRUE; - - if (priv->start_call_when_playing) - start_call (self); - } - } - break; - case GST_MESSAGE_ERROR: - { - GError *error = NULL; - GstElement *gst_error; - gchar *debug; - gchar *name; - - gst_message_parse_error (message, &error, &debug); - gst_error = GST_ELEMENT (GST_MESSAGE_SRC (message)); - - g_message ("Element error: %s -- %s\n", error->message, debug); - - name = gst_element_get_name (gst_error); - if (g_str_has_prefix (name, VIDEO_INPUT_ERROR_PREFIX)) - { - /* Remove the video input and continue */ - if (priv->video_input != NULL) - empathy_streamed_media_window_remove_video_input (self); - gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); - } - else - { - empathy_streamed_media_window_disconnected (self, TRUE); - } - g_free (name); - g_error_free (error); - g_free (debug); - } - case GST_MESSAGE_UNKNOWN: - case GST_MESSAGE_EOS: - case GST_MESSAGE_WARNING: - case GST_MESSAGE_INFO: - case GST_MESSAGE_TAG: - case GST_MESSAGE_BUFFERING: - case GST_MESSAGE_STATE_DIRTY: - case GST_MESSAGE_STEP_DONE: - case GST_MESSAGE_CLOCK_PROVIDE: - case GST_MESSAGE_CLOCK_LOST: - case GST_MESSAGE_NEW_CLOCK: - case GST_MESSAGE_STRUCTURE_CHANGE: - case GST_MESSAGE_STREAM_STATUS: - case GST_MESSAGE_APPLICATION: - case GST_MESSAGE_ELEMENT: - case GST_MESSAGE_SEGMENT_START: - case GST_MESSAGE_SEGMENT_DONE: - case GST_MESSAGE_DURATION: - case GST_MESSAGE_ANY: - default: - break; - } - - return TRUE; -} - -static void -empathy_streamed_media_window_update_avatars_visibility (EmpathyTpStreamedMedia *call, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (empathy_tp_streamed_media_is_receiving_video (call)) - { - gtk_widget_hide (priv->remote_user_avatar_widget); - gtk_widget_show (priv->video_output); - } - else - { - gtk_widget_hide (priv->video_output); - gtk_widget_show (priv->remote_user_avatar_widget); - } -} - -static void -call_handler_notify_tp_streamed_media_cb (EmpathyStreamedMediaHandler *handler, - GParamSpec *spec, - EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - EmpathyTpStreamedMedia *call; - - g_object_get (priv->handler, "tp-call", &call, NULL); - if (call == NULL) - return; - - tp_g_signal_connect_object (call, "audio-stream-error", - G_CALLBACK (empathy_streamed_media_window_audio_stream_error), self, 0); - tp_g_signal_connect_object (call, "video-stream-error", - G_CALLBACK (empathy_streamed_media_window_video_stream_error), self, 0); - - g_object_unref (call); -} - -static void -empathy_streamed_media_window_realized_cb (GtkWidget *widget, EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - EmpathyTpStreamedMedia *call; - - g_signal_connect (priv->handler, "conference-added", - G_CALLBACK (empathy_streamed_media_window_conference_added_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", - G_CALLBACK (empathy_streamed_media_window_src_added_cb), window); - g_signal_connect (priv->handler, "sink-pad-added", - G_CALLBACK (empathy_streamed_media_window_sink_added_cb), window); - g_signal_connect (priv->handler, "stream-closed", - G_CALLBACK (empathy_streamed_media_window_channel_stream_closed_cb), window); - - g_object_get (priv->handler, "tp-call", &call, NULL); - if (call != NULL) - { - tp_g_signal_connect_object (call, "audio-stream-error", - G_CALLBACK (empathy_streamed_media_window_audio_stream_error), window, - 0); - tp_g_signal_connect_object (call, "video-stream-error", - G_CALLBACK (empathy_streamed_media_window_video_stream_error), window, - 0); - - g_object_unref (call); - } - else - { - /* tp-call doesn't exist yet, we'll connect signals once it has been - * set */ - g_signal_connect (priv->handler, "notify::tp-call", - G_CALLBACK (call_handler_notify_tp_streamed_media_cb), window); - } - - gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); -} - -static gboolean -empathy_streamed_media_window_delete_cb (GtkWidget *widget, GdkEvent*event, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->pipeline != NULL) - { - if (priv->bus_message_source_id != 0) - { - g_source_remove (priv->bus_message_source_id); - priv->bus_message_source_id = 0; - } - - gst_element_set_state (priv->pipeline, GST_STATE_NULL); - } - - if (priv->call_state == CONNECTING) - empathy_sound_manager_stop (priv->sound_mgr, EMPATHY_SOUND_PHONE_OUTGOING); - - return FALSE; -} - -static void -show_controls (EmpathyStreamedMediaWindow *window, gboolean set_fullscreen) -{ - GtkWidget *menu; - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - menu = gtk_ui_manager_get_widget (priv->ui_manager, - "/menubar1"); - - if (set_fullscreen) - { - gtk_widget_hide (priv->sidebar); - gtk_widget_hide (menu); - gtk_widget_hide (priv->vbox); - gtk_widget_hide (priv->statusbar); - gtk_widget_hide (priv->toolbar); - } - else - { - if (priv->sidebar_was_visible_before_fs) - gtk_widget_show (priv->sidebar); - - gtk_widget_show (menu); - gtk_widget_show (priv->vbox); - gtk_widget_show (priv->statusbar); - gtk_widget_show (priv->toolbar); - - gtk_window_resize (GTK_WINDOW (window), priv->original_width_before_fs, - priv->original_height_before_fs); - } -} - -static void -show_borders (EmpathyStreamedMediaWindow *window, gboolean set_fullscreen) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - gtk_container_set_border_width (GTK_CONTAINER (priv->content_hbox), - set_fullscreen ? 0 : CONTENT_HBOX_BORDER_WIDTH); - gtk_box_set_spacing (GTK_BOX (priv->content_hbox), - set_fullscreen ? 0 : CONTENT_HBOX_SPACING); - - if (priv->video_output != NULL) - { - gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), - priv->video_output, TRUE, TRUE, - set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, - GTK_PACK_START); - } - - gtk_box_set_child_packing (GTK_BOX (priv->content_hbox), - priv->vbox, TRUE, TRUE, - set_fullscreen ? 0 : CONTENT_HBOX_CHILDREN_PACKING_PADDING, - GTK_PACK_START); -} - -static gboolean -empathy_streamed_media_window_state_event_cb (GtkWidget *widget, - GdkEventWindowState *event, EmpathyStreamedMediaWindow *window) -{ - if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) - { - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - gboolean set_fullscreen = event->new_window_state & - GDK_WINDOW_STATE_FULLSCREEN; - - if (set_fullscreen) - { - gboolean sidebar_was_visible; - GtkAllocation allocation; - gint original_width, original_height; - - gtk_widget_get_allocation (GTK_WIDGET (window), &allocation); - original_width = allocation.width; - original_height = allocation.height; - - g_object_get (priv->sidebar, "visible", &sidebar_was_visible, NULL); - - priv->sidebar_was_visible_before_fs = sidebar_was_visible; - priv->original_width_before_fs = original_width; - priv->original_height_before_fs = original_height; - - if (priv->video_output_motion_handler_id == 0 && - priv->video_output != NULL) - { - priv->video_output_motion_handler_id = g_signal_connect ( - G_OBJECT (priv->video_output), "motion-notify-event", - G_CALLBACK (empathy_streamed_media_window_video_output_motion_notify), - window); - } - } - else - { - disconnect_video_output_motion_handler (window); - } - - empathy_streamed_media_window_fullscreen_set_fullscreen (priv->fullscreen, - set_fullscreen); - show_controls (window, set_fullscreen); - show_borders (window, set_fullscreen); - gtk_action_set_stock_id (priv->menu_fullscreen, - (set_fullscreen ? "gtk-leave-fullscreen" : "gtk-fullscreen")); - priv->is_fullscreen = set_fullscreen; - } - - return FALSE; -} - -static void -empathy_streamed_media_window_sidebar_toggled_cb (GtkToggleButton *toggle, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - GtkWidget *arrow; - int w, h, handle_size; - GtkAllocation allocation, sidebar_allocation; - - gtk_widget_get_allocation (GTK_WIDGET (window), &allocation); - w = allocation.width; - h = allocation.height; - - gtk_widget_style_get (priv->pane, "handle_size", &handle_size, NULL); - - gtk_widget_get_allocation (priv->sidebar, &sidebar_allocation); - if (gtk_toggle_button_get_active (toggle)) - { - arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); - gtk_widget_show (priv->sidebar); - w += sidebar_allocation.width + handle_size; - } - else - { - arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - w -= sidebar_allocation.width + handle_size; - gtk_widget_hide (priv->sidebar); - } - - gtk_button_set_image (GTK_BUTTON (priv->sidebar_button), arrow); - - if (w > 0 && h > 0) - gtk_window_resize (GTK_WINDOW (window), w, h); -} - -static void -empathy_streamed_media_window_set_send_video (EmpathyStreamedMediaWindow *window, - CameraState state) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - EmpathyTpStreamedMedia *call; - - priv->sending_video = (state == CAMERA_STATE_ON); - - if (state == CAMERA_STATE_PREVIEW || - state == CAMERA_STATE_ON) - { - /* When we start sending video, we want to show the video preview by - default. */ - display_video_preview (window, TRUE); - } - else - { - display_video_preview (window, FALSE); - } - - if (priv->call_state != CONNECTED) - return; - - g_object_get (priv->handler, "tp-call", &call, NULL); - DEBUG ("%s sending video", priv->sending_video ? "start": "stop"); - empathy_tp_streamed_media_request_video_stream_direction (call, priv->sending_video); - g_object_unref (call); -} - -static void -empathy_streamed_media_window_mic_toggled_cb (GtkToggleToolButton *toggle, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - gboolean active; - - active = (gtk_toggle_tool_button_get_active (toggle)); - - if (active) - { - empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input), - priv->volume); - gtk_adjustment_set_value (priv->audio_input_adj, priv->volume * 100); - } - else - { - /* TODO, Instead of setting the input volume to 0 we should probably - * stop sending but this would cause the audio call to drop if both - * sides mute at the same time on certain CMs AFAIK. Need to revisit this - * in the future. GNOME #574574 - */ - empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input), - 0); - gtk_adjustment_set_value (priv->audio_input_adj, 0); - } -} - -static void -empathy_streamed_media_window_sidebar_hidden_cb (EvSidebar *sidebar, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->sidebar_button), - FALSE); -} - -static void -empathy_streamed_media_window_sidebar_shown_cb (EvSidebar *sidebar, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->sidebar_button), - TRUE); -} - -static void -empathy_streamed_media_window_hangup_cb (gpointer object, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - empathy_streamed_media_handler_stop_call (priv->handler); - - if (empathy_streamed_media_window_disconnected (window, FALSE)) - gtk_widget_destroy (GTK_WIDGET (window)); -} - -static void -empathy_streamed_media_window_restart_call (EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - /* Remove error info bars */ - gtk_container_forall (GTK_CONTAINER (priv->errors_vbox), - (GtkCallback) gtk_widget_destroy, NULL); - - create_video_output_widget (window); - - g_signal_connect (G_OBJECT (priv->audio_input_adj), "value-changed", - G_CALLBACK (empathy_streamed_media_window_mic_volume_changed_cb), window); - - /* While the call was disconnected, the input volume might have changed. - * However, since the audio_input source was destroyed, its volume has not - * been updated during that time. That's why we manually update it here */ - empathy_streamed_media_window_mic_volume_changed_cb (priv->audio_input_adj, window); - - priv->outgoing = TRUE; - empathy_streamed_media_window_set_state_connecting (window); - - if (priv->pipeline_playing) - start_call (window); - else - /* call will be started when the pipeline is ready */ - priv->start_call_when_playing = TRUE; - - - empathy_streamed_media_window_setup_avatars (window, priv->handler); - - gtk_action_set_sensitive (priv->redial, FALSE); - gtk_widget_set_sensitive (priv->redial_button, FALSE); -} - -static void -empathy_streamed_media_window_redial_cb (gpointer object, - EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->call_state == CONNECTED) - priv->call_state = REDIALING; - - empathy_streamed_media_handler_stop_call (priv->handler); - - if (priv->call_state != CONNECTED) - empathy_streamed_media_window_restart_call (window); -} - -static void -empathy_streamed_media_window_fullscreen_cb (gpointer object, - EmpathyStreamedMediaWindow *window) -{ - empathy_streamed_media_window_fullscreen_toggle (window); -} - -static void -empathy_streamed_media_window_fullscreen_toggle (EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->is_fullscreen) - gtk_window_unfullscreen (GTK_WINDOW (window)); - else - gtk_window_fullscreen (GTK_WINDOW (window)); -} - -static gboolean -empathy_streamed_media_window_video_button_press_cb (GtkWidget *video_output, - GdkEventButton *event, EmpathyStreamedMediaWindow *window) -{ - if (event->button == 3 && event->type == GDK_BUTTON_PRESS) - { - empathy_streamed_media_window_video_menu_popup (window, event->button); - return TRUE; - } - - return FALSE; -} - -static gboolean -empathy_streamed_media_window_key_press_cb (GtkWidget *video_output, - GdkEventKey *event, EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->is_fullscreen && event->keyval == GDK_KEY_Escape) - { - /* Since we are in fullscreen mode, toggling will bring us back to - normal mode. */ - empathy_streamed_media_window_fullscreen_toggle (window); - return TRUE; - } - - return FALSE; -} - -static gboolean -empathy_streamed_media_window_video_output_motion_notify (GtkWidget *widget, - GdkEventMotion *event, EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->is_fullscreen) - { - empathy_streamed_media_window_fullscreen_show_popup (priv->fullscreen); - return TRUE; - } - return FALSE; -} - -static void -empathy_streamed_media_window_video_menu_popup (EmpathyStreamedMediaWindow *window, - guint button) -{ - GtkWidget *menu; - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - menu = gtk_ui_manager_get_widget (priv->ui_manager, - "/video-popup"); - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, - button, gtk_get_current_event_time ()); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu), FALSE); -} - -static void -empathy_streamed_media_window_status_message (EmpathyStreamedMediaWindow *window, - gchar *message) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->context_id == 0) - { - priv->context_id = gtk_statusbar_get_context_id ( - GTK_STATUSBAR (priv->statusbar), "voip call status messages"); - } - else - { - gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), priv->context_id); - } - - gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), priv->context_id, - message); -} - -static void -empathy_streamed_media_window_volume_changed_cb (GtkScaleButton *button, - gdouble value, EmpathyStreamedMediaWindow *window) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (window); - - if (priv->audio_output == NULL) - return; - - empathy_audio_sink_set_volume (EMPATHY_GST_AUDIO_SINK (priv->audio_output), - value); -} - -/* block all the signals related to camera control widgets. This is useful - * when we are manually updating the UI and so don't want to fire the - * callbacks */ -static void -block_camera_control_signals (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - g_signal_handlers_block_by_func (priv->tool_button_camera_off, - tool_button_camera_off_toggled_cb, self); - g_signal_handlers_block_by_func (priv->tool_button_camera_preview, - tool_button_camera_preview_toggled_cb, self); - g_signal_handlers_block_by_func (priv->tool_button_camera_on, - tool_button_camera_on_toggled_cb, self); - g_signal_handlers_block_by_func (priv->action_camera_on, - action_camera_change_cb, self); -} - -static void -unblock_camera_control_signals (EmpathyStreamedMediaWindow *self) -{ - EmpathyStreamedMediaWindowPriv *priv = GET_PRIV (self); - - g_signal_handlers_unblock_by_func (priv->tool_button_camera_off, - tool_button_camera_off_toggled_cb, self); - g_signal_handlers_unblock_by_func (priv->tool_button_camera_preview, - tool_button_camera_preview_toggled_cb, self); - g_signal_handlers_unblock_by_func (priv->tool_button_camera_on, - tool_button_camera_on_toggled_cb, self); - g_signal_handlers_unblock_by_func (priv->action_camera_on, - action_camera_change_cb, self); -} diff --git a/src/empathy-streamed-media-window.h b/src/empathy-streamed-media-window.h deleted file mode 100644 index aae56d882..000000000 --- a/src/empathy-streamed-media-window.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * empathy-streamed-media-window.h - Header for EmpathyStreamedMediaWindow - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 - */ - -#ifndef __EMPATHY_STREAMED_MEDIA_WINDOW_H__ -#define __EMPATHY_STREAMED_MEDIA_WINDOW_H__ - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "empathy-streamed-media-handler.h" - -G_BEGIN_DECLS - -typedef struct _EmpathyStreamedMediaWindow EmpathyStreamedMediaWindow; -typedef struct _EmpathyStreamedMediaWindowClass EmpathyStreamedMediaWindowClass; - -struct _EmpathyStreamedMediaWindowClass { - GtkWindowClass parent_class; -}; - -struct _EmpathyStreamedMediaWindow { - GtkWindow parent; -}; - -GType empathy_streamed_media_window_get_type (void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_STREAMED_MEDIA_WINDOW \ - (empathy_streamed_media_window_get_type ()) -#define EMPATHY_STREAMED_MEDIA_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW, \ - EmpathyStreamedMediaWindow)) -#define EMPATHY_STREAMED_MEDIA_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW, \ - EmpathyStreamedMediaWindowClass)) -#define EMPATHY_IS_STREAMED_MEDIA_WINDOW(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW)) -#define EMPATHY_IS_STREAMED_MEDIA_WINDOW_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW)) -#define EMPATHY_STREAMED_MEDIA_WINDOW_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_STREAMED_MEDIA_WINDOW, \ - EmpathyStreamedMediaWindowClass)) - -EmpathyStreamedMediaWindow *empathy_streamed_media_window_new (EmpathyStreamedMediaHandler *handler); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_STREAMED_MEDIA_WINDOW_H__*/ diff --git a/src/empathy-streamed-media-window.ui b/src/empathy-streamed-media-window.ui deleted file mode 100644 index 5f1a16e8c..000000000 --- a/src/empathy-streamed-media-window.ui +++ /dev/null @@ -1,861 +0,0 @@ -<?xml version="1.0"?> -<!--Generated with glade3 3.4.5 on Mon Feb 16 12:31:56 2009 --> -<interface> - <object class="GtkUIManager" id="ui_manager"> - <child> - <object class="GtkActionGroup" id="actiongroup1"> - <child> - <object class="GtkAction" id="call"> - <property name="name">call</property> - <property name="label" translatable="yes">_Call</property> - </object> - </child> - <child> - <object class="GtkAction" id="menuhangup"> - <property name="icon_name">call-stop</property> - <property name="name">menuhangup</property> - <property name="label" translatable="yes">Hang up</property> - </object> - </child> - <child> - <object class="GtkAction" id="menuredial"> - <property name="stock_id">gtk-refresh</property> - <property name="name">menuredial</property> - <property name="label" translatable="yes">Redial</property> - <property name="sensitive">False</property> - </object> - </child> - <child> - <object class="GtkAction" id="camera"> - <property name="name">camera</property> - <property name="label" translatable="yes">V_ideo</property> - </object> - </child> - <child> - <object class="GtkRadioAction" id="action_camera_off"> - <property name="name">action_camera_off</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Video Off</property> - <property name="draw_as_radio">True</property> - <property name="value">0</property> - <property name="current-value">0</property> - </object> - </child> - <child> - <object class="GtkRadioAction" id="action_camera_preview"> - <property name="name">action_camera_preview</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Video Preview</property> - <property name="draw_as_radio">True</property> - <property name="group">action_camera_off</property> - <property name="value">1</property> - </object> - </child> - <child> - <object class="GtkRadioAction" id="action_camera_on"> - <property name="name">action_camera_on</property> - <property name="visible">True</property> - <property name="sensitive">False</property> - <property name="label" translatable="yes">Video On</property> - <property name="draw_as_radio">True</property> - <property name="group">action_camera_off</property> - <property name="value">2</property> - </object> - </child> - <child> - <object class="GtkAction" id="view"> - <property name="name">view</property> - <property name="label" translatable="yes">_View</property> - </object> - </child> - <child> - <object class="GtkAction" id="menufullscreen"> - <property name="stock_id">gtk-fullscreen</property> - <property name="name">menufullscreen</property> - </object> - <accelerator key="F11"/> - </child> - </object> - </child> - <ui> - <menubar name="menubar1"> - <menu action="call"> - <menuitem action="menuhangup"/> - <menuitem action="menuredial"/> - </menu> - <menu action="camera"> - <menuitem action="action_camera_off"/> - <menuitem action="action_camera_preview"/> - <menuitem action="action_camera_on"/> - </menu> - <menu action="view"> - <menuitem action="menufullscreen"/> - </menu> - </menubar> - <popup name="video-popup"> - <menuitem name="menufullscreen" action="menufullscreen"/> - </popup> - </ui> - </object> - <object class="GtkVBox" id="call_window_vbox"> - <property name="visible">True</property> - <child> - <object class="GtkMenuBar" constructor="ui_manager" id="menubar1"> - <property name="visible">True</property> - </object> - <packing> - <property name="expand">False</property> - </packing> - </child> - <child> - <object class="GtkToolbar" id="toolbar"> - <property name="visible">True</property> - <style> - <class name="primary-toolbar"/> - </style> - <child> - <object class="GtkToolButton" id="hangup"> - <property name="visible">True</property> - <property name="is_important">True</property> - <property name="label" translatable="yes">Hang up</property> - <property name="icon_name">call-stop</property> - <property name="tooltip_text" translatable="yes">Hang up current call</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToolButton" id="redial"> - <property name="visible">True</property> - <property name="is_important">True</property> - <property name="label" translatable="yes">Redial</property> - <property name="stock_id">gtk-refresh</property> - <property name="sensitive">False</property> - <property name="tooltip_text" translatable="yes">Call the contact again</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkSeparatorToolItem" id="toolbutton1"> - <property name="visible">True</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToggleToolButton" id="microphone"> - <property name="visible">True</property> - <property name="active">True</property> - <property name="label" translatable="yes">Send Audio</property> - <property name="icon_name">gnome-stock-mic</property> - <property name="tooltip_text" translatable="yes">Toggle audio transmission</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkSeparatorToolItem" id="camera_separator"> - <property name="visible">True</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToggleToolButton" id="camera_off"> - <property name="visible">True</property> - <property name="label" translatable="yes">Camera Off</property> - <property name="sensitive">True</property> - <property name="tooltip_text" translatable="yes">Disable camera and stop sending video</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToggleToolButton" id="camera_preview"> - <property name="visible">True</property> - <property name="label" translatable="yes">Preview</property> - <property name="icon_name">avatar-default</property> - <property name="sensitive">True</property> - <property name="tooltip_text" translatable="yes">Enable camera but don't send video</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - <child> - <object class="GtkToggleToolButton" id="camera_on"> - <property name="visible">True</property> - <property name="label" translatable="yes">Camera On</property> - <property name="icon_name">camera-web</property> - <property name="sensitive">False</property> - <property name="tooltip_text" translatable="yes">Enable camera and send video</property> - </object> - <packing> - <property name="homogeneous">True</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkVBox" id="errors_vbox"> - <property name="visible">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkHPaned" id="pane"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <child> - <placeholder/> - </child> - <child> - <placeholder/> - </child> - </object> - <packing> - <property name="position">3</property> - </packing> - </child> - <child> - <object class="GtkStatusbar" id="statusbar"> - <property name="visible">True</property> - <property name="spacing">2</property> - </object> - <packing> - <property name="expand">False</property> - <property name="position">4</property> - </packing> - </child> - </object> - - <object class="GtkVBox" id="details_vbox"> - <property name="border_width">6</property> - <property name="visible">False</property> - <property name="homogeneous">False</property> - <property name="spacing">18</property> - <property name="orientation">vertical</property> - - <child> - <object class="GtkVBox" id="video_vbox"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - <property name="orientation">vertical</property> - - <child> - <object class="GtkLabel" id="video_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Video</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <object class="GtkAlignment" id="alignment2"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">1</property> - <property name="yscale">1</property> - <property name="top_padding">0</property> - <property name="bottom_padding">0</property> - <property name="left_padding">12</property> - <property name="right_padding">0</property> - - <child> - <object class="GtkGrid" id="video"> - <property name="visible">True</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - - <child> - <object class="GtkLabel" id="vcodec1_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Encoding Codec:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - - <child> - - <object class="GtkLabel" id="vcodec_encoding_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="vcodec2_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Decoding Codec:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - - <child> - - <object class="GtkLabel" id="vcodec_decoding_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="vrc_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Remote Candidate:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="video_remote_candidate_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - </packing> - </child> - - <child> - <object class="GtkImage" id="video_remote_candidate_info_img"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">3</property> - </packing> - </child> - - - <child> - <object class="GtkLabel" id="vlc_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Local Candidate:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">4</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="video_local_candidate_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">4</property> - </packing> - </child> - - <child> - <object class="GtkImage" id="video_local_candidate_info_img"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">4</property> - </packing> - </child> - - </object> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <object class="GtkVBox" id="audio_vbox"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - <property name="orientation">vertical</property> - - <child> - <object class="GtkLabel" id="bvwp_audio_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Audio</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <object class="GtkAlignment" id="alignment3"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">1</property> - <property name="yscale">1</property> - <property name="top_padding">0</property> - <property name="bottom_padding">0</property> - <property name="left_padding">12</property> - <property name="right_padding">0</property> - - <child> - <object class="GtkGrid" id="audio"> - <property name="visible">True</property> - <property name="row_spacing">6</property> - <property name="column_spacing">12</property> - - <child> - <object class="GtkLabel" id="acodec1_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Encoding Codec:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="acodec_encoding_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">0</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="acodec2_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Decoding Codec:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">1</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="acodec_decoding_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">1</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="arc_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Remote Candidate:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">2</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="audio_remote_candidate_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">2</property> - </packing> - </child> - - <child> - <object class="GtkImage" id="audio_remote_candidate_info_img"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">2</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="alc_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Local Candidate:</property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - <attributes> - <attribute name="style" value="PANGO_STYLE_ITALIC"/> - </attributes> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">3</property> - </packing> - </child> - - <child> - <object class="GtkLabel" id="audio_local_candidate_label"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Unknown</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> - <property name="width_chars">-1</property> - <property name="single_line_mode">False</property> - <property name="angle">0</property> - </object> - <packing> - <property name="left_attach">1</property> - <property name="top_attach">3</property> - </packing> - </child> - - <child> - <object class="GtkImage" id="audio_local_candidate_info_img"> - <property name="visible">True</property> - <property name="stock">gtk-info</property> - <property name="xalign">0</property> - </object> - <packing> - <property name="left_attach">2</property> - <property name="top_attach">3</property> - </packing> - </child> - - </object> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </object> - -</interface> diff --git a/src/empathy-video-widget.c b/src/empathy-video-widget.c deleted file mode 100644 index 43ea212d5..000000000 --- a/src/empathy-video-widget.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * empathy-gst-gtk-widget.c - Source for EmpathyVideoWidget - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 <stdio.h> -#include <stdlib.h> - -#include <gdk/gdkx.h> -#include <gst/interfaces/xoverlay.h> -#include <farstream/fs-element-added-notifier.h> - -#include "empathy-video-widget.h" - -G_DEFINE_TYPE(EmpathyVideoWidget, empathy_video_widget, - GTK_TYPE_DRAWING_AREA) - -static void empathy_video_widget_element_added_cb ( - FsElementAddedNotifier *notifier, GstBin *bin, GstElement *element, - EmpathyVideoWidget *self); - -static void empathy_video_widget_sync_message_cb ( - GstBus *bus, GstMessage *message, EmpathyVideoWidget *self); - -/* signal enum */ -#if 0 -enum -{ - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = {0}; -#endif - -enum { - PROP_GST_ELEMENT = 1, - PROP_GST_BUS, - PROP_MIN_WIDTH, - PROP_MIN_HEIGHT, - PROP_SYNC, - PROP_ASYNC, - PROP_FLIP_VIDEO, -}; - -/* private structure */ -typedef struct _EmpathyVideoWidgetPriv EmpathyVideoWidgetPriv; - -struct _EmpathyVideoWidgetPriv -{ - gboolean dispose_has_run; - GstBus *bus; - GstElement *videosink; - GstPad *sink_pad; - GstElement *overlay; - GstElement *flip; - FsElementAddedNotifier *notifier; - gint min_width; - gint min_height; - gboolean sync; - gboolean async; - gboolean flip_video; - guintptr xid; - - GMutex *lock; -}; - -#define GET_PRIV(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - EMPATHY_TYPE_VIDEO_WIDGET, EmpathyVideoWidgetPriv)) - -static void -empathy_video_widget_init (EmpathyVideoWidget *obj) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (obj); - GdkRGBA black; - - priv->lock = g_mutex_new (); - - priv->notifier = fs_element_added_notifier_new (); - g_signal_connect (priv->notifier, "element-added", - G_CALLBACK (empathy_video_widget_element_added_cb), - obj); - - if (gdk_rgba_parse (&black, "Black")) - gtk_widget_override_background_color (GTK_WIDGET (obj), 0, &black); - - gtk_widget_set_double_buffered (GTK_WIDGET (obj), FALSE); -} - -static void -empathy_video_widget_realized (GtkWidget *widget, gpointer user_data) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (widget); - - /* requesting the XID forces the GdkWindow to be native in GTK+ 2.18 - * onwards, requesting the native window in a thread causes a BadWindowID, - * so we need to request it now. We could call gdk_window_ensure_native(), - * but that would mean we require GTK+ 2.18, so instead we call this */ - priv->xid = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (widget))); -} - -static void -empathy_video_widget_constructed (GObject *object) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (object); - GstElement *colorspace, *videoscale, *sink; - GstPad *pad; - - g_signal_connect (object, "realize", - G_CALLBACK (empathy_video_widget_realized), NULL); - - priv->videosink = gst_bin_new (NULL); - - gst_object_ref_sink (priv->videosink); - - sink = gst_element_factory_make ("gconfvideosink", NULL); - g_assert (sink != NULL); - - videoscale = gst_element_factory_make ("videoscale", NULL); - g_assert (videoscale != NULL); - - g_object_set (videoscale, "qos", FALSE, NULL); - - colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL); - g_assert (colorspace != NULL); - - g_object_set (colorspace, "qos", FALSE, NULL); - - priv->flip = gst_element_factory_make ("videoflip", NULL); - g_assert (priv->flip != NULL); - - gst_bin_add_many (GST_BIN (priv->videosink), colorspace, videoscale, - priv->flip, sink, NULL); - - if (!gst_element_link (colorspace, videoscale)) - g_error ("Failed to link ffmpegcolorspace and videoscale"); - - if (!gst_element_link (videoscale, priv->flip)) - g_error ("Failed to link videoscale and videoflip"); - - if (!gst_element_link (priv->flip, sink)) - g_error ("Failed to link videoflip and gconfvideosink"); - - pad = gst_element_get_static_pad (colorspace, "sink"); - g_assert (pad != NULL); - - priv->sink_pad = gst_ghost_pad_new ("sink", pad); - if (!gst_element_add_pad (priv->videosink, priv->sink_pad)) - g_error ("Couldn't add sink ghostpad to the bin"); - - gst_object_unref (pad); - - fs_element_added_notifier_add (priv->notifier, GST_BIN (priv->videosink)); - gst_bus_enable_sync_message_emission (priv->bus); - - g_signal_connect (priv->bus, "sync-message", - G_CALLBACK (empathy_video_widget_sync_message_cb), object); - - gtk_widget_set_size_request (GTK_WIDGET (object), priv->min_width, - priv->min_height); -} - -static void empathy_video_widget_dispose (GObject *object); -static void empathy_video_widget_finalize (GObject *object); - - -static gboolean empathy_video_widget_draw (GtkWidget *widget, - cairo_t *cr); - -static void -empathy_video_widget_element_set_sink_properties (EmpathyVideoWidget *self); - -static void -empathy_video_widget_set_property (GObject *object, - guint property_id, const GValue *value, GParamSpec *pspec) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_GST_BUS: - priv->bus = g_value_dup_object (value); - break; - case PROP_MIN_WIDTH: - priv->min_width = g_value_get_int (value); - break; - case PROP_MIN_HEIGHT: - priv->min_height = g_value_get_int (value); - break; - case PROP_SYNC: - priv->sync = g_value_get_boolean (value); - empathy_video_widget_element_set_sink_properties ( - EMPATHY_VIDEO_WIDGET (object)); - break; - case PROP_ASYNC: - priv->async = g_value_get_boolean (value); - empathy_video_widget_element_set_sink_properties ( - EMPATHY_VIDEO_WIDGET (object)); - break; - case PROP_FLIP_VIDEO: - priv->flip_video = g_value_get_boolean (value); - gst_util_set_object_arg (G_OBJECT (priv->flip), "method", - priv->flip_video ? "horizontal-flip" : "none"); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - -static void -empathy_video_widget_get_property (GObject *object, - guint property_id, GValue *value, GParamSpec *pspec) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (object); - - switch (property_id) - { - case PROP_GST_ELEMENT: - g_value_set_object (value, priv->videosink); - break; - case PROP_GST_BUS: - g_value_set_object (value, priv->bus); - break; - case PROP_MIN_WIDTH: - g_value_set_int (value, priv->min_width); - break; - case PROP_MIN_HEIGHT: - g_value_set_int (value, priv->min_height); - break; - case PROP_SYNC: - g_value_set_boolean (value, priv->sync); - break; - case PROP_ASYNC: - g_value_set_boolean (value, priv->async); - break; - case PROP_FLIP_VIDEO: - g_value_set_boolean (value, priv->flip_video); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - } -} - - -static void -empathy_video_widget_class_init ( - EmpathyVideoWidgetClass *empathy_video_widget_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (empathy_video_widget_class); - GtkWidgetClass *widget_class = - GTK_WIDGET_CLASS (empathy_video_widget_class); - GParamSpec *param_spec; - - g_type_class_add_private (empathy_video_widget_class, - sizeof (EmpathyVideoWidgetPriv)); - - object_class->dispose = empathy_video_widget_dispose; - object_class->finalize = empathy_video_widget_finalize; - object_class->constructed = empathy_video_widget_constructed; - - object_class->set_property = empathy_video_widget_set_property; - object_class->get_property = empathy_video_widget_get_property; - - widget_class->draw = empathy_video_widget_draw; - - param_spec = g_param_spec_object ("gst-element", - "gst-element", "The underlaying gstreamer element", - GST_TYPE_ELEMENT, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_GST_ELEMENT, param_spec); - - param_spec = g_param_spec_object ("gst-bus", - "gst-bus", - "The toplevel bus from the pipeline in which this bin will be added", - GST_TYPE_BUS, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_GST_BUS, param_spec); - - param_spec = g_param_spec_int ("min-width", - "min-width", - "Minimal width of the widget", - 0, G_MAXINT, EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_MIN_WIDTH, param_spec); - - param_spec = g_param_spec_int ("min-height", - "min-height", - "Minimal height of the widget", - 0, G_MAXINT, EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT, - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_MIN_HEIGHT, param_spec); - - param_spec = g_param_spec_boolean ("sync", - "sync", - "Whether the underlying sink should be sync or not", - TRUE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_SYNC, param_spec); - - param_spec = g_param_spec_boolean ("async", - "async", - "Whether the underlying sink should be async or not", - TRUE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_ASYNC, param_spec); - - param_spec = g_param_spec_boolean ("flip-video", - "flip video", - "Whether the video should be flipped horizontally or not", - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - g_object_class_install_property (object_class, PROP_FLIP_VIDEO, param_spec); -} - -void -empathy_video_widget_dispose (GObject *object) -{ - EmpathyVideoWidget *self = EMPATHY_VIDEO_WIDGET (object); - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - - if (priv->dispose_has_run) - return; - - priv->dispose_has_run = TRUE; - - g_signal_handlers_disconnect_by_func (priv->bus, - empathy_video_widget_sync_message_cb, object); - - if (priv->bus != NULL) - g_object_unref (priv->bus); - - priv->bus = NULL; - - if (priv->videosink != NULL) - g_object_unref (priv->videosink); - - priv->videosink = NULL; - - - /* release any references held by the object here */ - - if (G_OBJECT_CLASS (empathy_video_widget_parent_class)->dispose) - G_OBJECT_CLASS (empathy_video_widget_parent_class)->dispose (object); -} - -void -empathy_video_widget_finalize (GObject *object) -{ - EmpathyVideoWidget *self = EMPATHY_VIDEO_WIDGET (object); - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - - /* free any data held directly by the object here */ - g_mutex_free (priv->lock); - - G_OBJECT_CLASS (empathy_video_widget_parent_class)->finalize (object); -} - - -static void -empathy_video_widget_element_set_sink_properties_unlocked ( - EmpathyVideoWidget *self) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - - if (priv->overlay == NULL) - return; - - if (g_object_class_find_property (G_OBJECT_GET_CLASS (priv->overlay), - "force-aspect-ratio")) - g_object_set (G_OBJECT (priv->overlay), "force-aspect-ratio", TRUE, NULL); - - if (g_object_class_find_property ( - G_OBJECT_GET_CLASS (priv->overlay), "sync")) - g_object_set (G_OBJECT (priv->overlay), "sync", priv->sync, NULL); - - if (g_object_class_find_property (G_OBJECT_GET_CLASS (priv->overlay), - "async")) - g_object_set (G_OBJECT (priv->overlay), "async", priv->async, NULL); -} - -static void -empathy_video_widget_element_set_sink_properties (EmpathyVideoWidget *self) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - - g_mutex_lock (priv->lock); - empathy_video_widget_element_set_sink_properties_unlocked (self); - g_mutex_unlock (priv->lock); -} - -static void -empathy_video_widget_element_added_cb (FsElementAddedNotifier *notifier, - GstBin *bin, GstElement *element, EmpathyVideoWidget *self) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - - /* We assume the overlay is the sink */ - g_mutex_lock (priv->lock); - if (priv->overlay == NULL && GST_IS_X_OVERLAY (element)) - { - priv->overlay = element; - g_object_add_weak_pointer (G_OBJECT (element), - (gpointer) &priv->overlay); - empathy_video_widget_element_set_sink_properties_unlocked (self); - gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay)); - } - g_mutex_unlock (priv->lock); -} - -static void -empathy_video_widget_sync_message_cb (GstBus *bus, GstMessage *message, - EmpathyVideoWidget *self) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - const GstStructure *s; - - if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) - return; - - if (GST_MESSAGE_SRC (message) != (GstObject *) priv->overlay) - return; - - s = gst_message_get_structure (message); - - if (gst_structure_has_name (s, "prepare-xwindow-id")) - { - g_assert (priv->xid != 0); - gst_x_overlay_set_window_handle (GST_X_OVERLAY (priv->overlay), - priv->xid); - } -} - -static gboolean -empathy_video_widget_draw (GtkWidget *widget, - cairo_t *cr) -{ - EmpathyVideoWidget *self = EMPATHY_VIDEO_WIDGET (widget); - EmpathyVideoWidgetPriv *priv = GET_PRIV (self); - GtkAllocation allocation; - - if (priv->overlay == NULL) - { - gtk_widget_get_allocation (widget, &allocation); - - gtk_render_frame (gtk_widget_get_style_context (widget), cr, - 0, 0, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); - return TRUE; - } - - gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (priv->overlay), - GDK_WINDOW_XID (gtk_widget_get_window (widget))); - - gst_x_overlay_expose (GST_X_OVERLAY (priv->overlay)); - - return TRUE; -} - -GtkWidget * -empathy_video_widget_new_with_size (GstBus *bus, gint width, gint height) -{ - g_return_val_if_fail (bus != NULL, NULL); - - return GTK_WIDGET (g_object_new (EMPATHY_TYPE_VIDEO_WIDGET, - "gst-bus", bus, - "min-width", width, - "min-height", height, - NULL)); -} - -GtkWidget * -empathy_video_widget_new (GstBus *bus) -{ - g_return_val_if_fail (bus != NULL, NULL); - - return GTK_WIDGET (g_object_new (EMPATHY_TYPE_VIDEO_WIDGET, - "gst-bus", bus, - NULL)); -} - -GstPad * -empathy_video_widget_get_sink (EmpathyVideoWidget *widget) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (widget); - - return priv->sink_pad; -} - -GstElement * -empathy_video_widget_get_element (EmpathyVideoWidget *widget) -{ - EmpathyVideoWidgetPriv *priv = GET_PRIV (widget); - - return priv->videosink; -} diff --git a/src/empathy-video-widget.h b/src/empathy-video-widget.h deleted file mode 100644 index cfdd0354c..000000000 --- a/src/empathy-video-widget.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * empathy-gst-gtk-widget.h - Header for EmpathyVideoWidget - * Copyright (C) 2008 Collabora Ltd. - * @author Sjoerd Simons <sjoerd.simons@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 - */ - -#ifndef __EMPATHY_VIDEO_WIDGET_H__ -#define __EMPATHY_VIDEO_WIDGET_H__ - -#define EMPATHY_VIDEO_WIDGET_DEFAULT_WIDTH 320 -#define EMPATHY_VIDEO_WIDGET_DEFAULT_HEIGHT 240 - -#include <glib-object.h> -#include <gst/gst.h> -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -typedef struct _EmpathyVideoWidget EmpathyVideoWidget; -typedef struct _EmpathyVideoWidgetClass EmpathyVideoWidgetClass; - -struct _EmpathyVideoWidgetClass { - GtkDrawingAreaClass parent_class; -}; - -struct _EmpathyVideoWidget { - GtkDrawingArea parent; -}; - -GType empathy_video_widget_get_type (void); - -/* TYPE MACROS */ -#define EMPATHY_TYPE_VIDEO_WIDGET \ - (empathy_video_widget_get_type ()) -#define EMPATHY_VIDEO_WIDGET(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), EMPATHY_TYPE_VIDEO_WIDGET, \ - EmpathyVideoWidget)) -#define EMPATHY_VIDEO_WIDGET_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), EMPATHY_TYPE_VIDEO_WIDGET, \ - EmpathyVideoWidgetClass)) -#define EMPATHY_IS_VIDEO_WIDGET(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj), EMPATHY_TYPE_VIDEO_WIDGET)) -#define EMPATHY_IS_VIDEO_WIDGET_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass), EMPATHY_TYPE_VIDEO_WIDGET)) -#define EMPATHY_VIDEO_WIDGET_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_VIDEO_WIDGET, \ - EmpathyVideoWidgetClass)) - -GtkWidget *empathy_video_widget_new (GstBus *bus); -GtkWidget *empathy_video_widget_new_with_size (GstBus *bus, - gint width, gint height); - -GstElement *empathy_video_widget_get_element (EmpathyVideoWidget *widget); -GstPad *empathy_video_widget_get_sink (EmpathyVideoWidget *widget); - -G_END_DECLS - -#endif /* #ifndef __EMPATHY_VIDEO_WIDGET_H__*/ diff --git a/src/empathy.c b/src/empathy.c index b06b595e6..e2ae2632f 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -52,7 +52,6 @@ #include <libempathy/empathy-utils.h> #include <libempathy/empathy-chatroom-manager.h> #include <libempathy/empathy-account-settings.h> -#include <libempathy/empathy-connectivity.h> #include <libempathy/empathy-connection-managers.h> #include <libempathy/empathy-request-util.h> #include <libempathy/empathy-ft-factory.h> @@ -119,7 +118,6 @@ struct _EmpathyApp EmpathyChatroomManager *chatroom_manager; EmpathyFTFactory *ft_factory; EmpathyPresenceManager *presence_mgr; - EmpathyConnectivity *connectivity; GSettings *gsettings; EmpathyNotificationsApprover *notifications_approver; EmpathyConnectionAggregator *conn_aggregator; @@ -157,7 +155,6 @@ empathy_app_dispose (GObject *object) #endif tp_clear_object (&self->presence_mgr); - tp_clear_object (&self->connectivity); tp_clear_object (&self->icon); tp_clear_object (&self->account_manager); tp_clear_object (&self->log_manager); @@ -353,10 +350,17 @@ empathy_app_command_line (GApplication *app, self->activated = TRUE; /* Setting up UI */ - self->window = empathy_roster_window_dup (); + self->window = empathy_roster_window_new (GTK_APPLICATION (app)); + gtk_application_set_app_menu (GTK_APPLICATION (self), + empathy_roster_window_get_menu_model ( + EMPATHY_ROSTER_WINDOW (self->window))); gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (self->window)); + gtk_application_add_accelerator (GTK_APPLICATION (app), + "<Primary>h", + "win." EMPATHY_PREFS_UI_SHOW_OFFLINE, + NULL); /* check if Shell is running */ dbus = tp_dbus_daemon_dup (&error); @@ -442,6 +446,7 @@ empathy_app_local_command_line (GApplication *app, /* We create a group so that GOptionArgFuncs get the user data */ group = g_option_group_new ("empathy", NULL, NULL, app, NULL); + g_option_group_set_translation_domain (group, GETTEXT_PACKAGE); g_option_group_add_entries (group, options); optcontext = g_option_context_new (N_("- Empathy IM Client")); @@ -515,17 +520,6 @@ empathy_app_init (EmpathyApp *self) } static void -use_conn_notify_cb (GSettings *gsettings, - const gchar *key, - gpointer user_data) -{ - EmpathyConnectivity *connectivity = user_data; - - empathy_connectivity_set_use_conn (connectivity, - g_settings_get_boolean (gsettings, key)); -} - -static void migrate_config_to_xdg_dir (void) { gchar *xdg_dir, *old_dir, *xdg_filename, *old_filename; @@ -748,10 +742,10 @@ empathy_app_constructed (GObject *object) EmpathyApp *self = (EmpathyApp *) object; gboolean chatroom_manager_ready; + textdomain (GETTEXT_PACKAGE); g_set_application_name (_(PACKAGE_NAME)); gtk_window_set_default_icon_name ("empathy"); - textdomain (GETTEXT_PACKAGE); #ifdef ENABLE_DEBUG /* Set up debug sender */ @@ -766,14 +760,6 @@ empathy_app_constructed (GObject *object) self->gsettings = g_settings_new (EMPATHY_PREFS_SCHEMA); - /* Setting up Connectivity */ - self->connectivity = empathy_connectivity_dup_singleton (); - use_conn_notify_cb (self->gsettings, EMPATHY_PREFS_USE_CONN, - self->connectivity); - g_signal_connect (self->gsettings, - "changed::" EMPATHY_PREFS_USE_CONN, - G_CALLBACK (use_conn_notify_cb), self->connectivity); - /* account management */ self->account_manager = tp_account_manager_dup (); tp_proxy_prepare_async (self->account_manager, NULL, @@ -837,7 +823,6 @@ main (int argc, char *argv[]) EmpathyApp *app; gint retval; - g_thread_init (NULL); g_type_init (); #ifdef HAVE_LIBCHAMPLAIN diff --git a/src/ev-sidebar.c b/src/ev-sidebar.c deleted file mode 100644 index a9eca76d9..000000000 --- a/src/ev-sidebar.c +++ /dev/null @@ -1,351 +0,0 @@ -/* this file is part of evince, a gnome document viewer - * - * Copyright (C) 2004 Red Hat, Inc. - * (C) 2007 Jan Arne Petersen - * - * Authors: - * Jonathan Blandford <jrb@alum.mit.edu> - * Jan Arne Petersen <jpetersen@jpetersen.org> - * - * Evince is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Evince is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA. - * - * Thursday 03 May 2007: Bastien Nocera: Add exception clause. - * See license_change file for details. - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> - -#include "ev-sidebar.h" - -enum -{ - PAGE_COLUMN_ID, - PAGE_COLUMN_TITLE, - PAGE_COLUMN_NUM_COLS -}; - -struct _EvSidebarPrivate { - GtkWidget *combobox; - GtkWidget *notebook; -}; - -enum { - CLOSED, - CHANGED, - LAST_SIGNAL -}; - -static int ev_sidebar_table_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (EvSidebar, ev_sidebar, GTK_TYPE_VBOX) - -#define EV_SIDEBAR_GET_PRIVATE(object) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR, EvSidebarPrivate)) - -static void -ev_sidebar_class_init (EvSidebarClass *ev_sidebar_class) -{ - GObjectClass *g_object_class; - - g_object_class = G_OBJECT_CLASS (ev_sidebar_class); - - g_type_class_add_private (g_object_class, sizeof (EvSidebarPrivate)); - - ev_sidebar_table_signals[CLOSED] = - g_signal_new ("closed", - G_TYPE_FROM_CLASS (g_object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EvSidebarClass, closed), - NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, 0); - - ev_sidebar_table_signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (g_object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EvSidebarClass, closed), - NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, 1, G_TYPE_STRING); - -} - -static void -ev_sidebar_close_clicked_cb (GtkWidget *widget, - gpointer user_data) -{ - EvSidebar *ev_sidebar = EV_SIDEBAR (user_data); - - g_signal_emit (G_OBJECT (ev_sidebar), - ev_sidebar_table_signals[CLOSED], 0, NULL); - gtk_widget_hide (GTK_WIDGET (ev_sidebar)); -} - -static void -ev_sidebar_combobox_changed_cb (GtkComboBox *combo_box, - gpointer user_data) -{ - EvSidebar *ev_sidebar = EV_SIDEBAR (user_data); - GtkTreeModel *model; - GtkTreeIter iter; - - model = gtk_combo_box_get_model (combo_box); - - if (gtk_combo_box_get_active_iter (combo_box, &iter)) { - GtkTreePath *path; - gint *indices; - - path = gtk_tree_model_get_path (model, &iter); - indices = gtk_tree_path_get_indices (path); - - if (indices != NULL) { - gchar *page; - - gtk_notebook_set_current_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), indices[0]); - gtk_tree_model_get (model, &iter, PAGE_COLUMN_ID, &page, -1); - g_signal_emit (G_OBJECT (ev_sidebar), ev_sidebar_table_signals[CHANGED], 0, page); - g_free (page); - } - - gtk_tree_path_free (path); - } - -} - -static void -ev_sidebar_init (EvSidebar *ev_sidebar) -{ - GtkTreeModel *page_model; - GtkWidget *vbox, *hbox; - GtkWidget *close_button; - GtkCellRenderer *renderer; - GtkWidget *image; - - ev_sidebar->priv = EV_SIDEBAR_GET_PRIVATE (ev_sidebar); - - /* data model */ - page_model = (GtkTreeModel *) - gtk_list_store_new (PAGE_COLUMN_NUM_COLS, - G_TYPE_STRING, - G_TYPE_STRING, - GTK_TYPE_WIDGET, - G_TYPE_INT); - - /* create a 6 6 6 0 border with GtkBoxes */ - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (ev_sidebar), hbox, TRUE, TRUE, 6); - - vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), gtk_box_new (GTK_ORIENTATION_VERTICAL, 0), FALSE, FALSE, 0); - - /* top option menu */ - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - gtk_widget_show (hbox); - - ev_sidebar->priv->combobox = gtk_combo_box_new_with_model (page_model); - g_signal_connect (ev_sidebar->priv->combobox, "changed", - G_CALLBACK (ev_sidebar_combobox_changed_cb), - ev_sidebar); - - renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (ev_sidebar->priv->combobox), renderer, TRUE); - gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (ev_sidebar->priv->combobox), renderer, "text", PAGE_COLUMN_TITLE); - - gtk_box_pack_start (GTK_BOX (hbox), ev_sidebar->priv->combobox, TRUE, TRUE, 0); - gtk_widget_show (ev_sidebar->priv->combobox); - - g_object_unref (G_OBJECT (page_model)); - - close_button = gtk_button_new (); - gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE); - g_signal_connect (close_button, "clicked", - G_CALLBACK (ev_sidebar_close_clicked_cb), - ev_sidebar); - - image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, - GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (close_button), image); - gtk_widget_show (image); - - gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0); - gtk_widget_show (close_button); - - ev_sidebar->priv->notebook = gtk_notebook_new (); - gtk_notebook_set_show_border (GTK_NOTEBOOK (ev_sidebar->priv->notebook), FALSE); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ev_sidebar->priv->notebook), FALSE); - gtk_box_pack_start (GTK_BOX (vbox), ev_sidebar->priv->notebook, - TRUE, TRUE, 0); - gtk_widget_show (ev_sidebar->priv->notebook); -} - -/* Public functions */ - -GtkWidget * -ev_sidebar_new (void) -{ - GtkWidget *ev_sidebar; - - ev_sidebar = g_object_new (EV_TYPE_SIDEBAR, NULL); - - return ev_sidebar; -} - -/* NOTE: Return values from this have to be g_free()d */ -char * -ev_sidebar_get_current_page (EvSidebar *ev_sidebar) -{ - GtkTreeModel *model; - GtkTreeIter iter; - char *id; - - g_return_val_if_fail (EV_IS_SIDEBAR (ev_sidebar), NULL); - g_return_val_if_fail (ev_sidebar->priv != NULL, NULL); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox)); - - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter)) { - gtk_tree_model_get (model, &iter, PAGE_COLUMN_ID, &id, -1); - - return id; - } - - return NULL; -} - -static gboolean -ev_sidebar_get_iter_for_page_id (EvSidebar *ev_sidebar, - const char *new_page_id, - GtkTreeIter *iter) -{ - GtkTreeModel *model; - gboolean valid; - gchar *page_id; - - g_return_val_if_fail (EV_IS_SIDEBAR (ev_sidebar), FALSE); - g_return_val_if_fail (ev_sidebar->priv != NULL, FALSE); - g_return_val_if_fail (iter != NULL, FALSE); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox)); - - valid = gtk_tree_model_get_iter_first (model, iter); - - while (valid) { - gtk_tree_model_get (model, iter, PAGE_COLUMN_ID, &page_id, -1); - - if (page_id != NULL && strcmp (new_page_id, page_id) == 0) { - g_free (page_id); - return TRUE; - } - g_free (page_id); - - valid = gtk_tree_model_iter_next (model, iter); - } - - return FALSE; -} - -void -ev_sidebar_set_current_page (EvSidebar *ev_sidebar, const char *new_page_id) -{ - GtkTreeIter iter; - - g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar)); - g_return_if_fail (new_page_id != NULL); - - - if (ev_sidebar_get_iter_for_page_id (ev_sidebar, new_page_id, &iter)) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter); - } -} - -void -ev_sidebar_add_page (EvSidebar *ev_sidebar, - const gchar *page_id, - const gchar *title, - GtkWidget *main_widget) -{ - GtkTreeIter iter, iter2; - GtkTreeModel *model; - - g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar)); - g_return_if_fail (page_id != NULL); - g_return_if_fail (title != NULL); - g_return_if_fail (GTK_IS_WIDGET (main_widget)); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox)); - - gtk_widget_set_sensitive (GTK_WIDGET (ev_sidebar), TRUE); - - gtk_widget_show (main_widget); - gtk_notebook_append_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), main_widget, NULL); - - gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, -1, - PAGE_COLUMN_ID, page_id, - PAGE_COLUMN_TITLE, title, - -1); - - if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter2)) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter); - } -} - -void -ev_sidebar_remove_page (EvSidebar *ev_sidebar, - const gchar *page_id) -{ - GtkTreeIter iter; - GtkTreeModel *model; - - g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar)); - g_return_if_fail (page_id != NULL); - - model = gtk_combo_box_get_model (GTK_COMBO_BOX (ev_sidebar->priv->combobox)); - - if (ev_sidebar_get_iter_for_page_id (ev_sidebar, page_id, &iter)) { - GtkTreePath *path; - gint *indices; - - path = gtk_tree_model_get_path (model, &iter); - indices = gtk_tree_path_get_indices (path); - - g_assert (indices != NULL); - gtk_notebook_remove_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), indices[0]); - - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - - if (gtk_tree_model_iter_n_children (model, NULL) != 0) { - gtk_tree_path_prev (path); - - if (gtk_tree_model_get_iter (model, &iter, path)) { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (ev_sidebar->priv->combobox), &iter); - } - } else { - gtk_widget_set_sensitive (GTK_WIDGET (ev_sidebar), FALSE); - } - - gtk_tree_path_free (path); - } -} - diff --git a/src/ev-sidebar.h b/src/ev-sidebar.h deleted file mode 100644 index cfb57f2eb..000000000 --- a/src/ev-sidebar.h +++ /dev/null @@ -1,76 +0,0 @@ -/* ev-sidebar.h - * this file is part of evince, a gnome document viewer - * - * Copyright (C) 2004 Red Hat, Inc. - * - * Author: - * Jonathan Blandford <jrb@alum.mit.edu> - * - * Evince is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Evince is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA. - * - * Thursday 03 May 2007: Bastien Nocera: Add exception clause. - * See license_change file for details. - * - */ - -#ifndef __EV_SIDEBAR_H__ -#define __EV_SIDEBAR_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -typedef struct _EvSidebar EvSidebar; -typedef struct _EvSidebarClass EvSidebarClass; -typedef struct _EvSidebarPrivate EvSidebarPrivate; - -#define EV_TYPE_SIDEBAR (ev_sidebar_get_type()) -#define EV_SIDEBAR(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_SIDEBAR, EvSidebar)) -#define EV_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_SIDEBAR, EvSidebarClass)) -#define EV_IS_SIDEBAR(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_SIDEBAR)) -#define EV_IS_SIDEBAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_SIDEBAR)) -#define EV_SIDEBAR_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_SIDEBAR, EvSidebarClass)) - -struct _EvSidebar { - GtkVBox base_instance; - - EvSidebarPrivate *priv; -}; - -struct _EvSidebarClass { - GtkVBoxClass base_class; - - void (*closed) (EvSidebar *sidebar); -}; - -GType ev_sidebar_get_type (void); -GtkWidget *ev_sidebar_new (void); -void ev_sidebar_add_page (EvSidebar *ev_sidebar, - const gchar *page_id, - const gchar *title, - GtkWidget *main_widget); -void ev_sidebar_set_current_page - (EvSidebar *ev_sidebar, - const char *page_id); -char *ev_sidebar_get_current_page - (EvSidebar *ev_sidebar); -void ev_sidebar_remove_page (EvSidebar *ev_sidebar, - const gchar *page_id); - -G_END_DECLS - -#endif /* __EV_SIDEBAR_H__ */ - - diff --git a/src/gedit-close-button.c b/src/gedit-close-button.c deleted file mode 100644 index 6a9021aeb..000000000 --- a/src/gedit-close-button.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * gedit-close-button.c - * This file is part of gedit - * - * Copyright (C) 2010 - Paolo Borelli - * Copyright (C) 2011 - Ignacio Casal Quinteiro - * - * gedit 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. - * - * gedit 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 "gedit-close-button.h" - -struct _GeditCloseButtonClassPrivate -{ - GtkCssProvider *css; -}; - -G_DEFINE_TYPE_WITH_CODE (GeditCloseButton, gedit_close_button, GTK_TYPE_BUTTON, - g_type_add_class_private (g_define_type_id, sizeof (GeditCloseButtonClassPrivate))) - -static void -gedit_close_button_class_init (GeditCloseButtonClass *klass) -{ - static const gchar button_style[] = - "* {\n" - "-GtkButton-default-border : 0;\n" - "-GtkButton-default-outside-border : 0;\n" - "-GtkButton-inner-border: 0;\n" - "-GtkWidget-focus-line-width : 0;\n" - "-GtkWidget-focus-padding : 0;\n" - "padding: 0;\n" - "}"; - - klass->priv = G_TYPE_CLASS_GET_PRIVATE (klass, GEDIT_TYPE_CLOSE_BUTTON, GeditCloseButtonClassPrivate); - - klass->priv->css = gtk_css_provider_new (); - gtk_css_provider_load_from_data (klass->priv->css, button_style, -1, NULL); -} - -static void -gedit_close_button_init (GeditCloseButton *button) -{ - GtkStyleContext *context; - GtkWidget *image; - - image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, - GTK_ICON_SIZE_MENU); - gtk_widget_show (image); - - gtk_container_add (GTK_CONTAINER (button), image); - - /* make it small */ - context = gtk_widget_get_style_context (GTK_WIDGET (button)); - gtk_style_context_add_provider (context, - GTK_STYLE_PROVIDER (GEDIT_CLOSE_BUTTON_GET_CLASS (button)->priv->css), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); -} - -GtkWidget * -gedit_close_button_new () -{ - return GTK_WIDGET (g_object_new (GEDIT_TYPE_CLOSE_BUTTON, - "relief", GTK_RELIEF_NONE, - "focus-on-click", FALSE, - NULL)); -} - -/* ex:set ts=8 noet: */ diff --git a/src/gedit-close-button.h b/src/gedit-close-button.h deleted file mode 100644 index 791a73024..000000000 --- a/src/gedit-close-button.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * gedit-close-button.h - * This file is part of gedit - * - * Copyright (C) 2010 - Paolo Borelli - * - * gedit 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. - * - * gedit 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 - */ - -#ifndef __GEDIT_CLOSE_BUTTON_H__ -#define __GEDIT_CLOSE_BUTTON_H__ - -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define GEDIT_TYPE_CLOSE_BUTTON (gedit_close_button_get_type ()) -#define GEDIT_CLOSE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_CLOSE_BUTTON, GeditCloseButton)) -#define GEDIT_CLOSE_BUTTON_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_CLOSE_BUTTON, GeditCloseButton const)) -#define GEDIT_CLOSE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_CLOSE_BUTTON, GeditCloseButtonClass)) -#define GEDIT_IS_CLOSE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_CLOSE_BUTTON)) -#define GEDIT_IS_CLOSE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_CLOSE_BUTTON)) -#define GEDIT_CLOSE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_CLOSE_BUTTON, GeditCloseButtonClass)) - -typedef struct _GeditCloseButton GeditCloseButton; -typedef struct _GeditCloseButtonClass GeditCloseButtonClass; -typedef struct _GeditCloseButtonClassPrivate GeditCloseButtonClassPrivate; - -struct _GeditCloseButton -{ - GtkButton parent; -}; - -struct _GeditCloseButtonClass -{ - GtkButtonClass parent_class; - - GeditCloseButtonClassPrivate *priv; -}; - -GType gedit_close_button_get_type (void) G_GNUC_CONST; - -GtkWidget *gedit_close_button_new (void); - -G_END_DECLS - -#endif /* __GEDIT_CLOSE_BUTTON_H__ */ -/* ex:set ts=8 noet: */ |