Added replacing
This commit is contained in:
parent
00f73b51a2
commit
cca58988b2
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Reference in New Issue