[gtk/matthiasc/a11y] atspi: Implement EditableText interface
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/a11y] atspi: Implement EditableText interface
- Date: Sun, 11 Oct 2020 23:01:27 +0000 (UTC)
commit 909383a15ec5c920c622ebfd5d1d9e6b0b3b2d6b
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Oct 11 16:39:26 2020 -0400
atspi: Implement EditableText interface
Implement EditableText for GtkText and GtkTextView.
gtk/a11y/gtkatspieditabletext.c | 349 +++++++++++++++++++++++++++++++++
gtk/a11y/gtkatspieditabletextprivate.h | 30 +++
gtk/a11y/meson.build | 3 +-
3 files changed, 381 insertions(+), 1 deletion(-)
---
diff --git a/gtk/a11y/gtkatspieditabletext.c b/gtk/a11y/gtkatspieditabletext.c
new file mode 100644
index 0000000000..7d01fe6a7d
--- /dev/null
+++ b/gtk/a11y/gtkatspieditabletext.c
@@ -0,0 +1,349 @@
+/* gtkatspieditabletext.c: EditableText interface for GtkAtspiContext
+ *
+ * Copyright 2020 Red Hat, Inc
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * 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.1 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 "config.h"
+
+#include "gtkatspieditabletextprivate.h"
+#include "gtkatcontextprivate.h"
+
+#include "a11y/atspi/atspi-editabletext.h"
+
+#include "gtktext.h"
+#include "gtktextview.h"
+
+#include <gio/gio.h>
+
+typedef struct
+{
+ GtkWidget *widget;
+ int position;
+} PasteData;
+
+static void
+text_received (GObject *source,
+ GAsyncResult *result,
+ gpointer data)
+{
+ GdkClipboard *clipboard = GDK_CLIPBOARD (source);
+ PasteData *pdata = data;
+ char *text;
+
+ text = gdk_clipboard_read_text_finish (clipboard, result, NULL);
+ if (text)
+ gtk_editable_insert_text (GTK_EDITABLE (pdata->widget), text, -1, &pdata->position);
+ g_free (text);
+ g_free (pdata);
+}
+
+static void
+text_handle_method (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ GtkATContext *self = user_data;
+ GtkAccessible *accessible = gtk_at_context_get_accessible (self);
+ GtkWidget *widget = GTK_WIDGET (accessible);
+
+ if (g_strcmp0 (method_name, "SetTextContents") == 0)
+ {
+ char *text;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(&s)", &text);
+
+ if (gtk_editable_get_editable (GTK_EDITABLE (widget)))
+ {
+ gtk_editable_set_text (GTK_EDITABLE (widget), text);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "InsertText") == 0)
+ {
+ int position;
+ char *text;
+ int len;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(i&si)", &position, &text, &len);
+
+ if (gtk_editable_get_editable (GTK_EDITABLE (widget)))
+ {
+ gtk_editable_insert_text (GTK_EDITABLE (widget), text, -1, &position);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "CopyText") == 0)
+ {
+ int start, end;
+ char *str;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ str = gtk_editable_get_chars (GTK_EDITABLE (widget), start, end);
+ gdk_clipboard_set_text (gtk_widget_get_clipboard (widget), str);
+ g_free (str);
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ }
+ else if (g_strcmp0 (method_name, "CutText") == 0)
+ {
+ int start, end;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ if (gtk_editable_get_editable (GTK_EDITABLE (widget)))
+ {
+ char *str;
+
+ str = gtk_editable_get_chars (GTK_EDITABLE (widget), start, end);
+ gdk_clipboard_set_text (gtk_widget_get_clipboard (widget), str);
+ g_free (str);
+ gtk_editable_delete_text (GTK_EDITABLE (widget), start, end);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "DeleteText") == 0)
+ {
+ int start, end;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ if (gtk_editable_get_editable (GTK_EDITABLE (widget)))
+ {
+ gtk_editable_delete_text (GTK_EDITABLE (widget), start, end);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "PasteText") == 0)
+ {
+ int position;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(i)", &position);
+
+ if (gtk_editable_get_editable (GTK_EDITABLE (widget)))
+ {
+ PasteData *data;
+
+ data = g_new (PasteData, 1);
+ data->widget = widget;
+ data->position = position;
+
+ gdk_clipboard_read_text_async (gtk_widget_get_clipboard (widget), NULL, text_received, data);
+
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+}
+
+static const GDBusInterfaceVTable text_vtable = {
+ text_handle_method,
+ NULL,
+};
+
+
+static void
+text_view_received (GObject *source,
+ GAsyncResult *result,
+ gpointer data)
+{
+ GdkClipboard *clipboard = GDK_CLIPBOARD (source);
+ PasteData *pdata = data;
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pdata->widget));
+ GtkTextIter iter;
+ char *text;
+
+ text = gdk_clipboard_read_text_finish (clipboard, result, NULL);
+ if (text)
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, pdata->position);
+ gtk_text_buffer_insert (buffer, &iter, text, -1);
+ }
+
+ g_free (text);
+ g_free (pdata);
+}
+
+static void
+text_view_handle_method (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ GtkATContext *self = user_data;
+ GtkAccessible *accessible = gtk_at_context_get_accessible (self);
+ GtkWidget *widget = GTK_WIDGET (accessible);
+
+ if (g_strcmp0 (method_name, "SetTextContents") == 0)
+ {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ char *text;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(&s)", &text);
+
+ if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
+ {
+ gtk_text_buffer_set_text (buffer, text, -1);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "InsertText") == 0)
+ {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ GtkTextIter iter;
+ int position;
+ char *text;
+ int len;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(i&si)", &position, &text, &len);
+
+ if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, position);
+ gtk_text_buffer_insert (buffer, &iter, text, len);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "CopyText") == 0)
+ {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ GtkTextIter start_iter, end_iter;
+ int start, end;
+ char *str;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+ str = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
+ gdk_clipboard_set_text (gtk_widget_get_clipboard (widget), str);
+ g_free (str);
+ g_dbus_method_invocation_return_value (invocation, NULL);
+ }
+ else if (g_strcmp0 (method_name, "CutText") == 0)
+ {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ GtkTextIter start_iter, end_iter;
+ int start, end;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
+ {
+ char *str;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+ str = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
+ gdk_clipboard_set_text (gtk_widget_get_clipboard (widget), str);
+ g_free (str);
+ gtk_text_buffer_delete (buffer, &start_iter, &end_iter);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "DeleteText") == 0)
+ {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ GtkTextIter start_iter, end_iter;
+ int start, end;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(ii)", &start, &end);
+
+ if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
+ {
+ gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
+ gtk_text_buffer_delete (buffer, &start_iter, &end_iter);
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+ else if (g_strcmp0 (method_name, "PasteText") == 0)
+ {
+ int position;
+ gboolean ret = FALSE;
+
+ g_variant_get (parameters, "(i)", &position);
+
+ if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
+ {
+ PasteData *data;
+
+ data = g_new (PasteData, 1);
+ data->widget = widget;
+ data->position = position;
+
+ gdk_clipboard_read_text_async (gtk_widget_get_clipboard (widget), NULL, text_view_received, data);
+
+ ret = TRUE;
+ }
+
+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
+ }
+}
+
+static const GDBusInterfaceVTable text_view_vtable = {
+ text_view_handle_method,
+ NULL,
+};
+
+
+const GDBusInterfaceVTable *
+gtk_atspi_get_editable_text_vtable (GtkWidget *widget)
+{
+ if (GTK_IS_TEXT (widget))
+ return &text_vtable;
+ else if (GTK_IS_TEXT_VIEW (widget))
+ return &text_view_vtable;
+
+ return NULL;
+}
+
diff --git a/gtk/a11y/gtkatspieditabletextprivate.h b/gtk/a11y/gtkatspieditabletextprivate.h
new file mode 100644
index 0000000000..73686c12e4
--- /dev/null
+++ b/gtk/a11y/gtkatspieditabletextprivate.h
@@ -0,0 +1,30 @@
+/* gtkatspieditabletextprivate.h: AT-SPI EditableText implementation
+ *
+ * Copyright 2020 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * 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.1 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/>.
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+#include "gtkwidget.h"
+
+G_BEGIN_DECLS
+
+const GDBusInterfaceVTable *gtk_atspi_get_editable_text_vtable (GtkWidget *widget);
+
+G_END_DECLS
diff --git a/gtk/a11y/meson.build b/gtk/a11y/meson.build
index aaf54cdce9..2912746fc7 100644
--- a/gtk/a11y/meson.build
+++ b/gtk/a11y/meson.build
@@ -16,6 +16,7 @@ if gtk_a11y_backends.contains('atspi')
'gtkatspipango.c',
'gtkatspitextbuffer.c',
'gtkatspitext.c',
- 'gtkatspivalue.c'
+ 'gtkatspivalue.c',
+ 'gtkatspieditabletext.c',
])
endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]