talkatu/talkatu

Parents e6053b81861e
Children 7e0ffe7001ed
Move all attachment and send functionality from TalkatuView to TalkatuInput
--- a/demo/data/demo.ui Tue Jan 28 20:45:56 2020 -0600
+++ b/demo/data/demo.ui Tue Jan 28 21:53:46 2020 -0600
@@ -256,7 +256,7 @@
</packing>
</child>
<child internal-child="input">
- <object class="TalkatuView">
+ <object class="TalkatuInput">
<property name="hexpand_set">True</property>
<property name="vexpand_set">True</property>
<property name="buffer">buffer_plain</property>
--- a/talkatu/meson.build Tue Jan 28 20:45:56 2020 -0600
+++ b/talkatu/meson.build Tue Jan 28 21:53:46 2020 -0600
@@ -83,7 +83,7 @@
'talkatubuffer.h',
'talkatumessage.h',
'talkatutag.h',
- 'talkatuview.h',
+ 'talkatuinput.h',
]
###############################################################################
--- a/talkatu/talkatueditor.c Tue Jan 28 20:45:56 2020 -0600
+++ b/talkatu/talkatueditor.c Tue Jan 28 21:53:46 2020 -0600
@@ -17,10 +17,11 @@
*/
#include <gtk/gtk.h>
+#include <talkatu/talkatueditor.h>
+
#include <talkatu/talkatubuffer.h>
-#include <talkatu/talkatueditor.h>
+#include <talkatu/talkatuinput.h>
#include <talkatu/talkatutoolbar.h>
-#include <talkatu/talkatuview.h>
/**
* SECTION:talkatueditor
@@ -92,7 +93,7 @@
talkatu_editor_send_button_clicked_cb(GtkButton *button, gpointer data) {
TalkatuEditor *editor = TALKATU_EDITOR(data);
- talkatu_view_send_message(TALKATU_VIEW(editor->input));
+ talkatu_input_send_message(TALKATU_INPUT(editor->input));
gtk_widget_grab_focus(editor->input);
}
--- a/talkatu/talkatuinput.c Tue Jan 28 20:45:56 2020 -0600
+++ b/talkatu/talkatuinput.c Tue Jan 28 21:53:46 2020 -0600
@@ -15,34 +15,258 @@
* 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 <glib/gi18n-lib.h>
#include <gspell/gspell.h>
#include "talkatu/talkatuinput.h"
-struct _TalkatuInput {
+#include "talkatu/talkatuattachment.h"
+#include "talkatu/talkatuattachmentdialog.h"
+#include "talkatu/talkatuenums.h"
+#include "talkatu/talkatumarkup.h"
+
+typedef struct {
TalkatuView parent;
GspellTextView *gspell_view;
+
+ TalkatuInputSendBinding send_binding;
+
+ /* this mark is used to keep track of our context for the context menu. It
+ * is updated via cursor-moved and button-press callbacks.
+ */
+ GtkTextMark *context_mark;
+} TalkatuInputPrivate;
+
+enum {
+ PROP_0 = 0,
+ PROP_SEND_BINDING,
+ N_PROPERTIES,
};
+static GParamSpec *properties[N_PROPERTIES];
+
+enum {
+ SIG_SHOULD_SEND_MESSAGE,
+ SIG_SEND_MESSAGE,
+ LAST_SIGNAL,
+};
+static guint signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE_WITH_PRIVATE(TalkatuInput, talkatu_input, TALKATU_TYPE_VIEW)
/******************************************************************************
* Callbacks
*****************************************************************************/
static void
+talkatu_input_send_message_cb(GtkMenuItem *item, gpointer data) {
+ talkatu_input_send_message(TALKATU_INPUT(data));
+
+ gtk_widget_grab_focus(GTK_WIDGET(data));
+}
+
+
+static void
+talkatu_input_populate_popup_cb(GtkTextView *view, GtkWidget *popup) {
+ TalkatuInputPrivate *priv = NULL;
+ GtkTextBuffer *buffer = NULL;
+ GtkTextIter iter;
+ GtkWidget *item = NULL;
+ gint pos = 0;
+
+ /* if the popup isn't a menu, bail */
+ if(!GTK_IS_MENU(popup)) {
+ return;
+ }
+
+ priv = talkatu_input_get_instance_private(TALKATU_INPUT(view));
+
+ buffer = gtk_text_view_get_buffer(view);
+
+ gtk_text_buffer_get_iter_at_mark(buffer, &iter, priv->context_mark);
+
+ /* add the send message item */
+ if(gtk_text_view_get_editable(view)) {
+ item = gtk_menu_item_new_with_label(_("Send message"));
+ g_signal_connect_after(
+ G_OBJECT(item),
+ "activate",
+ G_CALLBACK(talkatu_input_send_message_cb),
+ view
+ );
+ gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item, pos++);
+ gtk_widget_show(item);
+
+ item = gtk_separator_menu_item_new();
+ gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item , pos++);
+ gtk_widget_show(item);
+ }
+}
+
+static void
talkatu_input_buffer_set_cb(GObject *view, GParamSpec *pspec, gpointer data) {
+ TalkatuInputPrivate *priv = NULL;
TalkatuInput *input = TALKATU_INPUT(view);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
+ GtkTextIter start;
- gspell_text_view_basic_setup(input->gspell_view);
+ priv = talkatu_input_get_instance_private(input);
+
+ gspell_text_view_basic_setup(priv->gspell_view);
+
+ /* grab our context_mark */
+ gtk_text_buffer_get_start_iter(buffer, &start);
+ priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE);
+
+}
+
+static void
+talkatu_input_attachment_response_cb(GtkDialog *dialog, gint response,
+ gpointer data)
+{
+ /* If the user hits escape response is set to GTK_RESPONSE_DELETE_EVENT
+ * and Gtk cleans up the dialog for us automatically.
+ */
+
+ if(response == GTK_RESPONSE_CANCEL) {
+ /* we call this separately for GTK_RESPONSE_CANCEL be
+ * GTK_RESPONSE_DELETE_EVENT already destroys the dialog.
+ */
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ } else if(response == GTK_RESPONSE_ACCEPT) {
+ GtkTextBuffer *buffer = NULL;
+ TalkatuAttachment *attachment = NULL;
+ TalkatuAttachmentDialog *adialog = TALKATU_ATTACHMENT_DIALOG(dialog);
+ TalkatuInput *input = TALKATU_INPUT(data);
+ const gchar *comment = NULL;
+
+ comment = talkatu_attachment_dialog_get_comment(adialog);
+
+ /* it's a pretty safe assumption that our buffer is a talkatu buffer */
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
+ talkatu_markup_set_html(TALKATU_BUFFER(buffer), comment, -1);
+
+ /* now send the attachment */
+ attachment = talkatu_attachment_dialog_get_attachment(adialog);
+ g_object_unref(G_OBJECT(attachment));
+
+ /* send the message */
+ talkatu_input_send_message(input);
+
+ /* kill the dialog */
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ }
+}
+
+static void
+talkatu_input_image_received_cb(GtkClipboard *clipboard, GdkPixbuf *pixbuf,
+ gpointer data)
+{
+ TalkatuAttachment *attachment = NULL;
+ GtkWidget *dialog = NULL, *input = NULL;
+ GtkTextBuffer *buffer = NULL;
+ gchar *comment = NULL;
+
+ input = GTK_WIDGET(data);
+ 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);
+
+ dialog = talkatu_attachment_dialog_new(attachment, comment);
+ g_signal_connect(G_OBJECT(dialog), "response",
+ G_CALLBACK(talkatu_input_attachment_response_cb), input);
+ gtk_widget_show_all(dialog);
+
+ g_free(comment);
+}
+
+/******************************************************************************
+ * Default Signal Handlers
+ *****************************************************************************/
+static gboolean
+talkatu_input_popup_menu(GtkWidget *widget) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(TALKATU_INPUT(widget));
+ GtkTextBuffer *buffer = NULL;
+ GtkTextIter iter;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+
+ gtk_text_buffer_get_iter_at_mark(
+ buffer,
+ &iter,
+ gtk_text_buffer_get_insert(buffer)
+ );
+
+ gtk_text_buffer_move_mark(buffer, priv->context_mark, &iter);
+
+ return GTK_WIDGET_CLASS(talkatu_input_parent_class)->popup_menu(widget);
+}
+
+static void
+talkatu_input_should_send_message(TalkatuInput *input, TalkatuInputSendBinding binding) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
+ if((priv->send_binding & binding) != 0) {
+ talkatu_input_send_message(input);
+ } else if(gtk_text_view_get_editable(GTK_TEXT_VIEW(input))) {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
+
+ gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
+ }
+}
+
+/******************************************************************************
+ * GtkTextViewClass overrides
+ *****************************************************************************/
+static void
+talkatu_input_paste_clipboard(GtkTextView *view) {
+ GtkClipboard *clipboard =
+ gtk_widget_get_clipboard(GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD);
+
+ if(gtk_clipboard_wait_is_image_available(clipboard)) {
+ gtk_clipboard_request_image(clipboard, talkatu_input_image_received_cb,
+ view);
+ } else {
+ GTK_TEXT_VIEW_CLASS(talkatu_input_parent_class)->paste_clipboard(view);
+ }
}
/******************************************************************************
* GObject Implementation
*****************************************************************************/
-G_DEFINE_TYPE(TalkatuInput, talkatu_input, TALKATU_TYPE_VIEW)
+static void
+talkatu_input_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
+ TalkatuInput *input = TALKATU_INPUT(obj);
+
+ switch(prop_id) {
+ case PROP_SEND_BINDING:
+ g_value_set_flags(value, talkatu_input_get_send_binding(input));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+talkatu_input_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) {
+ TalkatuInput *input = TALKATU_INPUT(obj);
+
+ switch(prop_id) {
+ case PROP_SEND_BINDING:
+ talkatu_input_set_send_binding(input, g_value_get_flags(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
static void
talkatu_input_init(TalkatuInput *input) {
+ TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+
/* we need to know when the buffer is changed in our parent so we can
* update our actions and other stuff.
*/
@@ -54,11 +278,92 @@
);
/* setup GSpell */
- input->gspell_view = gspell_text_view_get_from_gtk_text_view(GTK_TEXT_VIEW(input));
+ priv->gspell_view = gspell_text_view_get_from_gtk_text_view(GTK_TEXT_VIEW(input));
+
+ /* we need to connect this signal *AFTER* everything to make sure our items
+ * end up in the correct place.
+ */
+ g_signal_connect_after(
+ G_OBJECT(input),
+ "populate-popup",
+ G_CALLBACK(talkatu_input_populate_popup_cb),
+ NULL
+ );
}
static void
talkatu_input_class_init(TalkatuInputClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
+ GtkBindingSet *binding_set = NULL;
+
+ obj_class->get_property = talkatu_input_get_property;
+ obj_class->set_property = talkatu_input_set_property;
+
+ widget_class->popup_menu = talkatu_input_popup_menu;
+
+ text_view_class->paste_clipboard = talkatu_input_paste_clipboard;
+
+ klass->should_send_message = talkatu_input_should_send_message;
+
+ /* add our properties */
+ properties[PROP_SEND_BINDING] = g_param_spec_flags(
+ "send-binding", "send-binding", "The keybindings that will trigger the send signal",
+ TALKATU_TYPE_INPUT_SEND_BINDING,
+ TALKATU_INPUT_SEND_BINDING_RETURN | TALKATU_INPUT_SEND_BINDING_KP_ENTER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT
+ );
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+
+ /**
+ * TalkatuInput::should-send-message:
+ * @talkatuinput: The #TalkatuInput instance.
+ * @arg1: The #TalkatuInputSendBinding that was entered.
+ * @user_data: User supplied data.
+ *
+ * Emitted when a potential keybinding to send the message is entered to
+ * determine if the message should be sent.
+ */
+ signals[SIG_SHOULD_SEND_MESSAGE] = g_signal_new(
+ "should-send-message",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(TalkatuInputClass, should_send_message),
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 1,
+ TALKATU_TYPE_INPUT_SEND_BINDING
+ );
+
+ /**
+ * TalkatuInput::send-message:
+ * @talkatuinput: The #TalkatuInput instance.
+ * @user_data: User supplied data.
+ *
+ * Emitted when a message should be sent.
+ */
+ signals[SIG_SEND_MESSAGE] = g_signal_new(
+ "send-message",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(TalkatuInputClass, send_message),
+ NULL,
+ NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0
+ );
+
+ /* setup key bindings */
+ binding_set = gtk_binding_set_by_class(talkatu_input_parent_class);
+
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, 0, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_RETURN);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_SHIFT_MASK, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_CONTROL_MASK, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_CONTROL_RETURN);
+ gtk_binding_entry_add_signal(binding_set, GDK_KEY_KP_Enter, 0, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_KP_ENTER);
}
/******************************************************************************
@@ -68,3 +373,60 @@
talkatu_input_new(void) {
return NULL;
}
+
+/**
+ * talkatu_input_set_send_binding:
+ * @input: The #TalkatuInput instance.
+ * @bindings: The #TalkatuInputSendBinding value.
+ *
+ * Sets the bindings for when the send-message signal should be emitted.
+ */
+void
+talkatu_input_set_send_binding(TalkatuInput *input,
+ TalkatuInputSendBinding bindings)
+{
+ TalkatuInputPrivate *priv = NULL;
+
+ g_return_if_fail(TALKATU_IS_INPUT(input));
+
+ priv = talkatu_input_get_instance_private(TALKATU_INPUT(input));
+
+ priv->send_binding = bindings;
+
+ g_object_notify_by_pspec(G_OBJECT(input), properties[PROP_SEND_BINDING]);
+}
+
+/**
+ * talkatu_input_get_send_binding:
+ * @input: The #TalkatuInput instance.
+ *
+ * Gets the #TalkatuInputSendBinding which determines when send-message
+ * signal will be emitted.
+ *
+ * Returns: The #TalkatuInputSendBinding.
+ */
+TalkatuInputSendBinding
+talkatu_input_get_send_binding(TalkatuInput *input) {
+ TalkatuInputPrivate *priv = NULL;
+
+ g_return_val_if_fail(TALKATU_IS_INPUT(input), 0);
+
+ priv = talkatu_input_get_instance_private(TALKATU_INPUT(priv));
+
+ return priv->send_binding;
+}
+
+/**
+ * talkatu_input_send_message:
+ * @input: The #TalkatuInput instance.
+ *
+ * Emits the signal that @input is trying to send a message. This is used for
+ * cases like the optional send button in #TalkatuEditor and other instances
+ * where the user has performed an action to send a message.
+ */
+void
+talkatu_input_send_message(TalkatuInput *input) {
+ g_return_if_fail(TALKATU_IS_INPUT(input));
+
+ g_signal_emit(input, signals[SIG_SEND_MESSAGE], 0);
+}
--- a/talkatu/talkatuinput.h Tue Jan 28 20:45:56 2020 -0600
+++ b/talkatu/talkatuinput.h Tue Jan 28 21:53:46 2020 -0600
@@ -30,13 +30,38 @@
#include <talkatu/talkatuview.h>
+typedef enum _TalkatuInputSendBinding /*< prefix=TALKATU_INPUT_SEND_BINDING,underscore_name=TALKATU_INPUT_SEND_BINDING >*/
+{
+ TALKATU_INPUT_SEND_BINDING_RETURN = 1 << 0,
+ TALKATU_INPUT_SEND_BINDING_KP_ENTER = 1 << 1,
+ TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN = 1 << 2,
+ TALKATU_INPUT_SEND_BINDING_CONTROL_RETURN = 1 << 3,
+} TalkatuInputSendBinding;
+
G_BEGIN_DECLS
#define TALKATU_TYPE_INPUT (talkatu_input_get_type())
-G_DECLARE_FINAL_TYPE(TalkatuInput, talkatu_input, TALKATU, INPUT, TalkatuView)
+G_DECLARE_DERIVABLE_TYPE(TalkatuInput, talkatu_input, TALKATU, INPUT, TalkatuView)
+
+struct _TalkatuInputClass {
+ /*< private >*/
+ TalkatuViewClass parent;
+
+ /*< public >*/
+ void (*should_send_message)(TalkatuInput *input, TalkatuInputSendBinding binding);
+ void (*send_message)(TalkatuInput *input);
+
+ /*< private >*/
+ gpointer reserved[4];
+};
GtkWidget *talkatu_input_new(void);
+void talkatu_input_set_send_binding(TalkatuInput *input, TalkatuInputSendBinding bindings);
+TalkatuInputSendBinding talkatu_input_get_send_binding(TalkatuInput *input);
+
+void talkatu_input_send_message(TalkatuInput *input);
+
G_END_DECLS
#endif /* TALKATU_INPUT_H */
--- a/talkatu/talkatuview.c Tue Jan 28 20:45:56 2020 -0600
+++ b/talkatu/talkatuview.c Tue Jan 28 21:53:46 2020 -0600
@@ -25,7 +25,6 @@
#include "talkatu/talkatuattachment.h"
#include "talkatu/talkatuattachmentdialog.h"
#include "talkatu/talkatubuffer.h"
-#include "talkatu/talkatuenums.h"
#include "talkatu/talkatumarkup.h"
#include "talkatu/talkatutag.h"
#include "talkatu/talkatuview.h"
@@ -76,12 +75,6 @@
typedef struct {
GSimpleActionGroup *action_group;
- TalkatuViewSendBinding send_binding;
-
- /* this mark is used to keep track of our context for the context menu. It
- * is updated via cursor-moved and button-press callbacks.
- */
- GtkTextMark *context_mark;
/* we cache the cursor that's displayed while hovering over a link as well
* the tag for links/anchors to avoid extra lookups.
@@ -91,16 +84,7 @@
} TalkatuViewPrivate;
enum {
- PROP_0 = 0,
- PROP_SEND_BINDING,
- N_PROPERTIES,
-};
-static GParamSpec *properties[N_PROPERTIES];
-
-enum {
SIG_FORMAT_ACTIVATE,
- SIG_SHOULD_SEND_MESSAGE,
- SIG_SEND_MESSAGE,
SIG_OPEN_URL,
LAST_SIGNAL,
};
@@ -252,15 +236,11 @@
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(view));
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
GtkTextTagTable *table = gtk_text_buffer_get_tag_table(buffer);
- GtkTextIter start;
if(TALKATU_IS_BUFFER(buffer)) {
priv->action_group = talkatu_buffer_get_action_group(TALKATU_BUFFER(buffer));
}
- gtk_text_buffer_get_start_iter(buffer, &start);
- priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE);
-
/* check for the anchor tag, if we have it, add a signal handler to it */
priv->tag_anchor = gtk_text_tag_table_lookup(table, TALKATU_TAG_ANCHOR);
if(priv->tag_anchor != NULL) {
@@ -273,67 +253,6 @@
}
}
-static void
-talkaktu_view_attachment_response_cb(GtkDialog *dialog, gint response,
- gpointer data)
-{
- /* If the user hit's escape response is GTK_RESPONSE_DELETE_EVENT and
- * Gtk cleans up the dialog for us automatically.
- */
-
- if(response == GTK_RESPONSE_CANCEL) {
- /* we call this separately for GTK_RESPONSE_CANCEL be
- * GTK_RESPONSE_DELETE_EVENT already destroys the dialog.
- */
- gtk_widget_destroy(GTK_WIDGET(dialog));
- } else if(response == GTK_RESPONSE_ACCEPT) {
- GtkTextBuffer *buffer = NULL;
- TalkatuAttachment *attachment = NULL;
- TalkatuAttachmentDialog *adialog = TALKATU_ATTACHMENT_DIALOG(dialog);
- TalkatuView *view = TALKATU_VIEW(data);
- const gchar *comment = NULL;
-
- comment = talkatu_attachment_dialog_get_comment(adialog);
-
- /* it's a pretty safe assumption that our buffer is a talkatu buffer */
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- talkatu_markup_set_html(TALKATU_BUFFER(buffer), comment, -1);
-
- /* now send the attachment */
- attachment = talkatu_attachment_dialog_get_attachment(adialog);
- g_object_unref(G_OBJECT(attachment));
-
- /* send the message */
- talkatu_view_send_message(view);
-
- /* kill the dialog */
- gtk_widget_destroy(GTK_WIDGET(dialog));
- }
-}
-
-static void
-talkatu_view_image_received_cb(GtkClipboard *clipboard, GdkPixbuf *pixbuf,
- gpointer data)
-{
- TalkatuAttachment *attachment = NULL;
- GtkWidget *dialog = NULL, *view = NULL;
- GtkTextBuffer *buffer = NULL;
- gchar *comment = NULL;
-
- view = GTK_WIDGET(data);
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- comment = talkatu_markup_get_html(buffer, NULL);
-
- attachment = talkatu_attachment_new_from_pixbuf("unknown.png", pixbuf);
-
- dialog = talkatu_attachment_dialog_new(attachment, comment);
- g_signal_connect(G_OBJECT(dialog), "response",
- G_CALLBACK(talkaktu_view_attachment_response_cb), view);
- gtk_widget_show_all(dialog);
-
- g_free(comment);
-}
-
/******************************************************************************
* Default Signal Handlers
*****************************************************************************/
@@ -350,82 +269,6 @@
}
}
-static void
-talkatu_view_should_send_message(TalkatuView *view, TalkatuViewSendBinding binding) {
- TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
-
- if((priv->send_binding & binding) != 0) {
- talkatu_view_send_message(view);
- } else if(gtk_text_view_get_editable(GTK_TEXT_VIEW(view))) {
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
-
- gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
- }
-}
-
-static gboolean
-talkatu_view_popup_menu(GtkWidget *widget) {
- TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(widget));
- GtkTextBuffer *buffer = NULL;
- GtkTextIter iter;
-
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
-
- gtk_text_buffer_get_iter_at_mark(
- buffer,
- &iter,
- gtk_text_buffer_get_insert(buffer)
- );
-
- gtk_text_buffer_move_mark(buffer, priv->context_mark, &iter);
-
- return GTK_WIDGET_CLASS(talkatu_view_parent_class)->popup_menu(widget);
-}
-
-static void
-talkatu_view_send_message_cb(GtkMenuItem *item, gpointer data) {
- talkatu_view_send_message(TALKATU_VIEW(data));
-
- gtk_widget_grab_focus(GTK_WIDGET(data));
-}
-
-static void
-talkatu_view_populate_popup_cb(GtkTextView *view, GtkWidget *popup) {
- TalkatuViewPrivate *priv = NULL;
- GtkTextBuffer *buffer = NULL;
- GtkTextIter iter;
- GtkWidget *item = NULL;
- gint pos = 0;
-
- /* if the popup isn't a menu, bail */
- if(!GTK_IS_MENU(popup)) {
- return;
- }
-
- priv = talkatu_view_get_instance_private(TALKATU_VIEW(view));
-
- buffer = gtk_text_view_get_buffer(view);
-
- gtk_text_buffer_get_iter_at_mark(buffer, &iter, priv->context_mark);
-
- /* add the send message item */
- if(gtk_text_view_get_editable(view)) {
- item = gtk_menu_item_new_with_label(_("Send message"));
- g_signal_connect_after(
- G_OBJECT(item),
- "activate",
- G_CALLBACK(talkatu_view_send_message_cb),
- view
- );
- gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item, pos++);
- gtk_widget_show(item);
-
- item = gtk_separator_menu_item_new();
- gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item , pos++);
- gtk_widget_show(item);
- }
-}
-
static gboolean
talkatu_view_query_tooltip(GtkWidget *widget,
gint x,
@@ -505,19 +348,6 @@
return talkatu_buffer_new(NULL);
}
-static void
-talkatu_view_paste_clipboard(GtkTextView *view) {
- GtkClipboard *clipboard =
- gtk_widget_get_clipboard(GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD);
-
- if(gtk_clipboard_wait_is_image_available(clipboard)) {
- gtk_clipboard_request_image(clipboard, talkatu_view_image_received_cb,
- view);
- } else {
- GTK_TEXT_VIEW_CLASS(talkatu_view_parent_class)->paste_clipboard(view);
- }
-}
-
/******************************************************************************
* GObject Stuff
*****************************************************************************/
@@ -531,34 +361,6 @@
}
static void
-talkatu_view_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
- TalkatuView *view = TALKATU_VIEW(obj);
-
- switch(prop_id) {
- case PROP_SEND_BINDING:
- g_value_set_flags(value, talkatu_view_get_send_binding(view));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-talkatu_view_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) {
- TalkatuView *view = TALKATU_VIEW(obj);
-
- switch(prop_id) {
- case PROP_SEND_BINDING:
- talkatu_view_set_send_binding(view, g_value_get_flags(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
- break;
- }
-}
-
-static void
talkatu_view_init(TalkatuView *view) {
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
@@ -584,16 +386,6 @@
G_CALLBACK(talkatu_view_buffer_set_cb),
NULL
);
-
- /* we need to connect this signal *AFTER* everything to make sure our items
- * end up in the correct place.
- */
- g_signal_connect_after(
- G_OBJECT(view),
- "populate-popup",
- G_CALLBACK(talkatu_view_populate_popup_cb),
- NULL
- );
}
static void
@@ -603,29 +395,15 @@
GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
GtkBindingSet *binding_set = NULL;
- obj_class->get_property = talkatu_view_get_property;
- obj_class->set_property = talkatu_view_set_property;
obj_class->finalize = talkatu_view_finalize;
widget_class->motion_notify_event = talkatu_view_motion_notify_event;
- widget_class->popup_menu = talkatu_view_popup_menu;
widget_class->query_tooltip = talkatu_view_query_tooltip;
text_view_class->create_buffer = talkatu_view_create_buffer;
- text_view_class->paste_clipboard = talkatu_view_paste_clipboard;
/* add our default signal handlers */
klass->format_activate = talkatu_view_format_activate;
- klass->should_send_message = talkatu_view_should_send_message;
-
- /* add our properties */
- properties[PROP_SEND_BINDING] = g_param_spec_flags(
- "send-binding", "send-binding", "The keybindings that will trigger the send signal",
- TALKATU_TYPE_VIEW_SEND_BINDING,
- TALKATU_VIEW_SEND_BINDING_RETURN | TALKATU_VIEW_SEND_BINDING_KP_ENTER,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT
- );
- g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
/* add our signals */
@@ -651,47 +429,6 @@
);
/**
- * TalkatuView::should-send-message:
- * @talkatutextview: The #TalkatuView instance.
- * @arg1: The #TalkatuViewSendBinding that was entered.
- * @user_data: User supplied data.
- *
- * Emitted when a potential keybinding to send the message is entered to
- * determine if the message should be sent.
- */
- signals[SIG_SHOULD_SEND_MESSAGE] = g_signal_new(
- "should-send-message",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(TalkatuViewClass, should_send_message),
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 1,
- TALKATU_TYPE_VIEW_SEND_BINDING
- );
-
- /**
- * TalkatuView::send-message:
- * @talkatuview: The #TalkatuView instance.
- * @user_data: User supplied data.
- *
- * Emitted when a message should be sent.
- */
- signals[SIG_SEND_MESSAGE] = g_signal_new(
- "send-message",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(TalkatuViewClass, send_message),
- NULL,
- NULL,
- NULL,
- G_TYPE_NONE,
- 0
- );
-
- /**
* TalkatuView::open-url:
* @talkatutextview: The #TalkatuView instances.
* @url: The URL to open.
@@ -727,11 +464,6 @@
gtk_binding_entry_add_signal(binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_GROW);
gtk_binding_entry_add_signal(binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_SHRINK);
gtk_binding_entry_add_signal(binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format-activate", 1, G_TYPE_STRING, TALKATU_ACTION_FORMAT_RESET);
-
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, 0, "should-send-message", 1, TALKATU_TYPE_VIEW_SEND_BINDING, TALKATU_VIEW_SEND_BINDING_RETURN);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_SHIFT_MASK, "should-send-message", 1, TALKATU_TYPE_VIEW_SEND_BINDING, TALKATU_VIEW_SEND_BINDING_SHIFT_RETURN);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_CONTROL_MASK, "should-send-message", 1, TALKATU_TYPE_VIEW_SEND_BINDING, TALKATU_VIEW_SEND_BINDING_CONTROL_RETURN);
- gtk_binding_entry_add_signal(binding_set, GDK_KEY_KP_Enter, 0, "should-send-message", 1, TALKATU_TYPE_VIEW_SEND_BINDING, TALKATU_VIEW_SEND_BINDING_KP_ENTER);
}
/******************************************************************************
@@ -763,58 +495,3 @@
"buffer", buffer,
NULL));
}
-
-/**
- * talkatu_view_set_send_binding:
- * @view: The #TalkatuView instance.
- * @bindings: The #TalkatuViewSendBinding value.
- *
- * Sets the bindings for when the send-message signal should be emitted.
- */
-void
-talkatu_view_set_send_binding(TalkatuView *view, TalkatuViewSendBinding bindings) {
- TalkatuViewPrivate *priv = NULL;
-
- g_return_if_fail(TALKATU_IS_VIEW(view));
-
- priv = talkatu_view_get_instance_private(view);
-
- priv->send_binding = bindings;
-
- g_object_notify_by_pspec(G_OBJECT(view), properties[PROP_SEND_BINDING]);
-}
-
-/**
- * talkatu_view_get_send_binding:
- * @view: The #TalkatuView instance.
- *
- * Gets the #TalkatuViewSendBinding which determines when send-message
- * signal will be emitted.
- *
- * Returns: The #TalkatuViewSendBinding.
- */
-TalkatuViewSendBinding
-talkatu_view_get_send_binding(TalkatuView *view) {
- TalkatuViewPrivate *priv = NULL;
-
- g_return_val_if_fail(TALKATU_IS_VIEW(view), 0);
-
- priv = talkatu_view_get_instance_private(view);
-
- return priv->send_binding;
-}
-
-/**
- * talkatu_view_send_message:
- * @view: The #TalkatuView instance.
- *
- * Emits the signal that @view is trying to send a message. This is used for
- * cases like the optional send button in #TalkatuEditor and other instances
- * where the user has performed an action to send a message.
- */
-void
-talkatu_view_send_message(TalkatuView *view) {
- g_return_if_fail(TALKATU_IS_VIEW(view));
-
- g_signal_emit(view, signals[SIG_SEND_MESSAGE], 0);
-}
--- a/talkatu/talkatuview.h Tue Jan 28 20:45:56 2020 -0600
+++ b/talkatu/talkatuview.h Tue Jan 28 21:53:46 2020 -0600
@@ -28,14 +28,6 @@
#include <gtk/gtk.h>
-typedef enum _TalkatuViewSendBinding /*< prefix=TALKATU_VIEW_SEND_BINDING,underscore_name=TALKATU_VIEW_SEND_BINDING >*/
-{
- TALKATU_VIEW_SEND_BINDING_RETURN = 1 << 0,
- TALKATU_VIEW_SEND_BINDING_KP_ENTER = 1 << 1,
- TALKATU_VIEW_SEND_BINDING_SHIFT_RETURN = 1 << 2,
- TALKATU_VIEW_SEND_BINDING_CONTROL_RETURN = 1 << 3,
-} TalkatuViewSendBinding;
-
G_BEGIN_DECLS
#define TALKATU_TYPE_VIEW (talkatu_view_get_type())
@@ -49,9 +41,6 @@
/*< public >*/
void (*format_activate)(TalkatuView *view, const gchar *action_name);
- void (*should_send_message)(TalkatuView *view, TalkatuViewSendBinding binding);
- void (*send_message)(TalkatuView *view);
-
void (*open_url)(TalkatuView *view, const gchar *url);
/*< private >*/
@@ -61,11 +50,6 @@
GtkWidget *talkatu_view_new(void);
GtkWidget *talkatu_view_new_with_buffer(GtkTextBuffer *buffer);
-void talkatu_view_set_send_binding(TalkatuView *view, TalkatuViewSendBinding bindings);
-TalkatuViewSendBinding talkatu_view_get_send_binding(TalkatuView *view);
-
-void talkatu_view_send_message(TalkatuView *view);
-
G_END_DECLS
#endif /* TALKATU_VIEW_H */