static void
load_images(MarkdownTextView * self)
{
    GtkTextBuffer *buffer;
    GtkTextIter iter;
    GSList *tags, *tagp;
    gchar *image_path;
    
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self));
    gtk_text_buffer_get_start_iter(buffer, &iter);
    
    do {
       tags = gtk_text_iter_get_tags(&iter);
       for (tagp = tags; tagp != NULL; tagp = tagp->next) {
           GtkTextTag *tag = tagp->data;
           gint is_underline = 0;
           gchar *lang = NULL;

           g_object_get(G_OBJECT(tag),
                        "underline", &is_underline,
                        "language", &lang,
                        NULL);

           if (is_underline == 2 && lang) {
               GdkPixbuf *pixbuf;
               gchar *path;
               
               image_path = egg_markdown_get_link_uri(self->markdown, atoi(lang));
               path = g_build_filename(self->image_directory, image_path, NULL);
               pixbuf = gdk_pixbuf_new_from_file(path, NULL);
               if (pixbuf) {
                   GtkTextMark *mark;
                   GtkTextIter start;

                   mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE);
                   
                   gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
                   gtk_text_iter_forward_to_tag_toggle(&iter, tag);
                   gtk_text_buffer_delete(buffer, &start, &iter);

                   gtk_text_buffer_insert_pixbuf(buffer, &iter, pixbuf);
  
                   g_object_unref(pixbuf);
                   gtk_text_buffer_delete_mark(buffer, mark);
               }
               
               g_free(image_path);
               g_free(lang);
               g_free(path);
               break;
           }

           g_free(lang);
       }
       
       if (tags)
           g_slist_free(tags);
   } while (gtk_text_iter_forward_to_tag_toggle(&iter, NULL));
}
Esempio n. 2
0
gboolean
ide_editor_spell_utils_skip_no_spell_check (GtkTextTag        *no_spell_check_tag,
                                            GtkTextIter       *start,
                                            const GtkTextIter *end)
{
  g_return_val_if_fail (start != NULL, FALSE);
  g_return_val_if_fail (end != NULL, FALSE);

  if (no_spell_check_tag == NULL)
    return TRUE;

  g_return_val_if_fail (GTK_IS_TEXT_TAG (no_spell_check_tag), FALSE);

  while (gtk_text_iter_has_tag (start, no_spell_check_tag))
    {
      GtkTextIter last = *start;

      if (!gtk_text_iter_forward_to_tag_toggle (start, no_spell_check_tag))
        return FALSE;

      if (gtk_text_iter_compare (start, &last) <= 0)
        return FALSE;

      ide_editor_spell_utils_text_iter_forward_word_end (start);
      ide_editor_spell_utils_text_iter_backward_word_start (start);

      if (gtk_text_iter_compare (start, &last) <= 0)
        return FALSE;

      if (gtk_text_iter_compare (start, end) >= 0)
        return FALSE;
  }

  return TRUE;
}
Esempio n. 3
0
static gboolean link_event_handler(GtkTextTag *tag, GObject *text_view,GdkEvent *event, GtkTextIter *iter, gpointer user_data) {
	if(event->type == GDK_BUTTON_PRESS) {
		GtkTextIter uri_begin = *iter;
		GtkTextIter uri_end = *iter;
		gchar *uri = NULL;
		gtk_text_iter_backward_to_tag_toggle(&uri_begin, tag);
		gtk_text_iter_forward_to_tag_toggle(&uri_end, tag);
		uri = gtk_text_iter_get_slice(&uri_begin, &uri_end);
		if(((GdkEventButton *)event)->button == 1) {
			GError *error = NULL;
			gtk_show_uri(NULL, uri, gdk_event_get_time(event), &error);
			if(error) {
				g_warning("Could not open %s from chat: %s", uri, error->message);
				g_error_free(error);
			}
		} else if(((GdkEventButton *)event)->button == 3) {
			GtkMenu *menu = GTK_MENU(g_object_get_data(text_view, "link_ctx_menu"));
			g_object_set_data_full(G_OBJECT(menu), "uri", g_strdup(uri), g_free);
			gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 3, gdk_event_get_time(event));
		}
		g_free(uri);
		return TRUE;
	}
	return FALSE;
}
Esempio n. 4
0
static gboolean link_event_handler(GtkTextTag *tag, GObject *text_view,GdkEvent *event, GtkTextIter *iter, GtkWidget *chat_view) {
	if(event->type == GDK_BUTTON_PRESS) {
		GtkTextIter uri_begin = *iter;
		GtkTextIter uri_end = *iter;
		gchar *uri = NULL;
		LinphoneChatRoom *chat_room = (LinphoneChatRoom *)g_object_get_data(G_OBJECT(chat_view), "cr");
		
		gtk_text_iter_backward_to_tag_toggle(&uri_begin, tag);
		gtk_text_iter_forward_to_tag_toggle(&uri_end, tag);
		uri = gtk_text_iter_get_slice(&uri_begin, &uri_end);
		if(((GdkEventButton *)event)->button == 1) {
			linphone_gtk_open_browser(uri);
		} else if(((GdkEventButton *)event)->button == 3) {
			GtkMenu *menu = GTK_MENU(g_object_get_data(text_view, "link_ctx_menu"));
			g_object_set_data_full(G_OBJECT(menu), "uri", g_strdup(uri), g_free);
			gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 3, gdk_event_get_time(event));
		}
		g_free(uri);
		
		linphone_chat_room_mark_as_read(chat_room);
		linphone_gtk_friend_list_update_chat_picture();
		
		return TRUE;
	}
	return FALSE;
}
Esempio n. 5
0
static void log_window_clip(LogWindow *logwin, guint clip_length)
{
        guint length;
	guint point;
	GtkTextBuffer *textbuf = logwin->buffer;
	GtkTextIter start_iter, end_iter;
	
	length = gtk_text_buffer_get_line_count(textbuf);
	/* debug_print("Log window length: %u\n", length); */
	
	if (length > clip_length) {
	        /* find the end of the first line after the cut off
		 * point */
       	        point = length - clip_length;
		gtk_text_buffer_get_iter_at_line(textbuf, &end_iter, point);
		if (!gtk_text_iter_forward_to_line_end(&end_iter))
			return;
		gtk_text_buffer_get_start_iter(textbuf, &start_iter);
		gtk_text_buffer_delete(textbuf, &start_iter, &end_iter);
		if (logwin->has_error) {
			gtk_text_buffer_get_start_iter(textbuf, &start_iter);
			if (mainwindow_get_mainwindow() && !gtk_text_iter_forward_to_tag_toggle(&start_iter, logwin->error_tag)) {
				mainwindow_clear_error(mainwindow_get_mainwindow());
				logwin->has_error = FALSE;
			}
		}
	}
}
Esempio n. 6
0
File: text.c Progetto: polarcat/yad
static gboolean
tag_event_cb (GtkTextTag *tag, GObject *obj, GdkEvent *ev,
	      GtkTextIter *iter, gpointer d)
{
  GtkTextIter start = *iter;
  GtkTextIter end = *iter;
  gchar *url, *cmdline;

  if (ev->type == GDK_BUTTON_PRESS)
    {
      GdkEventButton *bev = (GdkEventButton *) ev;

      if (bev->button == 1)
        {
          gtk_text_iter_backward_to_tag_toggle (&start, tag);
          gtk_text_iter_forward_to_tag_toggle (&end, tag);

          url = gtk_text_iter_get_text (&start, &end);
          cmdline = g_strdup_printf ("xdg-open '%s'", url);
          g_free (url);

          g_spawn_command_line_async (cmdline, NULL);

          g_free (cmdline);
	  return TRUE;
        }
    }

  return FALSE;
}
Esempio n. 7
0
static gboolean
get_tag_bounds (GtkTextIter *iter,
                GtkTextTag *tag,
                GtkTextIter *start,
                GtkTextIter *end)
{
	gboolean res = FALSE;

	g_return_val_if_fail (iter != NULL, FALSE);
	g_return_val_if_fail (tag != NULL, FALSE);
	g_return_val_if_fail (start != NULL, FALSE);
	g_return_val_if_fail (end != NULL, FALSE);

	if (gtk_text_iter_has_tag (iter, tag)) {
		*start = *iter;
		*end = *iter;

		if (!gtk_text_iter_begins_tag (start, tag))
			gtk_text_iter_backward_to_tag_toggle (start, tag);

		if (!gtk_text_iter_ends_tag (end, tag))
			gtk_text_iter_forward_to_tag_toggle (end, tag);

		res = TRUE;
	}

	return res;
}
Esempio n. 8
0
static VALUE
rg_forward_to_tag_toggle(int argc, VALUE *argv, VALUE self)
{
    VALUE tag;

    rb_scan_args(argc, argv, "01", &tag);
    return CBOOL2RVAL(gtk_text_iter_forward_to_tag_toggle(_SELF(self),
                                                          NIL_P(tag) ? NULL : RVAL2TAG(tag)));
}
Esempio n. 9
0
gchar *
utl_gui_text_buffer_get_text_with_tags (GtkTextBuffer *buffer) {

GtkTextIter start, prev;
GSList *tags = NULL, *i;
gchar tag_char_utf8[7] = {0};
gchar *text = g_strdup (""), *oldtext = NULL, *tmp;
gboolean done = FALSE;

    gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);

    g_unichar_to_utf8 (TAG_CHAR, tag_char_utf8);

    prev = start;

    while (!done)
    {
        tmp = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &prev, &start, TRUE);
        oldtext = text;
        text = g_strconcat (text, tmp, NULL);
        g_free (oldtext);
        g_free (tmp);

        tags = gtk_text_iter_get_toggled_tags (&start, TRUE);
        for (i = tags; i; i = i->next)
        {
            gchar *name;
            g_object_get (G_OBJECT (i->data), "name", &name, NULL);
            oldtext = text;
            text = g_strconcat (text, tag_char_utf8, name, tag_char_utf8, NULL);
            g_free (oldtext);
            g_free (name);
        }
        g_slist_free (tags);

        tags = gtk_text_iter_get_toggled_tags (&start, FALSE);
        for (i = tags; i; i = i->next)
        {
            gchar *name;
            g_object_get (G_OBJECT (i->data), "name", &name, NULL);
            oldtext = text;
            text = g_strconcat (text, tag_char_utf8, "/", name, tag_char_utf8, NULL);
            g_free (oldtext);
            g_free (name);
        }
        g_slist_free (tags);

        if (gtk_text_iter_is_end (&start))
            done = TRUE;
        prev = start;
        gtk_text_iter_forward_to_tag_toggle (&start, NULL);
    }

    return text;
}
static void
chat_text_view_maybe_trim_buffer (EmpathyChatTextView *view)
{
	EmpathyChatTextViewPriv *priv;
	GtkTextIter         top, bottom;
	gint                line;
	gint                remove;
	GtkTextTagTable    *table;
	GtkTextTag         *tag;
	
	priv = GET_PRIV (view);
	
	gtk_text_buffer_get_end_iter (priv->buffer, &bottom);
	line = gtk_text_iter_get_line (&bottom);
	if (line < MAX_LINES) {
		return;
	}
	
	remove = line - MAX_LINES;
	gtk_text_buffer_get_start_iter (priv->buffer, &top);
	
	bottom = top;
	if (!gtk_text_iter_forward_lines (&bottom, remove)) {
		return;
	}
	
	/* Track backwords to a place where we can safely cut, we don't do it in
	  * the middle of a tag.
	  */
	table = gtk_text_buffer_get_tag_table (priv->buffer);
	tag = gtk_text_tag_table_lookup (table, EMPATHY_CHAT_TEXT_VIEW_TAG_CUT);
	if (!tag) {
		return;
	}
	
	if (!gtk_text_iter_forward_to_tag_toggle (&bottom, tag)) {
		return;
	}
	
	if (!gtk_text_iter_equal (&top, &bottom)) {
		gtk_text_buffer_delete (priv->buffer, &top, &bottom);
	}
}
Esempio n. 11
0
void
gb_source_view_move_next_match (GbSourceView *view)
{
   GtkTextBuffer *buffer;
   GdkRectangle rect;
   GtkTextIter iter;
   GtkTextTag *search_tag;
   gboolean wrapped = FALSE;

   g_return_if_fail(GB_IS_SOURCE_VIEW(view));

   /*
    * TODO: Track current match, so move next match jumps past it next time.
    */

   search_tag = gb_source_view_ref_search_tag(view);
   gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(view), &rect);
   gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(view),
                                      &iter, rect.x, rect.y);

again:
   if (!gtk_text_iter_begins_tag(&iter, search_tag)) {
      if (gtk_text_iter_forward_to_tag_toggle(&iter, search_tag)) {
         if (!gtk_text_iter_begins_tag(&iter, search_tag)) {
            gtk_text_iter_backward_to_tag_toggle(&iter, search_tag);
         }
         gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(view), &iter,
                                      0.25, FALSE, 0, 0);
         goto cleanup;
      }
      if (!wrapped) {
         buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
         gtk_text_buffer_get_start_iter(buffer, &iter);
         wrapped = TRUE;
         goto again;
      }
   }

cleanup:
   g_object_unref(search_tag);
}
static gboolean
chat_text_view_url_event_cb (GtkTextTag          *tag,
			     GObject             *object,
			     GdkEvent            *event,
			     GtkTextIter         *iter,
			     EmpathyChatTextView *view)
{
	EmpathyChatTextViewPriv *priv;
	GtkTextIter              start, end;
	gchar                   *str;

	priv = GET_PRIV (view);

	/* If the link is being selected, don't do anything. */
	gtk_text_buffer_get_selection_bounds (priv->buffer, &start, &end);
	if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) {
		return FALSE;
	}
	
	if (event->type == GDK_BUTTON_RELEASE && event->button.button == 1) {
		start = end = *iter;
		
		if (gtk_text_iter_backward_to_tag_toggle (&start, tag) &&
		    gtk_text_iter_forward_to_tag_toggle (&end, tag)) {
			    str = gtk_text_buffer_get_text (priv->buffer,
							    &start,
							    &end,
							    FALSE);

			    empathy_url_show (GTK_WIDGET (view), str);
			    g_free (str);
		    }
	}
	
	return FALSE;
}
static void
chat_text_view_populate_popup (EmpathyChatTextView *view,
			  GtkMenu        *menu,
			  gpointer        user_data)
{
	EmpathyChatTextViewPriv *priv;
	GtkTextTagTable    *table;
	GtkTextTag         *tag;
	gint                x, y;
	GtkTextIter         iter, start, end;
	GtkWidget          *item;
	gchar              *str = NULL;
	
	priv = GET_PRIV (view);
	
	/* Clear menu item */
	if (gtk_text_buffer_get_char_count (priv->buffer) > 0) {
		item = gtk_menu_item_new ();
		gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
		gtk_widget_show (item);
		
		item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
		gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
		gtk_widget_show (item);
		
		g_signal_connect (item,
				  "activate",
				  G_CALLBACK (chat_text_view_clear_view_cb),
				  view);
	}
	
	/* Link context menu items */
	table = gtk_text_buffer_get_tag_table (priv->buffer);
	tag = gtk_text_tag_table_lookup (table, EMPATHY_CHAT_TEXT_VIEW_TAG_LINK);
	
	gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y);
	
	gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (view),
					       GTK_TEXT_WINDOW_WIDGET,
					       x, y,
					       &x, &y);
	
	gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (view), &iter, x, y);
	
	start = end = iter;
	
	if (gtk_text_iter_backward_to_tag_toggle (&start, tag) &&
	    gtk_text_iter_forward_to_tag_toggle (&end, tag)) {
		    str = gtk_text_buffer_get_text (priv->buffer,
						    &start, &end, FALSE);
	    }
	
	if (EMP_STR_EMPTY (str)) {
		g_free (str);
		return;
	}
	
	/* NOTE: Set data just to get the string freed when not needed. */
	g_object_set_data_full (G_OBJECT (menu),
				"url", str,
				(GDestroyNotify) g_free);
	
	item = gtk_menu_item_new ();
	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
	gtk_widget_show (item);
	
	item = gtk_menu_item_new_with_mnemonic (_("_Copy Link Address"));
	g_signal_connect (item,
			  "activate",
			  G_CALLBACK (chat_text_view_copy_address_cb),
			  str);
	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
	gtk_widget_show (item);
	
	item = gtk_menu_item_new_with_mnemonic (_("_Open Link"));
	g_signal_connect (item,
			  "activate",
			  G_CALLBACK (chat_text_view_open_address_cb),
			  str);
	gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
	gtk_widget_show (item);
}
Esempio n. 14
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;
}
Esempio n. 15
0
/**
 * gtk_text_buffer_deserialize:
 * @register_buffer: the #GtkTextBuffer @format is registered with
 * @content_buffer: the #GtkTextBuffer to deserialize into
 * @format: the rich text format to use for deserializing
 * @iter: insertion point for the deserialized text
 * @data: (array length=length): data to deserialize
 * @length: length of @data
 * @error: return location for a #GError
 *
 * This function deserializes rich text in format @format and inserts
 * it at @iter.
 *
 * @format<!-- -->s to be used must be registered using
 * gtk_text_buffer_register_deserialize_format() or
 * gtk_text_buffer_register_deserialize_tagset() beforehand.
 *
 * Return value: %TRUE on success, %FALSE otherwise.
 *
 * Since: 2.10
 **/
gboolean
gtk_text_buffer_deserialize (GtkTextBuffer  *register_buffer,
                             GtkTextBuffer  *content_buffer,
                             GdkAtom         format,
                             GtkTextIter    *iter,
                             const guint8   *data,
                             gsize           length,
                             GError        **error)
{
  GList    *formats;
  GList    *list;

  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (register_buffer), FALSE);
  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (content_buffer), FALSE);
  g_return_val_if_fail (format != GDK_NONE, FALSE);
  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (data != NULL, FALSE);
  g_return_val_if_fail (length > 0, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  formats = g_object_get_qdata (G_OBJECT (register_buffer),
                                deserialize_quark ());

  for (list = formats; list; list = g_list_next (list))
    {
      GtkRichTextFormat *fmt = list->data;

      if (fmt->atom == format)
        {
          GtkTextBufferDeserializeFunc function = fmt->function;
          gboolean                     success;
          GSList                      *split_tags;
          GSList                      *list;
          GtkTextMark                 *left_end        = NULL;
          GtkTextMark                 *right_start     = NULL;
          GSList                      *left_start_list = NULL;
          GSList                      *right_end_list  = NULL;

          /*  We don't want the tags that are effective at the insertion
           *  point to affect the pasted text, therefore we remove and
           *  remember them, so they can be re-applied left and right of
           *  the inserted text after pasting
           */
          split_tags = gtk_text_iter_get_tags (iter);

          list = split_tags;
          while (list)
            {
              GtkTextTag *tag = list->data;

              list = g_slist_next (list);

              /*  If a tag begins at the insertion point, ignore it
               *  because it doesn't affect the pasted text
               */
              if (gtk_text_iter_begins_tag (iter, tag))
                split_tags = g_slist_remove (split_tags, tag);
            }

          if (split_tags)
            {
              /*  Need to remember text marks, because text iters
               *  don't survive pasting
               */
              left_end = gtk_text_buffer_create_mark (content_buffer,
                                                      NULL, iter, TRUE);
              right_start = gtk_text_buffer_create_mark (content_buffer,
                                                         NULL, iter, FALSE);

              for (list = split_tags; list; list = g_slist_next (list))
                {
                  GtkTextTag  *tag             = list->data;
                  GtkTextIter *backward_toggle = gtk_text_iter_copy (iter);
                  GtkTextIter *forward_toggle  = gtk_text_iter_copy (iter);
                  GtkTextMark *left_start      = NULL;
                  GtkTextMark *right_end       = NULL;

                  gtk_text_iter_backward_to_tag_toggle (backward_toggle, tag);
                  left_start = gtk_text_buffer_create_mark (content_buffer,
                                                            NULL,
                                                            backward_toggle,
                                                            FALSE);

                  gtk_text_iter_forward_to_tag_toggle (forward_toggle, tag);
                  right_end = gtk_text_buffer_create_mark (content_buffer,
                                                           NULL,
                                                           forward_toggle,
                                                           TRUE);

                  left_start_list = g_slist_prepend (left_start_list, left_start);
                  right_end_list = g_slist_prepend (right_end_list, right_end);

                  gtk_text_buffer_remove_tag (content_buffer, tag,
                                              backward_toggle,
                                              forward_toggle);

                  gtk_text_iter_free (forward_toggle);
                  gtk_text_iter_free (backward_toggle);
                }

              left_start_list = g_slist_reverse (left_start_list);
              right_end_list = g_slist_reverse (right_end_list);
            }

          success = function (register_buffer, content_buffer,
                              iter, data, length,
                              fmt->can_create_tags,
                              fmt->user_data,
                              error);

          if (!success && error != NULL && *error == NULL)
            g_set_error (error, 0, 0,
                         _("Unknown error when trying to deserialize %s"),
                         gdk_atom_name (format));

          if (split_tags)
            {
              GSList      *left_list;
              GSList      *right_list;
              GtkTextIter  left_e;
              GtkTextIter  right_s;

              /*  Turn the remembered marks back into iters so they
               *  can by used to re-apply the remembered tags
               */
              gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                &left_e, left_end);
              gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                &right_s, right_start);

              for (list = split_tags,
                     left_list = left_start_list,
                     right_list = right_end_list;
                   list && left_list && right_list;
                   list = g_slist_next (list),
                     left_list = g_slist_next (left_list),
                     right_list = g_slist_next (right_list))
                {
                  GtkTextTag  *tag        = list->data;
                  GtkTextMark *left_start = left_list->data;
                  GtkTextMark *right_end  = right_list->data;
                  GtkTextIter  left_s;
                  GtkTextIter  right_e;

                  gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                    &left_s, left_start);
                  gtk_text_buffer_get_iter_at_mark (content_buffer,
                                                    &right_e, right_end);

                  gtk_text_buffer_apply_tag (content_buffer, tag,
                                             &left_s, &left_e);
                  gtk_text_buffer_apply_tag (content_buffer, tag,
                                             &right_s, &right_e);

                  gtk_text_buffer_delete_mark (content_buffer, left_start);
                  gtk_text_buffer_delete_mark (content_buffer, right_end);
                }

              gtk_text_buffer_delete_mark (content_buffer, left_end);
              gtk_text_buffer_delete_mark (content_buffer, right_start);

              g_slist_free (split_tags);
              g_slist_free (left_start_list);
              g_slist_free (right_end_list);
            }

          return success;
        }
    }

  g_set_error (error, 0, 0,
               _("No deserialize function found for format %s"),
               gdk_atom_name (format));

  return FALSE;
}
static void
gb_color_picker_document_monitor_uncolorize (GbColorPickerDocumentMonitor *self,
                                             GtkTextBuffer                *buffer,
                                             GtkTextIter                  *begin,
                                             GtkTextIter                  *end)
{
  GtkTextTagTable *tag_table;
  GtkTextIter real_begin;
  GtkTextIter real_end;

  g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));

  tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (buffer));

  if (begin == NULL && end == NULL)
    {
      g_autoptr(GPtrArray) taglist = g_ptr_array_new_with_free_func (g_free);

      gtk_text_tag_table_foreach (tag_table, (GtkTextTagTableForeach)collect_tag_names, taglist);
      for (guint n = 0; n < taglist->len; ++n)
        gtk_text_tag_table_remove (tag_table, g_ptr_array_index (taglist, n));

      return;
    }

  if (begin == NULL)
    gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &real_begin);
  else
    real_begin = *begin;

  if (end == NULL)
    gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &real_end);
  else
    real_end = *end;

  while (TRUE)
    {
      g_autoptr(GSList) tags = NULL;
      GtkTextTag *color_tag = NULL;

      tags = gtk_text_iter_get_toggled_tags (&real_begin, TRUE);

      for (const GSList *l = tags; l != NULL; l = l->next)
        {
          g_autofree gchar *name = NULL;
          GtkTextTag *tag = l->data;

          g_object_get (G_OBJECT (tag), "name", &name, NULL);

          if (name != NULL && g_str_has_prefix (name, COLOR_TAG_PREFIX))
            {
              color_tag = tag;
              break;
            }
        }

      if (color_tag != NULL)
        {
          gtk_text_iter_forward_to_tag_toggle (&real_begin, color_tag);
          gtk_text_tag_table_remove (tag_table, color_tag);
        }

      if (!gtk_text_iter_forward_to_tag_toggle (&real_begin, NULL))
        break;

      if (gtk_text_iter_compare (&real_begin, &real_end) != -1)
        break;
    }
}