Skip to content

Commit f0eddb8

Browse files
committed
Fix issues searching RichTextLabel when search result is in a table
Fixes for cases where search results would be skipped or repeatedly found involving tables in RichTextLabel: - If previous result was found in last cell of table, earlier cells would be skipped, since the end of the table was reached. Updated to not skip earlier cells when searching in reverse. - When choosing next line to continue from after searching table, the inner line number within the table's cell was added, causing the search to jump forward if not on line 0 in the cell. This could cause lines to get skipped when searching forward, or searching the table again when searching in reverse. Updated to continue from the immediate next line before/after the table. - If a table cell has multiple lines, repeated searching would only include the line where the previous result was found, then jump to the next cell. Updated to search remaining lines in the same cell first.
1 parent c81fd6c commit f0eddb8

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

scene/gui/rich_text_label.cpp

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6591,23 +6591,36 @@ bool RichTextLabel::_is_click_inside_selection() const {
65916591
}
65926592
}
65936593

6594+
bool RichTextLabel::_search_table_cell(ItemTable *p_table, List<Item *>::Element *p_cell, const String &p_string, bool p_reverse_search, int p_from_line) {
6595+
ERR_FAIL_COND_V(p_cell->get()->type != ITEM_FRAME, false); // Children should all be frames.
6596+
ItemFrame *frame = static_cast<ItemFrame *>(p_cell->get());
6597+
if (p_from_line < 0) {
6598+
p_from_line = (int)frame->lines.size() - 1;
6599+
}
6600+
6601+
if (p_reverse_search) {
6602+
for (int i = p_from_line; i >= 0; i--) {
6603+
if (_search_line(frame, i, p_string, -1, p_reverse_search)) {
6604+
return true;
6605+
}
6606+
}
6607+
} else {
6608+
for (int i = p_from_line; i < (int)frame->lines.size(); i++) {
6609+
if (_search_line(frame, i, p_string, 0, p_reverse_search)) {
6610+
return true;
6611+
}
6612+
}
6613+
}
6614+
6615+
return false;
6616+
}
6617+
65946618
bool RichTextLabel::_search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search) {
65956619
List<Item *>::Element *E = p_from;
65966620
while (E != nullptr) {
6597-
ERR_CONTINUE(E->get()->type != ITEM_FRAME); // Children should all be frames.
6598-
ItemFrame *frame = static_cast<ItemFrame *>(E->get());
6599-
if (p_reverse_search) {
6600-
for (int i = (int)frame->lines.size() - 1; i >= 0; i--) {
6601-
if (_search_line(frame, i, p_string, -1, p_reverse_search)) {
6602-
return true;
6603-
}
6604-
}
6605-
} else {
6606-
for (int i = 0; i < (int)frame->lines.size(); i++) {
6607-
if (_search_line(frame, i, p_string, 0, p_reverse_search)) {
6608-
return true;
6609-
}
6610-
}
6621+
int from_line = p_reverse_search ? -1 : 0;
6622+
if (_search_table_cell(p_table, E, p_string, p_reverse_search, from_line)) {
6623+
return true;
66116624
}
66126625
E = p_reverse_search ? E->prev() : E->next();
66136626
}
@@ -6695,7 +6708,8 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
66956708
char_idx = p_search_previous ? -1 : 0;
66966709

66976710
// Next, check to see if the current search result is in a table
6698-
if (selection.from_frame->parent != nullptr && selection.from_frame->parent->type == ITEM_TABLE) {
6711+
bool in_table = selection.from_frame->parent != nullptr && selection.from_frame->parent->type == ITEM_TABLE;
6712+
if (in_table) {
66996713
// Find last search result in table
67006714
ItemTable *parent_table = static_cast<ItemTable *>(selection.from_frame->parent);
67016715
List<Item *>::Element *parent_element = p_search_previous ? parent_table->subitems.back() : parent_table->subitems.front();
@@ -6705,9 +6719,17 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
67056719
ERR_FAIL_NULL_V(parent_element, false);
67066720
}
67076721

6722+
// Search remainder of current cell
6723+
int from_line = p_search_previous ? selection.from_line - 1 : selection.from_line + 1;
6724+
if (from_line >= 0 && _search_table_cell(parent_table, parent_element, p_string, p_search_previous, from_line)) {
6725+
scroll_to_selection();
6726+
queue_redraw();
6727+
return true;
6728+
}
6729+
67086730
// Search remainder of table
67096731
if (!(p_search_previous && parent_element == parent_table->subitems.front()) &&
6710-
parent_element != parent_table->subitems.back()) {
6732+
!(!p_search_previous && parent_element == parent_table->subitems.back())) {
67116733
parent_element = p_search_previous ? parent_element->prev() : parent_element->next(); // Don't want to search current item
67126734
ERR_FAIL_NULL_V(parent_element, false);
67136735

@@ -6720,7 +6742,10 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
67206742
}
67216743
}
67226744

6723-
ending_line = selection.from_frame->line + selection.from_line;
6745+
ending_line = selection.from_frame->line;
6746+
if (!in_table) {
6747+
ending_line += selection.from_line;
6748+
}
67246749
current_line = p_search_previous ? ending_line - 1 : ending_line + 1;
67256750
} else if (p_search_previous) {
67266751
current_line = ending_line;

scene/gui/rich_text_label.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,8 +631,9 @@ class RichTextLabel : public Control {
631631
void _find_click(ItemFrame *p_frame, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr, bool *r_outside = nullptr, bool p_meta = false);
632632

633633
String _get_line_text(ItemFrame *p_frame, int p_line, Selection p_sel) const;
634-
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
634+
bool _search_table_cell(ItemTable *p_table, List<Item *>::Element *p_cell, const String &p_string, bool p_reverse_search, int p_from_line);
635635
bool _search_table(ItemTable *p_table, List<Item *>::Element *p_from, const String &p_string, bool p_reverse_search);
636+
bool _search_line(ItemFrame *p_frame, int p_line, const String &p_string, int p_char_idx, bool p_reverse_search);
636637

637638
float _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, float p_h, int *r_char_offset);
638639
float _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, float p_h);

0 commit comments

Comments
 (0)