Fix of #5202 - Fuzzy Search engine is too fuzzy

* changed evaluation coefficients inside fuzzy_match_recursive
 * don't add markers to the labels before it's used in fuzzy_match_recursive
 + follow-up 78a3d8b63e - added missed fix for one more line (use std::towlower instead of std::tolower for wchar_t) Problem was appearance on Cyrillic languages
This commit is contained in:
YuSanka 2021-01-26 21:32:44 +01:00 committed by enricoturri1966
parent 1158dae587
commit 6f85a7d3fd
2 changed files with 16 additions and 13 deletions

View File

@ -124,11 +124,12 @@ static wxString wrap_string(const wxString& str)
} }
// Mark a string using ColorMarkerStart and ColorMarkerEnd symbols // Mark a string using ColorMarkerStart and ColorMarkerEnd symbols
static std::wstring mark_string(const std::wstring &str, const std::vector<uint16_t> &matches) static std::wstring mark_string(const std::wstring &str, const std::vector<uint16_t> &matches, Preset::Type type, PrinterTechnology pt)
{ {
std::wstring out; std::wstring out;
out += marker_by_type(type, pt);
if (matches.empty()) if (matches.empty())
out = str; out += str;
else { else {
out.reserve(str.size() * 2); out.reserve(str.size() * 2);
if (matches.front() > 0) if (matches.front() > 0)
@ -181,10 +182,11 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
bool full_list = search.empty(); bool full_list = search.empty();
std::wstring sep = L" : "; std::wstring sep = L" : ";
auto get_label = [this, &sep](const Option& opt) auto get_label = [this, &sep](const Option& opt, bool marked = true)
{ {
std::wstring out; std::wstring out;
out += marker_by_type(opt.type, printer_technology); if (marked)
out += marker_by_type(opt.type, printer_technology);
const std::wstring *prev = nullptr; const std::wstring *prev = nullptr;
for (const std::wstring * const s : { for (const std::wstring * const s : {
view_params.category ? &opt.category_local : nullptr, view_params.category ? &opt.category_local : nullptr,
@ -198,10 +200,11 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
return out; return out;
}; };
auto get_label_english = [this, &sep](const Option& opt) auto get_label_english = [this, &sep](const Option& opt, bool marked = true)
{ {
std::wstring out; std::wstring out;
out += marker_by_type(opt.type, printer_technology); if (marked)
out += marker_by_type(opt.type, printer_technology);
const std::wstring*prev = nullptr; const std::wstring*prev = nullptr;
for (const std::wstring * const s : { for (const std::wstring * const s : {
view_params.category ? &opt.category : nullptr, view_params.category ? &opt.category : nullptr,
@ -234,8 +237,8 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
std::wstring wsearch = boost::nowide::widen(search); std::wstring wsearch = boost::nowide::widen(search);
boost::trim_left(wsearch); boost::trim_left(wsearch);
std::wstring label = get_label(opt); std::wstring label = get_label(opt, false);
std::wstring label_english = get_label_english(opt); std::wstring label_english = get_label_english(opt, false);
int score = std::numeric_limits<int>::min(); int score = std::numeric_limits<int>::min();
int score2; int score2;
matches.clear(); matches.clear();
@ -252,8 +255,8 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
matches = std::move(matches2); matches = std::move(matches2);
score = score2; score = score2;
} }
if (score > std::numeric_limits<int>::min()) { if (score > 90/*std::numeric_limits<int>::min()*/) {
label = mark_string(label, matches); label = mark_string(label, matches, opt.type, printer_technology);
label += L" [" + std::to_wstring(score) + L"]";// add score value label += L" [" + std::to_wstring(score) + L"]";// add score value
std::string label_u8 = into_u8(label); std::string label_u8 = into_u8(label);
std::string label_plain = label_u8; std::string label_plain = label_u8;

View File

@ -113,7 +113,7 @@ namespace fts {
bool first_match = true; bool first_match = true;
while (*pattern != '\0' && *str != '\0') { while (*pattern != '\0' && *str != '\0') {
int num_matched = std::tolower(*pattern) == std::tolower(*str) ? 1 : 0; int num_matched = std::towlower(*pattern) == std::towlower(*str) ? 1 : 0;
bool folded_match = false; bool folded_match = false;
if (! num_matched) { if (! num_matched) {
wchar_t tmp[4]; wchar_t tmp[4];
@ -168,11 +168,11 @@ namespace fts {
// Calculate score // Calculate score
if (matched) { if (matched) {
static constexpr int sequential_bonus = 15; // bonus for adjacent matches static constexpr int sequential_bonus = 15; // bonus for adjacent matches
static constexpr int separator_bonus = 30; // bonus if match occurs after a separator static constexpr int separator_bonus = 10/*30*/; // bonus if match occurs after a separator
static constexpr int camel_bonus = 30; // bonus if match is uppercase and prev is lower static constexpr int camel_bonus = 30; // bonus if match is uppercase and prev is lower
static constexpr int first_letter_bonus = 15; // bonus if the first letter is matched static constexpr int first_letter_bonus = 15; // bonus if the first letter is matched
static constexpr int leading_letter_penalty = -5; // penalty applied for every letter in str before the first match static constexpr int leading_letter_penalty = -1/*-5*/; // penalty applied for every letter in str before the first match
static constexpr int max_leading_letter_penalty = -15; // maximum penalty for leading letters static constexpr int max_leading_letter_penalty = -15; // maximum penalty for leading letters
static constexpr int unmatched_letter_penalty = -1; // penalty for every letter that doesn't matter static constexpr int unmatched_letter_penalty = -1; // penalty for every letter that doesn't matter