static void gglk_text_update_editable_region(GtkTextBuffer *unused_widget, gpointer user_data) { GglkText *tb = user_data; GtkTextIter b, e; gboolean fixup = FALSE; gtk_text_buffer_get_iter_at_mark(tb->buffer, &e, tb->endedit); if(gtk_text_iter_is_end(&e)) { /* deleted the end bit; add it back */ fixup = TRUE; } else { gtk_text_iter_forward_char(&e); if(!gtk_text_iter_is_end(&e)) { /* user pasted extra stuff at end */ fixup = TRUE; } } if(fixup) { gtk_text_buffer_get_end_iter(tb->buffer, &e); gtk_text_buffer_insert(tb->buffer, &e, " ", -1); gtk_text_iter_backward_char(&e); gtk_text_buffer_move_mark(tb->buffer, tb->endedit, &e); } gtk_text_buffer_get_iter_at_mark(tb->buffer, &b, tb->startedit); gtk_text_buffer_get_end_iter(tb->buffer, &e); gtk_text_buffer_apply_tag_by_name(tb->buffer, "Input", &b, &e); gtk_text_buffer_apply_tag_by_name(tb->buffer, "editable", &b, &e); gtk_text_buffer_get_end_iter(tb->buffer, &tb->iter); }
static gchar * smie_gtk_source_buffer_forward_token (gpointer data) { smie_gtk_source_buffer_context_t *context = data; GtkTextIter iter; /* Skip comments and whitespaces. */ while (!gtk_text_iter_is_end (&context->iter) && (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || g_unichar_isspace (gtk_text_iter_get_char (&context->iter)))) gtk_text_iter_forward_char (&context->iter); if (gtk_text_iter_is_end (&context->iter)) return NULL; gtk_text_iter_assign (&iter, &context->iter); if (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "string")) { /* Read a string literal. */ while (!gtk_text_iter_is_end (&context->iter) && gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "string")) gtk_text_iter_forward_char (&context->iter); } else if (g_unichar_ispunct (gtk_text_iter_get_char (&context->iter))) { /* Read a punctuation. */ while (!gtk_text_iter_is_end (&context->iter) && g_unichar_ispunct (gtk_text_iter_get_char (&context->iter))) gtk_text_iter_forward_char (&context->iter); } else { /* Read a normal token. */ while (!gtk_text_iter_is_end (&context->iter) && !(gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "string") || g_unichar_ispunct (gtk_text_iter_get_char (&context->iter)) || g_unichar_isspace (gtk_text_iter_get_char (&context->iter)))) gtk_text_iter_forward_char (&context->iter); } return gtk_text_iter_get_slice (&iter, &context->iter); }
static void update_lines (ExampleAppWindow *win) { ExampleAppWindowPrivate *priv; GtkWidget *tab, *view; GtkTextBuffer *buffer; GtkTextIter iter; int count; gchar *lines; priv = example_app_window_get_instance_private (win); tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack)); if (tab == NULL) return; view = gtk_bin_get_child (GTK_BIN (tab)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); count = 0; gtk_text_buffer_get_start_iter (buffer, &iter); while (!gtk_text_iter_is_end (&iter)) { count++; if (!gtk_text_iter_forward_line (&iter)) break; } lines = g_strdup_printf ("%d", count); gtk_label_set_text (GTK_LABEL (priv->lines), lines); g_free (lines); }
/* Go to the end of the next or current "full word". A full word is a group of * non-blank chars. * In other words, this function is the same as the 'E' Vim command. * * Examples ('|' is the iter position): * "|---- abcd" -> "----| abcd" * "| ---- abcd" -> " ----| abcd" * "--|-- abcd" -> "----| abcd" * "---- a|bcd" -> "---- abcd|" */ void _gtk_source_iter_forward_full_word_end (GtkTextIter *iter) { GtkTextIter pos; gboolean non_blank_found = FALSE; /* It would be better to use gtk_text_iter_forward_visible_char(), but * it doesn't exist. So move by cursor position instead, it should be * equivalent here. */ pos = *iter; while (g_unichar_isspace (gtk_text_iter_get_char (&pos))) { gtk_text_iter_forward_visible_cursor_position (&pos); } while (!gtk_text_iter_is_end (&pos) && !g_unichar_isspace (gtk_text_iter_get_char (&pos))) { non_blank_found = TRUE; gtk_text_iter_forward_visible_cursor_position (&pos); } if (non_blank_found) { *iter = pos; } }
static std::vector<LineInfo> getLinesInfo(GtkTextView* textView, int height) { std::vector<LineInfo> linesInfo; int y1 = 0; int y2 = height; gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT, 0, y1, NULL, &y1); gtk_text_view_window_to_buffer_coords(textView, GTK_TEXT_WINDOW_LEFT, 0, y2, NULL, &y2); GtkTextIter iter; gtk_text_view_get_line_at_y(textView, &iter, y1, NULL); while(!gtk_text_iter_is_end(&iter)) { int y, height; gtk_text_view_get_line_yrange(textView, &iter, &y, &height); int line = gtk_text_iter_get_line(&iter); linesInfo.push_back(LineInfo(line+1, y)); if((y + height) >= y2) { break; } gtk_text_iter_forward_line(&iter); } if(linesInfo.size() == 0) { linesInfo.push_back(LineInfo(1, 1)); } return linesInfo; }
static void do_invert_case (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end) { GString *s = g_string_new (NULL); while (!gtk_text_iter_is_end (start) && !gtk_text_iter_equal (start, end)) { gunichar c, nc; c = gtk_text_iter_get_char (start); if (g_unichar_islower (c)) nc = g_unichar_toupper (c); else nc = g_unichar_tolower (c); g_string_append_unichar (s, nc); gtk_text_iter_forward_char (start); } gtk_text_buffer_delete_selection (buffer, TRUE, TRUE); gtk_text_buffer_insert_at_cursor (buffer, s->str, s->len); g_string_free (s, TRUE); }
gboolean _gtk_source_iter_ends_extra_natural_word (const GtkTextIter *iter, gboolean visible) { GtkTextIter prev; gboolean ends_word; prev = *iter; if (!backward_cursor_position (&prev, visible)) { return FALSE; } ends_word = gtk_text_iter_ends_word (iter); if (gtk_text_iter_is_end (iter)) { return ends_word || gtk_text_iter_get_char (&prev) == '_'; } if (ends_word) { return gtk_text_iter_get_char (iter) != '_'; } return (gtk_text_iter_get_char (&prev) == '_' && gtk_text_iter_get_char (iter) != '_' && !gtk_text_iter_starts_word (iter)); }
/** Kolorowanie słów. Słowa nie znajdujące się w słowniku - potencjalnie błędne - zostają oznaczone na czerwono. */ static void show_errors() { GtkTextIter start, end, text_end; int i, range; char *word; gunichar *wword; gtk_text_buffer_create_tag(editor_buf, "red_fg", "foreground", "red", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_get_end_iter(editor_buf, &text_end); gtk_text_buffer_get_start_iter(editor_buf, &end); range = gtk_text_buffer_get_char_count(editor_buf); while (!gtk_text_iter_is_end(&end)) { gtk_text_iter_forward_word_end(&end); start = end; gtk_text_iter_backward_word_start(&start); word = gtk_text_iter_get_text(&start, &end); wword = g_utf8_to_ucs4_fast(word, -1, NULL); if (make_lowercase(wword)) { if (!dictionary_find(dict, wword)) gtk_text_buffer_apply_tag_by_name(editor_buf, "red_fg", &start, &end); } g_free(word); g_free(wword); } }
//カーソルのある行を削除する void kill_line(void) { int delete_flag = 0; GtkTextIter start, end; GtkClipboard *clipboard = gtk_widget_get_clipboard(view, GDK_SELECTION_CLIPBOARD); buf[0] = '\0'; if (kill_flag == 1) { char *text = gtk_clipboard_wait_for_text(clipboard); strcat(buf, text); free(text); } gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(buffer), &start, gtk_text_buffer_get_insert(GTK_TEXT_BUFFER(buffer))); end = start; gtk_text_iter_forward_line(&end); if (!gtk_text_iter_starts_line(&start) && !gtk_text_iter_ends_line(&start) && !gtk_text_iter_is_end(&end) && kill_flag == 0) gtk_text_iter_backward_char(&end); char *text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer), &start, &end, TRUE); strcat(buf, text); free(text); if (buf[0] != '\0') delete_flag = 1; gtk_clipboard_set_text(clipboard, buf, -1); gtk_text_buffer_delete(GTK_TEXT_BUFFER(buffer), &start, &end); kill_flag = delete_flag; }
void apotheke_highlight_buffer_diff (GtkTextBuffer *buffer, GtkTextIter *start) { GtkTextIter *end; GtkTextIter *word_end; gchar *c; if (!gtk_text_iter_starts_line (start)) gtk_text_iter_set_line_offset (start, 0); while (!gtk_text_iter_is_end (start)) { end = gtk_text_iter_copy (start); if (!gtk_text_iter_forward_to_line_end (end)) break; word_end = gtk_text_iter_copy (start); gtk_text_iter_forward_char (word_end); c = gtk_text_iter_get_text (start, word_end); if (g_ascii_strcasecmp ("+", c) == 0) { gtk_text_buffer_apply_tag_by_name (buffer, "diff-added", start, end); } else if (g_ascii_strcasecmp ("-", c) == 0) { gtk_text_buffer_apply_tag_by_name (buffer, "diff-removed", start, end); } gtk_text_iter_forward_line (start); } }
static void update_words (ExampleAppWindow *win) { ExampleAppWindowPrivate *priv; GHashTable *strings; GHashTableIter iter; GtkWidget *tab, *view, *row; GtkTextBuffer *buffer; GtkTextIter start, end; GList *children, *l; gchar *word, *key; priv = example_app_window_get_instance_private (win); tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack)); if (tab == NULL) return; view = gtk_bin_get_child (GTK_BIN (tab)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); gtk_text_buffer_get_start_iter (buffer, &start); while (!gtk_text_iter_is_end (&start)) { while (!gtk_text_iter_starts_word (&start)) { if (!gtk_text_iter_forward_char (&start)) goto done; } end = start; if (!gtk_text_iter_forward_word_end (&end)) goto done; word = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); g_hash_table_add (strings, g_utf8_strdown (word, -1)); g_free (word); start = end; } done: children = gtk_container_get_children (GTK_CONTAINER (priv->words)); for (l = children; l; l = l->next) gtk_container_remove (GTK_CONTAINER (priv->words), GTK_WIDGET (l->data)); g_list_free (children); g_hash_table_iter_init (&iter, strings); while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL)) { row = gtk_button_new_with_label (key); g_signal_connect (row, "clicked", G_CALLBACK (find_word), win); gtk_widget_show (row); gtk_container_add (GTK_CONTAINER (priv->words), row); } g_hash_table_unref (strings); }
static void insert_icon_at_mark(GtkTextMark * requested_mark, gpointer user_data) { GList *win_list; GtkIMHtml *target_imhtml = NULL; GtkTextBuffer *target_buffer = NULL; GtkTextIter insertion_point; TwitterConvIcon *conv_icon = user_data; /* find the conversation that contains the mark */ for (win_list = pidgin_conv_windows_get_list(); win_list; win_list = win_list->next) { PidginWindow *win = win_list->data; GList *conv_list; for (conv_list = pidgin_conv_window_get_gtkconvs(win); conv_list; conv_list = conv_list->next) { PidginConversation *conv = conv_list->data; GtkIMHtml *current_imhtml = GTK_IMHTML(conv->imhtml); GtkTextBuffer *current_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(current_imhtml)); if (current_buffer == gtk_text_mark_get_buffer(requested_mark)) { target_imhtml = current_imhtml; target_buffer = current_buffer; break; } } } if (!(target_imhtml && target_buffer)) { purple_debug_warning(PLUGIN_ID, "No target imhtml/target buffer\n"); return; } /* insert icon to the mark */ gtk_text_buffer_get_iter_at_mark(target_buffer, &insertion_point, requested_mark); /* in this function, we put an icon for pending marks. we should * not invalidate the icon here, otherwise it may result in * thrashing. --yaz */ if (!conv_icon || !conv_icon->pixbuf) { purple_debug_warning(PLUGIN_ID, "No pixbuf\n"); return; } /* We only want to add the icon if the mark is still on screen. If the user cleared the screen with a ctrl-L, this won't be true. TODO -- can we get a callback at the clear and just delete the mark there? */ if (TRUE == gtk_text_iter_is_end(&insertion_point)) { purple_debug_warning(PLUGIN_ID, "Not adding the icon, since the insertion point is no longer in the buffer\n"); } else { /* insert icon actually */ gtk_text_buffer_insert_pixbuf(target_buffer, &insertion_point, conv_icon->pixbuf); } gtk_text_buffer_delete_mark(target_buffer, requested_mark); requested_mark = NULL; purple_debug_info(PLUGIN_ID, "inserted icon into conv\n"); }
static void forward_chars_with_skipping (GtkTextIter *iter, gint count, gboolean skip_invisible, gboolean skip_nontext, gboolean skip_decomp) { gint i; g_return_if_fail (count >= 0); i = count; while (i > 0) { gboolean ignored = FALSE; /* minimal workaround to avoid the infinite loop of bug #168247. * It doesn't fix the problemjust the symptom... */ if (gtk_text_iter_is_end (iter)) return; if (skip_nontext && gtk_text_iter_get_char (iter) == GTK_TEXT_UNKNOWN_CHAR) ignored = TRUE; /* FIXME: char_is_invisible() gets list of tags for each char there, and checks every tag. It doesn't sound like a good idea. */ if (!ignored && skip_invisible && char_is_invisible (iter)) ignored = TRUE; if (!ignored && skip_decomp) { /* being UTF8 correct sucks; this accounts for extra offsets coming from canonical decompositions of UTF8 characters (e.g. accented characters) which g_utf8_normalize() performs */ gchar *normal; gchar *casefold; gchar buffer[6]; gint buffer_len; buffer_len = g_unichar_to_utf8 (gtk_text_iter_get_char (iter), buffer); casefold = g_utf8_casefold (buffer, buffer_len); normal = g_utf8_normalize (casefold, -1, G_NORMALIZE_NFD); i -= (g_utf8_strlen (normal, -1) - 1); g_free (normal); g_free (casefold); } gtk_text_iter_forward_char (iter); if (!ignored) --i; } }
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 update_current (GeditDocument *doc, gint current) { CheckRange *range; GtkTextIter iter; GtkTextIter end_iter; gedit_debug (DEBUG_PLUGINS); g_return_if_fail (doc != NULL); g_return_if_fail (current >= 0); range = get_check_range (doc); g_return_if_fail (range != NULL); gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &iter, current); if (!gtk_text_iter_inside_word (&iter)) { /* if we're not inside a word, * we must be in some spaces. * skip forward to the beginning of the next word. */ if (!gtk_text_iter_is_end (&iter)) { gtk_text_iter_forward_word_end (&iter); gtk_text_iter_backward_word_start (&iter); } } else { if (!gtk_text_iter_starts_word (&iter)) gtk_text_iter_backward_word_start (&iter); } gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); if (gtk_text_iter_compare (&end_iter, &iter) < 0) { gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &end_iter); } else { gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &iter); } }
gboolean _gtk_source_iter_ends_full_word (const GtkTextIter *iter) { GtkTextIter prev = *iter; if (!gtk_text_iter_backward_visible_cursor_position (&prev)) { return FALSE; } return (!g_unichar_isspace (gtk_text_iter_get_char (&prev)) && (gtk_text_iter_is_end (iter) || g_unichar_isspace (gtk_text_iter_get_char (iter)))); }
Highlight::Highlight(GtkTextBuffer * buffer, GtkWidget * textview, const ustring & project, GtkTextTag * tag, const ustring & verse) { // Save and initialize variables. maintextbuffer = buffer; maintextview = GTK_TEXT_VIEW(textview); mytag = tag; locations_ready = false; interrupt_thread = false; // Remove any previous highlights. remove_previous_highlights(maintextbuffer); // Determine the boundaries between which to highlight, // in order to highlight only the words that are within the right verse. { GtkTextIter startiter; GtkTextIter enditer; gtk_text_buffer_get_start_iter(maintextbuffer, &startiter); gtk_text_buffer_get_end_iter(maintextbuffer, &enditer); GtkTextIter iter = startiter; bool started = false; bool ended = false; bool start = true; ustring verse_style = style_get_verse_marker(project); while (!gtk_text_iter_is_end(&iter)) { ustring paragraph_style, character_style; get_styles_at_iterator(iter, paragraph_style, character_style); if (start || (character_style == verse_style)) { ustring verse_at_iter = get_verse_number_at_iterator(iter, verse_style, "", NULL); if (verse == verse_at_iter) { if (!started) { started = true; startiter = iter; } } else { if (started) { if (!ended) { ended = true; enditer = iter; } } } } start = false; gtk_text_iter_forward_char(&iter); } main_start_offset = gtk_text_iter_get_offset(&startiter); main_end_offset = gtk_text_iter_get_offset(&enditer); } }
static gboolean smie_gtk_source_buffer_forward_comment (gpointer data) { smie_gtk_source_buffer_context_t *context = data; GtkTextIter start_iter; gtk_text_iter_assign (&start_iter, &context->iter); while (!gtk_text_iter_is_end (&context->iter) && (gtk_source_buffer_iter_has_context_class (context->buffer, &context->iter, "comment") || g_unichar_isspace (gtk_text_iter_get_char (&context->iter))) && gtk_text_iter_forward_char (&context->iter)) ; return !gtk_text_iter_equal (&context->iter, &start_iter); }
static gchar * get_current_word (GeditDocument *doc, gint *start, gint *end) { const CheckRange *range; GtkTextIter end_iter; GtkTextIter current_iter; gint range_end; gedit_debug (DEBUG_PLUGINS); g_return_val_if_fail (doc != NULL, NULL); g_return_val_if_fail (start != NULL, NULL); g_return_val_if_fail (end != NULL, NULL); range = get_check_range (doc); g_return_val_if_fail (range != NULL, NULL); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); range_end = gtk_text_iter_get_offset (&end_iter); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), ¤t_iter, range->current_mark); end_iter = current_iter; if (!gtk_text_iter_is_end (&end_iter)) { gedit_debug_message (DEBUG_PLUGINS, "Current is not end"); gtk_text_iter_forward_word_end (&end_iter); } *start = gtk_text_iter_get_offset (¤t_iter); *end = MIN (gtk_text_iter_get_offset (&end_iter), range_end); gedit_debug_message (DEBUG_PLUGINS, "Current word extends [%d, %d]", *start, *end); if (!(*start < *end)) return NULL; return gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), ¤t_iter, &end_iter, TRUE); }
bool Gobby::FindDialog::find_wrap(const GtkTextIter* from, SearchDirection direction, GtkTextIter* match_start, GtkTextIter* match_end) { SessionView* view = m_folder->get_current_document(); TextSessionView* text_view = dynamic_cast<TextSessionView*>(view); g_assert(text_view != NULL); GtkTextIter start_pos = *from; bool result = find_range(&start_pos, NULL, direction, match_start, match_end); if(result == true) return true; if(!m_check_wrap_around->get_active()) return false; // Wrap around GtkTextIter restart_pos; GtkTextBuffer* buffer = GTK_TEXT_BUFFER(text_view->get_text_buffer()); if(direction == SEARCH_FORWARD) gtk_text_buffer_get_start_iter(buffer, &restart_pos); else gtk_text_buffer_get_end_iter(buffer, &restart_pos); // Limit to search to: Normally the position where we started. GtkTextIter* relimit = &start_pos; if(direction == SEARCH_BACKWARD) { // ??? gtk_text_iter_forward_chars(&start_pos, get_find_text().length()); if(gtk_text_iter_is_end(&start_pos)) relimit = NULL; } return find_range(&restart_pos, relimit, direction, match_start, match_end); }
gboolean ide_editor_spell_utils_text_iter_ends_word (const GtkTextIter *iter) { GtkTextIter next_char; g_return_val_if_fail (iter != NULL, FALSE); if (!gtk_text_iter_ends_word (iter)) return FALSE; if (gtk_text_iter_is_end (iter)) return TRUE; next_char = *iter; gtk_text_iter_forward_char (&next_char); if (is__text_iter_apostrophe_or_dash (iter) && gtk_text_iter_starts_word (&next_char)) return FALSE; return TRUE; }
/* Similar to gtk_text_iter_backward_visible_word_starts(). */ gboolean _gtk_source_iter_backward_visible_word_starts (GtkTextIter *iter, gint count) { GtkTextIter orig = *iter; gint i; if (count < 0) { return _gtk_source_iter_forward_visible_word_ends (iter, -count); } for (i = 0; i < count; i++) { if (!_gtk_source_iter_backward_visible_word_start (iter)) { break; } } return !gtk_text_iter_equal (&orig, iter) && !gtk_text_iter_is_end (iter); }
static void get_lines (GtkTextView *text_view, gint y1, gint y2, GArray *buffer_coords, GArray *numbers, gint *countp) { GtkTextIter iter; gint count; gint size; gint last_line_num; g_array_set_size (buffer_coords, 0); g_array_set_size (numbers, 0); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, y1, NULL); /* For each iter, get its location and add it to the arrays. * Stop when we pass y2 */ count = 0; size = 0; while (!gtk_text_iter_is_end (&iter)) { gint y, height; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (buffer_coords, y); last_line_num = gtk_text_iter_get_line (&iter); g_array_append_val (numbers, last_line_num); ++count; if ((y + height) >= y2) break; gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (buffer_coords, y); g_array_append_val (numbers, line_num); ++count; } } *countp = count; }
static gboolean smie_gtk_source_buffer_is_end (gpointer data) { smie_gtk_source_buffer_context_t *context = data; return gtk_text_iter_is_end (&context->iter); }
static gssize xedit_document_input_stream_read (GInputStream *stream, void *buffer, gsize count, GCancellable *cancellable, GError **error) { XeditDocumentInputStream *dstream; GtkTextIter iter; gssize space_left, read, n; dstream = XEDIT_DOCUMENT_INPUT_STREAM (stream); if (count < 6) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, "Not enougth space in destination"); return -1; } if (g_cancellable_set_error_if_cancelled (cancellable, error)) return -1; /* Initialize the mark to the first char in the text buffer */ if (!dstream->priv->is_initialized) { gtk_text_buffer_get_start_iter (dstream->priv->buffer, &iter); dstream->priv->pos = gtk_text_buffer_create_mark (dstream->priv->buffer, NULL, &iter, FALSE); dstream->priv->is_initialized = TRUE; } space_left = count; read = 0; do { n = read_line (dstream, buffer + read, space_left); read += n; space_left -= n; } while (space_left > 0 && n != 0 && dstream->priv->bytes_partial == 0); /* Make sure that non-empty files are always terminated with \n (see bug #95676). * Note that we strip the trailing \n when loading the file */ gtk_text_buffer_get_iter_at_mark (dstream->priv->buffer, &iter, dstream->priv->pos); if (gtk_text_iter_is_end (&iter) && !gtk_text_iter_is_start (&iter)) { gssize newline_size; newline_size = get_new_line_size (dstream); if (space_left >= newline_size && !dstream->priv->newline_added) { const gchar *newline; newline = get_new_line (dstream); memcpy (buffer + read, newline, newline_size); read += newline_size; dstream->priv->newline_added = TRUE; } } return read; }
static gsize read_line (XeditDocumentInputStream *stream, gchar *outbuf, gsize space_left) { GtkTextIter start, next, end; gchar *buf; gint bytes; /* int since it's what iter_get_offset returns */ gsize bytes_to_write, newline_size, read; const gchar *newline; gboolean is_last; gtk_text_buffer_get_iter_at_mark (stream->priv->buffer, &start, stream->priv->pos); if (gtk_text_iter_is_end (&start)) return 0; end = next = start; newline = get_new_line (stream); /* Check needed for empty lines */ if (!gtk_text_iter_ends_line (&end)) gtk_text_iter_forward_to_line_end (&end); gtk_text_iter_forward_line (&next); buf = gtk_text_iter_get_slice (&start, &end); /* the bytes of a line includes also the newline, so with the offsets we remove the newline and we add the new newline size */ bytes = gtk_text_iter_get_bytes_in_line (&start) - stream->priv->bytes_partial; /* bytes_in_line includes the newlines, so we remove that assuming that they are single byte characters */ bytes = bytes - (gtk_text_iter_get_offset (&next) - gtk_text_iter_get_offset (&end)); is_last = gtk_text_iter_is_end (&end); /* bytes_to_write contains the amount of bytes we would like to write. This means its the amount of bytes in the line (without the newline in the buffer) + the amount of bytes for the newline we want to write (newline_size) */ bytes_to_write = bytes; /* do not add the new newline_size for the last line */ newline_size = get_new_line_size (stream); if (!is_last) bytes_to_write += newline_size; if (bytes_to_write > space_left) { gchar *ptr; gint char_offset; gint written; gsize to_write; /* Here the line does not fit in the buffer, we thus write the amount of bytes we can still fit, storing the position for the next read with the mark. Do not try to write the new newline in this case, it will be handled in the next iteration */ to_write = MIN (space_left, bytes); ptr = buf; written = 0; char_offset = 0; while (written < to_write) { gint w; ptr = g_utf8_next_char (ptr); w = (ptr - buf); if (w > to_write) { break; } else { written = w; ++char_offset; } } memcpy (outbuf, buf, written); /* Note: offset is one past what we wrote */ gtk_text_iter_forward_chars (&start, char_offset); stream->priv->bytes_partial += written; read = written; } else { /* First just copy the bytes without the newline */ memcpy (outbuf, buf, bytes); /* Then add the newline, but not for the last line */ if (!is_last) { memcpy (outbuf + bytes, newline, newline_size); } start = next; stream->priv->bytes_partial = 0; read = bytes_to_write; } gtk_text_buffer_move_mark (stream->priv->buffer, stream->priv->pos, &start); g_free (buf); return read; }
/* This function is taken and adapted from gtk+/tests/testtext.c */ static LinesInfo * get_lines_info (GtkTextView *text_view, gint first_y_buffer_coord, gint last_y_buffer_coord) { LinesInfo *info; GtkTextIter iter; gint last_line_num = -1; info = lines_info_new (); /* Get iter at first y */ gtk_text_view_get_line_at_y (text_view, &iter, first_y_buffer_coord, NULL); info->start = iter; /* For each iter, get its location and add it to the arrays. * Stop when we pass last_y_buffer_coord. */ while (!gtk_text_iter_is_end (&iter)) { gint y; gint height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_heights, height); info->total_height += height; line_num = gtk_text_iter_get_line (&iter); g_array_append_val (info->line_numbers, line_num); last_line_num = line_num; info->lines_count++; if (last_y_buffer_coord <= (y + height)) { break; } gtk_text_iter_forward_line (&iter); } if (gtk_text_iter_is_end (&iter)) { gint y; gint height; gint line_num; gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); line_num = gtk_text_iter_get_line (&iter); if (line_num != last_line_num) { g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_heights, height); info->total_height += height; g_array_append_val (info->line_numbers, line_num); info->lines_count++; } } if (info->lines_count == 0) { gint y = 0; gint n = 0; gint height; info->lines_count = 1; g_array_append_val (info->buffer_coords, y); g_array_append_val (info->line_numbers, n); gtk_text_view_get_line_yrange (text_view, &iter, &y, &height); g_array_append_val (info->line_heights, height); info->total_height += height; } info->end = iter; return info; }
/* Symmetric of _gtk_source_iter_forward_visible_word_end(). */ gboolean _gtk_source_iter_backward_visible_word_start (GtkTextIter *iter) { GtkTextIter orig = *iter; GtkTextIter farthest = *iter; GtkTextIter prev_word_start = *iter; GtkTextIter word_end; /* 'farthest' is the farthest position that this function can return. Example: * "aaaa ----|" -> "aaaa |----" */ _gtk_source_iter_backward_full_word_start (&farthest); /* Go to the previous extra-natural word start. It can be farther than * 'farthest': * "aaaa ----|" -> "|aaaa ----" * * Or it can remain at the same place: * "---- |aaaa" -> "---- |aaaa" */ _gtk_source_iter_backward_extra_natural_word_start (&prev_word_start); if (gtk_text_iter_compare (&prev_word_start, &farthest) < 0 || gtk_text_iter_equal (iter, &prev_word_start)) { *iter = farthest; goto end; } /* From 'prev_word_start', go to the next extra-natural word end. * * Example 1: * iter: "ab|cd" * prev_word_start: "|abcd" -> the good one * word_end: "abcd|" * * Example 2: * iter: "()abcd |" * prev_word_start: "()|abcd " -> the good one * word_end: "()abcd| " * * Example 3: * iter: "abcd()|" * prev_word_start: "|abcd()" * word_end: "abcd|()" -> the good one, at the start of the word "()". */ word_end = prev_word_start; _gtk_source_iter_forward_extra_natural_word_end (&word_end); /* Example 1 */ if (gtk_text_iter_compare (iter, &word_end) <= 0) { *iter = prev_word_start; } /* Example 2 */ else if (_gtk_source_iter_ends_full_word (&word_end)) { *iter = prev_word_start; } /* Example 3 */ else { *iter = word_end; } end: return !gtk_text_iter_equal (&orig, iter) && !gtk_text_iter_is_end (iter); }
static void set_check_range (GeditDocument *doc, GtkTextIter *start, GtkTextIter *end) { CheckRange *range; GtkTextIter iter; gedit_debug (DEBUG_PLUGINS); range = get_check_range (doc); if (range == NULL) { gedit_debug_message (DEBUG_PLUGINS, "There was not a previous check range"); gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); range = g_new0 (CheckRange, 1); range->start_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), "check_range_start_mark", &iter, TRUE); range->end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), "check_range_end_mark", &iter, FALSE); range->current_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), "check_range_current_mark", &iter, TRUE); g_object_set_qdata_full (G_OBJECT (doc), check_range_id, range, (GDestroyNotify)g_free); } if (gedit_spell_utils_skip_no_spell_check (start, end)) { if (!gtk_text_iter_inside_word (end)) { /* if we're neither inside a word, * we must be in some spaces. * skip backward to the end of the previous word. */ if (!gtk_text_iter_is_end (end)) { gtk_text_iter_backward_word_start (end); gtk_text_iter_forward_word_end (end); } } else { if (!gtk_text_iter_ends_word (end)) gtk_text_iter_forward_word_end (end); } } else { /* no spell checking in the specified range */ start = end; } gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->start_mark, start); gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->end_mark, end); range->mw_start = -1; range->mw_end = -1; update_current (doc, gtk_text_iter_get_offset (start)); }
static gboolean editor_application_window_key_press_event (GtkWidget *widget, GdkEventKey *event) { EditorApplicationWindow *window = EDITOR_APPLICATION_WINDOW (widget); if (event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_Tab) { GtkTextMark *mark; smie_gtk_source_buffer_context_t context; gint indent, current_indent; GtkTextIter iter, start_iter, end_iter; memset (&context, 0, sizeof (smie_gtk_source_buffer_context_t)); context.buffer = window->buffer; mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (window->buffer)); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (window->buffer), &iter, mark); gtk_text_iter_assign (&context.iter, &iter); indent = smie_indenter_calculate (window->indenter, &context); if (indent < 0) { g_printf ("indent: undetermined\n"); return TRUE; } else g_printf ("indent: %d\n", indent); /* Point START_ITER to the beginning of the line. */ gtk_text_iter_assign (&start_iter, &iter); while (!gtk_text_iter_is_start (&start_iter) && !gtk_text_iter_starts_line (&start_iter) && gtk_text_iter_backward_char (&start_iter)) ; /* Point END_ITER to the end of the indent and count the offset. */ gtk_text_iter_assign (&end_iter, &start_iter); current_indent = 0; while (!gtk_text_iter_is_end (&end_iter) && !gtk_text_iter_ends_line (&end_iter) && g_unichar_isspace (gtk_text_iter_get_char (&end_iter)) && gtk_text_iter_forward_char (&end_iter)) current_indent++; /* Replace the current indent if it doesn't match the computed one. */ if (indent < current_indent) { gtk_text_iter_forward_chars (&start_iter, indent); gtk_text_buffer_delete (GTK_TEXT_BUFFER (window->buffer), &start_iter, &end_iter); } else if (indent > current_indent) { gchar *text = g_new0 (gchar, indent - current_indent); memset (text, ' ', indent * sizeof (gchar)); gtk_text_buffer_insert (GTK_TEXT_BUFFER (window->buffer), &start_iter, text, indent - current_indent); g_free (text); } return TRUE; } return GTK_WIDGET_CLASS (editor_application_window_parent_class)->key_press_event (widget, event); }