From 7e4c58c56331f0a6f98c9ac950135041d8578f97 Mon Sep 17 00:00:00 2001 From: Ignacio Etcheverry Date: Mon, 30 May 2016 18:15:41 +0200 Subject: Fixed and improved search bar - Search no longer selects the results - Return focus to the text editor when hiding the bar - Fix connecting to invalid signal - Update/redraw the text editor after searching --- tools/editor/code_editor.cpp | 200 +++++++++++++++++++++++++------------------ tools/editor/code_editor.h | 17 ++-- 2 files changed, 128 insertions(+), 89 deletions(-) (limited to 'tools') diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp index a9e31a6561..f62209fafa 100644 --- a/tools/editor/code_editor.cpp +++ b/tools/editor/code_editor.cpp @@ -122,82 +122,30 @@ void FindReplaceBar::_unhandled_input(const InputEvent &p_event) { } } -bool FindReplaceBar::_search(bool p_include_current, bool p_backwards) { +bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) { + int line, col; String text=get_search_text(); - uint32_t flags=0; - - if (is_whole_words()) - flags|=TextEdit::SEARCH_WHOLE_WORDS; - if (is_case_sensitive()) - flags|=TextEdit::SEARCH_MATCH_CASE; - if (p_backwards) - flags|=TextEdit::SEARCH_BACKWARDS; - - int line=text_edit->cursor_get_line(); - int col=text_edit->cursor_get_column(); - - if (text_edit->is_selection_active() && !replace_all_mode) { - line = text_edit->get_selection_from_line(); - col = text_edit->get_selection_from_column(); - } - - bool cursor_at_result=false; - - if (line==current_result_line && col>=current_result_col && col<=current_result_col+text.length()) { - col=current_result_col; - cursor_at_result=true; - } - - if (!p_include_current) { - if (p_backwards) { - col-=text.length(); - if (col<0) { - line-=1; - if (line<0) - line=text_edit->get_line_count()-1; - col=text_edit->get_line(line).length(); - } - } else if (cursor_at_result) { - col+=text.length(); - if (col>text_edit->get_line(line).length()) { - line+=1; - if (line>=text_edit->get_line_count()) - line=0; - col=0; - } - } - } - bool found = text_edit->search(text,flags,line,col,line,col); + bool found=text_edit->search(text,p_flags,p_from_line,p_from_col,line,col); - if (!found) { - if (p_backwards) { - line = text_edit->get_line_count()-1; - col = text_edit->get_line(line).length()-1; - } else { - line = 0; - col = 0; + if (found) { + if (!preserve_cursor) { + text_edit->cursor_set_line(line); + text_edit->cursor_set_column(col+text.length()); } - found = text_edit->search(text,flags,line,col,line,col); - } - - if (found) { - text_edit->cursor_set_line(line); - text_edit->cursor_set_column(p_backwards?col:col+text.length()); - text_edit->select(line,col,line,col+text.length()); text_edit->set_search_text(text); - text_edit->set_search_flags(flags); + text_edit->set_search_flags(p_flags); text_edit->set_current_search_result(line,col); - current_result_line = line; - current_result_col = col; + result_line=line; + result_col=col; set_error(""); } else { - current_result_line = -1; - current_result_col = -1; + result_line=-1; + result_col=-1; text_edit->set_search_text(""); set_error(text.empty()?"":TTR("No Matches")); } @@ -207,8 +155,13 @@ bool FindReplaceBar::_search(bool p_include_current, bool p_backwards) { void FindReplaceBar::_replace() { - if (text_edit->get_selection_text()==get_search_text()) { + if (result_line!=-1 && result_col!=-1) { + text_edit->begin_complex_operation(); + + text_edit->select(result_line,result_col,result_line,result_col+get_search_text().length()); text_edit->insert_text_at_cursor(get_replace_text()); + + text_edit->end_complex_operation(); } search_current(); @@ -232,28 +185,26 @@ void FindReplaceBar::_replace_all() { text_edit->cursor_set_line(0); text_edit->cursor_set_column(0); + int search_text_len=get_search_text().length(); int rc=0; replace_all_mode = true; text_edit->begin_complex_operation(); - while(_search(false)) { - - if (!text_edit->is_selection_active()) { - // search selects - break; - } + while (search_next()) { // replace area - Point2i match_from(text_edit->get_selection_from_line(),text_edit->get_selection_from_column()); - Point2i match_to(text_edit->get_selection_to_line(),text_edit->get_selection_to_column()); + Point2i match_from(result_line,result_col); + Point2i match_to(result_line,result_col+search_text_len); if (match_from < prev_match) break; // done prev_match=match_to; + text_edit->select(result_line,result_col,result_line,match_to.y); + if (selection_enabled && is_selection_only()) { if (match_fromselection_end) @@ -264,7 +215,7 @@ void FindReplaceBar::_replace_all() { if (match_to.x==selection_end.x) selection_end.y+=get_replace_text().length() - get_search_text().length(); } else { - //just replace + // just replace text_edit->insert_text_at_cursor(get_replace_text()); } @@ -290,26 +241,96 @@ void FindReplaceBar::_replace_all() { set_error(vformat(TTR("Replaced %d Ocurrence(s)."), rc)); } -void FindReplaceBar::search_current() { +void FindReplaceBar::_get_search_from(int& r_line, int& r_col) { + + r_line=text_edit->cursor_get_line(); + r_col=text_edit->cursor_get_column(); + + if (text_edit->is_selection_active() && !replace_all_mode) { + r_line=text_edit->get_selection_from_line(); + r_col=text_edit->get_selection_to_column(); + } - _search(true); + if (r_line==result_line && r_col>=result_col && r_col<=result_col+get_search_text().length()) { + r_col=result_col; + } } -void FindReplaceBar::search_prev() { +bool FindReplaceBar::search_current() { + + uint32_t flags=0; - _search(false, true); + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + + int line, col; + _get_search_from(line, col); + + return _search(flags,line,col); } -void FindReplaceBar::search_next() { +bool FindReplaceBar::search_prev() { - _search(); + uint32_t flags=0; + String text = get_search_text(); + + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + + flags|=TextEdit::SEARCH_BACKWARDS; + + int line, col; + _get_search_from(line, col); + + col-=text.length(); + if (col<0) { + line-=1; + if (line<0) + line=text_edit->get_line_count()-1; + col=text_edit->get_line(line).length(); + } + + return _search(flags,line,col); +} + +bool FindReplaceBar::search_next() { + + uint32_t flags=0; + String text = get_search_text(); + + if (is_whole_words()) + flags|=TextEdit::SEARCH_WHOLE_WORDS; + if (is_case_sensitive()) + flags|=TextEdit::SEARCH_MATCH_CASE; + + int line, col; + _get_search_from(line, col); + + if (line==result_line && col==result_col) { + col+=text.length(); + if (col>text_edit->get_line(line).length()) { + line+=1; + if (line>=text_edit->get_line_count()) + line=0; + col=0; + } + } + + return _search(flags,line,col); } void FindReplaceBar::_hide_bar() { + if (replace_text->has_focus() || search_text->has_focus()) + text_edit->grab_focus(); + text_edit->set_search_text(""); - current_result_line = -1; - current_result_col = -1; + result_line = -1; + result_col = -1; replace_hbc->hide(); replace_options_hbc->hide(); hide(); @@ -354,6 +375,15 @@ void FindReplaceBar::_search_options_changed(bool p_pressed) { search_current(); } +void FindReplaceBar::_editor_text_changed() { + + if (is_visible()) { + preserve_cursor=true; + search_current(); + preserve_cursor=false; + } +} + void FindReplaceBar::_search_text_changed(const String& p_text) { search_current(); @@ -397,13 +427,14 @@ void FindReplaceBar::set_error(const String &p_label) { void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) { text_edit = p_text_edit; - text_edit->connect("_text_changed",this,"_search_text_changed",varray(String())); + text_edit->connect("text_changed",this,"_editor_text_changed"); } void FindReplaceBar::_bind_methods() { ObjectTypeDB::bind_method("_unhandled_input",&FindReplaceBar::_unhandled_input); + ObjectTypeDB::bind_method("_editor_text_changed",&FindReplaceBar::_editor_text_changed); ObjectTypeDB::bind_method("_search_text_changed",&FindReplaceBar::_search_text_changed); ObjectTypeDB::bind_method("_search_text_entered",&FindReplaceBar::_search_text_entered); ObjectTypeDB::bind_method("_search_current",&FindReplaceBar::search_current); @@ -419,6 +450,9 @@ void FindReplaceBar::_bind_methods() { FindReplaceBar::FindReplaceBar() { + replace_all_mode=false; + preserve_cursor=false; + text_vbc = memnew(VBoxContainer); add_child(text_vbc); diff --git a/tools/editor/code_editor.h b/tools/editor/code_editor.h index 52a36c979d..2e1bf46c02 100644 --- a/tools/editor/code_editor.h +++ b/tools/editor/code_editor.h @@ -83,13 +83,18 @@ class FindReplaceBar : public HBoxContainer { TextEdit *text_edit; - int current_result_line; - int current_result_col; + int result_line; + int result_col; bool replace_all_mode; + bool preserve_cursor; + + void _get_search_from(int& r_line, int& r_col); void _show_search(); void _hide_bar(); + + void _editor_text_changed(); void _search_options_changed(bool p_pressed); void _search_text_changed(const String& p_text); void _search_text_entered(const String& p_text); @@ -98,7 +103,7 @@ protected: void _notification(int p_what); void _unhandled_input(const InputEvent &p_event); - bool _search(bool p_include_current=false, bool p_backwards=false); + bool _search(uint32_t p_flags, int p_from_line, int p_from_col); void _replace(); void _replace_all(); @@ -119,9 +124,9 @@ public: void popup_search(); void popup_replace(); - void search_current(); - void search_prev(); - void search_next(); + bool search_current(); + bool search_prev(); + bool search_next(); FindReplaceBar(); }; -- cgit v1.2.3