Adapt migration for files
[pidgin-git.git] / libpurple / message.c
blobd4a8ed14fbd3cf3335aea28f1e6c47bf64fa2088
1 /* purple
3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "internal.h"
23 #include "dbus-maybe.h"
24 #include "glibcompat.h"
26 #include "debug.h"
27 #include "enums.h"
28 #include "message.h"
30 #define PURPLE_MESSAGE_GET_PRIVATE(obj) \
31 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_MESSAGE, PurpleMessagePrivate))
33 typedef struct {
34 guint id;
35 gchar *author;
36 gchar *author_alias;
37 gchar *recipient;
38 gchar *contents;
39 guint64 msgtime;
40 PurpleMessageFlags flags;
41 } PurpleMessagePrivate;
43 enum
45 PROP_0,
46 PROP_ID,
47 PROP_AUTHOR,
48 PROP_AUTHOR_ALIAS,
49 PROP_RECIPIENT,
50 PROP_CONTENTS,
51 PROP_TIME,
52 PROP_FLAGS,
53 PROP_LAST
56 static GObjectClass *parent_class;
57 static GParamSpec *properties[PROP_LAST];
59 static GHashTable *messages = NULL;
61 /******************************************************************************
62 * API implementation
63 ******************************************************************************/
65 PurpleMessage *
66 purple_message_new_outgoing(const gchar *who, const gchar *contents,
67 PurpleMessageFlags flags)
69 g_warn_if_fail(!(flags & PURPLE_MESSAGE_RECV));
70 g_warn_if_fail(!(flags & PURPLE_MESSAGE_SYSTEM));
72 flags |= PURPLE_MESSAGE_SEND;
74 /* who may be NULL for outgoing MUC messages */
75 return g_object_new(PURPLE_TYPE_MESSAGE,
76 "author-alias", _("Me"),
77 "recipient", who,
78 "contents", contents,
79 "time", (guint64)time(NULL),
80 "flags", flags,
81 NULL);
84 PurpleMessage *
85 purple_message_new_incoming(const gchar *who, const gchar *contents,
86 PurpleMessageFlags flags, guint64 timestamp)
88 g_warn_if_fail(!(flags & PURPLE_MESSAGE_SEND));
89 g_warn_if_fail(!(flags & PURPLE_MESSAGE_SYSTEM));
91 flags |= PURPLE_MESSAGE_RECV;
93 if (timestamp == 0)
94 timestamp = time(NULL);
96 return g_object_new(PURPLE_TYPE_MESSAGE,
97 "author", who,
98 "author-alias", who,
99 "contents", contents,
100 "time", timestamp,
101 "flags", flags,
102 NULL);
105 PurpleMessage *
106 purple_message_new_system(const gchar *contents, PurpleMessageFlags flags)
108 g_warn_if_fail(!(flags & PURPLE_MESSAGE_SEND));
109 g_warn_if_fail(!(flags & PURPLE_MESSAGE_RECV));
111 flags |= PURPLE_MESSAGE_SYSTEM;
113 return g_object_new(PURPLE_TYPE_MESSAGE,
114 "contents", contents,
115 "time", (guint64)time(NULL),
116 "flags", flags,
117 NULL);
120 guint
121 purple_message_get_id(const PurpleMessage *msg)
123 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
125 g_return_val_if_fail(priv != NULL, 0);
127 return priv->id;
130 PurpleMessage *
131 purple_message_find_by_id(guint id)
133 g_return_val_if_fail(id > 0, NULL);
135 return g_hash_table_lookup(messages, GINT_TO_POINTER(id));
138 const gchar *
139 purple_message_get_author(const PurpleMessage *msg)
141 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
143 g_return_val_if_fail(priv != NULL, NULL);
145 return priv->author;
148 const gchar *
149 purple_message_get_recipient(const PurpleMessage *msg)
151 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
153 g_return_val_if_fail(priv != NULL, NULL);
155 return priv->recipient;
158 void
159 purple_message_set_author_alias(PurpleMessage *msg, const gchar *alias)
161 g_object_set(msg, "author-alias", alias, NULL);
164 const gchar *
165 purple_message_get_author_alias(const PurpleMessage *msg)
167 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
169 g_return_val_if_fail(priv != NULL, NULL);
171 if (priv->author_alias == NULL)
172 return purple_message_get_author(msg);
174 return priv->author_alias;
177 void
178 purple_message_set_contents(PurpleMessage *msg, const gchar *cont)
180 g_object_set(msg, "contents", cont, NULL);
183 const gchar *
184 purple_message_get_contents(const PurpleMessage *msg)
186 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
188 g_return_val_if_fail(priv != NULL, NULL);
190 return priv->contents;
193 gboolean
194 purple_message_is_empty(const PurpleMessage *msg)
196 const gchar *cont = purple_message_get_contents(msg);
198 return (cont == NULL || cont[0] == '\0');
201 void
202 purple_message_set_time(PurpleMessage *msg, guint64 msgtime)
204 g_object_set(msg, "time", msgtime, NULL);
207 guint64
208 purple_message_get_time(const PurpleMessage *msg)
210 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
212 g_return_val_if_fail(priv != NULL, 0);
214 return priv->msgtime;
217 void
218 purple_message_set_flags(PurpleMessage *msg, PurpleMessageFlags flags)
220 g_object_set(msg, "flags", flags, NULL);
223 PurpleMessageFlags
224 purple_message_get_flags(const PurpleMessage *msg)
226 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
228 g_return_val_if_fail(priv != NULL, 0);
230 return priv->flags;
233 /******************************************************************************
234 * Object stuff
235 ******************************************************************************/
237 static void
238 purple_message_init(GTypeInstance *instance, gpointer klass)
240 static guint max_id = 0;
242 PurpleMessage *msg = PURPLE_MESSAGE(instance);
243 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(msg);
244 PURPLE_DBUS_REGISTER_POINTER(msg, PurpleMessage);
246 priv->id = ++max_id;
247 g_hash_table_insert(messages, GINT_TO_POINTER(max_id), msg);
250 static void
251 purple_message_finalize(GObject *obj)
253 PurpleMessage *message = PURPLE_MESSAGE(obj);
254 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(message);
256 g_free(priv->author);
257 g_free(priv->author_alias);
258 g_free(priv->recipient);
259 g_free(priv->contents);
261 G_OBJECT_CLASS(parent_class)->finalize(obj);
264 static void
265 purple_message_get_property(GObject *object, guint par_id, GValue *value,
266 GParamSpec *pspec)
268 PurpleMessage *message = PURPLE_MESSAGE(object);
269 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(message);
271 switch (par_id) {
272 case PROP_ID:
273 g_value_set_uint(value, priv->id);
274 break;
275 case PROP_AUTHOR:
276 g_value_set_string(value, priv->author);
277 break;
278 case PROP_AUTHOR_ALIAS:
279 g_value_set_string(value, priv->author_alias);
280 break;
281 case PROP_RECIPIENT:
282 g_value_set_string(value, priv->recipient);
283 break;
284 case PROP_CONTENTS:
285 g_value_set_string(value, priv->contents);
286 break;
287 case PROP_TIME:
288 g_value_set_uint64(value, priv->msgtime);
289 break;
290 case PROP_FLAGS:
291 g_value_set_flags(value, priv->flags);
292 break;
293 default:
294 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec);
295 break;
299 static void
300 purple_message_set_property(GObject *object, guint par_id, const GValue *value,
301 GParamSpec *pspec)
303 PurpleMessage *message = PURPLE_MESSAGE(object);
304 PurpleMessagePrivate *priv = PURPLE_MESSAGE_GET_PRIVATE(message);
306 switch (par_id) {
307 case PROP_AUTHOR:
308 g_free(priv->author);
309 priv->author = g_strdup(g_value_get_string(value));
310 break;
311 case PROP_AUTHOR_ALIAS:
312 g_free(priv->author_alias);
313 priv->author_alias = g_strdup(g_value_get_string(value));
314 break;
315 case PROP_RECIPIENT:
316 g_free(priv->recipient);
317 priv->recipient = g_strdup(g_value_get_string(value));
318 break;
319 case PROP_CONTENTS:
320 g_free(priv->contents);
321 priv->contents = g_strdup(g_value_get_string(value));
322 break;
323 case PROP_TIME:
324 priv->msgtime = g_value_get_uint64(value);
325 break;
326 case PROP_FLAGS:
327 priv->flags = g_value_get_flags(value);
328 break;
329 default:
330 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, par_id, pspec);
331 break;
335 static void
336 purple_message_class_init(PurpleMessageClass *klass)
338 GObjectClass *gobj_class = G_OBJECT_CLASS(klass);
340 parent_class = g_type_class_peek_parent(klass);
342 g_type_class_add_private(klass, sizeof(PurpleMessagePrivate));
344 gobj_class->finalize = purple_message_finalize;
345 gobj_class->get_property = purple_message_get_property;
346 gobj_class->set_property = purple_message_set_property;
348 properties[PROP_ID] = g_param_spec_uint("id",
349 "ID", "The session-unique message id",
350 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
351 properties[PROP_AUTHOR] = g_param_spec_string("author",
352 "Author", "The username of the person, who sent the message.",
353 NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
354 properties[PROP_AUTHOR_ALIAS] = g_param_spec_string("author-alias",
355 "Author's alias", "The alias of the person, who sent the "
356 "message. For outgoing messages, it's your alias.",
357 NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
358 properties[PROP_RECIPIENT] = g_param_spec_string("recipient",
359 "Recipient", "The username of the recipient.",
360 NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
361 properties[PROP_CONTENTS] = g_param_spec_string("contents",
362 "Contents", "The message text",
363 NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
364 properties[PROP_TIME] = g_param_spec_uint64("time",
365 "Time", "Message timestamp",
366 0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
367 properties[PROP_FLAGS] = g_param_spec_flags("flags",
368 "Flags", "Bitwise set of #PurpleMessageFlags flags",
369 PURPLE_TYPE_MESSAGE_FLAGS, 0,
370 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
372 g_object_class_install_properties(gobj_class, PROP_LAST, properties);
375 GType
376 purple_message_get_type(void)
378 static GType type = 0;
380 if (G_UNLIKELY(type == 0)) {
381 static const GTypeInfo info = {
382 .class_size = sizeof(PurpleMessageClass),
383 .class_init = (GClassInitFunc)purple_message_class_init,
384 .instance_size = sizeof(PurpleMessage),
385 .instance_init = purple_message_init,
388 type = g_type_register_static(G_TYPE_OBJECT,
389 "PurpleMessage", &info, 0);
392 return type;
395 void
396 _purple_message_init(void)
398 messages = g_hash_table_new_full(g_direct_hash, g_direct_equal,
399 NULL, g_object_unref);
402 void
403 _purple_message_uninit(void)
405 g_hash_table_destroy(messages);
406 messages = NULL;