+
+ /* Update favourite rooms sensitivity */
+ children = gtk_container_get_children (GTK_CONTAINER (priv->room_menu));
+ for (l = children; l != NULL; l = l->next) {
+ if (g_object_get_data (G_OBJECT (l->data), "is_favorite") != NULL) {
+ gtk_widget_set_sensitive (GTK_WIDGET (l->data), connected);
+ }
+ }
+ g_list_free (children);
+}
+
+static char *
+main_window_account_to_action_name (TpAccount *account)
+{
+ char *r;
+
+ /* action names can't have '/' in them, replace it with '.' */
+ r = g_strdup (tp_account_get_path_suffix (account));
+ r = g_strdelimit (r, "/", '.');
+
+ return r;
+}
+
+static void
+main_window_balance_activate_cb (GtkAction *action,
+ EmpathyMainWindow *window)
+{
+ const char *uri;
+
+ uri = g_object_get_data (G_OBJECT (action), "manage-credit-uri");
+
+ if (!tp_str_empty (uri)) {
+ DEBUG ("Top-up credit URI: %s", uri);
+ empathy_url_show (GTK_WIDGET (window), uri);
+ } else {
+ DEBUG ("unknown protocol for top-up");
+ }
+}
+
+static void
+main_window_balance_update_balance (GtkAction *action,
+ TpConnection *conn)
+{
+ TpAccount *account = tp_connection_get_account (conn);
+ GtkWidget *label;
+ int amount = 0;
+ guint scale = G_MAXINT32;
+ const gchar *currency = "";
+ char *money, *str;
+
+ if (!tp_connection_get_balance (conn, &amount, &scale, ¤cy))
+ return;
+
+ if (amount == 0 &&
+ scale == G_MAXINT32 &&
+ tp_str_empty (currency)) {
+ /* unknown balance */
+ money = g_strdup ("--");
+ } else {
+ char *tmp = empathy_format_currency (amount, scale, currency);
+
+ money = g_strdup_printf ("%s %s", currency, tmp);
+ g_free (tmp);
+ }
+
+ /* Translators: this string will be something like:
+ * Top up My Account ($1.23)..." */
+ str = g_strdup_printf (_("Top up %s (%s)..."),
+ tp_account_get_display_name (account),
+ money);
+
+ gtk_action_set_label (action, str);
+ g_free (str);
+
+ /* update the money label in the roster */
+ label = g_object_get_data (G_OBJECT (action), "money-label");
+
+ gtk_label_set_text (GTK_LABEL (label), money);
+ g_free (money);
+}
+
+static void
+main_window_balance_changed_cb (TpConnection *conn,
+ guint balance,
+ guint scale,
+ const gchar *currency,
+ GtkAction *action)
+{
+ main_window_balance_update_balance (action, conn);
+}
+
+static GtkAction *
+main_window_setup_balance_create_action (EmpathyMainWindow *window,
+ TpAccount *account)
+{
+ EmpathyMainWindowPriv *priv = GET_PRIV (window);
+ GtkAction *action;
+ char *name, *ui;
+ guint merge_id;
+ GError *error = NULL;
+
+ /* create the action group if required */
+ if (priv->balance_action_group == NULL) {
+ priv->balance_action_group =
+ gtk_action_group_new ("balance-action-group");
+
+ gtk_ui_manager_insert_action_group (priv->ui_manager,
+ priv->balance_action_group, -1);
+ }
+
+ /* create the action */
+ name = main_window_account_to_action_name (account);
+ action = gtk_action_new (name,
+ tp_account_get_display_name (account),
+ _("Top up account credit"),
+ NULL);
+ g_object_bind_property (account, "icon-name", action, "icon-name",
+ G_BINDING_SYNC_CREATE);
+
+ g_signal_connect (action, "activate",
+ G_CALLBACK (main_window_balance_activate_cb), window);
+
+ gtk_action_group_add_action (priv->balance_action_group, action);
+ g_object_unref (action);
+
+ ui = g_strdup_printf (
+ "<ui>"
+ " <menubar name='menubar'>"
+ " <menu action='view'>"
+ " <placeholder name='view_balance_placeholder'>"
+ " <menuitem action='%s'/>"
+ " </placeholder>"
+ " </menu>"
+ " </menubar>"
+ "</ui>",
+ name);
+
+ merge_id = gtk_ui_manager_add_ui_from_string (priv->ui_manager,
+ ui, -1, &error);
+ if (error != NULL) {
+ DEBUG ("Failed to add balance UI for %s: %s",
+ tp_account_get_display_name (account),
+ error->message);
+ g_error_free (error);
+ }
+
+ g_object_set_data (G_OBJECT (action),
+ "merge-id", GUINT_TO_POINTER (merge_id));
+
+ g_free (name);
+ g_free (ui);
+
+ return action;
+}
+
+static GtkWidget *
+main_window_setup_balance_create_widget (EmpathyMainWindow *window,
+ GtkAction *action,
+ TpAccount *account)
+{
+ EmpathyMainWindowPriv *priv = GET_PRIV (window);
+ GtkWidget *hbox, *image, *label, *button;
+
+ hbox = gtk_hbox_new (FALSE, 6);
+
+ /* protocol icon */
+ image = gtk_image_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
+ g_object_bind_property (action, "icon-name", image, "icon-name",
+ G_BINDING_SYNC_CREATE);
+
+ /* account name label */
+ label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+ g_object_bind_property (account, "display-name", label, "label",
+ G_BINDING_SYNC_CREATE);
+
+ /* balance label */
+ label = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ g_object_set_data (G_OBJECT (action), "money-label", label);
+
+ /* top up button */
+ button = gtk_button_new_with_label (_("Top Up..."));
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
+ g_signal_connect_swapped (button, "clicked",
+ G_CALLBACK (gtk_action_activate), action);
+
+ gtk_box_pack_start (GTK_BOX (priv->balance_vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show_all (hbox);
+
+ /* tie the lifetime of the widget to the lifetime of the action */
+ g_object_weak_ref (G_OBJECT (action),
+ (GWeakNotify) gtk_widget_destroy, hbox);
+
+ return hbox;
+}
+
+static void
+main_window_setup_balance (EmpathyMainWindow *window,
+ TpAccount *account)
+{
+ EmpathyMainWindowPriv *priv = GET_PRIV (window);
+ TpConnection *conn = tp_account_get_connection (account);
+ GtkAction *action;
+ const gchar *uri;
+
+ if (conn == NULL)
+ return;
+
+ if (!tp_proxy_is_prepared (conn, TP_CONNECTION_FEATURE_BALANCE))
+ return;
+
+ DEBUG ("Setting up balance for acct: %s",
+ tp_account_get_display_name (account));
+
+ /* create the action */
+ action = main_window_setup_balance_create_action (window, account);
+
+ if (action == NULL)
+ return;
+
+ gtk_action_set_visible (priv->view_balance_show_in_roster, TRUE);
+
+ /* create the display widget */
+ main_window_setup_balance_create_widget (window, action, account);
+
+ /* check the current balance and monitor for any changes */
+ uri = tp_connection_get_balance_uri (conn);
+
+ g_object_set_data_full (G_OBJECT (action), "manage-credit-uri",
+ g_strdup (uri), g_free);
+ gtk_action_set_sensitive (GTK_ACTION (action), !tp_str_empty (uri));
+
+ main_window_balance_update_balance (GTK_ACTION (action), conn);
+
+ g_signal_connect (conn, "balance-changed",
+ G_CALLBACK (main_window_balance_changed_cb), action);
+
+}
+
+static void
+main_window_remove_balance_action (EmpathyMainWindow *window,
+ TpAccount *account)
+{
+ EmpathyMainWindowPriv *priv = GET_PRIV (window);
+ GtkAction *action;
+ char *name;
+ GList *a;
+
+ if (priv->balance_action_group == NULL)
+ return;
+
+ name = main_window_account_to_action_name (account);
+
+ action = gtk_action_group_get_action (
+ priv->balance_action_group, name);
+
+ if (action != NULL) {
+ guint merge_id;
+
+ DEBUG ("Removing action");
+
+ merge_id = GPOINTER_TO_UINT (g_object_get_data (
+ G_OBJECT (action),
+ "merge-id"));
+
+ gtk_ui_manager_remove_ui (priv->ui_manager,
+ merge_id);
+ gtk_action_group_remove_action (
+ priv->balance_action_group, action);
+ }
+
+ g_free (name);
+
+ a = gtk_action_group_list_actions (
+ priv->balance_action_group);
+
+ gtk_action_set_visible (
+ priv->view_balance_show_in_roster,
+ g_list_length (a) > 0);
+
+ g_list_free (a);