diff --git a/moo/mooedit/mooeditwindow.c b/moo/mooedit/mooeditwindow.c index 20a1276d..e77b8634 100644 --- a/moo/mooedit/mooeditwindow.c +++ b/moo/mooedit/mooeditwindow.c @@ -196,6 +196,9 @@ static void moo_edit_window_next_tab (MooEditWindow *window); static void moo_edit_window_toggle_bookmark (MooEditWindow *window); static void moo_edit_window_next_bookmark (MooEditWindow *window); static void moo_edit_window_prev_bookmark (MooEditWindow *window); +static void moo_edit_window_next_ph (MooEditWindow *window); +static void moo_edit_window_prev_ph (MooEditWindow *window); + #if GTK_CHECK_VERSION(2,10,0) static void moo_edit_window_page_setup (MooEditWindow *window); @@ -587,6 +590,24 @@ moo_edit_window_class_init (MooEditWindowClass *klass) "condition::visible", "has-open-document", NULL); + moo_window_class_new_action (window_class, "NextPlaceholder", + "name", "Next Placeholder", + "label", "Next Placeholder", + "tooltip", "Go to next placeholder", + "icon-stock-id", GTK_STOCK_GO_FORWARD, + "closure-callback", moo_edit_window_next_ph, + "condition::visible", "has-open-document", + NULL); + + moo_window_class_new_action (window_class, "PrevPlaceholder", + "name", "Previous Placeholder", + "label", "Previous Placeholder", + "tooltip", "Go to previous placeholder", + "icon-stock-id", GTK_STOCK_GO_BACK, + "closure-callback", moo_edit_window_prev_ph, + "condition::visible", "has-open-document", + NULL); + moo_window_class_new_action (window_class, "QuickSearch", "name", "Quick Search", "label", "Quick Search", @@ -1065,6 +1086,24 @@ moo_edit_window_prev_bookmark (MooEditWindow *window) } +static void +moo_edit_window_next_ph (MooEditWindow *window) +{ + MooEdit *doc = moo_edit_window_get_active_doc (window); + g_return_if_fail (doc != NULL); + moo_text_view_next_placeholder (MOO_TEXT_VIEW (doc)); +} + + +static void +moo_edit_window_prev_ph (MooEditWindow *window) +{ + MooEdit *doc = moo_edit_window_get_active_doc (window); + g_return_if_fail (doc != NULL); + moo_text_view_prev_placeholder (MOO_TEXT_VIEW (doc)); +} + + #if GTK_CHECK_VERSION(2,10,0) static void moo_edit_window_page_setup (MooEditWindow *window) diff --git a/moo/mooedit/mooplaceholder.h b/moo/mooedit/mooplaceholder.h index 7e8a1caf..7964c8c6 100644 --- a/moo/mooedit/mooplaceholder.h +++ b/moo/mooedit/mooplaceholder.h @@ -38,6 +38,9 @@ G_BEGIN_DECLS #define MOO_IS_TEXT_ANCHOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_TEXT_ANCHOR)) #define MOO_TEXT_ANCHOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_TEXT_ANCHOR, MooTextAnchorClass)) +#define MOO_TEXT_UNKNOWN_CHAR 0xFFFC +#define MOO_TEXT_UNKNOWN_CHAR_S "\xEF\xBF\xBC" + typedef struct _MooPlaceholder MooPlaceholder; typedef struct _MooPlaceholderPrivate MooPlaceholderPrivate; diff --git a/moo/mooedit/mootextview.c b/moo/mooedit/mootextview.c index 3ddfc709..99f0a78c 100644 --- a/moo/mooedit/mootextview.c +++ b/moo/mooedit/mootextview.c @@ -1928,15 +1928,8 @@ moo_text_view_draw_placeholders (GtkTextView *text_view, while (gtk_text_iter_compare (&iter, end) < 0) { - if (gtk_text_iter_get_char (&iter) == 0xFFFC) - { - GtkTextChildAnchor *anchor; - - anchor = gtk_text_iter_get_child_anchor (&iter); - - if (MOO_IS_TEXT_ANCHOR (anchor)) - draw_placeholder (text_view, event, &iter); - } + if (moo_text_view_has_placeholder_at_iter (MOO_TEXT_VIEW (text_view), &iter)) + draw_placeholder (text_view, event, &iter); if (!gtk_text_iter_forward_char (&iter)) break; @@ -4121,5 +4114,91 @@ has_placeholders (MooTextView *view) } -gboolean moo_text_view_next_placeholder (MooTextView *view); -gboolean moo_text_view_prev_placeholder (MooTextView *view); +gboolean +moo_text_view_has_placeholder_at_iter (MooTextView *view, + GtkTextIter *iter) +{ + GtkTextChildAnchor *anchor; + + g_return_val_if_fail (MOO_IS_TEXT_VIEW (view), FALSE); + g_return_val_if_fail (iter != NULL, FALSE); + + if (gtk_text_iter_get_char (iter) != MOO_TEXT_UNKNOWN_CHAR) + return FALSE; + + anchor = gtk_text_iter_get_child_anchor (iter); + return MOO_IS_TEXT_ANCHOR (anchor) && + MOO_IS_PLACEHOLDER (MOO_TEXT_ANCHOR(anchor)->widget); +} + + +gboolean +moo_text_view_next_placeholder (MooTextView *view) +{ + GtkTextIter start, end, match_start, match_end; + GtkTextBuffer *buffer; + + g_return_val_if_fail (MOO_IS_TEXT_VIEW (view), FALSE); + + buffer = get_buffer (view); + + if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) + { + if (moo_text_view_has_placeholder_at_iter (view, &start) && + gtk_text_iter_get_line_offset (&end) == gtk_text_iter_get_line_offset (&start) + 1) + start = end; + else + moo_text_view_get_cursor (view, &start); + } + + while (gtk_text_iter_forward_search (&start, MOO_TEXT_UNKNOWN_CHAR_S, + 0, &match_start, &match_end, NULL)) + { + if (moo_text_view_has_placeholder_at_iter (view, &match_start)) + { + gtk_text_buffer_select_range (buffer, &match_end, &match_start); + return TRUE; + } + else + { + start = match_end; + } + } + + return FALSE; +} + + +gboolean +moo_text_view_prev_placeholder (MooTextView *view) +{ + GtkTextIter start, end, match_start, match_end; + GtkTextBuffer *buffer; + + g_return_val_if_fail (MOO_IS_TEXT_VIEW (view), FALSE); + + buffer = get_buffer (view); + + if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end) && + !moo_text_view_has_placeholder_at_iter (view, &start) && + gtk_text_iter_get_line_offset (&end) != gtk_text_iter_get_line_offset (&start) + 1) + { + moo_text_view_get_cursor (view, &start); + } + + while (gtk_text_iter_backward_search (&start, MOO_TEXT_UNKNOWN_CHAR_S, + 0, &match_start, &match_end, NULL)) + { + if (moo_text_view_has_placeholder_at_iter (view, &match_start)) + { + gtk_text_buffer_select_range (buffer, &match_start, &match_end); + return TRUE; + } + else + { + start = match_start; + } + } + + return FALSE; +} diff --git a/moo/mooedit/mootextview.h b/moo/mooedit/mootextview.h index 258c22c6..9f9dd312 100644 --- a/moo/mooedit/mootextview.h +++ b/moo/mooedit/mootextview.h @@ -162,6 +162,8 @@ void moo_text_view_insert_placeholder (MooTextView *view, GtkTextIter *iter); gboolean moo_text_view_next_placeholder (MooTextView *view); gboolean moo_text_view_prev_placeholder (MooTextView *view); +gboolean moo_text_view_has_placeholder_at_iter (MooTextView *view, + GtkTextIter *iter); void moo_text_view_start_quick_search (MooTextView *view); void moo_text_view_stop_quick_search (MooTextView *view); diff --git a/tests/medit-ui.xml b/tests/medit-ui.xml index 1ca559d7..8023d88a 100644 --- a/tests/medit-ui.xml +++ b/tests/medit-ui.xml @@ -54,6 +54,9 @@ + + +