# HG changeset patch # User Mark Doliner # Date 1102895872 0 # Node ID 64bc206c7473c7ef9bb7605e2fc37ba99b674c29 # Parent 4d2ecbb139a0d270a771ab3febf145d37f37ecb3 [gaim-migrate @ 11562] Ability to read sub-statuses from ~/.gaim/status.xml. We don't actually WRITE these to the file yet, so this doesn't do anything. Also a few other minor changes elsewhere. committer: Tailor Script diff -r 4d2ecbb139a0 -r 64bc206c7473 src/blist.h --- a/src/blist.h Sun Dec 12 18:20:17 2004 +0000 +++ b/src/blist.h Sun Dec 12 23:57:52 2004 +0000 @@ -718,12 +718,6 @@ /*@{*/ /** - * Force an immediate write of the buddy list. Normally the buddy list is - * saved automatically a few seconds after a change is made. - */ -void gaim_blist_sync(); - -/** * Parses the toc-style buddy list used in older versions of Gaim and for SSI in toc.c * * @param account This is the account that the buddies and groups from config will get added to @@ -738,6 +732,12 @@ void gaim_blist_load(); /** + * Force an immediate write of the buddy list. Normally the buddy list is + * saved automatically a few seconds after a change is made. + */ +void gaim_blist_sync(); + +/** * Requests from the user information needed to add a buddy to the * buddy list. * diff -r 4d2ecbb139a0 -r 64bc206c7473 src/gtkconv.c --- a/src/gtkconv.c Sun Dec 12 18:20:17 2004 +0000 +++ b/src/gtkconv.c Sun Dec 12 23:57:52 2004 +0000 @@ -5029,9 +5029,7 @@ gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf, 0); } else if (flags & GAIM_MESSAGE_RAW) { - g_snprintf(buf, BUF_LONG, "%s", message); - - gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf, 0); + gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, 0); } else { char *new_message = g_memdup(message, length); char *who_escaped = (who ? g_markup_escape_text(who, strlen(who)) : g_strdup("")); diff -r 4d2ecbb139a0 -r 64bc206c7473 src/gtkstatus.c --- a/src/gtkstatus.c Sun Dec 12 18:20:17 2004 +0000 +++ b/src/gtkstatus.c Sun Dec 12 23:57:52 2004 +0000 @@ -432,7 +432,7 @@ saved_status = (GaimStatusSaved *)saved_statuses->data; gtk_list_store_append(dialog->model, &iter); gtk_list_store_set(dialog->model, &iter, 0, - gaim_statuses_saved_get_name(saved_status), -1); + gaim_statuses_saved_get_title(saved_status), -1); } } diff -r 4d2ecbb139a0 -r 64bc206c7473 src/gtkutils.c --- a/src/gtkutils.c Sun Dec 12 18:20:17 2004 +0000 +++ b/src/gtkutils.c Sun Dec 12 23:57:52 2004 +0000 @@ -1507,10 +1507,11 @@ if (gc) prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); + if (prpl_info && prpl_info->options & OPT_PROTO_IM_IMAGE) im = TRUE; - if (prpl_info && prpl_info->send_file) + if (prpl_info && prpl_info->can_receive_file) ft = prpl_info->can_receive_file(gc, who); if (im && ft) diff -r 4d2ecbb139a0 -r 64bc206c7473 src/log.h --- a/src/log.h Sun Dec 12 18:20:17 2004 +0000 +++ b/src/log.h Sun Dec 12 23:57:52 2004 +0000 @@ -38,11 +38,11 @@ typedef enum { GAIM_LOG_IM, GAIM_LOG_CHAT, - GAIM_LOG_SYSTEM, + GAIM_LOG_SYSTEM } GaimLogType; typedef enum { - GAIM_LOG_READ_NO_NEWLINE = 1, + GAIM_LOG_READ_NO_NEWLINE = 1 } GaimLogReadFlags; #include "account.h" diff -r 4d2ecbb139a0 -r 64bc206c7473 src/status.c --- a/src/status.c Sun Dec 12 18:20:17 2004 +0000 +++ b/src/status.c Sun Dec 12 23:57:52 2004 +0000 @@ -135,17 +135,17 @@ */ struct _GaimStatusSaved { - char *name; - GaimStatusType *type; + char *title; + GaimStatusPrimitive type; char *message; - GList *individual; /**< A list of GaimStatusSavedSub's. */ + GList *substatuses; /**< A list of GaimStatusSavedSub's. */ }; struct _GaimStatusSavedSub { GaimAccount *account; - GaimStatusType *type; + const GaimStatusType *type; char *message; }; @@ -169,6 +169,37 @@ #define SCORE_IDLE 5 #define SCORE_IDLE_TIME 6 +/** + * Elements of this array correspond to the GaimStatusPrimitive + * enumeration. + */ +static const char *primitive_names[] = +{ + "unset", + "offline", + "available", + "unavailable", + "hidden", + "away", + "extended_away" +}; + +static GaimStatusPrimitive +gaim_primitive_get_type(const char *name) +{ + int i; + + g_return_val_if_fail(name != NULL, GAIM_STATUS_UNSET); + + for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) + { + if (!strcmp(name, primitive_names[i])) + return i; + } + + return GAIM_STATUS_UNSET; +} + /************************************************************************** * GaimStatusType API **************************************************************************/ @@ -432,6 +463,24 @@ return status_type->attrs; } +const GaimStatusType * +gaim_status_type_find_with_id(GList *status_types, const char *id) +{ + GaimStatusType *status_type; + + g_return_val_if_fail(id != NULL, NULL); + + while (status_types != NULL) + { + status_type = status_types->data; + + if (!strcmp(id, status_type->id)) + return status_type; + } + + return NULL; +} + /************************************************************************** * GaimStatusAttr API @@ -613,12 +662,31 @@ } else if (context == GAIM_PRESENCE_CONTEXT_CONV) { -/* TODO */ #if 0 GaimConversationUiOps *ops; GaimConversation *conv; conv = gaim_status_get_conversation(new_status); +/* + * TODO: Probably need to do some of the following here? This is copied + * from some old status code that was removed. + * + * char *tmp = g_strdup_printf(_("%s logged in."), alias); + * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); + * g_free(tmp); + * + * char *tmp = g_strdup_printf(_("%s logged out."), alias); + * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); + * g_free(tmp); + * + * char *tmp = g_strdup_printf(_("%s signed off"), alias); + * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); + * g_free(tmp); + * + * serv_got_typing_stopped(gc, name); + * + * gaim_conversation_update(c, GAIM_CONV_UPDATE_AWAY); + */ #endif } else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) @@ -630,6 +698,14 @@ notify_buddy_status_update((GaimBuddy *)l->data, presence, old_status, new_status); } + +/* + * TODO: Maybe we should do this here? + * GaimLog *log = gaim_account_get_log(account); + * char *tmp = g_strdup_printf(_("%s signed on"), alias); + * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); + * g_free(tmp); + */ } } @@ -1168,35 +1244,6 @@ gaim_presence_add_status(presence, (GaimStatus *)l->data); } -/* - * TODO: Should we g_return_if_fail(active == status_id->active); ? - * - * TODO: If a buddy signed on or off, should we do any of the following? - * (Note: We definitely need to do some of this somewhere, I'm just - * not sure if here is the correct place.) - * - * char *tmp = g_strdup_printf(_("%s logged in."), alias); - * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); - * g_free(tmp); - * - * GaimLog *log = gaim_account_get_log(account); - * char *tmp = g_strdup_printf(_("%s signed on"), alias); - * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); - * g_free(tmp); - * - * char *tmp = g_strdup_printf(_("%s logged out."), alias); - * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); - * g_free(tmp); - * - * char *tmp = g_strdup_printf(_("%s signed off"), alias); - * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); - * g_free(tmp); - * - * serv_got_typing_stopped(gc, name); - * - * gaim_conversation_update(c, GAIM_CONV_UPDATE_AWAY); - * - */ void gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, gboolean active) @@ -1209,6 +1256,8 @@ status = gaim_presence_get_status(presence, status_id); g_return_if_fail(status != NULL); + /* TODO: Should we do the following? */ + /* g_return_if_fail(active == status->active); */ if (gaim_status_is_exclusive(status)) { @@ -1656,7 +1705,7 @@ } GaimStatusSaved * -gaim_statuses_find_saved(const char *name) +gaim_statuses_find_saved(const char *title) { GList *l; GaimStatusSaved *status; @@ -1664,7 +1713,7 @@ for (l = saved_statuses; l != NULL; l = g_list_next(l)) { status = (GaimStatusSaved *)l->data; - if (!strcmp(status->name, name)) + if (!strcmp(status->title, title)) return status; } @@ -1672,12 +1721,12 @@ } const char * -gaim_statuses_saved_get_name(const GaimStatusSaved *saved_status) +gaim_statuses_saved_get_title(const GaimStatusSaved *saved_status) { - return saved_status->name; + return saved_status->title; } -const GaimStatusType * +GaimStatusPrimitive gaim_statuses_saved_get_type(const GaimStatusSaved *saved_status) { return saved_status->type; @@ -1751,10 +1800,49 @@ } } -void -gaim_statuses_sync(void) +static GaimStatusSavedSub * +gaim_statuses_read_parse_substatus(xmlnode *substatus) { - /* TODO: Write me, baby. */ + GaimStatusSavedSub *ret; + xmlnode *node; + const char *tmp; + + ret = g_new0(GaimStatusSavedSub, 1); + + /* Read the account */ + node = xmlnode_get_child(substatus, "account"); + if (node != NULL) + { + const char *acct_name; + const char *protocol; + acct_name = xmlnode_get_data(node); + protocol = xmlnode_get_attrib(node, "protocol"); + if ((acct_name != NULL) && (protocol != NULL)) + ret->account = gaim_accounts_find(acct_name, protocol); + } + + if (ret->account == NULL) + { + g_free(ret); + return NULL; + } + + /* Read the state */ + node = xmlnode_get_child(substatus, "state"); + if (node != NULL) + tmp = xmlnode_get_data(node); + if (tmp != NULL) + ret->type = gaim_status_type_find_with_id(ret->account->status_types, + tmp); + + /* Read the message */ + node = xmlnode_get_child(substatus, "message"); + if (node != NULL) + tmp = xmlnode_get_data(node); + if (tmp != NULL) + ret->message = g_strdup(tmp); + + return ret; } /** @@ -1767,58 +1855,76 @@ * And it's chill to hear them talk * And I can always make them smile * From White Castle to the Nile + * + * markdoliner + * available + * The ladies man is here to answer your queries. + * + * + * giantgraypanda + * away + * A.C. ain't in charge no more. + * * * * I know. Moving, huh? */ -static void +static GaimStatusSaved * gaim_statuses_read_parse_status(xmlnode *status) { + GaimStatusSaved *ret; xmlnode *node; - const char *name, *state, *message; - GaimStatusSaved *new; + const char *tmp; int i; - name = xmlnode_get_attrib(status, "name"); - if (name == NULL) - name = "No Title"; - - node = xmlnode_get_child(status, "state"); - if (node != NULL) { - state = xmlnode_get_data(node); - } - - node = xmlnode_get_child(status, "message"); - if (node != NULL) { - message = xmlnode_get_data(node); - } + ret = g_new0(GaimStatusSaved, 1); - /* TODO: Need to read in substatuses here */ - - new = g_new0(GaimStatusSaved, 1); - - new->name = g_strdup(name); - /* TODO: Need to set type based on "state" */ - new->type = NULL; - if (message != NULL) - new->message = g_strdup(message); - + /* Read the title */ + tmp = xmlnode_get_attrib(status, "name"); + if (tmp == NULL) + tmp = "No Title"; /* Ensure the title is unique */ + ret->title = g_strdup(tmp); i = 2; - while (gaim_statuses_find_saved(new->name) != NULL) { - g_free(new->name); - new->name = g_strdup_printf("%s %d", name, i); + while (gaim_statuses_find_saved(ret->title) != NULL) + { + g_free(ret->title); + ret->title = g_strdup_printf("%s %d", tmp, i); i++; } - saved_statuses = g_list_append(saved_statuses, new); + /* Read the primitive status type */ + node = xmlnode_get_child(status, "state"); + if (node != NULL) + tmp = xmlnode_get_data(node); + if (tmp != NULL) + ret->type = gaim_primitive_get_type(tmp); + + /* Read the message */ + node = xmlnode_get_child(status, "message"); + if (node != NULL) + tmp = xmlnode_get_data(node); + if (tmp != NULL) + ret->message = g_strdup(tmp); + + /* Read substatuses */ + for (node = xmlnode_get_child(status, "status"); node != NULL; + node = xmlnode_get_next_twin(node)) + { + GaimStatusSavedSub *new; + new = gaim_statuses_read_parse_substatus(node); + if (new != NULL) + ret->substatuses = g_list_append(ret->substatuses, new); + } + + return ret; } /** * @return TRUE on success, FALSE on failure (if the file can not * be opened, or if it contains invalid XML). */ -gboolean +static gboolean gaim_statuses_read(const char *filename) { GError *error; @@ -1828,7 +1934,8 @@ gaim_debug_info("status", "Reading %s\n", filename); - if (!g_file_get_contents(filename, &contents, &length, &error)) { + if (!g_file_get_contents(filename, &contents, &length, &error)) + { gaim_debug_error("status", "Error reading statuses: %s\n", error->message); g_error_free(error); @@ -1837,16 +1944,20 @@ statuses = xmlnode_from_str(contents, length); - if (statuses == NULL) { + if (statuses == NULL) + { FILE *backup; gchar *name; gaim_debug_error("status", "Error parsing statuses\n"); name = g_strdup_printf("%s~", filename); - if ((backup = fopen(name, "w"))) { + if ((backup = fopen(name, "w"))) + { fwrite(contents, length, 1, backup); fclose(backup); chmod(name, S_IRUSR | S_IWUSR); - } else { + } + else + { gaim_debug_error("status", "Unable to write backup %s\n", name); } g_free(name); @@ -1857,8 +1968,11 @@ g_free(contents); for (status = xmlnode_get_child(statuses, "status"); status != NULL; - status = xmlnode_get_next_twin(status)) { - gaim_statuses_read_parse_status(status); + status = xmlnode_get_next_twin(status)) + { + GaimStatusSaved *new; + new = gaim_statuses_read_parse_status(status); + saved_statuses = g_list_append(saved_statuses, new); } gaim_debug_info("status", "Finished reading statuses\n"); @@ -1880,8 +1994,10 @@ filename = g_build_filename(user_dir, "status.xml", NULL); - if (g_file_test(filename, G_FILE_TEST_EXISTS)) { - if (!gaim_statuses_read(filename)) { + if (g_file_test(filename, G_FILE_TEST_EXISTS)) + { + if (!gaim_statuses_read(filename)) + { msg = g_strdup_printf(_("An error was encountered parsing the " "file containing your saved statuses (%s). They " "have not been loaded, and the old file has been " @@ -1893,3 +2009,9 @@ g_free(filename); } + +void +gaim_statuses_sync(void) +{ + /* TODO: Write me, baby. */ +} diff -r 4d2ecbb139a0 -r 64bc206c7473 src/status.h --- a/src/status.h Sun Dec 12 18:20:17 2004 +0000 +++ b/src/status.h Sun Dec 12 23:57:52 2004 +0000 @@ -58,7 +58,8 @@ GAIM_STATUS_UNAVAILABLE, GAIM_STATUS_HIDDEN, GAIM_STATUS_AWAY, - GAIM_STATUS_EXTENDED_AWAY + GAIM_STATUS_EXTENDED_AWAY, + GAIM_STATUS_NUM_PRIMITIVES } GaimStatusPrimitive; @@ -296,6 +297,18 @@ */ const GList *gaim_status_type_get_attrs(const GaimStatusType *status_type); +/** + * Find the GaimStatusType with the given id. + * + * @param status_types A list of status types. Often account->status_types. + * @param id The unique ID of the status type you wish to find. + * + * @return The status type with the given ID, or NULL if one could + * not be found. + */ +const GaimStatusType *gaim_status_type_find_with_id(GList *status_types, + const char *id); + /*@}*/ /**************************************************************************/ @@ -896,11 +909,20 @@ /** * Finds a saved status with the specified title. * - * @param name The name of the saved status. + * @param title The name of the saved status. * * @return The saved status if found, or NULL. */ -GaimStatusSaved *gaim_statuses_find_saved(const char *name); +GaimStatusSaved *gaim_statuses_find_saved(const char *title); + +/** + * Return the name of a given saved status. + * + * @param saved_status The saved status. + * + * @return The title. + */ +const char *gaim_statuses_saved_get_title(const GaimStatusSaved *saved_status); /** * Return the name of a given saved status. @@ -909,16 +931,7 @@ * * @return The name. */ -const char *gaim_statuses_saved_get_name(const GaimStatusSaved *saved_status); - -/** - * Return the name of a given saved status. - * - * @param saved_status The saved status. - * - * @return The name. - */ -const GaimStatusType *gaim_statuses_saved_get_type(const GaimStatusSaved *saved_status); +GaimStatusPrimitive gaim_statuses_saved_get_type(const GaimStatusSaved *saved_status); /** * Return the name of a given saved status. @@ -947,15 +960,15 @@ void gaim_statuses_uninit(void); /** + * Syncs status information from a file. + */ +void gaim_statuses_load(void); + +/** * Syncs status information to the file. */ void gaim_statuses_sync(void); -/** - * Syncs status information from a file. - */ -void gaim_statuses_load(void); - /*@}*/ #endif /* _GAIM_STATUS_H_ */