Commit d4e7368a authored by Gaël Bonithon's avatar Gaël Bonithon Committed by Matthew Brush

Add regex search

Closes #1, #9
parent d5b5f9ab
......@@ -35,7 +35,6 @@ enum {
MOUSEPAD_RESPONSE_REVERT,
MOUSEPAD_RESPONSE_SAVE,
MOUSEPAD_RESPONSE_SAVE_AS,
MOUSEPAD_RESPONSE_CHECK_ENTRY
};
......
......@@ -182,8 +182,10 @@ mousepad_document_init (MousepadDocument *document)
gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (document), NULL);
gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (document), NULL);
/* create a textbuffer */
/* create a textbuffer and associated search context */
document->buffer = GTK_TEXT_BUFFER (gtk_source_buffer_new (NULL));
document->search_context = gtk_source_search_context_new (GTK_SOURCE_BUFFER (document->buffer), NULL);
gtk_source_search_context_set_highlight (document->search_context, FALSE);
/* initialize the file */
document->file = mousepad_file_new (document->buffer);
......
......@@ -46,8 +46,9 @@ struct _MousepadDocument
/* file */
MousepadFile *file;
/* text buffer */
/* text buffer and associated search context */
GtkTextBuffer *buffer;
GtkSourceSearchContext *search_context;
/* text view */
MousepadView *textview;
......
......@@ -226,6 +226,13 @@ mousepad_replace_dialog_init (MousepadReplaceDialog *dialog)
mousepad_replace_dialog_bind_setting (dialog, MOUSEPAD_SETTING_SEARCH_MATCH_CASE, check, "active");
/* enable regex search */
check = gtk_check_button_new_with_mnemonic (_("_Enable Regex"));
gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
gtk_widget_show (check);
mousepad_replace_dialog_bind_setting (dialog, MOUSEPAD_SETTING_SEARCH_ENABLE_REGEX, check, "active");
/* match whole word */
check = gtk_check_button_new_with_mnemonic (_("_Match whole word"));
gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0);
......@@ -304,21 +311,25 @@ mousepad_replace_dialog_response (GtkWidget *widget,
const gchar *search_str, *replace_str;
gchar *message;
gint search_direction, replace_all_location;
gboolean match_case, match_whole_word, replace_all;
gboolean match_case, enable_regex, match_whole_word, replace_all;
/* close dialog */
if (response_id == MOUSEPAD_RESPONSE_CLOSE || response_id < 0)
{
gtk_widget_destroy (widget);
return;
}
/* read the search settings */
search_direction = MOUSEPAD_SETTING_GET_INT (SEARCH_DIRECTION);
replace_all_location = MOUSEPAD_SETTING_GET_INT (SEARCH_REPLACE_ALL_LOCATION);
match_case = MOUSEPAD_SETTING_GET_BOOLEAN (SEARCH_MATCH_CASE);
enable_regex = MOUSEPAD_SETTING_GET_BOOLEAN (SEARCH_ENABLE_REGEX);
match_whole_word = MOUSEPAD_SETTING_GET_BOOLEAN (SEARCH_MATCH_WHOLE_WORD);
replace_all = MOUSEPAD_SETTING_GET_BOOLEAN (SEARCH_REPLACE_ALL);
/* close dialog */
if (response_id == MOUSEPAD_RESPONSE_CLOSE)
goto destroy_dialog;
/* search direction */
if (search_direction == DIRECTION_UP && ! replace_all)
if (search_direction == DIRECTION_UP)
flags = MOUSEPAD_SEARCH_FLAGS_DIR_BACKWARD;
else
flags = MOUSEPAD_SEARCH_FLAGS_DIR_FORWARD;
......@@ -327,38 +338,34 @@ mousepad_replace_dialog_response (GtkWidget *widget,
if (match_case)
flags |= MOUSEPAD_SEARCH_FLAGS_MATCH_CASE;
/* enable regex search */
if (enable_regex)
flags |= MOUSEPAD_SEARCH_FLAGS_ENABLE_REGEX;
/* only match whole words */
if (match_whole_word)
flags |= MOUSEPAD_SEARCH_FLAGS_WHOLE_WORD;
/* wrap around */
if (search_direction == DIRECTION_BOTH && ! replace_all)
if (search_direction == DIRECTION_BOTH)
flags |= MOUSEPAD_SEARCH_FLAGS_WRAP_AROUND;
/* search area */
if (replace_all && replace_all_location == IN_SELECTION)
flags |= MOUSEPAD_SEARCH_FLAGS_AREA_SELECTION;
else
flags |= MOUSEPAD_SEARCH_FLAGS_AREA_DOCUMENT;
/* start position */
if (response_id == MOUSEPAD_RESPONSE_CHECK_ENTRY)
if (replace_all)
{
/* no visible actions */
flags |= MOUSEPAD_SEARCH_FLAGS_ACTION_NONE;
if (replace_all)
goto replace_flags;
else
goto search_flags;
flags |= MOUSEPAD_SEARCH_FLAGS_ENTIRE_AREA;
if (replace_all_location == IN_ALL_DOCUMENTS)
flags |= MOUSEPAD_SEARCH_FLAGS_AREA_ALL_DOCUMENTS;
else if (replace_all_location == IN_SELECTION)
flags |= MOUSEPAD_SEARCH_FLAGS_AREA_SELECTION;
}
else if (response_id == MOUSEPAD_RESPONSE_FIND)
/* start position */
if (response_id == MOUSEPAD_RESPONSE_FIND)
{
/* select the first match */
flags |= MOUSEPAD_SEARCH_FLAGS_ACTION_SELECT;
search_flags:
/* start at the 'end' of the selection */
if (flags & MOUSEPAD_SEARCH_FLAGS_DIR_BACKWARD)
flags |= MOUSEPAD_SEARCH_FLAGS_ITER_SEL_START;
......@@ -370,36 +377,11 @@ mousepad_replace_dialog_response (GtkWidget *widget,
/* replace matches */
flags |= MOUSEPAD_SEARCH_FLAGS_ACTION_REPLACE;
if (replace_all)
{
replace_flags:
/* replace all from the beginning of the document */
flags |= MOUSEPAD_SEARCH_FLAGS_ITER_AREA_START
| MOUSEPAD_SEARCH_FLAGS_ENTIRE_AREA;
/* search all opened documents (flag used in mousepad-window.c) */
if (replace_all_location == IN_ALL_DOCUMENTS)
flags |= MOUSEPAD_SEARCH_FLAGS_ALL_DOCUMENTS;
}
/* start at the 'beginning' of the selection */
if (flags & MOUSEPAD_SEARCH_FLAGS_DIR_BACKWARD)
flags |= MOUSEPAD_SEARCH_FLAGS_ITER_SEL_END;
else
{
/* start at the 'beginning' of the selection */
if (flags & MOUSEPAD_SEARCH_FLAGS_DIR_BACKWARD)
flags |= MOUSEPAD_SEARCH_FLAGS_ITER_SEL_END;
else
flags |= MOUSEPAD_SEARCH_FLAGS_ITER_SEL_START;
}
}
else
{
destroy_dialog:
/* destroy the window */
gtk_widget_destroy (widget);
/* leave */
return;
flags |= MOUSEPAD_SEARCH_FLAGS_ITER_SEL_START;
}
/* get strings */
......@@ -448,7 +430,7 @@ mousepad_replace_dialog_changed (MousepadReplaceDialog *dialog)
if (text != NULL && *text != '\0')
{
/* do an invisible search to give the user some visible feedback */
gtk_dialog_response (GTK_DIALOG (dialog), MOUSEPAD_RESPONSE_CHECK_ENTRY);
gtk_dialog_response (GTK_DIALOG (dialog), MOUSEPAD_RESPONSE_FIND);
/* buttons are sensitive */
sensitive = TRUE;
......
......@@ -28,7 +28,6 @@
#define TOOL_BAR_ICON_SIZE GTK_ICON_SIZE_MENU
#define HIGHTLIGHT_TIMEOUT 225
......@@ -46,9 +45,8 @@ static void mousepad_search_bar_highlight_toggled (GtkWidget
MousepadSearchBar *bar);
static void mousepad_search_bar_match_case_toggled (GtkWidget *button,
MousepadSearchBar *bar);
static void mousepad_search_bar_highlight_schedule (MousepadSearchBar *bar);
static gboolean mousepad_search_bar_highlight_timeout (gpointer user_data);
static void mousepad_search_bar_highlight_timeout_destroy (gpointer user_data);
static void mousepad_search_bar_enable_regex_toggled (GtkWidget *button,
MousepadSearchBar *bar);
......@@ -73,13 +71,12 @@ struct _MousepadSearchBar
/* menu entries */
GtkWidget *match_case_entry;
GtkWidget *enable_regex_entry;
/* flags */
guint highlight_all : 1;
guint match_case : 1;
/* highlight id */
guint highlight_id;
guint enable_regex : 1;
};
......@@ -185,14 +182,15 @@ mousepad_search_bar_init (MousepadSearchBar *bar)
{
GtkWidget *label, *image, *check, *menuitem;
GtkToolItem *item;
gboolean match_case;
gboolean match_case, enable_regex;
/* load some saved state */
match_case = MOUSEPAD_SETTING_GET_BOOLEAN (SEARCH_MATCH_CASE);
enable_regex = MOUSEPAD_SETTING_GET_BOOLEAN (SEARCH_ENABLE_REGEX);
/* init variables */
bar->highlight_id = 0;
bar->match_case = match_case;
bar->enable_regex = enable_regex;
/* the close button */
item = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
......@@ -279,6 +277,29 @@ mousepad_search_bar_init (MousepadSearchBar *bar)
/* Keep toolbar check button and overflow proxy menu item in sync */
g_object_bind_property (check, "active", menuitem, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_widget_show (menuitem);
/* check button for enabling regex, including the proxy menu item */
item = gtk_tool_item_new ();
g_signal_connect_object (G_OBJECT (bar), "destroy", G_CALLBACK (gtk_widget_destroy), item, G_CONNECT_SWAPPED);
gtk_toolbar_insert (GTK_TOOLBAR (bar), item, -1);
gtk_widget_show (GTK_WIDGET (item));
check = gtk_check_button_new_with_mnemonic (_("_Enable Regex"));
g_signal_connect_object (G_OBJECT (bar), "destroy", G_CALLBACK (gtk_widget_destroy), item, G_CONNECT_SWAPPED);
gtk_container_add (GTK_CONTAINER (item), check);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), enable_regex);
g_signal_connect (G_OBJECT (check), "toggled", G_CALLBACK (mousepad_search_bar_enable_regex_toggled), bar);
gtk_widget_show (check);
/* keep the widgets in sync with the GSettings */
MOUSEPAD_SETTING_BIND (SEARCH_ENABLE_REGEX, check, "active", G_SETTINGS_BIND_DEFAULT);
bar->enable_regex_entry = menuitem = gtk_check_menu_item_new_with_mnemonic (_("_Enable Regex"));
g_signal_connect_object (G_OBJECT (bar), "destroy", G_CALLBACK (gtk_widget_destroy), item, G_CONNECT_SWAPPED);
gtk_tool_item_set_proxy_menu_item (item, "enable-regex", menuitem);
/* Keep toolbar check button and overflow proxy menu item in sync */
g_object_bind_property (check, "active", menuitem, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
gtk_widget_show (menuitem);
}
......@@ -286,12 +307,6 @@ mousepad_search_bar_init (MousepadSearchBar *bar)
static void
mousepad_search_bar_finalize (GObject *object)
{
MousepadSearchBar *bar = MOUSEPAD_SEARCH_BAR (object);
/* stop a running highlight timeout */
if (bar->highlight_id != 0)
g_source_remove (bar->highlight_id);
(*G_OBJECT_CLASS (mousepad_search_bar_parent_class)->finalize) (object);
}
......@@ -304,11 +319,8 @@ mousepad_search_bar_find_string (MousepadSearchBar *bar,
const gchar *string;
gint nmatches;
/* search the entire document */
flags |= MOUSEPAD_SEARCH_FLAGS_AREA_DOCUMENT;
/* if we don't hightlight, we select with wrapping */
if ((flags & MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHTLIGHT) == 0)
if (! (flags & MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHLIGHT_ON))
flags |= MOUSEPAD_SEARCH_FLAGS_ACTION_SELECT
| MOUSEPAD_SEARCH_FLAGS_WRAP_AROUND;
......@@ -316,6 +328,10 @@ mousepad_search_bar_find_string (MousepadSearchBar *bar,
if (bar->match_case)
flags |= MOUSEPAD_SEARCH_FLAGS_MATCH_CASE;
/* append the regex flags when needed */
if (bar->enable_regex)
flags |= MOUSEPAD_SEARCH_FLAGS_ENABLE_REGEX;
/* get the entry string */
string = gtk_entry_get_text (GTK_ENTRY (bar->entry));
......@@ -323,7 +339,7 @@ mousepad_search_bar_find_string (MousepadSearchBar *bar,
g_signal_emit (G_OBJECT (bar), search_bar_signals[SEARCH], 0, flags, string, NULL, &nmatches);
/* do nothing with the error entry when highlight when trigged with highlight */
if ((flags & MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHTLIGHT) == 0)
if (! (flags & MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHLIGHT_ON))
{
/* make sure the search entry is not red when no text was typed */
if (string == NULL || *string == '\0')
......@@ -377,9 +393,6 @@ mousepad_search_bar_entry_changed (GtkWidget *entry,
/* find */
mousepad_search_bar_find_string (bar, flags);
/* schedule a new highlight */
mousepad_search_bar_highlight_schedule (bar);
}
......@@ -392,27 +405,15 @@ mousepad_search_bar_highlight_toggled (GtkWidget *button,
g_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (bar));
/* set the new state */
/* set the new state and search flags */
bar->highlight_all = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (button));
if (bar->highlight_all)
{
/* reschedule the highlight */
mousepad_search_bar_highlight_schedule (bar);
}
flags = MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHLIGHT_ON;
else
{
/* stop timeout */
if (bar->highlight_id != 0)
g_source_remove (bar->highlight_id);
flags = MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHLIGHT_OFF;
/* set search flags */
flags = MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHTLIGHT
| MOUSEPAD_SEARCH_FLAGS_ACTION_CLEANUP;
/* emit signal to cleanup the highlight */
mousepad_search_bar_find_string (bar, flags);
}
/* emit signal to set the highlight */
mousepad_search_bar_find_string (bar, flags);
}
......@@ -433,56 +434,26 @@ mousepad_search_bar_match_case_toggled (GtkWidget *button,
/* search ahead with this new flags */
mousepad_search_bar_entry_changed (NULL, bar);
/* schedule a new hightlight */
mousepad_search_bar_highlight_schedule (bar);
}
static void
mousepad_search_bar_highlight_schedule (MousepadSearchBar *bar)
{
g_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (bar));
/* stop a pending timeout */
if (bar->highlight_id != 0)
g_source_remove (bar->highlight_id);
/* schedule a new timeout */
if (bar->highlight_all)
{
bar->highlight_id = g_timeout_add_full (G_PRIORITY_LOW, HIGHTLIGHT_TIMEOUT, mousepad_search_bar_highlight_timeout,
bar, mousepad_search_bar_highlight_timeout_destroy);
}
}
static void
mousepad_search_bar_highlight_timeout_destroy (gpointer user_data)
mousepad_search_bar_enable_regex_toggled (GtkWidget *button,
MousepadSearchBar *bar)
{
MOUSEPAD_SEARCH_BAR (user_data)->highlight_id = 0;
}
gboolean active;
static gboolean
mousepad_search_bar_highlight_timeout (gpointer user_data)
{
MousepadSearchBar *bar = MOUSEPAD_SEARCH_BAR (user_data);
MousepadSearchFlags flags;
g_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (bar));
/* set search flags */
flags = MOUSEPAD_SEARCH_FLAGS_DIR_FORWARD
| MOUSEPAD_SEARCH_FLAGS_ITER_AREA_START
| MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHTLIGHT;
/* get the state of the toggle button */
active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
/* emit signal */
mousepad_search_bar_find_string (bar, flags);
/* save the state */
bar->enable_regex = active;
/* stop the timeout */
return FALSE;
/* search ahead with this new flags */
mousepad_search_bar_entry_changed (NULL, bar);
}
......@@ -501,16 +472,22 @@ mousepad_search_bar_entry (MousepadSearchBar *bar)
void
mousepad_search_bar_focus (MousepadSearchBar *bar)
{
MousepadSearchFlags flags;
g_return_if_fail (MOUSEPAD_IS_SEARCH_BAR (bar));
/* focus the entry field */
gtk_widget_grab_focus (bar->entry);
/* update the highlight */
mousepad_search_bar_highlight_schedule (bar);
/* select the entire entry */
gtk_editable_select_region (GTK_EDITABLE (bar->entry), 0, -1);
/* highlighting has been disabled by hiding the search bar */
if (bar->highlight_all)
{
flags = MOUSEPAD_SEARCH_FLAGS_ACTION_HIGHLIGHT_ON;
mousepad_search_bar_find_string (bar, flags);
}
}
......
......@@ -60,6 +60,7 @@ G_BEGIN_DECLS
/* State setting names */
#define MOUSEPAD_SETTING_SEARCH_DIRECTION "/state/search/direction"
#define MOUSEPAD_SETTING_SEARCH_MATCH_CASE "/state/search/match-case"
#define MOUSEPAD_SETTING_SEARCH_ENABLE_REGEX "/state/search/enable-regex"
#define MOUSEPAD_SETTING_SEARCH_MATCH_WHOLE_WORD "/state/search/match-whole-word"
#define MOUSEPAD_SETTING_SEARCH_REPLACE_ALL "/state/search/replace-all"
#define MOUSEPAD_SETTING_SEARCH_REPLACE_ALL_LOCATION "/state/search/replace-all-location"
......
......@@ -17,6 +17,7 @@
#include <mousepad/mousepad-private.h>
#include <mousepad/mousepad-gtkcompat.h>
#include <mousepad/mousepad-util.h>
#include <gtksourceview/gtksource.h>
......@@ -626,430 +627,128 @@ mousepad_util_search_flags_get_type (void)
static gboolean
mousepad_util_search_iter (const GtkTextIter *start,
const gchar *string,
MousepadSearchFlags flags,
GtkTextIter *match_start,
GtkTextIter *match_end,
const GtkTextIter *limit)
{
GtkTextIter iter, begin;
gunichar iter_char, str_char;
gboolean succeed = FALSE;
const gchar *needle = string;
gboolean match_case, search_backwards, whole_word;
guint needle_offset = 0;
g_return_val_if_fail (start != NULL, FALSE);
g_return_val_if_fail (string != NULL, FALSE);
g_return_val_if_fail (limit != NULL, FALSE);
/* search properties */
match_case = (flags & MOUSEPAD_SEARCH_FLAGS_MATCH_CASE) != 0;
search_backwards = (flags & MOUSEPAD_SEARCH_FLAGS_DIR_BACKWARD) != 0;
whole_word = (flags & MOUSEPAD_SEARCH_FLAGS_WHOLE_WORD) != 0;
/* set the start iter */
iter = *start;
/* walk from the start to the end iter */
for (;;)
{
/* break when we reach the limit iter, for backwards searching it's
* it has to be less than the limit which is 0 so that we can match
* at the very start of the buffer. for forwards searching the limit
* is the index after the last char so break when we are at or past
* the limit. */
if ((search_backwards && gtk_text_iter_compare (&iter, limit) < 0) ||
(!search_backwards && gtk_text_iter_compare (&iter, limit) >= 0))
{
break;
}
/* get the unichar characters */
iter_char = gtk_text_iter_get_char (&iter);
str_char = g_utf8_get_char (needle);
/* skip unknown characters */
if (G_UNLIKELY (iter_char == 0xFFFC))
goto continue_searching;
/* lower case searching */
if (!match_case)
{
/* convert the characters to lower case */
iter_char = g_unichar_tolower (iter_char);
str_char = g_unichar_tolower (str_char);
}
/* compare the two characters */
if (iter_char == str_char)
{
/* first character matched, set the begin iter */
if (needle_offset == 0)
begin = iter;
/* get the next character and increase the offset counter */
needle = g_utf8_next_char (needle);
needle_offset++;
/* we hit the end of the search string, so we had a full match */
if (G_UNLIKELY (*needle == '\0'))
{
if (G_LIKELY (!search_backwards))
{
/* set the end iter after the character (for selection) */
gtk_text_iter_forward_char (&iter);
/* check if we match a whole word */
if (whole_word && !(mousepad_util_iter_starts_word (&begin) && mousepad_util_iter_ends_word (&iter)))
goto reset_and_continue_searching;
}
else
{
/* set the start iter after the character (for selection) */
gtk_text_iter_forward_char (&begin);
/* check if we match a whole word */
if (whole_word && !(mousepad_util_iter_starts_word (&iter) && mousepad_util_iter_ends_word (&begin)))
goto reset_and_continue_searching;
}
/* set the start and end iters */
*match_start = begin;
*match_end = iter;
/* return true and stop searching */
succeed = TRUE;
break;
}
}
else if (needle_offset > 0)
{
/* label */
reset_and_continue_searching:
/* reset the needle */
needle = string;
needle_offset = 0;
/* reset the iter */
iter = begin;
}
/* label */
continue_searching:
/* jump to next iter in the buffer */
if ((!search_backwards && !gtk_text_iter_forward_char (&iter))
|| (search_backwards && !gtk_text_iter_backward_char (&iter)))
break;
}
return succeed;
}
static void
mousepad_util_search_get_iters (GtkTextBuffer *buffer,
MousepadSearchFlags flags,
GtkTextIter *start,
GtkTextIter *end,
GtkTextIter *iter)
gint
mousepad_util_search (GtkSourceSearchContext *search_context,
const gchar *string,
const gchar *replace,
MousepadSearchFlags flags)
{
GtkTextIter sel_start, sel_end, tmp;
/* get selection bounds */
gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end);
if (flags & MOUSEPAD_SEARCH_FLAGS_AREA_DOCUMENT)
{
/* get document bounds */
gtk_text_buffer_get_bounds (buffer, start, end);
/* set the start iter */
if (flags & MOUSEPAD_SEARCH_FLAGS_ITER_AREA_START)
*iter = *start;
else if (flags & MOUSEPAD_SEARCH_FLAGS_ITER_AREA_END)
*iter = *end;
else
goto set_selection_iter;
}
else if (flags & MOUSEPAD_SEARCH_FLAGS_AREA_SELECTION)
{
/* set area iters */
*start = sel_start;
*end = sel_end;
GtkSourceSearchSettings *search_settings;
GtkTextBuffer *buffer, *selection_buffer;
GtkTextIter start, end, iter, bstart, fend, biter, fiter;
const gchar *selected_text;
gint counter = 0;
gboolean found;
g_return_val_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search_context), -1);
g_return_val_if_fail (string != NULL && g_utf8_validate (string, -1, NULL), -1);
g_return_val_if_fail (replace == NULL || g_utf8_validate (replace, -1, NULL), -1);
set_selection_iter:
/* freeze buffer notifications */
buffer = GTK_TEXT_BUFFER (gtk_source_search_context_get_buffer (search_context));
g_object_freeze_notify (G_OBJECT (buffer));
/* set the start iter */
if (flags & (MOUSEPAD_SEARCH_FLAGS_ITER_AREA_START | MOUSEPAD_SEARCH_FLAGS_ITER_SEL_START))
*iter = sel_start;
else if (flags & (MOUSEPAD_SEARCH_FLAGS_ITER_AREA_END | MOUSEPAD_SEARCH_FLAGS_ITER_SEL_END))
*iter = sel_end;
else
g_assert_not_reached ();
}
/* get the search iters */
if (flags & MOUSEPAD_SEARCH_FLAGS_ITER_SEL_START)
gtk_text_buffer_get_selection_bounds (buffer, &iter, NULL);
else
{
/* this should never happen */