talkatu/talkatu

Fix a few things found in review

2020-06-29, Gary Kramlich
a831357ccddd
Fix a few things found in review
/*
* talkatu
* Copyright (C) 2017-2019 Gary Kramlich <grim@reaperworld.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
#include <talkatu/talkatuhistorybuffer.h>
#include <talkatu/talkatutag.h>
#include <talkatu/talkatutagtable.h>
/**
* SECTION:talkatuhistorybuffer
* @Title: History Buffer
* @Short_description: The buffer used for displaying chat history
*
* This buffer is used to displayed the chat history. It has some helper
* methods to make it easier to add messages to it as text should not be
* manually.
*/
/**
* TALKATU_TYPE_HISTORY_BUFFER:
*
* The standard _get_type macro for #TalkatuHistoryBuffer.
*/
/**
* TalkatuHistoryBuffer:
*
* A #TalkatuBuffer subclass that works on #TalkatuMessage's rather than raw
* text.
*/
/**
* TalkatuHistoryBufferClass:
* @write_message: The write_message vfunc is called to render a
* #TalkatuMessage into the #TalkatuHistoryBuffer.
*
* The backing class to #TalkatuHistoryBuffer.
*/
typedef struct {
GtkTextBuffer *buffer;
GtkTextIter *iter;
} TalkatuHistoryBufferForeachAttachmentData;
G_DEFINE_TYPE(TalkatuHistoryBuffer, talkatu_history_buffer, GTK_TYPE_TEXT_BUFFER);
/******************************************************************************
* Helpers
*****************************************************************************/
static void
talkatu_history_buffer_add_attachment(TalkatuAttachment *attachment,
gpointer data)
{
TalkatuHistoryBufferForeachAttachmentData *d = NULL;
GtkTextChildAnchor *anchor = NULL;
d = (TalkatuHistoryBufferForeachAttachmentData *)data;
gtk_text_buffer_insert(d->buffer, d->iter, "\n", -1);
/* we have to create the anchor first so that we can add the attachment to
* it before it's inserted into the buffer.
*/
anchor = gtk_text_child_anchor_new();
g_object_set_data_full(G_OBJECT(anchor), "talkatu:attachment",
g_object_ref(attachment), g_object_unref);
gtk_text_buffer_insert_child_anchor(d->buffer, d->iter, anchor);
g_object_unref(G_OBJECT(anchor));
}
/******************************************************************************
* GObject Stuff
*****************************************************************************/
static void
talkatu_history_buffer_real_write_message(TalkatuHistoryBuffer *talkatu_buffer,
TalkatuMessage *message)
{
TalkatuHistoryBufferForeachAttachmentData data;
GtkTextBuffer *buffer = GTK_TEXT_BUFFER(talkatu_buffer);
GtkTextIter start, end;
GDateTime *timestamp = NULL;
gchar *author = NULL, *contents = NULL;
/* if there's already text in the buffer, insert a newline */
gtk_text_buffer_get_bounds(buffer, &start, &end);
if(!gtk_text_iter_equal(&start, &end)) {
gtk_text_buffer_insert(buffer, &end, "\n", -1);
}
timestamp = talkatu_message_get_timestamp(message);
if(timestamp != NULL) {
gchar *timestamp_str = g_date_time_format(timestamp, "(%-l:%M %p) ");
gtk_text_buffer_insert_with_tags_by_name(
buffer,
&end,
timestamp_str,
-1,
TALKATU_TAG_TIMESTAMP,
NULL
);
g_free(timestamp_str);
g_date_time_unref(timestamp);
}
author = talkatu_message_get_author(message);
gtk_text_buffer_insert_with_tags_by_name(
buffer,
&end,
author,
-1,
TALKATU_TAG_BOLD,
TALKATU_TAG_AUTHOR,
NULL
);
g_free(author);
/* insert a space after the author */
gtk_text_buffer_insert(buffer, &end, " ", -1);
contents = talkatu_message_get_contents(message);
gtk_text_buffer_insert_with_tags_by_name(
buffer,
&end,
contents,
-1,
TALKATU_TAG_CONTENTS,
NULL
);
g_free(contents);
/* add any and all attachments */
data.buffer = buffer;
data.iter = &end;
talkatu_message_foreach_attachment(message,
talkatu_history_buffer_add_attachment,
&data);
}
/******************************************************************************
* GObject Stuff
*****************************************************************************/
static void
talkatu_history_buffer_init(TalkatuHistoryBuffer *buffer) {
}
static void
talkatu_history_buffer_class_init(TalkatuHistoryBufferClass *klass) {
klass->write_message = talkatu_history_buffer_real_write_message;
}
/******************************************************************************
* Public API
*****************************************************************************/
/**
* talkatu_history_buffer_new:
*
* Creates a new TalkatuHistoryBuffer for display conversation history.
*
* Returns: (transfer full): The #TalkatuHistoryBuffer instance.
*/
GtkTextBuffer *
talkatu_history_buffer_new(void) {
return GTK_TEXT_BUFFER(g_object_new(
TALKATU_TYPE_HISTORY_BUFFER,
"tag-table", talkatu_tag_table_new(),
NULL
));
}
/**
* talkatu_history_buffer_write_message:
* @buffer: The #TalkatuHistoryBuffer instance.
* @message: The #TalkatuMessage to write.
*
* Writes @message to @buffer.
*/
void
talkatu_history_buffer_write_message(TalkatuHistoryBuffer *buffer,
TalkatuMessage *message)
{
TalkatuHistoryBufferClass *klass = NULL;
g_return_if_fail(TALKATU_IS_HISTORY_BUFFER(buffer));
g_return_if_fail(message != NULL);
klass = TALKATU_HISTORY_BUFFER_GET_CLASS(buffer);
if(klass && klass->write_message) {
klass->write_message(buffer, message);
}
}