Mercurial > pidgin
changeset 21366:8858a42ca237
Make PurpleAccount keep track of the last connection error suffered (or not, if
the account is happily connected or is disconnected without error). Add a
signal which fires when the current error changes, and an accessor to get the
current error. The error itself is stored inside a private struct.
author | Will Thompson <will.thompson@collabora.co.uk> |
---|---|
date | Sat, 27 Oct 2007 17:26:17 +0000 |
parents | 3a269007711e |
children | 640551a3e75a |
files | doc/account-signals.dox libpurple/account.c libpurple/account.h |
diffstat | 3 files changed, 113 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/account-signals.dox Sat Oct 27 12:14:15 2007 +0000 +++ b/doc/account-signals.dox Sat Oct 27 17:26:17 2007 +0000 @@ -12,6 +12,7 @@ @signal account-authorization-requested @signal account-authorization-denied @signal account-authorization-granted + @signal account-error-changed @endsignals @see account.h @@ -141,5 +142,17 @@ @since 2.3.0 @endsignaldef + @signaldef account-error-changed + @signalproto +void (*account_error_changed)(PurpleAccount *account, const PurpleAccountCurrentError *current_error); + @endsignalproto + @signaldesc + Emitted when @a account's error changes. + @param account The account whose error has changed. + @param current_error The account's current error, or @c NULL if it has no error. + @see purple_account_get_current_error() + @since 2.3.0 + @endsignaldef + */ // vim: syntax=c.doxygen tw=75 et
--- a/libpurple/account.c Sat Oct 27 12:14:15 2007 +0000 +++ b/libpurple/account.c Sat Oct 27 17:26:17 2007 +0000 @@ -41,6 +41,14 @@ #include "util.h" #include "xmlnode.h" +typedef struct +{ + PurpleAccountCurrentError *current_error; +} PurpleAccountPrivate; + +#define PURPLE_ACCOUNT_GET_PRIVATE(account) \ + ((PurpleAccountPrivate *) (account->priv)) + /* TODO: Should use PurpleValue instead of this? What about "ui"? */ typedef struct { @@ -77,6 +85,8 @@ static GList *handles = NULL; +static void clear_current_error(PurpleAccount *account); + /********************************************************************* * Writing to disk * *********************************************************************/ @@ -827,6 +837,7 @@ purple_account_new(const char *username, const char *protocol_id) { PurpleAccount *account = NULL; + PurpleAccountPrivate *priv = NULL; PurplePlugin *prpl = NULL; PurplePluginProtocolInfo *prpl_info = NULL; PurpleStatusType *status_type; @@ -841,6 +852,8 @@ account = g_new0(PurpleAccount, 1); PURPLE_DBUS_REGISTER_POINTER(account, PurpleAccount); + priv = g_new0(PurpleAccountPrivate, 1); + account->priv = priv; purple_account_set_username(account, username); @@ -881,6 +894,7 @@ void purple_account_destroy(PurpleAccount *account) { + PurpleAccountPrivate *priv = NULL; GList *l; g_return_if_fail(account != NULL); @@ -912,6 +926,10 @@ if(account->system_log) purple_log_free(account->system_log); + priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + g_free(priv->current_error); + g_free(priv); + PURPLE_DBUS_UNREGISTER_POINTER(account); g_free(account); } @@ -2214,6 +2232,53 @@ return prpl_info->offline_message(buddy); } +static void +clear_current_error(PurpleAccount *account) +{ + PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + if (priv->current_error) + { + g_free (priv->current_error); + priv->current_error = NULL; + } + + purple_signal_emit(purple_accounts_get_handle(), "account-error-changed", + account, priv->current_error); +} + +static void +signed_on_cb(PurpleConnection *gc, + gpointer unused) +{ + PurpleAccount *account = purple_connection_get_account(gc); + clear_current_error(account); +} + +static void +connection_error_cb(PurpleConnection *gc, + PurpleConnectionError err, + const gchar *desc, + gpointer unused) +{ + PurpleAccount *account = purple_connection_get_account(gc); + PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + + if (!priv->current_error) + priv->current_error = g_new0(PurpleAccountCurrentError, 1); + priv->current_error->reason = err; + priv->current_error->description = desc; + + purple_signal_emit(purple_accounts_get_handle(), "account-error-changed", + account, priv->current_error); +} + +const PurpleAccountCurrentError * +purple_account_get_current_error(PurpleAccount *account) +{ + PurpleAccountPrivate *priv = PURPLE_ACCOUNT_GET_PRIVATE(account); + return priv->current_error; +} + void purple_accounts_add(PurpleAccount *account) { @@ -2238,6 +2303,7 @@ schedule_accounts_save(); + clear_current_error(account); purple_signal_emit(purple_accounts_get_handle(), "account-removed", account); } @@ -2443,6 +2509,7 @@ purple_accounts_init(void) { void *handle = purple_accounts_get_handle(); + void *conn_handle = purple_connections_get_handle(); purple_signal_register(handle, "account-connecting", purple_marshal_VOID__POINTER, NULL, 1, @@ -2513,6 +2580,15 @@ PURPLE_SUBTYPE_ACCOUNT), purple_value_new(PURPLE_TYPE_STRING)); + purple_signal_register(handle, "account-error-changed", + purple_marshal_VOID__POINTER_POINTER, NULL, 2, + purple_value_new(PURPLE_TYPE_SUBTYPE, + PURPLE_SUBTYPE_ACCOUNT), + purple_value_new(PURPLE_TYPE_POINTER)); + + purple_signal_connect(conn_handle, "signed-on", handle, + PURPLE_CALLBACK(signed_on_cb), NULL); + load_accounts(); } @@ -2520,6 +2596,7 @@ void purple_accounts_uninit(void) { + gpointer handle = purple_accounts_get_handle(); if (save_timer != 0) { purple_timeout_remove(save_timer); @@ -2527,5 +2604,6 @@ sync_accounts(); } - purple_signals_unregister_by_instance(purple_accounts_get_handle()); + purple_signals_disconnect_by_handle(handle); + purple_signals_unregister_by_instance(handle); }
--- a/libpurple/account.h Sat Oct 27 12:14:15 2007 +0000 +++ b/libpurple/account.h Sat Oct 27 17:26:17 2007 +0000 @@ -140,8 +140,19 @@ void *ui_data; /**< The UI can put data here. */ PurpleAccountRegistrationCb registration_cb; void *registration_cb_user_data; + + gpointer priv; /**< Pointer to opaque private data. */ }; +/** The error most recently encountered on an account. */ +typedef struct +{ + /** The type of error. */ + PurpleConnectionError reason; + /** A localised, human-readable description of the error. */ + const char *description; +} PurpleAccountCurrentError; + #ifdef __cplusplus extern "C" { #endif @@ -893,6 +904,16 @@ */ gboolean purple_account_supports_offline_message(PurpleAccount *account, PurpleBuddy *buddy); +/** + * Get the error that caused the account to be disconnected, or @c NULL if the + * account is happily connected or disconnected without an error. + * + * @param account The account whose error should be retrieved. + * @constreturn The type of error and a human-readable description of the + * current error, or @c NULL if there is no current error. + */ +const PurpleAccountCurrentError *purple_account_get_current_error(PurpleAccount *account); + /*@}*/ /**************************************************************************/