talkatu/talkatu

Parents c4c0f624de92
Children 28fa81b6d992
Change TalkatuAttachment to an interface and move it's implementation to TalkatuSimpleAttachment.

Also included the fix for TALKATU-82.

Testing Done:
Ran the demo in gdb with `G_DEBUG=fatal-warnings` and verified that attachments still worked as expected.

Bugs closed: TALKATU-82

Reviewed at https://reviews.imfreedom.org/r/24/
--- a/talkatu/meson.build Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/meson.build Tue Jul 21 20:57:01 2020 -0500
@@ -22,6 +22,7 @@
'talkatumenutoolbutton.h',
'talkatumessage.h',
'talkatumessageactions.h',
+ 'talkatusimpleattachment.h',
'talkatutag.h',
'talkatutagtable.h',
'talkatutoolbar.h',
@@ -50,6 +51,7 @@
'talkatumenutoolbutton.c',
'talkatumessage.c',
'talkatumessageactions.c',
+ 'talkatusimpleattachment.c',
'talkatutag.c',
'talkatutagtable.c',
'talkatutoolbar.c',
--- a/talkatu/talkatuactiongroup.c Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/talkatuactiongroup.c Tue Jul 21 20:57:01 2020 -0500
@@ -24,6 +24,7 @@
#include "talkatu/talkatulinkdialog.h"
#include "talkatu/talkatumarkup.h"
#include "talkatu/talkatumessage.h"
+#include "talkatu/talkatusimpleattachment.h"
#include "talkatu/talkatutag.h"
/**
@@ -407,7 +408,8 @@
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
content_type = g_content_type_guess(filename, NULL, 0, NULL);
- attachment = talkatu_attachment_new(G_GUINT64_CONSTANT(0), content_type);
+ attachment = talkatu_simple_attachment_new(G_GUINT64_CONSTANT(0),
+ content_type);
g_free(content_type);
talkatu_attachment_set_local_uri(attachment, filename);
--- a/talkatu/talkatuattachment.c Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/talkatuattachment.c Tue Jul 21 20:57:01 2020 -0500
@@ -42,164 +42,75 @@
* regular file but only images will be previewed based on their actual
* contents.
*/
-struct _TalkatuAttachment {
- GObject parent;
- guint64 id;
- gchar *content_type;
-
- gchar *local_uri;
- gchar *remote_uri;
-
- guint64 size;
-
- GdkPixbuf *preview;
- gboolean preview_ready;
-};
-
-G_DEFINE_TYPE(TalkatuAttachment, talkatu_attachment, G_TYPE_OBJECT);
-
-enum {
- PROP_0 = 0,
- PROP_ID,
- PROP_CONTENT_TYPE,
- PROP_LOCAL_URI,
- PROP_REMOTE_URI,
- PROP_SIZE,
- N_PROPERTIES,
-};
-static GParamSpec *properties[N_PROPERTIES];
-
-/******************************************************************************
- * Private Setters
- *****************************************************************************/
-static void
-talkatu_attachment_set_content_type(TalkatuAttachment *attachment,
- const gchar *content_type)
-{
- if(attachment->content_type == content_type) {
- return;
- }
-
- g_clear_pointer(&attachment->content_type, g_free);
-
- attachment->content_type = g_strdup(content_type);
-
- g_object_notify_by_pspec(G_OBJECT(attachment),
- properties[PROP_CONTENT_TYPE]);
-}
+G_DEFINE_INTERFACE(TalkatuAttachment, talkatu_attachment, G_TYPE_INVALID);
/******************************************************************************
* GObject Implementation
*****************************************************************************/
static void
-talkatu_attachment_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
- 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;
- case PROP_LOCAL_URI:
- g_value_set_string(value, talkatu_attachment_get_local_uri(attachment));
- break;
- case PROP_REMOTE_URI:
- g_value_set_string(value, talkatu_attachment_get_remote_uri(attachment));
- break;
- case PROP_SIZE:
- g_value_set_uint64(value, talkatu_attachment_get_size(attachment));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-talkatu_attachment_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) {
- TalkatuAttachment *attachment = TALKATU_ATTACHMENT(obj);
+talkatu_attachment_default_init(TalkatuAttachmentInterface *iface) {
+ GParamSpec *pspec = NULL;
- 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;
- case PROP_LOCAL_URI:
- talkatu_attachment_set_local_uri(attachment, g_value_get_string(value));
- break;
- case PROP_REMOTE_URI:
- talkatu_attachment_set_remote_uri(attachment, g_value_get_string(value));
- break;
- case PROP_SIZE:
- talkatu_attachment_set_size(attachment, g_value_get_uint64(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-talkatu_attachment_finalize(GObject *obj) {
- TalkatuAttachment *attachment = TALKATU_ATTACHMENT(obj);
-
- g_clear_pointer(&attachment->content_type, g_free);
- g_clear_pointer(&attachment->local_uri, g_free);
- g_clear_pointer(&attachment->remote_uri, g_free);
- g_clear_object(&attachment->preview);
-
- G_OBJECT_CLASS(talkatu_attachment_parent_class)->finalize(obj);
-}
-
-static void
-talkatu_attachment_init(TalkatuAttachment *attachment) {
-}
-
-static void
-talkatu_attachment_class_init(TalkatuAttachmentClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
- obj_class->get_property = talkatu_attachment_get_property;
- obj_class->set_property = talkatu_attachment_set_property;
- obj_class->finalize = talkatu_attachment_finalize;
-
- /* add our properties */
- properties[PROP_ID] = g_param_spec_uint64(
+ /**
+ * TalkatuAttachment::id:
+ *
+ * The identifier of the attachment.
+ */
+ pspec = g_param_spec_uint64(
"id", "id", "The identifier of the attachment",
0, G_MAXUINT64, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
);
+ g_object_interface_install_property(iface, pspec);
- properties[PROP_CONTENT_TYPE] = g_param_spec_string(
+ /**
+ * TalkatuAttachment::content-type:
+ *
+ * The content type of the attachment.
+ */
+ pspec = g_param_spec_string(
"content-type", "content-type", "The content type of the attachment",
"application/octet-stream",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
);
+ g_object_interface_install_property(iface, pspec);
- properties[PROP_LOCAL_URI] = g_param_spec_string(
+ /**
+ * TalkatuAttachment::local-uri:
+ *
+ * The local URI of the attachment.
+ */
+ pspec = g_param_spec_string(
"local-uri", "local-uri", "The local URI of the attachment",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
);
+ g_object_interface_install_property(iface, pspec);
- properties[PROP_REMOTE_URI] = g_param_spec_string(
+ /**
+ * TalkatuAttachment::remote-uri:
+ *
+ * The remote URI of the attachment.
+ */
+ pspec = g_param_spec_string(
"remote-uri", "remote-uri", "The remote URI of the attachment",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
);
+ g_object_interface_install_property(iface, pspec);
- properties[PROP_SIZE] = g_param_spec_uint64(
+ /**
+ * TalkatuAttachment::size:
+ *
+ * The size of the attachment.
+ */
+ pspec = g_param_spec_uint64(
"size", "size", "The file size of the attachment in bytes",
0, G_MAXUINT64, 0,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
);
-
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+ g_object_interface_install_property(iface, pspec);
}
/******************************************************************************
@@ -237,9 +148,13 @@
*/
guint64
talkatu_attachment_get_id(TalkatuAttachment *attachment) {
+ guint64 ret = 0;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), 0);
- return attachment->id;
+ g_object_get(G_OBJECT(attachment), "id", &ret, NULL);
+
+ return ret;
}
/**
@@ -254,9 +169,13 @@
*/
guint64 *
talkatu_attachment_get_hash_key(TalkatuAttachment *attachment) {
+ TalkatuAttachmentInterface *iface = NULL;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
- return &attachment->id;
+ iface = TALKATU_ATTACHMENT_GET_IFACE(attachment);
+
+ return iface->get_hash_key(attachment);
}
/**
@@ -270,13 +189,7 @@
talkatu_attachment_set_id(TalkatuAttachment *attachment, guint64 id) {
g_return_if_fail(TALKATU_IS_ATTACHMENT(attachment));
- if(attachment->id == id) {
- return;
- }
-
- attachment->id = id;
-
- g_object_notify_by_pspec(G_OBJECT(attachment), properties[PROP_ID]);
+ g_object_set(G_OBJECT(attachment), "id", id, NULL);
}
/**
@@ -287,11 +200,15 @@
*
* Returns: The content type of @attachment.
*/
-const gchar *
+gchar *
talkatu_attachment_get_content_type(TalkatuAttachment *attachment) {
+ gchar *content_type = NULL;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
- return attachment->content_type;
+ g_object_get(G_OBJECT(attachment), "content-type", &content_type, NULL);
+
+ return content_type;
}
/**
@@ -300,13 +217,17 @@
*
* Gets the local URI if any for @attachment.
*
- * Returns: (nullable): The local URI for @attachment.
+ * Returns: The local URI for @attachment.
*/
-const gchar *
+gchar *
talkatu_attachment_get_local_uri(TalkatuAttachment *attachment) {
+ gchar *local_uri = NULL;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
- return attachment->local_uri;
+ g_object_get(G_OBJECT(attachment), "local-uri", &local_uri, NULL);
+
+ return local_uri;
}
/**
@@ -322,25 +243,7 @@
{
g_return_if_fail(TALKATU_IS_ATTACHMENT(attachment));
- if(attachment->local_uri == local_uri) {
- return;
- }
-
- g_free(attachment->local_uri);
-
- if(local_uri != NULL) {
- gchar *scheme = g_uri_parse_scheme(local_uri);
- if(scheme == NULL) {
- attachment->local_uri = g_filename_to_uri(local_uri, NULL, NULL);
- } else {
- g_free(scheme);
- attachment->local_uri = g_strdup(local_uri);
- }
- } else {
- attachment->local_uri = NULL;
- }
-
- g_object_notify_by_pspec(G_OBJECT(attachment), properties[PROP_LOCAL_URI]);
+ g_object_set(G_OBJECT(attachment), "local-uri", local_uri, NULL);
}
/**
@@ -351,11 +254,15 @@
*
* Returns: (nullable): The remote URI for @attachment.
*/
-const gchar *
+gchar *
talkatu_attachment_get_remote_uri(TalkatuAttachment *attachment) {
+ gchar *remote_uri = NULL;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
- return attachment->remote_uri;
+ g_object_get(G_OBJECT(attachment), "remote-uri", &remote_uri, NULL);
+
+ return remote_uri;
}
/**
@@ -371,14 +278,7 @@
{
g_return_if_fail(TALKATU_IS_ATTACHMENT(attachment));
- if(attachment->remote_uri == remote_uri) {
- return;
- }
-
- g_free(attachment->remote_uri);
- attachment->remote_uri = g_strdup(remote_uri);
-
- g_object_notify_by_pspec(G_OBJECT(attachment), properties[PROP_REMOTE_URI]);
+ g_object_set(G_OBJECT(attachment), "remote-uri", remote_uri, NULL);
}
/**
@@ -391,9 +291,13 @@
*/
guint64
talkatu_attachment_get_size(TalkatuAttachment *attachment) {
+ guint64 size;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), 0);
- return attachment->size;
+ g_object_get(G_OBJECT(attachment), "size", &size, NULL);
+
+ return size;
}
/**
@@ -407,9 +311,7 @@
talkatu_attachment_set_size(TalkatuAttachment *attachment, guint64 size) {
g_return_if_fail(TALKATU_IS_ATTACHMENT(attachment));
- attachment->size = size;
-
- g_object_notify_by_pspec(G_OBJECT(attachment), properties[PROP_SIZE]);
+ g_object_set(G_OBJECT(attachment), "size", size, NULL);
}
/**
@@ -423,14 +325,26 @@
*/
gchar *
talkatu_attachment_get_filename(TalkatuAttachment *attachment) {
+ gchar *remote_uri = NULL, *local_uri = NULL;
+
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
- if(attachment->remote_uri != NULL && attachment->remote_uri[0] != '\0') {
- return g_path_get_basename(attachment->remote_uri);
+ remote_uri = talkatu_attachment_get_remote_uri(attachment);
+ if(remote_uri != NULL && remote_uri[0] != '\0') {
+ gchar *ret = g_path_get_basename(remote_uri);
+
+ g_free(remote_uri);
+
+ return ret;
}
- if(attachment->local_uri != NULL && attachment->local_uri[0] != '\0') {
- return g_path_get_basename(attachment->local_uri);
+ local_uri = talkatu_attachment_get_local_uri(attachment);
+ if(local_uri != NULL && local_uri[0] != '\0') {
+ gchar *ret = g_path_get_basename(local_uri);
+
+ g_free(local_uri);
+
+ return ret;
}
return g_strdup("unknown");
@@ -446,26 +360,37 @@
*/
GIcon *
talkatu_attachment_get_preview(TalkatuAttachment *attachment) {
+ gchar *content_type = NULL;
const gchar *name = "text-x-generic-template";
g_return_val_if_fail(TALKATU_IS_ATTACHMENT(attachment), NULL);
- if(g_str_has_prefix(attachment->content_type, "image/")) {
- if(attachment->local_uri != NULL) {
- GFile *file = g_file_new_for_uri(attachment->local_uri);
+ content_type = talkatu_attachment_get_content_type(attachment);
+ if(content_type == NULL) {
+ return g_themed_icon_new(name);
+ }
+
+ if(g_str_has_prefix(content_type, "image/")) {
+ gchar *local_uri = talkatu_attachment_get_local_uri(attachment);
+ if(local_uri != NULL) {
+ GFile *file = g_file_new_for_uri(local_uri);
GIcon *icon = g_file_icon_new(file);
g_object_unref(G_OBJECT(file));
+ g_free(local_uri);
+ g_free(content_type);
return icon;
}
name = "image-x-generic";
- } else if(g_str_has_prefix(attachment->content_type, "text/")) {
+ } else if(g_str_has_prefix(content_type, "text/")) {
name = "text-x-generic";
- } else if(g_str_has_prefix(attachment->content_type, "audio/")) {
+ } else if(g_str_has_prefix(content_type, "audio/")) {
name = "audio-x-generic";
}
+ g_free(content_type);
+
return g_themed_icon_new(name);
}
--- a/talkatu/talkatuattachment.h Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/talkatuattachment.h Tue Jul 21 20:57:01 2020 -0500
@@ -23,28 +23,37 @@
#ifndef TALKATU_ATTACHMENT_H
#define TALKATU_ATTACHMENT_H
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gtk/gtk.h>
+#include <glib.h>
+#include <gio/gio.h>
G_BEGIN_DECLS
#define TALKATU_TYPE_ATTACHMENT (talkatu_attachment_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuAttachment, talkatu_attachment, TALKATU, ATTACHMENT, GObject)
+G_DECLARE_INTERFACE(TalkatuAttachment, talkatu_attachment, TALKATU, ATTACHMENT, GObject)
+
+struct _TalkatuAttachmentInterface {
+ /*< private >*/
+ GTypeInterface parent;
+
+ /*< public >*/
+ guint64 *(*get_hash_key)(TalkatuAttachment *attachment);
+
+ /*< private >*/
+ gpointer reserved[4];
+};
typedef void (*TalkatuAttachmentForeachFunc)(TalkatuAttachment *attachment, gpointer data);
-TalkatuAttachment *talkatu_attachment_new(guint64 id, const gchar *content_type);
-
guint64 talkatu_attachment_get_id(TalkatuAttachment *attachment);
guint64 *talkatu_attachment_get_hash_key(TalkatuAttachment *attachment);
void talkatu_attachment_set_id(TalkatuAttachment *attachment, guint64 id);
-const gchar *talkatu_attachment_get_content_type(TalkatuAttachment *attachment);
+gchar *talkatu_attachment_get_content_type(TalkatuAttachment *attachment);
-const gchar *talkatu_attachment_get_local_uri(TalkatuAttachment *attachment);
+gchar *talkatu_attachment_get_local_uri(TalkatuAttachment *attachment);
void talkatu_attachment_set_local_uri(TalkatuAttachment *attachment, const gchar *local_uri);
-const gchar *talkatu_attachment_get_remote_uri(TalkatuAttachment *attachment);
+gchar *talkatu_attachment_get_remote_uri(TalkatuAttachment *attachment);
void talkatu_attachment_set_remote_uri(TalkatuAttachment *attachment, const gchar *remote_uri);
gsize talkatu_attachment_get_size(TalkatuAttachment *attachment);
--- a/talkatu/talkatuattachmentdialog.c Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/talkatuattachmentdialog.c Tue Jul 21 20:57:01 2020 -0500
@@ -166,7 +166,7 @@
properties[PROP_ATTACHMENT] = g_param_spec_object(
"attachment", "attachment",
"The attachment that this dialog is customizing",
- TALKATU_TYPE_ATTACHMENT,
+ G_TYPE_OBJECT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
properties[PROP_COMMENT] = g_param_spec_string(
--- a/talkatu/talkatuattachmentpreview.c Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/talkatuattachmentpreview.c Tue Jul 21 20:57:01 2020 -0500
@@ -161,7 +161,7 @@
properties[PROP_ATTACHMENT] = g_param_spec_object(
"attachment", "attachment",
"The attachment that this preview is customizing",
- TALKATU_TYPE_ATTACHMENT,
+ G_TYPE_OBJECT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
--- a/talkatu/talkatuinput.c Tue Jul 21 20:49:33 2020 -0500
+++ b/talkatu/talkatuinput.c Tue Jul 21 20:57:01 2020 -0500
@@ -24,11 +24,11 @@
#include "talkatu/talkatuinput.h"
#include "talkatu/talkatuactiongroup.h"
-#include "talkatu/talkatuattachment.h"
#include "talkatu/talkatuattachmentdialog.h"
#include "talkatu/talkatuenums.h"
#include "talkatu/talkatumarkup.h"
#include "talkatu/talkatumessage.h"
+#include "talkatu/talkatusimpleattachment.h"
/**
* SECTION:talkatuinput
@@ -506,7 +506,7 @@
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
comment = talkatu_markup_get_html(buffer, NULL);
- attachment = talkatu_attachment_new(G_GUINT64_CONSTANT(0), "image/png");
+ attachment = talkatu_simple_attachment_new(G_GUINT64_CONSTANT(0), "image/png");
filename = g_file_get_uri(file);
talkatu_attachment_set_local_uri(attachment, filename);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatusimpleattachment.c Tue Jul 21 20:57:01 2020 -0500
@@ -0,0 +1,290 @@
+/*
+ * talkatu
+ * 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
+ * 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 "talkatu/talkatusimpleattachment.h"
+
+#include <glib/gi18n-lib.h>
+
+/**
+ * SECTION:talkatusimpleattachment
+ * @Title: Simple Attachments
+ * @Short_description: A Simple Message Attachment
+ *
+ * #TalkatuSimpleAttachment is simple implementation of the #TalkatuAttachment
+ * interface. This is the easiest way to create a #TalkatuAction and attach it
+ * to a #TalkatuMessage.
+ */
+
+/**
+ * TALKATU_TYPE_SIMPLE_ATTACHMENT:
+ *
+ * The standard _get_type macro for #TalkatuSimpleAttachment.
+ */
+
+/**
+ * TalkatuSimpleAttachment:
+ *
+ * TalkatuSimpleAttachment is an opaque data structure and can not be used
+ * directly.
+ */
+struct _TalkatuSimpleAttachment {
+ GObject parent;
+
+ guint64 id;
+ gchar *content_type;
+
+ gchar *local_uri;
+ gchar *remote_uri;
+
+ guint64 size;
+};
+
+enum {
+ PROP_0 = 0,
+ N_PROPERTIES,
+ /* overrides */
+ PROP_ID = N_PROPERTIES,
+ PROP_CONTENT_TYPE,
+ PROP_LOCAL_URI,
+ PROP_REMOTE_URI,
+ PROP_SIZE,
+};
+
+/******************************************************************************
+ * TalkatuAttachment Implementation
+ *****************************************************************************/
+static guint64
+talkatu_simple_attachment_get_id(TalkatuSimpleAttachment *attachment) {
+ return attachment->id;
+}
+
+static guint64 *
+talkatu_simple_attachment_get_hash_key(TalkatuAttachment *attachment) {
+ TalkatuSimpleAttachment *simple = TALKATU_SIMPLE_ATTACHMENT(attachment);
+
+ return &simple->id;
+}
+
+static void
+talkatu_simple_attachment_set_id(TalkatuSimpleAttachment *attachment,
+ guint64 id)
+{
+ attachment->id = id;
+
+ g_object_notify(G_OBJECT(attachment), "id");
+}
+
+static gchar *
+talkatu_simple_attachment_get_content_type(TalkatuSimpleAttachment *attachment) {
+ return g_strdup(attachment->content_type);
+}
+
+static void
+talkatu_simple_attachment_set_content_type(TalkatuSimpleAttachment *attachment,
+ const gchar *content_type)
+{
+ g_clear_pointer(&attachment->content_type, g_free);
+
+ attachment->content_type = g_strdup(content_type);
+
+ g_object_notify(G_OBJECT(attachment), "content-type");
+}
+
+static gchar *
+talkatu_simple_attachment_get_local_uri(TalkatuSimpleAttachment *attachment) {
+ return g_strdup(attachment->local_uri);
+}
+
+static void
+talkatu_simple_attachment_set_local_uri(TalkatuSimpleAttachment *attachment,
+ const gchar *local_uri)
+{
+ g_free(attachment->local_uri);
+
+ if(local_uri != NULL) {
+ gchar *scheme = g_uri_parse_scheme(local_uri);
+ if(scheme == NULL) {
+ attachment->local_uri = g_filename_to_uri(local_uri, NULL, NULL);
+ } else {
+ g_free(scheme);
+ attachment->local_uri = g_strdup(local_uri);
+ }
+ } else {
+ attachment->local_uri = NULL;
+ }
+
+ g_object_notify(G_OBJECT(attachment), "local-uri");
+}
+
+static gchar *
+talkatu_simple_attachment_get_remote_uri(TalkatuSimpleAttachment *attachment) {
+ return g_strdup(attachment->remote_uri);
+}
+
+static void
+talkatu_simple_attachment_set_remote_uri(TalkatuSimpleAttachment *attachment,
+ const gchar *remote_uri)
+{
+ g_free(attachment->remote_uri);
+ attachment->remote_uri = g_strdup(remote_uri);
+
+ g_object_notify(G_OBJECT(attachment), "remote-uri");
+}
+
+static guint64
+talkatu_simple_attachment_get_size(TalkatuSimpleAttachment *attachment) {
+ return attachment->size;
+}
+
+static void
+talkatu_simple_attachment_set_size(TalkatuSimpleAttachment *attachment,
+ guint64 size)
+{
+ attachment->size = size;
+
+ g_object_notify(G_OBJECT(attachment), "size");
+}
+
+static void
+talkatu_simple_attachment_attachment_init(TalkatuAttachmentInterface *iface) {
+ iface->get_hash_key = talkatu_simple_attachment_get_hash_key;
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE_EXTENDED(
+ TalkatuSimpleAttachment,
+ talkatu_simple_attachment,
+ G_TYPE_OBJECT,
+ 0,
+ G_IMPLEMENT_INTERFACE(TALKATU_TYPE_ATTACHMENT,
+ talkatu_simple_attachment_attachment_init)
+);
+
+static void
+talkatu_simple_attachment_get_property(GObject *obj, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ TalkatuSimpleAttachment *attachment = TALKATU_SIMPLE_ATTACHMENT(obj);
+
+ switch(prop_id) {
+ case PROP_ID:
+ g_value_set_uint64(value, talkatu_simple_attachment_get_id(attachment));
+ break;
+ case PROP_CONTENT_TYPE:
+ g_value_take_string(value, talkatu_simple_attachment_get_content_type(attachment));
+ break;
+ case PROP_LOCAL_URI:
+ g_value_take_string(value, talkatu_simple_attachment_get_local_uri(attachment));
+ break;
+ case PROP_REMOTE_URI:
+ g_value_take_string(value, talkatu_simple_attachment_get_remote_uri(attachment));
+ break;
+ case PROP_SIZE:
+ g_value_set_uint64(value, talkatu_simple_attachment_get_size(attachment));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+talkatu_simple_attachment_set_property(GObject *obj, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ TalkatuSimpleAttachment *attachment = TALKATU_SIMPLE_ATTACHMENT(obj);
+
+ switch(prop_id) {
+ case PROP_ID:
+ talkatu_simple_attachment_set_id(attachment, g_value_get_uint64(value));
+ break;
+ case PROP_CONTENT_TYPE:
+ talkatu_simple_attachment_set_content_type(attachment, g_value_get_string(value));
+ break;
+ case PROP_LOCAL_URI:
+ talkatu_simple_attachment_set_local_uri(attachment, g_value_get_string(value));
+ break;
+ case PROP_REMOTE_URI:
+ talkatu_simple_attachment_set_remote_uri(attachment, g_value_get_string(value));
+ break;
+ case PROP_SIZE:
+ talkatu_simple_attachment_set_size(attachment, g_value_get_uint64(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+talkatu_simple_attachment_finalize(GObject *obj) {
+ TalkatuSimpleAttachment *attachment = TALKATU_SIMPLE_ATTACHMENT(obj);
+
+ g_clear_pointer(&attachment->content_type, g_free);
+ g_clear_pointer(&attachment->local_uri, g_free);
+ g_clear_pointer(&attachment->remote_uri, g_free);
+
+ G_OBJECT_CLASS(talkatu_simple_attachment_parent_class)->finalize(obj);
+}
+
+static void
+talkatu_simple_attachment_init(TalkatuSimpleAttachment *attachment) {
+}
+
+static void
+talkatu_simple_attachment_class_init(TalkatuSimpleAttachmentClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->get_property = talkatu_simple_attachment_get_property;
+ obj_class->set_property = talkatu_simple_attachment_set_property;
+ obj_class->finalize = talkatu_simple_attachment_finalize;
+
+ /* add our overridden properties */
+ g_object_class_override_property(obj_class, PROP_ID, "id");
+ g_object_class_override_property(obj_class, PROP_CONTENT_TYPE, "content-type");
+ g_object_class_override_property(obj_class, PROP_LOCAL_URI, "local-uri");
+ g_object_class_override_property(obj_class, PROP_REMOTE_URI, "remote-uri");
+ g_object_class_override_property(obj_class, PROP_SIZE, "size");
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+
+/**
+ * talkatu_simple_attachment_new:
+ * @id: The identifier of the attachment.
+ * @content_type: The content type of the attachment.
+ *
+ * Creates a new attachment with @content_type.
+ *
+ * Returns: (transfer full): The new #TalkatuSimpleAttachment.
+ */
+TalkatuAttachment *
+talkatu_simple_attachment_new(guint64 id, const gchar *content_type) {
+ g_return_val_if_fail(content_type != NULL, NULL);
+
+ return TALKATU_ATTACHMENT(g_object_new(
+ TALKATU_TYPE_SIMPLE_ATTACHMENT,
+ "id", id,
+ "content-type", content_type,
+ NULL
+ ));
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatusimpleattachment.h Tue Jul 21 20:57:01 2020 -0500
@@ -0,0 +1,37 @@
+/*
+ * talkatu
+ * 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
+ * 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/>.
+ */
+
+#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
+#error "only <talkatu.h> may be included directly"
+#endif
+
+#ifndef TALKATU_SIMPLE_ATTACHMENT_H
+#define TALKATU_SIMPLE_ATTACHMENT_H
+
+#include <talkatu/talkatuattachment.h>
+
+G_BEGIN_DECLS
+
+#define TALKATU_TYPE_SIMPLE_ATTACHMENT (talkatu_simple_attachment_get_type())
+G_DECLARE_FINAL_TYPE(TalkatuSimpleAttachment, talkatu_simple_attachment, TALKATU, SIMPLE_ATTACHMENT, GObject)
+
+TalkatuAttachment *talkatu_simple_attachment_new(guint64 id, const gchar *content_type);
+
+G_END_DECLS
+
+#endif /* TALKATU_SIMPLE_ATTACHMENT_H */