static void
gtk_source_tag_set_property (GObject      *object,
			     guint         prop_id,
			     const GValue *value,
			     GParamSpec   *pspec)
{
	GtkSourceTag *tag;
	GtkSourceTagPrivate *priv;
	gboolean size_changed = FALSE;

	tag = GTK_SOURCE_TAG (object);
	priv = gtk_source_tag_get_instance_private (tag);

	switch (prop_id)
	{
		case PROP_DRAW_SPACES:
			priv->draw_spaces = g_value_get_boolean (value);
			priv->draw_spaces_set = TRUE;
			g_object_notify (object, "draw-spaces-set");
			break;

		case PROP_DRAW_SPACES_SET:
			priv->draw_spaces_set = g_value_get_boolean (value);
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}

	gtk_text_tag_changed (GTK_TEXT_TAG (tag), size_changed);
}
static VALUE
event(VALUE self, VALUE event_object, VALUE event, VALUE iter)
{
    gboolean ret = gtk_text_tag_event(GTK_TEXT_TAG(RVAL2GOBJ(self)), 
                                      RVAL2GOBJ(event_object),
                                      RVAL2GEV(event),
                                      (GtkTextIter*)RVAL2BOXED(iter, GTK_TYPE_TEXT_ITER));
    return CBOOL2RVAL(ret);
}
static gboolean _text_view_click_handler(GtkWidget *widget, GdkEvent *event)
{
	GtkTextView *text_view = GTK_TEXT_VIEW(widget);

	if (event->type == GDK_BUTTON_RELEASE)
	{
		GdkEventButton *button_event = GDK_EVENT_BUTTON(event);

		if (button_event->button == 1)
		{
			GtkTextBuffer *text_buffer = gtk_text_view_get_buffer(text_view);
			gint x;
			gint y;
			GtkTextIter text_iter;

			gtk_text_view_window_to_buffer_coords(text_view, GTK_TEXT_WINDOW_WIDGET, button_event->x, button_event->y, &x, &y);
			gtk_text_view_get_iter_at_location(text_view, &text_iter, x, y);

			{
				GSList *text_tag_list = gtk_text_iter_get_tags(&text_iter);
				GSList *text_tag_list_item;

				for (text_tag_list_item = text_tag_list; text_tag_list_item != NULL; text_tag_list_item = text_tag_list_item->next)
				{
					GtkTextTag *text_tag = GTK_TEXT_TAG(text_tag_list_item->data);

					if (g_object_get_data(G_OBJECT(text_tag), "column_type") != NULL)
					{
						gtk_text_buffer_place_cursor(text_buffer);
						break;
					}
				}

				if (text_tag_list != NULL) g_slist_free(text_tag_list);
			}

			return TRUE;
		}
	}

	return FALSE;
}
void
gm_text_buffer_enhancer_insert_text (GmTextBufferEnhancer* self,
				     GtkTextIter* iter,
				     const gchar* text,
				     gint len)
{
  GmTextBufferEnhancerPrivate* priv = NULL;
  gint position = 0;
  gint length = 0;
  GSList* active_tags = NULL;
  GmTextBufferEnhancerHelper* best_helper = NULL;
  gint best_start = 0;
  gint best_length = 0;
  GSList* helper_ptr = NULL;
  GmTextBufferEnhancerHelper* considered_helper = NULL;
  gint considered_start = 0;
  gint considered_length = 0;
  GSList* tag_ptr = NULL;
  GtkTextMark* mark = NULL;
  GtkTextIter tag_start_iter;

  g_return_if_fail (GM_IS_TEXT_BUFFER_ENHANCER (self));
  g_return_if_fail (iter != NULL); // can't do better
  g_return_if_fail (text != NULL);

  priv = GM_TEXT_BUFFER_ENHANCER_GET_PRIVATE (self);

  if (len < 0)
    length = strlen (text);
  else
    length = len;

  mark = gtk_text_buffer_create_mark (priv->buffer, NULL, iter, TRUE);

  while (position < length) {

    /* try to find the best helper,
     * starting for the worse case that none is good */
    best_helper = NULL;
    best_start = length;
    best_length = 0;
    for (helper_ptr = priv->helpers ;
	 helper_ptr != NULL ;
	 helper_ptr = g_slist_next (helper_ptr)) {

      considered_helper
	= GM_TEXT_BUFFER_ENHANCER_HELPER (helper_ptr->data);
      gm_text_buffer_enhancer_helper_check (considered_helper,
					    text, position,
					    &considered_start,
					    &considered_length);
      if (((considered_start < best_start)
	   && (considered_length > 0))
	  || ((considered_start == best_start)
	      && (considered_length > best_length))) {

	best_helper = considered_helper;
	best_start = considered_start;
	best_length = considered_length;
      }
    }

    /* whatever we found can be further down : just apply the tags to
     * the part of the text before */
    if (position < best_start) {

      gtk_text_buffer_move_mark (priv->buffer, mark, iter);
      gtk_text_buffer_insert (priv->buffer, iter,
			      text + position, best_start - position);
      gtk_text_buffer_get_iter_at_mark (priv->buffer, &tag_start_iter, mark);
      for (tag_ptr = active_tags;
	   tag_ptr != NULL;
	   tag_ptr = g_slist_next (tag_ptr)) {

	gtk_text_buffer_apply_tag (priv->buffer, GTK_TEXT_TAG (tag_ptr->data),
				   &tag_start_iter, iter);
      }
      position = best_start;
    }

    /* ok, now we're either at the end without a best helper or still in the
     * middle with a best helper : apply that one if it's there!
     */
    if (best_helper != NULL)
      gm_text_buffer_enhancer_helper_enhance (best_helper,
					      priv->buffer,
					      iter,
					      &active_tags,
					      text,
					      &position,
					      best_length);
  }

  gtk_text_buffer_delete_mark (priv->buffer, mark);
  g_slist_free (active_tags);
}
Exemple #5
0
/**
 * gail_misc_buffer_get_run_attributes:
 * @buffer: The #GtkTextBuffer for which the attributes will be obtained
 * @offset: The offset at which the attributes are required
 * @start_offset: The start offset of the current run
 * @end_offset: The end offset of the current run
 *
 * Creates an AtkAttributeSet which contains the attributes for the 
 * run starting at offset.
 *
 * Returns: A pointer to the #AtkAttributeSet.
 **/
AtkAttributeSet*
gail_misc_buffer_get_run_attributes (GtkTextBuffer *buffer,
                                     gint          offset,
                                     gint	    *start_offset,
                                     gint          *end_offset)
{
  GtkTextIter iter;
  AtkAttributeSet *attrib_set = NULL;
  AtkAttribute *at;
  GSList *tags, *temp_tags;
  gdouble scale = 1;
  gboolean val_set = FALSE;

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);

  gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
  *end_offset = gtk_text_iter_get_offset (&iter);

  gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
  *start_offset = gtk_text_iter_get_offset (&iter);

  gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);

  tags = gtk_text_iter_get_tags (&iter);
  tags = g_slist_reverse (tags);

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "style-set", &val_set, NULL);
      if (val_set)
        {
          PangoStyle style;
          gchar *value;

          g_object_get (tag, "style", &style, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, style));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "variant-set", &val_set, NULL);
      if (val_set)
        {
          PangoVariant variant;
          gchar *value;

          g_object_get (tag, "variant", &variant, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, variant));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "stretch-set", &val_set, NULL);
      if (val_set)
        {
          PangoStretch stretch;
          gchar *value;

          g_object_get (tag, "stretch", &stretch, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, stretch));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "justification-set", &val_set, NULL);
      if (val_set)
        {
          GtkJustification justification;
          gchar *value;

          g_object_get (tag, "justification", &justification, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justification));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
      GtkTextDirection direction;

      g_object_get (tag, "direction", &direction, NULL);

      if (direction != GTK_TEXT_DIR_NONE)
        {
          gchar *value;
          val_set = TRUE;
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, direction));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "wrap-mode-set", &val_set, NULL);
      if (val_set)
        {
          GtkWrapMode wrap_mode;
          gchar *value;

          g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, wrap_mode));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "foreground-set", &val_set, NULL);
      if (val_set)
        {
          GdkRGBA *rgba;
          gchar *value;

          g_object_get (tag, "foreground-rgba", &rgba, NULL);
          value = g_strdup_printf ("%u,%u,%u",
                                   (guint) rgba->red * 65535,
                                   (guint) rgba->green * 65535,
                                   (guint) rgba->blue * 65535);
          gdk_rgba_free (rgba);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "background-set", &val_set, NULL);
      if (val_set)
        {
          GdkRGBA *rgba;
          gchar *value;

          g_object_get (tag, "background-rgba", &rgba, NULL);
          value = g_strdup_printf ("%u,%u,%u",
                                   (guint) rgba->red * 65535,
                                   (guint) rgba->green * 65535,
                                   (guint) rgba->blue * 65535);
          gdk_rgba_free (rgba);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "family-set", &val_set, NULL);

      if (val_set)
        {
          gchar *value;
          g_object_get (tag, "family", &value, NULL);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "language-set", &val_set, NULL);

      if (val_set)
        {
          gchar *value;
          g_object_get (tag, "language", &value, NULL);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "weight-set", &val_set, NULL);

      if (val_set)
        {
          gint weight;
          gchar *value;

          g_object_get (tag, "weight", &weight, NULL);
          value = g_strdup_printf ("%d", weight);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;


  /*
   * scale is special as the scale is the product of all scale values
   * specified.
   */
  temp_tags = tags;
  while (temp_tags)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
      gboolean scale_set;

      g_object_get (tag, "scale-set", &scale_set, NULL);
      if (scale_set)
        {
          gdouble font_scale;

          g_object_get (tag, "scale", &font_scale, NULL);
          val_set = TRUE;
          scale *= font_scale;
        }
      temp_tags = temp_tags->next;
    }
  if (val_set)
    {
      at = g_malloc(sizeof(AtkAttribute));
      at->name = g_strdup(atk_text_attribute_get_name (ATK_TEXT_ATTR_SCALE));
      at->value = g_strdup_printf("%g", scale);
      attrib_set = g_slist_prepend(attrib_set, at);
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "size-set", &val_set, NULL);
      if (val_set)
        {
          gint size;
          gchar *value;
          g_object_get (tag, "size", &size, NULL);
          value = g_strdup_printf ("%i", size);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "strikethrough-set", &val_set, NULL);
      if (val_set)
        {
          gboolean strikethrough;
          gchar *value;
          g_object_get (tag, "strikethrough", &strikethrough, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "underline-set", &val_set, NULL);
      if (val_set)
        {
          PangoUnderline underline;
          gchar *value;
          g_object_get (tag, "underline", &underline, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, underline));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "rise-set", &val_set, NULL);
      if (val_set)
        {
          gint rise;
          gchar *value;
          g_object_get (tag, "rise", &rise, NULL);
          value = g_strdup_printf ("%i", rise);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "background-full-height-set", &val_set, NULL);
      if (val_set)
        {
          gboolean bg_full_height;
          gchar *value;
          g_object_get (tag, "background-full-height", &bg_full_height, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
      if (val_set)
        {
          gint pixels;
          gchar *value;
          g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
          value = g_strdup_printf ("%i", pixels);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
      if (val_set)
        {
          gint pixels;
          gchar *value;
          g_object_get (tag, "pixels-below-lines", &pixels, NULL);
          value = g_strdup_printf ("%i", pixels);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
      if (val_set)
        {
          gint pixels;
          gchar *value;
          g_object_get (tag, "pixels-above-lines", &pixels, NULL);
          value = g_strdup_printf ("%i", pixels);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "editable-set", &val_set, NULL);
      if (val_set)
        {
          gboolean editable;
          gchar *value;
          g_object_get (tag, "editable", &editable, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, editable));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "invisible-set", &val_set, NULL);
      if (val_set)
        {
          gboolean invisible;
          gchar *value;
          g_object_get (tag, "invisible", &invisible, NULL);
          value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE, invisible));
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "indent-set", &val_set, NULL);
      if (val_set)
        {
          gint indent;
          gchar *value;
          g_object_get (tag, "indent", &indent, NULL);
          value = g_strdup_printf ("%i", indent);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "right-margin-set", &val_set, NULL);
      if (val_set)
        {
          gint margin;
          gchar *value;
          g_object_get (tag, "right-margin", &margin, NULL);
          value = g_strdup_printf ("%i", margin);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  temp_tags = tags;
  while (temp_tags && !val_set)
    {
      GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);

      g_object_get (tag, "left-margin-set", &val_set, NULL);
      if (val_set)
        {
          gint margin;
          gchar *value;
          g_object_get (tag, "left-margin", &margin, NULL);
          value = g_strdup_printf ("%i", margin);
          attrib_set = gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
        }
      temp_tags = temp_tags->next;
    }
  val_set = FALSE;

  g_slist_free (tags);
  return attrib_set;
}
Exemple #6
0
static void
row_clicked (GdauiCloud *cloud, gint row, GtkTextTag *tag)
{
	if (cloud->priv->selection_mode == GTK_SELECTION_NONE) {
		/* emit "activate" signal */
		g_signal_emit (cloud, objects_cloud_signals [ACTIVATE], 0, row);
		return;
	}

	/* toggle @rows's selection */
	if (g_slist_find (cloud->priv->selected_tags, tag)) {
		cloud->priv->selected_tags = g_slist_remove (cloud->priv->selected_tags, tag);
		g_object_set ((GObject*) tag,
			      "background-set", FALSE,
			      NULL);
		g_object_unref ((GObject*) tag);
	}
	else {
		cloud->priv->selected_tags = g_slist_prepend (cloud->priv->selected_tags, tag);
		g_object_ref ((GObject*) tag);
		g_object_set ((GObject*) tag,
			      "background", "yellow",
			      "background-set", TRUE,
			      NULL);

		GtkTextIter iter;
		gtk_text_buffer_get_iter_at_mark (cloud->priv->tbuffer, &iter,
                                                  gtk_text_buffer_get_insert (cloud->priv->tbuffer));
		while (1) {
			gunichar guchar;
			guchar = gtk_text_iter_get_char (&iter);
			if (g_unichar_isspace (guchar) && (guchar != 0x00A0)) {
				gtk_text_iter_forward_char (&iter);
				break;
			}
			if (!gtk_text_iter_backward_char (&iter))
				break;
		}
		gtk_text_buffer_place_cursor (cloud->priv->tbuffer, &iter);
	}

	if ((cloud->priv->selection_mode == GTK_SELECTION_SINGLE) ||
	    (cloud->priv->selection_mode == GTK_SELECTION_BROWSE)) {
		/* no more than 1 element can be selected */
		if (cloud->priv->selected_tags && cloud->priv->selected_tags->next) {
			GtkTextTag *tag2;
			tag2 = GTK_TEXT_TAG (cloud->priv->selected_tags->next->data);
			cloud->priv->selected_tags = g_slist_remove (cloud->priv->selected_tags, tag2);
			g_object_set ((GObject*) tag2,
				      "background-set", FALSE,
				      NULL);
			g_object_unref ((GObject*) tag2);
		}
	}
	if (cloud->priv->selection_mode == GTK_SELECTION_BROWSE) {
		/* one element is always selected */
		if (! cloud->priv->selected_tags) {
			cloud->priv->selected_tags = g_slist_prepend (cloud->priv->selected_tags, tag);
			g_object_ref ((GObject*) tag);
			g_object_set ((GObject*) tag,
				      "background", "yellow",
				      "background-set", TRUE,
				      NULL);
		}
	}

	sync_iter_with_selection (cloud);
	g_signal_emit_by_name (cloud, "selection-changed");
}
static VALUE
set_priority(VALUE self, VALUE priority)
{
    gtk_text_tag_set_priority(GTK_TEXT_TAG(RVAL2GOBJ(self)), NUM2INT(priority));
    return priority;
}
static VALUE
get_priority(VALUE self)
{
    return INT2NUM(gtk_text_tag_get_priority(GTK_TEXT_TAG(RVAL2GOBJ(self))));
}
static gboolean
ide_highlight_engine_tick (IdeHighlightEngine *self)
{
    GtkTextBuffer *buffer;
    GtkTextIter iter;
    GtkTextIter invalid_begin;
    GtkTextIter invalid_end;
    GSList *tags_iter;

    IDE_PROBE;

    g_assert (IDE_IS_HIGHLIGHT_ENGINE (self));
    g_assert (self->buffer != NULL);
    g_assert (self->highlighter != NULL);
    g_assert (self->invalid_begin != NULL);
    g_assert (self->invalid_end != NULL);

    self->quanta_expiration = g_get_monotonic_time () + HIGHLIGHT_QUANTA_USEC;

    buffer = GTK_TEXT_BUFFER (self->buffer);

    gtk_text_buffer_get_iter_at_mark (buffer, &invalid_begin, self->invalid_begin);
    gtk_text_buffer_get_iter_at_mark (buffer, &invalid_end, self->invalid_end);

    IDE_TRACE_MSG ("Highlight Range [%u:%u,%u:%u] (%s)",
                   gtk_text_iter_get_line (&invalid_begin),
                   gtk_text_iter_get_line_offset (&invalid_begin),
                   gtk_text_iter_get_line (&invalid_end),
                   gtk_text_iter_get_line_offset (&invalid_end),
                   G_OBJECT_TYPE_NAME (self->highlighter));

    if (gtk_text_iter_compare (&invalid_begin, &invalid_end) >= 0)
        IDE_GOTO (up_to_date);

    /*Clear all our tags*/
    for (tags_iter = self->private_tags; tags_iter; tags_iter = tags_iter->next)
        gtk_text_buffer_remove_tag (buffer,
                                    GTK_TEXT_TAG (tags_iter->data),
                                    &invalid_begin,
                                    &invalid_end);

    iter = invalid_begin;

    ide_highlighter_update (self->highlighter, ide_highlight_engine_apply_style,
                            &invalid_begin, &invalid_end, &iter);

    if (gtk_text_iter_compare (&iter, &invalid_end) >= 0)
        IDE_GOTO (up_to_date);

    /* Stop processing until further instruction if no movement was made */
    if (gtk_text_iter_equal (&iter, &invalid_begin))
        return FALSE;

    gtk_text_buffer_move_mark (buffer, self->invalid_begin, &iter);

    return TRUE;

up_to_date:
    gtk_text_buffer_get_start_iter (buffer, &iter);
    gtk_text_buffer_move_mark (buffer, self->invalid_begin, &iter);
    gtk_text_buffer_move_mark (buffer, self->invalid_end, &iter);

    return FALSE;
}