forked from AuroraMiddleware/gtk
label: Save links in an array
Stop using GList for this.
This commit is contained in:
parent
ca47e96d35
commit
99998d25f8
376
gtk/gtklabel.c
376
gtk/gtklabel.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user