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)); }
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; }
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; }
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; }
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; } } } }
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; }
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; }
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))); }
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); } }
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); }
/** * 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; }
/** * 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; } }