/soc/2015/igor.gajowiak/chatlog: c7be85360543: Implemented loadi...

Igor Gajowiak igor.gajowiak at gmail.com
Sun Aug 16 16:07:46 EDT 2015


Changeset: c7be853605438f5d2fbba47cc77a0877645370a0
Author:	 Igor Gajowiak <igor.gajowiak at gmail.com>
Date:	 2015-08-16 22:07 +0200
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/igor.gajowiak/chatlog/rev/c7be85360543

Description:

Implemented loading history into a conversation window.

diffstat:

 libpurple/conversation.c          |  181 +++++++++++++++++++++++++++++++++++
 libpurple/conversation.h          |   16 +++
 libpurple/conversationtypes.c     |   11 ++
 libpurple/genericlog.c            |    6 +-
 libpurple/genericlog.h            |   22 ++--
 libpurple/internal.h              |    2 +
 libpurple/plugins/log/logsqlite.c |  112 ++++++++++++++++-----
 pidgin/gtkconv.c                  |  195 ++++++++++++++++++++++++++++++++++++++
 pidgin/gtkwebview.h               |    3 +-
 pidgin/gtkwebviewtoolbar.c        |   39 +++++++-
 pidgin/themes/Template.html       |   10 +
 11 files changed, 552 insertions(+), 45 deletions(-)

diffs (truncated from 939 to 300 lines):

diff --git a/libpurple/conversation.c b/libpurple/conversation.c
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -65,6 +65,8 @@ struct _PurpleConversationPrivate
 	 * but we don't have any class for people not on our buddy
 	 * list (PurpleDude?). So, if we have one, we should switch to it. */
 	PurpleSmileyList *remote_smileys;
+
+	PurpleMessage *oldest_msg;
 };
 
 /* GObject Property enums */
@@ -776,6 +778,120 @@ void
 		conv, pmsg);
 }
 
+static void
+purple_conversation_set_oldest_msg(PurpleConversation *conv,
+	PurpleMessage* msg)
+{
+	g_return_if_fail(conv != NULL);
+
+	PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+	g_return_if_fail(priv != NULL);
+
+	if (priv->oldest_msg == msg)
+		return;
+
+	g_object_unref(G_OBJECT(priv->oldest_msg));
+
+	if (msg)
+		g_object_ref(G_OBJECT(msg));
+	priv->oldest_msg = msg;
+}
+
+// TODO: Implemenatation copied from _purple_conversation_write_common, try to refactor
+void
+_purple_conversation_prepend_common(PurpleConversation *conv, PurpleMessage *pmsg)
+{
+	PurpleProtocol *protocol = NULL;
+	PurpleConnection *gc = NULL;
+	PurpleAccount *account;
+	PurpleConversationUiOps *ops;
+	PurpleBuddy *b;
+	int plugin_return;
+	PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+	/* int logging_font_options = 0; */
+
+	g_return_if_fail(priv != NULL);
+	g_return_if_fail(pmsg != NULL);
+
+	ops = purple_conversation_get_ui_ops(conv);
+
+	account = purple_conversation_get_account(conv);
+
+	if (account != NULL)
+		gc = purple_account_get_connection(account);
+
+	if (PURPLE_IS_CHAT_CONVERSATION(conv) &&
+		(gc != NULL && !g_slist_find(purple_connection_get_active_chats(gc), conv)))
+		return;
+
+	if (PURPLE_IS_IM_CONVERSATION(conv) &&
+		!g_list_find(purple_conversations_get_all(), conv))
+		return;
+
+	plugin_return = GPOINTER_TO_INT(purple_signal_emit_return_1(
+		purple_conversations_get_handle(),
+		(PURPLE_IS_IM_CONVERSATION(conv) ? "writing-im-msg" : "writing-chat-msg"),
+		conv, pmsg));
+
+	if (purple_message_is_empty(pmsg))
+		return;
+
+	if (plugin_return)
+		return;
+
+	if (account != NULL) {
+		protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+
+		if (PURPLE_IS_IM_CONVERSATION(conv) ||
+			!(purple_protocol_get_options(protocol) & OPT_PROTO_UNIQUE_CHATNAME)) {
+
+			if (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_SEND) {
+				const gchar *alias;
+
+				b = purple_blist_find_buddy(account,
+					purple_account_get_username(account));
+
+				if (purple_account_get_private_alias(account) != NULL)
+					alias = purple_account_get_private_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);
+
+				purple_message_set_author_alias(pmsg, alias);
+			}
+			else if (purple_message_get_flags(pmsg) & PURPLE_MESSAGE_RECV)
+			{
+				/* TODO: PurpleDude - folks not on the buddy list */
+				b = purple_blist_find_buddy(account,
+					purple_message_get_author(pmsg));
+
+				if (b != NULL) {
+					purple_message_set_author_alias(pmsg,
+						purple_buddy_get_contact_alias(b));
+				}
+			}
+		}
+	}
+
+	if (ops) {
+		if (PURPLE_IS_CHAT_CONVERSATION(conv) && ops->prepend_chat)
+			ops->prepend_chat(PURPLE_CHAT_CONVERSATION(conv), pmsg);
+		else if (PURPLE_IS_IM_CONVERSATION(conv) && ops->prepend_im)
+			ops->prepend_im(PURPLE_IM_CONVERSATION(conv), pmsg);
+		else if (ops->prepend_conv)
+			ops->prepend_conv(conv, pmsg);
+	}
+
+	purple_signal_emit(purple_conversations_get_handle(),
+		(PURPLE_IS_IM_CONVERSATION(conv) ? "wrote-im-msg" : "wrote-chat-msg"),
+		conv, pmsg);
+}
+
 void
 purple_conversation_write_message(PurpleConversation *conv, PurpleMessage *msg)
 {
@@ -787,6 +903,12 @@ purple_conversation_write_message(Purple
 
 	if (klass && klass->write_message)
 		klass->write_message(conv, msg);
+
+	PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+	g_return_if_fail(priv != NULL);
+
+	if (msg && priv->oldest_msg == NULL)
+		purple_conversation_set_oldest_msg(conv, msg);
 }
 
 void
@@ -805,6 +927,63 @@ purple_conversation_replace_message(Purp
 		klass->replace_message(conv, replaced_msg_id, msg);
 }
 
+static void
+purple_conversation_prepend_message(PurpleConversation *conv,
+	PurpleMessage *msg)
+{
+	PurpleConversationClass *klass = NULL;
+
+	g_return_if_fail(PURPLE_IS_CONVERSATION(conv));
+	g_return_if_fail(msg != NULL);
+
+	klass = PURPLE_CONVERSATION_GET_CLASS(conv);
+
+	if (klass && klass->prepend_message)
+		klass->prepend_message(conv, msg);
+}
+
+void
+purple_conversation_load_older_msgs(PurpleConversation *conv,
+	guint limit)
+{
+	g_return_if_fail(conv != NULL);
+	g_return_if_fail(limit > 0);
+
+	PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
+	g_return_if_fail(priv != NULL);
+
+	PurpleAccount *account = purple_conversation_get_account(conv);
+	PurpleMessage *oldest_msg = priv->oldest_msg;
+
+	PurpleBlistNode *contact = NULL;
+	if (PURPLE_IS_CHAT_CONVERSATION(conv)) {
+		contact = PURPLE_BLIST_NODE(purple_blist_find_chat(account,
+			purple_conversation_get_name(conv)));
+	}
+	else {
+		contact = PURPLE_BLIST_NODE(purple_blist_find_buddy(account,
+			purple_conversation_get_name(conv)));
+	}
+
+	g_return_if_fail(contact != NULL);
+
+	GList *messages = NULL;
+	if (!purple_genericlog_get_older_msgs(contact, oldest_msg,
+			limit, &messages, NULL)) {
+		return;
+	}
+
+	GList *it;
+	for (it = g_list_last(messages); it != NULL; it = it->prev) {
+		oldest_msg = PURPLE_MESSAGE(it->data);
+		purple_conversation_prepend_message(conv, oldest_msg);
+	}
+
+	purple_conversation_set_oldest_msg(conv, oldest_msg);
+
+	g_list_free_full(messages, g_object_unref);
+}
+
 void purple_conversation_write_system_message(PurpleConversation *conv,
 	const gchar *message, PurpleMessageFlags flags)
 {
@@ -974,6 +1153,8 @@ void purple_conversation_clear_message_h
 	g_list_free_full(list, g_object_unref);
 	priv->message_history = NULL;
 
+	purple_conversation_set_oldest_msg(conv, NULL);
+
 	purple_signal_emit(purple_conversations_get_handle(),
 			"cleared-message-history", conv);
 }
diff --git a/libpurple/conversation.h b/libpurple/conversation.h
--- a/libpurple/conversation.h
+++ b/libpurple/conversation.h
@@ -182,6 +182,8 @@ struct _PurpleConversationClass {
 
 	void (*replace_message)(PurpleConversation *conv, guint replaced_msg_id, PurpleMessage *msg);
 
+	void (*prepend_message)(PurpleConversation *conv, PurpleMessage *msg);
+
 	/*< private >*/
 	void (*_purple_reserved1)(void);
 	void (*_purple_reserved2)(void);
@@ -258,6 +260,10 @@ struct _PurpleConversationUiOps
 	void (*replace_im)(PurpleIMConversation *im, guint replaced_msg_id, PurpleMessage *msg);
 	void (*replace_conv)(PurpleConversation *conv, guint replaced_msg_id, PurpleMessage *msg);
 
+	void (*prepend_chat)(PurpleChatConversation *conv, PurpleMessage *msg);
+	void (*prepend_im)(PurpleIMConversation *conv, PurpleMessage *msg);
+	void (*prepend_conv)(PurpleConversation *conv, PurpleMessage *msg);
+
 	void (*chat_add_users)(PurpleChatConversation *chat,
 	                       GList *cbuddies,
 	                       gboolean new_arrivals);
@@ -489,6 +495,16 @@ void purple_conversation_replace_message
 	guint replaced_msg_id, PurpleMessage *msg);
 
 /**
+ * purple_conversation_load_older_msgs:
+ * @conv:  The conversation.
+ * @limit: The number of messages to load.
+ *
+ * Loads up to limit messages from a log to the given conversation.
+ */
+void purple_conversation_load_older_msgs(PurpleConversation *conv,
+	guint limit);
+
+/**
  * purple_conversation_write_system_message:
  * @conv:    The conversation.
  * @message: The message to write.
diff --git a/libpurple/conversationtypes.c b/libpurple/conversationtypes.c
--- a/libpurple/conversationtypes.c
+++ b/libpurple/conversationtypes.c
@@ -386,6 +386,16 @@ im_conversation_replace_message(PurpleCo
 	_purple_conversation_replace_common(conv, replaced_msg_id, msg);
 }
 
+static void
+im_conversation_prepend_message(PurpleConversation *conv, PurpleMessage *msg)
+{
+	PurpleIMConversation *im = PURPLE_IM_CONVERSATION(conv);
+	g_return_if_fail(im != NULL);
+	g_return_if_fail(msg != NULL);
+
+	_purple_conversation_prepend_common(conv, msg);
+}
+
 /**************************************************************************
  * GObject code for IMs
  **************************************************************************/
@@ -527,6 +537,7 @@ static void purple_im_conversation_class
 
 	conv_class->write_message = im_conversation_write_message;
 	conv_class->replace_message = im_conversation_replace_message;
+	conv_class->prepend_message = im_conversation_prepend_message;
 
 	g_type_class_add_private(klass, sizeof(PurpleIMConversationPrivate));
 
diff --git a/libpurple/genericlog.c b/libpurple/genericlog.c
--- a/libpurple/genericlog.c
+++ b/libpurple/genericlog.c
@@ -299,15 +299,15 @@ purple_genericlog_get_all_msgs(PurpleBli
 }
 
 gboolean
-purple_genericlog_get_older_msgs(PurpleBlistNode *contact, guint64 timestamp,
-	PurpleMessage *message, GList **result, GError **error)
+purple_genericlog_get_older_msgs(PurpleBlistNode *contact,
+	PurpleMessage *message, guint limit, GList **result, GError **error)
 {
 	GENERICLOG_CHECK_CONTACT(contact);



More information about the Commits mailing list