From: Matthias Clasen Date: Mon, 16 May 2011 23:03:23 +0000 (-0400) Subject: Hacky support for combo boxes X-Git-Url: http://pileus.org/git/?p=~andy%2Fgtk;a=commitdiff_plain;h=68fcede223d055c7d6d739848a15c0b4a8ecc737 Hacky support for combo boxes This extends the current hacks in gailmenuitem to not only recognize menuitems with labels in them, but also menuitems which contain a GtkCellView, since those are used by GtkComboBox nowadays. Some of the AtkText apis are not fully supported. https://bugzilla.gnome.org/show_bug.cgi?id=650302 --- diff --git a/modules/other/gail/gailmenuitem.c b/modules/other/gail/gailmenuitem.c index 928679ef3..7aea9bfd3 100644 --- a/modules/other/gail/gailmenuitem.c +++ b/modules/other/gail/gailmenuitem.c @@ -112,6 +112,7 @@ static AtkAttributeSet* gail_menu_item_get_run_attributes (AtkText *text, gint *end_offset); static AtkAttributeSet* gail_menu_item_get_default_attributes (AtkText *text); static GtkWidget* get_label_from_container (GtkWidget *container); +static gchar * get_text_from_label_widget (GtkWidget *widget); G_DEFINE_TYPE_WITH_CODE (GailMenuItem, gail_menu_item, GAIL_TYPE_CONTAINER, @@ -148,16 +149,13 @@ gail_menu_item_real_initialize (AtkObject *obj, item->text = NULL; label = get_label_from_container (GTK_WIDGET (data)); - if (GTK_IS_LABEL (label)) - { - if (gtk_widget_get_mapped (label)) - gail_menu_item_init_textutil (item, label); - else - g_signal_connect (label, - "map", - G_CALLBACK (gail_menu_item_label_map_gtk), - item); - } + if (gtk_widget_get_mapped (label)) + gail_menu_item_init_textutil (item, label); + else + g_signal_connect (label, + "map", + G_CALLBACK (gail_menu_item_label_map_gtk), + item); g_signal_connect (data, "select", @@ -258,7 +256,7 @@ gail_menu_item_init_textutil (GailMenuItem *item, (GCallback) gail_menu_item_notify_label_gtk, item); } - label_text = gtk_label_get_text (GTK_LABEL (label)); + label_text = get_text_from_label_widget (label); gail_text_util_text_setup (item->textutil, label_text); } @@ -296,22 +294,17 @@ gail_menu_item_get_text (AtkText *text, label = get_label_from_container (widget); - if (!GTK_IS_LABEL (label)) - return NULL; - item = GAIL_MENU_ITEM (text); - if (!item->textutil) + if (!item->textutil) gail_menu_item_init_textutil (item, label); - label_text = gtk_label_get_text (GTK_LABEL (label)); + label_text = get_text_from_label_widget (label); if (label_text == NULL) return NULL; else - { - return gail_text_util_get_substring (item->textutil, + return gail_text_util_get_substring (item->textutil, start_pos, end_pos); - } } static gchar* @@ -334,15 +327,12 @@ gail_menu_item_get_text_before_offset (AtkText *text, /* Get label */ label = get_label_from_container (widget); - if (!GTK_IS_LABEL(label)) - return NULL; - item = GAIL_MENU_ITEM (text); if (!item->textutil) gail_menu_item_init_textutil (item, label); return gail_text_util_get_text (item->textutil, - gtk_label_get_layout (GTK_LABEL (label)), GAIL_BEFORE_OFFSET, + NULL, GAIL_BEFORE_OFFSET, boundary_type, offset, start_offset, end_offset); } @@ -366,15 +356,12 @@ gail_menu_item_get_text_at_offset (AtkText *text, /* Get label */ label = get_label_from_container (widget); - if (!GTK_IS_LABEL(label)) - return NULL; - item = GAIL_MENU_ITEM (text); if (!item->textutil) gail_menu_item_init_textutil (item, label); return gail_text_util_get_text (item->textutil, - gtk_label_get_layout (GTK_LABEL (label)), GAIL_AT_OFFSET, + NULL, GAIL_AT_OFFSET, boundary_type, offset, start_offset, end_offset); } @@ -400,35 +387,31 @@ gail_menu_item_get_text_after_offset (AtkText *text, /* Get label */ label = get_label_from_container (widget); - if (!GTK_IS_LABEL(label)) - return NULL; - item = GAIL_MENU_ITEM (text); if (!item->textutil) gail_menu_item_init_textutil (item, label); return gail_text_util_get_text (item->textutil, - gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET, + NULL, GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); } static gint -gail_menu_item_get_character_count (AtkText *text) +gail_menu_item_get_character_count (AtkText *atk_text) { - GtkWidget *widget; - GtkWidget *label; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return 0; - - label = get_label_from_container (widget); + gchar *text; + gint len; - if (!GTK_IS_LABEL(label)) - return 0; + text = gail_menu_item_get_text (atk_text, 0, -1); + if (text) + { + len = g_utf8_strlen (text, -1); + g_free (text); + } + else + len = 0; - return g_utf8_strlen (gtk_label_get_text (GTK_LABEL (label)), -1); + return len; } static void @@ -456,15 +439,15 @@ gail_menu_item_get_character_extents (AtkText *text, if (!GTK_IS_LABEL(label)) return; - + gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout); label_text = gtk_label_get_text (GTK_LABEL (label)); index = g_utf8_offset_to_pointer (label_text, offset) - label_text; pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect); - - gail_misc_get_extents_from_pango_rectangle (label, &char_rect, + + gail_misc_get_extents_from_pango_rectangle (label, &char_rect, x_layout, y_layout, x, y, width, height, coords); -} +} static gint gail_menu_item_get_offset_at_point (AtkText *text, @@ -578,26 +561,23 @@ static gunichar gail_menu_item_get_character_at_offset (AtkText *text, gint offset) { - GtkWidget *widget; - GtkWidget *label; - const gchar *string; + gchar *string; gchar *index; + gunichar ch; - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); - if (widget == NULL) - /* State is defunct */ - return '\0'; + string = gail_menu_item_get_text (text, 0, -1); - label = get_label_from_container (widget); + if (string == NULL || offset >= g_utf8_strlen (string, -1)) + ch = '\0'; + else + { + index = g_utf8_offset_to_pointer (string, offset); + ch = g_utf8_get_char (index); + } - if (!GTK_IS_LABEL(label)) - return '\0'; - string = gtk_label_get_text (GTK_LABEL (label)); - if (offset >= g_utf8_strlen (string, -1)) - return '\0'; - index = g_utf8_offset_to_pointer (string, offset); + g_free (string); - return g_utf8_get_char (index); + return ch; } static GtkWidget* @@ -616,8 +596,13 @@ get_label_from_container (GtkWidget *container) { if (GTK_IS_LABEL (tmp_list->data)) { - label = tmp_list->data; - break; + label = tmp_list->data; + break; + } + else if (GTK_IS_CELL_VIEW (tmp_list->data)) + { + label = tmp_list->data; + break; } /* * * Get label from menu item in desktop background preferences @@ -625,9 +610,9 @@ get_label_from_container (GtkWidget *container) * */ else if (GTK_IS_BOX (tmp_list->data)) { - label = get_label_from_container (GTK_WIDGET (tmp_list->data)); - if (label) - break; + label = get_label_from_container (GTK_WIDGET (tmp_list->data)); + if (label) + break; } } g_list_free (children); @@ -635,6 +620,49 @@ get_label_from_container (GtkWidget *container) return label; } +static gchar * +get_text_from_label_widget (GtkWidget *label) +{ + if (GTK_IS_LABEL (label)) + return g_strdup (gtk_label_get_text (GTK_LABEL (label))); + else if (GTK_IS_CELL_VIEW (label)) + { + GList *cells, *l; + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreePath *path; + GtkCellArea *area; + gchar *text; + + model = gtk_cell_view_get_model (GTK_CELL_VIEW (label)); + path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (label)); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (label)); + + gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE); + + cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (label)); + for (l = cells; l; l = l->next) + { + GtkCellRenderer *cell = l->data; + + if (GTK_IS_CELL_RENDERER_TEXT (cell)) + { + g_object_get (cell, "text", &text, NULL); + break; + } + } + + g_list_free (cells); + + return text; + } + + return NULL; +} + AtkObject* gail_menu_item_new (GtkWidget *widget) {