[gtksourceview/wip/search] search: wrap around flag
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/search] search: wrap around flag
- Date: Sat, 29 Jun 2013 20:12:54 +0000 (UTC)
commit a7b3118918aa6e13eaec58e4d2de5d034fe60a6e
Author: Sébastien Wilmet <swilmet gnome org>
Date: Sat Jun 29 16:01:25 2013 +0200
search: wrap around flag
gtksourceview/gtksourcebuffer.h | 6 ++-
gtksourceview/gtksourcesearch.c | 96 +++++++++++++++++++++++++++++++++------
tests/test-search-ui.c | 25 ++++++++++
tests/test-search-ui.ui | 16 +++++++
4 files changed, 128 insertions(+), 15 deletions(-)
---
diff --git a/gtksourceview/gtksourcebuffer.h b/gtksourceview/gtksourcebuffer.h
index 3cba252..41b2579 100644
--- a/gtksourceview/gtksourcebuffer.h
+++ b/gtksourceview/gtksourcebuffer.h
@@ -61,6 +61,9 @@ typedef enum
* @GTK_SOURCE_SEARCH_CASE_SENSITIVE: Case sensitive search.
* @GTK_SOURCE_SEARCH_AT_WORD_BOUNDARIES: A search match must start and end a
* word. The match can span multiple words.
+ * @GTK_SOURCE_SEARCH_WRAP_AROUND: For a forward search, continue at the
+ * beginning of the buffer if no search occurrence is found at the end of the
+ * buffer. For a backward search, continue at the end of the buffer.
*
* Flags affecting how the search is done. Internally, GtkSourceView always
* enables #GTK_TEXT_SEARCH_VISIBLE_ONLY and #GTK_TEXT_SEARCH_TEXT_ONLY.
@@ -70,7 +73,8 @@ typedef enum
typedef enum
{
GTK_SOURCE_SEARCH_CASE_SENSITIVE = 1 << 0,
- GTK_SOURCE_SEARCH_AT_WORD_BOUNDARIES = 1 << 1
+ GTK_SOURCE_SEARCH_AT_WORD_BOUNDARIES = 1 << 1,
+ GTK_SOURCE_SEARCH_WRAP_AROUND = 1 << 2
} GtkSourceSearchFlags;
struct _GtkSourceBuffer
diff --git a/gtksourceview/gtksourcesearch.c b/gtksourceview/gtksourcesearch.c
index 52ea71d..69cf757 100644
--- a/gtksourceview/gtksourcesearch.c
+++ b/gtksourceview/gtksourcesearch.c
@@ -143,6 +143,7 @@ struct _GtkSourceSearchPrivate
GtkTextTag *found_tag;
guint at_word_boundaries : 1;
+ guint wrap_around : 1;
};
typedef struct
@@ -151,6 +152,7 @@ typedef struct
GtkTextIter match_start;
GtkTextIter match_end;
guint found : 1;
+ guint wrapped_around : 1;
/* forward or backward */
guint is_forward : 1;
@@ -460,19 +462,31 @@ forward_backward_data_free (ForwardBackwardData *data)
static void
smart_forward_search_async (GtkSourceSearch *search,
const GtkTextIter *start_at,
- GTask *task)
+ GTask *task,
+ gboolean wrapped_around)
{
GtkTextIter iter = *start_at;
GtkTextIter limit;
GtkTextRegion *region = NULL;
ForwardBackwardData *task_data;
- if (gtk_text_iter_is_end (start_at) ||
- search->priv->text == NULL)
+ if (gtk_text_iter_is_end (start_at))
{
+ if (search->priv->text != NULL &&
+ !wrapped_around &&
+ search->priv->wrap_around)
+ {
+ GtkTextIter start_iter;
+ gtk_text_buffer_get_start_iter (search->priv->buffer, &start_iter);
+
+ smart_forward_search_async (search, &start_iter, task, TRUE);
+ return;
+ }
+
task_data = g_slice_new0 (ForwardBackwardData);
task_data->found = FALSE;
task_data->is_forward = TRUE;
+ task_data->wrapped_around = wrapped_around;
g_task_return_pointer (task,
task_data,
@@ -520,6 +534,7 @@ smart_forward_search_async (GtkSourceSearch *search,
task_data->match_start = match_start;
task_data->match_end = match_end;
task_data->is_forward = TRUE;
+ task_data->wrapped_around = wrapped_around;
g_task_return_pointer (task,
task_data,
@@ -529,12 +544,13 @@ smart_forward_search_async (GtkSourceSearch *search,
return;
}
- smart_forward_search_async (search, &limit, task);
+ smart_forward_search_async (search, &limit, task, wrapped_around);
return;
}
task_data = g_slice_new0 (ForwardBackwardData);
task_data->is_forward = TRUE;
+ task_data->wrapped_around = wrapped_around;
task_data->start_at = gtk_text_buffer_create_mark (search->priv->buffer,
NULL,
start_at,
@@ -554,19 +570,31 @@ smart_forward_search_async (GtkSourceSearch *search,
static void
smart_backward_search_async (GtkSourceSearch *search,
const GtkTextIter *start_at,
- GTask *task)
+ GTask *task,
+ gboolean wrapped_around)
{
GtkTextIter iter = *start_at;
GtkTextIter limit;
GtkTextRegion *region = NULL;
ForwardBackwardData *task_data;
- if (gtk_text_iter_is_start (start_at) ||
- search->priv->text == NULL)
+ if (gtk_text_iter_is_start (start_at))
{
+ if (search->priv->text != NULL &&
+ !wrapped_around &&
+ search->priv->wrap_around)
+ {
+ GtkTextIter end_iter;
+ gtk_text_buffer_get_end_iter (search->priv->buffer, &end_iter);
+
+ smart_backward_search_async (search, &end_iter, task, TRUE);
+ return;
+ }
+
task_data = g_slice_new0 (ForwardBackwardData);
task_data->found = FALSE;
task_data->is_forward = FALSE;
+ task_data->wrapped_around = wrapped_around;
g_task_return_pointer (task,
task_data,
@@ -616,6 +644,7 @@ smart_backward_search_async (GtkSourceSearch *search,
task_data->match_start = match_start;
task_data->match_end = match_end;
task_data->is_forward = FALSE;
+ task_data->wrapped_around = wrapped_around;
g_task_return_pointer (task,
task_data,
@@ -625,12 +654,13 @@ smart_backward_search_async (GtkSourceSearch *search,
return;
}
- smart_backward_search_async (search, &limit, task);
+ smart_backward_search_async (search, &limit, task, wrapped_around);
return;
}
task_data = g_slice_new0 (ForwardBackwardData);
task_data->is_forward = FALSE;
+ task_data->wrapped_around = wrapped_around;
task_data->start_at = gtk_text_buffer_create_mark (search->priv->buffer,
NULL,
start_at,
@@ -1066,11 +1096,17 @@ scan_task_region (GtkSourceSearch *search)
if (task_data->is_forward)
{
- smart_forward_search_async (search, &start_at, task);
+ smart_forward_search_async (search,
+ &start_at,
+ task,
+ task_data->wrapped_around);
}
else
{
- smart_backward_search_async (search, &start_at, task);
+ smart_backward_search_async (search,
+ &start_at,
+ task,
+ task_data->wrapped_around);
}
}
@@ -1125,6 +1161,7 @@ install_idle_scan (GtkSourceSearch *search)
}
}
+/* Doesn't wrap around. */
static gboolean
smart_forward_search (GtkSourceSearch *search,
const GtkTextIter *start_at,
@@ -1182,6 +1219,7 @@ smart_forward_search (GtkSourceSearch *search,
return smart_forward_search (search, start_at, match_start, match_end);
}
+/* Doesn't wrap around. */
static gboolean
smart_backward_search (GtkSourceSearch *search,
const GtkTextIter *start_at,
@@ -1538,6 +1576,7 @@ _gtk_source_search_set_flags (GtkSourceSearch *search,
}
search->priv->at_word_boundaries = (flags & GTK_SOURCE_SEARCH_AT_WORD_BOUNDARIES) != 0;
+ search->priv->wrap_around = (flags & GTK_SOURCE_SEARCH_WRAP_AROUND) != 0;
update (search);
}
@@ -1559,6 +1598,11 @@ _gtk_source_search_get_flags (GtkSourceSearch *search)
source_flags |= GTK_SOURCE_SEARCH_AT_WORD_BOUNDARIES;
}
+ if (search->priv->wrap_around)
+ {
+ source_flags |= GTK_SOURCE_SEARCH_WRAP_AROUND;
+ }
+
return source_flags;
}
@@ -1630,9 +1674,21 @@ _gtk_source_search_forward (GtkSourceSearch *search,
GtkTextIter *match_start,
GtkTextIter *match_end)
{
+ gboolean found;
+
g_return_val_if_fail (GTK_SOURCE_IS_SEARCH (search), FALSE);
- return smart_forward_search (search, iter, match_start, match_end);
+ found = smart_forward_search (search, iter, match_start, match_end);
+
+ if (!found && search->priv->wrap_around)
+ {
+ GtkTextIter start_iter;
+ gtk_text_buffer_get_start_iter (search->priv->buffer, &start_iter);
+
+ found = smart_forward_search (search, &start_iter, match_start, match_end);
+ }
+
+ return found;
}
void
@@ -1648,7 +1704,7 @@ _gtk_source_search_forward_async (GtkSourceSearch *search,
task = g_task_new (search->priv->buffer, cancellable, callback, user_data);
- smart_forward_search_async (search, iter, task);
+ smart_forward_search_async (search, iter, task, FALSE);
}
gboolean
@@ -1696,9 +1752,21 @@ _gtk_source_search_backward (GtkSourceSearch *search,
GtkTextIter *match_start,
GtkTextIter *match_end)
{
+ gboolean found;
+
g_return_val_if_fail (GTK_SOURCE_IS_SEARCH (search), FALSE);
- return smart_backward_search (search, iter, match_start, match_end);
+ found = smart_backward_search (search, iter, match_start, match_end);
+
+ if (!found && search->priv->wrap_around)
+ {
+ GtkTextIter end_iter;
+ gtk_text_buffer_get_end_iter (search->priv->buffer, &end_iter);
+
+ found = smart_backward_search (search, &end_iter, match_start, match_end);
+ }
+
+ return found;
}
void
@@ -1714,7 +1782,7 @@ _gtk_source_search_backward_async (GtkSourceSearch *search,
task = g_task_new (search->priv->buffer, cancellable, callback, user_data);
- smart_backward_search_async (search, iter, task);
+ smart_backward_search_async (search, iter, task, FALSE);
}
gboolean
diff --git a/tests/test-search-ui.c b/tests/test-search-ui.c
index ad4c200..d005fc1 100644
--- a/tests/test-search-ui.c
+++ b/tests/test-search-ui.c
@@ -110,6 +110,24 @@ on_at_word_boundaries_toggled_cb (GtkToggleButton *button,
}
static void
+on_wrap_around_toggled_cb (GtkToggleButton *button,
+ GtkSourceBuffer *buffer)
+{
+ GtkSourceSearchFlags flags = gtk_source_buffer_get_search_flags (buffer);
+
+ if (gtk_toggle_button_get_active (button))
+ {
+ flags |= GTK_SOURCE_SEARCH_WRAP_AROUND;
+ }
+ else
+ {
+ flags &= ~GTK_SOURCE_SEARCH_WRAP_AROUND;
+ }
+
+ gtk_source_buffer_set_search_flags (buffer, flags);
+}
+
+static void
select_search_occurrence (GtkTextView *view,
const GtkTextIter *match_start,
const GtkTextIter *match_end)
@@ -202,6 +220,7 @@ create_window (void)
GtkLabel *label_occurrences_count;
GtkCheckButton *match_case;
GtkCheckButton *at_word_boundaries;
+ GtkCheckButton *wrap_around;
GtkButton *button_previous;
GtkButton *button_next;
PangoFontDescription *font;
@@ -223,6 +242,7 @@ create_window (void)
label_occurrences_count = GTK_LABEL (gtk_builder_get_object (builder, "label_occurrences_count"));
match_case = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_match_case"));
at_word_boundaries = GTK_CHECK_BUTTON (gtk_builder_get_object (builder,
"checkbutton_at_word_boundaries"));
+ wrap_around = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_wrap_around"));
button_previous = GTK_BUTTON (gtk_builder_get_object (builder, "button_previous"));
button_next = GTK_BUTTON (gtk_builder_get_object (builder, "button_next"));
@@ -268,6 +288,11 @@ create_window (void)
G_CALLBACK (on_at_word_boundaries_toggled_cb),
source_buffer);
+ g_signal_connect (wrap_around,
+ "toggled",
+ G_CALLBACK (on_wrap_around_toggled_cb),
+ source_buffer);
+
g_signal_connect (button_previous,
"clicked",
G_CALLBACK (on_button_previous_clicked_cb),
diff --git a/tests/test-search-ui.ui b/tests/test-search-ui.ui
index 5de2949..5bfa595 100644
--- a/tests/test-search-ui.ui
+++ b/tests/test-search-ui.ui
@@ -174,6 +174,22 @@
<property name="height">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton_wrap_around">
+ <property name="label">Wrap around</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="left_attach">0</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]