Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  gtkaccessibletext.c

  Sprache: C
 

/* gtkaccessibletext.c: Interface for accessible text objects
 *
 * SPDX-FileCopyrightText: 2023  Emmanuele Bassi
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */


#include "config.h"

#include "gtkaccessibletextprivate.h"

#include "gtkatcontextprivate.h"

G_DEFINE_INTERFACE (GtkAccessibleText, gtk_accessible_text, GTK_TYPE_ACCESSIBLE)

static GBytes *
gtk_accessible_text_default_get_contents (GtkAccessibleText *self,
                                          unsigned int start,
                                          unsigned int end)
{
  g_warning ("GtkAccessibleText::get_contents not implemented for %s",
             G_OBJECT_TYPE_NAME (self));

  return NULL;
}

static GBytes *
gtk_accessible_text_default_get_contents_at (GtkAccessibleText            *self,
                                             unsigned int                  offset,
                                             GtkAccessibleTextGranularity  granularity,
                                             unsigned int                 *start,
                                             unsigned int                 *end)
{
  g_warning ("GtkAccessibleText::get_contents_at not implemented for %s",
             G_OBJECT_TYPE_NAME (self));

  if (start != NULL)
    *start = 0;
  if (end != NULL)
    *end = 0;

  return NULL;
}

static unsigned int
gtk_accessible_text_default_get_caret_position (GtkAccessibleText *self)
{
  return 0;
}

static gboolean
gtk_accessible_text_default_get_selection (GtkAccessibleText       *self,
                                           gsize                   *n_ranges,
                                           GtkAccessibleTextRange **ranges)
{
  return FALSE;
}

static gboolean
gtk_accessible_text_default_get_attributes (GtkAccessibleText        *self,
                                            unsigned int              offset,
                                            gsize                    *n_ranges,
                                            GtkAccessibleTextRange  **ranges,
                                            char                   ***attribute_names,
                                            char                   ***attribute_values)
{
  *attribute_names = NULL;
  *attribute_values = NULL;
  *n_ranges = 0;
  return FALSE;
}

static void
gtk_accessible_text_default_get_default_attributes (GtkAccessibleText   *self,
                                                    char              ***attribute_names,
                                                    char              ***attribute_values)
{
  *attribute_names = g_new0 (char *, 1);
  *attribute_values = g_new0 (char *, 1);
}

static gboolean
gtk_accessible_text_default_set_caret_position (GtkAccessibleText *self,
                                                unsigned int       offset)
{
  return FALSE;
}

static gboolean
gtk_accessible_text_default_set_selection (GtkAccessibleText      *self,
                                           gsize                   i,
                                           GtkAccessibleTextRange *range)
{
  return FALSE;
}

static void
gtk_accessible_text_default_init (GtkAccessibleTextInterface *iface)
{
  iface->get_contents = gtk_accessible_text_default_get_contents;
  iface->get_contents_at = gtk_accessible_text_default_get_contents_at;
  iface->get_caret_position = gtk_accessible_text_default_get_caret_position;
  iface->get_selection = gtk_accessible_text_default_get_selection;
  iface->get_attributes = gtk_accessible_text_default_get_attributes;
  iface->get_default_attributes = gtk_accessible_text_default_get_default_attributes;
  iface->set_caret_position = gtk_accessible_text_default_set_caret_position;
  iface->set_selection = gtk_accessible_text_default_set_selection;
}

static GBytes *
nul_terminate_contents (GBytes *bytes)
{
  const char *data;
  gsize size;

  data = g_bytes_get_data (bytes, &size);
  if (size == 0 || (size > 0 && data[size - 1] != '\0'))
    {
      guchar *copy;

      copy = g_new (guchar, size + 1);
      if (size > 0)
        memcpy (copy, data, size);
      copy[size] = '\0';

      g_bytes_unref (bytes);
      bytes = g_bytes_new_take (copy, size + 1);
    }

  return bytes;
}

/*< private >
 * gtk_accessible_text_get_contents:
 * @self: the accessible object
 * @start: the beginning of the range, in characters
 * @end: the end of the range, in characters
 *
 * Retrieve the current contents of the accessible object within
 * the given range.
 *
 * If @end is `G_MAXUINT`, the end of the range is the full content of the
 * accessible object.
 *
 * Returns: (transfer full): the requested slice of the contents of the
 *   accessible object, as NUL-terminated UTF-8
 *
 * Since: 4.14
 */

GBytes *
gtk_accessible_text_get_contents (GtkAccessibleText *self,
                                  unsigned int       start,
                                  unsigned int       end)
{
  GBytes *bytes;

  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), NULL);
  g_return_val_if_fail (end >= start, NULL);

  bytes = GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_contents (self, start, end);

  return nul_terminate_contents (bytes);
}

/*< private >
 * gtk_accessible_text_get_contents_at:
 * @self: the accessible object
 * @offset: the offset of the text to retrieve
 * @granularity: specify the boundaries of the text
 * @start: (out): the starting offset of the contents, in characters
 * @end: (out): the ending offset of the contents, in characters
 *
 * Retrieve the current contents of the accessible object at the given
 * offset.
 *
 * Using the @granularity enumeration allows to adjust the offset so that
 * this function can return the beginning of the word, line, or sentence;
 * the initial and final boundaries are stored in @start and @end.
 *
 * Returns: (transfer full): the requested slice of the contents of the
 *   accessible object, as NUL-terminated UTF-8 buffer
 *
 * Since: 4.14
 */

GBytes *
gtk_accessible_text_get_contents_at (GtkAccessibleText            *self,
                                     unsigned int                  offset,
                                     GtkAccessibleTextGranularity  granularity,
                                     unsigned int                 *start,
                                     unsigned int                 *end)
{
  static const char empty[] = {0};
  GBytes *bytes;

  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), NULL);

  bytes = GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_contents_at (self, offset, granularity, start, end);

  if (bytes == NULL)
    return g_bytes_new_static (empty, sizeof empty);

  return nul_terminate_contents (bytes);
}

/*< private >
 * gtk_accessible_text_get_character_count:
 * @self: the accessible object
 *
 * Returns the amount of characters that the text contains.
 *
 * Returns: the length of the text, in characters
 *
 * Since: 4.18
 */

unsigned int
gtk_accessible_text_get_character_count (GtkAccessibleText *self)
{
  GBytes *contents;
  const char *str;
  gsize len;

  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), 0);

  contents = gtk_accessible_text_get_contents (self, 0, G_MAXUINT);
  str = g_bytes_get_data (contents, NULL);
  len = g_utf8_strlen (str, -1);
  g_bytes_unref (contents);

  return len;
}

/*< private >
 * gtk_accessible_text_get_caret_position:
 * @self: the accessible object
 *
 * Retrieves the position of the caret inside the accessible object.
 *
 * If the accessible has no caret, 0 is returned.
 *
 * Returns: the position of the caret, in characters
 *
 * Since: 4.14
 */

unsigned int
gtk_accessible_text_get_caret_position (GtkAccessibleText *self)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), 0);

  return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_caret_position (self);
}

/*< private >
 * gtk_accessible_text_get_selection:
 * @self: the accessible object
 * @n_ranges: (out): the number of selection ranges
 * @ranges: (optional) (out) (array length=n_ranges): the selection ranges
 *
 * Retrieves the selection ranges in the accessible object.
 *
 * If this function returns true, `n_ranges` will be set to a value
 * greater than or equal to one, and @ranges will be set to a newly
 * allocated array of [struct#Gtk.AccessibleTextRange].
 *
 * Returns: true if there's at least one selected range inside the
 *   accessible object, and false otherwise
 *
 * Since: 4.14
 */

gboolean
gtk_accessible_text_get_selection (GtkAccessibleText       *self,
                                   gsize                   *n_ranges,
                                   GtkAccessibleTextRange **ranges)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);

  return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_selection (self, n_ranges, ranges);
}

/*< private >
 * gtk_accessible_text_get_attributes:
 * @self: the accessible object
 * @offset: the offset, in characters
 * @n_ranges: (out): the number of attributes
 * @ranges: (out) (array length=n_attributes) (optional): the ranges of the attributes
 *   inside the accessible object
 * @attribute_names: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
 *   the names of the attributes inside the accessible object
 * @attribute_values: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
 *   the values of the attributes inside the accessible object
 *
 * Retrieves the text attributes inside the accessible object.
 *
 * Each attribute is composed by:
 *
 * - a range
 * - a name, typically in the form of a reverse DNS identifier
 * - a value
 *
 * If this function returns true, `n_attributes` will be set to a value
 * greater than or equal to one, @ranges will be set to a newly
 * allocated array of [struct#Gtk.AccessibleTextRange] which should
 * be freed with g_free(), @attribute_names and @attribute_values
 * will be set to string arrays that should be freed with g_strfreev().
 *
 * Returns: true if the accessible object has at least an attribute,
 *   and false otherwise
 *
 * Since: 4.14
 */

gboolean
gtk_accessible_text_get_attributes (GtkAccessibleText        *self,
                                    unsigned int              offset,
                                    gsize                    *n_ranges,
                                    GtkAccessibleTextRange  **ranges,
                                    char                   ***attribute_names,
                                    char                   ***attribute_values)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);

  return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_attributes (self,
                                                               offset,
                                                               n_ranges,
                                                               ranges,
                                                               attribute_names,
                                                               attribute_values);
}

/*< private >
 * gtk_accessible_text_get_default_attributes:
 * @self: the accessible object
 * @attribute_names: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
 *   the names of the attributes inside the accessible object
 * @attribute_values: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
 *   the values of the attributes inside the accessible object
 *
 * Retrieves the default text attributes inside the accessible object.
 *
 * Each attribute is composed by:
 *
 * - a name, typically in the form of a reverse DNS identifier
 * - a value
 *
 * If this function returns true, @attribute_names and @attribute_values
 * will be set to string arrays that should be freed with g_strfreev().
 *
 * Since: 4.14
 */

void
gtk_accessible_text_get_default_attributes (GtkAccessibleText   *self,
                                            char              ***attribute_names,
                                            char              ***attribute_values)
{
  g_return_if_fail (GTK_IS_ACCESSIBLE_TEXT (self));

  GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_default_attributes (self,
                                                                attribute_names,
                                                                attribute_values);
}

/*< private >
 * gtk_accessible_text_get_attributes_run:
 * @self: the accessible object
 * @offset: the offset, in characters
 * @include_defaults: whether to include the default attributes in the
 *   returned array
 * @n_attributes: (out): the number of attributes
 * @attribute_names: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
 *   the names of the attributes inside the accessible object
 * @attribute_values: (out) (array zero-terminated=1) (element-type utf8) (optional) (transfer full):
 *   the values of the attributes inside the accessible object
 * @start (out): the start index of the attribute run (portion of text where attributes are the same)
 * @end (out): the end index of the attribute run (portion of text where attributes are the same)
 *
 * Retrieves the text attributes inside the accessible object.
 *
 * Each attribute is composed by:
 *
 * - a range
 * - a name, typically in the form of a reverse DNS identifier
 * - a value
 *
 * If this function returns true, `n_attributes` will be set to a value
 * greater than or equal to one, @attribute_names and @attribute_values
 * will be set to string arrays that should be freed with g_strfreev()
 * and @start and @end will be set to the start and end (character) index
 * of the run.
 *
 * Returns: true if the accessible object has at least an attribute,
 *   and false otherwise
 *
 * Since: 4.18
 */

gboolean
gtk_accessible_text_get_attributes_run (GtkAccessibleText        *self,
                                        unsigned int              offset,
                                        gboolean                  include_defaults,
                                        gsize                    *n_attributes,
                                        char                   ***attribute_names,
                                        char                   ***attribute_values,
                                        int                      *start,
                                        int                      *end)
{
  GHashTable *attrs;
  GHashTableIter attr_iter;
  gpointer key, value;
  char **attr_names, **attr_values;
  gboolean res;
  GStrvBuilder *names_builder;
  GStrvBuilder *values_builder;
  GtkAccessibleTextRange *ranges = NULL;

  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);

  attrs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  if (include_defaults)
    {
      gtk_accessible_text_get_default_attributes (self,
                                                  &attr_names,
                                                  &attr_values);

      for (unsigned i = 0; attr_names[i] != NULL; i++)
        {
          g_hash_table_insert (attrs,
                               g_steal_pointer (&attr_names[i]),
                               g_steal_pointer (&attr_values[i]));
        }

      g_free (attr_names);
      g_free (attr_values);
      attr_names = NULL;
      attr_values = NULL;
    }

  res = gtk_accessible_text_get_attributes (self,
                                            offset,
                                            n_attributes,
                                            &ranges,
                                            &attr_names,
                                            &attr_values);

  /* If there are no attributes, we can bail out early */
  if (!res && !include_defaults)
    {
      g_hash_table_unref (attrs);
      *attribute_names = NULL;
      *attribute_values = NULL;
      return FALSE;
    }

  *start = 0;
  *end = G_MAXINT;

  /* The text attributes override the default ones */
  for (unsigned i = 0; i < *n_attributes; i++)
    {
      g_hash_table_insert (attrs,
                           g_steal_pointer (&attr_names[i]),
                           g_steal_pointer (&attr_values[i]));
      *start = MAX (*start, ranges[i].start);
      *end = MIN (*end, *start + ranges[i].length);
    }

  if (*end == G_MAXINT)
    *end = gtk_accessible_text_get_character_count (self);

  g_free (attr_names);
  g_free (attr_values);

  names_builder = g_strv_builder_new ();
  values_builder = g_strv_builder_new ();
  g_hash_table_iter_init (&attr_iter, attrs);
  *n_attributes = 0;
  while (g_hash_table_iter_next (&attr_iter, &key, &value))
    {
      g_strv_builder_add (names_builder, key);
      g_strv_builder_add (values_builder, value);
      (*n_attributes)++;
    }

  *attribute_names = g_strv_builder_end (names_builder);
  *attribute_values = g_strv_builder_end (values_builder);

  g_strv_builder_unref (names_builder);
  g_strv_builder_unref (values_builder);
  g_hash_table_unref (attrs);
  g_clear_pointer (&ranges, g_free);

  return *n_attributes > 0;
}

/*< private >
 * gtk_accessible_text_get_extents:
 * @self: a `GtkAccessibleText`
 * @start: start offset, in characters
 * @end: end offset, in characters
 * @extents: (out caller-allocates): return location for the extents
 *
 * Obtains the extents of a range of text, in widget coordinates.
 *
 * Returns: true if the extents were filled in, false otherwise
 *
 * Since: 4.16
 */

gboolean
gtk_accessible_text_get_extents (GtkAccessibleText *self,
                                 unsigned int       start,
                                 unsigned int       end,
                                 graphene_rect_t   *extents)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);
  g_return_val_if_fail (start <= end, FALSE);
  g_return_val_if_fail (extents != NULL, FALSE);

  if (GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_extents != NULL)
    return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_extents (self, start, end, extents);

  return FALSE;
}

/*< private >
 * gtk_accessible_get_text_offset:
 * @self: a `GtkAccessibleText`
 * @point: a point in widget coordinates
 * @offset: (out): return location for the text offset at @point
 *
 * Determines the text offset at the given position in the
 * widget.
 *
 * Returns: true if the offset was set, and false otherwise
 */

gboolean
gtk_accessible_text_get_offset (GtkAccessibleText      *self,
                                const graphene_point_t *point,
                                unsigned int           *offset)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);

  if (GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_offset != NULL)
    return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_offset (self, point, offset);

  return FALSE;
}

/*< private >
 * gtk_accessible_text_set_caret_position:
 * @self: the accessible object
 * @offset: the text offset in characters
 *
 * Sets the caret position.
 *
 * Returns: true if the caret position was updated
 */

gboolean
gtk_accessible_text_set_caret_position (GtkAccessibleText *self,
                                        unsigned int       offset)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);

  return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->set_caret_position (self, offset);
}

/*< private >
 * gtk_accessible_text_set_selection:
 * @self: the accessible object
 * @i: the selection to set
 * @range: the range to set the selection to
 *
 * Sets the caret position.
 *
 * Returns: true if the selection was updated
 */

gboolean
gtk_accessible_text_set_selection (GtkAccessibleText      *self,
                                   gsize                   i,
                                   GtkAccessibleTextRange *range)
{
  g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);

  return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->set_selection (self, i, range);
}

/**
 * gtk_accessible_text_update_caret_position:
 * @self: the accessible object
 *
 * Updates the position of the caret.
 *
 * Implementations of the `GtkAccessibleText` interface should call this
 * function every time the caret has moved, in order to notify assistive
 * technologies.
 *
 * Since: 4.14
 */

void
gtk_accessible_text_update_caret_position (GtkAccessibleText *self)
{
  GtkATContext *context;

  g_return_if_fail (GTK_IS_ACCESSIBLE_TEXT (self));

  context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (self));
  if (context == NULL)
    return;

  gtk_at_context_update_caret_position (context);

  g_object_unref (context);
}

/**
 * gtk_accessible_text_update_selection_bound:
 * @self: the accessible object
 *
 * Updates the boundary of the selection.
 *
 * Implementations of the `GtkAccessibleText` interface should call this
 * function every time the selection has moved, in order to notify assistive
 * technologies.
 *
 * Since: 4.14
 */

void
gtk_accessible_text_update_selection_bound (GtkAccessibleText *self)
{
  GtkATContext *context;

  g_return_if_fail (GTK_IS_ACCESSIBLE_TEXT (self));

  context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (self));
  if (context == NULL)
    return;

  gtk_at_context_update_selection_bound (context);

  g_object_unref (context);
}

/**
 * gtk_accessible_text_update_contents:
 * @self: the accessible object
 * @change: the type of change in the contents
 * @start: the starting offset of the change, in characters
 * @end: the end offset of the change, in characters
 *
 * Notifies assistive technologies of a change in contents.
 *
 * Implementations of the `GtkAccessibleText` interface should call this
 * function every time their contents change as the result of an operation,
 * like an insertion or a removal.
 *
 * Note: If the change is a deletion, this function must be called *before*
 * removing the contents, if it is an insertion, it must be called *after*
 * inserting the new contents.
 *
 * Since: 4.14
 */

void
gtk_accessible_text_update_contents (GtkAccessibleText              *self,
                                     GtkAccessibleTextContentChange  change,
                                     unsigned int                    start,
                                     unsigned int                    end)
{
  GtkATContext *context;

  g_return_if_fail (GTK_IS_ACCESSIBLE_TEXT (self));

  context = gtk_accessible_get_at_context (GTK_ACCESSIBLE (self));
  if (context == NULL)
    return;

  gtk_at_context_update_text_contents (context, change, start, end);

  g_object_unref (context);
}

Messung V0.5 in Prozent
C=98 H=96 G=96

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-07-02) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik