static gchar* gail_label_get_text (AtkText *text, gint start_pos, gint end_pos) { GtkWidget *widget; GtkLabel *label; const gchar *label_text; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) /* State is defunct */ return NULL; label = GTK_LABEL (widget); label_text = gtk_label_get_text (label); if (label_text == NULL) return NULL; else { if (GAIL_LABEL (text)->textutil == NULL) gail_label_init_text_util (GAIL_LABEL (text), widget); return gail_text_util_get_substring (GAIL_LABEL(text)->textutil, start_pos, end_pos); } }
static gchar* gail_label_get_selection (AtkText *text, gint selection_num, gint *start_pos, gint *end_pos) { GtkWidget *widget; GtkLabel *label; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) /* State is defunct */ return NULL; label = GTK_LABEL (widget); /* Only let the user get the selection if one is set, and if the * selection_num is 0. */ if (!gtk_label_get_selectable( label) || selection_num != 0) return NULL; if (gtk_label_get_selection_bounds (label, start_pos, end_pos)) { const gchar* label_text = gtk_label_get_text (label); if (label_text == NULL) return 0; else return gail_text_util_get_substring (GAIL_LABEL (text)->textutil, *start_pos, *end_pos); } else return NULL; }
static gchar* gail_label_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkLabel *label; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) { /* State is defunct */ return NULL; } /* Get label */ label = GTK_LABEL (widget); return gail_text_util_get_text (GAIL_LABEL (text)->textutil, gtk_label_get_layout (label), GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); }
static void window_created (GObject *obj, gpointer data) { g_return_if_fail (GAIL_LABEL (data)); notify_name_change (ATK_OBJECT (data)); }
static void gail_label_finalize (GObject *object) { GailLabel *label = GAIL_LABEL (object); if (label->textutil) g_object_unref (label->textutil); G_OBJECT_CLASS (gail_label_parent_class)->finalize (object); }
static void gail_label_map_gtk (GtkWidget *widget, gpointer data) { GailLabel *gail_label; gail_label = GAIL_LABEL (data); gail_label_init_text_util (gail_label, widget); }
static void gail_label_real_initialize (AtkObject *obj, gpointer data) { GtkWidget *widget; GailLabel *gail_label; ATK_OBJECT_CLASS (gail_label_parent_class)->initialize (obj, data); gail_label = GAIL_LABEL (obj); gail_label->window_create_handler = 0; gail_label->has_top_level = FALSE; gail_label->cursor_position = 0; gail_label->selection_bound = 0; gail_label->textutil = NULL; gail_label->label_length = 0; widget = GTK_WIDGET (data); if (gtk_widget_get_mapped (widget)) gail_label_init_text_util (gail_label, widget); else g_signal_connect (widget, "map", G_CALLBACK (gail_label_map_gtk), gail_label); /* * Check whether ancestor of GtkLabel is a GtkButton and if so * set accessible parent for GailLabel */ while (widget != NULL) { widget = gtk_widget_get_parent (widget); if (GTK_IS_BUTTON (widget)) { atk_object_set_parent (obj, gtk_widget_get_accessible (widget)); break; } } if (GTK_IS_ACCEL_LABEL (widget)) obj->role = ATK_ROLE_ACCEL_LABEL; else obj->role = ATK_ROLE_LABEL; }
static gchar* gail_label_get_text_before_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkLabel *label; widget = GTK_ACCESSIBLE (text)->widget; if (widget == NULL) /* State is defunct */ return NULL; /* Get label */ label = GTK_LABEL (widget); return gail_text_util_get_text (GAIL_LABEL (text)->textutil, gtk_label_get_layout (label), GAIL_BEFORE_OFFSET, boundary_type, offset, start_offset, end_offset); }
static gint gail_label_get_caret_offset (AtkText *text) { return GAIL_LABEL (text)->cursor_position; }
static void gail_label_real_notify_gtk (GObject *obj, GParamSpec *pspec) { GtkWidget *widget = GTK_WIDGET (obj); AtkObject* atk_obj = gtk_widget_get_accessible (widget); GtkLabel *label; GailLabel *gail_label; GObject *gail_obj; AtkObject *top_level; AtkObject *temp_obj; gail_label = GAIL_LABEL (atk_obj); if (strcmp (pspec->name, "label") == 0) { /* * We may get a label change for a label which is not attached to an * application. We wait until the toplevel window is created before * emitting the notification. * * This happens when [Ctrl+]Alt+Tab is pressed in metacity */ if (!gail_label->has_top_level) { temp_obj = atk_obj; top_level = NULL; while (temp_obj) { top_level = temp_obj; temp_obj = atk_object_get_parent (top_level); } if (atk_object_get_role (top_level) != ATK_ROLE_APPLICATION) { if (gail_label->window_create_handler == 0 && GAIL_IS_WINDOW (top_level)) gail_label->window_create_handler = g_signal_connect_after (top_level, "create", G_CALLBACK (window_created), atk_obj); } else gail_label->has_top_level = TRUE; } if (gail_label->has_top_level) notify_name_change (atk_obj); } else if (strcmp (pspec->name, "cursor-position") == 0) { gint start, end, tmp; gboolean text_caret_moved = FALSE; gboolean selection_changed = FALSE; gail_obj = G_OBJECT (atk_obj); label = GTK_LABEL (widget); if (gail_label->selection_bound != -1 && gail_label->selection_bound < gail_label->cursor_position) { tmp = gail_label->selection_bound; gail_label->selection_bound = gail_label->cursor_position; gail_label->cursor_position = tmp; } if (gtk_label_get_selection_bounds (label, &start, &end)) { if (start != gail_label->cursor_position || end != gail_label->selection_bound) { if (end != gail_label->selection_bound) { gail_label->selection_bound = start; gail_label->cursor_position = end; } else { gail_label->selection_bound = end; gail_label->cursor_position = start; } text_caret_moved = TRUE; if (start != end) selection_changed = TRUE; } } else { if (gail_label->cursor_position != gail_label->selection_bound) selection_changed = TRUE; if (gtk_label_get_selectable (label)) { if (gail_label->cursor_position != -1 && start != gail_label->cursor_position) text_caret_moved = TRUE; if (gail_label->selection_bound != -1 && end != gail_label->selection_bound) { text_caret_moved = TRUE; gail_label->cursor_position = end; gail_label->selection_bound = start; } else { gail_label->cursor_position = start; gail_label->selection_bound = end; } } else { /* GtkLabel has become non selectable */ gail_label->cursor_position = 0; gail_label->selection_bound = 0; text_caret_moved = TRUE; } } if (text_caret_moved) g_signal_emit_by_name (gail_obj, "text_caret_moved", gail_label->cursor_position); if (selection_changed) g_signal_emit_by_name (gail_obj, "text_selection_changed"); } else GAIL_WIDGET_CLASS (gail_label_parent_class)->notify_gtk (obj, pspec); }
static void notify_name_change (AtkObject *atk_obj) { GtkLabel *label; GailLabel *gail_label; GtkWidget *widget; GObject *gail_obj; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj)); if (widget == NULL) /* * State is defunct */ return; gail_obj = G_OBJECT (atk_obj); label = GTK_LABEL (widget); gail_label = GAIL_LABEL (atk_obj); if (gail_label->textutil == NULL) return; /* * Check whether the label has actually changed before emitting * notification. */ if (gail_label->textutil->buffer) { GtkTextIter start, end; const char *new_label; char *old_label; int same; gtk_text_buffer_get_start_iter (gail_label->textutil->buffer, &start); gtk_text_buffer_get_end_iter (gail_label->textutil->buffer, &end); old_label = gtk_text_buffer_get_text (gail_label->textutil->buffer, &start, &end, FALSE); new_label = gtk_label_get_text (label); same = strcmp (new_label, old_label); g_free (old_label); if (same == 0) return; } /* Create a delete text and an insert text signal */ g_signal_emit_by_name (gail_obj, "text_changed::delete", 0, gail_label->label_length); gail_label_init_text_util (gail_label, widget); g_signal_emit_by_name (gail_obj, "text_changed::insert", 0, gail_label->label_length); if (atk_obj->name == NULL) /* * The label has changed so notify a change in accessible-name */ g_object_notify (gail_obj, "accessible-name"); g_signal_emit_by_name (gail_obj, "visible_data_changed"); }