option for not-fuzzy (regexp) search

supermerill/SuperSlicer#1211
This commit is contained in:
remi durand 2021-06-01 12:15:24 +02:00
parent 03cc99cdf7
commit e0f085bb03
3 changed files with 38 additions and 6 deletions

View File

@ -837,6 +837,7 @@ void ImGuiWrapper::search_list(const ImVec2& size_, bool (*items_getter)(int, co
check_box(_L("Category"), view_params.category); check_box(_L("Category"), view_params.category);
if (is_localized) if (is_localized)
check_box(_L("Search in English"), view_params.english); check_box(_L("Search in English"), view_params.english);
check_box(_L("Exact pattern"), view_params.exact);
} }
void ImGuiWrapper::title(const std::string& str) void ImGuiWrapper::title(const std::string& str)

View File

@ -175,6 +175,26 @@ static bool fuzzy_match(const std::wstring &search_pattern, const std::wstring &
return false; return false;
} }
static bool strong_match(const std::wstring& search_pattern, const std::wstring& label, int& out_score, std::vector<uint16_t>& out_matches) {
std::wregex pattern(search_pattern, std::regex_constants::icase);
std::wsmatch sm;
out_matches.clear();
out_score = 0;
std::wstring str_search = label;
size_t pos = 0;
while(std::regex_search(str_search, sm, pattern)){
pos += sm.position();
for (size_t j = 0; j < sm.length(); ++j)
out_matches.push_back(pos + j);
out_score += std::max(1, int(30 - pos));
pos += sm.length();
str_search = sm.suffix().str();
}
if (out_score <= 0)
out_score = std::numeric_limits<int>::min();
return out_score > 0;
}
bool OptionsSearcher::search(const std::string& search, bool force/* = false*/) bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
{ {
if (search_line == search && !force) if (search_line == search && !force)
@ -243,15 +263,19 @@ bool OptionsSearcher::search(const std::string& search, bool force/* = false*/)
int score = std::numeric_limits<int>::min(); int score = std::numeric_limits<int>::min();
int score2; int score2;
matches.clear(); matches.clear();
if(view_params.exact)
strong_match(wsearch, label, score, matches);
else
fuzzy_match(wsearch, label, score, matches); fuzzy_match(wsearch, label, score, matches);
if (fuzzy_match(wsearch, opt.opt_key, score2, matches2) && score2 > score) {
if ( (view_params.exact ? strong_match(wsearch, opt.opt_key, score2, matches2):fuzzy_match(wsearch, opt.opt_key, score2, matches2)) && (view_params.exact || score2 > score) ) {
for (fts::pos_type &pos : matches2) for (fts::pos_type &pos : matches2)
pos += label.size() + 1; pos += label.size() + 1;
label += L"(" + opt.opt_key + L")"; label += L"(" + opt.opt_key + L")";
append(matches, matches2); append(matches, matches2);
score = score2; score = std::max(score, score2);
} }
if (view_params.english && fuzzy_match(wsearch, label_english, score2, matches2) && score2 > score) { if (view_params.english && (view_params.exact ? strong_match(wsearch, label_english, score2, matches2) : fuzzy_match(wsearch, label_english, score2, matches2)) && score2 > score) {
label = std::move(label_english); label = std::move(label_english);
matches = std::move(matches2); matches = std::move(matches2);
score = score2; score = score2;
@ -387,6 +411,7 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
check_category = new wxCheckBox(this, wxID_ANY, _L("Category")); check_category = new wxCheckBox(this, wxID_ANY, _L("Category"));
if (GUI::wxGetApp().is_localized()) if (GUI::wxGetApp().is_localized())
check_english = new wxCheckBox(this, wxID_ANY, _L("Search in English")); check_english = new wxCheckBox(this, wxID_ANY, _L("Search in English"));
check_exact = new wxCheckBox(this, wxID_ANY, _L("Exact pattern"));
wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL); wxStdDialogButtonSizer* cancel_btn = this->CreateStdDialogButtonSizer(wxCANCEL);
@ -394,6 +419,7 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border); check_sizer->Add(check_category, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
if (check_english) if (check_english)
check_sizer->Add(check_english, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border); check_sizer->Add(check_english, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
check_sizer->Add(check_exact, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, border);
check_sizer->AddStretchSpacer(border); check_sizer->AddStretchSpacer(border);
check_sizer->Add(cancel_btn, 0, wxALIGN_CENTER_VERTICAL); check_sizer->Add(cancel_btn, 0, wxALIGN_CENTER_VERTICAL);
@ -425,6 +451,7 @@ SearchDialog::SearchDialog(OptionsSearcher* searcher)
check_category->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this); check_category->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
if (check_english) if (check_english)
check_english->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this); check_english->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
check_exact->Bind(wxEVT_CHECKBOX, &SearchDialog::OnCheck, this);
// Bind(wxEVT_MOTION, &SearchDialog::OnMotion, this); // Bind(wxEVT_MOTION, &SearchDialog::OnMotion, this);
Bind(wxEVT_LEFT_DOWN, &SearchDialog::OnLeftDown, this); Bind(wxEVT_LEFT_DOWN, &SearchDialog::OnLeftDown, this);
@ -446,6 +473,7 @@ void SearchDialog::Popup(wxPoint position /*= wxDefaultPosition*/)
check_category->SetValue(params.category); check_category->SetValue(params.category);
if (check_english) if (check_english)
check_english->SetValue(params.english); check_english->SetValue(params.english);
check_exact->SetValue(params.exact);
this->SetPosition(position); this->SetPosition(position);
this->ShowModal(); this->ShowModal();
@ -560,6 +588,7 @@ void SearchDialog::OnCheck(wxCommandEvent& event)
if (check_english) if (check_english)
params.english = check_english->GetValue(); params.english = check_english->GetValue();
params.category = check_category->GetValue(); params.category = check_category->GetValue();
params.exact = check_exact->GetValue();
searcher->search(); searcher->search();
update_list(); update_list();

View File

@ -68,6 +68,7 @@ struct OptionViewParameters
{ {
bool category {false}; bool category {false};
bool english {false}; bool english {false};
bool exact {false};
int hovered_id {0}; int hovered_id {0};
}; };
@ -154,6 +155,7 @@ class SearchDialog : public GUI::DPIDialog
SearchListModel* search_list_model { nullptr }; SearchListModel* search_list_model { nullptr };
wxCheckBox* check_category { nullptr }; wxCheckBox* check_category { nullptr };
wxCheckBox* check_english { nullptr }; wxCheckBox* check_english { nullptr };
wxCheckBox* check_exact { nullptr };
OptionsSearcher* searcher { nullptr }; OptionsSearcher* searcher { nullptr };