# HG changeset patch
# Node ID afe04a2bbe7937e5978575a133e5352b4f24baf3
# Parent  c6caa9bd7afe9bba7fb99cda793ba70fae09e784
diff --git a/libpurple/purpleaccount.c b/libpurple/purpleaccount.c
--- a/libpurple/purpleaccount.c
+++ b/libpurple/purpleaccount.c
@@ -33,6 +33,7 @@
 #include "purpleaddcontactrequest.h"
 #include "purpleconversationmanager.h"
 #include "purplecredentialmanager.h"
+#include "purpleenums.h"
 #include "purplenotification.h"
 #include "purplenotificationconnectionerror.h"
 #include "purplenotificationmanager.h"
@@ -92,6 +93,7 @@
 	PROP_CONTACT_INFO,
 	PROP_REQUIRE_PASSWORD,
 	PROP_ENABLED,
+	PROP_CONNECTION_STATE,
 	PROP_CONNECTION,
 	PROP_PROTOCOL_ID,
 	PROP_USER_INFO,
@@ -116,6 +118,22 @@
  * Helpers
  *****************************************************************************/
 static void
+purple_account_set_connection_state(PurpleAccount *account,
+                                    PurpleConnectionState connection_state)
+{
+	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+
+	if(PURPLE_IS_CONNECTION(account->gc)) {
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+		purple_connection_set_state(account->gc, connection_state);
+		G_GNUC_END_IGNORE_DEPRECATIONS
+
+		g_object_notify_by_pspec(G_OBJECT(account),
+		                         properties[PROP_CONNECTION_STATE]);
+	}
+}
+
+static void
 purple_account_set_id(PurpleAccount *account, const char *id) {
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
 
@@ -176,9 +194,14 @@
 
 	g_return_if_fail(PURPLE_IS_CONNECTION(connection));
 
+	purple_account_set_connection_state(account,
+	                                    PURPLE_CONNECTION_STATE_CONNECTING);
+
 	purple_account_set_connection(account, connection);
 	if(!purple_connection_connect(connection, &error)) {
 		purple_account_set_error(account, error);
+		purple_account_set_connection_state(account,
+		                                    PURPLE_CONNECTION_STATE_DISCONNECTED);
 	}
 
 	/* Finally remove our reference to the connection. */
@@ -645,6 +668,9 @@
 	case PROP_ENABLED:
 		g_value_set_boolean(value, purple_account_get_enabled(account));
 		break;
+	case PROP_CONNECTION_STATE:
+		g_value_set_enum(value, purple_account_get_connection_state(account));
+		break;
 	case PROP_CONNECTION:
 		g_value_set_object(value, purple_account_get_connection(account));
 		break;
@@ -860,6 +886,19 @@
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	/**
+	 * PurpleAccount:connection-state:
+	 *
+	 * The connection state of the account.
+	 *
+	 * Since: 3.0
+	 */
+	properties[PROP_CONNECTION_STATE] = g_param_spec_enum(
+		"connection-state", NULL, NULL,
+		PURPLE_TYPE_CONNECTION_STATE,
+		PURPLE_CONNECTION_STATE_DISCONNECTED,
+		G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+	/**
 	 * PurpleAccount:connection:
 	 *
 	 * The [class@Connection] object for this account. This will be %NULL when
@@ -1014,6 +1053,14 @@
 /******************************************************************************
  * Public API
  *****************************************************************************/
+void
+purple_account_connected(PurpleAccount *account) {
+	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
+
+	purple_account_set_connection_state(account,
+	                                    PURPLE_CONNECTION_STATE_CONNECTED);
+}
+
 PurpleAccount *
 purple_account_new(const char *username, const char *protocol_id) {
 	g_return_val_if_fail(username != NULL, NULL);
@@ -1103,8 +1150,7 @@
 }
 
 void
-purple_account_disconnect(PurpleAccount *account)
-{
+purple_account_disconnect(PurpleAccount *account) {
 	GError *error = NULL;
 
 	g_return_if_fail(PURPLE_IS_ACCOUNT(account));
@@ -1114,7 +1160,8 @@
 	purple_debug_info("account", "Disconnecting account %s (%p)\n",
 	                  account->username, account);
 
-	account->disconnecting = TRUE;
+	purple_account_set_connection_state(account,
+	                                    PURPLE_CONNECTION_STATE_DISCONNECTING);
 
 	if(!purple_connection_disconnect(account->gc, &error)) {
 		g_warning("error while disconnecting account %s (%s): %s",
@@ -1125,8 +1172,8 @@
 	}
 
 	purple_account_set_connection(account, NULL);
-
-	account->disconnecting = FALSE;
+	purple_account_set_connection_state(account,
+	                                    PURPLE_CONNECTION_STATE_DISCONNECTED);
 }
 
 void
@@ -1139,11 +1186,10 @@
 }
 
 gboolean
-purple_account_is_disconnecting(PurpleAccount *account)
-{
+purple_account_is_disconnecting(PurpleAccount *account) {
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), TRUE);
 
-	return account->disconnecting;
+	return (purple_account_get_state(account) == PURPLE_CONNECTION_STATE_DISCONNECTING);
 }
 
 void
@@ -1446,6 +1492,18 @@
 	        _(purple_protocol_get_name(p)) : _("Unknown"));
 }
 
+PurpleConnectionState
+purple_account_get_connection_state(PurpleAccount *account) {
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account),
+	                     PURPLE_CONNECTION_STATE_DISCONNECTED);
+
+	if(PURPLE_IS_CONNECTION(account->gc)) {
+		return purple_connection_get_state(account->gc);
+	}
+
+	return PURPLE_CONNECTION_STATE_DISCONNECTED;
+}
+
 PurpleConnection *
 purple_account_get_connection(PurpleAccount *account) {
 	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
diff --git a/libpurple/purpleaccount.h b/libpurple/purpleaccount.h
--- a/libpurple/purpleaccount.h
+++ b/libpurple/purpleaccount.h
@@ -56,6 +56,20 @@
 G_DECLARE_FINAL_TYPE(PurpleAccount, purple_account, PURPLE, ACCOUNT, GObject)
 
 /**
+ * purple_account_connected:
+ * @account: The instance.
+ *
+ * Sets the connection state of @account to connected.
+ *
+ * > Note: This is intended to be called by protocol plugins when they have
+ * completed their initial connection and are ready for normal user actions.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+void purple_account_connected(PurpleAccount *account);
+
+/**
  * purple_account_new:
  * @username: The username.
  * @protocol_id: The protocol ID.
@@ -108,6 +122,19 @@
 void purple_account_set_username(PurpleAccount *account, const char *username);
 
 /**
+ * purple_account_get_connection_state:
+ * @account: The instance.
+ *
+ * Gets the [enum@ConnectionState] of @account.
+ *
+ * Returns: The connection state.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+PurpleConnectionState purple_account_get_connection_state(PurpleAccount *account);
+
+/**
  * purple_account_get_contact_info:
  * @account: The instance.
  *
diff --git a/libpurple/purpleconnection.c b/libpurple/purpleconnection.c
--- a/libpurple/purpleconnection.c
+++ b/libpurple/purpleconnection.c
@@ -256,7 +256,9 @@
 		priv->protocol = g_value_get_object(value);
 		break;
 	case PROP_STATE:
+		G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 		purple_connection_set_state(connection, g_value_get_enum(value));
+		G_GNUC_END_IGNORE_DEPRECATIONS
 		break;
 	case PROP_ACCOUNT:
 		purple_connection_set_account(connection, g_value_get_object(value));
@@ -310,7 +312,9 @@
 
 	priv->cancellable = g_cancellable_new();
 
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	purple_connection_set_state(connection, PURPLE_CONNECTION_STATE_CONNECTING);
+	G_GNUC_END_IGNORE_DEPRECATIONS
 }
 
 static void
@@ -506,8 +510,10 @@
 	priv = purple_connection_get_instance_private(connection);
 
 	purple_debug_info("connection", "Disconnecting connection %p", connection);
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	purple_connection_set_state(connection,
 	                            PURPLE_CONNECTION_STATE_DISCONNECTING);
+	G_GNUC_END_IGNORE_DEPRECATIONS
 
 	/* Dispatch to the connection's disconnect method. */
 	klass = PURPLE_CONNECTION_GET_CLASS(connection);
@@ -515,8 +521,10 @@
 		ret = klass->disconnect(connection, error);
 	}
 
+	G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 	purple_connection_set_state(connection,
 	                            PURPLE_CONNECTION_STATE_DISCONNECTED);
+	G_GNUC_END_IGNORE_DEPRECATIONS
 
 	purple_account_request_close_with_account(priv->account);
 	purple_request_close_with_handle(connection);
diff --git a/libpurple/purpleconnection.h b/libpurple/purpleconnection.h
--- a/libpurple/purpleconnection.h
+++ b/libpurple/purpleconnection.h
@@ -223,7 +223,7 @@
  *
  * Since: 2.0
  */
-PURPLE_AVAILABLE_IN_ALL
+PURPLE_DEPRECATED_FOR(purple_account_connected)
 void purple_connection_set_state(PurpleConnection *connection, PurpleConnectionState state);
 
 /**
