1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2005-2007 Imendio AB
4 * Copyright (C) 2007-2008 Collabora Ltd.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301 USA
21 * Authors: Martyn Russell <martyn@imendio.com>
22 * Xavier Claessens <xclaesse@gmail.com>
29 #include <glib/gi18n-lib.h>
32 #include <telepathy-glib/account-manager.h>
33 #include <telepathy-glib/util.h>
35 #include <libempathy/empathy-utils.h>
37 #include "empathy-ui-utils.h"
38 #include "empathy-account-chooser.h"
40 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
41 #include <libempathy/empathy-debug.h>
44 * SECTION:empathy-account-chooser
45 * @title:EmpathyAccountChooser
46 * @short_description: A widget used to choose from a list of accounts
47 * @include: libempathy-gtk/empathy-account-chooser.h
49 * #EmpathyAccountChooser is a widget which extends #GtkComboBox to provide
50 * a chooser of available accounts.
54 * EmpathyAccountChooser:
55 * @parent: parent object
57 * Widget which extends #GtkComboBox to provide a chooser of available accounts.
60 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountChooser)
62 TpAccountManager
*manager
;
63 gboolean set_active_item
;
64 gboolean account_manually_set
;
65 gboolean has_all_option
;
66 EmpathyAccountChooserFilterFunc filter
;
69 } EmpathyAccountChooserPriv
;
72 EmpathyAccountChooser
*chooser
;
78 EmpathyAccountChooser
*chooser
;
81 } FilterResultCallbackData
;
83 static FilterResultCallbackData
*
84 filter_result_callback_data_new (EmpathyAccountChooser
*chooser
,
88 FilterResultCallbackData
*data
;
90 data
= g_slice_new0 (FilterResultCallbackData
);
91 data
->chooser
= g_object_ref (chooser
);
92 data
->account
= g_object_ref (account
);
93 data
->iter
= gtk_tree_iter_copy (iter
);
99 filter_result_callback_data_free (FilterResultCallbackData
*data
)
101 g_object_unref (data
->chooser
);
102 g_object_unref (data
->account
);
103 gtk_tree_iter_free (data
->iter
);
104 g_slice_free (FilterResultCallbackData
, data
);
107 /* Distinguishes between store entries which are actually accounts, and special
108 * items like the "All" entry and the separator below it, so they can be sorted
109 * correctly. Higher-numbered entries will sort earlier.
120 COL_ACCOUNT_ENABLED
, /* Usually tied to connected state */
121 COL_ACCOUNT_ROW_TYPE
,
126 static void account_chooser_constructed (GObject
*object
);
127 static void account_chooser_finalize (GObject
*object
);
128 static void account_chooser_get_property (GObject
*object
,
132 static void account_chooser_set_property (GObject
*object
,
136 static void account_chooser_setup (EmpathyAccountChooser
*chooser
);
137 static void account_chooser_account_validity_changed_cb (TpAccountManager
*manager
,
140 EmpathyAccountChooser
*chooser
);
141 static void account_chooser_account_add_foreach (TpAccount
*account
,
142 EmpathyAccountChooser
*chooser
);
143 static void account_chooser_account_removed_cb (TpAccountManager
*manager
,
145 EmpathyAccountChooser
*chooser
);
146 static void account_chooser_account_remove_foreach (TpAccount
*account
,
147 EmpathyAccountChooser
*chooser
);
148 static void account_chooser_update_iter (EmpathyAccountChooser
*chooser
,
150 static void account_chooser_status_changed_cb (TpAccount
*account
,
154 gchar
*dbus_error_name
,
157 static gboolean
account_chooser_separator_func (GtkTreeModel
*model
,
159 EmpathyAccountChooser
*chooser
);
160 static gboolean
account_chooser_set_account_foreach (GtkTreeModel
*model
,
163 SetAccountData
*data
);
175 static guint signals
[LAST_SIGNAL
] = { 0 };
177 G_DEFINE_TYPE (EmpathyAccountChooser
, empathy_account_chooser
, GTK_TYPE_COMBO_BOX
);
180 empathy_account_chooser_class_init (EmpathyAccountChooserClass
*klass
)
182 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
184 object_class
->constructed
= account_chooser_constructed
;
185 object_class
->finalize
= account_chooser_finalize
;
186 object_class
->get_property
= account_chooser_get_property
;
187 object_class
->set_property
= account_chooser_set_property
;
190 * EmpathyAccountChooser:has-all-option:
192 * Have an additional option in the list to mean all accounts.
194 g_object_class_install_property (object_class
,
196 g_param_spec_boolean ("has-all-option",
198 "Have a separate option in the list to mean ALL accounts",
203 g_signal_new ("ready",
204 G_OBJECT_CLASS_TYPE (object_class
),
208 g_cclosure_marshal_VOID__VOID
,
212 g_type_class_add_private (object_class
, sizeof (EmpathyAccountChooserPriv
));
216 empathy_account_chooser_init (EmpathyAccountChooser
*chooser
)
218 EmpathyAccountChooserPriv
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (chooser
,
219 EMPATHY_TYPE_ACCOUNT_CHOOSER
, EmpathyAccountChooserPriv
);
221 chooser
->priv
= priv
;
222 priv
->set_active_item
= FALSE
;
223 priv
->account_manually_set
= FALSE
;
225 priv
->filter_data
= NULL
;
227 priv
->manager
= tp_account_manager_dup ();
229 g_signal_connect (priv
->manager
, "account-validity-changed",
230 G_CALLBACK (account_chooser_account_validity_changed_cb
),
232 g_signal_connect (priv
->manager
, "account-removed",
233 G_CALLBACK (account_chooser_account_removed_cb
),
238 account_chooser_constructed (GObject
*object
)
240 EmpathyAccountChooser
*self
= (EmpathyAccountChooser
*) object
;
242 account_chooser_setup (self
);
246 account_chooser_finalize (GObject
*object
)
248 EmpathyAccountChooserPriv
*priv
= GET_PRIV (object
);
250 g_signal_handlers_disconnect_by_func (priv
->manager
,
251 account_chooser_account_validity_changed_cb
,
253 g_signal_handlers_disconnect_by_func (priv
->manager
,
254 account_chooser_account_removed_cb
,
256 g_object_unref (priv
->manager
);
258 G_OBJECT_CLASS (empathy_account_chooser_parent_class
)->finalize (object
);
262 account_chooser_get_property (GObject
*object
,
267 EmpathyAccountChooserPriv
*priv
;
269 priv
= GET_PRIV (object
);
272 case PROP_HAS_ALL_OPTION
:
273 g_value_set_boolean (value
, priv
->has_all_option
);
276 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
282 account_chooser_set_property (GObject
*object
,
287 EmpathyAccountChooserPriv
*priv
;
289 priv
= GET_PRIV (object
);
292 case PROP_HAS_ALL_OPTION
:
293 empathy_account_chooser_set_has_all_option (EMPATHY_ACCOUNT_CHOOSER (object
),
294 g_value_get_boolean (value
));
297 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
303 * empathy_account_chooser_new:
305 * Creates a new #EmpathyAccountChooser.
307 * Return value: A new #EmpathyAccountChooser
310 empathy_account_chooser_new (void)
314 chooser
= g_object_new (EMPATHY_TYPE_ACCOUNT_CHOOSER
, NULL
);
320 * empathy_account_chooser_dup_account:
321 * @chooser: an #EmpathyAccountChooser
323 * Returns the account which is currently selected in the chooser or %NULL
324 * if there is no account selected. The #TpAccount returned should be
325 * unrefed with g_object_unref() when finished with.
327 * Return value: a new ref to the #TpAccount currently selected, or %NULL.
330 empathy_account_chooser_dup_account (EmpathyAccountChooser
*chooser
)
332 EmpathyAccountChooserPriv
*priv
;
337 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser
), NULL
);
339 priv
= GET_PRIV (chooser
);
341 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (chooser
));
342 if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (chooser
), &iter
)) {
346 gtk_tree_model_get (model
, &iter
, COL_ACCOUNT_POINTER
, &account
, -1);
352 * empathy_account_chooser_get_connection:
353 * @chooser: an #EmpathyAccountChooser
355 * Returns a borrowed reference to the #TpConnection associated with the
356 * account currently selected. The caller must reference the returned object with
357 * g_object_ref() if it will be kept
359 * Return value: a borrowed reference to the #TpConnection associated with the
360 * account curently selected.
363 empathy_account_chooser_get_connection (EmpathyAccountChooser
*chooser
)
365 EmpathyAccountChooserPriv
*priv
;
367 TpConnection
*connection
;
369 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser
), NULL
);
371 priv
= GET_PRIV (chooser
);
373 account
= empathy_account_chooser_dup_account (chooser
);
375 /* if the returned account is NULL, then the account manager probably
376 * hasn't been prepared yet. It should be safe to return NULL here
378 if (account
== NULL
) {
382 connection
= tp_account_get_connection (account
);
383 g_object_unref (account
);
389 * empathy_account_chooser_set_account:
390 * @chooser: an #EmpathyAccountChooser
391 * @account: a #TpAccount
393 * Sets the currently selected account to @account, if it exists in the list.
395 * Return value: whether the chooser was set to @account.
398 empathy_account_chooser_set_account (EmpathyAccountChooser
*chooser
,
401 EmpathyAccountChooserPriv
*priv
;
402 GtkComboBox
*combobox
;
407 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser
), FALSE
);
409 priv
= GET_PRIV (chooser
);
411 combobox
= GTK_COMBO_BOX (chooser
);
412 model
= gtk_combo_box_get_model (combobox
);
413 gtk_combo_box_get_active_iter (combobox
, &iter
);
415 data
.chooser
= chooser
;
416 data
.account
= account
;
418 gtk_tree_model_foreach (model
,
419 (GtkTreeModelForeachFunc
) account_chooser_set_account_foreach
,
422 priv
->account_manually_set
= data
.set
;
428 * empathy_account_chooser_get_has_all_option:
429 * @chooser: an #EmpathyAccountChooser
431 * Returns whether @chooser has the #EmpathyAccountChooser:has-all-option property
434 * Return value: whether @chooser has the #EmpathyAccountChooser:has-all-option property
438 empathy_account_chooser_get_has_all_option (EmpathyAccountChooser
*chooser
)
440 EmpathyAccountChooserPriv
*priv
;
442 g_return_val_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser
), FALSE
);
444 priv
= GET_PRIV (chooser
);
446 return priv
->has_all_option
;
450 * empathy_account_chooser_set_has_all_option:
451 * @chooser: an #EmpathyAccountChooser
452 * @has_all_option: a new value for the #EmpathyAccountChooser:has-all-option property
454 * Sets the #EmpathyAccountChooser:has-all-option property.
457 empathy_account_chooser_set_has_all_option (EmpathyAccountChooser
*chooser
,
458 gboolean has_all_option
)
460 EmpathyAccountChooserPriv
*priv
;
461 GtkComboBox
*combobox
;
466 g_return_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser
));
468 priv
= GET_PRIV (chooser
);
470 if (priv
->has_all_option
== has_all_option
) {
474 combobox
= GTK_COMBO_BOX (chooser
);
475 model
= gtk_combo_box_get_model (combobox
);
476 store
= GTK_LIST_STORE (model
);
478 priv
->has_all_option
= has_all_option
;
481 * The first 2 options are the ALL and separator
484 if (has_all_option
) {
485 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (chooser
),
486 (GtkTreeViewRowSeparatorFunc
)
487 account_chooser_separator_func
,
491 gtk_list_store_prepend (store
, &iter
);
492 gtk_list_store_set (store
, &iter
,
493 COL_ACCOUNT_TEXT
, NULL
,
494 COL_ACCOUNT_ENABLED
, TRUE
,
495 COL_ACCOUNT_POINTER
, NULL
,
496 COL_ACCOUNT_ROW_TYPE
, ROW_SEPARATOR
,
499 gtk_list_store_prepend (store
, &iter
);
500 gtk_list_store_set (store
, &iter
,
501 COL_ACCOUNT_TEXT
, _("All"),
502 COL_ACCOUNT_ENABLED
, TRUE
,
503 COL_ACCOUNT_POINTER
, NULL
,
504 COL_ACCOUNT_ROW_TYPE
, ROW_ALL
,
507 if (gtk_tree_model_get_iter_first (model
, &iter
)) {
508 if (gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
)) {
509 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
513 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (chooser
),
514 (GtkTreeViewRowSeparatorFunc
)
520 g_object_notify (G_OBJECT (chooser
), "has-all-option");
524 account_manager_prepared_cb (GObject
*source_object
,
525 GAsyncResult
*result
,
529 TpAccountManager
*manager
= TP_ACCOUNT_MANAGER (source_object
);
530 EmpathyAccountChooser
*chooser
= user_data
;
531 EmpathyAccountChooserPriv
*priv
= GET_PRIV (chooser
);
532 GError
*error
= NULL
;
534 if (!tp_account_manager_prepare_finish (manager
, result
, &error
)) {
535 DEBUG ("Failed to prepare account manager: %s", error
->message
);
536 g_error_free (error
);
540 accounts
= tp_account_manager_get_valid_accounts (manager
);
542 for (l
= accounts
; l
!= NULL
; l
= l
->next
) {
543 TpAccount
*account
= l
->data
;
545 account_chooser_account_add_foreach (account
, chooser
);
547 tp_g_signal_connect_object (account
, "status-changed",
548 G_CALLBACK (account_chooser_status_changed_cb
),
552 g_list_free (accounts
);
555 g_signal_emit (chooser
, signals
[READY
], 0);
559 account_cmp (GtkTreeModel
*model
,
564 RowType a_type
, b_type
;
565 gboolean a_enabled
, b_enabled
;
566 gchar
*a_text
, *b_text
;
569 gtk_tree_model_get (model
, a
,
570 COL_ACCOUNT_ENABLED
, &a_enabled
,
571 COL_ACCOUNT_ROW_TYPE
, &a_type
,
573 gtk_tree_model_get (model
, b
,
574 COL_ACCOUNT_ENABLED
, &b_enabled
,
575 COL_ACCOUNT_ROW_TYPE
, &b_type
,
578 /* This assumes that we have at most one of each special row type. */
579 if (a_type
!= b_type
) {
580 /* Display higher-numbered special row types first. */
581 return (b_type
- a_type
);
584 /* Enabled accounts are displayed first */
585 if (a_enabled
!= b_enabled
)
586 return a_enabled
? -1: 1;
588 gtk_tree_model_get (model
, a
, COL_ACCOUNT_TEXT
, &a_text
, -1);
589 gtk_tree_model_get (model
, b
, COL_ACCOUNT_TEXT
, &b_text
, -1);
591 if (a_text
== b_text
)
593 else if (a_text
== NULL
)
595 else if (b_text
== NULL
)
598 result
= g_ascii_strcasecmp (a_text
, b_text
);
607 account_chooser_setup (EmpathyAccountChooser
*chooser
)
609 EmpathyAccountChooserPriv
*priv
;
611 GtkCellRenderer
*renderer
;
612 GtkComboBox
*combobox
;
614 priv
= GET_PRIV (chooser
);
616 /* Set up combo box with new store */
617 combobox
= GTK_COMBO_BOX (chooser
);
619 gtk_cell_layout_clear (GTK_CELL_LAYOUT (combobox
));
621 store
= gtk_list_store_new (COL_ACCOUNT_COUNT
,
622 G_TYPE_STRING
, /* Image */
623 G_TYPE_STRING
, /* Name */
624 G_TYPE_BOOLEAN
, /* Enabled */
625 G_TYPE_UINT
, /* Row type */
628 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store
),
629 account_cmp
, chooser
, NULL
);
630 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store
),
631 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
, GTK_SORT_ASCENDING
);
633 gtk_combo_box_set_model (combobox
, GTK_TREE_MODEL (store
));
635 renderer
= gtk_cell_renderer_pixbuf_new ();
636 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox
), renderer
, FALSE
);
637 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox
), renderer
,
638 "icon-name", COL_ACCOUNT_IMAGE
,
639 "sensitive", COL_ACCOUNT_ENABLED
,
641 g_object_set (renderer
, "stock-size", GTK_ICON_SIZE_BUTTON
, NULL
);
643 renderer
= gtk_cell_renderer_text_new ();
644 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combobox
), renderer
, TRUE
);
645 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox
), renderer
,
646 "text", COL_ACCOUNT_TEXT
,
647 "sensitive", COL_ACCOUNT_ENABLED
,
650 /* Populate accounts */
651 tp_account_manager_prepare_async (priv
->manager
, NULL
,
652 account_manager_prepared_cb
, chooser
);
654 g_object_unref (store
);
658 account_chooser_account_validity_changed_cb (TpAccountManager
*manager
,
661 EmpathyAccountChooser
*chooser
)
664 account_chooser_account_add_foreach (account
, chooser
);
666 account_chooser_account_remove_foreach (account
, chooser
);
671 account_chooser_account_add_foreach (TpAccount
*account
,
672 EmpathyAccountChooser
*chooser
)
675 GtkComboBox
*combobox
;
679 combobox
= GTK_COMBO_BOX (chooser
);
680 store
= GTK_LIST_STORE (gtk_combo_box_get_model (combobox
));
682 position
= gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store
), NULL
);
683 gtk_list_store_insert_with_values (store
, &iter
, position
,
684 COL_ACCOUNT_POINTER
, account
,
686 account_chooser_update_iter (chooser
, &iter
);
690 account_chooser_account_removed_cb (TpAccountManager
*manager
,
692 EmpathyAccountChooser
*chooser
)
694 account_chooser_account_remove_foreach (account
, chooser
);
704 account_chooser_find_account_foreach (GtkTreeModel
*model
,
709 FindAccountData
*data
= user_data
;
712 gtk_tree_model_get (model
, iter
, COL_ACCOUNT_POINTER
, &account
, -1);
714 if (account
== data
->account
) {
716 *(data
->iter
) = *iter
;
717 g_object_unref (account
);
722 g_object_unref (account
);
728 account_chooser_find_account (EmpathyAccountChooser
*chooser
,
733 GtkComboBox
*combobox
;
734 FindAccountData data
;
736 combobox
= GTK_COMBO_BOX (chooser
);
737 store
= GTK_LIST_STORE (gtk_combo_box_get_model (combobox
));
739 data
.account
= account
;
741 gtk_tree_model_foreach (GTK_TREE_MODEL (store
),
742 account_chooser_find_account_foreach
,
749 account_chooser_account_remove_foreach (TpAccount
*account
,
750 EmpathyAccountChooser
*chooser
)
753 GtkComboBox
*combobox
;
756 combobox
= GTK_COMBO_BOX (chooser
);
757 store
= GTK_LIST_STORE (gtk_combo_box_get_model (combobox
));
759 if (account_chooser_find_account (chooser
, account
, &iter
)) {
760 gtk_list_store_remove (store
, &iter
);
765 account_chooser_filter_ready_cb (gboolean is_enabled
,
768 FilterResultCallbackData
*fr_data
= data
;
769 EmpathyAccountChooser
*chooser
;
770 EmpathyAccountChooserPriv
*priv
;
774 GtkComboBox
*combobox
;
775 const gchar
*icon_name
;
777 chooser
= fr_data
->chooser
;
778 priv
= GET_PRIV (chooser
);
779 account
= fr_data
->account
;
780 iter
= fr_data
->iter
;
781 combobox
= GTK_COMBO_BOX (chooser
);
782 store
= GTK_LIST_STORE (gtk_combo_box_get_model (combobox
));
784 icon_name
= tp_account_get_icon_name (account
);
786 gtk_list_store_set (store
, iter
,
787 COL_ACCOUNT_IMAGE
, icon_name
,
788 COL_ACCOUNT_TEXT
, tp_account_get_display_name (account
),
789 COL_ACCOUNT_ENABLED
, is_enabled
,
792 /* set first connected account as active account */
793 if (priv
->account_manually_set
== FALSE
&&
794 priv
->set_active_item
== FALSE
&& is_enabled
) {
795 priv
->set_active_item
= TRUE
;
796 gtk_combo_box_set_active_iter (combobox
, iter
);
799 g_object_unref (account
);
800 filter_result_callback_data_free (fr_data
);
804 account_chooser_update_iter (EmpathyAccountChooser
*chooser
,
807 EmpathyAccountChooserPriv
*priv
;
809 GtkComboBox
*combobox
;
811 FilterResultCallbackData
*data
;
813 priv
= GET_PRIV (chooser
);
815 combobox
= GTK_COMBO_BOX (chooser
);
816 store
= GTK_LIST_STORE (gtk_combo_box_get_model (combobox
));
818 gtk_tree_model_get (GTK_TREE_MODEL (store
), iter
,
819 COL_ACCOUNT_POINTER
, &account
,
822 /* Skip rows without account associated */
826 data
= filter_result_callback_data_new (chooser
, account
, iter
);
829 priv
->filter (account
, account_chooser_filter_ready_cb
,
830 (gpointer
) data
, priv
->filter_data
);
832 account_chooser_filter_ready_cb (TRUE
, (gpointer
) data
);
836 account_chooser_status_changed_cb (TpAccount
*account
,
840 gchar
*dbus_error_name
,
844 EmpathyAccountChooser
*chooser
= user_data
;
847 if (account_chooser_find_account (chooser
, account
, &iter
)) {
848 account_chooser_update_iter (chooser
, &iter
);
853 account_chooser_separator_func (GtkTreeModel
*model
,
855 EmpathyAccountChooser
*chooser
)
859 gtk_tree_model_get (model
, iter
, COL_ACCOUNT_ROW_TYPE
, &row_type
, -1);
860 return (row_type
== ROW_SEPARATOR
);
864 account_chooser_set_account_foreach (GtkTreeModel
*model
,
867 SetAccountData
*data
)
872 gtk_tree_model_get (model
, iter
, COL_ACCOUNT_POINTER
, &account
, -1);
874 equal
= (data
->account
== account
);
877 g_object_unref (account
);
881 GtkComboBox
*combobox
;
883 combobox
= GTK_COMBO_BOX (data
->chooser
);
884 gtk_combo_box_set_active_iter (combobox
, iter
);
893 account_chooser_filter_foreach (GtkTreeModel
*model
,
898 account_chooser_update_iter (chooser
, iter
);
903 * empathy_account_chooser_set_filter:
904 * @chooser: an #EmpathyAccountChooser
906 * @user_data: data to pass to @filter, or %NULL
908 * Sets a filter on the @chooser so only accounts that are %TRUE in the eyes
909 * of the filter are visible in the @chooser.
912 empathy_account_chooser_set_filter (EmpathyAccountChooser
*chooser
,
913 EmpathyAccountChooserFilterFunc filter
,
916 EmpathyAccountChooserPriv
*priv
;
919 g_return_if_fail (EMPATHY_IS_ACCOUNT_CHOOSER (chooser
));
921 priv
= GET_PRIV (chooser
);
923 priv
->filter
= filter
;
924 priv
->filter_data
= user_data
;
926 /* Refilter existing data */
927 priv
->set_active_item
= FALSE
;
928 model
= gtk_combo_box_get_model (GTK_COMBO_BOX (chooser
));
929 gtk_tree_model_foreach (model
, account_chooser_filter_foreach
, chooser
);
933 * EmpathyAccountChooserFilterFunc:
934 * @account: a #TpAccount
935 * @user_data: user data, or %NULL
937 * A function which decides whether the account indicated by @account
940 * Return value: whether the account indicated by @account is visible.
944 * empathy_account_chooser_filter_is_connected:
945 * @account: a #TpAccount
946 * @callback: an #EmpathyAccountChooserFilterResultCallback accepting the result
947 * @callback_data: data passed to the @callback
948 * @user_data: user data or %NULL
950 * A useful #EmpathyAccountChooserFilterFunc that one could pass into
951 * empathy_account_chooser_set_filter() and only show connected accounts.
953 * Returns (via the callback) TRUE is @account is connected
956 empathy_account_chooser_filter_is_connected (
958 EmpathyAccountChooserFilterResultCallback callback
,
959 gpointer callback_data
,
962 gboolean is_connected
=
963 tp_account_get_connection_status (account
, NULL
)
964 == TP_CONNECTION_STATUS_CONNECTED
;
965 callback (is_connected
, callback_data
);
969 EmpathyAccountChooserFilterResultCallback callback
;
971 } FilterCallbackData
;
974 conn_prepared_cb (GObject
*conn
,
975 GAsyncResult
*result
,
978 FilterCallbackData
*data
= user_data
;
979 GError
*myerr
= NULL
;
980 TpCapabilities
*caps
;
982 if (!tp_proxy_prepare_finish (conn
, result
, &myerr
)) {
983 data
->callback (FALSE
, data
->user_data
);
984 g_slice_free (FilterCallbackData
, data
);
988 caps
= tp_connection_get_capabilities (TP_CONNECTION (conn
));
989 data
->callback (tp_capabilities_supports_text_chatrooms (caps
),
992 g_slice_free (FilterCallbackData
, data
);
996 * empathy_account_chooser_filter_supports_multichat:
997 * @account: a #TpAccount
998 * @callback: an #EmpathyAccountChooserFilterResultCallback accepting the result
999 * @callback_data: data passed to the @callback
1000 * @user_data: user data or %NULL
1002 * An #EmpathyAccountChooserFilterFunc that returns accounts that both
1003 * support multiuser text chat and are connected.
1005 * Returns (via the callback) TRUE if @account both supports muc and is connected
1008 empathy_account_chooser_filter_supports_chatrooms (
1010 EmpathyAccountChooserFilterResultCallback callback
,
1011 gpointer callback_data
,
1014 TpConnection
*connection
;
1015 FilterCallbackData
*cb_data
;
1016 GQuark features
[] = { TP_CONNECTION_FEATURE_CAPABILITIES
, 0 };
1018 if (tp_account_get_connection_status (account
, NULL
) !=
1019 TP_CONNECTION_STATUS_CONNECTED
) {
1020 callback (FALSE
, callback_data
);
1024 /* check if CM supports multiuser text chat */
1025 connection
= tp_account_get_connection (account
);
1026 if (connection
== NULL
) {
1027 callback (FALSE
, callback_data
);
1031 cb_data
= g_slice_new0 (FilterCallbackData
);
1032 cb_data
->callback
= callback
;
1033 cb_data
->user_data
= callback_data
;
1035 tp_proxy_prepare_async (connection
, features
, conn_prepared_cb
,
1040 empathy_account_chooser_is_ready (EmpathyAccountChooser
*self
)
1042 EmpathyAccountChooserPriv
*priv
= GET_PRIV (self
);
1048 empathy_account_chooser_get_account (EmpathyAccountChooser
*chooser
)
1052 account
= empathy_account_chooser_dup_account (chooser
);
1053 if (account
== NULL
)
1056 g_object_unref (account
);