label: Save links in an array

Stop using GList for this.
This commit is contained in:
Timm Bäder 2020-04-10 15:41:56 +02:00
parent ca47e96d35
commit 99998d25f8

View File

@ -359,7 +359,8 @@ struct _GtkLabelSelectionInfo
GtkCssNode *selection_node; GtkCssNode *selection_node;
GdkContentProvider *provider; GdkContentProvider *provider;
GList *links; GtkLabelLink *links;
guint n_links;
GtkLabelLink *active_link; GtkLabelLink *active_link;
GtkLabelLink *context_link; GtkLabelLink *context_link;
@ -2026,7 +2027,7 @@ gtk_label_get_label (GtkLabel *label)
typedef struct typedef struct
{ {
GtkLabel *label; GtkLabel *label;
GList *links; GArray *links;
GString *new_str; GString *new_str;
gsize text_len; gsize text_len;
} UriParserData; } UriParserData;
@ -2044,7 +2045,7 @@ start_element_handler (GMarkupParseContext *context,
if (strcmp (element_name, "a") == 0) if (strcmp (element_name, "a") == 0)
{ {
GtkLabelLink *link; GtkLabelLink link;
const gchar *uri = NULL; const gchar *uri = NULL;
const gchar *title = NULL; const gchar *title = NULL;
const gchar *class = NULL; const gchar *class = NULL;
@ -2093,40 +2094,42 @@ start_element_handler (GMarkupParseContext *context,
visited = FALSE; visited = FALSE;
if (priv->track_links && priv->select_info) if (priv->track_links && priv->select_info)
{ {
GList *l; for (i = 0; i < priv->select_info->n_links; i++)
for (l = priv->select_info->links; l; l = l->next)
{ {
link = l->data; const GtkLabelLink *l = &priv->select_info->links[i];
if (strcmp (uri, link->uri) == 0)
if (strcmp (uri, l->uri) == 0)
{ {
visited = link->visited; visited = l->visited;
break; break;
} }
} }
} }
link = g_new0 (GtkLabelLink, 1); if (!pdata->links)
link->uri = g_strdup (uri); pdata->links = g_array_new (FALSE, TRUE, sizeof (GtkLabelLink));
link->title = g_strdup (title);
link.uri = g_strdup (uri);
link.title = g_strdup (title);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (pdata->label)); widget_node = gtk_widget_get_css_node (GTK_WIDGET (pdata->label));
link->cssnode = gtk_css_node_new (); link.cssnode = gtk_css_node_new ();
gtk_css_node_set_name (link->cssnode, g_quark_from_static_string ("link")); gtk_css_node_set_name (link.cssnode, g_quark_from_static_string ("link"));
gtk_css_node_set_parent (link->cssnode, widget_node); gtk_css_node_set_parent (link.cssnode, widget_node);
if (class) if (class)
gtk_css_node_add_class (link->cssnode, g_quark_from_string (class)); gtk_css_node_add_class (link.cssnode, g_quark_from_string (class));
state = gtk_css_node_get_state (widget_node); state = gtk_css_node_get_state (widget_node);
if (visited) if (visited)
state |= GTK_STATE_FLAG_VISITED; state |= GTK_STATE_FLAG_VISITED;
else else
state |= GTK_STATE_FLAG_LINK; state |= GTK_STATE_FLAG_LINK;
gtk_css_node_set_state (link->cssnode, state); gtk_css_node_set_state (link.cssnode, state);
g_object_unref (link->cssnode); g_object_unref (link.cssnode);
link->visited = visited; link.visited = visited;
link->start = pdata->text_len; link.start = pdata->text_len;
pdata->links = g_list_prepend (pdata->links, link); g_array_append_val (pdata->links, link);
} }
else else
{ {
@ -2165,7 +2168,7 @@ end_element_handler (GMarkupParseContext *context,
if (!strcmp (element_name, "a")) if (!strcmp (element_name, "a"))
{ {
GtkLabelLink *link = pdata->links->data; GtkLabelLink *link = &g_array_index (pdata->links, GtkLabelLink, pdata->links->len - 1);
link->end = pdata->text_len; link->end = pdata->text_len;
} }
else else
@ -2213,16 +2216,15 @@ link_free (GtkLabelLink *link)
gtk_css_node_set_parent (link->cssnode, NULL); gtk_css_node_set_parent (link->cssnode, NULL);
g_free (link->uri); g_free (link->uri);
g_free (link->title); g_free (link->title);
g_free (link);
} }
static gboolean static gboolean
parse_uri_markup (GtkLabel *label, parse_uri_markup (GtkLabel *label,
const gchar *str, const gchar *str,
gchar **new_str, gchar **new_str,
GList **links, GtkLabelLink **links,
GError **error) guint *out_n_links,
GError **error)
{ {
GMarkupParseContext *context = NULL; GMarkupParseContext *context = NULL;
const gchar *p, *end; const gchar *p, *end;
@ -2268,14 +2270,25 @@ parse_uri_markup (GtkLabel *label,
g_markup_parse_context_free (context); g_markup_parse_context_free (context);
*new_str = g_string_free (pdata.new_str, FALSE); *new_str = g_string_free (pdata.new_str, FALSE);
*links = pdata.links;
if (pdata.links)
{
*out_n_links = pdata.links->len;
*links = (GtkLabelLink *)g_array_free (pdata.links, FALSE);
}
else
{
*links = NULL;
}
return TRUE; return TRUE;
failed: failed:
g_markup_parse_context_free (context); g_markup_parse_context_free (context);
g_string_free (pdata.new_str, TRUE); g_string_free (pdata.new_str, TRUE);
g_list_free_full (pdata.links, (GDestroyNotify) link_free);
if (pdata.links)
g_array_free (pdata.links, TRUE);
return FALSE; return FALSE;
} }
@ -2284,12 +2297,13 @@ static void
gtk_label_ensure_has_tooltip (GtkLabel *label) gtk_label_ensure_has_tooltip (GtkLabel *label)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GList *l; guint i;
gboolean has_tooltip = FALSE; gboolean has_tooltip = FALSE;
for (l = priv->select_info->links; l; l = l->next) for (i = 0; i < priv->select_info->n_links; i++)
{ {
GtkLabelLink *link = l->data; const GtkLabelLink *link = &priv->select_info->links[i];
if (link->title) if (link->title)
{ {
has_tooltip = TRUE; has_tooltip = TRUE;
@ -2312,9 +2326,10 @@ gtk_label_set_markup_internal (GtkLabel *label,
gunichar accel_char = 0; gunichar accel_char = 0;
gchar *str_for_display = NULL; gchar *str_for_display = NULL;
gchar *str_for_accel = NULL; gchar *str_for_accel = NULL;
GList *links = NULL; GtkLabelLink *links = NULL;
guint n_links = 0;
if (!parse_uri_markup (label, str, &str_for_display, &links, &error)) if (!parse_uri_markup (label, str, &str_for_display, &links, &n_links, &error))
{ {
g_warning ("Failed to set text '%s' from markup due to error parsing markup: %s", g_warning ("Failed to set text '%s' from markup due to error parsing markup: %s",
str, error->message); str, error->message);
@ -2327,7 +2342,8 @@ gtk_label_set_markup_internal (GtkLabel *label,
if (links) if (links)
{ {
gtk_label_ensure_select_info (label); gtk_label_ensure_select_info (label);
priv->select_info->links = g_list_reverse (links); priv->select_info->links = g_steal_pointer (&links);
priv->select_info->n_links = n_links;
_gtk_label_accessible_update_links (label); _gtk_label_accessible_update_links (label);
gtk_label_ensure_has_tooltip (label); gtk_label_ensure_has_tooltip (label);
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (label)), "link"); gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (label)), "link");
@ -3026,18 +3042,17 @@ gtk_label_update_layout_attributes (GtkLabel *label)
if (priv->layout == NULL) if (priv->layout == NULL)
return; return;
if (priv->select_info && priv->select_info->links) if (priv->select_info && priv->select_info->links)
{ {
const GdkRGBA *link_color; const GdkRGBA *link_color;
PangoAttribute *attribute; PangoAttribute *attribute;
GList *list; guint i;
attrs = pango_attr_list_new (); attrs = pango_attr_list_new ();
for (list = priv->select_info->links; list; list = list->next) for (i = 0; i < priv->select_info->n_links; i++)
{ {
GtkLabelLink *link = list->data; const GtkLabelLink *link = &priv->select_info->links[i];
attribute = pango_attr_underline_new (TRUE); attribute = pango_attr_underline_new (TRUE);
attribute->start_index = link->start; attribute->start_index = link->start;
@ -3454,15 +3469,15 @@ static void
update_link_state (GtkLabel *label) update_link_state (GtkLabel *label)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GList *l;
GtkStateFlags state; GtkStateFlags state;
guint i;
if (!priv->select_info) if (!priv->select_info)
return; return;
for (l = priv->select_info->links; l; l = l->next) for (i = 0; i < priv->select_info->n_links; i++)
{ {
GtkLabelLink *link = l->data; const GtkLabelLink *link = &priv->select_info->links[i];
state = gtk_widget_get_state_flags (GTK_WIDGET (label)); state = gtk_widget_get_state_flags (GTK_WIDGET (label));
if (link->visited) if (link->visited)
@ -3543,26 +3558,30 @@ get_cursor_direction (GtkLabel *label)
} }
static GtkLabelLink * static GtkLabelLink *
gtk_label_get_focus_link (GtkLabel *label) gtk_label_get_focus_link (GtkLabel *label,
int *out_index)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GtkLabelSelectionInfo *info = priv->select_info; GtkLabelSelectionInfo *info = priv->select_info;
GList *l; int link_index;
if (!info) if (!info ||
return NULL; info->selection_anchor != info->selection_end)
goto nope;
if (info->selection_anchor != info->selection_end) link_index = _gtk_label_get_link_at (label, info->selection_anchor);
return NULL;
for (l = info->links; l; l = l->next) if (link_index != -1)
{ {
GtkLabelLink *link = l->data; if (out_index)
if (link->start <= info->selection_anchor && *out_index = link_index;
info->selection_anchor <= link->end)
return link; return &info->links[link_index];
} }
nope:
if (out_index)
*out_index = -1;
return NULL; return NULL;
} }
@ -3652,7 +3671,7 @@ gtk_label_snapshot (GtkWidget *widget,
cursor_direction); cursor_direction);
} }
focus_link = gtk_label_get_focus_link (label); focus_link = gtk_label_get_focus_link (label, NULL);
active_link = info->active_link; active_link = info->active_link;
if (active_link) if (active_link)
@ -3974,8 +3993,6 @@ gtk_label_grab_focus (GtkWidget *widget)
GtkLabel *label = GTK_LABEL (widget); GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
gboolean select_on_focus; gboolean select_on_focus;
GtkLabelLink *link;
GList *l;
if (priv->select_info == NULL) if (priv->select_info == NULL)
return FALSE; return FALSE;
@ -3997,9 +4014,12 @@ gtk_label_grab_focus (GtkWidget *widget)
{ {
if (priv->select_info->links && !priv->in_click) if (priv->select_info->links && !priv->in_click)
{ {
for (l = priv->select_info->links; l; l = l->next) guint i;
for (i = 0; i < priv->select_info->n_links; i++)
{ {
link = l->data; const GtkLabelLink *link = &priv->select_info->links[i];
if (!range_is_in_ellipsis (label, link->start, link->end)) if (!range_is_in_ellipsis (label, link->start, link->end))
{ {
priv->select_info->selection_anchor = link->start; priv->select_info->selection_anchor = link->start;
@ -4022,19 +4042,19 @@ gtk_label_focus (GtkWidget *widget,
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GtkLabelSelectionInfo *info = priv->select_info; GtkLabelSelectionInfo *info = priv->select_info;
GtkLabelLink *focus_link; GtkLabelLink *focus_link;
GList *l;
if (!gtk_widget_is_focus (widget)) if (!gtk_widget_is_focus (widget))
{ {
gtk_widget_grab_focus (widget); gtk_widget_grab_focus (widget);
if (info) if (info)
{ {
focus_link = gtk_label_get_focus_link (label); focus_link = gtk_label_get_focus_link (label, NULL);
if (focus_link && direction == GTK_DIR_TAB_BACKWARD) if (focus_link && direction == GTK_DIR_TAB_BACKWARD)
{ {
for (l = g_list_last (info->links); l; l = l->prev) int i;
for (i = info->n_links - 1; i >= 0; i--)
{ {
focus_link = l->data; focus_link = &info->links[i];
if (!range_is_in_ellipsis (label, focus_link->start, focus_link->end)) if (!range_is_in_ellipsis (label, focus_link->start, focus_link->end))
{ {
info->selection_anchor = focus_link->start; info->selection_anchor = focus_link->start;
@ -4063,54 +4083,63 @@ gtk_label_focus (GtkWidget *widget,
index = info->selection_anchor; index = info->selection_anchor;
if (direction == GTK_DIR_TAB_FORWARD) if (direction == GTK_DIR_TAB_FORWARD)
for (l = info->links; l; l = l->next) {
{ guint i;
GtkLabelLink *link = l->data; for (i = 0; i < info->n_links; i++)
{
const GtkLabelLink *link = &info->links[i];
if (link->start > index) if (link->start > index)
{ {
if (!range_is_in_ellipsis (label, link->start, link->end)) if (!range_is_in_ellipsis (label, link->start, link->end))
{ {
gtk_label_select_region_index (label, link->start, link->start); gtk_label_select_region_index (label, link->start, link->start);
_gtk_label_accessible_focus_link_changed (label); _gtk_label_accessible_focus_link_changed (label);
return TRUE; return TRUE;
} }
} }
} }
}
else if (direction == GTK_DIR_TAB_BACKWARD) else if (direction == GTK_DIR_TAB_BACKWARD)
for (l = g_list_last (info->links); l; l = l->prev) {
{ int i;
GtkLabelLink *link = l->data; for (i = info->n_links - 1; i >= 0; i--)
{
GtkLabelLink *link = &info->links[i];
if (link->end < index) if (link->end < index)
{ {
if (!range_is_in_ellipsis (label, link->start, link->end)) if (!range_is_in_ellipsis (label, link->start, link->end))
{ {
gtk_label_select_region_index (label, link->start, link->start); gtk_label_select_region_index (label, link->start, link->start);
_gtk_label_accessible_focus_link_changed (label); _gtk_label_accessible_focus_link_changed (label);
return TRUE; return TRUE;
} }
} }
} }
}
goto out; goto out;
} }
else else
{ {
focus_link = gtk_label_get_focus_link (label); int focus_link_index;
int new_index = -1;
int i;
focus_link = gtk_label_get_focus_link (label, &focus_link_index);
switch (direction) switch (direction)
{ {
case GTK_DIR_TAB_FORWARD: case GTK_DIR_TAB_FORWARD:
if (focus_link) if (focus_link)
{ new_index = (focus_link_index + 1) % info->n_links;
l = g_list_find (info->links, focus_link);
l = l->next;
}
else else
l = info->links; new_index = 0;
for (; l; l = l->next)
for (i = new_index; i < info->n_links; i++)
{ {
GtkLabelLink *link = l->data; const GtkLabelLink *link = &info->links[i];
if (!range_is_in_ellipsis (label, link->start, link->end)) if (!range_is_in_ellipsis (label, link->start, link->end))
break; break;
} }
@ -4118,15 +4147,13 @@ gtk_label_focus (GtkWidget *widget,
case GTK_DIR_TAB_BACKWARD: case GTK_DIR_TAB_BACKWARD:
if (focus_link) if (focus_link)
{ new_index = focus_link_index == 0 ? info->n_links - 1 : focus_link_index - 1;
l = g_list_find (info->links, focus_link);
l = l->prev;
}
else else
l = g_list_last (info->links); new_index = info->n_links - 1;
for (; l; l = l->prev)
for (i = new_index; i >= 0; i--)
{ {
GtkLabelLink *link = l->data; const GtkLabelLink *link = &info->links[i];
if (!range_is_in_ellipsis (label, link->start, link->end)) if (!range_is_in_ellipsis (label, link->start, link->end))
break; break;
} }
@ -4140,9 +4167,9 @@ gtk_label_focus (GtkWidget *widget,
goto out; goto out;
} }
if (l) if (new_index != -1)
{ {
focus_link = l->data; focus_link = &info->links[new_index];
info->selection_anchor = focus_link->start; info->selection_anchor = focus_link->start;
info->selection_end = focus_link->start; info->selection_end = focus_link->start;
_gtk_label_accessible_focus_link_changed (label); _gtk_label_accessible_focus_link_changed (label);
@ -4514,7 +4541,6 @@ gtk_label_update_active_link (GtkWidget *widget,
if (info->links && !info->in_drag) if (info->links && !info->in_drag)
{ {
GList *l;
GtkLabelLink *link; GtkLabelLink *link;
gboolean found = FALSE; gboolean found = FALSE;
@ -4522,15 +4548,14 @@ gtk_label_update_active_link (GtkWidget *widget,
{ {
if (get_layout_index (label, x, y, &index)) if (get_layout_index (label, x, y, &index))
{ {
for (l = info->links; l != NULL; l = l->next) const int link_index = _gtk_label_get_link_at (label, index);
if (link_index != -1)
{ {
link = l->data; link = &info->links[link_index];
if (index >= link->start && index <= link->end)
{ if (!range_is_in_ellipsis (label, link->start, link->end))
if (!range_is_in_ellipsis (label, link->start, link->end)) found = TRUE;
found = TRUE;
break;
}
} }
} }
} }
@ -5604,7 +5629,7 @@ gtk_label_copy_clipboard (GtkLabel *label)
{ {
GtkLabelLink *link; GtkLabelLink *link;
link = gtk_label_get_focus_link (label); link = gtk_label_get_focus_link (label, NULL);
if (link) if (link)
gdk_clipboard_set_text (clipboard, link->uri); gdk_clipboard_set_text (clipboard, link->uri);
} }
@ -5626,7 +5651,7 @@ gtk_label_activate_link_open (GtkWidget *widget,
{ {
GtkLabel *label = GTK_LABEL (widget); GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GtkLabelLink *link = priv->select_info->context_link; GtkLabelLink *link = priv->select_info->context_link;
if (link) if (link)
emit_activate_link (label, link); emit_activate_link (label, link);
@ -5691,7 +5716,7 @@ gtk_label_update_actions (GtkLabel *label)
else else
{ {
has_selection = FALSE; has_selection = FALSE;
link = gtk_label_get_focus_link (label); link = gtk_label_get_focus_link (label, NULL);
} }
gtk_widget_action_set_enabled (widget, "clipboard.copy", has_selection); gtk_widget_action_set_enabled (widget, "clipboard.copy", has_selection);
@ -5754,7 +5779,7 @@ gtk_label_do_popup (GtkLabel *label,
if (priv->select_info->link_clicked) if (priv->select_info->link_clicked)
priv->select_info->context_link = priv->select_info->active_link; priv->select_info->context_link = priv->select_info->active_link;
else else
priv->select_info->context_link = gtk_label_get_focus_link (label); priv->select_info->context_link = gtk_label_get_focus_link (label, NULL);
gtk_label_update_actions (label); gtk_label_update_actions (label);
@ -5798,12 +5823,16 @@ static void
gtk_label_clear_links (GtkLabel *label) gtk_label_clear_links (GtkLabel *label)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
guint i;
if (!priv->select_info) if (!priv->select_info)
return; return;
g_list_free_full (priv->select_info->links, (GDestroyNotify) link_free); for (i = 0; i < priv->select_info->n_links; i++)
link_free (&priv->select_info->links[i]);
g_free (priv->select_info->links);
priv->select_info->links = NULL; priv->select_info->links = NULL;
priv->select_info->n_links = 0;
priv->select_info->active_link = NULL; priv->select_info->active_link = NULL;
gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (label)), "link"); gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (label)), "link");
@ -5856,7 +5885,7 @@ gtk_label_activate_current_link (GtkLabel *label)
GtkLabelLink *link; GtkLabelLink *link;
GtkWidget *widget = GTK_WIDGET (label); GtkWidget *widget = GTK_WIDGET (label);
link = gtk_label_get_focus_link (label); link = gtk_label_get_focus_link (label, NULL);
if (link) if (link)
emit_activate_link (label, link); emit_activate_link (label, link);
@ -5876,7 +5905,7 @@ gtk_label_get_current_link (GtkLabel *label)
if (priv->select_info->link_clicked) if (priv->select_info->link_clicked)
link = priv->select_info->active_link; link = priv->select_info->active_link;
else else
link = gtk_label_get_focus_link (label); link = gtk_label_get_focus_link (label, NULL);
return link; return link;
} }
@ -5970,7 +5999,6 @@ gtk_label_query_tooltip (GtkWidget *widget,
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
GtkLabelSelectionInfo *info = priv->select_info; GtkLabelSelectionInfo *info = priv->select_info;
gint index = -1; gint index = -1;
GList *l;
if (info && info->links) if (info && info->links)
{ {
@ -5987,17 +6015,15 @@ gtk_label_query_tooltip (GtkWidget *widget,
if (index != -1) if (index != -1)
{ {
for (l = info->links; l != NULL; l = l->next) const int link_index = _gtk_label_get_link_at (label, index);
if (link_index != -1)
{ {
GtkLabelLink *link = l->data; const GtkLabelLink *link = &info->links[link_index];
if (index >= link->start && index <= link->end)
if (link->title)
{ {
if (link->title) gtk_tooltip_set_markup (tooltip, link->title);
{
gtk_tooltip_set_markup (tooltip, link->title);
return TRUE;
}
break;
} }
} }
} }
@ -6085,7 +6111,7 @@ _gtk_label_get_n_links (GtkLabel *label)
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
if (priv->select_info) if (priv->select_info)
return g_list_length (priv->select_info->links); return priv->select_info->n_links;
return 0; return 0;
} }
@ -6097,11 +6123,7 @@ _gtk_label_get_link_uri (GtkLabel *label,
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
if (priv->select_info) if (priv->select_info)
{ return priv->select_info->links[idx].uri;
GtkLabelLink *link = g_list_nth_data (priv->select_info->links, idx);
if (link)
return link->uri;
}
return NULL; return NULL;
} }
@ -6113,42 +6135,39 @@ _gtk_label_get_link_extent (GtkLabel *label,
gint *end) gint *end)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
gint i;
GList *l;
GtkLabelLink *link;
if (priv->select_info) if (priv->select_info)
for (l = priv->select_info->links, i = 0; l; l = l->next, i++) {
{ const GtkLabelLink *link = &priv->select_info->links[idx];
if (i == idx)
{
link = l->data;
*start = link->start;
*end = link->end;
return;
}
}
*start = -1; *start = link->start;
*end = -1; *end = link->end;
}
else
{
*start = -1;
*end = -1;
}
} }
gint int
_gtk_label_get_link_at (GtkLabel *label, _gtk_label_get_link_at (GtkLabel *label,
gint pos) int pos)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
gint i;
GList *l;
GtkLabelLink *link;
if (priv->select_info) if (priv->select_info)
for (l = priv->select_info->links, i = 0; l; l = l->next, i++) {
{ guint i;
link = l->data;
if (link->start <= pos && pos < link->end) for (i = 0; i < priv->select_info->n_links; i++)
return i; {
} const GtkLabelLink *link = &priv->select_info->links[i];
if (link->start <= pos && pos < link->end)
return i;
}
}
return -1; return -1;
} }
@ -6161,10 +6180,9 @@ _gtk_label_activate_link (GtkLabel *label,
if (priv->select_info) if (priv->select_info)
{ {
GtkLabelLink *link = g_list_nth_data (priv->select_info->links, idx); GtkLabelLink *link = &priv->select_info->links[idx];
if (link) emit_activate_link (label, link);
emit_activate_link (label, link);
} }
} }
@ -6175,10 +6193,7 @@ _gtk_label_get_link_visited (GtkLabel *label,
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
if (priv->select_info) if (priv->select_info)
{ return priv->select_info->links[idx].visited;
GtkLabelLink *link = g_list_nth_data (priv->select_info->links, idx);
return link ? link->visited : FALSE;
}
return FALSE; return FALSE;
} }
@ -6188,9 +6203,6 @@ _gtk_label_get_link_focused (GtkLabel *label,
gint idx) gint idx)
{ {
GtkLabelPrivate *priv = gtk_label_get_instance_private (label); GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
gint i;
GList *l;
GtkLabelLink *link;
GtkLabelSelectionInfo *info = priv->select_info; GtkLabelSelectionInfo *info = priv->select_info;
if (!info) if (!info)
@ -6199,15 +6211,13 @@ _gtk_label_get_link_focused (GtkLabel *label,
if (info->selection_anchor != info->selection_end) if (info->selection_anchor != info->selection_end)
return FALSE; return FALSE;
for (l = info->links, i = 0; l; l = l->next, i++) if (idx >= 0 && idx < info->n_links)
{ {
if (i == idx) const GtkLabelLink *link = &info->links[idx];
{
link = l->data; if (link->start <= info->selection_anchor &&
if (link->start <= info->selection_anchor && info->selection_anchor <= link->end)
info->selection_anchor <= link->end) return TRUE;
return TRUE;
}
} }
return FALSE; return FALSE;