/* * Search forward */ static gboolean editor_search_forward(const av_editor *editor, const gchar *text_search, GtkTextSearchFlags flags_search, const GtkTextIter *iter_start, const GtkTextIter *iter_end, GtkTextIter *iter_match_start, GtkTextIter *iter_match_end) { GtkTextIter m_start, m_end; gboolean found = FALSE; g_return_val_if_fail(editor != NULL && editor->textview != NULL && editor->textbuf != NULL, FALSE); g_return_val_if_fail(text_search != NULL, FALSE); g_return_val_if_fail(iter_start != NULL, FALSE); g_return_val_if_fail(iter_match_start != NULL && iter_match_end != NULL, FALSE); found = gtk_text_iter_forward_search(iter_start, text_search, flags_search, &m_start, &m_end, iter_end); if (found) { *iter_match_start = m_start; *iter_match_end = m_end; } return found; }
void cmdfind_clicked (GtkWidget *widget) { GtkTextIter start_iter, end_iter; GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view); const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry_text)); GtkTextSearchFlags flags = GTK_TEXT_SEARCH_TEXT_ONLY; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chkCase))) flags = flags | GTK_TEXT_SEARCH_CASE_INSENSITIVE; gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, 0); if (gtk_text_iter_forward_search (&start_iter, text, flags, &start_iter, &end_iter, NULL)) { gtk_text_buffer_select_range (buffer, &start_iter, &end_iter); gtk_text_view_scroll_to_iter (text_view, &start_iter, 0.1, FALSE, 0.5, 0.5); } else { //Status Bar show cannot find text } search_text = g_strdup (text); }
/****** 'text_tags' function *************************************************/ gint text_tags(GtkTextBuffer *buffer, const gchar *text) { GtkTextTag *tag; GtkTextIter start, match_end, match_start; gtk_text_buffer_get_iter_at_line_offset(buffer, &start, char_line, char_line_offset); if(gtk_text_iter_forward_search(&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE, &match_start, &match_end, NULL)) { tag = gtk_text_buffer_create_tag(buffer, NULL, "font", "italic 12", "weight", 650, "underline", PANGO_UNDERLINE_SINGLE, NULL); gtk_text_buffer_apply_tag(buffer, tag, &match_start, &match_end); char_line = gtk_text_iter_get_line(&match_end); char_line_offset = gtk_text_iter_get_line_offset(&match_end); return 0; } else { return -1; } }
static void search_text_changed (GtkEntry *entry) { ExampleAppWindow *win; ExampleAppWindowPrivate *priv; const gchar *text; GtkWidget *tab; GtkWidget *view; GtkTextBuffer *buffer; GtkTextIter start, match_start, match_end; text = gtk_entry_get_text (entry); if (text[0] == '\0') return; win = EXAMPLE_APP_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (entry))); priv = example_app_window_get_instance_private (win); tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack)); view = gtk_bin_get_child (GTK_BIN (tab)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); /* Very simple-minded search implementation */ gtk_text_buffer_get_start_iter (buffer, &start); if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE, &match_start, &match_end, NULL)) { gtk_text_buffer_select_range (buffer, &match_start, &match_end); gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start, 0.0, FALSE, 0.0, 0.0); } }
gboolean key_pressed(GtkWidget * window, GdkEventKey* event, GtkTextBuffer *buffer) { GtkTextIter start_sel, end_sel; GtkTextIter start_find, end_find; GtkTextIter start_match, end_match; gboolean selected; gchar *text; if ((event->type == GDK_KEY_PRESS) && (event->state & GDK_CONTROL_MASK)) { switch (event->keyval) { case GDK_m : selected = gtk_text_buffer_get_selection_bounds(buffer, &start_sel, &end_sel); if (selected) { gtk_text_buffer_get_start_iter(buffer, &start_find); gtk_text_buffer_get_end_iter(buffer, &end_find); gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg", &start_find, &end_find); text = (char *) gtk_text_buffer_get_text(buffer, &start_sel, &end_sel, FALSE); while ( gtk_text_iter_forward_search(&start_find, text, GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_VISIBLE_ONLY, &start_match, &end_match, NULL) ) { gtk_text_buffer_apply_tag_by_name(buffer, "gray_bg", &start_match, &end_match); int offset = gtk_text_iter_get_offset(&end_match); gtk_text_buffer_get_iter_at_offset(buffer, &start_find, offset); } g_free(text); } break; case GDK_r: gtk_text_buffer_get_start_iter(buffer, &start_find); gtk_text_buffer_get_end_iter(buffer, &end_find); gtk_text_buffer_remove_tag_by_name(buffer, "gray_bg", &start_find, &end_find); break; } } return FALSE; }
static void chat_text_view_highlight (EmpathyChatView *view, const gchar *text, gboolean match_case) { GtkTextBuffer *buffer; GtkTextIter iter; GtkTextIter iter_start; GtkTextIter iter_end; GtkTextIter iter_match_start; GtkTextIter iter_match_end; gboolean found; g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); gtk_text_buffer_get_start_iter (buffer, &iter); gtk_text_buffer_get_bounds (buffer, &iter_start, &iter_end); gtk_text_buffer_remove_tag_by_name (buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT, &iter_start, &iter_end); if (EMP_STR_EMPTY (text)) { return; } while (1) { if (match_case) { found = gtk_text_iter_forward_search (&iter, text, 0, &iter_match_start, &iter_match_end, NULL); } else { found = empathy_text_iter_forward_search (&iter, text, &iter_match_start, &iter_match_end, NULL); } if (!found) { break; } gtk_text_buffer_apply_tag_by_name (buffer, EMPATHY_CHAT_TEXT_VIEW_TAG_HIGHLIGHT, &iter_match_start, &iter_match_end); iter = iter_match_end; } }
static VALUE rg_forward_search(int argc, VALUE *argv, VALUE self) { GtkTextIter m_start, m_end; VALUE str, flags, limit; gboolean ret; rb_scan_args(argc, argv, "21", &str, &flags, &limit); if (is_compat_240){ ret = gtk_text_iter_forward_search(_SELF(self), RVAL2CSTR(str), RVAL2GFLAGS(flags, GTK_TYPE_TEXT_SEARCH_FLAGS), &m_start, &m_end, NIL_P(limit) ? NULL : _SELF(limit)); } else { ret = gtk_text_iter_forward_search(_SELF(self), RVAL2CSTR(str), RVAL2GENUM(flags, GTK_TYPE_TEXT_SEARCH_FLAGS), &m_start, &m_end, NIL_P(limit) ? NULL : _SELF(limit)); } return ret ? rb_ary_new3(2, ITR2RVAL(&m_start), ITR2RVAL(&m_end)) : Qnil; }
static gboolean search_elem_locate(GtkTextBuffer* buf, gint* pline, gint* poffset, CppElem* elem) { GtkTextIter iter; GtkTextIter limit; GtkTextIter ps; GtkTextIter pe; guint ch; gboolean full_matched; gboolean need_move_cursor; *pline = elem->sline - 1; *poffset = -1; gtk_text_buffer_get_iter_at_line(buf, &iter, *pline); limit = iter; gtk_text_iter_forward_to_line_end(&limit); need_move_cursor = TRUE; full_matched = FALSE; while( gtk_text_iter_forward_search(&iter, elem->name->buf, 0, &ps, &pe, &limit) ) { *poffset = gtk_text_iter_get_line_offset(&pe); gtk_text_buffer_select_range(buf, &pe, &ps); need_move_cursor = FALSE; if( gtk_text_iter_starts_line(&ps) ) { full_matched = TRUE; } else { iter = ps; gtk_text_iter_backward_char(&iter); ch = gtk_text_iter_get_char(&iter); if( !g_unichar_isalnum(ch) && ch!='_' ) full_matched = TRUE; } if( full_matched && !gtk_text_iter_ends_line(&pe) ) { iter = pe; gtk_text_iter_forward_char(&iter); ch = gtk_text_iter_get_char(&iter); if( g_unichar_isalnum(ch) || ch=='_' ) full_matched = FALSE; } if( full_matched ) break; iter = ps; gtk_text_iter_forward_char(&iter); } return need_move_cursor; }
void replace (GtkTextView *text_view, const gchar *text, const gchar *text1, GtkTextIter *iter) { GtkTextIter mstart, mend; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); gboolean found; found = gtk_text_iter_forward_search (iter, text, 0, &mstart, &mend, NULL); if (found) { gtk_text_buffer_select_range(buffer, &mstart, &mend); gtk_text_buffer_create_mark(buffer, "last_pos", &mend, FALSE); int len = strlen(text1); gtk_text_buffer_delete(buffer, &mstart, &mend); gtk_text_buffer_insert(buffer, &mstart, text1, len); } }
void search_btn_clicked(GtkWidget *wid,gpointer data){ SearchBox *search = (SearchBox*) data; gchar const *txt_to_find; txt_to_find = gtk_entry_get_text(GTK_ENTRY(search->find_entry)); if(gtk_text_iter_forward_search (&iStart, (gchar*)txt_to_find ,0,&iBegin, &iEnd, NULL)){ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(search->app->editor->source_view),&iStart,0,TRUE,0.5,0.5); gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER(search->app->editor->buffer),&iBegin); gtk_text_buffer_select_range (GTK_TEXT_BUFFER(search->app->editor->buffer),&iBegin,&iEnd); iStart = iEnd; isFound = TRUE; }else{ gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(search->app->editor->buffer),&iStart); isFound = FALSE; } }
static void on_find_clicked (GtkButton *button, Widgets *w) { g_return_if_fail (GTK_IS_TEXT_VIEW(w->textview)); g_return_if_fail (GTK_IS_ENTRY(w->entry)); GtkTextBuffer *buffer; GtkTextIter iter = {0,}; GtkTextIter start = {0,}; GtkTextIter end = {0,}; gboolean found = FALSE; const gchar *find; gchar *output; buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(w->textview)); /* * Let's check whether there is something to search for. */ if (0 == gtk_entry_get_text_length (GTK_ENTRY(w->entry))) { return; } find = gtk_entry_get_text (GTK_ENTRY(w->entry)); gtk_text_buffer_get_start_iter (buffer, &iter); /* * Will only find first match, if not looped over. * TODO: Find every match, indicate if no match was found. */ found = gtk_text_iter_forward_search (&iter, find, GTK_TEXT_SEARCH_TEXT_ONLY, &start, &end, NULL); /* * The start and end iterators may only be valid if * gtk_text_iter_forward_search() returned successfully! Remember that you * have no control ("opaque") over iterators whatsoever. */ if (found) { output = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); create_message_dialog(w, "Text found", output); } }
static void gbp_spell_navigator_change_all (GspellNavigator *navigator, const gchar *word, const gchar *change_to) { GbpSpellNavigator *self = (GbpSpellNavigator *)navigator; GtkTextIter iter; g_assert (GBP_IS_SPELL_NAVIGATOR (self)); g_assert (GTK_IS_TEXT_MARK (self->start_boundary)); g_assert (GTK_IS_TEXT_MARK (self->end_boundary)); gtk_text_buffer_get_iter_at_mark (self->buffer, &iter, self->start_boundary); gtk_text_buffer_begin_user_action (self->buffer); while (TRUE) { gboolean found; GtkTextIter match_start; GtkTextIter match_end; GtkTextIter limit; gtk_text_buffer_get_iter_at_mark (self->buffer, &limit, self->end_boundary); found = gtk_text_iter_forward_search (&iter, word, GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, &limit); if (!found) break; if (gbp_spell_utils_text_iter_starts_word (&match_start) && gbp_spell_utils_text_iter_ends_word (&match_end)) { gtk_text_buffer_delete (self->buffer, &match_start, &match_end); gtk_text_buffer_insert (self->buffer, &match_end, change_to, -1); } iter = match_end; } gtk_text_buffer_end_user_action (self->buffer); }
/* Extends the definition of a natural-language word used by Pango. The * underscore is added to the possible characters of a natural-language word. */ void _gtk_source_iter_forward_extra_natural_word_end (GtkTextIter *iter) { GtkTextIter next_word_end = *iter; GtkTextIter next_underscore_end = *iter; GtkTextIter *limit = NULL; gboolean found; if (gtk_text_iter_forward_visible_word_end (&next_word_end)) { limit = &next_word_end; } found = gtk_text_iter_forward_search (iter, "_", GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &next_underscore_end, limit); if (found) { *iter = next_underscore_end; } else { *iter = next_word_end; } while (TRUE) { if (gtk_text_iter_get_char (iter) == '_') { gtk_text_iter_forward_visible_cursor_position (iter); } else if (gtk_text_iter_starts_word (iter)) { gtk_text_iter_forward_visible_word_end (iter); } else { break; } } }
static void help_window_scroll(GtkWidget *text, const gchar *key) { gchar *needle; GtkTextBuffer *buffer; GtkTextIter iter; GtkTextIter start, end; if (!text || !key) return; needle = g_strdup_printf("[section:%s]", key); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); if (gtk_text_iter_forward_search(&iter, needle, GTK_TEXT_SEARCH_TEXT_ONLY, &start, &end, NULL)) { gint line; GtkTextMark *mark; line = gtk_text_iter_get_line(&start); gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, line, 0); gtk_text_buffer_place_cursor(buffer, &iter); #if 0 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(text), &iter, 0.0, TRUE, 0, 0); #endif /* apparently only scroll_to_mark works when the textview is not visible yet */ /* if mark exists, move it instead of creating one for every scroll */ mark = gtk_text_buffer_get_mark(buffer, SCROLL_MARKNAME); if (mark) { gtk_text_buffer_move_mark(buffer, mark, &iter); } else { mark = gtk_text_buffer_create_mark(buffer, SCROLL_MARKNAME, &iter, FALSE); } gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(text), mark, 0.0, TRUE, 0, 0); } g_free(needle); }
void goto_local_label (const gchar *l) { gchar *t = g_utf8_find_next_char (l, NULL); gchar *s = g_strconcat ("<a name=\"", t, NULL); GtkTextIter iter; GtkTextIter match_start; GtkTextMark *m = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(cur_text_doc->text_buffer)); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER(cur_text_doc->text_buffer), &iter, m); if (gtk_text_iter_forward_search (&iter, s, GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, NULL, NULL)) { gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER(cur_text_doc->text_buffer), &match_start ); gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW(cur_text_doc->text_view), &match_start, 0.0, TRUE, 0.0, 0.0 ); gtk_text_view_place_cursor_onscreen (GTK_TEXT_VIEW (cur_text_doc->text_view)); } g_free (s); }
static gboolean text_iter_in_cdata (const GtkTextIter *location) { GtkTextIter iter = *location; gboolean ret = FALSE; if (gtk_text_iter_backward_search (&iter, "<![CDATA[", GTK_TEXT_SEARCH_TEXT_ONLY, NULL, &iter, NULL)) { if (!gtk_text_iter_forward_search (&iter, "]]>", GTK_TEXT_SEARCH_TEXT_ONLY, NULL, NULL, location)) { ret = TRUE; IDE_GOTO (cleanup); } } cleanup: return ret; }
void find (GtkTextView *text_view, const gchar *text, GtkTextIter *iter) { GtkTextIter mstart, mend; GtkTextBuffer *buffer; GtkTextMark *last_pos; gboolean found; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); found = gtk_text_iter_forward_search(iter, text, 0, &mstart, &mend, NULL); last_pos = gtk_text_buffer_get_mark(buffer, "last_pos"); if (found) { gtk_text_buffer_select_range(buffer, &mstart, &mend); if (last_pos) gtk_text_buffer_move_mark(buffer, last_pos, &mend); else gtk_text_buffer_create_mark(buffer, "last_pos", &mend, FALSE); } else { if (last_pos) gtk_text_buffer_delete_mark(buffer, last_pos); // Not found } }
static void remove_tag_to_word (GeditAutomaticSpellChecker *spell, const gchar *word) { GtkTextIter iter; GtkTextIter match_start, match_end; gboolean found; gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (spell->doc), &iter, 0); found = TRUE; while (found) { found = gtk_text_iter_forward_search (&iter, word, GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL); if (found) { if (gtk_text_iter_starts_word (&match_start) && gtk_text_iter_ends_word (&match_end)) { gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, &match_start, &match_end); } iter = match_end; } } }
int main (int argc, char *argv[]) { GtkSourceBuffer *buffer; GtkSourceSearchContext *search_context; GtkSourceSearchSettings *search_settings; GtkTextIter iter; GtkTextIter match_end; GTimer *timer; gint i; GtkTextSearchFlags flags; gchar *regex_pattern; gtk_init (&argc, &argv); buffer = gtk_source_buffer_new (NULL); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); for (i = 0; i < NB_LINES; i++) { gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, "A line of text to fill the text buffer. Is it long enough?\n", -1); } gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, "foo\n", -1); /* Basic search, no flags */ timer = g_timer_new (); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); flags = 0; while (gtk_text_iter_forward_search (&iter, "foo", flags, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("basic forward search, no flags: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Basic search, with flags always enabled by gsv */ g_timer_start (timer); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY; while (gtk_text_iter_forward_search (&iter, "foo", flags, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("basic forward search, visible and text only flags: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Basic search, with default flags in gsv */ g_timer_start (timer); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); flags = GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY | GTK_TEXT_SEARCH_CASE_INSENSITIVE; while (gtk_text_iter_forward_search (&iter, "foo", flags, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("basic forward search, all flags: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Smart forward search, with default flags in gsv */ search_settings = gtk_source_search_settings_new (); search_context = gtk_source_search_context_new (buffer, search_settings); g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("smart synchronous forward search, case insensitive: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Smart forward search, case sensitive */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, NULL); gtk_source_search_settings_set_case_sensitive (search_settings, TRUE); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("smart synchronous forward search, case sensitive: %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search "foo" */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, NULL); gtk_source_search_settings_set_regex_enabled (search_settings, TRUE); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: 'foo' (no partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search "fill" */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, "fill"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: 'fill' (no partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search single lines */ g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, ".*"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: match single lines (no partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search matches of 3 lines */ g_timer_start (timer); /* The space at the beginning of the pattern permits to not have contiguous * matches. There is a performance issue with contiguous matches. */ gtk_source_search_settings_set_search_text (search_settings, " (.*\n){3}"); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: matches of 3 lines (small partial matches): %lf seconds.\n", g_timer_elapsed (timer, NULL)); /* Regex search: search matches of really big chunks */ g_timer_start (timer); regex_pattern = g_strdup_printf (" (.*\n){%d}", NB_LINES / 10); gtk_source_search_settings_set_search_text (search_settings, regex_pattern); g_free (regex_pattern); gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter); while (gtk_source_search_context_forward (search_context, &iter, NULL, &match_end, NULL)) { iter = match_end; } g_timer_stop (timer); g_print ("regex search: 10 matches of %d lines (big partial matches): %lf seconds.\n", NB_LINES / 10, g_timer_elapsed (timer, NULL)); /* Smart search, case sensitive, asynchronous */ /* The asynchronous overhead doesn't depend on the search flags, it * depends on the maximum number of lines to scan in one batch, and * (obviously), on the buffer size. * You can tune SCAN_BATCH_SIZE in gtksourcesearchcontext.c to see a * difference in the overhead. */ g_signal_connect (search_context, "notify::occurrences-count", G_CALLBACK (on_notify_search_occurrences_count_cb), timer); g_timer_start (timer); gtk_source_search_settings_set_search_text (search_settings, NULL); gtk_source_search_settings_set_regex_enabled (search_settings, FALSE); gtk_source_search_settings_set_search_text (search_settings, "foo"); gtk_main (); return 0; }
/********** 'set_chord_position' function ************************************/ gint set_chord_position(GtkWidget *t_view, GtkTextBuffer *buffer) { GtkTextTag *tag; GtkTextMark *end_chord, *start_chord; GtkTextIter ch, chord_S, chord_E, match_end, match_start, start_of_line; GtkClipboard *clipboard; gint line_num_1, line_num_2, line_count_V, line_offset_1, line_offset_2; line_count_V = gtk_text_buffer_get_line_count(buffer); clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); gtk_text_buffer_get_start_iter(buffer, &start_of_line); if(gtk_text_iter_forward_search(&start_of_line, "[", 1, &match_start, &match_end, NULL)) { gtk_text_buffer_create_mark(buffer, "start_chord", &match_start, FALSE); start_chord = gtk_text_buffer_get_mark(buffer, "start_chord"); } else { return -1; } if(gtk_text_iter_forward_search(&start_of_line, "]", 1, &match_start, &match_end, NULL)) { gtk_text_buffer_create_mark(buffer, "end_chord", &match_end, FALSE); end_chord = gtk_text_buffer_get_mark(buffer, "end_chord"); } else { return -1; } // Initializes iters at mark. gtk_text_buffer_get_iter_at_mark(buffer, &chord_S, start_chord); gtk_text_buffer_get_iter_at_mark(buffer, &chord_E, end_chord); // Get line and line offset of iter. If we just obtain the offset // within buffer then chord_S will not format as desired. line_num_1 = gtk_text_iter_get_line(&chord_S); line_offset_1 = gtk_text_iter_get_line_index(&chord_S); line_num_2 = gtk_text_iter_get_line(&chord_E); line_offset_2 = gtk_text_iter_get_line_index(&chord_E); // This returns with error if end bracket does not have a // matching start bracket. if(line_offset_1 > line_offset_2) { return -1; } //g_print("Lineoffset of start:end bracket:\n%d\n%d\n", line_offset_1, line_offset_2); // If chord found is found more than two lines down // refresh global values of 'line_count_C' and 'line_num_C'. if(line_num_1 > (line_num_C + 1)) { line_num_C = line_num_1; line_count_C = line_count_V; } // Copy, cut, and add tags to the section between the marks. gtk_text_buffer_select_range(buffer, &chord_S, &chord_E); tag = gtk_text_buffer_create_tag(buffer, NULL, "background", "gold", "weight", "500", "foreground-gdk", "black3", NULL); gtk_text_buffer_apply_tag(buffer, tag, &chord_S, &chord_E); gtk_text_buffer_cut_clipboard(buffer, clipboard, TRUE); // This finds first chord of line. if(line_count_V == line_count_C) { gtk_text_buffer_get_iter_at_line(buffer, &start_of_line, line_num_1); gtk_text_buffer_insert(buffer, &start_of_line, "\n", -1); } // This finds the rest of the chord_S on the same line as the first. if(line_num_1 == (line_num_C + 1)) { line_num_1 = line_num_1 - 1; line_num_2 = line_num_2 - 1; } gtk_text_buffer_get_iter_at_line(buffer, &ch, line_num_1); // Insert 110 blank spaces so we can insert chord_S at higher offsets than 0. // GtkTextBuffer does not allow us to insert past a newline character // so we move it with spaces to allow us to place chord_S at offsets // past a newline character. if(gtk_text_iter_get_char(&ch) == '\n') { gtk_text_buffer_insert(buffer, &ch, " ", -1); } // Place iter at the same offset one line above. gtk_text_buffer_get_iter_at_line_index(buffer, &ch, line_num_1, line_offset_1); //g_print("Position after cut: %d\n", line_offset_1); gtk_text_buffer_paste_clipboard(buffer, clipboard, &ch, TRUE); gtk_text_buffer_get_iter_at_line_offset(buffer, &ch, line_num_1, line_offset_2); // Deletes the end bracket. gtk_text_buffer_backspace(buffer, &ch, FALSE, TRUE); gtk_text_buffer_get_iter_at_line_offset(buffer, &ch, line_num_1, line_offset_1 +1); // Deletes the start bracket. gtk_text_buffer_backspace(buffer, &ch, FALSE, TRUE); gtk_text_buffer_delete_mark_by_name(buffer, "start_chord"); gtk_text_buffer_delete_mark_by_name(buffer, "end_chord"); return 0; }
/****** 'display function' ***************************************************/ void display(GtkTextBuffer *buffer, GtkWidget *t_view) { GtkTextTag *tag; GtkTextIter end, start, match_end, match_start; gint i, j; gchar *key, *body, *title, *artist; const gchar *song_section[] = {"Verse:", "Verse 1", "Verse 2:", "Verse 3:","Bridge:", "Bridge 1:", "Bridge 2:", "Bridge 3:", "Intro:", "End:", "PreChorus:", "Verso:", "Chorus:", "Coro:", "Puente:", "Key Shift:", "Instrumental:", "Chorus 1:", "Chorus 2:", "Chorus 3:", "Verso 1:", "Verso 2:", "Verso 3:", "Tag:"}; //----------------------------------------------------------------------------- gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_delete(buffer, &start, &end); gtk_text_view_set_editable(GTK_TEXT_VIEW(t_view), FALSE); //----------------------------------------------------------------------------- // Sets attributes for Title (line 0). title = gtk_editable_get_chars(GTK_EDITABLE(entry_title), 0, -1); gtk_text_buffer_get_iter_at_line(buffer, &start, 0); gtk_text_buffer_place_cursor(buffer, &start); gtk_text_buffer_insert_at_cursor(buffer, title, -1); g_free(title); gtk_text_buffer_get_iter_at_line(buffer, &start, 0); gtk_text_buffer_get_iter_at_line(buffer, &end, 0); gtk_text_iter_forward_to_line_end(&end); tag = gtk_text_buffer_create_tag(buffer, NULL, "weight", 1000, "font", "monospace 30", "underline", PANGO_UNDERLINE_SINGLE, NULL); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); //----------------------------------------------------------------------------- // Inserts text 'by:' before artist with attributes. tag = gtk_text_buffer_create_tag(buffer, NULL, "font", "monospace 10", "weight-set", TRUE, "weight", 650, NULL); gtk_text_buffer_get_iter_at_line(buffer, &start, 0); gtk_text_iter_forward_to_line_end(&start); gtk_text_buffer_place_cursor(buffer, &start); // Have to insert '\n' to create next line gtk_text_buffer_insert_at_cursor(buffer, "\n", -1); gtk_text_buffer_get_iter_at_line(buffer, &start, 1); gtk_text_buffer_place_cursor(buffer, &start); gtk_text_buffer_insert_at_cursor(buffer, "Artist: ", -1); gtk_text_buffer_get_iter_at_line(buffer, &start, 1); gtk_text_buffer_get_iter_at_line(buffer, &end, 1); gtk_text_iter_forward_to_line_end(&end); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); //----------------------------------------------------------------------------- artist = gtk_editable_get_chars(GTK_EDITABLE(entry_artist), 0, -1); gtk_text_buffer_get_iter_at_line_offset(buffer, &start, 1, 8); gtk_text_buffer_place_cursor(buffer, &start); gtk_text_buffer_insert_at_cursor(buffer, artist, -1); g_free(artist); // Sets attributes for Artist (line 1). gtk_text_buffer_get_iter_at_line_offset(buffer, &start, 1, 8); gtk_text_buffer_get_iter_at_line(buffer, &end, 1); gtk_text_iter_forward_to_line_end(&end); tag = gtk_text_buffer_create_tag(buffer, NULL, "weight", 500, "weight-set", TRUE, "font", "monospace italic 12", NULL); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); //----------------------------------------------------------------------------- tag = gtk_text_buffer_create_tag(buffer, NULL, "font", "monospace 10", "weight", 650, NULL); gtk_text_buffer_get_iter_at_line(buffer, &start, 1); gtk_text_iter_forward_to_line_end(&start); gtk_text_buffer_place_cursor(buffer, &start); // Have to insert '\n' to create next line gtk_text_buffer_insert_at_cursor(buffer, "\n", -1); gtk_text_buffer_get_iter_at_line(buffer, &start, 2); gtk_text_buffer_place_cursor(buffer, &start); gtk_text_buffer_insert_at_cursor(buffer, "Key: ", -1); gtk_text_buffer_get_iter_at_line(buffer, &start, 2); gtk_text_buffer_get_iter_at_line(buffer, &end, 2); gtk_text_iter_forward_to_line_end(&end); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); //----------------------------------------------------------------------------- key = gtk_editable_get_chars(GTK_EDITABLE(entry_key), 0, -1); gtk_text_buffer_get_iter_at_line_offset(buffer, &start, 2, 5); gtk_text_buffer_place_cursor(buffer, &start); gtk_text_buffer_insert_at_cursor(buffer, key, -1); g_free(key); gtk_text_buffer_get_iter_at_line_offset(buffer, &start, 2, 5); gtk_text_buffer_get_iter_at_line(buffer, &end, 2); gtk_text_iter_forward_to_line_end(&end); tag = gtk_text_buffer_create_tag(buffer, NULL, "weight", 500, "weight-set", TRUE, "font", "monospace italic 12", NULL); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); //----------------------------------------------------------------------------- gtk_text_buffer_get_iter_at_line(buffer, &start, 2); gtk_text_iter_forward_to_line_end(&start); gtk_text_buffer_place_cursor(buffer, &start); // Have to insert '\n' to create next line gtk_text_buffer_insert_at_cursor(buffer, "\n\n", -1); gtk_text_buffer_get_start_iter(t_buffer_editor, &start); gtk_text_buffer_get_end_iter(t_buffer_editor, &end); body = gtk_text_buffer_get_text(t_buffer_editor, &start, &end, FALSE); gtk_text_buffer_get_iter_at_line(buffer, &start, 4); gtk_text_buffer_place_cursor(buffer, &start); gtk_text_buffer_insert_at_cursor(buffer, body, -1); //----------------------------------------------------------------------------- gtk_text_buffer_get_iter_at_line(buffer, &start, 4); gtk_text_buffer_get_end_iter(buffer, &end); tag = gtk_text_buffer_create_tag(buffer, NULL, "font", "monospace", NULL); gtk_text_buffer_apply_tag(buffer, tag, &start, &end); line_count_C = gtk_text_buffer_get_line_count(buffer); gtk_text_buffer_get_start_iter(buffer, &start); if(gtk_text_iter_forward_search(&start, "[", 1, &match_start, &match_end, NULL)) { line_num_C = gtk_text_iter_get_line(&match_start); } for(i = 0; i == 0;) { i = set_chord_position(t_view, buffer); } //----------------------------------------------------------------------------- // This section is for setting the attributes of the text // 'Verse:', 'Chorus:'etc... char_line = 0; char_line_offset = 0; for(i = 0; i < 24;) { for(j = 0; j == 0;) { j = text_tags(buffer, song_section[i]); } if(j != 0) { char_line = 0; char_line_offset = 0; i++; } } //----------------------------------------------------------------------------- //g_print("Function return: %d\n", set_chord_position(t_view, buffer)); //g_print("Line number of chord: %d\n", line_num_C);*/ }
void my_text_buffer_highlight(GtkTextBuffer *buffer, char *word, short mode) { /*mode: 0:title/occurance 1:title 2:keyword, 3:invisible 4:highlight 5:normal others:normal*/ gboolean found = TRUE, titled = FALSE; GtkTextTag *tag = occurance; gtk_text_buffer_get_iter_at_offset(text2, &start, 0); current = start; end = start; #ifdef MinGW int zhTitle = 0; int isTitle = 0; #endif while(found) { found = gtk_text_iter_forward_search( &end, word, GTK_TEXT_SEARCH_VISIBLE_ONLY, ¤t, &end, NULL); if(found) { #ifdef MinGW /*check zh char*/ char *sample = gtk_text_iter_get_slice (¤t, &end); int sampleLen = strlen(sample); if( testZh(sample, sampleLen)) zhTitle = 1; #endif /*title or body*/ if(1== mode || (0 == mode && !titled && 0 == gtk_text_iter_get_line(¤t))) { #ifdef MinGW isTitle = 1; #endif tag = title; titled = TRUE; } else if( 0 == mode ) { tag = occurance; } else if( 2 == mode) { #ifdef MinGW /*keyword, pretend title to use better font*/ isTitle = 1; #endif tag = keyword; } else if( 3 == mode) { tag = invisible; #ifdef MinGW zhTitle = 0; isTitle = 0; #endif } else if( 4 == mode) { tag = highlight; } else if( 5 == mode) { tag = normal; /* will do remove-tag after extending to full word */ } else { tag = normal; #ifdef MinGW zhTitle = 0; isTitle = 0; #endif } /*extend word*/ if( 2 != mode && 3 != mode && !gtk_text_iter_starts_word(¤t)) { gtk_text_iter_backward_visible_word_start(¤t); } if(2 != mode && 3 != mode && !gtk_text_iter_ends_word(&end)) { gtk_text_iter_forward_visible_word_end(&end); } if (5 == mode) { gtk_text_buffer_remove_tag (buffer, highlight, ¤t, &end); } #ifdef MinGW /*Clear default_font to allow better font only when no zh chars present*/ if( !zhTitle && isTitle ) gtk_text_buffer_remove_tag (buffer, default_font, ¤t, &end); #endif gtk_text_buffer_apply_tag(buffer, tag, ¤t, &end); } } current = start; end = start; }
/** * gtk_source_iter_forward_search: * @iter: start of search. * @str: a search string. * @flags: flags affecting how the search is done. * @match_start: return location for start of match, or %%NULL. * @match_end: return location for end of match, or %%NULL. * @limit: bound for the search, or %%NULL for the end of the buffer. * * Searches forward for @str. Any match is returned by setting * @match_start to the first character of the match and @match_end to the * first character after the match. The search will not continue past * @limit. Note that a search is a linear or O(n) operation, so you * may wish to use @limit to avoid locking up your UI on large * buffers. * * If the #GTK_SOURCE_SEARCH_VISIBLE_ONLY flag is present, the match may * have invisible text interspersed in @str. i.e. @str will be a * possibly-noncontiguous subsequence of the matched range. similarly, * if you specify #GTK_SOURCE_SEARCH_TEXT_ONLY, the match may have * pixbufs or child widgets mixed inside the matched range. If these * flags are not given, the match must be exact; the special 0xFFFC * character in @str will match embedded pixbufs or child widgets. * If you specify the #GTK_SOURCE_SEARCH_CASE_INSENSITIVE flag, the text will * be matched regardless of what case it is in. * * Same as gtk_text_iter_forward_search(), but supports case insensitive * searching. * * Return value: whether a match was found. **/ gboolean gtk_source_iter_forward_search (const GtkTextIter *iter, const gchar *str, GtkSourceSearchFlags flags, GtkTextIter *match_start, GtkTextIter *match_end, const GtkTextIter *limit) { gchar **lines = NULL; GtkTextIter match; gboolean retval = FALSE; GtkTextIter search; gboolean visible_only; gboolean slice; g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (str != NULL, FALSE); if ((flags & GTK_SOURCE_SEARCH_CASE_INSENSITIVE) == 0) return gtk_text_iter_forward_search (iter, str, flags, match_start, match_end, limit); if (limit && gtk_text_iter_compare (iter, limit) >= 0) return FALSE; if (*str == '\0') { /* If we can move one char, return the empty string there */ match = *iter; if (gtk_text_iter_forward_char (&match)) { if (limit && gtk_text_iter_equal (&match, limit)) return FALSE; if (match_start) *match_start = match; if (match_end) *match_end = match; return TRUE; } else { return FALSE; } } visible_only = (flags & GTK_SOURCE_SEARCH_VISIBLE_ONLY) != 0; slice = (flags & GTK_SOURCE_SEARCH_TEXT_ONLY) == 0; /* locate all lines */ lines = strbreakup (str, "\n", -1); search = *iter; do { /* This loop has an inefficient worst-case, where * gtk_text_iter_get_text () is called repeatedly on * a single line. */ GtkTextIter end; if (limit && gtk_text_iter_compare (&search, limit) >= 0) break; if (lines_match (&search, (const gchar**)lines, visible_only, slice, &match, &end)) { if (limit == NULL || (limit && gtk_text_iter_compare (&end, limit) <= 0)) { retval = TRUE; if (match_start) *match_start = match; if (match_end) *match_end = end; } break; } } while (gtk_text_iter_forward_line (&search)); g_strfreev ((gchar**)lines); return retval; }
static GtkSnippetsGtvVar* search_var(GtkSnippetsInPlaceParser *self, GtkTextBuffer *buffer,GtkTextMark *init_mark, GtkTextMark *limit_mark) { GtkSnippetsGtvVar *var = NULL; GtkTextMark *start_mark, *end_mark, *temp_mark; gchar *definition; const gchar *default_value; GtkTextIter start, end, temp_iter; GtkTextIter pos, limit; GError *error = NULL; gtk_text_buffer_get_iter_at_mark(buffer,&pos, init_mark); gtk_text_buffer_get_iter_at_mark(buffer,&limit, limit_mark); gboolean found = gtk_text_iter_forward_search(&pos, "${", GTK_TEXT_SEARCH_VISIBLE_ONLY, &start, NULL, &limit); if (found) { temp_iter = start; gtk_text_iter_forward_to_line_end(&temp_iter); found = gtk_text_iter_forward_search(&start, "}", GTK_TEXT_SEARCH_VISIBLE_ONLY, &end, NULL, &temp_iter); if (found) { gtk_text_iter_forward_char(&end); start_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE); end_mark = gtk_text_buffer_create_mark(buffer, NULL, &end, FALSE); gtk_text_iter_forward_chars(&start,2); gtk_text_iter_forward_chars(&end,-1); definition = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); var = gtksnippets_gtv_var_new(definition, self->priv->view, start_mark, end_mark, VAR_TAG_NAME, VAR_ERROR_TAG_NAME); g_free(definition); default_value = gsnippets_variable_get_default_value(GSNIPPETS_VARIABLE(var)); if (default_value==NULL) default_value = gsnippets_variable_get_name(GSNIPPETS_VARIABLE(var)); gtk_text_buffer_begin_user_action(buffer); gtksnippets_gtv_var_set_text(var, default_value, &error); gtk_text_buffer_end_user_action(buffer); if (error != NULL) { g_warning("Error parsing variable: %s",error->message); g_error_free(error); } } else { /* If there is ${ but not } in the line, we must to search a new variable because if we return NULL, it is the end of the search */ gtk_text_iter_forward_chars(&start,2); temp_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE); gtk_text_buffer_move_mark(buffer,temp_mark,&start); var = search_var(self,buffer,temp_mark,limit_mark); gtk_text_buffer_delete_mark(buffer,temp_mark); } } return var; }
static void chat_text_view_find_abilities (EmpathyChatView *view, const gchar *search_criteria, gboolean match_case, gboolean *can_do_previous, gboolean *can_do_next) { EmpathyChatTextViewPriv *priv; GtkTextBuffer *buffer; GtkTextIter iter_at_mark; GtkTextIter iter_match_start; GtkTextIter iter_match_end; g_return_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view)); g_return_if_fail (search_criteria != NULL); g_return_if_fail (can_do_previous != NULL && can_do_next != NULL); priv = GET_PRIV (view); buffer = priv->buffer; if (can_do_previous) { if (priv->find_mark_previous) { gtk_text_buffer_get_iter_at_mark (buffer, &iter_at_mark, priv->find_mark_previous); } else { gtk_text_buffer_get_start_iter (buffer, &iter_at_mark); } if (match_case) { *can_do_previous = gtk_text_iter_backward_search (&iter_at_mark, search_criteria, 0, &iter_match_start, &iter_match_end, NULL); } else { *can_do_previous = empathy_text_iter_backward_search (&iter_at_mark, search_criteria, &iter_match_start, &iter_match_end, NULL); } } if (can_do_next) { if (priv->find_mark_next) { gtk_text_buffer_get_iter_at_mark (buffer, &iter_at_mark, priv->find_mark_next); } else { gtk_text_buffer_get_start_iter (buffer, &iter_at_mark); } if (match_case) { *can_do_next = gtk_text_iter_forward_search (&iter_at_mark, search_criteria, 0, &iter_match_start, &iter_match_end, NULL); } else { *can_do_next = empathy_text_iter_forward_search (&iter_at_mark, search_criteria, &iter_match_start, &iter_match_end, NULL); } } }
/** @brief Search forward from @a iter to try to to find next match of @a str in textbuffer This is like gtk_text_iter_forward_search(), but supports case-insensitive and whole-word searching. Any match is returned by setting @a match_start to the first character of the match and @a match_end to the first character after the match. The search will not continue past @a limit. Note that a search is a linear or O(n) operation, so you may wish to use @a limit to avoid locking up your UI on large buffers. If the GTK_SOURCE_SEARCH_VISIBLE_ONLY flag is present, the match may have invisible text interspersed in @a str. i.e. @a str will be a possibly-noncontiguous subset of the matched range. Similarly, if you specify GTK_SOURCE_SEARCH_TEXT_ONLY, the match may have pixbufs or child widgets inside the matched range. If these flags are not given, the match must be exact; the special 0xFFFC character in @a str will match embedded pixbufs or child widgets. If you specify the GTK_SOURCE_SEARCH_CASE_INSENSITIVE flag, the text will be matched regardless of its case. @param iter GtkTextIter where the search begins @param str search string, may include 1 or more \n @param flags flags affecting how the search is done @param match_start return location for start of match, or NULL @param match_end return location for end of match, or NULL @param limit upper bound for the match start, or NULL for the end of the buffer @return TRUE if a match was found */ gboolean e2_iter_forward_search ( const GtkTextIter *iter, const gchar *str, E2TextSearchFlags flags, GtkTextIter *match_start, GtkTextIter *match_end, const GtkTextIter *limit) { gboolean visible_only, slice, retval; GtkTextIter match, search; g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (str != NULL, FALSE); if (!(flags & E2_SEARCH_CASE_INSENSITIVE)) { search = *iter; rescan: retval = gtk_text_iter_forward_search (&search, str, flags, match_start, match_end, limit); if (retval && (flags & E2_SEARCH_WHOLE_WORD) && (!gtk_text_iter_starts_word (match_start) //to allow incremental searching, whole_words option causes only a check //for word start here, the end-check is done when highlighting //|| !gtk_text_iter_ends_word (match_end) )) { search = *match_start; if (gtk_text_iter_forward_char (&search)) goto rescan; retval = FALSE; } return retval; } if (limit != NULL && gtk_text_iter_compare (iter, limit) > 0) return FALSE; if (*str == '\0') //matching nothing { //if we can move one char, return that location for a match match = *iter; if (gtk_text_iter_forward_char (&match)) { if (limit == NULL || gtk_text_iter_compare (&match, limit) <= 0) { if (match_start != NULL) *match_start = match; if (match_end != NULL) *match_end = match; return TRUE; } } return FALSE; } //split search string into lines gchar **lines = e2_utils_str_breakup (str, "\n", -1); if (lines == NULL) return FALSE; //FIXME warn user about error visible_only = (flags & E2_SEARCH_VISIBLE_ONLY) != 0; slice = (flags & E2_SEARCH_TEXT_ONLY) == 0; retval = FALSE; search = *iter; do { /* This loop has an inefficient worst-case, where gtk_text_iter_get_text() is called repeatedly on a single line */ GtkTextIter end; rescan2: if (limit != NULL && gtk_text_iter_compare (&search, limit) > 0) break; if (_e2_textiter_forward_lines_match (&search, (const gchar**)lines, visible_only, slice, &match, &end)) { if (limit == NULL || gtk_text_iter_compare (&end, limit) <= 0) { if ((flags & E2_SEARCH_WHOLE_WORD) && (!gtk_text_iter_starts_word (&match) //see comment above re end-checking when highlighting || !gtk_text_iter_ends_word (&end) )) { search = match; if (gtk_text_iter_forward_char (&search)) goto rescan2; } else { retval = TRUE; if (match_start != NULL) *match_start = match; if (match_end != NULL) *match_end = end; } } break; } } while (gtk_text_iter_forward_line (&search)); g_strfreev (lines); return retval; }
static gboolean chat_text_view_find_next (EmpathyChatView *view, const gchar *search_criteria, gboolean new_search, gboolean match_case) { EmpathyChatTextViewPriv *priv; GtkTextBuffer *buffer; GtkTextIter iter_at_mark; GtkTextIter iter_match_start; GtkTextIter iter_match_end; gboolean found; gboolean from_start = FALSE; g_return_val_if_fail (EMPATHY_IS_CHAT_TEXT_VIEW (view), FALSE); g_return_val_if_fail (search_criteria != NULL, FALSE); priv = GET_PRIV (view); buffer = priv->buffer; if (EMP_STR_EMPTY (search_criteria)) { if (priv->find_mark_next) { gtk_text_buffer_get_start_iter (buffer, &iter_at_mark); gtk_text_buffer_move_mark (buffer, priv->find_mark_next, &iter_at_mark); gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view), priv->find_mark_next, 0.0, TRUE, 0.0, 0.0); gtk_text_buffer_select_range (buffer, &iter_at_mark, &iter_at_mark); } return FALSE; } if (new_search) { from_start = TRUE; } if (!new_search && priv->find_mark_next) { gtk_text_buffer_get_iter_at_mark (buffer, &iter_at_mark, priv->find_mark_next); } else { gtk_text_buffer_get_start_iter (buffer, &iter_at_mark); from_start = TRUE; } priv->find_last_direction = TRUE; /* Use the standard GTK+ method for case sensitive searches. It can't do * case insensitive searches (see bug #61852), so keep the custom method * around for case insensitive searches. */ if (match_case) { found = gtk_text_iter_forward_search (&iter_at_mark, search_criteria, 0, &iter_match_start, &iter_match_end, NULL); } else { found = empathy_text_iter_forward_search (&iter_at_mark, search_criteria, &iter_match_start, &iter_match_end, NULL); } if (!found) { gboolean result = FALSE; if (from_start) { return result; } /* Here we wrap around. */ if (!new_search && !priv->find_wrapped) { priv->find_wrapped = TRUE; result = chat_text_view_find_next (view, search_criteria, FALSE, match_case); priv->find_wrapped = FALSE; } return result; } /* Set new mark and show on screen */ if (!priv->find_mark_next) { priv->find_mark_next = gtk_text_buffer_create_mark (buffer, NULL, &iter_match_end, TRUE); } else { gtk_text_buffer_move_mark (buffer, priv->find_mark_next, &iter_match_end); } if (!priv->find_mark_previous) { priv->find_mark_previous = gtk_text_buffer_create_mark (buffer, NULL, &iter_match_start, TRUE); } else { gtk_text_buffer_move_mark (buffer, priv->find_mark_previous, &iter_match_start); } gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view), priv->find_mark_next, 0.0, TRUE, 0.5, 0.5); gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", &iter_match_start); gtk_text_buffer_move_mark_by_name (buffer, "insert", &iter_match_end); return TRUE; }
void myre_move_to_string(GtkTextBuffer *text, char *needle, int mode) { int found = 0; end = current; switch (mode) { case 1:/*search forward*/ found = gtk_text_iter_forward_search( &end, needle, GTK_TEXT_SEARCH_VISIBLE_ONLY, ¤t, &end, NULL); if(!found) gtk_statusbar_push(status, gtk_statusbar_get_context_id(status, "status"), "Search forward reaches end"); else gtk_statusbar_push(status, gtk_statusbar_get_context_id(status, "status"), needle); /*place cursor*/ gtk_text_buffer_place_cursor(text, ¤t); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(textview2), ¤t, 0.0, TRUE, 0.0, 0.0 ); /*move current to end*/ current = end; break; case 0:/*search backward*/ found = gtk_text_iter_backward_search( ¤t, needle, GTK_TEXT_SEARCH_VISIBLE_ONLY, ¤t, &end, NULL); if(!found) gtk_statusbar_push(status, gtk_statusbar_get_context_id(status, "status"), "Search backward reaches start"); else gtk_statusbar_push(status, gtk_statusbar_get_context_id(status, "status"), needle); /*place cursor*/ gtk_text_buffer_place_cursor(text, ¤t); gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(textview2), ¤t, 0.0, TRUE, 0.0, 0.0 ); break; default: break; } }