[Core] Add case-insensitive `String::containsn`
This commit is contained in:
parent
281fe39929
commit
b4c6cc7d82
|
@ -429,6 +429,8 @@ public:
|
|||
_FORCE_INLINE_ bool is_empty() const { return length() == 0; }
|
||||
_FORCE_INLINE_ bool contains(const char *p_str) const { return find(p_str) != -1; }
|
||||
_FORCE_INLINE_ bool contains(const String &p_str) const { return find(p_str) != -1; }
|
||||
_FORCE_INLINE_ bool containsn(const char *p_str) const { return findn(p_str) != -1; }
|
||||
_FORCE_INLINE_ bool containsn(const String &p_str) const { return findn(p_str) != -1; }
|
||||
|
||||
// path functions
|
||||
bool is_absolute_path() const;
|
||||
|
|
|
@ -1707,6 +1707,7 @@ static void _register_variant_builtin_methods() {
|
|||
bind_string_method(sha256_buffer, sarray(), varray());
|
||||
bind_string_method(is_empty, sarray(), varray());
|
||||
bind_string_methodv(contains, static_cast<bool (String::*)(const String &) const>(&String::contains), sarray("what"), varray());
|
||||
bind_string_methodv(containsn, static_cast<bool (String::*)(const String &) const>(&String::containsn), sarray("what"), varray());
|
||||
|
||||
bind_string_method(is_absolute_path, sarray(), varray());
|
||||
bind_string_method(is_relative_path, sarray(), varray());
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
[/codeblock]
|
||||
</description>
|
||||
</method>
|
||||
<method name="contains" qualifiers="const" keywords="includes, has">
|
||||
<method name="contains" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="what" type="String" />
|
||||
<description>
|
||||
|
@ -142,7 +142,15 @@
|
|||
GD.Print("team".Contains("I")); // Prints false
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
If you need to know where [param what] is within the string, use [method find].
|
||||
If you need to know where [param what] is within the string, use [method find]. See also [method containsn].
|
||||
</description>
|
||||
</method>
|
||||
<method name="containsn" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="what" type="String" />
|
||||
<description>
|
||||
Returns [code]true[/code] if the string contains [param what], [b]ignoring case[/b].
|
||||
If you need to know where [param what] is within the string, use [method findn]. See also [method contains].
|
||||
</description>
|
||||
</method>
|
||||
<method name="count" qualifiers="const">
|
||||
|
|
|
@ -126,7 +126,15 @@
|
|||
GD.Print("team".Contains("I")); // Prints false
|
||||
[/csharp]
|
||||
[/codeblocks]
|
||||
If you need to know where [param what] is within the string, use [method find].
|
||||
If you need to know where [param what] is within the string, use [method find]. See also [method containsn].
|
||||
</description>
|
||||
</method>
|
||||
<method name="containsn" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="what" type="String" />
|
||||
<description>
|
||||
Returns [code]true[/code] if the string contains [param what], [b]ignoring case[/b].
|
||||
If you need to know where [param what] is within the string, use [method findn]. See also [method contains].
|
||||
</description>
|
||||
</method>
|
||||
<method name="count" qualifiers="const">
|
||||
|
|
|
@ -157,7 +157,7 @@ Config::Config() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (renderer.findn(v) != -1) {
|
||||
if (renderer.containsn(v)) {
|
||||
use_depth_prepass = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7122,7 +7122,7 @@ void AnimationTrackEditor::_pick_track_select_recursive(TreeItem *p_item, const
|
|||
NodePath np = p_item->get_metadata(0);
|
||||
Node *node = get_node_or_null(np);
|
||||
|
||||
if (node && !p_filter.is_empty() && ((String)node->get_name()).findn(p_filter) != -1) {
|
||||
if (node && !p_filter.is_empty() && ((String)node->get_name()).containsn(p_filter)) {
|
||||
p_select_candidates.push_back(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ List<MethodInfo> ConnectDialog::_filter_method_list(const List<MethodInfo> &p_me
|
|||
List<MethodInfo> ret;
|
||||
|
||||
for (const MethodInfo &mi : p_methods) {
|
||||
if (!p_search_string.is_empty() && mi.name.findn(p_search_string) == -1) {
|
||||
if (!p_search_string.is_empty() && !mi.name.containsn(p_search_string)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ private:
|
|||
if (p_path.contains("\\")) {
|
||||
String project_path = ProjectSettings::get_singleton()->get_resource_path();
|
||||
String path = p_path.replace("\\", "/");
|
||||
return path.findn(project_path) != -1;
|
||||
return path.containsn(project_path);
|
||||
}
|
||||
return p_path.begins_with(ProjectSettings::get_singleton()->get_resource_path());
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
bool EditorHelpSearch::_all_terms_in_name(const Vector<String> &p_terms, const String &p_name) const {
|
||||
for (int i = 0; i < p_terms.size(); i++) {
|
||||
if (p_name.findn(p_terms[i]) < 0) {
|
||||
if (!p_name.containsn(p_terms[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ Dictionary EditorHelpSearch::_native_search_cb(const String &p_search_string, in
|
|||
if (class_doc.name.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
if (class_doc.name.findn(term) > -1) {
|
||||
if (class_doc.name.containsn(term)) {
|
||||
ret[vformat("class_name:%s", class_doc.name)] = class_doc.name;
|
||||
}
|
||||
if (term.length() > 1 || term == "@") {
|
||||
|
@ -746,7 +746,7 @@ bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String
|
|||
if (search_flags & SEARCH_CASE_SENSITIVE) {
|
||||
return p_string.find(p_term) > -1;
|
||||
} else {
|
||||
return p_string.findn(p_term) > -1;
|
||||
return p_string.containsn(p_term);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "scene/resources/style_box_flat.h"
|
||||
|
||||
bool EditorInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
|
||||
if (p_property_path.findn(p_filter) != -1) {
|
||||
if (p_property_path.containsn(p_filter)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -322,7 +322,7 @@ void EditorLog::_rebuild_log() {
|
|||
bool EditorLog::_check_display_message(LogMessage &p_message) {
|
||||
bool filter_active = type_filter_map[p_message.type]->is_active();
|
||||
String search_text = search_box->get_text();
|
||||
bool search_match = search_text.is_empty() || p_message.text.findn(search_text) > -1;
|
||||
bool search_match = search_text.is_empty() || p_message.text.containsn(search_text);
|
||||
return filter_active && search_match;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "editor/themes/editor_scale.h"
|
||||
|
||||
static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
|
||||
if (p_property_path.findn(p_filter) != -1) {
|
||||
if (p_property_path.containsn(p_filter)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ static bool _teststr(const String &p_what, const String &p_str) {
|
|||
what = what.substr(0, what.length() - 1);
|
||||
}
|
||||
|
||||
if (what.findn("$" + p_str) != -1) { //blender and other stuff
|
||||
if (what.containsn("$" + p_str)) { // Blender and other stuff.
|
||||
return true;
|
||||
}
|
||||
if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
|
||||
|
@ -410,7 +410,7 @@ static String _fixstr(const String &p_what, const String &p_str) {
|
|||
|
||||
String end = p_what.substr(what.length(), p_what.length() - what.length());
|
||||
|
||||
if (what.findn("$" + p_str) != -1) { //blender and other stuff
|
||||
if (what.containsn("$" + p_str)) { // Blender and other stuff.
|
||||
return what.replace("$" + p_str, "") + end;
|
||||
}
|
||||
if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
|
||||
|
|
|
@ -285,7 +285,7 @@ void InputEventConfigurationDialog::_update_input_list() {
|
|||
for (int i = 0; i < keycode_get_count(); i++) {
|
||||
String name = keycode_get_name_by_index(i);
|
||||
|
||||
if (!search_term.is_empty() && name.findn(search_term) == -1) {
|
||||
if (!search_term.is_empty() && !name.containsn(search_term)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ void InputEventConfigurationDialog::_update_input_list() {
|
|||
mb->set_button_index(mouse_buttons[i]);
|
||||
String desc = EventListenerLineEdit::get_event_text(mb, false);
|
||||
|
||||
if (!search_term.is_empty() && desc.findn(search_term) == -1) {
|
||||
if (!search_term.is_empty() && !desc.containsn(search_term)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ void InputEventConfigurationDialog::_update_input_list() {
|
|||
joyb->set_button_index((JoyButton)i);
|
||||
String desc = EventListenerLineEdit::get_event_text(joyb, false);
|
||||
|
||||
if (!search_term.is_empty() && desc.findn(search_term) == -1) {
|
||||
if (!search_term.is_empty() && !desc.containsn(search_term)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ void InputEventConfigurationDialog::_update_input_list() {
|
|||
joym->set_axis_value(direction);
|
||||
String desc = EventListenerLineEdit::get_event_text(joym, false);
|
||||
|
||||
if (!search_term.is_empty() && desc.findn(search_term) == -1) {
|
||||
if (!search_term.is_empty() && !desc.containsn(search_term)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -374,7 +374,7 @@ void ScriptEditorQuickOpen::_update_search() {
|
|||
|
||||
for (int i = 0; i < functions.size(); i++) {
|
||||
String file = functions[i];
|
||||
if ((search_box->get_text().is_empty() || file.findn(search_box->get_text()) != -1)) {
|
||||
if ((search_box->get_text().is_empty() || file.containsn(search_box->get_text()))) {
|
||||
TreeItem *ti = search_options->create_item(root);
|
||||
ti->set_text(0, file);
|
||||
if (root->get_first_child() == ti) {
|
||||
|
|
|
@ -106,7 +106,7 @@ void ThemeItemImportTree::_update_items_tree() {
|
|||
type_node->set_checked(IMPORT_ITEM_DATA, false);
|
||||
type_node->set_editable(IMPORT_ITEM_DATA, true);
|
||||
|
||||
bool is_matching_filter = (filter_text.is_empty() || type_name.findn(filter_text) > -1);
|
||||
bool is_matching_filter = (filter_text.is_empty() || type_name.containsn(filter_text));
|
||||
bool has_filtered_items = false;
|
||||
|
||||
for (int i = 0; i < Theme::DATA_TYPE_MAX; i++) {
|
||||
|
@ -120,7 +120,7 @@ void ThemeItemImportTree::_update_items_tree() {
|
|||
|
||||
for (const StringName &F : names) {
|
||||
String item_name = (String)F;
|
||||
bool is_item_matching_filter = (item_name.findn(filter_text) > -1);
|
||||
bool is_item_matching_filter = item_name.containsn(filter_text);
|
||||
if (!filter_text.is_empty() && !is_matching_filter && !is_item_matching_filter) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1957,7 +1957,7 @@ void VisualShaderEditor::_update_options_menu() {
|
|||
}
|
||||
|
||||
for (int i = 0; i < add_options.size(); i++) {
|
||||
if (!use_filter || add_options[i].name.findn(filter) != -1) {
|
||||
if (!use_filter || add_options[i].name.containsn(filter)) {
|
||||
// port type filtering
|
||||
if (members_output_port_type != VisualShaderNode::PORT_TYPE_MAX || members_input_port_type != VisualShaderNode::PORT_TYPE_MAX) {
|
||||
Ref<VisualShaderNode> vsn;
|
||||
|
|
|
@ -545,7 +545,7 @@ void ProjectList::sort_projects() {
|
|||
}
|
||||
|
||||
// When searching, display projects whose name or path contain the search term and whose tags match the searched tags.
|
||||
item_visible = !missing_tags && (search_term.is_empty() || item.project_name.findn(search_term) != -1 || search_path.findn(search_term) != -1);
|
||||
item_visible = !missing_tags && (search_term.is_empty() || item.project_name.containsn(search_term) || search_path.containsn(search_term));
|
||||
}
|
||||
|
||||
item.control->set_visible(item_visible);
|
||||
|
|
|
@ -190,7 +190,7 @@ void PropertySelector::_update_search() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!search_box->get_text().is_empty() && E.name.findn(search_text) == -1) {
|
||||
if (!search_box->get_text().is_empty() && !E.name.containsn(search_text)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ void PropertySelector::_update_search() {
|
|||
item->set_metadata(0, E.name);
|
||||
item->set_icon(0, type_icons[E.type]);
|
||||
|
||||
if (!found && !search_box->get_text().is_empty() && E.name.findn(search_text) != -1) {
|
||||
if (!found && !search_box->get_text().is_empty() && E.name.containsn(search_text)) {
|
||||
item->select(0);
|
||||
found = true;
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ void PropertySelector::_update_search() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!search_box->get_text().is_empty() && name.findn(search_text) == -1) {
|
||||
if (!search_box->get_text().is_empty() && !name.containsn(search_text)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -330,7 +330,7 @@ void PropertySelector::_update_search() {
|
|||
item->set_metadata(0, name);
|
||||
item->set_selectable(0, true);
|
||||
|
||||
if (!found && !search_box->get_text().is_empty() && name.findn(search_text) != -1) {
|
||||
if (!found && !search_box->get_text().is_empty() && name.containsn(search_text)) {
|
||||
item->select(0);
|
||||
found = true;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ void EditorSceneExporterGLTFSettings::_get_property_list(List<PropertyInfo> *p_l
|
|||
for (PropertyInfo prop : _property_list) {
|
||||
if (prop.name == "lossy_quality") {
|
||||
String image_format = get("image_format");
|
||||
bool is_image_format_lossy = image_format == "JPEG" || image_format.findn("Lossy") != -1;
|
||||
bool is_image_format_lossy = image_format == "JPEG" || image_format.containsn("Lossy");
|
||||
prop.usage = is_image_format_lossy ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_STORAGE;
|
||||
}
|
||||
p_list->push_back(prop);
|
||||
|
|
|
@ -81,7 +81,7 @@ void ReplicationEditor::_pick_node_select_recursive(TreeItem *p_item, const Stri
|
|||
NodePath np = p_item->get_metadata(0);
|
||||
Node *node = get_node(np);
|
||||
|
||||
if (!p_filter.is_empty() && ((String)node->get_name()).findn(p_filter) != -1) {
|
||||
if (!p_filter.is_empty() && ((String)node->get_name()).containsn(p_filter)) {
|
||||
p_select_candidates.push_back(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
|
|||
String new_request;
|
||||
|
||||
for (const String &E : rheaders) {
|
||||
if (E.findn("Location: ") != -1) {
|
||||
if (E.containsn("Location: ")) {
|
||||
new_request = E.substr(9, E.length()).strip_edges();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -297,6 +297,19 @@ TEST_CASE("[String] Contains") {
|
|||
CHECK(!s.contains(String("\\char_test.tscn")));
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Contains case insensitive") {
|
||||
String s = "C:\\Godot\\project\\string_test.tscn";
|
||||
CHECK(s.containsn("Godot"));
|
||||
CHECK(s.containsn("godot"));
|
||||
CHECK(s.containsn(String("Project\\string_test")));
|
||||
CHECK(s.containsn(String("\\string_Test.tscn")));
|
||||
|
||||
CHECK(!s.containsn("Godoh"));
|
||||
CHECK(!s.containsn("godoh"));
|
||||
CHECK(!s.containsn(String("project\\string test")));
|
||||
CHECK(!s.containsn(String("\\char_test.tscn")));
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Test chr") {
|
||||
CHECK(String::chr('H') == "H");
|
||||
CHECK(String::chr(0x3012)[0] == 0x3012);
|
||||
|
@ -376,7 +389,7 @@ TEST_CASE("[String] Find") {
|
|||
MULTICHECK_STRING_INT_EQ(s, rfind, "", 15, -1);
|
||||
}
|
||||
|
||||
TEST_CASE("[String] Find no case") {
|
||||
TEST_CASE("[String] Find case insensitive") {
|
||||
String s = "Pretty Whale Whale";
|
||||
MULTICHECK_STRING_EQ(s, findn, "WHA", 7);
|
||||
MULTICHECK_STRING_INT_EQ(s, findn, "WHA", 9, 13);
|
||||
|
|
Loading…
Reference in New Issue