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-lib.h>
33 #include <dbus/dbus-glib.h>
35 #include <telepathy-glib/account-manager.h>
36 #include <telepathy-glib/defs.h>
37 #include <telepathy-glib/util.h>
39 #include <libempathy/empathy-utils.h>
40 #include <libempathy/empathy-connection-managers.h>
41 #include <libempathy/empathy-connectivity.h>
43 #include <libempathy-gtk/empathy-ui-utils.h>
44 #include <libempathy-gtk/empathy-protocol-chooser.h>
45 #include <libempathy-gtk/empathy-account-widget.h>
46 #include <libempathy-gtk/empathy-account-widget-irc.h>
47 #include <libempathy-gtk/empathy-account-widget-sip.h>
48 #include <libempathy-gtk/empathy-cell-renderer-activatable.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"
55 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT
56 #include <libempathy/empathy-debug.h>
58 /* Flashing delay for icons (milliseconds). */
59 #define FLASH_TIMEOUT 500
61 /* The primary text of the dialog shown to the user when he is about to lose
63 #define PENDING_CHANGES_QUESTION_PRIMARY_TEXT \
64 _("There are unsaved modifications to your %s account.")
65 /* The primary text of the dialog shown to the user when he is about to lose
66 * an unsaved new account */
67 #define UNSAVED_NEW_ACCOUNT_QUESTION_PRIMARY_TEXT \
68 _("Your new account has not been saved yet.")
70 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog)
71 G_DEFINE_TYPE (EmpathyAccountsDialog
, empathy_accounts_dialog
, GTK_TYPE_DIALOG
);
75 NOTEBOOK_PAGE_ACCOUNT
= 0,
80 GtkWidget
*alignment_settings
;
81 GtkWidget
*alignment_infobar
;
83 GtkWidget
*vbox_details
;
85 GtkWidget
*label_status
;
86 GtkWidget
*image_status
;
88 GtkWidget
*enabled_switch
;
89 GtkWidget
*frame_no_protocol
;
93 GtkWidget
*button_add
;
94 GtkWidget
*button_remove
;
95 GtkWidget
*button_import
;
97 GtkWidget
*combobox_protocol
;
98 GtkWidget
*hbox_protocol
;
100 GtkWidget
*image_type
;
101 GtkWidget
*label_name
;
102 GtkWidget
*label_type
;
103 GtkWidget
*settings_widget
;
105 GtkWidget
*notebook_account
;
109 /* We have to keep a weak reference on the actual EmpathyAccountWidget, not
110 * just its GtkWidget. It is the only reliable source we can query to know if
111 * there are any unsaved changes to the currently selected account. We can't
112 * look at the account settings because it does not contain everything that
113 * can be changed using the EmpathyAccountWidget. For instance, it does not
114 * contain the state of the "Enabled" checkbox.
116 * Even if we create it ourself, we just get a weak ref and not a strong one
117 * as EmpathyAccountWidget unrefs itself when the GtkWidget is destroyed.
118 * That's kinda ugly; cf bgo #640417.
121 EmpathyAccountWidget
*setting_widget_object
;
123 gboolean connecting_show
;
126 gulong settings_ready_id
;
127 EmpathyAccountSettings
*settings_ready
;
129 TpAccountManager
*account_manager
;
130 EmpathyConnectionManagers
*cms
;
131 EmpathyConnectivity
*connectivity
;
133 GtkWindow
*parent_window
;
134 TpAccount
*initial_selection
;
136 /* Those are needed when changing the selected row. When a user selects
137 * another account and there are unsaved changes on the currently selected
138 * one, a confirmation message box is presented to him. Since his answer
139 * is retrieved asynchronously, we keep some information as member of the
140 * EmpathyAccountsDialog object. */
141 gboolean force_change_row
;
142 GtkTreeRowReference
*destination_row
;
143 } EmpathyAccountsDialogPriv
;
149 COL_ACCOUNT_SETTINGS
,
157 static EmpathyAccountSettings
* accounts_dialog_model_get_selected_settings (
158 EmpathyAccountsDialog
*dialog
);
160 static gboolean
accounts_dialog_get_settings_iter (
161 EmpathyAccountsDialog
*dialog
,
162 EmpathyAccountSettings
*settings
,
165 static void accounts_dialog_model_select_first (EmpathyAccountsDialog
*dialog
);
167 static void accounts_dialog_update_settings (EmpathyAccountsDialog
*dialog
,
168 EmpathyAccountSettings
*settings
);
170 static void accounts_dialog_add (EmpathyAccountsDialog
*dialog
,
171 EmpathyAccountSettings
*settings
);
173 static void accounts_dialog_model_set_selected (EmpathyAccountsDialog
*dialog
,
174 EmpathyAccountSettings
*settings
);
176 static void accounts_dialog_connection_changed_cb (TpAccount
*account
,
180 gchar
*dbus_error_name
,
182 EmpathyAccountsDialog
*dialog
);
184 static void accounts_dialog_presence_changed_cb (TpAccount
*account
,
187 gchar
*status_message
,
188 EmpathyAccountsDialog
*dialog
);
190 static void accounts_dialog_model_selection_changed (
191 GtkTreeSelection
*selection
,
192 EmpathyAccountsDialog
*dialog
);
195 accounts_dialog_update_name_label (EmpathyAccountsDialog
*dialog
,
196 const gchar
*display_name
)
199 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
201 text
= g_markup_printf_escaped ("<b>%s</b>", display_name
);
202 gtk_label_set_markup (GTK_LABEL (priv
->label_name
), text
);
208 accounts_dialog_status_infobar_set_message (EmpathyAccountsDialog
*dialog
,
209 const gchar
*message
)
211 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
212 gchar
*message_markup
;
214 message_markup
= g_markup_printf_escaped ("<i>%s</i>", message
);
215 gtk_label_set_markup (GTK_LABEL (priv
->label_status
), message_markup
);
216 g_free (message_markup
);
220 accounts_dialog_enable_account_cb (GObject
*account
,
221 GAsyncResult
*result
,
224 GError
*error
= NULL
;
226 tp_account_set_enabled_finish (TP_ACCOUNT (account
), result
, &error
);
230 DEBUG ("Could not enable the account: %s", error
->message
);
231 g_error_free (error
);
235 TpAccountManager
*am
= tp_account_manager_dup ();
237 empathy_connect_new_account (TP_ACCOUNT (account
), am
);
243 accounts_dialog_enable_switch_active_cb (GtkSwitch
*sw
,
245 EmpathyAccountsDialog
*dialog
)
247 EmpathyAccountSettings
*settings
;
250 settings
= accounts_dialog_model_get_selected_settings (dialog
);
251 if (settings
== NULL
)
254 account
= empathy_account_settings_get_account (settings
);
258 tp_account_set_enabled_async (account
, gtk_switch_get_active (sw
),
259 accounts_dialog_enable_account_cb
, NULL
);
263 accounts_dialog_update_status_infobar (EmpathyAccountsDialog
*dialog
,
266 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
267 gchar
*status_message
= NULL
;
273 GtkTreeSelection
*selection
;
275 TpAccount
*selected_account
;
276 gboolean account_enabled
;
277 gboolean creating_account
;
278 TpStorageRestrictionFlags storage_restrictions
= 0;
280 view
= GTK_TREE_VIEW (priv
->treeview
);
281 selection
= gtk_tree_view_get_selection (view
);
283 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
286 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT
, &selected_account
, -1);
287 if (selected_account
!= NULL
)
288 g_object_unref (selected_account
);
290 /* do not update the infobar when the account is not selected */
291 if (account
!= selected_account
)
296 status
= tp_account_get_connection_status (account
, &reason
);
297 presence
= tp_account_get_current_presence (account
, NULL
, &status_message
);
298 account_enabled
= tp_account_is_enabled (account
);
299 creating_account
= FALSE
;
301 if (status
== TP_CONNECTION_STATUS_CONNECTED
&&
302 (presence
== TP_CONNECTION_PRESENCE_TYPE_OFFLINE
||
303 presence
== TP_CONNECTION_PRESENCE_TYPE_UNSET
))
304 /* If presence is Unset (CM doesn't implement SimplePresence) but we
305 * are connected, consider ourself as Available.
306 * We also check Offline because of this MC5 bug: fd.o #26060 */
307 presence
= TP_CONNECTION_PRESENCE_TYPE_AVAILABLE
;
309 /* set presence to offline if account is disabled
310 * (else no icon is shown in infobar)*/
311 if (!account_enabled
)
312 presence
= TP_CONNECTION_PRESENCE_TYPE_OFFLINE
;
314 storage_restrictions
= tp_account_get_storage_restrictions (account
);
318 status
= TP_CONNECTION_STATUS_DISCONNECTED
;
319 presence
= TP_CONNECTION_PRESENCE_TYPE_OFFLINE
;
320 account_enabled
= FALSE
;
321 creating_account
= TRUE
;
324 gtk_image_set_from_icon_name (GTK_IMAGE (priv
->image_status
),
325 empathy_icon_name_for_presence (presence
), GTK_ICON_SIZE_SMALL_TOOLBAR
);
327 /* update the enabled switch */
328 g_signal_handlers_block_by_func (priv
->enabled_switch
,
329 accounts_dialog_enable_switch_active_cb
, dialog
);
330 gtk_switch_set_active (GTK_SWITCH (priv
->enabled_switch
),
332 g_signal_handlers_unblock_by_func (priv
->enabled_switch
,
333 accounts_dialog_enable_switch_active_cb
, dialog
);
335 /* Display the Enable switch if account supports it */
336 gtk_widget_set_visible (priv
->enabled_switch
,
337 !(storage_restrictions
& TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED
));
343 case TP_CONNECTION_STATUS_CONNECTING
:
344 accounts_dialog_status_infobar_set_message (dialog
,
346 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
349 gtk_spinner_start (GTK_SPINNER (priv
->throbber
));
350 gtk_widget_show (priv
->throbber
);
351 gtk_widget_hide (priv
->image_status
);
353 case TP_CONNECTION_STATUS_CONNECTED
:
354 if (g_strcmp0 (status_message
, "") == 0)
358 message
= g_strdup_printf ("%s",
359 empathy_presence_get_default_message (presence
));
361 accounts_dialog_status_infobar_set_message (dialog
, message
);
368 message
= g_strdup_printf ("%s — %s",
369 empathy_presence_get_default_message (presence
),
372 accounts_dialog_status_infobar_set_message (dialog
, message
);
375 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
378 gtk_widget_show (priv
->image_status
);
379 gtk_widget_hide (priv
->throbber
);
381 case TP_CONNECTION_STATUS_DISCONNECTED
:
382 if (reason
== TP_CONNECTION_STATUS_REASON_REQUESTED
)
386 message
= g_strdup_printf (_("Offline — %s"),
387 empathy_account_get_error_message (account
, NULL
));
388 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
389 GTK_MESSAGE_WARNING
);
391 accounts_dialog_status_infobar_set_message (dialog
, message
);
398 message
= g_strdup_printf (_("Disconnected — %s"),
399 empathy_account_get_error_message (account
, NULL
));
400 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
403 accounts_dialog_status_infobar_set_message (dialog
, message
);
407 if (!empathy_connectivity_is_online (priv
->connectivity
))
408 accounts_dialog_status_infobar_set_message (dialog
,
409 _("Offline — No Network Connection"));
411 gtk_spinner_stop (GTK_SPINNER (priv
->throbber
));
412 gtk_widget_show (priv
->image_status
);
413 gtk_widget_hide (priv
->throbber
);
416 accounts_dialog_status_infobar_set_message (dialog
, _("Unknown Status"));
417 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
418 GTK_MESSAGE_WARNING
);
420 gtk_spinner_stop (GTK_SPINNER (priv
->throbber
));
421 gtk_widget_hide (priv
->image_status
);
422 gtk_widget_hide (priv
->throbber
);
427 accounts_dialog_status_infobar_set_message (dialog
,
428 _("Offline — Account Disabled"));
430 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv
->infobar
),
431 GTK_MESSAGE_WARNING
);
432 gtk_spinner_stop (GTK_SPINNER (priv
->throbber
));
433 gtk_widget_show (priv
->image_status
);
434 gtk_widget_hide (priv
->throbber
);
437 gtk_widget_show (priv
->label_status
);
439 if (!creating_account
)
440 gtk_widget_show (priv
->infobar
);
442 gtk_widget_hide (priv
->infobar
);
444 g_free (status_message
);
448 empathy_account_dialog_cancel (EmpathyAccountsDialog
*dialog
)
452 GtkTreeSelection
*selection
;
454 EmpathyAccountSettings
*settings
;
456 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
458 view
= GTK_TREE_VIEW (priv
->treeview
);
459 selection
= gtk_tree_view_get_selection (view
);
461 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
464 gtk_tree_model_get (model
, &iter
,
465 COL_ACCOUNT_SETTINGS
, &settings
,
466 COL_ACCOUNT
, &account
, -1);
468 empathy_account_widget_discard_pending_changes (priv
->setting_widget_object
);
472 /* We were creating an account. We remove the selected row */
473 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
477 /* We were modifying an account. We discard the changes by reloading the
478 * settings and the UI. */
479 accounts_dialog_update_settings (dialog
, settings
);
480 g_object_unref (account
);
483 gtk_widget_set_sensitive (priv
->treeview
, TRUE
);
484 gtk_widget_set_sensitive (priv
->button_add
, TRUE
);
485 gtk_widget_set_sensitive (priv
->button_remove
, TRUE
);
486 gtk_widget_set_sensitive (priv
->button_import
, TRUE
);
488 if (settings
!= NULL
)
489 g_object_unref (settings
);
493 empathy_account_dialog_widget_cancelled_cb (
494 EmpathyAccountWidget
*widget_object
,
495 EmpathyAccountsDialog
*dialog
)
497 empathy_account_dialog_cancel (dialog
);
501 empathy_account_dialog_account_created_cb (EmpathyAccountWidget
*widget_object
,
503 EmpathyAccountsDialog
*dialog
)
505 EmpathyAccountSettings
*settings
=
506 accounts_dialog_model_get_selected_settings (dialog
);
507 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
509 accounts_dialog_update_settings (dialog
, settings
);
510 accounts_dialog_update_status_infobar (dialog
,
511 empathy_account_settings_get_account (settings
));
513 gtk_widget_set_sensitive (priv
->treeview
, TRUE
);
514 gtk_widget_set_sensitive (priv
->button_add
, TRUE
);
515 gtk_widget_set_sensitive (priv
->button_remove
, TRUE
);
516 gtk_widget_set_sensitive (priv
->button_import
, TRUE
);
519 g_object_unref (settings
);
523 accounts_dialog_has_valid_accounts (EmpathyAccountsDialog
*dialog
)
525 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
530 g_object_get (priv
->setting_widget_object
,
531 "creating-account", &creating
, NULL
);
536 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
538 if (gtk_tree_model_get_iter_first (model
, &iter
))
539 return gtk_tree_model_iter_next (model
, &iter
);
545 account_dialog_create_settings_widget (EmpathyAccountsDialog
*dialog
,
546 EmpathyAccountSettings
*settings
)
548 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
549 const gchar
*icon_name
;
552 if (priv
->setting_widget_object
!= NULL
)
553 g_object_remove_weak_pointer (G_OBJECT (priv
->setting_widget_object
),
554 (gpointer
*) &priv
->setting_widget_object
);
556 priv
->setting_widget_object
=
557 empathy_account_widget_new_for_protocol (settings
, FALSE
);
559 g_object_add_weak_pointer (G_OBJECT (priv
->setting_widget_object
),
560 (gpointer
*) &priv
->setting_widget_object
);
562 if (accounts_dialog_has_valid_accounts (dialog
))
563 empathy_account_widget_set_other_accounts_exist (
564 priv
->setting_widget_object
, TRUE
);
566 priv
->settings_widget
=
567 empathy_account_widget_get_widget (priv
->setting_widget_object
);
569 g_signal_connect (priv
->setting_widget_object
, "account-created",
570 G_CALLBACK (empathy_account_dialog_account_created_cb
), dialog
);
571 g_signal_connect (priv
->setting_widget_object
, "cancelled",
572 G_CALLBACK (empathy_account_dialog_widget_cancelled_cb
), dialog
);
574 gtk_container_add (GTK_CONTAINER (priv
->alignment_settings
),
575 priv
->settings_widget
);
576 gtk_widget_show (priv
->settings_widget
);
578 icon_name
= empathy_account_settings_get_icon_name (settings
);
580 if (!gtk_icon_theme_has_icon (gtk_icon_theme_get_default (),
582 /* show the default icon; keep this in sync with the default
583 * one in empathy-accounts-dialog.ui.
585 icon_name
= GTK_STOCK_CUT
;
587 gtk_image_set_from_icon_name (GTK_IMAGE (priv
->image_type
),
588 icon_name
, GTK_ICON_SIZE_DIALOG
);
589 gtk_widget_set_tooltip_text (priv
->image_type
,
590 empathy_protocol_name_to_display_name
591 (empathy_account_settings_get_protocol (settings
)));
592 gtk_widget_show (priv
->image_type
);
594 accounts_dialog_update_name_label (dialog
,
595 empathy_account_settings_get_display_name (settings
));
597 account
= empathy_account_settings_get_account (settings
);
598 accounts_dialog_update_status_infobar (dialog
, account
);
602 account_dialog_settings_ready_cb (EmpathyAccountSettings
*settings
,
604 EmpathyAccountsDialog
*dialog
)
606 if (empathy_account_settings_is_ready (settings
))
607 account_dialog_create_settings_widget (dialog
, settings
);
611 accounts_dialog_model_select_first (EmpathyAccountsDialog
*dialog
)
615 GtkTreeSelection
*selection
;
617 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
620 view
= GTK_TREE_VIEW (priv
->treeview
);
621 model
= gtk_tree_view_get_model (view
);
623 if (gtk_tree_model_get_iter_first (model
, &iter
))
625 selection
= gtk_tree_view_get_selection (view
);
626 gtk_tree_selection_select_iter (selection
, &iter
);
630 accounts_dialog_update_settings (dialog
, NULL
);
635 accounts_dialog_has_pending_change (EmpathyAccountsDialog
*dialog
,
640 GtkTreeSelection
*selection
;
641 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
643 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
645 if (gtk_tree_selection_get_selected (selection
, &model
, &iter
))
646 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT
, account
, -1);
648 return priv
->setting_widget_object
!= NULL
649 && empathy_account_widget_contains_pending_changes (
650 priv
->setting_widget_object
);
654 accounts_dialog_setup_ui_to_add_account (EmpathyAccountsDialog
*dialog
)
656 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
657 EmpathyAccountSettings
*settings
;
659 settings
= empathy_protocol_chooser_create_account_settings (
660 EMPATHY_PROTOCOL_CHOOSER (priv
->combobox_protocol
));
661 if (settings
== NULL
)
664 accounts_dialog_add (dialog
, settings
);
665 accounts_dialog_model_set_selected (dialog
, settings
);
667 gtk_widget_show_all (priv
->hbox_protocol
);
669 g_object_unref (settings
);
673 accounts_dialog_protocol_changed_cb (GtkWidget
*widget
,
674 EmpathyAccountsDialog
*dialog
)
676 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
677 GtkTreeSelection
*selection
;
681 EmpathyAccountSettings
*settings
;
682 gchar
*account
= NULL
, *password
= NULL
;
684 /* The "changed" signal is fired during the initiation of the
685 * EmpathyProtocolChooser while populating the widget. Such signals should
686 * be ignored so we check if we are actually creating a new account. */
687 if (priv
->setting_widget_object
== NULL
)
690 g_object_get (priv
->setting_widget_object
,
691 "creating-account", &creating
, NULL
);
695 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
697 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
700 /* Save "account" and "password" parameters */
701 g_object_get (priv
->setting_widget_object
, "settings", &settings
, NULL
);
703 if (settings
!= NULL
)
705 account
= g_strdup (empathy_account_settings_get_string (settings
,
707 password
= g_strdup (empathy_account_settings_get_string (settings
,
709 g_object_unref (settings
);
712 /* We are creating a new widget to replace the current one, don't ask
713 * confirmation to the user. */
714 priv
->force_change_row
= TRUE
;
716 /* We'll update the selection after we create the new account widgets;
717 * updating it right now causes problems for the # of accounts = zero case */
718 g_signal_handlers_block_by_func (selection
,
719 accounts_dialog_model_selection_changed
, dialog
);
721 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
723 g_signal_handlers_unblock_by_func (selection
,
724 accounts_dialog_model_selection_changed
, dialog
);
726 accounts_dialog_setup_ui_to_add_account (dialog
);
728 /* Restore "account" and "password" parameters in the new widget */
731 empathy_account_widget_set_account_param (priv
->setting_widget_object
,
736 if (password
!= NULL
)
738 empathy_account_widget_set_password_param (priv
->setting_widget_object
,
745 accounts_dialog_show_question_dialog (EmpathyAccountsDialog
*dialog
,
746 const gchar
*primary_text
,
747 const gchar
*secondary_text
,
748 GCallback response_callback
,
750 const gchar
*first_button_text
,
754 GtkWidget
*message_dialog
;
755 const gchar
*button_text
;
757 message_dialog
= gtk_message_dialog_new (GTK_WINDOW (dialog
),
758 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
759 GTK_MESSAGE_QUESTION
,
763 gtk_message_dialog_format_secondary_text (
764 GTK_MESSAGE_DIALOG (message_dialog
), "%s", secondary_text
);
766 va_start (button_args
, first_button_text
);
767 for (button_text
= first_button_text
;
769 button_text
= va_arg (button_args
, const gchar
*))
772 response_id
= va_arg (button_args
, gint
);
774 gtk_dialog_add_button (GTK_DIALOG (message_dialog
), button_text
,
777 va_end (button_args
);
779 g_signal_connect (message_dialog
, "response", response_callback
, user_data
);
781 gtk_widget_show (message_dialog
);
785 accounts_dialog_add_pending_changes_response_cb (GtkDialog
*message_dialog
,
789 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
790 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
792 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
794 if (response_id
== GTK_RESPONSE_YES
)
796 empathy_account_widget_discard_pending_changes (
797 priv
->setting_widget_object
);
798 accounts_dialog_setup_ui_to_add_account (dialog
);
803 get_dialog_primary_text (TpAccount
*account
)
807 /* Existing account */
808 return g_strdup_printf (PENDING_CHANGES_QUESTION_PRIMARY_TEXT
,
809 tp_account_get_display_name (account
));
813 /* Newly created account */
814 return g_strdup (UNSAVED_NEW_ACCOUNT_QUESTION_PRIMARY_TEXT
);
819 accounts_dialog_button_add_clicked_cb (GtkWidget
*button
,
820 EmpathyAccountsDialog
*dialog
)
822 TpAccount
*account
= NULL
;
823 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
825 if (accounts_dialog_has_pending_change (dialog
, &account
))
827 gchar
*question_dialog_primary_text
= get_dialog_primary_text (account
);
829 accounts_dialog_show_question_dialog (dialog
,
830 question_dialog_primary_text
,
831 _("You are about to create a new account, which will discard\n"
832 "your changes. Are you sure you want to proceed?"),
833 G_CALLBACK (accounts_dialog_add_pending_changes_response_cb
),
835 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
836 GTK_STOCK_DISCARD
, GTK_RESPONSE_YES
, NULL
);
838 g_free (question_dialog_primary_text
);
842 accounts_dialog_setup_ui_to_add_account (dialog
);
843 gtk_widget_set_sensitive (priv
->treeview
, FALSE
);
844 gtk_widget_set_sensitive (priv
->button_add
, FALSE
);
845 gtk_widget_set_sensitive (priv
->button_remove
, FALSE
);
846 gtk_widget_set_sensitive (priv
->button_import
, FALSE
);
850 g_object_unref (account
);
854 accounts_dialog_update_settings (EmpathyAccountsDialog
*dialog
,
855 EmpathyAccountSettings
*settings
)
857 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
859 if (priv
->settings_ready
!= NULL
)
861 g_signal_handler_disconnect (priv
->settings_ready
,
862 priv
->settings_ready_id
);
863 priv
->settings_ready
= NULL
;
864 priv
->settings_ready_id
= 0;
871 GtkTreeSelection
*selection
;
873 view
= GTK_TREE_VIEW (priv
->treeview
);
874 model
= gtk_tree_view_get_model (view
);
875 selection
= gtk_tree_view_get_selection (view
);
877 if (gtk_tree_model_iter_n_children (model
, NULL
) > 0)
879 /* We have configured accounts, select the first one if there
880 * is no other account selected already. */
881 if (!gtk_tree_selection_get_selected (selection
, NULL
, NULL
))
882 accounts_dialog_model_select_first (dialog
);
886 if (empathy_connection_managers_get_cms_num (priv
->cms
) > 0)
888 /* We have no account configured but we have some
889 * profiles installed. The user obviously wants to add
890 * an account. Click on the Add button for him. */
891 accounts_dialog_button_add_clicked_cb (priv
->button_add
,
896 /* No account and no profile, warn the user */
897 gtk_widget_hide (priv
->vbox_details
);
898 gtk_widget_show (priv
->frame_no_protocol
);
899 gtk_widget_set_sensitive (priv
->button_add
, FALSE
);
903 /* We have an account selected, destroy old settings and create a new
904 * one for the account selected */
905 gtk_widget_hide (priv
->frame_no_protocol
);
906 gtk_widget_show (priv
->vbox_details
);
907 gtk_widget_hide (priv
->hbox_protocol
);
909 if (priv
->settings_widget
)
911 gtk_widget_destroy (priv
->settings_widget
);
912 priv
->settings_widget
= NULL
;
915 if (empathy_account_settings_is_ready (settings
))
917 account_dialog_create_settings_widget (dialog
, settings
);
921 priv
->settings_ready
= settings
;
922 priv
->settings_ready_id
=
923 g_signal_connect (settings
, "notify::ready",
924 G_CALLBACK (account_dialog_settings_ready_cb
), dialog
);
930 accounts_dialog_name_editing_started_cb (GtkCellRenderer
*renderer
,
931 GtkCellEditable
*editable
,
933 EmpathyAccountsDialog
*dialog
)
935 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
937 if (priv
->connecting_id
)
938 g_source_remove (priv
->connecting_id
);
940 DEBUG ("Editing account name started; stopping flashing");
944 get_status_icon_for_account (EmpathyAccountsDialog
*self
,
947 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (self
);
948 TpConnectionStatus status
;
949 TpConnectionStatusReason reason
;
950 TpConnectionPresenceType presence
;
953 return empathy_icon_name_for_presence (TP_CONNECTION_PRESENCE_TYPE_OFFLINE
);
955 if (!tp_account_is_enabled (account
))
956 return empathy_icon_name_for_presence (TP_CONNECTION_PRESENCE_TYPE_OFFLINE
);
958 status
= tp_account_get_connection_status (account
, &reason
);
960 if (status
== TP_CONNECTION_STATUS_DISCONNECTED
)
962 if (reason
!= TP_CONNECTION_STATUS_REASON_REQUESTED
)
963 /* An error occured */
964 return GTK_STOCK_DIALOG_ERROR
;
966 presence
= TP_CONNECTION_PRESENCE_TYPE_OFFLINE
;
968 else if (status
== TP_CONNECTION_STATUS_CONNECTING
)
970 /* Account is connecting. Display a blinking account alternating between
971 * the offline icon and the requested presence. */
972 if (priv
->connecting_show
)
973 presence
= tp_account_get_requested_presence (account
, NULL
, NULL
);
975 presence
= TP_CONNECTION_PRESENCE_TYPE_OFFLINE
;
979 /* status == TP_CONNECTION_STATUS_CONNECTED */
980 presence
= tp_account_get_current_presence (account
, NULL
, NULL
);
982 /* If presence is Unset (CM doesn't implement SimplePresence),
983 * display the 'available' icon.
984 * We also check Offline because of this MC5 bug: fd.o #26060 */
985 if (presence
== TP_CONNECTION_PRESENCE_TYPE_OFFLINE
||
986 presence
== TP_CONNECTION_PRESENCE_TYPE_UNSET
)
987 presence
= TP_CONNECTION_PRESENCE_TYPE_AVAILABLE
;
990 return empathy_icon_name_for_presence (presence
);
994 accounts_dialog_model_status_pixbuf_data_func (GtkTreeViewColumn
*tree_column
,
995 GtkCellRenderer
*cell
,
998 EmpathyAccountsDialog
*dialog
)
1002 gtk_tree_model_get (model
, iter
, COL_ACCOUNT
, &account
, -1);
1005 "icon-name", get_status_icon_for_account (dialog
, account
),
1008 if (account
!= NULL
)
1009 g_object_unref (account
);
1013 accounts_dialog_model_protocol_pixbuf_data_func (GtkTreeViewColumn
*tree_column
,
1014 GtkCellRenderer
*cell
,
1015 GtkTreeModel
*model
,
1017 EmpathyAccountsDialog
*dialog
)
1019 EmpathyAccountSettings
*settings
;
1022 TpConnectionStatus status
;
1024 gtk_tree_model_get (model
, iter
,
1025 COL_STATUS
, &status
,
1026 COL_ACCOUNT_SETTINGS
, &settings
,
1029 icon_name
= empathy_account_settings_get_icon_name (settings
);
1030 pixbuf
= empathy_pixbuf_from_icon_name (icon_name
, GTK_ICON_SIZE_BUTTON
);
1037 g_object_unref (settings
);
1040 g_object_unref (pixbuf
);
1044 accounts_dialog_row_changed_foreach (GtkTreeModel
*model
,
1051 gtk_tree_model_get (model
, iter
, COL_ACCOUNT
, &account
, -1);
1053 if (account
== NULL
)
1056 if (tp_account_get_connection_status (account
, NULL
) ==
1057 TP_CONNECTION_STATUS_CONNECTING
)
1059 /* Only update the row where we have a connecting account as that's the
1060 * ones having a blinking icon. */
1061 gtk_tree_model_row_changed (model
, path
, iter
);
1064 g_object_unref (account
);
1069 accounts_dialog_flash_connecting_cb (EmpathyAccountsDialog
*dialog
)
1072 GtkTreeModel
*model
;
1073 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1075 priv
->connecting_show
= !priv
->connecting_show
;
1077 view
= GTK_TREE_VIEW (priv
->treeview
);
1078 model
= gtk_tree_view_get_model (view
);
1080 gtk_tree_model_foreach (model
, accounts_dialog_row_changed_foreach
, NULL
);
1086 accounts_dialog_name_edited_cb (GtkCellRendererText
*renderer
,
1089 EmpathyAccountsDialog
*dialog
)
1091 EmpathyAccountSettings
*settings
;
1092 GtkTreeModel
*model
;
1093 GtkTreePath
*treepath
;
1095 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1096 gboolean connecting
;
1098 empathy_account_manager_get_accounts_connected (&connecting
);
1102 priv
->connecting_id
= g_timeout_add (FLASH_TIMEOUT
,
1103 (GSourceFunc
) accounts_dialog_flash_connecting_cb
,
1107 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1108 treepath
= gtk_tree_path_new_from_string (path
);
1109 gtk_tree_model_get_iter (model
, &iter
, treepath
);
1110 gtk_tree_model_get (model
, &iter
,
1111 COL_ACCOUNT_SETTINGS
, &settings
,
1113 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1116 gtk_tree_path_free (treepath
);
1118 empathy_account_settings_set_display_name_async (settings
, new_text
,
1120 g_object_set (settings
, "display-name-overridden", TRUE
, NULL
);
1121 g_object_unref (settings
);
1125 accounts_dialog_delete_account_response_cb (GtkDialog
*message_dialog
,
1130 GtkTreeModel
*model
;
1132 GtkTreeSelection
*selection
;
1133 EmpathyAccountsDialog
*account_dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1134 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (account_dialog
);
1136 if (response_id
== GTK_RESPONSE_YES
)
1138 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1140 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
1143 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT
, &account
, -1);
1145 if (account
!= NULL
)
1147 tp_account_remove_async (account
, NULL
, NULL
);
1148 g_object_unref (account
);
1152 /* No need to call accounts_dialog_model_selection_changed while
1153 * removing as we are going to call accounts_dialog_model_select_first
1154 * right after which will update the selection. */
1155 g_signal_handlers_block_by_func (selection
,
1156 accounts_dialog_model_selection_changed
, account_dialog
);
1158 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
1160 g_signal_handlers_unblock_by_func (selection
,
1161 accounts_dialog_model_selection_changed
, account_dialog
);
1163 accounts_dialog_model_select_first (account_dialog
);
1166 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
1170 accounts_dialog_remove_account_iter (EmpathyAccountsDialog
*dialog
,
1173 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1175 GtkTreeModel
*model
;
1176 gchar
*question_dialog_primary_text
;
1178 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1180 gtk_tree_model_get (model
, iter
, COL_ACCOUNT
, &account
, -1);
1182 if (account
== NULL
|| !tp_account_is_valid (account
))
1184 if (account
!= NULL
)
1185 g_object_unref (account
);
1186 gtk_list_store_remove (GTK_LIST_STORE (model
), iter
);
1187 accounts_dialog_model_select_first (dialog
);
1191 question_dialog_primary_text
= g_strdup_printf (
1192 _("Do you want to remove %s from your computer?"),
1193 tp_account_get_display_name (account
));
1195 accounts_dialog_show_question_dialog (dialog
, question_dialog_primary_text
,
1196 _("This will not remove your account on the server."),
1197 G_CALLBACK (accounts_dialog_delete_account_response_cb
),
1199 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
1200 GTK_STOCK_REMOVE
, GTK_RESPONSE_YES
, NULL
);
1202 g_free (question_dialog_primary_text
);
1203 g_object_unref (account
);
1207 accounts_dialog_button_remove_clicked_cb (GtkWidget
*button
,
1208 EmpathyAccountsDialog
*dialog
)
1210 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1212 GtkTreeSelection
*selection
;
1215 view
= GTK_TREE_VIEW (priv
->treeview
);
1216 selection
= gtk_tree_view_get_selection (view
);
1217 if (!gtk_tree_selection_get_selected (selection
, NULL
, &iter
))
1220 accounts_dialog_remove_account_iter (dialog
, &iter
);
1225 accounts_dialog_view_delete_activated_cb (EmpathyCellRendererActivatable
*cell
,
1226 const gchar
*path_string
,
1227 EmpathyAccountsDialog
*dialog
)
1229 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1230 GtkTreeModel
*model
;
1233 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1234 if (!gtk_tree_model_get_iter_from_string (model
, &iter
, path_string
))
1237 accounts_dialog_remove_account_iter (dialog
, &iter
);
1239 #endif /* HAVE_MEEGO */
1242 accounts_dialog_model_add_columns (EmpathyAccountsDialog
*dialog
)
1245 GtkTreeViewColumn
*column
;
1246 GtkCellRenderer
*cell
;
1247 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1249 view
= GTK_TREE_VIEW (priv
->treeview
);
1250 gtk_tree_view_set_headers_visible (view
, FALSE
);
1252 /* Account column */
1253 column
= gtk_tree_view_column_new ();
1254 gtk_tree_view_column_set_expand (column
, TRUE
);
1255 gtk_tree_view_append_column (view
, column
);
1257 /* Status icon renderer */
1258 cell
= gtk_cell_renderer_pixbuf_new ();
1259 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
1260 gtk_tree_view_column_set_cell_data_func (column
, cell
,
1261 (GtkTreeCellDataFunc
)
1262 accounts_dialog_model_status_pixbuf_data_func
,
1266 /* Protocol icon renderer */
1267 cell
= gtk_cell_renderer_pixbuf_new ();
1268 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
1269 gtk_tree_view_column_set_cell_data_func (column
, cell
,
1270 (GtkTreeCellDataFunc
)
1271 accounts_dialog_model_protocol_pixbuf_data_func
,
1276 cell
= gtk_cell_renderer_text_new ();
1278 "ellipsize", PANGO_ELLIPSIZE_END
,
1282 gtk_tree_view_column_pack_start (column
, cell
, TRUE
);
1283 gtk_tree_view_column_add_attribute (column
, cell
, "text", COL_NAME
);
1284 g_signal_connect (cell
, "edited",
1285 G_CALLBACK (accounts_dialog_name_edited_cb
),
1287 g_signal_connect (cell
, "editing-started",
1288 G_CALLBACK (accounts_dialog_name_editing_started_cb
),
1290 g_object_set (cell
, "ypad", 4, NULL
);
1294 cell
= empathy_cell_renderer_activatable_new ();
1295 gtk_tree_view_column_pack_start (column
, cell
, FALSE
);
1297 "icon-name", GTK_STOCK_DELETE
,
1298 "show-on-select", TRUE
,
1301 g_signal_connect (cell
, "path-activated",
1302 G_CALLBACK (accounts_dialog_view_delete_activated_cb
),
1304 #endif /* HAVE_MEEGO */
1307 static EmpathyAccountSettings
*
1308 accounts_dialog_model_get_selected_settings (EmpathyAccountsDialog
*dialog
)
1311 GtkTreeModel
*model
;
1312 GtkTreeSelection
*selection
;
1314 EmpathyAccountSettings
*settings
;
1315 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1317 view
= GTK_TREE_VIEW (priv
->treeview
);
1318 selection
= gtk_tree_view_get_selection (view
);
1320 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
1323 gtk_tree_model_get (model
, &iter
,
1324 COL_ACCOUNT_SETTINGS
, &settings
, -1);
1330 accounts_dialog_model_selection_changed (GtkTreeSelection
*selection
,
1331 EmpathyAccountsDialog
*dialog
)
1333 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1334 EmpathyAccountSettings
*settings
;
1335 GtkTreeModel
*model
;
1337 gboolean is_selection
;
1338 gboolean creating
= FALSE
;
1340 is_selection
= gtk_tree_selection_get_selected (selection
, &model
, &iter
);
1342 settings
= accounts_dialog_model_get_selected_settings (dialog
);
1343 accounts_dialog_update_settings (dialog
, settings
);
1345 if (settings
!= NULL
)
1346 g_object_unref (settings
);
1348 if (priv
->setting_widget_object
!= NULL
)
1350 g_object_get (priv
->setting_widget_object
,
1351 "creating-account", &creating
, NULL
);
1354 /* Update remove button sensitivity */
1355 gtk_widget_set_sensitive (priv
->button_remove
, is_selection
&& !creating
&&
1360 accounts_dialog_selection_change_response_cb (GtkDialog
*message_dialog
,
1362 gpointer
*user_data
)
1364 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1365 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1367 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
1369 if (response_id
== GTK_RESPONSE_YES
&& priv
->destination_row
!= NULL
)
1371 /* The user wants to lose unsaved changes to the currently selected
1372 * account and select another account. We discard the changes and
1373 * select the other account. */
1375 GtkTreeSelection
*selection
;
1377 priv
->force_change_row
= TRUE
;
1378 empathy_account_widget_discard_pending_changes (
1379 priv
->setting_widget_object
);
1381 path
= gtk_tree_row_reference_get_path (priv
->destination_row
);
1382 selection
= gtk_tree_view_get_selection (
1383 GTK_TREE_VIEW (priv
->treeview
));
1387 /* This will trigger a call to
1388 * accounts_dialog_account_selection_change() */
1389 gtk_tree_selection_select_path (selection
, path
);
1390 gtk_tree_path_free (path
);
1393 gtk_tree_row_reference_free (priv
->destination_row
);
1397 priv
->force_change_row
= FALSE
;
1402 accounts_dialog_account_selection_change (GtkTreeSelection
*selection
,
1403 GtkTreeModel
*model
,
1405 gboolean path_currently_selected
,
1408 TpAccount
*account
= NULL
;
1409 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (data
);
1410 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1413 if (priv
->force_change_row
)
1415 /* We came back here because the user wants to discard changes to his
1416 * modified account. The changes have already been discarded so we
1417 * just change the selected row. */
1418 priv
->force_change_row
= FALSE
;
1422 if (accounts_dialog_has_pending_change (dialog
, &account
))
1424 /* The currently selected account has some unsaved changes. We ask
1425 * the user if he really wants to lose his changes and select another
1427 gchar
*question_dialog_primary_text
= get_dialog_primary_text (account
);
1428 priv
->destination_row
= gtk_tree_row_reference_new (model
, path
);
1430 accounts_dialog_show_question_dialog (dialog
,
1431 question_dialog_primary_text
,
1432 _("You are about to select another account, which will discard\n"
1433 "your changes. Are you sure you want to proceed?"),
1434 G_CALLBACK (accounts_dialog_selection_change_response_cb
),
1436 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
1437 GTK_STOCK_DISCARD
, GTK_RESPONSE_YES
, NULL
);
1439 g_free (question_dialog_primary_text
);
1447 if (account
!= NULL
)
1448 g_object_unref (account
);
1454 accounts_dialog_model_setup (EmpathyAccountsDialog
*dialog
)
1456 GtkListStore
*store
;
1457 GtkTreeSelection
*selection
;
1458 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1460 store
= gtk_list_store_new (COL_COUNT
,
1461 G_TYPE_STRING
, /* name */
1462 G_TYPE_UINT
, /* status */
1463 TP_TYPE_ACCOUNT
, /* account */
1464 EMPATHY_TYPE_ACCOUNT_SETTINGS
); /* settings */
1466 gtk_tree_view_set_model (GTK_TREE_VIEW (priv
->treeview
),
1467 GTK_TREE_MODEL (store
));
1469 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1470 gtk_tree_selection_set_mode (selection
, GTK_SELECTION_SINGLE
);
1471 gtk_tree_selection_set_select_function (selection
,
1472 accounts_dialog_account_selection_change
, dialog
, NULL
);
1474 g_signal_connect (selection
, "changed",
1475 G_CALLBACK (accounts_dialog_model_selection_changed
),
1478 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store
),
1479 COL_NAME
, GTK_SORT_ASCENDING
);
1481 accounts_dialog_model_add_columns (dialog
);
1483 g_object_unref (store
);
1487 accounts_dialog_get_settings_iter (EmpathyAccountsDialog
*dialog
,
1488 EmpathyAccountSettings
*settings
,
1492 GtkTreeModel
*model
;
1494 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1496 /* Update the status in the model */
1497 view
= GTK_TREE_VIEW (priv
->treeview
);
1498 model
= gtk_tree_view_get_model (view
);
1500 for (ok
= gtk_tree_model_get_iter_first (model
, iter
);
1502 ok
= gtk_tree_model_iter_next (model
, iter
))
1504 EmpathyAccountSettings
*this_settings
;
1507 gtk_tree_model_get (model
, iter
,
1508 COL_ACCOUNT_SETTINGS
, &this_settings
,
1511 equal
= (this_settings
== settings
);
1512 g_object_unref (this_settings
);
1522 accounts_dialog_get_account_iter (EmpathyAccountsDialog
*dialog
,
1527 GtkTreeModel
*model
;
1529 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1531 /* Update the status in the model */
1532 view
= GTK_TREE_VIEW (priv
->treeview
);
1533 model
= gtk_tree_view_get_model (view
);
1535 for (ok
= gtk_tree_model_get_iter_first (model
, iter
);
1537 ok
= gtk_tree_model_iter_next (model
, iter
))
1539 EmpathyAccountSettings
*settings
;
1542 gtk_tree_model_get (model
, iter
,
1543 COL_ACCOUNT_SETTINGS
, &settings
,
1546 equal
= empathy_account_settings_has_account (settings
, account
);
1547 g_object_unref (settings
);
1557 select_and_scroll_to_iter (EmpathyAccountsDialog
*dialog
,
1560 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1561 GtkTreeSelection
*selection
;
1563 GtkTreeModel
*model
;
1565 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1567 gtk_tree_selection_select_iter (selection
, iter
);
1569 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1570 path
= gtk_tree_model_get_path (model
, iter
);
1572 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv
->treeview
), path
, NULL
,
1575 gtk_tree_path_free (path
);
1579 accounts_dialog_model_set_selected (EmpathyAccountsDialog
*dialog
,
1580 EmpathyAccountSettings
*settings
)
1584 if (accounts_dialog_get_settings_iter (dialog
, settings
, &iter
))
1585 select_and_scroll_to_iter (dialog
, &iter
);
1589 accounts_dialog_treeview_enabled_cb (GtkMenuItem
*item
,
1594 enabled
= tp_account_is_enabled (account
);
1595 tp_account_set_enabled_async (account
, !enabled
, NULL
, NULL
);
1599 accounts_dialog_treeview_button_press_event_cb (GtkTreeView
*view
,
1600 GdkEventButton
*event
,
1601 EmpathyAccountsDialog
*dialog
)
1603 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1604 TpAccount
*account
= NULL
;
1605 GtkTreeModel
*model
= NULL
;
1606 GtkTreePath
*path
= NULL
;
1609 GtkWidget
*item_enable
, *item_disable
;
1610 GtkWidget
*image_enable
, *image_disable
;
1612 /* ignore multiple clicks */
1613 if (event
->type
!= GDK_BUTTON_PRESS
)
1616 if (event
->button
!= 3)
1619 /* Selection is not yet set, so we have to get account from event position */
1620 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1621 if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (priv
->treeview
),
1622 event
->x
, event
->y
, &path
, NULL
, NULL
, NULL
))
1625 if (!gtk_tree_model_get_iter (model
, &iter
, path
))
1628 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT
, &account
, -1);
1630 /* Create the menu */
1631 menu
= empathy_context_menu_new (GTK_WIDGET (view
));
1633 /* Get images for menu items */
1634 image_enable
= gtk_image_new_from_icon_name (empathy_icon_name_for_presence (
1635 tp_account_manager_get_most_available_presence (
1636 priv
->account_manager
, NULL
, NULL
)),
1637 GTK_ICON_SIZE_MENU
);
1638 image_disable
= gtk_image_new_from_icon_name (
1639 empathy_icon_name_for_presence (TP_CONNECTION_PRESENCE_TYPE_OFFLINE
),
1640 GTK_ICON_SIZE_MENU
);
1642 /* Menu items: to enabled/disable the account */
1643 item_enable
= gtk_image_menu_item_new_with_mnemonic (_("_Enable"));
1644 item_disable
= gtk_image_menu_item_new_with_mnemonic (_("_Disable"));
1645 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_enable
),
1647 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item_disable
),
1650 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item_enable
);
1651 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item_disable
);
1653 if (tp_account_is_enabled (account
))
1655 tp_g_signal_connect_object (item_disable
, "activate",
1656 G_CALLBACK (accounts_dialog_treeview_enabled_cb
), account
, 0);
1657 gtk_widget_set_sensitive (item_enable
, FALSE
);
1661 tp_g_signal_connect_object (item_enable
, "activate",
1662 G_CALLBACK (accounts_dialog_treeview_enabled_cb
), account
, 0);
1663 gtk_widget_set_sensitive (item_disable
, FALSE
);
1666 gtk_widget_show (item_enable
);
1667 gtk_widget_show (item_disable
);
1669 /* FIXME: Add here presence items, to be able to set per-account presence */
1672 gtk_menu_popup (GTK_MENU (menu
), NULL
, NULL
, NULL
, NULL
,
1673 event
->button
, event
->time
);
1676 tp_clear_object (&account
);
1677 gtk_tree_path_free (path
);
1683 accounts_dialog_add (EmpathyAccountsDialog
*dialog
,
1684 EmpathyAccountSettings
*settings
)
1686 GtkTreeModel
*model
;
1689 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1691 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1692 name
= empathy_account_settings_get_display_name (settings
);
1694 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
1696 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1698 COL_STATUS
, TP_CONNECTION_STATUS_DISCONNECTED
,
1699 COL_ACCOUNT_SETTINGS
, settings
,
1704 accounts_dialog_connection_changed_cb (TpAccount
*account
,
1708 gchar
*dbus_error_name
,
1709 GHashTable
*details
,
1710 EmpathyAccountsDialog
*dialog
)
1712 GtkTreeModel
*model
;
1715 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1717 /* Update the status-infobar in the details view */
1718 accounts_dialog_update_status_infobar (dialog
, account
);
1720 /* Update the status in the model */
1721 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1723 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1727 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1728 COL_STATUS
, current
,
1731 path
= gtk_tree_model_get_path (model
, &iter
);
1732 gtk_tree_model_row_changed (model
, path
, &iter
);
1733 gtk_tree_path_free (path
);
1736 empathy_account_manager_get_accounts_connected (&found
);
1738 if (!found
&& priv
->connecting_id
)
1740 g_source_remove (priv
->connecting_id
);
1741 priv
->connecting_id
= 0;
1744 if (found
&& !priv
->connecting_id
)
1745 priv
->connecting_id
= g_timeout_add (FLASH_TIMEOUT
,
1746 (GSourceFunc
) accounts_dialog_flash_connecting_cb
,
1751 update_account_in_treeview (EmpathyAccountsDialog
*self
,
1754 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (self
);
1756 GtkTreeModel
*model
;
1758 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1759 if (accounts_dialog_get_account_iter (self
, account
, &iter
))
1763 path
= gtk_tree_model_get_path (model
, &iter
);
1764 gtk_tree_model_row_changed (model
, path
, &iter
);
1765 gtk_tree_path_free (path
);
1770 accounts_dialog_presence_changed_cb (TpAccount
*account
,
1773 gchar
*status_message
,
1774 EmpathyAccountsDialog
*dialog
)
1776 /* Update the status-infobar in the details view */
1777 accounts_dialog_update_status_infobar (dialog
, account
);
1779 update_account_in_treeview (dialog
, account
);
1783 accounts_dialog_account_display_name_changed_cb (TpAccount
*account
,
1787 const gchar
*display_name
;
1789 GtkTreeModel
*model
;
1790 EmpathyAccountSettings
*settings
;
1791 TpAccount
*selected_account
;
1792 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1793 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1795 display_name
= tp_account_get_display_name (account
);
1796 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1797 settings
= accounts_dialog_model_get_selected_settings (dialog
);
1798 if (settings
== NULL
)
1801 selected_account
= empathy_account_settings_get_account (settings
);
1803 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1805 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1806 COL_NAME
, display_name
,
1810 if (selected_account
== account
)
1811 accounts_dialog_update_name_label (dialog
, display_name
);
1813 g_object_unref (settings
);
1817 accounts_dialog_add_account (EmpathyAccountsDialog
*dialog
,
1820 EmpathyAccountSettings
*settings
;
1821 GtkTreeModel
*model
;
1823 TpConnectionStatus status
;
1825 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1826 gboolean selected
= FALSE
;
1828 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
1829 status
= tp_account_get_connection_status (account
, NULL
);
1830 name
= tp_account_get_display_name (account
);
1832 settings
= empathy_account_settings_new_for_account (account
);
1834 if (!accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1836 gtk_list_store_append (GTK_LIST_STORE (model
), &iter
);
1840 GtkTreeSelection
*selection
;
1842 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
1843 selected
= gtk_tree_selection_iter_is_selected (selection
, &iter
);
1846 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
,
1849 COL_ACCOUNT
, account
,
1850 COL_ACCOUNT_SETTINGS
, settings
,
1855 /* We just modified the selected account. Its display name may have been
1856 * changed and so it's place in the treeview. Scroll to it so it stays
1858 select_and_scroll_to_iter (dialog
, &iter
);
1861 accounts_dialog_connection_changed_cb (account
,
1864 TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED
,
1869 tp_g_signal_connect_object (account
, "notify::display-name",
1870 G_CALLBACK (accounts_dialog_account_display_name_changed_cb
),
1873 tp_g_signal_connect_object (account
, "status-changed",
1874 G_CALLBACK (accounts_dialog_connection_changed_cb
), dialog
, 0);
1875 tp_g_signal_connect_object (account
, "presence-changed",
1876 G_CALLBACK (accounts_dialog_presence_changed_cb
), dialog
, 0);
1878 g_object_unref (settings
);
1882 account_prepare_cb (GObject
*source_object
,
1883 GAsyncResult
*result
,
1886 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (user_data
);
1887 TpAccount
*account
= TP_ACCOUNT (source_object
);
1888 GError
*error
= NULL
;
1890 if (!tp_account_prepare_finish (account
, result
, &error
))
1892 DEBUG ("Failed to prepare account: %s", error
->message
);
1893 g_error_free (error
);
1897 accounts_dialog_add_account (dialog
, account
);
1901 accounts_dialog_account_validity_changed_cb (TpAccountManager
*manager
,
1904 EmpathyAccountsDialog
*dialog
)
1906 tp_account_prepare_async (account
, NULL
, account_prepare_cb
, dialog
);
1910 accounts_dialog_accounts_model_row_inserted_cb (GtkTreeModel
*model
,
1913 EmpathyAccountsDialog
*dialog
)
1915 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1917 if (priv
->setting_widget_object
!= NULL
&&
1918 accounts_dialog_has_valid_accounts (dialog
))
1920 empathy_account_widget_set_other_accounts_exist (
1921 priv
->setting_widget_object
, TRUE
);
1926 accounts_dialog_accounts_model_row_deleted_cb (GtkTreeModel
*model
,
1928 EmpathyAccountsDialog
*dialog
)
1930 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1932 if (priv
->setting_widget_object
!= NULL
&&
1933 !accounts_dialog_has_valid_accounts (dialog
))
1935 empathy_account_widget_set_other_accounts_exist (
1936 priv
->setting_widget_object
, FALSE
);
1941 accounts_dialog_account_removed_cb (TpAccountManager
*manager
,
1943 EmpathyAccountsDialog
*dialog
)
1946 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
1948 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
1950 gtk_list_store_remove (GTK_LIST_STORE (
1951 gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
))), &iter
);
1956 enable_or_disable_account (EmpathyAccountsDialog
*dialog
,
1960 /* Update the status-infobar in the details view */
1961 accounts_dialog_update_status_infobar (dialog
, account
);
1963 DEBUG ("Account %s is now %s",
1964 tp_account_get_display_name (account
),
1965 enabled
? "enabled" : "disabled");
1969 accounts_dialog_account_disabled_cb (TpAccountManager
*manager
,
1971 EmpathyAccountsDialog
*dialog
)
1973 enable_or_disable_account (dialog
, account
, FALSE
);
1974 update_account_in_treeview (dialog
, account
);
1978 accounts_dialog_account_enabled_cb (TpAccountManager
*manager
,
1980 EmpathyAccountsDialog
*dialog
)
1982 enable_or_disable_account (dialog
, account
, TRUE
);
1986 accounts_dialog_button_import_clicked_cb (GtkWidget
*button
,
1987 EmpathyAccountsDialog
*dialog
)
1989 GtkWidget
*import_dialog
;
1991 import_dialog
= empathy_import_dialog_new (GTK_WINDOW (dialog
),
1993 gtk_widget_show (import_dialog
);
1997 accounts_dialog_close_response_cb (GtkDialog
*message_dialog
,
2001 GtkWidget
*account_dialog
= GTK_WIDGET (user_data
);
2003 gtk_widget_destroy (GTK_WIDGET (message_dialog
));
2005 if (response_id
== GTK_RESPONSE_YES
)
2006 gtk_widget_destroy (account_dialog
);
2010 accounts_dialog_delete_event_cb (GtkWidget
*widget
,
2012 EmpathyAccountsDialog
*dialog
)
2014 /* we maunally handle responses to delete events */
2019 accounts_dialog_set_selected_account (EmpathyAccountsDialog
*dialog
,
2024 if (accounts_dialog_get_account_iter (dialog
, account
, &iter
))
2025 select_and_scroll_to_iter (dialog
, &iter
);
2029 finished_loading (EmpathyAccountsDialog
*self
)
2031 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (self
);
2032 GtkTreeSelection
*selection
;
2033 gboolean has_selected
;
2035 priv
->loading
= FALSE
;
2037 gtk_widget_set_sensitive (priv
->button_add
, TRUE
);
2038 gtk_widget_set_sensitive (priv
->button_import
, TRUE
);
2039 gtk_widget_set_sensitive (priv
->treeview
, TRUE
);
2041 /* Sensitive the remove button if there is an account selected */
2042 selection
= gtk_tree_view_get_selection (GTK_TREE_VIEW (priv
->treeview
));
2043 has_selected
= gtk_tree_selection_get_selected (selection
, NULL
, NULL
);
2044 gtk_widget_set_sensitive (priv
->button_remove
, has_selected
);
2046 gtk_spinner_stop (GTK_SPINNER (priv
->spinner
));
2047 gtk_notebook_set_current_page (GTK_NOTEBOOK (priv
->notebook_account
),
2048 NOTEBOOK_PAGE_ACCOUNT
);
2052 accounts_dialog_cms_prepare_cb (GObject
*source
,
2053 GAsyncResult
*result
,
2056 EmpathyConnectionManagers
*cms
= EMPATHY_CONNECTION_MANAGERS (source
);
2057 EmpathyAccountsDialog
*dialog
= user_data
;
2058 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
2060 if (!empathy_connection_managers_prepare_finish (cms
, result
, NULL
))
2063 /* No need to update the settings if we are already preparing one */
2064 if (priv
->settings_ready
== NULL
)
2065 accounts_dialog_update_settings (dialog
, NULL
);
2067 if (priv
->initial_selection
!= NULL
)
2069 accounts_dialog_set_selected_account (dialog
, priv
->initial_selection
);
2070 g_object_unref (priv
->initial_selection
);
2071 priv
->initial_selection
= NULL
;
2075 finished_loading (dialog
);
2079 accounts_dialog_accounts_setup (EmpathyAccountsDialog
*dialog
)
2081 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
2082 GList
*accounts
, *l
;
2084 g_signal_connect (priv
->account_manager
, "account-validity-changed",
2085 G_CALLBACK (accounts_dialog_account_validity_changed_cb
),
2087 g_signal_connect (priv
->account_manager
, "account-removed",
2088 G_CALLBACK (accounts_dialog_account_removed_cb
),
2090 g_signal_connect (priv
->account_manager
, "account-enabled",
2091 G_CALLBACK (accounts_dialog_account_enabled_cb
),
2093 g_signal_connect (priv
->account_manager
, "account-disabled",
2094 G_CALLBACK (accounts_dialog_account_disabled_cb
),
2097 /* Add existing accounts */
2098 accounts
= tp_account_manager_get_valid_accounts (priv
->account_manager
);
2099 for (l
= accounts
; l
; l
= l
->next
)
2101 accounts_dialog_add_account (dialog
, l
->data
);
2103 g_list_free (accounts
);
2105 priv
->cms
= empathy_connection_managers_dup_singleton ();
2107 empathy_connection_managers_prepare_async (priv
->cms
,
2108 accounts_dialog_cms_prepare_cb
, dialog
);
2110 accounts_dialog_model_select_first (dialog
);
2114 accounts_dialog_manager_ready_cb (GObject
*source_object
,
2115 GAsyncResult
*result
,
2118 TpAccountManager
*manager
= TP_ACCOUNT_MANAGER (source_object
);
2119 GError
*error
= NULL
;
2121 if (!tp_account_manager_prepare_finish (manager
, result
, &error
))
2123 DEBUG ("Failed to prepare account manager: %s", error
->message
);
2124 g_error_free (error
);
2128 accounts_dialog_accounts_setup (user_data
);
2132 dialog_response_cb (GtkWidget
*widget
,
2136 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (widget
);
2138 if (response_id
== GTK_RESPONSE_HELP
)
2140 empathy_url_show (widget
, "ghelp:empathy?accounts-window");
2142 else if (response_id
== GTK_RESPONSE_CLOSE
||
2143 response_id
== GTK_RESPONSE_DELETE_EVENT
)
2145 TpAccount
*account
= NULL
;
2147 if (accounts_dialog_has_pending_change (dialog
, &account
))
2149 gchar
*question_dialog_primary_text
= get_dialog_primary_text (
2152 accounts_dialog_show_question_dialog (dialog
,
2153 question_dialog_primary_text
,
2154 _("You are about to close the window, which will discard\n"
2155 "your changes. Are you sure you want to proceed?"),
2156 G_CALLBACK (accounts_dialog_close_response_cb
),
2158 GTK_STOCK_CANCEL
, GTK_RESPONSE_NO
,
2159 GTK_STOCK_DISCARD
, GTK_RESPONSE_YES
, NULL
);
2161 g_free (question_dialog_primary_text
);
2165 gtk_widget_destroy (widget
);
2168 if (account
!= NULL
)
2169 g_object_unref (account
);
2174 accounts_dialog_build_ui (EmpathyAccountsDialog
*dialog
)
2176 GtkWidget
*top_hbox
;
2179 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
2180 GtkWidget
*content_area
;
2181 GtkWidget
*action_area
, *vbox
, *hbox
, *align
;
2183 GtkWidget
*sw
, *toolbar
;
2184 GtkStyleContext
*context
;
2186 filename
= empathy_file_lookup ("empathy-accounts-dialog.ui", "src");
2188 gui
= empathy_builder_get_file (filename
,
2189 "accounts_dialog_hbox", &top_hbox
,
2190 "vbox_details", &priv
->vbox_details
,
2191 "frame_no_protocol", &priv
->frame_no_protocol
,
2192 "alignment_settings", &priv
->alignment_settings
,
2193 "alignment_infobar", &priv
->alignment_infobar
,
2194 "treeview", &priv
->treeview
,
2195 "button_add", &priv
->button_add
,
2196 "button_remove", &priv
->button_remove
,
2197 "button_import", &priv
->button_import
,
2198 "hbox_protocol", &priv
->hbox_protocol
,
2199 "notebook_account", &priv
->notebook_account
,
2200 "alignment_loading", &alig
,
2202 "add_remove_toolbar", &toolbar
,
2206 gtk_widget_set_no_show_all (priv
->frame_no_protocol
, TRUE
);
2208 empathy_builder_connect (gui
, dialog
,
2209 "button_add", "clicked", accounts_dialog_button_add_clicked_cb
,
2210 "button_remove", "clicked", accounts_dialog_button_remove_clicked_cb
,
2211 "button_import", "clicked", accounts_dialog_button_import_clicked_cb
,
2212 "treeview", "button-press-event",
2213 accounts_dialog_treeview_button_press_event_cb
,
2216 content_area
= gtk_dialog_get_content_area (GTK_DIALOG (dialog
));
2218 gtk_box_pack_start (GTK_BOX (content_area
), top_hbox
, TRUE
, TRUE
, 0);
2220 g_object_unref (gui
);
2222 action_area
= gtk_dialog_get_action_area (GTK_DIALOG (dialog
));
2225 gtk_widget_hide (action_area
);
2226 gtk_widget_hide (priv
->button_remove
);
2227 #endif /* HAVE_MEEGO */
2229 /* Display loading page */
2230 priv
->loading
= TRUE
;
2232 priv
->spinner
= gtk_spinner_new ();
2234 gtk_spinner_start (GTK_SPINNER (priv
->spinner
));
2235 gtk_widget_show (priv
->spinner
);
2237 gtk_container_add (GTK_CONTAINER (alig
), priv
->spinner
);
2239 gtk_notebook_set_current_page (GTK_NOTEBOOK (priv
->notebook_account
),
2240 NOTEBOOK_PAGE_LOADING
);
2242 /* Remove button is insensitive until we have a selected account */
2243 gtk_widget_set_sensitive (priv
->button_remove
, FALSE
);
2245 /* Add and Import buttons and treeview are insensitive while the dialog
2247 gtk_widget_set_sensitive (priv
->button_add
, FALSE
);
2248 gtk_widget_set_sensitive (priv
->button_import
, FALSE
);
2249 gtk_widget_set_sensitive (priv
->treeview
, FALSE
);
2251 priv
->combobox_protocol
= empathy_protocol_chooser_new ();
2252 gtk_box_pack_start (GTK_BOX (priv
->hbox_protocol
), priv
->combobox_protocol
,
2254 g_signal_connect (priv
->combobox_protocol
, "changed",
2255 G_CALLBACK (accounts_dialog_protocol_changed_cb
),
2258 if (priv
->parent_window
)
2259 gtk_window_set_transient_for (GTK_WINDOW (dialog
),
2260 priv
->parent_window
);
2262 priv
->infobar
= gtk_info_bar_new ();
2263 gtk_container_add (GTK_CONTAINER (priv
->alignment_infobar
),
2265 gtk_widget_show (priv
->infobar
);
2267 content_area
= gtk_info_bar_get_content_area (GTK_INFO_BAR (priv
->infobar
));
2269 priv
->image_type
= gtk_image_new_from_stock (GTK_STOCK_CUT
,
2270 GTK_ICON_SIZE_DIALOG
);
2271 gtk_misc_set_alignment (GTK_MISC (priv
->image_type
), 0.0, 0.5);
2272 gtk_box_pack_start (GTK_BOX (content_area
), priv
->image_type
, FALSE
, FALSE
, 0);
2273 gtk_widget_show (priv
->image_type
);
2275 vbox
= gtk_vbox_new (FALSE
, 6);
2276 gtk_box_pack_start (GTK_BOX (content_area
), vbox
, TRUE
, TRUE
, 0);
2277 gtk_widget_show (vbox
);
2280 align
= gtk_alignment_new (0.5, 0.0, 0.0, 0.0);
2281 gtk_widget_show (align
);
2283 priv
->label_name
= gtk_label_new (NULL
);
2284 gtk_container_add (GTK_CONTAINER (align
), priv
->label_name
);
2285 gtk_widget_show (priv
->label_name
);
2287 gtk_box_pack_start (GTK_BOX (vbox
), align
, TRUE
, TRUE
, 0);
2290 align
= gtk_alignment_new (0.5, 0.0, 0.0, 0.0);
2291 gtk_widget_show (align
);
2292 hbox
= gtk_hbox_new (FALSE
, 6);
2293 gtk_widget_show (hbox
);
2294 gtk_container_add (GTK_CONTAINER (align
), hbox
);
2296 gtk_box_pack_start (GTK_BOX (vbox
), align
, TRUE
, TRUE
, 0);
2298 /* set up spinner */
2299 priv
->throbber
= gtk_spinner_new ();
2301 priv
->image_status
= gtk_image_new_from_icon_name (
2302 empathy_icon_name_for_presence (
2303 TP_CONNECTION_PRESENCE_TYPE_OFFLINE
), GTK_ICON_SIZE_SMALL_TOOLBAR
);
2305 priv
->label_status
= gtk_label_new (NULL
);
2306 gtk_label_set_line_wrap (GTK_LABEL (priv
->label_status
), TRUE
);
2307 gtk_widget_show (priv
->label_status
);
2309 gtk_box_pack_start (GTK_BOX (hbox
), priv
->throbber
, FALSE
, FALSE
, 0);
2310 gtk_box_pack_start (GTK_BOX (hbox
), priv
->image_status
, FALSE
, FALSE
, 3);
2311 gtk_box_pack_start (GTK_BOX (hbox
), priv
->label_status
, TRUE
, TRUE
, 0);
2313 /* enabled switch */
2314 align
= gtk_alignment_new (0.5, 0.5, 1., 0.);
2315 gtk_box_pack_start (GTK_BOX (content_area
), align
, FALSE
, TRUE
, 0);
2317 priv
->enabled_switch
= gtk_switch_new ();
2318 gtk_container_add (GTK_CONTAINER (align
), priv
->enabled_switch
);
2319 g_signal_connect (priv
->enabled_switch
, "notify::active",
2320 G_CALLBACK (accounts_dialog_enable_switch_active_cb
), dialog
);
2321 gtk_widget_show_all (align
);
2323 /* Tweak the dialog */
2324 gtk_window_set_title (GTK_WINDOW (dialog
), _("Messaging and VoIP Accounts"));
2325 gtk_window_set_role (GTK_WINDOW (dialog
), "accounts");
2327 gtk_window_set_default_size (GTK_WINDOW (dialog
), 640, 450);
2329 gtk_window_set_type_hint (GTK_WINDOW (dialog
), GDK_WINDOW_TYPE_HINT_DIALOG
);
2331 /* join the add/remove toolbar to the treeview */
2332 context
= gtk_widget_get_style_context (sw
);
2333 gtk_style_context_set_junction_sides (context
, GTK_JUNCTION_BOTTOM
);
2335 context
= gtk_widget_get_style_context (toolbar
);
2336 gtk_style_context_set_junction_sides (context
, GTK_JUNCTION_TOP
);
2338 /* add dialog buttons */
2339 gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area
), GTK_BUTTONBOX_END
);
2341 gtk_dialog_add_buttons (GTK_DIALOG (dialog
),
2342 GTK_STOCK_HELP
, GTK_RESPONSE_HELP
,
2343 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
,
2346 g_signal_connect (dialog
, "response",
2347 G_CALLBACK (dialog_response_cb
), dialog
);
2349 g_signal_connect (dialog
, "delete-event",
2350 G_CALLBACK (accounts_dialog_delete_event_cb
), dialog
);
2354 do_dispose (GObject
*obj
)
2356 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (obj
);
2357 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
2359 if (priv
->connecting_id
!= 0)
2361 g_source_remove (priv
->connecting_id
);
2362 priv
->connecting_id
= 0;
2365 if (priv
->account_manager
!= NULL
)
2367 g_object_unref (priv
->account_manager
);
2368 priv
->account_manager
= NULL
;
2371 if (priv
->cms
!= NULL
)
2373 g_object_unref (priv
->cms
);
2377 if (priv
->connectivity
)
2379 g_object_unref (priv
->connectivity
);
2380 priv
->connectivity
= NULL
;
2383 if (priv
->initial_selection
!= NULL
)
2385 g_object_unref (priv
->initial_selection
);
2386 priv
->initial_selection
= NULL
;
2389 G_OBJECT_CLASS (empathy_accounts_dialog_parent_class
)->dispose (obj
);
2393 do_get_property (GObject
*object
,
2398 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (object
);
2400 switch (property_id
)
2403 g_value_set_object (value
, priv
->parent_window
);
2406 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
2411 do_set_property (GObject
*object
,
2413 const GValue
*value
,
2416 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (object
);
2418 switch (property_id
)
2421 priv
->parent_window
= g_value_get_object (value
);
2424 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
2429 do_constructed (GObject
*object
)
2431 EmpathyAccountsDialog
*dialog
= EMPATHY_ACCOUNTS_DIALOG (object
);
2432 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
2433 GtkTreeModel
*model
;
2435 accounts_dialog_build_ui (dialog
);
2436 accounts_dialog_model_setup (dialog
);
2438 model
= gtk_tree_view_get_model (GTK_TREE_VIEW (priv
->treeview
));
2439 g_signal_connect (model
, "row-inserted",
2440 (GCallback
) accounts_dialog_accounts_model_row_inserted_cb
, dialog
);
2441 g_signal_connect (model
, "row-deleted",
2442 (GCallback
) accounts_dialog_accounts_model_row_deleted_cb
, dialog
);
2444 /* Set up signalling */
2445 priv
->account_manager
= tp_account_manager_dup ();
2447 tp_account_manager_prepare_async (priv
->account_manager
, NULL
,
2448 accounts_dialog_manager_ready_cb
, dialog
);
2450 priv
->connectivity
= empathy_connectivity_dup_singleton ();
2454 empathy_accounts_dialog_class_init (EmpathyAccountsDialogClass
*klass
)
2456 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
2457 GParamSpec
*param_spec
;
2459 oclass
->dispose
= do_dispose
;
2460 oclass
->constructed
= do_constructed
;
2461 oclass
->set_property
= do_set_property
;
2462 oclass
->get_property
= do_get_property
;
2464 param_spec
= g_param_spec_object ("parent",
2465 "parent", "The parent window",
2467 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
| G_PARAM_CONSTRUCT_ONLY
);
2468 g_object_class_install_property (oclass
, PROP_PARENT
, param_spec
);
2470 g_type_class_add_private (klass
, sizeof (EmpathyAccountsDialogPriv
));
2474 empathy_accounts_dialog_init (EmpathyAccountsDialog
*dialog
)
2476 EmpathyAccountsDialogPriv
*priv
;
2478 priv
= G_TYPE_INSTANCE_GET_PRIVATE ((dialog
),
2479 EMPATHY_TYPE_ACCOUNTS_DIALOG
,
2480 EmpathyAccountsDialogPriv
);
2481 dialog
->priv
= priv
;
2484 /* public methods */
2487 empathy_accounts_dialog_show (GtkWindow
*parent
,
2488 TpAccount
*selected_account
)
2490 EmpathyAccountsDialog
*dialog
;
2491 EmpathyAccountsDialogPriv
*priv
;
2493 dialog
= g_object_new (EMPATHY_TYPE_ACCOUNTS_DIALOG
,
2494 "parent", parent
, NULL
);
2496 priv
= GET_PRIV (dialog
);
2498 if (selected_account
)
2500 if (priv
->cms
!= NULL
&& empathy_connection_managers_is_ready (priv
->cms
))
2501 accounts_dialog_set_selected_account (dialog
, selected_account
);
2503 /* save the selection to set it later when the cms
2506 priv
->initial_selection
= g_object_ref (selected_account
);
2509 gtk_window_present (GTK_WINDOW (dialog
));
2511 return GTK_WIDGET (dialog
);
2515 empathy_accounts_dialog_show_application (GdkScreen
*screen
,
2516 TpAccount
*selected_account
,
2522 g_return_if_fail (!selected_account
|| TP_IS_ACCOUNT (selected_account
));
2524 args
= g_string_new (NULL
);
2526 if (selected_account
!= NULL
)
2527 g_string_append_printf (args
, " --select-account=%s",
2528 tp_account_get_path_suffix (selected_account
));
2531 g_string_append_printf (args
, " --if-needed");
2534 g_string_append_printf (args
, " --hidden");
2536 DEBUG ("Launching empathy-accounts (if_needed: %d, hidden: %d, account: %s)",
2538 selected_account
== NULL
? "<none selected>" :
2539 tp_proxy_get_object_path (TP_PROXY (selected_account
)));
2541 empathy_launch_program (BIN_DIR
, "empathy-accounts", args
->str
);
2543 g_string_free (args
, TRUE
);
2547 empathy_accounts_dialog_is_creating (EmpathyAccountsDialog
*dialog
)
2549 EmpathyAccountsDialogPriv
*priv
= GET_PRIV (dialog
);
2550 gboolean result
= FALSE
;
2552 if (priv
->setting_widget_object
== NULL
)
2555 g_object_get (priv
->setting_widget_object
,
2556 "creating-account", &result
, NULL
);