2 * Copyright (C) 2005-2007 Imendio AB
3 * Copyright (C) 2007-2009 Collabora Ltd.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301 USA
20 * Authors: Martyn Russell <martyn@imendio.com>
21 * Xavier Claessens <xclaesse@gmail.com>
22 * Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
23 * Jonathan Tellier <jonathan.tellier@gmail.com>
32 #include <glib/gi18n.h>
33 #include <dbus/dbus-glib.h>
35 #include <telepathy-glib/account-manager.h>
36 #include <telepathy-glib/util.h>
38 #include <libempathy/empathy-utils.h>
39 #include <libempathy/empathy-connection-managers.h>
40 #include <libempathy/empathy-connectivity.h>
41 #include <libempathy-gtk/empathy-ui-utils.h>
43 #include <libempathy-gtk/empathy-protocol-chooser.h>
44 #include <libempathy-gtk/empathy-account-widget.h>
45 #include <libempathy-gtk/empathy-account-widget-irc.h>
46 #include <libempathy-gtk/empathy-account-widget-sip.h>
47 #include <libempathy-gtk/empathy-cell-renderer-activatable.h>
48 #include <libempathy-gtk/empathy-conf.h>
49 #include <libempathy-gtk/empathy-images.h>
51 #include "empathy-accounts-dialog.h"
52 #include "empathy-import-dialog.h"
53 #include "empathy-import-utils.h"
54 #include "ephy-spinner.h"
56 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
57 #include <libempathy/empathy-debug.h>
59 /* Flashing delay for icons (milliseconds). */
60 #define FLASH_TIMEOUT 500
62 /* The primary text of the dialog shown to the user when he is about to lose
64 #define PENDING_CHANGES_QUESTION_PRIMARY_TEXT \
65 _("There are unsaved modification regarding your %s account.")
66 /* The primary text of the dialog shown to the user when he is about to lose
67 * an unsaved new account */
68 #define UNSAVED_NEW_ACCOUNT_QUESTION_PRIMARY_TEXT \
69 _("Your new account has not been saved yet.")
71 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog)
72 G_DEFINE_TYPE (EmpathyAccountsDialog
, empathy_accounts_dialog
, G_TYPE_OBJECT
);
74 static EmpathyAccountsDialog
*dialog_singleton
= NULL
;
79 GtkWidget
*alignment_settings
;
80 GtkWidget
*alignment_infobar
;
82 GtkWidget
*vbox_details
;
84 GtkWidget
*label_status
;
85 GtkWidget
*image_status
;
87 GtkWidget
*frame_no_protocol
;
91 GtkWidget
*button_add
;
92 GtkWidget
*button_import
;
94 GtkWidget
*frame_new_account
;
95 GtkWidget
*combobox_protocol
;
97 GtkWidget
*button_create
;
98 GtkWidget
*button_back
;
99 GtkWidget
*radiobutton_reuse
;
100 GtkWidget
*radiobutton_register
;
102 GtkWidget
*image_type
;
103 GtkWidget
*label_name
;
104 GtkWidget
*label_type
;
105 GtkWidget
*settings_widget
;
107 /* We have to keep a reference on the actual EmpathyAccountWidget, not just
108 * his GtkWidget. It is the only reliable source we can query to know if
109 * there are any unsaved changes to the currently selected account. We can't
110 * look at the account settings because it does not contain everything that
111 * can be changed using the EmpathyAccountWidget. For instance, it does not
112 * contain the state of the "Enabled" checkbox. */
113 EmpathyAccountWidget
*setting_widget_object
;
115 gboolean connecting_show
;
118 gulong settings_ready_id
;
119 EmpathyAccountSettings
*settings_ready
;
121 TpAccountManager
*account_manager
;
122 EmpathyConnectionManagers
*cms
;
124 GtkWindow
*parent_window
;
125 TpAccount
*initial_selection
;
127 /* Those are needed when changing the selected row. When a user selects
128 * another account and there are unsaved changes on the currently selected
129 * one, a confirmation message box is presented to him. Since his answer
130 * is retrieved asynchronously, we keep some information as member of the
131 * EmpathyAccountsDialog object. */
132 gboolean force_change_row
;
133 GtkTreeRowReference
*destination_row
;
136 } EmpathyAccountsDialogPriv
;
142 COL_ACCOUNT_SETTINGS_POINTER
,
150 static EmpathyAccountSettings
* accounts_dialog_model_get_selected_settings (
151 EmpathyAccountsDialog
*dialog
);
153 static gboolean
accounts_dialog_get_settings_iter (
154 EmpathyAccountsDialog
*dialog
,
155 EmpathyAccountSettings
*settings
,
158 static void accounts_dialog_model_select_first (EmpathyAccountsDialog
*dialog
);
160 static void accounts_dialog_update_settings (EmpathyAccountsDialog
*dialog
,
161 EmpathyAccountSettings
*settings
);
164 accounts_dialog_update_name_label (EmpathyAccountsDialog
*dialog
,
165 const gchar
*display_name
)
168 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
170 text
= g_markup_printf_escaped ("<big><b>%s</b></big>", display_name
);
171 gtk_label_set_markup (GTK_LABEL (priv
->label_name
), text
);
177 accounts_dialog_update_status_infobar (EmpathyAccountsDialog
*dialog
,
180 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
181 const gchar
*message
;
182 gchar
*status_message
;
186 EmpathyConnectivity
*connectivity
;
189 GtkTreeSelection
*selection
;
191 TpAccount
*selected_account
;
192 gboolean account_enabled
;
193 gboolean creating_account
;
195 view
= GTK_TREE_VIEW (priv
->treeview
);
196 selection
= gtk_tree_view_get_selection (view
);
198 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
201 gtk_tree_model_get (model
, &iter
,
202 COL_ACCOUNT_POINTER
, &selected_account
, -1);
204 /* do not update the infobar when the account is not selected */
205 if (account
!= selected_account
)
212 status
= tp_account_get_connection_status (account
, &reason
);
213 presence
= tp_account_get_current_presence (account
, NULL
, &status_message
);
214 account_enabled
= tp_account_is_enabled (account
);
215 creating_account
= FALSE
;
219 status
= TP_CONNECTION_STATUS_DISCONNECTED
;
220 presence
= TP_CONNECTION_PRESENCE_TYPE_OFFLINE
;
221 account_enabled
= FALSE
;
222 creating_account
= TRUE
;
225 gtk_image_set_from_icon_name (GTK_IMAGE (priv
->image_status
),
226 empathy_icon_name_for_presence (presence
), GTK_ICON_SIZE_SMALL_TOOLBAR
);
232 case TP_CONNECTION_STATUS_CONNECTING
:
233 message
= _("Connecting...");
234 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
237 ephy_spinner_start (EPHY_SPINNER (priv
->throbber
));
238 gtk_widget_show (priv
->throbber
);
239 gtk_widget_hide (priv
->image_status
);
241 case TP_CONNECTION_STATUS_CONNECTED
:
242 if (g_strcmp0 (status_message
, "") == 0)
244 message
= g_strdup_printf ("%s",
245 empathy_presence_get_default_message (presence
));
249 message
= g_strdup_printf ("%s - %s",
250 empathy_presence_get_default_message (presence
),
253 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
256 gtk_widget_show (priv
->image_status
);
257 gtk_widget_hide (priv
->throbber
);
259 case TP_CONNECTION_STATUS_DISCONNECTED
:
260 message
= g_strdup_printf (_("Disconnected - %s"),
261 empathy_status_reason_get_default_message (reason
));
263 if (reason
== TP_CONNECTION_STATUS_REASON_REQUESTED
)
265 message
= g_strdup_printf (_("Offline - %s"),
266 empathy_status_reason_get_default_message (reason
));
267 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
268 GTK_MESSAGE_WARNING
);
272 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
276 connectivity
= empathy_connectivity_dup_singleton ();
277 if (!empathy_connectivity_is_online (connectivity
))
278 message
= _("Offline - No Network Connection");
280 g_object_unref (connectivity
);
281 ephy_spinner_stop (EPHY_SPINNER (priv
->throbber
));
282 gtk_widget_show (priv
->image_status
);
283 gtk_widget_hide (priv
->throbber
);
286 message
= _("Unknown Status");
287 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
288 GTK_MESSAGE_WARNING
);
290 ephy_spinner_stop (EPHY_SPINNER (priv
->throbber
));
291 gtk_widget_hide (priv
->image_status
);
292 gtk_widget_hide (priv
->throbber
);
297 if (creating_account
)
299 message
= _("Offline - Account not created yet");
303 message
= _("Offline - Account disabled");
306 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
307 GTK_MESSAGE_WARNING
);
308 ephy_spinner_stop (EPHY_SPINNER (priv
->throbber
));
309 gtk_widget_show (priv
->image_status
);
310 gtk_widget_hide (priv
->throbber
);
313 gtk_label_set_text (GTK_LABEL (priv
->label_status
), message
);
314 gtk_widget_show (priv
->label_status
);
315 gtk_widget_show (priv
->infobar
);
317 if (!creating_account
)
318 g_free (status_message
);
322 empathy_account_dialog_widget_cancelled_cb (
323 EmpathyAccountWidget
*widget_object
,
324 EmpathyAccountsDialog
*dialog
)
328 GtkTreeSelection
*selection
;
330 EmpathyAccountSettings
*settings
;
332 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
334 view
= GTK_TREE_VIEW (priv
->treeview
);
335 selection
= gtk_tree_view_get_selection (view
);
337 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
340 gtk_tree_model_get (model
, &iter
,
341 COL_ACCOUNT_SETTINGS_POINTER
, &settings
,
342 COL_ACCOUNT_POINTER
, &account
, -1);
344 empathy_account_widget_discard_pending_changes (priv
->setting_widget_object
);
348 /* We were creating an account. We remove the selected row */
349 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
353 /* We were modifying an account. We discard the changes by reloading the
354 * settings and the UI. */
355 accounts_dialog_update_settings (dialog
, settings
);
356 g_object_unref (account
);
359 if (settings
!= NULL
)
360 g_object_unref (settings
);
364 empathy_account_dialog_account_created_cb (EmpathyAccountWidget
*widget_object
,
365 EmpathyAccountsDialog
*dialog
)
368 EmpathyAccountSettings
*settings
=
369 accounts_dialog_model_get_selected_settings (dialog
);
371 display_name
= empathy_account_widget_get_default_display_name (
374 empathy_account_settings_set_display_name_async (settings
,
375 display_name
, NULL
, NULL
);
377 g_free (display_name
);
379 accounts_dialog_update_settings (dialog
, settings
);
380 accounts_dialog_update_status_infobar (dialog
,
381 empathy_account_settings_get_account (settings
));
384 g_object_unref (settings
);
388 account_dialog_create_settings_widget (EmpathyAccountsDialog
*dialog
,
389 EmpathyAccountSettings
*settings
)
391 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
395 priv
->setting_widget_object
=
396 empathy_account_widget_new_for_protocol (settings
, FALSE
);
398 priv
->settings_widget
=
399 empathy_account_widget_get_widget (priv
->setting_widget_object
);
401 priv
->settings_widget
=
402 empathy_account_widget_get_widget (priv
->setting_widget_object
);
403 g_signal_connect (priv
->setting_widget_object
, "account-created",
404 G_CALLBACK (empathy_account_dialog_account_created_cb
), dialog
);
405 g_signal_connect (priv
->setting_widget_object
, "cancelled",
406 G_CALLBACK (empathy_account_dialog_widget_cancelled_cb
), dialog
);
408 gtk_container_add (GTK_CONTAINER (priv
->alignment_settings
),
409 priv
->settings_widget
);
410 gtk_widget_show (priv
->settings_widget
);
412 icon_name
= empathy_account_settings_get_icon_name (settings
);
414 if (!gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
416 /* show the default icon; keep this in sync with the default
417 * one in empathy-accounts-dialog.ui.
419 icon_name
= GTK_STOCK_CUT
;
421 gtk_image_set_from_icon_name (GTK_IMAGE (priv
->image_type
),
422 icon_name
, GTK_ICON_SIZE_DIALOG
);
423 gtk_widget_set_tooltip_text (priv
->image_type
,
424 empathy_protocol_name_to_display_name
425 (empathy_account_settings_get_protocol (settings
)));
426 gtk_widget_show (priv
->image_type
);
428 accounts_dialog_update_name_label (dialog
,
429 empathy_account_settings_get_display_name (settings
));
431 account
= empathy_account_settings_get_account (settings
);
432 accounts_dialog_update_status_infobar (dialog
, account
);
436 account_dialog_settings_ready_cb (EmpathyAccountSettings
*settings
,
438 EmpathyAccountsDialog
*dialog
)
440 if (empathy_account_settings_is_ready (settings
))
441 account_dialog_create_settings_widget (dialog
, settings
);
445 accounts_dialog_model_select_first (EmpathyAccountsDialog
*dialog
)
449 GtkTreeSelection
*selection
;
451 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
454 view
= GTK_TREE_VIEW (priv
->treeview
);
455 model
= gtk_tree_view_get_model (view
);
457 if (gtk_tree_model_get_iter_first (model
, &iter
))
459 selection
= gtk_tree_view_get_selection (view
);
460 gtk_tree_selection_select_iter (selection
, &iter
);
464 accounts_dialog_update_settings (dialog
, NULL
);
469 accounts_dialog_has_pending_change (EmpathyAccountsDialog
*dialog
,
474 GtkTreeSelection
*selection
;
475 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
477 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
479 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
480 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT_POINTER
, account
, -1);
482 return priv
->setting_widget_object
!= NULL
483 && empathy_account_widget_contains_pending_changes (
484 priv
->setting_widget_object
);
488 accounts_dialog_protocol_changed_cb (GtkWidget
*widget
,
489 EmpathyAccountsDialog
*dialog
)
491 TpConnectionManager
*cm
;
492 TpConnectionManagerProtocol
*proto
;
494 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
496 cm
= empathy_protocol_chooser_dup_selected (
497 EMPATHY_PROTOCOL_CHOOSER (priv
->combobox_protocol
), &proto
, &is_gtalk
);
509 if (tp_connection_manager_protocol_can_register (proto
) && !is_gtalk
)
511 gtk_widget_show (priv
->radiobutton_register
);
512 gtk_widget_show (priv
->radiobutton_reuse
);
516 gtk_widget_hide (priv
->radiobutton_register
);
517 gtk_widget_hide (priv
->radiobutton_reuse
);
520 gtk_widget_hide (priv
->radiobutton_register
);
521 gtk_widget_hide (priv
->radiobutton_reuse
);
528 accounts_dialog_setup_ui_to_add_account (EmpathyAccountsDialog
*dialog
)
532 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
534 view
= GTK_TREE_VIEW (priv
->treeview
);
535 model
= gtk_tree_view_get_model (view
);
537 gtk_widget_set_sensitive (priv
->button_add
, FALSE
);
538 gtk_widget_hide (priv
->vbox_details
);
539 gtk_widget_hide (priv
->frame_no_protocol
);
540 gtk_widget_show (priv
->frame_new_account
);
542 /* If we have no account, no need of a back button */
543 if (gtk_tree_model_iter_n_children (model
, NULL
) > 0)
544 gtk_widget_show (priv
->button_back
);
546 gtk_widget_hide (priv
->button_back
);
548 accounts_dialog_protocol_changed_cb (priv
->radiobutton_register
, dialog
);
549 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv
->radiobutton_reuse
),
551 gtk_combo_box_set_active (GTK_COMBO_BOX (priv
->combobox_protocol
), 0);
552 gtk_widget_grab_focus (priv
->combobox_protocol
);
556 accounts_dialog_show_question_dialog (EmpathyAccountsDialog
*dialog
,
557 const gchar
*primary_text
,
558 const gchar
*secondary_text
,
559 GCallback response_callback
,
561 const gchar
*first_button_text
,
565 GtkWidget
*message_dialog
;
566 const gchar
*button_text
;
567 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
569 message_dialog
= gtk_message_dialog_new (GTK_WINDOW (priv
->window
),
570 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
571 GTK_MESSAGE_QUESTION
,
575 gtk_message_dialog_format_secondary_text (
576 GTK_MESSAGE_DIALOG (message_dialog
), "%s", secondary_text
);
578 va_start (button_args
, first_button_text
);
579 for (button_text
= first_button_text
;
581 button_text
= va_arg (button_args
, const gchar
*))
584 response_id
= va_arg (button_args
, gint
);
586 gtk_dialog_add_button (GTK_DIALOG (message_dialog
), button_text
,
589 va_end (button_args
);
591 g_signal_connect (message_dialog
, "response", response_callback
, user_data
);
593 gtk_widget_show (message_dialog
);
597 accounts_dialog_add_pending_changes_response_cb (GtkDialog
*message_dialog
,
601 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
602 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
604 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
606 if (response_id
== GTK_RESPONSE_YES
)
608 empathy_account_widget_discard_pending_changes (
609 priv
->setting_widget_object
);
610 accounts_dialog_setup_ui_to_add_account (dialog
);
615 get_dialog_primary_text (TpAccount
*account
)
619 /* Existing account */
620 return g_strdup_printf (PENDING_CHANGES_QUESTION_PRIMARY_TEXT
,
621 tp_account_get_display_name (account
));
625 /* Newly created account */
626 return g_strdup (UNSAVED_NEW_ACCOUNT_QUESTION_PRIMARY_TEXT
);
631 accounts_dialog_button_add_clicked_cb (GtkWidget
*button
,
632 EmpathyAccountsDialog
*dialog
)
634 TpAccount
*account
= NULL
;
636 if (accounts_dialog_has_pending_change (dialog
, &account
))
638 gchar
*question_dialog_primary_text
= get_dialog_primary_text (account
);
640 accounts_dialog_show_question_dialog (dialog
,
641 question_dialog_primary_text
,
642 _("You are about to create a new account, which will discard\n"
643 "your changes. Are you sure you want to proceed?"),
644 G_CALLBACK (accounts_dialog_add_pending_changes_response_cb
),
646 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
647 GTK_STOCK_DISCARD
, GTK_RESPONSE_YES
, NULL
);
649 g_free (question_dialog_primary_text
);
653 accounts_dialog_setup_ui_to_add_account (dialog
);
658 accounts_dialog_update_settings (EmpathyAccountsDialog
*dialog
,
659 EmpathyAccountSettings
*settings
)
661 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
663 if (priv
->settings_ready
!= NULL
)
665 g_signal_handler_disconnect (priv
->settings_ready
,
666 priv
->settings_ready_id
);
667 priv
->settings_ready
= NULL
;
668 priv
->settings_ready_id
= 0;
675 GtkTreeSelection
*selection
;
677 view
= GTK_TREE_VIEW (priv
->treeview
);
678 model
= gtk_tree_view_get_model (view
);
679 selection
= gtk_tree_view_get_selection (view
);
681 if (gtk_tree_model_iter_n_children (model
, NULL
) > 0)
683 /* We have configured accounts, select the first one if there
684 * is no other account selected already. */
685 if (!gtk_tree_selection_get_selected (selection
, NULL
, NULL
))
686 accounts_dialog_model_select_first (dialog
);
690 if (empathy_connection_managers_get_cms_num (priv
->cms
) > 0)
692 /* We have no account configured but we have some
693 * profiles installed. The user obviously wants to add
694 * an account. Click on the Add button for him. */
695 accounts_dialog_button_add_clicked_cb (priv
->button_add
,
700 /* No account and no profile, warn the user */
701 gtk_widget_hide (priv
->vbox_details
);
702 gtk_widget_hide (priv
->frame_new_account
);
703 gtk_widget_show (priv
->frame_no_protocol
);
704 gtk_widget_set_sensitive (priv
->button_add
, FALSE
);
708 /* We have an account selected, destroy old settings and create a new
709 * one for the account selected */
710 gtk_widget_hide (priv
->frame_new_account
);
711 gtk_widget_hide (priv
->frame_no_protocol
);
712 gtk_widget_show (priv
->vbox_details
);
713 gtk_widget_set_sensitive (priv
->button_add
, TRUE
);
715 if (priv
->settings_widget
)
717 gtk_widget_destroy (priv
->settings_widget
);
718 priv
->settings_widget
= NULL
;
721 if (empathy_account_settings_is_ready (settings
))
723 account_dialog_create_settings_widget (dialog
, settings
);
727 priv
->settings_ready
= settings
;
728 priv
->settings_ready_id
=
729 g_signal_connect (settings
, "notify::ready",
730 G_CALLBACK (account_dialog_settings_ready_cb
), dialog
);
736 accounts_dialog_name_editing_started_cb (GtkCellRenderer
*renderer
,
737 GtkCellEditable
*editable
,
739 EmpathyAccountsDialog
*dialog
)
741 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
743 if (priv
->connecting_id
)
744 g_source_remove (priv
->connecting_id
);
746 DEBUG ("Editing account name started; stopping flashing");
750 accounts_dialog_model_pixbuf_data_func (GtkTreeViewColumn
*tree_column
,
751 GtkCellRenderer
*cell
,
754 EmpathyAccountsDialog
*dialog
)
756 EmpathyAccountSettings
*settings
;
759 TpConnectionStatus status
;
760 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
762 gtk_tree_model_get (model
, iter
,
764 COL_ACCOUNT_SETTINGS_POINTER
, &settings
,
767 icon_name
= empathy_account_settings_get_icon_name (settings
);
768 pixbuf
= empathy_pixbuf_from_icon_name (icon_name
, GTK_ICON_SIZE_BUTTON
);
772 if (status
== TP_CONNECTION_STATUS_DISCONNECTED
||
773 (status
== TP_CONNECTION_STATUS_CONNECTING
&&
774 !priv
->connecting_show
))
776 GdkPixbuf
*modded_pixbuf
;
778 modded_pixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
,
781 gdk_pixbuf_get_width (pixbuf
),
782 gdk_pixbuf_get_height (pixbuf
));
784 gdk_pixbuf_saturate_and_pixelate (pixbuf
,
788 g_object_unref (pixbuf
);
789 pixbuf
= modded_pixbuf
;
798 g_object_unref (settings
);
801 g_object_unref (pixbuf
);
805 accounts_dialog_row_changed_foreach (GtkTreeModel
*model
,
810 gtk_tree_model_row_changed (model
, path
, iter
);
816 accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog
*dialog
)
820 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
822 priv
->connecting_show
= !priv
->connecting_show
;
824 view
= GTK_TREE_VIEW (priv
->treeview
);
825 model
= gtk_tree_view_get_model (view
);
827 gtk_tree_model_foreach (model
, accounts_dialog_row_changed_foreach
, NULL
);
833 accounts_dialog_name_edited_cb (GtkCellRendererText
*renderer
,
836 EmpathyAccountsDialog
*dialog
)
838 EmpathyAccountSettings
*settings
;
840 GtkTreePath
*treepath
;
842 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
845 empathy_account_manager_get_accounts_connected (&connecting
);
849 priv
->connecting_id
= g_timeout_add (FLASH_TIMEOUT
,
850 (GSourceFunc
) accounts_dialog_flash_connecting_cb
,
854 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
855 treepath
= gtk_tree_path_new_from_string (path
);
856 gtk_tree_model_get_iter (model
, &iter
, treepath
);
857 gtk_tree_model_get (model
, &iter
,
858 COL_ACCOUNT_SETTINGS_POINTER
, &settings
,
860 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
863 gtk_tree_path_free (treepath
);
865 empathy_account_settings_set_display_name_async (settings
, new_text
,
867 g_object_set (settings
, "display-name-overridden", TRUE
, NULL
);
868 g_object_unref (settings
);
872 accounts_dialog_delete_account_response_cb (GtkDialog
*message_dialog
,
879 GtkTreeSelection
*selection
;
880 EmpathyAccountsDialog
*account_dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
881 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (account_dialog
);
883 if (response_id
== GTK_RESPONSE_YES
)
885 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
887 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
890 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT_POINTER
, &account
, -1);
894 tp_account_remove_async (account
, NULL
, NULL
);
895 g_object_unref (account
);
899 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
900 accounts_dialog_model_select_first (account_dialog
);
903 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
907 accounts_dialog_view_delete_activated_cb (EmpathyCellRendererActivatable
*cell
,
908 const gchar
*path_string
,
909 EmpathyAccountsDialog
*dialog
)
914 gchar
*question_dialog_primary_text
;
915 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
917 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
919 if (!gtk_tree_model_get_iter_from_string (model
, &iter
, path_string
))
922 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT_POINTER
, &account
, -1);
924 if (account
== NULL
|| !tp_account_is_valid (account
))
926 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
927 accounts_dialog_model_select_first (dialog
);
931 question_dialog_primary_text
= g_strdup_printf (
932 _("Do you want to remove %s from your computer?"),
933 tp_account_get_display_name (account
));
935 accounts_dialog_show_question_dialog (dialog
, question_dialog_primary_text
,
936 _("This will not remove your account on the server."),
937 G_CALLBACK (accounts_dialog_delete_account_response_cb
),
939 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
940 GTK_STOCK_REMOVE
, GTK_RESPONSE_YES
, NULL
);
942 g_free (question_dialog_primary_text
);
946 g_object_unref (account
);
952 accounts_dialog_model_add_columns (EmpathyAccountsDialog
*dialog
)
955 GtkTreeViewColumn
*column
;
956 GtkCellRenderer
*cell
;
957 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
959 view
= GTK_TREE_VIEW (priv
->treeview
);
960 gtk_tree_view_set_headers_visible (view
, FALSE
);
963 column
= gtk_tree_view_column_new ();
964 gtk_tree_view_column_set_expand (column
, TRUE
);
965 gtk_tree_view_append_column (view
, column
);
968 cell
= gtk_cell_renderer_pixbuf_new ();
969 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
970 gtk_tree_view_column_set_cell_data_func (column
, cell
,
971 (GtkTreeCellDataFunc
)
972 accounts_dialog_model_pixbuf_data_func
,
977 cell
= gtk_cell_renderer_text_new ();
979 "ellipsize", PANGO_ELLIPSIZE_END
,
983 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
984 gtk_tree_view_column_add_attribute (column
, cell
, "text", COL_NAME
);
985 g_signal_connect (cell
, "edited",
986 G_CALLBACK (accounts_dialog_name_edited_cb
),
988 g_signal_connect (cell
, "editing-started",
989 G_CALLBACK (accounts_dialog_name_editing_started_cb
),
991 g_object_set (cell
, "ypad", 4, NULL
);
994 cell
= empathy_cell_renderer_activatable_new ();
995 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
997 "icon-name", GTK_STOCK_DELETE
,
998 "show-on-select", TRUE
,
1001 g_signal_connect (cell
, "path-activated",
1002 G_CALLBACK (accounts_dialog_view_delete_activated_cb
),
1006 static EmpathyAccountSettings
*
1007 accounts_dialog_model_get_selected_settings (EmpathyAccountsDialog
*dialog
)
1010 GtkTreeModel
*model
;
1011 GtkTreeSelection
*selection
;
1013 EmpathyAccountSettings
*settings
;
1014 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1016 view
= GTK_TREE_VIEW (priv
->treeview
);
1017 selection
= gtk_tree_view_get_selection (view
);
1019 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
1022 gtk_tree_model_get (model
, &iter
,
1023 COL_ACCOUNT_SETTINGS_POINTER
, &settings
, -1);
1029 accounts_dialog_model_selection_changed (GtkTreeSelection
*selection
,
1030 EmpathyAccountsDialog
*dialog
)
1032 EmpathyAccountSettings
*settings
;
1033 GtkTreeModel
*model
;
1035 gboolean is_selection
;
1037 is_selection
= gtk_tree_selection_get_selected (selection
, &model
, &iter
);
1039 settings
= accounts_dialog_model_get_selected_settings (dialog
);
1040 accounts_dialog_update_settings (dialog
, settings
);
1042 if (settings
!= NULL
)
1043 g_object_unref (settings
);
1047 accounts_dialog_selection_change_response_cb (GtkDialog
*message_dialog
,
1049 gpointer
*user_data
)
1051 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1052 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1054 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
1056 if (response_id
== GTK_RESPONSE_YES
&& priv
->destination_row
!= NULL
)
1058 /* The user wants to lose unsaved changes to the currently selected
1059 * account and select another account. We discard the changes and
1060 * select the other account. */
1062 GtkTreeSelection
*selection
;
1064 priv
->force_change_row
= TRUE
;
1065 empathy_account_widget_discard_pending_changes (
1066 priv
->setting_widget_object
);
1068 path
= gtk_tree_row_reference_get_path (priv
->destination_row
);
1069 selection
= gtk_tree_view_get_selection (
1070 GTK_TREE_VIEW (priv
->treeview
));
1074 /* This will trigger a call to
1075 * accounts_dialog_account_selection_change() */
1076 gtk_tree_selection_select_path (selection
, path
);
1077 gtk_tree_path_free (path
);
1080 gtk_tree_row_reference_free (priv
->destination_row
);
1084 priv
->force_change_row
= FALSE
;
1089 accounts_dialog_account_selection_change (GtkTreeSelection
*selection
,
1090 GtkTreeModel
*model
,
1092 gboolean path_currently_selected
,
1095 TpAccount
*account
= NULL
;
1096 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (data
);
1097 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1099 if (priv
->force_change_row
)
1101 /* We came back here because the user wants to discard changes to his
1102 * modified account. The changes have already been discarded so we
1103 * just change the selected row. */
1104 priv
->force_change_row
= FALSE
;
1108 if (accounts_dialog_has_pending_change (dialog
, &account
))
1110 /* The currently selected account has some unsaved changes. We ask
1111 * the user if he really wants to lose his changes and select another
1113 gchar
*question_dialog_primary_text
= get_dialog_primary_text (account
);
1114 priv
->destination_row
= gtk_tree_row_reference_new (model
, path
);
1116 accounts_dialog_show_question_dialog (dialog
,
1117 question_dialog_primary_text
,
1118 _("You are about to select another account, which will discard\n"
1119 "your changes. Are you sure you want to proceed?"),
1120 G_CALLBACK (accounts_dialog_selection_change_response_cb
),
1122 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
1123 GTK_STOCK_DISCARD
, GTK_RESPONSE_YES
, NULL
);
1125 g_free (question_dialog_primary_text
);
1136 accounts_dialog_model_setup (EmpathyAccountsDialog
*dialog
)
1138 GtkListStore
*store
;
1139 GtkTreeSelection
*selection
;
1140 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1142 store
= gtk_list_store_new (COL_COUNT
,
1143 G_TYPE_STRING
, /* name */
1144 G_TYPE_UINT
, /* status */
1145 TP_TYPE_ACCOUNT
, /* account */
1146 EMPATHY_TYPE_ACCOUNT_SETTINGS
); /* settings */
1148 gtk_tree_view_set_model (GTK_TREE_VIEW (priv
->treeview
),
1149 GTK_TREE_MODEL (store
));
1151 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1152 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
1153 gtk_tree_selection_set_select_function (selection
,
1154 accounts_dialog_account_selection_change
, dialog
, NULL
);
1156 g_signal_connect (selection
, "changed",
1157 G_CALLBACK (accounts_dialog_model_selection_changed
),
1160 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store
),
1161 COL_NAME
, GTK_SORT_ASCENDING
);
1163 accounts_dialog_model_add_columns (dialog
);
1165 g_object_unref (store
);
1169 accounts_dialog_get_settings_iter (EmpathyAccountsDialog
*dialog
,
1170 EmpathyAccountSettings
*settings
,
1174 GtkTreeSelection
*selection
;
1175 GtkTreeModel
*model
;
1177 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1179 /* Update the status in the model */
1180 view
= GTK_TREE_VIEW (priv
->treeview
);
1181 selection
= gtk_tree_view_get_selection (view
);
1182 model
= gtk_tree_view_get_model (view
);
1184 for (ok
= gtk_tree_model_get_iter_first (model
, iter
);
1186 ok
= gtk_tree_model_iter_next (model
, iter
))
1188 EmpathyAccountSettings
*this_settings
;
1191 gtk_tree_model_get (model
, iter
,
1192 COL_ACCOUNT_SETTINGS_POINTER
, &this_settings
,
1195 equal
= (this_settings
== settings
);
1196 g_object_unref (this_settings
);
1206 accounts_dialog_get_account_iter (EmpathyAccountsDialog
*dialog
,
1211 GtkTreeSelection
*selection
;
1212 GtkTreeModel
*model
;
1214 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1216 /* Update the status in the model */
1217 view
= GTK_TREE_VIEW (priv
->treeview
);
1218 selection
= gtk_tree_view_get_selection (view
);
1219 model
= gtk_tree_view_get_model (view
);
1221 for (ok
= gtk_tree_model_get_iter_first (model
, iter
);
1223 ok
= gtk_tree_model_iter_next (model
, iter
))
1225 EmpathyAccountSettings
*settings
;
1228 gtk_tree_model_get (model
, iter
,
1229 COL_ACCOUNT_SETTINGS_POINTER
, &settings
,
1232 equal
= empathy_account_settings_has_account (settings
, account
);
1233 g_object_unref (settings
);
1243 accounts_dialog_model_set_selected (EmpathyAccountsDialog
*dialog
,
1244 EmpathyAccountSettings
*settings
)
1246 GtkTreeSelection
*selection
;
1248 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1250 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1251 if (accounts_dialog_get_settings_iter (dialog
, settings
, &iter
))
1252 gtk_tree_selection_select_iter (selection
, &iter
);
1255 accounts_dialog_add (EmpathyAccountsDialog
*dialog
,
1256 EmpathyAccountSettings
*settings
)
1258 GtkTreeModel
*model
;
1261 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1263 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1264 name
= empathy_account_settings_get_display_name (settings
);
1266 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
1268 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1270 COL_STATUS
, TP_CONNECTION_STATUS_DISCONNECTED
,
1271 COL_ACCOUNT_SETTINGS_POINTER
, settings
,
1276 accounts_dialog_connection_changed_cb (TpAccount
*account
,
1280 gchar
*dbus_error_name
,
1281 GHashTable
*details
,
1282 EmpathyAccountsDialog
*dialog
)
1284 GtkTreeModel
*model
;
1287 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1289 /* Update the status-infobar in the details view */
1290 accounts_dialog_update_status_infobar (dialog
, account
);
1292 /* Update the status in the model */
1293 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1295 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1299 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1300 COL_STATUS
, current
,
1303 path
= gtk_tree_model_get_path (model
, &iter
);
1304 gtk_tree_model_row_changed (model
, path
, &iter
);
1305 gtk_tree_path_free (path
);
1308 empathy_account_manager_get_accounts_connected (&found
);
1310 if (!found
&& priv
->connecting_id
)
1312 g_source_remove (priv
->connecting_id
);
1313 priv
->connecting_id
= 0;
1316 if (found
&& !priv
->connecting_id
)
1317 priv
->connecting_id
= g_timeout_add (FLASH_TIMEOUT
,
1318 (GSourceFunc
) accounts_dialog_flash_connecting_cb
,
1323 accounts_dialog_presence_changed_cb (TpAccount
*account
,
1326 gchar
*status_message
,
1327 EmpathyAccountsDialog
*dialog
)
1329 /* Update the status-infobar in the details view */
1330 accounts_dialog_update_status_infobar (dialog
, account
);
1334 accounts_dialog_account_display_name_changed_cb (TpAccount
*account
,
1338 const gchar
*display_name
;
1340 GtkTreeModel
*model
;
1341 EmpathyAccountSettings
*settings
;
1342 TpAccount
*selected_account
;
1343 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1344 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1346 display_name
= tp_account_get_display_name (account
);
1347 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1348 settings
= accounts_dialog_model_get_selected_settings (dialog
);
1349 if (settings
== NULL
)
1352 selected_account
= empathy_account_settings_get_account (settings
);
1354 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1356 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1357 COL_NAME
, display_name
,
1361 if (selected_account
== account
)
1362 accounts_dialog_update_name_label (dialog
, display_name
);
1364 g_object_unref (settings
);
1368 accounts_dialog_add_account (EmpathyAccountsDialog
*dialog
,
1371 EmpathyAccountSettings
*settings
;
1372 GtkTreeModel
*model
;
1374 TpConnectionStatus status
;
1377 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1379 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1380 status
= tp_account_get_connection_status (account
, NULL
);
1381 name
= tp_account_get_display_name (account
);
1382 enabled
= tp_account_is_enabled (account
);
1384 settings
= empathy_account_settings_new_for_account (account
);
1386 if (!accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1387 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
1389 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1392 COL_ACCOUNT_POINTER
, account
,
1393 COL_ACCOUNT_SETTINGS_POINTER
, settings
,
1396 accounts_dialog_connection_changed_cb (account
,
1399 TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED
,
1404 empathy_signal_connect_weak (account
, "notify::display-name",
1405 G_CALLBACK (accounts_dialog_account_display_name_changed_cb
),
1408 g_object_unref (settings
);
1412 account_prepare_cb (GObject
*source_object
,
1413 GAsyncResult
*result
,
1416 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1417 TpAccount
*account
= TP_ACCOUNT (source_object
);
1418 GError
*error
= NULL
;
1420 if (!tp_account_prepare_finish (account
, result
, &error
))
1422 DEBUG ("Failed to prepare account: %s", error
->message
);
1423 g_error_free (error
);
1427 accounts_dialog_add_account (dialog
, account
);
1431 accounts_dialog_account_validity_changed_cb (TpAccountManager
*manager
,
1434 EmpathyAccountsDialog
*dialog
)
1436 tp_account_prepare_async (account
, NULL
, account_prepare_cb
, dialog
);
1440 accounts_dialog_account_removed_cb (TpAccountManager
*manager
,
1442 EmpathyAccountsDialog
*dialog
)
1445 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1447 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1449 gtk_list_store_remove (GTK_LIST_STORE (
1450 gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
))), &iter
);
1455 enable_or_disable_account (EmpathyAccountsDialog
*dialog
,
1459 GtkTreeModel
*model
;
1460 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1462 /* Update the status in the model */
1463 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1465 /* Update the status-infobar in the details view when disabling */
1467 accounts_dialog_update_status_infobar (dialog
, account
);
1469 DEBUG ("Account %s is now %s",
1470 tp_account_get_display_name (account
),
1471 enabled
? "enabled" : "disabled");
1475 accounts_dialog_account_disabled_cb (TpAccountManager
*manager
,
1477 EmpathyAccountsDialog
*dialog
)
1479 enable_or_disable_account (dialog
, account
, FALSE
);
1483 accounts_dialog_account_enabled_cb (TpAccountManager
*manager
,
1485 EmpathyAccountsDialog
*dialog
)
1487 enable_or_disable_account (dialog
, account
, TRUE
);
1491 accounts_dialog_button_create_clicked_cb (GtkWidget
*button
,
1492 EmpathyAccountsDialog
*dialog
)
1494 EmpathyAccountSettings
*settings
;
1496 const gchar
*display_name
;
1497 TpConnectionManager
*cm
;
1498 TpConnectionManagerProtocol
*proto
;
1499 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1502 cm
= empathy_protocol_chooser_dup_selected (
1503 EMPATHY_PROTOCOL_CHOOSER (priv
->combobox_protocol
), &proto
, &is_gtalk
);
1505 display_name
= empathy_protocol_name_to_display_name (
1506 is_gtalk
? "gtalk" : proto
->name
);
1508 if (display_name
== NULL
)
1509 display_name
= proto
->name
;
1511 /* Create account */
1512 /* To translator: %s is the name of the protocol, such as "Google Talk" or
1515 str
= g_strdup_printf (_("New %s account"), display_name
);
1516 settings
= empathy_account_settings_new (cm
->name
, proto
->name
, str
);
1521 if (tp_connection_manager_protocol_can_register (proto
))
1525 active
= gtk_toggle_button_get_active
1526 (GTK_TOGGLE_BUTTON (priv
->radiobutton_register
));
1528 empathy_account_settings_set_boolean (settings
, "register", TRUE
);
1533 empathy_account_settings_set_icon_name_async (settings
, "im-google-talk",
1536 accounts_dialog_add (dialog
, settings
);
1537 accounts_dialog_model_set_selected (dialog
, settings
);
1539 g_object_unref (settings
);
1540 g_object_unref (cm
);
1544 accounts_dialog_button_back_clicked_cb (GtkWidget
*button
,
1545 EmpathyAccountsDialog
*dialog
)
1547 EmpathyAccountSettings
*settings
;
1549 settings
= accounts_dialog_model_get_selected_settings (dialog
);
1550 accounts_dialog_update_settings (dialog
, settings
);
1553 g_object_unref (settings
);
1557 accounts_dialog_button_help_clicked_cb (GtkWidget
*button
,
1558 EmpathyAccountsDialog
*dialog
)
1560 empathy_url_show (button
, "ghelp:empathy?accounts-window");
1564 accounts_dialog_button_import_clicked_cb (GtkWidget
*button
,
1565 EmpathyAccountsDialog
*dialog
)
1567 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1568 GtkWidget
*import_dialog
;
1570 import_dialog
= empathy_import_dialog_new (GTK_WINDOW (priv
->window
),
1572 gtk_widget_show (import_dialog
);
1576 accounts_dialog_close_response_cb (GtkDialog
*message_dialog
,
1580 GtkWidget
*account_dialog
= GTK_WIDGET (user_data
);
1582 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
1584 if (response_id
== GTK_RESPONSE_YES
)
1585 gtk_widget_destroy (account_dialog
);
1589 accounts_dialog_response_cb (GtkWidget
*widget
,
1591 EmpathyAccountsDialog
*dialog
)
1593 TpAccount
*account
= NULL
;
1595 if (accounts_dialog_has_pending_change (dialog
, &account
))
1597 gchar
*question_dialog_primary_text
= get_dialog_primary_text (account
);
1599 accounts_dialog_show_question_dialog (dialog
,
1600 question_dialog_primary_text
,
1601 _("You are about to close the window, which will discard\n"
1602 "your changes. Are you sure you want to proceed?"),
1603 G_CALLBACK (accounts_dialog_close_response_cb
),
1605 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
1606 GTK_STOCK_DISCARD
, GTK_RESPONSE_YES
, NULL
);
1608 g_free (question_dialog_primary_text
);
1610 else if (response
== GTK_RESPONSE_CLOSE
||
1611 response
== GTK_RESPONSE_DELETE_EVENT
)
1612 gtk_widget_destroy (widget
);
1616 accounts_dialog_delete_event_cb (GtkWidget
*widget
,
1618 EmpathyAccountsDialog
*dialog
)
1620 /* we maunally handle responses to delete events */
1625 accounts_dialog_destroy_cb (GtkObject
*obj
,
1626 EmpathyAccountsDialog
*dialog
)
1630 g_object_unref (dialog
);
1634 accounts_dialog_set_selected_account (EmpathyAccountsDialog
*dialog
,
1637 GtkTreeSelection
*selection
;
1639 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1641 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1642 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1643 gtk_tree_selection_select_iter (selection
, &iter
);
1647 accounts_dialog_cms_ready_cb (EmpathyConnectionManagers
*cms
,
1649 EmpathyAccountsDialog
*dialog
)
1651 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1653 if (empathy_connection_managers_is_ready (cms
))
1655 accounts_dialog_update_settings (dialog
, NULL
);
1657 if (priv
->initial_selection
!= NULL
)
1659 accounts_dialog_set_selected_account
1660 (dialog
, priv
->initial_selection
);
1661 g_object_unref (priv
->initial_selection
);
1662 priv
->initial_selection
= NULL
;
1668 accounts_dialog_accounts_setup (EmpathyAccountsDialog
*dialog
)
1670 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1671 GList
*accounts
, *l
;
1673 g_signal_connect (priv
->account_manager
, "account-validity-changed",
1674 G_CALLBACK (accounts_dialog_account_validity_changed_cb
),
1676 g_signal_connect (priv
->account_manager
, "account-removed",
1677 G_CALLBACK (accounts_dialog_account_removed_cb
),
1679 g_signal_connect (priv
->account_manager
, "account-enabled",
1680 G_CALLBACK (accounts_dialog_account_enabled_cb
),
1682 g_signal_connect (priv
->account_manager
, "account-disabled",
1683 G_CALLBACK (accounts_dialog_account_disabled_cb
),
1686 /* Add existing accounts */
1687 accounts
= tp_account_manager_get_valid_accounts (priv
->account_manager
);
1688 for (l
= accounts
; l
; l
= l
->next
)
1690 accounts_dialog_add_account (dialog
, l
->data
);
1692 empathy_signal_connect_weak (l
->data
, "status-changed",
1693 G_CALLBACK (accounts_dialog_connection_changed_cb
), G_OBJECT (dialog
));
1694 empathy_signal_connect_weak (l
->data
, "presence-changed",
1695 G_CALLBACK (accounts_dialog_presence_changed_cb
), G_OBJECT (dialog
));
1697 g_list_free (accounts
);
1699 priv
->cms
= empathy_connection_managers_dup_singleton ();
1700 if (!empathy_connection_managers_is_ready (priv
->cms
))
1701 g_signal_connect (priv
->cms
, "notify::ready",
1702 G_CALLBACK (accounts_dialog_cms_ready_cb
), dialog
);
1704 accounts_dialog_model_select_first (dialog
);
1708 accounts_dialog_manager_ready_cb (GObject
*source_object
,
1709 GAsyncResult
*result
,
1712 TpAccountManager
*manager
= TP_ACCOUNT_MANAGER (source_object
);
1713 GError
*error
= NULL
;
1715 if (!tp_account_manager_prepare_finish (manager
, result
, &error
))
1717 DEBUG ("Failed to prepare account manager: %s", error
->message
);
1718 g_error_free (error
);
1722 accounts_dialog_accounts_setup (user_data
);
1726 accounts_dialog_build_ui (EmpathyAccountsDialog
*dialog
)
1730 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1731 GtkWidget
*content_area
;
1733 GtkWidget
*action_area
;
1736 filename
= empathy_file_lookup ("empathy-accounts-dialog.ui", "src");
1738 gui
= empathy_builder_get_file (filename
,
1739 "accounts_dialog", &priv
->window
,
1740 "vbox_details", &priv
->vbox_details
,
1741 "frame_no_protocol", &priv
->frame_no_protocol
,
1742 "alignment_settings", &priv
->alignment_settings
,
1743 "alignment_infobar", &priv
->alignment_infobar
,
1744 "treeview", &priv
->treeview
,
1745 "frame_new_account", &priv
->frame_new_account
,
1746 "hbox_type", &priv
->hbox_type
,
1747 "button_create", &priv
->button_create
,
1748 "button_back", &priv
->button_back
,
1749 "radiobutton_reuse", &priv
->radiobutton_reuse
,
1750 "radiobutton_register", &priv
->radiobutton_register
,
1751 "image_type", &priv
->image_type
,
1752 "label_name", &priv
->label_name
,
1753 "button_add", &priv
->button_add
,
1754 "button_import", &priv
->button_import
,
1758 empathy_builder_connect (gui
, dialog
,
1759 "accounts_dialog", "response", accounts_dialog_response_cb
,
1760 "accounts_dialog", "destroy", accounts_dialog_destroy_cb
,
1761 "accounts_dialog", "delete-event", accounts_dialog_delete_event_cb
,
1762 "button_create", "clicked", accounts_dialog_button_create_clicked_cb
,
1763 "button_back", "clicked", accounts_dialog_button_back_clicked_cb
,
1764 "button_add", "clicked", accounts_dialog_button_add_clicked_cb
,
1765 "button_help", "clicked", accounts_dialog_button_help_clicked_cb
,
1766 "button_import", "clicked", accounts_dialog_button_import_clicked_cb
,
1769 g_object_unref (gui
);
1772 action_area
= gtk_dialog_get_action_area (GTK_DIALOG (priv
->window
));
1773 gtk_widget_hide (action_area
);
1775 /* Translators: this is used only when built on a moblin platform */
1776 gtk_button_set_label (GTK_BUTTON (priv
->button_create
), _("_Next"));
1777 gtk_button_set_use_underline (GTK_BUTTON (priv
->button_create
), TRUE
);
1780 priv
->combobox_protocol
= empathy_protocol_chooser_new ();
1781 gtk_box_pack_start (GTK_BOX (priv
->hbox_type
),
1782 priv
->combobox_protocol
,
1784 gtk_widget_show (priv
->combobox_protocol
);
1785 g_signal_connect (priv
->combobox_protocol
, "changed",
1786 G_CALLBACK (accounts_dialog_protocol_changed_cb
),
1789 if (priv
->parent_window
)
1790 gtk_window_set_transient_for (GTK_WINDOW (priv
->window
),
1791 priv
->parent_window
);
1793 /* set up spinner */
1794 priv
->throbber
= ephy_spinner_new ();
1795 ephy_spinner_set_size (EPHY_SPINNER (priv
->throbber
), GTK_ICON_SIZE_SMALL_TOOLBAR
);
1797 priv
->infobar
= gtk_info_bar_new ();
1798 gtk_container_add (GTK_CONTAINER (priv
->alignment_infobar
),
1800 gtk_widget_show (priv
->infobar
);
1802 priv
->image_status
= gtk_image_new_from_icon_name (
1803 empathy_icon_name_for_presence (
1804 TP_CONNECTION_PRESENCE_TYPE_OFFLINE
), GTK_ICON_SIZE_SMALL_TOOLBAR
);
1806 priv
->label_status
= gtk_label_new (NULL
);
1808 content_area
= gtk_info_bar_get_content_area (GTK_INFO_BAR (priv
->infobar
));
1809 gtk_box_pack_start (GTK_BOX (content_area
), priv
->throbber
,
1811 gtk_box_pack_start (GTK_BOX (content_area
), priv
->image_status
,
1813 gtk_container_add (GTK_CONTAINER (content_area
), priv
->label_status
);
1817 do_dispose (GObject
*obj
)
1819 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (obj
);
1820 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1822 /* Disconnect signals */
1823 g_signal_handlers_disconnect_by_func (priv
->account_manager
,
1824 accounts_dialog_account_validity_changed_cb
,
1826 g_signal_handlers_disconnect_by_func (priv
->account_manager
,
1827 accounts_dialog_account_removed_cb
,
1829 g_signal_handlers_disconnect_by_func (priv
->account_manager
,
1830 accounts_dialog_account_enabled_cb
,
1832 g_signal_handlers_disconnect_by_func (priv
->account_manager
,
1833 accounts_dialog_account_disabled_cb
,
1835 g_signal_handlers_disconnect_by_func (priv
->account_manager
,
1836 accounts_dialog_manager_ready_cb
,
1839 if (priv
->connecting_id
)
1840 g_source_remove (priv
->connecting_id
);
1842 if (priv
->account_manager
!= NULL
)
1844 g_object_unref (priv
->account_manager
);
1845 priv
->account_manager
= NULL
;
1848 if (priv
->cms
!= NULL
)
1850 g_object_unref (priv
->cms
);
1854 if (priv
->initial_selection
!= NULL
)
1855 g_object_unref (priv
->initial_selection
);
1856 priv
->initial_selection
= NULL
;
1858 G_OBJECT_CLASS (empathy_accounts_dialog_parent_class
)->dispose (obj
);
1862 do_constructor (GType type
,
1864 GObjectConstructParam
*props
)
1868 if (dialog_singleton
)
1870 retval
= G_OBJECT (dialog_singleton
);
1871 g_object_ref (retval
);
1876 G_OBJECT_CLASS (empathy_accounts_dialog_parent_class
)->constructor
1877 (type
, n_props
, props
);
1879 dialog_singleton
= EMPATHY_ACCOUNTS_DIALOG (retval
);
1880 g_object_add_weak_pointer (retval
, (gpointer
) &dialog_singleton
);
1881 /* We add an extra reference that we'll release when the dialog is
1882 * destroyed (accounts_dialog_destroy_cb) */
1883 g_object_ref (retval
);
1890 do_get_property (GObject
*object
,
1895 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (object
);
1897 switch (property_id
)
1900 g_value_set_object (value
, priv
->parent_window
);
1903 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1908 do_set_property (GObject
*object
,
1910 const GValue
*value
,
1913 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (object
);
1915 switch (property_id
)
1918 priv
->parent_window
= g_value_get_object (value
);
1921 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
1926 do_constructed (GObject
*object
)
1928 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (object
);
1929 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1930 gboolean import_asked
;
1932 accounts_dialog_build_ui (dialog
);
1933 accounts_dialog_model_setup (dialog
);
1935 /* Set up signalling */
1936 priv
->account_manager
= tp_account_manager_dup ();
1938 tp_account_manager_prepare_async (priv
->account_manager
, NULL
,
1939 accounts_dialog_manager_ready_cb
, dialog
);
1941 empathy_conf_get_bool (empathy_conf_get (),
1942 EMPATHY_PREFS_IMPORT_ASKED
, &import_asked
);
1944 if (empathy_import_accounts_to_import ())
1946 gtk_widget_show (priv
->button_import
);
1950 GtkWidget
*import_dialog
;
1952 empathy_conf_set_bool (empathy_conf_get (),
1953 EMPATHY_PREFS_IMPORT_ASKED
, TRUE
);
1954 import_dialog
= empathy_import_dialog_new (GTK_WINDOW (priv
->window
),
1956 gtk_widget_show (import_dialog
);
1962 empathy_accounts_dialog_class_init (EmpathyAccountsDialogClass
*klass
)
1964 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
1965 GParamSpec
*param_spec
;
1967 oclass
->constructor
= do_constructor
;
1968 oclass
->dispose
= do_dispose
;
1969 oclass
->constructed
= do_constructed
;
1970 oclass
->set_property
= do_set_property
;
1971 oclass
->get_property
= do_get_property
;
1973 param_spec
= g_param_spec_object ("parent",
1974 "parent", "The parent window",
1976 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
| G_PARAM_CONSTRUCT_ONLY
);
1977 g_object_class_install_property (oclass
, PROP_PARENT
, param_spec
);
1979 g_type_class_add_private (klass
, sizeof (EmpathyAccountsDialogPriv
));
1983 empathy_accounts_dialog_init (EmpathyAccountsDialog
*dialog
)
1985 EmpathyAccountsDialogPriv
*priv
;
1987 priv
= G_TYPE_INSTANCE_GET_PRIVATE ((dialog
),
1988 EMPATHY_TYPE_ACCOUNTS_DIALOG
,
1989 EmpathyAccountsDialogPriv
);
1990 dialog
->priv
= priv
;
1993 /* public methods */
1996 empathy_accounts_dialog_show (GtkWindow
*parent
,
1997 TpAccount
*selected_account
)
1999 EmpathyAccountsDialog
*dialog
;
2000 EmpathyAccountsDialogPriv
*priv
;
2002 dialog
= g_object_new (EMPATHY_TYPE_ACCOUNTS_DIALOG
,
2003 "parent", parent
, NULL
);
2005 priv
= GET_PRIV (dialog
);
2007 if (selected_account
)
2009 if (priv
->cms
!= NULL
&& empathy_connection_managers_is_ready (priv
->cms
))
2010 accounts_dialog_set_selected_account (dialog
, selected_account
);
2012 /* save the selection to set it later when the cms
2015 priv
->initial_selection
= g_object_ref (selected_account
);
2018 gtk_window_present (GTK_WINDOW (priv
->window
));
2019 /* EmpathyAccountsDialog kepts a ref on itself until the dialog is
2020 * destroyed so we can release the ref returned by the constructor now. */
2021 g_object_unref (dialog
);
2023 return priv
->window
;