From cca58988b2cacbbb7253265e9ed38ecd3136180d Mon Sep 17 00:00:00 2001 From: Jesse van den Kieboom Date: Fri, 23 Dec 2005 13:22:20 +0000 Subject: [PATCH] Added replacing --- gnoemoe/widgets/gm-searchable.c | 127 +++++++++++++++++++++++++++++++- gnoemoe/widgets/gm-searchable.h | 10 +++ 2 files changed, 134 insertions(+), 3 deletions(-) diff --git a/gnoemoe/widgets/gm-searchable.c b/gnoemoe/widgets/gm-searchable.c index 86ee078..0e20d6f 100644 --- a/gnoemoe/widgets/gm-searchable.c +++ b/gnoemoe/widgets/gm-searchable.c @@ -42,10 +42,18 @@ gm_searchable_text_view_find_next(GtkTextView *text_view, const gchar *str, if (buffer) { if (!gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) { - if (flags & GM_SEARCHABLE_SEARCH_BACKWARDS) { - gtk_text_buffer_get_end_iter(buffer, &end); + // For editables, search from the insertion position + if (gtk_text_view_get_editable(text_view)) { + gtk_text_buffer_get_iter_at_mark(buffer, &end, + gtk_text_buffer_get_insert(buffer)); } else { - gtk_text_buffer_get_start_iter(buffer, &end); + // For non editables, search from start (or end, depending on + // the search direction + if (flags & GM_SEARCHABLE_SEARCH_FORWARDS) { + gtk_text_buffer_get_start_iter(buffer, &end); + } else { + gtk_text_buffer_get_end_iter(buffer, &end); + } } start = end; @@ -98,6 +106,46 @@ gm_searchable_text_view_find_first(GtkTextView *text_view, return FALSE; } +gboolean +gm_searchable_text_view_replace(GtkTextView *text_view, gchar const *replace) { + GtkTextBuffer *buffer = NULL; + GtkTextIter end, start; + + buffer = gtk_text_view_get_buffer(text_view); + + if (buffer) { + if (!gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) { + return FALSE; + } else { + gtk_text_buffer_begin_user_action(buffer); + gtk_text_buffer_delete(buffer, &start, &end); + gtk_text_buffer_insert(buffer, &start, replace, -1); + gtk_text_buffer_end_user_action(buffer); + + return TRUE; + } + } else { + return FALSE; + } +} + +gboolean +gm_searchable_text_view_replace_all(GtkTextView *text_view, gchar const *str, + gchar const *replace, GmSearchableSearchFlags flags) { + gboolean found = gm_searchable_text_view_find_first(text_view, str, flags); + + if (found) { + while (found) { + gm_searchable_text_view_replace(text_view, replace); + found = gm_searchable_text_view_find_next(text_view, str, flags); + } + } else { + return FALSE; + } + + return TRUE; +} + GtkTextView * gm_searchable_interface_get_text_view(GmSearchable *self, GmSearchableInterface *iface) { @@ -191,3 +239,76 @@ gm_searchable_find_next(GmSearchable *self, const gchar *str, return (* iface->find_next) (self, str, flags); } + +gboolean +gm_searchable_can_replace(GmSearchable *self) { + GmSearchableInterface *iface; + GtkTextView *text_view; + + g_return_val_if_fail(GM_IS_SEARCHABLE(self), FALSE); + + iface = GM_SEARCHABLE_GET_INTERFACE(self); + + g_return_val_if_fail(iface != NULL, FALSE); + + if (iface->replace == NULL || iface->replace_all == NULL) { + text_view = gm_searchable_interface_get_text_view(self, iface); + if (text_view != NULL && gtk_text_view_get_editable(text_view)) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } +} + +gboolean +gm_searchable_replace(GmSearchable *self, const gchar *replace) { + GmSearchableInterface *iface; + GtkTextView *text_view; + + g_return_val_if_fail(GM_IS_SEARCHABLE(self), FALSE); + + iface = GM_SEARCHABLE_GET_INTERFACE(self); + + g_return_val_if_fail(iface != NULL, FALSE); + + if (iface->replace == NULL) { + text_view = gm_searchable_interface_get_text_view(self, iface); + + if (text_view && gtk_text_view_get_editable(text_view)) { + return gm_searchable_text_view_replace(text_view, replace, flags); + } else { + g_return_val_if_reached(FALSE); + } + } + + return (* iface->replace) (self, replace, flags); +} + +gboolean +gm_searchable_replace_all(GmSearchable *self, gchar const *str, + gchar const *replace, GmSearchableSearchFlags flags) { + GmSearchableInterface *iface; + GtkTextView *text_view; + + g_return_val_if_fail(GM_IS_SEARCHABLE(self), FALSE); + + iface = GM_SEARCHABLE_GET_INTERFACE(self); + + g_return_val_if_fail(iface != NULL, FALSE); + + if (iface->replace_all == NULL) { + text_view = gm_searchable_interface_get_text_view(self, iface); + + if (text_view && gtk_text_view_get_editable(text_view)) { + return gm_searchable_text_view_replace_all(text_view, str, replace, + flags); + } else { + g_return_val_if_reached(FALSE); + } + } + + return (* iface->replace_all) (self, str, replace, flags); +} diff --git a/gnoemoe/widgets/gm-searchable.h b/gnoemoe/widgets/gm-searchable.h index f48ce02..821c368 100644 --- a/gnoemoe/widgets/gm-searchable.h +++ b/gnoemoe/widgets/gm-searchable.h @@ -31,6 +31,10 @@ struct _GmSearchableInterface { GmSearchableSearchFlags flags); gboolean (* find_next) (GmSearchable *self, gchar const *str, GmSearchableSearchFlags flags); + + gboolean (* replace) (GmSearchable *self, gchar const *replace); + gboolean (* replace_all) (GmSearchable *self, gchar const *str, + gchar const *replace, GmSearchableSearchFlags flags); }; GType gm_searchable_get_type(); @@ -41,5 +45,11 @@ gboolean gm_searchable_find_first(GmSearchable *self, const gchar *str, GmSearchableSearchFlags flags); gboolean gm_searchable_find_next(GmSearchable *self, const gchar *str, GmSearchableSearchFlags flags); + +gboolean gm_searchable_can_replace(GmSearchable *self); +gboolean gm_searchable_replace(GmSearchable *self, gchar const *str, + GmSearchableSearchFlags flags); +gboolean gm_searchable_replace_all(GmSearchable *self, gchar const *str, + GmSearchableSearchFlags flags); #endif /* __GM_SEARCHABLE_H__ */