qulogic/talkatu

Parents e613440f1a44
Children d0e944867bab
Create a subclass of GSimpleActionGroup to that we can easily track format changes
--- a/talkatu/meson.build Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/meson.build Thu Sep 13 22:02:02 2018 -0500
@@ -4,7 +4,7 @@
TALKATU_LIBRARY_VERSION = '0.1.0'
TALKATU_HEADERS = [
- 'talkatuaction.h',
+ 'talkatuactiongroup.h',
'talkatubuffer.h',
'talkatucodeset.h',
'talkatucore.h',
@@ -27,7 +27,7 @@
]
TALKATU_SOURCES = [
- 'talkatuaction.c',
+ 'talkatuactiongroup.c',
'talkatubuffer.c',
'talkatucodeset.c',
'talkatucore.c',
--- a/talkatu/talkatuaction.c Thu Sep 13 12:24:30 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,401 +0,0 @@
-/*
- * talkatu
- * Copyright (C) 2017-2018 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 <glib/gi18n-lib.h>
-
-#include "talkatu/talkatuaction.h"
-#include "talkatu/talkatubuffer.h"
-#include "talkatu/talkatulinkdialog.h"
-#include "talkatu/talkatutag.h"
-
-/**
- * SECTION:talkatuaction
- * @Title: Talkatu Actions
- * @Short_description: GAction Helpers
- *
- * A lot of Talkatu's user interation is handled by #GAction's. These
- * functions help make that easier.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_BOLD:
- *
- * A constant that represents the bold font style action.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_ITALIC:
- *
- * A constant that represents the italic font style action.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_UNDERLINE:
- *
- * A constant that represents the underline font style action.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_STRIKETHROUGH:
- *
- * A constant that represents the strike through font style action.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_GROW:
- *
- * A constant that represents the increase font size action.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_SHRINK:
- *
- * A constant that represents the decrease font size action.
- */
-
-/**
- * TALKATU_ACTION_FORMAT_RESET:
- *
- * A constant that represents the reset all formatting action.
- */
-
-/******************************************************************************
- * Callbacks
- *****************************************************************************/
-typedef struct {
- const gchar *name;
- GCallback activate;
- GCallback change_state;
-} TalkatuActionEntry;
-
-/******************************************************************************
- * Callbacks
- *****************************************************************************/
-static void
-talkatu_action_activate(GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- g_message(_("activating action %s"), g_action_get_name(G_ACTION(action)));
-}
-
-static void
-talkatu_action_toggle(GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GVariant *state = NULL;
-
- g_message(_("toggling action %s"), g_action_get_name(G_ACTION(action)));
-
- state = g_action_get_state(G_ACTION(action));
- g_action_change_state(
- G_ACTION(action),
- g_variant_new_boolean(!g_variant_get_boolean(state))
- );
- g_variant_unref(state);
-}
-
-static void
-talkatu_action_format_toggle(GSimpleAction *action,
- GVariant *state,
- gpointer data)
-{
- GtkTextBuffer *buffer = GTK_TEXT_BUFFER(data);
- GtkTextIter start, end;
- TalkatuBufferStyle style = talkatu_buffer_get_style(TALKATU_BUFFER(buffer));
- gboolean apply = FALSE;
-
- if(style == TALKATU_BUFFER_STYLE_WHOLE) {
- gtk_text_buffer_get_bounds(buffer, &start, &end);
- apply = TRUE;
- } else {
- if(gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) {
- apply = TRUE;
- }
- }
-
- if(apply) {
- const gchar *tag_name = NULL, *name = NULL;
-
- name = g_action_get_name(G_ACTION(action));
- tag_name = talkatu_tag_name_for_action_name(name);
-
- if(tag_name == NULL) {
- return;
- }
-
- gtk_text_buffer_begin_user_action(buffer);
-
- if(g_variant_get_boolean(state)) {
- gtk_text_buffer_apply_tag_by_name(buffer, tag_name, &start, &end);
- } else {
- gtk_text_buffer_remove_tag_by_name(buffer, tag_name, &start, &end);
- }
-
- gtk_text_buffer_end_user_action(buffer);
- }
-
- g_simple_action_set_state(action, state);
-}
-
-
-static void
-talkatu_action_insert_link(GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
- GtkWidget *link_dialog = talkatu_link_dialog_new();
-
- if(gtk_dialog_run(GTK_DIALOG(link_dialog)) == GTK_RESPONSE_ACCEPT) {
- GtkTextChildAnchor *anchor = NULL;
- GtkTextMark *insert_mark = NULL;
- GtkTextIter insert;
- gchar *url = NULL, *label = NULL;
-
- if(gtk_text_buffer_get_has_selection(buffer)) {
- gtk_text_buffer_delete_selection(buffer, TRUE, TRUE);
- }
-
- insert_mark = gtk_text_buffer_get_insert(buffer);
- gtk_text_buffer_get_iter_at_mark(buffer, &insert, insert_mark);
-
- anchor = gtk_text_buffer_create_child_anchor(buffer, &insert);
-
- url = talkatu_link_dialog_get_url(TALKATU_LINK_DIALOG(link_dialog));
- g_object_set_data_full(G_OBJECT(anchor), "talkatu-url", url, g_free);
-
- label = talkatu_link_dialog_get_display_text(TALKATU_LINK_DIALOG(link_dialog));
- g_object_set_data_full(G_OBJECT(anchor), "talkatu-url-label", label, g_free);
-
- gtk_text_buffer_insert_child_anchor(buffer, &insert, anchor);
- }
-
- gtk_widget_destroy(link_dialog);
-}
-
-/******************************************************************************
- * Helpers
- *****************************************************************************/
-static GSimpleAction *
-talkatu_action_new(TalkatuActionEntry *entry, GtkTextBuffer *buffer) {
- GSimpleAction *action = NULL;
-
- /* if we have a state_cb create a stateful action */
- if(entry->change_state != NULL) {
- GVariant *variant = g_variant_new_boolean(FALSE);
- action = g_simple_action_new_stateful(entry->name, NULL, variant);
-
- g_signal_connect(G_OBJECT(action), "change-state", entry->change_state, buffer);
- } else {
- action = g_simple_action_new(entry->name, NULL);
- }
-
- if(entry->activate != NULL) {
- g_signal_connect(G_OBJECT(action), "activate", entry->activate, buffer);
- }
-
- return action;
-}
-
-static void
-talkatu_action_add(GActionMap *map,
- GtkTextBuffer *buffer,
- TalkatuActionEntry *entry)
-{
- GSimpleAction *action = NULL;
-
- g_return_if_fail(G_IS_ACTION_MAP(map));
- g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-
- action = talkatu_action_new(entry, buffer);
- g_action_map_add_action(map, G_ACTION(action));
- g_object_unref(G_OBJECT(action));
-}
-
-/******************************************************************************
- * API
- *****************************************************************************/
-
-/**
- * talkatu_action_add_bold:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make will apply bold formatting when activated.
- */
-void
-talkatu_action_add_bold(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_BOLD,
- .activate = G_CALLBACK(talkatu_action_toggle),
- .change_state = G_CALLBACK(talkatu_action_format_toggle)
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_italic:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make will apply italic formatting when activated.
- */
-void
-talkatu_action_add_italic(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_ITALIC,
- .activate = G_CALLBACK(talkatu_action_toggle),
- .change_state = G_CALLBACK(talkatu_action_format_toggle)
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_underline:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make will apply underlined formatting when
- * activated.
- */
-void
-talkatu_action_add_underline(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_UNDERLINE,
- .activate = G_CALLBACK(talkatu_action_toggle),
- .change_state = G_CALLBACK(talkatu_action_format_toggle)
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_strikethrough:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make will apply strikethrough formatting when
- * activated.
- */
-void
-talkatu_action_add_strikethrough(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_STRIKETHROUGH,
- .activate = G_CALLBACK(talkatu_action_toggle),
- .change_state = G_CALLBACK(talkatu_action_format_toggle)
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_grow:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make will increase the font size when activated.
- */
-void
-talkatu_action_add_grow(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_GROW,
- .activate = G_CALLBACK(talkatu_action_activate),
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_shrink:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make will decrease the font size when activated.
- */
-void
-talkatu_action_add_shrink(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_SHRINK,
- .activate = G_CALLBACK(talkatu_action_activate),
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_reset:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will make remove all formatting when activated.
- */
-void
-talkatu_action_add_reset(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_FORMAT_RESET,
- .activate = G_CALLBACK(talkatu_action_activate),
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_add_link:
- * @map: The #GActionMap to add the action to.
- * @buffer: The #GtkTextBuffer to add this action to.
- *
- * Adds an action that will display an anchor link window when activated.
- */
-void
-talkatu_action_add_link(GActionMap *map, GtkTextBuffer *buffer) {
- TalkatuActionEntry entry = {
- .name = TALKATU_ACTION_INSERT_LINK,
- .activate = G_CALLBACK(talkatu_action_insert_link),
- .change_state = G_CALLBACK(talkatu_action_format_toggle),
- };
-
- talkatu_action_add(map, buffer, &entry);
-}
-
-/**
- * talkatu_action_name_for_tag_name:
- * @tag_name: The name of the tag to lookup.
- *
- * Looks up a #GAction for the the tag named @tag_name.
- *
- * Returns: The #GAction if one is found, otherwise %NULL.
- */
-const gchar *
-talkatu_action_name_for_tag_name(const gchar *tag_name) {
- if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_BOLD) == 0) {
- return TALKATU_ACTION_FORMAT_BOLD;
- } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_ITALIC) == 0) {
- return TALKATU_ACTION_FORMAT_ITALIC;
- } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_UNDERLINE) == 0) {
- return TALKATU_ACTION_FORMAT_UNDERLINE;
- } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_STRIKETHROUGH) == 0) {
- return TALKATU_ACTION_FORMAT_STRIKETHROUGH;
- } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_ANCHOR) == 0) {
- return TALKATU_ACTION_INSERT_LINK;
- }
-
- return NULL;
-}
--- a/talkatu/talkatuaction.h Thu Sep 13 12:24:30 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * talkatu
- * Copyright (C) 2017-2018 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 __GI_SCANNER__ /* hide this bit from g-ir-scanner */
-#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
-#error "only <talkatu.h> may be included directly"
-#endif
-#endif /* __GI_SCANNER__ */
-
-#ifndef TALKATU_ACTION_H
-#define TALKATU_ACTION_H
-
-#include <gio/gio.h>
-#include <gtk/gtk.h>
-
-#define TALKATU_ACTION_FORMAT_BOLD ("format-bold")
-#define TALKATU_ACTION_FORMAT_ITALIC ("format-italic")
-#define TALKATU_ACTION_FORMAT_UNDERLINE ("format-underline")
-#define TALKATU_ACTION_FORMAT_STRIKETHROUGH ("format-strikethrough")
-#define TALKATU_ACTION_FORMAT_GROW ("format-grow")
-#define TALKATU_ACTION_FORMAT_SHRINK ("format-shrink")
-#define TALKATU_ACTION_FORMAT_RESET ("format-reset")
-
-#define TALKATU_ACTION_INSERT_LINK ("insert-link")
-
-G_BEGIN_DECLS
-
-void talkatu_action_add_bold(GActionMap *map, GtkTextBuffer *buffer);
-void talkatu_action_add_italic(GActionMap *map, GtkTextBuffer *buffer);
-void talkatu_action_add_underline(GActionMap *map, GtkTextBuffer *buffer);
-void talkatu_action_add_strikethrough(GActionMap *map, GtkTextBuffer *buffer);
-void talkatu_action_add_grow(GActionMap *map, GtkTextBuffer *buffer);
-void talkatu_action_add_shrink(GActionMap *map, GtkTextBuffer *buffer);
-void talkatu_action_add_reset(GActionMap *map, GtkTextBuffer *buffer);
-
-void talkatu_action_add_link(GActionMap *map, GtkTextBuffer *buffer);
-
-const gchar *talkatu_action_name_for_tag_name(const gchar *tag_name);
-
-G_END_DECLS
-
-#endif /* TALKATU_ACTION_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatuactiongroup.c Thu Sep 13 22:02:02 2018 -0500
@@ -0,0 +1,423 @@
+/*
+ * talkatu
+ * Copyright (C) 2017-2018 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 <glib/gi18n-lib.h>
+
+#include "talkatu/talkatuactiongroup.h"
+#include "talkatu/talkatubuffer.h"
+#include "talkatu/talkatulinkdialog.h"
+#include "talkatu/talkatutag.h"
+
+/**
+ * SECTION:talkatuaction
+ * @Title: Talkatu Actions
+ * @Short_description: GAction Helpers
+ *
+ * A lot of Talkatu's user interation is handled by #GAction's. These
+ * functions help make that easier.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_BOLD:
+ *
+ * A constant that represents the bold font style action.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_ITALIC:
+ *
+ * A constant that represents the italic font style action.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_UNDERLINE:
+ *
+ * A constant that represents the underline font style action.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_STRIKETHROUGH:
+ *
+ * A constant that represents the strike through font style action.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_GROW:
+ *
+ * A constant that represents the increase font size action.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_SHRINK:
+ *
+ * A constant that represents the decrease font size action.
+ */
+
+/**
+ * TALKATU_ACTION_FORMAT_RESET:
+ *
+ * A constant that represents the reset all formatting action.
+ */
+
+typedef struct {
+ GtkTextBuffer *buffer;
+} TalkatuActionGroupPrivate;
+
+enum {
+ PROP_0,
+ PROP_BUFFER,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = {NULL,};
+
+G_DEFINE_TYPE_WITH_PRIVATE(TalkatuActionGroup, talkatu_action_group, G_TYPE_SIMPLE_ACTION_GROUP)
+
+/******************************************************************************
+ * Callbacks
+ *****************************************************************************/
+static void
+talkatu_action_activate(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ g_message(_("activating action %s"), g_action_get_name(G_ACTION(action)));
+}
+
+static void
+talkatu_action_toggle(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GVariant *state = NULL;
+
+ g_message(_("toggling action %s"), g_action_get_name(G_ACTION(action)));
+
+ state = g_action_get_state(G_ACTION(action));
+ g_action_change_state(
+ G_ACTION(action),
+ g_variant_new_boolean(!g_variant_get_boolean(state))
+ );
+ g_variant_unref(state);
+}
+
+static void
+talkatu_action_format_toggle(GSimpleAction *action,
+ GVariant *state,
+ gpointer data)
+{
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER(data);
+ GtkTextIter start, end;
+ TalkatuBufferStyle style = talkatu_buffer_get_style(TALKATU_BUFFER(buffer));
+ gboolean apply = FALSE;
+
+ if(style == TALKATU_BUFFER_STYLE_WHOLE) {
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ apply = TRUE;
+ } else {
+ if(gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) {
+ apply = TRUE;
+ }
+ }
+
+ if(apply) {
+ const gchar *tag_name = NULL, *name = NULL;
+
+ name = g_action_get_name(G_ACTION(action));
+ tag_name = talkatu_tag_name_for_action_name(name);
+
+ if(tag_name == NULL) {
+ return;
+ }
+
+ gtk_text_buffer_begin_user_action(buffer);
+
+ if(g_variant_get_boolean(state)) {
+ gtk_text_buffer_apply_tag_by_name(buffer, tag_name, &start, &end);
+ } else {
+ gtk_text_buffer_remove_tag_by_name(buffer, tag_name, &start, &end);
+ }
+
+ gtk_text_buffer_end_user_action(buffer);
+ }
+
+ g_simple_action_set_state(action, state);
+}
+
+
+static void
+talkatu_action_insert_link(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
+ GtkWidget *link_dialog = talkatu_link_dialog_new();
+
+ if(gtk_dialog_run(GTK_DIALOG(link_dialog)) == GTK_RESPONSE_ACCEPT) {
+ GtkTextChildAnchor *anchor = NULL;
+ GtkTextMark *insert_mark = NULL;
+ GtkTextIter insert;
+ gchar *url = NULL, *label = NULL;
+
+ if(gtk_text_buffer_get_has_selection(buffer)) {
+ gtk_text_buffer_delete_selection(buffer, TRUE, TRUE);
+ }
+
+ insert_mark = gtk_text_buffer_get_insert(buffer);
+ gtk_text_buffer_get_iter_at_mark(buffer, &insert, insert_mark);
+
+ anchor = gtk_text_buffer_create_child_anchor(buffer, &insert);
+
+ url = talkatu_link_dialog_get_url(TALKATU_LINK_DIALOG(link_dialog));
+ g_object_set_data_full(G_OBJECT(anchor), "talkatu-url", url, g_free);
+
+ label = talkatu_link_dialog_get_display_text(TALKATU_LINK_DIALOG(link_dialog));
+ g_object_set_data_full(G_OBJECT(anchor), "talkatu-url-label", label, g_free);
+
+ gtk_text_buffer_insert_child_anchor(buffer, &insert, anchor);
+ }
+
+ gtk_widget_destroy(link_dialog);
+}
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+talkatu_action_group_set_buffer(TalkatuActionGroup *ag, GtkTextBuffer *buffer) {
+ TalkatuActionGroupPrivate *priv = talkatu_action_group_get_instance_private(ag);
+
+ if(priv->buffer) {
+ g_object_unref(priv->buffer);
+ }
+
+ priv->buffer = g_object_ref(buffer);
+}
+
+/******************************************************************************
+ * GObject Stuff
+ *****************************************************************************/
+static void
+talkatu_action_group_get_property(GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(obj);
+
+ switch(prop_id) {
+ case PROP_BUFFER:
+ g_value_set_object(value, talkatu_action_group_get_buffer(ag));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+talkatu_action_group_set_property(GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(obj);
+
+ switch(prop_id) {
+ case PROP_BUFFER:
+ talkatu_action_group_set_buffer(ag, g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+talkatu_action_group_finalize(GObject *obj) {
+ TalkatuActionGroupPrivate *priv = talkatu_action_group_get_instance_private(TALKATU_ACTION_GROUP(obj));
+
+ if(priv->buffer) {
+ g_object_unref(priv->buffer);
+ priv->buffer = NULL;
+ }
+
+ G_OBJECT_CLASS(talkatu_action_group_parent_class)->finalize(obj);
+}
+
+static void
+talkatu_action_group_constructed(GObject *object) {
+ TalkatuActionGroup *ag = TALKATU_ACTION_GROUP(object);
+ TalkatuActionGroupPrivate *priv = talkatu_action_group_get_instance_private(ag);
+ gint i;
+ GActionEntry entries[] = {
+ {
+ .name = TALKATU_ACTION_FORMAT_BOLD,
+ .activate = talkatu_action_toggle,
+ .state = "false",
+ .change_state = talkatu_action_format_toggle
+ }, {
+ .name = TALKATU_ACTION_FORMAT_ITALIC,
+ .activate = talkatu_action_toggle,
+ .state = "false",
+ .change_state = talkatu_action_format_toggle
+ }, {
+ .name = TALKATU_ACTION_FORMAT_UNDERLINE,
+ .activate = talkatu_action_toggle,
+ .state = "false",
+ .change_state = talkatu_action_format_toggle
+ }, {
+ .name = TALKATU_ACTION_FORMAT_STRIKETHROUGH,
+ .activate = talkatu_action_toggle,
+ .state = "false",
+ .change_state = talkatu_action_format_toggle
+ }, {
+ .name = TALKATU_ACTION_FORMAT_GROW,
+ .activate = talkatu_action_activate,
+ }, {
+ .name = TALKATU_ACTION_FORMAT_SHRINK,
+ .activate = talkatu_action_activate,
+ }, {
+ .name = TALKATU_ACTION_FORMAT_RESET,
+ .activate = talkatu_action_activate,
+ }, {
+ .name = TALKATU_ACTION_INSERT_LINK,
+ .activate = talkatu_action_insert_link,
+ .state = "false",
+ .change_state = talkatu_action_format_toggle,
+ },
+ };
+
+ g_action_map_add_action_entries(G_ACTION_MAP(ag), entries, G_N_ELEMENTS(entries), priv->buffer);
+
+ /* disable all of the actions by default */
+ for(i = 0; i < G_N_ELEMENTS(entries); i++) {
+ GAction *action = NULL;
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(ag), entries[i].name);
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(action), FALSE);
+ }
+}
+
+static void
+talkatu_action_group_init(TalkatuActionGroup *group) {
+}
+
+static void
+talkatu_action_group_class_init(TalkatuActionGroupClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->constructed = talkatu_action_group_constructed;
+ obj_class->get_property = talkatu_action_group_get_property;
+ obj_class->set_property = talkatu_action_group_set_property;
+ obj_class->finalize = talkatu_action_group_finalize;
+
+ properties[PROP_BUFFER] = g_param_spec_object(
+ "buffer", "buffer", "The buffer to work on",
+ GTK_TYPE_TEXT_BUFFER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY
+ );
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+
+/**
+ * talkatu_action_group_new:
+ * @buffer: The #GtkTextBuffer to bind this action group to.
+ *
+ * Creates a new #TalkatuActionGroup bound to @buffer.
+ *
+ * Returns: (transfer full): The new #TalkatuActionGroup instance.
+ */
+GSimpleActionGroup *
+talkatu_action_group_new(GtkTextBuffer *buffer) {
+ return g_object_new(
+ TALKATU_TYPE_ACTION_GROUP,
+ "buffer", buffer,
+ NULL
+ );
+}
+
+/**
+ * talkatu_action_group_get_buffer:
+ * @ag: The #TalkatuActionGroup instance.
+ *
+ * #TalkatuActionGroups are bound to a specific #GtkTextBuffer. This function
+ * return the one that @ag is bound to.
+ *
+ * Returns: (transfer none): The #GtkTextBuffer that @ag is bound to.
+ */
+GtkTextBuffer *
+talkatu_action_group_get_buffer(TalkatuActionGroup *ag) {
+ TalkatuActionGroupPrivate *priv = NULL;
+
+ g_return_val_if_fail(TALKATU_IS_ACTION_GROUP(ag), NULL);
+
+ priv = talkatu_action_group_get_instance_private(ag);
+
+ return priv->buffer;
+}
+
+/**
+ * talkatu_action_group_enable_action:
+ * @ag: The #TalkatuActionGroup instance.
+ * @name: The name of the action to enable.
+ *
+ * By default a #TalkatuActionGroup's actions are all disabled. To enable them
+ * you must call this function one at time.
+ */
+void
+talkatu_action_group_enable_action(TalkatuActionGroup *ag, const gchar *name) {
+ GAction *action = NULL;
+
+ g_return_if_fail(TALKATU_IS_ACTION_GROUP(ag));
+ g_return_if_fail(name != NULL);
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(ag), name);
+ if(action != NULL) {
+ g_simple_action_set_enabled(G_SIMPLE_ACTION(action), TRUE);
+ }
+}
+
+/**
+ * talkatu_action_name_for_tag_name:
+ * @tag_name: The name of the tag to lookup.
+ *
+ * Looks up a #GAction for the the tag named @tag_name.
+ *
+ * Returns: The #GAction if one is found, otherwise %NULL.
+ */
+const gchar *
+talkatu_action_name_for_tag_name(const gchar *tag_name) {
+ if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_BOLD) == 0) {
+ return TALKATU_ACTION_FORMAT_BOLD;
+ } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_ITALIC) == 0) {
+ return TALKATU_ACTION_FORMAT_ITALIC;
+ } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_UNDERLINE) == 0) {
+ return TALKATU_ACTION_FORMAT_UNDERLINE;
+ } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_STRIKETHROUGH) == 0) {
+ return TALKATU_ACTION_FORMAT_STRIKETHROUGH;
+ } else if(g_ascii_strcasecmp(tag_name, TALKATU_TAG_ANCHOR) == 0) {
+ return TALKATU_ACTION_INSERT_LINK;
+ }
+
+ return NULL;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/talkatu/talkatuactiongroup.h Thu Sep 13 22:02:02 2018 -0500
@@ -0,0 +1,84 @@
+/*
+ * talkatu
+ * Copyright (C) 2017-2018 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 __GI_SCANNER__ /* hide this bit from g-ir-scanner */
+#if !defined(TALKATU_GLOBAL_HEADER_INSIDE) && !defined(TALKATU_COMPILATION)
+#error "only <talkatu.h> may be included directly"
+#endif
+#endif /* __GI_SCANNER__ */
+
+#ifndef TALKATU_ACTION_GROUP_H
+#define TALKATU_ACTION_GROUP_H
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#define TALKATU_TYPE_ACTION_GROUP (talkatu_action_group_get_type())
+#define TALKATU_ACTION_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TALKATU_TYPE_ACTION_GROUP, TalkatuActionGroup))
+#define TALKATU_ACTION_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TALKATU_TYPE_ACTION_GROUP, TalkatuActionGroupClass))
+#define TALKATU_IS_ACTION_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TALKATU_TYPE_ACTION_GROUP))
+#define TALKATU_IS_ACTION_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TALKATU_TYPE_ACTION_GROUP))
+#define TALKATU_ACTION_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TALKATU_TYPE_ACTION_GROUP, TalkatuActionGroupClass))
+
+typedef struct _TalkatuActionGroup TalkatuActionGroup;
+typedef struct _TalkatuActionGroupClass TalkatuActionGroupClass;
+
+struct _TalkatuActionGroup {
+ GSimpleActionGroup parent;
+
+ void (*_talkatu_reserved1)(void);
+ void (*_talkatu_reserved2)(void);
+ void (*_talkatu_reserved3)(void);
+ void (*_talkatu_reserved4)(void);
+};
+
+struct _TalkatuActionGroupClass {
+ GSimpleActionGroupClass parent;
+
+ void (*_talkatu_reserved1)(void);
+ void (*_talkatu_reserved2)(void);
+ void (*_talkatu_reserved3)(void);
+ void (*_talkatu_reserved4)(void);
+};
+
+
+#define TALKATU_ACTION_FORMAT_BOLD ("format-bold")
+#define TALKATU_ACTION_FORMAT_ITALIC ("format-italic")
+#define TALKATU_ACTION_FORMAT_UNDERLINE ("format-underline")
+#define TALKATU_ACTION_FORMAT_STRIKETHROUGH ("format-strikethrough")
+#define TALKATU_ACTION_FORMAT_GROW ("format-grow")
+#define TALKATU_ACTION_FORMAT_SHRINK ("format-shrink")
+#define TALKATU_ACTION_FORMAT_RESET ("format-reset")
+
+#define TALKATU_ACTION_INSERT_LINK ("insert-link")
+
+G_BEGIN_DECLS
+
+GType talkatu_action_group_get_type(void);
+
+GSimpleActionGroup *talkatu_action_group_new(GtkTextBuffer *buffer);
+
+GtkTextBuffer *talkatu_action_group_get_buffer(TalkatuActionGroup *ag);
+
+void talkatu_action_group_enable_action(TalkatuActionGroup *ag, const gchar *name);
+
+const gchar *talkatu_action_name_for_tag_name(const gchar *tag_name);
+
+G_END_DECLS
+
+#endif /* TALKATU_ACTIONGROUP_H */
--- a/talkatu/talkatubuffer.c Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/talkatubuffer.c Thu Sep 13 22:02:02 2018 -0500
@@ -18,7 +18,7 @@
#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
-#include <talkatu/talkatuaction.h>
+#include <talkatu/talkatuactiongroup.h>
#include <talkatu/talkatubuffer.h>
#include <talkatu/talkatuenums.h>
#include <talkatu/talkatutag.h>
--- a/talkatu/talkatuhtmlbuffer.c Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/talkatuhtmlbuffer.c Thu Sep 13 22:02:02 2018 -0500
@@ -16,7 +16,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "talkatu/talkatuaction.h"
+#include "talkatu/talkatuactiongroup.h"
#include "talkatu/talkatubuffer.h"
#include "talkatu/talkatucodeset.h"
#include "talkatu/talkatuhtmlbuffer.h"
@@ -40,21 +40,18 @@
*****************************************************************************/
static GSimpleActionGroup *
talkatu_html_buffer_create_action_group(TalkatuBuffer *buffer) {
- GSimpleActionGroup *action_group = g_simple_action_group_new();
+ GSimpleActionGroup *ag = talkatu_action_group_new(GTK_TEXT_BUFFER(buffer));
- /* order of operation sucks, we need the buffer for the callbacks, but we
- * need the group to create the buffer.
- */
- talkatu_action_add_bold(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_italic(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_underline(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_strikethrough(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_grow(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_shrink(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_reset(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_link(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_BOLD);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_ITALIC);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_UNDERLINE);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_STRIKETHROUGH);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_SHRINK);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_GROW);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_RESET);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_INSERT_LINK);
- return action_group;
+ return ag;
}
/******************************************************************************
--- a/talkatu/talkatumarkdownbuffer.c Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/talkatumarkdownbuffer.c Thu Sep 13 22:02:02 2018 -0500
@@ -18,7 +18,7 @@
#include <cmark.h>
-#include "talkatu/talkatuaction.h"
+#include "talkatu/talkatuactiongroup.h"
#include "talkatu/talkatubuffer.h"
#include "talkatu/talkatucodeset.h"
#include "talkatu/talkatumarkdownbuffer.h"
@@ -247,16 +247,16 @@
*****************************************************************************/
static GSimpleActionGroup *
talkatu_markdown_buffer_create_action_group(TalkatuBuffer *buffer) {
- GSimpleActionGroup *action_group = g_simple_action_group_new();
+ GSimpleActionGroup *ag = talkatu_action_group_new(GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_bold(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_italic(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_underline(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_strikethrough(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_reset(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_link(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_BOLD);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_ITALIC);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_UNDERLINE);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_STRIKETHROUGH);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_RESET);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_INSERT_LINK);
- return action_group;
+ return ag;
}
/******************************************************************************
--- a/talkatu/talkatutag.c Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/talkatutag.c Thu Sep 13 22:02:02 2018 -0500
@@ -16,7 +16,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "talkatu/talkatuaction.h"
+#include "talkatu/talkatuactiongroup.h"
#include "talkatu/talkatutag.h"
/**
--- a/talkatu/talkatuview.c Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/talkatuview.c Thu Sep 13 22:02:02 2018 -0500
@@ -22,7 +22,7 @@
#include <gumbo.h>
#include <stdio.h>
-#include "talkatu/talkatuaction.h"
+#include "talkatu/talkatuactiongroup.h"
#include "talkatu/talkatubuffer.h"
#include "talkatu/talkatuenums.h"
#include "talkatu/talkatutag.h"
--- a/talkatu/talkatuwholebuffer.c Thu Sep 13 12:24:30 2018 -0500
+++ b/talkatu/talkatuwholebuffer.c Thu Sep 13 22:02:02 2018 -0500
@@ -17,7 +17,7 @@
*/
#include <gtk/gtk.h>
-#include "talkatu/talkatuaction.h"
+#include "talkatu/talkatuactiongroup.h"
#include "talkatu/talkatuwholebuffer.h"
/**
@@ -36,21 +36,18 @@
*****************************************************************************/
static GSimpleActionGroup *
talkatu_whole_buffer_create_action_group(TalkatuBuffer *buffer) {
- GSimpleActionGroup *action_group = g_simple_action_group_new();
+ GSimpleActionGroup *ag = talkatu_action_group_new(GTK_TEXT_BUFFER(buffer));
- /* order of operation sucks, we need the buffer for the callbacks, but we
- * need the group to create the buffer.
- */
- talkatu_action_add_bold(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_italic(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_underline(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_strikethrough(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_grow(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_shrink(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_reset(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
- talkatu_action_add_link(G_ACTION_MAP(action_group), GTK_TEXT_BUFFER(buffer));
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_BOLD);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_ITALIC);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_UNDERLINE);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_STRIKETHROUGH);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_SHRINK);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_GROW);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_FORMAT_RESET);
+ talkatu_action_group_enable_action(TALKATU_ACTION_GROUP(ag), TALKATU_ACTION_INSERT_LINK);
- return action_group;
+ return ag;
}
/******************************************************************************