diff options
author | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2011-04-15 12:20:31 +0800 |
---|---|---|
committer | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2011-05-05 15:05:08 +0800 |
commit | 416da629fa9a0e9293b811d36547b0b189b6e13d (patch) | |
tree | 64e6d29ad921748a9f40bbe20af16db7efdc6e0b | |
parent | 1cc68d03a0339cf5f31fabb308b3f1cd9bdb9272 (diff) | |
download | gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.tar gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.tar.gz gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.tar.bz2 gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.tar.lz gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.tar.xz gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.tar.zst gsoc2013-empathy-416da629fa9a0e9293b811d36547b0b189b6e13d.zip |
Add a menuitem to report the account balance for each account
Adds a menu item for each connection that supports Conn.I.Balance, requests
the current balance and then tracks further updates to the balance.
TODO:
- remove the menu item when the account is disconnected
- implement the activated signal
-rw-r--r-- | src/empathy-main-window.c | 197 | ||||
-rw-r--r-- | src/empathy-main-window.ui | 2 |
2 files changed, 199 insertions, 0 deletions
diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c index 851a424ea..8d031385a 100644 --- a/src/empathy-main-window.c +++ b/src/empathy-main-window.c @@ -145,6 +145,8 @@ struct _EmpathyMainWindowPriv { GtkWidget *edit_context; GtkWidget *edit_context_separator; + GtkActionGroup *balance_action_group; + guint size_timeout_id; /* reffed TpAccount* => visible GtkInfoBar* */ @@ -783,6 +785,196 @@ main_window_update_status (EmpathyMainWindow *window) 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) +{ + DEBUG ("ACTIVATE!"); +} + +static void +main_window_balance_update_balance (GtkAction *action, + GValueArray *balance) +{ + TpAccount *account = g_object_get_data (G_OBJECT (action), "account"); + int amount = 0; + guint scale = G_MAXINT32; + const char *currency = ""; + char *str; + + if (balance != NULL) + tp_value_array_unpack (balance, 3, + &amount, + &scale, + ¤cy); + + if (amount == 0 && + scale == G_MAXINT32 && + tp_str_empty (currency)) { + /* unknown balance */ + str = g_strdup_printf ("%s (--)", + tp_account_get_display_name (account)); + } else { + char *money = empathy_format_currency (amount, scale, currency); + + str = g_strdup_printf ("%s (%s %s)", + tp_account_get_display_name (account), + currency, money); + g_free (money); + } + + gtk_action_set_label (action, str); + g_free (str); +} + +static void +main_window_setup_balance_got_balance (TpProxy *conn, + const GValue *value, + const GError *in_error, + gpointer user_data, + GObject *action) +{ + GValueArray *balance = NULL; + + if (in_error != NULL) { + DEBUG ("Failed to get account balance: %s", + in_error->message); + } else if (!G_VALUE_HOLDS (value, TP_STRUCT_TYPE_CURRENCY_AMOUNT)) { + DEBUG ("Type mismatch"); + } else { + balance = g_value_get_boxed (value); + } + + main_window_balance_update_balance (GTK_ACTION (action), balance); +} + +static void +main_window_balance_changed_cb (TpConnection *conn, + const GValueArray *balance, + gpointer user_data, + GObject *action) +{ + main_window_balance_update_balance (GTK_ACTION (action), + (GValueArray *) balance); +} + +static void +main_window_setup_balance_conn_ready (GObject *conn, + GAsyncResult *result, + gpointer user_data) +{ + EmpathyMainWindow *window = user_data; + EmpathyMainWindowPriv *priv = GET_PRIV (window); + TpAccount *account = g_object_get_data (conn, "account"); + GtkAction *action; + char *name, *ui; + GError *error = NULL; + + if (!tp_proxy_prepare_finish (conn, result, &error)) { + DEBUG ("Failed to prepare connection: %s", error->message); + + g_error_free (error); + return; + } + + if (!tp_proxy_has_interface_by_id (conn, + TP_IFACE_QUARK_CONNECTION_INTERFACE_BALANCE)) { + return; + } + + DEBUG ("Setting up balance for acct: %s", + tp_account_get_display_name (account)); + + if (priv->balance_action_group == NULL) { + /* create the action group */ + 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"), + tp_account_get_icon_name (account)); + + g_object_set_data (G_OBJECT (action), "account", account); + 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); + + /* FIXME: do we want the merge id, can use it to unmerge the UI */ + gtk_ui_manager_add_ui_from_string (priv->ui_manager, ui, -1, + &error); + + g_free (name); + g_free (ui); + + if (error != NULL) { + DEBUG ("Failed to add balance UI for %s: %s", + tp_account_get_display_name (account), + error->message); + g_error_free (error); + return; + } + + /* request the current balance and monitor for any changes */ + tp_cli_dbus_properties_call_get (conn, -1, + TP_IFACE_CONNECTION_INTERFACE_BALANCE, + "AccountBalance", + main_window_setup_balance_got_balance, + window, NULL, G_OBJECT (action)); + + tp_cli_connection_interface_balance_connect_to_balance_changed ( + TP_CONNECTION (conn), main_window_balance_changed_cb, + window, NULL, G_OBJECT (action), NULL); +} + +static void +main_window_setup_balance (EmpathyMainWindow *window, + TpAccount *account) +{ + TpConnection *conn = tp_account_get_connection (account); + + if (conn == NULL) + return; + + /* need to prepare the connection: + * store the account on the connection */ + g_object_set_data (G_OBJECT (conn), "account", account); + tp_proxy_prepare_async (conn, NULL, + main_window_setup_balance_conn_ready, window); +} + static void main_window_connection_changed_cb (TpAccount *account, guint old_status, @@ -804,6 +996,8 @@ main_window_connection_changed_cb (TpAccount *account, if (current == TP_CONNECTION_STATUS_DISCONNECTED) { empathy_sound_manager_play (priv->sound_mgr, GTK_WIDGET (window), EMPATHY_SOUND_ACCOUNT_DISCONNECTED); + + /* FIXME: remove balance */ } if (current == TP_CONNECTION_STATUS_CONNECTED) { @@ -812,6 +1006,7 @@ main_window_connection_changed_cb (TpAccount *account, /* Account connected without error, remove error message if any */ main_window_remove_error (window, account); + main_window_setup_balance (window, account); } } @@ -1677,6 +1872,8 @@ account_manager_prepared_cb (GObject *source_object, window); g_hash_table_insert (priv->status_changed_handlers, account, GUINT_TO_POINTER (handler_id)); + + main_window_setup_balance (window, account); } g_signal_connect (manager, "account-validity-changed", diff --git a/src/empathy-main-window.ui b/src/empathy-main-window.ui index 864be1d28..91b493b56 100644 --- a/src/empathy-main-window.ui +++ b/src/empathy-main-window.ui @@ -265,6 +265,8 @@ <menuitem action="view_show_offline"/> <menuitem action="view_show_protocols"/> <separator/> + <placeholder name="view_balance_placeholder"/> + <separator/> <menuitem action="view_sort_by_name"/> <menuitem action="view_sort_by_status"/> <separator/> |