Fri, 04 Oct 2024 01:09:26 -0500
Remove the Purple.Signals API
This was a long time coming but we've finally replaced it all!
Testing Done:
Connected a demo and irc accounts without issues. Also called in the turtles.
Reviewed at https://reviews.imfreedom.org/r/3568/
/* * Purple - Internet Messaging Library * Copyright (C) Pidgin Developers <devel@pidgin.im> * * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this library; if not, see <https://www.gnu.org/licenses/>. */ #include "purplecontactinfo.h" #include "purpleenums.h" #include "util.h" typedef struct { char *id; char *username; char *display_name; char *alias; char *color; char *email; char *phone_number; GTimeZone *time_zone; char *note; char *sid; gboolean favorite; char *name_for_display; PurpleAvatar *avatar; PurplePresence *presence; PurpleTags *tags; PurplePerson *person; PurpleContactInfoPermission permission; } PurpleContactInfoPrivate; enum { PROP_0, PROP_ID, PROP_USERNAME, PROP_DISPLAY_NAME, PROP_ALIAS, PROP_COLOR, PROP_EMAIL, PROP_PHONE_NUMBER, PROP_TIME_ZONE, PROP_NOTE, PROP_AVATAR, PROP_PRESENCE, PROP_TAGS, PROP_PERSON, PROP_PERMISSION, PROP_SID, PROP_FAVORITE, PROP_NAME_FOR_DISPLAY, N_PROPERTIES, }; static GParamSpec *properties[N_PROPERTIES] = {NULL, }; enum { SIG_PRESENCE_CHANGED, SIG_POPULATE_MENU, N_SIGNALS, }; static guint signals[N_SIGNALS] = {0, }; G_DEFINE_TYPE_WITH_PRIVATE(PurpleContactInfo, purple_contact_info, G_TYPE_OBJECT) /****************************************************************************** * Helpers *****************************************************************************/ static void purple_contact_info_update_name_for_display(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; const char *name_for_display = NULL; priv = purple_contact_info_get_instance_private(info); /* If the info has an alias set, use it. */ if(name_for_display == NULL && !purple_strempty(priv->alias)) { name_for_display = priv->alias; } /* If info is associated with a PurplePerson that has an alias set, use the * alias of that PurplePerson. */ if(name_for_display == NULL && priv->person != NULL) { const char *alias = purple_person_get_alias(priv->person); if(!purple_strempty(alias)) { name_for_display = alias; } } /* If the info has a display name set, use it. */ if(name_for_display == NULL && !purple_strempty(priv->display_name)) { name_for_display = priv->display_name; } /* Fallback to the username if that is set. */ if(name_for_display == NULL && !purple_strempty(priv->username)) { name_for_display = priv->username; } /* Finally, in a last ditch effort, use the id of the info. */ if(name_for_display == NULL) { name_for_display = priv->id; } if(g_set_str(&priv->name_for_display, name_for_display)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_NAME_FOR_DISPLAY]); } } /****************************************************************************** * Callbacks *****************************************************************************/ static void purple_contact_info_person_alias_changed_cb(G_GNUC_UNUSED GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, gpointer data) { purple_contact_info_update_name_for_display(data); } /* * This is a notify callback on the presence for a contact info, it is used * to emit the presence-changed signal. */ static void purple_contact_info_presence_notify_cb(GObject *source, GParamSpec *pspec, gpointer data) { g_signal_emit(data, signals[SIG_PRESENCE_CHANGED], g_param_spec_get_name_quark(pspec), source, pspec); } /****************************************************************************** * GObject Implementation *****************************************************************************/ static void purple_contact_info_get_property(GObject *obj, guint param_id, GValue *value, GParamSpec *pspec) { PurpleContactInfo *info = PURPLE_CONTACT_INFO(obj); switch(param_id) { case PROP_ID: g_value_set_string(value, purple_contact_info_get_id(info)); break; case PROP_USERNAME: g_value_set_string(value, purple_contact_info_get_username(info)); break; case PROP_DISPLAY_NAME: g_value_set_string(value, purple_contact_info_get_display_name(info)); break; case PROP_ALIAS: g_value_set_string(value, purple_contact_info_get_alias(info)); break; case PROP_COLOR: g_value_set_string(value, purple_contact_info_get_color(info)); break; case PROP_EMAIL: g_value_set_string(value, purple_contact_info_get_email(info)); break; case PROP_PHONE_NUMBER: g_value_set_string(value, purple_contact_info_get_phone_number(info)); break; case PROP_TIME_ZONE: g_value_set_boxed(value, purple_contact_info_get_time_zone(info)); break; case PROP_NOTE: g_value_set_string(value, purple_contact_info_get_note(info)); break; case PROP_AVATAR: g_value_set_object(value, purple_contact_info_get_avatar(info)); break; case PROP_PRESENCE: g_value_set_object(value, purple_contact_info_get_presence(info)); break; case PROP_TAGS: g_value_set_object(value, purple_contact_info_get_tags(info)); break; case PROP_PERSON: g_value_set_object(value, purple_contact_info_get_person(info)); break; case PROP_PERMISSION: g_value_set_enum(value, purple_contact_info_get_permission(info)); break; case PROP_NAME_FOR_DISPLAY: g_value_set_string(value, purple_contact_info_get_name_for_display(info)); break; case PROP_SID: g_value_set_string(value, purple_contact_info_get_sid(info)); break; case PROP_FAVORITE: g_value_set_boolean(value, purple_contact_info_get_favorite(info)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); break; } } static void purple_contact_info_set_property(GObject *obj, guint param_id, const GValue *value, GParamSpec *pspec) { PurpleContactInfo *info = PURPLE_CONTACT_INFO(obj); switch(param_id) { case PROP_ID: purple_contact_info_set_id(info, g_value_get_string(value)); break; case PROP_USERNAME: purple_contact_info_set_username(info, g_value_get_string(value)); break; case PROP_DISPLAY_NAME: purple_contact_info_set_display_name(info, g_value_get_string(value)); break; case PROP_ALIAS: purple_contact_info_set_alias(info, g_value_get_string(value)); break; case PROP_COLOR: purple_contact_info_set_color(info, g_value_get_string(value)); break; case PROP_EMAIL: purple_contact_info_set_email(info, g_value_get_string(value)); break; case PROP_PHONE_NUMBER: purple_contact_info_set_phone_number(info, g_value_get_string(value)); break; case PROP_TIME_ZONE: purple_contact_info_set_time_zone(info, g_value_get_boxed(value)); break; case PROP_NOTE: purple_contact_info_set_note(info, g_value_get_string(value)); break; case PROP_AVATAR: purple_contact_info_set_avatar(info, g_value_get_object(value)); break; case PROP_PERSON: purple_contact_info_set_person(info, g_value_get_object(value)); break; case PROP_PERMISSION: purple_contact_info_set_permission(info, g_value_get_enum(value)); break; case PROP_SID: purple_contact_info_set_sid(info, g_value_get_string(value)); break; case PROP_FAVORITE: purple_contact_info_set_favorite(info, g_value_get_boolean(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); break; } } static void purple_contact_info_dispose(GObject *obj) { PurpleContactInfo *info = PURPLE_CONTACT_INFO(obj); PurpleContactInfoPrivate *priv = NULL; priv = purple_contact_info_get_instance_private(info); g_clear_object(&priv->avatar); g_clear_object(&priv->presence); g_clear_object(&priv->tags); g_clear_object(&priv->person); G_OBJECT_CLASS(purple_contact_info_parent_class)->dispose(obj); } static void purple_contact_info_finalize(GObject *obj) { PurpleContactInfo *info = PURPLE_CONTACT_INFO(obj); PurpleContactInfoPrivate *priv = NULL; priv = purple_contact_info_get_instance_private(info); g_clear_pointer(&priv->id, g_free); g_clear_pointer(&priv->username, g_free); g_clear_pointer(&priv->display_name, g_free); g_clear_pointer(&priv->alias, g_free); g_clear_pointer(&priv->color, g_free); g_clear_pointer(&priv->email, g_free); g_clear_pointer(&priv->phone_number, g_free); g_clear_pointer(&priv->time_zone, g_time_zone_unref); g_clear_pointer(&priv->note, g_free); g_clear_pointer(&priv->sid, g_free); g_clear_pointer(&priv->name_for_display, g_free); G_OBJECT_CLASS(purple_contact_info_parent_class)->finalize(obj); } static void purple_contact_info_constructed(GObject *obj) { PurpleContactInfo *info = NULL; PurpleContactInfoPrivate *priv = NULL; G_OBJECT_CLASS(purple_contact_info_parent_class)->constructed(obj); info = PURPLE_CONTACT_INFO(obj); priv = purple_contact_info_get_instance_private(info); if(purple_strempty(priv->id)) { purple_contact_info_set_id(info, NULL); } purple_contact_info_update_name_for_display(info); } static void purple_contact_info_init(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; priv = purple_contact_info_get_instance_private(info); priv->tags = purple_tags_new(); priv->presence = g_object_new(PURPLE_TYPE_PRESENCE, NULL); g_signal_connect_object(priv->presence, "notify", G_CALLBACK(purple_contact_info_presence_notify_cb), info, 0); } static void purple_contact_info_class_init(PurpleContactInfoClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS(klass); obj_class->constructed = purple_contact_info_constructed; obj_class->dispose = purple_contact_info_dispose; obj_class->finalize = purple_contact_info_finalize; obj_class->get_property = purple_contact_info_get_property; obj_class->set_property = purple_contact_info_set_property; /** * PurpleContactInfo:id: * * The protocol specific id for the contact. * * Since: 3.0 */ properties[PROP_ID] = g_param_spec_string( "id", "id", "The id of the contact", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:username: * * The username for this contact. In rare cases this can change, like when * a user changes their "nick" on IRC which is their user name. * * Since: 3.0 */ properties[PROP_USERNAME] = g_param_spec_string( "username", "username", "The username of the contact", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:display-name: * * The display name for this contact. This is generally set by the person * the contact is representing and controlled via the protocol plugin. * * Since: 3.0 */ properties[PROP_DISPLAY_NAME] = g_param_spec_string( "display-name", "display-name", "The display name of the contact", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:alias: * * The alias for this contact. This is controlled by the libpurple user and * may be used by the protocol if it allows for aliasing. * * Since: 3.0 */ properties[PROP_ALIAS] = g_param_spec_string( "alias", "alias", "The alias of the contact.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:color: * * The color for this contact. This is an RGB hex code that user interfaces * can use when rendering the contact. This may also be controlled via a * protocol plugin in the event that the protocol allows people to set a * highlight/branding color. * * Since: 3.0 */ properties[PROP_COLOR] = g_param_spec_string( "color", "color", "The color to use when rendering the contact.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:email: * * The primary email address for the contact. This may also be controlled * via a protocol plugin in the event that the protocol makes it available. * * Since: 3.0 */ properties[PROP_EMAIL] = g_param_spec_string( "email", "email", "The primary email address for the contact.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:phone-number: * * The primary phone number for the contact. This may also be set via a * protocol plugin in the event that the protocol knows it. * * Since: 3.0 */ properties[PROP_PHONE_NUMBER] = g_param_spec_string( "phone-number", "phone-number", "The primary phone number for the contact.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:time-zone: * * The time zone for this contact. This is typically controlled by the * protocol and should only be read by others. * * Since: 3.0 */ properties[PROP_TIME_ZONE] = g_param_spec_boxed( "time-zone", "time-zone", "The time zone for the contact.", G_TYPE_TIME_ZONE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:note: * * A note for this contact. Many protocols will allow you to set a note on * a contact and store it server side. This property is where that is kept * track of. * * Since: 3.0 */ properties[PROP_NOTE] = g_param_spec_string( "note", "note", "A note for the contact.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:avatar: * * The avatar for this contact. This is typically controlled by the * protocol and should only be read by others. * * Since: 3.0 */ properties[PROP_AVATAR] = g_param_spec_object( "avatar", "avatar", "The avatar of the contact", PURPLE_TYPE_AVATAR, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:presence: * * The [class@Purple.Presence] for this contact. This is typically * controlled by the protocol and should only be read by others. * * Since: 3.0 */ properties[PROP_PRESENCE] = g_param_spec_object( "presence", "presence", "The presence of the contact", PURPLE_TYPE_PRESENCE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:tags: * * The [class@Purple.Tags] for this contact. * * Since: 3.0 */ properties[PROP_TAGS] = g_param_spec_object( "tags", "tags", "The tags for the contact", PURPLE_TYPE_TAGS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:person: * * The [class@Purple.Person] that this contact belongs to. * * Since: 3.0 */ properties[PROP_PERSON] = g_param_spec_object( "person", "person", "The person this contact belongs to.", PURPLE_TYPE_PERSON, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:permission: * * The permission level for the contact. * * Since: 3.0 */ properties[PROP_PERMISSION] = g_param_spec_enum( "permission", "permission", "The permission level of the contact", PURPLE_TYPE_CONTACT_INFO_PERMISSION, PURPLE_CONTACT_INFO_PERMISSION_UNSET, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:sid: * * The sid, or secondary id, is an additional identifier field for a * contact. * * This could be used to hold the `ident` for an IRC contact, the * `resource` for an XMPP contact, or something similar. * * Since: 3.0 */ properties[PROP_SID] = g_param_spec_string( "sid", "sid", "The secondary id for the contact.", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:favorite: * * Whether or not the contact info has been marked as a favorite or stared. * * Since: 3.0 */ properties[PROP_FAVORITE] = g_param_spec_boolean( "favorite", "favorite", "Whether or not this is a favorite contact.", FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** * PurpleContactInfo:name-for-display: * * The name that the user interface should display for this contact info. * * This will first check [property@Purple.ContactInfo:alias] and return * that if it is set. * * Next, if the [property@Purple.ContactInfo:person] points to a valid * [class@Purple.Person], the alias of [class@Purple.Person] will be * returned if it is set. * * Otherwise, this will be set to the first set property from the following * list: * * * [property@Purple.ContactInfo:display-name] * * [property@Purple.ContactInfo:username] * * [property@Purple.ContactInfo:id] * * Since: 3.0 */ properties[PROP_NAME_FOR_DISPLAY] = g_param_spec_string( "name-for-display", "name-for-display", "The name that should be displayed for the contact info", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, properties); /** * PurpleContactInfo::presence-changed: * @info: The instance. * @presence: The presence that was changed. * @pspec: The [class@GObject.ParamSpec] for the property that changed. * * This is a propagation of the notify signal from @presence. This means * that your callback will be called when anything in the presence changes. * * This also supports details, so you can specify the signal name as * something like `presence-changed::message` and your callback will only * be called when the message property of @presence has been changed. * * Since: 3.0 */ signals[SIG_PRESENCE_CHANGED] = g_signal_new_class_handler( "presence-changed", G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, NULL, NULL, NULL, NULL, G_TYPE_NONE, 2, PURPLE_TYPE_PRESENCE, G_TYPE_PARAM); /** * PurpleContactInfo::populate-menu: * @info: The instance. * @menu: The [class@Birb.ActionMenu] to be displayed. * * Emitted in response to [method@PurpleContactInfo.get_menu] being called, * so that plugins can add additional items to @menu. * * The user interface is responsible for displaying @menu which means it * can add additional items, hide items, and lay them out however it * pleases. * * Since: 3.0 */ signals[SIG_POPULATE_MENU] = g_signal_new_class_handler( "populate-menu", G_OBJECT_CLASS_TYPE(klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, NULL, NULL, NULL, NULL, G_TYPE_NONE, 1, BIRB_TYPE_ACTION_MENU); } /****************************************************************************** * Public API *****************************************************************************/ PurpleContactInfo * purple_contact_info_new(const gchar *id) { return g_object_new( PURPLE_TYPE_CONTACT_INFO, "id", id, NULL); } const gchar * purple_contact_info_get_id(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->id; } void purple_contact_info_set_id(PurpleContactInfo *info, const gchar *id) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->id, id)) { g_object_freeze_notify(G_OBJECT(info)); g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_ID]); purple_contact_info_update_name_for_display(info); g_object_thaw_notify(G_OBJECT(info)); } } const gchar * purple_contact_info_get_username(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->username; } void purple_contact_info_set_username(PurpleContactInfo *info, const gchar *username) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->username, username)) { g_object_freeze_notify(G_OBJECT(info)); g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_USERNAME]); purple_contact_info_update_name_for_display(info); g_object_thaw_notify(G_OBJECT(info)); } } const gchar * purple_contact_info_get_display_name(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->display_name; } void purple_contact_info_set_display_name(PurpleContactInfo *info, const gchar *display_name) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->display_name, display_name)) { g_object_freeze_notify(G_OBJECT(info)); g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_DISPLAY_NAME]); purple_contact_info_update_name_for_display(info); g_object_thaw_notify(G_OBJECT(info)); } } const gchar * purple_contact_info_get_alias(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->alias; } void purple_contact_info_set_alias(PurpleContactInfo *info, const gchar *alias) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->alias, alias)) { g_object_freeze_notify(G_OBJECT(info)); g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_ALIAS]); purple_contact_info_update_name_for_display(info); g_object_thaw_notify(G_OBJECT(info)); } } const char * purple_contact_info_get_color(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->color; } void purple_contact_info_set_color(PurpleContactInfo *info, const char *color) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->color, color)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_COLOR]); } } const char * purple_contact_info_get_email(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->email; } void purple_contact_info_set_email(PurpleContactInfo *info, const char *email) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->email, email)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_EMAIL]); } } const char * purple_contact_info_get_phone_number(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->phone_number; } void purple_contact_info_set_phone_number(PurpleContactInfo *info, const char *phone_number) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->phone_number, phone_number)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_PHONE_NUMBER]); } } GTimeZone * purple_contact_info_get_time_zone(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->time_zone; } void purple_contact_info_set_time_zone(PurpleContactInfo *info, GTimeZone *time_zone) { PurpleContactInfoPrivate *priv = NULL; GTimeZone *old = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); old = priv->time_zone; priv->time_zone = NULL; if(time_zone != NULL) { priv->time_zone = g_time_zone_ref(time_zone); } if(old != NULL) { g_time_zone_unref(old); } g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_TIME_ZONE]); } const char * purple_contact_info_get_note(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->note; } void purple_contact_info_set_note(PurpleContactInfo *info, const char *note) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->note, note)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_NOTE]); } } PurpleAvatar * purple_contact_info_get_avatar(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->avatar; } void purple_contact_info_set_avatar(PurpleContactInfo *info, PurpleAvatar *avatar) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_object(&priv->avatar, avatar)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_AVATAR]); } } PurplePresence * purple_contact_info_get_presence(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->presence; } PurpleTags * purple_contact_info_get_tags(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->tags; } void purple_contact_info_set_person(PurpleContactInfo *info, PurplePerson *person) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_object(&priv->person, person)) { /* If we got a new person, we need to connect to the notify::alias * signal. */ if(PURPLE_IS_PERSON(priv->person)) { g_signal_connect_object(priv->person, "notify::alias", G_CALLBACK(purple_contact_info_person_alias_changed_cb), info, 0); } /* Freeze notifications as the person update could change the * name-for-display property. */ g_object_freeze_notify(G_OBJECT(info)); g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_PERSON]); /* Update the name-for-display property */ purple_contact_info_update_name_for_display(info); g_object_thaw_notify(G_OBJECT(info)); } } PurplePerson * purple_contact_info_get_person(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->person; } PurpleContactInfoPermission purple_contact_info_get_permission(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), PURPLE_CONTACT_INFO_PERMISSION_UNSET); priv = purple_contact_info_get_instance_private(info); return priv->permission; } void purple_contact_info_set_permission(PurpleContactInfo *info, PurpleContactInfoPermission permission) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); priv->permission = permission; g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_PERMISSION]); } const char * purple_contact_info_get_sid(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->sid; } void purple_contact_info_set_sid(PurpleContactInfo *info, const char *sid) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(g_set_str(&priv->sid, sid)) { g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_SID]); } } gboolean purple_contact_info_get_favorite(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), FALSE); priv = purple_contact_info_get_instance_private(info); return priv->favorite; } void purple_contact_info_set_favorite(PurpleContactInfo *info, gboolean favorite) { PurpleContactInfoPrivate *priv = NULL; g_return_if_fail(PURPLE_IS_CONTACT_INFO(info)); priv = purple_contact_info_get_instance_private(info); if(priv->favorite != favorite) { priv->favorite = favorite; g_object_notify_by_pspec(G_OBJECT(info), properties[PROP_FAVORITE]); } } const char * purple_contact_info_get_name_for_display(PurpleContactInfo *info) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); priv = purple_contact_info_get_instance_private(info); return priv->name_for_display; } int purple_contact_info_compare(PurpleContactInfo *a, PurpleContactInfo *b) { PurplePerson *person_a = NULL; PurplePerson *person_b = NULL; const char *name_a = NULL; const char *name_b = NULL; /* Check for NULL values. */ if(a != NULL && b == NULL) { return -1; } else if(a == NULL && b != NULL) { return 1; } else if(a == NULL && b == NULL) { return 0; } /* Check if the contacts have persons associated with them. */ person_a = purple_contact_info_get_person(a); person_b = purple_contact_info_get_person(b); if(person_a != NULL && person_b == NULL) { return -1; } else if(person_a == NULL && person_b != NULL) { return 1; } /* Finally get the names for the displaying and compare those. */ name_a = purple_contact_info_get_name_for_display(a); name_b = purple_contact_info_get_name_for_display(b); return purple_utf8_strcasecmp(name_a, name_b); } gboolean purple_contact_info_equal(PurpleContactInfo *a, PurpleContactInfo *b) { return purple_contact_info_compare(a, b) == 0; } gboolean purple_contact_info_matches(PurpleContactInfo *info, const char *needle) { PurpleContactInfoPrivate *priv = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), FALSE); if(purple_strempty(needle)) { return TRUE; } priv = purple_contact_info_get_instance_private(info); if(!purple_strempty(priv->username)) { if(purple_strmatches(needle, priv->username)) { return TRUE; } } if(!purple_strempty(priv->alias)) { if(purple_strmatches(needle, priv->alias)) { return TRUE; } } if(!purple_strempty(priv->display_name)) { if(purple_strmatches(needle, priv->display_name)) { return TRUE; } } /* Nothing matched, so return FALSE. */ return FALSE; } BirbActionMenu * purple_contact_info_get_menu(PurpleContactInfo *info) { BirbActionMenu *menu = NULL; g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); menu = birb_action_menu_new(); g_signal_emit(info, signals[SIG_POPULATE_MENU], 0, menu); return menu; }