talkatu/talkatu

Parents f9989cac8f7a
Children 06b60cbecd02
Implement the TalkatuMessage interface with TalkatuInput, delete TalkatuDemoMessage, and change TalkatuAttachment's id from gint64 to guint64
--- a/demo/meson.build Tue Jan 28 21:53:46 2020 -0600
+++ b/demo/meson.build Wed Jan 29 08:35:45 2020 -0600
@@ -3,8 +3,6 @@
###############################################################################
sources = [
'talkatudemo.c',
- 'talkatudemomessage.c',
- 'talkatudemomessage.h',
'talkatudemowindow.c',
'talkatudemowindow.h',
]
--- a/demo/talkatudemomessage.c Tue Jan 28 21:53:46 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-/*
- * 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 "talkatudemomessage.h"
-
-struct _TalkatuDemoMessage {
- GObject parent;
-
- guint64 id;
- GDateTime *timestamp;
- TalkatuContentType content_type;
- gchar *author;
- gchar *contents;
-};
-
-enum {
- PROP_0,
- N_PROPERTIES,
- /* overrides */
- PROP_ID = N_PROPERTIES,
- PROP_CONTENT_TYPE,
- PROP_AUTHOR,
- PROP_CONTENTS,
- PROP_TIMESTAMP,
-};
-
-static void
-talkatu_demo_message_iface_init(TalkatuMessageInterface *iface) {
-}
-
-G_DEFINE_TYPE_EXTENDED(
- TalkatuDemoMessage,
- talkatu_demo_message,
- G_TYPE_OBJECT,
- 0,
- G_IMPLEMENT_INTERFACE(TALKATU_TYPE_MESSAGE, talkatu_demo_message_iface_init)
-);
-
-/******************************************************************************
- * Accessors
- *****************************************************************************/
-static guint64
-talkatu_demo_message_get_id(TalkatuDemoMessage *message) {
- return message->id;
-}
-
-static void
-talkatu_demo_message_set_id(TalkatuDemoMessage *message, guint64 id) {
- message->id = id;
-
- g_object_notify(G_OBJECT(message), "id");
-}
-
-static GDateTime *
-talkatu_demo_message_get_timestamp(TalkatuDemoMessage *message) {
- return (message->timestamp) ? g_date_time_ref(message->timestamp) : NULL;
-}
-
-static void
-talkatu_demo_message_set_timestamp(TalkatuDemoMessage *message, GDateTime *timestamp) {
- g_clear_pointer(&message->timestamp, g_date_time_unref);
-
- if(timestamp) {
- message->timestamp = g_date_time_ref(timestamp);
- }
-}
-
-static TalkatuContentType
-talkatu_demo_message_get_content_type(TalkatuDemoMessage *message) {
- return message->content_type;
-}
-
-static void
-talkatu_demo_message_set_content_type(TalkatuDemoMessage *message, TalkatuContentType content_type) {
- message->content_type = content_type;
-
- g_object_notify(G_OBJECT(message), "content-type");
-}
-
-static gchar *
-talkatu_demo_message_get_author(TalkatuDemoMessage *message) {
- return message->author;
-}
-
-static void
-talkatu_demo_message_set_author(TalkatuDemoMessage *message, const gchar *author) {
- g_free(message->author);
-
- message->author = g_strdup(author);
-
- g_object_notify(G_OBJECT(message), "author");
-}
-
-static gchar *
-talkatu_demo_message_get_contents(TalkatuDemoMessage *message) {
- return message->contents;
-}
-
-static void
-talkatu_demo_message_set_contents(TalkatuDemoMessage *message, const gchar *contents) {
- g_free(message->contents);
-
- message->contents = g_strdup(contents);
-
- g_object_notify(G_OBJECT(message), "contents");
-}
-
-/******************************************************************************
- * GObject Stuff
- *****************************************************************************/
-static void
-talkatu_demo_message_get_property(GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TalkatuDemoMessage *message = TALKATU_DEMO_MESSAGE(obj);
-
- switch(prop_id) {
- case PROP_ID:
- g_value_set_uint64(value, talkatu_demo_message_get_id(message));
- break;
- case PROP_TIMESTAMP:
- g_value_set_pointer(value, talkatu_demo_message_get_timestamp(message));
- break;
- case PROP_CONTENT_TYPE:
- g_value_set_enum(value, talkatu_demo_message_get_content_type(message));
- break;
- case PROP_AUTHOR:
- g_value_set_string(value, talkatu_demo_message_get_author(message));
- break;
- case PROP_CONTENTS:
- g_value_set_string(value, talkatu_demo_message_get_contents(message));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-talkatu_demo_message_set_property(GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TalkatuDemoMessage *message = TALKATU_DEMO_MESSAGE(obj);
-
- switch(prop_id) {
- case PROP_ID:
- talkatu_demo_message_set_id(message, g_value_get_uint64(value));
- break;
- case PROP_TIMESTAMP:
- talkatu_demo_message_set_timestamp(message, g_value_get_pointer(value));
- break;
- case PROP_CONTENT_TYPE:
- talkatu_demo_message_set_content_type(message, g_value_get_enum(value));
- break;
- case PROP_AUTHOR:
- talkatu_demo_message_set_author(message, g_value_get_string(value));
- break;
- case PROP_CONTENTS:
- talkatu_demo_message_set_contents(message, g_value_get_string(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-talkatu_demo_message_finalize(GObject *obj) {
- TalkatuDemoMessage *message = TALKATU_DEMO_MESSAGE(obj);
-
- talkatu_demo_message_set_timestamp(message, NULL);
- talkatu_demo_message_set_author(message, NULL);
- talkatu_demo_message_set_contents(message, NULL);
-
- G_OBJECT_CLASS(talkatu_demo_message_parent_class)->finalize(obj);
-}
-
-static void
-talkatu_demo_message_init(TalkatuDemoMessage *toolbar) {
-}
-
-static void
-talkatu_demo_message_class_init(TalkatuDemoMessageClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
- obj_class->get_property = talkatu_demo_message_get_property;
- obj_class->set_property = talkatu_demo_message_set_property;
- obj_class->finalize = talkatu_demo_message_finalize;
-
- g_object_class_override_property(obj_class, PROP_ID, "id");
- g_object_class_override_property(obj_class, PROP_TIMESTAMP, "timestamp");
- g_object_class_override_property(obj_class, PROP_CONTENT_TYPE, "content-type");
- g_object_class_override_property(obj_class, PROP_AUTHOR, "author");
- g_object_class_override_property(obj_class, PROP_CONTENTS, "contents");
-}
-
-/******************************************************************************
- * Public API
- *****************************************************************************/
-TalkatuMessage *talkatu_demo_message_new(guint64 id,
- TalkatuContentType content_type,
- const gchar *author,
- const gchar *contents)
-{
- GObject *obj = NULL;
- GDateTime *timestamp = g_date_time_new_now_local();
-
- obj = g_object_new(
- TALKATU_TYPE_DEMO_MESSAGE,
- "id", id,
- "timestamp", timestamp,
- "content-type", content_type,
- "author", author,
- "contents", contents,
- NULL
- );
-
- g_date_time_unref(timestamp);
-
- return TALKATU_MESSAGE(obj);
-}
--- a/demo/talkatudemomessage.h Tue Jan 28 21:53:46 2020 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * 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/>.
- */
-
-#ifndef TALKATU_DEMO_MESSAGE_H
-#define TALKATU_DEMO_MESSAGE_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include <talkatu/talkatu.h>
-
-G_BEGIN_DECLS
-
-#define TALKATU_TYPE_DEMO_MESSAGE (talkatu_demo_message_get_type())
-
-G_DECLARE_FINAL_TYPE(TalkatuDemoMessage, talkatu_demo_message, TALKATU_DEMO, MESSAGE, GObject)
-
-TalkatuMessage *talkatu_demo_message_new(guint64 id, TalkatuContentType content_type, const gchar *author, const gchar *message);
-
-G_END_DECLS
-
-#endif /* TALKATU_DEMO_MESSAGE_H */
--- a/demo/talkatudemowindow.c Tue Jan 28 21:53:46 2020 -0600
+++ b/demo/talkatudemowindow.c Wed Jan 29 08:35:45 2020 -0600
@@ -19,7 +19,6 @@
#include <gtk/gtk.h>
#include "talkatudemowindow.h"
-#include "talkatudemomessage.h"
struct _TalkatuDemoWindow {
GtkWindow parent;
@@ -45,7 +44,6 @@
GtkWidget *author_button;
GtkWidget *author_popover;
GtkWidget *author_item;
- gchar *author;
};
G_DEFINE_TYPE(TalkatuDemoWindow, talkatu_demo_window, GTK_TYPE_WINDOW);
@@ -204,36 +202,27 @@
}
static void
-talkatu_demo_window_view_send_message_cb(TalkatuView *view, gpointer data) {
+talkatu_demo_window_view_send_message_cb(TalkatuInput *input, gpointer data) {
TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
- TalkatuContentType content_type = TALKATU_CONTENT_TYPE_PLAIN;
- gchar *plain_text = NULL;
- TalkatuMessage *message = NULL;
- GtkTextBuffer *input = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
static guint64 id = 0;
if(TALKATU_IS_HTML_BUFFER(input)) {
- content_type = TALKATU_CONTENT_TYPE_HTML;
+ talkatu_message_set_content_type(TALKATU_MESSAGE(input),
+ TALKATU_CONTENT_TYPE_HTML);
} else if(TALKATU_IS_MARKDOWN_BUFFER(input)) {
- content_type = TALKATU_CONTENT_TYPE_MARKDOWN;
+ talkatu_message_set_content_type(TALKATU_MESSAGE(input),
+ TALKATU_CONTENT_TYPE_MARKDOWN);
}
- plain_text = talkatu_buffer_get_plain_text(TALKATU_BUFFER(input));
- message = talkatu_demo_message_new(
- id++,
- content_type,
- window->author,
- plain_text
- );
- g_free(plain_text);
+ talkatu_message_set_id(TALKATU_MESSAGE(input), id++);
talkatu_history_buffer_write_message(
TALKATU_HISTORY_BUFFER(window->buffer_history),
- message
+ TALKATU_MESSAGE(input)
);
- talkatu_buffer_clear(TALKATU_BUFFER(input));
- g_object_unref(G_OBJECT(message));
+ talkatu_message_set_contents(TALKATU_MESSAGE(input), "");
+ talkatu_message_clear_attachments(TALKATU_MESSAGE(input));
}
static gboolean
@@ -266,8 +255,11 @@
TalkatuDemoWindow *window = TALKATU_DEMO_WINDOW(data);
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(item))) {
- g_free(window->author);
- window->author = g_strdup(gtk_button_get_label(GTK_BUTTON(item)));
+ TalkatuEditor *editor = TALKATU_EDITOR(window->editor);
+ GtkWidget *input = talkatu_editor_get_input(editor);
+
+ talkatu_message_set_author(TALKATU_MESSAGE(input),
+ gtk_button_get_label(GTK_BUTTON(item)));
}
}
--- a/talkatu/talkatuattachment.c Tue Jan 28 21:53:46 2020 -0600
+++ b/talkatu/talkatuattachment.c Wed Jan 29 08:35:45 2020 -0600
@@ -44,6 +44,8 @@
struct _TalkatuAttachment {
GObject parent;
+ guint64 id;
+
gchar *content_type;
gchar *filename;
GBytes *contents;
@@ -56,6 +58,7 @@
enum {
PROP_0 = 0,
+ PROP_ID,
PROP_CONTENT_TYPE,
PROP_FILENAME,
PROP_CONTENTS,
@@ -67,6 +70,13 @@
* Private Setters
*****************************************************************************/
static void
+talkatu_attachment_set_id(TalkatuAttachment *attachment, guint64 id) {
+ attachment->id = id;
+
+ g_object_notify_by_pspec(G_OBJECT(attachment), properties[PROP_ID]);
+}
+
+static void
talkatu_attachment_set_content_type(TalkatuAttachment *attachment,
const gchar *content_type)
{
@@ -111,6 +121,9 @@
TalkatuAttachment *attachment = TALKATU_ATTACHMENT(obj);
switch(prop_id) {
+ case PROP_ID:
+ g_value_set_uint64(value, talkatu_attachment_get_id(attachment));
+ break;
case PROP_CONTENT_TYPE:
g_value_set_string(value, talkatu_attachment_get_content_type(attachment));
break;
@@ -131,6 +144,9 @@
TalkatuAttachment *attachment = TALKATU_ATTACHMENT(obj);
switch(prop_id) {
+ case PROP_ID:
+ talkatu_attachment_set_id(attachment, g_value_get_uint64(value));
+ break;
case PROP_CONTENT_TYPE:
talkatu_attachment_set_content_type(attachment, g_value_get_string(value));
break;
@@ -159,7 +175,7 @@
}
static void
-talkatu_attachment_init(TalkatuAttachment *tag) {
+talkatu_attachment_init(TalkatuAttachment *attachment) {
}
static void
@@ -171,6 +187,12 @@
obj_class->finalize = talkatu_attachment_finalize;
/* add our properties */
+ properties[PROP_ID] = g_param_spec_uint64(
+ "id", "id", "The identifier of the attachment",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
+ );
+
properties[PROP_CONTENT_TYPE] = g_param_spec_string(
"content-type", "content-type", "The content type of the attachment",
"application/octet-stream",
@@ -198,6 +220,7 @@
/**
* talkatu_attachment_new:
+ * @id: The identifier of the attachment.
* @content_type: The content type of the attachment.
* @filename: The filename of the attachment.
* @contents: A #GBytes that contains the data of the attachment.
@@ -207,8 +230,8 @@
* Returns: (transfer full): The new #TalkatuAttachment.
*/
TalkatuAttachment *
-talkatu_attachment_new(const gchar *content_type, const gchar *filename,
- GBytes *contents)
+talkatu_attachment_new(guint64 id, const gchar *content_type,
+ const gchar *filename, GBytes *contents)
{
g_return_val_if_fail(content_type != NULL, NULL);
g_return_val_if_fail(filename != NULL, NULL);
@@ -216,6 +239,7 @@
return TALKATU_ATTACHMENT(g_object_new(
TALKATU_TYPE_ATTACHMENT,
+ "id", id,
"content-type", content_type,
"filename", filename,
"contents", contents,
@@ -225,6 +249,7 @@
/**
* talkatu_attachment_new_from_pixbuf:
+ * @id: The identifier of the attachment.
* @filename: The filename of the attachment.
* @pixbuf: The #GdkPixbuf to create an attachment for.
*
@@ -233,7 +258,9 @@
* Returns: (transfer full): The new #TalkatuAttachment.
*/
TalkatuAttachment *
-talkatu_attachment_new_from_pixbuf(const gchar *filename, GdkPixbuf *pixbuf) {
+talkatu_attachment_new_from_pixbuf(guint64 id, const gchar *filename,
+ GdkPixbuf *pixbuf)
+{
TalkatuAttachment *attachment = NULL;
GBytes *contents = NULL;
GError *error = NULL;
@@ -256,7 +283,7 @@
contents = g_bytes_new_take(data, data_sz);
- attachment = talkatu_attachment_new("image/png", filename, contents);
+ attachment = talkatu_attachment_new(id, "image/png", filename, contents);
g_bytes_unref(contents);
@@ -264,6 +291,38 @@
}
/**
+ * talkatu_attachment_get_id:
+ * @attachment: The #TalkatuAttachment instance.
+ *
+ * Gets the ID associated with @attachment.
+ *
+ * Returns: The ID of @attachment.
+ */
+guint64
+talkatu_attachment_get_id(TalkatuAttachment *attachment) {
+ g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), 0);
+
+ return attachment->id;
+}
+
+/**
+ * talkatu_attachment_get_hash_key:
+ * @attachment: The #TalkatuAttachment instance.
+ *
+ * Gets the hash key of @attachment. This should only be used when
+ * trying to address a #TalkatuAttachment in a #GHashTable that is using
+ * #g_int64_hash as the key function.
+ *
+ * Returns: (transfer none): The hash key of @attachment.
+ */
+guint64 *
+talkatu_attachment_get_hash_key(TalkatuAttachment *attachment) {
+ g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
+
+ return &attachment->id;
+}
+
+/**
* talkatu_attachment_get_content_type:
* @attachment: The #TalkatuAttachment instance.
*
--- a/talkatu/talkatuattachment.h Tue Jan 28 21:53:46 2020 -0600
+++ b/talkatu/talkatuattachment.h Wed Jan 29 08:35:45 2020 -0600
@@ -33,8 +33,11 @@
typedef void (*TalkatuAttachmentForeachFunc)(TalkatuAttachment *attachment, gpointer data);
-TalkatuAttachment *talkatu_attachment_new(const gchar *content_type, const gchar *filename, GBytes *contents);
-TalkatuAttachment *talkatu_attachment_new_from_pixbuf(const gchar *filename, GdkPixbuf *pixbuf);
+TalkatuAttachment *talkatu_attachment_new(guint64 id, const gchar *content_type, const gchar *filename, GBytes *contents);
+TalkatuAttachment *talkatu_attachment_new_from_pixbuf(guint64 id, const gchar *filename, GdkPixbuf *pixbuf);
+
+guint64 talkatu_attachment_get_id(TalkatuAttachment *attachment);
+guint64 *talkatu_attachment_get_hash_key(TalkatuAttachment *attachment);
const gchar *talkatu_attachment_get_content_type(TalkatuAttachment *attachment);
const gchar *talkatu_attachment_get_filename(TalkatuAttachment *attachment);
--- a/talkatu/talkatubuffer.c Tue Jan 28 21:53:46 2020 -0600
+++ b/talkatu/talkatubuffer.c Wed Jan 29 08:35:45 2020 -0600
@@ -673,6 +673,7 @@
g_return_val_if_fail(TALKATU_IS_BUFFER(buffer), NULL);
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer), &start, &end);
+
return gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &start, &end, FALSE);
}
--- a/talkatu/talkatuinput.c Tue Jan 28 21:53:46 2020 -0600
+++ b/talkatu/talkatuinput.c Wed Jan 29 08:35:45 2020 -0600
@@ -1,6 +1,6 @@
/*
* talkatu
- * Copyright (C) 2017-2019 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2020 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
@@ -25,10 +25,13 @@
#include "talkatu/talkatuattachmentdialog.h"
#include "talkatu/talkatuenums.h"
#include "talkatu/talkatumarkup.h"
+#include "talkatu/talkatumessage.h"
typedef struct {
TalkatuView parent;
+ GHashTable *attachments;
+
GspellTextView *gspell_view;
TalkatuInputSendBinding send_binding;
@@ -37,12 +40,33 @@
* is updated via cursor-moved and button-press callbacks.
*/
GtkTextMark *context_mark;
+
+ /* TalkatuMessage properties: content type and contents are derived from
+ * the widget itself.
+ */
+ guint64 id;
+ GDateTime *timestamp;
+ TalkatuContentType content_type;
+ gchar *author;
+ gboolean edited;
} TalkatuInputPrivate;
+typedef struct {
+ TalkatuAttachmentForeachFunc func;
+ gpointer data;
+} TalkatuInputForeachAttachmentData;
+
enum {
PROP_0 = 0,
PROP_SEND_BINDING,
N_PROPERTIES,
+ /* overrides */
+ PROP_ID = N_PROPERTIES,
+ PROP_TIMESTAMP,
+ PROP_CONTENT_TYPE,
+ PROP_AUTHOR,
+ PROP_CONTENTS,
+ PROP_EDITED,
};
static GParamSpec *properties[N_PROPERTIES];
@@ -53,7 +77,209 @@
};
static guint signals[LAST_SIGNAL] = {0, };
-G_DEFINE_TYPE_WITH_PRIVATE(TalkatuInput, talkatu_input, TALKATU_TYPE_VIEW)
+static void talkatu_input_message_init(TalkatuMessageInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED(
+ TalkatuInput, talkatu_input, TALKATU_TYPE_VIEW,
+ 0,
+ G_ADD_PRIVATE(TalkatuInput)
+ G_IMPLEMENT_INTERFACE(TALKATU_TYPE_MESSAGE, talkatu_input_message_init)
+);
+
+/******************************************************************************
+ * TalkatuMessage Interface
+ *****************************************************************************/
+static guint64
+talkatu_input_get_id(TalkatuInput *input) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ return priv->id;
+}
+
+static void
+talkatu_input_set_id(TalkatuInput *input, guint64 id) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ priv->id = id;
+
+ g_object_notify(G_OBJECT(input), "id");
+}
+
+static GDateTime *
+talkatu_input_get_timestamp(TalkatuInput *input) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+
+ return priv->timestamp;
+}
+
+static void
+talkatu_input_set_timestamp(TalkatuInput *input, GDateTime *timestamp) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ g_clear_pointer(&priv->timestamp, g_date_time_unref);
+ if(timestamp != NULL) {
+ priv->timestamp = g_date_time_ref(timestamp);
+ }
+
+ g_object_notify(G_OBJECT(input), "timestamp");
+}
+
+static TalkatuContentType
+talkatu_input_get_content_type(TalkatuInput *input) {
+ /* TODO: look at our buffer and map it */
+ return TALKATU_CONTENT_TYPE_PLAIN;
+}
+
+static void
+talkatu_input_set_content_type(TalkatuInput *input,
+ TalkatuContentType content_type)
+{
+ /* TODO: set the buffer here? */
+
+ g_object_notify(G_OBJECT(input), "content-type");
+}
+
+static gchar *
+talkatu_input_get_author(TalkatuInput *input) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ return priv->author;
+}
+
+static void
+talkatu_input_set_author(TalkatuInput *input, const gchar *author) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ g_clear_pointer(&priv->author, g_free);
+
+ if(author) {
+ priv->author = g_strdup(author);
+ }
+
+ g_object_notify(G_OBJECT(input), "author");
+}
+
+static gchar *
+talkatu_input_get_contents(TalkatuInput *input) {
+ GtkTextBuffer *buffer = NULL;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
+
+ return talkatu_markup_get_html(buffer, NULL);
+}
+
+static void
+talkatu_input_set_contents(TalkatuInput *input, const gchar *contents) {
+ GtkTextBuffer *buffer = NULL;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
+
+ if(contents == NULL) {
+ talkatu_buffer_clear(TALKATU_BUFFER(buffer));
+ } else {
+ talkatu_markup_set_html(TALKATU_BUFFER(buffer), contents, -1);
+ }
+
+ g_object_notify(G_OBJECT(input), "contents");
+}
+
+static gboolean
+talkatu_input_get_edited(TalkatuInput *input) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ return priv->edited;
+}
+
+static void
+talkatu_input_set_edited(TalkatuInput *input, gboolean edited) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ priv->edited = edited;
+
+ g_object_notify(G_OBJECT(input), "edited");
+}
+
+static gboolean
+talkatu_input_add_attachment(TalkatuMessage *message,
+ TalkatuAttachment *attachment)
+{
+ TalkatuInput *input = TALKATU_INPUT(message);
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ return g_hash_table_insert(
+ priv->attachments,
+ talkatu_attachment_get_hash_key(attachment),
+ g_object_ref(G_OBJECT(attachment))
+ );
+}
+
+static gboolean
+talkatu_input_remove_attachment(TalkatuMessage *message, gint64 id) {
+ TalkatuInput *input = TALKATU_INPUT(message);
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ return g_hash_table_remove(priv->attachments, &id);
+}
+
+static TalkatuAttachment *
+talkatu_input_get_attachment(TalkatuMessage *message, gint64 id) {
+ TalkatuInput *input = TALKATU_INPUT(message);
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+ TalkatuAttachment *attachment = NULL;
+
+ attachment = g_hash_table_lookup(priv->attachments, &id);
+
+ if(TALKATU_IS_ATTACHMENT(attachment)) {
+ return TALKATU_ATTACHMENT(g_object_ref(G_OBJECT(attachment)));
+ }
+
+ return NULL;
+}
+
+static void
+talkatu_input_foreach_attachment_helper(gpointer key, gpointer value,
+ gpointer data)
+{
+ TalkatuInputForeachAttachmentData *d = (TalkatuInputForeachAttachmentData *)data;
+
+ d->func(TALKATU_ATTACHMENT(value), d->data);
+}
+
+static void
+talkatu_input_foreach_attachment(TalkatuMessage *message,
+ TalkatuAttachmentForeachFunc func,
+ gpointer data)
+{
+ TalkatuInput *input = TALKATU_INPUT(message);
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ TalkatuInputForeachAttachmentData d = {
+ .func = func,
+ .data = data
+ };
+
+ g_hash_table_foreach(priv->attachments,
+ talkatu_input_foreach_attachment_helper,
+ &d);
+}
+
+static void
+talkatu_input_clear_attachments(TalkatuMessage *message) {
+ TalkatuInput *input = TALKATU_INPUT(message);
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ g_hash_table_remove_all(priv->attachments);
+}
+
+static void
+talkatu_input_message_init(TalkatuMessageInterface *iface) {
+ iface->add_attachment = talkatu_input_add_attachment;
+ iface->remove_attachment = talkatu_input_remove_attachment;
+ iface->get_attachment = talkatu_input_get_attachment;
+ iface->foreach_attachment = talkatu_input_foreach_attachment;
+ iface->clear_attachments = talkatu_input_clear_attachments;
+}
/******************************************************************************
* Callbacks
@@ -148,6 +374,7 @@
/* now send the attachment */
attachment = talkatu_attachment_dialog_get_attachment(adialog);
+ talkatu_message_add_attachment(TALKATU_MESSAGE(input), attachment);
g_object_unref(G_OBJECT(attachment));
/* send the message */
@@ -171,7 +398,8 @@
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
comment = talkatu_markup_get_html(buffer, NULL);
- attachment = talkatu_attachment_new_from_pixbuf("unknown.png", pixbuf);
+ attachment = talkatu_attachment_new_from_pixbuf(G_GUINT64_CONSTANT(0),
+ "unknown.png", pixbuf);
dialog = talkatu_attachment_dialog_new(attachment, comment);
g_signal_connect(G_OBJECT(dialog), "response",
@@ -243,6 +471,24 @@
case PROP_SEND_BINDING:
g_value_set_flags(value, talkatu_input_get_send_binding(input));
break;
+ case PROP_ID:
+ g_value_set_uint64(value, talkatu_input_get_id(input));
+ break;
+ case PROP_TIMESTAMP:
+ g_value_set_boxed(value, talkatu_input_get_timestamp(input));
+ break;
+ case PROP_CONTENT_TYPE:
+ g_value_set_enum(value, talkatu_input_get_content_type(input));
+ break;
+ case PROP_AUTHOR:
+ g_value_set_string(value, talkatu_input_get_author(input));
+ break;
+ case PROP_CONTENTS:
+ g_value_set_string(value, talkatu_input_get_contents(input));
+ break;
+ case PROP_EDITED:
+ g_value_set_boolean(value, talkatu_input_get_edited(input));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
break;
@@ -257,6 +503,24 @@
case PROP_SEND_BINDING:
talkatu_input_set_send_binding(input, g_value_get_flags(value));
break;
+ case PROP_ID:
+ talkatu_input_set_id(input, g_value_get_uint64(value));
+ break;
+ case PROP_TIMESTAMP:
+ talkatu_input_set_timestamp(input, g_value_get_boxed(value));
+ break;
+ case PROP_CONTENT_TYPE:
+ talkatu_input_set_content_type(input, g_value_get_enum(value));
+ break;
+ case PROP_AUTHOR:
+ talkatu_input_set_author(input, g_value_get_string(value));
+ break;
+ case PROP_CONTENTS:
+ talkatu_input_set_contents(input, g_value_get_string(value));
+ break;
+ case PROP_EDITED:
+ talkatu_input_set_edited(input, g_value_get_boolean(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
break;
@@ -267,6 +531,9 @@
talkatu_input_init(TalkatuInput *input) {
TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+ priv->attachments = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+ NULL, g_object_unref);
+
/* we need to know when the buffer is changed in our parent so we can
* update our actions and other stuff.
*/
@@ -292,6 +559,16 @@
}
static void
+talkatu_input_finalize(GObject *obj) {
+ TalkatuInput *input = TALKATU_INPUT(obj);
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ g_hash_table_destroy(priv->attachments);
+
+ G_OBJECT_CLASS(talkatu_input_parent_class)->finalize(obj);
+}
+
+static void
talkatu_input_class_init(TalkatuInputClass *klass) {
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
@@ -300,6 +577,7 @@
obj_class->get_property = talkatu_input_get_property;
obj_class->set_property = talkatu_input_set_property;
+ obj_class->finalize = talkatu_input_finalize;
widget_class->popup_menu = talkatu_input_popup_menu;
@@ -316,6 +594,14 @@
);
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+ /* override the properties for the interface */
+ g_object_class_override_property(obj_class, PROP_ID, "id");
+ g_object_class_override_property(obj_class, PROP_TIMESTAMP, "timestamp");
+ g_object_class_override_property(obj_class, PROP_CONTENT_TYPE, "content-type");
+ g_object_class_override_property(obj_class, PROP_AUTHOR, "author");
+ g_object_class_override_property(obj_class, PROP_CONTENTS, "contents");
+ g_object_class_override_property(obj_class, PROP_EDITED, "edited");
+
/**
* TalkatuInput::should-send-message:
* @talkatuinput: The #TalkatuInput instance.
--- a/talkatu/talkatumessage.c Tue Jan 28 21:53:46 2020 -0600
+++ b/talkatu/talkatumessage.c Wed Jan 29 08:35:45 2020 -0600
@@ -86,8 +86,9 @@
*
* The timestamp for when this message was created.
*/
- pspec = g_param_spec_pointer(
+ pspec = g_param_spec_boxed(
"timestamp", "timestamp", "The timestamp of the message",
+ G_TYPE_DATE_TIME,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
);
g_object_interface_install_property(iface, pspec);
@@ -237,6 +238,22 @@
}
/**
+ * talkatu_message_set_content_type:
+ * @message: The #TalkatuMessage instance.
+ * @content_type: The new #TalkatuContentType to set.
+ *
+ * Sets the content type of @message to @content_type.
+ */
+void
+talkatu_message_set_content_type(TalkatuMessage *message,
+ TalkatuContentType content_type)
+{
+ g_return_if_fail(TALKATU_IS_MESSAGE(message));
+
+ g_object_set(G_OBJECT(message), "content-type", content_type, NULL);
+}
+
+/**
* talkatu_message_get_author:
* @message: The #TalkatuMessage instance.
*
--- a/talkatu/talkatumessage.h Tue Jan 28 21:53:46 2020 -0600
+++ b/talkatu/talkatumessage.h Wed Jan 29 08:35:45 2020 -0600
@@ -65,6 +65,7 @@
void talkatu_message_set_timestamp(TalkatuMessage *message, GDateTime *timestamp);
TalkatuContentType talkatu_message_get_content_type(TalkatuMessage *message);
+void talkatu_message_set_content_type(TalkatuMessage *message, TalkatuContentType content_type);
gchar *talkatu_message_get_author(TalkatuMessage *message);
void talkatu_message_set_author(TalkatuMessage *message, const gchar *author);