4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25 #include "internal.h" /* TODO: this needs to die */
28 typedef struct _PurpleContactPrivate PurpleContactPrivate
;
30 struct _PurpleContactPrivate
{
31 char *alias
; /* The user-set alias of the contact */
32 PurpleBuddy
*priority_buddy
; /* The "top" buddy for this contact */
33 gboolean priority_valid
; /* Is priority valid? */
44 /******************************************************************************
46 *****************************************************************************/
47 static GParamSpec
*properties
[PROP_LAST
];
49 G_DEFINE_TYPE_WITH_PRIVATE(PurpleContact
, purple_contact
,
50 PURPLE_TYPE_COUNTING_NODE
);
52 /******************************************************************************
54 *****************************************************************************/
56 purple_contact_compute_priority_buddy(PurpleContact
*contact
) {
57 PurpleBlistNode
*bnode
;
58 PurpleBuddy
*new_priority
= NULL
;
59 PurpleContactPrivate
*priv
=
60 purple_contact_get_instance_private(contact
);
62 priv
->priority_buddy
= NULL
;
63 for (bnode
= PURPLE_BLIST_NODE(contact
)->child
;
69 if (!PURPLE_IS_BUDDY(bnode
))
72 buddy
= PURPLE_BUDDY(bnode
);
73 if (new_priority
== NULL
)
79 if (purple_account_is_connected(purple_buddy_get_account(buddy
)))
82 if (purple_account_is_connected(purple_buddy_get_account(new_priority
)))
83 cmp
= purple_buddy_presence_compare(
84 PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(new_priority
)),
85 PURPLE_BUDDY_PRESENCE(purple_buddy_get_presence(buddy
)));
87 if (cmp
> 0 || (cmp
== 0 &&
88 purple_prefs_get_bool("/purple/contact/last_match")))
95 priv
->priority_buddy
= new_priority
;
96 priv
->priority_valid
= TRUE
;
98 g_object_notify_by_pspec(G_OBJECT(contact
),
99 properties
[PROP_PRIORITY_BUDDY
]);
103 purple_contact_get_group(const PurpleContact
*contact
)
105 g_return_val_if_fail(PURPLE_IS_CONTACT(contact
), NULL
);
107 return PURPLE_GROUP(PURPLE_BLIST_NODE(contact
)->parent
);
111 purple_contact_set_alias(PurpleContact
*contact
, const char *alias
)
113 PurpleContactPrivate
*priv
= NULL
;
114 PurpleIMConversation
*im
;
115 PurpleBlistNode
*bnode
;
117 char *new_alias
= NULL
;
119 g_return_if_fail(PURPLE_IS_CONTACT(contact
));
120 priv
= purple_contact_get_instance_private(contact
);
122 if ((alias
!= NULL
) && (*alias
!= '\0'))
123 new_alias
= purple_utf8_strip_unprintables(alias
);
125 if (!purple_strequal(priv
->alias
, new_alias
)) {
130 old_alias
= priv
->alias
;
132 if ((new_alias
!= NULL
) && (*new_alias
!= '\0'))
133 priv
->alias
= new_alias
;
136 g_free(new_alias
); /* could be "\0" */
139 g_object_notify_by_pspec(G_OBJECT(contact
),
140 properties
[PROP_ALIAS
]);
142 purple_blist_save_node(purple_blist_get_default(),
143 PURPLE_BLIST_NODE(contact
));
144 purple_blist_update_node(purple_blist_get_default(),
145 PURPLE_BLIST_NODE(contact
));
147 for(bnode
= PURPLE_BLIST_NODE(contact
)->child
; bnode
!= NULL
; bnode
= bnode
->next
)
149 PurpleBuddy
*buddy
= PURPLE_BUDDY(bnode
);
151 im
= purple_conversations_find_im_with_account(purple_buddy_get_name(buddy
),
152 purple_buddy_get_account(buddy
));
154 purple_conversation_autoset_title(PURPLE_CONVERSATION(im
));
157 purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
162 const char *purple_contact_get_alias(PurpleContact
* contact
)
164 PurpleContactPrivate
*priv
= NULL
;
166 g_return_val_if_fail(PURPLE_IS_CONTACT(contact
), NULL
);
168 priv
= purple_contact_get_instance_private(contact
);
172 return purple_buddy_get_alias(purple_contact_get_priority_buddy(contact
));
175 gboolean
purple_contact_on_account(PurpleContact
*c
, PurpleAccount
*account
)
177 PurpleBlistNode
*bnode
, *cnode
= (PurpleBlistNode
*) c
;
179 g_return_val_if_fail(PURPLE_IS_CONTACT(c
), FALSE
);
180 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), FALSE
);
182 for (bnode
= cnode
->child
; bnode
; bnode
= bnode
->next
) {
185 if (! PURPLE_IS_BUDDY(bnode
))
188 buddy
= (PurpleBuddy
*)bnode
;
189 if (purple_buddy_get_account(buddy
) == account
)
195 void purple_contact_invalidate_priority_buddy(PurpleContact
*contact
)
197 PurpleContactPrivate
*priv
= NULL
;
199 g_return_if_fail(PURPLE_IS_CONTACT(contact
));
201 priv
= purple_contact_get_instance_private(contact
);
202 priv
->priority_valid
= FALSE
;
205 PurpleBuddy
*purple_contact_get_priority_buddy(PurpleContact
*contact
)
207 PurpleContactPrivate
*priv
= NULL
;
209 g_return_val_if_fail(PURPLE_IS_CONTACT(contact
), NULL
);
211 priv
= purple_contact_get_instance_private(contact
);
212 if (!priv
->priority_valid
)
213 purple_contact_compute_priority_buddy(contact
);
215 return priv
->priority_buddy
;
218 void purple_contact_merge(PurpleContact
*source
, PurpleBlistNode
*node
)
220 PurpleBlistNode
*sourcenode
= (PurpleBlistNode
*)source
;
221 PurpleBlistNode
*prev
, *cur
, *next
;
222 PurpleContact
*target
;
224 g_return_if_fail(PURPLE_IS_CONTACT(source
));
225 g_return_if_fail(PURPLE_IS_BLIST_NODE(node
));
227 if (PURPLE_IS_CONTACT(node
)) {
228 target
= (PurpleContact
*)node
;
229 prev
= _purple_blist_get_last_child(node
);
230 } else if (PURPLE_IS_BUDDY(node
)) {
231 target
= (PurpleContact
*)node
->parent
;
237 if (source
== target
|| !target
)
240 next
= sourcenode
->child
;
245 if (PURPLE_IS_BUDDY(cur
)) {
246 purple_blist_add_buddy((PurpleBuddy
*)cur
, target
, NULL
, prev
);
252 /**************************************************************************
254 **************************************************************************/
255 /* Set method for GObject properties */
257 purple_contact_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
260 PurpleContact
*contact
= PURPLE_CONTACT(obj
);
264 purple_contact_set_alias(contact
, g_value_get_string(value
));
267 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
272 /* Get method for GObject properties */
274 purple_contact_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
277 PurpleContact
*contact
= PURPLE_CONTACT(obj
);
278 PurpleContactPrivate
*priv
=
279 purple_contact_get_instance_private(contact
);
283 g_value_set_string(value
, priv
->alias
);
285 case PROP_PRIORITY_BUDDY
:
286 g_value_set_object(value
, purple_contact_get_priority_buddy(contact
));
289 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
294 /* GObject initialization function */
296 purple_contact_init(PurpleContact
*contact
)
298 purple_blist_new_node(purple_blist_get_default(),
299 PURPLE_BLIST_NODE(contact
));
302 /* GObject finalize function */
304 purple_contact_finalize(GObject
*object
)
306 PurpleContactPrivate
*priv
= purple_contact_get_instance_private(
307 PURPLE_CONTACT(object
));
311 G_OBJECT_CLASS(purple_contact_parent_class
)->finalize(object
);
314 /* Class initializer function */
315 static void purple_contact_class_init(PurpleContactClass
*klass
)
317 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
319 obj_class
->finalize
= purple_contact_finalize
;
321 /* Setup properties */
322 obj_class
->get_property
= purple_contact_get_property
;
323 obj_class
->set_property
= purple_contact_set_property
;
325 properties
[PROP_ALIAS
] = g_param_spec_string(
328 "The alias for the contact.",
330 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
333 properties
[PROP_PRIORITY_BUDDY
] = g_param_spec_object(
336 "The priority buddy of the contact.",
338 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
341 g_object_class_install_properties(obj_class
, PROP_LAST
, properties
);
345 purple_contact_new(void)
347 return g_object_new(PURPLE_TYPE_CONTACT
, NULL
);