mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 14:10:30 +00:00
Implement GtkAccessibleText for GtkTextView
This commit is contained in:
parent
a44701faa2
commit
045262282b
@ -44,6 +44,7 @@
|
||||
#include "gtkimmulticontext.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtktextutilprivate.h"
|
||||
#include "gtktextbufferprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtkscrollable.h"
|
||||
@ -62,7 +63,7 @@
|
||||
#include "gtksnapshot.h"
|
||||
#include "gtkrenderbackgroundprivate.h"
|
||||
#include "gtkrenderborderprivate.h"
|
||||
|
||||
#include "gtkaccessibletext-private.h"
|
||||
|
||||
/**
|
||||
* GtkTextView:
|
||||
@ -547,6 +548,15 @@ static void gtk_text_view_paste_done_handler (GtkTextBuffer *buffer,
|
||||
gpointer data);
|
||||
static void gtk_text_view_buffer_changed_handler (GtkTextBuffer *buffer,
|
||||
gpointer data);
|
||||
static void gtk_text_view_insert_text_handler (GtkTextBuffer *buffer,
|
||||
GtkTextIter *iter,
|
||||
char *text,
|
||||
int len,
|
||||
gpointer data);
|
||||
static void gtk_text_view_delete_range_handler (GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end,
|
||||
gpointer data);
|
||||
static void gtk_text_view_buffer_notify_redo (GtkTextBuffer *buffer,
|
||||
GParamSpec *pspec,
|
||||
GtkTextView *view);
|
||||
@ -680,9 +690,13 @@ static int text_window_get_height (GtkTextWindow *win);
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void gtk_text_view_accessible_text_init (GtkAccessibleTextInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkTextView, gtk_text_view, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (GtkTextView)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACCESSIBLE_TEXT,
|
||||
gtk_text_view_accessible_text_init))
|
||||
|
||||
static GtkTextBuffer*
|
||||
get_buffer (GtkTextView *text_view)
|
||||
@ -2155,6 +2169,12 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer,
|
||||
gtk_text_view_buffer_notify_undo,
|
||||
text_view);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer,
|
||||
gtk_text_view_insert_text_handler,
|
||||
text_view);
|
||||
g_signal_handlers_disconnect_by_func (priv->buffer,
|
||||
gtk_text_view_delete_range_handler,
|
||||
text_view);
|
||||
|
||||
if (gtk_widget_get_realized (GTK_WIDGET (text_view)))
|
||||
{
|
||||
@ -2211,6 +2231,12 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
|
||||
g_signal_connect (priv->buffer, "notify",
|
||||
G_CALLBACK (gtk_text_view_buffer_notify_redo),
|
||||
text_view);
|
||||
g_signal_connect_after (priv->buffer, "insert-text",
|
||||
G_CALLBACK (gtk_text_view_insert_text_handler),
|
||||
text_view);
|
||||
g_signal_connect (priv->buffer, "delete-range",
|
||||
G_CALLBACK (gtk_text_view_delete_range_handler),
|
||||
text_view);
|
||||
|
||||
can_undo = gtk_text_buffer_get_can_undo (buffer);
|
||||
can_redo = gtk_text_buffer_get_can_redo (buffer);
|
||||
@ -7128,6 +7154,40 @@ gtk_text_view_buffer_changed_handler (GtkTextBuffer *buffer,
|
||||
gtk_text_view_update_handles (text_view);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_insert_text_handler (GtkTextBuffer *buffer,
|
||||
GtkTextIter *iter,
|
||||
char *text,
|
||||
int len,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTextView *text_view = data;
|
||||
int position;
|
||||
int length;
|
||||
|
||||
position = gtk_text_iter_get_offset (iter);
|
||||
length = g_utf8_strlen (text, len);
|
||||
|
||||
gtk_accessible_text_update_contents (GTK_ACCESSIBLE_TEXT (text_view),
|
||||
GTK_ACCESSIBLE_TEXT_CONTENT_CHANGE_INSERT,
|
||||
position - length,
|
||||
position);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_delete_range_handler (GtkTextBuffer *buffer,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTextView *text_view = data;
|
||||
|
||||
gtk_accessible_text_update_contents (GTK_ACCESSIBLE_TEXT (text_view),
|
||||
GTK_ACCESSIBLE_TEXT_CONTENT_CHANGE_REMOVE,
|
||||
gtk_text_iter_get_offset (start),
|
||||
gtk_text_iter_get_offset (end));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_toggle_overwrite (GtkTextView *text_view)
|
||||
{
|
||||
@ -8767,10 +8827,12 @@ gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
|
||||
text_view->priv->virtual_cursor_x = -1;
|
||||
text_view->priv->virtual_cursor_y = -1;
|
||||
gtk_text_view_update_im_spot_location (text_view);
|
||||
gtk_accessible_text_update_caret_position (GTK_ACCESSIBLE_TEXT (text_view));
|
||||
need_reset = TRUE;
|
||||
}
|
||||
else if (mark == gtk_text_buffer_get_selection_bound (buffer))
|
||||
{
|
||||
gtk_accessible_text_update_selection_bound (GTK_ACCESSIBLE_TEXT (text_view));
|
||||
need_reset = TRUE;
|
||||
}
|
||||
|
||||
@ -10301,3 +10363,117 @@ gtk_text_view_get_key_controller (GtkTextView *text_view)
|
||||
{
|
||||
return text_view->priv->key_controller;
|
||||
}
|
||||
|
||||
/* {{{ GtkAccessibleText implementation */
|
||||
|
||||
static GBytes *
|
||||
gtk_text_view_accessible_text_get_contents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end)
|
||||
{
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
|
||||
GtkTextIter start_iter, end_iter;
|
||||
char *string;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end == G_MAXUINT ? -1 : end);
|
||||
|
||||
string = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
|
||||
|
||||
return g_bytes_new_take (string, strlen (string) + 1);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
gtk_text_view_accessible_text_get_caret_position (GtkAccessibleText *self)
|
||||
{
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
|
||||
GtkTextMark *insert;
|
||||
GtkTextIter iter;
|
||||
|
||||
insert = gtk_text_buffer_get_insert (buffer);
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
|
||||
|
||||
return gtk_text_iter_get_offset (&iter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_view_accessible_text_get_selection (GtkAccessibleText *self,
|
||||
gsize *n_ranges,
|
||||
GtkAccessibleTextRange **ranges)
|
||||
{
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
|
||||
GtkTextIter start_iter, end_iter;
|
||||
int start, end;
|
||||
|
||||
if (!gtk_text_buffer_get_selection_bounds (buffer, &start_iter, &end_iter))
|
||||
return FALSE;
|
||||
|
||||
start = gtk_text_iter_get_offset (&start_iter);
|
||||
end = gtk_text_iter_get_offset (&end_iter);
|
||||
|
||||
*n_ranges = 1;
|
||||
|
||||
*ranges = g_new (GtkAccessibleTextRange, 1);
|
||||
(*ranges)[0].start = start;
|
||||
(*ranges)[0].length = end - start;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_view_accessible_text_get_attributes (GtkAccessibleText *self,
|
||||
unsigned int offset,
|
||||
gsize *n_ranges,
|
||||
GtkAccessibleTextRange **ranges,
|
||||
char ***attribute_names,
|
||||
char ***attribute_values)
|
||||
{
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self));
|
||||
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
|
||||
int start, end;
|
||||
|
||||
gtk_text_buffer_get_run_attributes (buffer, &builder, offset, &start, &end);
|
||||
|
||||
GVariant *v = g_variant_builder_end (&builder);
|
||||
unsigned n = g_variant_n_children (v);
|
||||
if (n == 0)
|
||||
{
|
||||
g_variant_unref (v);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*n_ranges = n;
|
||||
*ranges = g_new (GtkAccessibleTextRange, n);
|
||||
*attribute_names = g_new (char *, n + 1);
|
||||
*attribute_values = g_new (char *, n + 1);
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
char *name, *value;
|
||||
|
||||
((*ranges)[i]).start = start;
|
||||
((*ranges)[i]).length = end - start;
|
||||
|
||||
g_variant_get_child (v, i, "{ss}", &name, &value);
|
||||
(*attribute_names)[i] = g_steal_pointer (&name);
|
||||
(*attribute_values)[i] = g_steal_pointer (&value);
|
||||
}
|
||||
|
||||
(*attribute_names)[n] = NULL;
|
||||
(*attribute_values)[n] = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
{
|
||||
iface->get_contents = gtk_text_view_accessible_text_get_contents;
|
||||
iface->get_caret_position = gtk_text_view_accessible_text_get_caret_position;
|
||||
iface->get_selection = gtk_text_view_accessible_text_get_selection;
|
||||
iface->get_attributes = gtk_text_view_accessible_text_get_attributes;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
Loading…
Reference in New Issue
Block a user