changeset 12056:6dc48f991b8d

[gaim-migrate @ 14351] Part of sf patch #1354886, from Sadrul Habib Chowdhury "Allow custom-saved statuses" I'm still working on the UI parts committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sat, 12 Nov 2005 22:33:41 +0000
parents 0747647faca1
children 68c18dd8a316
files src/savedstatuses.c src/savedstatuses.h
diffstat 2 files changed, 213 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/savedstatuses.c	Sat Nov 12 20:19:39 2005 +0000
+++ b/src/savedstatuses.c	Sat Nov 12 22:33:41 2005 +0000
@@ -31,6 +31,10 @@
 #include "util.h"
 #include "xmlnode.h"
 
+/*
+ * TODO: Need to allow transient statuses to have empty titles.
+ */
+
 /**
  * The information of a snap-shot of the statuses of all
  * your accounts.  Basically these are your saved away messages.
@@ -41,8 +45,6 @@
  * The changes to status.xml caused by the new status API
  * are fully backward compatible.  The new status API just
  * adds the optional sub-statuses to the XML file.
- *
- * TODO: This should probably just use a GaimStatus...
  */
 struct _GaimSavedStatus
 {
@@ -344,13 +346,13 @@
 	}
 
 	/* Read substatuses */
-	for (node = xmlnode_get_child(status, "status"); node != NULL;
+	for (node = xmlnode_get_child(status, "substatus"); node != NULL;
 			node = xmlnode_get_next_twin(node))
 	{
 		GaimSavedStatusSub *new;
 		new = parse_substatus(node);
 		if (new != NULL)
-			ret->substatuses = g_list_append(ret->substatuses, new);
+			ret->substatuses = g_list_prepend(ret->substatuses, new);
 	}
 
 	return ret;
@@ -379,7 +381,7 @@
 	{
 		GaimSavedStatus *new;
 		new = parse_status(status);
-		saved_statuses = g_list_append(saved_statuses, new);
+		saved_statuses = g_list_prepend(saved_statuses, new);
 	}
 
 	xmlnode_free(statuses);
@@ -394,13 +396,14 @@
 {
 	GaimSavedStatus *status;
 
+	/* Make sure we don't already have a saved status with this title. */
 	g_return_val_if_fail(gaim_savedstatus_find(title) == NULL, NULL);
 
 	status = g_new0(GaimSavedStatus, 1);
 	status->title = g_strdup(title);
 	status->type = type;
 
-	saved_statuses = g_list_append(saved_statuses, status);
+	saved_statuses = g_list_prepend(saved_statuses, status);
 
 	schedule_save();
 
@@ -408,6 +411,20 @@
 }
 
 void
+gaim_savedstatus_set_title(GaimSavedStatus *status, const char *title)
+{
+	g_return_if_fail(status != NULL);
+
+	/* Make sure we don't already have a saved status with this title. */
+	g_return_if_fail(gaim_savedstatus_find(title) == NULL);
+
+	g_free(status->title);
+	status->title = g_strdup(title);
+
+	schedule_save();
+}
+
+void
 gaim_savedstatus_set_type(GaimSavedStatus *status, GaimStatusPrimitive type)
 {
 	g_return_if_fail(status != NULL);
@@ -428,6 +445,57 @@
 	schedule_save();
 }
 
+void
+gaim_savedstatus_set_substatus_for_account(GaimSavedStatus *saved_status,
+										   const GaimAccount *account,
+										   const GaimStatusType *type,
+										   const char *message)
+{
+	GaimSavedStatusSub *substatus;
+
+	g_return_if_fail(saved_status != NULL);
+	g_return_if_fail(account      != NULL);
+	g_return_if_fail(type         != NULL);
+
+	/* Find an existing substatus or create a new one */
+	substatus = gaim_savedstatus_get_substatus_for_account(saved_status, account);
+	if (substatus == NULL)
+	{
+		substatus = g_new0(GaimSavedStatusSub, 1);
+		substatus->account = (GaimAccount *)account;
+		saved_status->substatuses = g_list_prepend(saved_status->substatuses, substatus);
+	}
+
+	substatus->type = type;
+	g_free(substatus->message);
+	substatus->message = g_strdup(message);
+
+	schedule_save();
+}
+
+void
+gaim_savedstatus_unset_substatus_for_account(GaimSavedStatus *saved_status,
+											 const GaimAccount *account)
+{
+	GList *iter;
+	GaimSavedStatusSub *substatus;
+
+	g_return_if_fail(saved_status != NULL);
+	g_return_if_fail(account      != NULL);
+
+	for (iter = saved_status->substatuses; iter != NULL; iter = iter->next)
+	{
+		substatus = iter->data;
+		if (substatus->account == account)
+		{
+			saved_status->substatuses = g_list_delete_link(saved_status->substatuses, iter);
+			g_free(substatus->message);
+			g_free(substatus);
+			return;
+		}
+	}
+}
+
 gboolean
 gaim_savedstatus_delete(const char *title)
 {
@@ -455,14 +523,14 @@
 GaimSavedStatus *
 gaim_savedstatus_find(const char *title)
 {
-	GList *l;
+	GList *iter;
 	GaimSavedStatus *status;
 
 	g_return_val_if_fail(title != NULL, NULL);
 
-	for (l = saved_statuses; l != NULL; l = g_list_next(l))
+	for (iter = saved_statuses; iter != NULL; iter = iter->next)
 	{
-		status = (GaimSavedStatus *)l->data;
+		status = (GaimSavedStatus *)iter->data;
 		if (!strcmp(status->title, title))
 			return status;
 	}
@@ -500,6 +568,42 @@
 	return (saved_status->substatuses != NULL);
 }
 
+GaimSavedStatusSub *
+gaim_savedstatus_get_substatus_for_account(const GaimSavedStatus *saved_status,
+										   const GaimAccount *account)
+{
+	GList *iter;
+	GaimSavedStatusSub *substatus;
+
+	g_return_val_if_fail(saved_status != NULL, NULL);
+	g_return_val_if_fail(account      != NULL, NULL);
+
+	for (iter = saved_status->substatuses; iter != NULL; iter = iter->next)
+	{
+		substatus = iter->data;
+		if (substatus->account == account)
+			return substatus;
+	}
+
+	return NULL;
+}
+
+const GaimStatusType *
+gaim_savedstatus_substatus_get_type(const GaimSavedStatusSub *substatus)
+{
+	g_return_val_if_fail(substatus != NULL, NULL);
+
+	return substatus->type;
+}
+
+const char *
+gaim_savedstatus_substatus_get_message(const GaimSavedStatusSub *substatus)
+{
+	g_return_val_if_fail(substatus != NULL, NULL);
+
+	return substatus->message;
+}
+
 void
 gaim_savedstatus_activate(const GaimSavedStatus *saved_status)
 {
@@ -527,26 +631,37 @@
 gaim_savedstatus_activate_for_account(const GaimSavedStatus *saved_status,
 									  GaimAccount *account)
 {
-	GaimStatusType *status_type;
+	const GaimStatusType *status_type;
+	const GaimSavedStatusSub *substatus;
+	const char *message = NULL;
 
 	g_return_if_fail(saved_status != NULL);
 	g_return_if_fail(account != NULL);
 
-	status_type = gaim_account_get_status_type_with_primitive(account, saved_status->type);
-
-	if (status_type != NULL)
+	substatus = gaim_savedstatus_get_substatus_for_account(saved_status, account);
+	if (substatus != NULL)
+	{
+		status_type = substatus->type;
+		message = substatus->message;
+	}
+	else
 	{
-		if ((saved_status->message != NULL) &&
-			(gaim_status_type_get_attr(status_type, "message")))
-		{
-			gaim_account_set_status(account, gaim_status_type_get_id(status_type),
-									TRUE, "message", saved_status->message, NULL);
-		}
-		else
-		{
-			gaim_account_set_status(account, gaim_status_type_get_id(status_type),
-									TRUE, NULL);
-		}
+		status_type = gaim_account_get_status_type_with_primitive(account, saved_status->type);
+		if (status_type == NULL)
+			return;
+		message = saved_status->message;
+	}
+
+	if ((message != NULL) &&
+		(gaim_status_type_get_attr(status_type, "message")))
+	{
+		gaim_account_set_status(account, gaim_status_type_get_id(status_type),
+								TRUE, "message", message, NULL);
+	}
+	else
+	{
+		gaim_account_set_status(account, gaim_status_type_get_id(status_type),
+								TRUE, NULL);
 	}
 }
 
@@ -590,8 +705,9 @@
 	}
 
 	while (saved_statuses != NULL) {
-		GaimSavedStatus *status = saved_statuses->data;
-		saved_statuses = g_list_remove(saved_statuses, status);
-		free_statussaved(status);
+		GaimSavedStatus *saved_status = saved_statuses->data;
+		saved_statuses = g_list_remove(saved_statuses, saved_status);
+		free_statussaved(saved_status);
 	}
 }
+
--- a/src/savedstatuses.h	Sat Nov 12 20:19:39 2005 +0000
+++ b/src/savedstatuses.h	Sat Nov 12 22:33:41 2005 +0000
@@ -63,6 +63,15 @@
 									  GaimStatusPrimitive type);
 
 /**
+ * Set the title for the given saved status.
+ *
+ * @param status  The saved status.
+ * @param title   The title of the saved status.
+ */
+void gaim_savedstatus_set_title(GaimSavedStatus *status,
+								const char *title);
+
+/**
  * Set the type for the given saved status.
  *
  * @param status  The saved status.
@@ -82,6 +91,32 @@
 								  const char *message);
 
 /**
+ * Set a substatus for an account in a saved status.
+ *
+ * @param status	The saved status.
+ * @param account	The account.
+ * @param type		The status type for the account in the staved
+ *                  status.
+ * @param message	The message for the account in the substatus.
+ */
+void gaim_savedstatus_set_substatus_for_account(GaimSavedStatus *status,
+												const GaimAccount *account,
+												const GaimStatusType *type,
+												const char *message);
+
+/**
+ * Unset a substatus for an account in a saved status.  This clears
+ * the previosly set substatus for the GaimSavedStatus.  If this
+ * saved status is activated then this account will use the default
+ * status type and message.
+ *
+ * @param status	The saved status.
+ * @param account	The account.
+*/
+void gaim_savedstatus_unset_substatus_for_account(GaimSavedStatus *saved_status,
+												  const GaimAccount *account);
+
+/**
  * Delete a saved status.  This removes the saved status from the list
  * of saved statuses, and writes the revised list to status.xml.
  *
@@ -138,7 +173,7 @@
 const char *gaim_savedstatus_get_title(const GaimSavedStatus *saved_status);
 
 /**
- * Return the name of a given saved status.
+ * Return the type of a given saved status.
  *
  * @param saved_status The saved status.
  *
@@ -147,7 +182,7 @@
 GaimStatusPrimitive gaim_savedstatus_get_type(const GaimSavedStatus *saved_status);
 
 /**
- * Return the name of a given saved status.
+ * Return the default message of a given saved status.
  *
  * @param saved_status The saved status.
  *
@@ -168,6 +203,39 @@
 gboolean gaim_savedstatus_has_substatuses(const GaimSavedStatus *saved_status);
 
 /**
+ * Get the substatus for an account in a saved status.
+ *
+ * @param status  The saved status.
+ * @param account The account.
+ *
+ * @return The GaimSavedStatusSub for the account, or NULL if
+ *         the given account does not have a substatus that
+ *         differs from the default status of this GaimSavedStatus.
+ */
+GaimSavedStatusSub *gaim_savedstatus_get_substatus_for_account(
+									const GaimSavedStatus *saved_status,
+									const GaimAccount *account);
+
+/**
+ * Get the status type of a given substatus.
+ *
+ * @param substatus The substatus.
+ *
+ * @return The status type.
+ */
+const GaimStatusType *gaim_savedstatus_substatus_get_type(const GaimSavedStatusSub *substatus);
+
+/**
+ * Get the message of a given substatus.
+ *
+ * @param substatus The substatus.
+ *
+ * @return The message of the substatus, or NULL if this substatus does
+ *         not have a message.
+ */
+const char *gaim_savedstatus_substatus_get_message(const GaimSavedStatusSub *substatus);
+
+/**
  * Sets the statuses for all your accounts to those specified
  * by the given saved_status.  This function calls
  * gaim_savedstatus_activate_for_account() for all your accounts.