Signed-off-by: Jakub Filak jfilak@redhat.com --- src/gui-wizard-gtk/wizard.c | 245 ++++++++++++++++++++++++++++++++------------ 1 file changed, 182 insertions(+), 63 deletions(-)
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index ab6d01a..94cc63d 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -2013,16 +2013,147 @@ static void log_ready_state(void) } #endif
-static gboolean highligh_word_in_tabs(const char *search_word, int flags) +static int compare_search_item(gconstpointer a, gconstpointer b) { - gboolean found = false; - GtkTextBuffer *buffer; + const search_item_t *lhs = a; + const search_item_t *rhs = b; + return gtk_text_iter_compare(&(lhs->start), &(rhs->start)); +} + +static bool highligh_words_in_textview(int page, GtkTextView *tev, GList *words, int flags) +{ + GtkTextBuffer *buffer = gtk_text_view_get_buffer(tev); + gtk_text_buffer_set_modified(buffer, FALSE); + GtkTextIter start_find; - GtkTextIter end_find; + gtk_text_buffer_get_start_iter(buffer, &start_find); + + int bufferpos = -1; + GList *after_buffer = NULL; + + if (flags & CLEAR_PREVIOUS_RESULT) + { + int allwordspos = 0; + int bufferwords = 0; + for (GList* item = g_search_result_list; item; ++allwordspos) + { + GList* current = item; + item = g_list_next(item); + + search_item_t *word = (search_item_t *)current->data; + if (word->buffer == buffer) + { + ++bufferwords; + + if (allwordspos < g_current_highlighted_word) + ++bufferpos; + + g_search_result_list = g_list_delete_link(g_search_result_list, current); + free(word); + } + else if(after_buffer == NULL && bufferwords != 0) + after_buffer = current; + } + + GtkTextIter end_find; + gtk_text_buffer_get_end_iter(buffer, &end_find); + + gtk_text_buffer_remove_tag_by_name(buffer, "search_result_bg", &start_find, &end_find); + gtk_text_buffer_remove_tag_by_name(buffer, "current_result_bg", &start_find, &end_find); + } + GtkTextIter start_match; GtkTextIter end_match; + int found = 0; + GList *result = NULL; + for (GList *w = words; w; w = g_list_next(w)) + { + gtk_text_buffer_get_start_iter(buffer, &start_find); + + const char *search_word = w->data; + while (search_word && search_word[0] && gtk_text_iter_forward_search(&start_find, search_word, + GTK_TEXT_SEARCH_TEXT_ONLY, + &start_match, + &end_match, NULL)) + { + ++found; + + search_item_t * found_word = (search_item_t *)xmalloc(sizeof(search_item_t)); + found_word->start = start_match; + found_word->end = end_match; + found_word->buffer = buffer; + found_word->tev = tev; + found_word->page = page; + result = g_list_prepend(result, found_word); + + gtk_text_buffer_apply_tag_by_name(buffer, "search_result_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); + } + } + + if (found) + { + /* The current order of the found words is defined by order of words in the + * passed list. We have to order the words according to their occurrence in + * the buffer. + */ + result = g_list_sort(result, compare_search_item); + + /* Put words of the buffer at the correct place */ + if (after_buffer == g_search_result_list) + { + /* + * The original list: + * (buffer, after buffer) + */ + g_search_result_list = g_list_concat(result, after_buffer); + } + else + { + /* + * The original: + * (before buffer, buffer, after buffer) + * After removing buffer's words: + * (before buffer, after buffer) + */ + if (after_buffer && after_buffer->prev) + { + /* split to two lists (before buffer) and (after buffer) */ + after_buffer->prev->next = NULL; + after_buffer->prev = NULL; + } + + /* create (before buffer, buffer) */ + g_search_result_list = g_list_concat(g_search_result_list, result); + + if (after_buffer) + /* create (before buffer, buffer, after buffer) */ + g_search_result_list = g_list_concat(g_search_result_list, after_buffer); + } + } + + if (flags & CLEAR_PREVIOUS_RESULT) + { + /* The bufferpos variable greater than 0 means that current word was in + * the buffer or the currently highlighted word was after all buffer's + * words, therefore we have to decrease the index of the currently + * highlighted word. If any word was found the highlighting process + * will start from the beginning of the buffer. If no word was found + * the currently highlighted word will be the first word in a next buffer. + */ + if (bufferpos >= 0) + g_current_highlighted_word -= (bufferpos + (found == 0)); + } + + return found; +} + +static gboolean highligh_words_in_tabs(GList *words, int flags) +{ + gboolean found = false; PangoAttrList *attrs; - int offset = 0;
if (flags & CLEAR_PREVIOUS_RESULT) { @@ -2038,16 +2169,14 @@ static gboolean highligh_word_in_tabs(const char *search_word, int flags) { //notebook_page->scrolled_window->text_view GtkWidget *notebook_child = gtk_notebook_get_nth_page(g_notebook, page); - GtkTextView *tev = GTK_TEXT_VIEW(gtk_bin_get_child(GTK_BIN(notebook_child))); - buffer = gtk_text_view_get_buffer(tev); - gtk_text_buffer_get_start_iter(buffer, &start_find); - gtk_text_buffer_get_end_iter(buffer, &end_find); GtkWidget *tab_lbl = gtk_notebook_get_tab_label(g_notebook, notebook_child); - //reset previous results + + if (strncmp(gtk_label_get_text(GTK_LABEL(tab_lbl)), "page 1", 5) == 0) + continue; + + //reset previous results if (flags & CLEAR_PREVIOUS_RESULT) { - gtk_text_buffer_remove_tag_by_name(buffer, "search_result_bg", &start_find, &end_find); - gtk_text_buffer_remove_tag_by_name(buffer, "current_result_bg", &start_find, &end_find); attrs = gtk_label_get_attributes(GTK_LABEL(tab_lbl)); gtk_label_set_attributes(GTK_LABEL(tab_lbl), NULL); pango_attr_list_unref(attrs); //If the result is zero, free the attribute list and the attributes it contains. @@ -2063,46 +2192,22 @@ static gboolean highligh_word_in_tabs(const char *search_word, int flags) free(lbl); */
- bool lbl_set = false; + GtkTextView *tev = GTK_TEXT_VIEW(gtk_bin_get_child(GTK_BIN(notebook_child))); + found = highligh_words_in_textview(page, tev, words, flags);
- if (strncmp(gtk_label_get_text(GTK_LABEL(tab_lbl)), "page 1", 5) == 0) + if (found) { - continue; - } - - while (search_word && search_word[0] && gtk_text_iter_forward_search(&start_find, search_word, - GTK_TEXT_SEARCH_TEXT_ONLY, - &start_match, - &end_match, NULL)) - { - search_item_t * found_word = (search_item_t *)xmalloc(sizeof(search_item_t)); - found_word->start = start_match; - found_word->end = end_match; - found_word->buffer = buffer; - found_word->tev = tev; - found_word->page = page; - g_search_result_list = g_list_append(g_search_result_list, found_word); - found = true; - if (!lbl_set) - { - attrs = pango_attr_list_new(); - PangoAttribute *foreground_attr = pango_attr_foreground_new(65535, 0, 0); - pango_attr_list_insert(attrs, foreground_attr); - gtk_label_set_attributes(GTK_LABEL(tab_lbl), attrs); - - /* adds * instead of changing color - usable for gtk < 2.8 */ - /* - char *found_lbl = xasprintf("*%s", gtk_label_get_text(GTK_LABEL(tab_lbl))); - gtk_label_set_text(GTK_LABEL(tab_lbl), found_lbl); - free(found_lbl); - */ - - lbl_set = true; - } - gtk_text_buffer_apply_tag_by_name(buffer, "search_result_bg", - &start_match, &end_match); - offset = gtk_text_iter_get_offset(&end_match); - gtk_text_buffer_get_iter_at_offset(buffer, &start_find, offset); + attrs = pango_attr_list_new(); + PangoAttribute *foreground_attr = pango_attr_foreground_new(65535, 0, 0); + pango_attr_list_insert(attrs, foreground_attr); + gtk_label_set_attributes(GTK_LABEL(tab_lbl), attrs); + + /* adds * instead of changing color - usable for gtk < 2.8 */ + /* + char *found_lbl = xasprintf("*%s", gtk_label_get_text(GTK_LABEL(tab_lbl))); + gtk_label_set_text(GTK_LABEL(tab_lbl), found_lbl); + free(found_lbl); + */ } } return found; @@ -2110,19 +2215,11 @@ static gboolean highligh_word_in_tabs(const char *search_word, int flags)
static void highlight_forbidden(void) { - gboolean found = false; GList *forbidden_words = load_forbidden_words(); - GList *cur_word = forbidden_words; - while (cur_word && ((char *)cur_word->data)[0]) - { - if(highligh_word_in_tabs((char *)cur_word->data, 0)) - found = true; - cur_word = g_list_next(cur_word); - } - if (found) - { + + if (highligh_words_in_tabs(forbidden_words, 0)) add_warning(_("Possible sensitive data detected, please review the highlighted tabs carefully.")); - } + list_free_with_free(forbidden_words); }
@@ -2383,13 +2480,26 @@ static void unhighlight_widget(GtkWidget *widget, gpointer *user_data) gtk_drag_unhighlight(widget); }
+static void rehighlight_forbidden_words(int page, GtkTextView *tev) +{ + GList *forbidden_words = load_forbidden_words(); + highligh_words_in_textview(page, tev, forbidden_words, CLEAR_PREVIOUS_RESULT); + list_free_with_free(forbidden_words); + + /* Don't increment resp. decrement in search_down() resp. search_up() */ + g_first_highlight = true; +} + static void unhighlight_current_word(void) { search_item_t *word = NULL; word = (search_item_t *)g_list_nth_data(g_search_result_list, g_current_highlighted_word); if (word) { - gtk_text_buffer_remove_tag_by_name(word->buffer, "current_result_bg", &(word->start), &(word->end)); + if (gtk_text_buffer_get_modified(word->buffer)) + rehighlight_forbidden_words(word->page, word->tev); + else + gtk_text_buffer_remove_tag_by_name(word->buffer, "current_result_bg", &(word->start), &(word->end)); } }
@@ -2399,6 +2509,13 @@ static void highlight_current_word(void) word = (search_item_t *)g_list_nth_data(g_search_result_list, g_current_highlighted_word); if (word) { + if (gtk_text_buffer_get_modified(word->buffer)) + { + rehighlight_forbidden_words(word->page, word->tev); + highlight_current_word(); + return; + } + gtk_notebook_set_current_page(g_notebook, word->page); gtk_text_buffer_apply_tag_by_name(word->buffer, "current_result_bg", &(word->start), &(word->end)); gtk_text_buffer_place_cursor(word->buffer, &(word->start)); @@ -2436,7 +2553,9 @@ static gboolean highlight_search(gpointer user_data)
VERB1 log("searching: '%s'", gtk_entry_get_text(entry));
- highligh_word_in_tabs(gtk_entry_get_text(entry), CLEAR_PREVIOUS_RESULT); + GList *words = g_list_append(NULL, (gpointer)gtk_entry_get_text(entry)); + highligh_words_in_tabs(words, CLEAR_PREVIOUS_RESULT); + g_list_free(words);
/* returning false will make glib to remove this event */ return false;