forked from AuroraMiddleware/gtk
atspi: Add textview utilities
These are very similar to the pango utilities, and are copying code from the textview accessible implementation in GTK 3.
This commit is contained in:
parent
ba63daa1d2
commit
925ef1f90f
984
gtk/a11y/gtkatspitextbuffer.c
Normal file
984
gtk/a11y/gtkatspitextbuffer.c
Normal file
@ -0,0 +1,984 @@
|
||||
/* gtkatspitextbuffer.c - GtkTextBuffer-related utilities for AT-SPI
|
||||
*
|
||||
* Copyright (c) 2020 Red Hat, Inc.
|
||||
*
|
||||
* 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/>.Free
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtkatspitextbufferprivate.h"
|
||||
#include "gtkatspipangoprivate.h"
|
||||
#include "gtktextviewprivate.h"
|
||||
|
||||
static const char *
|
||||
gtk_justification_to_string (GtkJustification just)
|
||||
{
|
||||
switch (just)
|
||||
{
|
||||
case GTK_JUSTIFY_LEFT:
|
||||
return "left";
|
||||
case GTK_JUSTIFY_RIGHT:
|
||||
return "right";
|
||||
case GTK_JUSTIFY_CENTER:
|
||||
return "center";
|
||||
case GTK_JUSTIFY_FILL:
|
||||
return "fill";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
gtk_text_direction_to_string (GtkTextDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case GTK_TEXT_DIR_NONE:
|
||||
return "none";
|
||||
case GTK_TEXT_DIR_LTR:
|
||||
return "ltr";
|
||||
case GTK_TEXT_DIR_RTL:
|
||||
return "rtl";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_view_add_default_attributes (GtkTextView *view,
|
||||
GVariantBuilder *builder)
|
||||
{
|
||||
GtkTextAttributes *text_attrs;
|
||||
PangoFontDescription *font;
|
||||
char *value;
|
||||
|
||||
text_attrs = gtk_text_view_get_default_attributes (view);
|
||||
|
||||
font = text_attrs->font;
|
||||
|
||||
if (font)
|
||||
gtk_pango_get_font_attributes (font, builder);
|
||||
|
||||
g_variant_builder_add (builder, "{ss}", "justification",
|
||||
gtk_justification_to_string (text_attrs->justification));
|
||||
g_variant_builder_add (builder, "{ss}", "direction",
|
||||
gtk_text_direction_to_string (text_attrs->direction));
|
||||
g_variant_builder_add (builder, "{ss}", "wrap-mode",
|
||||
pango_wrap_mode_to_string (text_attrs->wrap_mode));
|
||||
g_variant_builder_add (builder, "{ss}", "editable",
|
||||
text_attrs->editable ? "true" : "false");
|
||||
g_variant_builder_add (builder, "{ss}", "invisible",
|
||||
text_attrs->invisible ? "true" : "false");
|
||||
g_variant_builder_add (builder, "{ss}", "bg-full-height",
|
||||
text_attrs->bg_full_height ? "true" : "false");
|
||||
g_variant_builder_add (builder, "{ss}", "strikethrough",
|
||||
text_attrs->appearance.strikethrough ? "true" : "false");
|
||||
g_variant_builder_add (builder, "{ss}", "underline",
|
||||
pango_underline_to_string (text_attrs->appearance.underline));
|
||||
|
||||
value = g_strdup_printf ("%u,%u,%u",
|
||||
(guint)(text_attrs->appearance.bg_rgba->red * 65535),
|
||||
(guint)(text_attrs->appearance.bg_rgba->green * 65535),
|
||||
(guint)(text_attrs->appearance.bg_rgba->blue * 65535));
|
||||
g_variant_builder_add (builder, "{ss}", "bg-color", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%u,%u,%u",
|
||||
(guint)(text_attrs->appearance.fg_rgba->red * 65535),
|
||||
(guint)(text_attrs->appearance.fg_rgba->green * 65535),
|
||||
(guint)(text_attrs->appearance.fg_rgba->blue * 65535));
|
||||
g_variant_builder_add (builder, "{ss}", "bg-color", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%g", text_attrs->font_scale);
|
||||
g_variant_builder_add (builder, "{ss}", "scale", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup ((gchar *)(text_attrs->language));
|
||||
g_variant_builder_add (builder, "{ss}", "language", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->appearance.rise);
|
||||
g_variant_builder_add (builder, "{ss}", "rise", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
|
||||
g_variant_builder_add (builder, "{ss}", "pixels-inside-wrap", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
|
||||
g_variant_builder_add (builder, "{ss}", "pixels-below-lines", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
|
||||
g_variant_builder_add (builder, "{ss}", "pixels-above-lines", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->indent);
|
||||
g_variant_builder_add (builder, "{ss}", "indent", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->left_margin);
|
||||
g_variant_builder_add (builder, "{ss}", "left-margin", value);
|
||||
g_free (value);
|
||||
|
||||
value = g_strdup_printf ("%i", text_attrs->right_margin);
|
||||
g_variant_builder_add (builder, "{ss}", "right-margin", value);
|
||||
g_free (value);
|
||||
|
||||
gtk_text_attributes_unref (text_attrs);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_buffer_get_run_attributes (GtkTextBuffer *buffer,
|
||||
GVariantBuilder *builder,
|
||||
int offset,
|
||||
int *start_offset,
|
||||
int *end_offset)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GSList *tags, *temp_tags;
|
||||
gdouble scale = 1;
|
||||
gboolean val_set = FALSE;
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
|
||||
|
||||
gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
|
||||
*end_offset = gtk_text_iter_get_offset (&iter);
|
||||
|
||||
gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
|
||||
*start_offset = gtk_text_iter_get_offset (&iter);
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
|
||||
|
||||
tags = gtk_text_iter_get_tags (&iter);
|
||||
tags = g_slist_reverse (tags);
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
PangoStyle style;
|
||||
|
||||
g_object_get (tag,
|
||||
"style-set", &val_set,
|
||||
"style", &style,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "style", pango_style_to_string (style));
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
PangoVariant variant;
|
||||
|
||||
g_object_get (tag,
|
||||
"variant-set", &val_set,
|
||||
"variant", &variant,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "variant", pango_variant_to_string (variant));
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
PangoStretch stretch;
|
||||
|
||||
g_object_get (tag,
|
||||
"stretch-set", &val_set,
|
||||
"stretch", &stretch,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "stretch", pango_stretch_to_string (stretch));
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
GtkJustification justification;
|
||||
|
||||
g_object_get (tag,
|
||||
"justification-set", &val_set,
|
||||
"justification", &justification,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "justification", gtk_justification_to_string (justification));
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
GtkTextDirection direction;
|
||||
|
||||
g_object_get (tag, "direction", &direction, NULL);
|
||||
if (direction != GTK_TEXT_DIR_NONE)
|
||||
{
|
||||
val_set = TRUE;
|
||||
g_variant_builder_add (builder, "{ss}", "direction", gtk_text_direction_to_string (direction));
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
GtkWrapMode wrap_mode;
|
||||
|
||||
g_object_get (tag,
|
||||
"wrap-mode-set", &val_set,
|
||||
"wrap-mode", &wrap_mode,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "wrap-mode", pango_wrap_mode_to_string (wrap_mode));
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
|
||||
g_object_get (tag, "foreground-set", &val_set, NULL);
|
||||
if (val_set)
|
||||
{
|
||||
GdkRGBA *rgba;
|
||||
char *value;
|
||||
|
||||
g_object_get (tag, "foreground", &rgba, NULL);
|
||||
value = g_strdup_printf ("%u,%u,%u",
|
||||
(guint) rgba->red * 65535,
|
||||
(guint) rgba->green * 65535,
|
||||
(guint) rgba->blue * 65535);
|
||||
gdk_rgba_free (rgba);
|
||||
g_variant_builder_add (builder, "{ss}", "fg-color", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
|
||||
g_object_get (tag, "background-set", &val_set, NULL);
|
||||
if (val_set)
|
||||
{
|
||||
GdkRGBA *rgba;
|
||||
char *value;
|
||||
|
||||
g_object_get (tag, "background-rgba", &rgba, NULL);
|
||||
value = g_strdup_printf ("%u,%u,%u",
|
||||
(guint) rgba->red * 65535,
|
||||
(guint) rgba->green * 65535,
|
||||
(guint) rgba->blue * 65535);
|
||||
gdk_rgba_free (rgba);
|
||||
g_variant_builder_add (builder, "{ss}", "bg-color", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
|
||||
g_object_get (tag, "family-set", &val_set, NULL);
|
||||
|
||||
if (val_set)
|
||||
{
|
||||
char *value;
|
||||
g_object_get (tag, "family", &value, NULL);
|
||||
g_variant_builder_add (builder, "{ss}", "family-name", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
|
||||
g_object_get (tag, "language-set", &val_set, NULL);
|
||||
|
||||
if (val_set)
|
||||
{
|
||||
char *value;
|
||||
g_object_get (tag, "language", &value, NULL);
|
||||
g_variant_builder_add (builder, "{ss}", "language", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int weight;
|
||||
|
||||
g_object_get (tag,
|
||||
"weight-set", &val_set,
|
||||
"weight", &weight,
|
||||
NULL);
|
||||
|
||||
if (val_set)
|
||||
{
|
||||
char *value;
|
||||
value = g_strdup_printf ("%d", weight);
|
||||
g_variant_builder_add (builder, "{ss}", "weight", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
/* scale is special as the effective value is the product
|
||||
* of all specified values
|
||||
*/
|
||||
temp_tags = tags;
|
||||
while (temp_tags)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
gboolean scale_set;
|
||||
|
||||
g_object_get (tag, "scale-set", &scale_set, NULL);
|
||||
if (scale_set)
|
||||
{
|
||||
double font_scale;
|
||||
g_object_get (tag, "scale", &font_scale, NULL);
|
||||
val_set = TRUE;
|
||||
scale *= font_scale;
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%g", scale);
|
||||
g_variant_builder_add (builder, "{ss}", "scale", value);
|
||||
g_free (value);
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int size;
|
||||
|
||||
g_object_get (tag,
|
||||
"size-set", &val_set,
|
||||
"size", &size,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", size);
|
||||
g_variant_builder_add (builder, "{ss}", "size", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
gboolean strikethrough;
|
||||
|
||||
g_object_get (tag,
|
||||
"strikethrough-set", &val_set,
|
||||
"strikethrough", &strikethrough,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "strikethrough", strikethrough ? "true" : "false");
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
PangoUnderline underline;
|
||||
|
||||
g_object_get (tag,
|
||||
"underline-set", &val_set,
|
||||
"underline", &underline,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "underline",
|
||||
pango_underline_to_string (underline));
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int rise;
|
||||
|
||||
g_object_get (tag,
|
||||
"rise-set", &val_set,
|
||||
"rise", &rise,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", rise);
|
||||
g_variant_builder_add (builder, "{ss}", "rise", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
gboolean bg_full_height;
|
||||
|
||||
g_object_get (tag,
|
||||
"background-full-height-set", &val_set,
|
||||
"background-full-height", &bg_full_height,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "bg-full-height", bg_full_height ? "true" : "false");
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int pixels;
|
||||
|
||||
g_object_get (tag,
|
||||
"pixels-inside-wrap-set", &val_set,
|
||||
"pixels-inside-wrap", &pixels,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", pixels);
|
||||
g_variant_builder_add (builder, "{ss}", "pixels-inside-wrap", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int pixels;
|
||||
|
||||
g_object_get (tag,
|
||||
"pixels-below-lines-set", &val_set,
|
||||
"pixels-below-lines", &pixels,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", pixels);
|
||||
g_variant_builder_add (builder, "{ss}", "pixels-below-lines", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int pixels;
|
||||
|
||||
g_object_get (tag,
|
||||
"pixels-above-lines-set", &val_set,
|
||||
"pixels-above-lines", &pixels,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", pixels);
|
||||
g_variant_builder_add (builder, "{ss}", "pixels-above-lines", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
gboolean editable;
|
||||
|
||||
g_object_get (tag,
|
||||
"editable-set", &val_set,
|
||||
"editable", &editable,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "editable", editable ? "true" : "false");
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
gboolean invisible;
|
||||
|
||||
g_object_get (tag,
|
||||
"invisible-set", &val_set,
|
||||
"invisible", &invisible,
|
||||
NULL);
|
||||
if (val_set)
|
||||
g_variant_builder_add (builder, "{ss}", "invisible", invisible ? "true" : "false");
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int indent;
|
||||
|
||||
g_object_get (tag,
|
||||
"indent-set", &val_set,
|
||||
"indent", &indent,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", indent);
|
||||
g_variant_builder_add (builder, "{ss}", "indent", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int margin;
|
||||
|
||||
g_object_get (tag,
|
||||
"right-margin-set", &val_set,
|
||||
"right-margin", &margin,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", margin);
|
||||
g_variant_builder_add (builder, "{ss}", "right-margin", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
temp_tags = tags;
|
||||
while (temp_tags && !val_set)
|
||||
{
|
||||
GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
|
||||
int margin;
|
||||
|
||||
g_object_get (tag,
|
||||
"left-margin-set", &val_set,
|
||||
"left-margin", &margin,
|
||||
NULL);
|
||||
if (val_set)
|
||||
{
|
||||
char *value = g_strdup_printf ("%i", margin);
|
||||
g_variant_builder_add (builder, "{ss}", "left-margin", value);
|
||||
g_free (value);
|
||||
}
|
||||
temp_tags = temp_tags->next;
|
||||
}
|
||||
val_set = FALSE;
|
||||
|
||||
g_slist_free (tags);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_text_view_get_text_before (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextBoundaryType boundary_type,
|
||||
int *start_offset,
|
||||
int *end_offset)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter pos, start, end;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (view);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
|
||||
start = end = pos;
|
||||
|
||||
switch (boundary_type)
|
||||
{
|
||||
case ATSPI_TEXT_BOUNDARY_CHAR:
|
||||
gtk_text_iter_backward_char (&start);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_WORD_START:
|
||||
if (!gtk_text_iter_starts_word (&start))
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
end = start;
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_WORD_END:
|
||||
if (gtk_text_iter_inside_word (&start) &&
|
||||
!gtk_text_iter_starts_word (&start))
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
while (!gtk_text_iter_ends_word (&start))
|
||||
{
|
||||
if (!gtk_text_iter_backward_char (&start))
|
||||
break;
|
||||
}
|
||||
end = start;
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
while (!gtk_text_iter_ends_word (&start))
|
||||
{
|
||||
if (!gtk_text_iter_backward_char (&start))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_SENTENCE_START:
|
||||
if (!gtk_text_iter_starts_sentence (&start))
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
end = start;
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_SENTENCE_END:
|
||||
if (gtk_text_iter_inside_sentence (&start) &&
|
||||
!gtk_text_iter_starts_sentence (&start))
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
while (!gtk_text_iter_ends_sentence (&start))
|
||||
{
|
||||
if (!gtk_text_iter_backward_char (&start))
|
||||
break;
|
||||
}
|
||||
end = start;
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
while (!gtk_text_iter_ends_sentence (&start))
|
||||
{
|
||||
if (!gtk_text_iter_backward_char (&start))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_LINE_START:
|
||||
gtk_text_view_backward_display_line_start (view, &start);
|
||||
end = start;
|
||||
gtk_text_view_backward_display_line (view, &start);
|
||||
gtk_text_view_backward_display_line_start (view, &start);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_LINE_END:
|
||||
gtk_text_view_backward_display_line_start (view, &start);
|
||||
if (!gtk_text_iter_is_start (&start))
|
||||
{
|
||||
gtk_text_view_backward_display_line (view, &start);
|
||||
end = start;
|
||||
gtk_text_view_forward_display_line_end (view, &end);
|
||||
if (!gtk_text_iter_is_start (&start))
|
||||
{
|
||||
if (gtk_text_view_backward_display_line (view, &start))
|
||||
gtk_text_view_forward_display_line_end (view, &start);
|
||||
else
|
||||
gtk_text_iter_set_offset (&start, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
end = start;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
*start_offset = gtk_text_iter_get_offset (&start);
|
||||
*end_offset = gtk_text_iter_get_offset (&end);
|
||||
|
||||
return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_text_view_get_text_at (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextBoundaryType boundary_type,
|
||||
int *start_offset,
|
||||
int *end_offset)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter pos, start, end;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (view);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
|
||||
start = end = pos;
|
||||
|
||||
switch (boundary_type)
|
||||
{
|
||||
case ATSPI_TEXT_BOUNDARY_CHAR:
|
||||
gtk_text_iter_forward_char (&end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_WORD_START:
|
||||
if (!gtk_text_iter_starts_word (&start))
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
if (gtk_text_iter_inside_word (&end))
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
while (!gtk_text_iter_starts_word (&end))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&end))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_WORD_END:
|
||||
if (gtk_text_iter_inside_word (&start) &&
|
||||
!gtk_text_iter_starts_word (&start))
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
while (!gtk_text_iter_ends_word (&start))
|
||||
{
|
||||
if (!gtk_text_iter_backward_char (&start))
|
||||
break;
|
||||
}
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_SENTENCE_START:
|
||||
if (!gtk_text_iter_starts_sentence (&start))
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
if (gtk_text_iter_inside_sentence (&end))
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
while (!gtk_text_iter_starts_sentence (&end))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&end))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_SENTENCE_END:
|
||||
if (gtk_text_iter_inside_sentence (&start) &&
|
||||
!gtk_text_iter_starts_sentence (&start))
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
while (!gtk_text_iter_ends_sentence (&start))
|
||||
{
|
||||
if (!gtk_text_iter_backward_char (&start))
|
||||
break;
|
||||
}
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_LINE_START:
|
||||
gtk_text_view_backward_display_line_start (view, &start);
|
||||
gtk_text_view_forward_display_line (view, &end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_LINE_END:
|
||||
gtk_text_view_backward_display_line_start (view, &start);
|
||||
if (!gtk_text_iter_is_start (&start))
|
||||
{
|
||||
gtk_text_view_backward_display_line (view, &start);
|
||||
gtk_text_view_forward_display_line_end (view, &start);
|
||||
}
|
||||
gtk_text_view_forward_display_line_end (view, &end);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
*start_offset = gtk_text_iter_get_offset (&start);
|
||||
*end_offset = gtk_text_iter_get_offset (&end);
|
||||
|
||||
return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_text_view_get_text_after (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextBoundaryType boundary_type,
|
||||
int *start_offset,
|
||||
int *end_offset)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter pos, start, end;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (view);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
|
||||
start = end = pos;
|
||||
|
||||
switch (boundary_type)
|
||||
{
|
||||
case ATSPI_TEXT_BOUNDARY_CHAR:
|
||||
gtk_text_iter_forward_char (&start);
|
||||
gtk_text_iter_forward_chars (&end, 2);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_WORD_START:
|
||||
if (gtk_text_iter_inside_word (&end))
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
while (!gtk_text_iter_starts_word (&end))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&end))
|
||||
break;
|
||||
}
|
||||
start = end;
|
||||
if (!gtk_text_iter_is_end (&end))
|
||||
{
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
while (!gtk_text_iter_starts_word (&end))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&end))
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_WORD_END:
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
start = end;
|
||||
if (!gtk_text_iter_is_end (&end))
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_SENTENCE_START:
|
||||
if (gtk_text_iter_inside_sentence (&end))
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
while (!gtk_text_iter_starts_sentence (&end))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&end))
|
||||
break;
|
||||
}
|
||||
start = end;
|
||||
if (!gtk_text_iter_is_end (&end))
|
||||
{
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
while (!gtk_text_iter_starts_sentence (&end))
|
||||
{
|
||||
if (!gtk_text_iter_forward_char (&end))
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_SENTENCE_END:
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
start = end;
|
||||
if (!gtk_text_iter_is_end (&end))
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_LINE_START:
|
||||
gtk_text_view_forward_display_line (view, &end);
|
||||
start = end;
|
||||
gtk_text_view_forward_display_line (view, &end);
|
||||
break;
|
||||
|
||||
case ATSPI_TEXT_BOUNDARY_LINE_END:
|
||||
gtk_text_view_forward_display_line_end (view, &end);
|
||||
start = end;
|
||||
gtk_text_view_forward_display_line (view, &end);
|
||||
gtk_text_view_forward_display_line_end (view, &end);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
*start_offset = gtk_text_iter_get_offset (&start);
|
||||
*end_offset = gtk_text_iter_get_offset (&end);
|
||||
|
||||
return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
gtk_text_view_get_string_at (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextGranularity granularity,
|
||||
int *start_offset,
|
||||
int *end_offset)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter pos, start, end;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (view);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
|
||||
start = end = pos;
|
||||
|
||||
if (granularity == ATSPI_TEXT_GRANULARITY_CHAR)
|
||||
{
|
||||
gtk_text_iter_forward_char (&end);
|
||||
}
|
||||
else if (granularity == ATSPI_TEXT_GRANULARITY_WORD)
|
||||
{
|
||||
if (!gtk_text_iter_starts_word (&start))
|
||||
gtk_text_iter_backward_word_start (&start);
|
||||
gtk_text_iter_forward_word_end (&end);
|
||||
}
|
||||
else if (granularity == ATSPI_TEXT_GRANULARITY_SENTENCE)
|
||||
{
|
||||
if (!gtk_text_iter_starts_sentence (&start))
|
||||
gtk_text_iter_backward_sentence_start (&start);
|
||||
gtk_text_iter_forward_sentence_end (&end);
|
||||
}
|
||||
else if (granularity == ATSPI_TEXT_GRANULARITY_LINE)
|
||||
{
|
||||
if (!gtk_text_view_starts_display_line (view, &start))
|
||||
gtk_text_view_backward_display_line (view, &start);
|
||||
gtk_text_view_forward_display_line_end (view, &end);
|
||||
}
|
||||
else if (granularity == ATSPI_TEXT_GRANULARITY_PARAGRAPH)
|
||||
{
|
||||
gtk_text_iter_set_line_offset (&start, 0);
|
||||
gtk_text_iter_forward_to_line_end (&end);
|
||||
}
|
||||
|
||||
*start_offset = gtk_text_iter_get_offset (&start);
|
||||
*end_offset = gtk_text_iter_get_offset (&end);
|
||||
|
||||
return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
|
||||
}
|
54
gtk/a11y/gtkatspitextbufferprivate.h
Normal file
54
gtk/a11y/gtkatspitextbufferprivate.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* gtkatspitextbufferprivate.h: Utilities for GtkTextBuffer and AT-SPI
|
||||
* Copyright 2020 Red Hat, Inc
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkatspiprivate.h"
|
||||
#include "gtktextview.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_text_view_add_default_attributes (GtkTextView *view,
|
||||
GVariantBuilder *builder);
|
||||
void gtk_text_buffer_get_run_attributes (GtkTextBuffer *buffer,
|
||||
GVariantBuilder *builder,
|
||||
int offset,
|
||||
int *start_offset,
|
||||
int *end_offset);
|
||||
|
||||
char *gtk_text_view_get_text_before (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextBoundaryType boundary_type,
|
||||
int *start_offset,
|
||||
int *end_offset);
|
||||
char *gtk_text_view_get_text_at (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextBoundaryType boundary_type,
|
||||
int *start_offset,
|
||||
int *end_offset);
|
||||
char *gtk_text_view_get_text_after (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextBoundaryType boundary_type,
|
||||
int *start_offset,
|
||||
int *end_offset);
|
||||
char *gtk_text_view_get_string_at (GtkTextView *view,
|
||||
int offset,
|
||||
AtspiTextGranularity granularity,
|
||||
int *start_offset,
|
||||
int *end_offset);
|
||||
|
||||
G_END_DECLS
|
@ -14,5 +14,6 @@ if gtk_a11y_backends.contains('atspi')
|
||||
'gtkatspiroot.c',
|
||||
'gtkatspiutils.c',
|
||||
'gtkatspipango.c',
|
||||
'gtkatspitextbuffer.c',
|
||||
])
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user