--- a/demo/data/demo.ui Sun Aug 02 16:14:42 2020 -0500
+++ b/demo/data/demo.ui Wed Aug 19 04:05:05 2020 -0500
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1
+<!-- Generated with glade 3.22.2 Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
@@ -22,25 +22,6 @@
<requires lib="Talkatu" version="0.0"/>
<requires lib="gtk+" version="3.18"/>
- <object class="TalkatuTagTable" id="table_history"/>
- <object class="TalkatuHistoryBuffer" id="buffer_history">
- <property name="tag_table">table_history</property>
- <object class="TalkatuTagTable" id="table_html"/>
- <object class="TalkatuHtmlBuffer" id="buffer_html">
- <property name="tag_table">table_html</property>
- <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
- <object class="TalkatuTagTable" id="table_markdown"/>
- <object class="TalkatuMarkdownBuffer" id="buffer_markdown">
- <property name="tag_table">table_markdown</property>
- <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
- <object class="TalkatuTagTable" id="table_plain"/>
- <object class="TalkatuBuffer" id="buffer_plain">
- <property name="tag_table">table_plain</property>
- <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/>
<!-- interface-license-type gplv2 -->
<!-- interface-name Talkatu -->
<!-- interface-description GTK+ widgets for chat applications -->
@@ -49,7 +30,7 @@
<property name="can_focus">False</property>
<property name="border_width">12</property>
<signal name="delete-event" handler="talkatu_demo_window_closed_cb" swapped="no"/>
+ <child type="titlebar"> @@ -59,20 +40,18 @@
<property name="orientation">vertical</property>
<property name="wide_handle">True</property>
- <object class="GtkScrolledWindow">
+ <object class="TalkatuScrolledWindow"> <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
- <object class="TalkatuHistory" id="view_history">
- <property name="name">view_history</property>
+ <object class="TalkatuHistory" id="history"> + <property name="name">history</property> <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="hexpand_set">True</property>
<property name="vexpand_set">True</property>
- <property name="editable">False</property>
- <property name="wrap_mode">word</property>
@@ -232,7 +211,7 @@
<object class="GtkToggleToolButton" id="toggle_toolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Toogle toolbar visibility</property>
+ <property name="tooltip_text" translatable="yes">Toggle toolbar visibility</property> <property name="label" translatable="yes">Toolbar</property>
<property name="use_underline">True</property>
@@ -254,6 +233,19 @@
<property name="homogeneous">True</property>
+ <object class="GtkToggleToolButton" id="toggle_edited"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">Toggle whether the message is edited</property> + <property name="label" translatable="yes">Edited</property> + <property name="use_underline">True</property> + <property name="expand">False</property> + <property name="homogeneous">True</property> <property name="expand">False</property>
@@ -435,6 +427,22 @@
+ <object class="TalkatuTagTable" id="table_history"/> + <object class="TalkatuTagTable" id="table_html"/> + <object class="TalkatuHtmlBuffer" id="buffer_html"> + <property name="tag_table">table_html</property> + <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/> + <object class="TalkatuTagTable" id="table_markdown"/> + <object class="TalkatuMarkdownBuffer" id="buffer_markdown"> + <property name="tag_table">table_markdown</property> + <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/> + <object class="TalkatuTagTable" id="table_plain"/> + <object class="TalkatuBuffer" id="buffer_plain"> + <property name="tag_table">table_plain</property> + <signal name="changed" handler="talkatu_demo_window_buffer_modified_cb" object="TalkatuDemoWindow" swapped="no"/> <object class="TalkatuWholeBuffer" id="buffer_whole">
<property name="tag_table">table_plain</property>
<property name="style">whole</property>
--- a/demo/talkatudemowindow.c Sun Aug 02 16:14:42 2020 -0500
+++ b/demo/talkatudemowindow.c Wed Aug 19 04:05:05 2020 -0500
@@ -23,7 +23,7 @@
struct _TalkatuDemoWindow {
- GtkWidget *view_history;
@@ -34,12 +34,12 @@
GtkToggleToolButton *toggle_toolbar;
GtkToggleToolButton *toggle_send_button;
+ GtkToggleToolButton *toggle_edited; GtkTextBuffer *buffer_plain;
GtkTextBuffer *buffer_whole;
GtkTextBuffer *buffer_html;
GtkTextBuffer *buffer_markdown;
- GtkTextBuffer *buffer_history;
GtkWidget *author_button;
GtkWidget *author_popover;
@@ -222,8 +222,8 @@
talkatu_message_set_id(TALKATU_MESSAGE(input), id++);
- talkatu_history_buffer_write_message(
- TALKATU_HISTORY_BUFFER(window->buffer_history),
+ talkatu_history_write_message( + TALKATU_HISTORY(window->history), @@ -276,8 +276,6 @@
talkatu_demo_window_init(TalkatuDemoWindow *window) {
gtk_widget_init_template(GTK_WIDGET(window));
- gtk_text_view_set_buffer(GTK_TEXT_VIEW(window->view_history), window->buffer_history);
/* activate the first menu item to make sure its label gets stored
@@ -294,6 +292,12 @@
window->toggle_send_button, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL
+ g_object_bind_property( + talkatu_editor_get_input(TALKATU_EDITOR(window->editor)), "edited", + window->toggle_edited, "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL @@ -305,7 +309,7 @@
"/org/bitbucket/rw_grim/talkatu/ui/demo/demo.ui"
- gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, view_history);
+ gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, history); gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, editor);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, typing);
@@ -313,7 +317,6 @@
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, buffer_whole);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, buffer_html);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, buffer_markdown);
- gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, buffer_history);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_plain);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_whole);
@@ -326,6 +329,7 @@
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_toolbar);
gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_send_button);
+ gtk_widget_class_bind_template_child(widget_class, TalkatuDemoWindow, toggle_edited); gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_closed_cb);
gtk_widget_class_bind_template_callback(widget_class, talkatu_demo_window_buffer_changed_cb);
--- a/po/POTFILES Sun Aug 02 16:14:42 2020 -0500
+++ b/po/POTFILES Wed Aug 19 04:05:05 2020 -0500
@@ -4,6 +4,7 @@
talkatu/data/attachmentdialog.ui
talkatu/data/attachmentpreview.ui
+talkatu/data/historyrow.ui talkatu/data/linkdialog.ui
talkatu/data/messageactions.ui
@@ -15,7 +16,7 @@
-talkatu/talkatuhistorybuffer.c
+talkatu/talkatuhistoryrow.c talkatu/talkatuhtmlbuffer.c
@@ -25,6 +26,7 @@
talkatu/talkatumenutoolbutton.c
talkatu/talkatumessageactions.c
+talkatu/talkatuscrolledwindow.c talkatu/talkatusimpleattachment.c
talkatu/talkatutagtable.c
--- a/talkatu/data/talkatu.gresource.xml Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/data/talkatu.gresource.xml Wed Aug 19 04:05:05 2020 -0500
@@ -4,6 +4,7 @@
<file compressed="true">attachmentdialog.ui</file>
<file compressed="true">attachmentpreview.ui</file>
<file compressed="true">editor.ui</file>
+ <file compressed="true">historyrow.ui</file> <file compressed="true">linkdialog.ui</file>
<file compressed="true">messageactions.ui</file>
<file compressed="true">toolbar.ui</file>
--- a/talkatu/meson.build Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/meson.build Wed Aug 19 04:05:05 2020 -0500
@@ -13,7 +13,7 @@
- 'talkatuhistorybuffer.h',
@@ -22,6 +22,7 @@
'talkatumenutoolbutton.h',
'talkatumessageactions.h',
+ 'talkatuscrolledwindow.h', 'talkatusimpleattachment.h',
@@ -42,7 +43,7 @@
- 'talkatuhistorybuffer.c',
@@ -51,6 +52,7 @@
'talkatumenutoolbutton.c',
'talkatumessageactions.c',
+ 'talkatuscrolledwindow.c', 'talkatusimpleattachment.c',
--- a/talkatu/reference/talkatu-docs.xml Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/reference/talkatu-docs.xml Wed Aug 19 04:05:05 2020 -0500
@@ -37,8 +37,8 @@
<xi:include href="xml/talkatumarkup.xml"/>
- <xi:include href="xml/talkatuhistorybuffer.xml"/>
<xi:include href="xml/talkatuhistory.xml"/>
+ <xi:include href="xml/talkatuhistoryrow.xml"/> <xi:include href="xml/talkatuinput.xml"/>
@@ -52,6 +52,8 @@
<xi:include href="xml/talkatutooldrawer.xml"/>
<xi:include href="xml/talkatumenutoolbutton.xml"/>
+ <xi:include href="xml/talkatuscrolledwindow.xml"/> <xi:include href="xml/talkatutypinglabel.xml"/>
<xi:include href="xml/talkatuattachment.xml"/>
--- a/talkatu/talkatu.xml Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/talkatu.xml Wed Aug 19 04:05:05 2020 -0500
@@ -12,9 +12,11 @@
<glade-widget-class name="TalkatuAttachmentDialog" generic-name="attachment_dialog" title="Attachment Dialog"/>
<glade-widget-class name="TalkatuAttachmentPreview" generic-name="attachment_preview" title="Attachment Preview"/>
<glade-widget-class name="TalkatuHistory" generic-name="history" title="History"/>
+ <glade-widget-class name="TalkatuHistoryRow" generic-name="history_row" title="HistoryRow"/> <glade-widget-class name="TalkatuInput" generic-name="input" title="Input"/>
<glade-widget-class name="TalkatuLinkDialog" generic-name="link_dialog" title="LinkDialog"/>
<glade-widget-class name="TalkatuMenuToolButton" generic-name="menu_tool_button" title="MenuToolButton"/>
+ <glade-widget-class name="TalkatuScrolledWindow" generic-name="scrolled_window" title="ScrolledWindow"/> <glade-widget-class name="TalkatuToolDrawer" generic-name="tool_drawer" title="ToolDrawer"/>
<glade-widget-class name="TalkatuToolbar" generic-name="toolbar" title="Toolbar"/>
<glade-widget-class name="TalkatuView" generic-name="view" title="View"/>
@@ -45,11 +47,6 @@
- <glade-widget-class name="TalkatuHistoryBuffer" generic-name="buffer" title="History Buffer" toplevel="True">
- <property translatable="True" multiline="True" id="text"/>
<glade-widget-group name="Talkatu" title="Talkatu">
<glade-widget-class-ref name="TalkatuAttachmentDialog"/>
@@ -57,12 +54,13 @@
<glade-widget-class-ref name="TalkatuBuffer"/>
<glade-widget-class-ref name="TalkatuEditor"/>
<glade-widget-class-ref name="TalkatuHistory"/>
- <glade-widget-class-ref name="TalkatuHistoryBuffer"/>
+ <glade-widget-class-ref name="TalkatuHistoryRow"/> <glade-widget-class-ref name="TalkatuHtmlBuffer"/>
<glade-widget-class-ref name="TalkatuInput"/>
<glade-widget-class-ref name="TalkatuLinkDialog"/>
<glade-widget-class-ref name="TalkatuMarkdownBuffer"/>
<glade-widget-class-ref name="TalkatuMenuToolButton"/>
+ <glade-widget-class-ref name="TalkatuScrolledWindow"/> <glade-widget-class-ref name="TalkatuToolDrawer"/>
<glade-widget-class-ref name="TalkatuToolbar"/>
<glade-widget-class-ref name="TalkatuTypingLabel"/>
--- a/talkatu/talkatuhistory.c Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/talkatuhistory.c Wed Aug 19 04:05:05 2020 -0500
@@ -20,7 +20,7 @@
#include <talkatu/talkatuhistory.h>
#include <talkatu/talkatuattachmentpreview.h>
-#include <talkatu/talkatuhistorybuffer.h>
+#include <talkatu/talkatuhistoryrow.h> #include <talkatu/talkatumessage.h>
@@ -44,137 +44,20 @@
* A #TalkatuView subclass that is used to display a conversation.
- GtkAdjustment *vadjustment;
-G_DEFINE_TYPE(TalkatuHistory, talkatu_history, TALKATU_TYPE_VIEW)
-/******************************************************************************
- *****************************************************************************/
-talkatu_history_vadjustment_changed_cb(GtkAdjustment *adjustment,
- TalkatuHistory *history = TALKATU_HISTORY(data);
- if(history->auto_scroll) {
- gdouble upper, pagesize;
- upper = gtk_adjustment_get_upper(adjustment);
- pagesize = gtk_adjustment_get_page_size(adjustment);
- gtk_adjustment_set_value(adjustment, upper - pagesize);
-talkatu_history_vadjustment_value_changed_cb(GtkAdjustment *adjustment,
- TalkatuHistory *history = TALKATU_HISTORY(data);
- gdouble current, upper, pagesize;
- current = gtk_adjustment_get_value(adjustment);
- upper = gtk_adjustment_get_upper(adjustment);
- pagesize = gtk_adjustment_get_page_size(adjustment);
- history->auto_scroll = (current + pagesize >= upper);
-talkatu_history_vadjustment_notify_cb(GObject *obj, GParamSpec *pspec,
- TalkatuHistory *history = TALKATU_HISTORY(obj);
- GtkAdjustment *adjustment = NULL;
- adjustment = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(obj));
- if(g_set_object(&history->vadjustment, adjustment)) {
- history->auto_scroll = TRUE;
- g_signal_connect(G_OBJECT(adjustment), "value-changed",
- G_CALLBACK(talkatu_history_vadjustment_value_changed_cb),
- g_signal_connect(G_OBJECT(adjustment), "changed",
- G_CALLBACK(talkatu_history_vadjustment_changed_cb),
-talkatu_history_insert_child_anchor_cb(GtkTextBuffer *buffer, GtkTextIter *iter,
- GtkTextChildAnchor *anchor,
- TalkatuAttachment *attachment = NULL;
- GtkTextView *view = GTK_TEXT_VIEW(data);
- attachment = g_object_get_data(G_OBJECT(anchor), "talkatu:attachment");
- if(TALKATU_IS_ATTACHMENT(attachment)) {
- GtkWidget *preview = talkatu_attachment_preview_new(attachment);
- gtk_text_view_add_child_at_anchor(view, preview, anchor);
- gtk_widget_show(preview);
-talkatu_history_buffer_set_cb(GObject *view, GParamSpec *pspec, gpointer data) {
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- g_signal_handlers_disconnect_by_func(G_OBJECT(buffer),
- G_CALLBACK(talkatu_history_insert_child_anchor_cb),
- g_signal_connect_after(G_OBJECT(buffer), "insert-child-anchor",
- G_CALLBACK(talkatu_history_insert_child_anchor_cb),
-/******************************************************************************
- * GtkTextViewClass overrides
- *****************************************************************************/
-talkatu_history_create_buffer(GtkTextView *view) {
- return talkatu_history_buffer_new();
+G_DEFINE_TYPE(TalkatuHistory, talkatu_history, GTK_TYPE_LIST_BOX) /******************************************************************************
*****************************************************************************/
talkatu_history_init(TalkatuHistory *history) {
- gtk_text_view_set_editable(GTK_TEXT_VIEW(history), FALSE);
- gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(history), FALSE);
- g_signal_connect(G_OBJECT(history), "notify::buffer",
- G_CALLBACK(talkatu_history_buffer_set_cb), NULL);
- history->auto_scroll = TRUE;
- g_signal_connect(G_OBJECT(history), "notify::vadjustment",
- G_CALLBACK(talkatu_history_vadjustment_notify_cb), NULL);
-talkatu_history_finalize(GObject *obj) {
- TalkatuHistory *history = TALKATU_HISTORY(obj);
- g_clear_object(&history->vadjustment);
- G_OBJECT_CLASS(talkatu_history_parent_class)->finalize(obj);
talkatu_history_class_init(TalkatuHistoryClass *klass) {
- GObjectClass *obj_class = G_OBJECT_CLASS(klass);
- GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
- obj_class->finalize = talkatu_history_finalize;
- text_view_class->create_buffer = talkatu_history_create_buffer;
/******************************************************************************
@@ -196,40 +79,22 @@
- * talkatu_history_page_up:
+ * talkatu_history_write_message: * @history: The #TalkatuHistory instance.
+ * @message: The #TalkatuMessage to add to @history. - * Scrolls @history up one page.
+ * Adds @message to @history. Messages are sorted by timestamp so make sure -talkatu_history_page_up(TalkatuHistory *history) {
- g_return_if_fail(TALKATU_IS_HISTORY(history));
- if(history->vadjustment != NULL) {
- value = gtk_adjustment_get_value(history->vadjustment);
- value -= gtk_adjustment_get_page_increment(history->vadjustment);
- gtk_adjustment_set_value(history->vadjustment, value);
+talkatu_history_write_message(TalkatuHistory *history, + TalkatuMessage *message)
- * talkatu_history_page_down:
- * @history: The #TalkatuHistory instance.
- * Scrolls @history down one page.
-talkatu_history_page_down(TalkatuHistory *history) {
g_return_if_fail(TALKATU_IS_HISTORY(history));
+ g_return_if_fail(TALKATU_IS_MESSAGE(message)); - if(history->vadjustment != NULL) {
- value = gtk_adjustment_get_value(history->vadjustment);
- value += gtk_adjustment_get_page_increment(history->vadjustment);
- gtk_adjustment_set_value(history->vadjustment, value);
+ row = talkatu_history_row_new(message); + gtk_container_add(GTK_CONTAINER(history), row);
--- a/talkatu/talkatuhistory.h Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/talkatuhistory.h Wed Aug 19 04:05:05 2020 -0500
@@ -28,18 +28,17 @@
-#include <talkatu/talkatuview.h>
+#include <talkatu/talkatumessage.h> -#define TALKATU_TYPE_HISTORY (talkatu_history_get_type())
+#define TALKATU_TYPE_HISTORY (talkatu_history_get_type()) -G_DECLARE_FINAL_TYPE(TalkatuHistory, talkatu_history, TALKATU, HISTORY, TalkatuView)
+G_DECLARE_FINAL_TYPE(TalkatuHistory, talkatu_history, TALKATU, HISTORY, GtkListBox) GtkWidget *talkatu_history_new(void);
-void talkatu_history_page_up(TalkatuHistory *history);
-void talkatu_history_page_down(TalkatuHistory *history);
+void talkatu_history_write_message(TalkatuHistory *history, TalkatuMessage *message); --- a/talkatu/talkatuinput.c Sun Aug 02 16:14:42 2020 -0500
+++ b/talkatu/talkatuinput.c Wed Aug 19 04:05:05 2020 -0500
@@ -147,8 +147,15 @@
talkatu_input_get_timestamp(TalkatuInput *input) {
TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+ /* If the timestamp has been explicitly set, return that. */ + if(priv->timestamp != NULL) { + return priv->timestamp; - return priv->timestamp;
+ /* If no timestamp has been explicitly set, just return the current local + return g_date_time_new_now_local();