gobjectification.conversation: af477e6f: Add msg-send, msg-receive and msg-write ...
sadrul at pidgin.im
sadrul at pidgin.im
Sat Jul 24 23:10:43 EDT 2010
----------------------------------------------------------------------
Revision: af477e6f7be8d5d99d9e9b469c61262a1507bf49
Parent: 12901a85801f8916a18a8e9d8d555da7a7ff5efe
Author: sadrul at pidgin.im
Date: 07/24/10 21:43:36
Branch: im.pidgin.gobjectification.conversation
URL: http://d.pidgin.im/viewmtn/revision/info/af477e6f7be8d5d99d9e9b469c61262a1507bf49
Changelog:
Add msg-send, msg-receive and msg-write signals, and some skeleton code.
serv_send_im is removed. purple_conversation_send should be used instead.
serv_got_im is also removed, purple_im_new_with_receive should be used
instead.
Changes against parent 12901a85801f8916a18a8e9d8d555da7a7ff5efe
patched libpurple/conversation/conv-im.c
patched libpurple/conversation/conv-im.h
patched libpurple/conversation/conv-muc.c
patched libpurple/conversation/conv-muc.h
patched libpurple/conversation/conv.c
patched libpurple/conversation/conv.h
patched libpurple/conversation.c
patched libpurple/server.c
patched libpurple/server.h
-------------- next part --------------
============================================================
--- libpurple/server.c 77e0f2206e6927255953149830be6cf429c7dd6d
+++ libpurple/server.c 2552ab3acd76f509b0621c6d5d3ec06b95443797
@@ -23,6 +23,8 @@
/* This file is the fullcrap */
+#define purple_conversations_get_handle() NULL /* No ... *this* is */
+
#include "internal.h"
#include "blist.h"
#include "conversation.h"
@@ -117,6 +119,7 @@ get_last_auto_response(PurpleConnection
return lar;
}
+#if 0
int serv_send_im(PurpleConnection *gc, const char *name, const char *message,
PurpleMessageFlags flags)
{
@@ -165,6 +168,7 @@ int serv_send_im(PurpleConnection *gc, c
return val;
}
+#endif
void serv_get_info(PurpleConnection *gc, const char *name)
{
@@ -484,7 +488,7 @@ void serv_chat_invite(PurpleConnection *
PurpleConversation *conv;
char *buffy = message && *message ? g_strdup(message) : NULL;
- conv = purple_find_chat(gc, id);
+ conv = purple_conversations_find_muc(gc, id);
if(conv == NULL)
return;
@@ -552,6 +556,7 @@ int serv_chat_send(PurpleConnection *gc,
return -EINVAL;
}
+#if 0
/*
* woo. i'm actually going to comment this function. isn't that fun. make
* sure to follow along, kids
@@ -696,6 +701,7 @@ void serv_got_im(PurpleConnection *gc, c
g_free(name);
}
+#endif
void serv_got_typing(PurpleConnection *gc, const char *name, int timeout,
PurpleTypingState state) {
============================================================
--- libpurple/conversation.c 6a1826fb6833a914e1a3e208e66d1ee88a1bdccb
+++ libpurple/conversation.c 9761e4c1e29225c5b290df3b312b2f99fce96b5c
@@ -782,29 +782,6 @@ purple_conversation_set_account(PurpleCo
purple_conversation_update(conv, PURPLE_CONV_UPDATE_ACCOUNT);
}
-PurpleAccount *
-purple_conversation_get_account(const PurpleConversation *conv)
-{
- g_return_val_if_fail(conv != NULL, NULL);
-
- return conv->account;
-}
-
-PurpleConnection *
-purple_conversation_get_gc(const PurpleConversation *conv)
-{
- PurpleAccount *account;
-
- g_return_val_if_fail(conv != NULL, NULL);
-
- account = purple_conversation_get_account(conv);
-
- if (account == NULL)
- return NULL;
-
- return purple_account_get_connection(account);
-}
-
void
purple_conversation_set_title(PurpleConversation *conv, const char *title)
{
@@ -889,14 +866,6 @@ purple_conversation_set_name(PurpleConve
purple_conversation_autoset_title(conv);
}
-const char *
-purple_conversation_get_name(const PurpleConversation *conv)
-{
- g_return_val_if_fail(conv != NULL, NULL);
-
- return conv->name;
-}
-
PurpleBuddy *
purple_conversation_find_buddy(const PurpleConversation *conv)
{
@@ -1039,124 +1008,6 @@ purple_find_conversation_with_account(Pu
return c;
}
-void
-purple_conversation_write(PurpleConversation *conv, const char *who,
- const char *message, PurpleMessageFlags flags,
- time_t mtime)
-{
- PurplePluginProtocolInfo *prpl_info = NULL;
- PurpleConnection *gc = NULL;
- PurpleAccount *account;
- PurpleConversationUiOps *ops;
- const char *alias;
- char *displayed = NULL;
- PurpleBuddy *b;
- int plugin_return;
- PurpleConversationType type;
- /* int logging_font_options = 0; */
-
- g_return_if_fail(conv != NULL);
- g_return_if_fail(message != NULL);
-
- ops = purple_conversation_get_ui_ops(conv);
-
- account = purple_conversation_get_account(conv);
- type = purple_conversation_get_type(conv);
-
- if (account != NULL)
- gc = purple_account_get_connection(account);
-
-#warning I think commenting this breaks unnamed chats
-#if 0
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
- (gc != NULL && !g_slist_find(gc->buddy_chats, conv)))
- return;
-#endif
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM &&
- !g_list_find(purple_get_conversations(), conv))
- return;
-
- displayed = g_strdup(message);
-
- if (who == NULL || *who == '\0')
- who = purple_conversation_get_name(conv);
- alias = who;
-
- plugin_return =
- GPOINTER_TO_INT(purple_signal_emit_return_1(
- purple_conversations_get_handle(),
- (type == PURPLE_CONV_TYPE_IM ? "writing-im-msg" : "writing-chat-msg"),
- account, who, &displayed, conv, flags));
-
- if (displayed == NULL)
- return;
-
- if (plugin_return) {
- g_free(displayed);
- return;
- }
-
- if (account != NULL) {
- prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account)));
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM ||
- !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) {
-
- if (flags & PURPLE_MESSAGE_SEND) {
- b = purple_find_buddy(account,
- purple_account_get_username(account));
-
- if (purple_account_get_alias(account) != NULL)
- alias = purple_account_get_alias(account);
- else if (b != NULL && !purple_strequal(purple_buddy_get_name(b), purple_buddy_get_contact_alias(b)))
- alias = purple_buddy_get_contact_alias(b);
- else if (purple_connection_get_display_name(gc) != NULL)
- alias = purple_connection_get_display_name(gc);
- else
- alias = purple_account_get_username(account);
- }
- else
- {
- b = purple_find_buddy(account, who);
-
- if (b != NULL)
- alias = purple_buddy_get_contact_alias(b);
- }
- }
- }
-
- if (!(flags & PURPLE_MESSAGE_NO_LOG) && purple_conversation_is_logging(conv)) {
- GList *log;
-
- if (conv->logs == NULL)
- open_log(conv);
-
- log = conv->logs;
- while (log != NULL) {
- purple_log_write((PurpleLog *)log->data, flags, alias, mtime, displayed);
- log = log->next;
- }
- }
-
- if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
- if ((flags & PURPLE_MESSAGE_RECV) == PURPLE_MESSAGE_RECV) {
- purple_conv_im_set_typing_state(PURPLE_CONV_IM(conv), PURPLE_NOT_TYPING);
- }
- }
-
- if (ops && ops->write_conv)
- ops->write_conv(conv, who, alias, displayed, flags, mtime);
-
- add_message_to_history(conv, who, alias, message, flags, mtime);
-
- purple_signal_emit(purple_conversations_get_handle(),
- (type == PURPLE_CONV_TYPE_IM ? "wrote-im-msg" : "wrote-chat-msg"),
- account, who, displayed, conv, flags);
-
- g_free(displayed);
-}
-
gboolean
purple_conversation_has_focus(PurpleConversation *conv)
{
@@ -1200,30 +1051,6 @@ void
}
void
-purple_conv_im_set_icon(PurpleConvIm *im, PurpleBuddyIcon *icon)
-{
- g_return_if_fail(im != NULL);
-
- if (im->icon != icon)
- {
- purple_buddy_icon_unref(im->icon);
-
- im->icon = (icon == NULL ? NULL : purple_buddy_icon_ref(icon));
- }
-
- purple_conversation_update(purple_conv_im_get_conversation(im),
- PURPLE_CONV_UPDATE_ICON);
-}
-
-PurpleBuddyIcon *
-purple_conv_im_get_icon(const PurpleConvIm *im)
-{
- g_return_val_if_fail(im != NULL, NULL);
-
- return im->icon;
-}
-
-void
purple_conv_im_set_typing_state(PurpleConvIm *im, PurpleTypingState state)
{
g_return_if_fail(im != NULL);
@@ -1356,24 +1183,6 @@ void
}
void
-purple_conv_im_write(PurpleConvIm *im, const char *who, const char *message,
- PurpleMessageFlags flags, time_t mtime)
-{
- PurpleConversation *c;
-
- g_return_if_fail(im != NULL);
- g_return_if_fail(message != NULL);
-
- c = purple_conv_im_get_conversation(im);
-
- /* Pass this on to either the ops structure or the default write func. */
- if (c->ui_ops != NULL && c->ui_ops->write_im != NULL)
- c->ui_ops->write_im(c, who, message, flags, mtime);
- else
- purple_conversation_write(c, who, message, flags, mtime);
-}
-
-void
purple_conv_im_send(PurpleConvIm *im, const char *message)
{
purple_conv_im_send_with_flags(im, message, 0);
============================================================
--- libpurple/conversation/conv.h ab68f4cdf147fc2c4308b364de044119170a8ad9
+++ libpurple/conversation/conv.h 2a6546cdb9115d52de39a62aa731b14404af4493
@@ -27,6 +27,8 @@
#ifndef _PURPLE_CONVERSATION_H_
#define _PURPLE_CONVERSATION_H_
+#include "buddyicon.h"
+
G_BEGIN_DECLS
#define PURPLE_TYPE_CONVERSATION purple_conversation_get_type()
@@ -59,6 +61,9 @@ struct _PurpleConversationClass
struct _PurpleConversationClass
{
PurpleObjectClass parent_class;
+
+ gboolean (*send)(PurpleConversation *conv, PurpleMessage *msg);
+ gboolean (*receive)(PurpleConversation *conv, PurpleMessage *msg);
};
GType purple_conversation_get_type (void);
@@ -256,29 +261,6 @@ void *purple_conversation_get_ui_data(Pu
#endif
/**
- * Returns the specified conversation's purple_account.
- *
- * This purple_account represents the user using purple, not the person the user
- * is having a conversation/chat/flame with.
- *
- * @param conv The conversation.
- *
- * @return The conversation's purple_account.
- */
-PurpleAccount *purple_conversation_get_account(const PurpleConversation *conv);
-
-/**
- * Returns the specified conversation's purple_connection.
- *
- * This is the same as purple_conversation_get_user(conv)->gc.
- *
- * @param conv The conversation.
- *
- * @return The conversation's purple_connection.
- */
-PurpleConnection *purple_conversation_get_gc(const PurpleConversation *conv);
-
-/**
* Sets the specified conversation's title.
*
* @param conv The conversation.
@@ -1077,6 +1059,7 @@ const char *purple_conv_chat_get_nick(Pu
const char *purple_conv_chat_get_nick(PurpleConvChat *chat);
#endif
+#if 0
/**
* Finds a chat with the specified chat ID.
*
@@ -1087,7 +1070,6 @@ PurpleConversation *purple_find_chat(con
*/
PurpleConversation *purple_find_chat(const PurpleConnection *gc, int id);
-#if 0
/**
* Lets the core know we left a chat, without destroying it.
* Called from serv_got_chat_left().
@@ -1203,12 +1185,14 @@ gboolean purple_conversation_do_command(
/**************************************************************************/
/*@{*/
+#if 0
/**
* Returns the conversation subsystem handle.
*
* @return The conversation subsystem handle.
*/
void *purple_conversations_get_handle(void);
+#endif
/**
* Initializes the conversation subsystem.
@@ -1267,6 +1251,8 @@ void purple_conversation_set_icon(Purple
void purple_conversation_set_icon(PurpleConversation *conv, PurpleBuddyIcon *icon);
+PurpleBuddyIcon *purple_conversation_get_icon(PurpleConversation *conv);
+
void purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdate update);
PurpleTypingState purple_conversation_get_typing_state(PurpleConversation *conv);
@@ -1283,6 +1269,45 @@ void purple_conversation_write(PurpleCon
void purple_conversation_write(PurpleConversation *conv, PurpleMessage *msg);
+void purple_conversation_write_message(PurpleConversation *conv, const char *message,
+ PurpleMessageFlags flag);
+
+void purple_conversation_present(PurpleConversation *conv);
+
+void purple_conversation_send_confirm(PurpleConversation *conv, const char *message);
+
+/**
+ * Returns the specified conversation's purple_account.
+ *
+ * This purple_account represents the user using purple, not the person the user
+ * is having a conversation/chat/flame with.
+ *
+ * @param conv The conversation.
+ *
+ * @return The conversation's purple_account.
+ */
+PurpleAccount *purple_conversation_get_account(const PurpleConversation *conv);
+
+/**
+ * Returns the specified conversation's purple_connection.
+ *
+ * This is the same as purple_conversation_get_user(conv)->gc.
+ *
+ * @param conv The conversation.
+ *
+ * @return The conversation's purple_connection.
+ */
+PurpleConnection *purple_conversation_get_connection(const PurpleConversation *conv);
+
+/** Returns a PurpleMessage object if the message was sent successfully. If there was
+ * an error, returns NULL. */
+PurpleMessage * purple_conversation_send(PurpleConversation *conv, const char *message, PurpleMessageFlags flags);
+
+/** Returns TRUE if the message was successfully received, and FALSE otherwise (i.e. if
+ * some plugin decides the block the message, e.g. when the user is ignored etc.)
+ */
+gboolean purple_conversation_receive(PurpleConversation *conv, PurpleMessage *msg);
+
#ifdef __cplusplus
}
#endif
============================================================
--- libpurple/server.h 378604ab6158441b1ea1d8e9f89375a10bcbd928
+++ libpurple/server.h 79b516516c3455a36c0d2a3e169604971b8d27c2
@@ -56,7 +56,9 @@ void serv_move_buddy(PurpleBuddy *, Purp
unsigned int serv_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state);
void serv_move_buddy(PurpleBuddy *, PurpleGroup *, PurpleGroup *);
+#if 0
int serv_send_im(PurpleConnection *, const char *, const char *, PurpleMessageFlags flags);
+#endif
/** Get information about an account's attention commands, from the prpl.
*
@@ -141,8 +143,10 @@ void serv_got_typing_stopped(PurpleConne
*/
void serv_got_typing_stopped(PurpleConnection *gc, const char *name);
+#if 0
void serv_got_im(PurpleConnection *gc, const char *who, const char *msg,
PurpleMessageFlags flags, time_t mtime);
+#endif
/**
* @param data The hash function should be g_str_hash() and the equal
============================================================
--- libpurple/conversation/conv-im.c ce5c5be6f3893e2c4d15907a77cf38a1c42ea21f
+++ libpurple/conversation/conv-im.c e480931cc71cf1f32564794dde2ec84bc73ea328
@@ -27,6 +27,7 @@
#include "internal.h"
#include "conversation/conv-im.h"
+#include "prpl.h"
enum
{
@@ -42,6 +43,7 @@ struct _PurpleIMPrivate
struct _PurpleIMPrivate
{
+ int dummy;
};
static void
@@ -78,6 +80,48 @@ purple_im_get_property(GObject *obj, gui
}
}
+static gboolean
+purple_im_send(PurpleConversation *conv, PurpleMessage *msg)
+{
+ PurpleConnection *gc = purple_conversation_get_connection(conv);
+ PurplePlugin *prpl = NULL;
+ PurplePluginProtocolInfo *prpl_info = NULL;
+ int val;
+
+ prpl = purple_connection_get_prpl(gc);
+ prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
+
+ if (!prpl_info->send_im) {
+ g_warning("The PRPL should've had a send_im!\n");
+ return FALSE;
+ }
+
+ val = prpl_info->send_im(gc, purple_conversation_get_name(conv),
+ purple_message_get_message(msg),
+ purple_message_get_flags(msg));
+
+ if (val < 0) {
+ /* TODO: Make the error status available to UI/client. */
+ return FALSE;
+ }
+
+ if (val == 0) {
+ purple_message_set_flags(msg,
+ purple_message_get_flags(msg) | PURPLE_MESSAGE_INVISIBLE);
+ }
+
+ /* TODO: Reset auto-reply */
+
+ return TRUE;
+}
+
+static gboolean
+purple_im_receive(PurpleConversation *conv, PurpleMessage *msg)
+{
+ /* TODO: Setup auto-reply if applicable */
+ return TRUE;
+}
+
static void
purple_im_class_init (PurpleIMClass *klass)
{
@@ -90,6 +134,9 @@ purple_im_class_init (PurpleIMClass *kla
object_class->get_property = purple_im_get_property;
object_class->set_property = purple_im_set_property;
+
+ PURPLE_CONVERSATION_CLASS(klass)->send = purple_im_send;
+ PURPLE_CONVERSATION_CLASS(klass)->receive = purple_im_receive;
}
static void
@@ -98,11 +145,13 @@ PurpleIM*
}
PurpleIM*
-purple_im_new (const PurpleAccount *account, const char *who)
+purple_im_new (PurpleAccount *account, const char *who)
{
PurpleIM *im;
- /* TODO: First, look for an existing IM */
+ im = PURPLE_IM(purple_conversations_find(PURPLE_TYPE_IM, account, who));
+ if (im)
+ return im;
im = g_object_new (PURPLE_TYPE_IM,
"account", account,
@@ -114,3 +163,50 @@ purple_im_new (const PurpleAccount *acco
return im;
}
+/** Returns an IM initiated by a received message. The idea behind having this instead
+ * of simply using purple_im_new and purple_conversation_receive is that if an incoming
+ * message (that would create a new conversation) is blocked for some reason, then we
+ * don't want the conversation to actually exist. So we create a temporary IM
+ * conversation, do purple_conversation_receive, and if that fails, destroy the new IM.
+ * Plugins that want to block incoming messages should be listening to MSG_RECV signal,
+ * and block the message from the callback. Since the 'new' signal is emitted only
+ * after the message has been accepted, the client wouldn't create a UI for the
+ * temporary conversation in case the message has been blocked.
+ *
+ * The caveat is that the MSG_RECV callback won't have this conversation in the list
+ * from purple_conversations_list, since that list is populated by the 'new' callback.
+ *
+ * One interesting note: plugins like bot-sentry can do purple_conversation_send in
+ * the MSG_RECV callbacks.
+ */
+PurpleIM *
+purple_im_new_with_receive(PurpleAccount *account, PurpleMessage *msg)
+{
+ PurpleIM *im;
+ const char *who = purple_message_get_sender(msg);
+ gboolean newim = FALSE;
+
+ im = PURPLE_IM(purple_conversations_find(PURPLE_TYPE_IM, account, who));
+
+ if (!im) {
+ newim = TRUE;
+ im = g_object_new (PURPLE_TYPE_IM,
+ "account", account,
+ "name", who,
+ NULL);
+ }
+
+ if (!purple_conversation_receive(PURPLE_CONVERSATION(im), msg)) {
+ if (newim)
+ g_object_unref(G_OBJECT(im));
+ return NULL;
+ }
+
+ if (newim)
+ g_signal_emit_by_name(G_OBJECT(im), "new");
+
+ purple_conversation_write(PURPLE_CONVERSATION(im), msg);
+
+ return im;
+}
+
============================================================
--- libpurple/conversation/conv-im.h ad0d567073ce0eb8df1e85488aad3f012269057f
+++ libpurple/conversation/conv-im.h cb3f8b5298041d86ae3854725f746a3597ad485e
@@ -60,8 +60,10 @@ GType purple_im_get_type (void);
GType purple_im_get_type (void);
-PurpleIM* purple_im_new (const PurpleAccount *account, const char *who);
+PurpleIM* purple_im_new (PurpleAccount *account, const char *who);
+PurpleIM * purple_im_new_with_receive(PurpleAccount *account, PurpleMessage *msg);
+
G_END_DECLS
#endif
============================================================
--- libpurple/conversation/conv-muc.c 33889b3ed38777a411002aaa4496e99cc828b9a5
+++ libpurple/conversation/conv-muc.c 140b668930d82ec779b2a341cb1e292956b6c226
@@ -22,8 +22,10 @@
#include "conv-muc.h"
+/** GObject stuff {{{ */
enum
{
+ PROP_0,
PROP_TOPIC,
PROP_TOPIC_USER,
PROP_TOPIC_TIME,
@@ -135,6 +137,8 @@ purple_muc_init (PurpleMUC *self)
{
}
+/* }}} */
+
PurpleMUC*
purple_muc_new (PurpleAccount *account, const char *name)
{
@@ -170,3 +174,50 @@ purple_muc_get_nick(PurpleMUC *muc)
return NULL;
}
+const char *
+purple_muc_get_topic(PurpleMUC *muc)
+{
+ /* TODO: */
+ return NULL;
+}
+
+void
+purple_muc_set_topic(PurpleMUC *muc, const char *who, const char *topic, time_t when)
+{
+ /* TODO: */
+}
+
+void
+purple_muc_add_user(PurpleMUC *muc, const char *user,
+ const char *extra_msg, int flags,
+ gboolean new_arrival)
+{
+ /* TODO: */
+}
+
+void
+purple_muc_remove_user(PurpleMUC *muc, const char *user, const char *reason)
+{
+ /* TODO: */
+}
+
+void
+purple_muc_add_users(PurpleMUC *muc, GList *users, GList *extra_msgs,
+ GList *flags, gboolean new_arrivals)
+{
+ /* TODO: */
+}
+
+void
+purple_muc_user_set_flags(PurpleMUC *muc, const char *user, int flags)
+{
+ /* TODO: */
+}
+
+int
+purple_muc_user_get_flags(PurpleMUC *muc, const char *user)
+{
+ /* TODO: */
+ return 0;
+}
+
============================================================
--- libpurple/conversation/conv-muc.h fc1dede8e31464c2478b47b68fb80e202fd82d58
+++ libpurple/conversation/conv-muc.h d6ee7cc1732863deba8a14994fe880f405d48005
@@ -70,6 +70,24 @@ const char * purple_muc_get_nick(PurpleM
const char * purple_muc_get_nick(PurpleMUC *muc);
+const char * purple_muc_get_topic(PurpleMUC *muc);
+
+void purple_muc_set_topic(PurpleMUC *muc, const char *who, const char *topic, time_t when);
+
+void purple_muc_add_user(PurpleMUC *muc, const char *user,
+ const char *extra_msg, int flags,
+ gboolean new_arrival);
+
+void purple_muc_remove_user(PurpleMUC *muc, const char *user, const char *reason);
+
+void purple_muc_add_users(PurpleMUC *muc, GList *users, GList *extra_msgs,
+ GList *flags, gboolean new_arrivals);
+
+void purple_muc_user_set_flags(PurpleMUC *muc, const char *user,
+ int flags);
+
+int purple_muc_user_get_flags(PurpleMUC *muc, const char *user);
+
G_END_DECLS
#endif
============================================================
--- libpurple/conversation/conv.c 1007b49cd34e14c97458dcc0f4ebc1c90cceb45b
+++ libpurple/conversation/conv.c d243a11fbf2f2a1858e74f0163b526c9ab17c76f
@@ -21,18 +21,25 @@
#include "internal.h"
#include "conversation/conv.h"
+#include "marshallers.h"
+#include "gsignal.h"
/** GObject stuff {{{ */
enum
{
+ PROP_0,
PROP_ACCOUNT,
- PROP_NAME
+ PROP_NAME,
+ PROP_BUDDY_ICON,
+ PROP_TYPING_STATE,
+ PROP_LAST
};
enum
{
SIG_MSG_RECEIVE,
SIG_MSG_SEND,
+ SIG_MSG_WRITE,
SIG_LAST
};
@@ -47,8 +54,9 @@ struct _PurpleConversationPrivate
struct _PurpleConversationPrivate
{
- PurpleAccount *account;
+ PurpleAccount *account;
char *name;
+ PurpleBuddyIcon *icon;
};
static void
@@ -65,6 +73,9 @@ purple_conversation_get_property (GObjec
case PROP_NAME:
g_value_set_string(value, priv->name);
break;
+ case PROP_BUDDY_ICON:
+ g_value_set_pointer(value, priv->icon); /* XXX: */
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -85,6 +96,9 @@ purple_conversation_set_property (GObjec
g_free(priv->name);
priv->name = g_strdup(g_value_get_string(value));
break;
+ case PROP_BUDDY_ICON:
+ purple_conversation_set_icon(conv, g_value_get_pointer(value)); /* XXX: */
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -125,6 +139,38 @@ purple_conversation_class_init (PurpleCo
_("The name of the conversation."), NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/* Should we allow changing the name once it's been created? */
+
+ g_object_class_install_property(object_class, PROP_BUDDY_ICON,
+ g_param_spec_pointer("icon", _("Buddy icon"),
+ _("The icon for this conversation."),
+ G_PARAM_READWRITE)); /* XXX: */
+
+
+ /* XXX: Should PurpleMessage be a boxed type? If so, make sure we use the
+ * proper marshaller etc. in the following signals. */
+
+ signals[SIG_MSG_WRITE] = g_signal_new("msg-write", G_TYPE_FROM_CLASS(klass),
+ 0, 0,
+ NULL, NULL,
+ purple_smarshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ /* The signal callbacks should return TRUE if the message has been processed
+ * (i.e. if a plugin wants to block the message from being sent, then it would
+ * return TRUE from the callback).
+ */
+ signals[SIG_MSG_SEND] = g_signal_new("msg-send", G_TYPE_FROM_CLASS(klass),
+ 0, 0,
+ purple_signal_boolean_accumulator, NULL,
+ purple_smarshal_BOOLEAN__POINTER,
+ G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
+
+ /* Same as for SIG_MSG_SEND */
+ signals[SIG_MSG_RECEIVE] = g_signal_new("msg-receive", G_TYPE_FROM_CLASS(klass),
+ 0, 0,
+ purple_signal_boolean_accumulator, NULL,
+ purple_smarshal_BOOLEAN__POINTER,
+ G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
}
static void
@@ -134,14 +180,7 @@ purple_conversation_init (PurpleConversa
/* }}} */
-
void
-purple_conversation_set_icon(PurpleConversation *conv, PurpleBuddyIcon *icon)
-{
- /* TODO: */
-}
-
-void
purple_conversation_update(PurpleConversation *conv, PurpleConversationUpdate update)
{
/* TODO: */
@@ -187,6 +226,142 @@ purple_conversation_write(PurpleConversa
void
purple_conversation_write(PurpleConversation *conv, PurpleMessage *msg)
{
+ /* TODO: If alias is not set in msg, set it */
+ g_signal_emit(G_OBJECT(conv), signals[SIG_MSG_WRITE], 0, msg);
+
+ /* TODO: Add msg to history */
+
+ /* TODO: Do something about logging the message */
+}
+
+void
+purple_conversation_write_message(PurpleConversation *conv, const char *message,
+ PurpleMessageFlags flag)
+{
+ PurpleMessage *msg = purple_message_new(NULL, NULL, message, flag, time(NULL));
+ purple_conversation_write(conv, msg);
+}
+
+const char *
+purple_conversation_get_name(const PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = GET_PRIVATE(conv);
+ g_return_val_if_fail(priv, NULL);
+
+ return priv->name;
+}
+
+PurpleAccount *
+purple_conversation_get_account(const PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = GET_PRIVATE(conv);
+ g_return_val_if_fail(priv, NULL);
+
+ return priv->account;
+}
+
+PurpleConnection *
+purple_conversation_get_connection(const PurpleConversation *conv)
+{
+ PurpleAccount *account = purple_conversation_get_account(conv);
+ g_return_val_if_fail(account, NULL);
+
+ return purple_account_get_connection(account);
+}
+
+void
+purple_conversation_set_icon(PurpleConversation *conv, PurpleBuddyIcon *icon)
+{
+ PurpleConversationPrivate *priv = GET_PRIVATE(conv);
+ g_return_if_fail(priv);
+
+ if (priv->icon)
+ purple_buddy_icon_unref(priv->icon);
+
+ priv->icon = icon ? purple_buddy_icon_ref(icon) : NULL;
+ g_object_notify(G_OBJECT(conv), "icon");
+}
+
+PurpleBuddyIcon *
+purple_conversation_get_icon(PurpleConversation *conv)
+{
+ PurpleConversationPrivate *priv = GET_PRIVATE(conv);
+ g_return_val_if_fail(priv, NULL);
+
+ return priv->icon;
+}
+
+void
+purple_conversation_autoset_title(PurpleConversation *conv)
+{
/* TODO: */
}
+void
+purple_conversation_present(PurpleConversation *conv)
+{
+ /* TODO: */
+}
+
+void
+purple_conversation_send_confirm(PurpleConversation *conv, const char *message)
+{
+ /* TODO: */
+}
+
+PurpleMessage *
+purple_conversation_send(PurpleConversation *conv, const char *message, PurpleMessageFlags flags)
+{
+ PurpleConnection *gc;
+ PurpleMessage *msg;
+ gboolean processed = FALSE;
+
+ gc = purple_conversation_get_connection(conv);
+
+ if (!gc || !PURPLE_CONNECTION_IS_CONNECTED(gc))
+ return NULL;
+
+ msg = purple_message_new(NULL, NULL, message,
+ flags | PURPLE_MESSAGE_SEND, time(NULL));
+ g_signal_emit(G_OBJECT(conv), signals[SIG_MSG_SEND], 0, msg, &processed);
+ if (processed) {
+ purple_message_free(msg);
+ return NULL;
+ }
+
+ if (!PURPLE_CONVERSATION_GET_CLASS(conv)->send(conv, msg)) {
+ purple_message_free(msg);
+ return NULL;
+ }
+
+ /* Reset typing notification. */
+ if (purple_conversation_get_send_typed_timeout(conv))
+ purple_conversation_stop_send_typed_timeout(conv);
+
+ return msg;
+}
+
+gboolean
+purple_conversation_receive(PurpleConversation *conv, PurpleMessage *msg)
+{
+ PurpleAccount *account;
+ gboolean processed = FALSE;
+
+ account = purple_conversation_get_account(conv);
+ if (!purple_privacy_check(account, purple_message_get_sender(msg))) {
+ /* TODO: emit a signal */
+ return FALSE;
+ }
+
+ g_signal_emit(G_OBJECT(conv), signals[SIG_MSG_RECEIVE], 0, msg, &processed);
+ if (processed) {
+ return FALSE;
+ }
+
+ if (!PURPLE_CONVERSATION_GET_CLASS(conv)->receive(conv, msg)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
More information about the Commits
mailing list