Sat, 13 Jul 2024 01:13:52 -0500
Mutliple cleanups to Purple.Message
* Reorder a bunch stuff so it is alphabetical
* Added purple_message_new and deprecated the other constructors for it.
* Added a new author-name property and marked the author property as deprecated
for it.
* Added new event and notice properties
* De-dented get_property and set_property
* Turned on warning for deprecated signals and properties in the devenv and
purple unit tests.
* Added purple_message_set_timestamp_now to set the timestamp to utc now
Testing Done:
Cowabunga'd with the turtles.
Sent some messages over dm and channels.
Bugs closed: PIDGIN-17869
Reviewed at https://reviews.imfreedom.org/r/3289/
--- a/libpurple/purplemessage.c Fri Jul 12 19:57:40 2024 -0500 +++ b/libpurple/purplemessage.c Sat Jul 13 01:13:52 2024 -0500 @@ -31,12 +31,14 @@ GObject parent; char *id; - char *author; + char *author_name; char *author_name_color; char *author_alias; char *contents; gboolean action; + gboolean event; + gboolean notice; GDateTime *timestamp; PurpleMessageFlags flags; @@ -51,19 +53,22 @@ enum { PROP_0, - PROP_ID, + PROP_ACTION, PROP_AUTHOR, PROP_AUTHOR_ALIAS, + PROP_AUTHOR_NAME, PROP_AUTHOR_NAME_COLOR, PROP_CONTENTS, - PROP_ACTION, - PROP_TIMESTAMP, - PROP_FLAGS, - PROP_ERROR, PROP_DELIVERED, PROP_DELIVERED_AT, PROP_EDITED, PROP_EDITED_AT, + PROP_ERROR, + PROP_EVENT, + PROP_FLAGS, + PROP_ID, + PROP_NOTICE, + PROP_TIMESTAMP, N_PROPERTIES, }; static GParamSpec *properties[N_PROPERTIES] = {NULL, }; @@ -74,9 +79,14 @@ * Helpers *****************************************************************************/ static void -purple_message_set_author(PurpleMessage *message, const char *author) { - if(g_set_str(&message->author, author)) { - g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_AUTHOR]); +purple_message_set_author_name(PurpleMessage *message, const char *author) { + if(g_set_str(&message->author_name, author)) { + GObject *obj = G_OBJECT(message); + + g_object_freeze_notify(obj); + g_object_notify_by_pspec(obj, properties[PROP_AUTHOR]); + g_object_notify_by_pspec(obj, properties[PROP_AUTHOR_NAME]); + g_object_thaw_notify(obj); } } @@ -90,49 +100,56 @@ PurpleMessage *message = PURPLE_MESSAGE(object); switch(param_id) { - case PROP_ID: - g_value_set_string(value, purple_message_get_id(message)); - break; - case PROP_AUTHOR: - g_value_set_string(value, purple_message_get_author(message)); - break; - case PROP_AUTHOR_ALIAS: - g_value_set_string(value, purple_message_get_author_alias(message)); - break; - case PROP_AUTHOR_NAME_COLOR: - g_value_set_string(value, - purple_message_get_author_name_color(message)); - break; - case PROP_CONTENTS: - g_value_set_string(value, purple_message_get_contents(message)); - break; - case PROP_ACTION: - g_value_set_boolean(value, purple_message_get_action(message)); - break; - case PROP_TIMESTAMP: - g_value_set_boxed(value, purple_message_get_timestamp(message)); - break; - case PROP_FLAGS: - g_value_set_flags(value, purple_message_get_flags(message)); - break; - case PROP_ERROR: - g_value_set_boxed(value, purple_message_get_error(message)); - break; - case PROP_DELIVERED: - g_value_set_boolean(value, purple_message_get_delivered(message)); - break; - case PROP_DELIVERED_AT: - g_value_set_boxed(value, purple_message_get_delivered_at(message)); - break; - case PROP_EDITED: - g_value_set_boolean(value, purple_message_get_edited(message)); - break; - case PROP_EDITED_AT: - g_value_set_boxed(value, purple_message_get_edited_at(message)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; + case PROP_ACTION: + g_value_set_boolean(value, purple_message_get_action(message)); + break; + case PROP_AUTHOR: + case PROP_AUTHOR_NAME: + g_value_set_string(value, purple_message_get_author_name(message)); + break; + case PROP_AUTHOR_ALIAS: + g_value_set_string(value, purple_message_get_author_alias(message)); + break; + case PROP_AUTHOR_NAME_COLOR: + g_value_set_string(value, + purple_message_get_author_name_color(message)); + break; + case PROP_CONTENTS: + g_value_set_string(value, purple_message_get_contents(message)); + break; + case PROP_DELIVERED: + g_value_set_boolean(value, purple_message_get_delivered(message)); + break; + case PROP_DELIVERED_AT: + g_value_set_boxed(value, purple_message_get_delivered_at(message)); + break; + case PROP_EDITED: + g_value_set_boolean(value, purple_message_get_edited(message)); + break; + case PROP_EDITED_AT: + g_value_set_boxed(value, purple_message_get_edited_at(message)); + break; + case PROP_ERROR: + g_value_set_boxed(value, purple_message_get_error(message)); + break; + case PROP_EVENT: + g_value_set_boolean(value, purple_message_get_event(message)); + break; + case PROP_FLAGS: + g_value_set_flags(value, purple_message_get_flags(message)); + break; + case PROP_ID: + g_value_set_string(value, purple_message_get_id(message)); + break; + case PROP_NOTICE: + g_value_set_boolean(value, purple_message_get_notice(message)); + break; + case PROP_TIMESTAMP: + g_value_set_boxed(value, purple_message_get_timestamp(message)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + break; } } @@ -143,49 +160,56 @@ PurpleMessage *message = PURPLE_MESSAGE(object); switch(param_id) { - case PROP_ID: - purple_message_set_id(message, g_value_get_string(value)); - break; - case PROP_AUTHOR: - purple_message_set_author(message, g_value_get_string(value)); - break; - case PROP_AUTHOR_ALIAS: - purple_message_set_author_alias(message, g_value_get_string(value)); - break; - case PROP_AUTHOR_NAME_COLOR: - purple_message_set_author_name_color(message, - g_value_get_string(value)); - break; - case PROP_CONTENTS: - purple_message_set_contents(message, g_value_get_string(value)); - break; - case PROP_ACTION: - purple_message_set_action(message, g_value_get_boolean(value)); - break; - case PROP_TIMESTAMP: - purple_message_set_timestamp(message, g_value_get_boxed(value)); - break; - case PROP_FLAGS: - purple_message_set_flags(message, g_value_get_flags(value)); - break; - case PROP_ERROR: - purple_message_set_error(message, g_value_get_boxed(value)); - break; - case PROP_DELIVERED: - purple_message_set_delivered(message, g_value_get_boolean(value)); - break; - case PROP_DELIVERED_AT: - purple_message_set_delivered_at(message, g_value_get_boxed(value)); - break; - case PROP_EDITED: - purple_message_set_edited(message, g_value_get_boolean(value)); - break; - case PROP_EDITED_AT: - purple_message_set_edited_at(message, g_value_get_boxed(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); - break; + case PROP_ACTION: + purple_message_set_action(message, g_value_get_boolean(value)); + break; + case PROP_AUTHOR: + case PROP_AUTHOR_NAME: + purple_message_set_author_name(message, g_value_get_string(value)); + break; + case PROP_AUTHOR_ALIAS: + purple_message_set_author_alias(message, g_value_get_string(value)); + break; + case PROP_AUTHOR_NAME_COLOR: + purple_message_set_author_name_color(message, + g_value_get_string(value)); + break; + case PROP_CONTENTS: + purple_message_set_contents(message, g_value_get_string(value)); + break; + case PROP_DELIVERED: + purple_message_set_delivered(message, g_value_get_boolean(value)); + break; + case PROP_DELIVERED_AT: + purple_message_set_delivered_at(message, g_value_get_boxed(value)); + break; + case PROP_EDITED: + purple_message_set_edited(message, g_value_get_boolean(value)); + break; + case PROP_EDITED_AT: + purple_message_set_edited_at(message, g_value_get_boxed(value)); + break; + case PROP_ERROR: + purple_message_set_error(message, g_value_get_boxed(value)); + break; + case PROP_EVENT: + purple_message_set_event(message, g_value_get_boolean(value)); + break; + case PROP_FLAGS: + purple_message_set_flags(message, g_value_get_flags(value)); + break; + case PROP_ID: + purple_message_set_id(message, g_value_get_string(value)); + break; + case PROP_NOTICE: + purple_message_set_notice(message, g_value_get_boolean(value)); + break; + case PROP_TIMESTAMP: + purple_message_set_timestamp(message, g_value_get_boxed(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + break; } } @@ -194,7 +218,7 @@ PurpleMessage *message = PURPLE_MESSAGE(obj); g_free(message->id); - g_free(message->author); + g_free(message->author_name); g_free(message->author_name_color); g_free(message->author_alias); g_free(message->contents); @@ -225,71 +249,6 @@ obj_class->finalize = purple_message_finalize; /** - * PurpleMessage:id: - * - * The protocol-specific identifier of the message. - * - * Since: 3.0 - */ - properties[PROP_ID] = g_param_spec_string( - "id", "ID", - "The protocol specific message id", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - /** - * PurpleMessage:author: - * - * The author of the message. - * - * Since: 3.0 - */ - properties[PROP_AUTHOR] = g_param_spec_string( - "author", "Author", - "The username of the person, who sent the message.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - /** - * PurpleMessage:author-name-color: - * - * The hex color for the author's name. - * - * Since: 3.0 - */ - properties[PROP_AUTHOR_NAME_COLOR] = g_param_spec_string( - "author-name-color", "author-name-color", - "The hex color to display the author's name with", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - /** - * PurpleMessage:author-alias: - * - * The alias of the author. - * - * Since: 3.0 - */ - properties[PROP_AUTHOR_ALIAS] = g_param_spec_string( - "author-alias", "Author's alias", - "The alias of the sender", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - /** - * PurpleMessage:contents: - * - * The contents of the message. - * - * Since: 3.0 - */ - properties[PROP_CONTENTS] = g_param_spec_string( - "contents", "Contents", - "The message text", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - /** * PurpleMessage:action: * * Whether or not the message is an action. @@ -302,49 +261,71 @@ * Since: 3.0 */ properties[PROP_ACTION] = g_param_spec_boolean( - "action", "action", - "Whether or not the message is an action.", + "action", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * PurpleMessage:timestamp: + * PurpleMessage:author: * - * The timestamp of the message. + * The author of the message. * - * Since: 3.0 + * Deprecated: 3.0: This going to be repurposed once all uses are removed. */ - properties[PROP_TIMESTAMP] = g_param_spec_boxed( - "timestamp", "timestamp", - "The timestamp of the message", - G_TYPE_DATE_TIME, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + properties[PROP_AUTHOR] = g_param_spec_string( + "author", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED); /** - * PurpleMessage:flags: + * PurpleMessage:author-alias: * - * The #PurpleMessageFlags for the message. + * The alias of the author. * * Since: 3.0 */ - properties[PROP_FLAGS] = g_param_spec_flags( - "flags", "Flags", - "Bitwise set of #PurpleMessageFlags flags", - PURPLE_TYPE_MESSAGE_FLAGS, 0, + properties[PROP_AUTHOR_ALIAS] = g_param_spec_string( + "author-alias", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:author-name: + * + * The name of author of the message. + * + * This is a temporary property that will be used to migrate to so that + * [property@Message:author]'s type can be changed in the near future. + * + * Since: 3.0 + */ + properties[PROP_AUTHOR_NAME] = g_param_spec_string( + "author-name", NULL, NULL, + NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * PurpleMessage:error: + * PurpleMessage:author-name-color: * - * An error that this message encountered. This could be something like a - * failed delivery, or failed redaction, or rate limited, etc. + * The hex color for the author's name. * * Since: 3.0 */ - properties[PROP_ERROR] = g_param_spec_boxed( - "error", "error", - "An error that the message encountered", - G_TYPE_ERROR, + properties[PROP_AUTHOR_NAME_COLOR] = g_param_spec_string( + "author-name-color", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:contents: + * + * The contents of the message. + * + * Since: 3.0 + */ + properties[PROP_CONTENTS] = g_param_spec_string( + "contents", NULL, NULL, + NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** @@ -357,8 +338,7 @@ * Since: 3.0 */ properties[PROP_DELIVERED] = g_param_spec_boolean( - "delivered", "delivered", - "Whether or not the message was delivered.", + "delivered", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -372,8 +352,7 @@ * Since: 3.0 */ properties[PROP_DELIVERED_AT] = g_param_spec_boxed( - "delivered-at", "delivered-at", - "The time that the message was delivered.", + "delivered-at", NULL, NULL, G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -387,8 +366,7 @@ * Since: 3.0 */ properties[PROP_EDITED] = g_param_spec_boolean( - "edited", "edited", - "Whether or not this message has been edited.", + "edited", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -402,8 +380,88 @@ * Since: 3.0 */ properties[PROP_EDITED_AT] = g_param_spec_boxed( - "edited-at", "edited-at", - "The time that the message was last edited.", + "edited-at", NULL, NULL, + G_TYPE_DATE_TIME, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:error: + * + * An error that this message encountered. This could be something like a + * failed delivery, or failed redaction, or rate limited, etc. + * + * Since: 3.0 + */ + properties[PROP_ERROR] = g_param_spec_boxed( + "error", NULL, NULL, + G_TYPE_ERROR, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:event: + * + * Whether or not this message is for an event. + * + * Event messages can include things like a topic changing, a contact + * changing their display name, someone joining or leaving a channel, and + * so on. + * + * Since: 3.0 + */ + properties[PROP_EVENT] = g_param_spec_boolean( + "event", NULL, NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:flags: + * + * The #PurpleMessageFlags for the message. + * + * Since: 3.0 + */ + properties[PROP_FLAGS] = g_param_spec_flags( + "flags", NULL, NULL, + PURPLE_TYPE_MESSAGE_FLAGS, 0, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:id: + * + * The protocol-specific identifier of the message. + * + * Since: 3.0 + */ + properties[PROP_ID] = g_param_spec_string( + "id", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:notice: + * + * Whether or not this message is a notice. + * + * Notice typically means that a message should not be auto replied to, but + * this can vary across protocols. However, user interfaces may just want + * to notice that the message was a notice instead of a normal message. + * + * Since: 3.0 + */ + properties[PROP_NOTICE] = g_param_spec_boolean( + "notice", NULL, NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + /** + * PurpleMessage:timestamp: + * + * The timestamp of the message. + * + * Since: 3.0 + */ + properties[PROP_TIMESTAMP] = g_param_spec_boxed( + "timestamp", NULL, NULL, G_TYPE_DATE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -414,6 +472,25 @@ * Public API *****************************************************************************/ PurpleMessage * +purple_message_new(PurpleContactInfo *author, const char *contents) { + const char *author_name = NULL; + + g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(author), NULL); + g_return_val_if_fail(contents != NULL, NULL); + + author_name = purple_contact_info_get_username(author); + if(author_name == NULL) { + author_name = purple_contact_info_get_id(author); + } + + return g_object_new( + PURPLE_TYPE_MESSAGE, + "author-name", author_name, + "contents", contents, + NULL); +} + +PurpleMessage * purple_message_new_outgoing(const char *author, const char *contents, PurpleMessageFlags flags) { @@ -495,19 +572,21 @@ return message; } -const char * -purple_message_get_id(PurpleMessage *message) { - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); +gboolean +purple_message_get_action(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); - return message->id; + return message->action; } void -purple_message_set_id(PurpleMessage *message, const char *id) { +purple_message_set_action(PurpleMessage *message, gboolean action) { g_return_if_fail(PURPLE_IS_MESSAGE(message)); - if(g_set_str(&message->id, id)) { - g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ID]); + if(action != message->action) { + message->action = action; + + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ACTION]); } } @@ -515,7 +594,14 @@ purple_message_get_author(PurpleMessage *message) { g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - return message->author; + return purple_message_get_author_name(message); +} + +const char * +purple_message_get_author_name(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + + return message->author_name; } void @@ -553,10 +639,11 @@ purple_message_get_author_alias(PurpleMessage *message) { g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - if (message->author_alias == NULL) - return purple_message_get_author(message); + if(message->author_alias != NULL) { + return message->author_alias; + } - return message->author_alias; + return message->author_name; } void @@ -576,158 +663,6 @@ } gboolean -purple_message_is_empty(PurpleMessage *message) { - return (message->contents == NULL || message->contents[0] == '\0'); -} - -void -purple_message_set_timestamp(PurpleMessage *message, GDateTime *timestamp) { - g_return_if_fail(PURPLE_IS_MESSAGE(message)); - - g_clear_pointer(&message->timestamp, g_date_time_unref); - if(timestamp != NULL) { - message->timestamp = g_date_time_ref(timestamp); - } - - g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_TIMESTAMP]); -} - -GDateTime * -purple_message_get_timestamp(PurpleMessage *message) { - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); - - if(message->timestamp == NULL) { - GDateTime *dt = g_date_time_new_now_local(); - purple_message_set_timestamp(message, dt); - g_date_time_unref(dt); - } - - return message->timestamp; -} - -char * -purple_message_format_timestamp(PurpleMessage *message, const char *format) { - GDateTime *dt = NULL; - - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - g_return_val_if_fail(format != NULL, NULL); - - dt = purple_message_get_timestamp(message); - - return g_date_time_format(dt, format); -} - -void -purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags) { - g_return_if_fail(PURPLE_IS_MESSAGE(message)); - - message->flags = flags; - - g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_FLAGS]); -} - -PurpleMessageFlags -purple_message_get_flags(PurpleMessage *message) { - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); - - return message->flags; -} - -void -purple_message_set_error(PurpleMessage *message, GError *error) { - g_return_if_fail(PURPLE_IS_MESSAGE(message)); - - g_clear_error(&message->error); - if(error != NULL) { - message->error = g_error_copy(error); - } - - g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ERROR]); -} - -GError * -purple_message_get_error(PurpleMessage *message) { - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - - return message->error; -} - -gboolean -purple_message_add_attachment(PurpleMessage *message, - PurpleAttachment *attachment) -{ - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); - g_return_val_if_fail(PURPLE_IS_ATTACHMENT(attachment), FALSE); - - return g_hash_table_insert(message->attachments, - purple_attachment_get_hash_key(attachment), - g_object_ref(attachment)); -} - -gboolean -purple_message_remove_attachment(PurpleMessage *message, guint64 id) { - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); - - return g_hash_table_remove(message->attachments, &id); -} - -PurpleAttachment * -purple_message_get_attachment(PurpleMessage *message, guint64 id) { - PurpleAttachment *attachment = NULL; - - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); - - attachment = g_hash_table_lookup(message->attachments, &id); - if(PURPLE_IS_ATTACHMENT(attachment)) { - return g_object_ref(attachment); - } - - return NULL; -} - -void -purple_message_foreach_attachment(PurpleMessage *message, - PurpleAttachmentForeachFunc func, - gpointer data) -{ - GHashTableIter iter; - gpointer value; - - g_return_if_fail(PURPLE_IS_MESSAGE(message)); - g_return_if_fail(func != NULL); - - g_hash_table_iter_init(&iter, message->attachments); - while(g_hash_table_iter_next(&iter, NULL, &value)) { - func(PURPLE_ATTACHMENT(value), data); - } -} - -void -purple_message_clear_attachments(PurpleMessage *message) { - g_return_if_fail(PURPLE_IS_MESSAGE(message)); - - g_hash_table_remove_all(message->attachments); -} - -gboolean -purple_message_get_action(PurpleMessage *message) { - g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); - - return message->action; -} - -void -purple_message_set_action(PurpleMessage *message, gboolean action) { - g_return_if_fail(PURPLE_IS_MESSAGE(message)); - - if(action != message->action) { - message->action = action; - - g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ACTION]); - } -} - -gboolean purple_message_get_delivered(PurpleMessage *message) { g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); @@ -848,3 +783,201 @@ g_object_notify_by_pspec(obj, properties[PROP_EDITED_AT]); g_object_thaw_notify(obj); } + +GError * +purple_message_get_error(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + + return message->error; +} + +void +purple_message_set_error(PurpleMessage *message, GError *error) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + g_clear_error(&message->error); + if(error != NULL) { + message->error = g_error_copy(error); + } + + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ERROR]); +} + +gboolean +purple_message_get_event(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); + + return message->event; +} + +void +purple_message_set_event(PurpleMessage *message, gboolean event) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + if(message->event != event) { + message->event = event; + + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_EVENT]); + } +} + +PurpleMessageFlags +purple_message_get_flags(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); + + return message->flags; +} + +void +purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + message->flags = flags; + + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_FLAGS]); +} + +const char * +purple_message_get_id(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); + + return message->id; +} + +void +purple_message_set_id(PurpleMessage *message, const char *id) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + if(g_set_str(&message->id, id)) { + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ID]); + } +} + +gboolean +purple_message_is_empty(PurpleMessage *message) { + return (message->contents == NULL || message->contents[0] == '\0'); +} + +gboolean +purple_message_get_notice(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); + + return message->notice; +} + +void +purple_message_set_notice(PurpleMessage *message, gboolean notice) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + if(message->notice != notice) { + message->notice = notice; + + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_NOTICE]); + } +} + +GDateTime * +purple_message_get_timestamp(PurpleMessage *message) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), 0); + + if(message->timestamp == NULL) { + GDateTime *dt = g_date_time_new_now_local(); + purple_message_set_timestamp(message, dt); + g_date_time_unref(dt); + } + + return message->timestamp; +} + +void +purple_message_set_timestamp(PurpleMessage *message, GDateTime *timestamp) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + g_clear_pointer(&message->timestamp, g_date_time_unref); + if(timestamp != NULL) { + message->timestamp = g_date_time_ref(timestamp); + } + + g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_TIMESTAMP]); +} + +void +purple_message_set_timestamp_now(PurpleMessage *message) { + GDateTime *dt = NULL; + + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + dt = g_date_time_new_now_utc(); + purple_message_set_timestamp(message, dt); + g_date_time_unref(dt); +} + +char * +purple_message_format_timestamp(PurpleMessage *message, const char *format) { + GDateTime *dt = NULL; + + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + g_return_val_if_fail(format != NULL, NULL); + + dt = purple_message_get_timestamp(message); + + return g_date_time_format(dt, format); +} + +gboolean +purple_message_add_attachment(PurpleMessage *message, + PurpleAttachment *attachment) +{ + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); + g_return_val_if_fail(PURPLE_IS_ATTACHMENT(attachment), FALSE); + + return g_hash_table_insert(message->attachments, + purple_attachment_get_hash_key(attachment), + g_object_ref(attachment)); +} + +gboolean +purple_message_remove_attachment(PurpleMessage *message, guint64 id) { + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), FALSE); + + return g_hash_table_remove(message->attachments, &id); +} + +PurpleAttachment * +purple_message_get_attachment(PurpleMessage *message, guint64 id) { + PurpleAttachment *attachment = NULL; + + g_return_val_if_fail(PURPLE_IS_MESSAGE(message), NULL); + + attachment = g_hash_table_lookup(message->attachments, &id); + if(PURPLE_IS_ATTACHMENT(attachment)) { + return g_object_ref(attachment); + } + + return NULL; +} + +void +purple_message_foreach_attachment(PurpleMessage *message, + PurpleAttachmentForeachFunc func, + gpointer data) +{ + GHashTableIter iter; + gpointer value; + + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + g_return_if_fail(func != NULL); + + g_hash_table_iter_init(&iter, message->attachments); + while(g_hash_table_iter_next(&iter, NULL, &value)) { + func(PURPLE_ATTACHMENT(value), data); + } +} + +void +purple_message_clear_attachments(PurpleMessage *message) { + g_return_if_fail(PURPLE_IS_MESSAGE(message)); + + g_hash_table_remove_all(message->attachments); +} +
--- a/libpurple/purplemessage.h Fri Jul 12 19:57:40 2024 -0500 +++ b/libpurple/purplemessage.h Sat Jul 13 01:13:52 2024 -0500 @@ -30,6 +30,7 @@ #include <glib-object.h> #include "purpleattachment.h" +#include "purplecontactinfo.h" #include "purpleversion.h" G_BEGIN_DECLS @@ -90,6 +91,20 @@ G_DECLARE_FINAL_TYPE(PurpleMessage, purple_message, PURPLE, MESSAGE, GObject) /** + * purple_message_new: + * @author: The author. + * @contents: The contents of the message. + * + * Creates a new message from @author with @contents. + * + * Returns: (transfer full): The new message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +PurpleMessage *purple_message_new(PurpleContactInfo *author, const char *contents); + +/** * purple_message_new_outgoing: * @author: The author. * @contents: The contents. @@ -104,7 +119,7 @@ * * Since: 3.0 */ -PURPLE_AVAILABLE_IN_3_0 +PURPLE_DEPRECATED_FOR(purple_message_new) PurpleMessage *purple_message_new_outgoing(const char *author, const char *contents, PurpleMessageFlags flags); /** @@ -122,7 +137,7 @@ * * Since: 3.0 */ -PURPLE_AVAILABLE_IN_3_0 +PURPLE_DEPRECATED_FOR(purple_message_new) PurpleMessage *purple_message_new_incoming(const char *who, const char *contents, PurpleMessageFlags flags, guint64 timestamp); /** @@ -138,303 +153,10 @@ * * Since: 3.0 */ -PURPLE_AVAILABLE_IN_3_0 +PURPLE_DEPRECATED_FOR(purple_message_new) PurpleMessage *purple_message_new_system(const char *contents, PurpleMessageFlags flags); /** - * purple_message_get_id: - * @message: The message. - * - * Returns the unique identifier of the message. These identifiers are not - * serialized - it's a per-session id. - * - * Returns: the global identifier of @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_message_get_id(PurpleMessage *message); - -/** - * purple_message_set_id: - * @message: The instance. - * @id: (nullable): The new id to set. - * - * Sets the id of @message to @id. - * - * > Note: This should really only be used by protocol plugins to update an id - * of a sent message when the server has assigned the final id to the message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_id(PurpleMessage *message, const char *id); - -/** - * purple_message_get_author: - * @message: The message. - * - * Returns the author of the message, not a local alias. - * - * Returns: the author of @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_message_get_author(PurpleMessage *message); - -/** - * purple_message_set_author_name_color: - * @message: The #PurpleMessage instance. - * @color: The hex color code for the author of @message. - * - * Sets the author's name color of @message to @color. This is the color that - * will be used to display the author's name in a user interface. The user - * interface might not use this exact color, as it might need to adapt for - * contrast or limits on the number of colors. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_author_name_color(PurpleMessage *message, const char *color); - -/** - * purple_message_get_author_name_color: - * @message: The #PurpleMessage instance. - * - * Gets the author's name color for @message. - * - * Returns: (transfer none): The hex color for the author of @message's name. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_message_get_author_name_color(PurpleMessage *message); - -/** - * purple_message_set_author_alias: - * @message: The message. - * @alias: The alias. - * - * Sets the alias of @message's author. You don't normally need to call this. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_author_alias(PurpleMessage *message, const char *alias); - -/** - * purple_message_get_author_alias: - * @message: The message. - * - * Returns the alias of @message author. - * - * Returns: the @message author's alias. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_message_get_author_alias(PurpleMessage *message); - -/** - * purple_message_set_contents: - * @message: The message. - * @cont: The contents. - * - * Sets the contents of the @message. It might be HTML. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_contents(PurpleMessage *message, const char *cont); - -/** - * purple_message_get_contents: - * @message: The message. - * - * Returns the contents of the message. - * - * Returns: the contents of @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_message_get_contents(PurpleMessage *message); - -/** - * purple_message_is_empty: - * @message: The message. - * - * Checks, if the message's body is empty. - * - * Returns: %TRUE, if @message is empty. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -gboolean purple_message_is_empty(PurpleMessage *message); - -/** - * purple_message_set_timestamp: - * @message: The #PurpleMessage instance. - * @timestamp: (nullable): The #GDateTime of the message. - * - * Sets the timestamp of @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_timestamp(PurpleMessage *message, GDateTime *timestamp); - -/** - * purple_message_get_timestamp: - * @message: The message. - * - * Returns a @message's timestamp. If @message does not currently have a - * timestamp, the current time will be set as the time stamp and returned. - * - * Returns: (transfer none): The #GDateTime timestamp from @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GDateTime *purple_message_get_timestamp(PurpleMessage *message); - -/** - * purple_message_format_timestamp: - * @message: The #PurpleMessage instance. - * @format: The format to output the time stamp as. - * - * Formats the timestamp of @message and returns it. - * - * Returns: The formatted timestamp. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -char *purple_message_format_timestamp(PurpleMessage *message, const char *format); - -/** - * purple_message_set_flags: - * @message: The message. - * @flags: The message flags. - * - * Sets flags for @message. It shouldn't be in a conflict with a message type, - * so use it carefully. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags); - -/** - * purple_message_get_flags: - * @message: The message. - * - * Returns the flags of a @message. - * - * Returns: the flags of a @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleMessageFlags purple_message_get_flags(PurpleMessage *message); - -/** - * purple_message_set_error: - * @message: The instance. - * @error: (nullable) (transfer none): The error to set. - * - * Sets the error of @message to @error. Primarily this will be used for - * delivery failure. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_set_error(PurpleMessage *message, GError *error); - -/** - * purple_message_get_error: - * @message: The instance. - * - * Gets the error from @message. - * - * Returns: (nullable) (transfer none): The error from @message or %NULL. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GError *purple_message_get_error(PurpleMessage *message); - -/** - * purple_message_add_attachment: - * @message: The #PurpleMessage instance. - * @attachment: The #PurpleAttachment instance. - * - * Adds @attachment to @message. - * - * Returns: %TRUE if an attachment with the same ID did not already exist. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -gboolean purple_message_add_attachment(PurpleMessage *message, PurpleAttachment *attachment); - -/** - * purple_message_remove_attachment: - * @message: The #PurpleMessage instance. - * @id: The id of the #PurpleAttachment - * - * Removes the #PurpleAttachment identified by @id if it exists. - * - * Returns: %TRUE if the #PurpleAttachment was found and removed, %FALSE - * otherwise. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -gboolean purple_message_remove_attachment(PurpleMessage *message, guint64 id); - -/** - * purple_message_get_attachment: - * @message: The #PurpleMessage instance. - * @id: The id of the #PurpleAttachment to get. - * - * Retrieves the #PurpleAttachment identified by @id from @message. - * - * Returns: (transfer full): The #PurpleAttachment if it was found, otherwise - * %NULL. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleAttachment *purple_message_get_attachment(PurpleMessage *message, guint64 id); - -/** - * purple_message_foreach_attachment: - * @message: The #PurpleMessage instance. - * @func: (scope call): The #PurpleAttachmentForeachFunc to call. - * @data: User data to pass to @func. - * - * Calls @func for each #PurpleAttachment that's attached to @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_foreach_attachment(PurpleMessage *message, PurpleAttachmentForeachFunc func, gpointer data); - -/** - * purple_message_clear_attachments: - * @message: The #PurpleMessage instance. - * - * Removes all attachments from @message. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_message_clear_attachments(PurpleMessage *message); - -/** * purple_message_get_action: * @message: The instance. * @@ -464,6 +186,110 @@ void purple_message_set_action(PurpleMessage *message, gboolean action); /** + * purple_message_get_author: + * @message: The message. + * + * Returns the author of the message, not a local alias. + * + * Returns: the author of @message. + * + * Deprecated: 3.0: this is being repurposed in the future. + */ +PURPLE_DEPRECATED_FOR(purple_message_get_author_name) +const char *purple_message_get_author(PurpleMessage *message); + +/** + * purple_message_get_author_name: + * @message: The message. + * + * Returns the author of the message, not a local alias. + * + * Returns: the author of @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +const char *purple_message_get_author_name(PurpleMessage *message); + +/** + * purple_message_get_author_name_color: + * @message: The #PurpleMessage instance. + * + * Gets the author's name color for @message. + * + * Returns: (transfer none): The hex color for the author of @message's name. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +const char *purple_message_get_author_name_color(PurpleMessage *message); + +/** + * purple_message_set_author_name_color: + * @message: The #PurpleMessage instance. + * @color: The hex color code for the author of @message. + * + * Sets the author's name color of @message to @color. This is the color that + * will be used to display the author's name in a user interface. The user + * interface might not use this exact color, as it might need to adapt for + * contrast or limits on the number of colors. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_author_name_color(PurpleMessage *message, const char *color); + +/** + * purple_message_get_author_alias: + * @message: The message. + * + * Returns the alias of @message author. + * + * Returns: the @message author's alias. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +const char *purple_message_get_author_alias(PurpleMessage *message); + +/** + * purple_message_set_author_alias: + * @message: The message. + * @alias: The alias. + * + * Sets the alias of @message's author. You don't normally need to call this. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_author_alias(PurpleMessage *message, const char *alias); + +/** + * purple_message_get_contents: + * @message: The message. + * + * Returns the contents of the message. + * + * Returns: the contents of @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +const char *purple_message_get_contents(PurpleMessage *message); + +/** + * purple_message_set_contents: + * @message: The message. + * @cont: The contents. + * + * Sets the contents of the @message. It might be HTML. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_contents(PurpleMessage *message, const char *cont); + +/** * purple_message_get_delivered: * @message: The instance. * @@ -558,6 +384,31 @@ void purple_message_set_edited(PurpleMessage *message, gboolean edited); /** + * purple_message_get_event: + * @message: The instance. + * + * Gets whether or not @message is for an event. + * + * Returns: %TRUE if the message is for an event, otherwise %FALSE. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +gboolean purple_message_get_event(PurpleMessage *message); + +/** + * purple_message_set_event: + * @message: The instance. + * @event: The new event state. + * + * Sets whether or not @message is for an event. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_event(PurpleMessage *message, gboolean event); + +/** * purple_message_get_edited_at: * @message: The instance. * @@ -586,6 +437,244 @@ PURPLE_AVAILABLE_IN_3_0 void purple_message_set_edited_at(PurpleMessage *message, GDateTime *datetime); +/** + * purple_message_get_error: + * @message: The instance. + * + * Gets the error from @message. + * + * Returns: (nullable) (transfer none): The error from @message or %NULL. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +GError *purple_message_get_error(PurpleMessage *message); + +/** + * purple_message_set_error: + * @message: The instance. + * @error: (nullable) (transfer none): The error to set. + * + * Sets the error of @message to @error. Primarily this will be used for + * delivery failure. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_error(PurpleMessage *message, GError *error); + +/** + * purple_message_get_flags: + * @message: The message. + * + * Returns the flags of a @message. + * + * Returns: the flags of a @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +PurpleMessageFlags purple_message_get_flags(PurpleMessage *message); + +/** + * purple_message_set_flags: + * @message: The message. + * @flags: The message flags. + * + * Sets flags for @message. It shouldn't be in a conflict with a message type, + * so use it carefully. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_flags(PurpleMessage *message, PurpleMessageFlags flags); + +/** + * purple_message_get_id: + * @message: The message. + * + * Returns the unique identifier of the message. These identifiers are not + * serialized - it's a per-session id. + * + * Returns: the global identifier of @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +const char *purple_message_get_id(PurpleMessage *message); + +/** + * purple_message_set_id: + * @message: The instance. + * @id: (nullable): The new id to set. + * + * Sets the id of @message to @id. + * + * > Note: This should really only be used by protocol plugins to update an id + * of a sent message when the server has assigned the final id to the message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_id(PurpleMessage *message, const char *id); + +/** + * purple_message_is_empty: + * @message: The message. + * + * Checks, if the message's body is empty. + * + * Returns: %TRUE, if @message is empty. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +gboolean purple_message_is_empty(PurpleMessage *message); + +/** + * purple_message_get_notice: + * @message: The instance. + * + * Gets whether or not @message is a notice. + * + * Returns: %TRUE if @message is a notice, otherwise %FALSE. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +gboolean purple_message_get_notice(PurpleMessage *message); + +/** + * purple_message_set_notice: + * @message: The instance. + * @notice: %TRUE if this message is a NOTICE. + * + * Sets whether or not @message is a notice. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_notice(PurpleMessage *message, gboolean notice); + +/** + * purple_message_get_timestamp: + * @message: The message. + * + * Returns a @message's timestamp. If @message does not currently have a + * timestamp, the current time will be set as the time stamp and returned. + * + * Returns: (transfer none): The #GDateTime timestamp from @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +GDateTime *purple_message_get_timestamp(PurpleMessage *message); + +/** + * purple_message_set_timestamp: + * @message: The #PurpleMessage instance. + * @timestamp: (nullable): The #GDateTime of the message. + * + * Sets the timestamp of @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_timestamp(PurpleMessage *message, GDateTime *timestamp); + +/** + * purple_message_set_timestamp_now: + * @message: The instance. + * + * Calls [method@Message.set_timestamp] with the current UTC time. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_set_timestamp_now(PurpleMessage *message); + +/** + * purple_message_format_timestamp: + * @message: The #PurpleMessage instance. + * @format: The format to output the time stamp as. + * + * Formats the timestamp of @message and returns it. + * + * Returns: The formatted timestamp. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +char *purple_message_format_timestamp(PurpleMessage *message, const char *format); + +/** + * purple_message_add_attachment: + * @message: The #PurpleMessage instance. + * @attachment: The #PurpleAttachment instance. + * + * Adds @attachment to @message. + * + * Returns: %TRUE if an attachment with the same ID did not already exist. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +gboolean purple_message_add_attachment(PurpleMessage *message, PurpleAttachment *attachment); + +/** + * purple_message_remove_attachment: + * @message: The #PurpleMessage instance. + * @id: The id of the #PurpleAttachment + * + * Removes the #PurpleAttachment identified by @id if it exists. + * + * Returns: %TRUE if the #PurpleAttachment was found and removed, %FALSE + * otherwise. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +gboolean purple_message_remove_attachment(PurpleMessage *message, guint64 id); + +/** + * purple_message_get_attachment: + * @message: The #PurpleMessage instance. + * @id: The id of the #PurpleAttachment to get. + * + * Retrieves the #PurpleAttachment identified by @id from @message. + * + * Returns: (transfer full): The #PurpleAttachment if it was found, otherwise + * %NULL. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +PurpleAttachment *purple_message_get_attachment(PurpleMessage *message, guint64 id); + +/** + * purple_message_foreach_attachment: + * @message: The #PurpleMessage instance. + * @func: (scope call): The #PurpleAttachmentForeachFunc to call. + * @data: User data to pass to @func. + * + * Calls @func for each #PurpleAttachment that's attached to @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_foreach_attachment(PurpleMessage *message, PurpleAttachmentForeachFunc func, gpointer data); + +/** + * purple_message_clear_attachments: + * @message: The #PurpleMessage instance. + * + * Removes all attachments from @message. + * + * Since: 3.0 + */ +PURPLE_AVAILABLE_IN_3_0 +void purple_message_clear_attachments(PurpleMessage *message); + G_END_DECLS #endif /* PURPLE_MESSAGE_H */
--- a/libpurple/tests/meson.build Fri Jul 12 19:57:40 2024 -0500 +++ b/libpurple/tests/meson.build Sat Jul 13 01:13:52 2024 -0500 @@ -59,6 +59,7 @@ ) testenv.set('XDG_CONFIG_HOME', meson.current_build_dir() / 'config') +testenv.set('G_ENABLE_DIAGNOSTIC', '1') foreach prog : PROGS e = executable(f'test_@prog@', f'test_@prog@.c',
--- a/libpurple/tests/test_message.c Fri Jul 12 19:57:40 2024 -0500 +++ b/libpurple/tests/test_message.c Sat Jul 13 01:13:52 2024 -0500 @@ -54,6 +54,8 @@ gboolean action = FALSE; gboolean delivered = FALSE; gboolean edited = FALSE; + gboolean event = FALSE; + gboolean notice = FALSE; timestamp = g_date_time_new_from_unix_utc(911347200); error = g_error_new(g_quark_from_static_string("test-message"), 0, @@ -65,61 +67,80 @@ */ message = g_object_new( PURPLE_TYPE_MESSAGE, - "id", "id", "action", TRUE, - "author", "author", "author-alias", "alias", + "author-name", "author", "author-name-color", "purple", + "contents", "Now that is a big door", "delivered", TRUE, "edited", TRUE, - "contents", "Now that is a big door", + "error", error, + "event", TRUE, + "flags", PURPLE_MESSAGE_SYSTEM, + "id", "id", + "notice", TRUE, "timestamp", timestamp, - "flags", PURPLE_MESSAGE_SYSTEM, - "error", error, NULL); g_object_get( message, - "id", &id, "action", &action, - "author", &author, "author-alias", &author_alias, + "author-name", &author, "author-name-color", &author_name_color, + "contents", &contents, "delivered", &delivered, "delivered-at", &delivered_at1, "edited", &edited, "edited-at", &edited_at1, - "contents", &contents, + "error", &error1, + "event", &event, + "flags", &flags, + "id", &id, + "notice", ¬ice, "timestamp", ×tamp1, - "flags", &flags, - "error", &error1, NULL); - g_assert_cmpstr(id, ==, "id"); g_assert_true(action); + g_assert_cmpstr(author, ==, "author"); + g_clear_pointer(&author, g_free); + g_assert_cmpstr(author_alias, ==, "alias"); + g_clear_pointer(&author_alias, g_free); + g_assert_cmpstr(author_name_color, ==, "purple"); + g_clear_pointer(&author_name_color, g_free); + + g_assert_cmpstr(contents, ==, "Now that is a big door"); + g_clear_pointer(&contents, g_free); + g_assert_true(delivered); g_assert_nonnull(delivered_at1); + g_clear_pointer(&delivered_at1, g_date_time_unref); + g_assert_true(edited); g_assert_nonnull(edited_at1); - g_assert_cmpstr(contents, ==, "Now that is a big door"); - g_assert_true(g_date_time_equal(timestamp1, timestamp)); + g_clear_pointer(&edited_at1, g_date_time_unref); + + g_assert_error(error1, error->domain, error->code); + g_clear_error(&error); + g_clear_error(&error1); + + g_assert_true(event); + g_assert_cmpint(flags, ==, PURPLE_MESSAGE_SYSTEM); - g_assert_error(error1, error->domain, error->code); + g_assert_cmpstr(id, ==, "id"); g_clear_pointer(&id, g_free); - g_clear_pointer(&author, g_free); - g_clear_pointer(&author_alias, g_free); - g_clear_pointer(&author_name_color, g_free); - g_clear_pointer(&delivered_at1, g_date_time_unref); - g_clear_pointer(&edited_at1, g_date_time_unref); - g_clear_pointer(&contents, g_free); + + g_assert_true(notice); + + g_assert_true(g_date_time_equal(timestamp1, timestamp)); g_clear_pointer(×tamp, g_date_time_unref); g_clear_pointer(×tamp1, g_date_time_unref); - g_clear_error(&error1); - g_clear_object(&message); + + g_assert_finalize_object(message); } static void
--- a/meson.build Fri Jul 12 19:57:40 2024 -0500 +++ b/meson.build Sat Jul 13 01:13:52 2024 -0500 @@ -77,6 +77,10 @@ # For running `meson devenv`. devenv = environment() +# Set G_ENABLE_DIAGNOSTIC so we get warnings about deprecated signals and +# properties. +devenv.set('G_ENABLE_DIAGNOSTIC', '1') + # For man pages. man_conf.set('VERSION', meson.project_version()) man_conf.set('prefix', get_option('prefix'))